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