rfc_ts_frames.c 29 KB

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