pan_api.cc 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703
  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 main functions to support PAN profile
  21. * commands and events.
  22. *
  23. *****************************************************************************/
  24. #include "pan_api.h"
  25. #include <base/logging.h>
  26. #include <string.h>
  27. #include "bnep_api.h"
  28. #include "bt_common.h"
  29. #include "bt_types.h"
  30. #include "bta_sys.h"
  31. #include "btm_api.h"
  32. #include "hcidefs.h"
  33. #include "l2c_api.h"
  34. #include "pan_int.h"
  35. #include "sdp_api.h"
  36. #include "sdpdefs.h"
  37. using bluetooth::Uuid;
  38. /*******************************************************************************
  39. *
  40. * Function PAN_Register
  41. *
  42. * Description This function is called by the application to register
  43. * its callbacks with PAN profile. The application then
  44. * should set the PAN role explicitly.
  45. *
  46. * Parameters: p_register - contains all callback function pointers
  47. *
  48. *
  49. * Returns none
  50. *
  51. ******************************************************************************/
  52. void PAN_Register(tPAN_REGISTER* p_register) {
  53. BTM_SetDiscoverability(BTM_GENERAL_DISCOVERABLE, 0, 0);
  54. BTM_SetConnectability(BTM_CONNECTABLE, 0, 0);
  55. pan_register_with_bnep();
  56. if (!p_register) return;
  57. pan_cb.pan_conn_state_cb = p_register->pan_conn_state_cb;
  58. pan_cb.pan_bridge_req_cb = p_register->pan_bridge_req_cb;
  59. pan_cb.pan_data_buf_ind_cb = p_register->pan_data_buf_ind_cb;
  60. pan_cb.pan_data_ind_cb = p_register->pan_data_ind_cb;
  61. pan_cb.pan_pfilt_ind_cb = p_register->pan_pfilt_ind_cb;
  62. pan_cb.pan_mfilt_ind_cb = p_register->pan_mfilt_ind_cb;
  63. pan_cb.pan_tx_data_flow_cb = p_register->pan_tx_data_flow_cb;
  64. return;
  65. }
  66. /*******************************************************************************
  67. *
  68. * Function PAN_Deregister
  69. *
  70. * Description This function is called by the application to de-register
  71. * its callbacks with PAN profile. This will make the PAN to
  72. * become inactive. This will deregister PAN services from SDP
  73. * and close all active connections
  74. *
  75. * Parameters: none
  76. *
  77. *
  78. * Returns none
  79. *
  80. ******************************************************************************/
  81. void PAN_Deregister(void) {
  82. pan_cb.pan_bridge_req_cb = NULL;
  83. pan_cb.pan_data_buf_ind_cb = NULL;
  84. pan_cb.pan_data_ind_cb = NULL;
  85. pan_cb.pan_conn_state_cb = NULL;
  86. pan_cb.pan_pfilt_ind_cb = NULL;
  87. pan_cb.pan_mfilt_ind_cb = NULL;
  88. PAN_SetRole(PAN_ROLE_INACTIVE, NULL, NULL, NULL, NULL);
  89. BNEP_Deregister();
  90. return;
  91. }
  92. /*******************************************************************************
  93. *
  94. * Function PAN_SetRole
  95. *
  96. * Description This function is called by the application to set the PAN
  97. * profile role. This should be called after PAN_Register.
  98. * This can be called any time to change the PAN role
  99. *
  100. * Parameters: role - is bit map of roles to be active
  101. * PAN_ROLE_CLIENT is for PANU role
  102. * PAN_ROLE_GN_SERVER is for GN role
  103. * PAN_ROLE_NAP_SERVER is for NAP role
  104. * sec_mask - Security mask for different roles
  105. * It is array of uint8_t. The bytes
  106. * represent the security for roles PANU,
  107. * GN and NAP in order
  108. * p_user_name - Service name for PANU role
  109. * p_gn_name - Service name for GN role
  110. * p_nap_name - Service name for NAP role
  111. * Can be NULL if user wants the default
  112. *
  113. * Returns PAN_SUCCESS - if the role is set successfully
  114. * PAN_FAILURE - if the role is not valid
  115. *
  116. ******************************************************************************/
  117. tPAN_RESULT PAN_SetRole(uint8_t role, uint8_t* sec_mask,
  118. const char* p_user_name, const char* p_gn_name,
  119. const char* p_nap_name) {
  120. const char* p_desc;
  121. uint8_t security[3] = {PAN_PANU_SECURITY_LEVEL, PAN_GN_SECURITY_LEVEL,
  122. PAN_NAP_SECURITY_LEVEL};
  123. uint8_t* p_sec;
  124. /* If the role is not a valid combination reject it */
  125. if ((!(role &
  126. (PAN_ROLE_CLIENT | PAN_ROLE_GN_SERVER | PAN_ROLE_NAP_SERVER))) &&
  127. role != PAN_ROLE_INACTIVE) {
  128. PAN_TRACE_ERROR("PAN role %d is invalid", role);
  129. return PAN_FAILURE;
  130. }
  131. /* If the current active role is same as the role being set do nothing */
  132. if (pan_cb.role == role) {
  133. PAN_TRACE_EVENT("PAN role already was set to: %d", role);
  134. return PAN_SUCCESS;
  135. }
  136. if (!sec_mask)
  137. p_sec = security;
  138. else
  139. p_sec = sec_mask;
  140. /* Register all the roles with SDP */
  141. PAN_TRACE_API("PAN_SetRole() called with role 0x%x", role);
  142. #if (PAN_SUPPORTS_ROLE_NAP == TRUE)
  143. if (role & PAN_ROLE_NAP_SERVER) {
  144. /* Check the service name */
  145. if ((p_nap_name == NULL) || (*p_nap_name == 0))
  146. p_nap_name = PAN_NAP_DEFAULT_SERVICE_NAME;
  147. /* Registering for NAP service with SDP */
  148. p_desc = PAN_NAP_DEFAULT_DESCRIPTION;
  149. if (pan_cb.pan_nap_sdp_handle != 0)
  150. SDP_DeleteRecord(pan_cb.pan_nap_sdp_handle);
  151. pan_cb.pan_nap_sdp_handle =
  152. pan_register_with_sdp(UUID_SERVCLASS_NAP, p_sec[2], p_nap_name, p_desc);
  153. bta_sys_add_uuid(UUID_SERVCLASS_NAP);
  154. }
  155. /* If the NAP role is already active and now being cleared delete the record
  156. */
  157. else if (pan_cb.role & PAN_ROLE_NAP_SERVER) {
  158. if (pan_cb.pan_nap_sdp_handle != 0) {
  159. SDP_DeleteRecord(pan_cb.pan_nap_sdp_handle);
  160. pan_cb.pan_nap_sdp_handle = 0;
  161. bta_sys_remove_uuid(UUID_SERVCLASS_NAP);
  162. }
  163. }
  164. #endif
  165. #if (PAN_SUPPORTS_ROLE_GN == TRUE)
  166. if (role & PAN_ROLE_GN_SERVER) {
  167. /* Check the service name */
  168. if ((p_gn_name == NULL) || (*p_gn_name == 0))
  169. p_gn_name = PAN_GN_DEFAULT_SERVICE_NAME;
  170. /* Registering for GN service with SDP */
  171. p_desc = PAN_GN_DEFAULT_DESCRIPTION;
  172. if (pan_cb.pan_gn_sdp_handle != 0)
  173. SDP_DeleteRecord(pan_cb.pan_gn_sdp_handle);
  174. pan_cb.pan_gn_sdp_handle =
  175. pan_register_with_sdp(UUID_SERVCLASS_GN, p_sec[1], p_gn_name, p_desc);
  176. bta_sys_add_uuid(UUID_SERVCLASS_GN);
  177. }
  178. /* If the GN role is already active and now being cleared delete the record */
  179. else if (pan_cb.role & PAN_ROLE_GN_SERVER) {
  180. if (pan_cb.pan_gn_sdp_handle != 0) {
  181. SDP_DeleteRecord(pan_cb.pan_gn_sdp_handle);
  182. pan_cb.pan_gn_sdp_handle = 0;
  183. bta_sys_remove_uuid(UUID_SERVCLASS_GN);
  184. }
  185. }
  186. #endif
  187. #if (PAN_SUPPORTS_ROLE_PANU == TRUE)
  188. if (role & PAN_ROLE_CLIENT) {
  189. /* Check the service name */
  190. if ((p_user_name == NULL) || (*p_user_name == 0))
  191. p_user_name = PAN_PANU_DEFAULT_SERVICE_NAME;
  192. /* Registering for PANU service with SDP */
  193. p_desc = PAN_PANU_DEFAULT_DESCRIPTION;
  194. if (pan_cb.pan_user_sdp_handle != 0)
  195. SDP_DeleteRecord(pan_cb.pan_user_sdp_handle);
  196. pan_cb.pan_user_sdp_handle = pan_register_with_sdp(
  197. UUID_SERVCLASS_PANU, p_sec[0], p_user_name, p_desc);
  198. bta_sys_add_uuid(UUID_SERVCLASS_PANU);
  199. }
  200. /* If the PANU role is already active and now being cleared delete the record
  201. */
  202. else if (pan_cb.role & PAN_ROLE_CLIENT) {
  203. if (pan_cb.pan_user_sdp_handle != 0) {
  204. SDP_DeleteRecord(pan_cb.pan_user_sdp_handle);
  205. pan_cb.pan_user_sdp_handle = 0;
  206. bta_sys_remove_uuid(UUID_SERVCLASS_PANU);
  207. }
  208. }
  209. #endif
  210. /* Check if it is a shutdown request */
  211. if (role == PAN_ROLE_INACTIVE) pan_close_all_connections();
  212. pan_cb.role = role;
  213. PAN_TRACE_EVENT("PAN role set to: %d", role);
  214. return PAN_SUCCESS;
  215. }
  216. /*******************************************************************************
  217. *
  218. * Function PAN_Connect
  219. *
  220. * Description This function is called by the application to initiate a
  221. * connection to the remote device
  222. *
  223. * Parameters: rem_bda - BD Addr of the remote device
  224. * src_role - Role of the local device for the connection
  225. * dst_role - Role of the remote device for the connection
  226. * PAN_ROLE_CLIENT is for PANU role
  227. * PAN_ROLE_GN_SERVER is for GN role
  228. * PAN_ROLE_NAP_SERVER is for NAP role
  229. * *handle - Pointer for returning Handle to the connection
  230. *
  231. * Returns PAN_SUCCESS - if the connection is initiated
  232. * successfully
  233. * PAN_NO_RESOURCES - resources are not sufficent
  234. * PAN_FAILURE - if the connection cannot be initiated
  235. * this can be because of the combination of
  236. * src and dst roles may not be valid or
  237. * allowed at that point of time
  238. *
  239. ******************************************************************************/
  240. tPAN_RESULT PAN_Connect(const RawAddress& rem_bda, uint8_t src_role,
  241. uint8_t dst_role, uint16_t* handle) {
  242. uint32_t mx_chan_id;
  243. /*
  244. ** Initialize the handle so that in case of failure return values
  245. ** the profile will not get confused
  246. */
  247. *handle = BNEP_INVALID_HANDLE;
  248. /* Check if PAN is active or not */
  249. if (!(pan_cb.role & src_role)) {
  250. PAN_TRACE_ERROR("PAN is not active for the role %d", src_role);
  251. return PAN_FAILURE;
  252. }
  253. /* Validate the parameters before proceeding */
  254. if ((src_role != PAN_ROLE_CLIENT && src_role != PAN_ROLE_GN_SERVER &&
  255. src_role != PAN_ROLE_NAP_SERVER) ||
  256. (dst_role != PAN_ROLE_CLIENT && dst_role != PAN_ROLE_GN_SERVER &&
  257. dst_role != PAN_ROLE_NAP_SERVER)) {
  258. PAN_TRACE_ERROR("Either source %d or destination role %d is invalid",
  259. src_role, dst_role);
  260. return PAN_FAILURE;
  261. }
  262. /* Check if connection exists for this remote device */
  263. tPAN_CONN* pcb = pan_get_pcb_by_addr(rem_bda);
  264. uint16_t src_uuid, dst_uuid;
  265. /* If we are PANU for this role validate destination role */
  266. if (src_role == PAN_ROLE_CLIENT) {
  267. if ((pan_cb.num_conns > 1) || (pan_cb.num_conns && (!pcb))) {
  268. /*
  269. ** If the request is not for existing connection reject it
  270. ** because if there is already a connection we cannot accept
  271. ** another connection in PANU role
  272. */
  273. PAN_TRACE_ERROR(
  274. "Cannot make PANU connections when there are more than one "
  275. "connection");
  276. return PAN_INVALID_SRC_ROLE;
  277. }
  278. src_uuid = UUID_SERVCLASS_PANU;
  279. if (dst_role == PAN_ROLE_CLIENT) {
  280. dst_uuid = UUID_SERVCLASS_PANU;
  281. } else if (dst_role == PAN_ROLE_GN_SERVER) {
  282. dst_uuid = UUID_SERVCLASS_GN;
  283. } else {
  284. dst_uuid = UUID_SERVCLASS_NAP;
  285. }
  286. mx_chan_id = dst_uuid;
  287. }
  288. /* If destination is PANU role validate source role */
  289. else if (dst_role == PAN_ROLE_CLIENT) {
  290. if (pan_cb.num_conns && pan_cb.active_role == PAN_ROLE_CLIENT && !pcb) {
  291. PAN_TRACE_ERROR("Device already have a connection in PANU role");
  292. return PAN_INVALID_SRC_ROLE;
  293. }
  294. dst_uuid = UUID_SERVCLASS_PANU;
  295. if (src_role == PAN_ROLE_GN_SERVER) {
  296. src_uuid = UUID_SERVCLASS_GN;
  297. } else {
  298. src_uuid = UUID_SERVCLASS_NAP;
  299. }
  300. mx_chan_id = src_uuid;
  301. }
  302. /* The role combination is not valid */
  303. else {
  304. PAN_TRACE_ERROR(
  305. "Source %d and Destination roles %d are not valid combination",
  306. src_role, dst_role);
  307. return PAN_FAILURE;
  308. }
  309. /* Allocate control block and initiate connection */
  310. if (!pcb) pcb = pan_allocate_pcb(rem_bda, BNEP_INVALID_HANDLE);
  311. if (!pcb) {
  312. PAN_TRACE_ERROR("PAN Connection failed because of no resources");
  313. return PAN_NO_RESOURCES;
  314. }
  315. BTM_SetOutService(rem_bda, BTM_SEC_SERVICE_BNEP_PANU, mx_chan_id);
  316. VLOG(0) << __func__ << " for BD Addr: " << rem_bda;
  317. if (pcb->con_state == PAN_STATE_IDLE) {
  318. pan_cb.num_conns++;
  319. } else if (pcb->con_state == PAN_STATE_CONNECTED) {
  320. pcb->con_flags |= PAN_FLAGS_CONN_COMPLETED;
  321. } else
  322. /* PAN connection is still in progress */
  323. return PAN_WRONG_STATE;
  324. pcb->con_state = PAN_STATE_CONN_START;
  325. pcb->prv_src_uuid = pcb->src_uuid;
  326. pcb->prv_dst_uuid = pcb->dst_uuid;
  327. pcb->src_uuid = src_uuid;
  328. pcb->dst_uuid = dst_uuid;
  329. tBNEP_RESULT ret = BNEP_Connect(rem_bda, Uuid::From16Bit(src_uuid),
  330. Uuid::From16Bit(dst_uuid), &(pcb->handle));
  331. if (ret != BNEP_SUCCESS) {
  332. pan_release_pcb(pcb);
  333. return ret;
  334. }
  335. PAN_TRACE_DEBUG("PAN_Connect() current active role set to %d", src_role);
  336. pan_cb.prv_active_role = pan_cb.active_role;
  337. pan_cb.active_role = src_role;
  338. *handle = pcb->handle;
  339. return PAN_SUCCESS;
  340. }
  341. /*******************************************************************************
  342. *
  343. * Function PAN_Disconnect
  344. *
  345. * Description This is used to disconnect the connection
  346. *
  347. * Parameters: handle - handle for the connection
  348. *
  349. * Returns PAN_SUCCESS - if the connection is closed successfully
  350. * PAN_FAILURE - if the connection is not found or
  351. * there is an error in disconnecting
  352. *
  353. ******************************************************************************/
  354. tPAN_RESULT PAN_Disconnect(uint16_t handle) {
  355. tPAN_CONN* pcb;
  356. tBNEP_RESULT result;
  357. /* Check if the connection exists */
  358. pcb = pan_get_pcb_by_handle(handle);
  359. if (!pcb) {
  360. PAN_TRACE_ERROR("PAN connection not found for the handle %d", handle);
  361. return PAN_FAILURE;
  362. }
  363. result = BNEP_Disconnect(pcb->handle);
  364. if (pcb->con_state != PAN_STATE_IDLE) pan_cb.num_conns--;
  365. if (pan_cb.pan_bridge_req_cb && pcb->src_uuid == UUID_SERVCLASS_NAP)
  366. (*pan_cb.pan_bridge_req_cb)(pcb->rem_bda, false);
  367. pan_release_pcb(pcb);
  368. if (result != BNEP_SUCCESS) {
  369. PAN_TRACE_EVENT("Error in closing PAN connection");
  370. return PAN_FAILURE;
  371. }
  372. PAN_TRACE_EVENT("PAN connection closed");
  373. return PAN_SUCCESS;
  374. }
  375. /*******************************************************************************
  376. *
  377. * Function PAN_Write
  378. *
  379. * Description This sends data over the PAN connections. If this is called
  380. * on GN or NAP side and the packet is multicast or broadcast
  381. * it will be sent on all the links. Otherwise the correct link
  382. * is found based on the destination address and forwarded on
  383. * it.
  384. *
  385. * Parameters: handle - handle for the connection
  386. * dst - MAC or BD Addr of the destination device
  387. * src - MAC or BD Addr of the source who sent this packet
  388. * protocol - protocol of the ethernet packet like IP or ARP
  389. * p_data - pointer to the data
  390. * len - length of the data
  391. * ext - to indicate that extension headers present
  392. *
  393. * Returns PAN_SUCCESS - if the data is sent successfully
  394. * PAN_FAILURE - if the connection is not found or
  395. * there is an error in sending data
  396. *
  397. ******************************************************************************/
  398. tPAN_RESULT PAN_Write(uint16_t handle, const RawAddress& dst,
  399. const RawAddress& src, uint16_t protocol, uint8_t* p_data,
  400. uint16_t len, bool ext) {
  401. if (pan_cb.role == PAN_ROLE_INACTIVE || !pan_cb.num_conns) {
  402. PAN_TRACE_ERROR("%s PAN is not active, data write failed.", __func__);
  403. return PAN_FAILURE;
  404. }
  405. // If the packet is broadcast or multicast, we're going to have to create
  406. // a copy of the packet for each connection. We can save one extra copy
  407. // by fast-pathing here and calling BNEP_Write instead of placing the packet
  408. // in a BT_HDR buffer, calling BNEP_Write, and then freeing the buffer.
  409. if (dst.address[0] & 0x01) {
  410. int i;
  411. for (i = 0; i < MAX_PAN_CONNS; ++i) {
  412. if (pan_cb.pcb[i].con_state == PAN_STATE_CONNECTED)
  413. BNEP_Write(pan_cb.pcb[i].handle, dst, p_data, len, protocol, &src, ext);
  414. }
  415. return PAN_SUCCESS;
  416. }
  417. BT_HDR* buffer = (BT_HDR*)osi_malloc(PAN_BUF_SIZE);
  418. buffer->len = len;
  419. buffer->offset = PAN_MINIMUM_OFFSET;
  420. memcpy((uint8_t*)buffer + sizeof(BT_HDR) + buffer->offset, p_data,
  421. buffer->len);
  422. return PAN_WriteBuf(handle, dst, src, protocol, buffer, ext);
  423. }
  424. /*******************************************************************************
  425. *
  426. * Function PAN_WriteBuf
  427. *
  428. * Description This sends data over the PAN connections. If this is called
  429. * on GN or NAP side and the packet is multicast or broadcast
  430. * it will be sent on all the links. Otherwise the correct link
  431. * is found based on the destination address and forwarded on
  432. * it. If the return value is not PAN_SUCCESS, the application
  433. * should take care of releasing the message buffer.
  434. *
  435. * Parameters: handle - handle for the connection
  436. * dst - MAC or BD Addr of the destination device
  437. * src - MAC or BD Addr of the source who sent this packet
  438. * protocol - protocol of the ethernet packet like IP or ARP
  439. * p_buf - pointer to the data buffer
  440. * ext - to indicate that extension headers present
  441. *
  442. * Returns PAN_SUCCESS - if the data is sent successfully
  443. * PAN_FAILURE - if the connection is not found or
  444. * there is an error in sending data
  445. *
  446. ******************************************************************************/
  447. tPAN_RESULT PAN_WriteBuf(uint16_t handle, const RawAddress& dst,
  448. const RawAddress& src, uint16_t protocol,
  449. BT_HDR* p_buf, bool ext) {
  450. tPAN_CONN* pcb;
  451. uint16_t i;
  452. tBNEP_RESULT result;
  453. if (pan_cb.role == PAN_ROLE_INACTIVE || (!(pan_cb.num_conns))) {
  454. PAN_TRACE_ERROR("PAN is not active Data write failed");
  455. osi_free(p_buf);
  456. return PAN_FAILURE;
  457. }
  458. /* Check if it is broadcast or multicast packet */
  459. if (dst.address[0] & 0x01) {
  460. uint8_t* data = (uint8_t*)p_buf + sizeof(BT_HDR) + p_buf->offset;
  461. for (i = 0; i < MAX_PAN_CONNS; ++i) {
  462. if (pan_cb.pcb[i].con_state == PAN_STATE_CONNECTED)
  463. BNEP_Write(pan_cb.pcb[i].handle, dst, data, p_buf->len, protocol, &src,
  464. ext);
  465. }
  466. osi_free(p_buf);
  467. return PAN_SUCCESS;
  468. }
  469. /* Check if the data write is on PANU side */
  470. if (pan_cb.active_role == PAN_ROLE_CLIENT) {
  471. /* Data write is on PANU connection */
  472. for (i = 0; i < MAX_PAN_CONNS; i++) {
  473. if (pan_cb.pcb[i].con_state == PAN_STATE_CONNECTED &&
  474. pan_cb.pcb[i].src_uuid == UUID_SERVCLASS_PANU)
  475. break;
  476. }
  477. if (i == MAX_PAN_CONNS) {
  478. PAN_TRACE_ERROR("PAN Don't have any user connections");
  479. osi_free(p_buf);
  480. return PAN_FAILURE;
  481. }
  482. result =
  483. BNEP_WriteBuf(pan_cb.pcb[i].handle, dst, p_buf, protocol, &src, ext);
  484. if (result == BNEP_IGNORE_CMD) {
  485. PAN_TRACE_DEBUG("PAN ignored data write for PANU connection");
  486. return result;
  487. } else if (result != BNEP_SUCCESS) {
  488. PAN_TRACE_ERROR("PAN failed to write data for the PANU connection");
  489. return result;
  490. }
  491. PAN_TRACE_DEBUG("PAN successfully wrote data for the PANU connection");
  492. return PAN_SUCCESS;
  493. }
  494. /* findout to which connection the data is meant for */
  495. pcb = pan_get_pcb_by_handle(handle);
  496. if (!pcb) {
  497. PAN_TRACE_ERROR("PAN Buf write for wrong handle");
  498. osi_free(p_buf);
  499. return PAN_FAILURE;
  500. }
  501. if (pcb->con_state != PAN_STATE_CONNECTED) {
  502. PAN_TRACE_ERROR("PAN Buf write when conn is not active");
  503. osi_free(p_buf);
  504. return PAN_FAILURE;
  505. }
  506. result = BNEP_WriteBuf(pcb->handle, dst, p_buf, protocol, &src, ext);
  507. if (result == BNEP_IGNORE_CMD) {
  508. PAN_TRACE_DEBUG("PAN ignored data buf write to PANU");
  509. return result;
  510. } else if (result != BNEP_SUCCESS) {
  511. PAN_TRACE_ERROR("PAN failed to send data buf to the PANU");
  512. return result;
  513. }
  514. PAN_TRACE_DEBUG("PAN successfully sent data buf to the PANU");
  515. return PAN_SUCCESS;
  516. }
  517. /*******************************************************************************
  518. *
  519. * Function PAN_SetProtocolFilters
  520. *
  521. * Description This function is used to set protocol filters on the peer
  522. *
  523. * Parameters: handle - handle for the connection
  524. * num_filters - number of protocol filter ranges
  525. * start - array of starting protocol numbers
  526. * end - array of ending protocol numbers
  527. *
  528. *
  529. * Returns PAN_SUCCESS if protocol filters are set successfully
  530. * PAN_FAILURE if connection not found or error in setting
  531. *
  532. ******************************************************************************/
  533. tPAN_RESULT PAN_SetProtocolFilters(uint16_t handle, uint16_t num_filters,
  534. uint16_t* p_start_array,
  535. uint16_t* p_end_array) {
  536. tPAN_CONN* pcb;
  537. tPAN_RESULT result;
  538. /* Check if the connection exists */
  539. pcb = pan_get_pcb_by_handle(handle);
  540. if (!pcb) {
  541. PAN_TRACE_ERROR("PAN connection not found for the handle %d", handle);
  542. return PAN_FAILURE;
  543. }
  544. result = BNEP_SetProtocolFilters(pcb->handle, num_filters, p_start_array,
  545. p_end_array);
  546. if (result != BNEP_SUCCESS) {
  547. PAN_TRACE_ERROR("PAN failed to set protocol filters for handle %d", handle);
  548. return result;
  549. }
  550. PAN_TRACE_API("PAN successfully sent protocol filters for handle %d", handle);
  551. return PAN_SUCCESS;
  552. }
  553. /*******************************************************************************
  554. *
  555. * Function PAN_SetMulticastFilters
  556. *
  557. * Description This function is used to set multicast filters on the peer
  558. *
  559. * Parameters: handle - handle for the connection
  560. * num_filters - number of multicast filter ranges
  561. * start - array of starting multicast filter addresses
  562. * end - array of ending multicast filter addresses
  563. *
  564. *
  565. * Returns PAN_SUCCESS if multicast filters are set successfully
  566. * PAN_FAILURE if connection not found or error in setting
  567. *
  568. ******************************************************************************/
  569. tBNEP_RESULT PAN_SetMulticastFilters(uint16_t handle,
  570. uint16_t num_mcast_filters,
  571. uint8_t* p_start_array,
  572. uint8_t* p_end_array) {
  573. tPAN_CONN* pcb;
  574. tPAN_RESULT result;
  575. /* Check if the connection exists */
  576. pcb = pan_get_pcb_by_handle(handle);
  577. if (!pcb) {
  578. PAN_TRACE_ERROR("PAN connection not found for the handle %d", handle);
  579. return PAN_FAILURE;
  580. }
  581. result = BNEP_SetMulticastFilters(pcb->handle, num_mcast_filters,
  582. p_start_array, p_end_array);
  583. if (result != BNEP_SUCCESS) {
  584. PAN_TRACE_ERROR("PAN failed to set multicast filters for handle %d",
  585. handle);
  586. return result;
  587. }
  588. PAN_TRACE_API("PAN successfully sent multicast filters for handle %d",
  589. handle);
  590. return PAN_SUCCESS;
  591. }
  592. /*******************************************************************************
  593. *
  594. * Function PAN_SetTraceLevel
  595. *
  596. * Description This function sets the trace level for PAN. If called with
  597. * a value of 0xFF, it simply reads the current trace level.
  598. *
  599. * Returns the new (current) trace level
  600. *
  601. ******************************************************************************/
  602. uint8_t PAN_SetTraceLevel(uint8_t new_level) {
  603. if (new_level != 0xFF)
  604. pan_cb.trace_level = new_level;
  605. else
  606. pan_dump_status();
  607. return (pan_cb.trace_level);
  608. }
  609. /*******************************************************************************
  610. *
  611. * Function PAN_Init
  612. *
  613. * Description This function initializes the PAN module variables
  614. *
  615. * Parameters: none
  616. *
  617. * Returns none
  618. *
  619. ******************************************************************************/
  620. void PAN_Init(void) {
  621. memset(&pan_cb, 0, sizeof(tPAN_CB));
  622. #if defined(PAN_INITIAL_TRACE_LEVEL)
  623. pan_cb.trace_level = PAN_INITIAL_TRACE_LEVEL;
  624. #else
  625. pan_cb.trace_level = BT_TRACE_LEVEL_NONE; /* No traces */
  626. #endif
  627. }