rfc_ts_frames.c 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901
  1. /******************************************************************************
  2. *
  3. * Copyright (C) 1999-2012 Broadcom Corporation
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at:
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. *
  17. ******************************************************************************/
  18. /******************************************************************************
  19. *
  20. * This file contains functions to send TS 07.10 frames
  21. *
  22. ******************************************************************************/
  23. #include <stddef.h>
  24. #include "bt_target.h"
  25. #include "rfcdefs.h"
  26. #include "port_api.h"
  27. #include "l2c_api.h"
  28. #include "port_int.h"
  29. #include "rfc_int.h"
  30. #include "mutex.h"
  31. #include "allocator.h"
  32. #if (defined RFCOMM_INCLUDED && RFCOMM_INCLUDED == TRUE)
  33. /*******************************************************************************
  34. **
  35. ** Function rfc_send_sabme
  36. **
  37. ** Description This function sends SABME frame.
  38. **
  39. *******************************************************************************/
  40. void rfc_send_sabme (tRFC_MCB *p_mcb, UINT8 dlci)
  41. {
  42. BT_HDR *p_buf;
  43. UINT8 *p_data;
  44. UINT8 cr = RFCOMM_CR(p_mcb->is_initiator, TRUE);
  45. if ((p_buf = (BT_HDR *)osi_malloc(RFCOMM_CMD_BUF_SIZE)) == NULL) {
  46. return;
  47. }
  48. p_buf->offset = L2CAP_MIN_OFFSET;
  49. p_data = (UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET;
  50. /* SABME frame, command, PF = 1, dlci */
  51. *p_data++ = RFCOMM_EA | cr | (dlci << RFCOMM_SHIFT_DLCI);
  52. *p_data++ = RFCOMM_SABME | RFCOMM_PF;
  53. *p_data++ = RFCOMM_EA | 0;
  54. *p_data = RFCOMM_SABME_FCS ((UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET, cr, dlci);
  55. p_buf->len = 4;
  56. rfc_check_send_cmd(p_mcb, p_buf);
  57. }
  58. /*******************************************************************************
  59. **
  60. ** Function rfc_send_ua
  61. **
  62. ** Description This function sends UA frame.
  63. **
  64. *******************************************************************************/
  65. void rfc_send_ua (tRFC_MCB *p_mcb, UINT8 dlci)
  66. {
  67. BT_HDR *p_buf;
  68. UINT8 *p_data;
  69. UINT8 cr = RFCOMM_CR(p_mcb->is_initiator, FALSE);
  70. if ((p_buf = (BT_HDR *)osi_malloc(RFCOMM_CMD_BUF_SIZE)) == NULL) {
  71. return;
  72. }
  73. p_buf->offset = L2CAP_MIN_OFFSET;
  74. p_data = (UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET;
  75. /* ua frame, response, PF = 1, dlci */
  76. *p_data++ = RFCOMM_EA | cr | (dlci << RFCOMM_SHIFT_DLCI);
  77. *p_data++ = RFCOMM_UA | RFCOMM_PF;
  78. *p_data++ = RFCOMM_EA | 0;
  79. *p_data = RFCOMM_UA_FCS ((UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET, cr, dlci);
  80. p_buf->len = 4;
  81. rfc_check_send_cmd(p_mcb, p_buf);
  82. }
  83. /*******************************************************************************
  84. **
  85. ** Function rfc_send_dm
  86. **
  87. ** Description This function sends DM frame.
  88. **
  89. *******************************************************************************/
  90. void rfc_send_dm (tRFC_MCB *p_mcb, UINT8 dlci, BOOLEAN pf)
  91. {
  92. BT_HDR *p_buf;
  93. UINT8 *p_data;
  94. UINT8 cr = RFCOMM_CR(p_mcb->is_initiator, FALSE);
  95. if ((p_buf = (BT_HDR *)osi_malloc(RFCOMM_CMD_BUF_SIZE)) == NULL) {
  96. return;
  97. }
  98. p_buf->offset = L2CAP_MIN_OFFSET;
  99. p_data = (UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET;
  100. /* DM frame, response, PF = 1, dlci */
  101. *p_data++ = RFCOMM_EA | cr | (dlci << RFCOMM_SHIFT_DLCI);
  102. *p_data++ = RFCOMM_DM | ((pf) ? RFCOMM_PF : 0);
  103. *p_data++ = RFCOMM_EA | 0;
  104. *p_data = RFCOMM_DM_FCS ((UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET, cr, dlci);
  105. p_buf->len = 4;
  106. rfc_check_send_cmd(p_mcb, p_buf);
  107. }
  108. /*******************************************************************************
  109. **
  110. ** Function rfc_send_disc
  111. **
  112. ** Description This function sends DISC frame.
  113. **
  114. *******************************************************************************/
  115. void rfc_send_disc (tRFC_MCB *p_mcb, UINT8 dlci)
  116. {
  117. BT_HDR *p_buf;
  118. UINT8 *p_data;
  119. UINT8 cr = RFCOMM_CR(p_mcb->is_initiator, TRUE);
  120. if ((p_buf = (BT_HDR *)osi_malloc(RFCOMM_CMD_BUF_SIZE)) == NULL) {
  121. return;
  122. }
  123. p_buf->offset = L2CAP_MIN_OFFSET;
  124. p_data = (UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET;
  125. /* DISC frame, command, PF = 1, dlci */
  126. *p_data++ = RFCOMM_EA | cr | (dlci << RFCOMM_SHIFT_DLCI);
  127. *p_data++ = RFCOMM_DISC | RFCOMM_PF;
  128. *p_data++ = RFCOMM_EA | 0;
  129. *p_data = RFCOMM_DISC_FCS ((UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET, cr, dlci);
  130. p_buf->len = 4;
  131. rfc_check_send_cmd(p_mcb, p_buf);
  132. }
  133. /*******************************************************************************
  134. **
  135. ** Function rfc_send_buf_uih
  136. **
  137. ** Description This function sends UIH frame.
  138. **
  139. *******************************************************************************/
  140. void rfc_send_buf_uih (tRFC_MCB *p_mcb, UINT8 dlci, BT_HDR *p_buf)
  141. {
  142. UINT8 *p_data;
  143. UINT8 cr = RFCOMM_CR(p_mcb->is_initiator, TRUE);
  144. UINT8 credits;
  145. p_buf->offset -= RFCOMM_CTRL_FRAME_LEN;
  146. if (p_buf->len > 127) {
  147. p_buf->offset--;
  148. }
  149. if (dlci) {
  150. credits = (UINT8)p_buf->layer_specific;
  151. } else {
  152. credits = 0;
  153. }
  154. if (credits) {
  155. p_buf->offset--;
  156. }
  157. p_data = (UINT8 *)(p_buf + 1) + p_buf->offset;
  158. /* UIH frame, command, PF = 0, dlci */
  159. *p_data++ = RFCOMM_EA | cr | (dlci << RFCOMM_SHIFT_DLCI);
  160. *p_data++ = RFCOMM_UIH | ((credits) ? RFCOMM_PF : 0);
  161. if (p_buf->len <= 127) {
  162. *p_data++ = RFCOMM_EA | (p_buf->len << 1);
  163. p_buf->len += 3;
  164. } else {
  165. *p_data++ = (p_buf->len & 0x7f) << 1;
  166. *p_data++ = p_buf->len >> RFCOMM_SHIFT_LENGTH2;
  167. p_buf->len += 4;
  168. }
  169. if (credits) {
  170. *p_data++ = credits;
  171. p_buf->len++;
  172. }
  173. p_data = (UINT8 *)(p_buf + 1) + p_buf->offset + p_buf->len++;
  174. *p_data = RFCOMM_UIH_FCS ((UINT8 *)(p_buf + 1) + p_buf->offset, dlci);
  175. if (dlci == RFCOMM_MX_DLCI) {
  176. rfc_check_send_cmd(p_mcb, p_buf);
  177. } else {
  178. L2CA_DataWrite (p_mcb->lcid, p_buf);
  179. }
  180. }
  181. /*******************************************************************************
  182. **
  183. ** Function rfc_send_pn
  184. **
  185. ** Description This function sends DLC Parameters Negotiation Frame.
  186. **
  187. *******************************************************************************/
  188. void rfc_send_pn (tRFC_MCB *p_mcb, UINT8 dlci, BOOLEAN is_command, UINT16 mtu, UINT8 cl, UINT8 k)
  189. {
  190. BT_HDR *p_buf;
  191. UINT8 *p_data;
  192. if ((p_buf = (BT_HDR *)osi_malloc(RFCOMM_CMD_BUF_SIZE)) == NULL) {
  193. return;
  194. }
  195. p_buf->offset = L2CAP_MIN_OFFSET + RFCOMM_CTRL_FRAME_LEN;
  196. p_data = (UINT8 *)(p_buf + 1) + p_buf->offset;
  197. *p_data++ = RFCOMM_EA | RFCOMM_I_CR(is_command) | RFCOMM_MX_PN;
  198. *p_data++ = RFCOMM_EA | (RFCOMM_MX_PN_LEN << 1);
  199. *p_data++ = dlci;
  200. *p_data++ = RFCOMM_PN_FRAM_TYPE_UIH | cl;
  201. /* It appeared that we need to reply with the same priority bits as we received.
  202. ** We will use the fact that we reply in the same context so rx_frame can still be used.
  203. */
  204. if (is_command) {
  205. *p_data++ = RFCOMM_PN_PRIORITY_0;
  206. } else {
  207. *p_data++ = rfc_cb.rfc.rx_frame.u.pn.priority;
  208. }
  209. *p_data++ = RFCOMM_T1_DSEC;
  210. *p_data++ = mtu & 0xFF;
  211. *p_data++ = mtu >> 8;
  212. *p_data++ = RFCOMM_N2;
  213. *p_data = k;
  214. /* Total length is sizeof PN data + mx header 2 */
  215. p_buf->len = RFCOMM_MX_PN_LEN + 2;
  216. rfc_send_buf_uih (p_mcb, RFCOMM_MX_DLCI, p_buf);
  217. }
  218. /*******************************************************************************
  219. **
  220. ** Function rfc_send_fcon
  221. **
  222. ** Description This function sends Flow Control On Command.
  223. **
  224. *******************************************************************************/
  225. void rfc_send_fcon (tRFC_MCB *p_mcb, BOOLEAN is_command)
  226. {
  227. BT_HDR *p_buf;
  228. UINT8 *p_data;
  229. if ((p_buf = (BT_HDR *)osi_malloc(RFCOMM_CMD_BUF_SIZE)) == NULL) {
  230. return;
  231. }
  232. p_buf->offset = L2CAP_MIN_OFFSET + RFCOMM_CTRL_FRAME_LEN;
  233. p_data = (UINT8 *)(p_buf + 1) + p_buf->offset;
  234. *p_data++ = RFCOMM_EA | RFCOMM_I_CR(is_command) | RFCOMM_MX_FCON;
  235. *p_data++ = RFCOMM_EA | (RFCOMM_MX_FCON_LEN << 1);
  236. /* Total length is sizeof FCON data + mx header 2 */
  237. p_buf->len = RFCOMM_MX_FCON_LEN + 2;
  238. rfc_send_buf_uih (p_mcb, RFCOMM_MX_DLCI, p_buf);
  239. }
  240. /*******************************************************************************
  241. **
  242. ** Function rfc_send_fcoff
  243. **
  244. ** Description This function sends Flow Control Off Command.
  245. **
  246. *******************************************************************************/
  247. void rfc_send_fcoff (tRFC_MCB *p_mcb, BOOLEAN is_command)
  248. {
  249. BT_HDR *p_buf;
  250. UINT8 *p_data;
  251. if ((p_buf = (BT_HDR *)osi_malloc(RFCOMM_CMD_BUF_SIZE)) == NULL) {
  252. return;
  253. }
  254. p_buf->offset = L2CAP_MIN_OFFSET + RFCOMM_CTRL_FRAME_LEN;
  255. p_data = (UINT8 *)(p_buf + 1) + p_buf->offset;
  256. *p_data++ = RFCOMM_EA | RFCOMM_I_CR(is_command) | RFCOMM_MX_FCOFF;
  257. *p_data++ = RFCOMM_EA | (RFCOMM_MX_FCOFF_LEN << 1);
  258. /* Total length is sizeof FCOFF data + mx header 2 */
  259. p_buf->len = RFCOMM_MX_FCOFF_LEN + 2;
  260. rfc_send_buf_uih (p_mcb, RFCOMM_MX_DLCI, p_buf);
  261. }
  262. /*******************************************************************************
  263. **
  264. ** Function rfc_send_msc
  265. **
  266. ** Description This function sends Modem Status Command Frame.
  267. **
  268. *******************************************************************************/
  269. void rfc_send_msc (tRFC_MCB *p_mcb, UINT8 dlci, BOOLEAN is_command,
  270. tPORT_CTRL *p_pars)
  271. {
  272. BT_HDR *p_buf;
  273. UINT8 *p_data;
  274. UINT8 signals;
  275. UINT8 break_duration;
  276. UINT8 len;
  277. signals = p_pars->modem_signal;
  278. break_duration = p_pars->break_signal;
  279. if ((p_buf = (BT_HDR *)osi_malloc(RFCOMM_CMD_BUF_SIZE)) == NULL) {
  280. return;
  281. }
  282. p_buf->offset = L2CAP_MIN_OFFSET + RFCOMM_CTRL_FRAME_LEN;
  283. p_data = (UINT8 *)(p_buf + 1) + p_buf->offset;
  284. if (break_duration) {
  285. len = RFCOMM_MX_MSC_LEN_WITH_BREAK;
  286. } else {
  287. len = RFCOMM_MX_MSC_LEN_NO_BREAK;
  288. }
  289. *p_data++ = RFCOMM_EA | RFCOMM_I_CR(is_command) | RFCOMM_MX_MSC;
  290. *p_data++ = RFCOMM_EA | (len << 1);
  291. *p_data++ = RFCOMM_EA | RFCOMM_CR_MASK | (dlci << RFCOMM_SHIFT_DLCI);
  292. *p_data++ = RFCOMM_EA |
  293. ((p_pars->fc) ? RFCOMM_MSC_FC : 0) |
  294. ((signals & MODEM_SIGNAL_DTRDSR) ? RFCOMM_MSC_RTC : 0) |
  295. ((signals & MODEM_SIGNAL_RTSCTS) ? RFCOMM_MSC_RTR : 0) |
  296. ((signals & MODEM_SIGNAL_RI) ? RFCOMM_MSC_IC : 0) |
  297. ((signals & MODEM_SIGNAL_DCD) ? RFCOMM_MSC_DV : 0);
  298. if (break_duration) {
  299. *p_data++ = RFCOMM_EA | RFCOMM_MSC_BREAK_PRESENT_MASK |
  300. (break_duration << RFCOMM_MSC_SHIFT_BREAK);
  301. }
  302. /* Total length is sizeof MSC data + mx header 2 */
  303. p_buf->len = len + 2;
  304. rfc_send_buf_uih (p_mcb, RFCOMM_MX_DLCI, p_buf);
  305. }
  306. /*******************************************************************************
  307. **
  308. ** Function rfc_send_rls
  309. **
  310. ** Description This function sends Remote Line Status Command Frame.
  311. **
  312. *******************************************************************************/
  313. void rfc_send_rls (tRFC_MCB *p_mcb, UINT8 dlci, BOOLEAN is_command, UINT8 status)
  314. {
  315. BT_HDR *p_buf;
  316. UINT8 *p_data;
  317. if ((p_buf = (BT_HDR *)osi_malloc(RFCOMM_CMD_BUF_SIZE)) == NULL) {
  318. return;
  319. }
  320. p_buf->offset = L2CAP_MIN_OFFSET + RFCOMM_CTRL_FRAME_LEN;
  321. p_data = (UINT8 *)(p_buf + 1) + p_buf->offset;
  322. *p_data++ = RFCOMM_EA | RFCOMM_I_CR(is_command) | RFCOMM_MX_RLS;
  323. *p_data++ = RFCOMM_EA | (RFCOMM_MX_RLS_LEN << 1);
  324. *p_data++ = RFCOMM_EA | RFCOMM_CR_MASK | (dlci << RFCOMM_SHIFT_DLCI);
  325. *p_data++ = RFCOMM_RLS_ERROR | status;
  326. /* Total length is sizeof RLS data + mx header 2 */
  327. p_buf->len = RFCOMM_MX_RLS_LEN + 2;
  328. rfc_send_buf_uih (p_mcb, RFCOMM_MX_DLCI, p_buf);
  329. }
  330. /*******************************************************************************
  331. **
  332. ** Function rfc_send_nsc
  333. **
  334. ** Description This function sends Non Supported Command Response.
  335. **
  336. *******************************************************************************/
  337. void rfc_send_nsc (tRFC_MCB *p_mcb)
  338. {
  339. BT_HDR *p_buf;
  340. UINT8 *p_data;
  341. if ((p_buf = (BT_HDR *)osi_malloc(RFCOMM_CMD_BUF_SIZE)) == NULL) {
  342. return;
  343. }
  344. p_buf->offset = L2CAP_MIN_OFFSET + RFCOMM_CTRL_FRAME_LEN;
  345. p_data = (UINT8 *)(p_buf + 1) + p_buf->offset;
  346. *p_data++ = RFCOMM_EA | RFCOMM_I_CR(FALSE) | RFCOMM_MX_NSC;
  347. *p_data++ = RFCOMM_EA | (RFCOMM_MX_NSC_LEN << 1);
  348. *p_data++ = rfc_cb.rfc.rx_frame.ea |
  349. (rfc_cb.rfc.rx_frame.cr << RFCOMM_SHIFT_CR) |
  350. rfc_cb.rfc.rx_frame.type;
  351. /* Total length is sizeof NSC data + mx header 2 */
  352. p_buf->len = RFCOMM_MX_NSC_LEN + 2;
  353. rfc_send_buf_uih (p_mcb, RFCOMM_MX_DLCI, p_buf);
  354. }
  355. /*******************************************************************************
  356. **
  357. ** Function rfc_send_rpn
  358. **
  359. ** Description This function sends Remote Port Negotiation Command
  360. **
  361. *******************************************************************************/
  362. void rfc_send_rpn (tRFC_MCB *p_mcb, UINT8 dlci, BOOLEAN is_command,
  363. tPORT_STATE *p_pars, UINT16 mask)
  364. {
  365. BT_HDR *p_buf;
  366. UINT8 *p_data;
  367. if ((p_buf = (BT_HDR *)osi_malloc(RFCOMM_CMD_BUF_SIZE)) == NULL) {
  368. return;
  369. }
  370. p_buf->offset = L2CAP_MIN_OFFSET + RFCOMM_CTRL_FRAME_LEN;
  371. p_data = (UINT8 *)(p_buf + 1) + p_buf->offset;
  372. *p_data++ = RFCOMM_EA | RFCOMM_I_CR(is_command) | RFCOMM_MX_RPN;
  373. if (!p_pars) {
  374. *p_data++ = RFCOMM_EA | (RFCOMM_MX_RPN_REQ_LEN << 1);
  375. *p_data++ = RFCOMM_EA | RFCOMM_CR_MASK | (dlci << RFCOMM_SHIFT_DLCI);
  376. p_buf->len = RFCOMM_MX_RPN_REQ_LEN + 2;
  377. } else {
  378. *p_data++ = RFCOMM_EA | (RFCOMM_MX_RPN_LEN << 1);
  379. *p_data++ = RFCOMM_EA | RFCOMM_CR_MASK | (dlci << RFCOMM_SHIFT_DLCI);
  380. *p_data++ = p_pars->baud_rate;
  381. *p_data++ = (p_pars->byte_size << RFCOMM_RPN_BITS_SHIFT)
  382. | (p_pars->stop_bits << RFCOMM_RPN_STOP_BITS_SHIFT)
  383. | (p_pars->parity << RFCOMM_RPN_PARITY_SHIFT)
  384. | (p_pars->parity_type << RFCOMM_RPN_PARITY_TYPE_SHIFT);
  385. *p_data++ = p_pars->fc_type;
  386. *p_data++ = p_pars->xon_char;
  387. *p_data++ = p_pars->xoff_char;
  388. *p_data++ = (mask & 0xFF);
  389. *p_data++ = (mask >> 8);
  390. /* Total length is sizeof RPN data + mx header 2 */
  391. p_buf->len = RFCOMM_MX_RPN_LEN + 2;
  392. }
  393. rfc_send_buf_uih (p_mcb, RFCOMM_MX_DLCI, p_buf);
  394. }
  395. /*******************************************************************************
  396. **
  397. ** Function rfc_send_test
  398. **
  399. ** Description This function sends Test frame.
  400. **
  401. *******************************************************************************/
  402. void rfc_send_test (tRFC_MCB *p_mcb, BOOLEAN is_command, BT_HDR *p_buf)
  403. {
  404. UINT8 *p_data;
  405. UINT16 xx;
  406. UINT8 *p_src, *p_dest;
  407. /* Shift buffer to give space for header */
  408. if (p_buf->offset < (L2CAP_MIN_OFFSET + RFCOMM_MIN_OFFSET + 2)) {
  409. p_src = (UINT8 *) (p_buf + 1) + p_buf->offset + p_buf->len - 1;
  410. p_dest = (UINT8 *) (p_buf + 1) + L2CAP_MIN_OFFSET + RFCOMM_MIN_OFFSET + 2 + p_buf->len - 1;
  411. for (xx = 0; xx < p_buf->len; xx++) {
  412. *p_dest-- = *p_src--;
  413. }
  414. p_buf->offset = L2CAP_MIN_OFFSET + RFCOMM_MIN_OFFSET + 2;
  415. }
  416. /* Adjust offset by number of bytes we are going to fill */
  417. p_buf->offset -= 2;
  418. p_data = (UINT8 *)(p_buf + 1) + p_buf->offset;
  419. *p_data++ = RFCOMM_EA | RFCOMM_I_CR(is_command) | RFCOMM_MX_TEST;
  420. *p_data++ = RFCOMM_EA | (p_buf->len << 1);
  421. p_buf->len += 2;
  422. rfc_send_buf_uih (p_mcb, RFCOMM_MX_DLCI, p_buf);
  423. }
  424. /*******************************************************************************
  425. **
  426. ** Function rfc_send_credit
  427. **
  428. ** Description This function sends a flow control credit in UIH frame.
  429. **
  430. *******************************************************************************/
  431. void rfc_send_credit(tRFC_MCB *p_mcb, UINT8 dlci, UINT8 credit)
  432. {
  433. BT_HDR *p_buf;
  434. UINT8 *p_data;
  435. UINT8 cr = RFCOMM_CR(p_mcb->is_initiator, TRUE);
  436. if ((p_buf = (BT_HDR *)osi_malloc(RFCOMM_CMD_BUF_SIZE)) == NULL) {
  437. return;
  438. }
  439. p_buf->offset = L2CAP_MIN_OFFSET;
  440. p_data = (UINT8 *)(p_buf + 1) + p_buf->offset;
  441. *p_data++ = RFCOMM_EA | cr | (dlci << RFCOMM_SHIFT_DLCI);
  442. *p_data++ = RFCOMM_UIH | RFCOMM_PF;
  443. *p_data++ = RFCOMM_EA | 0;
  444. *p_data++ = credit;
  445. *p_data = RFCOMM_UIH_FCS ((UINT8 *)(p_buf + 1) + p_buf->offset, dlci);
  446. p_buf->len = 5;
  447. rfc_check_send_cmd(p_mcb, p_buf);
  448. }
  449. /*******************************************************************************
  450. **
  451. ** Function rfc_parse_data
  452. **
  453. ** Description This function processes data packet received from L2CAP
  454. **
  455. *******************************************************************************/
  456. UINT8 rfc_parse_data (tRFC_MCB *p_mcb, MX_FRAME *p_frame, BT_HDR *p_buf)
  457. {
  458. UINT8 ead, eal, fcs;
  459. UINT8 *p_data = (UINT8 *)(p_buf + 1) + p_buf->offset;
  460. UINT8 *p_start = p_data;
  461. UINT16 len;
  462. if (p_buf->len < RFCOMM_CTRL_FRAME_LEN) {
  463. RFCOMM_TRACE_ERROR ("Bad Length1: %d", p_buf->len);
  464. return (RFC_EVENT_BAD_FRAME);
  465. }
  466. RFCOMM_PARSE_CTRL_FIELD (ead, p_frame->cr, p_frame->dlci, p_data);
  467. if ( !ead ) {
  468. RFCOMM_TRACE_ERROR ("Bad Address(EA must be 1)");
  469. return (RFC_EVENT_BAD_FRAME);
  470. }
  471. RFCOMM_PARSE_TYPE_FIELD (p_frame->type, p_frame->pf, p_data);
  472. RFCOMM_PARSE_LEN_FIELD (eal, len, p_data);
  473. p_buf->len -= (3 + !ead + !eal + 1); /* Additional 1 for FCS */
  474. p_buf->offset += (3 + !ead + !eal);
  475. /* handle credit if credit based flow control */
  476. if ((p_mcb->flow == PORT_FC_CREDIT) && (p_frame->type == RFCOMM_UIH) &&
  477. (p_frame->dlci != RFCOMM_MX_DLCI) && (p_frame->pf == 1)) {
  478. p_frame->credit = *p_data++;
  479. p_buf->len--;
  480. p_buf->offset++;
  481. } else {
  482. p_frame->credit = 0;
  483. }
  484. if (p_buf->len != len) {
  485. RFCOMM_TRACE_ERROR ("Bad Length2 %d %d", p_buf->len, len);
  486. return (RFC_EVENT_BAD_FRAME);
  487. }
  488. fcs = *(p_data + len);
  489. /* All control frames that we are sending are sent with P=1, expect */
  490. /* reply with F=1 */
  491. /* According to TS 07.10 spec ivalid frames are discarded without */
  492. /* notification to the sender */
  493. switch (p_frame->type) {
  494. case RFCOMM_SABME:
  495. if (RFCOMM_FRAME_IS_RSP(p_mcb->is_initiator, p_frame->cr)
  496. || !p_frame->pf || len || !RFCOMM_VALID_DLCI (p_frame->dlci)
  497. || !rfc_check_fcs (RFCOMM_CTRL_FRAME_LEN, p_start, fcs)) {
  498. RFCOMM_TRACE_ERROR ("Bad SABME");
  499. return (RFC_EVENT_BAD_FRAME);
  500. } else {
  501. return (RFC_EVENT_SABME);
  502. }
  503. case RFCOMM_UA:
  504. if (RFCOMM_FRAME_IS_CMD(p_mcb->is_initiator, p_frame->cr)
  505. || !p_frame->pf || len || !RFCOMM_VALID_DLCI (p_frame->dlci)
  506. || !rfc_check_fcs (RFCOMM_CTRL_FRAME_LEN, p_start, fcs)) {
  507. RFCOMM_TRACE_ERROR ("Bad UA");
  508. return (RFC_EVENT_BAD_FRAME);
  509. } else {
  510. return (RFC_EVENT_UA);
  511. }
  512. case RFCOMM_DM:
  513. if (RFCOMM_FRAME_IS_CMD(p_mcb->is_initiator, p_frame->cr)
  514. || len || !RFCOMM_VALID_DLCI(p_frame->dlci)
  515. || !rfc_check_fcs (RFCOMM_CTRL_FRAME_LEN, p_start, fcs)) {
  516. RFCOMM_TRACE_ERROR ("Bad DM");
  517. return (RFC_EVENT_BAD_FRAME);
  518. } else {
  519. return (RFC_EVENT_DM);
  520. }
  521. case RFCOMM_DISC:
  522. if (RFCOMM_FRAME_IS_RSP(p_mcb->is_initiator, p_frame->cr)
  523. || !p_frame->pf || len || !RFCOMM_VALID_DLCI(p_frame->dlci)
  524. || !rfc_check_fcs (RFCOMM_CTRL_FRAME_LEN, p_start, fcs)) {
  525. RFCOMM_TRACE_ERROR ("Bad DISC");
  526. return (RFC_EVENT_BAD_FRAME);
  527. } else {
  528. return (RFC_EVENT_DISC);
  529. }
  530. case RFCOMM_UIH:
  531. if (!RFCOMM_VALID_DLCI(p_frame->dlci)) {
  532. RFCOMM_TRACE_ERROR ("Bad UIH - invalid DLCI");
  533. return (RFC_EVENT_BAD_FRAME);
  534. } else if (!rfc_check_fcs (2, p_start, fcs)) {
  535. RFCOMM_TRACE_ERROR ("Bad UIH - FCS");
  536. return (RFC_EVENT_BAD_FRAME);
  537. } else if (RFCOMM_FRAME_IS_RSP(p_mcb->is_initiator, p_frame->cr)) {
  538. /* we assume that this is ok to allow bad implementations to work */
  539. RFCOMM_TRACE_ERROR ("Bad UIH - response");
  540. return (RFC_EVENT_UIH);
  541. } else {
  542. return (RFC_EVENT_UIH);
  543. }
  544. }
  545. return (RFC_EVENT_BAD_FRAME);
  546. }
  547. /*******************************************************************************
  548. **
  549. ** Function rfc_process_mx_message
  550. **
  551. ** Description This function processes UIH frames received on the
  552. ** multiplexer control channel.
  553. **
  554. *******************************************************************************/
  555. void rfc_process_mx_message (tRFC_MCB *p_mcb, BT_HDR *p_buf)
  556. {
  557. UINT8 *p_data = (UINT8 *)(p_buf + 1) + p_buf->offset;
  558. MX_FRAME *p_rx_frame = &rfc_cb.rfc.rx_frame;
  559. UINT16 length = p_buf->len;
  560. UINT8 ea, cr, mx_len;
  561. BOOLEAN is_command;
  562. p_rx_frame->ea = *p_data & RFCOMM_EA;
  563. p_rx_frame->cr = (*p_data & RFCOMM_CR_MASK) >> RFCOMM_SHIFT_CR;
  564. p_rx_frame->type = *p_data++ & ~(RFCOMM_CR_MASK | RFCOMM_EA_MASK);
  565. if (!p_rx_frame->ea || !length) {
  566. RFCOMM_TRACE_ERROR ("Illegal MX Frame ea:%d len:%d", p_rx_frame->ea, length);
  567. osi_free (p_buf);
  568. return;
  569. }
  570. length--;
  571. is_command = p_rx_frame->cr;
  572. ea = *p_data & RFCOMM_EA;
  573. mx_len = *p_data++ >> RFCOMM_SHIFT_LENGTH1;
  574. length--;
  575. if (!ea) {
  576. mx_len += *p_data++ << RFCOMM_SHIFT_LENGTH2;
  577. length --;
  578. }
  579. if (mx_len != length) {
  580. RFCOMM_TRACE_ERROR ("Bad MX frame");
  581. osi_free (p_buf);
  582. return;
  583. }
  584. switch (p_rx_frame->type) {
  585. case RFCOMM_MX_PN:
  586. if (length != RFCOMM_MX_PN_LEN) {
  587. break;
  588. }
  589. p_rx_frame->dlci = *p_data++ & RFCOMM_PN_DLCI_MASK;
  590. p_rx_frame->u.pn.frame_type = *p_data & RFCOMM_PN_FRAME_TYPE_MASK;
  591. p_rx_frame->u.pn.conv_layer = *p_data++ & RFCOMM_PN_CONV_LAYER_MASK;
  592. p_rx_frame->u.pn.priority = *p_data++ & RFCOMM_PN_PRIORITY_MASK;
  593. p_rx_frame->u.pn.t1 = *p_data++;
  594. p_rx_frame->u.pn.mtu = *p_data + (*(p_data + 1) << 8);
  595. p_data += 2;
  596. p_rx_frame->u.pn.n2 = *p_data++;
  597. p_rx_frame->u.pn.k = *p_data++ & RFCOMM_PN_K_MASK;
  598. if (!p_rx_frame->dlci
  599. || !RFCOMM_VALID_DLCI (p_rx_frame->dlci)
  600. || (p_rx_frame->u.pn.mtu < RFCOMM_MIN_MTU)
  601. || (p_rx_frame->u.pn.mtu > RFCOMM_MAX_MTU)) {
  602. RFCOMM_TRACE_ERROR ("Bad PN frame");
  603. break;
  604. }
  605. osi_free (p_buf);
  606. rfc_process_pn (p_mcb, is_command, p_rx_frame);
  607. return;
  608. case RFCOMM_MX_TEST:
  609. if (!length) {
  610. break;
  611. }
  612. p_rx_frame->u.test.p_data = p_data;
  613. p_rx_frame->u.test.data_len = length;
  614. p_buf->offset += 2;
  615. p_buf->len -= 2;
  616. if (is_command) {
  617. rfc_send_test (p_mcb, FALSE, p_buf);
  618. } else {
  619. rfc_process_test_rsp (p_mcb, p_buf);
  620. }
  621. return;
  622. case RFCOMM_MX_FCON:
  623. if (length != RFCOMM_MX_FCON_LEN) {
  624. break;
  625. }
  626. osi_free (p_buf);
  627. rfc_process_fcon (p_mcb, is_command);
  628. return;
  629. case RFCOMM_MX_FCOFF:
  630. if (length != RFCOMM_MX_FCOFF_LEN) {
  631. break;
  632. }
  633. osi_free (p_buf);
  634. rfc_process_fcoff (p_mcb, is_command);
  635. return;
  636. case RFCOMM_MX_MSC:
  637. ea = *p_data & RFCOMM_EA;
  638. cr = (*p_data & RFCOMM_CR_MASK) >> RFCOMM_SHIFT_CR;
  639. p_rx_frame->dlci = *p_data++ >> RFCOMM_SHIFT_DLCI;
  640. if (!ea || !cr || !p_rx_frame->dlci
  641. || !RFCOMM_VALID_DLCI (p_rx_frame->dlci)) {
  642. RFCOMM_TRACE_ERROR ("Bad MSC frame");
  643. break;
  644. }
  645. p_rx_frame->u.msc.signals = *p_data++;
  646. if (mx_len == RFCOMM_MX_MSC_LEN_WITH_BREAK) {
  647. p_rx_frame->u.msc.break_present = *p_data & RFCOMM_MSC_BREAK_PRESENT_MASK;
  648. p_rx_frame->u.msc.break_duration = (*p_data & RFCOMM_MSC_BREAK_MASK) >> RFCOMM_MSC_SHIFT_BREAK;
  649. } else {
  650. p_rx_frame->u.msc.break_present = FALSE;
  651. p_rx_frame->u.msc.break_duration = 0;
  652. }
  653. osi_free (p_buf);
  654. rfc_process_msc (p_mcb, is_command, p_rx_frame);
  655. return;
  656. case RFCOMM_MX_NSC:
  657. if ((length != RFCOMM_MX_NSC_LEN) || !is_command) {
  658. break;
  659. }
  660. p_rx_frame->u.nsc.ea = *p_data & RFCOMM_EA;
  661. p_rx_frame->u.nsc.cr = (*p_data & RFCOMM_CR_MASK) >> RFCOMM_SHIFT_CR;
  662. p_rx_frame->u.nsc.type = *p_data++ >> RFCOMM_SHIFT_DLCI;
  663. osi_free (p_buf);
  664. rfc_process_nsc (p_mcb, p_rx_frame);
  665. return;
  666. case RFCOMM_MX_RPN:
  667. if ((length != RFCOMM_MX_RPN_REQ_LEN) && (length != RFCOMM_MX_RPN_LEN)) {
  668. break;
  669. }
  670. ea = *p_data & RFCOMM_EA;
  671. cr = (*p_data & RFCOMM_CR_MASK) >> RFCOMM_SHIFT_CR;
  672. p_rx_frame->dlci = *p_data++ >> RFCOMM_SHIFT_DLCI;
  673. if (!ea || !cr || !p_rx_frame->dlci
  674. || !RFCOMM_VALID_DLCI (p_rx_frame->dlci)) {
  675. RFCOMM_TRACE_ERROR ("Bad RPN frame");
  676. break;
  677. }
  678. p_rx_frame->u.rpn.is_request = (length == RFCOMM_MX_RPN_REQ_LEN);
  679. if (!p_rx_frame->u.rpn.is_request) {
  680. p_rx_frame->u.rpn.baud_rate = *p_data++;
  681. p_rx_frame->u.rpn.byte_size = (*p_data >> RFCOMM_RPN_BITS_SHIFT) & RFCOMM_RPN_BITS_MASK;
  682. p_rx_frame->u.rpn.stop_bits = (*p_data >> RFCOMM_RPN_STOP_BITS_SHIFT) & RFCOMM_RPN_STOP_BITS_MASK;
  683. p_rx_frame->u.rpn.parity = (*p_data >> RFCOMM_RPN_PARITY_SHIFT) & RFCOMM_RPN_PARITY_MASK;
  684. p_rx_frame->u.rpn.parity_type = (*p_data++ >> RFCOMM_RPN_PARITY_TYPE_SHIFT) & RFCOMM_RPN_PARITY_TYPE_MASK;
  685. p_rx_frame->u.rpn.fc_type = *p_data++ & RFCOMM_FC_MASK;
  686. p_rx_frame->u.rpn.xon_char = *p_data++;
  687. p_rx_frame->u.rpn.xoff_char = *p_data++;
  688. p_rx_frame->u.rpn.param_mask = (*p_data + (*(p_data + 1) << 8)) & RFCOMM_RPN_PM_MASK;
  689. }
  690. osi_free (p_buf);
  691. rfc_process_rpn (p_mcb, is_command, p_rx_frame->u.rpn.is_request, p_rx_frame);
  692. return;
  693. case RFCOMM_MX_RLS:
  694. if (length != RFCOMM_MX_RLS_LEN) {
  695. break;
  696. }
  697. ea = *p_data & RFCOMM_EA;
  698. cr = (*p_data & RFCOMM_CR_MASK) >> RFCOMM_SHIFT_CR;
  699. p_rx_frame->dlci = *p_data++ >> RFCOMM_SHIFT_DLCI;
  700. p_rx_frame->u.rls.line_status = (*p_data & ~0x01);
  701. if (!ea || !cr || !p_rx_frame->dlci
  702. || !RFCOMM_VALID_DLCI (p_rx_frame->dlci)) {
  703. RFCOMM_TRACE_ERROR ("Bad RPN frame");
  704. break;
  705. }
  706. osi_free (p_buf);
  707. rfc_process_rls (p_mcb, is_command, p_rx_frame);
  708. return;
  709. }
  710. osi_free (p_buf);
  711. if (is_command) {
  712. rfc_send_nsc (p_mcb);
  713. }
  714. }
  715. #endif ///(defined RFCOMM_INCLUDED && RFCOMM_INCLUDED == TRUE)