sdp_main.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708
  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 main SDP functions
  21. *
  22. ******************************************************************************/
  23. #include <stdlib.h>
  24. #include <string.h>
  25. //#include <stdio.h>
  26. #include "common/bt_target.h"
  27. #include "osi/allocator.h"
  28. #include "stack/l2cdefs.h"
  29. #include "stack/hcidefs.h"
  30. #include "stack/hcimsgs.h"
  31. #include "stack/l2c_api.h"
  32. #include "stack/l2cdefs.h"
  33. #include "stack/btu.h"
  34. #include "stack/btm_api.h"
  35. #include "stack/sdp_api.h"
  36. #include "sdpint.h"
  37. #include "osi/list.h"
  38. #if (SDP_INCLUDED == TRUE)
  39. /********************************************************************************/
  40. /* G L O B A L S D P D A T A */
  41. /********************************************************************************/
  42. #if SDP_DYNAMIC_MEMORY == FALSE
  43. tSDP_CB sdp_cb;
  44. #else
  45. tSDP_CB *sdp_cb_ptr;
  46. #endif
  47. /********************************************************************************/
  48. /* L O C A L F U N C T I O N P R O T O T Y P E S */
  49. /********************************************************************************/
  50. static void sdp_connect_ind (BD_ADDR bd_addr, UINT16 l2cap_cid, UINT16 psm,
  51. UINT8 l2cap_id);
  52. static void sdp_config_ind (UINT16 l2cap_cid, tL2CAP_CFG_INFO *p_cfg);
  53. static void sdp_config_cfm (UINT16 l2cap_cid, tL2CAP_CFG_INFO *p_cfg);
  54. static void sdp_disconnect_ind (UINT16 l2cap_cid, BOOLEAN ack_needed);
  55. static void sdp_data_ind (UINT16 l2cap_cid, BT_HDR *p_msg);
  56. #if SDP_CLIENT_ENABLED == TRUE
  57. static void sdp_connect_cfm (UINT16 l2cap_cid, UINT16 result);
  58. static void sdp_disconnect_cfm (UINT16 l2cap_cid, UINT16 result);
  59. #else
  60. #define sdp_connect_cfm NULL
  61. #define sdp_disconnect_cfm NULL
  62. #endif
  63. /*******************************************************************************
  64. **
  65. ** Function sdp_init
  66. **
  67. ** Description This function initializes the SDP unit.
  68. **
  69. ** Returns void
  70. **
  71. *******************************************************************************/
  72. void sdp_init (void)
  73. {
  74. #if SDP_DYNAMIC_MEMORY
  75. sdp_cb_ptr = (tSDP_CB *)osi_malloc(sizeof(tSDP_CB));
  76. #endif /* #if SDP_DYNAMIC_MEMORY */
  77. /* Clears all structures and local SDP database (if Server is enabled) */
  78. memset (&sdp_cb, 0, sizeof (tSDP_CB));
  79. sdp_cb.server_db.p_record_list = list_new(osi_free_func);
  80. /* Initialize the L2CAP configuration. We only care about MTU and flush */
  81. sdp_cb.l2cap_my_cfg.mtu_present = TRUE;
  82. sdp_cb.l2cap_my_cfg.mtu = SDP_MTU_SIZE;
  83. sdp_cb.l2cap_my_cfg.flush_to_present = TRUE;
  84. sdp_cb.l2cap_my_cfg.flush_to = SDP_FLUSH_TO;
  85. sdp_cb.max_attr_list_size = SDP_MTU_SIZE - 16;
  86. sdp_cb.max_recs_per_search = SDP_MAX_DISC_SERVER_RECS;
  87. #if SDP_SERVER_ENABLED == TRUE
  88. /* Register with Security Manager for the specific security level */
  89. if (!BTM_SetSecurityLevel (FALSE, SDP_SERVICE_NAME, BTM_SEC_SERVICE_SDP_SERVER,
  90. SDP_SECURITY_LEVEL, SDP_PSM, 0, 0)) {
  91. SDP_TRACE_ERROR ("Security Registration Server failed\n");
  92. return;
  93. }
  94. #endif
  95. #if SDP_CLIENT_ENABLED == TRUE
  96. /* Register with Security Manager for the specific security level */
  97. if (!BTM_SetSecurityLevel (TRUE, SDP_SERVICE_NAME, BTM_SEC_SERVICE_SDP_SERVER,
  98. SDP_SECURITY_LEVEL, SDP_PSM, 0, 0)) {
  99. SDP_TRACE_ERROR ("Security Registration for Client failed\n");
  100. return;
  101. }
  102. #endif
  103. #if defined(SDP_INITIAL_TRACE_LEVEL)
  104. sdp_cb.trace_level = SDP_INITIAL_TRACE_LEVEL;
  105. #else
  106. sdp_cb.trace_level = BT_TRACE_LEVEL_NONE; /* No traces */
  107. #endif
  108. sdp_cb.reg_info.pL2CA_ConnectInd_Cb = sdp_connect_ind;
  109. sdp_cb.reg_info.pL2CA_ConnectCfm_Cb = sdp_connect_cfm;
  110. sdp_cb.reg_info.pL2CA_ConnectPnd_Cb = NULL;
  111. sdp_cb.reg_info.pL2CA_ConfigInd_Cb = sdp_config_ind;
  112. sdp_cb.reg_info.pL2CA_ConfigCfm_Cb = sdp_config_cfm;
  113. sdp_cb.reg_info.pL2CA_DisconnectInd_Cb = sdp_disconnect_ind;
  114. sdp_cb.reg_info.pL2CA_DisconnectCfm_Cb = sdp_disconnect_cfm;
  115. sdp_cb.reg_info.pL2CA_QoSViolationInd_Cb = NULL;
  116. sdp_cb.reg_info.pL2CA_DataInd_Cb = sdp_data_ind;
  117. sdp_cb.reg_info.pL2CA_CongestionStatus_Cb = NULL;
  118. sdp_cb.reg_info.pL2CA_TxComplete_Cb = NULL;
  119. /* Now, register with L2CAP */
  120. if (!L2CA_Register (SDP_PSM, &sdp_cb.reg_info)) {
  121. SDP_TRACE_ERROR ("SDP Registration failed\n");
  122. }
  123. }
  124. void sdp_deinit (void)
  125. {
  126. list_free(sdp_cb.server_db.p_record_list);
  127. #if SDP_DYNAMIC_MEMORY
  128. osi_free(sdp_cb_ptr);
  129. sdp_cb_ptr = NULL;
  130. #endif /* #if SDP_DYNAMIC_MEMORY */
  131. }
  132. #if (defined(SDP_DEBUG) && SDP_DEBUG == TRUE)
  133. /*******************************************************************************
  134. **
  135. ** Function sdp_set_max_attr_list_size
  136. **
  137. ** Description This function sets the max attribute list size to use
  138. **
  139. ** Returns void
  140. **
  141. *******************************************************************************/
  142. UINT16 sdp_set_max_attr_list_size (UINT16 max_size)
  143. {
  144. if (max_size > (sdp_cb.l2cap_my_cfg.mtu - 16) ) {
  145. max_size = sdp_cb.l2cap_my_cfg.mtu - 16;
  146. }
  147. sdp_cb.max_attr_list_size = max_size;
  148. return sdp_cb.max_attr_list_size;
  149. }
  150. #endif
  151. /*******************************************************************************
  152. **
  153. ** Function sdp_connect_ind
  154. **
  155. ** Description This function handles an inbound connection indication
  156. ** from L2CAP. This is the case where we are acting as a
  157. ** server.
  158. **
  159. ** Returns void
  160. **
  161. *******************************************************************************/
  162. static void sdp_connect_ind (BD_ADDR bd_addr, UINT16 l2cap_cid, UINT16 psm, UINT8 l2cap_id)
  163. {
  164. UNUSED(psm);
  165. #if SDP_SERVER_ENABLED == TRUE
  166. tCONN_CB *p_ccb;
  167. /* Allocate a new CCB. Return if none available. */
  168. if ((p_ccb = sdpu_allocate_ccb()) == NULL) {
  169. return;
  170. }
  171. /* Transition to the next appropriate state, waiting for config setup. */
  172. p_ccb->con_state = SDP_STATE_CFG_SETUP;
  173. /* Save the BD Address and Channel ID. */
  174. memcpy (&p_ccb->device_address[0], bd_addr, sizeof (BD_ADDR));
  175. p_ccb->connection_id = l2cap_cid;
  176. /* Send response to the L2CAP layer. */
  177. L2CA_ConnectRsp (bd_addr, l2cap_id, l2cap_cid, L2CAP_CONN_OK, L2CAP_CONN_OK);
  178. {
  179. tL2CAP_CFG_INFO cfg = sdp_cb.l2cap_my_cfg;
  180. if (cfg.fcr_present) {
  181. SDP_TRACE_DEBUG("sdp_connect_ind: mode %u, txwinsz %u, max_trans %u, rtrans_tout %u, mon_tout %u, mps %u\n",
  182. cfg.fcr.mode, cfg.fcr.tx_win_sz, cfg.fcr.max_transmit,
  183. cfg.fcr.rtrans_tout, cfg.fcr.mon_tout, cfg.fcr.mps);
  184. }
  185. if ((!L2CA_ConfigReq (l2cap_cid, &cfg)) && cfg.fcr_present
  186. && cfg.fcr.mode != L2CAP_FCR_BASIC_MODE) {
  187. /* FCR not desired; try again in basic mode */
  188. cfg.fcr.mode = L2CAP_FCR_BASIC_MODE;
  189. cfg.fcr_present = FALSE;
  190. L2CA_ConfigReq (l2cap_cid, &cfg);
  191. }
  192. }
  193. SDP_TRACE_EVENT ("SDP - Rcvd L2CAP conn ind, sent config req, CID 0x%x\n", p_ccb->connection_id);
  194. #else /* No server */
  195. /* Reject the connection */
  196. L2CA_ConnectRsp (bd_addr, l2cap_id, l2cap_cid, L2CAP_CONN_NO_PSM, 0);
  197. #endif
  198. }
  199. #if SDP_CLIENT_ENABLED == TRUE
  200. /*******************************************************************************
  201. **
  202. ** Function sdp_connect_cfm
  203. **
  204. ** Description This function handles the connect confirm events
  205. ** from L2CAP. This is the case when we are acting as a
  206. ** client and have sent a connect request.
  207. **
  208. ** Returns void
  209. **
  210. *******************************************************************************/
  211. static void sdp_connect_cfm (UINT16 l2cap_cid, UINT16 result)
  212. {
  213. tCONN_CB *p_ccb;
  214. tL2CAP_CFG_INFO cfg;
  215. /* Find CCB based on CID */
  216. if ((p_ccb = sdpu_find_ccb_by_cid (l2cap_cid)) == NULL) {
  217. SDP_TRACE_WARNING ("SDP - Rcvd conn cnf for unknown CID 0x%x\n", l2cap_cid);
  218. return;
  219. }
  220. /* If the connection response contains success status, then */
  221. /* Transition to the next state and startup the timer. */
  222. if ((result == L2CAP_CONN_OK) && (p_ccb->con_state == SDP_STATE_CONN_SETUP)) {
  223. p_ccb->con_state = SDP_STATE_CFG_SETUP;
  224. cfg = sdp_cb.l2cap_my_cfg;
  225. if (cfg.fcr_present) {
  226. SDP_TRACE_DEBUG("sdp_connect_cfm: mode %u, txwinsz %u, max_trans %u, rtrans_tout %u, mon_tout %u, mps %u\n",
  227. cfg.fcr.mode, cfg.fcr.tx_win_sz, cfg.fcr.max_transmit,
  228. cfg.fcr.rtrans_tout, cfg.fcr.mon_tout, cfg.fcr.mps);
  229. }
  230. if ((!L2CA_ConfigReq (l2cap_cid, &cfg)) && cfg.fcr_present
  231. && cfg.fcr.mode != L2CAP_FCR_BASIC_MODE) {
  232. /* FCR not desired; try again in basic mode */
  233. cfg.fcr_present = FALSE;
  234. cfg.fcr.mode = L2CAP_FCR_BASIC_MODE;
  235. L2CA_ConfigReq (l2cap_cid, &cfg);
  236. }
  237. SDP_TRACE_EVENT ("SDP - got conn cnf, sent cfg req, CID: 0x%x\n", p_ccb->connection_id);
  238. } else {
  239. SDP_TRACE_WARNING ("SDP - Rcvd conn cnf with error: 0x%x CID 0x%x\n", result, p_ccb->connection_id);
  240. /* Tell the user if he has a callback */
  241. if (p_ccb->p_cb || p_ccb->p_cb2) {
  242. UINT16 err = -1;
  243. if ((result == HCI_ERR_HOST_REJECT_SECURITY)
  244. || (result == HCI_ERR_AUTH_FAILURE)
  245. || (result == HCI_ERR_PAIRING_NOT_ALLOWED)
  246. || (result == HCI_ERR_PAIRING_WITH_UNIT_KEY_NOT_SUPPORTED)
  247. || (result == HCI_ERR_KEY_MISSING)) {
  248. err = SDP_SECURITY_ERR;
  249. } else if (result == HCI_ERR_HOST_REJECT_DEVICE) {
  250. err = SDP_CONN_REJECTED;
  251. } else {
  252. err = SDP_CONN_FAILED;
  253. }
  254. if (p_ccb->p_cb) {
  255. (*p_ccb->p_cb)(err);
  256. } else if (p_ccb->p_cb2) {
  257. (*p_ccb->p_cb2)(err, p_ccb->user_data);
  258. }
  259. }
  260. sdpu_release_ccb (p_ccb);
  261. }
  262. }
  263. #endif /* SDP_CLIENT_ENABLED == TRUE */
  264. /*******************************************************************************
  265. **
  266. ** Function sdp_config_ind
  267. **
  268. ** Description This function processes the L2CAP configuration indication
  269. ** event.
  270. **
  271. ** Returns void
  272. **
  273. *******************************************************************************/
  274. static void sdp_config_ind (UINT16 l2cap_cid, tL2CAP_CFG_INFO *p_cfg)
  275. {
  276. tCONN_CB *p_ccb;
  277. /* Find CCB based on CID */
  278. if ((p_ccb = sdpu_find_ccb_by_cid (l2cap_cid)) == NULL) {
  279. SDP_TRACE_WARNING ("SDP - Rcvd L2CAP cfg ind, unknown CID: 0x%x\n", l2cap_cid);
  280. return;
  281. }
  282. /* Remember the remote MTU size */
  283. if (!p_cfg->mtu_present) {
  284. /* use min(L2CAP_DEFAULT_MTU,SDP_MTU_SIZE) for GKI buffer size reasons */
  285. p_ccb->rem_mtu_size = (L2CAP_DEFAULT_MTU > SDP_MTU_SIZE) ? SDP_MTU_SIZE : L2CAP_DEFAULT_MTU;
  286. } else {
  287. if (p_cfg->mtu > SDP_MTU_SIZE) {
  288. p_ccb->rem_mtu_size = SDP_MTU_SIZE;
  289. } else {
  290. p_ccb->rem_mtu_size = p_cfg->mtu;
  291. }
  292. }
  293. /* For now, always accept configuration from the other side */
  294. p_cfg->flush_to_present = FALSE;
  295. p_cfg->mtu_present = FALSE;
  296. p_cfg->result = L2CAP_CFG_OK;
  297. /* Check peer config request against our rfcomm configuration */
  298. if (p_cfg->fcr_present) {
  299. /* Reject the window size if it is bigger than we want it to be */
  300. if (p_cfg->fcr.mode != L2CAP_FCR_BASIC_MODE) {
  301. if (sdp_cb.l2cap_my_cfg.fcr.mode != L2CAP_FCR_BASIC_MODE
  302. && p_cfg->fcr.tx_win_sz > sdp_cb.l2cap_my_cfg.fcr.tx_win_sz) {
  303. p_cfg->fcr.tx_win_sz = sdp_cb.l2cap_my_cfg.fcr.tx_win_sz;
  304. p_cfg->result = L2CAP_CFG_UNACCEPTABLE_PARAMS;
  305. SDP_TRACE_DEBUG("sdp_config_ind(CONFIG) -> Please try again with SMALLER TX WINDOW\n");
  306. }
  307. /* Reject if locally we want basic and they don't */
  308. if (sdp_cb.l2cap_my_cfg.fcr.mode == L2CAP_FCR_BASIC_MODE) {
  309. /* Ask for a new setup */
  310. p_cfg->fcr.mode = L2CAP_FCR_BASIC_MODE;
  311. p_cfg->result = L2CAP_CFG_UNACCEPTABLE_PARAMS;
  312. SDP_TRACE_DEBUG("sdp_config_ind(CONFIG) -> Please try again with BASIC mode\n");
  313. }
  314. /* Remain in configure state and give the peer our desired configuration */
  315. if (p_cfg->result != L2CAP_CFG_OK) {
  316. SDP_TRACE_WARNING ("SDP - Rcvd cfg ind, Unacceptable Parameters sent cfg cfm, CID: 0x%x\n", l2cap_cid);
  317. L2CA_ConfigRsp (l2cap_cid, p_cfg);
  318. return;
  319. }
  320. } else { /* We agree with peer's request */
  321. p_cfg->fcr_present = FALSE;
  322. }
  323. }
  324. L2CA_ConfigRsp (l2cap_cid, p_cfg);
  325. SDP_TRACE_EVENT ("SDP - Rcvd cfg ind, sent cfg cfm, CID: 0x%x\n", l2cap_cid);
  326. p_ccb->con_flags |= SDP_FLAGS_HIS_CFG_DONE;
  327. if (p_ccb->con_flags & SDP_FLAGS_MY_CFG_DONE) {
  328. p_ccb->con_state = SDP_STATE_CONNECTED;
  329. if (p_ccb->con_flags & SDP_FLAGS_IS_ORIG) {
  330. sdp_disc_connected (p_ccb);
  331. } else
  332. /* Start inactivity timer */
  333. {
  334. btu_start_timer (&p_ccb->timer_entry, BTU_TTYPE_SDP, SDP_INACT_TIMEOUT);
  335. }
  336. }
  337. }
  338. /*******************************************************************************
  339. **
  340. ** Function sdp_config_cfm
  341. **
  342. ** Description This function processes the L2CAP configuration confirmation
  343. ** event.
  344. **
  345. ** Returns void
  346. **
  347. *******************************************************************************/
  348. static void sdp_config_cfm (UINT16 l2cap_cid, tL2CAP_CFG_INFO *p_cfg)
  349. {
  350. tCONN_CB *p_ccb;
  351. SDP_TRACE_EVENT ("SDP - Rcvd cfg cfm, CID: 0x%x Result: %d\n", l2cap_cid, p_cfg->result);
  352. /* Find CCB based on CID */
  353. if ((p_ccb = sdpu_find_ccb_by_cid (l2cap_cid)) == NULL) {
  354. SDP_TRACE_WARNING ("SDP - Rcvd L2CAP cfg ind, unknown CID: 0x%x\n", l2cap_cid);
  355. return;
  356. }
  357. /* For now, always accept configuration from the other side */
  358. if (p_cfg->result == L2CAP_CFG_OK) {
  359. p_ccb->con_flags |= SDP_FLAGS_MY_CFG_DONE;
  360. if (p_ccb->con_flags & SDP_FLAGS_HIS_CFG_DONE) {
  361. p_ccb->con_state = SDP_STATE_CONNECTED;
  362. if (p_ccb->con_flags & SDP_FLAGS_IS_ORIG) {
  363. sdp_disc_connected (p_ccb);
  364. } else
  365. /* Start inactivity timer */
  366. {
  367. btu_start_timer (&p_ccb->timer_entry, BTU_TTYPE_SDP, SDP_INACT_TIMEOUT);
  368. }
  369. }
  370. } else {
  371. /* If peer has rejected FCR and suggested basic then try basic */
  372. if (p_cfg->fcr_present) {
  373. tL2CAP_CFG_INFO cfg = sdp_cb.l2cap_my_cfg;
  374. cfg.fcr_present = FALSE;
  375. L2CA_ConfigReq (l2cap_cid, &cfg);
  376. /* Remain in configure state */
  377. return;
  378. }
  379. #if SDP_CLIENT_ENABLED == TRUE
  380. sdp_disconnect(p_ccb, SDP_CFG_FAILED);
  381. #endif
  382. }
  383. }
  384. /*******************************************************************************
  385. **
  386. ** Function sdp_disconnect_ind
  387. **
  388. ** Description This function handles a disconnect event from L2CAP. If
  389. ** requested to, we ack the disconnect before dropping the CCB
  390. **
  391. ** Returns void
  392. **
  393. *******************************************************************************/
  394. static void sdp_disconnect_ind (UINT16 l2cap_cid, BOOLEAN ack_needed)
  395. {
  396. tCONN_CB *p_ccb;
  397. /* Find CCB based on CID */
  398. if ((p_ccb = sdpu_find_ccb_by_cid (l2cap_cid)) == NULL) {
  399. SDP_TRACE_WARNING ("SDP - Rcvd L2CAP disc, unknown CID: 0x%x\n", l2cap_cid);
  400. return;
  401. }
  402. if (ack_needed) {
  403. L2CA_DisconnectRsp (l2cap_cid);
  404. }
  405. SDP_TRACE_EVENT ("SDP - Rcvd L2CAP disc, CID: 0x%x\n", l2cap_cid);
  406. #if SDP_CLIENT_ENABLED == TRUE
  407. /* Tell the user if he has a callback */
  408. if (p_ccb->p_cb) {
  409. (*p_ccb->p_cb) ((UINT16) ((p_ccb->con_state == SDP_STATE_CONNECTED) ?
  410. SDP_SUCCESS : SDP_CONN_FAILED));
  411. } else if (p_ccb->p_cb2) {
  412. (*p_ccb->p_cb2) ((UINT16) ((p_ccb->con_state == SDP_STATE_CONNECTED) ?
  413. SDP_SUCCESS : SDP_CONN_FAILED), p_ccb->user_data);
  414. }
  415. #endif
  416. sdpu_release_ccb (p_ccb);
  417. }
  418. /*******************************************************************************
  419. **
  420. ** Function sdp_data_ind
  421. **
  422. ** Description This function is called when data is received from L2CAP.
  423. ** if we are the originator of the connection, we are the SDP
  424. ** client, and the received message is queued up for the client.
  425. **
  426. ** If we are the destination of the connection, we are the SDP
  427. ** server, so the message is passed to the server processing
  428. ** function.
  429. **
  430. ** Returns void
  431. **
  432. *******************************************************************************/
  433. static void sdp_data_ind (UINT16 l2cap_cid, BT_HDR *p_msg)
  434. {
  435. tCONN_CB *p_ccb;
  436. /* Find CCB based on CID */
  437. if ((p_ccb = sdpu_find_ccb_by_cid (l2cap_cid)) != NULL) {
  438. if (p_ccb->con_state == SDP_STATE_CONNECTED) {
  439. if (p_ccb->con_flags & SDP_FLAGS_IS_ORIG) {
  440. sdp_disc_server_rsp (p_ccb, p_msg);
  441. } else {
  442. sdp_server_handle_client_req (p_ccb, p_msg);
  443. }
  444. } else {
  445. SDP_TRACE_WARNING ("SDP - Ignored L2CAP data while in state: %d, CID: 0x%x\n",
  446. p_ccb->con_state, l2cap_cid);
  447. }
  448. } else {
  449. SDP_TRACE_WARNING ("SDP - Rcvd L2CAP data, unknown CID: 0x%x\n", l2cap_cid);
  450. }
  451. osi_free (p_msg);
  452. }
  453. #if SDP_CLIENT_ENABLED == TRUE
  454. /*******************************************************************************
  455. **
  456. ** Function sdp_conn_originate
  457. **
  458. ** Description This function is called from the API to originate a
  459. ** connection.
  460. **
  461. ** Returns void
  462. **
  463. *******************************************************************************/
  464. tCONN_CB *sdp_conn_originate (UINT8 *p_bd_addr)
  465. {
  466. tCONN_CB *p_ccb;
  467. UINT16 cid;
  468. /* Allocate a new CCB. Return if none available. */
  469. if ((p_ccb = sdpu_allocate_ccb()) == NULL) {
  470. SDP_TRACE_WARNING ("SDP - no spare CCB for orig\n");
  471. return (NULL);
  472. }
  473. SDP_TRACE_EVENT ("SDP - Originate started\n");
  474. /* We are the originator of this connection */
  475. p_ccb->con_flags |= SDP_FLAGS_IS_ORIG;
  476. /* Save the BD Address and Channel ID. */
  477. memcpy (&p_ccb->device_address[0], p_bd_addr, sizeof (BD_ADDR));
  478. /* Transition to the next appropriate state, waiting for connection confirm. */
  479. p_ccb->con_state = SDP_STATE_CONN_SETUP;
  480. cid = L2CA_ConnectReq (SDP_PSM, p_bd_addr);
  481. /* Check if L2CAP started the connection process */
  482. if (cid != 0) {
  483. p_ccb->connection_id = cid;
  484. return (p_ccb);
  485. } else {
  486. SDP_TRACE_WARNING ("SDP - Originate failed\n");
  487. sdpu_release_ccb (p_ccb);
  488. return (NULL);
  489. }
  490. }
  491. /*******************************************************************************
  492. **
  493. ** Function sdp_disconnect
  494. **
  495. ** Description This function disconnects a connection.
  496. **
  497. ** Returns void
  498. **
  499. *******************************************************************************/
  500. void sdp_disconnect (tCONN_CB *p_ccb, UINT16 reason)
  501. {
  502. #if (defined(SDP_BROWSE_PLUS) && SDP_BROWSE_PLUS == TRUE)
  503. /* If we are browsing for multiple UUIDs ... */
  504. if ((p_ccb->con_state == SDP_STATE_CONNECTED)
  505. && (p_ccb->con_flags & SDP_FLAGS_IS_ORIG)
  506. && ((reason == SDP_SUCCESS) || (reason == SDP_NO_RECS_MATCH))) {
  507. /* If the browse found something, do no more searching */
  508. if ((p_ccb->cur_uuid_idx == 0) && (p_ccb->p_db->p_first_rec)) {
  509. p_ccb->cur_uuid_idx = p_ccb->p_db->num_uuid_filters;
  510. }
  511. while (++p_ccb->cur_uuid_idx < p_ccb->p_db->num_uuid_filters) {
  512. /* Check we have not already found the UUID (maybe through browse) */
  513. if ((p_ccb->p_db->uuid_filters[p_ccb->cur_uuid_idx].len == 2)
  514. && (SDP_FindServiceInDb (p_ccb->p_db,
  515. p_ccb->p_db->uuid_filters[p_ccb->cur_uuid_idx].uu.uuid16,
  516. NULL))) {
  517. continue;
  518. }
  519. if ((p_ccb->p_db->uuid_filters[p_ccb->cur_uuid_idx].len > 2)
  520. && (SDP_FindServiceUUIDInDb (p_ccb->p_db,
  521. &p_ccb->p_db->uuid_filters[p_ccb->cur_uuid_idx], NULL))) {
  522. continue;
  523. }
  524. p_ccb->cur_handle = 0;
  525. SDP_TRACE_EVENT ("SDP - looking for for more, CID: 0x%x\n",
  526. p_ccb->connection_id);
  527. sdp_disc_connected (p_ccb);
  528. return;
  529. }
  530. }
  531. if ((reason == SDP_NO_RECS_MATCH) && (p_ccb->p_db->p_first_rec)) {
  532. reason = SDP_SUCCESS;
  533. }
  534. #endif
  535. SDP_TRACE_EVENT ("SDP - disconnect CID: 0x%x\n", p_ccb->connection_id);
  536. /* Check if we have a connection ID */
  537. if (p_ccb->connection_id != 0) {
  538. L2CA_DisconnectReq (p_ccb->connection_id);
  539. p_ccb->disconnect_reason = reason;
  540. }
  541. /* If at setup state, we may not get callback ind from L2CAP */
  542. /* Call user callback immediately */
  543. if (p_ccb->con_state == SDP_STATE_CONN_SETUP) {
  544. /* Tell the user if he has a callback */
  545. if (p_ccb->p_cb) {
  546. (*p_ccb->p_cb) (reason);
  547. } else if (p_ccb->p_cb2) {
  548. (*p_ccb->p_cb2) (reason, p_ccb->user_data);
  549. }
  550. sdpu_release_ccb (p_ccb);
  551. }
  552. }
  553. /*******************************************************************************
  554. **
  555. ** Function sdp_disconnect_cfm
  556. **
  557. ** Description This function handles a disconnect confirm event from L2CAP.
  558. **
  559. ** Returns void
  560. **
  561. *******************************************************************************/
  562. static void sdp_disconnect_cfm (UINT16 l2cap_cid, UINT16 result)
  563. {
  564. tCONN_CB *p_ccb;
  565. UNUSED(result);
  566. /* Find CCB based on CID */
  567. if ((p_ccb = sdpu_find_ccb_by_cid (l2cap_cid)) == NULL) {
  568. SDP_TRACE_WARNING ("SDP - Rcvd L2CAP disc cfm, unknown CID: 0x%x\n", l2cap_cid);
  569. return;
  570. }
  571. SDP_TRACE_EVENT ("SDP - Rcvd L2CAP disc cfm, CID: 0x%x, rsn %d\n", l2cap_cid, p_ccb->disconnect_reason);
  572. /* Tell the user if he has a callback */
  573. if (p_ccb->p_cb) {
  574. (*p_ccb->p_cb) (p_ccb->disconnect_reason);
  575. } else if (p_ccb->p_cb2) {
  576. (*p_ccb->p_cb2) (p_ccb->disconnect_reason, p_ccb->user_data);
  577. }
  578. sdpu_release_ccb (p_ccb);
  579. }
  580. #endif /* SDP_CLIENT_ENABLED == TRUE */
  581. /*******************************************************************************
  582. **
  583. ** Function sdp_conn_timeout
  584. **
  585. ** Description This function processes a timeout. Currently, we simply send
  586. ** a disconnect request to L2CAP.
  587. **
  588. ** Returns void
  589. **
  590. *******************************************************************************/
  591. void sdp_conn_timeout (tCONN_CB *p_ccb)
  592. {
  593. SDP_TRACE_EVENT ("SDP - CCB timeout in state: %d CID: 0x%x\n",
  594. p_ccb->con_state, p_ccb->connection_id);
  595. L2CA_DisconnectReq (p_ccb->connection_id);
  596. #if SDP_CLIENT_ENABLED == TRUE
  597. /* Tell the user if he has a callback */
  598. if (p_ccb->p_cb) {
  599. (*p_ccb->p_cb) (SDP_CONN_FAILED);
  600. } else if (p_ccb->p_cb2) {
  601. (*p_ccb->p_cb2) (SDP_CONN_FAILED, p_ccb->user_data);
  602. }
  603. #endif
  604. sdpu_release_ccb (p_ccb);
  605. }
  606. #endif ///SDP_INCLUDED == TRUE