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 "gki.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 *******************************************************************************/ 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 // btla-specific ++ 85 #if 0 86 availability = 0xFF; 87 SDP_AddAttribute (sdp_handle, ATTR_ID_SERVICE_AVAILABILITY, UINT_DESC_TYPE, 1, &availability); 88 #endif 89 // btla-specific -- 90 91 /* Language base */ 92 SDP_AddLanguageBaseAttrIDList (sdp_handle, LANG_ID_CODE_ENGLISH, LANG_ID_CHAR_ENCODE_UTF8, LANGUAGE_BASE_ID); 93 94 /* Profile descriptor list */ 95 SDP_AddProfileDescriptorList (sdp_handle, uuid, PAN_PROFILE_VERSION); 96 97 /* Service Name */ 98 SDP_AddAttribute (sdp_handle, ATTR_ID_SERVICE_NAME, TEXT_STR_DESC_TYPE, 99 (UINT8) (strlen(p_name) + 1), (UINT8 *)p_name); 100 101 /* Service description */ 102 SDP_AddAttribute (sdp_handle, ATTR_ID_SERVICE_DESCRIPTION, TEXT_STR_DESC_TYPE, 103 (UINT8) (strlen(p_desc) + 1), (UINT8 *)p_desc); 104 105 /* Security description */ 106 if (sec_mask) 107 { 108 UINT16_TO_BE_FIELD(&security, 0x0001); 109 } 110 SDP_AddAttribute (sdp_handle, ATTR_ID_SECURITY_DESCRIPTION, UINT_DESC_TYPE, 2, (UINT8 *)&security); 111 112 #if (defined (PAN_SUPPORTS_ROLE_NAP) && PAN_SUPPORTS_ROLE_NAP == TRUE) 113 if (uuid == UUID_SERVCLASS_NAP) 114 { 115 UINT16 NetAccessType = 0x0005; /* Ethernet */ 116 UINT32 NetAccessRate = 0x0001312D0; /* 10Mb/sec */ 117 UINT8 array[10], *p; 118 119 /* Net access type. */ 120 p = array; 121 UINT16_TO_BE_STREAM (p, NetAccessType); 122 SDP_AddAttribute (sdp_handle, ATTR_ID_NET_ACCESS_TYPE, UINT_DESC_TYPE, 2, array); 123 124 /* Net access rate. */ 125 p = array; 126 UINT32_TO_BE_STREAM (p, NetAccessRate); 127 SDP_AddAttribute (sdp_handle, ATTR_ID_MAX_NET_ACCESS_RATE, UINT_DESC_TYPE, 4, array); 128 129 /* Register with Security Manager for the specific security level */ 130 if ((!BTM_SetSecurityLevel (TRUE, p_name, BTM_SEC_SERVICE_BNEP_NAP, 131 sec_mask, BT_PSM_BNEP, BTM_SEC_PROTO_BNEP, UUID_SERVCLASS_NAP)) 132 || (!BTM_SetSecurityLevel (FALSE, p_name, BTM_SEC_SERVICE_BNEP_NAP, 133 sec_mask, BT_PSM_BNEP, BTM_SEC_PROTO_BNEP, UUID_SERVCLASS_NAP))) 134 { 135 PAN_TRACE_ERROR ("PAN Security Registration failed for PANU"); 136 } 137 } 138 #endif 139 #if (defined (PAN_SUPPORTS_ROLE_GN) && PAN_SUPPORTS_ROLE_GN == TRUE) 140 if (uuid == UUID_SERVCLASS_GN) 141 { 142 if ((!BTM_SetSecurityLevel (TRUE, p_name, BTM_SEC_SERVICE_BNEP_GN, 143 sec_mask, BT_PSM_BNEP, BTM_SEC_PROTO_BNEP, UUID_SERVCLASS_GN)) 144 || (!BTM_SetSecurityLevel (FALSE, p_name, BTM_SEC_SERVICE_BNEP_GN, 145 sec_mask, BT_PSM_BNEP, BTM_SEC_PROTO_BNEP, UUID_SERVCLASS_GN))) 146 { 147 PAN_TRACE_ERROR ("PAN Security Registration failed for GN"); 148 } 149 } 150 #endif 151 #if (defined (PAN_SUPPORTS_ROLE_PANU) && PAN_SUPPORTS_ROLE_PANU == TRUE) 152 if (uuid == UUID_SERVCLASS_PANU) 153 { 154 if ((!BTM_SetSecurityLevel (TRUE, p_name, BTM_SEC_SERVICE_BNEP_PANU, 155 sec_mask, BT_PSM_BNEP, BTM_SEC_PROTO_BNEP, UUID_SERVCLASS_PANU)) 156 || (!BTM_SetSecurityLevel (FALSE, p_name, BTM_SEC_SERVICE_BNEP_PANU, 157 sec_mask, BT_PSM_BNEP, BTM_SEC_PROTO_BNEP, UUID_SERVCLASS_PANU))) 158 { 159 PAN_TRACE_ERROR ("PAN Security Registration failed for PANU"); 160 } 161 } 162 #endif 163 164 /* Make the service browsable */ 165 SDP_AddUuidSequence (sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1, &browse_list); 166 167 168 return sdp_handle; 169 } 170 171 172 173 /******************************************************************************* 174 ** 175 ** Function pan_allocate_pcb 176 ** 177 ** Description 178 ** 179 ** Returns 180 ** 181 *******************************************************************************/ 182 tPAN_CONN *pan_allocate_pcb (BD_ADDR p_bda, UINT16 handle) 183 { 184 UINT16 i; 185 186 for (i=0; i<MAX_PAN_CONNS; i++) 187 { 188 if (pan_cb.pcb[i].con_state != PAN_STATE_IDLE && 189 pan_cb.pcb[i].handle == handle) 190 return NULL; 191 } 192 193 for (i=0; i<MAX_PAN_CONNS; i++) 194 { 195 if (pan_cb.pcb[i].con_state != PAN_STATE_IDLE && 196 memcmp (pan_cb.pcb[i].rem_bda, p_bda, BD_ADDR_LEN) == 0) 197 return NULL; 198 } 199 200 for (i=0; i<MAX_PAN_CONNS; i++) 201 { 202 if (pan_cb.pcb[i].con_state == PAN_STATE_IDLE) 203 { 204 memset (&(pan_cb.pcb[i]), 0, sizeof (tPAN_CONN)); 205 memcpy (pan_cb.pcb[i].rem_bda, p_bda, BD_ADDR_LEN); 206 pan_cb.pcb[i].handle = handle; 207 return &(pan_cb.pcb[i]); 208 } 209 } 210 return NULL; 211 } 212 213 214 /******************************************************************************* 215 ** 216 ** Function pan_get_pcb_by_handle 217 ** 218 ** Description 219 ** 220 ** Returns 221 ** 222 *******************************************************************************/ 223 tPAN_CONN *pan_get_pcb_by_handle (UINT16 handle) 224 { 225 UINT16 i; 226 227 for (i=0; i<MAX_PAN_CONNS; i++) 228 { 229 if (pan_cb.pcb[i].con_state != PAN_STATE_IDLE && 230 pan_cb.pcb[i].handle == handle) 231 return &(pan_cb.pcb[i]); 232 } 233 234 return NULL; 235 } 236 237 238 /******************************************************************************* 239 ** 240 ** Function pan_get_pcb_by_addr 241 ** 242 ** Description 243 ** 244 ** Returns 245 ** 246 *******************************************************************************/ 247 tPAN_CONN *pan_get_pcb_by_addr (BD_ADDR p_bda) 248 { 249 UINT16 i; 250 251 for (i=0; i<MAX_PAN_CONNS; i++) 252 { 253 if (pan_cb.pcb[i].con_state == PAN_STATE_IDLE) 254 continue; 255 256 if (memcmp (pan_cb.pcb[i].rem_bda, p_bda, BD_ADDR_LEN) == 0) 257 return &(pan_cb.pcb[i]); 258 259 /* 260 if (pan_cb.pcb[i].mfilter_present && 261 (memcmp (p_bda, pan_cb.pcb[i].multi_cast_bridge, BD_ADDR_LEN) == 0)) 262 return &(pan_cb.pcb[i]); 263 */ 264 } 265 266 return NULL; 267 } 268 269 270 271 272 /******************************************************************************* 273 ** 274 ** Function pan_close_all_connections 275 ** 276 ** Description 277 ** 278 ** Returns void 279 ** 280 *******************************************************************************/ 281 void pan_close_all_connections (void) 282 { 283 UINT16 i; 284 285 for (i=0; i<MAX_PAN_CONNS; i++) 286 { 287 if (pan_cb.pcb[i].con_state != PAN_STATE_IDLE) 288 { 289 BNEP_Disconnect (pan_cb.pcb[i].handle); 290 pan_cb.pcb[i].con_state = PAN_STATE_IDLE; 291 } 292 } 293 294 pan_cb.active_role = PAN_ROLE_INACTIVE; 295 pan_cb.num_conns = 0; 296 return; 297 } 298 299 300 /******************************************************************************* 301 ** 302 ** Function pan_release_pcb 303 ** 304 ** Description This function releases a PCB. 305 ** 306 ** Returns void 307 ** 308 *******************************************************************************/ 309 void pan_release_pcb (tPAN_CONN *p_pcb) 310 { 311 /* Drop any response pointer we may be holding */ 312 memset (p_pcb, 0, sizeof (tPAN_CONN)); 313 p_pcb->con_state = PAN_STATE_IDLE; 314 } 315 316 317 /******************************************************************************* 318 ** 319 ** Function pan_dump_status 320 ** 321 ** Description This function dumps the pan control block and connection 322 ** blocks information 323 ** 324 ** Returns none 325 ** 326 *******************************************************************************/ 327 void pan_dump_status (void) 328 { 329 #if (defined (PAN_SUPPORTS_DEBUG_DUMP) && PAN_SUPPORTS_DEBUG_DUMP == TRUE) 330 UINT16 i; 331 char buff[200]; 332 tPAN_CONN *p_pcb; 333 334 PAN_TRACE_DEBUG ("PAN role %x, active role %d, num_conns %d", 335 pan_cb.role, pan_cb.active_role, pan_cb.num_conns); 336 337 for (i = 0, p_pcb = pan_cb.pcb; i < MAX_PAN_CONNS; i++, p_pcb++) 338 { 339 sprintf (buff, "%d state %d, handle %d, src 0x%x, dst 0x%x, BD %x.%x.%x.%x.%x.%x", 340 i, p_pcb->con_state, p_pcb->handle, p_pcb->src_uuid, p_pcb->dst_uuid, 341 p_pcb->rem_bda[0], p_pcb->rem_bda[1], p_pcb->rem_bda[2], 342 p_pcb->rem_bda[3], p_pcb->rem_bda[4], p_pcb->rem_bda[5]); 343 344 PAN_TRACE_DEBUG (buff); 345 } 346 #endif 347 } 348 349 350 351