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