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 (®_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 (®_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