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