l2c_csm.cc 53 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400
  1. /******************************************************************************
  2. *
  3. * Copyright 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 channel state machine
  21. *
  22. ******************************************************************************/
  23. #include <stdio.h>
  24. #include <stdlib.h>
  25. #include <string.h>
  26. #include "bt_common.h"
  27. #include "bt_target.h"
  28. #include "btm_int.h"
  29. #include "btu.h"
  30. #include "common/time_util.h"
  31. #include "hcidefs.h"
  32. #include "hcimsgs.h"
  33. #include "l2c_int.h"
  34. #include "l2cdefs.h"
  35. /******************************************************************************/
  36. /* L O C A L F U N C T I O N P R O T O T Y P E S */
  37. /******************************************************************************/
  38. static void l2c_csm_closed(tL2C_CCB* p_ccb, uint16_t event, void* p_data);
  39. static void l2c_csm_orig_w4_sec_comp(tL2C_CCB* p_ccb, uint16_t event,
  40. void* p_data);
  41. static void l2c_csm_term_w4_sec_comp(tL2C_CCB* p_ccb, uint16_t event,
  42. void* p_data);
  43. static void l2c_csm_w4_l2cap_connect_rsp(tL2C_CCB* p_ccb, uint16_t event,
  44. void* p_data);
  45. static void l2c_csm_w4_l2ca_connect_rsp(tL2C_CCB* p_ccb, uint16_t event,
  46. void* p_data);
  47. static void l2c_csm_config(tL2C_CCB* p_ccb, uint16_t event, void* p_data);
  48. static void l2c_csm_open(tL2C_CCB* p_ccb, uint16_t event, void* p_data);
  49. static void l2c_csm_w4_l2cap_disconnect_rsp(tL2C_CCB* p_ccb, uint16_t event,
  50. void* p_data);
  51. static void l2c_csm_w4_l2ca_disconnect_rsp(tL2C_CCB* p_ccb, uint16_t event,
  52. void* p_data);
  53. static const char* l2c_csm_get_event_name(uint16_t event);
  54. /*******************************************************************************
  55. *
  56. * Function l2c_csm_execute
  57. *
  58. * Description This function executes the state machine.
  59. *
  60. * Returns void
  61. *
  62. ******************************************************************************/
  63. void l2c_csm_execute(tL2C_CCB* p_ccb, uint16_t event, void* p_data) {
  64. if (!l2cu_is_ccb_active(p_ccb)) {
  65. L2CAP_TRACE_WARNING("%s CCB not in use, event (%d) cannot be processed",
  66. __func__, event);
  67. return;
  68. }
  69. switch (p_ccb->chnl_state) {
  70. case CST_CLOSED:
  71. l2c_csm_closed(p_ccb, event, p_data);
  72. break;
  73. case CST_ORIG_W4_SEC_COMP:
  74. l2c_csm_orig_w4_sec_comp(p_ccb, event, p_data);
  75. break;
  76. case CST_TERM_W4_SEC_COMP:
  77. l2c_csm_term_w4_sec_comp(p_ccb, event, p_data);
  78. break;
  79. case CST_W4_L2CAP_CONNECT_RSP:
  80. l2c_csm_w4_l2cap_connect_rsp(p_ccb, event, p_data);
  81. break;
  82. case CST_W4_L2CA_CONNECT_RSP:
  83. l2c_csm_w4_l2ca_connect_rsp(p_ccb, event, p_data);
  84. break;
  85. case CST_CONFIG:
  86. l2c_csm_config(p_ccb, event, p_data);
  87. break;
  88. case CST_OPEN:
  89. l2c_csm_open(p_ccb, event, p_data);
  90. break;
  91. case CST_W4_L2CAP_DISCONNECT_RSP:
  92. l2c_csm_w4_l2cap_disconnect_rsp(p_ccb, event, p_data);
  93. break;
  94. case CST_W4_L2CA_DISCONNECT_RSP:
  95. l2c_csm_w4_l2ca_disconnect_rsp(p_ccb, event, p_data);
  96. break;
  97. default:
  98. L2CAP_TRACE_DEBUG("Unhandled event! event = %d", event);
  99. break;
  100. }
  101. }
  102. /*******************************************************************************
  103. *
  104. * Function l2c_csm_closed
  105. *
  106. * Description This function handles events when the channel is in
  107. * CLOSED state. This state exists only when the link is
  108. * being initially established.
  109. *
  110. * Returns void
  111. *
  112. ******************************************************************************/
  113. static void l2c_csm_closed(tL2C_CCB* p_ccb, uint16_t event, void* p_data) {
  114. tL2C_CONN_INFO* p_ci = (tL2C_CONN_INFO*)p_data;
  115. uint16_t local_cid = p_ccb->local_cid;
  116. tL2CA_DISCONNECT_IND_CB* disconnect_ind;
  117. tL2CA_CONNECT_CFM_CB* connect_cfm;
  118. if (p_ccb->p_rcb == NULL) {
  119. L2CAP_TRACE_ERROR("L2CAP - LCID: 0x%04x st: CLOSED evt: %s p_rcb == NULL",
  120. p_ccb->local_cid, l2c_csm_get_event_name(event));
  121. return;
  122. }
  123. disconnect_ind = p_ccb->p_rcb->api.pL2CA_DisconnectInd_Cb;
  124. connect_cfm = p_ccb->p_rcb->api.pL2CA_ConnectCfm_Cb;
  125. L2CAP_TRACE_EVENT("L2CAP - LCID: 0x%04x st: CLOSED evt: %s",
  126. p_ccb->local_cid, l2c_csm_get_event_name(event));
  127. switch (event) {
  128. case L2CEVT_LP_DISCONNECT_IND: /* Link was disconnected */
  129. L2CAP_TRACE_API(
  130. "L2CAP - Calling Disconnect_Ind_Cb(), CID: 0x%04x No Conf Needed",
  131. p_ccb->local_cid);
  132. l2cu_release_ccb(p_ccb);
  133. (*disconnect_ind)(local_cid, false);
  134. break;
  135. case L2CEVT_LP_CONNECT_CFM: /* Link came up */
  136. if (p_ccb->p_lcb->transport == BT_TRANSPORT_LE) {
  137. p_ccb->chnl_state = CST_ORIG_W4_SEC_COMP;
  138. l2ble_sec_access_req(p_ccb->p_lcb->remote_bd_addr, p_ccb->p_rcb->psm,
  139. true, &l2c_link_sec_comp2, p_ccb);
  140. } else {
  141. p_ccb->chnl_state = CST_ORIG_W4_SEC_COMP;
  142. btm_sec_l2cap_access_req(p_ccb->p_lcb->remote_bd_addr,
  143. p_ccb->p_rcb->psm, p_ccb->p_lcb->handle, true,
  144. &l2c_link_sec_comp, p_ccb);
  145. }
  146. break;
  147. case L2CEVT_LP_CONNECT_CFM_NEG: /* Link failed */
  148. /* Disconnect unless ACL collision and upper layer wants to handle it */
  149. if (p_ci->status != HCI_ERR_CONNECTION_EXISTS ||
  150. !btm_acl_notif_conn_collision(p_ccb->p_lcb->remote_bd_addr)) {
  151. L2CAP_TRACE_API(
  152. "L2CAP - Calling ConnectCfm_Cb(), CID: 0x%04x Status: %d",
  153. p_ccb->local_cid, p_ci->status);
  154. l2cu_release_ccb(p_ccb);
  155. (*connect_cfm)(local_cid, p_ci->status);
  156. }
  157. break;
  158. case L2CEVT_L2CA_CONNECT_REQ: /* API connect request */
  159. if (p_ccb->p_lcb->transport == BT_TRANSPORT_LE) {
  160. p_ccb->chnl_state = CST_ORIG_W4_SEC_COMP;
  161. l2ble_sec_access_req(p_ccb->p_lcb->remote_bd_addr, p_ccb->p_rcb->psm,
  162. true, &l2c_link_sec_comp2, p_ccb);
  163. } else {
  164. /* Cancel sniff mode if needed */
  165. tBTM_PM_PWR_MD settings;
  166. memset((void*)&settings, 0, sizeof(settings));
  167. settings.mode = BTM_PM_MD_ACTIVE;
  168. BTM_SetPowerMode(BTM_PM_SET_ONLY_ID, p_ccb->p_lcb->remote_bd_addr,
  169. &settings);
  170. /* If sec access does not result in started SEC_COM or COMP_NEG are
  171. * already processed */
  172. if (btm_sec_l2cap_access_req(p_ccb->p_lcb->remote_bd_addr,
  173. p_ccb->p_rcb->psm, p_ccb->p_lcb->handle,
  174. true, &l2c_link_sec_comp,
  175. p_ccb) == BTM_CMD_STARTED) {
  176. p_ccb->chnl_state = CST_ORIG_W4_SEC_COMP;
  177. }
  178. }
  179. break;
  180. case L2CEVT_SEC_COMP:
  181. p_ccb->chnl_state = CST_W4_L2CAP_CONNECT_RSP;
  182. /* Wait for the info resp in this state before sending connect req (if
  183. * needed) */
  184. if (!p_ccb->p_lcb->w4_info_rsp) {
  185. /* Need to have at least one compatible channel to continue */
  186. if (!l2c_fcr_chk_chan_modes(p_ccb)) {
  187. l2cu_release_ccb(p_ccb);
  188. (*p_ccb->p_rcb->api.pL2CA_ConnectCfm_Cb)(local_cid,
  189. L2CAP_CONN_NO_LINK);
  190. } else {
  191. l2cu_send_peer_connect_req(p_ccb);
  192. alarm_set_on_mloop(p_ccb->l2c_ccb_timer,
  193. L2CAP_CHNL_CONNECT_TIMEOUT_MS,
  194. l2c_ccb_timer_timeout, p_ccb);
  195. }
  196. }
  197. break;
  198. case L2CEVT_SEC_COMP_NEG: /* something is really bad with security */
  199. L2CAP_TRACE_API(
  200. "L2CAP - Calling ConnectCfm_Cb(), CID: 0x%04x Status: %d",
  201. p_ccb->local_cid, L2CAP_CONN_TIMEOUT);
  202. l2cu_release_ccb(p_ccb);
  203. (*connect_cfm)(local_cid, L2CAP_CONN_SECURITY_BLOCK);
  204. break;
  205. case L2CEVT_L2CAP_CONNECT_REQ: /* Peer connect request */
  206. /* stop link timer to avoid race condition between A2MP, Security, and
  207. * L2CAP */
  208. alarm_cancel(p_ccb->p_lcb->l2c_lcb_timer);
  209. if (p_ccb->p_lcb->transport == BT_TRANSPORT_LE) {
  210. p_ccb->chnl_state = CST_TERM_W4_SEC_COMP;
  211. tL2CAP_LE_RESULT_CODE result = l2ble_sec_access_req(
  212. p_ccb->p_lcb->remote_bd_addr, p_ccb->p_rcb->psm, false,
  213. &l2c_link_sec_comp2, p_ccb);
  214. switch (result) {
  215. case L2CAP_LE_RESULT_INSUFFICIENT_AUTHENTICATION:
  216. case L2CAP_LE_RESULT_INSUFFICIENT_ENCRYP_KEY_SIZE:
  217. case L2CAP_LE_RESULT_INSUFFICIENT_ENCRYP:
  218. l2cu_reject_ble_connection(p_ccb->p_lcb, p_ccb->remote_id, result);
  219. l2cu_release_ccb(p_ccb);
  220. break;
  221. // TODO: Handle the other return codes
  222. }
  223. } else {
  224. /* Cancel sniff mode if needed */
  225. {
  226. tBTM_PM_PWR_MD settings;
  227. memset((void*)&settings, 0, sizeof(settings));
  228. settings.mode = BTM_PM_MD_ACTIVE;
  229. BTM_SetPowerMode(BTM_PM_SET_ONLY_ID, p_ccb->p_lcb->remote_bd_addr,
  230. &settings);
  231. }
  232. p_ccb->chnl_state = CST_TERM_W4_SEC_COMP;
  233. if (btm_sec_l2cap_access_req(p_ccb->p_lcb->remote_bd_addr,
  234. p_ccb->p_rcb->psm, p_ccb->p_lcb->handle,
  235. false, &l2c_link_sec_comp,
  236. p_ccb) == BTM_CMD_STARTED) {
  237. /* started the security process, tell the peer to set a longer timer
  238. */
  239. l2cu_send_peer_connect_rsp(p_ccb, L2CAP_CONN_PENDING, 0);
  240. }
  241. }
  242. break;
  243. case L2CEVT_TIMEOUT:
  244. L2CAP_TRACE_API(
  245. "L2CAP - Calling ConnectCfm_Cb(), CID: 0x%04x Status: %d",
  246. p_ccb->local_cid, L2CAP_CONN_TIMEOUT);
  247. l2cu_release_ccb(p_ccb);
  248. (*connect_cfm)(local_cid, L2CAP_CONN_TIMEOUT);
  249. break;
  250. case L2CEVT_L2CAP_DATA: /* Peer data packet rcvd */
  251. case L2CEVT_L2CA_DATA_WRITE: /* Upper layer data to send */
  252. osi_free(p_data);
  253. break;
  254. case L2CEVT_L2CA_DISCONNECT_REQ: /* Upper wants to disconnect */
  255. l2cu_release_ccb(p_ccb);
  256. break;
  257. }
  258. }
  259. /*******************************************************************************
  260. *
  261. * Function l2c_csm_orig_w4_sec_comp
  262. *
  263. * Description This function handles events when the channel is in
  264. * CST_ORIG_W4_SEC_COMP state.
  265. *
  266. * Returns void
  267. *
  268. ******************************************************************************/
  269. static void l2c_csm_orig_w4_sec_comp(tL2C_CCB* p_ccb, uint16_t event,
  270. void* p_data) {
  271. tL2CA_DISCONNECT_IND_CB* disconnect_ind =
  272. p_ccb->p_rcb->api.pL2CA_DisconnectInd_Cb;
  273. tL2CA_CONNECT_CFM_CB* connect_cfm = p_ccb->p_rcb->api.pL2CA_ConnectCfm_Cb;
  274. uint16_t local_cid = p_ccb->local_cid;
  275. L2CAP_TRACE_EVENT(
  276. "%s: %sL2CAP - LCID: 0x%04x st: ORIG_W4_SEC_COMP evt: %s", __func__,
  277. ((p_ccb->p_lcb) && (p_ccb->p_lcb->transport == BT_TRANSPORT_LE)) ? "LE "
  278. : "",
  279. p_ccb->local_cid, l2c_csm_get_event_name(event));
  280. switch (event) {
  281. case L2CEVT_LP_DISCONNECT_IND: /* Link was disconnected */
  282. L2CAP_TRACE_API(
  283. "L2CAP - Calling Disconnect_Ind_Cb(), CID: 0x%04x No Conf Needed",
  284. p_ccb->local_cid);
  285. l2cu_release_ccb(p_ccb);
  286. (*disconnect_ind)(local_cid, false);
  287. break;
  288. case L2CEVT_SEC_RE_SEND_CMD: /* BTM has enough info to proceed */
  289. case L2CEVT_LP_CONNECT_CFM: /* Link came up */
  290. if (p_ccb->p_lcb->transport == BT_TRANSPORT_LE) {
  291. l2ble_sec_access_req(p_ccb->p_lcb->remote_bd_addr, p_ccb->p_rcb->psm,
  292. false, &l2c_link_sec_comp2, p_ccb);
  293. } else {
  294. btm_sec_l2cap_access_req(p_ccb->p_lcb->remote_bd_addr,
  295. p_ccb->p_rcb->psm, p_ccb->p_lcb->handle, true,
  296. &l2c_link_sec_comp, p_ccb);
  297. }
  298. break;
  299. case L2CEVT_SEC_COMP: /* Security completed success */
  300. /* Wait for the info resp in this state before sending connect req (if
  301. * needed) */
  302. p_ccb->chnl_state = CST_W4_L2CAP_CONNECT_RSP;
  303. if (p_ccb->p_lcb->transport == BT_TRANSPORT_LE) {
  304. alarm_set_on_mloop(p_ccb->l2c_ccb_timer, L2CAP_CHNL_CONNECT_TIMEOUT_MS,
  305. l2c_ccb_timer_timeout, p_ccb);
  306. l2cble_credit_based_conn_req(p_ccb); /* Start Connection */
  307. } else {
  308. if (!p_ccb->p_lcb->w4_info_rsp) {
  309. /* Need to have at least one compatible channel to continue */
  310. if (!l2c_fcr_chk_chan_modes(p_ccb)) {
  311. l2cu_release_ccb(p_ccb);
  312. (*connect_cfm)(local_cid, L2CAP_CONN_NO_LINK);
  313. } else {
  314. alarm_set_on_mloop(p_ccb->l2c_ccb_timer,
  315. L2CAP_CHNL_CONNECT_TIMEOUT_MS,
  316. l2c_ccb_timer_timeout, p_ccb);
  317. l2cu_send_peer_connect_req(p_ccb); /* Start Connection */
  318. }
  319. }
  320. }
  321. break;
  322. case L2CEVT_SEC_COMP_NEG:
  323. L2CAP_TRACE_API(
  324. "L2CAP - Calling ConnectCfm_Cb(), CID: 0x%04x Status: %d",
  325. p_ccb->local_cid, HCI_ERR_AUTH_FAILURE);
  326. /* If last channel immediately disconnect the ACL for better security.
  327. Also prevents a race condition between BTM and L2CAP */
  328. if ((p_ccb == p_ccb->p_lcb->ccb_queue.p_first_ccb) &&
  329. (p_ccb == p_ccb->p_lcb->ccb_queue.p_last_ccb)) {
  330. p_ccb->p_lcb->idle_timeout = 0;
  331. }
  332. l2cu_release_ccb(p_ccb);
  333. (*connect_cfm)(local_cid, HCI_ERR_AUTH_FAILURE);
  334. break;
  335. case L2CEVT_L2CA_DATA_WRITE: /* Upper layer data to send */
  336. case L2CEVT_L2CAP_DATA: /* Peer data packet rcvd */
  337. osi_free(p_data);
  338. break;
  339. case L2CEVT_L2CA_DISCONNECT_REQ: /* Upper wants to disconnect */
  340. /* Tell security manager to abort */
  341. btm_sec_abort_access_req(p_ccb->p_lcb->remote_bd_addr);
  342. l2cu_release_ccb(p_ccb);
  343. break;
  344. }
  345. }
  346. /*******************************************************************************
  347. *
  348. * Function l2c_csm_term_w4_sec_comp
  349. *
  350. * Description This function handles events when the channel is in
  351. * CST_TERM_W4_SEC_COMP state.
  352. *
  353. * Returns void
  354. *
  355. ******************************************************************************/
  356. static void l2c_csm_term_w4_sec_comp(tL2C_CCB* p_ccb, uint16_t event,
  357. void* p_data) {
  358. L2CAP_TRACE_EVENT("L2CAP - LCID: 0x%04x st: TERM_W4_SEC_COMP evt: %s",
  359. p_ccb->local_cid, l2c_csm_get_event_name(event));
  360. switch (event) {
  361. case L2CEVT_LP_DISCONNECT_IND: /* Link was disconnected */
  362. /* Tell security manager to abort */
  363. btm_sec_abort_access_req(p_ccb->p_lcb->remote_bd_addr);
  364. l2cu_release_ccb(p_ccb);
  365. break;
  366. case L2CEVT_SEC_COMP:
  367. p_ccb->chnl_state = CST_W4_L2CA_CONNECT_RSP;
  368. /* Wait for the info resp in next state before sending connect ind (if
  369. * needed) */
  370. if (!p_ccb->p_lcb->w4_info_rsp) {
  371. /* Don't need to get info from peer or already retrieved so continue */
  372. alarm_set_on_mloop(p_ccb->l2c_ccb_timer, L2CAP_CHNL_CONNECT_TIMEOUT_MS,
  373. l2c_ccb_timer_timeout, p_ccb);
  374. L2CAP_TRACE_API("L2CAP - Calling Connect_Ind_Cb(), CID: 0x%04x",
  375. p_ccb->local_cid);
  376. (*p_ccb->p_rcb->api.pL2CA_ConnectInd_Cb)(
  377. p_ccb->p_lcb->remote_bd_addr, p_ccb->local_cid, p_ccb->p_rcb->psm,
  378. p_ccb->remote_id);
  379. } else {
  380. /*
  381. ** L2CAP Connect Response will be sent out by 3 sec timer expiration
  382. ** because Bluesoleil doesn't respond to L2CAP Information Request.
  383. ** Bluesoleil seems to disconnect ACL link as failure case, because
  384. ** it takes too long (4~7secs) to get response.
  385. ** product version : Bluesoleil 2.1.1.0 EDR Release 060123
  386. ** stack version : 05.04.11.20060119
  387. */
  388. /* Waiting for the info resp, tell the peer to set a longer timer */
  389. l2cu_send_peer_connect_rsp(p_ccb, L2CAP_CONN_PENDING, 0);
  390. }
  391. break;
  392. case L2CEVT_SEC_COMP_NEG:
  393. if (((tL2C_CONN_INFO*)p_data)->status == BTM_DELAY_CHECK) {
  394. /* start a timer - encryption change not received before L2CAP connect
  395. * req */
  396. alarm_set_on_mloop(p_ccb->l2c_ccb_timer,
  397. L2CAP_DELAY_CHECK_SM4_TIMEOUT_MS,
  398. l2c_ccb_timer_timeout, p_ccb);
  399. } else {
  400. if (p_ccb->p_lcb->transport == BT_TRANSPORT_LE)
  401. l2cu_reject_ble_connection(
  402. p_ccb->p_lcb, p_ccb->remote_id,
  403. L2CAP_LE_RESULT_INSUFFICIENT_AUTHENTICATION);
  404. else
  405. l2cu_send_peer_connect_rsp(p_ccb, L2CAP_CONN_SECURITY_BLOCK, 0);
  406. l2cu_release_ccb(p_ccb);
  407. }
  408. break;
  409. case L2CEVT_L2CA_DATA_WRITE: /* Upper layer data to send */
  410. case L2CEVT_L2CAP_DATA: /* Peer data packet rcvd */
  411. osi_free(p_data);
  412. break;
  413. case L2CEVT_L2CA_DISCONNECT_REQ: /* Upper wants to disconnect */
  414. l2cu_release_ccb(p_ccb);
  415. break;
  416. case L2CEVT_L2CAP_DISCONNECT_REQ: /* Peer disconnected request */
  417. l2cu_send_peer_disc_rsp(p_ccb->p_lcb, p_ccb->remote_id, p_ccb->local_cid,
  418. p_ccb->remote_cid);
  419. /* Tell security manager to abort */
  420. btm_sec_abort_access_req(p_ccb->p_lcb->remote_bd_addr);
  421. l2cu_release_ccb(p_ccb);
  422. break;
  423. case L2CEVT_TIMEOUT:
  424. /* SM4 related. */
  425. btsnd_hcic_disconnect(p_ccb->p_lcb->handle, HCI_ERR_AUTH_FAILURE);
  426. break;
  427. case L2CEVT_SEC_RE_SEND_CMD: /* BTM has enough info to proceed */
  428. btm_sec_l2cap_access_req(p_ccb->p_lcb->remote_bd_addr, p_ccb->p_rcb->psm,
  429. p_ccb->p_lcb->handle, false, &l2c_link_sec_comp,
  430. p_ccb);
  431. break;
  432. }
  433. }
  434. /*******************************************************************************
  435. *
  436. * Function l2c_csm_w4_l2cap_connect_rsp
  437. *
  438. * Description This function handles events when the channel is in
  439. * CST_W4_L2CAP_CONNECT_RSP state.
  440. *
  441. * Returns void
  442. *
  443. ******************************************************************************/
  444. static void l2c_csm_w4_l2cap_connect_rsp(tL2C_CCB* p_ccb, uint16_t event,
  445. void* p_data) {
  446. tL2C_CONN_INFO* p_ci = (tL2C_CONN_INFO*)p_data;
  447. tL2CA_DISCONNECT_IND_CB* disconnect_ind =
  448. p_ccb->p_rcb->api.pL2CA_DisconnectInd_Cb;
  449. tL2CA_CONNECT_CFM_CB* connect_cfm = p_ccb->p_rcb->api.pL2CA_ConnectCfm_Cb;
  450. uint16_t local_cid = p_ccb->local_cid;
  451. L2CAP_TRACE_EVENT("L2CAP - LCID: 0x%04x st: W4_L2CAP_CON_RSP evt: %s",
  452. p_ccb->local_cid, l2c_csm_get_event_name(event));
  453. switch (event) {
  454. case L2CEVT_LP_DISCONNECT_IND: /* Link was disconnected */
  455. /* Send disc indication unless peer to peer race condition AND normal
  456. * disconnect */
  457. /* *((uint8_t *)p_data) != HCI_ERR_PEER_USER happens when peer device try
  458. * to disconnect for normal reason */
  459. p_ccb->chnl_state = CST_CLOSED;
  460. if ((p_ccb->flags & CCB_FLAG_NO_RETRY) || !p_data ||
  461. (*((uint8_t*)p_data) != HCI_ERR_PEER_USER)) {
  462. L2CAP_TRACE_API(
  463. "L2CAP - Calling Disconnect_Ind_Cb(), CID: 0x%04x No Conf Needed",
  464. p_ccb->local_cid);
  465. l2cu_release_ccb(p_ccb);
  466. (*disconnect_ind)(local_cid, false);
  467. }
  468. p_ccb->flags |= CCB_FLAG_NO_RETRY;
  469. break;
  470. case L2CEVT_L2CAP_CONNECT_RSP: /* Got peer connect confirm */
  471. p_ccb->remote_cid = p_ci->remote_cid;
  472. if (p_ccb->p_lcb->transport == BT_TRANSPORT_LE) {
  473. /* Connection is completed */
  474. alarm_cancel(p_ccb->l2c_ccb_timer);
  475. p_ccb->chnl_state = CST_OPEN;
  476. } else {
  477. p_ccb->chnl_state = CST_CONFIG;
  478. alarm_set_on_mloop(p_ccb->l2c_ccb_timer, L2CAP_CHNL_CFG_TIMEOUT_MS,
  479. l2c_ccb_timer_timeout, p_ccb);
  480. }
  481. L2CAP_TRACE_API("L2CAP - Calling Connect_Cfm_Cb(), CID: 0x%04x, Success",
  482. p_ccb->local_cid);
  483. (*p_ccb->p_rcb->api.pL2CA_ConnectCfm_Cb)(local_cid, L2CAP_CONN_OK);
  484. break;
  485. case L2CEVT_L2CAP_CONNECT_RSP_PND: /* Got peer connect pending */
  486. p_ccb->remote_cid = p_ci->remote_cid;
  487. alarm_set_on_mloop(p_ccb->l2c_ccb_timer,
  488. L2CAP_CHNL_CONNECT_EXT_TIMEOUT_MS,
  489. l2c_ccb_timer_timeout, p_ccb);
  490. if (p_ccb->p_rcb->api.pL2CA_ConnectPnd_Cb) {
  491. L2CAP_TRACE_API("L2CAP - Calling Connect_Pnd_Cb(), CID: 0x%04x",
  492. p_ccb->local_cid);
  493. (*p_ccb->p_rcb->api.pL2CA_ConnectPnd_Cb)(p_ccb->local_cid);
  494. }
  495. break;
  496. case L2CEVT_L2CAP_CONNECT_RSP_NEG: /* Peer rejected connection */
  497. LOG(WARNING) << __func__ << ": L2CAP connection rejected, lcid="
  498. << loghex(p_ccb->local_cid)
  499. << ", reason=" << loghex(p_ci->l2cap_result);
  500. l2cu_release_ccb(p_ccb);
  501. (*connect_cfm)(local_cid, p_ci->l2cap_result);
  502. break;
  503. case L2CEVT_TIMEOUT:
  504. LOG(WARNING) << __func__ << ": L2CAP connection timeout, lcid="
  505. << loghex(p_ccb->local_cid);
  506. l2cu_release_ccb(p_ccb);
  507. (*connect_cfm)(local_cid, L2CAP_CONN_TIMEOUT);
  508. break;
  509. case L2CEVT_L2CA_DISCONNECT_REQ: /* Upper wants to disconnect */
  510. /* If we know peer CID from connect pending, we can send disconnect */
  511. if (p_ccb->remote_cid != 0) {
  512. l2cu_send_peer_disc_req(p_ccb);
  513. p_ccb->chnl_state = CST_W4_L2CAP_DISCONNECT_RSP;
  514. alarm_set_on_mloop(p_ccb->l2c_ccb_timer,
  515. L2CAP_CHNL_DISCONNECT_TIMEOUT_MS,
  516. l2c_ccb_timer_timeout, p_ccb);
  517. } else {
  518. tL2CA_DISCONNECT_CFM_CB* disconnect_cfm =
  519. p_ccb->p_rcb->api.pL2CA_DisconnectCfm_Cb;
  520. l2cu_release_ccb(p_ccb);
  521. if (disconnect_cfm) {
  522. L2CAP_TRACE_API("%s: L2CAP - Calling DisconnectCfm_Cb(), CID: 0x%04x",
  523. __func__, local_cid);
  524. (*disconnect_cfm)(local_cid, L2CAP_CONN_NO_LINK);
  525. }
  526. }
  527. break;
  528. case L2CEVT_L2CA_DATA_WRITE: /* Upper layer data to send */
  529. case L2CEVT_L2CAP_DATA: /* Peer data packet rcvd */
  530. osi_free(p_data);
  531. break;
  532. case L2CEVT_L2CAP_INFO_RSP:
  533. /* Need to have at least one compatible channel to continue */
  534. if (!l2c_fcr_chk_chan_modes(p_ccb)) {
  535. l2cu_release_ccb(p_ccb);
  536. (*connect_cfm)(local_cid, L2CAP_CONN_NO_LINK);
  537. } else {
  538. /* We have feature info, so now send peer connect request */
  539. alarm_set_on_mloop(p_ccb->l2c_ccb_timer, L2CAP_CHNL_CONNECT_TIMEOUT_MS,
  540. l2c_ccb_timer_timeout, p_ccb);
  541. l2cu_send_peer_connect_req(p_ccb); /* Start Connection */
  542. }
  543. break;
  544. }
  545. }
  546. /*******************************************************************************
  547. *
  548. * Function l2c_csm_w4_l2ca_connect_rsp
  549. *
  550. * Description This function handles events when the channel is in
  551. * CST_W4_L2CA_CONNECT_RSP state.
  552. *
  553. * Returns void
  554. *
  555. ******************************************************************************/
  556. static void l2c_csm_w4_l2ca_connect_rsp(tL2C_CCB* p_ccb, uint16_t event,
  557. void* p_data) {
  558. tL2C_CONN_INFO* p_ci;
  559. tL2CA_DISCONNECT_IND_CB* disconnect_ind =
  560. p_ccb->p_rcb->api.pL2CA_DisconnectInd_Cb;
  561. uint16_t local_cid = p_ccb->local_cid;
  562. L2CAP_TRACE_EVENT("L2CAP - LCID: 0x%04x st: W4_L2CA_CON_RSP evt: %s",
  563. p_ccb->local_cid, l2c_csm_get_event_name(event));
  564. switch (event) {
  565. case L2CEVT_LP_DISCONNECT_IND: /* Link was disconnected */
  566. L2CAP_TRACE_API(
  567. "L2CAP - Calling Disconnect_Ind_Cb(), CID: 0x%04x No Conf Needed",
  568. p_ccb->local_cid);
  569. l2cu_release_ccb(p_ccb);
  570. (*disconnect_ind)(local_cid, false);
  571. break;
  572. case L2CEVT_L2CA_CONNECT_RSP:
  573. p_ci = (tL2C_CONN_INFO*)p_data;
  574. if (p_ccb->p_lcb->transport == BT_TRANSPORT_LE) {
  575. /* Result should be OK or Reject */
  576. if ((!p_ci) || (p_ci->l2cap_result == L2CAP_CONN_OK)) {
  577. l2cble_credit_based_conn_res(p_ccb, L2CAP_CONN_OK);
  578. p_ccb->chnl_state = CST_OPEN;
  579. alarm_cancel(p_ccb->l2c_ccb_timer);
  580. } else {
  581. l2cble_credit_based_conn_res(p_ccb, p_ci->l2cap_result);
  582. l2cu_release_ccb(p_ccb);
  583. }
  584. } else {
  585. /* Result should be OK or PENDING */
  586. if ((!p_ci) || (p_ci->l2cap_result == L2CAP_CONN_OK)) {
  587. l2cu_send_peer_connect_rsp(p_ccb, L2CAP_CONN_OK, 0);
  588. p_ccb->chnl_state = CST_CONFIG;
  589. alarm_set_on_mloop(p_ccb->l2c_ccb_timer, L2CAP_CHNL_CFG_TIMEOUT_MS,
  590. l2c_ccb_timer_timeout, p_ccb);
  591. } else {
  592. /* If pending, stay in same state and start extended timer */
  593. l2cu_send_peer_connect_rsp(p_ccb, p_ci->l2cap_result,
  594. p_ci->l2cap_status);
  595. alarm_set_on_mloop(p_ccb->l2c_ccb_timer,
  596. L2CAP_CHNL_CONNECT_EXT_TIMEOUT_MS,
  597. l2c_ccb_timer_timeout, p_ccb);
  598. }
  599. }
  600. break;
  601. case L2CEVT_L2CA_CONNECT_RSP_NEG:
  602. p_ci = (tL2C_CONN_INFO*)p_data;
  603. if (p_ccb->p_lcb->transport == BT_TRANSPORT_LE)
  604. l2cble_credit_based_conn_res(p_ccb, p_ci->l2cap_result);
  605. else
  606. l2cu_send_peer_connect_rsp(p_ccb, p_ci->l2cap_result,
  607. p_ci->l2cap_status);
  608. l2cu_release_ccb(p_ccb);
  609. break;
  610. case L2CEVT_TIMEOUT:
  611. l2cu_send_peer_connect_rsp(p_ccb, L2CAP_CONN_NO_PSM, 0);
  612. L2CAP_TRACE_API(
  613. "L2CAP - Calling Disconnect_Ind_Cb(), CID: 0x%04x No Conf Needed",
  614. p_ccb->local_cid);
  615. l2cu_release_ccb(p_ccb);
  616. (*disconnect_ind)(local_cid, false);
  617. break;
  618. case L2CEVT_L2CA_DATA_WRITE: /* Upper layer data to send */
  619. case L2CEVT_L2CAP_DATA: /* Peer data packet rcvd */
  620. osi_free(p_data);
  621. break;
  622. case L2CEVT_L2CA_DISCONNECT_REQ: /* Upper wants to disconnect */
  623. l2cu_send_peer_disc_req(p_ccb);
  624. p_ccb->chnl_state = CST_W4_L2CAP_DISCONNECT_RSP;
  625. alarm_set_on_mloop(p_ccb->l2c_ccb_timer, L2CAP_CHNL_DISCONNECT_TIMEOUT_MS,
  626. l2c_ccb_timer_timeout, p_ccb);
  627. break;
  628. case L2CEVT_L2CAP_INFO_RSP:
  629. /* We have feature info, so now give the upper layer connect IND */
  630. alarm_set_on_mloop(p_ccb->l2c_ccb_timer, L2CAP_CHNL_CONNECT_TIMEOUT_MS,
  631. l2c_ccb_timer_timeout, p_ccb);
  632. L2CAP_TRACE_API("L2CAP - Calling Connect_Ind_Cb(), CID: 0x%04x",
  633. p_ccb->local_cid);
  634. (*p_ccb->p_rcb->api.pL2CA_ConnectInd_Cb)(
  635. p_ccb->p_lcb->remote_bd_addr, p_ccb->local_cid, p_ccb->p_rcb->psm,
  636. p_ccb->remote_id);
  637. break;
  638. }
  639. }
  640. /*******************************************************************************
  641. *
  642. * Function l2c_csm_config
  643. *
  644. * Description This function handles events when the channel is in
  645. * CONFIG state.
  646. *
  647. * Returns void
  648. *
  649. ******************************************************************************/
  650. static void l2c_csm_config(tL2C_CCB* p_ccb, uint16_t event, void* p_data) {
  651. tL2CAP_CFG_INFO* p_cfg = (tL2CAP_CFG_INFO*)p_data;
  652. tL2CA_DISCONNECT_IND_CB* disconnect_ind =
  653. p_ccb->p_rcb->api.pL2CA_DisconnectInd_Cb;
  654. uint16_t local_cid = p_ccb->local_cid;
  655. uint8_t cfg_result;
  656. L2CAP_TRACE_EVENT("L2CAP - LCID: 0x%04x st: CONFIG evt: %s",
  657. p_ccb->local_cid, l2c_csm_get_event_name(event));
  658. switch (event) {
  659. case L2CEVT_LP_DISCONNECT_IND: /* Link was disconnected */
  660. L2CAP_TRACE_API(
  661. "L2CAP - Calling Disconnect_Ind_Cb(), CID: 0x%04x No Conf Needed",
  662. p_ccb->local_cid);
  663. l2cu_release_ccb(p_ccb);
  664. (*disconnect_ind)(local_cid, false);
  665. break;
  666. case L2CEVT_L2CAP_CONFIG_REQ: /* Peer config request */
  667. cfg_result = l2cu_process_peer_cfg_req(p_ccb, p_cfg);
  668. if (cfg_result == L2CAP_PEER_CFG_OK) {
  669. L2CAP_TRACE_EVENT(
  670. "L2CAP - Calling Config_Req_Cb(), CID: 0x%04x, C-bit %d",
  671. p_ccb->local_cid, (p_cfg->flags & L2CAP_CFG_FLAGS_MASK_CONT));
  672. (*p_ccb->p_rcb->api.pL2CA_ConfigInd_Cb)(p_ccb->local_cid, p_cfg);
  673. } else if (cfg_result == L2CAP_PEER_CFG_DISCONNECT) {
  674. /* Disconnect if channels are incompatible */
  675. L2CAP_TRACE_EVENT("L2CAP - incompatible configurations disconnect");
  676. l2cu_disconnect_chnl(p_ccb);
  677. } else /* Return error to peer so he can renegotiate if possible */
  678. {
  679. L2CAP_TRACE_EVENT(
  680. "L2CAP - incompatible configurations trying reconfig");
  681. l2cu_send_peer_config_rsp(p_ccb, p_cfg);
  682. }
  683. break;
  684. case L2CEVT_L2CAP_CONFIG_RSP: /* Peer config response */
  685. l2cu_process_peer_cfg_rsp(p_ccb, p_cfg);
  686. if (p_cfg->result != L2CAP_CFG_PENDING) {
  687. /* TBD: When config options grow beyong minimum MTU (48 bytes)
  688. * logic needs to be added to handle responses with
  689. * continuation bit set in flags field.
  690. * 1. Send additional config request out until C-bit is cleared in
  691. * response
  692. */
  693. p_ccb->config_done |= OB_CFG_DONE;
  694. if (p_ccb->config_done & IB_CFG_DONE) {
  695. /* Verify two sides are in compatible modes before continuing */
  696. if (p_ccb->our_cfg.fcr.mode != p_ccb->peer_cfg.fcr.mode) {
  697. l2cu_send_peer_disc_req(p_ccb);
  698. L2CAP_TRACE_WARNING(
  699. "L2CAP - Calling Disconnect_Ind_Cb(Incompatible CFG), CID: "
  700. "0x%04x No Conf Needed",
  701. p_ccb->local_cid);
  702. l2cu_release_ccb(p_ccb);
  703. (*disconnect_ind)(local_cid, false);
  704. break;
  705. }
  706. p_ccb->config_done |= RECONFIG_FLAG;
  707. p_ccb->chnl_state = CST_OPEN;
  708. l2c_link_adjust_chnl_allocation();
  709. alarm_cancel(p_ccb->l2c_ccb_timer);
  710. /* If using eRTM and waiting for an ACK, restart the ACK timer */
  711. if (p_ccb->fcrb.wait_ack) l2c_fcr_start_timer(p_ccb);
  712. /*
  713. ** check p_ccb->our_cfg.fcr.mon_tout and
  714. *p_ccb->our_cfg.fcr.rtrans_tout
  715. ** we may set them to zero when sending config request during
  716. *renegotiation
  717. */
  718. if ((p_ccb->our_cfg.fcr.mode == L2CAP_FCR_ERTM_MODE) &&
  719. ((p_ccb->our_cfg.fcr.mon_tout == 0) ||
  720. (p_ccb->our_cfg.fcr.rtrans_tout))) {
  721. l2c_fcr_adj_monitor_retran_timeout(p_ccb);
  722. }
  723. #if (L2CAP_ERTM_STATS == TRUE)
  724. p_ccb->fcrb.connect_tick_count =
  725. bluetooth::common::time_get_os_boottime_ms();
  726. #endif
  727. /* See if we can forward anything on the hold queue */
  728. if (!fixed_queue_is_empty(p_ccb->xmit_hold_q)) {
  729. l2c_link_check_send_pkts(p_ccb->p_lcb, NULL, NULL);
  730. }
  731. }
  732. }
  733. L2CAP_TRACE_API("L2CAP - Calling Config_Rsp_Cb(), CID: 0x%04x",
  734. p_ccb->local_cid);
  735. (*p_ccb->p_rcb->api.pL2CA_ConfigCfm_Cb)(p_ccb->local_cid, p_cfg);
  736. break;
  737. case L2CEVT_L2CAP_CONFIG_RSP_NEG: /* Peer config error rsp */
  738. /* Disable the Timer */
  739. alarm_cancel(p_ccb->l2c_ccb_timer);
  740. /* If failure was channel mode try to renegotiate */
  741. if (!l2c_fcr_renegotiate_chan(p_ccb, p_cfg)) {
  742. L2CAP_TRACE_API(
  743. "L2CAP - Calling Config_Rsp_Cb(), CID: 0x%04x, Failure: %d",
  744. p_ccb->local_cid, p_cfg->result);
  745. (*p_ccb->p_rcb->api.pL2CA_ConfigCfm_Cb)(p_ccb->local_cid, p_cfg);
  746. }
  747. break;
  748. case L2CEVT_L2CAP_DISCONNECT_REQ: /* Peer disconnected request */
  749. alarm_set_on_mloop(p_ccb->l2c_ccb_timer, L2CAP_CHNL_DISCONNECT_TIMEOUT_MS,
  750. l2c_ccb_timer_timeout, p_ccb);
  751. p_ccb->chnl_state = CST_W4_L2CA_DISCONNECT_RSP;
  752. L2CAP_TRACE_API(
  753. "L2CAP - Calling Disconnect_Ind_Cb(), CID: 0x%04x Conf Needed",
  754. p_ccb->local_cid);
  755. (*p_ccb->p_rcb->api.pL2CA_DisconnectInd_Cb)(p_ccb->local_cid, true);
  756. break;
  757. case L2CEVT_L2CA_CONFIG_REQ: /* Upper layer config req */
  758. l2cu_process_our_cfg_req(p_ccb, p_cfg);
  759. l2cu_send_peer_config_req(p_ccb, p_cfg);
  760. alarm_set_on_mloop(p_ccb->l2c_ccb_timer, L2CAP_CHNL_CFG_TIMEOUT_MS,
  761. l2c_ccb_timer_timeout, p_ccb);
  762. break;
  763. case L2CEVT_L2CA_CONFIG_RSP: /* Upper layer config rsp */
  764. l2cu_process_our_cfg_rsp(p_ccb, p_cfg);
  765. /* Not finished if continuation flag is set */
  766. if ((p_cfg->flags & L2CAP_CFG_FLAGS_MASK_CONT) ||
  767. (p_cfg->result == L2CAP_CFG_PENDING)) {
  768. /* Send intermediate response; remain in cfg state */
  769. l2cu_send_peer_config_rsp(p_ccb, p_cfg);
  770. break;
  771. }
  772. /* Local config done; clear cached configuration in case reconfig takes
  773. * place later */
  774. p_ccb->peer_cfg.mtu_present = false;
  775. p_ccb->peer_cfg.flush_to_present = false;
  776. p_ccb->peer_cfg.qos_present = false;
  777. p_ccb->config_done |= IB_CFG_DONE;
  778. if (p_ccb->config_done & OB_CFG_DONE) {
  779. /* Verify two sides are in compatible modes before continuing */
  780. if (p_ccb->our_cfg.fcr.mode != p_ccb->peer_cfg.fcr.mode) {
  781. l2cu_send_peer_disc_req(p_ccb);
  782. L2CAP_TRACE_WARNING(
  783. "L2CAP - Calling Disconnect_Ind_Cb(Incompatible CFG), CID: "
  784. "0x%04x No Conf Needed",
  785. p_ccb->local_cid);
  786. l2cu_release_ccb(p_ccb);
  787. (*disconnect_ind)(local_cid, false);
  788. break;
  789. }
  790. p_ccb->config_done |= RECONFIG_FLAG;
  791. p_ccb->chnl_state = CST_OPEN;
  792. l2c_link_adjust_chnl_allocation();
  793. alarm_cancel(p_ccb->l2c_ccb_timer);
  794. }
  795. l2cu_send_peer_config_rsp(p_ccb, p_cfg);
  796. /* If using eRTM and waiting for an ACK, restart the ACK timer */
  797. if (p_ccb->fcrb.wait_ack) l2c_fcr_start_timer(p_ccb);
  798. #if (L2CAP_ERTM_STATS == TRUE)
  799. p_ccb->fcrb.connect_tick_count =
  800. bluetooth::common::time_get_os_boottime_ms();
  801. #endif
  802. /* See if we can forward anything on the hold queue */
  803. if ((p_ccb->chnl_state == CST_OPEN) &&
  804. (!fixed_queue_is_empty(p_ccb->xmit_hold_q))) {
  805. l2c_link_check_send_pkts(p_ccb->p_lcb, NULL, NULL);
  806. }
  807. break;
  808. case L2CEVT_L2CA_CONFIG_RSP_NEG: /* Upper layer config reject */
  809. l2cu_send_peer_config_rsp(p_ccb, p_cfg);
  810. alarm_set_on_mloop(p_ccb->l2c_ccb_timer, L2CAP_CHNL_CFG_TIMEOUT_MS,
  811. l2c_ccb_timer_timeout, p_ccb);
  812. break;
  813. case L2CEVT_L2CA_DISCONNECT_REQ: /* Upper wants to disconnect */
  814. l2cu_send_peer_disc_req(p_ccb);
  815. p_ccb->chnl_state = CST_W4_L2CAP_DISCONNECT_RSP;
  816. alarm_set_on_mloop(p_ccb->l2c_ccb_timer, L2CAP_CHNL_DISCONNECT_TIMEOUT_MS,
  817. l2c_ccb_timer_timeout, p_ccb);
  818. break;
  819. case L2CEVT_L2CAP_DATA: /* Peer data packet rcvd */
  820. L2CAP_TRACE_API("L2CAP - Calling DataInd_Cb(), CID: 0x%04x",
  821. p_ccb->local_cid);
  822. #if (L2CAP_NUM_FIXED_CHNLS > 0)
  823. if (p_ccb->local_cid >= L2CAP_FIRST_FIXED_CHNL &&
  824. p_ccb->local_cid <= L2CAP_LAST_FIXED_CHNL) {
  825. if (p_ccb->local_cid < L2CAP_BASE_APPL_CID) {
  826. if (l2cb.fixed_reg[p_ccb->local_cid - L2CAP_FIRST_FIXED_CHNL]
  827. .pL2CA_FixedData_Cb)
  828. (*l2cb.fixed_reg[p_ccb->local_cid - L2CAP_FIRST_FIXED_CHNL]
  829. .pL2CA_FixedData_Cb)(p_ccb->local_cid,
  830. p_ccb->p_lcb->remote_bd_addr,
  831. (BT_HDR*)p_data);
  832. else
  833. osi_free(p_data);
  834. break;
  835. }
  836. }
  837. #endif
  838. (*p_ccb->p_rcb->api.pL2CA_DataInd_Cb)(p_ccb->local_cid, (BT_HDR*)p_data);
  839. break;
  840. case L2CEVT_L2CA_DATA_WRITE: /* Upper layer data to send */
  841. if (p_ccb->config_done & OB_CFG_DONE)
  842. l2c_enqueue_peer_data(p_ccb, (BT_HDR*)p_data);
  843. else
  844. osi_free(p_data);
  845. break;
  846. case L2CEVT_TIMEOUT:
  847. l2cu_send_peer_disc_req(p_ccb);
  848. L2CAP_TRACE_API(
  849. "L2CAP - Calling Disconnect_Ind_Cb(), CID: 0x%04x No Conf Needed",
  850. p_ccb->local_cid);
  851. l2cu_release_ccb(p_ccb);
  852. (*disconnect_ind)(local_cid, false);
  853. break;
  854. }
  855. }
  856. /*******************************************************************************
  857. *
  858. * Function l2c_csm_open
  859. *
  860. * Description This function handles events when the channel is in
  861. * OPEN state.
  862. *
  863. * Returns void
  864. *
  865. ******************************************************************************/
  866. static void l2c_csm_open(tL2C_CCB* p_ccb, uint16_t event, void* p_data) {
  867. uint16_t local_cid = p_ccb->local_cid;
  868. tL2CAP_CFG_INFO* p_cfg;
  869. tL2C_CHNL_STATE tempstate;
  870. uint8_t tempcfgdone;
  871. uint8_t cfg_result;
  872. uint16_t* credit;
  873. L2CAP_TRACE_EVENT("L2CAP - LCID: 0x%04x st: OPEN evt: %s", p_ccb->local_cid,
  874. l2c_csm_get_event_name(event));
  875. switch (event) {
  876. case L2CEVT_LP_DISCONNECT_IND: /* Link was disconnected */
  877. L2CAP_TRACE_API(
  878. "L2CAP - Calling Disconnect_Ind_Cb(), CID: 0x%04x No Conf Needed",
  879. p_ccb->local_cid);
  880. l2cu_release_ccb(p_ccb);
  881. if (p_ccb->p_rcb)
  882. (*p_ccb->p_rcb->api.pL2CA_DisconnectInd_Cb)(local_cid, false);
  883. break;
  884. case L2CEVT_LP_QOS_VIOLATION_IND: /* QOS violation */
  885. /* Tell upper layer. If service guaranteed, then clear the channel */
  886. if (p_ccb->p_rcb->api.pL2CA_QoSViolationInd_Cb)
  887. (*p_ccb->p_rcb->api.pL2CA_QoSViolationInd_Cb)(
  888. p_ccb->p_lcb->remote_bd_addr);
  889. break;
  890. case L2CEVT_L2CAP_CONFIG_REQ: /* Peer config request */
  891. p_cfg = (tL2CAP_CFG_INFO*)p_data;
  892. tempstate = p_ccb->chnl_state;
  893. tempcfgdone = p_ccb->config_done;
  894. p_ccb->chnl_state = CST_CONFIG;
  895. p_ccb->config_done &= ~IB_CFG_DONE;
  896. alarm_set_on_mloop(p_ccb->l2c_ccb_timer, L2CAP_CHNL_CFG_TIMEOUT_MS,
  897. l2c_ccb_timer_timeout, p_ccb);
  898. cfg_result = l2cu_process_peer_cfg_req(p_ccb, p_cfg);
  899. if (cfg_result == L2CAP_PEER_CFG_OK) {
  900. (*p_ccb->p_rcb->api.pL2CA_ConfigInd_Cb)(p_ccb->local_cid, p_cfg);
  901. }
  902. /* Error in config parameters: reset state and config flag */
  903. else if (cfg_result == L2CAP_PEER_CFG_UNACCEPTABLE) {
  904. alarm_cancel(p_ccb->l2c_ccb_timer);
  905. p_ccb->chnl_state = tempstate;
  906. p_ccb->config_done = tempcfgdone;
  907. l2cu_send_peer_config_rsp(p_ccb, p_cfg);
  908. } else /* L2CAP_PEER_CFG_DISCONNECT */
  909. {
  910. /* Disconnect if channels are incompatible
  911. * Note this should not occur if reconfigure
  912. * since this should have never passed original config.
  913. */
  914. l2cu_disconnect_chnl(p_ccb);
  915. }
  916. break;
  917. case L2CEVT_L2CAP_DISCONNECT_REQ: /* Peer disconnected request */
  918. if (p_ccb->p_lcb->transport != BT_TRANSPORT_LE) {
  919. /* Make sure we are not in sniff mode */
  920. {
  921. tBTM_PM_PWR_MD settings;
  922. memset((void*)&settings, 0, sizeof(settings));
  923. settings.mode = BTM_PM_MD_ACTIVE;
  924. BTM_SetPowerMode(BTM_PM_SET_ONLY_ID, p_ccb->p_lcb->remote_bd_addr,
  925. &settings);
  926. }
  927. }
  928. p_ccb->chnl_state = CST_W4_L2CA_DISCONNECT_RSP;
  929. alarm_set_on_mloop(p_ccb->l2c_ccb_timer, L2CAP_CHNL_DISCONNECT_TIMEOUT_MS,
  930. l2c_ccb_timer_timeout, p_ccb);
  931. L2CAP_TRACE_API(
  932. "L2CAP - Calling Disconnect_Ind_Cb(), CID: 0x%04x Conf Needed",
  933. p_ccb->local_cid);
  934. (*p_ccb->p_rcb->api.pL2CA_DisconnectInd_Cb)(p_ccb->local_cid, true);
  935. break;
  936. case L2CEVT_L2CAP_DATA: /* Peer data packet rcvd */
  937. if ((p_ccb->p_rcb) && (p_ccb->p_rcb->api.pL2CA_DataInd_Cb))
  938. (*p_ccb->p_rcb->api.pL2CA_DataInd_Cb)(p_ccb->local_cid,
  939. (BT_HDR*)p_data);
  940. break;
  941. case L2CEVT_L2CA_DISCONNECT_REQ: /* Upper wants to disconnect */
  942. if (p_ccb->p_lcb->transport != BT_TRANSPORT_LE) {
  943. /* Make sure we are not in sniff mode */
  944. {
  945. tBTM_PM_PWR_MD settings;
  946. memset((void*)&settings, 0, sizeof(settings));
  947. settings.mode = BTM_PM_MD_ACTIVE;
  948. BTM_SetPowerMode(BTM_PM_SET_ONLY_ID, p_ccb->p_lcb->remote_bd_addr,
  949. &settings);
  950. }
  951. }
  952. if (p_ccb->p_lcb->transport == BT_TRANSPORT_LE)
  953. l2cble_send_peer_disc_req(p_ccb);
  954. else
  955. l2cu_send_peer_disc_req(p_ccb);
  956. p_ccb->chnl_state = CST_W4_L2CAP_DISCONNECT_RSP;
  957. alarm_set_on_mloop(p_ccb->l2c_ccb_timer, L2CAP_CHNL_DISCONNECT_TIMEOUT_MS,
  958. l2c_ccb_timer_timeout, p_ccb);
  959. break;
  960. case L2CEVT_L2CA_DATA_WRITE: /* Upper layer data to send */
  961. l2c_enqueue_peer_data(p_ccb, (BT_HDR*)p_data);
  962. l2c_link_check_send_pkts(p_ccb->p_lcb, NULL, NULL);
  963. break;
  964. case L2CEVT_L2CA_CONFIG_REQ: /* Upper layer config req */
  965. p_ccb->chnl_state = CST_CONFIG;
  966. p_ccb->config_done &= ~CFG_DONE_MASK;
  967. l2cu_process_our_cfg_req(p_ccb, (tL2CAP_CFG_INFO*)p_data);
  968. l2cu_send_peer_config_req(p_ccb, (tL2CAP_CFG_INFO*)p_data);
  969. alarm_set_on_mloop(p_ccb->l2c_ccb_timer, L2CAP_CHNL_CFG_TIMEOUT_MS,
  970. l2c_ccb_timer_timeout, p_ccb);
  971. break;
  972. case L2CEVT_TIMEOUT:
  973. /* Process the monitor/retransmission time-outs in flow control/retrans
  974. * mode */
  975. if (p_ccb->peer_cfg.fcr.mode == L2CAP_FCR_ERTM_MODE)
  976. l2c_fcr_proc_tout(p_ccb);
  977. break;
  978. case L2CEVT_ACK_TIMEOUT:
  979. l2c_fcr_proc_ack_tout(p_ccb);
  980. break;
  981. case L2CEVT_L2CA_SEND_FLOW_CONTROL_CREDIT:
  982. L2CAP_TRACE_DEBUG("%s Sending credit", __func__);
  983. credit = (uint16_t*)p_data;
  984. l2cble_send_flow_control_credit(p_ccb, *credit);
  985. break;
  986. case L2CEVT_L2CAP_RECV_FLOW_CONTROL_CREDIT:
  987. credit = (uint16_t*)p_data;
  988. L2CAP_TRACE_DEBUG("%s Credits received %d", __func__, *credit);
  989. if ((p_ccb->peer_conn_cfg.credits + *credit) > L2CAP_LE_CREDIT_MAX) {
  990. /* we have received credits more than max coc credits,
  991. * so disconnecting the Le Coc Channel
  992. */
  993. l2cble_send_peer_disc_req(p_ccb);
  994. } else {
  995. p_ccb->peer_conn_cfg.credits += *credit;
  996. tL2CA_CREDITS_RECEIVED_CB* cr_cb =
  997. p_ccb->p_rcb->api.pL2CA_CreditsReceived_Cb;
  998. if (p_ccb->p_lcb->transport == BT_TRANSPORT_LE && (cr_cb)) {
  999. (*cr_cb)(p_ccb->local_cid, *credit, p_ccb->peer_conn_cfg.credits);
  1000. }
  1001. l2c_link_check_send_pkts(p_ccb->p_lcb, NULL, NULL);
  1002. }
  1003. break;
  1004. }
  1005. }
  1006. /*******************************************************************************
  1007. *
  1008. * Function l2c_csm_w4_l2cap_disconnect_rsp
  1009. *
  1010. * Description This function handles events when the channel is in
  1011. * CST_W4_L2CAP_DISCONNECT_RSP state.
  1012. *
  1013. * Returns void
  1014. *
  1015. ******************************************************************************/
  1016. static void l2c_csm_w4_l2cap_disconnect_rsp(tL2C_CCB* p_ccb, uint16_t event,
  1017. void* p_data) {
  1018. tL2CA_DISCONNECT_CFM_CB* disconnect_cfm =
  1019. p_ccb->p_rcb->api.pL2CA_DisconnectCfm_Cb;
  1020. uint16_t local_cid = p_ccb->local_cid;
  1021. L2CAP_TRACE_EVENT("L2CAP - LCID: 0x%04x st: W4_L2CAP_DISC_RSP evt: %s",
  1022. p_ccb->local_cid, l2c_csm_get_event_name(event));
  1023. switch (event) {
  1024. case L2CEVT_L2CAP_DISCONNECT_RSP: /* Peer disconnect response */
  1025. l2cu_release_ccb(p_ccb);
  1026. if (disconnect_cfm) {
  1027. L2CAP_TRACE_API("L2CAP - Calling DisconnectCfm_Cb(), CID: 0x%04x",
  1028. local_cid);
  1029. (*disconnect_cfm)(local_cid, L2CAP_DISC_OK);
  1030. }
  1031. break;
  1032. case L2CEVT_L2CAP_DISCONNECT_REQ: /* Peer disconnect request */
  1033. l2cu_send_peer_disc_rsp(p_ccb->p_lcb, p_ccb->remote_id, p_ccb->local_cid,
  1034. p_ccb->remote_cid);
  1035. l2cu_release_ccb(p_ccb);
  1036. if (disconnect_cfm) {
  1037. L2CAP_TRACE_API("L2CAP - Calling DisconnectCfm_Cb(), CID: 0x%04x",
  1038. local_cid);
  1039. (*disconnect_cfm)(local_cid, L2CAP_DISC_OK);
  1040. }
  1041. break;
  1042. case L2CEVT_LP_DISCONNECT_IND: /* Link was disconnected */
  1043. case L2CEVT_TIMEOUT: /* Timeout */
  1044. l2cu_release_ccb(p_ccb);
  1045. if (disconnect_cfm) {
  1046. L2CAP_TRACE_API("L2CAP - Calling DisconnectCfm_Cb(), CID: 0x%04x",
  1047. local_cid);
  1048. (*disconnect_cfm)(local_cid, L2CAP_DISC_TIMEOUT);
  1049. }
  1050. break;
  1051. case L2CEVT_L2CAP_DATA: /* Peer data packet rcvd */
  1052. case L2CEVT_L2CA_DATA_WRITE: /* Upper layer data to send */
  1053. osi_free(p_data);
  1054. break;
  1055. }
  1056. }
  1057. /*******************************************************************************
  1058. *
  1059. * Function l2c_csm_w4_l2ca_disconnect_rsp
  1060. *
  1061. * Description This function handles events when the channel is in
  1062. * CST_W4_L2CA_DISCONNECT_RSP state.
  1063. *
  1064. * Returns void
  1065. *
  1066. ******************************************************************************/
  1067. static void l2c_csm_w4_l2ca_disconnect_rsp(tL2C_CCB* p_ccb, uint16_t event,
  1068. void* p_data) {
  1069. tL2CA_DISCONNECT_IND_CB* disconnect_ind =
  1070. p_ccb->p_rcb->api.pL2CA_DisconnectInd_Cb;
  1071. uint16_t local_cid = p_ccb->local_cid;
  1072. L2CAP_TRACE_EVENT("L2CAP - LCID: 0x%04x st: W4_L2CA_DISC_RSP evt: %s",
  1073. p_ccb->local_cid, l2c_csm_get_event_name(event));
  1074. switch (event) {
  1075. case L2CEVT_LP_DISCONNECT_IND: /* Link was disconnected */
  1076. L2CAP_TRACE_API(
  1077. "L2CAP - Calling Disconnect_Ind_Cb(), CID: 0x%04x No Conf Needed",
  1078. p_ccb->local_cid);
  1079. l2cu_release_ccb(p_ccb);
  1080. (*disconnect_ind)(local_cid, false);
  1081. break;
  1082. case L2CEVT_TIMEOUT:
  1083. l2cu_send_peer_disc_rsp(p_ccb->p_lcb, p_ccb->remote_id, p_ccb->local_cid,
  1084. p_ccb->remote_cid);
  1085. L2CAP_TRACE_API(
  1086. "L2CAP - Calling Disconnect_Ind_Cb(), CID: 0x%04x No Conf Needed",
  1087. p_ccb->local_cid);
  1088. l2cu_release_ccb(p_ccb);
  1089. (*disconnect_ind)(local_cid, false);
  1090. break;
  1091. case L2CEVT_L2CA_DISCONNECT_REQ: /* Upper disconnect request */
  1092. case L2CEVT_L2CA_DISCONNECT_RSP: /* Upper disconnect response */
  1093. l2cu_send_peer_disc_rsp(p_ccb->p_lcb, p_ccb->remote_id, p_ccb->local_cid,
  1094. p_ccb->remote_cid);
  1095. l2cu_release_ccb(p_ccb);
  1096. break;
  1097. case L2CEVT_L2CAP_DATA: /* Peer data packet rcvd */
  1098. case L2CEVT_L2CA_DATA_WRITE: /* Upper layer data to send */
  1099. osi_free(p_data);
  1100. break;
  1101. }
  1102. }
  1103. /*******************************************************************************
  1104. *
  1105. * Function l2c_csm_get_event_name
  1106. *
  1107. * Description This function returns the event name.
  1108. *
  1109. * NOTE conditionally compiled to save memory.
  1110. *
  1111. * Returns pointer to the name
  1112. *
  1113. ******************************************************************************/
  1114. static const char* l2c_csm_get_event_name(uint16_t event) {
  1115. switch (event) {
  1116. case L2CEVT_LP_CONNECT_CFM: /* Lower layer connect confirm */
  1117. return ("LOWER_LAYER_CONNECT_CFM");
  1118. case L2CEVT_LP_CONNECT_CFM_NEG: /* Lower layer connect confirm (failed) */
  1119. return ("LOWER_LAYER_CONNECT_CFM_NEG");
  1120. case L2CEVT_LP_CONNECT_IND: /* Lower layer connect indication */
  1121. return ("LOWER_LAYER_CONNECT_IND");
  1122. case L2CEVT_LP_DISCONNECT_IND: /* Lower layer disconnect indication */
  1123. return ("LOWER_LAYER_DISCONNECT_IND");
  1124. case L2CEVT_LP_QOS_CFM: /* Lower layer QOS confirmation */
  1125. return ("LOWER_LAYER_QOS_CFM");
  1126. case L2CEVT_LP_QOS_CFM_NEG: /* Lower layer QOS confirmation (failed)*/
  1127. return ("LOWER_LAYER_QOS_CFM_NEG");
  1128. case L2CEVT_LP_QOS_VIOLATION_IND: /* Lower layer QOS violation indication */
  1129. return ("LOWER_LAYER_QOS_VIOLATION_IND");
  1130. case L2CEVT_SEC_COMP: /* Security cleared successfully */
  1131. return ("SECURITY_COMPLETE");
  1132. case L2CEVT_SEC_COMP_NEG: /* Security procedure failed */
  1133. return ("SECURITY_COMPLETE_NEG");
  1134. case L2CEVT_L2CAP_CONNECT_REQ: /* Peer connection request */
  1135. return ("PEER_CONNECT_REQ");
  1136. case L2CEVT_L2CAP_CONNECT_RSP: /* Peer connection response */
  1137. return ("PEER_CONNECT_RSP");
  1138. case L2CEVT_L2CAP_CONNECT_RSP_PND: /* Peer connection response pending */
  1139. return ("PEER_CONNECT_RSP_PND");
  1140. case L2CEVT_L2CAP_CONNECT_RSP_NEG: /* Peer connection response (failed) */
  1141. return ("PEER_CONNECT_RSP_NEG");
  1142. case L2CEVT_L2CAP_CONFIG_REQ: /* Peer configuration request */
  1143. return ("PEER_CONFIG_REQ");
  1144. case L2CEVT_L2CAP_CONFIG_RSP: /* Peer configuration response */
  1145. return ("PEER_CONFIG_RSP");
  1146. case L2CEVT_L2CAP_CONFIG_RSP_NEG: /* Peer configuration response (failed) */
  1147. return ("PEER_CONFIG_RSP_NEG");
  1148. case L2CEVT_L2CAP_DISCONNECT_REQ: /* Peer disconnect request */
  1149. return ("PEER_DISCONNECT_REQ");
  1150. case L2CEVT_L2CAP_DISCONNECT_RSP: /* Peer disconnect response */
  1151. return ("PEER_DISCONNECT_RSP");
  1152. case L2CEVT_L2CAP_DATA: /* Peer data */
  1153. return ("PEER_DATA");
  1154. case L2CEVT_L2CA_CONNECT_REQ: /* Upper layer connect request */
  1155. return ("UPPER_LAYER_CONNECT_REQ");
  1156. case L2CEVT_L2CA_CONNECT_RSP: /* Upper layer connect response */
  1157. return ("UPPER_LAYER_CONNECT_RSP");
  1158. case L2CEVT_L2CA_CONNECT_RSP_NEG: /* Upper layer connect response (failed)*/
  1159. return ("UPPER_LAYER_CONNECT_RSP_NEG");
  1160. case L2CEVT_L2CA_CONFIG_REQ: /* Upper layer config request */
  1161. return ("UPPER_LAYER_CONFIG_REQ");
  1162. case L2CEVT_L2CA_CONFIG_RSP: /* Upper layer config response */
  1163. return ("UPPER_LAYER_CONFIG_RSP");
  1164. case L2CEVT_L2CA_CONFIG_RSP_NEG: /* Upper layer config response (failed) */
  1165. return ("UPPER_LAYER_CONFIG_RSP_NEG");
  1166. case L2CEVT_L2CA_DISCONNECT_REQ: /* Upper layer disconnect request */
  1167. return ("UPPER_LAYER_DISCONNECT_REQ");
  1168. case L2CEVT_L2CA_DISCONNECT_RSP: /* Upper layer disconnect response */
  1169. return ("UPPER_LAYER_DISCONNECT_RSP");
  1170. case L2CEVT_L2CA_DATA_READ: /* Upper layer data read */
  1171. return ("UPPER_LAYER_DATA_READ");
  1172. case L2CEVT_L2CA_DATA_WRITE: /* Upper layer data write */
  1173. return ("UPPER_LAYER_DATA_WRITE");
  1174. case L2CEVT_TIMEOUT: /* Timeout */
  1175. return ("TIMEOUT");
  1176. case L2CEVT_SEC_RE_SEND_CMD:
  1177. return ("SEC_RE_SEND_CMD");
  1178. case L2CEVT_L2CAP_INFO_RSP: /* Peer information response */
  1179. return ("L2CEVT_L2CAP_INFO_RSP");
  1180. case L2CEVT_ACK_TIMEOUT:
  1181. return ("L2CEVT_ACK_TIMEOUT");
  1182. case L2CEVT_L2CA_SEND_FLOW_CONTROL_CREDIT: /* Upper layer send credit packet
  1183. */
  1184. return ("SEND_FLOW_CONTROL_CREDIT");
  1185. case L2CEVT_L2CAP_RECV_FLOW_CONTROL_CREDIT: /* Peer send credit packet */
  1186. return ("RECV_FLOW_CONTROL_CREDIT");
  1187. default:
  1188. return ("???? UNKNOWN EVENT");
  1189. }
  1190. }
  1191. /*******************************************************************************
  1192. *
  1193. * Function l2c_enqueue_peer_data
  1194. *
  1195. * Description Enqueues data destined for the peer in the ccb. Handles
  1196. * FCR segmentation and checks for congestion.
  1197. *
  1198. * Returns void
  1199. *
  1200. ******************************************************************************/
  1201. void l2c_enqueue_peer_data(tL2C_CCB* p_ccb, BT_HDR* p_buf) {
  1202. uint8_t* p;
  1203. if (p_ccb->peer_cfg.fcr.mode != L2CAP_FCR_BASIC_MODE) {
  1204. p_buf->event = 0;
  1205. } else {
  1206. /* Save the channel ID for faster counting */
  1207. p_buf->event = p_ccb->local_cid;
  1208. /* Step back to add the L2CAP header */
  1209. p_buf->offset -= L2CAP_PKT_OVERHEAD;
  1210. p_buf->len += L2CAP_PKT_OVERHEAD;
  1211. /* Set the pointer to the beginning of the data */
  1212. p = (uint8_t*)(p_buf + 1) + p_buf->offset;
  1213. /* Now the L2CAP header */
  1214. UINT16_TO_STREAM(p, p_buf->len - L2CAP_PKT_OVERHEAD);
  1215. UINT16_TO_STREAM(p, p_ccb->remote_cid);
  1216. }
  1217. if (p_ccb->xmit_hold_q == NULL) {
  1218. L2CAP_TRACE_ERROR(
  1219. "%s: empty queue: p_ccb = %p p_ccb->in_use = %d p_ccb->chnl_state = %d "
  1220. "p_ccb->local_cid = %u p_ccb->remote_cid = %u",
  1221. __func__, p_ccb, p_ccb->in_use, p_ccb->chnl_state, p_ccb->local_cid,
  1222. p_ccb->remote_cid);
  1223. }
  1224. fixed_queue_enqueue(p_ccb->xmit_hold_q, p_buf);
  1225. l2cu_check_channel_congestion(p_ccb);
  1226. #if (L2CAP_ROUND_ROBIN_CHANNEL_SERVICE == TRUE)
  1227. /* if new packet is higher priority than serving ccb and it is not overrun */
  1228. if ((p_ccb->p_lcb->rr_pri > p_ccb->ccb_priority) &&
  1229. (p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].quota > 0)) {
  1230. /* send out higher priority packet */
  1231. p_ccb->p_lcb->rr_pri = p_ccb->ccb_priority;
  1232. }
  1233. #endif
  1234. /* if we are doing a round robin scheduling, set the flag */
  1235. if (p_ccb->p_lcb->link_xmit_quota == 0) l2cb.check_round_robin = true;
  1236. }