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 <base/logging.h> 27#include <stdio.h> 28#include <string.h> 29#include "bnep_api.h" 30#include "bt_common.h" 31#include "btm_api.h" 32#include "hcidefs.h" 33#include "l2c_api.h" 34#include "pan_api.h" 35#include "pan_int.h" 36#include "sdp_api.h" 37#include "sdpdefs.h" 38 39static const uint8_t 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, 47 0x00, /* BNEP specific parameter 0 -- Version of BNEP = version 1 = 0x0001 48 */ 49 0x35, 50 0x06, /* BNEP specific parameter 1 -- Supported network packet type list */ 51 0x09, 0x08, 0x00, /* network packet type IPv4 = 0x0800 */ 52 0x09, 0x08, 0x06 /* network packet type ARP = 0x0806 */ 53}; 54 55/******************************************************************************* 56 * 57 * Function pan_register_with_sdp 58 * 59 * Description 60 * 61 * Returns 62 * 63 ******************************************************************************/ 64uint32_t pan_register_with_sdp(uint16_t uuid, uint8_t sec_mask, 65 const char* p_name, const char* p_desc) { 66 uint32_t sdp_handle; 67 uint16_t browse_list = UUID_SERVCLASS_PUBLIC_BROWSE_GROUP; 68 uint16_t security = 0; 69 uint32_t proto_len = (uint32_t)pan_proto_elem_data[1]; 70 71 /* Create a record */ 72 sdp_handle = SDP_CreateRecord(); 73 74 if (sdp_handle == 0) { 75 PAN_TRACE_ERROR("PAN_SetRole - could not create SDP record"); 76 return 0; 77 } 78 79 /* Service Class ID List */ 80 SDP_AddServiceClassIdList(sdp_handle, 1, &uuid); 81 82 /* Add protocol element sequence from the constant string */ 83 SDP_AddAttribute(sdp_handle, ATTR_ID_PROTOCOL_DESC_LIST, 84 DATA_ELE_SEQ_DESC_TYPE, proto_len, 85 (uint8_t*)(pan_proto_elem_data + 2)); 86 87 /* Language base */ 88 SDP_AddLanguageBaseAttrIDList(sdp_handle, LANG_ID_CODE_ENGLISH, 89 LANG_ID_CHAR_ENCODE_UTF8, LANGUAGE_BASE_ID); 90 91 /* Profile descriptor list */ 92 SDP_AddProfileDescriptorList(sdp_handle, uuid, PAN_PROFILE_VERSION); 93 94 /* Service Name */ 95 SDP_AddAttribute(sdp_handle, ATTR_ID_SERVICE_NAME, TEXT_STR_DESC_TYPE, 96 (uint8_t)(strlen(p_name) + 1), (uint8_t*)p_name); 97 98 /* Service description */ 99 SDP_AddAttribute(sdp_handle, ATTR_ID_SERVICE_DESCRIPTION, TEXT_STR_DESC_TYPE, 100 (uint8_t)(strlen(p_desc) + 1), (uint8_t*)p_desc); 101 102 /* Security description */ 103 if (sec_mask) { 104 UINT16_TO_BE_FIELD(&security, 0x0001); 105 } 106 SDP_AddAttribute(sdp_handle, ATTR_ID_SECURITY_DESCRIPTION, UINT_DESC_TYPE, 2, 107 (uint8_t*)&security); 108 109#if (PAN_SUPPORTS_ROLE_NAP == TRUE) 110 if (uuid == UUID_SERVCLASS_NAP) { 111 uint16_t NetAccessType = 0x0005; /* Ethernet */ 112 uint32_t NetAccessRate = 0x0001312D0; /* 10Mb/sec */ 113 uint8_t array[10], *p; 114 115 /* Net access type. */ 116 p = array; 117 UINT16_TO_BE_STREAM(p, NetAccessType); 118 SDP_AddAttribute(sdp_handle, ATTR_ID_NET_ACCESS_TYPE, UINT_DESC_TYPE, 2, 119 array); 120 121 /* Net access rate. */ 122 p = array; 123 UINT32_TO_BE_STREAM(p, NetAccessRate); 124 SDP_AddAttribute(sdp_handle, ATTR_ID_MAX_NET_ACCESS_RATE, UINT_DESC_TYPE, 4, 125 array); 126 127 /* Register with Security Manager for the specific security level */ 128 if ((!BTM_SetSecurityLevel(true, p_name, BTM_SEC_SERVICE_BNEP_NAP, sec_mask, 129 BT_PSM_BNEP, BTM_SEC_PROTO_BNEP, 130 UUID_SERVCLASS_NAP)) || 131 (!BTM_SetSecurityLevel(false, p_name, BTM_SEC_SERVICE_BNEP_NAP, 132 sec_mask, BT_PSM_BNEP, BTM_SEC_PROTO_BNEP, 133 UUID_SERVCLASS_NAP))) { 134 PAN_TRACE_ERROR("PAN Security Registration failed for PANU"); 135 } 136 } 137#endif 138#if (PAN_SUPPORTS_ROLE_GN == TRUE) 139 if (uuid == UUID_SERVCLASS_GN) { 140 if ((!BTM_SetSecurityLevel(true, p_name, BTM_SEC_SERVICE_BNEP_GN, sec_mask, 141 BT_PSM_BNEP, BTM_SEC_PROTO_BNEP, 142 UUID_SERVCLASS_GN)) || 143 (!BTM_SetSecurityLevel(false, p_name, BTM_SEC_SERVICE_BNEP_GN, sec_mask, 144 BT_PSM_BNEP, BTM_SEC_PROTO_BNEP, 145 UUID_SERVCLASS_GN))) { 146 PAN_TRACE_ERROR("PAN Security Registration failed for GN"); 147 } 148 } 149#endif 150#if (PAN_SUPPORTS_ROLE_PANU == TRUE) 151 if (uuid == UUID_SERVCLASS_PANU) { 152 if ((!BTM_SetSecurityLevel(true, p_name, BTM_SEC_SERVICE_BNEP_PANU, 153 sec_mask, BT_PSM_BNEP, BTM_SEC_PROTO_BNEP, 154 UUID_SERVCLASS_PANU)) || 155 (!BTM_SetSecurityLevel(false, p_name, BTM_SEC_SERVICE_BNEP_PANU, 156 sec_mask, BT_PSM_BNEP, BTM_SEC_PROTO_BNEP, 157 UUID_SERVCLASS_PANU))) { 158 PAN_TRACE_ERROR("PAN Security Registration failed for PANU"); 159 } 160 } 161#endif 162 163 /* Make the service browsable */ 164 SDP_AddUuidSequence(sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1, &browse_list); 165 166 return sdp_handle; 167} 168 169/******************************************************************************* 170 * 171 * Function pan_allocate_pcb 172 * 173 * Description 174 * 175 * Returns 176 * 177 ******************************************************************************/ 178tPAN_CONN* pan_allocate_pcb(const RawAddress& p_bda, uint16_t handle) { 179 uint16_t i; 180 181 for (i = 0; i < MAX_PAN_CONNS; i++) { 182 if (pan_cb.pcb[i].con_state != PAN_STATE_IDLE && 183 pan_cb.pcb[i].handle == handle) 184 return NULL; 185 } 186 187 for (i = 0; i < MAX_PAN_CONNS; i++) { 188 if (pan_cb.pcb[i].con_state != PAN_STATE_IDLE && 189 pan_cb.pcb[i].rem_bda == p_bda) 190 return NULL; 191 } 192 193 for (i = 0; i < MAX_PAN_CONNS; i++) { 194 if (pan_cb.pcb[i].con_state == PAN_STATE_IDLE) { 195 memset(&(pan_cb.pcb[i]), 0, sizeof(tPAN_CONN)); 196 pan_cb.pcb[i].rem_bda = p_bda; 197 pan_cb.pcb[i].handle = handle; 198 return &(pan_cb.pcb[i]); 199 } 200 } 201 return NULL; 202} 203 204/******************************************************************************* 205 * 206 * Function pan_get_pcb_by_handle 207 * 208 * Description 209 * 210 * Returns 211 * 212 ******************************************************************************/ 213tPAN_CONN* pan_get_pcb_by_handle(uint16_t handle) { 214 uint16_t i; 215 216 for (i = 0; i < MAX_PAN_CONNS; i++) { 217 if (pan_cb.pcb[i].con_state != PAN_STATE_IDLE && 218 pan_cb.pcb[i].handle == handle) 219 return &(pan_cb.pcb[i]); 220 } 221 222 return NULL; 223} 224 225/******************************************************************************* 226 * 227 * Function pan_get_pcb_by_addr 228 * 229 * Description 230 * 231 * Returns 232 * 233 ******************************************************************************/ 234tPAN_CONN* pan_get_pcb_by_addr(const RawAddress& p_bda) { 235 uint16_t i; 236 237 for (i = 0; i < MAX_PAN_CONNS; i++) { 238 if (pan_cb.pcb[i].con_state == PAN_STATE_IDLE) continue; 239 240 if (pan_cb.pcb[i].rem_bda == p_bda) return &(pan_cb.pcb[i]); 241 242 /* 243 if (pan_cb.pcb[i].mfilter_present && 244 p_bda == pan_cb.pcb[i].multi_cast_bridge) 245 return &(pan_cb.pcb[i]); 246 */ 247 } 248 249 return NULL; 250} 251 252/******************************************************************************* 253 * 254 * Function pan_close_all_connections 255 * 256 * Description 257 * 258 * Returns void 259 * 260 ******************************************************************************/ 261void pan_close_all_connections(void) { 262 uint16_t i; 263 264 for (i = 0; i < MAX_PAN_CONNS; i++) { 265 if (pan_cb.pcb[i].con_state != PAN_STATE_IDLE) { 266 BNEP_Disconnect(pan_cb.pcb[i].handle); 267 pan_cb.pcb[i].con_state = PAN_STATE_IDLE; 268 } 269 } 270 271 pan_cb.active_role = PAN_ROLE_INACTIVE; 272 pan_cb.num_conns = 0; 273 return; 274} 275 276/******************************************************************************* 277 * 278 * Function pan_release_pcb 279 * 280 * Description This function releases a PCB. 281 * 282 * Returns void 283 * 284 ******************************************************************************/ 285void pan_release_pcb(tPAN_CONN* p_pcb) { 286 /* Drop any response pointer we may be holding */ 287 memset(p_pcb, 0, sizeof(tPAN_CONN)); 288 p_pcb->con_state = PAN_STATE_IDLE; 289} 290 291/******************************************************************************* 292 * 293 * Function pan_dump_status 294 * 295 * Description This function dumps the pan control block and connection 296 * blocks information 297 * 298 * Returns none 299 * 300 ******************************************************************************/ 301void pan_dump_status(void) { 302#if (PAN_SUPPORTS_DEBUG_DUMP == TRUE) 303 uint16_t i; 304 tPAN_CONN* p_pcb; 305 306 PAN_TRACE_DEBUG("PAN role %x, active role %d, num_conns %d", pan_cb.role, 307 pan_cb.active_role, pan_cb.num_conns); 308 309 for (i = 0, p_pcb = pan_cb.pcb; i < MAX_PAN_CONNS; i++, p_pcb++) { 310 VLOG(1) << +i << " state:" << p_pcb->con_state 311 << ", handle:" << p_pcb->handle << ", src" << p_pcb->src_uuid 312 << ", BD:" << p_pcb->rem_bda; 313 } 314#endif 315} 316