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