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 
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 // 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 *******************************************************************************/
pan_allocate_pcb(BD_ADDR p_bda,UINT16 handle)182 tPAN_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 *******************************************************************************/
pan_get_pcb_by_handle(UINT16 handle)223 tPAN_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 *******************************************************************************/
pan_get_pcb_by_addr(BD_ADDR p_bda)247 tPAN_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 *******************************************************************************/
pan_close_all_connections(void)281 void 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 *******************************************************************************/
pan_release_pcb(tPAN_CONN * p_pcb)309 void 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 *******************************************************************************/
pan_dump_status(void)327 void 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