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 #include "btm_api.h"
37
38
39 /*******************************************************************************
40 **
41 ** Function PAN_Register
42 **
43 ** Description This function is called by the application to register
44 ** its callbacks with PAN profile. The application then
45 ** should set the PAN role explicitly.
46 **
47 ** Parameters: p_register - contains all callback function pointers
48 **
49 **
50 ** Returns none
51 **
52 *******************************************************************************/
PAN_Register(tPAN_REGISTER * p_register)53 void PAN_Register (tPAN_REGISTER *p_register)
54 {
55 BTM_SetDiscoverability (BTM_GENERAL_DISCOVERABLE, 0, 0);
56 BTM_SetConnectability (BTM_CONNECTABLE, 0, 0);
57
58 pan_register_with_bnep ();
59
60 if (!p_register)
61 return;
62
63 pan_cb.pan_conn_state_cb = p_register->pan_conn_state_cb;
64 pan_cb.pan_bridge_req_cb = p_register->pan_bridge_req_cb;
65 pan_cb.pan_data_buf_ind_cb = p_register->pan_data_buf_ind_cb;
66 pan_cb.pan_data_ind_cb = p_register->pan_data_ind_cb;
67 pan_cb.pan_pfilt_ind_cb = p_register->pan_pfilt_ind_cb;
68 pan_cb.pan_mfilt_ind_cb = p_register->pan_mfilt_ind_cb;
69 pan_cb.pan_tx_data_flow_cb = p_register->pan_tx_data_flow_cb;
70
71 return;
72 }
73
74
75
76 /*******************************************************************************
77 **
78 ** Function PAN_Deregister
79 **
80 ** Description This function is called by the application to de-register
81 ** its callbacks with PAN profile. This will make the PAN to
82 ** become inactive. This will deregister PAN services from SDP
83 ** and close all active connections
84 **
85 ** Parameters: none
86 **
87 **
88 ** Returns none
89 **
90 *******************************************************************************/
PAN_Deregister(void)91 void PAN_Deregister (void)
92 {
93 pan_cb.pan_bridge_req_cb = NULL;
94 pan_cb.pan_data_buf_ind_cb = NULL;
95 pan_cb.pan_data_ind_cb = NULL;
96 pan_cb.pan_conn_state_cb = NULL;
97 pan_cb.pan_pfilt_ind_cb = NULL;
98 pan_cb.pan_mfilt_ind_cb = NULL;
99
100 PAN_SetRole (PAN_ROLE_INACTIVE, NULL, NULL, NULL, NULL);
101 BNEP_Deregister ();
102
103 return;
104 }
105
106
107
108
109 /*******************************************************************************
110 **
111 ** Function PAN_SetRole
112 **
113 ** Description This function is called by the application to set the PAN
114 ** profile role. This should be called after PAN_Register.
115 ** This can be called any time to change the PAN role
116 **
117 ** Parameters: role - is bit map of roles to be active
118 ** PAN_ROLE_CLIENT is for PANU role
119 ** PAN_ROLE_GN_SERVER is for GN role
120 ** PAN_ROLE_NAP_SERVER is for NAP role
121 ** sec_mask - Security mask for different roles
122 ** It is array of UINT8. The byte represent the
123 ** security for roles PANU, GN and NAP in order
124 ** p_user_name - Service name for PANU role
125 ** p_gn_name - Service name for GN role
126 ** p_nap_name - Service name for NAP role
127 ** Can be NULL if user wants it to be default
128 **
129 ** Returns PAN_SUCCESS - if the role is set successfully
130 ** PAN_FAILURE - if the role is not valid
131 **
132 *******************************************************************************/
PAN_SetRole(UINT8 role,UINT8 * sec_mask,char * p_user_name,char * p_gn_name,char * p_nap_name)133 tPAN_RESULT PAN_SetRole (UINT8 role,
134 UINT8 *sec_mask,
135 char *p_user_name,
136 char *p_gn_name,
137 char *p_nap_name)
138 {
139 char *p_desc;
140 UINT8 security[3] = {PAN_PANU_SECURITY_LEVEL,
141 PAN_GN_SECURITY_LEVEL,
142 PAN_NAP_SECURITY_LEVEL};
143 UINT8 *p_sec;
144
145 /* If the role is not a valid combination reject it */
146 if ((!(role & (PAN_ROLE_CLIENT | PAN_ROLE_GN_SERVER | PAN_ROLE_NAP_SERVER))) &&
147 role != PAN_ROLE_INACTIVE)
148 {
149 PAN_TRACE_ERROR1 ("PAN role %d is invalid", role);
150 return PAN_FAILURE;
151 }
152
153 /* If the current active role is same as the role being set do nothing */
154 if (pan_cb.role == role)
155 {
156 PAN_TRACE_EVENT1 ("PAN role already was set to: %d", role);
157 return PAN_SUCCESS;
158 }
159
160 if (!sec_mask)
161 p_sec = security;
162 else
163 p_sec = sec_mask;
164
165 /* Register all the roles with SDP */
166 PAN_TRACE_API1 ("PAN_SetRole() called with role 0x%x", role);
167 #if (defined (PAN_SUPPORTS_ROLE_NAP) && PAN_SUPPORTS_ROLE_NAP == TRUE)
168 /* Check the service name */
169 if ((p_nap_name == NULL) || (*p_nap_name == 0))
170 p_nap_name = PAN_NAP_DEFAULT_SERVICE_NAME;
171
172 if (role & PAN_ROLE_NAP_SERVER)
173 {
174 /* Registering for NAP service with SDP */
175 p_desc = PAN_NAP_DEFAULT_DESCRIPTION;
176
177 if (pan_cb.pan_nap_sdp_handle != 0)
178 SDP_DeleteRecord (pan_cb.pan_nap_sdp_handle);
179
180 pan_cb.pan_nap_sdp_handle = pan_register_with_sdp (UUID_SERVCLASS_NAP, p_sec[2], p_nap_name, p_desc);
181 // btla-specific ++
182 bta_sys_add_uuid(UUID_SERVCLASS_NAP);
183 // btla-specific --
184 }
185 /* If the NAP role is already active and now being cleared delete the record */
186 else if (pan_cb.role & PAN_ROLE_NAP_SERVER)
187 {
188 if (pan_cb.pan_nap_sdp_handle != 0)
189 {
190 SDP_DeleteRecord (pan_cb.pan_nap_sdp_handle);
191 pan_cb.pan_nap_sdp_handle = 0;
192 // btla-specific ++
193 bta_sys_remove_uuid(UUID_SERVCLASS_NAP);
194 // btla-specific --
195 }
196 }
197 #endif
198
199 #if (defined (PAN_SUPPORTS_ROLE_GN) && PAN_SUPPORTS_ROLE_GN == TRUE)
200 /* Check the service name */
201 if ((p_gn_name == NULL) || (*p_gn_name == 0))
202 p_gn_name = PAN_GN_DEFAULT_SERVICE_NAME;
203
204 if (role & PAN_ROLE_GN_SERVER)
205 {
206 /* Registering for GN service with SDP */
207 p_desc = PAN_GN_DEFAULT_DESCRIPTION;
208
209 if (pan_cb.pan_gn_sdp_handle != 0)
210 SDP_DeleteRecord (pan_cb.pan_gn_sdp_handle);
211
212 pan_cb.pan_gn_sdp_handle = pan_register_with_sdp (UUID_SERVCLASS_GN, p_sec[1], p_gn_name, p_desc);
213 // btla-specific ++
214 bta_sys_add_uuid(UUID_SERVCLASS_GN);
215 // btla-specific --
216 }
217 /* If the GN role is already active and now being cleared delete the record */
218 else if (pan_cb.role & PAN_ROLE_GN_SERVER)
219 {
220 if (pan_cb.pan_gn_sdp_handle != 0)
221 {
222 SDP_DeleteRecord (pan_cb.pan_gn_sdp_handle);
223 pan_cb.pan_gn_sdp_handle = 0;
224 // btla-specific ++
225 bta_sys_remove_uuid(UUID_SERVCLASS_GN);
226 // btla-specific --
227 }
228 }
229 #endif
230
231 #if (defined (PAN_SUPPORTS_ROLE_PANU) && PAN_SUPPORTS_ROLE_PANU == TRUE)
232 /* Check the service name */
233 if ((p_user_name == NULL) || (*p_user_name == 0))
234 p_user_name = PAN_PANU_DEFAULT_SERVICE_NAME;
235
236 if (role & PAN_ROLE_CLIENT)
237 {
238 /* Registering for PANU service with SDP */
239 p_desc = PAN_PANU_DEFAULT_DESCRIPTION;
240 if (pan_cb.pan_user_sdp_handle != 0)
241 SDP_DeleteRecord (pan_cb.pan_user_sdp_handle);
242
243 pan_cb.pan_user_sdp_handle = pan_register_with_sdp (UUID_SERVCLASS_PANU, p_sec[0], p_user_name, p_desc);
244 // btla-specific ++
245 bta_sys_add_uuid(UUID_SERVCLASS_PANU);
246 // btla-specific --
247 }
248 /* If the PANU role is already active and now being cleared delete the record */
249 else if (pan_cb.role & PAN_ROLE_CLIENT)
250 {
251 if (pan_cb.pan_user_sdp_handle != 0)
252 {
253 SDP_DeleteRecord (pan_cb.pan_user_sdp_handle);
254 pan_cb.pan_user_sdp_handle = 0;
255 // btla-specific ++
256 bta_sys_remove_uuid(UUID_SERVCLASS_PANU);
257 // btla-specific --
258 }
259 }
260 #endif
261
262 /* Check if it is a shutdown request */
263 if (role == PAN_ROLE_INACTIVE)
264 pan_close_all_connections ();
265
266 pan_cb.role = role;
267 PAN_TRACE_EVENT1 ("PAN role set to: %d", role);
268 return PAN_SUCCESS;
269 }
270
271
272
273 /*******************************************************************************
274 **
275 ** Function PAN_Connect
276 **
277 ** Description This function is called by the application to initiate a
278 ** connection to the remote device
279 **
280 ** Parameters: rem_bda - BD Addr of the remote device
281 ** src_role - Role of the local device for the connection
282 ** dst_role - Role of the remote device for the connection
283 ** PAN_ROLE_CLIENT is for PANU role
284 ** PAN_ROLE_GN_SERVER is for GN role
285 ** PAN_ROLE_NAP_SERVER is for NAP role
286 ** *handle - Pointer for returning Handle to the connection
287 **
288 ** Returns PAN_SUCCESS - if the connection is initiated successfully
289 ** PAN_NO_RESOURCES - resources are not sufficent
290 ** PAN_FAILURE - if the connection cannot be initiated
291 ** this can be because of the combination of
292 ** src and dst roles may not be valid or
293 ** allowed at that point of time
294 **
295 *******************************************************************************/
PAN_Connect(BD_ADDR rem_bda,UINT8 src_role,UINT8 dst_role,UINT16 * handle)296 tPAN_RESULT PAN_Connect (BD_ADDR rem_bda, UINT8 src_role, UINT8 dst_role, UINT16 *handle)
297 {
298 tPAN_CONN *pcb;
299 tBNEP_RESULT result;
300 tBT_UUID src_uuid, dst_uuid;
301 UINT8 service_id;
302 UINT32 mx_chan_id;
303
304 /*
305 ** Initialize the handle so that in case of failure return values
306 ** the profile will not get confused
307 */
308 *handle = BNEP_INVALID_HANDLE;
309
310 /* Check if PAN is active or not */
311 if (!(pan_cb.role & src_role))
312 {
313 PAN_TRACE_ERROR1 ("PAN is not active for the role %d", src_role);
314 return PAN_FAILURE;
315 }
316
317 /* Validate the parameters before proceeding */
318 if ((src_role != PAN_ROLE_CLIENT && src_role != PAN_ROLE_GN_SERVER && src_role != PAN_ROLE_NAP_SERVER) ||
319 (dst_role != PAN_ROLE_CLIENT && dst_role != PAN_ROLE_GN_SERVER && dst_role != PAN_ROLE_NAP_SERVER))
320 {
321 PAN_TRACE_ERROR2 ("Either source %d or destination role %d is invalid", src_role, dst_role);
322 return PAN_FAILURE;
323 }
324
325 /* Check if connection exists for this remote device */
326 pcb = pan_get_pcb_by_addr (rem_bda);
327
328 /* If we are PANU for this role validate destination role */
329 if (src_role == PAN_ROLE_CLIENT)
330 {
331 if ((pan_cb.num_conns > 1) || (pan_cb.num_conns && (!pcb)))
332 {
333 /*
334 ** If the request is not for existing connection reject it
335 ** because if there is already a connection we cannot accept
336 ** another connection in PANU role
337 */
338 PAN_TRACE_ERROR0 ("Cannot make PANU connections when there are more than one connection");
339 return PAN_INVALID_SRC_ROLE;
340 }
341
342 src_uuid.uu.uuid16 = UUID_SERVCLASS_PANU;
343 if (dst_role == PAN_ROLE_CLIENT)
344 {
345 service_id = BTM_SEC_SERVICE_BNEP_PANU;
346 dst_uuid.uu.uuid16 = UUID_SERVCLASS_PANU;
347 }
348 else if (dst_role == PAN_ROLE_GN_SERVER)
349 {
350 service_id = BTM_SEC_SERVICE_BNEP_GN;
351 dst_uuid.uu.uuid16 = UUID_SERVCLASS_GN;
352 }
353 else
354 {
355 service_id = BTM_SEC_SERVICE_BNEP_NAP;
356 dst_uuid.uu.uuid16 = UUID_SERVCLASS_NAP;
357 }
358 mx_chan_id = dst_uuid.uu.uuid16;
359 }
360 /* If destination is PANU role validate source role */
361 else if (dst_role == PAN_ROLE_CLIENT)
362 {
363 if (pan_cb.num_conns && pan_cb.active_role == PAN_ROLE_CLIENT && !pcb)
364 {
365 PAN_TRACE_ERROR0 ("Device already have a connection in PANU role");
366 return PAN_INVALID_SRC_ROLE;
367 }
368
369 dst_uuid.uu.uuid16 = UUID_SERVCLASS_PANU;
370 if (src_role == PAN_ROLE_GN_SERVER)
371 {
372 service_id = BTM_SEC_SERVICE_BNEP_GN;
373 src_uuid.uu.uuid16 = UUID_SERVCLASS_GN;
374 }
375 else
376 {
377 service_id = BTM_SEC_SERVICE_BNEP_NAP;
378 src_uuid.uu.uuid16 = UUID_SERVCLASS_NAP;
379 }
380 mx_chan_id = src_uuid.uu.uuid16;
381 }
382 /* The role combination is not valid */
383 else
384 {
385 PAN_TRACE_ERROR2 ("Source %d and Destination roles %d are not valid combination",
386 src_role, dst_role);
387 return PAN_FAILURE;
388 }
389
390 /* Allocate control block and initiate connection */
391 if (!pcb)
392 pcb = pan_allocate_pcb (rem_bda, BNEP_INVALID_HANDLE);
393 if (!pcb)
394 {
395 PAN_TRACE_ERROR0 ("PAN Connection failed because of no resources");
396 return PAN_NO_RESOURCES;
397 }
398 BTM_SetOutService(rem_bda, BTM_SEC_SERVICE_BNEP_PANU, mx_chan_id);
399
400 PAN_TRACE_API6 ("PAN_Connect() for BD Addr %x.%x.%x.%x.%x.%x",
401 rem_bda[0], rem_bda[1], rem_bda[2], rem_bda[3], rem_bda[4], rem_bda[5]);
402 if (pcb->con_state == PAN_STATE_IDLE)
403 {
404 pan_cb.num_conns++;
405 }
406 else if (pcb->con_state == PAN_STATE_CONNECTED)
407 {
408 pcb->con_flags |= PAN_FLAGS_CONN_COMPLETED;
409 }
410 else
411 /* PAN connection is still in progress */
412 return PAN_WRONG_STATE;
413
414 pcb->con_state = PAN_STATE_CONN_START;
415 pcb->prv_src_uuid = pcb->src_uuid;
416 pcb->prv_dst_uuid = pcb->dst_uuid;
417
418 pcb->src_uuid = src_uuid.uu.uuid16;
419 pcb->dst_uuid = dst_uuid.uu.uuid16;
420
421 src_uuid.len = 2;
422 dst_uuid.len = 2;
423
424 result = BNEP_Connect (rem_bda, &src_uuid, &dst_uuid, &(pcb->handle));
425 if (result != BNEP_SUCCESS)
426 {
427 pan_release_pcb (pcb);
428 return result;
429 }
430
431 PAN_TRACE_DEBUG1 ("PAN_Connect() current active role set to %d", src_role);
432 pan_cb.prv_active_role = pan_cb.active_role;
433 pan_cb.active_role = src_role;
434 *handle = pcb->handle;
435 return PAN_SUCCESS;
436 }
437
438
439
440
441 /*******************************************************************************
442 **
443 ** Function PAN_Disconnect
444 **
445 ** Description This is used to disconnect the connection
446 **
447 ** Parameters: handle - handle for the connection
448 **
449 ** Returns PAN_SUCCESS - if the connection is closed successfully
450 ** PAN_FAILURE - if the connection is not found or
451 ** there is an error in disconnecting
452 **
453 *******************************************************************************/
PAN_Disconnect(UINT16 handle)454 tPAN_RESULT PAN_Disconnect (UINT16 handle)
455 {
456 tPAN_CONN *pcb;
457 tBNEP_RESULT result;
458
459 /* Check if the connection exists */
460 pcb = pan_get_pcb_by_handle (handle);
461 if(!pcb)
462 {
463 PAN_TRACE_ERROR1 ("PAN connection not found for the handle %d", handle);
464 return PAN_FAILURE;
465 }
466
467 result = BNEP_Disconnect (pcb->handle);
468 if (pcb->con_state == PAN_STATE_CONNECTED)
469 pan_cb.num_conns--;
470
471 if (pan_cb.pan_bridge_req_cb && pcb->src_uuid == UUID_SERVCLASS_NAP)
472 (*pan_cb.pan_bridge_req_cb) (pcb->rem_bda, FALSE);
473
474 pan_release_pcb (pcb);
475
476 if (result != BNEP_SUCCESS)
477 {
478 PAN_TRACE_EVENT0 ("Error in closing PAN connection");
479 return PAN_FAILURE;
480 }
481
482 PAN_TRACE_EVENT0 ("PAN connection closed");
483 return PAN_SUCCESS;
484 }
485
486
487 /*******************************************************************************
488 **
489 ** Function PAN_Write
490 **
491 ** Description This sends data over the PAN connections. If this is called
492 ** on GN or NAP side and the packet is multicast or broadcast
493 ** it will be sent on all the links. Otherwise the correct link
494 ** is found based on the destination address and forwarded on it
495 ** If the return value is not PAN_SUCCESS the application should
496 ** take care of releasing the message buffer
497 **
498 ** Parameters: handle - handle for the connection
499 ** dst - MAC or BD Addr of the destination device
500 ** src - MAC or BD Addr of the source who sent this packet
501 ** protocol - protocol of the ethernet packet like IP or ARP
502 ** p_data - pointer to the data
503 ** len - length of the data
504 ** ext - to indicate that extension headers present
505 **
506 ** Returns PAN_SUCCESS - if the data is sent successfully
507 ** PAN_FAILURE - if the connection is not found or
508 ** there is an error in sending data
509 **
510 *******************************************************************************/
PAN_Write(UINT16 handle,BD_ADDR dst,BD_ADDR src,UINT16 protocol,UINT8 * p_data,UINT16 len,BOOLEAN ext)511 tPAN_RESULT PAN_Write (UINT16 handle, BD_ADDR dst, BD_ADDR src, UINT16 protocol, UINT8 *p_data, UINT16 len, BOOLEAN ext)
512 {
513 tPAN_CONN *pcb;
514 UINT16 i;
515 tBNEP_RESULT result;
516
517 if (pan_cb.role == PAN_ROLE_INACTIVE || (!(pan_cb.num_conns)))
518 {
519 PAN_TRACE_ERROR0 ("PAN is not active Data write failed");
520 return PAN_FAILURE;
521 }
522
523 /* Check if it is broadcast or multicast packet */
524 if (dst[0] & 0x01)
525 {
526 for (i=0; i<MAX_PAN_CONNS; i++)
527 {
528 if (pan_cb.pcb[i].con_state == PAN_STATE_CONNECTED)
529 BNEP_Write (pan_cb.pcb[i].handle, dst, p_data, len, protocol, src, ext);
530 }
531
532 return PAN_SUCCESS;
533 }
534
535 if (pan_cb.active_role == PAN_ROLE_CLIENT)
536 {
537 /* Data write is on PANU connection */
538 for (i=0; i<MAX_PAN_CONNS; i++)
539 {
540 if (pan_cb.pcb[i].con_state == PAN_STATE_CONNECTED &&
541 pan_cb.pcb[i].src_uuid == UUID_SERVCLASS_PANU)
542 break;
543 }
544
545 if (i == MAX_PAN_CONNS)
546 {
547 PAN_TRACE_ERROR0 ("PAN Don't have any user connections");
548 return PAN_FAILURE;
549 }
550
551 result = BNEP_Write (pan_cb.pcb[i].handle, dst, p_data, len, protocol, src, ext);
552 if (result == BNEP_IGNORE_CMD)
553 {
554 PAN_TRACE_DEBUG0 ("PAN ignored data for PANU connection");
555 return result;
556 }
557 else if (result != BNEP_SUCCESS)
558 {
559 PAN_TRACE_ERROR0 ("PAN failed to write data for the PANU connection");
560 return result;
561 }
562
563 PAN_TRACE_DEBUG0 ("PAN successfully wrote data for the PANU connection");
564 return PAN_SUCCESS;
565 }
566
567 pcb = pan_get_pcb_by_handle (handle);
568 if (!pcb)
569 {
570 PAN_TRACE_ERROR0 ("PAN Data write for wrong addr");
571 return PAN_FAILURE;
572 }
573
574 if (pcb->con_state != PAN_STATE_CONNECTED)
575 {
576 PAN_TRACE_ERROR0 ("PAN Data write when conn is not active");
577 return PAN_FAILURE;
578 }
579
580 result = BNEP_Write (pcb->handle, dst, p_data, len, protocol, src, ext);
581 if (result == BNEP_IGNORE_CMD)
582 {
583 PAN_TRACE_DEBUG0 ("PAN ignored data write to PANU");
584 return result;
585 }
586 else if (result != BNEP_SUCCESS)
587 {
588 PAN_TRACE_ERROR0 ("PAN failed to send data to the PANU");
589 return result;
590 }
591
592 PAN_TRACE_DEBUG0 ("PAN successfully sent data to the PANU");
593 return PAN_SUCCESS;
594 }
595
596
597 /*******************************************************************************
598 **
599 ** Function PAN_WriteBuf
600 **
601 ** Description This sends data over the PAN connections. If this is called
602 ** on GN or NAP side and the packet is multicast or broadcast
603 ** it will be sent on all the links. Otherwise the correct link
604 ** is found based on the destination address and forwarded on it
605 ** If the return value is not PAN_SUCCESS the application should
606 ** take care of releasing the message buffer
607 **
608 ** Parameters: handle - handle for the connection
609 ** dst - MAC or BD Addr of the destination device
610 ** src - MAC or BD Addr of the source who sent this packet
611 ** protocol - protocol of the ethernet packet like IP or ARP
612 ** p_buf - pointer to the data buffer
613 ** ext - to indicate that extension headers present
614 **
615 ** Returns PAN_SUCCESS - if the data is sent successfully
616 ** PAN_FAILURE - if the connection is not found or
617 ** there is an error in sending data
618 **
619 *******************************************************************************/
PAN_WriteBuf(UINT16 handle,BD_ADDR dst,BD_ADDR src,UINT16 protocol,BT_HDR * p_buf,BOOLEAN ext)620 tPAN_RESULT PAN_WriteBuf (UINT16 handle, BD_ADDR dst, BD_ADDR src, UINT16 protocol, BT_HDR *p_buf, BOOLEAN ext)
621 {
622 tPAN_CONN *pcb;
623 UINT16 i;
624 tBNEP_RESULT result;
625
626 /* Check if it is broadcast or multicast packet */
627 if (dst[0] & 0x01)
628 {
629 UINT8 *p_data;
630 UINT16 len;
631
632 p_data = (UINT8 *)(p_buf + 1) + p_buf->offset;
633 len = p_buf->len;
634 PAN_Write (handle, dst, src, protocol, p_data, len, ext);
635 GKI_freebuf (p_buf);
636 return PAN_SUCCESS;
637 }
638
639 if (pan_cb.role == PAN_ROLE_INACTIVE || (!(pan_cb.num_conns)))
640 {
641 PAN_TRACE_ERROR0 ("PAN is not active Data write failed");
642 GKI_freebuf (p_buf);
643 return PAN_FAILURE;
644 }
645
646 /* Check if the data write is on PANU side */
647 if (pan_cb.active_role == PAN_ROLE_CLIENT)
648 {
649 /* Data write is on PANU connection */
650 for (i=0; i<MAX_PAN_CONNS; i++)
651 {
652 if (pan_cb.pcb[i].con_state == PAN_STATE_CONNECTED &&
653 pan_cb.pcb[i].src_uuid == UUID_SERVCLASS_PANU)
654 break;
655 }
656
657 if (i == MAX_PAN_CONNS)
658 {
659 PAN_TRACE_ERROR0 ("PAN Don't have any user connections");
660 GKI_freebuf (p_buf);
661 return PAN_FAILURE;
662 }
663
664 result = BNEP_WriteBuf (pan_cb.pcb[i].handle, dst, p_buf, protocol, src, ext);
665 if (result == BNEP_IGNORE_CMD)
666 {
667 PAN_TRACE_DEBUG0 ("PAN ignored data write for PANU connection");
668 return result;
669 }
670 else if (result != BNEP_SUCCESS)
671 {
672 PAN_TRACE_ERROR0 ("PAN failed to write data for the PANU connection");
673 return result;
674 }
675
676 PAN_TRACE_DEBUG0 ("PAN successfully wrote data for the PANU connection");
677 return PAN_SUCCESS;
678 }
679
680 /* findout to which connection the data is meant for */
681 pcb = pan_get_pcb_by_handle (handle);
682 if (!pcb)
683 {
684 PAN_TRACE_ERROR0 ("PAN Buf write for wrong handle");
685 GKI_freebuf (p_buf);
686 return PAN_FAILURE;
687 }
688
689 if (pcb->con_state != PAN_STATE_CONNECTED)
690 {
691 PAN_TRACE_ERROR0 ("PAN Buf write when conn is not active");
692 GKI_freebuf (p_buf);
693 return PAN_FAILURE;
694 }
695
696 result = BNEP_WriteBuf (pcb->handle, dst, p_buf, protocol, src, ext);
697 if (result == BNEP_IGNORE_CMD)
698 {
699 PAN_TRACE_DEBUG0 ("PAN ignored data buf write to PANU");
700 return result;
701 }
702 else if (result != BNEP_SUCCESS)
703 {
704 PAN_TRACE_ERROR0 ("PAN failed to send data buf to the PANU");
705 return result;
706 }
707
708 PAN_TRACE_DEBUG0 ("PAN successfully sent data buf to the PANU");
709 return PAN_SUCCESS;
710 }
711
712
713 /*******************************************************************************
714 **
715 ** Function PAN_SetProtocolFilters
716 **
717 ** Description This function is used to set protocol filters on the peer
718 **
719 ** Parameters: handle - handle for the connection
720 ** num_filters - number of protocol filter ranges
721 ** start - array of starting protocol numbers
722 ** end - array of ending protocol numbers
723 **
724 **
725 ** Returns PAN_SUCCESS if protocol filters are set successfully
726 ** PAN_FAILURE if connection not found or error in setting
727 **
728 *******************************************************************************/
PAN_SetProtocolFilters(UINT16 handle,UINT16 num_filters,UINT16 * p_start_array,UINT16 * p_end_array)729 tPAN_RESULT PAN_SetProtocolFilters (UINT16 handle,
730 UINT16 num_filters,
731 UINT16 *p_start_array,
732 UINT16 *p_end_array)
733 {
734 #if (defined (BNEP_SUPPORTS_PROT_FILTERS) && BNEP_SUPPORTS_PROT_FILTERS == TRUE)
735 tPAN_CONN *pcb;
736 tPAN_RESULT result;
737
738 /* Check if the connection exists */
739 pcb = pan_get_pcb_by_handle (handle);
740 if(!pcb)
741 {
742 PAN_TRACE_ERROR1 ("PAN connection not found for the handle %d", handle);
743 return PAN_FAILURE;
744 }
745
746 result = BNEP_SetProtocolFilters (pcb->handle, num_filters, p_start_array, p_end_array);
747 if (result != BNEP_SUCCESS)
748 {
749 PAN_TRACE_ERROR1 ("PAN failed to set protocol filters for handle %d", handle);
750 return result;
751 }
752
753 PAN_TRACE_API1 ("PAN successfully sent protocol filters for handle %d", handle);
754 return PAN_SUCCESS;
755 #else
756 return PAN_FAILURE;
757 #endif
758 }
759
760
761
762 /*******************************************************************************
763 **
764 ** Function PAN_SetMulticastFilters
765 **
766 ** Description This function is used to set multicast filters on the peer
767 **
768 ** Parameters: handle - handle for the connection
769 ** num_filters - number of multicast filter ranges
770 ** start - array of starting multicast filter addresses
771 ** end - array of ending multicast filter addresses
772 **
773 **
774 ** Returns PAN_SUCCESS if multicast filters are set successfully
775 ** PAN_FAILURE if connection not found or error in setting
776 **
777 *******************************************************************************/
PAN_SetMulticastFilters(UINT16 handle,UINT16 num_mcast_filters,UINT8 * p_start_array,UINT8 * p_end_array)778 tBNEP_RESULT PAN_SetMulticastFilters (UINT16 handle,
779 UINT16 num_mcast_filters,
780 UINT8 *p_start_array,
781 UINT8 *p_end_array)
782 {
783 #if (defined (BNEP_SUPPORTS_MULTI_FILTERS) && BNEP_SUPPORTS_MULTI_FILTERS == TRUE)
784 tPAN_CONN *pcb;
785 tPAN_RESULT result;
786
787 /* Check if the connection exists */
788 pcb = pan_get_pcb_by_handle (handle);
789 if(!pcb)
790 {
791 PAN_TRACE_ERROR1 ("PAN connection not found for the handle %d", handle);
792 return PAN_FAILURE;
793 }
794
795 result = BNEP_SetMulticastFilters (pcb->handle,
796 num_mcast_filters, p_start_array, p_end_array);
797 if (result != BNEP_SUCCESS)
798 {
799 PAN_TRACE_ERROR1 ("PAN failed to set multicast filters for handle %d", handle);
800 return result;
801 }
802
803 PAN_TRACE_API1 ("PAN successfully sent multicast filters for handle %d", handle);
804 return PAN_SUCCESS;
805 #else
806 return PAN_FAILURE;
807 #endif
808 }
809
810
811 /*******************************************************************************
812 **
813 ** Function PAN_SetTraceLevel
814 **
815 ** Description This function sets the trace level for PAN. If called with
816 ** a value of 0xFF, it simply reads the current trace level.
817 **
818 ** Returns the new (current) trace level
819 **
820 *******************************************************************************/
PAN_SetTraceLevel(UINT8 new_level)821 UINT8 PAN_SetTraceLevel (UINT8 new_level)
822 {
823 if (new_level != 0xFF)
824 pan_cb.trace_level = new_level;
825 else
826 pan_dump_status ();
827
828 return (pan_cb.trace_level);
829 }
830
831 /*******************************************************************************
832 **
833 ** Function PAN_Init
834 **
835 ** Description This function initializes the PAN module variables
836 **
837 ** Parameters: none
838 **
839 ** Returns none
840 **
841 *******************************************************************************/
PAN_Init(void)842 void PAN_Init (void)
843 {
844 memset (&pan_cb, 0, sizeof (tPAN_CB));
845
846 #if defined(PAN_INITIAL_TRACE_LEVEL)
847 pan_cb.trace_level = PAN_INITIAL_TRACE_LEVEL;
848 #else
849 pan_cb.trace_level = BT_TRACE_LEVEL_NONE; /* No traces */
850 #endif
851 }
852
853
854