rfc_ts_frames.c 27 KB

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