l2c_ucd.c 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077
  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 the L2CAP UCD code
  21. *
  22. ******************************************************************************/
  23. #include <stdlib.h>
  24. #include <string.h>
  25. //#include <stdio.h>
  26. #include "stack/bt_types.h"
  27. #include "stack/hcidefs.h"
  28. #include "stack/hcimsgs.h"
  29. #include "stack/l2cdefs.h"
  30. #include "l2c_int.h"
  31. #include "stack/btu.h"
  32. #include "stack/btm_api.h"
  33. #include "btm_int.h"
  34. #if (L2CAP_UCD_INCLUDED == TRUE)
  35. static BOOLEAN l2c_ucd_connect ( BD_ADDR rem_bda );
  36. /*******************************************************************************
  37. **
  38. ** Function l2c_ucd_discover_cback
  39. **
  40. ** Description UCD Discover callback
  41. **
  42. ** Returns void
  43. **
  44. *******************************************************************************/
  45. static void l2c_ucd_discover_cback (BD_ADDR rem_bda, UINT8 info_type, UINT32 data)
  46. {
  47. tL2C_RCB *p_rcb = &l2cb.rcb_pool[0];
  48. UINT16 xx;
  49. L2CAP_TRACE_DEBUG ("L2CAP - l2c_ucd_discover_cback");
  50. for (xx = 0; xx < MAX_L2CAP_CLIENTS; xx++, p_rcb++) {
  51. if (p_rcb->in_use) {
  52. /* if this application is waiting UCD reception info */
  53. if (( info_type == L2CAP_UCD_INFO_TYPE_RECEPTION )
  54. && ( p_rcb->ucd.state & L2C_UCD_STATE_W4_RECEPTION )) {
  55. p_rcb->ucd.cb_info.pL2CA_UCD_Discover_Cb (rem_bda, info_type, data);
  56. p_rcb->ucd.state &= ~(L2C_UCD_STATE_W4_RECEPTION);
  57. }
  58. /* if this application is waiting UCD MTU info */
  59. if (( info_type == L2CAP_UCD_INFO_TYPE_MTU )
  60. && ( p_rcb->ucd.state & L2C_UCD_STATE_W4_MTU )) {
  61. p_rcb->ucd.cb_info.pL2CA_UCD_Discover_Cb (rem_bda, info_type, data);
  62. p_rcb->ucd.state &= ~(L2C_UCD_STATE_W4_MTU);
  63. }
  64. }
  65. }
  66. }
  67. /*******************************************************************************
  68. **
  69. ** Function l2c_ucd_data_ind_cback
  70. **
  71. ** Description UCD Data callback
  72. **
  73. ** Returns void
  74. **
  75. *******************************************************************************/
  76. static void l2c_ucd_data_ind_cback (BD_ADDR rem_bda, BT_HDR *p_buf)
  77. {
  78. UINT8 *p;
  79. UINT16 psm;
  80. tL2C_RCB *p_rcb;
  81. L2CAP_TRACE_DEBUG ("L2CAP - l2c_ucd_data_ind_cback");
  82. p = (UINT8 *)(p_buf + 1) + p_buf->offset;
  83. STREAM_TO_UINT16(psm, p)
  84. p_buf->offset += L2CAP_UCD_OVERHEAD;
  85. p_buf->len -= L2CAP_UCD_OVERHEAD;
  86. if ((p_rcb = l2cu_find_rcb_by_psm (psm)) == NULL) {
  87. L2CAP_TRACE_ERROR ("L2CAP - no RCB for l2c_ucd_data_ind_cback, PSM: 0x%04x", psm);
  88. osi_free (p_buf);
  89. } else {
  90. p_rcb->ucd.cb_info.pL2CA_UCD_Data_Cb(rem_bda, p_buf);
  91. }
  92. }
  93. /*******************************************************************************
  94. **
  95. ** Function l2c_ucd_congestion_status_cback
  96. **
  97. ** Description UCD Congestion Status callback
  98. **
  99. ** Returns void
  100. **
  101. *******************************************************************************/
  102. static void l2c_ucd_congestion_status_cback (BD_ADDR rem_bda, BOOLEAN is_congested)
  103. {
  104. tL2C_RCB *p_rcb = &l2cb.rcb_pool[0];
  105. UINT16 xx;
  106. L2CAP_TRACE_DEBUG ("L2CAP - l2c_ucd_congestion_status_cback");
  107. for (xx = 0; xx < MAX_L2CAP_CLIENTS; xx++, p_rcb++) {
  108. if (( p_rcb->in_use )
  109. && ( p_rcb->ucd.state != L2C_UCD_STATE_UNUSED )) {
  110. if ( p_rcb->ucd.cb_info.pL2CA_UCD_Congestion_Status_Cb ) {
  111. L2CAP_TRACE_DEBUG ("L2CAP - Calling UCDCongestionStatus_Cb (%d), PSM=0x%04x, BDA: %08x%04x,",
  112. is_congested, p_rcb->psm,
  113. (rem_bda[0] << 24) + (rem_bda[1] << 16) + (rem_bda[2] << 8) + rem_bda[3],
  114. (rem_bda[4] << 8) + rem_bda[5]);
  115. p_rcb->ucd.cb_info.pL2CA_UCD_Congestion_Status_Cb ( rem_bda, is_congested );
  116. }
  117. }
  118. }
  119. }
  120. /*******************************************************************************
  121. **
  122. ** Function l2c_ucd_disconnect_ind_cback
  123. **
  124. ** Description UCD disconnect callback (This prevent to access null pointer)
  125. **
  126. ** Returns void
  127. **
  128. *******************************************************************************/
  129. static void l2c_ucd_disconnect_ind_cback (UINT16 cid, BOOLEAN result)
  130. {
  131. /* do nothing */
  132. }
  133. /*******************************************************************************
  134. **
  135. ** Function l2c_ucd_config_ind_cback
  136. **
  137. ** Description UCD config callback (This prevent to access null pointer)
  138. **
  139. ** Returns void
  140. **
  141. *******************************************************************************/
  142. static void l2c_ucd_config_ind_cback (UINT16 cid, tL2CAP_CFG_INFO *p_cfg)
  143. {
  144. /* do nothing */
  145. }
  146. /*******************************************************************************
  147. **
  148. ** Function l2c_ucd_config_cfm_cback
  149. **
  150. ** Description UCD config callback (This prevent to access null pointer)
  151. **
  152. ** Returns void
  153. **
  154. *******************************************************************************/
  155. static void l2c_ucd_config_cfm_cback (UINT16 cid, tL2CAP_CFG_INFO *p_cfg)
  156. {
  157. /* do nothing */
  158. }
  159. /*******************************************************************************
  160. **
  161. ** Function L2CA_UcdRegister
  162. **
  163. ** Description Register PSM on UCD.
  164. **
  165. ** Parameters: tL2CAP_UCD_CB_INFO
  166. **
  167. ** Return value: TRUE if successs
  168. **
  169. *******************************************************************************/
  170. BOOLEAN L2CA_UcdRegister ( UINT16 psm, tL2CAP_UCD_CB_INFO *p_cb_info )
  171. {
  172. tL2C_RCB *p_rcb;
  173. L2CAP_TRACE_API ("L2CA_UcdRegister() PSM: 0x%04x", psm);
  174. if ((!p_cb_info->pL2CA_UCD_Discover_Cb)
  175. || (!p_cb_info->pL2CA_UCD_Data_Cb)) {
  176. L2CAP_TRACE_ERROR ("L2CAP - no callback registering PSM(0x%04x) on UCD", psm);
  177. return (FALSE);
  178. }
  179. if ((p_rcb = l2cu_find_rcb_by_psm (psm)) == NULL) {
  180. L2CAP_TRACE_ERROR ("L2CAP - no RCB for L2CA_UcdRegister, PSM: 0x%04x", psm);
  181. return (FALSE);
  182. }
  183. p_rcb->ucd.state = L2C_UCD_STATE_W4_DATA;
  184. p_rcb->ucd.cb_info = *p_cb_info;
  185. /* check if master rcb is created for UCD */
  186. if ((p_rcb = l2cu_find_rcb_by_psm (L2C_UCD_RCB_ID)) == NULL) {
  187. if ((p_rcb = l2cu_allocate_rcb (L2C_UCD_RCB_ID)) == NULL) {
  188. L2CAP_TRACE_ERROR ("L2CAP - no RCB available for L2CA_UcdRegister");
  189. return (FALSE);
  190. } else {
  191. /* these callback functions will forward data to each UCD application */
  192. p_rcb->ucd.cb_info.pL2CA_UCD_Discover_Cb = l2c_ucd_discover_cback;
  193. p_rcb->ucd.cb_info.pL2CA_UCD_Data_Cb = l2c_ucd_data_ind_cback;
  194. p_rcb->ucd.cb_info.pL2CA_UCD_Congestion_Status_Cb = l2c_ucd_congestion_status_cback;
  195. memset (&p_rcb->api, 0, sizeof(tL2CAP_APPL_INFO));
  196. p_rcb->api.pL2CA_DisconnectInd_Cb = l2c_ucd_disconnect_ind_cback;
  197. /* This will make L2CAP check UCD congestion callback */
  198. p_rcb->api.pL2CA_CongestionStatus_Cb = NULL;
  199. /* do nothing but prevent crash */
  200. p_rcb->api.pL2CA_ConfigInd_Cb = l2c_ucd_config_ind_cback;
  201. p_rcb->api.pL2CA_ConfigCfm_Cb = l2c_ucd_config_cfm_cback;
  202. }
  203. }
  204. return (TRUE);
  205. }
  206. /*******************************************************************************
  207. **
  208. ** Function L2CA_UcdDeregister
  209. **
  210. ** Description Deregister PSM on UCD.
  211. **
  212. ** Parameters: PSM
  213. **
  214. ** Return value: TRUE if successs
  215. **
  216. *******************************************************************************/
  217. BOOLEAN L2CA_UcdDeregister ( UINT16 psm )
  218. {
  219. tL2C_CCB *p_ccb;
  220. tL2C_RCB *p_rcb;
  221. UINT16 xx;
  222. L2CAP_TRACE_API ("L2CA_UcdDeregister() PSM: 0x%04x", psm);
  223. if ((p_rcb = l2cu_find_rcb_by_psm (psm)) == NULL) {
  224. L2CAP_TRACE_ERROR ("L2CAP - no RCB for L2CA_UcdDeregister, PSM: 0x%04x", psm);
  225. return (FALSE);
  226. }
  227. p_rcb->ucd.state = L2C_UCD_STATE_UNUSED;
  228. /* check this was the last UCD registration */
  229. p_rcb = &l2cb.rcb_pool[0];
  230. for (xx = 0; xx < MAX_L2CAP_CLIENTS; xx++, p_rcb++) {
  231. if ((p_rcb->in_use) && (p_rcb->ucd.state != L2C_UCD_STATE_UNUSED)) {
  232. return (TRUE);
  233. }
  234. }
  235. /* delete master rcb for UCD */
  236. if ((p_rcb = l2cu_find_rcb_by_psm (L2C_UCD_RCB_ID)) != NULL) {
  237. l2cu_release_rcb (p_rcb);
  238. }
  239. /* delete CCB for UCD */
  240. p_ccb = l2cb.ccb_pool;
  241. for ( xx = 0; xx < MAX_L2CAP_CHANNELS; xx++ ) {
  242. if (( p_ccb->in_use )
  243. && ( p_ccb->local_cid == L2CAP_CONNECTIONLESS_CID )) {
  244. l2cu_release_ccb (p_ccb);
  245. }
  246. p_ccb++;
  247. }
  248. return (TRUE);
  249. }
  250. /*******************************************************************************
  251. **
  252. ** Function L2CA_UcdDiscover
  253. **
  254. ** Description Discover UCD of remote device.
  255. **
  256. ** Parameters: PSM
  257. ** BD_ADDR of remote device
  258. ** info_type : L2CAP_UCD_INFO_TYPE_RECEPTION
  259. ** L2CAP_UCD_INFO_TYPE_MTU
  260. **
  261. **
  262. ** Return value: TRUE if successs
  263. **
  264. *******************************************************************************/
  265. BOOLEAN L2CA_UcdDiscover ( UINT16 psm, BD_ADDR rem_bda, UINT8 info_type )
  266. {
  267. tL2C_LCB *p_lcb;
  268. tL2C_CCB *p_ccb;
  269. tL2C_RCB *p_rcb;
  270. L2CAP_TRACE_API ("L2CA_UcdDiscover() PSM: 0x%04x BDA: %08x%04x, InfoType=0x%02x", psm,
  271. (rem_bda[0] << 24) + (rem_bda[1] << 16) + (rem_bda[2] << 8) + rem_bda[3],
  272. (rem_bda[4] << 8) + rem_bda[5], info_type);
  273. /* Fail if the PSM is not registered */
  274. if (((p_rcb = l2cu_find_rcb_by_psm (psm)) == NULL)
  275. || ( p_rcb->ucd.state == L2C_UCD_STATE_UNUSED )) {
  276. L2CAP_TRACE_WARNING ("L2CAP - no RCB for L2CA_UcdDiscover, PSM: 0x%04x", psm);
  277. return (FALSE);
  278. }
  279. /* First, see if we already have a link to the remote */
  280. /* then find the channel control block for UCD. */
  281. if (((p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda, BT_TRANSPORT_BR_EDR)) == NULL)
  282. || ((p_ccb = l2cu_find_ccb_by_cid (p_lcb, L2CAP_CONNECTIONLESS_CID)) == NULL)) {
  283. if ( l2c_ucd_connect (rem_bda) == FALSE ) {
  284. return (FALSE);
  285. }
  286. }
  287. /* set waiting flags in rcb */
  288. if ( info_type & L2CAP_UCD_INFO_TYPE_RECEPTION ) {
  289. p_rcb->ucd.state |= L2C_UCD_STATE_W4_RECEPTION;
  290. }
  291. if ( info_type & L2CAP_UCD_INFO_TYPE_MTU ) {
  292. p_rcb->ucd.state |= L2C_UCD_STATE_W4_MTU;
  293. }
  294. /* if link is already established */
  295. if ((p_lcb) && (p_lcb->link_state == LST_CONNECTED)) {
  296. if (!p_ccb) {
  297. p_ccb = l2cu_find_ccb_by_cid (p_lcb, L2CAP_CONNECTIONLESS_CID);
  298. }
  299. l2c_ucd_check_pending_info_req(p_ccb);
  300. }
  301. return (TRUE);
  302. }
  303. /*******************************************************************************
  304. **
  305. ** Function L2CA_UcdDataWrite
  306. **
  307. ** Description Send UCD to remote device
  308. **
  309. ** Parameters: PSM
  310. ** BD Address of remote
  311. ** Pointer to buffer of type BT_HDR
  312. ** flags : L2CAP_FLUSHABLE_CH_BASED
  313. ** L2CAP_FLUSHABLE_PKT
  314. ** L2CAP_NON_FLUSHABLE_PKT
  315. **
  316. ** Return value L2CAP_DW_SUCCESS, if data accepted
  317. ** L2CAP_DW_FAILED, if error
  318. **
  319. *******************************************************************************/
  320. UINT16 L2CA_UcdDataWrite (UINT16 psm, BD_ADDR rem_bda, BT_HDR *p_buf, UINT16 flags)
  321. {
  322. tL2C_LCB *p_lcb;
  323. tL2C_CCB *p_ccb;
  324. tL2C_RCB *p_rcb;
  325. UINT8 *p;
  326. L2CAP_TRACE_API ("L2CA_UcdDataWrite() PSM: 0x%04x BDA: %08x%04x", psm,
  327. (rem_bda[0] << 24) + (rem_bda[1] << 16) + (rem_bda[2] << 8) + rem_bda[3],
  328. (rem_bda[4] << 8) + rem_bda[5]);
  329. /* Fail if the PSM is not registered */
  330. if (((p_rcb = l2cu_find_rcb_by_psm (psm)) == NULL)
  331. || ( p_rcb->ucd.state == L2C_UCD_STATE_UNUSED )) {
  332. L2CAP_TRACE_WARNING ("L2CAP - no RCB for L2CA_UcdDataWrite, PSM: 0x%04x", psm);
  333. osi_free (p_buf);
  334. return (L2CAP_DW_FAILED);
  335. }
  336. /* First, see if we already have a link to the remote */
  337. /* then find the channel control block for UCD */
  338. if (((p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda, BT_TRANSPORT_BR_EDR)) == NULL)
  339. || ((p_ccb = l2cu_find_ccb_by_cid (p_lcb, L2CAP_CONNECTIONLESS_CID)) == NULL)) {
  340. if ( l2c_ucd_connect (rem_bda) == FALSE ) {
  341. osi_free (p_buf);
  342. return (L2CAP_DW_FAILED);
  343. }
  344. /* If we still don't have lcb and ccb after connect attempt, then can't proceed */
  345. if (((p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda, BT_TRANSPORT_BR_EDR)) == NULL)
  346. || ((p_ccb = l2cu_find_ccb_by_cid (p_lcb, L2CAP_CONNECTIONLESS_CID)) == NULL)) {
  347. osi_free (p_buf);
  348. return (L2CAP_DW_FAILED);
  349. }
  350. }
  351. /* write PSM */
  352. p_buf->offset -= L2CAP_UCD_OVERHEAD;
  353. p_buf->len += L2CAP_UCD_OVERHEAD;
  354. p = (UINT8 *)(p_buf + 1) + p_buf->offset;
  355. UINT16_TO_STREAM (p, psm);
  356. /* UCD MTU check */
  357. if ((p_lcb->ucd_mtu) && (p_buf->len > p_lcb->ucd_mtu)) {
  358. L2CAP_TRACE_WARNING ("L2CAP - Handle: 0x%04x UCD bigger than peer's UCD mtu size cannot be sent", p_lcb->handle);
  359. osi_free (p_buf);
  360. return (L2CAP_DW_FAILED);
  361. }
  362. /* If already congested, do not accept any more packets */
  363. if (p_ccb->cong_sent) {
  364. L2CAP_TRACE_ERROR ("L2CAP - Handle: 0x%04x UCD cannot be sent, already congested count: %u buff_quota: %u",
  365. p_lcb->handle,
  366. (fixed_queue_length(p_ccb->xmit_hold_q) +
  367. fixed_queue_length(p_lcb->ucd_out_sec_pending_q)),
  368. p_ccb->buff_quota);
  369. osi_free (p_buf);
  370. return (L2CAP_DW_FAILED);
  371. }
  372. /* channel based, packet based flushable or non-flushable */
  373. p_buf->layer_specific = flags;
  374. l2c_csm_execute (p_ccb, L2CEVT_L2CA_DATA_WRITE, p_buf);
  375. if (p_ccb->cong_sent) {
  376. return (L2CAP_DW_CONGESTED);
  377. } else {
  378. return (L2CAP_DW_SUCCESS);
  379. }
  380. }
  381. /*******************************************************************************
  382. **
  383. ** Function L2CA_UcdSetIdleTimeout
  384. **
  385. ** Description Set UCD Idle timeout.
  386. **
  387. ** Parameters: BD Addr
  388. ** Timeout in second
  389. **
  390. ** Return value: TRUE if successs
  391. **
  392. *******************************************************************************/
  393. BOOLEAN L2CA_UcdSetIdleTimeout ( BD_ADDR rem_bda, UINT16 timeout )
  394. {
  395. tL2C_LCB *p_lcb;
  396. tL2C_CCB *p_ccb;
  397. L2CAP_TRACE_API ("L2CA_UcdSetIdleTimeout() Timeout: 0x%04x BDA: %08x%04x", timeout,
  398. (rem_bda[0] << 24) + (rem_bda[1] << 16) + (rem_bda[2] << 8) + rem_bda[3],
  399. (rem_bda[4] << 8) + rem_bda[5]);
  400. /* First, see if we already have a link to the remote */
  401. /* then find the channel control block. */
  402. if (((p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda, BT_TRANSPORT_BR_EDR)) == NULL)
  403. || ((p_ccb = l2cu_find_ccb_by_cid (p_lcb, L2CAP_CONNECTIONLESS_CID)) == NULL)) {
  404. L2CAP_TRACE_WARNING ("L2CAP - no UCD channel");
  405. return (FALSE);
  406. } else {
  407. p_ccb->fixed_chnl_idle_tout = timeout;
  408. return (TRUE);
  409. }
  410. }
  411. /*******************************************************************************
  412. **
  413. ** Function L2CA_UCDSetTxPriority
  414. **
  415. ** Description Sets the transmission priority for a connectionless channel.
  416. **
  417. ** Returns TRUE if a valid channel, else FALSE
  418. **
  419. *******************************************************************************/
  420. BOOLEAN L2CA_UCDSetTxPriority ( BD_ADDR rem_bda, tL2CAP_CHNL_PRIORITY priority )
  421. {
  422. tL2C_LCB *p_lcb;
  423. tL2C_CCB *p_ccb;
  424. L2CAP_TRACE_API ("L2CA_UCDSetTxPriority() priority: 0x%02x BDA: %08x%04x", priority,
  425. (rem_bda[0] << 24) + (rem_bda[1] << 16) + (rem_bda[2] << 8) + rem_bda[3],
  426. (rem_bda[4] << 8) + rem_bda[5]);
  427. if ((p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda, BT_TRANSPORT_BR_EDR)) == NULL) {
  428. L2CAP_TRACE_WARNING ("L2CAP - no LCB for L2CA_UCDSetTxPriority");
  429. return (FALSE);
  430. }
  431. /* Find the channel control block */
  432. if ((p_ccb = l2cu_find_ccb_by_cid (p_lcb, L2CAP_CONNECTIONLESS_CID)) == NULL) {
  433. L2CAP_TRACE_WARNING ("L2CAP - no CCB for L2CA_UCDSetTxPriority");
  434. return (FALSE);
  435. }
  436. /* it will update the order of CCB in LCB by priority and update round robin service variables */
  437. l2cu_change_pri_ccb (p_ccb, priority);
  438. return (TRUE);
  439. }
  440. /*******************************************************************************
  441. **
  442. ** Function l2c_ucd_connect
  443. **
  444. ** Description Connect UCD to remote device.
  445. **
  446. ** Parameters: BD_ADDR of remote device
  447. **
  448. ** Return value: TRUE if successs
  449. **
  450. *******************************************************************************/
  451. static BOOLEAN l2c_ucd_connect ( BD_ADDR rem_bda )
  452. {
  453. tL2C_LCB *p_lcb;
  454. tL2C_CCB *p_ccb;
  455. tL2C_RCB *p_rcb;
  456. L2CAP_TRACE_DEBUG ("l2c_ucd_connect() BDA: %08x%04x",
  457. (rem_bda[0] << 24) + (rem_bda[1] << 16) + (rem_bda[2] << 8) + rem_bda[3],
  458. (rem_bda[4] << 8) + rem_bda[5]);
  459. /* Fail if we have not established communications with the controller */
  460. if (!BTM_IsDeviceUp()) {
  461. L2CAP_TRACE_WARNING ("l2c_ucd_connect - BTU not ready");
  462. return (FALSE);
  463. }
  464. /* First, see if we already have a link to the remote */
  465. if ((p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda, BT_TRANSPORT_BR_EDR)) == NULL) {
  466. /* No link. Get an LCB and start link establishment */
  467. if ( ((p_lcb = l2cu_allocate_lcb (rem_bda, FALSE, BT_TRANSPORT_BR_EDR)) == NULL)
  468. || (l2cu_create_conn(p_lcb, BT_TRANSPORT_BR_EDR) == FALSE) ) {
  469. L2CAP_TRACE_WARNING ("L2CAP - conn not started l2c_ucd_connect");
  470. return (FALSE);
  471. }
  472. } else if ( p_lcb->info_rx_bits & (1 << L2CAP_EXTENDED_FEATURES_INFO_TYPE) ) {
  473. if (!(p_lcb->peer_ext_fea & L2CAP_EXTFEA_UCD_RECEPTION)) {
  474. L2CAP_TRACE_WARNING ("L2CAP - UCD is not supported by peer, l2c_ucd_connect");
  475. return (FALSE);
  476. }
  477. }
  478. /* Find the channel control block. */
  479. if ((p_ccb = l2cu_find_ccb_by_cid (p_lcb, L2CAP_CONNECTIONLESS_CID)) == NULL) {
  480. /* Allocate a channel control block */
  481. if ((p_ccb = l2cu_allocate_ccb (p_lcb, 0)) == NULL) {
  482. L2CAP_TRACE_WARNING ("L2CAP - no CCB for l2c_ucd_connect");
  483. return (FALSE);
  484. } else {
  485. /* Set CID for the connection */
  486. p_ccb->local_cid = L2CAP_CONNECTIONLESS_CID;
  487. p_ccb->remote_cid = L2CAP_CONNECTIONLESS_CID;
  488. /* Set the default idle timeout value to use */
  489. p_ccb->fixed_chnl_idle_tout = L2CAP_UCD_IDLE_TIMEOUT;
  490. /* Set the default channel priority value to use */
  491. l2cu_change_pri_ccb (p_ccb, L2CAP_UCD_CH_PRIORITY);
  492. if ((p_rcb = l2cu_find_rcb_by_psm (L2C_UCD_RCB_ID)) == NULL) {
  493. L2CAP_TRACE_WARNING ("L2CAP - no UCD registered, l2c_ucd_connect");
  494. return (FALSE);
  495. }
  496. /* Save UCD registration info */
  497. p_ccb->p_rcb = p_rcb;
  498. /* There is no configuration, so if the link is up, the channel is up */
  499. if (p_lcb->link_state == LST_CONNECTED) {
  500. p_ccb->chnl_state = CST_OPEN;
  501. }
  502. }
  503. }
  504. return (TRUE);
  505. }
  506. /*******************************************************************************
  507. **
  508. ** Function l2c_ucd_delete_sec_pending_q
  509. **
  510. ** Description discard all of UCD packets in security pending queue
  511. **
  512. ** Returns None
  513. **
  514. *******************************************************************************/
  515. void l2c_ucd_delete_sec_pending_q(tL2C_LCB *p_lcb)
  516. {
  517. /* clean up any security pending UCD */
  518. while (p_lcb->ucd_out_sec_pending_q.p_first) {
  519. osi_free(fixed_queue_dequeue(p_lcb->ucd_out_sec_pending_q, 0));
  520. }
  521. fixed_queue_free(p_lcb->ucd_out_sec_pending_q, NULL);
  522. p_lcb->ucd_out_sec_pending_q = NULL;
  523. while (! fixed_queue_is_empty(p_lcb->ucd_in_sec_pending_q)) {
  524. osi_free(fixed_queue_dequeue(p_lcb->ucd_in_sec_pending_q, 0));
  525. }
  526. fixed_queue_free(p_lcb->ucd_in_sec_pending_q);
  527. p_lcb->ucd_in_sec_pending_q = NULL;
  528. }
  529. /*******************************************************************************
  530. **
  531. ** Function l2c_ucd_check_pending_info_req
  532. **
  533. ** Description check if any application is waiting for UCD information
  534. **
  535. ** Return TRUE if any pending UCD info request
  536. **
  537. *******************************************************************************/
  538. BOOLEAN l2c_ucd_check_pending_info_req(tL2C_CCB *p_ccb)
  539. {
  540. tL2C_RCB *p_rcb = &l2cb.rcb_pool[0];
  541. UINT16 xx;
  542. BOOLEAN pending = FALSE;
  543. if (p_ccb == NULL) {
  544. L2CAP_TRACE_ERROR ("L2CAP - NULL p_ccb in l2c_ucd_check_pending_info_req");
  545. return (FALSE);
  546. }
  547. for (xx = 0; xx < MAX_L2CAP_CLIENTS; xx++, p_rcb++) {
  548. if (p_rcb->in_use) {
  549. /* if application is waiting UCD reception info */
  550. if (p_rcb->ucd.state & L2C_UCD_STATE_W4_RECEPTION) {
  551. /* if this information is available */
  552. if ( p_ccb->p_lcb->info_rx_bits & (1 << L2CAP_EXTENDED_FEATURES_INFO_TYPE) ) {
  553. if (!(p_ccb->p_lcb->peer_ext_fea & L2CAP_EXTFEA_UCD_RECEPTION)) {
  554. L2CAP_TRACE_WARNING ("L2CAP - UCD is not supported by peer, l2c_ucd_check_pending_info_req");
  555. l2c_ucd_delete_sec_pending_q(p_ccb->p_lcb);
  556. l2cu_release_ccb (p_ccb);
  557. }
  558. p_ccb->p_rcb->ucd.cb_info.pL2CA_UCD_Discover_Cb (p_ccb->p_lcb->remote_bd_addr,
  559. L2CAP_UCD_INFO_TYPE_RECEPTION,
  560. p_ccb->p_lcb->peer_ext_fea & L2CAP_EXTFEA_UCD_RECEPTION);
  561. } else {
  562. pending = TRUE;
  563. if (p_ccb->p_lcb->w4_info_rsp == FALSE) {
  564. l2cu_send_peer_info_req (p_ccb->p_lcb, L2CAP_EXTENDED_FEATURES_INFO_TYPE);
  565. }
  566. }
  567. }
  568. /* if application is waiting for UCD MTU */
  569. if (p_rcb->ucd.state & L2C_UCD_STATE_W4_MTU) {
  570. /* if this information is available */
  571. if ( p_ccb->p_lcb->info_rx_bits & (1 << L2CAP_CONNLESS_MTU_INFO_TYPE)) {
  572. p_ccb->p_rcb->ucd.cb_info.pL2CA_UCD_Discover_Cb (p_ccb->p_lcb->remote_bd_addr,
  573. L2CAP_UCD_INFO_TYPE_MTU,
  574. p_ccb->p_lcb->ucd_mtu);
  575. } else {
  576. pending = TRUE;
  577. if (p_ccb->p_lcb->w4_info_rsp == FALSE) {
  578. l2cu_send_peer_info_req (p_ccb->p_lcb, L2CAP_CONNLESS_MTU_INFO_TYPE);
  579. }
  580. }
  581. }
  582. }
  583. }
  584. return (pending);
  585. }
  586. /*******************************************************************************
  587. **
  588. ** Function l2c_ucd_enqueue_pending_out_sec_q
  589. **
  590. ** Description enqueue outgoing UCD packet into security pending queue
  591. ** and check congestion
  592. **
  593. ** Return None
  594. **
  595. *******************************************************************************/
  596. void l2c_ucd_enqueue_pending_out_sec_q(tL2C_CCB *p_ccb, void *p_data)
  597. {
  598. fixed_queue_enqueue(p_ccb->p_lcb->ucd_out_sec_pending_q, p_data, FIXED_QUEUE_MAX_TIMEOUT);
  599. l2cu_check_channel_congestion (p_ccb);
  600. }
  601. /*******************************************************************************
  602. **
  603. ** Function l2c_ucd_check_pending_out_sec_q
  604. **
  605. ** Description check outgoing security
  606. **
  607. ** Return TRUE if any UCD packet for security
  608. **
  609. *******************************************************************************/
  610. BOOLEAN l2c_ucd_check_pending_out_sec_q(tL2C_CCB *p_ccb)
  611. {
  612. BT_HDR *p_buf = (BT_HDR*)fixed_queue_try_peek_first(p_ccb->p_lcb->ucd_out_sec_pending_q);
  613. if (p_buf != NULL) {
  614. UINT16 psm;
  615. UINT8 *p = (UINT8 *)(p_buf + 1) + p_buf->offset;
  616. STREAM_TO_UINT16(psm, p)
  617. p_ccb->chnl_state = CST_ORIG_W4_SEC_COMP;
  618. btm_sec_l2cap_access_req (p_ccb->p_lcb->remote_bd_addr, psm,
  619. p_ccb->p_lcb->handle, CONNLESS_ORIG, &l2c_link_sec_comp, p_ccb);
  620. return (TRUE);
  621. }
  622. return (FALSE);
  623. }
  624. /*******************************************************************************
  625. **
  626. ** Function l2c_ucd_send_pending_out_sec_q
  627. **
  628. ** Description dequeue UCD packet from security pending queue and
  629. ** enqueue it into CCB
  630. **
  631. ** Return None
  632. **
  633. *******************************************************************************/
  634. void l2c_ucd_send_pending_out_sec_q(tL2C_CCB *p_ccb)
  635. {
  636. BT_HDR *p_buf = (BT_HDR*)fixed_queue_dequeue(p_ccb->p_lcb->ucd_out_sec_pending_q, 0);
  637. if (p_buf != NULL) {
  638. l2c_enqueue_peer_data (p_ccb, (BT_HDR *)p_buf);
  639. l2c_link_check_send_pkts (p_ccb->p_lcb, NULL, NULL);
  640. }
  641. }
  642. /*******************************************************************************
  643. **
  644. ** Function l2c_ucd_discard_pending_out_sec_q
  645. **
  646. ** Description dequeue UCD packet from security pending queue and
  647. ** discard it.
  648. **
  649. ** Return None
  650. **
  651. *******************************************************************************/
  652. void l2c_ucd_discard_pending_out_sec_q(tL2C_CCB *p_ccb)
  653. {
  654. BT_HDR *p_buf = (BT_HDR*)fixed_queue_dequeue(p_ccb->p_lcb->ucd_out_sec_pending_q, 0);
  655. /* we may need to report to application */
  656. if (p_buf) {
  657. osi_free (p_buf);
  658. }
  659. }
  660. /*******************************************************************************
  661. **
  662. ** Function l2c_ucd_check_pending_in_sec_q
  663. **
  664. ** Description check incoming security
  665. **
  666. ** Return TRUE if any UCD packet for security
  667. **
  668. *******************************************************************************/
  669. BOOLEAN l2c_ucd_check_pending_in_sec_q(tL2C_CCB *p_ccb)
  670. {
  671. BT_HDR *p_buf = (BT_HDR*)fixed_queue_dequeue(p_ccb->p_lcb->ucd_in_sec_pending_q, 0);
  672. if (p_buf != NULL) {
  673. UINT16 psm;
  674. UINT8 *p = (UINT8 *)(p_buf + 1) + p_buf->offset;
  675. STREAM_TO_UINT16(psm, p)
  676. p_ccb->chnl_state = CST_TERM_W4_SEC_COMP;
  677. btm_sec_l2cap_access_req (p_ccb->p_lcb->remote_bd_addr, psm,
  678. p_ccb->p_lcb->handle, CONNLESS_TERM, &l2c_link_sec_comp, p_ccb);
  679. return (TRUE);
  680. }
  681. return (FALSE);
  682. }
  683. /*******************************************************************************
  684. **
  685. ** Function l2c_ucd_send_pending_in_sec_q
  686. **
  687. ** Description dequeue UCD packet from security pending queue and
  688. ** send it to application
  689. **
  690. ** Return None
  691. **
  692. *******************************************************************************/
  693. void l2c_ucd_send_pending_in_sec_q(tL2C_CCB *p_ccb)
  694. {
  695. BT_HDR *p_buf = (BT_HDR*)fixed_queue_dequeue(p_ccb->p_lcb->ucd_in_sec_pending_q, 0)
  696. if (p_buf != NULL) {
  697. p_ccb->p_rcb->ucd.cb_info.pL2CA_UCD_Data_Cb(p_ccb->p_lcb->remote_bd_addr, (BT_HDR *)p_buf);
  698. }
  699. }
  700. /*******************************************************************************
  701. **
  702. ** Function l2c_ucd_discard_pending_in_sec_q
  703. **
  704. ** Description dequeue UCD packet from security pending queue and
  705. ** discard it.
  706. **
  707. ** Return None
  708. **
  709. *******************************************************************************/
  710. void l2c_ucd_discard_pending_in_sec_q(tL2C_CCB *p_ccb)
  711. {
  712. BT_HDR *p_buf = (BT_HDR*)fixed_queue_dequeue(p_ccb->p_lcb->ucd_in_sec_pending_q, 0);
  713. if (p_buf) {
  714. osi_free (p_buf);
  715. }
  716. }
  717. /*******************************************************************************
  718. **
  719. ** Function l2c_ucd_check_rx_pkts
  720. **
  721. ** Description Check if UCD reception is registered.
  722. ** Process received UCD packet if application is expecting.
  723. **
  724. ** Return TRUE if UCD reception is registered
  725. **
  726. *******************************************************************************/
  727. BOOLEAN l2c_ucd_check_rx_pkts(tL2C_LCB *p_lcb, BT_HDR *p_msg)
  728. {
  729. tL2C_CCB *p_ccb;
  730. tL2C_RCB *p_rcb;
  731. if (((p_ccb = l2cu_find_ccb_by_cid (p_lcb, L2CAP_CONNECTIONLESS_CID)) != NULL)
  732. || ((p_rcb = l2cu_find_rcb_by_psm (L2C_UCD_RCB_ID)) != NULL)) {
  733. if (p_ccb == NULL) {
  734. /* Allocate a channel control block */
  735. if ((p_ccb = l2cu_allocate_ccb (p_lcb, 0)) == NULL) {
  736. L2CAP_TRACE_WARNING ("L2CAP - no CCB for UCD reception");
  737. osi_free (p_msg);
  738. return TRUE;
  739. } else {
  740. /* Set CID for the connection */
  741. p_ccb->local_cid = L2CAP_CONNECTIONLESS_CID;
  742. p_ccb->remote_cid = L2CAP_CONNECTIONLESS_CID;
  743. /* Set the default idle timeout value to use */
  744. p_ccb->fixed_chnl_idle_tout = L2CAP_UCD_IDLE_TIMEOUT;
  745. /* Set the default channel priority value to use */
  746. l2cu_change_pri_ccb (p_ccb, L2CAP_UCD_CH_PRIORITY);
  747. /* Save registration info */
  748. p_ccb->p_rcb = p_rcb;
  749. p_ccb->chnl_state = CST_OPEN;
  750. }
  751. }
  752. l2c_csm_execute(p_ccb, L2CEVT_L2CAP_DATA, p_msg);
  753. return TRUE;
  754. } else {
  755. return FALSE;
  756. }
  757. }
  758. /*******************************************************************************
  759. **
  760. ** Function l2c_ucd_process_event
  761. **
  762. ** Description This is called from main state machine when LCID is connectionless
  763. ** Process the event if it is for UCD.
  764. **
  765. ** Return TRUE if the event is consumed by UCD
  766. ** FALSE if the event needs to be processed by main state machine
  767. **
  768. *******************************************************************************/
  769. BOOLEAN l2c_ucd_process_event(tL2C_CCB *p_ccb, UINT16 event, void *p_data)
  770. {
  771. /* if the event is not processed by this function, this variable will be set to FALSE */
  772. BOOLEAN done = TRUE;
  773. switch (p_ccb->chnl_state) {
  774. case CST_CLOSED:
  775. switch (event) {
  776. case L2CEVT_LP_CONNECT_CFM: /* Link came up */
  777. /* check if waiting for UCD info */
  778. if (!l2c_ucd_check_pending_info_req (p_ccb)) {
  779. /* check if any outgoing UCD packet is waiting security check */
  780. if (!l2c_ucd_check_pending_out_sec_q(p_ccb)) {
  781. p_ccb->chnl_state = CST_OPEN;
  782. }
  783. }
  784. break;
  785. case L2CEVT_L2CAP_DATA: /* Peer data packet rcvd */
  786. fixed_queue_enqueue(p_ccb->p_lcb->ucd_in_sec_pending_q, p_data, FIXED_QUEUE_MAX_TIMEOUT);
  787. break;
  788. case L2CEVT_L2CA_DATA_WRITE: /* Upper layer data to send */
  789. l2c_ucd_enqueue_pending_out_sec_q(p_ccb, p_data);
  790. break;
  791. case L2CEVT_L2CAP_INFO_RSP:
  792. /* check if waiting for UCD info */
  793. if (!l2c_ucd_check_pending_info_req (p_ccb)) {
  794. /* check if any outgoing UCD packet is waiting security check */
  795. if (!l2c_ucd_check_pending_out_sec_q(p_ccb)) {
  796. p_ccb->chnl_state = CST_OPEN;
  797. }
  798. }
  799. break;
  800. default:
  801. done = FALSE; /* main state machine continues to process event */
  802. break;
  803. }
  804. break;
  805. case CST_ORIG_W4_SEC_COMP:
  806. switch (event) {
  807. case L2CEVT_SEC_RE_SEND_CMD: /* BTM has enough info to proceed */
  808. /* check if any outgoing UCD packet is waiting security check */
  809. if (!l2c_ucd_check_pending_out_sec_q(p_ccb)) {
  810. p_ccb->chnl_state = CST_OPEN;
  811. }
  812. break;
  813. case L2CEVT_SEC_COMP: /* Security completed success */
  814. p_ccb->chnl_state = CST_OPEN;
  815. l2c_ucd_send_pending_out_sec_q(p_ccb);
  816. if (! fixed_queue_is_empty(p_ccb->p_lcb->ucd_out_sec_pending_q))
  817. {
  818. /* start a timer to send next UCD packet in OPEN state */
  819. /* it will prevent stack overflow */
  820. btu_start_timer (&p_ccb->timer_entry, BTU_TTYPE_L2CAP_CHNL, 0);
  821. } else {
  822. /* start a timer for idle timeout of UCD */
  823. btu_start_timer (&p_ccb->timer_entry, BTU_TTYPE_L2CAP_CHNL, p_ccb->fixed_chnl_idle_tout);
  824. }
  825. break;
  826. case L2CEVT_SEC_COMP_NEG:
  827. p_ccb->chnl_state = CST_OPEN;
  828. l2c_ucd_discard_pending_out_sec_q(p_ccb);
  829. /* start a timer for idle timeout of UCD */
  830. btu_start_timer (&p_ccb->timer_entry, BTU_TTYPE_L2CAP_CHNL, p_ccb->fixed_chnl_idle_tout);
  831. break;
  832. case L2CEVT_L2CA_DATA_WRITE: /* Upper layer data to send */
  833. l2c_ucd_enqueue_pending_out_sec_q(p_ccb, p_data);
  834. break;
  835. case L2CEVT_L2CAP_DATA: /* Peer data packet rcvd */
  836. fixed_queue_enqueue(p_ccb->p_lcb->ucd_in_sec_pending_q, p_data, FIXED_QUEUE_MAX_TIMEOUT);
  837. break;
  838. case L2CEVT_L2CAP_INFO_RSP:
  839. /* check if waiting for UCD info */
  840. l2c_ucd_check_pending_info_req (p_ccb);
  841. break;
  842. default:
  843. done = FALSE; /* main state machine continues to process event */
  844. break;
  845. }
  846. break;
  847. case CST_TERM_W4_SEC_COMP:
  848. switch (event) {
  849. case L2CEVT_SEC_COMP:
  850. p_ccb->chnl_state = CST_OPEN;
  851. l2c_ucd_send_pending_in_sec_q (p_ccb);
  852. if (! fixed_queue_is_empty(p_ccb->p_lcb->ucd_in_sec_pending_q)) {
  853. /* start a timer to check next UCD packet in OPEN state */
  854. /* it will prevent stack overflow */
  855. btu_start_timer (&p_ccb->timer_entry, BTU_TTYPE_L2CAP_CHNL, 0);
  856. } else {
  857. /* start a timer for idle timeout of UCD */
  858. btu_start_timer (&p_ccb->timer_entry, BTU_TTYPE_L2CAP_CHNL, p_ccb->fixed_chnl_idle_tout);
  859. }
  860. break;
  861. case L2CEVT_SEC_COMP_NEG:
  862. if (((tL2C_CONN_INFO *)p_data)->status == BTM_DELAY_CHECK) {
  863. done = FALSE;
  864. break;
  865. }
  866. p_ccb->chnl_state = CST_OPEN;
  867. l2c_ucd_discard_pending_in_sec_q (p_ccb);
  868. /* start a timer for idle timeout of UCD */
  869. btu_start_timer (&p_ccb->timer_entry, BTU_TTYPE_L2CAP_CHNL, p_ccb->fixed_chnl_idle_tout);
  870. break;
  871. case L2CEVT_L2CA_DATA_WRITE: /* Upper layer data to send */
  872. l2c_ucd_enqueue_pending_out_sec_q(p_ccb, p_data);
  873. break;
  874. case L2CEVT_L2CAP_DATA: /* Peer data packet rcvd */
  875. fixed_queue_enqueue(p_ccb->p_lcb->ucd_in_sec_pending_q, p_data, FIXED_QUEUE_MAX_TIMEOUT);
  876. break;
  877. case L2CEVT_SEC_RE_SEND_CMD: /* BTM has enough info to proceed */
  878. /* check if any incoming UCD packet is waiting security check */
  879. if (!l2c_ucd_check_pending_in_sec_q(p_ccb)) {
  880. p_ccb->chnl_state = CST_OPEN;
  881. }
  882. break;
  883. case L2CEVT_L2CAP_INFO_RSP:
  884. /* check if waiting for UCD info */
  885. l2c_ucd_check_pending_info_req (p_ccb);
  886. break;
  887. default:
  888. done = FALSE; /* main state machine continues to process event */
  889. break;
  890. }
  891. break;
  892. case CST_OPEN:
  893. switch (event) {
  894. case L2CEVT_L2CAP_DATA: /* Peer data packet rcvd */
  895. /* stop idle timer of UCD */
  896. btu_stop_timer (&p_ccb->timer_entry);
  897. fixed_queue_enqueue(p_ccb->p_lcb->ucd_in_sec_pending_q, p_data, FIXED_QUEUE_MAX_TIMEOUT);
  898. l2c_ucd_check_pending_in_sec_q (p_ccb);
  899. break;
  900. case L2CEVT_L2CA_DATA_WRITE: /* Upper layer data to send */
  901. /* stop idle timer of UCD */
  902. btu_stop_timer (&p_ccb->timer_entry);
  903. l2c_ucd_enqueue_pending_out_sec_q(p_ccb, p_data);
  904. /* coverity[check_return] */ /* coverity[unchecked_value] */
  905. /* success changes state, failure stays in current state */
  906. l2c_ucd_check_pending_out_sec_q (p_ccb);
  907. break;
  908. case L2CEVT_TIMEOUT:
  909. /* check if any UCD packet is waiting security check */
  910. if ((!l2c_ucd_check_pending_in_sec_q(p_ccb))
  911. && (!l2c_ucd_check_pending_out_sec_q(p_ccb))) {
  912. l2cu_release_ccb (p_ccb);
  913. }
  914. break;
  915. case L2CEVT_L2CAP_INFO_RSP:
  916. /* check if waiting for UCD info */
  917. l2c_ucd_check_pending_info_req (p_ccb);
  918. break;
  919. default:
  920. done = FALSE; /* main state machine continues to process event */
  921. break;
  922. }
  923. break;
  924. default:
  925. done = FALSE; /* main state machine continues to process event */
  926. break;
  927. }
  928. return done;
  929. }
  930. #endif /* (L2CAP_UCD_INCLUDED == TRUE) */