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 pNanEnableReqMsg pFwReq = (pNanEnableReqMsg)malloc(message_len); 127 if (pFwReq == NULL) { 128 cleanup(); 129 return WIFI_ERROR_OUT_OF_MEMORY; 130 } 131 132 ALOGV("Message Len %zu", message_len); 133 memset (pFwReq, 0, message_len); 134 pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1; 135 pFwReq->fwHeader.msgId = NAN_MSG_ID_ENABLE_REQ; 136 pFwReq->fwHeader.msgLen = message_len; 137 pFwReq->fwHeader.transactionId = id; 138 139 u8* tlvs = pFwReq->ptlv; 140 141 /* Write the TLVs to the message. */ 142 143 tlvs = addTlv(NAN_TLV_TYPE_CLUSTER_ID_LOW, sizeof(pReq->cluster_low), 144 (const u8*)&pReq->cluster_low, tlvs); 145 tlvs = addTlv(NAN_TLV_TYPE_CLUSTER_ID_HIGH, sizeof(pReq->cluster_high), 146 (const u8*)&pReq->cluster_high, tlvs); 147 tlvs = addTlv(NAN_TLV_TYPE_MASTER_PREFERENCE, sizeof(pReq->master_pref), 148 (const u8*)&pReq->master_pref, tlvs); 149 if (pReq->config_support_5g) { 150 tlvs = addTlv(NAN_TLV_TYPE_5G_SUPPORT, sizeof(pReq->support_5g_val), 151 (const u8*)&pReq->support_5g_val, tlvs); 152 } 153 if (pReq->config_sid_beacon) { 154 tlvs = addTlv(NAN_TLV_TYPE_SID_BEACON, sizeof(pReq->sid_beacon_val), 155 (const u8*)&pReq->sid_beacon_val, tlvs); 156 } 157 if (pReq->config_2dot4g_rssi_close) { 158 tlvs = addTlv(NAN_TLV_TYPE_24G_RSSI_CLOSE, 159 sizeof(pReq->rssi_close_2dot4g_val), 160 (const u8*)&pReq->rssi_close_2dot4g_val, tlvs); 161 } 162 if (pReq->config_2dot4g_rssi_middle) { 163 tlvs = addTlv(NAN_TLV_TYPE_24G_RSSI_MIDDLE, 164 sizeof(pReq->rssi_middle_2dot4g_val), 165 (const u8*)&pReq->rssi_middle_2dot4g_val, tlvs); 166 } 167 if (pReq->config_hop_count_limit) { 168 tlvs = addTlv(NAN_TLV_TYPE_HOP_COUNT_LIMIT, 169 sizeof(pReq->hop_count_limit_val), 170 (const u8*)&pReq->hop_count_limit_val, tlvs); 171 } 172 if (pReq->config_2dot4g_support) { 173 tlvs = addTlv(NAN_TLV_TYPE_24G_SUPPORT, sizeof(pReq->support_2dot4g_val), 174 (const u8*)&pReq->support_2dot4g_val, tlvs); 175 } 176 if (pReq->config_2dot4g_beacons) { 177 tlvs = addTlv(NAN_TLV_TYPE_24G_BEACON, sizeof(pReq->beacon_2dot4g_val), 178 (const u8*)&pReq->beacon_2dot4g_val, tlvs); 179 } 180 if (pReq->config_2dot4g_sdf) { 181 tlvs = addTlv(NAN_TLV_TYPE_24G_SDF, sizeof(pReq->sdf_2dot4g_val), 182 (const u8*)&pReq->sdf_2dot4g_val, tlvs); 183 } 184 if (pReq->config_5g_beacons) { 185 tlvs = addTlv(NAN_TLV_TYPE_5G_BEACON, sizeof(pReq->beacon_5g_val), 186 (const u8*)&pReq->beacon_5g_val, tlvs); 187 } 188 if (pReq->config_5g_sdf) { 189 tlvs = addTlv(NAN_TLV_TYPE_5G_SDF, sizeof(pReq->sdf_5g_val), 190 (const u8*)&pReq->sdf_5g_val, tlvs); 191 } 192 if (pReq->config_2dot4g_rssi_proximity) { 193 tlvs = addTlv(NAN_TLV_TYPE_24G_RSSI_CLOSE_PROXIMITY, 194 sizeof(pReq->rssi_proximity_2dot4g_val), 195 (const u8*)&pReq->rssi_proximity_2dot4g_val, tlvs); 196 } 197 /* Add the support of sending 5G RSSI values */ 198 if (pReq->config_5g_rssi_close) { 199 tlvs = addTlv(NAN_TLV_TYPE_5G_RSSI_CLOSE, sizeof(pReq->rssi_close_5g_val), 200 (const u8*)&pReq->rssi_close_5g_val, tlvs); 201 } 202 if (pReq->config_5g_rssi_middle) { 203 tlvs = addTlv(NAN_TLV_TYPE_5G_RSSI_MIDDLE, sizeof(pReq->rssi_middle_5g_val), 204 (const u8*)&pReq->rssi_middle_5g_val, tlvs); 205 } 206 if (pReq->config_5g_rssi_close_proximity) { 207 tlvs = addTlv(NAN_TLV_TYPE_5G_RSSI_CLOSE_PROXIMITY, 208 sizeof(pReq->rssi_close_proximity_5g_val), 209 (const u8*)&pReq->rssi_close_proximity_5g_val, tlvs); 210 } 211 if (pReq->config_rssi_window_size) { 212 tlvs = addTlv(NAN_TLV_TYPE_RSSI_AVERAGING_WINDOW_SIZE, sizeof(pReq->rssi_window_size_val), 213 (const u8*)&pReq->rssi_window_size_val, tlvs); 214 } 215 if (pReq->config_oui) { 216 tlvs = addTlv(NAN_TLV_TYPE_CLUSTER_OUI_NETWORK_ID, sizeof(pReq->oui_val), 217 (const u8*)&pReq->oui_val, tlvs); 218 } 219 if (pReq->config_intf_addr) { 220 tlvs = addTlv(NAN_TLV_TYPE_SOURCE_MAC_ADDRESS, sizeof(pReq->intf_addr_val), 221 (const u8*)&pReq->intf_addr_val[0], tlvs); 222 } 223 if (pReq->config_cluster_attribute_val) { 224 tlvs = addTlv(NAN_TLV_TYPE_CLUSTER_ATTRIBUTE_IN_SDF, sizeof(pReq->config_cluster_attribute_val), 225 (const u8*)&pReq->config_cluster_attribute_val, tlvs); 226 } 227 if (pReq->config_scan_params) { 228 u32 socialChannelParamVal[NAN_MAX_SOCIAL_CHANNELS]; 229 /* Fill the social channel param */ 230 fillNanSocialChannelParamVal(&pReq->scan_params_val, 231 socialChannelParamVal); 232 int i; 233 for (i = 0; i < NAN_MAX_SOCIAL_CHANNELS; i++) { 234 tlvs = addTlv(NAN_TLV_TYPE_SOCIAL_CHANNEL_SCAN_PARAMS, 235 sizeof(socialChannelParamVal[i]), 236 (const u8*)&socialChannelParamVal[i], tlvs); 237 } 238 } 239 if (pReq->config_random_factor_force) { 240 tlvs = addTlv(NAN_TLV_TYPE_RANDOM_FACTOR_FORCE, 241 sizeof(pReq->random_factor_force_val), 242 (const u8*)&pReq->random_factor_force_val, tlvs); 243 } 244 if (pReq->config_hop_count_force) { 245 tlvs = addTlv(NAN_TLV_TYPE_HOP_COUNT_FORCE, 246 sizeof(pReq->hop_count_force_val), 247 (const u8*)&pReq->hop_count_force_val, tlvs); 248 } 249 if (pReq->config_24g_channel) { 250 tlvs = addTlv(NAN_TLV_TYPE_24G_CHANNEL, 251 sizeof(u32), 252 (const u8*)&pReq->channel_24g_val, tlvs); 253 } 254 if (pReq->config_5g_channel) { 255 tlvs = addTlv(NAN_TLV_TYPE_5G_CHANNEL, 256 sizeof(u32), 257 (const u8*)&pReq->channel_5g_val, tlvs); 258 } 259 mVendorData = (char*)pFwReq; 260 mDataLen = message_len; 261 262 //Insert the vendor specific data 263 int ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen); 264 if (ret < 0) { 265 ALOGE("%s: put_bytes Error:%d",__func__, ret); 266 cleanup(); 267 return ret; 268 } 269 hexdump(mVendorData, mDataLen); 270 return ret; 271 } 272 273 int NanCommand::putNanDisable(transaction_id id) 274 { 275 ALOGV("NAN_DISABLE"); 276 size_t message_len = sizeof(NanDisableReqMsg); 277 278 pNanDisableReqMsg pFwReq = (pNanDisableReqMsg)malloc(message_len); 279 if (pFwReq == NULL) { 280 cleanup(); 281 return WIFI_ERROR_OUT_OF_MEMORY; 282 } 283 284 ALOGV("Message Len %zu", message_len); 285 memset (pFwReq, 0, message_len); 286 pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1; 287 pFwReq->fwHeader.msgId = NAN_MSG_ID_DISABLE_REQ; 288 pFwReq->fwHeader.msgLen = message_len; 289 pFwReq->fwHeader.transactionId = id; 290 291 mVendorData = (char*)pFwReq; 292 mDataLen = message_len; 293 294 int ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen); 295 if (ret < 0) { 296 ALOGE("%s: put_bytes Error:%d",__func__, ret); 297 cleanup(); 298 return ret; 299 } 300 hexdump(mVendorData, mDataLen); 301 return ret; 302 } 303 304 int NanCommand::putNanConfig(transaction_id id, const NanConfigRequest *pReq) 305 { 306 ALOGV("NAN_CONFIG"); 307 size_t message_len = NAN_MAX_CONFIGURATION_REQ_SIZE; 308 int idx = 0; 309 310 if (pReq == NULL || 311 pReq->num_config_discovery_attr > NAN_MAX_POSTDISCOVERY_LEN) { 312 cleanup(); 313 return WIFI_ERROR_INVALID_ARGS; 314 } 315 316 message_len = sizeof(NanMsgHeader); 317 318 message_len += \ 319 ( 320 pReq->config_sid_beacon ? (SIZEOF_TLV_HDR + \ 321 sizeof(pReq->sid_beacon)) : 0 \ 322 ) + \ 323 ( 324 pReq->config_master_pref ? (SIZEOF_TLV_HDR + \ 325 sizeof(pReq->master_pref)) : 0 \ 326 ) + \ 327 ( 328 pReq->config_rssi_proximity ? (SIZEOF_TLV_HDR + \ 329 sizeof(pReq->rssi_proximity)) : 0 \ 330 ) + \ 331 ( 332 pReq->config_5g_rssi_close_proximity ? (SIZEOF_TLV_HDR + \ 333 sizeof(pReq->rssi_close_proximity_5g_val)) : 0 \ 334 ) + \ 335 ( 336 pReq->config_rssi_window_size ? (SIZEOF_TLV_HDR + \ 337 sizeof(pReq->rssi_window_size_val)) : 0 \ 338 ) + \ 339 ( 340 pReq->config_cluster_attribute_val ? (SIZEOF_TLV_HDR + \ 341 sizeof(pReq->config_cluster_attribute_val)) : 0 \ 342 ) + \ 343 ( 344 pReq->config_scan_params ? (SIZEOF_TLV_HDR + \ 345 NAN_MAX_SOCIAL_CHANNELS * sizeof(u32)) : 0 \ 346 ) + \ 347 ( 348 pReq->config_random_factor_force ? (SIZEOF_TLV_HDR + \ 349 sizeof(pReq->random_factor_force_val)) : 0 \ 350 ) + \ 351 ( 352 pReq->config_hop_count_force ? (SIZEOF_TLV_HDR + \ 353 sizeof(pReq->hop_count_force_val)) : 0 \ 354 ) + \ 355 ( 356 pReq->config_conn_capability ? (SIZEOF_TLV_HDR + \ 357 sizeof(u32)) : 0 \ 358 ); 359 360 if (pReq->num_config_discovery_attr) { 361 for (idx = 0; idx < pReq->num_config_discovery_attr; idx ++) { 362 message_len += SIZEOF_TLV_HDR +\ 363 calcNanTransmitPostDiscoverySize(&pReq->discovery_attr_val[idx]); 364 } 365 } 366 367 if (pReq->config_fam && \ 368 calcNanFurtherAvailabilityMapSize(&pReq->fam_val)) { 369 message_len += (SIZEOF_TLV_HDR + \ 370 calcNanFurtherAvailabilityMapSize(&pReq->fam_val)); 371 } 372 373 pNanConfigurationReqMsg pFwReq = (pNanConfigurationReqMsg)malloc(message_len); 374 if (pFwReq == NULL) { 375 cleanup(); 376 return WIFI_ERROR_OUT_OF_MEMORY; 377 } 378 379 ALOGV("Message Len %zu", message_len); 380 memset (pFwReq, 0, message_len); 381 pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1; 382 pFwReq->fwHeader.msgId = NAN_MSG_ID_CONFIGURATION_REQ; 383 pFwReq->fwHeader.msgLen = message_len; 384 pFwReq->fwHeader.transactionId = id; 385 386 u8* tlvs = pFwReq->ptlv; 387 if (pReq->config_sid_beacon) { 388 tlvs = addTlv(NAN_TLV_TYPE_SID_BEACON, sizeof(pReq->sid_beacon), 389 (const u8*)&pReq->sid_beacon, tlvs); 390 } 391 if (pReq->config_master_pref) { 392 tlvs = addTlv(NAN_TLV_TYPE_MASTER_PREFERENCE, sizeof(pReq->master_pref), 393 (const u8*)&pReq->master_pref, tlvs); 394 } 395 396 if (pReq->config_rssi_window_size) { 397 tlvs = addTlv(NAN_TLV_TYPE_RSSI_AVERAGING_WINDOW_SIZE, sizeof(pReq->rssi_window_size_val), 398 (const u8*)&pReq->rssi_window_size_val, tlvs); 399 } 400 if (pReq->config_rssi_proximity) { 401 tlvs = addTlv(NAN_TLV_TYPE_24G_RSSI_CLOSE_PROXIMITY, sizeof(pReq->rssi_proximity), 402 (const u8*)&pReq->rssi_proximity, tlvs); 403 } 404 if (pReq->config_scan_params) { 405 u32 socialChannelParamVal[NAN_MAX_SOCIAL_CHANNELS]; 406 /* Fill the social channel param */ 407 fillNanSocialChannelParamVal(&pReq->scan_params_val, 408 socialChannelParamVal); 409 int i; 410 for (i = 0; i < NAN_MAX_SOCIAL_CHANNELS; i++) { 411 tlvs = addTlv(NAN_TLV_TYPE_SOCIAL_CHANNEL_SCAN_PARAMS, 412 sizeof(socialChannelParamVal[i]), 413 (const u8*)&socialChannelParamVal[i], tlvs); 414 } 415 } 416 if (pReq->config_random_factor_force) { 417 tlvs = addTlv(NAN_TLV_TYPE_RANDOM_FACTOR_FORCE, 418 sizeof(pReq->random_factor_force_val), 419 (const u8*)&pReq->random_factor_force_val, tlvs); 420 } 421 if (pReq->config_hop_count_force) { 422 tlvs = addTlv(NAN_TLV_TYPE_HOP_COUNT_FORCE, 423 sizeof(pReq->hop_count_force_val), 424 (const u8*)&pReq->hop_count_force_val, tlvs); 425 } 426 if (pReq->config_conn_capability) { 427 u32 val = \ 428 getNanTransmitPostConnectivityCapabilityVal(&pReq->conn_capability_val); 429 tlvs = addTlv(NAN_TLV_TYPE_POST_NAN_CONNECTIVITY_CAPABILITIES_TRANSMIT, 430 sizeof(val), (const u8*)&val, tlvs); 431 } 432 if (pReq->num_config_discovery_attr) { 433 for (idx = 0; idx < pReq->num_config_discovery_attr; idx ++) { 434 fillNanTransmitPostDiscoveryVal(&pReq->discovery_attr_val[idx], 435 (u8*)(tlvs + SIZEOF_TLV_HDR)); 436 tlvs = addTlv(NAN_TLV_TYPE_POST_NAN_DISCOVERY_ATTRIBUTE_TRANSMIT, 437 calcNanTransmitPostDiscoverySize( 438 &pReq->discovery_attr_val[idx]), 439 (const u8*)(tlvs + SIZEOF_TLV_HDR), tlvs); 440 } 441 } 442 if (pReq->config_fam && \ 443 calcNanFurtherAvailabilityMapSize(&pReq->fam_val)) { 444 fillNanFurtherAvailabilityMapVal(&pReq->fam_val, 445 (u8*)(tlvs + SIZEOF_TLV_HDR)); 446 tlvs = addTlv(NAN_TLV_TYPE_FURTHER_AVAILABILITY_MAP, 447 calcNanFurtherAvailabilityMapSize(&pReq->fam_val), 448 (const u8*)(tlvs + SIZEOF_TLV_HDR), tlvs); 449 } 450 451 mVendorData = (char*)pFwReq; 452 mDataLen = message_len; 453 454 int ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen); 455 if (ret < 0) { 456 ALOGE("%s: put_bytes Error:%d",__func__, ret); 457 cleanup(); 458 return ret; 459 } 460 hexdump(mVendorData, mDataLen); 461 return ret; 462 } 463 464 465 int NanCommand::putNanPublish(transaction_id id, const NanPublishRequest *pReq) 466 { 467 ALOGV("NAN_PUBLISH"); 468 if (pReq == NULL) { 469 cleanup(); 470 return WIFI_ERROR_INVALID_ARGS; 471 } 472 473 size_t message_len = 474 sizeof(NanMsgHeader) + sizeof(NanPublishServiceReqParams) + 475 (pReq->service_name_len ? SIZEOF_TLV_HDR + pReq->service_name_len : 0) + 476 (pReq->service_specific_info_len ? SIZEOF_TLV_HDR + pReq->service_specific_info_len : 0) + 477 (pReq->rx_match_filter_len ? SIZEOF_TLV_HDR + pReq->rx_match_filter_len : 0) + 478 (pReq->tx_match_filter_len ? SIZEOF_TLV_HDR + pReq->tx_match_filter_len : 0); 479 480 pNanPublishServiceReqMsg pFwReq = (pNanPublishServiceReqMsg)malloc(message_len); 481 if (pFwReq == NULL) { 482 cleanup(); 483 return WIFI_ERROR_OUT_OF_MEMORY; 484 } 485 486 ALOGV("Message Len %zu", message_len); 487 memset(pFwReq, 0, message_len); 488 pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1; 489 pFwReq->fwHeader.msgId = NAN_MSG_ID_PUBLISH_SERVICE_REQ; 490 pFwReq->fwHeader.msgLen = message_len; 491 if (pReq->publish_id == 0) { 492 pFwReq->fwHeader.handle = 0xFFFF; 493 } else { 494 pFwReq->fwHeader.handle = pReq->publish_id; 495 } 496 pFwReq->fwHeader.transactionId = id; 497 498 pFwReq->publishServiceReqParams.ttl = pReq->ttl; 499 pFwReq->publishServiceReqParams.period = pReq->period; 500 pFwReq->publishServiceReqParams.reserved = 0; 501 pFwReq->publishServiceReqParams.publishType = pReq->publish_type; 502 pFwReq->publishServiceReqParams.txType = pReq->tx_type; 503 504 pFwReq->publishServiceReqParams.rssiThresholdFlag = pReq->rssi_threshold_flag; 505 pFwReq->publishServiceReqParams.matchAlg = pReq->publish_match_indicator; 506 pFwReq->publishServiceReqParams.count = pReq->publish_count; 507 pFwReq->publishServiceReqParams.connmap = pReq->connmap; 508 pFwReq->publishServiceReqParams.pubTerminatedIndDisableFlag = 509 (pReq->recv_indication_cfg & BIT_0) ? 1 : 0; 510 pFwReq->publishServiceReqParams.pubMatchExpiredIndDisableFlag = 511 (pReq->recv_indication_cfg & BIT_1) ? 1 : 0; 512 pFwReq->publishServiceReqParams.followupRxIndDisableFlag = 513 (pReq->recv_indication_cfg & BIT_2) ? 1 : 0; 514 515 pFwReq->publishServiceReqParams.reserved2 = 0; 516 517 u8* tlvs = pFwReq->ptlv; 518 if (pReq->service_name_len) { 519 tlvs = addTlv(NAN_TLV_TYPE_SERVICE_NAME, pReq->service_name_len, 520 (const u8*)&pReq->service_name[0], tlvs); 521 } 522 if (pReq->service_specific_info_len) { 523 tlvs = addTlv(NAN_TLV_TYPE_SERVICE_SPECIFIC_INFO, pReq->service_specific_info_len, 524 (const u8*)&pReq->service_specific_info[0], tlvs); 525 } 526 if (pReq->rx_match_filter_len) { 527 tlvs = addTlv(NAN_TLV_TYPE_RX_MATCH_FILTER, pReq->rx_match_filter_len, 528 (const u8*)&pReq->rx_match_filter[0], tlvs); 529 } 530 if (pReq->tx_match_filter_len) { 531 tlvs = addTlv(NAN_TLV_TYPE_TX_MATCH_FILTER, pReq->tx_match_filter_len, 532 (const u8*)&pReq->tx_match_filter[0], tlvs); 533 } 534 535 mVendorData = (char *)pFwReq; 536 mDataLen = message_len; 537 538 int ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen); 539 if (ret < 0) { 540 ALOGE("%s: put_bytes Error:%d",__func__, ret); 541 cleanup(); 542 return ret; 543 } 544 hexdump(mVendorData, mDataLen); 545 return ret; 546 } 547 548 int NanCommand::putNanPublishCancel(transaction_id id, const NanPublishCancelRequest *pReq) 549 { 550 ALOGV("NAN_PUBLISH_CANCEL"); 551 if (pReq == NULL) { 552 cleanup(); 553 return WIFI_ERROR_INVALID_ARGS; 554 } 555 size_t message_len = sizeof(NanPublishServiceCancelReqMsg); 556 557 pNanPublishServiceCancelReqMsg pFwReq = 558 (pNanPublishServiceCancelReqMsg)malloc(message_len); 559 if (pFwReq == NULL) { 560 cleanup(); 561 return WIFI_ERROR_OUT_OF_MEMORY; 562 } 563 564 ALOGV("Message Len %zu", message_len); 565 memset(pFwReq, 0, message_len); 566 pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1; 567 pFwReq->fwHeader.msgId = NAN_MSG_ID_PUBLISH_SERVICE_CANCEL_REQ; 568 pFwReq->fwHeader.msgLen = message_len; 569 pFwReq->fwHeader.handle = pReq->publish_id; 570 pFwReq->fwHeader.transactionId = id; 571 572 mVendorData = (char *)pFwReq; 573 mDataLen = message_len; 574 575 int ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen); 576 if (ret < 0) { 577 ALOGE("%s: put_bytes Error:%d",__func__, ret); 578 cleanup(); 579 return ret; 580 } 581 hexdump(mVendorData, mDataLen); 582 return ret; 583 } 584 585 int NanCommand::putNanSubscribe(transaction_id id, 586 const NanSubscribeRequest *pReq) 587 { 588 589 ALOGV("NAN_SUBSCRIBE"); 590 if (pReq == NULL) { 591 cleanup(); 592 return WIFI_ERROR_INVALID_ARGS; 593 } 594 595 size_t message_len = 596 sizeof(NanMsgHeader) + sizeof(NanSubscribeServiceReqParams) + 597 (pReq->service_name_len ? SIZEOF_TLV_HDR + pReq->service_name_len : 0) + 598 (pReq->service_specific_info_len ? SIZEOF_TLV_HDR + pReq->service_specific_info_len : 0) + 599 (pReq->rx_match_filter_len ? SIZEOF_TLV_HDR + pReq->rx_match_filter_len : 0) + 600 (pReq->tx_match_filter_len ? SIZEOF_TLV_HDR + pReq->tx_match_filter_len : 0); 601 602 message_len += \ 603 (pReq->num_intf_addr_present * (SIZEOF_TLV_HDR + NAN_MAC_ADDR_LEN)); 604 605 pNanSubscribeServiceReqMsg pFwReq = (pNanSubscribeServiceReqMsg)malloc(message_len); 606 if (pFwReq == NULL) { 607 cleanup(); 608 return WIFI_ERROR_OUT_OF_MEMORY; 609 } 610 611 ALOGV("Message Len %zu", message_len); 612 memset(pFwReq, 0, message_len); 613 pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1; 614 pFwReq->fwHeader.msgId = NAN_MSG_ID_SUBSCRIBE_SERVICE_REQ; 615 pFwReq->fwHeader.msgLen = message_len; 616 if (pReq->subscribe_id == 0) { 617 pFwReq->fwHeader.handle = 0xFFFF; 618 } else { 619 pFwReq->fwHeader.handle = pReq->subscribe_id; 620 } 621 pFwReq->fwHeader.transactionId = id; 622 623 pFwReq->subscribeServiceReqParams.ttl = pReq->ttl; 624 pFwReq->subscribeServiceReqParams.period = pReq->period; 625 pFwReq->subscribeServiceReqParams.subscribeType = pReq->subscribe_type; 626 pFwReq->subscribeServiceReqParams.srfAttr = pReq->serviceResponseFilter; 627 pFwReq->subscribeServiceReqParams.srfInclude = pReq->serviceResponseInclude; 628 pFwReq->subscribeServiceReqParams.srfSend = pReq->useServiceResponseFilter; 629 pFwReq->subscribeServiceReqParams.ssiRequired = pReq->ssiRequiredForMatchIndication; 630 pFwReq->subscribeServiceReqParams.matchAlg = pReq->subscribe_match_indicator; 631 pFwReq->subscribeServiceReqParams.count = pReq->subscribe_count; 632 pFwReq->subscribeServiceReqParams.rssiThresholdFlag = pReq->rssi_threshold_flag; 633 pFwReq->subscribeServiceReqParams.subTerminatedIndDisableFlag = 634 (pReq->recv_indication_cfg & BIT_0) ? 1 : 0; 635 pFwReq->subscribeServiceReqParams.subMatchExpiredIndDisableFlag = 636 (pReq->recv_indication_cfg & BIT_1) ? 1 : 0; 637 pFwReq->subscribeServiceReqParams.followupRxIndDisableFlag = 638 (pReq->recv_indication_cfg & BIT_2) ? 1 : 0; 639 pFwReq->subscribeServiceReqParams.connmap = pReq->connmap; 640 pFwReq->subscribeServiceReqParams.reserved = 0; 641 642 u8* tlvs = pFwReq->ptlv; 643 if (pReq->service_name_len) { 644 tlvs = addTlv(NAN_TLV_TYPE_SERVICE_NAME, pReq->service_name_len, 645 (const u8*)&pReq->service_name[0], tlvs); 646 } 647 if (pReq->service_specific_info_len) { 648 tlvs = addTlv(NAN_TLV_TYPE_SERVICE_SPECIFIC_INFO, pReq->service_specific_info_len, 649 (const u8*)&pReq->service_specific_info[0], tlvs); 650 } 651 if (pReq->rx_match_filter_len) { 652 tlvs = addTlv(NAN_TLV_TYPE_RX_MATCH_FILTER, pReq->rx_match_filter_len, 653 (const u8*)&pReq->rx_match_filter[0], tlvs); 654 } 655 if (pReq->tx_match_filter_len) { 656 tlvs = addTlv(NAN_TLV_TYPE_TX_MATCH_FILTER, pReq->tx_match_filter_len, 657 (const u8*)&pReq->tx_match_filter[0], tlvs); 658 } 659 660 int i = 0; 661 for (i = 0; i < pReq->num_intf_addr_present; i++) 662 { 663 tlvs = addTlv(NAN_TLV_TYPE_MAC_ADDRESS, 664 NAN_MAC_ADDR_LEN, 665 (const u8*)&pReq->intf_addr[i][0], tlvs); 666 } 667 668 mVendorData = (char *)pFwReq; 669 mDataLen = message_len; 670 int ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen); 671 if (ret < 0) { 672 ALOGE("%s: put_bytes Error:%d",__func__, ret); 673 cleanup(); 674 return ret; 675 } 676 hexdump(mVendorData, mDataLen); 677 return ret; 678 } 679 680 int NanCommand::putNanSubscribeCancel(transaction_id id, 681 const NanSubscribeCancelRequest *pReq) 682 { 683 ALOGV("NAN_SUBSCRIBE_CANCEL"); 684 if (pReq == NULL) { 685 cleanup(); 686 return WIFI_ERROR_INVALID_ARGS; 687 } 688 size_t message_len = sizeof(NanSubscribeServiceCancelReqMsg); 689 690 pNanSubscribeServiceCancelReqMsg pFwReq = 691 (pNanSubscribeServiceCancelReqMsg)malloc(message_len); 692 if (pFwReq == NULL) { 693 cleanup(); 694 return WIFI_ERROR_OUT_OF_MEMORY; 695 } 696 697 ALOGV("Message Len %zu", message_len); 698 memset(pFwReq, 0, message_len); 699 pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1; 700 pFwReq->fwHeader.msgId = NAN_MSG_ID_SUBSCRIBE_SERVICE_CANCEL_REQ; 701 pFwReq->fwHeader.msgLen = message_len; 702 pFwReq->fwHeader.handle = pReq->subscribe_id; 703 pFwReq->fwHeader.transactionId = id; 704 705 mVendorData = (char *)pFwReq; 706 mDataLen = message_len; 707 int ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen); 708 if (ret < 0) { 709 ALOGE("%s: put_bytes Error:%d",__func__, ret); 710 cleanup(); 711 return ret; 712 } 713 hexdump(mVendorData, mDataLen); 714 return ret; 715 } 716 717 718 int NanCommand::putNanTransmitFollowup(transaction_id id, 719 const NanTransmitFollowupRequest *pReq) 720 { 721 ALOGV("TRANSMIT_FOLLOWUP"); 722 if (pReq == NULL) { 723 cleanup(); 724 return WIFI_ERROR_INVALID_ARGS; 725 } 726 727 size_t message_len = 728 sizeof(NanMsgHeader) + sizeof(NanTransmitFollowupReqParams) + 729 (pReq->service_specific_info_len ? SIZEOF_TLV_HDR + 730 pReq->service_specific_info_len : 0); 731 732 /* Mac address needs to be added in TLV */ 733 message_len += (SIZEOF_TLV_HDR + sizeof(pReq->addr)); 734 735 pNanTransmitFollowupReqMsg pFwReq = (pNanTransmitFollowupReqMsg)malloc(message_len); 736 if (pFwReq == NULL) { 737 cleanup(); 738 return WIFI_ERROR_OUT_OF_MEMORY; 739 } 740 741 ALOGV("Message Len %zu", message_len); 742 memset (pFwReq, 0, message_len); 743 pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1; 744 pFwReq->fwHeader.msgId = NAN_MSG_ID_TRANSMIT_FOLLOWUP_REQ; 745 pFwReq->fwHeader.msgLen = message_len; 746 pFwReq->fwHeader.handle = pReq->publish_subscribe_id; 747 pFwReq->fwHeader.transactionId = id; 748 749 pFwReq->transmitFollowupReqParams.matchHandle = pReq->requestor_instance_id; 750 if (pReq->priority != NAN_TX_PRIORITY_HIGH) { 751 pFwReq->transmitFollowupReqParams.priority = 1; 752 } else { 753 pFwReq->transmitFollowupReqParams.priority = 2; 754 } 755 pFwReq->transmitFollowupReqParams.window = pReq->dw_or_faw; 756 pFwReq->transmitFollowupReqParams.followupTxRspDisableFlag = 757 (pReq->recv_indication_cfg & BIT_0) ? 1 : 0; 758 pFwReq->transmitFollowupReqParams.reserved = 0; 759 760 u8* tlvs = pFwReq->ptlv; 761 762 /* Mac address needs to be added in TLV */ 763 tlvs = addTlv(NAN_TLV_TYPE_MAC_ADDRESS, sizeof(pReq->addr), 764 (const u8*)&pReq->addr[0], tlvs); 765 u16 tlv_type = NAN_TLV_TYPE_SERVICE_SPECIFIC_INFO; 766 767 if (pReq->service_specific_info_len) { 768 tlvs = addTlv(tlv_type, pReq->service_specific_info_len, 769 (const u8*)&pReq->service_specific_info[0], tlvs); 770 } 771 772 mVendorData = (char *)pFwReq; 773 mDataLen = message_len; 774 775 int ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen); 776 if (ret < 0) { 777 ALOGE("%s: put_bytes Error:%d",__func__, ret); 778 cleanup(); 779 return ret; 780 } 781 hexdump(mVendorData, mDataLen); 782 return ret; 783 } 784 785 int NanCommand::putNanStats(transaction_id id, const NanStatsRequest *pReq) 786 { 787 ALOGV("NAN_STATS"); 788 if (pReq == NULL) { 789 cleanup(); 790 return WIFI_ERROR_INVALID_ARGS; 791 } 792 size_t message_len = sizeof(NanStatsReqMsg); 793 794 pNanStatsReqMsg pFwReq = 795 (pNanStatsReqMsg)malloc(message_len); 796 if (pFwReq == NULL) { 797 cleanup(); 798 return WIFI_ERROR_OUT_OF_MEMORY; 799 } 800 801 ALOGV("Message Len %zu", message_len); 802 memset(pFwReq, 0, message_len); 803 pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1; 804 pFwReq->fwHeader.msgId = NAN_MSG_ID_STATS_REQ; 805 pFwReq->fwHeader.msgLen = message_len; 806 pFwReq->fwHeader.transactionId = id; 807 808 pFwReq->statsReqParams.statsType = pReq->stats_type; 809 pFwReq->statsReqParams.clear = pReq->clear; 810 pFwReq->statsReqParams.reserved = 0; 811 812 mVendorData = (char *)pFwReq; 813 mDataLen = message_len; 814 815 int ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen); 816 if (ret < 0) { 817 ALOGE("%s: put_bytes Error:%d",__func__, ret); 818 cleanup(); 819 return ret; 820 } 821 hexdump(mVendorData, mDataLen); 822 return ret; 823 } 824 825 int NanCommand::putNanTCA(transaction_id id, const NanTCARequest *pReq) 826 { 827 ALOGV("NAN_TCA"); 828 if (pReq == NULL) { 829 cleanup(); 830 return WIFI_ERROR_INVALID_ARGS; 831 } 832 size_t message_len = sizeof(NanTcaReqMsg); 833 834 message_len += (SIZEOF_TLV_HDR + 2 * sizeof(u32)); 835 pNanTcaReqMsg pFwReq = 836 (pNanTcaReqMsg)malloc(message_len); 837 if (pFwReq == NULL) { 838 cleanup(); 839 return WIFI_ERROR_OUT_OF_MEMORY; 840 } 841 842 ALOGV("Message Len %zu", message_len); 843 memset(pFwReq, 0, message_len); 844 pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1; 845 pFwReq->fwHeader.msgId = NAN_MSG_ID_TCA_REQ; 846 pFwReq->fwHeader.msgLen = message_len; 847 pFwReq->fwHeader.transactionId = id; 848 849 u32 tcaReqParams[2]; 850 memset (tcaReqParams, 0, sizeof(tcaReqParams)); 851 tcaReqParams[0] = (pReq->rising_direction_evt_flag & 0x01); 852 tcaReqParams[0] |= (pReq->falling_direction_evt_flag & 0x01) << 1; 853 tcaReqParams[0] |= (pReq->clear & 0x01) << 2; 854 tcaReqParams[1] = pReq->threshold; 855 856 u8* tlvs = pFwReq->ptlv; 857 858 if (pReq->tca_type == NAN_TCA_ID_CLUSTER_SIZE) { 859 tlvs = addTlv(NAN_TLV_TYPE_CLUSTER_SIZE_REQ, sizeof(tcaReqParams), 860 (const u8*)&tcaReqParams[0], tlvs); 861 } 862 else { 863 ALOGE("%s: Unrecognized tca_type:%u", __FUNCTION__, pReq->tca_type); 864 cleanup(); 865 return WIFI_ERROR_INVALID_ARGS; 866 } 867 868 mVendorData = (char *)pFwReq; 869 mDataLen = message_len; 870 871 int ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen); 872 if (ret < 0) { 873 ALOGE("%s: put_bytes Error:%d",__func__, ret); 874 cleanup(); 875 return ret; 876 } 877 hexdump(mVendorData, mDataLen); 878 return ret; 879 } 880 881 int NanCommand::putNanBeaconSdfPayload(transaction_id id, 882 const NanBeaconSdfPayloadRequest *pReq) 883 { 884 ALOGV("NAN_BEACON_SDF_PAYLAOD"); 885 if (pReq == NULL) { 886 cleanup(); 887 return WIFI_ERROR_INVALID_ARGS; 888 } 889 size_t message_len = sizeof(NanMsgHeader) + \ 890 SIZEOF_TLV_HDR + sizeof(u32) + \ 891 pReq->vsa.vsa_len; 892 893 pNanBeaconSdfPayloadReqMsg pFwReq = 894 (pNanBeaconSdfPayloadReqMsg)malloc(message_len); 895 if (pFwReq == NULL) { 896 cleanup(); 897 return WIFI_ERROR_OUT_OF_MEMORY; 898 } 899 900 ALOGV("Message Len %zu", message_len); 901 memset(pFwReq, 0, message_len); 902 pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1; 903 pFwReq->fwHeader.msgId = NAN_MSG_ID_BEACON_SDF_REQ; 904 pFwReq->fwHeader.msgLen = message_len; 905 pFwReq->fwHeader.transactionId = id; 906 907 /* Construct First 4 bytes of NanBeaconSdfPayloadReqMsg */ 908 u32 temp = 0; 909 temp = pReq->vsa.payload_transmit_flag & 0x01; 910 temp |= (pReq->vsa.tx_in_discovery_beacon & 0x01) << 1; 911 temp |= (pReq->vsa.tx_in_sync_beacon & 0x01) << 2; 912 temp |= (pReq->vsa.tx_in_service_discovery & 0x01) << 3; 913 temp |= (pReq->vsa.vendor_oui & 0x00FFFFFF) << 8; 914 915 int tlv_len = sizeof(u32) + pReq->vsa.vsa_len; 916 u8* tempBuf = (u8*)malloc(tlv_len); 917 if (tempBuf == NULL) { 918 ALOGE("%s: Malloc failed", __func__); 919 free(pFwReq); 920 cleanup(); 921 return WIFI_ERROR_OUT_OF_MEMORY; 922 } 923 memset(tempBuf, 0, tlv_len); 924 memcpy(tempBuf, &temp, sizeof(u32)); 925 memcpy((tempBuf + sizeof(u32)), pReq->vsa.vsa, pReq->vsa.vsa_len); 926 927 u8* tlvs = pFwReq->ptlv; 928 929 /* Write the TLVs to the message. */ 930 tlvs = addTlv(NAN_TLV_TYPE_VENDOR_SPECIFIC_ATTRIBUTE_TRANSMIT, tlv_len, 931 (const u8*)tempBuf, tlvs); 932 free(tempBuf); 933 934 mVendorData = (char *)pFwReq; 935 mDataLen = message_len; 936 937 int ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen); 938 if (ret < 0) { 939 ALOGE("%s: put_bytes Error:%d",__func__, ret); 940 cleanup(); 941 return ret; 942 } 943 hexdump(mVendorData, mDataLen); 944 return ret; 945 } 946 947 //callback handlers registered for nl message send 948 static int error_handler_nan(struct sockaddr_nl *nla, struct nlmsgerr *err, 949 void *arg) 950 { 951 struct sockaddr_nl * tmp; 952 int *ret = (int *)arg; 953 tmp = nla; 954 *ret = err->error; 955 ALOGE("%s: Error code:%d (%s)", __func__, *ret, strerror(-(*ret))); 956 return NL_STOP; 957 } 958 959 //callback handlers registered for nl message send 960 static int ack_handler_nan(struct nl_msg *msg, void *arg) 961 { 962 int *ret = (int *)arg; 963 struct nl_msg * a; 964 965 ALOGE("%s: called", __func__); 966 a = msg; 967 *ret = 0; 968 return NL_STOP; 969 } 970 971 //callback handlers registered for nl message send 972 static int finish_handler_nan(struct nl_msg *msg, void *arg) 973 { 974 int *ret = (int *)arg; 975 struct nl_msg * a; 976 977 ALOGE("%s: called", __func__); 978 a = msg; 979 *ret = 0; 980 return NL_SKIP; 981 } 982 983 984 //Override base class requestEvent and implement little differently here 985 //This will send the request message 986 //We dont wait for any response back in case of Nan as it is asynchronous 987 //thus no wait for condition. 988 int NanCommand::requestEvent() 989 { 990 int res; 991 struct nl_cb * cb; 992 993 cb = nl_cb_alloc(NL_CB_DEFAULT); 994 if (!cb) { 995 ALOGE("%s: Callback allocation failed",__func__); 996 res = -1; 997 goto out; 998 } 999 1000 /* send message */ 1001 ALOGV("%s:Handle:%p Socket Value:%p", __func__, mInfo, mInfo->cmd_sock); 1002 res = nl_send_auto_complete(mInfo->cmd_sock, mMsg.getMessage()); 1003 if (res < 0) 1004 goto out; 1005 res = 1; 1006 1007 nl_cb_err(cb, NL_CB_CUSTOM, error_handler_nan, &res); 1008 nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler_nan, &res); 1009 nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler_nan, &res); 1010 1011 // err is populated as part of finish_handler 1012 while (res > 0) 1013 nl_recvmsgs(mInfo->cmd_sock, cb); 1014 1015 out: 1016 //free the VendorData 1017 if (mVendorData) { 1018 free(mVendorData); 1019 } 1020 mVendorData = NULL; 1021 //cleanup the mMsg 1022 mMsg.destroy(); 1023 return res; 1024 } 1025 1026 int NanCommand::calcNanTransmitPostDiscoverySize( 1027 const NanTransmitPostDiscovery *pPostDiscovery) 1028 { 1029 /* Fixed size of u32 for Conn Type, Device Role and R flag + Dur + Rsvd*/ 1030 int ret = sizeof(u32); 1031 /* size of availability interval bit map is 4 bytes */ 1032 ret += sizeof(u32); 1033 /* size of mac address is 6 bytes*/ 1034 ret += (SIZEOF_TLV_HDR + NAN_MAC_ADDR_LEN); 1035 if (pPostDiscovery && 1036 pPostDiscovery->type == NAN_CONN_WLAN_MESH) { 1037 /* size of WLAN_MESH_ID */ 1038 ret += (SIZEOF_TLV_HDR + \ 1039 pPostDiscovery->mesh_id_len); 1040 } 1041 if (pPostDiscovery && 1042 pPostDiscovery->type == NAN_CONN_WLAN_INFRA) { 1043 /* size of Infrastructure ssid */ 1044 ret += (SIZEOF_TLV_HDR + \ 1045 pPostDiscovery->infrastructure_ssid_len); 1046 } 1047 ALOGV("%s:size:%d", __func__, ret); 1048 return ret; 1049 } 1050 1051 void NanCommand::fillNanSocialChannelParamVal( 1052 const NanSocialChannelScanParams *pScanParams, 1053 u32* pChannelParamArr) 1054 { 1055 int i; 1056 if (pChannelParamArr) { 1057 memset(pChannelParamArr, 0, 1058 NAN_MAX_SOCIAL_CHANNELS * sizeof(u32)); 1059 for (i= 0; i < NAN_MAX_SOCIAL_CHANNELS; i++) { 1060 pChannelParamArr[i] = pScanParams->scan_period[i] << 16; 1061 pChannelParamArr[i] |= pScanParams->dwell_time[i] << 8; 1062 } 1063 pChannelParamArr[NAN_CHANNEL_24G_BAND] |= 6; 1064 pChannelParamArr[NAN_CHANNEL_5G_BAND_LOW]|= 44; 1065 pChannelParamArr[NAN_CHANNEL_5G_BAND_HIGH]|= 149; 1066 ALOGV("%s: Filled SocialChannelParamVal", __func__); 1067 hexdump((char*)pChannelParamArr, NAN_MAX_SOCIAL_CHANNELS * sizeof(u32)); 1068 } 1069 return; 1070 } 1071 1072 u32 NanCommand::getNanTransmitPostConnectivityCapabilityVal( 1073 const NanTransmitPostConnectivityCapability *pCapab) 1074 { 1075 u32 ret = 0; 1076 ret |= (pCapab->payload_transmit_flag? 1:0) << 16; 1077 ret |= (pCapab->is_mesh_supported? 1:0) << 5; 1078 ret |= (pCapab->is_ibss_supported? 1:0) << 4; 1079 ret |= (pCapab->wlan_infra_field? 1:0) << 3; 1080 ret |= (pCapab->is_tdls_supported? 1:0) << 2; 1081 ret |= (pCapab->is_wfds_supported? 1:0) << 1; 1082 ret |= (pCapab->is_wfd_supported? 1:0); 1083 ALOGV("%s: val:%d", __func__, ret); 1084 return ret; 1085 } 1086 1087 void NanCommand::fillNanTransmitPostDiscoveryVal( 1088 const NanTransmitPostDiscovery *pTxDisc, 1089 u8 *pOutValue) 1090 { 1091 1092 if (pTxDisc && pOutValue) { 1093 u8 *tlvs = &pOutValue[8]; 1094 pOutValue[0] = pTxDisc->type; 1095 pOutValue[1] = pTxDisc->role; 1096 pOutValue[2] = (pTxDisc->transmit_freq? 1:0); 1097 pOutValue[2] |= ((pTxDisc->duration & 0x03) << 1); 1098 memcpy(&pOutValue[4], &pTxDisc->avail_interval_bitmap, 1099 sizeof(pTxDisc->avail_interval_bitmap)); 1100 tlvs = addTlv(NAN_TLV_TYPE_MAC_ADDRESS, 1101 NAN_MAC_ADDR_LEN, 1102 (const u8*)&pTxDisc->addr[0], 1103 tlvs); 1104 if (pTxDisc->type == NAN_CONN_WLAN_MESH) { 1105 tlvs = addTlv(NAN_TLV_TYPE_WLAN_MESH_ID, 1106 pTxDisc->mesh_id_len, 1107 (const u8*)&pTxDisc->mesh_id[0], 1108 tlvs); 1109 } 1110 if (pTxDisc->type == NAN_CONN_WLAN_INFRA) { 1111 tlvs = addTlv(NAN_TLV_TYPE_WLAN_INFRA_SSID, 1112 pTxDisc->infrastructure_ssid_len, 1113 (const u8*)&pTxDisc->infrastructure_ssid_val[0], 1114 tlvs); 1115 } 1116 ALOGV("%s: Filled TransmitPostDiscoveryVal", __func__); 1117 hexdump((char*)pOutValue, calcNanTransmitPostDiscoverySize(pTxDisc)); 1118 } 1119 1120 return; 1121 } 1122 1123 void NanCommand::fillNanFurtherAvailabilityMapVal( 1124 const NanFurtherAvailabilityMap *pFam, 1125 u8 *pOutValue) 1126 { 1127 int idx = 0; 1128 1129 if (pFam && pOutValue) { 1130 u32 famsize = calcNanFurtherAvailabilityMapSize(pFam); 1131 pNanFurtherAvailabilityMapAttrTlv pFwReq = \ 1132 (pNanFurtherAvailabilityMapAttrTlv)pOutValue; 1133 1134 memset(pOutValue, 0, famsize); 1135 pFwReq->numChan = pFam->numchans; 1136 for (idx = 0; idx < pFam->numchans; idx++) { 1137 const NanFurtherAvailabilityChannel *pFamChan = \ 1138 &pFam->famchan[idx]; 1139 pNanFurtherAvailabilityChan pFwFamChan = \ 1140 (pNanFurtherAvailabilityChan)((u8*)&pFwReq->pFaChan[0] + \ 1141 (idx * sizeof(NanFurtherAvailabilityChan))); 1142 1143 pFwFamChan->entryCtrl.availIntDuration = \ 1144 pFamChan->entry_control; 1145 pFwFamChan->entryCtrl.mapId = \ 1146 pFamChan->mapid; 1147 pFwFamChan->opClass = pFamChan->class_val; 1148 pFwFamChan->channel = pFamChan->channel; 1149 memcpy(&pFwFamChan->availIntBitmap, 1150 &pFamChan->avail_interval_bitmap, 1151 sizeof(pFwFamChan->availIntBitmap)); 1152 } 1153 ALOGV("%s: Filled FurtherAvailabilityMapVal", __func__); 1154 hexdump((char*)pOutValue, famsize); 1155 } 1156 return; 1157 } 1158 1159 int NanCommand::calcNanFurtherAvailabilityMapSize( 1160 const NanFurtherAvailabilityMap *pFam) 1161 { 1162 int ret = 0; 1163 if (pFam && pFam->numchans && 1164 pFam->numchans <= NAN_MAX_FAM_CHANNELS) { 1165 /* Fixed size of u8 for numchans*/ 1166 ret = sizeof(u8); 1167 /* numchans * sizeof(FamChannels) */ 1168 ret += (pFam->numchans * sizeof(NanFurtherAvailabilityChan)); 1169 } 1170 ALOGV("%s:size:%d", __func__, ret); 1171 return ret; 1172 } 1173 1174 int NanCommand::putNanCapabilities(transaction_id id) 1175 { 1176 size_t message_len = sizeof(NanCapabilitiesReqMsg); 1177 1178 pNanCapabilitiesReqMsg pFwReq = (pNanCapabilitiesReqMsg)malloc(message_len); 1179 if (pFwReq == NULL) { 1180 cleanup(); 1181 return WIFI_ERROR_OUT_OF_MEMORY; 1182 } 1183 1184 memset (pFwReq, 0, message_len); 1185 pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1; 1186 pFwReq->fwHeader.msgId = NAN_MSG_ID_CAPABILITIES_REQ; 1187 pFwReq->fwHeader.msgLen = message_len; 1188 pFwReq->fwHeader.transactionId = id; 1189 1190 mVendorData = (char*)pFwReq; 1191 mDataLen = message_len; 1192 1193 int ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen); 1194 if (ret < 0) { 1195 ALOGE("%s: put_bytes Error:%d",__func__, ret); 1196 cleanup(); 1197 return ret; 1198 } 1199 hexdump(mVendorData, mDataLen); 1200 return ret; 1201 } 1202