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