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 "nan.h" 20 #include "wifi_hal.h" 21 #include "nan_i.h" 22 #include "nancommand.h" 23 24 int NanCommand::putNanEnable(const NanEnableRequest *pReq) 25 { 26 ALOGI("NAN_ENABLE"); 27 size_t message_len = NAN_MAX_ENABLE_REQ_SIZE; 28 29 if (pReq == NULL) { 30 return WIFI_ERROR_INVALID_ARGS; 31 } 32 33 #ifdef NAN_2_0 34 /* Removing the unsupported ones */ 35 message_len -= \ 36 (SIZEOF_TLV_HDR + sizeof(u8) /* Random Time */ + \ 37 SIZEOF_TLV_HDR + sizeof(u8) /* Full Scan Int */); 38 39 message_len += \ 40 ( 41 pReq->config_2dot4g_support ? (SIZEOF_TLV_HDR + \ 42 sizeof(pReq->support_2dot4g_val)) : 0 \ 43 ) + \ 44 ( 45 pReq->config_2dot4g_beacons ? (SIZEOF_TLV_HDR + \ 46 sizeof(pReq->beacon_2dot4g_val)) : 0 \ 47 ) + \ 48 ( 49 pReq->config_2dot4g_discovery ? (SIZEOF_TLV_HDR + \ 50 sizeof(pReq->discovery_2dot4g_val)) : 0 \ 51 ) + \ 52 ( 53 pReq->config_5g_beacons ? (SIZEOF_TLV_HDR + \ 54 sizeof(pReq->beacon_5g_val)) : 0 \ 55 ) + \ 56 ( 57 pReq->config_5g_discovery ? (SIZEOF_TLV_HDR + \ 58 sizeof(pReq->discovery_5g_val)) : 0 \ 59 ) + \ 60 ( 61 pReq->config_5g_rssi_close ? (SIZEOF_TLV_HDR + \ 62 sizeof(pReq->rssi_close_5g_val)) : 0 \ 63 ) + \ 64 ( 65 pReq->config_5g_rssi_middle ? (SIZEOF_TLV_HDR + \ 66 sizeof(pReq->rssi_middle_5g_val)) : 0 \ 67 ) + \ 68 ( 69 pReq->config_5g_rssi_close_proximity ? (SIZEOF_TLV_HDR + \ 70 sizeof(pReq->rssi_close_proximity_5g_val)) : 0 \ 71 ) + \ 72 ( 73 pReq->config_rssi_window_size ? (SIZEOF_TLV_HDR + \ 74 sizeof(pReq->rssi_window_size_val)) : 0 \ 75 ) + \ 76 ( 77 pReq->config_oui ? (SIZEOF_TLV_HDR + \ 78 sizeof(pReq->oui_val)) : 0 \ 79 ) + \ 80 ( 81 pReq->config_intf_addr ? (SIZEOF_TLV_HDR + \ 82 sizeof(pReq->intf_addr_val)) : 0 \ 83 ) + \ 84 ( 85 pReq->config_cluster_attribute_val ? (SIZEOF_TLV_HDR + \ 86 sizeof(pReq->config_cluster_attribute_val)) : 0 \ 87 ) + \ 88 ( 89 pReq->config_scan_params ? (SIZEOF_TLV_HDR + \ 90 NAN_MAX_SOCIAL_CHANNEL * sizeof(u32)) : 0 \ 91 ) + \ 92 ( 93 pReq->config_debug_flags ? (SIZEOF_TLV_HDR + \ 94 sizeof(u64)) : 0 \ 95 ) + \ 96 ( 97 pReq->config_random_factor_force ? (SIZEOF_TLV_HDR + \ 98 sizeof(pReq->random_factor_force_val)) : 0 \ 99 ) + \ 100 ( 101 pReq->config_hop_count_force ? (SIZEOF_TLV_HDR + \ 102 sizeof(pReq->hop_count_force_val)) : 0 \ 103 ); 104 #endif /* NAN_2_0 */ 105 106 pNanEnableReqMsg pFwReq = (pNanEnableReqMsg)malloc(message_len); 107 if (pFwReq == NULL) { 108 return WIFI_ERROR_OUT_OF_MEMORY; 109 } 110 111 ALOGI("Message Len %d", message_len); 112 memset (pFwReq, 0, message_len); 113 pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1; 114 pFwReq->fwHeader.msgId = NAN_MSG_ID_ENABLE_REQ; 115 pFwReq->fwHeader.msgLen = message_len; 116 pFwReq->fwHeader.handle = pReq->header.handle; 117 pFwReq->fwHeader.transactionId = pReq->header.transaction_id; 118 119 u8* tlvs = pFwReq->ptlv; 120 121 /* Write the TLVs to the message. */ 122 tlvs = addTlv(NAN_TLV_TYPE_5G_SUPPORT, sizeof(pReq->support_5g), 123 (const u8*)&pReq->support_5g, tlvs); 124 tlvs = addTlv(NAN_TLV_TYPE_CLUSTER_ID_LOW, sizeof(pReq->cluster_low), 125 (const u8*)&pReq->cluster_low, tlvs); 126 tlvs = addTlv(NAN_TLV_TYPE_CLUSTER_ID_HIGH, sizeof(pReq->cluster_high), 127 (const u8*)&pReq->cluster_high, tlvs); 128 tlvs = addTlv(NAN_TLV_TYPE_SID_BEACON, sizeof(pReq->sid_beacon), 129 (const u8*)&pReq->sid_beacon, tlvs); 130 tlvs = addTlv(NAN_TLV_TYPE_RSSI_CLOSE, sizeof(pReq->rssi_close), 131 (const u8*)&pReq->rssi_close, tlvs); 132 tlvs = addTlv(NAN_TLV_TYPE_RSSI_MEDIUM, sizeof(pReq->rssi_middle), 133 (const u8*)&pReq->rssi_middle, tlvs); 134 tlvs = addTlv(NAN_TLV_TYPE_HOP_COUNT_LIMIT, sizeof(pReq->hop_count_limit), 135 (const u8*)&pReq->hop_count_limit, tlvs); 136 #ifndef NAN_2_0 137 tlvs = addTlv(NAN_TLV_TYPE_RANDOM_UPDATE_TIME, sizeof(pReq->random_time), 138 (const u8*)&pReq->random_time, tlvs); 139 #endif /* NAN_2_0 */ 140 tlvs = addTlv(NAN_TLV_TYPE_MASTER_PREFERENCE, sizeof(pReq->master_pref), 141 (const u8*)&pReq->master_pref, tlvs); 142 #ifndef NAN_2_0 143 tlvs = addTlv(NAN_TLV_TYPE_PERIODIC_SCAN_INTERVAL, sizeof(pReq->periodic_scan_interval), 144 (const u8*)&pReq->periodic_scan_interval, tlvs); 145 #endif /* NAN_2_0 */ 146 147 #ifdef NAN_2_0 148 if (pReq->config_2dot4g_support) { 149 tlvs = addTlv(NAN_TLV_TYPE_2DOT4G_SUPPORT, sizeof(pReq->support_2dot4g_val), 150 (const u8*)&pReq->support_2dot4g_val, tlvs); 151 } 152 if (pReq->config_2dot4g_beacons) { 153 tlvs = addTlv(NAN_TLV_TYPE_2DOT4G_BEACONS, sizeof(pReq->beacon_2dot4g_val), 154 (const u8*)&pReq->beacon_2dot4g_val, tlvs); 155 } 156 if (pReq->config_2dot4g_discovery) { 157 tlvs = addTlv(NAN_TLV_TYPE_2DOT4G_SDF, sizeof(pReq->discovery_2dot4g_val), 158 (const u8*)&pReq->discovery_2dot4g_val, tlvs); 159 } 160 if (pReq->config_5g_beacons) { 161 tlvs = addTlv(NAN_TLV_TYPE_5G_BEACON, sizeof(pReq->beacon_5g_val), 162 (const u8*)&pReq->beacon_5g_val, tlvs); 163 } 164 if (pReq->config_5g_discovery) { 165 tlvs = addTlv(NAN_TLV_TYPE_5G_SDF, sizeof(pReq->discovery_5g_val), 166 (const u8*)&pReq->discovery_5g_val, tlvs); 167 } 168 /* Add the support of sending 5G RSSI values */ 169 if (pReq->config_5g_rssi_close) { 170 tlvs = addTlv(NAN_TLV_TYPE_5G_RSSI_CLOSE, sizeof(pReq->rssi_close_5g_val), 171 (const u8*)&pReq->rssi_close_5g_val, tlvs); 172 } 173 if (pReq->config_5g_rssi_middle) { 174 tlvs = addTlv(NAN_TLV_TYPE_5G_RSSI_MEDIUM, sizeof(pReq->rssi_middle_5g_val), 175 (const u8*)&pReq->rssi_middle_5g_val, tlvs); 176 } 177 if (pReq->config_5g_rssi_close_proximity) { 178 tlvs = addTlv(NAN_TLV_TYPE_5G_RSSI_CLOSE_PROXIMITY, 179 sizeof(pReq->rssi_close_proximity_5g_val), 180 (const u8*)&pReq->rssi_close_proximity_5g_val, tlvs); 181 } 182 if (pReq->config_rssi_window_size) { 183 tlvs = addTlv(NAN_TLV_TYPE_RSSI_AVERAGING_WINDOW_SIZE, sizeof(pReq->rssi_window_size_val), 184 (const u8*)&pReq->rssi_window_size_val, tlvs); 185 } 186 if (pReq->config_oui) { 187 tlvs = addTlv(NAN_TLV_TYPE_CLUSTER_OUI_NETWORK_ID, sizeof(pReq->oui_val), 188 (const u8*)&pReq->oui_val, tlvs); 189 } 190 if (pReq->config_intf_addr) { 191 tlvs = addTlv(NAN_TLV_TYPE_SOURCE_MAC_ADDRESS, sizeof(pReq->intf_addr_val), 192 (const u8*)&pReq->intf_addr_val[0], tlvs); 193 } 194 if (pReq->config_cluster_attribute_val) { 195 tlvs = addTlv(NAN_TLV_TYPE_CLUSTER_ATTRIBUTE_IN_SDF, sizeof(pReq->config_cluster_attribute_val), 196 (const u8*)&pReq->config_cluster_attribute_val, tlvs); 197 } 198 if (pReq->config_scan_params) { 199 u32 socialChannelParamVal[NAN_MAX_SOCIAL_CHANNEL]; 200 /* Fill the social channel param */ 201 fillNanSocialChannelParamVal(&pReq->scan_params_val, 202 socialChannelParamVal); 203 int i; 204 for (i = 0; i < NAN_MAX_SOCIAL_CHANNEL; i++) { 205 tlvs = addTlv(NAN_TLV_TYPE_SOCIAL_CHANNEL_SCAN_PARAMETERS, 206 sizeof(socialChannelParamVal[i]), 207 (const u8*)&socialChannelParamVal[i], tlvs); 208 } 209 } 210 if (pReq->config_debug_flags) { 211 tlvs = addTlv(NAN_TLV_TYPE_DEBUGGING_FLAGS, 212 sizeof(pReq->debug_flags_val), 213 (const u8*)&pReq->debug_flags_val, tlvs); 214 } 215 if (pReq->config_random_factor_force) { 216 tlvs = addTlv(NAN_TLV_TYPE_RANDOM_FACTOR_FORCE, 217 sizeof(pReq->random_factor_force_val), 218 (const u8*)&pReq->random_factor_force_val, tlvs); 219 } 220 if (pReq->config_hop_count_force) { 221 tlvs = addTlv(NAN_TLV_TYPE_HOP_COUNT_FORCE, 222 sizeof(pReq->hop_count_force_val), 223 (const u8*)&pReq->hop_count_force_val, tlvs); 224 } 225 #endif /* NAN_2_0 */ 226 227 mVendorData = (char*)pFwReq; 228 mDataLen = message_len; 229 230 return WIFI_SUCCESS; 231 } 232 233 int NanCommand::putNanDisable(const NanDisableRequest *pReq) 234 { 235 ALOGI("NAN_DISABLE"); 236 size_t message_len = sizeof(NanDisableReqMsg); 237 238 if (pReq == NULL) { 239 return WIFI_ERROR_INVALID_ARGS; 240 } 241 242 pNanDisableReqMsg pFwReq = (pNanDisableReqMsg)malloc(message_len); 243 if (pFwReq == NULL) { 244 return WIFI_ERROR_OUT_OF_MEMORY; 245 } 246 247 ALOGI("Message Len %d", message_len); 248 memset (pFwReq, 0, message_len); 249 pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1; 250 pFwReq->fwHeader.msgId = NAN_MSG_ID_DISABLE_REQ; 251 pFwReq->fwHeader.msgLen = message_len; 252 pFwReq->fwHeader.handle = pReq->header.handle; 253 pFwReq->fwHeader.transactionId = pReq->header.transaction_id; 254 255 mVendorData = (char*)pFwReq; 256 mDataLen = message_len; 257 258 return WIFI_SUCCESS; 259 } 260 261 int NanCommand::putNanConfig(const NanConfigRequest *pReq) 262 { 263 ALOGI("NAN_CONFIG"); 264 size_t message_len = NAN_MAX_CONFIGURATION_REQ_SIZE; 265 266 if (pReq == NULL) { 267 return WIFI_ERROR_INVALID_ARGS; 268 } 269 270 #ifndef NAN_2_0 271 // Add additional message size for transmitting 272 // further availability attribute if 273 // additional_disc_window_slots is Non-zero value. 274 if (pReq->additional_disc_window_slots != 0) { 275 message_len += (SIZEOF_TLV_HDR + \ 276 sizeof(pReq->additional_disc_window_slots)); 277 } 278 #endif /* NAN_2_0 */ 279 280 #ifdef NAN_2_0 281 message_len = sizeof(NanMsgHeader); 282 283 message_len += \ 284 ( 285 pReq->config_sid_beacon ? (SIZEOF_TLV_HDR + \ 286 sizeof(pReq->sid_beacon)) : 0 \ 287 ) + \ 288 ( 289 pReq->config_master_pref ? (SIZEOF_TLV_HDR + \ 290 sizeof(pReq->master_pref)) : 0 \ 291 ) + \ 292 ( 293 pReq->config_5g_rssi_close_proximity ? (SIZEOF_TLV_HDR + \ 294 sizeof(pReq->rssi_close_proximity_5g_val)) : 0 \ 295 ) + \ 296 ( 297 pReq->config_rssi_window_size ? (SIZEOF_TLV_HDR + \ 298 sizeof(pReq->rssi_window_size_val)) : 0 \ 299 ) + \ 300 ( 301 pReq->config_cluster_attribute_val ? (SIZEOF_TLV_HDR + \ 302 sizeof(pReq->config_cluster_attribute_val)) : 0 \ 303 ) + \ 304 ( 305 pReq->config_scan_params ? (SIZEOF_TLV_HDR + \ 306 NAN_MAX_SOCIAL_CHANNEL * sizeof(u32)) : 0 \ 307 ) + \ 308 ( 309 pReq->config_debug_flags ? (SIZEOF_TLV_HDR + \ 310 sizeof(u64)) : 0 \ 311 ) + \ 312 ( 313 pReq->config_random_factor_force ? (SIZEOF_TLV_HDR + \ 314 sizeof(pReq->random_factor_force_val)) : 0 \ 315 ) + \ 316 ( 317 pReq->config_hop_count_force ? (SIZEOF_TLV_HDR + \ 318 sizeof(pReq->hop_count_force_val)) : 0 \ 319 ) + \ 320 ( 321 pReq->config_conn_capability ? (SIZEOF_TLV_HDR + \ 322 sizeof(u32)) : 0 \ 323 ) + \ 324 ( 325 pReq->config_discovery_attr ? (SIZEOF_TLV_HDR + \ 326 calcNanTransmitPostDiscoverySize(&pReq->discovery_attr_val)) : 0 \ 327 ); 328 329 if (pReq->config_fam && \ 330 calcNanFurtherAvailabilityMapSize(&pReq->fam_val)) { 331 message_len += (SIZEOF_TLV_HDR + \ 332 calcNanFurtherAvailabilityMapSize(&pReq->fam_val)); 333 } 334 #endif /* NAN_2_0 */ 335 336 pNanConfigurationReqMsg pFwReq = (pNanConfigurationReqMsg)malloc(message_len); 337 if (pFwReq == NULL) { 338 return WIFI_ERROR_OUT_OF_MEMORY; 339 } 340 341 ALOGI("Message Len %d", message_len); 342 memset (pFwReq, 0, message_len); 343 pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1; 344 pFwReq->fwHeader.msgId = NAN_MSG_ID_CONFIGURATION_REQ; 345 pFwReq->fwHeader.msgLen = message_len; 346 pFwReq->fwHeader.handle = pReq->header.handle; 347 pFwReq->fwHeader.transactionId = pReq->header.transaction_id; 348 349 u8* tlvs = pFwReq->ptlv; 350 if (pReq->config_sid_beacon) { 351 tlvs = addTlv(NAN_TLV_TYPE_SID_BEACON, sizeof(pReq->sid_beacon), 352 (const u8*)&pReq->sid_beacon, tlvs); 353 } 354 #ifndef NAN_2_0 355 tlvs = addTlv(NAN_TLV_TYPE_RANDOM_UPDATE_TIME, sizeof(pReq->random_time), 356 (const u8*)&pReq->random_time, tlvs); 357 #endif /* NAN_2_0 */ 358 if (pReq->config_master_pref) { 359 tlvs = addTlv(NAN_TLV_TYPE_MASTER_PREFERENCE, sizeof(pReq->master_pref), 360 (const u8*)&pReq->master_pref, tlvs); 361 } 362 #ifndef NAN_2_0 363 tlvs = addTlv(NAN_TLV_TYPE_PERIODIC_SCAN_INTERVAL, sizeof(pReq->periodic_scan_interval), 364 (const u8*)&pReq->periodic_scan_interval, tlvs); 365 #endif /* NAN_2_0 */ 366 367 /* In 2.0 Version of NAN this parameter does not have any significance */ 368 #ifndef NAN_2_0 369 if (pReq->additional_disc_window_slots != 0) { 370 /* 371 Construct the value in this manner 372 Bit0 ==> 1/0 Enable/Disable FAW 373 Bit1-2 ==> reserved 374 Bit3-7 ==> FAW Slot Value. 375 */ 376 u8 faw_value = 0x01; /* Enable the first bit */ 377 /* Shifting the disc_window_slots by 3 and masking it with 0xf8 378 so that the Bit 3 to 7 are updated 379 */ 380 faw_value |= ((pReq->additional_disc_window_slots << 3) & (0xf8)); 381 tlvs = addTlv(NAN_TLV_TYPE_FURTHER_AVAILABILITY, 382 sizeof(faw_value), 383 (const u8*)&faw_value, tlvs); 384 } 385 #endif /* NAN_2_0 */ 386 387 #ifdef NAN_2_0 388 if (pReq->config_rssi_window_size) { 389 tlvs = addTlv(NAN_TLV_TYPE_RSSI_AVERAGING_WINDOW_SIZE, sizeof(pReq->rssi_window_size_val), 390 (const u8*)&pReq->rssi_window_size_val, tlvs); 391 } 392 if (pReq->config_scan_params) { 393 u32 socialChannelParamVal[NAN_MAX_SOCIAL_CHANNEL]; 394 /* Fill the social channel param */ 395 fillNanSocialChannelParamVal(&pReq->scan_params_val, 396 socialChannelParamVal); 397 int i; 398 for (i = 0; i < NAN_MAX_SOCIAL_CHANNEL; i++) { 399 tlvs = addTlv(NAN_TLV_TYPE_SOCIAL_CHANNEL_SCAN_PARAMETERS, 400 sizeof(socialChannelParamVal[i]), 401 (const u8*)&socialChannelParamVal[i], tlvs); 402 } 403 } 404 if (pReq->config_debug_flags) { 405 tlvs = addTlv(NAN_TLV_TYPE_DEBUGGING_FLAGS, 406 sizeof(pReq->debug_flags_val), 407 (const u8*)&pReq->debug_flags_val, tlvs); 408 } 409 if (pReq->config_random_factor_force) { 410 tlvs = addTlv(NAN_TLV_TYPE_RANDOM_FACTOR_FORCE, 411 sizeof(pReq->random_factor_force_val), 412 (const u8*)&pReq->random_factor_force_val, tlvs); 413 } 414 if (pReq->config_hop_count_force) { 415 tlvs = addTlv(NAN_TLV_TYPE_HOP_COUNT_FORCE, 416 sizeof(pReq->hop_count_force_val), 417 (const u8*)&pReq->hop_count_force_val, tlvs); 418 } 419 if (pReq->config_conn_capability) { 420 u32 val = \ 421 getNanTransmitPostConnectivityCapabilityVal(&pReq->conn_capability_val); 422 tlvs = addTlv(NAN_TLV_TYPE_POST_NAN_CONNECTIVITY_CAPABILITIES_TRANSMIT, 423 sizeof(val), (const u8*)&val, tlvs); 424 } 425 if (pReq->config_discovery_attr) { 426 fillNanTransmitPostDiscoveryVal(&pReq->discovery_attr_val, 427 (u8*)(tlvs + SIZEOF_TLV_HDR)); 428 tlvs = addTlv(NAN_TLV_TYPE_POST_NAN_DISCOVERY_ATTRIBUTE_TRANSMIT, 429 calcNanTransmitPostDiscoverySize(&pReq->discovery_attr_val), 430 (const u8*)(tlvs + SIZEOF_TLV_HDR), tlvs); 431 } 432 if (pReq->config_fam && \ 433 calcNanFurtherAvailabilityMapSize(&pReq->fam_val)) { 434 fillNanFurtherAvailabilityMapVal(&pReq->fam_val, 435 (u8*)(tlvs + SIZEOF_TLV_HDR)); 436 tlvs = addTlv(NAN_TLV_TYPE_FURTHER_AVAILABILITY_MAP, 437 calcNanFurtherAvailabilityMapSize(&pReq->fam_val), 438 (const u8*)(tlvs + SIZEOF_TLV_HDR), tlvs); 439 } 440 #endif /* NAN_2_0 */ 441 442 mVendorData = (char*)pFwReq; 443 mDataLen = message_len; 444 445 return WIFI_SUCCESS; 446 } 447 448 449 int NanCommand::putNanPublish(const NanPublishRequest *pReq) 450 { 451 ALOGI("NAN_PUBLISH"); 452 if (pReq == NULL) { 453 return WIFI_ERROR_INVALID_ARGS; 454 } 455 456 size_t message_len = 457 sizeof(NanMsgHeader) + sizeof(NanPublishServiceReqParams) + 458 (pReq->service_name_len ? SIZEOF_TLV_HDR + pReq->service_name_len : 0) + 459 (pReq->service_specific_info_len ? SIZEOF_TLV_HDR + pReq->service_specific_info_len : 0) + 460 (pReq->rx_match_filter_len ? SIZEOF_TLV_HDR + pReq->rx_match_filter_len : 0) + 461 (pReq->tx_match_filter_len ? SIZEOF_TLV_HDR + pReq->tx_match_filter_len : 0); 462 463 pNanPublishServiceReqMsg pFwReq = (pNanPublishServiceReqMsg)malloc(message_len); 464 if (pFwReq == NULL) { 465 return WIFI_ERROR_OUT_OF_MEMORY; 466 } 467 468 ALOGI("Message Len %d", message_len); 469 memset(pFwReq, 0, message_len); 470 pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1; 471 pFwReq->fwHeader.msgId = NAN_MSG_ID_PUBLISH_SERVICE_REQ; 472 pFwReq->fwHeader.msgLen = message_len; 473 pFwReq->fwHeader.handle = pReq->header.handle; 474 pFwReq->fwHeader.transactionId = pReq->header.transaction_id; 475 476 pFwReq->publishServiceReqParams.ttl = pReq->ttl; 477 pFwReq->publishServiceReqParams.period = pReq->period; 478 pFwReq->publishServiceReqParams.replyIndFlag = pReq->replied_event_flag; 479 pFwReq->publishServiceReqParams.publishType = pReq->publish_type; 480 pFwReq->publishServiceReqParams.txType = pReq->tx_type; 481 #ifdef NAN_2_0 482 /* Overwriting replyIndFlag to 0 based on v17 Nan Spec */ 483 pFwReq->publishServiceReqParams.replyIndFlag = 0; 484 pFwReq->publishServiceReqParams.rssiThresholdFlag = pReq->rssi_threshold_flag; 485 pFwReq->publishServiceReqParams.ota_flag = pReq->ota_flag; 486 pFwReq->publishServiceReqParams.matchAlg = pReq->publish_match; 487 #endif /* NAN_2_0 */ 488 pFwReq->publishServiceReqParams.count = pReq->publish_count; 489 #ifdef NAN_2_0 490 pFwReq->publishServiceReqParams.connmap = pReq->connmap; 491 #endif /* NAN_2_0 */ 492 pFwReq->publishServiceReqParams.reserved2 = 0; 493 494 u8* tlvs = pFwReq->ptlv; 495 if (pReq->service_name_len) { 496 tlvs = addTlv(NAN_TLV_TYPE_SERVICE_NAME, pReq->service_name_len, 497 (const u8*)&pReq->service_name[0], tlvs); 498 } 499 if (pReq->service_specific_info_len) { 500 tlvs = addTlv(NAN_TLV_TYPE_SERVICE_SPECIFIC_INFO, pReq->service_specific_info_len, 501 (const u8*)&pReq->service_specific_info[0], tlvs); 502 } 503 if (pReq->rx_match_filter_len) { 504 tlvs = addTlv(NAN_TLV_TYPE_RX_MATCH_FILTER, pReq->rx_match_filter_len, 505 (const u8*)&pReq->rx_match_filter[0], tlvs); 506 } 507 if (pReq->tx_match_filter_len) { 508 tlvs = addTlv(NAN_TLV_TYPE_TX_MATCH_FILTER, pReq->tx_match_filter_len, 509 (const u8*)&pReq->tx_match_filter[0], tlvs); 510 } 511 512 mVendorData = (char *)pFwReq; 513 mDataLen = message_len; 514 515 return WIFI_SUCCESS; 516 } 517 518 int NanCommand::putNanPublishCancel(const NanPublishCancelRequest *pReq) 519 { 520 ALOGI("NAN_PUBLISH_CANCEL"); 521 if (pReq == NULL) { 522 return WIFI_ERROR_INVALID_ARGS; 523 } 524 size_t message_len = sizeof(NanPublishServiceCancelReqMsg); 525 526 pNanPublishServiceCancelReqMsg pFwReq = 527 (pNanPublishServiceCancelReqMsg)malloc(message_len); 528 if (pFwReq == NULL) { 529 return WIFI_ERROR_INVALID_ARGS; 530 } 531 532 ALOGI("Message Len %d", message_len); 533 memset(pFwReq, 0, message_len); 534 pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1; 535 pFwReq->fwHeader.msgId = NAN_MSG_ID_PUBLISH_SERVICE_CANCEL_REQ; 536 pFwReq->fwHeader.msgLen = message_len; 537 pFwReq->fwHeader.handle = pReq->header.handle; 538 pFwReq->fwHeader.transactionId = pReq->header.transaction_id; 539 540 mVendorData = (char *)pFwReq; 541 mDataLen = message_len; 542 543 return WIFI_SUCCESS; 544 } 545 546 int NanCommand::putNanSubscribe(const NanSubscribeRequest *pReq) 547 { 548 549 ALOGI("NAN_SUBSCRIBE"); 550 if (pReq == NULL) { 551 return WIFI_ERROR_INVALID_ARGS; 552 } 553 554 size_t message_len = 555 sizeof(NanMsgHeader) + sizeof(NanSubscribeServiceReqParams) + 556 (pReq->service_name_len ? SIZEOF_TLV_HDR + pReq->service_name_len : 0) + 557 (pReq->service_specific_info_len ? SIZEOF_TLV_HDR + pReq->service_specific_info_len : 0) + 558 (pReq->rx_match_filter_len ? SIZEOF_TLV_HDR + pReq->rx_match_filter_len : 0) + 559 (pReq->tx_match_filter_len ? SIZEOF_TLV_HDR + pReq->tx_match_filter_len : 0); 560 561 #ifdef NAN_2_0 562 message_len += \ 563 (pReq->num_intf_addr_present * (SIZEOF_TLV_HDR + NAN_MAC_ADDR_LEN)); 564 #endif /* NAN_2_0 */ 565 566 pNanSubscribeServiceReqMsg pFwReq = (pNanSubscribeServiceReqMsg)malloc(message_len); 567 if (pFwReq == NULL) { 568 return WIFI_ERROR_INVALID_ARGS; 569 } 570 571 ALOGI("Message Len %d", message_len); 572 memset(pFwReq, 0, message_len); 573 pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1; 574 pFwReq->fwHeader.msgId = NAN_MSG_ID_SUBSCRIBE_SERVICE_REQ; 575 pFwReq->fwHeader.msgLen = message_len; 576 pFwReq->fwHeader.handle = pReq->header.handle; 577 pFwReq->fwHeader.transactionId = pReq->header.transaction_id; 578 579 580 pFwReq->subscribeServiceReqParams.ttl = pReq->ttl; 581 pFwReq->subscribeServiceReqParams.period = pReq->period; 582 pFwReq->subscribeServiceReqParams.subscribeType = pReq->subscribe_type; 583 pFwReq->subscribeServiceReqParams.srfAttr = pReq->serviceResponseFilter; 584 pFwReq->subscribeServiceReqParams.srfInclude = pReq->serviceResponseInclude; 585 pFwReq->subscribeServiceReqParams.srfSend = pReq->useServiceResponseFilter; 586 pFwReq->subscribeServiceReqParams.ssiRequired = pReq->ssiRequiredForMatchIndication; 587 pFwReq->subscribeServiceReqParams.matchAlg = pReq->subscribe_match; 588 pFwReq->subscribeServiceReqParams.count = pReq->subscribe_count; 589 #ifdef NAN_2_0 590 pFwReq->subscribeServiceReqParams.rssiThresholdFlag = pReq->rssi_threshold_flag; 591 pFwReq->subscribeServiceReqParams.ota_flag = pReq->ota_flag; 592 pFwReq->subscribeServiceReqParams.connmap = pReq->connmap; 593 #endif /* NAN_2_0 */ 594 pFwReq->subscribeServiceReqParams.reserved = 0; 595 596 u8* tlvs = pFwReq->ptlv; 597 if (pReq->service_name_len) { 598 tlvs = addTlv(NAN_TLV_TYPE_SERVICE_NAME, pReq->service_name_len, 599 (const u8*)&pReq->service_name[0], tlvs); 600 } 601 if (pReq->service_specific_info_len) { 602 tlvs = addTlv(NAN_TLV_TYPE_SERVICE_SPECIFIC_INFO, pReq->service_specific_info_len, 603 (const u8*)&pReq->service_specific_info[0], tlvs); 604 } 605 if (pReq->rx_match_filter_len) { 606 tlvs = addTlv(NAN_TLV_TYPE_RX_MATCH_FILTER, pReq->rx_match_filter_len, 607 (const u8*)&pReq->rx_match_filter[0], tlvs); 608 } 609 if (pReq->tx_match_filter_len) { 610 tlvs = addTlv(NAN_TLV_TYPE_TX_MATCH_FILTER, pReq->tx_match_filter_len, 611 (const u8*)&pReq->tx_match_filter[0], tlvs); 612 } 613 614 #ifdef NAN_2_0 615 int i = 0; 616 for (i = 0; i < pReq->num_intf_addr_present; i++) 617 { 618 tlvs = addTlv(NAN_TLV_TYPE_MAC_ADDRESS, 619 NAN_MAC_ADDR_LEN, 620 (const u8*)&pReq->intf_addr[i][0], tlvs); 621 } 622 #endif /* NAN_2_0 */ 623 624 mVendorData = (char *)pFwReq; 625 mDataLen = message_len; 626 627 return WIFI_SUCCESS; 628 } 629 630 int NanCommand::putNanSubscribeCancel(const NanSubscribeCancelRequest *pReq) 631 { 632 ALOGI("NAN_SUBSCRIBE_CANCEL"); 633 if (pReq == NULL) { 634 return WIFI_ERROR_INVALID_ARGS; 635 } 636 size_t message_len = sizeof(NanSubscribeServiceCancelReqMsg); 637 638 pNanSubscribeServiceCancelReqMsg pFwReq = 639 (pNanSubscribeServiceCancelReqMsg)malloc(message_len); 640 if (pFwReq == NULL) { 641 return WIFI_ERROR_INVALID_ARGS; 642 } 643 644 ALOGI("Message Len %d", message_len); 645 memset(pFwReq, 0, message_len); 646 pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1; 647 pFwReq->fwHeader.msgId = NAN_MSG_ID_SUBSCRIBE_SERVICE_CANCEL_REQ; 648 pFwReq->fwHeader.msgLen = message_len; 649 pFwReq->fwHeader.handle = pReq->header.handle; 650 pFwReq->fwHeader.transactionId = pReq->header.transaction_id; 651 652 mVendorData = (char *)pFwReq; 653 mDataLen = message_len; 654 655 return WIFI_SUCCESS; 656 } 657 658 659 int NanCommand::putNanTransmitFollowup(const NanTransmitFollowupRequest *pReq) 660 { 661 ALOGI("TRANSMIT_FOLLOWUP"); 662 if (pReq == NULL) { 663 return WIFI_ERROR_INVALID_ARGS; 664 } 665 666 size_t message_len = 667 sizeof(NanMsgHeader) + sizeof(NanTransmitFollowupReqParams) + 668 (pReq->service_specific_info_len ? SIZEOF_TLV_HDR + 669 pReq->service_specific_info_len : 0); 670 671 #ifdef NAN_2_0 672 /* Mac address needs to be added in TLV */ 673 message_len += (SIZEOF_TLV_HDR + sizeof(pReq->addr)); 674 #endif 675 676 pNanTransmitFollowupReqMsg pFwReq = (pNanTransmitFollowupReqMsg)malloc(message_len); 677 if (pFwReq == NULL) { 678 return WIFI_ERROR_INVALID_ARGS; 679 } 680 681 ALOGI("Message Len %d", message_len); 682 memset (pFwReq, 0, message_len); 683 pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1; 684 pFwReq->fwHeader.msgId = NAN_MSG_ID_TRANSMIT_FOLLOWUP_REQ; 685 pFwReq->fwHeader.msgLen = message_len; 686 pFwReq->fwHeader.handle = pReq->header.handle; 687 pFwReq->fwHeader.transactionId = pReq->header.transaction_id; 688 689 690 #ifndef NAN_2_0 691 memcpy(pFwReq->transmitFollowupReqParams.macAddr, pReq->addr, 692 sizeof(pFwReq->transmitFollowupReqParams.macAddr)); 693 #else /* NAN_2_0 */ 694 pFwReq->transmitFollowupReqParams.matchHandle = pReq->match_handle; 695 #endif /* NAN_2_0 */ 696 pFwReq->transmitFollowupReqParams.priority = pReq->priority; 697 pFwReq->transmitFollowupReqParams.window = pReq->dw_or_faw; 698 pFwReq->transmitFollowupReqParams.reserved = 0; 699 700 u8* tlvs = pFwReq->ptlv; 701 702 #ifdef NAN_2_0 703 /* Mac address needs to be added in TLV */ 704 tlvs = addTlv(NAN_TLV_TYPE_MAC_ADDRESS, sizeof(pReq->addr), 705 (const u8*)&pReq->addr[0], tlvs); 706 u16 tlv_type = NAN_TLV_TYPE_SERVICE_SPECIFIC_INFO; 707 #else /* NAN_2_0 */ 708 u16 tlv_type = (pReq->dw_or_faw == 0)? NAN_TLV_TYPE_SERVICE_SPECIFIC_INFO : 709 NAN_TLV_TYPE_EXT_SERVICE_SPECIFIC_INFO; 710 #endif /* NAN_2_0 */ 711 712 if (pReq->service_specific_info_len) { 713 tlvs = addTlv(tlv_type, pReq->service_specific_info_len, 714 (const u8*)&pReq->service_specific_info[0], tlvs); 715 } 716 717 mVendorData = (char *)pFwReq; 718 mDataLen = message_len; 719 720 return WIFI_SUCCESS; 721 } 722 723 int NanCommand::putNanStats(const NanStatsRequest *pReq) 724 { 725 ALOGI("NAN_STATS"); 726 if (pReq == NULL) { 727 return WIFI_ERROR_INVALID_ARGS; 728 } 729 size_t message_len = sizeof(NanStatsReqMsg); 730 731 pNanStatsReqMsg pFwReq = 732 (pNanStatsReqMsg)malloc(message_len); 733 if (pFwReq == NULL) { 734 return WIFI_ERROR_INVALID_ARGS; 735 } 736 737 ALOGI("Message Len %d", message_len); 738 memset(pFwReq, 0, message_len); 739 pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1; 740 pFwReq->fwHeader.msgId = NAN_MSG_ID_STATS_REQ; 741 pFwReq->fwHeader.msgLen = message_len; 742 pFwReq->fwHeader.handle = pReq->header.handle; 743 pFwReq->fwHeader.transactionId = pReq->header.transaction_id; 744 745 pFwReq->statsReqParams.statsId = pReq->stats_id; 746 pFwReq->statsReqParams.clear = pReq->clear; 747 pFwReq->statsReqParams.reserved = 0; 748 749 mVendorData = (char *)pFwReq; 750 mDataLen = message_len; 751 752 return WIFI_SUCCESS; 753 } 754 755 int NanCommand::putNanTCA(const NanTCARequest *pReq) 756 { 757 ALOGI("NAN_TCA"); 758 if (pReq == NULL) { 759 return WIFI_ERROR_INVALID_ARGS; 760 } 761 size_t message_len = sizeof(NanTcaReqMsg); 762 763 #ifdef NAN_2_0 764 message_len += (SIZEOF_TLV_HDR + 2 * sizeof(u32)); 765 #endif 766 767 pNanTcaReqMsg pFwReq = 768 (pNanTcaReqMsg)malloc(message_len); 769 if (pFwReq == NULL) { 770 return WIFI_ERROR_INVALID_ARGS; 771 } 772 773 ALOGI("Message Len %d", message_len); 774 memset(pFwReq, 0, message_len); 775 pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1; 776 pFwReq->fwHeader.msgId = NAN_MSG_ID_TCA_REQ; 777 pFwReq->fwHeader.msgLen = message_len; 778 pFwReq->fwHeader.handle = pReq->header.handle; 779 pFwReq->fwHeader.transactionId = pReq->header.transaction_id; 780 781 #ifndef NAN_2_0 782 pFwReq->tcaReqParams.tcaId = pReq->tca_id; 783 pFwReq->tcaReqParams.rising = pReq->rising_direction_evt_flag; 784 pFwReq->tcaReqParams.falling = pReq->falling_direction_evt_flag; 785 pFwReq->tcaReqParams.clear = pReq->clear; 786 pFwReq->tcaReqParams.reserved = 0; 787 pFwReq->tcaReqParams.threshold = pReq->threshold; 788 #else /* NAN_2_0 */ 789 u32 tcaReqParams[2]; 790 memset (tcaReqParams, 0, sizeof(tcaReqParams)); 791 tcaReqParams[0] = (pReq->rising_direction_evt_flag & 0x01); 792 tcaReqParams[0] |= (pReq->falling_direction_evt_flag & 0x01) << 1; 793 tcaReqParams[0] |= (pReq->clear & 0x01) << 2; 794 tcaReqParams[1] = pReq->threshold; 795 796 u8* tlvs = pFwReq->ptlv; 797 798 tlvs = addTlv(NAN_TLV_TYPE_TCA_CLUSTER_SIZE_REQ, sizeof(tcaReqParams), 799 (const u8*)&tcaReqParams[0], tlvs); 800 #endif 801 802 mVendorData = (char *)pFwReq; 803 mDataLen = message_len; 804 805 return WIFI_SUCCESS; 806 } 807 808 int NanCommand::putNanBeaconSdfPayload(const NanBeaconSdfPayloadRequest *pReq) 809 { 810 int ret = WIFI_ERROR_NOT_SUPPORTED; 811 #ifdef NAN_2_0 812 ALOGI("NAN_BEACON_SDF_PAYLAOD"); 813 if (pReq == NULL) { 814 return WIFI_ERROR_INVALID_ARGS; 815 } 816 size_t message_len = sizeof(NanMsgHeader) + \ 817 SIZEOF_TLV_HDR + sizeof(u32) + \ 818 pReq->vsa.vsa_len; 819 820 pNanBeaconSdfPayloadReqMsg pFwReq = 821 (pNanBeaconSdfPayloadReqMsg)malloc(message_len); 822 if (pFwReq == NULL) { 823 return WIFI_ERROR_INVALID_ARGS; 824 } 825 826 ALOGI("Message Len %d", message_len); 827 memset(pFwReq, 0, message_len); 828 pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1; 829 pFwReq->fwHeader.msgId = NAN_MSG_ID_BEACON_SDF_REQ; 830 pFwReq->fwHeader.msgLen = message_len; 831 pFwReq->fwHeader.handle = pReq->header.handle; 832 pFwReq->fwHeader.transactionId = pReq->header.transaction_id; 833 834 /* Construct First 4 bytes of NanBeaconSdfPayloadReqMsg */ 835 u32 temp = 0; 836 temp = pReq->vsa.payload_transmit_flag & 0x01; 837 temp |= (pReq->vsa.tx_in_discovery_beacon & 0x01) << 1; 838 temp |= (pReq->vsa.tx_in_sync_beacon & 0x01) << 2; 839 temp |= (pReq->vsa.tx_in_service_discovery & 0x01) << 3; 840 temp |= (pReq->vsa.vendor_oui & 0x00FFFFFF) << 8; 841 842 int tlv_len = sizeof(u32) + pReq->vsa.vsa_len; 843 u8* tempBuf = (u8*)malloc(tlv_len); 844 if (tempBuf == NULL) { 845 ALOGE("%s: Malloc failed", __func__); 846 free(pFwReq); 847 return WIFI_ERROR_INVALID_ARGS; 848 } 849 memset(tempBuf, 0, tlv_len); 850 memcpy(tempBuf, &temp, sizeof(u32)); 851 memcpy((tempBuf + sizeof(u32)), pReq->vsa.vsa, pReq->vsa.vsa_len); 852 853 u8* tlvs = pFwReq->ptlv; 854 855 /* Write the TLVs to the message. */ 856 tlvs = addTlv(NAN_TLV_TYPE_VENDOR_SPECIFIC_ATTRIBUTE_TRANSMIT, tlv_len, 857 (const u8*)tempBuf, tlvs); 858 free(tempBuf); 859 860 mVendorData = (char *)pFwReq; 861 mDataLen = message_len; 862 ret = WIFI_SUCCESS; 863 #endif /* NAN_2_0 */ 864 return ret; 865 } 866 //callback handlers registered for nl message send 867 static int error_handler_nan(struct sockaddr_nl *nla, struct nlmsgerr *err, 868 void *arg) 869 { 870 struct sockaddr_nl * tmp; 871 int *ret = (int *)arg; 872 tmp = nla; 873 *ret = err->error; 874 ALOGE("%s: Error code:%d (%s)", __func__, *ret, strerror(-(*ret))); 875 return NL_STOP; 876 } 877 878 //callback handlers registered for nl message send 879 static int ack_handler_nan(struct nl_msg *msg, void *arg) 880 { 881 int *ret = (int *)arg; 882 struct nl_msg * a; 883 884 ALOGE("%s: called", __func__); 885 a = msg; 886 *ret = 0; 887 return NL_STOP; 888 } 889 890 //callback handlers registered for nl message send 891 static int finish_handler_nan(struct nl_msg *msg, void *arg) 892 { 893 int *ret = (int *)arg; 894 struct nl_msg * a; 895 896 ALOGE("%s: called", __func__); 897 a = msg; 898 *ret = 0; 899 return NL_SKIP; 900 } 901 902 903 //Override base class requestEvent and implement little differently here 904 //This will send the request message 905 //We dont wait for any response back in case of Nan as it is asynchronous 906 //thus no wait for condition. 907 int NanCommand::requestEvent() 908 { 909 int res; 910 struct nl_cb * cb; 911 912 cb = nl_cb_alloc(NL_CB_DEFAULT); 913 if (!cb) { 914 ALOGE("%s: Callback allocation failed",__func__); 915 res = -1; 916 goto out; 917 } 918 919 /* create the message */ 920 res = create(); 921 if (res < 0) 922 goto out; 923 924 /* send message */ 925 ALOGE("%s:Handle:%p Socket Value:%p", __func__, mInfo, mInfo->cmd_sock); 926 res = nl_send_auto_complete(mInfo->cmd_sock, mMsg.getMessage()); 927 if (res < 0) 928 goto out; 929 res = 1; 930 931 nl_cb_err(cb, NL_CB_CUSTOM, error_handler_nan, &res); 932 nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler_nan, &res); 933 nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler_nan, &res); 934 935 // err is populated as part of finish_handler 936 while (res > 0) 937 nl_recvmsgs(mInfo->cmd_sock, cb); 938 939 ALOGD("%s: Command invoked return value:%d",__func__, res); 940 941 out: 942 //free the VendorData 943 if (mVendorData) { 944 free(mVendorData); 945 } 946 mVendorData = NULL; 947 //cleanup the mMsg 948 mMsg.destroy(); 949 return res; 950 } 951 952 int NanCommand::calcNanTransmitPostDiscoverySize( 953 const NanTransmitPostDiscovery *pPostDiscovery) 954 { 955 /* Fixed size of u32 for Conn Type, Device Role and R flag + Dur + Rsvd*/ 956 int ret = sizeof(u32); 957 /* size of availability interval bit map is 4 bytes */ 958 ret += sizeof(u32); 959 /* size of mac address is 6 bytes*/ 960 ret += (SIZEOF_TLV_HDR + NAN_MAC_ADDR_LEN); 961 if (pPostDiscovery && 962 pPostDiscovery->type == NAN_CONN_WLAN_MESH) { 963 /* size of WLAN_MESH_ID */ 964 ret += (SIZEOF_TLV_HDR + \ 965 pPostDiscovery->mesh_id_len); 966 } 967 if (pPostDiscovery && 968 pPostDiscovery->type == NAN_CONN_WLAN_INFRA) { 969 /* size of Infrastructure ssid */ 970 ret += (SIZEOF_TLV_HDR + \ 971 pPostDiscovery->infrastructure_ssid_len); 972 } 973 ALOGI("%s:size:%d", __func__, ret); 974 return ret; 975 } 976 977 void NanCommand::fillNanSocialChannelParamVal( 978 const NanSocialChannelScanParams *pScanParams, 979 u32* pChannelParamArr) 980 { 981 int i; 982 if (pChannelParamArr) { 983 memset(pChannelParamArr, 0, 984 NAN_MAX_SOCIAL_CHANNEL * sizeof(u32)); 985 for (i= 0; i < NAN_MAX_SOCIAL_CHANNEL; i++) { 986 pChannelParamArr[i] = pScanParams->scan_period[i] << 16; 987 pChannelParamArr[i] |= pScanParams->dwell_time[i] << 8; 988 } 989 pChannelParamArr[NAN_CHANNEL_6] |= 6; 990 pChannelParamArr[NAN_CHANNEL_44]|= 44; 991 pChannelParamArr[NAN_CHANNEL_149]|= 149; 992 ALOGI("%s: Filled SocialChannelParamVal", __func__); 993 hexdump((char*)pChannelParamArr, NAN_MAX_SOCIAL_CHANNEL * sizeof(u32)); 994 } 995 return; 996 } 997 998 u32 NanCommand::getNanTransmitPostConnectivityCapabilityVal( 999 const NanTransmitPostConnectivityCapability *pCapab) 1000 { 1001 u32 ret = 0; 1002 ret |= (pCapab->payload_transmit_flag? 1:0) << 16; 1003 ret |= (pCapab->is_mesh_supported? 1:0) << 5; 1004 ret |= (pCapab->is_ibss_supported? 1:0) << 4; 1005 ret |= (pCapab->wlan_infra_field? 1:0) << 3; 1006 ret |= (pCapab->is_tdls_supported? 1:0) << 2; 1007 ret |= (pCapab->is_wfds_supported? 1:0) << 1; 1008 ret |= (pCapab->is_wfd_supported? 1:0); 1009 ALOGI("%s: val:%d", __func__, ret); 1010 return ret; 1011 } 1012 1013 void NanCommand::fillNanTransmitPostDiscoveryVal( 1014 const NanTransmitPostDiscovery *pTxDisc, 1015 u8 *pOutValue) 1016 { 1017 #ifdef NAN_2_0 1018 if (pTxDisc && pOutValue) { 1019 u8 *tlvs = &pOutValue[8]; 1020 pOutValue[0] = pTxDisc->type; 1021 pOutValue[1] = pTxDisc->role; 1022 pOutValue[2] = (pTxDisc->transmit_freq? 1:0); 1023 pOutValue[2] |= ((pTxDisc->duration & 0x03) << 1); 1024 memcpy(&pOutValue[4], &pTxDisc->avail_interval_bitmap, 1025 sizeof(pTxDisc->avail_interval_bitmap)); 1026 tlvs = addTlv(NAN_TLV_TYPE_MAC_ADDRESS, 1027 NAN_MAC_ADDR_LEN, 1028 (const u8*)&pTxDisc->addr[0], 1029 tlvs); 1030 if (pTxDisc->type == NAN_CONN_WLAN_MESH) { 1031 tlvs = addTlv(NAN_TLV_TYPE_WLAN_MESH_ID, 1032 pTxDisc->mesh_id_len, 1033 (const u8*)&pTxDisc->mesh_id[0], 1034 tlvs); 1035 } 1036 if (pTxDisc->type == NAN_CONN_WLAN_INFRA) { 1037 tlvs = addTlv(NAN_TLV_TYPE_FW_WLAN_INFRASTRUCTURE_SSID, 1038 pTxDisc->infrastructure_ssid_len, 1039 (const u8*)&pTxDisc->infrastructure_ssid_val[0], 1040 tlvs); 1041 } 1042 ALOGI("%s: Filled TransmitPostDiscoveryVal", __func__); 1043 hexdump((char*)pOutValue, calcNanTransmitPostDiscoverySize(pTxDisc)); 1044 } 1045 #endif /* NAN_2_0 */ 1046 return; 1047 } 1048 1049 void NanCommand::fillNanFurtherAvailabilityMapVal( 1050 const NanFurtherAvailabilityMap *pFam, 1051 u8 *pOutValue) 1052 { 1053 //ToDo: Fixme - build issue 1054 #if 0 1055 int idx = 0; 1056 if (pFam && pOutValue) { 1057 u32 famsize = calcNanFurtherAvailabilityMapSize(pFam); 1058 pNanFurtherAvailabilityMapAttrTlv pFwReq = \ 1059 (pNanFurtherAvailabilityMapAttrTlv)pOutValue; 1060 1061 memset(pOutValue, 0, famsize); 1062 pFwReq->numChan = pFam->numchans; 1063 for (idx = 0; idx < pFam->numchans; idx++) { 1064 const NanFurtherAvailabilityChannel *pFamChan = \ 1065 &pFam->famchan[idx]; 1066 pNanFurtherAvailabilityChan pFwFamChan = \ 1067 (pNanFurtherAvailabilityChan)((u8*)&pFwReq->pFaChan[0] + \ 1068 (idx * sizeof(NanFurtherAvailabilityChan))); 1069 1070 pFwFamChan->entryCtrl.availIntDuration = \ 1071 pFamChan->entry_control; 1072 pFwFamChan->entryCtrl.mapId = \ 1073 pFamChan->mapid; 1074 pFwFamChan->opClass = pFamChan->class_val; 1075 pFwFamChan->channel = pFamChan->channel; 1076 memcpy(&pFwFamChan->availIntBitmap, 1077 &pFamChan->avail_interval_bitmap, 1078 sizeof(pFwFamChan->availIntBitmap)); 1079 } 1080 ALOGI("%s: Filled FurtherAvailabilityMapVal", __func__); 1081 hexdump((char*)pOutValue, famsize); 1082 } 1083 #endif 1084 return; 1085 } 1086 1087 int NanCommand::calcNanFurtherAvailabilityMapSize( 1088 const NanFurtherAvailabilityMap *pFam) 1089 { 1090 int ret = 0; 1091 if (pFam && pFam->numchans && 1092 pFam->numchans <= NAN_MAX_FAM_CHANNELS) { 1093 /* Fixed size of u8 for numchans*/ 1094 ret = sizeof(u8); 1095 /* numchans * sizeof(FamChannels) */ 1096 //ToDo: Fix build 1097 //ret += (pFam->numchans * sizeof(NanFurtherAvailabilityChan)); 1098 } 1099 ALOGI("%s:size:%d", __func__, ret); 1100 return ret; 1101 } 1102 1103