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