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 <stdio.h>
28#include "gki.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
39static const UINT8 pan_proto_elem_data[]   = {
40                                   0x35, 0x18,          /* data element sequence of length 0x18 bytes */
41                                   0x35, 0x06,          /* data element sequence for L2CAP descriptor */
42                                   0x19, 0x01, 0x00,    /* UUID for L2CAP - 0x0100 */
43                                   0x09, 0x00, 0x0F,    /* PSM for BNEP - 0x000F */
44                                   0x35, 0x0E,          /* data element seqence for BNEP descriptor */
45                                   0x19, 0x00, 0x0F,    /* UUID for BNEP - 0x000F */
46                                   0x09, 0x01, 0x00,    /* BNEP specific parameter 0 -- Version of BNEP = version 1 = 0x0001 */
47                                   0x35, 0x06,          /* BNEP specific parameter 1 -- Supported network packet type list */
48                                   0x09, 0x08, 0x00,    /* network packet type IPv4 = 0x0800 */
49                                   0x09, 0x08, 0x06     /* network packet type ARP  = 0x0806 */
50};
51
52/*******************************************************************************
53**
54** Function         pan_register_with_sdp
55**
56** Description
57**
58** Returns
59**
60*******************************************************************************/
61UINT32 pan_register_with_sdp (UINT16 uuid, UINT8 sec_mask, char *p_name, char *p_desc)
62{
63    UINT32  sdp_handle;
64    UINT16  browse_list = UUID_SERVCLASS_PUBLIC_BROWSE_GROUP;
65    UINT16  security = 0;
66    UINT32  proto_len = (UINT32)pan_proto_elem_data[1];
67
68    /* Create a record */
69    sdp_handle = SDP_CreateRecord ();
70
71    if (sdp_handle == 0)
72    {
73        PAN_TRACE_ERROR ("PAN_SetRole - could not create SDP record");
74        return 0;
75    }
76
77    /* Service Class ID List */
78    SDP_AddServiceClassIdList (sdp_handle, 1, &uuid);
79
80    /* Add protocol element sequence from the constant string */
81    SDP_AddAttribute (sdp_handle, ATTR_ID_PROTOCOL_DESC_LIST, DATA_ELE_SEQ_DESC_TYPE,
82                      proto_len, (UINT8 *)(pan_proto_elem_data+2));
83
84// btla-specific ++
85#if 0
86    availability = 0xFF;
87    SDP_AddAttribute (sdp_handle, ATTR_ID_SERVICE_AVAILABILITY, UINT_DESC_TYPE, 1, &availability);
88#endif
89// btla-specific --
90
91    /* Language base */
92    SDP_AddLanguageBaseAttrIDList (sdp_handle, LANG_ID_CODE_ENGLISH, LANG_ID_CHAR_ENCODE_UTF8, LANGUAGE_BASE_ID);
93
94    /* Profile descriptor list */
95    SDP_AddProfileDescriptorList (sdp_handle, uuid, PAN_PROFILE_VERSION);
96
97    /* Service Name */
98    SDP_AddAttribute (sdp_handle, ATTR_ID_SERVICE_NAME, TEXT_STR_DESC_TYPE,
99                        (UINT8) (strlen(p_name) + 1), (UINT8 *)p_name);
100
101    /* Service description */
102    SDP_AddAttribute (sdp_handle, ATTR_ID_SERVICE_DESCRIPTION, TEXT_STR_DESC_TYPE,
103                        (UINT8) (strlen(p_desc) + 1), (UINT8 *)p_desc);
104
105    /* Security description */
106    if (sec_mask)
107    {
108        UINT16_TO_BE_FIELD(&security, 0x0001);
109    }
110    SDP_AddAttribute (sdp_handle, ATTR_ID_SECURITY_DESCRIPTION, UINT_DESC_TYPE, 2, (UINT8 *)&security);
111
112#if (defined (PAN_SUPPORTS_ROLE_NAP) && PAN_SUPPORTS_ROLE_NAP == TRUE)
113    if (uuid == UUID_SERVCLASS_NAP)
114    {
115        UINT16  NetAccessType = 0x0005;      /* Ethernet */
116        UINT32  NetAccessRate = 0x0001312D0; /* 10Mb/sec */
117        UINT8   array[10], *p;
118
119        /* Net access type. */
120        p = array;
121        UINT16_TO_BE_STREAM (p, NetAccessType);
122        SDP_AddAttribute (sdp_handle, ATTR_ID_NET_ACCESS_TYPE, UINT_DESC_TYPE, 2, array);
123
124        /* Net access rate. */
125        p = array;
126        UINT32_TO_BE_STREAM (p, NetAccessRate);
127        SDP_AddAttribute (sdp_handle, ATTR_ID_MAX_NET_ACCESS_RATE, UINT_DESC_TYPE, 4, array);
128
129        /* Register with Security Manager for the specific security level */
130        if ((!BTM_SetSecurityLevel (TRUE, p_name, BTM_SEC_SERVICE_BNEP_NAP,
131                                    sec_mask, BT_PSM_BNEP, BTM_SEC_PROTO_BNEP, UUID_SERVCLASS_NAP))
132         || (!BTM_SetSecurityLevel (FALSE, p_name, BTM_SEC_SERVICE_BNEP_NAP,
133                                    sec_mask, BT_PSM_BNEP, BTM_SEC_PROTO_BNEP, UUID_SERVCLASS_NAP)))
134        {
135            PAN_TRACE_ERROR ("PAN Security Registration failed for PANU");
136        }
137    }
138#endif
139#if (defined (PAN_SUPPORTS_ROLE_GN) && PAN_SUPPORTS_ROLE_GN == TRUE)
140    if (uuid == UUID_SERVCLASS_GN)
141    {
142        if ((!BTM_SetSecurityLevel (TRUE, p_name, BTM_SEC_SERVICE_BNEP_GN,
143                                    sec_mask, BT_PSM_BNEP, BTM_SEC_PROTO_BNEP, UUID_SERVCLASS_GN))
144         || (!BTM_SetSecurityLevel (FALSE, p_name, BTM_SEC_SERVICE_BNEP_GN,
145                                    sec_mask, BT_PSM_BNEP, BTM_SEC_PROTO_BNEP, UUID_SERVCLASS_GN)))
146        {
147            PAN_TRACE_ERROR ("PAN Security Registration failed for GN");
148        }
149    }
150#endif
151#if (defined (PAN_SUPPORTS_ROLE_PANU) && PAN_SUPPORTS_ROLE_PANU == TRUE)
152    if (uuid == UUID_SERVCLASS_PANU)
153    {
154        if ((!BTM_SetSecurityLevel (TRUE, p_name, BTM_SEC_SERVICE_BNEP_PANU,
155                                    sec_mask, BT_PSM_BNEP, BTM_SEC_PROTO_BNEP, UUID_SERVCLASS_PANU))
156         || (!BTM_SetSecurityLevel (FALSE, p_name, BTM_SEC_SERVICE_BNEP_PANU,
157                                    sec_mask, BT_PSM_BNEP, BTM_SEC_PROTO_BNEP, UUID_SERVCLASS_PANU)))
158        {
159            PAN_TRACE_ERROR ("PAN Security Registration failed for PANU");
160        }
161    }
162#endif
163
164    /* Make the service browsable */
165    SDP_AddUuidSequence (sdp_handle,  ATTR_ID_BROWSE_GROUP_LIST, 1, &browse_list);
166
167
168    return sdp_handle;
169}
170
171
172
173/*******************************************************************************
174**
175** Function         pan_allocate_pcb
176**
177** Description
178**
179** Returns
180**
181*******************************************************************************/
182tPAN_CONN *pan_allocate_pcb (BD_ADDR p_bda, UINT16 handle)
183{
184    UINT16      i;
185
186    for (i=0; i<MAX_PAN_CONNS; i++)
187    {
188        if (pan_cb.pcb[i].con_state != PAN_STATE_IDLE &&
189            pan_cb.pcb[i].handle == handle)
190            return NULL;
191    }
192
193    for (i=0; i<MAX_PAN_CONNS; i++)
194    {
195        if (pan_cb.pcb[i].con_state != PAN_STATE_IDLE &&
196            memcmp (pan_cb.pcb[i].rem_bda, p_bda, BD_ADDR_LEN) == 0)
197            return NULL;
198    }
199
200    for (i=0; i<MAX_PAN_CONNS; i++)
201    {
202        if (pan_cb.pcb[i].con_state == PAN_STATE_IDLE)
203        {
204            memset (&(pan_cb.pcb[i]), 0, sizeof (tPAN_CONN));
205            memcpy (pan_cb.pcb[i].rem_bda, p_bda, BD_ADDR_LEN);
206            pan_cb.pcb[i].handle = handle;
207            return &(pan_cb.pcb[i]);
208        }
209    }
210    return NULL;
211}
212
213
214/*******************************************************************************
215**
216** Function         pan_get_pcb_by_handle
217**
218** Description
219**
220** Returns
221**
222*******************************************************************************/
223tPAN_CONN *pan_get_pcb_by_handle (UINT16 handle)
224{
225    UINT16      i;
226
227    for (i=0; i<MAX_PAN_CONNS; i++)
228    {
229        if (pan_cb.pcb[i].con_state != PAN_STATE_IDLE &&
230            pan_cb.pcb[i].handle == handle)
231            return &(pan_cb.pcb[i]);
232    }
233
234    return NULL;
235}
236
237
238/*******************************************************************************
239**
240** Function         pan_get_pcb_by_addr
241**
242** Description
243**
244** Returns
245**
246*******************************************************************************/
247tPAN_CONN *pan_get_pcb_by_addr (BD_ADDR p_bda)
248{
249    UINT16      i;
250
251    for (i=0; i<MAX_PAN_CONNS; i++)
252    {
253        if (pan_cb.pcb[i].con_state == PAN_STATE_IDLE)
254            continue;
255
256        if (memcmp (pan_cb.pcb[i].rem_bda, p_bda, BD_ADDR_LEN) == 0)
257            return &(pan_cb.pcb[i]);
258
259        /*
260        if (pan_cb.pcb[i].mfilter_present &&
261            (memcmp (p_bda, pan_cb.pcb[i].multi_cast_bridge, BD_ADDR_LEN) == 0))
262            return &(pan_cb.pcb[i]);
263        */
264    }
265
266    return NULL;
267}
268
269
270
271
272/*******************************************************************************
273**
274** Function         pan_close_all_connections
275**
276** Description
277**
278** Returns          void
279**
280*******************************************************************************/
281void pan_close_all_connections (void)
282{
283    UINT16      i;
284
285    for (i=0; i<MAX_PAN_CONNS; i++)
286    {
287        if (pan_cb.pcb[i].con_state != PAN_STATE_IDLE)
288        {
289            BNEP_Disconnect (pan_cb.pcb[i].handle);
290            pan_cb.pcb[i].con_state = PAN_STATE_IDLE;
291        }
292    }
293
294    pan_cb.active_role = PAN_ROLE_INACTIVE;
295    pan_cb.num_conns   = 0;
296    return;
297}
298
299
300/*******************************************************************************
301**
302** Function         pan_release_pcb
303**
304** Description      This function releases a PCB.
305**
306** Returns          void
307**
308*******************************************************************************/
309void pan_release_pcb (tPAN_CONN *p_pcb)
310{
311    /* Drop any response pointer we may be holding */
312    memset (p_pcb, 0, sizeof (tPAN_CONN));
313    p_pcb->con_state = PAN_STATE_IDLE;
314}
315
316
317/*******************************************************************************
318**
319** Function         pan_dump_status
320**
321** Description      This function dumps the pan control block and connection
322**                  blocks information
323**
324** Returns          none
325**
326*******************************************************************************/
327void pan_dump_status (void)
328{
329#if (defined (PAN_SUPPORTS_DEBUG_DUMP) && PAN_SUPPORTS_DEBUG_DUMP == TRUE)
330    UINT16          i;
331    char            buff[200];
332    tPAN_CONN      *p_pcb;
333
334    PAN_TRACE_DEBUG ("PAN role %x, active role %d, num_conns %d",
335        pan_cb.role, pan_cb.active_role, pan_cb.num_conns);
336
337    for (i = 0, p_pcb = pan_cb.pcb; i < MAX_PAN_CONNS; i++, p_pcb++)
338    {
339        sprintf (buff, "%d state %d, handle %d, src 0x%x, dst 0x%x, BD %x.%x.%x.%x.%x.%x",
340            i, p_pcb->con_state, p_pcb->handle, p_pcb->src_uuid, p_pcb->dst_uuid,
341            p_pcb->rem_bda[0], p_pcb->rem_bda[1], p_pcb->rem_bda[2],
342            p_pcb->rem_bda[3], p_pcb->rem_bda[4], p_pcb->rem_bda[5]);
343
344        PAN_TRACE_DEBUG (buff);
345    }
346#endif
347}
348
349
350
351