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