gap_conn.c 40 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243
  1. /******************************************************************************
  2. *
  3. * Copyright (C) 2009-2013 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. #include "bt_target.h"
  19. #include "bt_defs.h"
  20. #include "btu.h"
  21. #include "gap_int.h"
  22. #include "l2cdefs.h"
  23. #include "l2c_int.h"
  24. #include <string.h>
  25. #if GAP_CONN_INCLUDED == TRUE
  26. #include "btm_int.h"
  27. /********************************************************************************/
  28. /* L O C A L F U N C T I O N P R O T O T Y P E S */
  29. /********************************************************************************/
  30. static void gap_connect_ind (BD_ADDR bd_addr, UINT16 l2cap_cid, UINT16 psm, UINT8 l2cap_id);
  31. static void gap_connect_cfm (UINT16 l2cap_cid, UINT16 result);
  32. static void gap_config_ind (UINT16 l2cap_cid, tL2CAP_CFG_INFO *p_cfg);
  33. static void gap_config_cfm (UINT16 l2cap_cid, tL2CAP_CFG_INFO *p_cfg);
  34. static void gap_disconnect_ind (UINT16 l2cap_cid, BOOLEAN ack_needed);
  35. static void gap_data_ind (UINT16 l2cap_cid, BT_HDR *p_msg);
  36. static void gap_congestion_ind (UINT16 lcid, BOOLEAN is_congested);
  37. static tGAP_CCB *gap_find_ccb_by_cid (UINT16 cid);
  38. static tGAP_CCB *gap_find_ccb_by_handle (UINT16 handle);
  39. static tGAP_CCB *gap_allocate_ccb (void);
  40. static void gap_release_ccb (tGAP_CCB *p_ccb);
  41. /*******************************************************************************
  42. **
  43. ** Function gap_conn_init
  44. **
  45. ** Description This function is called to initialize GAP connection management
  46. **
  47. ** Returns void
  48. **
  49. *******************************************************************************/
  50. void gap_conn_init (void)
  51. {
  52. #if ((defined AMP_INCLUDED) && (AMP_INCLUDED == TRUE))
  53. gap_cb.conn.reg_info.pAMP_ConnectInd_Cb = gap_connect_ind;
  54. gap_cb.conn.reg_info.pAMP_ConnectCfm_Cb = gap_connect_cfm;
  55. gap_cb.conn.reg_info.pAMP_ConnectPnd_Cb = NULL;
  56. gap_cb.conn.reg_info.pAMP_ConfigInd_Cb = gap_config_ind;
  57. gap_cb.conn.reg_info.pAMP_ConfigCfm_Cb = gap_config_cfm;
  58. gap_cb.conn.reg_info.pAMP_DisconnectInd_Cb = gap_disconnect_ind;
  59. gap_cb.conn.reg_info.pAMP_DisconnectCfm_Cb = NULL;
  60. gap_cb.conn.reg_info.pAMP_QoSViolationInd_Cb = NULL;
  61. gap_cb.conn.reg_info.pAMP_DataInd_Cb = gap_data_ind;
  62. gap_cb.conn.reg_info.pAMP_CongestionStatus_Cb = gap_congestion_ind;
  63. gap_cb.conn.reg_info.pAMP_TxComplete_Cb = NULL;
  64. gap_cb.conn.reg_info.pAMP_MoveInd_Cb = NULL;
  65. gap_cb.conn.reg_info.pAMP_MoveRsp_Cb = NULL;
  66. gap_cb.conn.reg_info.pAMP_MoveCfm_Cb = NULL; //gap_move_cfm
  67. gap_cb.conn.reg_info.pAMP_MoveCfmRsp_Cb = NULL; //gap_move_cfm_rsp
  68. #else
  69. gap_cb.conn.reg_info.pL2CA_ConnectInd_Cb = gap_connect_ind;
  70. gap_cb.conn.reg_info.pL2CA_ConnectCfm_Cb = gap_connect_cfm;
  71. gap_cb.conn.reg_info.pL2CA_ConnectPnd_Cb = NULL;
  72. gap_cb.conn.reg_info.pL2CA_ConfigInd_Cb = gap_config_ind;
  73. gap_cb.conn.reg_info.pL2CA_ConfigCfm_Cb = gap_config_cfm;
  74. gap_cb.conn.reg_info.pL2CA_DisconnectInd_Cb = gap_disconnect_ind;
  75. gap_cb.conn.reg_info.pL2CA_DisconnectCfm_Cb = NULL;
  76. gap_cb.conn.reg_info.pL2CA_QoSViolationInd_Cb = NULL;
  77. gap_cb.conn.reg_info.pL2CA_DataInd_Cb = gap_data_ind;
  78. gap_cb.conn.reg_info.pL2CA_CongestionStatus_Cb = gap_congestion_ind;
  79. gap_cb.conn.reg_info.pL2CA_TxComplete_Cb = NULL;
  80. #endif
  81. }
  82. /*******************************************************************************
  83. **
  84. ** Function GAP_ConnOpen
  85. **
  86. ** Description This function is called to open an L2CAP connection.
  87. **
  88. ** Parameters: is_server - If TRUE, the connection is not created
  89. ** but put into a "listen" mode waiting for
  90. ** the remote side to connect.
  91. **
  92. ** service_id - Unique service ID from
  93. ** BTM_SEC_SERVICE_FIRST_EMPTY (6)
  94. ** to BTM_SEC_MAX_SERVICE_RECORDS (32)
  95. **
  96. ** p_rem_bda - Pointer to remote BD Address.
  97. ** If a server, and we don't care about the
  98. ** remote BD Address, then NULL should be passed.
  99. **
  100. ** psm - the PSM used for the connection
  101. **
  102. ** p_config - Optional pointer to configuration structure.
  103. ** If NULL, the default GAP configuration will
  104. ** be used.
  105. **
  106. ** security - security flags
  107. ** chan_mode_mask - (GAP_FCR_CHAN_OPT_BASIC, GAP_FCR_CHAN_OPT_ERTM,
  108. ** GAP_FCR_CHAN_OPT_STREAM)
  109. **
  110. ** p_cb - Pointer to callback function for events.
  111. **
  112. ** Returns handle of the connection if successful, else GAP_INVALID_HANDLE
  113. **
  114. *******************************************************************************/
  115. UINT16 GAP_ConnOpen (char *p_serv_name, UINT8 service_id, BOOLEAN is_server,
  116. BD_ADDR p_rem_bda, UINT16 psm, tL2CAP_CFG_INFO *p_cfg,
  117. tL2CAP_ERTM_INFO *ertm_info, UINT16 security, UINT8 chan_mode_mask,
  118. tGAP_CONN_CALLBACK *p_cb)
  119. {
  120. tGAP_CCB *p_ccb;
  121. UINT16 cid;
  122. //tBT_UUID bt_uuid = {2, {GAP_PROTOCOL_ID}};
  123. GAP_TRACE_EVENT ("GAP_CONN - Open Request");
  124. /* Allocate a new CCB. Return if none available. */
  125. if ((p_ccb = gap_allocate_ccb()) == NULL) {
  126. return (GAP_INVALID_HANDLE);
  127. }
  128. /* If caller specified a BD address, save it */
  129. if (p_rem_bda) {
  130. /* the bd addr is not BT_BD_ANY, then a bd address was specified */
  131. if (memcmp (p_rem_bda, BT_BD_ANY, BD_ADDR_LEN)) {
  132. p_ccb->rem_addr_specified = TRUE;
  133. }
  134. memcpy (&p_ccb->rem_dev_address[0], p_rem_bda, BD_ADDR_LEN);
  135. } else if (!is_server) {
  136. /* remore addr is not specified and is not a server -> bad */
  137. return (GAP_INVALID_HANDLE);
  138. }
  139. /* A client MUST have specified a bd addr to connect with */
  140. if (!p_ccb->rem_addr_specified && !is_server) {
  141. gap_release_ccb (p_ccb);
  142. GAP_TRACE_ERROR ("GAP ERROR: Client must specify a remote BD ADDR to connect to!");
  143. return (GAP_INVALID_HANDLE);
  144. }
  145. /* Check if configuration was specified */
  146. if (p_cfg) {
  147. p_ccb->cfg = *p_cfg;
  148. }
  149. p_ccb->p_callback = p_cb;
  150. /* If originator, use a dynamic PSM */
  151. #if ((defined AMP_INCLUDED) && (AMP_INCLUDED == TRUE))
  152. if (!is_server) {
  153. gap_cb.conn.reg_info.pAMP_ConnectInd_Cb = NULL;
  154. } else {
  155. gap_cb.conn.reg_info.pAMP_ConnectInd_Cb = gap_connect_ind;
  156. }
  157. #else
  158. if (!is_server) {
  159. gap_cb.conn.reg_info.pL2CA_ConnectInd_Cb = NULL;
  160. } else {
  161. gap_cb.conn.reg_info.pL2CA_ConnectInd_Cb = gap_connect_ind;
  162. }
  163. #endif
  164. /* Register the PSM with L2CAP */
  165. if ((p_ccb->psm = L2CA_REGISTER (psm, &gap_cb.conn.reg_info,
  166. AMP_AUTOSWITCH_ALLOWED | AMP_USE_AMP_IF_POSSIBLE)) == 0) {
  167. GAP_TRACE_ERROR ("GAP_ConnOpen: Failure registering PSM 0x%04x", psm);
  168. gap_release_ccb (p_ccb);
  169. return (GAP_INVALID_HANDLE);
  170. }
  171. /* Register with Security Manager for the specific security level */
  172. p_ccb->service_id = service_id;
  173. if (!BTM_SetSecurityLevel ((UINT8)!is_server, p_serv_name,
  174. p_ccb->service_id, security, p_ccb->psm, 0, 0)) {
  175. GAP_TRACE_ERROR ("GAP_CONN - Security Error");
  176. gap_release_ccb (p_ccb);
  177. return (GAP_INVALID_HANDLE);
  178. }
  179. /* Fill in eL2CAP parameter data */
  180. if ( p_ccb->cfg.fcr_present ) {
  181. if (ertm_info == NULL) {
  182. p_ccb->ertm_info.preferred_mode = p_ccb->cfg.fcr.mode;
  183. p_ccb->ertm_info.user_rx_pool_id = GAP_DATA_POOL_ID;
  184. p_ccb->ertm_info.user_tx_pool_id = GAP_DATA_POOL_ID;
  185. p_ccb->ertm_info.fcr_rx_pool_id = L2CAP_DEFAULT_ERM_POOL_ID;
  186. p_ccb->ertm_info.fcr_tx_pool_id = L2CAP_DEFAULT_ERM_POOL_ID;
  187. } else {
  188. p_ccb->ertm_info = *ertm_info;
  189. }
  190. }
  191. /* optional FCR channel modes */
  192. if (ertm_info != NULL) {
  193. p_ccb->ertm_info.allowed_modes =
  194. (chan_mode_mask) ? chan_mode_mask : (UINT8)L2CAP_FCR_CHAN_OPT_BASIC;
  195. }
  196. if (is_server) {
  197. p_ccb->con_flags |= GAP_CCB_FLAGS_SEC_DONE; /* assume btm/l2cap would handle it */
  198. p_ccb->con_state = GAP_CCB_STATE_LISTENING;
  199. return (p_ccb->gap_handle);
  200. } else {
  201. /* We are the originator of this connection */
  202. p_ccb->con_flags = GAP_CCB_FLAGS_IS_ORIG;
  203. /* Transition to the next appropriate state, waiting for connection confirm. */
  204. p_ccb->con_state = GAP_CCB_STATE_CONN_SETUP;
  205. /* mark security done flag, when security is not required */
  206. if ((security & (BTM_SEC_OUT_AUTHORIZE | BTM_SEC_OUT_AUTHENTICATE | BTM_SEC_OUT_ENCRYPT) ) == 0) {
  207. p_ccb->con_flags |= GAP_CCB_FLAGS_SEC_DONE;
  208. }
  209. /* Check if L2CAP started the connection process */
  210. if (p_rem_bda && ((cid = L2CA_CONNECT_REQ (p_ccb->psm, p_rem_bda, &p_ccb->ertm_info, &bt_uuid)) != 0)) {
  211. p_ccb->connection_id = cid;
  212. return (p_ccb->gap_handle);
  213. } else {
  214. gap_release_ccb (p_ccb);
  215. return (GAP_INVALID_HANDLE);
  216. }
  217. }
  218. }
  219. /*******************************************************************************
  220. **
  221. ** Function GAP_ConnClose
  222. **
  223. ** Description This function is called to close a connection.
  224. **
  225. ** Parameters: handle - Handle of the connection returned by GAP_ConnOpen
  226. **
  227. ** Returns BT_PASS - closed OK
  228. ** GAP_ERR_BAD_HANDLE - invalid handle
  229. **
  230. *******************************************************************************/
  231. UINT16 GAP_ConnClose (UINT16 gap_handle)
  232. {
  233. tGAP_CCB *p_ccb = gap_find_ccb_by_handle (gap_handle);
  234. GAP_TRACE_EVENT ("GAP_CONN - close handle: 0x%x", gap_handle);
  235. if (p_ccb) {
  236. /* Check if we have a connection ID */
  237. if (p_ccb->con_state != GAP_CCB_STATE_LISTENING) {
  238. L2CA_DISCONNECT_REQ (p_ccb->connection_id);
  239. }
  240. gap_release_ccb (p_ccb);
  241. return (BT_PASS);
  242. }
  243. return (GAP_ERR_BAD_HANDLE);
  244. }
  245. /*******************************************************************************
  246. **
  247. ** Function GAP_ConnReadData
  248. **
  249. ** Description Normally not GKI aware application will call this function
  250. ** after receiving GAP_EVT_RXDATA event.
  251. **
  252. ** Parameters: handle - Handle of the connection returned in the Open
  253. ** p_data - Data area
  254. ** max_len - Byte count requested
  255. ** p_len - Byte count received
  256. **
  257. ** Returns BT_PASS - data read
  258. ** GAP_ERR_BAD_HANDLE - invalid handle
  259. ** GAP_NO_DATA_AVAIL - no data available
  260. **
  261. *******************************************************************************/
  262. UINT16 GAP_ConnReadData (UINT16 gap_handle, UINT8 *p_data, UINT16 max_len, UINT16 *p_len)
  263. {
  264. tGAP_CCB *p_ccb = gap_find_ccb_by_handle (gap_handle);
  265. BT_HDR *p_buf;
  266. UINT16 copy_len;
  267. if (!p_ccb) {
  268. return (GAP_ERR_BAD_HANDLE);
  269. }
  270. *p_len = 0;
  271. p_buf = (BT_HDR *)GKI_getfirst (&p_ccb->rx_queue);
  272. if (!p_buf) {
  273. return (GAP_NO_DATA_AVAIL);
  274. }
  275. GKI_disable();
  276. while (max_len && p_buf) {
  277. copy_len = (p_buf->len > max_len) ? max_len : p_buf->len;
  278. max_len -= copy_len;
  279. *p_len += copy_len;
  280. if (p_data) {
  281. memcpy (p_data, (UINT8 *)(p_buf + 1) + p_buf->offset, copy_len);
  282. p_data += copy_len;
  283. }
  284. if (p_buf->len > copy_len) {
  285. p_buf->offset += copy_len;
  286. p_buf->len -= copy_len;
  287. break;
  288. } else {
  289. if (max_len) {
  290. p_buf = (BT_HDR *)GKI_getnext (p_buf);
  291. }
  292. GKI_freebuf (GKI_dequeue (&p_ccb->rx_queue));
  293. }
  294. }
  295. p_ccb->rx_queue_size -= *p_len;
  296. GKI_enable();
  297. GAP_TRACE_EVENT ("GAP_ConnReadData - rx_queue_size left=%d, *p_len=%d",
  298. p_ccb->rx_queue_size, *p_len);
  299. return (BT_PASS);
  300. }
  301. /*******************************************************************************
  302. **
  303. ** Function GAP_GetRxQueueCnt
  304. **
  305. ** Description This function return number of bytes on the rx queue.
  306. **
  307. ** Parameters: handle - Handle returned in the GAP_ConnOpen
  308. ** p_rx_queue_count - Pointer to return queue count in.
  309. **
  310. **
  311. *******************************************************************************/
  312. int GAP_GetRxQueueCnt (UINT16 handle, UINT32 *p_rx_queue_count)
  313. {
  314. tGAP_CCB *p_ccb;
  315. int rc = BT_PASS;
  316. /* Check that handle is valid */
  317. if (handle < GAP_MAX_CONNECTIONS) {
  318. p_ccb = &gap_cb.conn.ccb_pool[handle];
  319. if (p_ccb->con_state == GAP_CCB_STATE_CONNECTED) {
  320. *p_rx_queue_count = p_ccb->rx_queue_size;
  321. } else {
  322. rc = GAP_INVALID_HANDLE;
  323. }
  324. } else {
  325. rc = GAP_INVALID_HANDLE;
  326. }
  327. GAP_TRACE_EVENT ("GAP_GetRxQueueCnt - rc = 0x%04x, rx_queue_count=%d",
  328. rc , *p_rx_queue_count);
  329. return (rc);
  330. }
  331. /*******************************************************************************
  332. **
  333. ** Function GAP_ConnBTRead
  334. **
  335. ** Description Bluetooth aware applications will call this function after receiving
  336. ** GAP_EVT_RXDATA event.
  337. **
  338. ** Parameters: handle - Handle of the connection returned in the Open
  339. ** pp_buf - pointer to address of buffer with data,
  340. **
  341. ** Returns BT_PASS - data read
  342. ** GAP_ERR_BAD_HANDLE - invalid handle
  343. ** GAP_NO_DATA_AVAIL - no data available
  344. **
  345. *******************************************************************************/
  346. UINT16 GAP_ConnBTRead (UINT16 gap_handle, BT_HDR **pp_buf)
  347. {
  348. tGAP_CCB *p_ccb = gap_find_ccb_by_handle (gap_handle);
  349. BT_HDR *p_buf;
  350. if (!p_ccb) {
  351. return (GAP_ERR_BAD_HANDLE);
  352. }
  353. p_buf = (BT_HDR *)GKI_dequeue (&p_ccb->rx_queue);
  354. if (p_buf) {
  355. *pp_buf = p_buf;
  356. p_ccb->rx_queue_size -= p_buf->len;
  357. return (BT_PASS);
  358. } else {
  359. *pp_buf = NULL;
  360. return (GAP_NO_DATA_AVAIL);
  361. }
  362. }
  363. /*******************************************************************************
  364. **
  365. ** Function GAP_ConnBTWrite
  366. **
  367. ** Description Bluetooth Aware applications can call this function to write data.
  368. **
  369. ** Parameters: handle - Handle of the connection returned in the Open
  370. ** p_buf - pointer to address of buffer with data,
  371. **
  372. ** Returns BT_PASS - data read
  373. ** GAP_ERR_BAD_HANDLE - invalid handle
  374. ** GAP_ERR_BAD_STATE - connection not established
  375. ** GAP_INVALID_BUF_OFFSET - buffer offset is invalid
  376. *******************************************************************************/
  377. UINT16 GAP_ConnBTWrite (UINT16 gap_handle, BT_HDR *p_buf)
  378. {
  379. tGAP_CCB *p_ccb = gap_find_ccb_by_handle (gap_handle);
  380. if (!p_ccb) {
  381. GKI_freebuf (p_buf);
  382. return (GAP_ERR_BAD_HANDLE);
  383. }
  384. if (p_ccb->con_state != GAP_CCB_STATE_CONNECTED) {
  385. GKI_freebuf (p_buf);
  386. return (GAP_ERR_BAD_STATE);
  387. }
  388. if (p_buf->offset < L2CAP_MIN_OFFSET) {
  389. GKI_freebuf (p_buf);
  390. return (GAP_ERR_BUF_OFFSET);
  391. }
  392. GKI_enqueue (&p_ccb->tx_queue, p_buf);
  393. if (p_ccb->is_congested) {
  394. return (BT_PASS);
  395. }
  396. /* Send the buffer through L2CAP */
  397. #if (GAP_CONN_POST_EVT_INCLUDED == TRUE)
  398. gap_send_event (gap_handle);
  399. #else
  400. while ((p_buf = (BT_HDR *)GKI_dequeue (&p_ccb->tx_queue)) != NULL) {
  401. UINT8 status = L2CA_DATA_WRITE (p_ccb->connection_id, p_buf);
  402. if (status == L2CAP_DW_CONGESTED) {
  403. p_ccb->is_congested = TRUE;
  404. break;
  405. } else if (status != L2CAP_DW_SUCCESS) {
  406. return (GAP_ERR_BAD_STATE);
  407. }
  408. }
  409. #endif
  410. return (BT_PASS);
  411. }
  412. /*******************************************************************************
  413. **
  414. ** Function GAP_ConnWriteData
  415. **
  416. ** Description Normally not GKI aware application will call this function
  417. ** to send data to the connection.
  418. **
  419. ** Parameters: handle - Handle of the connection returned in the Open
  420. ** p_data - Data area
  421. ** max_len - Byte count requested
  422. ** p_len - Byte count received
  423. **
  424. ** Returns BT_PASS - data read
  425. ** GAP_ERR_BAD_HANDLE - invalid handle
  426. ** GAP_ERR_BAD_STATE - connection not established
  427. ** GAP_CONGESTION - system is congested
  428. **
  429. *******************************************************************************/
  430. UINT16 GAP_ConnWriteData (UINT16 gap_handle, UINT8 *p_data, UINT16 max_len, UINT16 *p_len)
  431. {
  432. tGAP_CCB *p_ccb = gap_find_ccb_by_handle (gap_handle);
  433. BT_HDR *p_buf;
  434. *p_len = 0;
  435. if (!p_ccb) {
  436. return (GAP_ERR_BAD_HANDLE);
  437. }
  438. if (p_ccb->con_state != GAP_CCB_STATE_CONNECTED) {
  439. return (GAP_ERR_BAD_STATE);
  440. }
  441. while (max_len) {
  442. if (p_ccb->cfg.fcr.mode == L2CAP_FCR_ERTM_MODE) {
  443. if ((p_buf = (BT_HDR *)GKI_getpoolbuf (p_ccb->ertm_info.user_tx_pool_id)) == NULL) {
  444. return (GAP_ERR_CONGESTED);
  445. }
  446. } else {
  447. if ((p_buf = (BT_HDR *)GKI_getpoolbuf (GAP_DATA_POOL_ID)) == NULL) {
  448. return (GAP_ERR_CONGESTED);
  449. }
  450. }
  451. p_buf->offset = L2CAP_MIN_OFFSET;
  452. p_buf->len = (p_ccb->rem_mtu_size < max_len) ? p_ccb->rem_mtu_size : max_len;
  453. p_buf->event = BT_EVT_TO_BTU_SP_DATA;
  454. memcpy ((UINT8 *)(p_buf + 1) + p_buf->offset, p_data, p_buf->len);
  455. *p_len += p_buf->len;
  456. max_len -= p_buf->len;
  457. p_data += p_buf->len;
  458. GAP_TRACE_EVENT ("GAP_WriteData %d bytes", p_buf->len);
  459. GKI_enqueue (&p_ccb->tx_queue, p_buf);
  460. }
  461. if (p_ccb->is_congested) {
  462. return (BT_PASS);
  463. }
  464. /* Send the buffer through L2CAP */
  465. #if (GAP_CONN_POST_EVT_INCLUDED == TRUE)
  466. gap_send_event (gap_handle);
  467. #else
  468. while ((p_buf = (BT_HDR *)GKI_dequeue (&p_ccb->tx_queue)) != NULL) {
  469. UINT8 status = L2CA_DATA_WRITE (p_ccb->connection_id, p_buf);
  470. if (status == L2CAP_DW_CONGESTED) {
  471. p_ccb->is_congested = TRUE;
  472. break;
  473. } else if (status != L2CAP_DW_SUCCESS) {
  474. return (GAP_ERR_BAD_STATE);
  475. }
  476. }
  477. #endif
  478. return (BT_PASS);
  479. }
  480. /*******************************************************************************
  481. **
  482. ** Function GAP_ConnReconfig
  483. **
  484. ** Description Applications can call this function to reconfigure the connection.
  485. **
  486. ** Parameters: handle - Handle of the connection
  487. ** p_cfg - Pointer to new configuration
  488. **
  489. ** Returns BT_PASS - config process started
  490. ** GAP_ERR_BAD_HANDLE - invalid handle
  491. **
  492. *******************************************************************************/
  493. UINT16 GAP_ConnReconfig (UINT16 gap_handle, tL2CAP_CFG_INFO *p_cfg)
  494. {
  495. tGAP_CCB *p_ccb = gap_find_ccb_by_handle (gap_handle);
  496. if (!p_ccb) {
  497. return (GAP_ERR_BAD_HANDLE);
  498. }
  499. p_ccb->cfg = *p_cfg;
  500. if (p_ccb->con_state == GAP_CCB_STATE_CONNECTED) {
  501. L2CA_CONFIG_REQ (p_ccb->connection_id, p_cfg);
  502. }
  503. return (BT_PASS);
  504. }
  505. /*******************************************************************************
  506. **
  507. ** Function GAP_ConnSetIdleTimeout
  508. **
  509. ** Description Higher layers call this function to set the idle timeout for
  510. ** a connection, or for all future connections. The "idle timeout"
  511. ** is the amount of time that a connection can remain up with
  512. ** no L2CAP channels on it. A timeout of zero means that the
  513. ** connection will be torn down immediately when the last channel
  514. ** is removed. A timeout of 0xFFFF means no timeout. Values are
  515. ** in seconds.
  516. **
  517. ** Parameters: handle - Handle of the connection
  518. ** timeout - in secs
  519. ** 0 = immediate disconnect when last channel is removed
  520. ** 0xFFFF = no idle timeout
  521. **
  522. ** Returns BT_PASS - config process started
  523. ** GAP_ERR_BAD_HANDLE - invalid handle
  524. **
  525. *******************************************************************************/
  526. UINT16 GAP_ConnSetIdleTimeout (UINT16 gap_handle, UINT16 timeout)
  527. {
  528. tGAP_CCB *p_ccb;
  529. if ((p_ccb = gap_find_ccb_by_handle (gap_handle)) == NULL) {
  530. return (GAP_ERR_BAD_HANDLE);
  531. }
  532. if (L2CA_SetIdleTimeout (p_ccb->connection_id, timeout, FALSE)) {
  533. return (BT_PASS);
  534. } else {
  535. return (GAP_ERR_BAD_HANDLE);
  536. }
  537. }
  538. /*******************************************************************************
  539. **
  540. ** Function GAP_ConnGetRemoteAddr
  541. **
  542. ** Description This function is called to get the remote BD address
  543. ** of a connection.
  544. **
  545. ** Parameters: handle - Handle of the connection returned by GAP_ConnOpen
  546. **
  547. ** Returns BT_PASS - closed OK
  548. ** GAP_ERR_BAD_HANDLE - invalid handle
  549. **
  550. *******************************************************************************/
  551. UINT8 *GAP_ConnGetRemoteAddr (UINT16 gap_handle)
  552. {
  553. tGAP_CCB *p_ccb = gap_find_ccb_by_handle (gap_handle);
  554. GAP_TRACE_EVENT ("GAP_ConnGetRemoteAddr gap_handle = %d", gap_handle);
  555. if ((p_ccb) && (p_ccb->con_state > GAP_CCB_STATE_LISTENING)) {
  556. GAP_TRACE_EVENT("GAP_ConnGetRemoteAddr bda :0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x\n", \
  557. p_ccb->rem_dev_address[0], p_ccb->rem_dev_address[1], p_ccb->rem_dev_address[2],
  558. p_ccb->rem_dev_address[3], p_ccb->rem_dev_address[4], p_ccb->rem_dev_address[5]);
  559. return (p_ccb->rem_dev_address);
  560. } else {
  561. GAP_TRACE_EVENT ("GAP_ConnGetRemoteAddr return Error ");
  562. return (NULL);
  563. }
  564. }
  565. /*******************************************************************************
  566. **
  567. ** Function GAP_ConnGetRemMtuSize
  568. **
  569. ** Description Returns the remote device's MTU size
  570. **
  571. ** Parameters: handle - Handle of the connection
  572. **
  573. ** Returns UINT16 - maximum size buffer that can be transmitted to the peer
  574. **
  575. *******************************************************************************/
  576. UINT16 GAP_ConnGetRemMtuSize (UINT16 gap_handle)
  577. {
  578. tGAP_CCB *p_ccb;
  579. if ((p_ccb = gap_find_ccb_by_handle (gap_handle)) == NULL) {
  580. return (0);
  581. }
  582. return (p_ccb->rem_mtu_size);
  583. }
  584. /*******************************************************************************
  585. **
  586. ** Function GAP_ConnGetL2CAPCid
  587. **
  588. ** Description Returns the L2CAP channel id
  589. **
  590. ** Parameters: handle - Handle of the connection
  591. **
  592. ** Returns UINT16 - The L2CAP channel id
  593. ** 0, if error
  594. **
  595. *******************************************************************************/
  596. UINT16 GAP_ConnGetL2CAPCid (UINT16 gap_handle)
  597. {
  598. tGAP_CCB *p_ccb;
  599. if ((p_ccb = gap_find_ccb_by_handle (gap_handle)) == NULL) {
  600. return (0);
  601. }
  602. return (p_ccb->connection_id);
  603. }
  604. /*******************************************************************************
  605. **
  606. ** Function gap_connect_ind
  607. **
  608. ** Description This function handles an inbound connection indication
  609. ** from L2CAP. This is the case where we are acting as a
  610. ** server.
  611. **
  612. ** Returns void
  613. **
  614. *******************************************************************************/
  615. static void gap_connect_ind (BD_ADDR bd_addr, UINT16 l2cap_cid, UINT16 psm, UINT8 l2cap_id)
  616. {
  617. UINT16 xx;
  618. tGAP_CCB *p_ccb;
  619. //tBT_UUID bt_uuid = {2, {GAP_PROTOCOL_ID}};
  620. /* See if we have a CCB listening for the connection */
  621. for (xx = 0, p_ccb = gap_cb.conn.ccb_pool; xx < GAP_MAX_CONNECTIONS; xx++, p_ccb++) {
  622. if ((p_ccb->con_state == GAP_CCB_STATE_LISTENING)
  623. && (p_ccb->psm == psm)
  624. && ((p_ccb->rem_addr_specified == FALSE)
  625. || (!memcmp (bd_addr, p_ccb->rem_dev_address, BD_ADDR_LEN)))) {
  626. break;
  627. }
  628. }
  629. if (xx == GAP_MAX_CONNECTIONS) {
  630. GAP_TRACE_WARNING("*******");
  631. GAP_TRACE_WARNING("WARNING: GAP Conn Indication for Unexpected Bd Addr...Disconnecting");
  632. GAP_TRACE_WARNING("*******");
  633. /* Disconnect because it is an unexpected connection */
  634. L2CA_DISCONNECT_REQ (l2cap_cid);
  635. return;
  636. }
  637. /* Transition to the next appropriate state, waiting for config setup. */
  638. p_ccb->con_state = GAP_CCB_STATE_CFG_SETUP;
  639. /* Save the BD Address and Channel ID. */
  640. memcpy (&p_ccb->rem_dev_address[0], bd_addr, BD_ADDR_LEN);
  641. p_ccb->connection_id = l2cap_cid;
  642. /* Send response to the L2CAP layer. */
  643. L2CA_CONNECT_RSP (bd_addr, l2cap_id, l2cap_cid, L2CAP_CONN_OK, L2CAP_CONN_OK, &p_ccb->ertm_info, &bt_uuid);
  644. GAP_TRACE_EVENT("GAP_CONN - Rcvd L2CAP conn ind, CID: 0x%x", p_ccb->connection_id);
  645. /* Send a Configuration Request. */
  646. L2CA_CONFIG_REQ (l2cap_cid, &p_ccb->cfg);
  647. }
  648. /*******************************************************************************
  649. **
  650. ** Function gap_checks_con_flags
  651. **
  652. ** Description This function processes the L2CAP configuration indication
  653. ** event.
  654. **
  655. ** Returns void
  656. **
  657. *******************************************************************************/
  658. static void gap_checks_con_flags (tGAP_CCB *p_ccb)
  659. {
  660. GAP_TRACE_EVENT ("gap_checks_con_flags conn_flags:0x%x, ", p_ccb->con_flags);
  661. /* if all the required con_flags are set, report the OPEN event now */
  662. if ((p_ccb->con_flags & GAP_CCB_FLAGS_CONN_DONE) == GAP_CCB_FLAGS_CONN_DONE) {
  663. p_ccb->con_state = GAP_CCB_STATE_CONNECTED;
  664. p_ccb->p_callback (p_ccb->gap_handle, GAP_EVT_CONN_OPENED);
  665. }
  666. }
  667. /*******************************************************************************
  668. **
  669. ** Function gap_sec_check_complete
  670. **
  671. ** Description The function called when Security Manager finishes
  672. ** verification of the service side connection
  673. **
  674. ** Returns void
  675. **
  676. *******************************************************************************/
  677. static void gap_sec_check_complete (BD_ADDR bd_addr, tBT_TRANSPORT transport, void *p_ref_data, UINT8 res)
  678. {
  679. tGAP_CCB *p_ccb = (tGAP_CCB *)p_ref_data;
  680. UNUSED(bd_addr);
  681. UNUSED (transport);
  682. GAP_TRACE_EVENT ("gap_sec_check_complete conn_state:%d, conn_flags:0x%x, status:%d",
  683. p_ccb->con_state, p_ccb->con_flags, res);
  684. if (p_ccb->con_state == GAP_CCB_STATE_IDLE) {
  685. return;
  686. }
  687. if (res == BTM_SUCCESS) {
  688. p_ccb->con_flags |= GAP_CCB_FLAGS_SEC_DONE;
  689. gap_checks_con_flags (p_ccb);
  690. } else {
  691. /* security failed - disconnect the channel */
  692. L2CA_DISCONNECT_REQ (p_ccb->connection_id);
  693. }
  694. }
  695. /*******************************************************************************
  696. **
  697. ** Function gap_connect_cfm
  698. **
  699. ** Description This function handles the connect confirm events
  700. ** from L2CAP. This is the case when we are acting as a
  701. ** client and have sent a connect request.
  702. **
  703. ** Returns void
  704. **
  705. *******************************************************************************/
  706. static void gap_connect_cfm (UINT16 l2cap_cid, UINT16 result)
  707. {
  708. tGAP_CCB *p_ccb;
  709. /* Find CCB based on CID */
  710. if ((p_ccb = gap_find_ccb_by_cid (l2cap_cid)) == NULL) {
  711. return;
  712. }
  713. /* initiate security process, if needed */
  714. if ( (p_ccb->con_flags & GAP_CCB_FLAGS_SEC_DONE) == 0) {
  715. btm_sec_mx_access_request (p_ccb->rem_dev_address, p_ccb->psm, TRUE,
  716. 0, 0, &gap_sec_check_complete, p_ccb);
  717. }
  718. /* If the connection response contains success status, then */
  719. /* Transition to the next state and startup the timer. */
  720. if ((result == L2CAP_CONN_OK) && (p_ccb->con_state == GAP_CCB_STATE_CONN_SETUP)) {
  721. p_ccb->con_state = GAP_CCB_STATE_CFG_SETUP;
  722. /* Send a Configuration Request. */
  723. L2CA_CONFIG_REQ (l2cap_cid, &p_ccb->cfg);
  724. } else {
  725. /* Tell the user if he has a callback */
  726. if (p_ccb->p_callback) {
  727. (*p_ccb->p_callback) (p_ccb->gap_handle, GAP_EVT_CONN_CLOSED);
  728. }
  729. gap_release_ccb (p_ccb);
  730. }
  731. }
  732. /*******************************************************************************
  733. **
  734. ** Function gap_config_ind
  735. **
  736. ** Description This function processes the L2CAP configuration indication
  737. ** event.
  738. **
  739. ** Returns void
  740. **
  741. *******************************************************************************/
  742. static void gap_config_ind (UINT16 l2cap_cid, tL2CAP_CFG_INFO *p_cfg)
  743. {
  744. tGAP_CCB *p_ccb;
  745. UINT16 local_mtu_size;
  746. /* Find CCB based on CID */
  747. if ((p_ccb = gap_find_ccb_by_cid (l2cap_cid)) == NULL) {
  748. return;
  749. }
  750. /* Remember the remote MTU size */
  751. if (p_ccb->cfg.fcr.mode == L2CAP_FCR_ERTM_MODE) {
  752. local_mtu_size = GKI_get_pool_bufsize (p_ccb->ertm_info.user_tx_pool_id)
  753. - sizeof(BT_HDR) - L2CAP_MIN_OFFSET;
  754. } else {
  755. local_mtu_size = L2CAP_MTU_SIZE;
  756. }
  757. if ((!p_cfg->mtu_present) || (p_cfg->mtu > local_mtu_size)) {
  758. p_ccb->rem_mtu_size = local_mtu_size;
  759. } else {
  760. p_ccb->rem_mtu_size = p_cfg->mtu;
  761. }
  762. /* For now, always accept configuration from the other side */
  763. p_cfg->flush_to_present = FALSE;
  764. p_cfg->mtu_present = FALSE;
  765. p_cfg->result = L2CAP_CFG_OK;
  766. p_cfg->fcs_present = FALSE;
  767. L2CA_CONFIG_RSP (l2cap_cid, p_cfg);
  768. p_ccb->con_flags |= GAP_CCB_FLAGS_HIS_CFG_DONE;
  769. gap_checks_con_flags (p_ccb);
  770. }
  771. /*******************************************************************************
  772. **
  773. ** Function gap_config_cfm
  774. **
  775. ** Description This function processes the L2CAP configuration confirmation
  776. ** event.
  777. **
  778. ** Returns void
  779. **
  780. *******************************************************************************/
  781. static void gap_config_cfm (UINT16 l2cap_cid, tL2CAP_CFG_INFO *p_cfg)
  782. {
  783. tGAP_CCB *p_ccb;
  784. /* Find CCB based on CID */
  785. if ((p_ccb = gap_find_ccb_by_cid (l2cap_cid)) == NULL) {
  786. return;
  787. }
  788. if (p_cfg->result == L2CAP_CFG_OK) {
  789. p_ccb->con_flags |= GAP_CCB_FLAGS_MY_CFG_DONE;
  790. if (p_ccb->cfg.fcr_present) {
  791. p_ccb->cfg.fcr.mode = p_cfg->fcr.mode;
  792. } else {
  793. p_ccb->cfg.fcr.mode = L2CAP_FCR_BASIC_MODE;
  794. }
  795. gap_checks_con_flags (p_ccb);
  796. } else {
  797. p_ccb->p_callback (p_ccb->gap_handle, GAP_EVT_CONN_CLOSED);
  798. gap_release_ccb (p_ccb);
  799. }
  800. }
  801. /*******************************************************************************
  802. **
  803. ** Function gap_disconnect_ind
  804. **
  805. ** Description This function handles a disconnect event from L2CAP. If
  806. ** requested to, we ack the disconnect before dropping the CCB
  807. **
  808. ** Returns void
  809. **
  810. *******************************************************************************/
  811. static void gap_disconnect_ind (UINT16 l2cap_cid, BOOLEAN ack_needed)
  812. {
  813. tGAP_CCB *p_ccb;
  814. GAP_TRACE_EVENT ("GAP_CONN - Rcvd L2CAP disc, CID: 0x%x", l2cap_cid);
  815. /* Find CCB based on CID */
  816. if ((p_ccb = gap_find_ccb_by_cid (l2cap_cid)) == NULL) {
  817. return;
  818. }
  819. if (ack_needed) {
  820. L2CA_DISCONNECT_RSP (l2cap_cid);
  821. }
  822. p_ccb->p_callback (p_ccb->gap_handle, GAP_EVT_CONN_CLOSED);
  823. gap_release_ccb (p_ccb);
  824. }
  825. /*******************************************************************************
  826. **
  827. ** Function gap_data_ind
  828. **
  829. ** Description This function is called when data is received from L2CAP.
  830. **
  831. ** Returns void
  832. **
  833. *******************************************************************************/
  834. static void gap_data_ind (UINT16 l2cap_cid, BT_HDR *p_msg)
  835. {
  836. tGAP_CCB *p_ccb;
  837. /* Find CCB based on CID */
  838. if ((p_ccb = gap_find_ccb_by_cid (l2cap_cid)) == NULL) {
  839. GKI_freebuf (p_msg);
  840. return;
  841. }
  842. if (p_ccb->con_state == GAP_CCB_STATE_CONNECTED) {
  843. GKI_enqueue (&p_ccb->rx_queue, p_msg);
  844. p_ccb->rx_queue_size += p_msg->len;
  845. /*
  846. GAP_TRACE_EVENT ("gap_data_ind - rx_queue_size=%d, msg len=%d",
  847. p_ccb->rx_queue_size, p_msg->len);
  848. */
  849. p_ccb->p_callback (p_ccb->gap_handle, GAP_EVT_CONN_DATA_AVAIL);
  850. } else {
  851. GKI_freebuf (p_msg);
  852. }
  853. }
  854. /*******************************************************************************
  855. **
  856. ** Function gap_congestion_ind
  857. **
  858. ** Description This is a callback function called by L2CAP when
  859. ** data L2CAP congestion status changes
  860. **
  861. *******************************************************************************/
  862. static void gap_congestion_ind (UINT16 lcid, BOOLEAN is_congested)
  863. {
  864. tGAP_CCB *p_ccb;
  865. UINT16 event;
  866. BT_HDR *p_buf;
  867. UINT8 status;
  868. GAP_TRACE_EVENT ("GAP_CONN - Rcvd L2CAP Is Congested (%d), CID: 0x%x",
  869. is_congested, lcid);
  870. /* Find CCB based on CID */
  871. if ((p_ccb = gap_find_ccb_by_cid (lcid)) == NULL) {
  872. return;
  873. }
  874. p_ccb->is_congested = is_congested;
  875. event = (is_congested) ? GAP_EVT_CONN_CONGESTED : GAP_EVT_CONN_UNCONGESTED;
  876. p_ccb->p_callback (p_ccb->gap_handle, event);
  877. if (!is_congested) {
  878. while ((p_buf = (BT_HDR *)GKI_dequeue (&p_ccb->tx_queue)) != NULL) {
  879. status = L2CA_DATA_WRITE (p_ccb->connection_id, p_buf);
  880. if (status == L2CAP_DW_CONGESTED) {
  881. p_ccb->is_congested = TRUE;
  882. break;
  883. } else if (status != L2CAP_DW_SUCCESS) {
  884. break;
  885. }
  886. }
  887. }
  888. }
  889. /*******************************************************************************
  890. **
  891. ** Function gap_find_ccb_by_cid
  892. **
  893. ** Description This function searches the CCB table for an entry with the
  894. ** passed CID.
  895. **
  896. ** Returns the CCB address, or NULL if not found.
  897. **
  898. *******************************************************************************/
  899. static tGAP_CCB *gap_find_ccb_by_cid (UINT16 cid)
  900. {
  901. UINT16 xx;
  902. tGAP_CCB *p_ccb;
  903. /* Look through each connection control block */
  904. for (xx = 0, p_ccb = gap_cb.conn.ccb_pool; xx < GAP_MAX_CONNECTIONS; xx++, p_ccb++) {
  905. if ((p_ccb->con_state != GAP_CCB_STATE_IDLE) && (p_ccb->connection_id == cid)) {
  906. return (p_ccb);
  907. }
  908. }
  909. /* If here, not found */
  910. return (NULL);
  911. }
  912. /*******************************************************************************
  913. **
  914. ** Function gap_find_ccb_by_handle
  915. **
  916. ** Description This function searches the CCB table for an entry with the
  917. ** passed handle.
  918. **
  919. ** Returns the CCB address, or NULL if not found.
  920. **
  921. *******************************************************************************/
  922. static tGAP_CCB *gap_find_ccb_by_handle (UINT16 handle)
  923. {
  924. tGAP_CCB *p_ccb;
  925. /* Check that handle is valid */
  926. if (handle < GAP_MAX_CONNECTIONS) {
  927. p_ccb = &gap_cb.conn.ccb_pool[handle];
  928. if (p_ccb->con_state != GAP_CCB_STATE_IDLE) {
  929. return (p_ccb);
  930. }
  931. }
  932. /* If here, handle points to invalid connection */
  933. return (NULL);
  934. }
  935. /*******************************************************************************
  936. **
  937. ** Function gap_allocate_ccb
  938. **
  939. ** Description This function allocates a new CCB.
  940. **
  941. ** Returns CCB address, or NULL if none available.
  942. **
  943. *******************************************************************************/
  944. static tGAP_CCB *gap_allocate_ccb (void)
  945. {
  946. UINT16 xx;
  947. tGAP_CCB *p_ccb;
  948. /* Look through each connection control block for a free one */
  949. for (xx = 0, p_ccb = gap_cb.conn.ccb_pool; xx < GAP_MAX_CONNECTIONS; xx++, p_ccb++) {
  950. if (p_ccb->con_state == GAP_CCB_STATE_IDLE) {
  951. memset (p_ccb, 0, sizeof (tGAP_CCB));
  952. p_ccb->gap_handle = xx;
  953. p_ccb->rem_mtu_size = L2CAP_MTU_SIZE;
  954. return (p_ccb);
  955. }
  956. }
  957. /* If here, no free CCB found */
  958. return (NULL);
  959. }
  960. /*******************************************************************************
  961. **
  962. ** Function gap_release_ccb
  963. **
  964. ** Description This function releases a CCB.
  965. **
  966. ** Returns void
  967. **
  968. *******************************************************************************/
  969. static void gap_release_ccb (tGAP_CCB *p_ccb)
  970. {
  971. UINT16 xx;
  972. UINT16 psm = p_ccb->psm;
  973. UINT8 service_id = p_ccb->service_id;
  974. /* Drop any buffers we may be holding */
  975. p_ccb->rx_queue_size = 0;
  976. while (p_ccb->rx_queue._p_first) {
  977. GKI_freebuf (GKI_dequeue (&p_ccb->rx_queue));
  978. }
  979. while (p_ccb->tx_queue._p_first) {
  980. GKI_freebuf (GKI_dequeue (&p_ccb->tx_queue));
  981. }
  982. p_ccb->con_state = GAP_CCB_STATE_IDLE;
  983. /* If no-one else is using the PSM, deregister from L2CAP */
  984. for (xx = 0, p_ccb = gap_cb.conn.ccb_pool; xx < GAP_MAX_CONNECTIONS; xx++, p_ccb++) {
  985. if ((p_ccb->con_state != GAP_CCB_STATE_IDLE) && (p_ccb->psm == psm)) {
  986. return;
  987. }
  988. }
  989. /* Free the security record for this PSM */
  990. BTM_SecClrService(service_id);
  991. L2CA_DEREGISTER (psm);
  992. }
  993. #if (GAP_CONN_POST_EVT_INCLUDED == TRUE)
  994. /*******************************************************************************
  995. **
  996. ** Function gap_send_event
  997. **
  998. ** Description Send BT_EVT_TO_GAP_MSG event to BTU task
  999. **
  1000. ** Returns None
  1001. **
  1002. *******************************************************************************/
  1003. void gap_send_event (UINT16 gap_handle)
  1004. {
  1005. BT_HDR *p_msg;
  1006. if ((p_msg = (BT_HDR *)GKI_getbuf(BT_HDR_SIZE)) != NULL) {
  1007. p_msg->event = BT_EVT_TO_GAP_MSG;
  1008. p_msg->len = 0;
  1009. p_msg->offset = 0;
  1010. p_msg->layer_specific = gap_handle;
  1011. GKI_send_msg(BTU_TASK, BTU_HCI_RCV_MBOX, p_msg);
  1012. } else {
  1013. GAP_TRACE_ERROR("Unable to allocate message buffer for event.");
  1014. }
  1015. }
  1016. /*******************************************************************************
  1017. **
  1018. ** Function gap_proc_btu_event
  1019. **
  1020. ** Description Event handler for BT_EVT_TO_GAP_MSG event from BTU task
  1021. **
  1022. ** Returns None
  1023. **
  1024. *******************************************************************************/
  1025. void gap_proc_btu_event(BT_HDR *p_msg)
  1026. {
  1027. tGAP_CCB *p_ccb = gap_find_ccb_by_handle (p_msg->layer_specific);
  1028. UINT8 status;
  1029. BT_HDR *p_buf;
  1030. if (!p_ccb) {
  1031. return;
  1032. }
  1033. if (p_ccb->con_state != GAP_CCB_STATE_CONNECTED) {
  1034. return;
  1035. }
  1036. if (p_ccb->is_congested) {
  1037. return;
  1038. }
  1039. /* Send the buffer through L2CAP */
  1040. while ((p_buf = (BT_HDR *)GKI_dequeue (&p_ccb->tx_queue)) != NULL) {
  1041. status = L2CA_DATA_WRITE (p_ccb->connection_id, p_buf);
  1042. if (status == L2CAP_DW_CONGESTED) {
  1043. p_ccb->is_congested = TRUE;
  1044. break;
  1045. } else if (status != L2CAP_DW_SUCCESS) {
  1046. break;
  1047. }
  1048. }
  1049. }
  1050. #endif /* (GAP_CONN_POST_EVT_INCLUDED == TRUE) */
  1051. #endif /* GAP_CONN_INCLUDED */