pan_main.cc 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651
  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 <string.h>
  25. #include "bnep_api.h"
  26. #include "bt_common.h"
  27. #include "bt_types.h"
  28. #include "bt_utils.h"
  29. #include "hcidefs.h"
  30. #include "l2c_api.h"
  31. #include "osi/include/osi.h"
  32. #include "pan_api.h"
  33. #include "pan_int.h"
  34. #include "sdp_api.h"
  35. #include "sdpdefs.h"
  36. using bluetooth::Uuid;
  37. tPAN_CB pan_cb;
  38. /*******************************************************************************
  39. *
  40. * Function pan_register_with_bnep
  41. *
  42. * Description This function registers PAN profile with BNEP
  43. *
  44. * Parameters: none
  45. *
  46. * Returns none
  47. *
  48. ******************************************************************************/
  49. void pan_register_with_bnep(void) {
  50. tBNEP_REGISTER reg_info;
  51. memset(&reg_info, 0, sizeof(tBNEP_REGISTER));
  52. reg_info.p_conn_ind_cb = pan_conn_ind_cb;
  53. reg_info.p_conn_state_cb = pan_connect_state_cb;
  54. reg_info.p_data_buf_cb = pan_data_buf_ind_cb;
  55. reg_info.p_data_ind_cb = NULL;
  56. reg_info.p_tx_data_flow_cb = pan_tx_data_flow_cb;
  57. reg_info.p_filter_ind_cb = pan_proto_filt_ind_cb;
  58. reg_info.p_mfilter_ind_cb = pan_mcast_filt_ind_cb;
  59. BNEP_Register(&reg_info);
  60. }
  61. /*******************************************************************************
  62. *
  63. * Function pan_conn_ind_cb
  64. *
  65. * Description This function is registered with BNEP as connection
  66. * indication callback. BNEP will call this when there is
  67. * connection request from the peer. PAN should call
  68. * BNEP_ConnectResp to indicate whether to accept the
  69. * connection or reject
  70. *
  71. * Parameters: handle - handle for the connection
  72. * p_bda - BD Addr of the peer requesting the connection
  73. * remote_uuid - UUID of the source role (peer device role)
  74. * local_uuid - UUID of the destination role (local device
  75. * role)
  76. * is_role_change - Flag to indicate that it is a role change
  77. *
  78. * Returns none
  79. *
  80. ******************************************************************************/
  81. void pan_conn_ind_cb(uint16_t handle, const RawAddress& p_bda,
  82. const Uuid& remote_uuid, const Uuid& local_uuid,
  83. bool is_role_change) {
  84. /* If we are in GN or NAP role and have one or more active connections and the
  85. * received connection is for user role reject it. If we are in user role with
  86. * one connection active reject the connection. Allocate PCB and store the
  87. * parameters. Make bridge request to the host system if connection is for NAP
  88. */
  89. if (!remote_uuid.Is16Bit()) {
  90. PAN_TRACE_ERROR("PAN Connection failed because of wrong remote UUID ");
  91. BNEP_ConnectResp(handle, BNEP_CONN_FAILED_SRC_UUID);
  92. return;
  93. }
  94. if (!local_uuid.Is16Bit()) {
  95. PAN_TRACE_ERROR("PAN Connection failed because of wrong local UUID ");
  96. BNEP_ConnectResp(handle, BNEP_CONN_FAILED_DST_UUID);
  97. return;
  98. }
  99. uint16_t remote_uuid16 = remote_uuid.As16Bit();
  100. uint16_t local_uuid16 = local_uuid.As16Bit();
  101. PAN_TRACE_EVENT(
  102. "%s - handle %d, current role %d, dst uuid 0x%x, src uuid 0x%x, role "
  103. "change %s",
  104. __func__, handle, pan_cb.role, local_uuid16, remote_uuid16,
  105. is_role_change ? "YES" : "NO");
  106. /* Check if the source UUID is a valid one */
  107. if (remote_uuid16 != UUID_SERVCLASS_PANU &&
  108. remote_uuid16 != UUID_SERVCLASS_NAP &&
  109. remote_uuid16 != UUID_SERVCLASS_GN) {
  110. PAN_TRACE_ERROR("Src UUID 0x%x is not valid", remote_uuid16);
  111. BNEP_ConnectResp(handle, BNEP_CONN_FAILED_SRC_UUID);
  112. return;
  113. }
  114. /* Check if the destination UUID is a valid one */
  115. if (local_uuid16 != UUID_SERVCLASS_PANU &&
  116. local_uuid16 != UUID_SERVCLASS_NAP && local_uuid16 != UUID_SERVCLASS_GN) {
  117. PAN_TRACE_ERROR("Dst UUID 0x%x is not valid", local_uuid16);
  118. BNEP_ConnectResp(handle, BNEP_CONN_FAILED_DST_UUID);
  119. return;
  120. }
  121. /* Check if currently we support the destination role requested */
  122. if (((!(pan_cb.role & UUID_SERVCLASS_PANU)) &&
  123. local_uuid16 == UUID_SERVCLASS_PANU) ||
  124. ((!(pan_cb.role & UUID_SERVCLASS_GN)) &&
  125. local_uuid16 == UUID_SERVCLASS_GN) ||
  126. ((!(pan_cb.role & UUID_SERVCLASS_NAP)) &&
  127. local_uuid16 == UUID_SERVCLASS_NAP)) {
  128. PAN_TRACE_ERROR(
  129. "PAN Connection failed because of unsupported destination UUID 0x%x",
  130. local_uuid16);
  131. BNEP_ConnectResp(handle, BNEP_CONN_FAILED_DST_UUID);
  132. return;
  133. }
  134. /* Check for valid interactions between the three PAN profile roles */
  135. /*
  136. * For reference, see Table 1 in PAN Profile v1.0 spec.
  137. * Note: the remote is the initiator.
  138. */
  139. bool is_valid_interaction = false;
  140. switch (remote_uuid16) {
  141. case UUID_SERVCLASS_NAP:
  142. case UUID_SERVCLASS_GN:
  143. if (local_uuid16 == UUID_SERVCLASS_PANU) is_valid_interaction = true;
  144. break;
  145. case UUID_SERVCLASS_PANU:
  146. is_valid_interaction = true;
  147. break;
  148. }
  149. /*
  150. * Explicitly disable connections to the local PANU if the remote is
  151. * not PANU.
  152. */
  153. if ((local_uuid16 == UUID_SERVCLASS_PANU) &&
  154. (remote_uuid16 != UUID_SERVCLASS_PANU)) {
  155. is_valid_interaction = false;
  156. }
  157. if (!is_valid_interaction) {
  158. PAN_TRACE_ERROR(
  159. "PAN Connection failed because of invalid PAN profile roles "
  160. "interaction: Remote UUID 0x%x Local UUID 0x%x",
  161. remote_uuid16, local_uuid16);
  162. BNEP_ConnectResp(handle, BNEP_CONN_FAILED_SRC_UUID);
  163. return;
  164. }
  165. uint8_t req_role;
  166. /* Requested destination role is */
  167. if (local_uuid16 == UUID_SERVCLASS_PANU)
  168. req_role = PAN_ROLE_CLIENT;
  169. else if (local_uuid16 == UUID_SERVCLASS_GN)
  170. req_role = PAN_ROLE_GN_SERVER;
  171. else
  172. req_role = PAN_ROLE_NAP_SERVER;
  173. /* If the connection indication is for the existing connection
  174. ** Check if the new destination role is acceptable
  175. */
  176. tPAN_CONN* pcb = pan_get_pcb_by_handle(handle);
  177. if (pcb) {
  178. if (pan_cb.num_conns > 1 && local_uuid16 == UUID_SERVCLASS_PANU) {
  179. /* There are connections other than this one
  180. ** so we cann't accept PANU role. Reject
  181. */
  182. PAN_TRACE_ERROR(
  183. "Dst UUID should be either GN or NAP only because there are other "
  184. "connections");
  185. BNEP_ConnectResp(handle, BNEP_CONN_FAILED_DST_UUID);
  186. return;
  187. }
  188. /* If it is already in connected state check for bridging status */
  189. if (pcb->con_state == PAN_STATE_CONNECTED) {
  190. PAN_TRACE_EVENT("PAN Role changing New Src 0x%x Dst 0x%x", remote_uuid16,
  191. local_uuid16);
  192. pcb->prv_src_uuid = pcb->src_uuid;
  193. pcb->prv_dst_uuid = pcb->dst_uuid;
  194. if (pcb->src_uuid == UUID_SERVCLASS_NAP &&
  195. local_uuid16 != UUID_SERVCLASS_NAP) {
  196. /* Remove bridging */
  197. if (pan_cb.pan_bridge_req_cb)
  198. (*pan_cb.pan_bridge_req_cb)(pcb->rem_bda, false);
  199. }
  200. }
  201. /* Set the latest active PAN role */
  202. pan_cb.active_role = req_role;
  203. pcb->src_uuid = local_uuid16;
  204. pcb->dst_uuid = remote_uuid16;
  205. BNEP_ConnectResp(handle, BNEP_SUCCESS);
  206. return;
  207. } else {
  208. /* If this a new connection and destination is PANU role and
  209. ** we already have a connection then reject the request.
  210. ** If we have a connection in PANU role then reject it
  211. */
  212. if (pan_cb.num_conns && (local_uuid16 == UUID_SERVCLASS_PANU ||
  213. pan_cb.active_role == PAN_ROLE_CLIENT)) {
  214. PAN_TRACE_ERROR("PAN already have a connection and can't be user");
  215. BNEP_ConnectResp(handle, BNEP_CONN_FAILED_DST_UUID);
  216. return;
  217. }
  218. }
  219. /* This is a new connection */
  220. PAN_TRACE_DEBUG("New connection indication for handle %d", handle);
  221. pcb = pan_allocate_pcb(p_bda, handle);
  222. if (!pcb) {
  223. PAN_TRACE_ERROR("PAN no control block for new connection");
  224. BNEP_ConnectResp(handle, BNEP_CONN_FAILED);
  225. return;
  226. }
  227. PAN_TRACE_EVENT("PAN connection destination UUID is 0x%x", local_uuid16);
  228. /* Set the latest active PAN role */
  229. pan_cb.active_role = req_role;
  230. pcb->src_uuid = local_uuid16;
  231. pcb->dst_uuid = remote_uuid16;
  232. pcb->con_state = PAN_STATE_CONN_START;
  233. pan_cb.num_conns++;
  234. BNEP_ConnectResp(handle, BNEP_SUCCESS);
  235. return;
  236. }
  237. /*******************************************************************************
  238. *
  239. * Function pan_connect_state_cb
  240. *
  241. * Description This function is registered with BNEP as connection state
  242. * change callback. BNEP will call this when the connection
  243. * is established successfully or terminated
  244. *
  245. * Parameters: handle - handle for the connection given in the connection
  246. * indication callback
  247. * rem_bda - remote device bd addr
  248. * result - indicates whether the connection is up or down
  249. * BNEP_SUCCESS if the connection is up all other
  250. * values indicate appropriate errors.
  251. * is_role_change - flag to indicate that it is a role change
  252. *
  253. * Returns none
  254. *
  255. ******************************************************************************/
  256. void pan_connect_state_cb(uint16_t handle,
  257. UNUSED_ATTR const RawAddress& rem_bda,
  258. tBNEP_RESULT result, bool is_role_change) {
  259. tPAN_CONN* pcb;
  260. uint8_t peer_role;
  261. PAN_TRACE_EVENT("pan_connect_state_cb - for handle %d, result %d", handle,
  262. result);
  263. pcb = pan_get_pcb_by_handle(handle);
  264. if (!pcb) {
  265. PAN_TRACE_ERROR("PAN State change indication for wrong handle %d", handle);
  266. return;
  267. }
  268. /* If the connection is getting terminated remove bridging */
  269. if (result != BNEP_SUCCESS) {
  270. /* Inform the application that connection is down */
  271. if (pan_cb.pan_conn_state_cb)
  272. (*pan_cb.pan_conn_state_cb)(pcb->handle, pcb->rem_bda, result,
  273. is_role_change, PAN_ROLE_INACTIVE,
  274. PAN_ROLE_INACTIVE);
  275. /* Check if this failure is for role change only */
  276. if (pcb->con_state != PAN_STATE_CONNECTED &&
  277. (pcb->con_flags & PAN_FLAGS_CONN_COMPLETED)) {
  278. /* restore the original values */
  279. PAN_TRACE_EVENT("restoring the connection state to active");
  280. pcb->con_state = PAN_STATE_CONNECTED;
  281. pcb->con_flags &= (~PAN_FLAGS_CONN_COMPLETED);
  282. pcb->src_uuid = pcb->prv_src_uuid;
  283. pcb->dst_uuid = pcb->prv_dst_uuid;
  284. pan_cb.active_role = pan_cb.prv_active_role;
  285. if ((pcb->src_uuid == UUID_SERVCLASS_NAP) && pan_cb.pan_bridge_req_cb)
  286. (*pan_cb.pan_bridge_req_cb)(pcb->rem_bda, true);
  287. return;
  288. }
  289. if (pcb->con_state == PAN_STATE_CONNECTED) {
  290. /* If the connections destination role is NAP remove bridging */
  291. if ((pcb->src_uuid == UUID_SERVCLASS_NAP) && pan_cb.pan_bridge_req_cb)
  292. (*pan_cb.pan_bridge_req_cb)(pcb->rem_bda, false);
  293. }
  294. pan_cb.num_conns--;
  295. pan_release_pcb(pcb);
  296. return;
  297. }
  298. /* Requested destination role is */
  299. if (pcb->src_uuid == UUID_SERVCLASS_PANU)
  300. pan_cb.active_role = PAN_ROLE_CLIENT;
  301. else if (pcb->src_uuid == UUID_SERVCLASS_GN)
  302. pan_cb.active_role = PAN_ROLE_GN_SERVER;
  303. else
  304. pan_cb.active_role = PAN_ROLE_NAP_SERVER;
  305. if (pcb->dst_uuid == UUID_SERVCLASS_PANU)
  306. peer_role = PAN_ROLE_CLIENT;
  307. else if (pcb->dst_uuid == UUID_SERVCLASS_GN)
  308. peer_role = PAN_ROLE_GN_SERVER;
  309. else
  310. peer_role = PAN_ROLE_NAP_SERVER;
  311. pcb->con_state = PAN_STATE_CONNECTED;
  312. /* Inform the application that connection is down */
  313. if (pan_cb.pan_conn_state_cb)
  314. (*pan_cb.pan_conn_state_cb)(pcb->handle, pcb->rem_bda, PAN_SUCCESS,
  315. is_role_change, pan_cb.active_role, peer_role);
  316. /* Create bridge if the destination role is NAP */
  317. if (pan_cb.pan_bridge_req_cb && pcb->src_uuid == UUID_SERVCLASS_NAP) {
  318. PAN_TRACE_EVENT("PAN requesting for bridge");
  319. (*pan_cb.pan_bridge_req_cb)(pcb->rem_bda, true);
  320. }
  321. }
  322. /*******************************************************************************
  323. *
  324. * Function pan_data_ind_cb
  325. *
  326. * Description This function is registered with BNEP as data indication
  327. * callback. BNEP will call this when the peer sends any data
  328. * on this connection
  329. *
  330. * Parameters: handle - handle for the connection
  331. * src - source BD Addr
  332. * dst - destination BD Addr
  333. * protocol - Network protocol of the Eth packet
  334. * p_data - pointer to the data
  335. * len - length of the data
  336. * fw_ext_present - to indicate whether the data contains any
  337. * extension headers before the payload
  338. *
  339. * Returns none
  340. *
  341. ******************************************************************************/
  342. void pan_data_ind_cb(uint16_t handle, const RawAddress& src,
  343. const RawAddress& dst, uint16_t protocol, uint8_t* p_data,
  344. uint16_t len, bool ext) {
  345. tPAN_CONN* pcb;
  346. uint16_t i;
  347. bool forward;
  348. /*
  349. ** Check the connection status
  350. ** If the destination address is MAC broadcast send on all links
  351. ** except on the one received
  352. ** If the destination uuid is for NAP send to host system also
  353. ** If the destination address is one of the devices connected
  354. ** send the packet to over that link
  355. ** If the destination address is unknown and destination uuid is NAP
  356. ** send it to the host system
  357. */
  358. PAN_TRACE_EVENT("pan_data_ind_cb - for handle %d", handle);
  359. pcb = pan_get_pcb_by_handle(handle);
  360. if (!pcb) {
  361. PAN_TRACE_ERROR("PAN Data indication for wrong handle %d", handle);
  362. return;
  363. }
  364. if (pcb->con_state != PAN_STATE_CONNECTED) {
  365. PAN_TRACE_ERROR("PAN Data indication in wrong state %d for handle %d",
  366. pcb->con_state, handle);
  367. return;
  368. }
  369. /* Check if it is broadcast packet */
  370. if (dst.address[0] & 0x01) {
  371. PAN_TRACE_DEBUG("PAN received broadcast packet on handle %d, src uuid 0x%x",
  372. handle, pcb->src_uuid);
  373. for (i = 0; i < MAX_PAN_CONNS; i++) {
  374. if (pan_cb.pcb[i].con_state == PAN_STATE_CONNECTED &&
  375. pan_cb.pcb[i].handle != handle &&
  376. pcb->src_uuid == pan_cb.pcb[i].src_uuid) {
  377. BNEP_Write(pan_cb.pcb[i].handle, dst, p_data, len, protocol, &src, ext);
  378. }
  379. }
  380. if (pan_cb.pan_data_ind_cb)
  381. (*pan_cb.pan_data_ind_cb)(pcb->handle, src, dst, protocol, p_data, len,
  382. ext, true);
  383. return;
  384. }
  385. /* Check if it is for any other PAN connection */
  386. for (i = 0; i < MAX_PAN_CONNS; i++) {
  387. if (pan_cb.pcb[i].con_state == PAN_STATE_CONNECTED &&
  388. pcb->src_uuid == pan_cb.pcb[i].src_uuid) {
  389. if (pan_cb.pcb[i].rem_bda == dst) {
  390. BNEP_Write(pan_cb.pcb[i].handle, dst, p_data, len, protocol, &src, ext);
  391. return;
  392. }
  393. }
  394. }
  395. if (pcb->src_uuid == UUID_SERVCLASS_NAP)
  396. forward = true;
  397. else
  398. forward = false;
  399. /* Send it over the LAN or give it to host software */
  400. if (pan_cb.pan_data_ind_cb)
  401. (*pan_cb.pan_data_ind_cb)(pcb->handle, src, dst, protocol, p_data, len, ext,
  402. forward);
  403. return;
  404. }
  405. /*******************************************************************************
  406. *
  407. * Function pan_data_buf_ind_cb
  408. *
  409. * Description This function is registered with BNEP as data buffer
  410. * indication callback. BNEP will call this when the peer sends
  411. * any data on this connection. PAN is responsible to release
  412. * the buffer
  413. *
  414. * Parameters: handle - handle for the connection
  415. * src - source BD Addr
  416. * dst - destination BD Addr
  417. * protocol - Network protocol of the Eth packet
  418. * p_buf - pointer to the data buffer
  419. * ext - to indicate whether the data contains any
  420. * extension headers before the payload
  421. *
  422. * Returns none
  423. *
  424. ******************************************************************************/
  425. void pan_data_buf_ind_cb(uint16_t handle, const RawAddress& src,
  426. const RawAddress& dst, uint16_t protocol,
  427. BT_HDR* p_buf, bool ext) {
  428. tPAN_CONN *pcb, *dst_pcb;
  429. tBNEP_RESULT result;
  430. uint16_t i, len;
  431. uint8_t* p_data;
  432. bool forward = false;
  433. /* Check if the connection is in right state */
  434. pcb = pan_get_pcb_by_handle(handle);
  435. if (!pcb) {
  436. PAN_TRACE_ERROR("PAN Data buffer indication for wrong handle %d", handle);
  437. osi_free(p_buf);
  438. return;
  439. }
  440. if (pcb->con_state != PAN_STATE_CONNECTED) {
  441. PAN_TRACE_ERROR("PAN Data indication in wrong state %d for handle %d",
  442. pcb->con_state, handle);
  443. osi_free(p_buf);
  444. return;
  445. }
  446. p_data = (uint8_t*)(p_buf + 1) + p_buf->offset;
  447. len = p_buf->len;
  448. PAN_TRACE_EVENT(
  449. "pan_data_buf_ind_cb - for handle %d, protocol 0x%x, length %d, ext %d",
  450. handle, protocol, len, ext);
  451. if (pcb->src_uuid == UUID_SERVCLASS_NAP)
  452. forward = true;
  453. else
  454. forward = false;
  455. /* Check if it is broadcast or multicast packet */
  456. if (pcb->src_uuid != UUID_SERVCLASS_PANU) {
  457. if (dst.address[0] & 0x01) {
  458. PAN_TRACE_DEBUG(
  459. "PAN received broadcast packet on handle %d, src uuid 0x%x", handle,
  460. pcb->src_uuid);
  461. for (i = 0; i < MAX_PAN_CONNS; i++) {
  462. if (pan_cb.pcb[i].con_state == PAN_STATE_CONNECTED &&
  463. pan_cb.pcb[i].handle != handle &&
  464. pcb->src_uuid == pan_cb.pcb[i].src_uuid) {
  465. BNEP_Write(pan_cb.pcb[i].handle, dst, p_data, len, protocol, &src,
  466. ext);
  467. }
  468. }
  469. if (pan_cb.pan_data_buf_ind_cb)
  470. (*pan_cb.pan_data_buf_ind_cb)(pcb->handle, src, dst, protocol, p_buf,
  471. ext, forward);
  472. else if (pan_cb.pan_data_ind_cb)
  473. (*pan_cb.pan_data_ind_cb)(pcb->handle, src, dst, protocol, p_data, len,
  474. ext, forward);
  475. osi_free(p_buf);
  476. return;
  477. }
  478. /* Check if it is for any other PAN connection */
  479. dst_pcb = pan_get_pcb_by_addr(dst);
  480. if (dst_pcb) {
  481. PAN_TRACE_EVENT(
  482. "%s - destination PANU found on handle %d and sending data, len: %d",
  483. __func__, dst_pcb->handle, len);
  484. result =
  485. BNEP_Write(dst_pcb->handle, dst, p_data, len, protocol, &src, ext);
  486. if (result != BNEP_SUCCESS && result != BNEP_IGNORE_CMD)
  487. PAN_TRACE_ERROR("Failed to write data for PAN connection handle %d",
  488. dst_pcb->handle);
  489. osi_free(p_buf);
  490. return;
  491. }
  492. }
  493. /* Send it over the LAN or give it to host software */
  494. if (pan_cb.pan_data_buf_ind_cb)
  495. (*pan_cb.pan_data_buf_ind_cb)(pcb->handle, src, dst, protocol, p_buf, ext,
  496. forward);
  497. else if (pan_cb.pan_data_ind_cb)
  498. (*pan_cb.pan_data_ind_cb)(pcb->handle, src, dst, protocol, p_data, len, ext,
  499. forward);
  500. osi_free(p_buf);
  501. return;
  502. }
  503. /*******************************************************************************
  504. *
  505. * Function pan_proto_filt_ind_cb
  506. *
  507. * Description This function is registered with BNEP to receive tx data
  508. * flow status
  509. *
  510. * Parameters: handle - handle for the connection
  511. * event - flow status
  512. *
  513. * Returns none
  514. *
  515. ******************************************************************************/
  516. void pan_tx_data_flow_cb(uint16_t handle, tBNEP_RESULT event) {
  517. if (pan_cb.pan_tx_data_flow_cb) (*pan_cb.pan_tx_data_flow_cb)(handle, event);
  518. return;
  519. }
  520. /*******************************************************************************
  521. *
  522. * Function pan_proto_filt_ind_cb
  523. *
  524. * Description This function is registered with BNEP as proto filter
  525. * indication callback. BNEP will call this when the peer sends
  526. * any protocol filter set for the connection or to indicate
  527. * the result of the protocol filter set by the local device
  528. *
  529. * Parameters: handle - handle for the connection
  530. * indication - true if this is indication
  531. * false if it is called to give the result of
  532. * local device protocol filter set
  533. * result - This gives the result of the filter set
  534. * operation
  535. * num_filters - number of filters set by the peer device
  536. * p_filters - pointer to the filters set by the peer device
  537. *
  538. * Returns none
  539. *
  540. ******************************************************************************/
  541. void pan_proto_filt_ind_cb(uint16_t handle, bool indication,
  542. tBNEP_RESULT result, uint16_t num_filters,
  543. uint8_t* p_filters) {
  544. PAN_TRACE_EVENT(
  545. "pan_proto_filt_ind_cb - called for handle %d with ind %d, result %d, "
  546. "num %d",
  547. handle, indication, result, num_filters);
  548. if (pan_cb.pan_pfilt_ind_cb)
  549. (*pan_cb.pan_pfilt_ind_cb)(handle, indication, result, num_filters,
  550. p_filters);
  551. }
  552. /*******************************************************************************
  553. *
  554. * Function pan_mcast_filt_ind_cb
  555. *
  556. * Description This function is registered with BNEP as mcast filter
  557. * indication callback. BNEP will call this when the peer sends
  558. * any multicast filter set for the connection or to indicate
  559. * the result of the multicast filter set by the local device
  560. *
  561. * Parameters: handle - handle for the connection
  562. * indication - true if this is indication
  563. * false if it is called to give the result of
  564. * local device multicast filter set
  565. * result - This gives the result of the filter set
  566. * operation
  567. * num_filters - number of filters set by the peer device
  568. * p_filters - pointer to the filters set by the peer device
  569. *
  570. * Returns none
  571. *
  572. ******************************************************************************/
  573. void pan_mcast_filt_ind_cb(uint16_t handle, bool indication,
  574. tBNEP_RESULT result, uint16_t num_filters,
  575. uint8_t* p_filters) {
  576. PAN_TRACE_EVENT(
  577. "pan_mcast_filt_ind_cb - called for handle %d with ind %d, result %d, "
  578. "num %d",
  579. handle, indication, result, num_filters);
  580. if (pan_cb.pan_mfilt_ind_cb)
  581. (*pan_cb.pan_mfilt_ind_cb)(handle, indication, result, num_filters,
  582. p_filters);
  583. }