• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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