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 *
21 * This file contains main functions to support PAN profile
22 * commands and events.
23 *
24 ******************************************************************************/
25
26 #include <string.h>
27 #include "gki.h"
28 #include "bt_types.h"
29 #include "bt_utils.h"
30 #include "bnep_api.h"
31 #include "pan_api.h"
32 #include "pan_int.h"
33 #include "sdp_api.h"
34 #include "sdpdefs.h"
35 #include "l2c_api.h"
36 #include "hcidefs.h"
37
38
39 #if PAN_DYNAMIC_MEMORY == FALSE
40 tPAN_CB pan_cb;
41 #endif
42
43 #define UUID_CONSTANT_PART 12
44 UINT8 constant_pan_uuid[UUID_CONSTANT_PART] = {0, 0, 0x10, 0, 0x80, 0x00, 0x00, 0x80, 0x5f, 0x9b, 0x34, 0xfb};
45
46
47 /*******************************************************************************
48 **
49 ** Function pan_register_with_bnep
50 **
51 ** Description This function registers PAN profile with BNEP
52 **
53 ** Parameters: none
54 **
55 ** Returns none
56 **
57 *******************************************************************************/
pan_register_with_bnep(void)58 void pan_register_with_bnep (void)
59 {
60 tBNEP_REGISTER reg_info;
61
62 memset (®_info, 0, sizeof (tBNEP_REGISTER));
63
64 reg_info.p_conn_ind_cb = pan_conn_ind_cb;
65 reg_info.p_conn_state_cb = pan_connect_state_cb;
66 reg_info.p_data_buf_cb = pan_data_buf_ind_cb;
67 reg_info.p_data_ind_cb = NULL;
68 reg_info.p_tx_data_flow_cb = pan_tx_data_flow_cb;
69 reg_info.p_filter_ind_cb = pan_proto_filt_ind_cb;
70 reg_info.p_mfilter_ind_cb = pan_mcast_filt_ind_cb;
71
72 BNEP_Register (®_info);
73 }
74
75
76 /*******************************************************************************
77 **
78 ** Function pan_conn_ind_cb
79 **
80 ** Description This function is registered with BNEP as connection indication
81 ** callback. BNEP will call this when there is connection
82 ** request from the peer. PAN should call BNEP_ConnectResp to
83 ** indicate whether to accept the connection or reject
84 **
85 ** Parameters: handle - handle for the connection
86 ** p_bda - BD Addr of the peer requesting the connection
87 ** remote_uuid - UUID of the source role (peer device role)
88 ** local_uuid - UUID of the destination role (local device role)
89 ** is_role_change - Flag to indicate that it is a role change
90 **
91 ** Returns none
92 **
93 *******************************************************************************/
pan_conn_ind_cb(UINT16 handle,BD_ADDR p_bda,tBT_UUID * remote_uuid,tBT_UUID * local_uuid,BOOLEAN is_role_change)94 void pan_conn_ind_cb (UINT16 handle,
95 BD_ADDR p_bda,
96 tBT_UUID *remote_uuid,
97 tBT_UUID *local_uuid,
98 BOOLEAN is_role_change)
99 {
100 tPAN_CONN *pcb;
101 UINT8 req_role;
102 BOOLEAN wrong_uuid;
103
104 /*
105 ** If we are in GN or NAP role and have one or more
106 ** active connections and the received connection is
107 ** for user role reject it.
108 ** If we are in user role with one connection active
109 ** reject the connection.
110 ** Allocate PCB and store the parameters
111 ** Make bridge request to the host system if connection
112 ** is for NAP
113 */
114 wrong_uuid = FALSE;
115 if (remote_uuid->len == 16)
116 {
117 /*
118 ** If the UUID is 16 bytes forst two bytes should be zeros
119 ** and last 12 bytes should match the spec defined constant value
120 */
121 if (memcmp (constant_pan_uuid, remote_uuid->uu.uuid128 + 4, UUID_CONSTANT_PART))
122 wrong_uuid = TRUE;
123
124 if (remote_uuid->uu.uuid128[0] || remote_uuid->uu.uuid128[1])
125 wrong_uuid = TRUE;
126
127 /* Extract the 16 bit equivalent of the UUID */
128 remote_uuid->uu.uuid16 = (UINT16)((remote_uuid->uu.uuid128[2] << 8) | remote_uuid->uu.uuid128[3]);
129 remote_uuid->len = 2;
130 }
131 if (remote_uuid->len == 4)
132 {
133 /* First two bytes should be zeros */
134 if (remote_uuid->uu.uuid32 & 0xFFFF0000)
135 wrong_uuid = TRUE;
136
137 remote_uuid->uu.uuid16 = (UINT16)remote_uuid->uu.uuid32;
138 remote_uuid->len = 2;
139 }
140
141 if (wrong_uuid)
142 {
143 PAN_TRACE_ERROR ("PAN Connection failed because of wrong remote UUID ");
144 BNEP_ConnectResp (handle, BNEP_CONN_FAILED_SRC_UUID);
145 return;
146 }
147
148 wrong_uuid = FALSE;
149 if (local_uuid->len == 16)
150 {
151 /*
152 ** If the UUID is 16 bytes forst two bytes should be zeros
153 ** and last 12 bytes should match the spec defined constant value
154 */
155 if (memcmp (constant_pan_uuid, local_uuid->uu.uuid128 + 4, UUID_CONSTANT_PART))
156 wrong_uuid = TRUE;
157
158 if (local_uuid->uu.uuid128[0] || local_uuid->uu.uuid128[1])
159 wrong_uuid = TRUE;
160
161 /* Extract the 16 bit equivalent of the UUID */
162 local_uuid->uu.uuid16 = (UINT16)((local_uuid->uu.uuid128[2] << 8) | local_uuid->uu.uuid128[3]);
163 local_uuid->len = 2;
164 }
165 if (local_uuid->len == 4)
166 {
167 /* First two bytes should be zeros */
168 if (local_uuid->uu.uuid32 & 0xFFFF0000)
169 wrong_uuid = TRUE;
170
171 local_uuid->uu.uuid16 = (UINT16)local_uuid->uu.uuid32;
172 local_uuid->len = 2;
173 }
174
175 if (wrong_uuid)
176 {
177 PAN_TRACE_ERROR ("PAN Connection failed because of wrong local UUID ");
178 BNEP_ConnectResp (handle, BNEP_CONN_FAILED_DST_UUID);
179 return;
180 }
181
182 PAN_TRACE_EVENT ("pan_conn_ind_cb - for handle %d, current role %d, dst uuid 0x%x, src uuid 0x%x, role change %s",
183 handle, pan_cb.role, local_uuid->uu.uuid16, remote_uuid->uu.uuid16, is_role_change?"YES":"NO");
184 /* The acceptable UUID size is only 2 */
185 if (remote_uuid->len != 2)
186 {
187 PAN_TRACE_ERROR ("PAN Connection failed because of wrong UUID size %d", remote_uuid->len);
188 BNEP_ConnectResp (handle, BNEP_CONN_FAILED_UUID_SIZE);
189 return;
190 }
191
192 /* Check if the source UUID is a valid one */
193 if (remote_uuid->uu.uuid16 != UUID_SERVCLASS_PANU &&
194 remote_uuid->uu.uuid16 != UUID_SERVCLASS_NAP &&
195 remote_uuid->uu.uuid16 != UUID_SERVCLASS_GN)
196 {
197 PAN_TRACE_ERROR ("Src UUID 0x%x is not valid", remote_uuid->uu.uuid16);
198 BNEP_ConnectResp (handle, BNEP_CONN_FAILED_SRC_UUID);
199 return;
200 }
201
202 /* Check if the destination UUID is a valid one */
203 if (local_uuid->uu.uuid16 != UUID_SERVCLASS_PANU &&
204 local_uuid->uu.uuid16 != UUID_SERVCLASS_NAP &&
205 local_uuid->uu.uuid16 != UUID_SERVCLASS_GN)
206 {
207 PAN_TRACE_ERROR ("Dst UUID 0x%x is not valid", remote_uuid->uu.uuid16);
208 BNEP_ConnectResp (handle, BNEP_CONN_FAILED_DST_UUID);
209 return;
210 }
211
212 /* Check if currently we support the destination role requested */
213 if (((!(pan_cb.role & UUID_SERVCLASS_PANU))
214 && local_uuid->uu.uuid16 == UUID_SERVCLASS_PANU) ||
215 ((!(pan_cb.role & UUID_SERVCLASS_GN))
216 && local_uuid->uu.uuid16 == UUID_SERVCLASS_GN) ||
217 ((!(pan_cb.role & UUID_SERVCLASS_NAP))
218 && local_uuid->uu.uuid16 == UUID_SERVCLASS_NAP))
219 {
220 PAN_TRACE_ERROR ("PAN Connection failed because of unsupported destination UUID 0x%x", local_uuid->uu.uuid16);
221 BNEP_ConnectResp (handle, BNEP_CONN_FAILED_DST_UUID);
222 return;
223 }
224
225 /* Requested destination role is */
226 if (local_uuid->uu.uuid16 == UUID_SERVCLASS_PANU)
227 req_role = PAN_ROLE_CLIENT;
228 else if (local_uuid->uu.uuid16 == UUID_SERVCLASS_GN)
229 req_role = PAN_ROLE_GN_SERVER;
230 else
231 req_role = PAN_ROLE_NAP_SERVER;
232
233 /* If the connection indication is for the existing connection
234 ** Check if the new destination role is acceptable
235 */
236 pcb = pan_get_pcb_by_handle (handle);
237 if (pcb)
238 {
239 if (pan_cb.num_conns > 1 && local_uuid->uu.uuid16 == UUID_SERVCLASS_PANU)
240 {
241 /* There are connections other than this one
242 ** so we cann't accept PANU role. Reject
243 */
244 PAN_TRACE_ERROR ("Dst UUID should be either GN or NAP only because there are other connections");
245 BNEP_ConnectResp (handle, BNEP_CONN_FAILED_DST_UUID);
246 return;
247 }
248
249 /* If it is already in connected state check for bridging status */
250 if (pcb->con_state == PAN_STATE_CONNECTED)
251 {
252 PAN_TRACE_EVENT ("PAN Role changing New Src 0x%x Dst 0x%x",
253 remote_uuid->uu.uuid16, local_uuid->uu.uuid16);
254
255 pcb->prv_src_uuid = pcb->src_uuid;
256 pcb->prv_dst_uuid = pcb->dst_uuid;
257
258 if (pcb->src_uuid == UUID_SERVCLASS_NAP &&
259 local_uuid->uu.uuid16 != UUID_SERVCLASS_NAP)
260 {
261 /* Remove bridging */
262 if (pan_cb.pan_bridge_req_cb)
263 (*pan_cb.pan_bridge_req_cb) (pcb->rem_bda, FALSE);
264 }
265 }
266 /* Set the latest active PAN role */
267 pan_cb.active_role = req_role;
268 pcb->src_uuid = local_uuid->uu.uuid16;
269 pcb->dst_uuid = remote_uuid->uu.uuid16;
270 BNEP_ConnectResp (handle, BNEP_SUCCESS);
271 return;
272 }
273 else
274 {
275 /* If this a new connection and destination is PANU role and
276 ** we already have a connection then reject the request.
277 ** If we have a connection in PANU role then reject it
278 */
279 if (pan_cb.num_conns &&
280 (local_uuid->uu.uuid16 == UUID_SERVCLASS_PANU ||
281 pan_cb.active_role == PAN_ROLE_CLIENT))
282 {
283 PAN_TRACE_ERROR ("PAN already have a connection and can't be user");
284 BNEP_ConnectResp (handle, BNEP_CONN_FAILED_DST_UUID);
285 return;
286 }
287 }
288
289 /* This is a new connection */
290 PAN_TRACE_DEBUG ("New connection indication for handle %d", handle);
291 pcb = pan_allocate_pcb (p_bda, handle);
292 if (!pcb)
293 {
294 PAN_TRACE_ERROR ("PAN no control block for new connection");
295 BNEP_ConnectResp (handle, BNEP_CONN_FAILED);
296 return;
297 }
298
299 PAN_TRACE_EVENT ("PAN connection destination UUID is 0x%x", local_uuid->uu.uuid16);
300 /* Set the latest active PAN role */
301 pan_cb.active_role = req_role;
302 pcb->src_uuid = local_uuid->uu.uuid16;
303 pcb->dst_uuid = remote_uuid->uu.uuid16;
304 pcb->con_state = PAN_STATE_CONN_START;
305 pan_cb.num_conns++;
306
307 BNEP_ConnectResp (handle, BNEP_SUCCESS);
308 return;
309 }
310
311
312 /*******************************************************************************
313 **
314 ** Function pan_connect_state_cb
315 **
316 ** Description This function is registered with BNEP as connection state
317 ** change callback. BNEP will call this when the connection
318 ** is established successfully or terminated
319 **
320 ** Parameters: handle - handle for the connection given in the connection
321 ** indication callback
322 ** rem_bda - remote device bd addr
323 ** result - indicates whether the connection is up or down
324 ** BNEP_SUCCESS if the connection is up
325 ** all other values indicates appropriate errors
326 ** is_role_change - flag to indicate that it is a role change
327 **
328 ** Returns none
329 **
330 *******************************************************************************/
pan_connect_state_cb(UINT16 handle,BD_ADDR rem_bda,tBNEP_RESULT result,BOOLEAN is_role_change)331 void pan_connect_state_cb (UINT16 handle, BD_ADDR rem_bda, tBNEP_RESULT result, BOOLEAN is_role_change)
332 {
333 tPAN_CONN *pcb;
334 UINT8 peer_role;
335 UNUSED(rem_bda);
336
337 PAN_TRACE_EVENT ("pan_connect_state_cb - for handle %d, result %d", handle, result);
338 pcb = pan_get_pcb_by_handle (handle);
339 if (!pcb)
340 {
341 PAN_TRACE_ERROR ("PAN State change indication for wrong handle %d", handle);
342 return;
343 }
344
345 /* If the connection is getting terminated remove bridging */
346 if (result != BNEP_SUCCESS)
347 {
348 /* Inform the application that connection is down */
349 if (pan_cb.pan_conn_state_cb)
350 (*pan_cb.pan_conn_state_cb) (pcb->handle, pcb->rem_bda, result, is_role_change, PAN_ROLE_INACTIVE, PAN_ROLE_INACTIVE);
351
352 /* Check if this failure is for role change only */
353 if (pcb->con_state != PAN_STATE_CONNECTED &&
354 (pcb->con_flags & PAN_FLAGS_CONN_COMPLETED))
355 {
356 /* restore the original values */
357 PAN_TRACE_EVENT ("restoring the connection state to active");
358 pcb->con_state = PAN_STATE_CONNECTED;
359 pcb->con_flags &= (~PAN_FLAGS_CONN_COMPLETED);
360
361 pcb->src_uuid = pcb->prv_src_uuid;
362 pcb->dst_uuid = pcb->prv_dst_uuid;
363 pan_cb.active_role = pan_cb.prv_active_role;
364
365 if ((pcb->src_uuid == UUID_SERVCLASS_NAP) && pan_cb.pan_bridge_req_cb)
366 (*pan_cb.pan_bridge_req_cb) (pcb->rem_bda, TRUE);
367
368 return;
369 }
370
371 if (pcb->con_state == PAN_STATE_CONNECTED)
372 {
373 /* If the connections destination role is NAP remove bridging */
374 if ((pcb->src_uuid == UUID_SERVCLASS_NAP) && pan_cb.pan_bridge_req_cb)
375 (*pan_cb.pan_bridge_req_cb) (pcb->rem_bda, FALSE);
376 }
377
378 pan_cb.num_conns--;
379 pan_release_pcb (pcb);
380 return;
381 }
382
383 /* Requested destination role is */
384 if (pcb->src_uuid == UUID_SERVCLASS_PANU)
385 pan_cb.active_role = PAN_ROLE_CLIENT;
386 else if (pcb->src_uuid == UUID_SERVCLASS_GN)
387 pan_cb.active_role = PAN_ROLE_GN_SERVER;
388 else
389 pan_cb.active_role = PAN_ROLE_NAP_SERVER;
390
391 if (pcb->dst_uuid == UUID_SERVCLASS_PANU)
392 peer_role = PAN_ROLE_CLIENT;
393 else if (pcb->dst_uuid == UUID_SERVCLASS_GN)
394 peer_role = PAN_ROLE_GN_SERVER;
395 else
396 peer_role = PAN_ROLE_NAP_SERVER;
397
398 pcb->con_state = PAN_STATE_CONNECTED;
399
400 /* Inform the application that connection is down */
401 if (pan_cb.pan_conn_state_cb)
402 (*pan_cb.pan_conn_state_cb) (pcb->handle, pcb->rem_bda, PAN_SUCCESS, is_role_change, pan_cb.active_role, peer_role);
403
404 /* Create bridge if the destination role is NAP */
405 if (pan_cb.pan_bridge_req_cb && pcb->src_uuid == UUID_SERVCLASS_NAP)
406 {
407 PAN_TRACE_EVENT ("PAN requesting for bridge");
408 (*pan_cb.pan_bridge_req_cb) (pcb->rem_bda, TRUE);
409 }
410 }
411
412
413 /*******************************************************************************
414 **
415 ** Function pan_data_ind_cb
416 **
417 ** Description This function is registered with BNEP as data indication
418 ** callback. BNEP will call this when the peer sends any data
419 ** on this connection
420 **
421 ** Parameters: handle - handle for the connection
422 ** src - source BD Addr
423 ** dst - destination BD Addr
424 ** protocol - Network protocol of the Eth packet
425 ** p_data - pointer to the data
426 ** len - length of the data
427 ** fw_ext_present - to indicate whether the data contains any
428 ** extension headers before the payload
429 **
430 ** Returns none
431 **
432 *******************************************************************************/
pan_data_ind_cb(UINT16 handle,UINT8 * src,UINT8 * dst,UINT16 protocol,UINT8 * p_data,UINT16 len,BOOLEAN ext)433 void pan_data_ind_cb (UINT16 handle,
434 UINT8 *src,
435 UINT8 *dst,
436 UINT16 protocol,
437 UINT8 *p_data,
438 UINT16 len,
439 BOOLEAN ext)
440 {
441 tPAN_CONN *pcb;
442 UINT16 i;
443 BOOLEAN forward;
444
445 /*
446 ** Check the connection status
447 ** If the destination address is MAC broadcast send on all links
448 ** except on the one received
449 ** If the destination uuid is for NAP send to host system also
450 ** If the destination address is one of the devices connected
451 ** send the packet to over that link
452 ** If the destination address is unknown and destination uuid is NAP
453 ** send it to the host system
454 */
455
456 PAN_TRACE_EVENT ("pan_data_ind_cb - for handle %d", handle);
457 pcb = pan_get_pcb_by_handle (handle);
458 if (!pcb)
459 {
460 PAN_TRACE_ERROR ("PAN Data indication for wrong handle %d", handle);
461 return;
462 }
463
464 if (pcb->con_state != PAN_STATE_CONNECTED)
465 {
466 PAN_TRACE_ERROR ("PAN Data indication in wrong state %d for handle %d",
467 pcb->con_state, handle);
468 return;
469 }
470
471 /* Check if it is broadcast packet */
472 if (dst[0] & 0x01)
473 {
474 PAN_TRACE_DEBUG ("PAN received broadcast packet on handle %d, src uuid 0x%x",
475 handle, pcb->src_uuid);
476 for (i=0; i<MAX_PAN_CONNS; i++)
477 {
478 if (pan_cb.pcb[i].con_state == PAN_STATE_CONNECTED &&
479 pan_cb.pcb[i].handle != handle &&
480 pcb->src_uuid == pan_cb.pcb[i].src_uuid)
481 {
482 BNEP_Write (pan_cb.pcb[i].handle, dst, p_data, len, protocol, src, ext);
483 }
484 }
485
486 if (pan_cb.pan_data_ind_cb)
487 (*pan_cb.pan_data_ind_cb) (pcb->handle, src, dst, protocol, p_data, len, ext, TRUE);
488
489 return;
490 }
491
492 /* Check if it is for any other PAN connection */
493 for (i=0; i<MAX_PAN_CONNS; i++)
494 {
495 if (pan_cb.pcb[i].con_state == PAN_STATE_CONNECTED &&
496 pcb->src_uuid == pan_cb.pcb[i].src_uuid)
497 {
498 if (memcmp (pan_cb.pcb[i].rem_bda, dst, BD_ADDR_LEN) == 0)
499 {
500 BNEP_Write (pan_cb.pcb[i].handle, dst, p_data, len, protocol, src, ext);
501 return;
502 }
503 }
504 }
505
506 if (pcb->src_uuid == UUID_SERVCLASS_NAP)
507 forward = TRUE;
508 else
509 forward = FALSE;
510
511 /* Send it over the LAN or give it to host software */
512 if (pan_cb.pan_data_ind_cb)
513 (*pan_cb.pan_data_ind_cb) (pcb->handle, src, dst, protocol, p_data, len, ext, forward);
514
515 return;
516 }
517
518
519 /*******************************************************************************
520 **
521 ** Function pan_data_buf_ind_cb
522 **
523 ** Description This function is registered with BNEP as data buffer indication
524 ** callback. BNEP will call this when the peer sends any data
525 ** on this connection. PAN is responsible to release the buffer
526 **
527 ** Parameters: handle - handle for the connection
528 ** src - source BD Addr
529 ** dst - destination BD Addr
530 ** protocol - Network protocol of the Eth packet
531 ** p_buf - pointer to the data buffer
532 ** ext - to indicate whether the data contains any
533 ** extension headers before the payload
534 **
535 ** Returns none
536 **
537 *******************************************************************************/
pan_data_buf_ind_cb(UINT16 handle,UINT8 * src,UINT8 * dst,UINT16 protocol,BT_HDR * p_buf,BOOLEAN ext)538 void pan_data_buf_ind_cb (UINT16 handle,
539 UINT8 *src,
540 UINT8 *dst,
541 UINT16 protocol,
542 BT_HDR *p_buf,
543 BOOLEAN ext)
544 {
545 tPAN_CONN *pcb, *dst_pcb;
546 tBNEP_RESULT result;
547 UINT16 i, len;
548 UINT8 *p_data;
549 BOOLEAN forward = FALSE;
550
551 /* Check if the connection is in right state */
552 pcb = pan_get_pcb_by_handle (handle);
553 if (!pcb)
554 {
555 PAN_TRACE_ERROR ("PAN Data buffer indication for wrong handle %d", handle);
556 GKI_freebuf (p_buf);
557 return;
558 }
559
560 if (pcb->con_state != PAN_STATE_CONNECTED)
561 {
562 PAN_TRACE_ERROR ("PAN Data indication in wrong state %d for handle %d",
563 pcb->con_state, handle);
564 GKI_freebuf (p_buf);
565 return;
566 }
567
568 p_data = (UINT8 *)(p_buf + 1) + p_buf->offset;
569 len = p_buf->len;
570
571 PAN_TRACE_EVENT ("pan_data_buf_ind_cb - for handle %d, protocol 0x%x, length %d, ext %d",
572 handle, protocol, len, ext);
573
574 if (pcb->src_uuid == UUID_SERVCLASS_NAP)
575 forward = TRUE;
576 else
577 forward = FALSE;
578
579 /* Check if it is broadcast or multicast packet */
580 if (pcb->src_uuid != UUID_SERVCLASS_PANU)
581 {
582 if (dst[0] & 0x01)
583 {
584 PAN_TRACE_DEBUG ("PAN received broadcast packet on handle %d, src uuid 0x%x",
585 handle, pcb->src_uuid);
586 for (i=0; i<MAX_PAN_CONNS; i++)
587 {
588 if (pan_cb.pcb[i].con_state == PAN_STATE_CONNECTED &&
589 pan_cb.pcb[i].handle != handle &&
590 pcb->src_uuid == pan_cb.pcb[i].src_uuid)
591 {
592 BNEP_Write (pan_cb.pcb[i].handle, dst, p_data, len, protocol, src, ext);
593 }
594 }
595
596 if (pan_cb.pan_data_buf_ind_cb)
597 (*pan_cb.pan_data_buf_ind_cb) (pcb->handle, src, dst, protocol, p_buf, ext, forward);
598 else if (pan_cb.pan_data_ind_cb)
599 {
600 (*pan_cb.pan_data_ind_cb) (pcb->handle, src, dst, protocol, p_data, len, ext, forward);
601 GKI_freebuf (p_buf);
602 }
603
604 return;
605 }
606
607 /* Check if it is for any other PAN connection */
608 dst_pcb = pan_get_pcb_by_addr (dst);
609 if (dst_pcb)
610 {
611 PAN_TRACE_EVENT ("%s - destination PANU found on handle %d and sending data, len: %d",
612 __func__, dst_pcb->handle, len);
613
614 result = BNEP_Write (dst_pcb->handle, dst, p_data, len, protocol, src, ext);
615 if (result != BNEP_SUCCESS && result != BNEP_IGNORE_CMD)
616 PAN_TRACE_ERROR ("Failed to write data for PAN connection handle %d", dst_pcb->handle);
617 GKI_freebuf (p_buf);
618 return;
619 }
620 }
621
622 /* Send it over the LAN or give it to host software */
623 if (pan_cb.pan_data_buf_ind_cb)
624 (*pan_cb.pan_data_buf_ind_cb) (pcb->handle, src, dst, protocol, p_buf, ext, forward);
625 else if (pan_cb.pan_data_ind_cb)
626 {
627 (*pan_cb.pan_data_ind_cb) (pcb->handle, src, dst, protocol, p_data, len, ext, forward);
628 GKI_freebuf (p_buf);
629 }
630 else
631 GKI_freebuf (p_buf);
632
633 return;
634 }
635
636 /*******************************************************************************
637 **
638 ** Function pan_proto_filt_ind_cb
639 **
640 ** Description This function is registered with BNEP to receive tx data
641 ** flow status
642 **
643 ** Parameters: handle - handle for the connection
644 ** event - flow status
645 **
646 ** Returns none
647 **
648 *******************************************************************************/
pan_tx_data_flow_cb(UINT16 handle,tBNEP_RESULT event)649 void pan_tx_data_flow_cb (UINT16 handle,
650 tBNEP_RESULT event)
651 {
652
653 if (pan_cb.pan_tx_data_flow_cb)
654 (*pan_cb.pan_tx_data_flow_cb) (handle, event);
655
656 return;
657 }
658
659 /*******************************************************************************
660 **
661 ** Function pan_proto_filt_ind_cb
662 **
663 ** Description This function is registered with BNEP as proto filter indication
664 ** callback. BNEP will call this when the peer sends any protocol
665 ** filter set for the connection or to indicate the result of the
666 ** protocol filter set by the local device
667 **
668 ** Parameters: handle - handle for the connection
669 ** indication - TRUE if this is indication
670 ** FALSE if it is called to give the result of local
671 ** device protocol filter set
672 ** result - This gives the result of the filter set operation
673 ** num_filters - number of filters set by the peer device
674 ** p_filters - pointer to the filters set by the peer device
675 **
676 ** Returns none
677 **
678 *******************************************************************************/
pan_proto_filt_ind_cb(UINT16 handle,BOOLEAN indication,tBNEP_RESULT result,UINT16 num_filters,UINT8 * p_filters)679 void pan_proto_filt_ind_cb (UINT16 handle,
680 BOOLEAN indication,
681 tBNEP_RESULT result,
682 UINT16 num_filters,
683 UINT8 *p_filters)
684 {
685 PAN_TRACE_EVENT ("pan_proto_filt_ind_cb - called for handle %d with ind %d, result %d, num %d",
686 handle, indication, result, num_filters);
687
688 if (pan_cb.pan_pfilt_ind_cb)
689 (*pan_cb.pan_pfilt_ind_cb) (handle, indication, result, num_filters, p_filters);
690 }
691
692
693 /*******************************************************************************
694 **
695 ** Function pan_mcast_filt_ind_cb
696 **
697 ** Description This function is registered with BNEP as mcast filter indication
698 ** callback. BNEP will call this when the peer sends any multicast
699 ** filter set for the connection or to indicate the result of the
700 ** multicast filter set by the local device
701 **
702 ** Parameters: handle - handle for the connection
703 ** indication - TRUE if this is indication
704 ** FALSE if it is called to give the result of local
705 ** device multicast filter set
706 ** result - This gives the result of the filter set operation
707 ** num_filters - number of filters set by the peer device
708 ** p_filters - pointer to the filters set by the peer device
709 **
710 ** Returns none
711 **
712 *******************************************************************************/
pan_mcast_filt_ind_cb(UINT16 handle,BOOLEAN indication,tBNEP_RESULT result,UINT16 num_filters,UINT8 * p_filters)713 void pan_mcast_filt_ind_cb (UINT16 handle,
714 BOOLEAN indication,
715 tBNEP_RESULT result,
716 UINT16 num_filters,
717 UINT8 *p_filters)
718 {
719 PAN_TRACE_EVENT ("pan_mcast_filt_ind_cb - called for handle %d with ind %d, result %d, num %d",
720 handle, indication, result, num_filters);
721
722 if (pan_cb.pan_mfilt_ind_cb)
723 (*pan_cb.pan_mfilt_ind_cb) (handle, indication, result, num_filters, p_filters);
724 }
725