• 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 #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