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