1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include "sync.h" 18 #include <utils/Log.h> 19 #include "wifi_hal.h" 20 #include "nan_i.h" 21 #include "nancommand.h" 22 23 wifi_error NanCommand::putNanEnable(transaction_id id, const NanEnableRequest *pReq) 24 { 25 wifi_error ret; 26 ALOGV("NAN_ENABLE"); 27 size_t message_len = NAN_MAX_ENABLE_REQ_SIZE; 28 29 if (pReq == NULL) { 30 cleanup(); 31 return WIFI_ERROR_INVALID_ARGS; 32 } 33 34 message_len += \ 35 ( 36 pReq->config_support_5g ? (SIZEOF_TLV_HDR + \ 37 sizeof(pReq->support_5g_val)) : 0 \ 38 ) + \ 39 ( 40 pReq->config_sid_beacon ? (SIZEOF_TLV_HDR + \ 41 sizeof(pReq->sid_beacon_val)) : 0 \ 42 ) + \ 43 ( 44 pReq->config_2dot4g_rssi_close ? (SIZEOF_TLV_HDR + \ 45 sizeof(pReq->rssi_close_2dot4g_val)) : 0 \ 46 ) + \ 47 ( 48 pReq->config_2dot4g_rssi_middle ? (SIZEOF_TLV_HDR + \ 49 sizeof(pReq->rssi_middle_2dot4g_val)) : 0 \ 50 ) + \ 51 ( 52 pReq->config_hop_count_limit ? (SIZEOF_TLV_HDR + \ 53 sizeof(pReq->hop_count_limit_val)) : 0 \ 54 ) + \ 55 ( 56 pReq->config_2dot4g_support ? (SIZEOF_TLV_HDR + \ 57 sizeof(pReq->support_2dot4g_val)) : 0 \ 58 ) + \ 59 ( 60 pReq->config_2dot4g_beacons ? (SIZEOF_TLV_HDR + \ 61 sizeof(pReq->beacon_2dot4g_val)) : 0 \ 62 ) + \ 63 ( 64 pReq->config_2dot4g_sdf ? (SIZEOF_TLV_HDR + \ 65 sizeof(pReq->sdf_2dot4g_val)) : 0 \ 66 ) + \ 67 ( 68 pReq->config_5g_beacons ? (SIZEOF_TLV_HDR + \ 69 sizeof(pReq->beacon_5g_val)) : 0 \ 70 ) + \ 71 ( 72 pReq->config_5g_sdf ? (SIZEOF_TLV_HDR + \ 73 sizeof(pReq->sdf_5g_val)) : 0 \ 74 ) + \ 75 ( 76 pReq->config_5g_rssi_close ? (SIZEOF_TLV_HDR + \ 77 sizeof(pReq->rssi_close_5g_val)) : 0 \ 78 ) + \ 79 ( 80 pReq->config_5g_rssi_middle ? (SIZEOF_TLV_HDR + \ 81 sizeof(pReq->rssi_middle_5g_val)) : 0 \ 82 ) + \ 83 ( 84 pReq->config_2dot4g_rssi_proximity ? (SIZEOF_TLV_HDR + \ 85 sizeof(pReq->rssi_proximity_2dot4g_val)) : 0 \ 86 ) + \ 87 ( 88 pReq->config_5g_rssi_close_proximity ? (SIZEOF_TLV_HDR + \ 89 sizeof(pReq->rssi_close_proximity_5g_val)) : 0 \ 90 ) + \ 91 ( 92 pReq->config_rssi_window_size ? (SIZEOF_TLV_HDR + \ 93 sizeof(pReq->rssi_window_size_val)) : 0 \ 94 ) + \ 95 ( 96 pReq->config_oui ? (SIZEOF_TLV_HDR + \ 97 sizeof(pReq->oui_val)) : 0 \ 98 ) + \ 99 ( 100 pReq->config_intf_addr ? (SIZEOF_TLV_HDR + \ 101 sizeof(pReq->intf_addr_val)) : 0 \ 102 ) + \ 103 ( 104 pReq->config_cluster_attribute_val ? (SIZEOF_TLV_HDR + \ 105 sizeof(pReq->config_cluster_attribute_val)) : 0 \ 106 ) + \ 107 ( 108 pReq->config_scan_params ? NAN_MAX_SOCIAL_CHANNELS * 109 (SIZEOF_TLV_HDR + sizeof(u32)) : 0 \ 110 ) + \ 111 ( 112 pReq->config_random_factor_force ? (SIZEOF_TLV_HDR + \ 113 sizeof(pReq->random_factor_force_val)) : 0 \ 114 ) + \ 115 ( 116 pReq->config_hop_count_force ? (SIZEOF_TLV_HDR + \ 117 sizeof(pReq->hop_count_force_val)) : 0 \ 118 ) + \ 119 ( 120 pReq->config_24g_channel ? (SIZEOF_TLV_HDR + \ 121 sizeof(u32)) : 0 \ 122 ) + \ 123 ( 124 pReq->config_5g_channel ? (SIZEOF_TLV_HDR + \ 125 sizeof(u32)) : 0 \ 126 ) + \ 127 ( 128 pReq->config_dw.config_2dot4g_dw_band ? (SIZEOF_TLV_HDR + \ 129 sizeof(u32)) : 0 \ 130 ) + \ 131 ( 132 pReq->config_dw.config_5g_dw_band ? (SIZEOF_TLV_HDR + \ 133 sizeof(u32)) : 0 \ 134 ) + \ 135 ( 136 pReq->config_disc_mac_addr_randomization ? (SIZEOF_TLV_HDR + \ 137 sizeof(u32)) : 0 \ 138 ) + \ 139 ( 140 /* Always include cfg discovery indication TLV */ 141 SIZEOF_TLV_HDR + sizeof(u32) \ 142 ) + \ 143 ( 144 pReq->config_subscribe_sid_beacon ? (SIZEOF_TLV_HDR + \ 145 sizeof(pReq->subscribe_sid_beacon_val)) : 0 \ 146 ) + \ 147 ( 148 pReq->config_discovery_beacon_int ? (SIZEOF_TLV_HDR + \ 149 sizeof(u32)) : 0 \ 150 ) + \ 151 ( 152 pReq->config_nss ? (SIZEOF_TLV_HDR + \ 153 sizeof(u32)) : 0 \ 154 ) + \ 155 ( 156 pReq->config_enable_ranging ? (SIZEOF_TLV_HDR + \ 157 sizeof(u32)) : 0 \ 158 ) + \ 159 ( 160 pReq->config_dw_early_termination ? (SIZEOF_TLV_HDR + \ 161 sizeof(u32)) : 0 \ 162 ); 163 164 pNanEnableReqMsg pFwReq = (pNanEnableReqMsg)malloc(message_len); 165 if (pFwReq == NULL) { 166 cleanup(); 167 return WIFI_ERROR_OUT_OF_MEMORY; 168 } 169 170 ALOGV("Message Len %zu", message_len); 171 memset (pFwReq, 0, message_len); 172 pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1; 173 pFwReq->fwHeader.msgId = NAN_MSG_ID_ENABLE_REQ; 174 pFwReq->fwHeader.msgLen = message_len; 175 pFwReq->fwHeader.transactionId = id; 176 177 u8* tlvs = pFwReq->ptlv; 178 179 /* Write the TLVs to the message. */ 180 181 tlvs = addTlv(NAN_TLV_TYPE_CLUSTER_ID_LOW, sizeof(pReq->cluster_low), 182 (const u8*)&pReq->cluster_low, tlvs); 183 tlvs = addTlv(NAN_TLV_TYPE_CLUSTER_ID_HIGH, sizeof(pReq->cluster_high), 184 (const u8*)&pReq->cluster_high, tlvs); 185 tlvs = addTlv(NAN_TLV_TYPE_MASTER_PREFERENCE, sizeof(pReq->master_pref), 186 (const u8*)&pReq->master_pref, tlvs); 187 if (pReq->config_support_5g) { 188 tlvs = addTlv(NAN_TLV_TYPE_5G_SUPPORT, sizeof(pReq->support_5g_val), 189 (const u8*)&pReq->support_5g_val, tlvs); 190 } 191 if (pReq->config_sid_beacon) { 192 tlvs = addTlv(NAN_TLV_TYPE_SID_BEACON, sizeof(pReq->sid_beacon_val), 193 (const u8*)&pReq->sid_beacon_val, tlvs); 194 } 195 if (pReq->config_2dot4g_rssi_close) { 196 tlvs = addTlv(NAN_TLV_TYPE_24G_RSSI_CLOSE, 197 sizeof(pReq->rssi_close_2dot4g_val), 198 (const u8*)&pReq->rssi_close_2dot4g_val, tlvs); 199 } 200 if (pReq->config_2dot4g_rssi_middle) { 201 tlvs = addTlv(NAN_TLV_TYPE_24G_RSSI_MIDDLE, 202 sizeof(pReq->rssi_middle_2dot4g_val), 203 (const u8*)&pReq->rssi_middle_2dot4g_val, tlvs); 204 } 205 if (pReq->config_hop_count_limit) { 206 tlvs = addTlv(NAN_TLV_TYPE_HOP_COUNT_LIMIT, 207 sizeof(pReq->hop_count_limit_val), 208 (const u8*)&pReq->hop_count_limit_val, tlvs); 209 } 210 if (pReq->config_2dot4g_support) { 211 tlvs = addTlv(NAN_TLV_TYPE_24G_SUPPORT, sizeof(pReq->support_2dot4g_val), 212 (const u8*)&pReq->support_2dot4g_val, tlvs); 213 } 214 if (pReq->config_2dot4g_beacons) { 215 tlvs = addTlv(NAN_TLV_TYPE_24G_BEACON, sizeof(pReq->beacon_2dot4g_val), 216 (const u8*)&pReq->beacon_2dot4g_val, tlvs); 217 } 218 if (pReq->config_2dot4g_sdf) { 219 tlvs = addTlv(NAN_TLV_TYPE_24G_SDF, sizeof(pReq->sdf_2dot4g_val), 220 (const u8*)&pReq->sdf_2dot4g_val, tlvs); 221 } 222 if (pReq->config_5g_beacons) { 223 tlvs = addTlv(NAN_TLV_TYPE_5G_BEACON, sizeof(pReq->beacon_5g_val), 224 (const u8*)&pReq->beacon_5g_val, tlvs); 225 } 226 if (pReq->config_5g_sdf) { 227 tlvs = addTlv(NAN_TLV_TYPE_5G_SDF, sizeof(pReq->sdf_5g_val), 228 (const u8*)&pReq->sdf_5g_val, tlvs); 229 } 230 if (pReq->config_2dot4g_rssi_proximity) { 231 tlvs = addTlv(NAN_TLV_TYPE_24G_RSSI_CLOSE_PROXIMITY, 232 sizeof(pReq->rssi_proximity_2dot4g_val), 233 (const u8*)&pReq->rssi_proximity_2dot4g_val, tlvs); 234 } 235 /* Add the support of sending 5G RSSI values */ 236 if (pReq->config_5g_rssi_close) { 237 tlvs = addTlv(NAN_TLV_TYPE_5G_RSSI_CLOSE, sizeof(pReq->rssi_close_5g_val), 238 (const u8*)&pReq->rssi_close_5g_val, tlvs); 239 } 240 if (pReq->config_5g_rssi_middle) { 241 tlvs = addTlv(NAN_TLV_TYPE_5G_RSSI_MIDDLE, sizeof(pReq->rssi_middle_5g_val), 242 (const u8*)&pReq->rssi_middle_5g_val, tlvs); 243 } 244 if (pReq->config_5g_rssi_close_proximity) { 245 tlvs = addTlv(NAN_TLV_TYPE_5G_RSSI_CLOSE_PROXIMITY, 246 sizeof(pReq->rssi_close_proximity_5g_val), 247 (const u8*)&pReq->rssi_close_proximity_5g_val, tlvs); 248 } 249 if (pReq->config_rssi_window_size) { 250 tlvs = addTlv(NAN_TLV_TYPE_RSSI_AVERAGING_WINDOW_SIZE, sizeof(pReq->rssi_window_size_val), 251 (const u8*)&pReq->rssi_window_size_val, tlvs); 252 } 253 if (pReq->config_oui) { 254 tlvs = addTlv(NAN_TLV_TYPE_CLUSTER_OUI_NETWORK_ID, sizeof(pReq->oui_val), 255 (const u8*)&pReq->oui_val, tlvs); 256 } 257 if (pReq->config_intf_addr) { 258 tlvs = addTlv(NAN_TLV_TYPE_SOURCE_MAC_ADDRESS, sizeof(pReq->intf_addr_val), 259 (const u8*)&pReq->intf_addr_val[0], tlvs); 260 } 261 if (pReq->config_cluster_attribute_val) { 262 tlvs = addTlv(NAN_TLV_TYPE_CLUSTER_ATTRIBUTE_IN_SDF, sizeof(pReq->config_cluster_attribute_val), 263 (const u8*)&pReq->config_cluster_attribute_val, tlvs); 264 } 265 if (pReq->config_scan_params) { 266 u32 socialChannelParamVal[NAN_MAX_SOCIAL_CHANNELS]; 267 /* Fill the social channel param */ 268 fillNanSocialChannelParamVal(&pReq->scan_params_val, 269 socialChannelParamVal); 270 int i; 271 for (i = 0; i < NAN_MAX_SOCIAL_CHANNELS; i++) { 272 tlvs = addTlv(NAN_TLV_TYPE_SOCIAL_CHANNEL_SCAN_PARAMS, 273 sizeof(socialChannelParamVal[i]), 274 (const u8*)&socialChannelParamVal[i], tlvs); 275 } 276 } 277 if (pReq->config_random_factor_force) { 278 tlvs = addTlv(NAN_TLV_TYPE_RANDOM_FACTOR_FORCE, 279 sizeof(pReq->random_factor_force_val), 280 (const u8*)&pReq->random_factor_force_val, tlvs); 281 } 282 if (pReq->config_hop_count_force) { 283 tlvs = addTlv(NAN_TLV_TYPE_HOP_COUNT_FORCE, 284 sizeof(pReq->hop_count_force_val), 285 (const u8*)&pReq->hop_count_force_val, tlvs); 286 } 287 if (pReq->config_24g_channel) { 288 tlvs = addTlv(NAN_TLV_TYPE_24G_CHANNEL, 289 sizeof(u32), 290 (const u8*)&pReq->channel_24g_val, tlvs); 291 } 292 if (pReq->config_5g_channel) { 293 tlvs = addTlv(NAN_TLV_TYPE_5G_CHANNEL, 294 sizeof(u32), 295 (const u8*)&pReq->channel_5g_val, tlvs); 296 } 297 if (pReq->config_dw.config_2dot4g_dw_band) { 298 tlvs = addTlv(NAN_TLV_TYPE_2G_COMMITTED_DW, 299 sizeof(pReq->config_dw.dw_2dot4g_interval_val), 300 (const u8*)&pReq->config_dw.dw_2dot4g_interval_val, tlvs); 301 } 302 if (pReq->config_dw.config_5g_dw_band) { 303 tlvs = addTlv(NAN_TLV_TYPE_5G_COMMITTED_DW, 304 sizeof(pReq->config_dw.dw_5g_interval_val), 305 (const u8*)&pReq->config_dw.dw_5g_interval_val, tlvs); 306 } 307 if (pReq->config_disc_mac_addr_randomization) { 308 tlvs = addTlv(NAN_TLV_TYPE_DISC_MAC_ADDR_RANDOM_INTERVAL, 309 sizeof(u32), 310 (const u8*)&pReq->disc_mac_addr_rand_interval_sec, tlvs); 311 } 312 313 u32 config_discovery_indications; 314 config_discovery_indications = (u32)pReq->discovery_indication_cfg; 315 tlvs = addTlv(NAN_TLV_TYPE_CONFIG_DISCOVERY_INDICATIONS, 316 sizeof(u32), 317 (const u8*)&config_discovery_indications, tlvs); 318 319 if (pReq->config_subscribe_sid_beacon) { 320 tlvs = addTlv(NAN_TLV_TYPE_SUBSCRIBE_SID_BEACON, 321 sizeof(pReq->subscribe_sid_beacon_val), 322 (const u8*)&pReq->subscribe_sid_beacon_val, tlvs); 323 } 324 if (pReq->config_discovery_beacon_int) { 325 tlvs = addTlv(NAN_TLV_TYPE_DB_INTERVAL, sizeof(u32), 326 (const u8*)&pReq->discovery_beacon_interval, tlvs); 327 } 328 if (pReq->config_nss) { 329 tlvs = addTlv(NAN_TLV_TYPE_TX_RX_CHAINS, sizeof(u32), 330 (const u8*)&pReq->nss, tlvs); 331 } 332 if (pReq->config_enable_ranging) { 333 tlvs = addTlv(NAN_TLV_TYPE_ENABLE_DEVICE_RANGING, sizeof(u32), 334 (const u8*)&pReq->enable_ranging, tlvs); 335 } 336 if (pReq->config_dw_early_termination) { 337 tlvs = addTlv(NAN_TLV_TYPE_DW_EARLY_TERMINATION, sizeof(u32), 338 (const u8*)&pReq->enable_dw_termination, tlvs); 339 } 340 341 mVendorData = (char*)pFwReq; 342 mDataLen = message_len; 343 344 //Insert the vendor specific data 345 ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen); 346 if (ret != WIFI_SUCCESS) { 347 ALOGE("%s: put_bytes Error:%d",__func__, ret); 348 cleanup(); 349 return ret; 350 } 351 hexdump(mVendorData, mDataLen); 352 return ret; 353 } 354 355 wifi_error NanCommand::putNanDisable(transaction_id id) 356 { 357 wifi_error ret; 358 ALOGV("NAN_DISABLE"); 359 size_t message_len = sizeof(NanDisableReqMsg); 360 361 pNanDisableReqMsg pFwReq = (pNanDisableReqMsg)malloc(message_len); 362 if (pFwReq == NULL) { 363 cleanup(); 364 return WIFI_ERROR_OUT_OF_MEMORY; 365 } 366 367 ALOGV("Message Len %zu", message_len); 368 memset (pFwReq, 0, message_len); 369 pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1; 370 pFwReq->fwHeader.msgId = NAN_MSG_ID_DISABLE_REQ; 371 pFwReq->fwHeader.msgLen = message_len; 372 pFwReq->fwHeader.transactionId = id; 373 374 mVendorData = (char*)pFwReq; 375 mDataLen = message_len; 376 377 ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen); 378 if (ret != WIFI_SUCCESS) { 379 ALOGE("%s: put_bytes Error:%d",__func__, ret); 380 cleanup(); 381 return ret; 382 } 383 hexdump(mVendorData, mDataLen); 384 return ret; 385 } 386 387 wifi_error NanCommand::putNanConfig(transaction_id id, const NanConfigRequest *pReq) 388 { 389 wifi_error ret; 390 ALOGV("NAN_CONFIG"); 391 size_t message_len = 0; 392 int idx = 0; 393 394 if (pReq == NULL || 395 pReq->num_config_discovery_attr > NAN_MAX_POSTDISCOVERY_LEN) { 396 cleanup(); 397 return WIFI_ERROR_INVALID_ARGS; 398 } 399 400 message_len = sizeof(NanMsgHeader); 401 402 message_len += \ 403 ( 404 pReq->config_sid_beacon ? (SIZEOF_TLV_HDR + \ 405 sizeof(pReq->sid_beacon)) : 0 \ 406 ) + \ 407 ( 408 pReq->config_master_pref ? (SIZEOF_TLV_HDR + \ 409 sizeof(pReq->master_pref)) : 0 \ 410 ) + \ 411 ( 412 pReq->config_rssi_proximity ? (SIZEOF_TLV_HDR + \ 413 sizeof(pReq->rssi_proximity)) : 0 \ 414 ) + \ 415 ( 416 pReq->config_5g_rssi_close_proximity ? (SIZEOF_TLV_HDR + \ 417 sizeof(pReq->rssi_close_proximity_5g_val)) : 0 \ 418 ) + \ 419 ( 420 pReq->config_rssi_window_size ? (SIZEOF_TLV_HDR + \ 421 sizeof(pReq->rssi_window_size_val)) : 0 \ 422 ) + \ 423 ( 424 pReq->config_cluster_attribute_val ? (SIZEOF_TLV_HDR + \ 425 sizeof(pReq->config_cluster_attribute_val)) : 0 \ 426 ) + \ 427 ( 428 pReq->config_scan_params ? NAN_MAX_SOCIAL_CHANNELS * 429 (SIZEOF_TLV_HDR + sizeof(u32)) : 0 \ 430 ) + \ 431 ( 432 pReq->config_random_factor_force ? (SIZEOF_TLV_HDR + \ 433 sizeof(pReq->random_factor_force_val)) : 0 \ 434 ) + \ 435 ( 436 pReq->config_hop_count_force ? (SIZEOF_TLV_HDR + \ 437 sizeof(pReq->hop_count_force_val)) : 0 \ 438 ) + \ 439 ( 440 pReq->config_conn_capability ? (SIZEOF_TLV_HDR + \ 441 sizeof(u32)) : 0 \ 442 ) + \ 443 ( 444 pReq->config_dw.config_2dot4g_dw_band ? (SIZEOF_TLV_HDR + \ 445 sizeof(u32)) : 0 \ 446 ) + \ 447 ( 448 pReq->config_dw.config_5g_dw_band ? (SIZEOF_TLV_HDR + \ 449 sizeof(u32)) : 0 \ 450 ) + \ 451 ( 452 pReq->config_disc_mac_addr_randomization ? (SIZEOF_TLV_HDR + \ 453 sizeof(u32)) : 0 \ 454 ) + \ 455 ( 456 pReq->config_subscribe_sid_beacon ? (SIZEOF_TLV_HDR + \ 457 sizeof(pReq->subscribe_sid_beacon_val)) : 0 \ 458 ) + \ 459 ( 460 /* Always include cfg discovery indication TLV */ 461 SIZEOF_TLV_HDR + sizeof(u32) \ 462 ) + \ 463 ( 464 pReq->config_discovery_beacon_int ? (SIZEOF_TLV_HDR + \ 465 sizeof(u32)) : 0 \ 466 ) + \ 467 ( 468 pReq->config_nss ? (SIZEOF_TLV_HDR + \ 469 sizeof(u32)) : 0 \ 470 ) + \ 471 ( 472 pReq->config_enable_ranging ? (SIZEOF_TLV_HDR + \ 473 sizeof(u32)) : 0 \ 474 ) + \ 475 ( 476 pReq->config_dw_early_termination ? (SIZEOF_TLV_HDR + \ 477 sizeof(u32)) : 0 \ 478 ); 479 480 if (pReq->num_config_discovery_attr) { 481 for (idx = 0; idx < pReq->num_config_discovery_attr; idx ++) { 482 message_len += SIZEOF_TLV_HDR +\ 483 calcNanTransmitPostDiscoverySize(&pReq->discovery_attr_val[idx]); 484 } 485 } 486 487 if (pReq->config_fam && \ 488 calcNanFurtherAvailabilityMapSize(&pReq->fam_val)) { 489 message_len += (SIZEOF_TLV_HDR + \ 490 calcNanFurtherAvailabilityMapSize(&pReq->fam_val)); 491 } 492 493 pNanConfigurationReqMsg pFwReq = (pNanConfigurationReqMsg)malloc(message_len); 494 if (pFwReq == NULL) { 495 cleanup(); 496 return WIFI_ERROR_OUT_OF_MEMORY; 497 } 498 499 ALOGV("Message Len %zu", message_len); 500 memset (pFwReq, 0, message_len); 501 pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1; 502 pFwReq->fwHeader.msgId = NAN_MSG_ID_CONFIGURATION_REQ; 503 pFwReq->fwHeader.msgLen = message_len; 504 pFwReq->fwHeader.transactionId = id; 505 506 u8* tlvs = pFwReq->ptlv; 507 if (pReq->config_sid_beacon) { 508 tlvs = addTlv(NAN_TLV_TYPE_SID_BEACON, sizeof(pReq->sid_beacon), 509 (const u8*)&pReq->sid_beacon, tlvs); 510 } 511 if (pReq->config_master_pref) { 512 tlvs = addTlv(NAN_TLV_TYPE_MASTER_PREFERENCE, sizeof(pReq->master_pref), 513 (const u8*)&pReq->master_pref, tlvs); 514 } 515 if (pReq->config_rssi_window_size) { 516 tlvs = addTlv(NAN_TLV_TYPE_RSSI_AVERAGING_WINDOW_SIZE, sizeof(pReq->rssi_window_size_val), 517 (const u8*)&pReq->rssi_window_size_val, tlvs); 518 } 519 if (pReq->config_rssi_proximity) { 520 tlvs = addTlv(NAN_TLV_TYPE_24G_RSSI_CLOSE_PROXIMITY, sizeof(pReq->rssi_proximity), 521 (const u8*)&pReq->rssi_proximity, tlvs); 522 } 523 if (pReq->config_5g_rssi_close_proximity) { 524 tlvs = addTlv(NAN_TLV_TYPE_5G_RSSI_CLOSE_PROXIMITY, 525 sizeof(pReq->rssi_close_proximity_5g_val), 526 (const u8*)&pReq->rssi_close_proximity_5g_val, tlvs); 527 } 528 if (pReq->config_cluster_attribute_val) { 529 tlvs = addTlv(NAN_TLV_TYPE_CLUSTER_ATTRIBUTE_IN_SDF, sizeof(pReq->config_cluster_attribute_val), 530 (const u8*)&pReq->config_cluster_attribute_val, tlvs); 531 } 532 if (pReq->config_scan_params) { 533 u32 socialChannelParamVal[NAN_MAX_SOCIAL_CHANNELS]; 534 /* Fill the social channel param */ 535 fillNanSocialChannelParamVal(&pReq->scan_params_val, 536 socialChannelParamVal); 537 int i; 538 for (i = 0; i < NAN_MAX_SOCIAL_CHANNELS; i++) { 539 tlvs = addTlv(NAN_TLV_TYPE_SOCIAL_CHANNEL_SCAN_PARAMS, 540 sizeof(socialChannelParamVal[i]), 541 (const u8*)&socialChannelParamVal[i], tlvs); 542 } 543 } 544 if (pReq->config_random_factor_force) { 545 tlvs = addTlv(NAN_TLV_TYPE_RANDOM_FACTOR_FORCE, 546 sizeof(pReq->random_factor_force_val), 547 (const u8*)&pReq->random_factor_force_val, tlvs); 548 } 549 if (pReq->config_hop_count_force) { 550 tlvs = addTlv(NAN_TLV_TYPE_HOP_COUNT_FORCE, 551 sizeof(pReq->hop_count_force_val), 552 (const u8*)&pReq->hop_count_force_val, tlvs); 553 } 554 if (pReq->config_conn_capability) { 555 u32 val = \ 556 getNanTransmitPostConnectivityCapabilityVal(&pReq->conn_capability_val); 557 tlvs = addTlv(NAN_TLV_TYPE_POST_NAN_CONNECTIVITY_CAPABILITIES_TRANSMIT, 558 sizeof(val), (const u8*)&val, tlvs); 559 } 560 if (pReq->num_config_discovery_attr) { 561 for (idx = 0; idx < pReq->num_config_discovery_attr; idx ++) { 562 fillNanTransmitPostDiscoveryVal(&pReq->discovery_attr_val[idx], 563 (u8*)(tlvs + SIZEOF_TLV_HDR)); 564 tlvs = addTlv(NAN_TLV_TYPE_POST_NAN_DISCOVERY_ATTRIBUTE_TRANSMIT, 565 calcNanTransmitPostDiscoverySize( 566 &pReq->discovery_attr_val[idx]), 567 (const u8*)(tlvs + SIZEOF_TLV_HDR), tlvs); 568 } 569 } 570 if (pReq->config_fam && \ 571 calcNanFurtherAvailabilityMapSize(&pReq->fam_val)) { 572 fillNanFurtherAvailabilityMapVal(&pReq->fam_val, 573 (u8*)(tlvs + SIZEOF_TLV_HDR)); 574 tlvs = addTlv(NAN_TLV_TYPE_FURTHER_AVAILABILITY_MAP, 575 calcNanFurtherAvailabilityMapSize(&pReq->fam_val), 576 (const u8*)(tlvs + SIZEOF_TLV_HDR), tlvs); 577 } 578 if (pReq->config_dw.config_2dot4g_dw_band) { 579 tlvs = addTlv(NAN_TLV_TYPE_2G_COMMITTED_DW, 580 sizeof(pReq->config_dw.dw_2dot4g_interval_val), 581 (const u8*)&pReq->config_dw.dw_2dot4g_interval_val, tlvs); 582 } 583 if (pReq->config_dw.config_5g_dw_band) { 584 tlvs = addTlv(NAN_TLV_TYPE_5G_COMMITTED_DW, 585 sizeof(pReq->config_dw.dw_5g_interval_val), 586 (const u8*)&pReq->config_dw.dw_5g_interval_val, tlvs); 587 } 588 if (pReq->config_disc_mac_addr_randomization) { 589 tlvs = addTlv(NAN_TLV_TYPE_DISC_MAC_ADDR_RANDOM_INTERVAL, 590 sizeof(u32), 591 (const u8*)&pReq->disc_mac_addr_rand_interval_sec, tlvs); 592 } 593 if (pReq->config_subscribe_sid_beacon) { 594 tlvs = addTlv(NAN_TLV_TYPE_SUBSCRIBE_SID_BEACON, 595 sizeof(pReq->subscribe_sid_beacon_val), 596 (const u8*)&pReq->subscribe_sid_beacon_val, tlvs); 597 } 598 if (pReq->config_discovery_beacon_int) { 599 tlvs = addTlv(NAN_TLV_TYPE_DB_INTERVAL, sizeof(u32), 600 (const u8*)&pReq->discovery_beacon_interval, tlvs); 601 } 602 603 u32 config_discovery_indications; 604 config_discovery_indications = (u32)(pReq->discovery_indication_cfg); 605 /* Always include the discovery cfg TLV as there is no cfg flag */ 606 tlvs = addTlv(NAN_TLV_TYPE_CONFIG_DISCOVERY_INDICATIONS, 607 sizeof(u32), 608 (const u8*)&config_discovery_indications, tlvs); 609 610 if (pReq->config_nss) { 611 tlvs = addTlv(NAN_TLV_TYPE_TX_RX_CHAINS, sizeof(u32), 612 (const u8*)&pReq->nss, tlvs); 613 } 614 if (pReq->config_enable_ranging) { 615 tlvs = addTlv(NAN_TLV_TYPE_ENABLE_DEVICE_RANGING, sizeof(u32), 616 (const u8*)&pReq->enable_ranging, tlvs); 617 } 618 if (pReq->config_dw_early_termination) { 619 tlvs = addTlv(NAN_TLV_TYPE_DW_EARLY_TERMINATION, sizeof(u32), 620 (const u8*)&pReq->enable_dw_termination, tlvs); 621 } 622 623 mVendorData = (char*)pFwReq; 624 mDataLen = message_len; 625 626 ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen); 627 if (ret != WIFI_SUCCESS) { 628 ALOGE("%s: put_bytes Error:%d",__func__, ret); 629 cleanup(); 630 return ret; 631 } 632 hexdump(mVendorData, mDataLen); 633 return ret; 634 } 635 636 wifi_error NanCommand::putNanPublish(transaction_id id, const NanPublishRequest *pReq) 637 { 638 wifi_error ret; 639 ALOGV("NAN_PUBLISH"); 640 if (pReq == NULL) { 641 cleanup(); 642 return WIFI_ERROR_INVALID_ARGS; 643 } 644 645 size_t message_len = 646 sizeof(NanMsgHeader) + sizeof(NanPublishServiceReqParams) + 647 (pReq->service_name_len ? SIZEOF_TLV_HDR + pReq->service_name_len : 0) + 648 (pReq->service_specific_info_len ? SIZEOF_TLV_HDR + pReq->service_specific_info_len : 0) + 649 (pReq->rx_match_filter_len ? SIZEOF_TLV_HDR + pReq->rx_match_filter_len : 0) + 650 (pReq->tx_match_filter_len ? SIZEOF_TLV_HDR + pReq->tx_match_filter_len : 0) + 651 (SIZEOF_TLV_HDR + sizeof(NanServiceAcceptPolicy)) + 652 (pReq->cipher_type ? SIZEOF_TLV_HDR + sizeof(NanCsidType) : 0) + 653 ((pReq->sdea_params.config_nan_data_path || pReq->sdea_params.security_cfg || 654 pReq->sdea_params.ranging_state || pReq->sdea_params.range_report || 655 pReq->sdea_params.qos_cfg) ? 656 SIZEOF_TLV_HDR + sizeof(NanFWSdeaCtrlParams) : 0) + 657 ((pReq->ranging_cfg.ranging_interval_msec || pReq->ranging_cfg.config_ranging_indications || 658 pReq->ranging_cfg.distance_ingress_mm || pReq->ranging_cfg.distance_egress_mm) ? 659 SIZEOF_TLV_HDR + sizeof(NanFWRangeConfigParams) : 0) + 660 ((pReq->range_response_cfg.publish_id || 661 pReq->range_response_cfg.ranging_response) ? 662 SIZEOF_TLV_HDR + sizeof(NanFWRangeReqMsg) : 0) + 663 (pReq->sdea_service_specific_info_len ? SIZEOF_TLV_HDR + pReq->sdea_service_specific_info_len : 0); 664 665 if ((pReq->key_info.key_type == NAN_SECURITY_KEY_INPUT_PMK) && 666 (pReq->key_info.body.pmk_info.pmk_len == NAN_PMK_INFO_LEN)) 667 message_len += SIZEOF_TLV_HDR + NAN_PMK_INFO_LEN; 668 else if ((pReq->key_info.key_type == NAN_SECURITY_KEY_INPUT_PASSPHRASE) && 669 (pReq->key_info.body.passphrase_info.passphrase_len >= 670 NAN_SECURITY_MIN_PASSPHRASE_LEN) && 671 (pReq->key_info.body.passphrase_info.passphrase_len <= 672 NAN_SECURITY_MAX_PASSPHRASE_LEN)) 673 message_len += SIZEOF_TLV_HDR + 674 pReq->key_info.body.passphrase_info.passphrase_len; 675 676 pNanPublishServiceReqMsg pFwReq = (pNanPublishServiceReqMsg)malloc(message_len); 677 if (pFwReq == NULL) { 678 cleanup(); 679 return WIFI_ERROR_OUT_OF_MEMORY; 680 } 681 682 ALOGV("Message Len %zu", message_len); 683 memset(pFwReq, 0, message_len); 684 pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1; 685 pFwReq->fwHeader.msgId = NAN_MSG_ID_PUBLISH_SERVICE_REQ; 686 pFwReq->fwHeader.msgLen = message_len; 687 if (pReq->publish_id == 0) { 688 pFwReq->fwHeader.handle = 0xFFFF; 689 } else { 690 pFwReq->fwHeader.handle = pReq->publish_id; 691 } 692 pFwReq->fwHeader.transactionId = id; 693 694 pFwReq->publishServiceReqParams.ttl = pReq->ttl; 695 pFwReq->publishServiceReqParams.period = pReq->period; 696 pFwReq->publishServiceReqParams.replyIndFlag = 697 (pReq->recv_indication_cfg & BIT_3) ? 0 : 1; 698 pFwReq->publishServiceReqParams.publishType = pReq->publish_type; 699 pFwReq->publishServiceReqParams.txType = pReq->tx_type; 700 701 pFwReq->publishServiceReqParams.rssiThresholdFlag = pReq->rssi_threshold_flag; 702 pFwReq->publishServiceReqParams.matchAlg = pReq->publish_match_indicator; 703 pFwReq->publishServiceReqParams.count = pReq->publish_count; 704 pFwReq->publishServiceReqParams.connmap = pReq->connmap; 705 pFwReq->publishServiceReqParams.pubTerminatedIndDisableFlag = 706 (pReq->recv_indication_cfg & BIT_0) ? 1 : 0; 707 pFwReq->publishServiceReqParams.pubMatchExpiredIndDisableFlag = 708 (pReq->recv_indication_cfg & BIT_1) ? 1 : 0; 709 pFwReq->publishServiceReqParams.followupRxIndDisableFlag = 710 (pReq->recv_indication_cfg & BIT_2) ? 1 : 0; 711 712 pFwReq->publishServiceReqParams.reserved2 = 0; 713 714 u8* tlvs = pFwReq->ptlv; 715 if (pReq->service_name_len) { 716 tlvs = addTlv(NAN_TLV_TYPE_SERVICE_NAME, pReq->service_name_len, 717 (const u8*)&pReq->service_name[0], tlvs); 718 } 719 if (pReq->service_specific_info_len) { 720 tlvs = addTlv(NAN_TLV_TYPE_SERVICE_SPECIFIC_INFO, pReq->service_specific_info_len, 721 (const u8*)&pReq->service_specific_info[0], tlvs); 722 } 723 if (pReq->rx_match_filter_len) { 724 tlvs = addTlv(NAN_TLV_TYPE_RX_MATCH_FILTER, pReq->rx_match_filter_len, 725 (const u8*)&pReq->rx_match_filter[0], tlvs); 726 } 727 if (pReq->tx_match_filter_len) { 728 tlvs = addTlv(NAN_TLV_TYPE_TX_MATCH_FILTER, pReq->tx_match_filter_len, 729 (const u8*)&pReq->tx_match_filter[0], tlvs); 730 } 731 732 /* Pass the Accept policy always */ 733 tlvs = addTlv(NAN_TLV_TYPE_NAN_SERVICE_ACCEPT_POLICY, sizeof(NanServiceAcceptPolicy), 734 (const u8*)&pReq->service_responder_policy, tlvs); 735 736 if (pReq->cipher_type) { 737 NanCsidType pNanCsidType; 738 pNanCsidType.csid_type = pReq->cipher_type; 739 tlvs = addTlv(NAN_TLV_TYPE_NAN_CSID, sizeof(NanCsidType), 740 (const u8*)&pNanCsidType, tlvs); 741 } 742 743 if ((pReq->key_info.key_type == NAN_SECURITY_KEY_INPUT_PMK) && 744 (pReq->key_info.body.pmk_info.pmk_len == NAN_PMK_INFO_LEN)) { 745 tlvs = addTlv(NAN_TLV_TYPE_NAN_PMK, 746 pReq->key_info.body.pmk_info.pmk_len, 747 (const u8*)&pReq->key_info.body.pmk_info.pmk[0], tlvs); 748 } else if ((pReq->key_info.key_type == NAN_SECURITY_KEY_INPUT_PASSPHRASE) && 749 (pReq->key_info.body.passphrase_info.passphrase_len >= 750 NAN_SECURITY_MIN_PASSPHRASE_LEN) && 751 (pReq->key_info.body.passphrase_info.passphrase_len <= 752 NAN_SECURITY_MAX_PASSPHRASE_LEN)) { 753 tlvs = addTlv(NAN_TLV_TYPE_NAN_PASSPHRASE, 754 pReq->key_info.body.passphrase_info.passphrase_len, 755 (const u8*)&pReq->key_info.body.passphrase_info.passphrase[0], 756 tlvs); 757 } 758 759 if (pReq->sdea_params.config_nan_data_path || 760 pReq->sdea_params.security_cfg || 761 pReq->sdea_params.ranging_state || 762 pReq->sdea_params.range_report || 763 pReq->sdea_params.qos_cfg) { 764 NanFWSdeaCtrlParams pNanFWSdeaCtrlParams; 765 memset(&pNanFWSdeaCtrlParams, 0, sizeof(NanFWSdeaCtrlParams)); 766 767 if (pReq->sdea_params.config_nan_data_path) { 768 pNanFWSdeaCtrlParams.data_path_required = 1; 769 pNanFWSdeaCtrlParams.data_path_type = 770 (pReq->sdea_params.ndp_type & BIT_0) ? 771 NAN_DATA_PATH_MULTICAST_MSG : 772 NAN_DATA_PATH_UNICAST_MSG; 773 774 } 775 if (pReq->sdea_params.security_cfg) { 776 pNanFWSdeaCtrlParams.security_required = 777 pReq->sdea_params.security_cfg; 778 } 779 if (pReq->sdea_params.ranging_state) { 780 pNanFWSdeaCtrlParams.ranging_required = 781 pReq->sdea_params.ranging_state; 782 } 783 if (pReq->sdea_params.range_report) { 784 pNanFWSdeaCtrlParams.range_report = 785 (((pReq->sdea_params.range_report & NAN_ENABLE_RANGE_REPORT) >> 1) ? 1 : 0); 786 } 787 if (pReq->sdea_params.qos_cfg) { 788 pNanFWSdeaCtrlParams.qos_required = pReq->sdea_params.qos_cfg; 789 } 790 tlvs = addTlv(NAN_TLV_TYPE_SDEA_CTRL_PARAMS, sizeof(NanFWSdeaCtrlParams), 791 (const u8*)&pNanFWSdeaCtrlParams, tlvs); 792 } 793 794 if (pReq->ranging_cfg.ranging_interval_msec || 795 pReq->ranging_cfg.config_ranging_indications || 796 pReq->ranging_cfg.distance_ingress_mm || 797 pReq->ranging_cfg.distance_egress_mm) { 798 NanFWRangeConfigParams pNanFWRangingCfg; 799 800 memset(&pNanFWRangingCfg, 0, sizeof(NanFWRangeConfigParams)); 801 pNanFWRangingCfg.range_interval = 802 pReq->ranging_cfg.ranging_interval_msec; 803 pNanFWRangingCfg.ranging_indication_event = 804 ((pReq->ranging_cfg.config_ranging_indications & NAN_RANGING_INDICATE_CONTINUOUS_MASK) | 805 (pReq->ranging_cfg.config_ranging_indications & NAN_RANGING_INDICATE_INGRESS_MET_MASK) | 806 (pReq->ranging_cfg.config_ranging_indications & NAN_RANGING_INDICATE_EGRESS_MET_MASK)); 807 808 pNanFWRangingCfg.ranging_indication_event = pReq->ranging_cfg.config_ranging_indications; 809 if (pReq->ranging_cfg.config_ranging_indications & NAN_RANGING_INDICATE_INGRESS_MET_MASK) 810 pNanFWRangingCfg.geo_fence_threshold.inner_threshold = 811 pReq->ranging_cfg.distance_ingress_mm; 812 if (pReq->ranging_cfg.config_ranging_indications & NAN_RANGING_INDICATE_EGRESS_MET_MASK) 813 pNanFWRangingCfg.geo_fence_threshold.outer_threshold = 814 pReq->ranging_cfg.distance_egress_mm; 815 tlvs = addTlv(NAN_TLV_TYPE_NAN_RANGING_CFG, sizeof(NanFWRangeConfigParams), 816 (const u8*)&pNanFWRangingCfg, tlvs); 817 } 818 819 if (pReq->sdea_service_specific_info_len) { 820 tlvs = addTlv(NAN_TLV_TYPE_SDEA_SERVICE_SPECIFIC_INFO, pReq->sdea_service_specific_info_len, 821 (const u8*)&pReq->sdea_service_specific_info[0], tlvs); 822 } 823 824 if (pReq->range_response_cfg.publish_id || pReq->range_response_cfg.ranging_response) { 825 826 NanFWRangeReqMsg pNanFWRangeReqMsg; 827 memset(&pNanFWRangeReqMsg, 0, sizeof(NanFWRangeReqMsg)); 828 pNanFWRangeReqMsg.range_id = 829 (u16)pReq->range_response_cfg.publish_id; 830 CHAR_ARRAY_TO_MAC_ADDR(pReq->range_response_cfg.peer_addr, pNanFWRangeReqMsg.range_mac_addr); 831 pNanFWRangeReqMsg.ranging_accept = 832 ((pReq->range_response_cfg.ranging_response == NAN_RANGE_REQUEST_ACCEPT) ? 1 : 0); 833 pNanFWRangeReqMsg.ranging_reject = 834 ((pReq->range_response_cfg.ranging_response == NAN_RANGE_REQUEST_REJECT) ? 1 : 0); 835 pNanFWRangeReqMsg.ranging_cancel = 836 ((pReq->range_response_cfg.ranging_response == NAN_RANGE_REQUEST_CANCEL) ? 1 : 0); 837 tlvs = addTlv(NAN_TLV_TYPE_NAN20_RANGING_REQUEST, sizeof(NanFWRangeReqMsg), 838 (const u8*)&pNanFWRangeReqMsg, tlvs); 839 } 840 841 mVendorData = (char *)pFwReq; 842 mDataLen = message_len; 843 844 ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen); 845 if (ret != WIFI_SUCCESS) { 846 ALOGE("%s: put_bytes Error:%d",__func__, ret); 847 cleanup(); 848 return ret; 849 } 850 hexdump(mVendorData, mDataLen); 851 return ret; 852 } 853 854 wifi_error NanCommand::putNanPublishCancel(transaction_id id, const NanPublishCancelRequest *pReq) 855 { 856 wifi_error ret; 857 ALOGV("NAN_PUBLISH_CANCEL"); 858 if (pReq == NULL) { 859 cleanup(); 860 return WIFI_ERROR_INVALID_ARGS; 861 } 862 size_t message_len = sizeof(NanPublishServiceCancelReqMsg); 863 864 pNanPublishServiceCancelReqMsg pFwReq = 865 (pNanPublishServiceCancelReqMsg)malloc(message_len); 866 if (pFwReq == NULL) { 867 cleanup(); 868 return WIFI_ERROR_OUT_OF_MEMORY; 869 } 870 871 ALOGV("Message Len %zu", message_len); 872 memset(pFwReq, 0, message_len); 873 pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1; 874 pFwReq->fwHeader.msgId = NAN_MSG_ID_PUBLISH_SERVICE_CANCEL_REQ; 875 pFwReq->fwHeader.msgLen = message_len; 876 pFwReq->fwHeader.handle = pReq->publish_id; 877 pFwReq->fwHeader.transactionId = id; 878 879 mVendorData = (char *)pFwReq; 880 mDataLen = message_len; 881 882 ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen); 883 if (ret != WIFI_SUCCESS) { 884 ALOGE("%s: put_bytes Error:%d",__func__, ret); 885 cleanup(); 886 return ret; 887 } 888 hexdump(mVendorData, mDataLen); 889 return ret; 890 } 891 892 wifi_error NanCommand::putNanSubscribe(transaction_id id, 893 const NanSubscribeRequest *pReq) 894 { 895 wifi_error ret; 896 897 ALOGV("NAN_SUBSCRIBE"); 898 if (pReq == NULL) { 899 cleanup(); 900 return WIFI_ERROR_INVALID_ARGS; 901 } 902 903 size_t message_len = 904 sizeof(NanMsgHeader) + sizeof(NanSubscribeServiceReqParams) + 905 (pReq->service_name_len ? SIZEOF_TLV_HDR + pReq->service_name_len : 0) + 906 (pReq->service_specific_info_len ? SIZEOF_TLV_HDR + pReq->service_specific_info_len : 0) + 907 (pReq->rx_match_filter_len ? SIZEOF_TLV_HDR + pReq->rx_match_filter_len : 0) + 908 (pReq->tx_match_filter_len ? SIZEOF_TLV_HDR + pReq->tx_match_filter_len : 0) + 909 (pReq->cipher_type ? SIZEOF_TLV_HDR + sizeof(NanCsidType) : 0) + 910 ((pReq->sdea_params.config_nan_data_path || pReq->sdea_params.security_cfg || 911 pReq->sdea_params.ranging_state || pReq->sdea_params.range_report || 912 pReq->sdea_params.qos_cfg) ? 913 SIZEOF_TLV_HDR + sizeof(NanFWSdeaCtrlParams) : 0) + 914 ((pReq->ranging_cfg.ranging_interval_msec || pReq->ranging_cfg.config_ranging_indications || 915 pReq->ranging_cfg.distance_ingress_mm || pReq->ranging_cfg.distance_egress_mm) ? 916 SIZEOF_TLV_HDR + sizeof(NanFWRangeConfigParams) : 0) + 917 ((pReq->range_response_cfg.requestor_instance_id || 918 pReq->range_response_cfg.ranging_response) ? 919 SIZEOF_TLV_HDR + sizeof(NanFWRangeReqMsg) : 0) + 920 (pReq->sdea_service_specific_info_len ? SIZEOF_TLV_HDR + pReq->sdea_service_specific_info_len : 0); 921 922 message_len += \ 923 (pReq->num_intf_addr_present * (SIZEOF_TLV_HDR + NAN_MAC_ADDR_LEN)); 924 925 926 if ((pReq->key_info.key_type == NAN_SECURITY_KEY_INPUT_PMK) && 927 (pReq->key_info.body.pmk_info.pmk_len == NAN_PMK_INFO_LEN)) 928 message_len += SIZEOF_TLV_HDR + NAN_PMK_INFO_LEN; 929 else if ((pReq->key_info.key_type == NAN_SECURITY_KEY_INPUT_PASSPHRASE) && 930 (pReq->key_info.body.passphrase_info.passphrase_len >= 931 NAN_SECURITY_MIN_PASSPHRASE_LEN) && 932 (pReq->key_info.body.passphrase_info.passphrase_len <= 933 NAN_SECURITY_MAX_PASSPHRASE_LEN)) 934 message_len += SIZEOF_TLV_HDR + 935 pReq->key_info.body.passphrase_info.passphrase_len; 936 937 938 pNanSubscribeServiceReqMsg pFwReq = (pNanSubscribeServiceReqMsg)malloc(message_len); 939 if (pFwReq == NULL) { 940 cleanup(); 941 return WIFI_ERROR_OUT_OF_MEMORY; 942 } 943 944 ALOGV("Message Len %zu", message_len); 945 memset(pFwReq, 0, message_len); 946 pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1; 947 pFwReq->fwHeader.msgId = NAN_MSG_ID_SUBSCRIBE_SERVICE_REQ; 948 pFwReq->fwHeader.msgLen = message_len; 949 if (pReq->subscribe_id == 0) { 950 pFwReq->fwHeader.handle = 0xFFFF; 951 } else { 952 pFwReq->fwHeader.handle = pReq->subscribe_id; 953 } 954 pFwReq->fwHeader.transactionId = id; 955 956 pFwReq->subscribeServiceReqParams.ttl = pReq->ttl; 957 pFwReq->subscribeServiceReqParams.period = pReq->period; 958 pFwReq->subscribeServiceReqParams.subscribeType = pReq->subscribe_type; 959 pFwReq->subscribeServiceReqParams.srfAttr = pReq->serviceResponseFilter; 960 pFwReq->subscribeServiceReqParams.srfInclude = pReq->serviceResponseInclude; 961 pFwReq->subscribeServiceReqParams.srfSend = pReq->useServiceResponseFilter; 962 pFwReq->subscribeServiceReqParams.ssiRequired = pReq->ssiRequiredForMatchIndication; 963 pFwReq->subscribeServiceReqParams.matchAlg = pReq->subscribe_match_indicator; 964 pFwReq->subscribeServiceReqParams.count = pReq->subscribe_count; 965 pFwReq->subscribeServiceReqParams.rssiThresholdFlag = pReq->rssi_threshold_flag; 966 pFwReq->subscribeServiceReqParams.subTerminatedIndDisableFlag = 967 (pReq->recv_indication_cfg & BIT_0) ? 1 : 0; 968 pFwReq->subscribeServiceReqParams.subMatchExpiredIndDisableFlag = 969 (pReq->recv_indication_cfg & BIT_1) ? 1 : 0; 970 pFwReq->subscribeServiceReqParams.followupRxIndDisableFlag = 971 (pReq->recv_indication_cfg & BIT_2) ? 1 : 0; 972 pFwReq->subscribeServiceReqParams.connmap = pReq->connmap; 973 pFwReq->subscribeServiceReqParams.reserved = 0; 974 975 u8* tlvs = pFwReq->ptlv; 976 if (pReq->service_name_len) { 977 tlvs = addTlv(NAN_TLV_TYPE_SERVICE_NAME, pReq->service_name_len, 978 (const u8*)&pReq->service_name[0], tlvs); 979 } 980 if (pReq->service_specific_info_len) { 981 tlvs = addTlv(NAN_TLV_TYPE_SERVICE_SPECIFIC_INFO, pReq->service_specific_info_len, 982 (const u8*)&pReq->service_specific_info[0], tlvs); 983 } 984 if (pReq->rx_match_filter_len) { 985 tlvs = addTlv(NAN_TLV_TYPE_RX_MATCH_FILTER, pReq->rx_match_filter_len, 986 (const u8*)&pReq->rx_match_filter[0], tlvs); 987 } 988 if (pReq->tx_match_filter_len) { 989 tlvs = addTlv(NAN_TLV_TYPE_TX_MATCH_FILTER, pReq->tx_match_filter_len, 990 (const u8*)&pReq->tx_match_filter[0], tlvs); 991 } 992 993 int i = 0; 994 for (i = 0; i < pReq->num_intf_addr_present; i++) 995 { 996 tlvs = addTlv(NAN_TLV_TYPE_MAC_ADDRESS, 997 NAN_MAC_ADDR_LEN, 998 (const u8*)&pReq->intf_addr[i][0], tlvs); 999 } 1000 1001 if (pReq->cipher_type) { 1002 NanCsidType pNanCsidType; 1003 pNanCsidType.csid_type = pReq->cipher_type; 1004 tlvs = addTlv(NAN_TLV_TYPE_NAN_CSID, sizeof(NanCsidType), 1005 (const u8*)&pNanCsidType, tlvs); 1006 } 1007 1008 if ((pReq->key_info.key_type == NAN_SECURITY_KEY_INPUT_PMK) && 1009 (pReq->key_info.body.pmk_info.pmk_len == NAN_PMK_INFO_LEN)) { 1010 tlvs = addTlv(NAN_TLV_TYPE_NAN_PMK, 1011 pReq->key_info.body.pmk_info.pmk_len, 1012 (const u8*)&pReq->key_info.body.pmk_info.pmk[0], tlvs); 1013 } else if ((pReq->key_info.key_type == NAN_SECURITY_KEY_INPUT_PASSPHRASE) && 1014 (pReq->key_info.body.passphrase_info.passphrase_len >= 1015 NAN_SECURITY_MIN_PASSPHRASE_LEN) && 1016 (pReq->key_info.body.passphrase_info.passphrase_len <= 1017 NAN_SECURITY_MAX_PASSPHRASE_LEN)) { 1018 tlvs = addTlv(NAN_TLV_TYPE_NAN_PASSPHRASE, 1019 pReq->key_info.body.passphrase_info.passphrase_len, 1020 (const u8*)&pReq->key_info.body.passphrase_info.passphrase[0], 1021 tlvs); 1022 } 1023 1024 if (pReq->sdea_params.config_nan_data_path || 1025 pReq->sdea_params.security_cfg || 1026 pReq->sdea_params.ranging_state || 1027 pReq->sdea_params.range_report || 1028 pReq->sdea_params.qos_cfg) { 1029 NanFWSdeaCtrlParams pNanFWSdeaCtrlParams; 1030 memset(&pNanFWSdeaCtrlParams, 0, sizeof(NanFWSdeaCtrlParams)); 1031 1032 if (pReq->sdea_params.config_nan_data_path) { 1033 pNanFWSdeaCtrlParams.data_path_required = 1; 1034 pNanFWSdeaCtrlParams.data_path_type = 1035 (pReq->sdea_params.ndp_type & BIT_0) ? 1036 NAN_DATA_PATH_MULTICAST_MSG : 1037 NAN_DATA_PATH_UNICAST_MSG; 1038 1039 } 1040 if (pReq->sdea_params.security_cfg) { 1041 pNanFWSdeaCtrlParams.security_required = 1042 pReq->sdea_params.security_cfg; 1043 } 1044 if (pReq->sdea_params.ranging_state) { 1045 pNanFWSdeaCtrlParams.ranging_required = 1046 pReq->sdea_params.ranging_state; 1047 } 1048 if (pReq->sdea_params.range_report) { 1049 pNanFWSdeaCtrlParams.range_report = 1050 ((pReq->sdea_params.range_report & NAN_ENABLE_RANGE_REPORT >> 1) ? 1 : 0); 1051 } 1052 if (pReq->sdea_params.qos_cfg) { 1053 pNanFWSdeaCtrlParams.qos_required = pReq->sdea_params.qos_cfg; 1054 } 1055 tlvs = addTlv(NAN_TLV_TYPE_SDEA_CTRL_PARAMS, sizeof(NanFWSdeaCtrlParams), 1056 (const u8*)&pNanFWSdeaCtrlParams, tlvs); 1057 1058 } 1059 1060 if (pReq->ranging_cfg.ranging_interval_msec || pReq->ranging_cfg.config_ranging_indications || pReq->ranging_cfg.distance_ingress_mm 1061 || pReq->ranging_cfg.distance_egress_mm) { 1062 NanFWRangeConfigParams pNanFWRangingCfg; 1063 memset(&pNanFWRangingCfg, 0, sizeof(NanFWRangeConfigParams)); 1064 pNanFWRangingCfg.range_interval = 1065 pReq->ranging_cfg.ranging_interval_msec; 1066 pNanFWRangingCfg.ranging_indication_event = 1067 ((pReq->ranging_cfg.config_ranging_indications & NAN_RANGING_INDICATE_CONTINUOUS_MASK) | 1068 (pReq->ranging_cfg.config_ranging_indications & NAN_RANGING_INDICATE_INGRESS_MET_MASK) | 1069 (pReq->ranging_cfg.config_ranging_indications & NAN_RANGING_INDICATE_EGRESS_MET_MASK)); 1070 1071 pNanFWRangingCfg.ranging_indication_event = 1072 pReq->ranging_cfg.config_ranging_indications; 1073 if (pReq->ranging_cfg.config_ranging_indications & NAN_RANGING_INDICATE_INGRESS_MET_MASK) 1074 pNanFWRangingCfg.geo_fence_threshold.inner_threshold = 1075 pReq->ranging_cfg.distance_ingress_mm; 1076 if (pReq->ranging_cfg.config_ranging_indications & NAN_RANGING_INDICATE_EGRESS_MET_MASK) 1077 pNanFWRangingCfg.geo_fence_threshold.outer_threshold = 1078 pReq->ranging_cfg.distance_egress_mm; 1079 tlvs = addTlv(NAN_TLV_TYPE_NAN_RANGING_CFG, sizeof(NanFWRangeConfigParams), 1080 (const u8*)&pNanFWRangingCfg, tlvs); 1081 } 1082 1083 if (pReq->sdea_service_specific_info_len) { 1084 tlvs = addTlv(NAN_TLV_TYPE_SDEA_SERVICE_SPECIFIC_INFO, pReq->sdea_service_specific_info_len, 1085 (const u8*)&pReq->sdea_service_specific_info[0], tlvs); 1086 } 1087 1088 if (pReq->range_response_cfg.requestor_instance_id || pReq->range_response_cfg.ranging_response) { 1089 NanFWRangeReqMsg pNanFWRangeReqMsg; 1090 memset(&pNanFWRangeReqMsg, 0, sizeof(NanFWRangeReqMsg)); 1091 pNanFWRangeReqMsg.range_id = 1092 pReq->range_response_cfg.requestor_instance_id; 1093 memcpy(&pNanFWRangeReqMsg.range_mac_addr, &pReq->range_response_cfg.peer_addr, NAN_MAC_ADDR_LEN); 1094 pNanFWRangeReqMsg.ranging_accept = 1095 ((pReq->range_response_cfg.ranging_response == NAN_RANGE_REQUEST_ACCEPT) ? 1 : 0); 1096 pNanFWRangeReqMsg.ranging_reject = 1097 ((pReq->range_response_cfg.ranging_response == NAN_RANGE_REQUEST_REJECT) ? 1 : 0); 1098 pNanFWRangeReqMsg.ranging_cancel = 1099 ((pReq->range_response_cfg.ranging_response == NAN_RANGE_REQUEST_CANCEL) ? 1 : 0); 1100 tlvs = addTlv(NAN_TLV_TYPE_NAN20_RANGING_REQUEST, sizeof(NanFWRangeReqMsg), 1101 (const u8*)&pNanFWRangeReqMsg, tlvs); 1102 } 1103 1104 mVendorData = (char *)pFwReq; 1105 mDataLen = message_len; 1106 ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen); 1107 if (ret != WIFI_SUCCESS) { 1108 ALOGE("%s: put_bytes Error:%d",__func__, ret); 1109 cleanup(); 1110 return ret; 1111 } 1112 hexdump(mVendorData, mDataLen); 1113 return ret; 1114 } 1115 1116 wifi_error NanCommand::putNanSubscribeCancel(transaction_id id, 1117 const NanSubscribeCancelRequest *pReq) 1118 { 1119 wifi_error ret; 1120 ALOGV("NAN_SUBSCRIBE_CANCEL"); 1121 if (pReq == NULL) { 1122 cleanup(); 1123 return WIFI_ERROR_INVALID_ARGS; 1124 } 1125 size_t message_len = sizeof(NanSubscribeServiceCancelReqMsg); 1126 1127 pNanSubscribeServiceCancelReqMsg pFwReq = 1128 (pNanSubscribeServiceCancelReqMsg)malloc(message_len); 1129 if (pFwReq == NULL) { 1130 cleanup(); 1131 return WIFI_ERROR_OUT_OF_MEMORY; 1132 } 1133 1134 ALOGV("Message Len %zu", message_len); 1135 memset(pFwReq, 0, message_len); 1136 pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1; 1137 pFwReq->fwHeader.msgId = NAN_MSG_ID_SUBSCRIBE_SERVICE_CANCEL_REQ; 1138 pFwReq->fwHeader.msgLen = message_len; 1139 pFwReq->fwHeader.handle = pReq->subscribe_id; 1140 pFwReq->fwHeader.transactionId = id; 1141 1142 mVendorData = (char *)pFwReq; 1143 mDataLen = message_len; 1144 ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen); 1145 if (ret != WIFI_SUCCESS) { 1146 ALOGE("%s: put_bytes Error:%d",__func__, ret); 1147 cleanup(); 1148 return ret; 1149 } 1150 hexdump(mVendorData, mDataLen); 1151 return ret; 1152 } 1153 1154 wifi_error NanCommand::putNanTransmitFollowup(transaction_id id, 1155 const NanTransmitFollowupRequest *pReq) 1156 { 1157 wifi_error ret; 1158 ALOGV("TRANSMIT_FOLLOWUP"); 1159 if (pReq == NULL) { 1160 cleanup(); 1161 return WIFI_ERROR_INVALID_ARGS; 1162 } 1163 1164 size_t message_len = 1165 sizeof(NanMsgHeader) + sizeof(NanTransmitFollowupReqParams) + 1166 (pReq->service_specific_info_len ? SIZEOF_TLV_HDR + 1167 pReq->service_specific_info_len : 0) + 1168 (pReq->sdea_service_specific_info_len ? SIZEOF_TLV_HDR + pReq->sdea_service_specific_info_len : 0); 1169 1170 /* Mac address needs to be added in TLV */ 1171 message_len += (SIZEOF_TLV_HDR + sizeof(pReq->addr)); 1172 1173 pNanTransmitFollowupReqMsg pFwReq = (pNanTransmitFollowupReqMsg)malloc(message_len); 1174 if (pFwReq == NULL) { 1175 cleanup(); 1176 return WIFI_ERROR_OUT_OF_MEMORY; 1177 } 1178 1179 ALOGV("Message Len %zu", message_len); 1180 memset (pFwReq, 0, message_len); 1181 pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1; 1182 pFwReq->fwHeader.msgId = NAN_MSG_ID_TRANSMIT_FOLLOWUP_REQ; 1183 pFwReq->fwHeader.msgLen = message_len; 1184 pFwReq->fwHeader.handle = pReq->publish_subscribe_id; 1185 pFwReq->fwHeader.transactionId = id; 1186 1187 pFwReq->transmitFollowupReqParams.matchHandle = pReq->requestor_instance_id; 1188 if (pReq->priority != NAN_TX_PRIORITY_HIGH) { 1189 pFwReq->transmitFollowupReqParams.priority = 1; 1190 } else { 1191 pFwReq->transmitFollowupReqParams.priority = 2; 1192 } 1193 pFwReq->transmitFollowupReqParams.window = pReq->dw_or_faw; 1194 pFwReq->transmitFollowupReqParams.followupTxRspDisableFlag = 1195 (pReq->recv_indication_cfg & BIT_0) ? 1 : 0; 1196 pFwReq->transmitFollowupReqParams.reserved = 0; 1197 1198 u8* tlvs = pFwReq->ptlv; 1199 1200 /* Mac address needs to be added in TLV */ 1201 tlvs = addTlv(NAN_TLV_TYPE_MAC_ADDRESS, sizeof(pReq->addr), 1202 (const u8*)&pReq->addr[0], tlvs); 1203 u16 tlv_type = NAN_TLV_TYPE_SERVICE_SPECIFIC_INFO; 1204 1205 if (pReq->service_specific_info_len) { 1206 tlvs = addTlv(tlv_type, pReq->service_specific_info_len, 1207 (const u8*)&pReq->service_specific_info[0], tlvs); 1208 } 1209 1210 if (pReq->sdea_service_specific_info_len) { 1211 tlvs = addTlv(NAN_TLV_TYPE_SDEA_SERVICE_SPECIFIC_INFO, pReq->sdea_service_specific_info_len, 1212 (const u8*)&pReq->sdea_service_specific_info[0], tlvs); 1213 } 1214 1215 mVendorData = (char *)pFwReq; 1216 mDataLen = message_len; 1217 1218 ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen); 1219 if (ret != WIFI_SUCCESS) { 1220 ALOGE("%s: put_bytes Error:%d",__func__, ret); 1221 cleanup(); 1222 return ret; 1223 } 1224 hexdump(mVendorData, mDataLen); 1225 return ret; 1226 } 1227 1228 wifi_error NanCommand::putNanStats(transaction_id id, const NanStatsRequest *pReq) 1229 { 1230 wifi_error ret; 1231 ALOGV("NAN_STATS"); 1232 if (pReq == NULL) { 1233 cleanup(); 1234 return WIFI_ERROR_INVALID_ARGS; 1235 } 1236 size_t message_len = sizeof(NanStatsReqMsg); 1237 1238 pNanStatsReqMsg pFwReq = 1239 (pNanStatsReqMsg)malloc(message_len); 1240 if (pFwReq == NULL) { 1241 cleanup(); 1242 return WIFI_ERROR_OUT_OF_MEMORY; 1243 } 1244 1245 ALOGV("Message Len %zu", message_len); 1246 memset(pFwReq, 0, message_len); 1247 pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1; 1248 pFwReq->fwHeader.msgId = NAN_MSG_ID_STATS_REQ; 1249 pFwReq->fwHeader.msgLen = message_len; 1250 pFwReq->fwHeader.transactionId = id; 1251 1252 pFwReq->statsReqParams.statsType = pReq->stats_type; 1253 pFwReq->statsReqParams.clear = pReq->clear; 1254 pFwReq->statsReqParams.reserved = 0; 1255 1256 mVendorData = (char *)pFwReq; 1257 mDataLen = message_len; 1258 1259 ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen); 1260 if (ret != WIFI_SUCCESS) { 1261 ALOGE("%s: put_bytes Error:%d",__func__, ret); 1262 cleanup(); 1263 return ret; 1264 } 1265 hexdump(mVendorData, mDataLen); 1266 return ret; 1267 } 1268 1269 wifi_error NanCommand::putNanTCA(transaction_id id, const NanTCARequest *pReq) 1270 { 1271 wifi_error ret; 1272 ALOGV("NAN_TCA"); 1273 if (pReq == NULL) { 1274 cleanup(); 1275 return WIFI_ERROR_INVALID_ARGS; 1276 } 1277 size_t message_len = sizeof(NanTcaReqMsg); 1278 1279 message_len += (SIZEOF_TLV_HDR + 2 * sizeof(u32)); 1280 pNanTcaReqMsg pFwReq = 1281 (pNanTcaReqMsg)malloc(message_len); 1282 if (pFwReq == NULL) { 1283 cleanup(); 1284 return WIFI_ERROR_OUT_OF_MEMORY; 1285 } 1286 1287 ALOGV("Message Len %zu", message_len); 1288 memset(pFwReq, 0, message_len); 1289 pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1; 1290 pFwReq->fwHeader.msgId = NAN_MSG_ID_TCA_REQ; 1291 pFwReq->fwHeader.msgLen = message_len; 1292 pFwReq->fwHeader.transactionId = id; 1293 1294 u32 tcaReqParams[2]; 1295 memset (tcaReqParams, 0, sizeof(tcaReqParams)); 1296 tcaReqParams[0] = (pReq->rising_direction_evt_flag & 0x01); 1297 tcaReqParams[0] |= (pReq->falling_direction_evt_flag & 0x01) << 1; 1298 tcaReqParams[0] |= (pReq->clear & 0x01) << 2; 1299 tcaReqParams[1] = pReq->threshold; 1300 1301 u8* tlvs = pFwReq->ptlv; 1302 1303 if (pReq->tca_type == NAN_TCA_ID_CLUSTER_SIZE) { 1304 tlvs = addTlv(NAN_TLV_TYPE_CLUSTER_SIZE_REQ, sizeof(tcaReqParams), 1305 (const u8*)&tcaReqParams[0], tlvs); 1306 } else { 1307 ALOGE("%s: Unrecognized tca_type:%u", __FUNCTION__, pReq->tca_type); 1308 cleanup(); 1309 return WIFI_ERROR_INVALID_ARGS; 1310 } 1311 1312 mVendorData = (char *)pFwReq; 1313 mDataLen = message_len; 1314 1315 ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen); 1316 if (ret != WIFI_SUCCESS) { 1317 ALOGE("%s: put_bytes Error:%d",__func__, ret); 1318 cleanup(); 1319 return ret; 1320 } 1321 hexdump(mVendorData, mDataLen); 1322 return ret; 1323 } 1324 1325 wifi_error NanCommand::putNanBeaconSdfPayload(transaction_id id, 1326 const NanBeaconSdfPayloadRequest *pReq) 1327 { 1328 wifi_error ret; 1329 ALOGV("NAN_BEACON_SDF_PAYLAOD"); 1330 if (pReq == NULL) { 1331 cleanup(); 1332 return WIFI_ERROR_INVALID_ARGS; 1333 } 1334 size_t message_len = sizeof(NanMsgHeader) + \ 1335 SIZEOF_TLV_HDR + sizeof(u32) + \ 1336 pReq->vsa.vsa_len; 1337 1338 pNanBeaconSdfPayloadReqMsg pFwReq = 1339 (pNanBeaconSdfPayloadReqMsg)malloc(message_len); 1340 if (pFwReq == NULL) { 1341 cleanup(); 1342 return WIFI_ERROR_OUT_OF_MEMORY; 1343 } 1344 1345 ALOGV("Message Len %zu", message_len); 1346 memset(pFwReq, 0, message_len); 1347 pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1; 1348 pFwReq->fwHeader.msgId = NAN_MSG_ID_BEACON_SDF_REQ; 1349 pFwReq->fwHeader.msgLen = message_len; 1350 pFwReq->fwHeader.transactionId = id; 1351 1352 /* Construct First 4 bytes of NanBeaconSdfPayloadReqMsg */ 1353 u32 temp = 0; 1354 temp = pReq->vsa.payload_transmit_flag & 0x01; 1355 temp |= (pReq->vsa.tx_in_discovery_beacon & 0x01) << 1; 1356 temp |= (pReq->vsa.tx_in_sync_beacon & 0x01) << 2; 1357 temp |= (pReq->vsa.tx_in_service_discovery & 0x01) << 3; 1358 temp |= (pReq->vsa.vendor_oui & 0x00FFFFFF) << 8; 1359 1360 int tlv_len = sizeof(u32) + pReq->vsa.vsa_len; 1361 u8* tempBuf = (u8*)malloc(tlv_len); 1362 if (tempBuf == NULL) { 1363 ALOGE("%s: Malloc failed", __func__); 1364 free(pFwReq); 1365 cleanup(); 1366 return WIFI_ERROR_OUT_OF_MEMORY; 1367 } 1368 memset(tempBuf, 0, tlv_len); 1369 memcpy(tempBuf, &temp, sizeof(u32)); 1370 memcpy((tempBuf + sizeof(u32)), pReq->vsa.vsa, pReq->vsa.vsa_len); 1371 1372 u8* tlvs = pFwReq->ptlv; 1373 1374 /* Write the TLVs to the message. */ 1375 tlvs = addTlv(NAN_TLV_TYPE_VENDOR_SPECIFIC_ATTRIBUTE_TRANSMIT, tlv_len, 1376 (const u8*)tempBuf, tlvs); 1377 free(tempBuf); 1378 1379 mVendorData = (char *)pFwReq; 1380 mDataLen = message_len; 1381 1382 ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen); 1383 if (ret != WIFI_SUCCESS) { 1384 ALOGE("%s: put_bytes Error:%d",__func__, ret); 1385 cleanup(); 1386 return ret; 1387 } 1388 hexdump(mVendorData, mDataLen); 1389 return ret; 1390 } 1391 1392 //callback handlers registered for nl message send 1393 static int error_handler_nan(struct sockaddr_nl *nla, struct nlmsgerr *err, 1394 void *arg) 1395 { 1396 struct sockaddr_nl * tmp; 1397 int *ret = (int *)arg; 1398 tmp = nla; 1399 *ret = err->error; 1400 ALOGE("%s: Error code:%d (%s)", __func__, *ret, strerror(-(*ret))); 1401 return NL_STOP; 1402 } 1403 1404 //callback handlers registered for nl message send 1405 static int ack_handler_nan(struct nl_msg *msg, void *arg) 1406 { 1407 int *ret = (int *)arg; 1408 struct nl_msg * a; 1409 1410 ALOGE("%s: called", __func__); 1411 a = msg; 1412 *ret = 0; 1413 return NL_STOP; 1414 } 1415 1416 //callback handlers registered for nl message send 1417 static int finish_handler_nan(struct nl_msg *msg, void *arg) 1418 { 1419 int *ret = (int *)arg; 1420 struct nl_msg * a; 1421 1422 ALOGE("%s: called", __func__); 1423 a = msg; 1424 *ret = 0; 1425 return NL_SKIP; 1426 } 1427 1428 1429 //Override base class requestEvent and implement little differently here 1430 //This will send the request message 1431 //We dont wait for any response back in case of Nan as it is asynchronous 1432 //thus no wait for condition. 1433 wifi_error NanCommand::requestEvent() 1434 { 1435 wifi_error res; 1436 int status; 1437 struct nl_cb * cb; 1438 1439 cb = nl_cb_alloc(NL_CB_DEFAULT); 1440 if (!cb) { 1441 ALOGE("%s: Callback allocation failed",__func__); 1442 res = WIFI_ERROR_OUT_OF_MEMORY; 1443 goto out; 1444 } 1445 1446 if (!mInfo->cmd_sock) { 1447 ALOGE("%s: Command socket is null",__func__); 1448 res = WIFI_ERROR_OUT_OF_MEMORY; 1449 goto out; 1450 } 1451 1452 /* send message */ 1453 ALOGV("%s:Handle:%p Socket Value:%p", __func__, mInfo, mInfo->cmd_sock); 1454 status = nl_send_auto_complete(mInfo->cmd_sock, mMsg.getMessage()); 1455 if (status < 0) { 1456 res = mapKernelErrortoWifiHalError(status); 1457 goto out; 1458 } 1459 1460 status = 1; 1461 1462 nl_cb_err(cb, NL_CB_CUSTOM, error_handler_nan, &status); 1463 nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler_nan, &status); 1464 nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler_nan, &status); 1465 1466 // err is populated as part of finish_handler 1467 while (status > 0) 1468 nl_recvmsgs(mInfo->cmd_sock, cb); 1469 1470 res = mapKernelErrortoWifiHalError(status); 1471 out: 1472 //free the VendorData 1473 if (mVendorData) { 1474 free(mVendorData); 1475 } 1476 mVendorData = NULL; 1477 //cleanup the mMsg 1478 mMsg.destroy(); 1479 return res; 1480 } 1481 1482 int NanCommand::calcNanTransmitPostDiscoverySize( 1483 const NanTransmitPostDiscovery *pPostDiscovery) 1484 { 1485 /* Fixed size of u32 for Conn Type, Device Role and R flag + Dur + Rsvd*/ 1486 int ret = sizeof(u32); 1487 /* size of availability interval bit map is 4 bytes */ 1488 ret += sizeof(u32); 1489 /* size of mac address is 6 bytes*/ 1490 ret += (SIZEOF_TLV_HDR + NAN_MAC_ADDR_LEN); 1491 if (pPostDiscovery && 1492 pPostDiscovery->type == NAN_CONN_WLAN_MESH) { 1493 /* size of WLAN_MESH_ID */ 1494 ret += (SIZEOF_TLV_HDR + \ 1495 pPostDiscovery->mesh_id_len); 1496 } 1497 if (pPostDiscovery && 1498 pPostDiscovery->type == NAN_CONN_WLAN_INFRA) { 1499 /* size of Infrastructure ssid */ 1500 ret += (SIZEOF_TLV_HDR + \ 1501 pPostDiscovery->infrastructure_ssid_len); 1502 } 1503 ALOGV("%s:size:%d", __func__, ret); 1504 return ret; 1505 } 1506 1507 void NanCommand::fillNanSocialChannelParamVal( 1508 const NanSocialChannelScanParams *pScanParams, 1509 u32* pChannelParamArr) 1510 { 1511 int i; 1512 if (pChannelParamArr) { 1513 memset(pChannelParamArr, 0, 1514 NAN_MAX_SOCIAL_CHANNELS * sizeof(u32)); 1515 for (i= 0; i < NAN_MAX_SOCIAL_CHANNELS; i++) { 1516 pChannelParamArr[i] = pScanParams->scan_period[i] << 16; 1517 pChannelParamArr[i] |= pScanParams->dwell_time[i] << 8; 1518 } 1519 pChannelParamArr[NAN_CHANNEL_24G_BAND] |= 6; 1520 pChannelParamArr[NAN_CHANNEL_5G_BAND_LOW]|= 44; 1521 pChannelParamArr[NAN_CHANNEL_5G_BAND_HIGH]|= 149; 1522 ALOGV("%s: Filled SocialChannelParamVal", __func__); 1523 hexdump((char*)pChannelParamArr, NAN_MAX_SOCIAL_CHANNELS * sizeof(u32)); 1524 } 1525 return; 1526 } 1527 1528 u32 NanCommand::getNanTransmitPostConnectivityCapabilityVal( 1529 const NanTransmitPostConnectivityCapability *pCapab) 1530 { 1531 u32 ret = 0; 1532 ret |= (pCapab->payload_transmit_flag? 1:0) << 16; 1533 ret |= (pCapab->is_mesh_supported? 1:0) << 5; 1534 ret |= (pCapab->is_ibss_supported? 1:0) << 4; 1535 ret |= (pCapab->wlan_infra_field? 1:0) << 3; 1536 ret |= (pCapab->is_tdls_supported? 1:0) << 2; 1537 ret |= (pCapab->is_wfds_supported? 1:0) << 1; 1538 ret |= (pCapab->is_wfd_supported? 1:0); 1539 ALOGV("%s: val:%d", __func__, ret); 1540 return ret; 1541 } 1542 1543 void NanCommand::fillNanTransmitPostDiscoveryVal( 1544 const NanTransmitPostDiscovery *pTxDisc, 1545 u8 *pOutValue) 1546 { 1547 1548 if (pTxDisc && pOutValue) { 1549 u8 *tlvs = &pOutValue[8]; 1550 pOutValue[0] = pTxDisc->type; 1551 pOutValue[1] = pTxDisc->role; 1552 pOutValue[2] = (pTxDisc->transmit_freq? 1:0); 1553 pOutValue[2] |= ((pTxDisc->duration & 0x03) << 1); 1554 memcpy(&pOutValue[4], &pTxDisc->avail_interval_bitmap, 1555 sizeof(pTxDisc->avail_interval_bitmap)); 1556 tlvs = addTlv(NAN_TLV_TYPE_MAC_ADDRESS, 1557 NAN_MAC_ADDR_LEN, 1558 (const u8*)&pTxDisc->addr[0], 1559 tlvs); 1560 if (pTxDisc->type == NAN_CONN_WLAN_MESH) { 1561 tlvs = addTlv(NAN_TLV_TYPE_WLAN_MESH_ID, 1562 pTxDisc->mesh_id_len, 1563 (const u8*)&pTxDisc->mesh_id[0], 1564 tlvs); 1565 } 1566 if (pTxDisc->type == NAN_CONN_WLAN_INFRA) { 1567 tlvs = addTlv(NAN_TLV_TYPE_WLAN_INFRA_SSID, 1568 pTxDisc->infrastructure_ssid_len, 1569 (const u8*)&pTxDisc->infrastructure_ssid_val[0], 1570 tlvs); 1571 } 1572 ALOGV("%s: Filled TransmitPostDiscoveryVal", __func__); 1573 hexdump((char*)pOutValue, calcNanTransmitPostDiscoverySize(pTxDisc)); 1574 } 1575 1576 return; 1577 } 1578 1579 void NanCommand::fillNanFurtherAvailabilityMapVal( 1580 const NanFurtherAvailabilityMap *pFam, 1581 u8 *pOutValue) 1582 { 1583 int idx = 0; 1584 1585 if (pFam && pOutValue) { 1586 u32 famsize = calcNanFurtherAvailabilityMapSize(pFam); 1587 pNanFurtherAvailabilityMapAttrTlv pFwReq = \ 1588 (pNanFurtherAvailabilityMapAttrTlv)pOutValue; 1589 1590 memset(pOutValue, 0, famsize); 1591 pFwReq->numChan = pFam->numchans; 1592 for (idx = 0; idx < pFam->numchans; idx++) { 1593 const NanFurtherAvailabilityChannel *pFamChan = \ 1594 &pFam->famchan[idx]; 1595 pNanFurtherAvailabilityChan pFwFamChan = \ 1596 (pNanFurtherAvailabilityChan)((u8*)&pFwReq->pFaChan[0] + \ 1597 (idx * sizeof(NanFurtherAvailabilityChan))); 1598 1599 pFwFamChan->entryCtrl.availIntDuration = \ 1600 pFamChan->entry_control; 1601 pFwFamChan->entryCtrl.mapId = \ 1602 pFamChan->mapid; 1603 pFwFamChan->opClass = pFamChan->class_val; 1604 pFwFamChan->channel = pFamChan->channel; 1605 memcpy(&pFwFamChan->availIntBitmap, 1606 &pFamChan->avail_interval_bitmap, 1607 sizeof(pFwFamChan->availIntBitmap)); 1608 } 1609 ALOGV("%s: Filled FurtherAvailabilityMapVal", __func__); 1610 hexdump((char*)pOutValue, famsize); 1611 } 1612 return; 1613 } 1614 1615 int NanCommand::calcNanFurtherAvailabilityMapSize( 1616 const NanFurtherAvailabilityMap *pFam) 1617 { 1618 int ret = 0; 1619 if (pFam && pFam->numchans && 1620 pFam->numchans <= NAN_MAX_FAM_CHANNELS) { 1621 /* Fixed size of u8 for numchans*/ 1622 ret = sizeof(u8); 1623 /* numchans * sizeof(FamChannels) */ 1624 ret += (pFam->numchans * sizeof(NanFurtherAvailabilityChan)); 1625 } 1626 ALOGV("%s:size:%d", __func__, ret); 1627 return ret; 1628 } 1629 1630 wifi_error NanCommand::putNanCapabilities(transaction_id id) 1631 { 1632 wifi_error ret; 1633 ALOGV("NAN_CAPABILITIES"); 1634 size_t message_len = sizeof(NanCapabilitiesReqMsg); 1635 1636 pNanCapabilitiesReqMsg pFwReq = (pNanCapabilitiesReqMsg)malloc(message_len); 1637 if (pFwReq == NULL) { 1638 cleanup(); 1639 return WIFI_ERROR_OUT_OF_MEMORY; 1640 } 1641 1642 memset (pFwReq, 0, message_len); 1643 pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1; 1644 pFwReq->fwHeader.msgId = NAN_MSG_ID_CAPABILITIES_REQ; 1645 pFwReq->fwHeader.msgLen = message_len; 1646 pFwReq->fwHeader.transactionId = id; 1647 1648 mVendorData = (char*)pFwReq; 1649 mDataLen = message_len; 1650 1651 ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen); 1652 if (ret != WIFI_SUCCESS) { 1653 ALOGE("%s: put_bytes Error:%d",__func__, ret); 1654 cleanup(); 1655 return ret; 1656 } 1657 hexdump(mVendorData, mDataLen); 1658 return ret; 1659 } 1660 1661 wifi_error NanCommand::putNanDebugCommand(NanDebugParams debug, 1662 int debug_msg_length) 1663 { 1664 wifi_error ret; 1665 ALOGV("NAN_AVAILABILITY_DEBUG"); 1666 size_t message_len = sizeof(NanTestModeReqMsg); 1667 1668 message_len += (SIZEOF_TLV_HDR + debug_msg_length); 1669 pNanTestModeReqMsg pFwReq = (pNanTestModeReqMsg)malloc(message_len); 1670 if (pFwReq == NULL) { 1671 cleanup(); 1672 return WIFI_ERROR_OUT_OF_MEMORY; 1673 } 1674 1675 ALOGV("Message Len %zu\n", message_len); 1676 ALOGV("%s: Debug Command Type = 0x%x \n", __func__, debug.cmd); 1677 ALOGV("%s: ** Debug Command Data Start **", __func__); 1678 hexdump(debug.debug_cmd_data, debug_msg_length); 1679 ALOGV("%s: ** Debug Command Data End **", __func__); 1680 1681 memset (pFwReq, 0, message_len); 1682 pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1; 1683 pFwReq->fwHeader.msgId = NAN_MSG_ID_TESTMODE_REQ; 1684 pFwReq->fwHeader.msgLen = message_len; 1685 pFwReq->fwHeader.transactionId = 0; 1686 1687 u8* tlvs = pFwReq->ptlv; 1688 tlvs = addTlv(NAN_TLV_TYPE_TESTMODE_GENERIC_CMD, debug_msg_length, 1689 (const u8*)&debug, tlvs); 1690 1691 mVendorData = (char*)pFwReq; 1692 mDataLen = message_len; 1693 1694 /* Write the TLVs to the message. */ 1695 ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen); 1696 if (ret != WIFI_SUCCESS) { 1697 ALOGE("%s: put_bytes Error:%d",__func__, ret); 1698 cleanup(); 1699 return ret; 1700 } 1701 hexdump(mVendorData, mDataLen); 1702 return ret; 1703 } 1704