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