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 39static 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*******************************************************************************/ 61UINT32 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*******************************************************************************/ 182tPAN_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*******************************************************************************/ 223tPAN_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*******************************************************************************/ 247tPAN_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*******************************************************************************/ 281void 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*******************************************************************************/ 309void 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*******************************************************************************/ 327void 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