bnep_api.cc 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696
  1. /******************************************************************************
  2. *
  3. * Copyright 2001-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 BNEP API code
  21. *
  22. ******************************************************************************/
  23. #include "bnep_api.h"
  24. #include <string.h>
  25. #include "bnep_int.h"
  26. using bluetooth::Uuid;
  27. /*******************************************************************************
  28. *
  29. * Function BNEP_Init
  30. *
  31. * Description This function initializes the BNEP unit. It should be called
  32. * before accessing any other APIs to initialize the control
  33. * block.
  34. *
  35. * Returns void
  36. *
  37. ******************************************************************************/
  38. void BNEP_Init(void) {
  39. memset(&bnep_cb, 0, sizeof(tBNEP_CB));
  40. #if defined(BNEP_INITIAL_TRACE_LEVEL)
  41. bnep_cb.trace_level = BNEP_INITIAL_TRACE_LEVEL;
  42. #else
  43. bnep_cb.trace_level = BT_TRACE_LEVEL_NONE; /* No traces */
  44. #endif
  45. }
  46. /*******************************************************************************
  47. *
  48. * Function BNEP_Register
  49. *
  50. * Description This function is called by the upper layer to register
  51. * its callbacks with BNEP
  52. *
  53. * Parameters: p_reg_info - contains all callback function pointers
  54. *
  55. *
  56. * Returns BNEP_SUCCESS if registered successfully
  57. * BNEP_FAILURE if connection state callback is missing
  58. *
  59. ******************************************************************************/
  60. tBNEP_RESULT BNEP_Register(tBNEP_REGISTER* p_reg_info) {
  61. /* There should be connection state call back registered */
  62. if ((!p_reg_info) || (!(p_reg_info->p_conn_state_cb)))
  63. return BNEP_SECURITY_FAIL;
  64. bnep_cb.p_conn_ind_cb = p_reg_info->p_conn_ind_cb;
  65. bnep_cb.p_conn_state_cb = p_reg_info->p_conn_state_cb;
  66. bnep_cb.p_data_ind_cb = p_reg_info->p_data_ind_cb;
  67. bnep_cb.p_data_buf_cb = p_reg_info->p_data_buf_cb;
  68. bnep_cb.p_filter_ind_cb = p_reg_info->p_filter_ind_cb;
  69. bnep_cb.p_mfilter_ind_cb = p_reg_info->p_mfilter_ind_cb;
  70. bnep_cb.p_tx_data_flow_cb = p_reg_info->p_tx_data_flow_cb;
  71. if (bnep_register_with_l2cap()) return BNEP_SECURITY_FAIL;
  72. bnep_cb.profile_registered = true;
  73. return BNEP_SUCCESS;
  74. }
  75. /*******************************************************************************
  76. *
  77. * Function BNEP_Deregister
  78. *
  79. * Description This function is called by the upper layer to de-register
  80. * its callbacks.
  81. *
  82. * Parameters: void
  83. *
  84. *
  85. * Returns void
  86. *
  87. ******************************************************************************/
  88. void BNEP_Deregister(void) {
  89. /* Clear all the call backs registered */
  90. bnep_cb.p_conn_ind_cb = NULL;
  91. bnep_cb.p_conn_state_cb = NULL;
  92. bnep_cb.p_data_ind_cb = NULL;
  93. bnep_cb.p_data_buf_cb = NULL;
  94. bnep_cb.p_filter_ind_cb = NULL;
  95. bnep_cb.p_mfilter_ind_cb = NULL;
  96. bnep_cb.profile_registered = false;
  97. L2CA_Deregister(BT_PSM_BNEP);
  98. }
  99. /*******************************************************************************
  100. *
  101. * Function BNEP_Connect
  102. *
  103. * Description This function creates a BNEP connection to a remote
  104. * device.
  105. *
  106. * Parameters: p_rem_addr - BD_ADDR of the peer
  107. * src_uuid - source uuid for the connection
  108. * dst_uuid - destination uuid for the connection
  109. * p_handle - pointer to return the handle for the
  110. * connection
  111. *
  112. * Returns BNEP_SUCCESS if connection started
  113. * BNEP_NO_RESOURCES if no resources
  114. *
  115. ******************************************************************************/
  116. tBNEP_RESULT BNEP_Connect(const RawAddress& p_rem_bda, const Uuid& src_uuid,
  117. const Uuid& dst_uuid, uint16_t* p_handle) {
  118. uint16_t cid;
  119. tBNEP_CONN* p_bcb = bnepu_find_bcb_by_bd_addr(p_rem_bda);
  120. VLOG(0) << __func__ << " BDA:" << p_rem_bda;
  121. if (!bnep_cb.profile_registered) return BNEP_WRONG_STATE;
  122. if (!p_bcb) {
  123. p_bcb = bnepu_allocate_bcb(p_rem_bda);
  124. if (p_bcb == NULL) return (BNEP_NO_RESOURCES);
  125. } else if (p_bcb->con_state != BNEP_STATE_CONNECTED)
  126. return BNEP_WRONG_STATE;
  127. else {
  128. /* Backup current UUID values to restore if role change fails */
  129. p_bcb->prv_src_uuid = p_bcb->src_uuid;
  130. p_bcb->prv_dst_uuid = p_bcb->dst_uuid;
  131. }
  132. /* We are the originator of this connection */
  133. p_bcb->con_flags |= BNEP_FLAGS_IS_ORIG;
  134. p_bcb->src_uuid = src_uuid;
  135. p_bcb->dst_uuid = dst_uuid;
  136. if (p_bcb->con_state == BNEP_STATE_CONNECTED) {
  137. /* Transition to the next appropriate state, waiting for connection confirm.
  138. */
  139. p_bcb->con_state = BNEP_STATE_SEC_CHECKING;
  140. BNEP_TRACE_API("BNEP initiating security procedures for src uuid %s",
  141. p_bcb->src_uuid.ToString().c_str());
  142. #if (BNEP_DO_AUTH_FOR_ROLE_SWITCH == TRUE)
  143. btm_sec_mx_access_request(p_bcb->rem_bda, BT_PSM_BNEP, true,
  144. BTM_SEC_PROTO_BNEP, src_uuid.As32Bit(),
  145. &bnep_sec_check_complete, p_bcb);
  146. #else
  147. bnep_sec_check_complete(p_bcb->rem_bda, p_bcb, BTM_SUCCESS);
  148. #endif
  149. } else {
  150. /* Transition to the next appropriate state, waiting for connection confirm.
  151. */
  152. p_bcb->con_state = BNEP_STATE_CONN_START;
  153. cid = L2CA_ConnectReq(BT_PSM_BNEP, p_bcb->rem_bda);
  154. if (cid != 0) {
  155. p_bcb->l2cap_cid = cid;
  156. } else {
  157. BNEP_TRACE_ERROR("BNEP - Originate failed");
  158. if (bnep_cb.p_conn_state_cb)
  159. (*bnep_cb.p_conn_state_cb)(p_bcb->handle, p_bcb->rem_bda,
  160. BNEP_CONN_FAILED, false);
  161. bnepu_release_bcb(p_bcb);
  162. return BNEP_CONN_FAILED;
  163. }
  164. /* Start timer waiting for connect */
  165. alarm_set_on_mloop(p_bcb->conn_timer, BNEP_CONN_TIMEOUT_MS,
  166. bnep_conn_timer_timeout, p_bcb);
  167. }
  168. *p_handle = p_bcb->handle;
  169. return (BNEP_SUCCESS);
  170. }
  171. /*******************************************************************************
  172. *
  173. * Function BNEP_ConnectResp
  174. *
  175. * Description This function is called in responce to connection indication
  176. *
  177. *
  178. * Parameters: handle - handle given in the connection indication
  179. * resp - responce for the connection indication
  180. *
  181. * Returns BNEP_SUCCESS if connection started
  182. * BNEP_WRONG_HANDLE if the connection is not found
  183. * BNEP_WRONG_STATE if the responce is not expected
  184. *
  185. ******************************************************************************/
  186. tBNEP_RESULT BNEP_ConnectResp(uint16_t handle, tBNEP_RESULT resp) {
  187. tBNEP_CONN* p_bcb;
  188. uint16_t resp_code = BNEP_SETUP_CONN_OK;
  189. if ((!handle) || (handle > BNEP_MAX_CONNECTIONS)) return (BNEP_WRONG_HANDLE);
  190. p_bcb = &(bnep_cb.bcb[handle - 1]);
  191. if (p_bcb->con_state != BNEP_STATE_CONN_SETUP ||
  192. (!(p_bcb->con_flags & BNEP_FLAGS_SETUP_RCVD)))
  193. return (BNEP_WRONG_STATE);
  194. BNEP_TRACE_API("BNEP_ConnectResp() for handle %d, responce %d", handle,
  195. resp);
  196. /* Form appropriate responce based on profile responce */
  197. if (resp == BNEP_CONN_FAILED_SRC_UUID)
  198. resp_code = BNEP_SETUP_INVALID_SRC_UUID;
  199. else if (resp == BNEP_CONN_FAILED_DST_UUID)
  200. resp_code = BNEP_SETUP_INVALID_DEST_UUID;
  201. else if (resp == BNEP_CONN_FAILED_UUID_SIZE)
  202. resp_code = BNEP_SETUP_INVALID_UUID_SIZE;
  203. else if (resp == BNEP_SUCCESS)
  204. resp_code = BNEP_SETUP_CONN_OK;
  205. else
  206. resp_code = BNEP_SETUP_CONN_NOT_ALLOWED;
  207. bnep_send_conn_responce(p_bcb, resp_code);
  208. p_bcb->con_flags &= (~BNEP_FLAGS_SETUP_RCVD);
  209. if (resp == BNEP_SUCCESS)
  210. bnep_connected(p_bcb);
  211. else if (p_bcb->con_flags & BNEP_FLAGS_CONN_COMPLETED) {
  212. /* Restore the original parameters */
  213. p_bcb->con_state = BNEP_STATE_CONNECTED;
  214. p_bcb->con_flags &= (~BNEP_FLAGS_SETUP_RCVD);
  215. p_bcb->src_uuid = p_bcb->prv_src_uuid;
  216. p_bcb->dst_uuid = p_bcb->prv_dst_uuid;
  217. }
  218. /* Process remaining part of the setup message (extension headers) */
  219. if (p_bcb->p_pending_data) {
  220. uint8_t extension_present = true, *p, ext_type;
  221. uint16_t rem_len;
  222. rem_len = p_bcb->p_pending_data->len;
  223. p = (uint8_t*)(p_bcb->p_pending_data + 1) + p_bcb->p_pending_data->offset;
  224. while (extension_present && p && rem_len) {
  225. ext_type = *p++;
  226. extension_present = ext_type >> 7;
  227. ext_type &= 0x7F;
  228. /* if unknown extension present stop processing */
  229. if (ext_type) break;
  230. p = bnep_process_control_packet(p_bcb, p, &rem_len, true);
  231. }
  232. osi_free_and_reset((void**)&p_bcb->p_pending_data);
  233. }
  234. return (BNEP_SUCCESS);
  235. }
  236. /*******************************************************************************
  237. *
  238. * Function BNEP_Disconnect
  239. *
  240. * Description This function is called to close the specified connection.
  241. *
  242. * Parameters: handle - handle of the connection
  243. *
  244. * Returns BNEP_SUCCESS if connection is disconnected
  245. * BNEP_WRONG_HANDLE if no connection is not found
  246. *
  247. ******************************************************************************/
  248. tBNEP_RESULT BNEP_Disconnect(uint16_t handle) {
  249. tBNEP_CONN* p_bcb;
  250. if ((!handle) || (handle > BNEP_MAX_CONNECTIONS)) return (BNEP_WRONG_HANDLE);
  251. p_bcb = &(bnep_cb.bcb[handle - 1]);
  252. if (p_bcb->con_state == BNEP_STATE_IDLE) return (BNEP_WRONG_HANDLE);
  253. BNEP_TRACE_API("BNEP_Disconnect() for handle %d", handle);
  254. L2CA_DisconnectReq(p_bcb->l2cap_cid);
  255. bnepu_release_bcb(p_bcb);
  256. return (BNEP_SUCCESS);
  257. }
  258. /*******************************************************************************
  259. *
  260. * Function BNEP_WriteBuf
  261. *
  262. * Description This function sends data in a GKI buffer on BNEP connection
  263. *
  264. * Parameters: handle - handle of the connection to write
  265. * p_dest_addr - BD_ADDR/Ethernet addr of the destination
  266. * p_buf - pointer to address of buffer with data
  267. * protocol - protocol type of the packet
  268. * p_src_addr - (optional) BD_ADDR/ethernet address of the
  269. * source
  270. * (should be NULL if it is local BD Addr)
  271. * fw_ext_present - forwarded extensions present
  272. *
  273. * Returns: BNEP_WRONG_HANDLE - if passed handle is not valid
  274. * BNEP_MTU_EXCEDED - If the data length is greater than
  275. * the MTU
  276. * BNEP_IGNORE_CMD - If the packet is filtered out
  277. * BNEP_Q_SIZE_EXCEEDED - If the Tx Q is full
  278. * BNEP_SUCCESS - If written successfully
  279. *
  280. ******************************************************************************/
  281. tBNEP_RESULT BNEP_WriteBuf(uint16_t handle, const RawAddress& p_dest_addr,
  282. BT_HDR* p_buf, uint16_t protocol,
  283. const RawAddress* p_src_addr, bool fw_ext_present) {
  284. tBNEP_CONN* p_bcb;
  285. uint8_t* p_data;
  286. if ((!handle) || (handle > BNEP_MAX_CONNECTIONS)) {
  287. osi_free(p_buf);
  288. return (BNEP_WRONG_HANDLE);
  289. }
  290. p_bcb = &(bnep_cb.bcb[handle - 1]);
  291. /* Check MTU size */
  292. if (p_buf->len > BNEP_MTU_SIZE) {
  293. BNEP_TRACE_ERROR("%s length %d exceeded MTU %d", __func__, p_buf->len,
  294. BNEP_MTU_SIZE);
  295. osi_free(p_buf);
  296. return (BNEP_MTU_EXCEDED);
  297. }
  298. /* Check if the packet should be filtered out */
  299. p_data = (uint8_t*)(p_buf + 1) + p_buf->offset;
  300. if (bnep_is_packet_allowed(p_bcb, p_dest_addr, protocol, fw_ext_present,
  301. p_data, p_buf->len) != BNEP_SUCCESS) {
  302. /*
  303. ** If packet is filtered and ext headers are present
  304. ** drop the data and forward the ext headers
  305. */
  306. if (fw_ext_present) {
  307. uint8_t ext, length;
  308. uint16_t org_len, new_len;
  309. /* parse the extension headers and findout the new packet len */
  310. org_len = p_buf->len;
  311. new_len = 0;
  312. do {
  313. if ((new_len + 2) > org_len) {
  314. osi_free(p_buf);
  315. return BNEP_IGNORE_CMD;
  316. }
  317. ext = *p_data++;
  318. length = *p_data++;
  319. p_data += length;
  320. new_len += (length + 2);
  321. if (new_len > org_len) {
  322. osi_free(p_buf);
  323. return BNEP_IGNORE_CMD;
  324. }
  325. } while (ext & 0x80);
  326. if (protocol != BNEP_802_1_P_PROTOCOL)
  327. protocol = 0;
  328. else {
  329. new_len += 4;
  330. if (new_len > org_len) return BNEP_IGNORE_CMD;
  331. p_data[2] = 0;
  332. p_data[3] = 0;
  333. }
  334. p_buf->len = new_len;
  335. } else {
  336. osi_free(p_buf);
  337. return BNEP_IGNORE_CMD;
  338. }
  339. }
  340. /* Check transmit queue */
  341. if (fixed_queue_length(p_bcb->xmit_q) >= BNEP_MAX_XMITQ_DEPTH) {
  342. osi_free(p_buf);
  343. return (BNEP_Q_SIZE_EXCEEDED);
  344. }
  345. /* Build the BNEP header */
  346. bnepu_build_bnep_hdr(p_bcb, p_buf, protocol, p_src_addr, &p_dest_addr,
  347. fw_ext_present);
  348. /* Send the data or queue it up */
  349. bnepu_check_send_packet(p_bcb, p_buf);
  350. return (BNEP_SUCCESS);
  351. }
  352. /*******************************************************************************
  353. *
  354. * Function BNEP_Write
  355. *
  356. * Description This function sends data over a BNEP connection
  357. *
  358. * Parameters: handle - handle of the connection to write
  359. * p_dest_addr - BD_ADDR/Ethernet addr of the destination
  360. * p_data - pointer to data start
  361. * protocol - protocol type of the packet
  362. * p_src_addr - (optional) BD_ADDR/ethernet address of the
  363. * source
  364. * (should be NULL if it is local BD Addr)
  365. * fw_ext_present - forwarded extensions present
  366. *
  367. * Returns: BNEP_WRONG_HANDLE - if passed handle is not valid
  368. * BNEP_MTU_EXCEDED - If the data length is greater than
  369. * the MTU
  370. * BNEP_IGNORE_CMD - If the packet is filtered out
  371. * BNEP_Q_SIZE_EXCEEDED - If the Tx Q is full
  372. * BNEP_NO_RESOURCES - If not able to allocate a buffer
  373. * BNEP_SUCCESS - If written successfully
  374. *
  375. ******************************************************************************/
  376. tBNEP_RESULT BNEP_Write(uint16_t handle, const RawAddress& p_dest_addr,
  377. uint8_t* p_data, uint16_t len, uint16_t protocol,
  378. const RawAddress* p_src_addr, bool fw_ext_present) {
  379. tBNEP_CONN* p_bcb;
  380. uint8_t* p;
  381. /* Check MTU size. Consider the possibility of having extension headers */
  382. if (len > BNEP_MTU_SIZE) {
  383. BNEP_TRACE_ERROR("%s length %d exceeded MTU %d", __func__, len,
  384. BNEP_MTU_SIZE);
  385. return (BNEP_MTU_EXCEDED);
  386. }
  387. if ((!handle) || (handle > BNEP_MAX_CONNECTIONS)) return (BNEP_WRONG_HANDLE);
  388. p_bcb = &(bnep_cb.bcb[handle - 1]);
  389. /* Check if the packet should be filtered out */
  390. if (bnep_is_packet_allowed(p_bcb, p_dest_addr, protocol, fw_ext_present,
  391. p_data, len) != BNEP_SUCCESS) {
  392. /*
  393. ** If packet is filtered and ext headers are present
  394. ** drop the data and forward the ext headers
  395. */
  396. if (fw_ext_present) {
  397. uint8_t ext, length;
  398. uint16_t org_len, new_len;
  399. /* parse the extension headers and findout the new packet len */
  400. org_len = len;
  401. new_len = 0;
  402. p = p_data;
  403. do {
  404. if ((new_len + 2) > org_len) {
  405. return BNEP_IGNORE_CMD;
  406. }
  407. ext = *p_data++;
  408. length = *p_data++;
  409. p_data += length;
  410. new_len += (length + 2);
  411. if (new_len > org_len) return BNEP_IGNORE_CMD;
  412. } while (ext & 0x80);
  413. if (protocol != BNEP_802_1_P_PROTOCOL)
  414. protocol = 0;
  415. else {
  416. new_len += 4;
  417. if (new_len > org_len) return BNEP_IGNORE_CMD;
  418. p_data[2] = 0;
  419. p_data[3] = 0;
  420. }
  421. len = new_len;
  422. p_data = p;
  423. } else
  424. return BNEP_IGNORE_CMD;
  425. }
  426. /* Check transmit queue */
  427. if (fixed_queue_length(p_bcb->xmit_q) >= BNEP_MAX_XMITQ_DEPTH)
  428. return (BNEP_Q_SIZE_EXCEEDED);
  429. /* Get a buffer to copy the data into */
  430. BT_HDR* p_buf = (BT_HDR*)osi_malloc(BNEP_BUF_SIZE);
  431. p_buf->len = len;
  432. p_buf->offset = BNEP_MINIMUM_OFFSET;
  433. p = (uint8_t*)(p_buf + 1) + BNEP_MINIMUM_OFFSET;
  434. memcpy(p, p_data, len);
  435. /* Build the BNEP header */
  436. bnepu_build_bnep_hdr(p_bcb, p_buf, protocol, p_src_addr, &p_dest_addr,
  437. fw_ext_present);
  438. /* Send the data or queue it up */
  439. bnepu_check_send_packet(p_bcb, p_buf);
  440. return (BNEP_SUCCESS);
  441. }
  442. /*******************************************************************************
  443. *
  444. * Function BNEP_SetProtocolFilters
  445. *
  446. * Description This function sets the protocol filters on peer device
  447. *
  448. * Parameters: handle - Handle for the connection
  449. * num_filters - total number of filter ranges
  450. * p_start_array - Array of beginings of all protocol ranges
  451. * p_end_array - Array of ends of all protocol ranges
  452. *
  453. * Returns BNEP_WRONG_HANDLE - if the connection handle is
  454. * not valid
  455. * BNEP_SET_FILTER_FAIL - if the connection is in wrong
  456. * state
  457. * BNEP_TOO_MANY_FILTERS - if too many filters
  458. * BNEP_SUCCESS - if request sent successfully
  459. *
  460. ******************************************************************************/
  461. tBNEP_RESULT BNEP_SetProtocolFilters(uint16_t handle, uint16_t num_filters,
  462. uint16_t* p_start_array,
  463. uint16_t* p_end_array) {
  464. uint16_t xx;
  465. tBNEP_CONN* p_bcb;
  466. if ((!handle) || (handle > BNEP_MAX_CONNECTIONS)) return (BNEP_WRONG_HANDLE);
  467. p_bcb = &(bnep_cb.bcb[handle - 1]);
  468. /* Check the connection state */
  469. if ((p_bcb->con_state != BNEP_STATE_CONNECTED) &&
  470. (!(p_bcb->con_flags & BNEP_FLAGS_CONN_COMPLETED)))
  471. return (BNEP_WRONG_STATE);
  472. /* Validate the parameters */
  473. if (num_filters && (!p_start_array || !p_end_array))
  474. return (BNEP_SET_FILTER_FAIL);
  475. if (num_filters > BNEP_MAX_PROT_FILTERS) return (BNEP_TOO_MANY_FILTERS);
  476. /* Fill the filter values in connnection block */
  477. for (xx = 0; xx < num_filters; xx++) {
  478. p_bcb->sent_prot_filter_start[xx] = *p_start_array++;
  479. p_bcb->sent_prot_filter_end[xx] = *p_end_array++;
  480. }
  481. p_bcb->sent_num_filters = num_filters;
  482. bnepu_send_peer_our_filters(p_bcb);
  483. return (BNEP_SUCCESS);
  484. }
  485. /*******************************************************************************
  486. *
  487. * Function BNEP_SetMulticastFilters
  488. *
  489. * Description This function sets the filters for multicast addresses for
  490. * BNEP.
  491. *
  492. * Parameters: handle - Handle for the connection
  493. * num_filters - total number of filter ranges
  494. * p_start_array - Pointer to sequence of beginings of all
  495. * multicast address ranges
  496. * p_end_array - Pointer to sequence of ends of all
  497. * multicast address ranges
  498. *
  499. * Returns BNEP_WRONG_HANDLE - if the connection handle is
  500. * not valid
  501. * BNEP_SET_FILTER_FAIL - if the connection is in wrong
  502. * state
  503. * BNEP_TOO_MANY_FILTERS - if too many filters
  504. * BNEP_SUCCESS - if request sent successfully
  505. *
  506. ******************************************************************************/
  507. tBNEP_RESULT BNEP_SetMulticastFilters(uint16_t handle, uint16_t num_filters,
  508. uint8_t* p_start_array,
  509. uint8_t* p_end_array) {
  510. uint16_t xx;
  511. tBNEP_CONN* p_bcb;
  512. if ((!handle) || (handle > BNEP_MAX_CONNECTIONS)) return (BNEP_WRONG_HANDLE);
  513. p_bcb = &(bnep_cb.bcb[handle - 1]);
  514. /* Check the connection state */
  515. if ((p_bcb->con_state != BNEP_STATE_CONNECTED) &&
  516. (!(p_bcb->con_flags & BNEP_FLAGS_CONN_COMPLETED)))
  517. return (BNEP_WRONG_STATE);
  518. /* Validate the parameters */
  519. if (num_filters && (!p_start_array || !p_end_array))
  520. return (BNEP_SET_FILTER_FAIL);
  521. if (num_filters > BNEP_MAX_MULTI_FILTERS) return (BNEP_TOO_MANY_FILTERS);
  522. /* Fill the multicast filter values in connnection block */
  523. for (xx = 0; xx < num_filters; xx++) {
  524. memcpy(p_bcb->sent_mcast_filter_start[xx].address, p_start_array,
  525. BD_ADDR_LEN);
  526. memcpy(p_bcb->sent_mcast_filter_end[xx].address, p_end_array, BD_ADDR_LEN);
  527. p_start_array += BD_ADDR_LEN;
  528. p_end_array += BD_ADDR_LEN;
  529. }
  530. p_bcb->sent_mcast_filters = num_filters;
  531. bnepu_send_peer_our_multi_filters(p_bcb);
  532. return (BNEP_SUCCESS);
  533. }
  534. /*******************************************************************************
  535. *
  536. * Function BNEP_SetTraceLevel
  537. *
  538. * Description This function sets the trace level for BNEP. If called with
  539. * a value of 0xFF, it simply reads the current trace level.
  540. *
  541. * Returns the new (current) trace level
  542. *
  543. ******************************************************************************/
  544. uint8_t BNEP_SetTraceLevel(uint8_t new_level) {
  545. if (new_level != 0xFF) bnep_cb.trace_level = new_level;
  546. return (bnep_cb.trace_level);
  547. }
  548. /*******************************************************************************
  549. *
  550. * Function BNEP_GetStatus
  551. *
  552. * Description This function gets the status information for BNEP
  553. * connection
  554. *
  555. * Returns BNEP_SUCCESS - if the status is available
  556. * BNEP_NO_RESOURCES - if no structure is passed for
  557. * output
  558. * BNEP_WRONG_HANDLE - if the handle is invalid
  559. * BNEP_WRONG_STATE - if not in connected state
  560. *
  561. ******************************************************************************/
  562. tBNEP_RESULT BNEP_GetStatus(uint16_t handle, tBNEP_STATUS* p_status) {
  563. #if (BNEP_SUPPORTS_STATUS_API == TRUE)
  564. tBNEP_CONN* p_bcb;
  565. if (!p_status) return BNEP_NO_RESOURCES;
  566. if ((!handle) || (handle > BNEP_MAX_CONNECTIONS)) return (BNEP_WRONG_HANDLE);
  567. p_bcb = &(bnep_cb.bcb[handle - 1]);
  568. memset(p_status, 0, sizeof(tBNEP_STATUS));
  569. if ((p_bcb->con_state != BNEP_STATE_CONNECTED) &&
  570. (!(p_bcb->con_flags & BNEP_FLAGS_CONN_COMPLETED)))
  571. return BNEP_WRONG_STATE;
  572. /* Read the status parameters from the connection control block */
  573. p_status->con_status = BNEP_STATUS_CONNECTED;
  574. p_status->l2cap_cid = p_bcb->l2cap_cid;
  575. p_status->rem_mtu_size = p_bcb->rem_mtu_size;
  576. p_status->xmit_q_depth = fixed_queue_length(p_bcb->xmit_q);
  577. p_status->sent_num_filters = p_bcb->sent_num_filters;
  578. p_status->sent_mcast_filters = p_bcb->sent_mcast_filters;
  579. p_status->rcvd_num_filters = p_bcb->rcvd_num_filters;
  580. p_status->rcvd_mcast_filters = p_bcb->rcvd_mcast_filters;
  581. p_status->rem_bda = p_bcb->rem_bda;
  582. p_status->src_uuid = p_bcb->src_uuid;
  583. p_status->dst_uuid = p_bcb->dst_uuid;
  584. return BNEP_SUCCESS;
  585. #else
  586. return (BNEP_IGNORE_CMD);
  587. #endif
  588. }