l2c_ucd.c 38 KB

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