• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "bnep_api.h"
30 #include "pan_api.h"
31 #include "pan_int.h"
32 #include "sdp_api.h"
33 #include "sdpdefs.h"
34 #include "l2c_api.h"
35 #include "hcidefs.h"
36 
37 
38 #if PAN_DYNAMIC_MEMORY == FALSE
39 tPAN_CB  pan_cb;
40 #endif
41 
42 #define UUID_CONSTANT_PART  12
43 UINT8 constant_pan_uuid[UUID_CONSTANT_PART] = {0, 0, 0x10, 0, 0x80, 0x00, 0x00, 0x80, 0x5f, 0x9b, 0x34, 0xfb};
44 
45 
46 /*******************************************************************************
47 **
48 ** Function         pan_register_with_bnep
49 **
50 ** Description      This function registers PAN profile with BNEP
51 **
52 ** Parameters:      none
53 **
54 ** Returns          none
55 **
56 *******************************************************************************/
pan_register_with_bnep(void)57 void pan_register_with_bnep (void)
58 {
59     tBNEP_REGISTER      reg_info;
60 
61     memset (&reg_info, 0, sizeof (tBNEP_REGISTER));
62 
63     reg_info.p_conn_ind_cb      = pan_conn_ind_cb;
64     reg_info.p_conn_state_cb    = pan_connect_state_cb;
65     reg_info.p_data_buf_cb      = pan_data_buf_ind_cb;
66     reg_info.p_data_ind_cb      = NULL;
67     reg_info.p_tx_data_flow_cb  = pan_tx_data_flow_cb;
68     reg_info.p_filter_ind_cb    = pan_proto_filt_ind_cb;
69     reg_info.p_mfilter_ind_cb   = pan_mcast_filt_ind_cb;
70 
71     BNEP_Register (&reg_info);
72 }
73 
74 
75 /*******************************************************************************
76 **
77 ** Function         pan_conn_ind_cb
78 **
79 ** Description      This function is registered with BNEP as connection indication
80 **                  callback. BNEP will call this when there is connection
81 **                  request from the peer. PAN should call BNEP_ConnectResp to
82 **                  indicate whether to accept the connection or reject
83 **
84 ** Parameters:      handle          - handle for the connection
85 **                  p_bda           - BD Addr of the peer requesting the connection
86 **                  remote_uuid     - UUID of the source role (peer device role)
87 **                  local_uuid      - UUID of the destination role (local device role)
88 **                  is_role_change  - Flag to indicate that it is a role change
89 **
90 ** Returns          none
91 **
92 *******************************************************************************/
pan_conn_ind_cb(UINT16 handle,BD_ADDR p_bda,tBT_UUID * remote_uuid,tBT_UUID * local_uuid,BOOLEAN is_role_change)93 void pan_conn_ind_cb (UINT16 handle,
94                       BD_ADDR p_bda,
95                       tBT_UUID *remote_uuid,
96                       tBT_UUID *local_uuid,
97                       BOOLEAN is_role_change)
98 {
99     tPAN_CONN       *pcb;
100     UINT8           req_role;
101     BOOLEAN         wrong_uuid;
102 
103     /*
104     ** If we are in GN or NAP role and have one or more
105     ** active connections and the received connection is
106     ** for user role reject it.
107     ** If we are in user role with one connection active
108     ** reject the connection.
109     ** Allocate PCB and store the parameters
110     ** Make bridge request to the host system if connection
111     ** is for NAP
112     */
113     wrong_uuid = FALSE;
114 #if (defined (BNEP_SUPPORTS_ALL_UUID_LENGTHS) && BNEP_SUPPORTS_ALL_UUID_LENGTHS == TRUE)
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_ERROR0 ("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_ERROR0 ("PAN Connection failed because of wrong local UUID ");
178         BNEP_ConnectResp (handle, BNEP_CONN_FAILED_DST_UUID);
179         return;
180     }
181 
182     PAN_TRACE_EVENT5 ("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_ERROR1 ("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 #endif
192 
193     /* Check if the source UUID is a valid one */
194     if (remote_uuid->uu.uuid16 != UUID_SERVCLASS_PANU &&
195         remote_uuid->uu.uuid16 != UUID_SERVCLASS_NAP &&
196         remote_uuid->uu.uuid16 != UUID_SERVCLASS_GN)
197     {
198         PAN_TRACE_ERROR1 ("Src UUID 0x%x is not valid", remote_uuid->uu.uuid16);
199         BNEP_ConnectResp (handle, BNEP_CONN_FAILED_SRC_UUID);
200         return;
201     }
202 
203     /* Check if the destination UUID is a valid one */
204     if (local_uuid->uu.uuid16 != UUID_SERVCLASS_PANU &&
205         local_uuid->uu.uuid16 != UUID_SERVCLASS_NAP &&
206         local_uuid->uu.uuid16 != UUID_SERVCLASS_GN)
207     {
208         PAN_TRACE_ERROR1 ("Dst UUID 0x%x is not valid", remote_uuid->uu.uuid16);
209         BNEP_ConnectResp (handle, BNEP_CONN_FAILED_DST_UUID);
210         return;
211     }
212 
213     /* Check if currently we support the destination role requested */
214     if (((!(pan_cb.role & UUID_SERVCLASS_PANU))
215         && local_uuid->uu.uuid16 == UUID_SERVCLASS_PANU) ||
216         ((!(pan_cb.role & UUID_SERVCLASS_GN))
217         && local_uuid->uu.uuid16 == UUID_SERVCLASS_GN) ||
218         ((!(pan_cb.role & UUID_SERVCLASS_NAP))
219         && local_uuid->uu.uuid16 == UUID_SERVCLASS_NAP))
220     {
221         PAN_TRACE_ERROR1 ("PAN Connection failed because of unsupported destination UUID 0x%x", local_uuid->uu.uuid16);
222         BNEP_ConnectResp (handle, BNEP_CONN_FAILED_DST_UUID);
223         return;
224     }
225 
226     /* Requested destination role is */
227     if (local_uuid->uu.uuid16 == UUID_SERVCLASS_PANU)
228         req_role = PAN_ROLE_CLIENT;
229     else if (local_uuid->uu.uuid16 == UUID_SERVCLASS_GN)
230         req_role = PAN_ROLE_GN_SERVER;
231     else
232         req_role = PAN_ROLE_NAP_SERVER;
233 
234     /* If the connection indication is for the existing connection
235     ** Check if the new destination role is acceptable
236     */
237     pcb = pan_get_pcb_by_handle (handle);
238     if (pcb)
239     {
240         if (pan_cb.num_conns > 1 && local_uuid->uu.uuid16 == UUID_SERVCLASS_PANU)
241         {
242             /* There are connections other than this one
243             ** so we cann't accept PANU role. Reject
244             */
245             PAN_TRACE_ERROR0 ("Dst UUID should be either GN or NAP only because there are other connections");
246             BNEP_ConnectResp (handle, BNEP_CONN_FAILED_DST_UUID);
247             return;
248         }
249 
250         /* If it is already in connected state check for bridging status */
251         if (pcb->con_state == PAN_STATE_CONNECTED)
252         {
253             PAN_TRACE_EVENT2 ("PAN Role changing New Src 0x%x Dst 0x%x",
254                 remote_uuid->uu.uuid16, local_uuid->uu.uuid16);
255 
256             pcb->prv_src_uuid = pcb->src_uuid;
257             pcb->prv_dst_uuid = pcb->dst_uuid;
258 
259             if (pcb->src_uuid == UUID_SERVCLASS_NAP &&
260                 local_uuid->uu.uuid16 != UUID_SERVCLASS_NAP)
261             {
262                 /* Remove bridging */
263                 if (pan_cb.pan_bridge_req_cb)
264                     (*pan_cb.pan_bridge_req_cb) (pcb->rem_bda, FALSE);
265             }
266         }
267         /* Set the latest active PAN role */
268         pan_cb.active_role = req_role;
269         pcb->src_uuid = local_uuid->uu.uuid16;
270         pcb->dst_uuid = remote_uuid->uu.uuid16;
271         BNEP_ConnectResp (handle, BNEP_SUCCESS);
272         return;
273     }
274     else
275     {
276         /* If this a new connection and destination is PANU role and
277         ** we already have a connection then reject the request.
278         ** If we have a connection in PANU role then reject it
279         */
280         if (pan_cb.num_conns &&
281             (local_uuid->uu.uuid16 == UUID_SERVCLASS_PANU ||
282             pan_cb.active_role == PAN_ROLE_CLIENT))
283         {
284             PAN_TRACE_ERROR0 ("PAN already have a connection and can't be user");
285             BNEP_ConnectResp (handle, BNEP_CONN_FAILED_DST_UUID);
286             return;
287         }
288     }
289 
290     /* This is a new connection */
291     PAN_TRACE_DEBUG1 ("New connection indication for handle %d", handle);
292     pcb = pan_allocate_pcb (p_bda, handle);
293     if (!pcb)
294     {
295         PAN_TRACE_ERROR0 ("PAN no control block for new connection");
296         BNEP_ConnectResp (handle, BNEP_CONN_FAILED);
297         return;
298     }
299 
300     PAN_TRACE_EVENT1 ("PAN connection destination UUID is 0x%x", local_uuid->uu.uuid16);
301     /* Set the latest active PAN role */
302     pan_cb.active_role = req_role;
303     pcb->src_uuid = local_uuid->uu.uuid16;
304     pcb->dst_uuid = remote_uuid->uu.uuid16;
305     pcb->con_state = PAN_STATE_CONN_START;
306     pan_cb.num_conns++;
307 
308     BNEP_ConnectResp (handle, BNEP_SUCCESS);
309     return;
310 }
311 
312 
313 /*******************************************************************************
314 **
315 ** Function         pan_connect_state_cb
316 **
317 ** Description      This function is registered with BNEP as connection state
318 **                  change callback. BNEP will call this when the connection
319 **                  is established successfully or terminated
320 **
321 ** Parameters:      handle      - handle for the connection given in the connection
322 **                                      indication callback
323 **                  rem_bda     - remote device bd addr
324 **                  result      - indicates whether the connection is up or down
325 **                                      BNEP_SUCCESS if the connection is up
326 **                                      all other values indicates appropriate errors
327 **                  is_role_change - flag to indicate that it is a role change
328 **
329 ** Returns          none
330 **
331 *******************************************************************************/
pan_connect_state_cb(UINT16 handle,BD_ADDR rem_bda,tBNEP_RESULT result,BOOLEAN is_role_change)332 void pan_connect_state_cb (UINT16 handle, BD_ADDR rem_bda, tBNEP_RESULT result, BOOLEAN is_role_change)
333 {
334     tPAN_CONN       *pcb;
335     UINT8            peer_role;
336 
337     PAN_TRACE_EVENT2 ("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_ERROR1 ("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_EVENT0 ("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_EVENT0 ("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_EVENT1 ("pan_data_ind_cb - for handle %d", handle);
457     pcb = pan_get_pcb_by_handle (handle);
458     if (!pcb)
459     {
460         PAN_TRACE_ERROR1 ("PAN Data indication for wrong handle %d", handle);
461         return;
462     }
463 
464     if (pcb->con_state != PAN_STATE_CONNECTED)
465     {
466         PAN_TRACE_ERROR2 ("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_DEBUG2 ("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_ERROR1 ("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_ERROR2 ("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_EVENT4 ("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_DEBUG2 ("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_EVENT0 ("pan_data_buf_ind_cb - destination PANU found and sending the data");
612             result = BNEP_WriteBuf (dst_pcb->handle, dst, p_buf, protocol, src, ext);
613             if (result != BNEP_SUCCESS && result != BNEP_IGNORE_CMD)
614                 PAN_TRACE_ERROR1 ("Failed to write data for PAN connection handle %d", dst_pcb->handle);
615             return;
616         }
617     }
618 
619     /* Send it over the LAN or give it to host software */
620     if (pan_cb.pan_data_buf_ind_cb)
621         (*pan_cb.pan_data_buf_ind_cb) (pcb->handle, src, dst, protocol, p_buf, ext, forward);
622     else if (pan_cb.pan_data_ind_cb)
623     {
624         (*pan_cb.pan_data_ind_cb) (pcb->handle, src, dst, protocol, p_data, len, ext, forward);
625         GKI_freebuf (p_buf);
626     }
627     else
628         GKI_freebuf (p_buf);
629 
630     return;
631 }
632 
633 /*******************************************************************************
634 **
635 ** Function         pan_proto_filt_ind_cb
636 **
637 ** Description      This function is registered with BNEP to receive tx data
638 **					flow status
639 **
640 ** Parameters:      handle      - handle for the connection
641 **					event       - flow status
642 **
643 ** Returns          none
644 **
645 *******************************************************************************/
pan_tx_data_flow_cb(UINT16 handle,tBNEP_RESULT event)646 void pan_tx_data_flow_cb (UINT16 handle,
647                             tBNEP_RESULT  event)
648 {
649 
650     if (pan_cb.pan_tx_data_flow_cb)
651         (*pan_cb.pan_tx_data_flow_cb) (handle, event);
652 
653     return;
654 }
655 
656 /*******************************************************************************
657 **
658 ** Function         pan_proto_filt_ind_cb
659 **
660 ** Description      This function is registered with BNEP as proto filter indication
661 **                  callback. BNEP will call this when the peer sends any protocol
662 **                  filter set for the connection or to indicate the result of the
663 **                  protocol filter set by the local device
664 **
665 ** Parameters:      handle      - handle for the connection
666 **                  indication  - TRUE if this is indication
667 **                                FALSE if it is called to give the result of local
668 **                                      device protocol filter set
669 **                  result      - This gives the result of the filter set operation
670 **                  num_filters - number of filters set by the peer device
671 **                  p_filters   - pointer to the filters set by the peer device
672 **
673 ** Returns          none
674 **
675 *******************************************************************************/
pan_proto_filt_ind_cb(UINT16 handle,BOOLEAN indication,tBNEP_RESULT result,UINT16 num_filters,UINT8 * p_filters)676 void pan_proto_filt_ind_cb (UINT16 handle,
677                             BOOLEAN indication,
678                             tBNEP_RESULT result,
679                             UINT16 num_filters,
680                             UINT8 *p_filters)
681 {
682 #if (defined (BNEP_SUPPORTS_PROT_FILTERS) && BNEP_SUPPORTS_PROT_FILTERS == TRUE)
683     PAN_TRACE_EVENT4 ("pan_proto_filt_ind_cb - called for handle %d with ind %d, result %d, num %d",
684                             handle, indication, result, num_filters);
685 
686     if (pan_cb.pan_pfilt_ind_cb)
687         (*pan_cb.pan_pfilt_ind_cb) (handle, indication, result, num_filters, p_filters);
688 #endif
689 
690     return;
691 }
692 
693 
694 /*******************************************************************************
695 **
696 ** Function         pan_mcast_filt_ind_cb
697 **
698 ** Description      This function is registered with BNEP as mcast filter indication
699 **                  callback. BNEP will call this when the peer sends any multicast
700 **                  filter set for the connection or to indicate the result of the
701 **                  multicast filter set by the local device
702 **
703 ** Parameters:      handle      - handle for the connection
704 **                  indication  - TRUE if this is indication
705 **                                FALSE if it is called to give the result of local
706 **                                      device multicast filter set
707 **                  result      - This gives the result of the filter set operation
708 **                  num_filters - number of filters set by the peer device
709 **                  p_filters   - pointer to the filters set by the peer device
710 **
711 ** Returns          none
712 **
713 *******************************************************************************/
pan_mcast_filt_ind_cb(UINT16 handle,BOOLEAN indication,tBNEP_RESULT result,UINT16 num_filters,UINT8 * p_filters)714 void pan_mcast_filt_ind_cb (UINT16 handle,
715                             BOOLEAN indication,
716                             tBNEP_RESULT result,
717                             UINT16 num_filters,
718                             UINT8 *p_filters)
719 {
720 #if (defined (BNEP_SUPPORTS_MULTI_FILTERS) && BNEP_SUPPORTS_MULTI_FILTERS == TRUE)
721     PAN_TRACE_EVENT4 ("pan_mcast_filt_ind_cb - called for handle %d with ind %d, result %d, num %d",
722                             handle, indication, result, num_filters);
723 
724     if (pan_cb.pan_mfilt_ind_cb)
725         (*pan_cb.pan_mfilt_ind_cb) (handle, indication, result, num_filters, p_filters);
726 #endif
727 
728     return;
729 }
730 
731