diff options
Diffstat (limited to 'bcmdhd/wifi_hal/nan.cpp')
-rwxr-xr-x | bcmdhd/wifi_hal/nan.cpp | 435 |
1 files changed, 389 insertions, 46 deletions
diff --git a/bcmdhd/wifi_hal/nan.cpp b/bcmdhd/wifi_hal/nan.cpp index 0805128..e74d9a1 100755 --- a/bcmdhd/wifi_hal/nan.cpp +++ b/bcmdhd/wifi_hal/nan.cpp @@ -40,13 +40,13 @@ #include <utils/Log.h> #include <log/log.h> -#include "wifi_hal.h" +#include <hardware_legacy/wifi_hal.h> #include "common.h" #include "cpp_bindings.h" #include "netinet/in.h" #include "arpa/inet.h" #include <openssl/sha.h> -#include <openssl/evp.h> +#include <openssl/evp.h> #include <sys/ioctl.h> /* Changes between incompatible Version of NAN */ @@ -288,7 +288,10 @@ typedef enum { NAN_ATTRIBUTE_ENABLE_RANGING = 226, NAN_ATTRIBUTE_DW_EARLY_TERM = 227, NAN_ATTRIBUTE_CHANNEL_INFO = 228, - NAN_ATTRIBUTE_NUM_CHANNELS = 229 + NAN_ATTRIBUTE_NUM_CHANNELS = 229, + NAN_ATTRIBUTE_INSTANT_MODE_ENABLE = 230, + NAN_ATTRIBUTE_INSTANT_COMM_CHAN = 231, + NAN_ATTRIBUTE_CHRE_REQUEST = 232, } NAN_ATTRIBUTE; typedef enum { @@ -857,6 +860,11 @@ class NanDiscEnginePrimitive : public WifiCommand } if (mParams->scid_len) { + if ((mParams->scid_len > NAN_MAX_SCID_BUF_LEN) || + (mParams->scid_len % NAN_SCID_INFO_LEN)) { + ALOGE("%s: Invalid scid len, = %d\n", __func__, mParams->scid_len); + return NAN_STATUS_INVALID_PARAM; + } result = request.put_u32(NAN_ATTRIBUTE_SCID_LEN, mParams->scid_len); if (result < 0) { @@ -1168,7 +1176,45 @@ class NanDiscEnginePrimitive : public WifiCommand return result; } + result = request.put_u8(NAN_ATTRIBUTE_CIPHER_SUITE_TYPE, + mParams->cipher_type); + if (result < 0) { + ALOGE("%s: Failed to fill NAN_ATTRIBUTE_CIPHER_SUITE_TYPE, result = %d\n", + __func__, result); + return result; + } + + result = request.put_u8(NAN_ATTRIBUTE_KEY_TYPE, + mParams->key_info.key_type); + if (result < 0) { + ALOGE("%s: Failed to fill NAN_ATTRIBUTE_KEY_TYPE, result = %d\n", + __func__, result); + return result; + } + + if (mParams->key_info.key_type == NAN_SECURITY_KEY_INPUT_PMK) { + if (mParams->key_info.body.pmk_info.pmk_len) { + result = request.put_u32(NAN_ATTRIBUTE_KEY_LEN, + mParams->key_info.body.pmk_info.pmk_len); + if (result < 0) { + ALOGE("%s: Failed to fill pmk len, result = %d\n", __func__, result); + return result; + } + result = request.put(NAN_ATTRIBUTE_KEY_DATA, + (void *)mParams->key_info.body.pmk_info.pmk, + mParams->key_info.body.pmk_info.pmk_len); + if (result < 0) { + ALOGE("%s: Failed to fill pmk, result = %d\n", __func__, result); + return result; + } + } + } + if (mParams->scid_len) { + if (mParams->scid_len != NAN_SCID_INFO_LEN) { + ALOGE("%s: Invalid scid len, = %d\n", __func__, mParams->scid_len); + return NAN_STATUS_INVALID_PARAM; + } result = request.put_u32(NAN_ATTRIBUTE_SCID_LEN, mParams->scid_len); if (result < 0) { @@ -1176,7 +1222,6 @@ class NanDiscEnginePrimitive : public WifiCommand return result; } - prhex(NULL, mParams->scid, mParams->scid_len); result = request.put(NAN_ATTRIBUTE_SCID, (void *)mParams->scid, mParams->scid_len); if (result < 0) { @@ -2014,6 +2059,26 @@ class NanDataPathPrimitive : public WifiCommand } } + if (mParams->scid_len) { + if (mParams->scid_len != NAN_SCID_INFO_LEN) { + ALOGE("%s: Invalid scid len, = %d\n", __func__, mParams->scid_len); + return NAN_STATUS_INVALID_PARAM; + } + result = request.put_u32(NAN_ATTRIBUTE_SCID_LEN, + mParams->scid_len); + if (result < 0) { + ALOGE("%s: Failed to fill scid len, result = %d\n", __func__, result); + return result; + } + + result = request.put(NAN_ATTRIBUTE_SCID, + (void *)mParams->scid, mParams->scid_len); + if (result < 0) { + ALOGE("%s: Failed to fill scid, result = %d\n", __func__, result); + return result; + } + } + request.attr_end(data); return WIFI_SUCCESS; } @@ -2159,6 +2224,27 @@ class NanDataPathPrimitive : public WifiCommand } } + if (mParams->scid_len) { + if (mParams->scid_len != NAN_SCID_INFO_LEN) { + ALOGE("%s: Invalid scid len, = %d\n", __func__, mParams->scid_len); + return NAN_STATUS_INVALID_PARAM; + } + result = request.put_u32(NAN_ATTRIBUTE_SCID_LEN, + mParams->scid_len); + if (result < 0) { + ALOGE("%s: Failed to fill scid len, result = %d\n", __func__, result); + return result; + } + + prhex(NULL, mParams->scid, mParams->scid_len); + result = request.put(NAN_ATTRIBUTE_SCID, + (void *)mParams->scid, mParams->scid_len); + if (result < 0) { + ALOGE("%s: Failed to fill scid, result = %d\n", __func__, result); + return result; + } + } + request.attr_end(data); return WIFI_SUCCESS; } @@ -2300,7 +2386,7 @@ class NanDataPathPrimitive : public WifiCommand attr_type = it.get_type(); if (attr_type == NAN_ATTRIBUTE_PUBLISH_ID) { - ALOGI("publish_id: %u", it.get_u32()); + ALOGI("publish_id: %u\n", it.get_u32()); ndp_request_event.service_instance_id = it.get_u32(); } else if (attr_type == NAN_ATTRIBUTE_MAC_ADDR) { @@ -2310,17 +2396,17 @@ class NanDataPathPrimitive : public WifiCommand MAC2STR(ndp_request_event.peer_disc_mac_addr)); } else if (attr_type == NAN_ATTRIBUTE_NDP_ID) { - ALOGI("ndp id: %u", it.get_u32()); + ALOGI("ndp id: %u\n", it.get_u32()); ndp_request_event.ndp_instance_id = it.get_u32(); } else if (attr_type == NAN_ATTRIBUTE_SECURITY) { - ALOGI("security: %u", + ALOGI("security: %u\n", (NanDataPathSecurityCfgStatus)it.get_u8()); ndp_request_event.ndp_cfg.security_cfg = (NanDataPathSecurityCfgStatus)it.get_u8(); } else if (attr_type == NAN_ATTRIBUTE_QOS) { - ALOGI("QoS: %u", (NanDataPathQosCfg)it.get_u8()); + ALOGI("QoS: %u\n", (NanDataPathQosCfg)it.get_u8()); ndp_request_event.ndp_cfg.qos_cfg = (NanDataPathQosCfg)it.get_u8(); } else if (attr_type == NAN_ATTRIBUTE_SERVICE_SPECIFIC_INFO_LEN) { @@ -2332,7 +2418,17 @@ class NanDataPathPrimitive : public WifiCommand ndp_ind_app_info_len); ndp_request_event.app_info.ndp_app_info [ndp_ind_app_info_len] = '\0'; - ALOGI("service info: %s", ndp_request_event.app_info.ndp_app_info); + ALOGI("service info: %s\n", ndp_request_event.app_info.ndp_app_info); + + } else if (attr_type == NAN_ATTRIBUTE_SCID_LEN) { + ALOGI("scid len: %u\n", it.get_u32()); + ndp_request_event.scid_len = it.get_u32(); + + } else if (attr_type == NAN_ATTRIBUTE_SCID) { + memcpy(ndp_request_event.scid, it.get_data(), + ndp_request_event.scid_len); + ndp_request_event.scid[ndp_request_event.scid_len] = '\0'; + ALOGI("scid : %s\n", ndp_request_event.scid); } } @@ -2448,6 +2544,7 @@ class NanMacControl : public WifiCommand wifi_interface_handle mIface; NanRequestType mType; u32 mVersion; + u8 mChreNan; public: NanMacControl(wifi_interface_handle iface, int id, @@ -2487,6 +2584,10 @@ class NanMacControl : public WifiCommand mParams = params; } + void setChreNan(u8 chre_nan) { + mChreNan = chre_nan; + } + int createRequest(WifiRequest& request) { ALOGI("NAN CMD: %s\n", NanCmdToString(mType)); if (mType == NAN_REQUEST_ENABLE) { @@ -2866,6 +2967,32 @@ class NanMacControl : public WifiCommand } } + if (mParams->config_enable_instant_mode) { + result = request.put_u32(NAN_ATTRIBUTE_INSTANT_MODE_ENABLE, + mParams->enable_instant_mode); + if (result < 0) { + ALOGE("%s: Failing to fill enable instant mode, result = %d\n", __func__, result); + return result; + } + } + + if (mParams->enable_instant_mode && mParams->config_instant_mode_channel + && mParams->instant_mode_channel) { + result = request.put_u32(NAN_ATTRIBUTE_INSTANT_COMM_CHAN, + mParams->instant_mode_channel); + if (result < 0) { + ALOGE("%s: Failing in config instant channel, result = %d\n", __func__, result); + return result; + } + ALOGI("%s: instant mode channel = %d\n", __func__, mParams->instant_mode_channel); + } + + result = request.put_u8(NAN_ATTRIBUTE_CHRE_REQUEST, mChreNan); + if (result < 0) { + ALOGE("%s: Failing in config chreNan, result = %d\n", __func__, result); + return result; + } + request.attr_end(data); NAN_DBG_EXIT(); return WIFI_SUCCESS; @@ -2882,6 +3009,12 @@ class NanMacControl : public WifiCommand nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA); + result = request.put_u8(NAN_ATTRIBUTE_CHRE_REQUEST, mChreNan); + if (result < 0) { + ALOGE("%s: Failing in config chreNan, result = %d\n", __func__, result); + return result; + } + request.attr_end(data); NAN_DBG_EXIT(); @@ -3129,6 +3262,27 @@ class NanMacControl : public WifiCommand return result; } } + + if (mParams->config_enable_instant_mode) { + result = request.put_u32(NAN_ATTRIBUTE_INSTANT_MODE_ENABLE, + mParams->enable_instant_mode); + if (result < 0) { + ALOGE("%s: Failing to fill enable instant mode, result = %d\n", __func__, result); + return result; + } + } + + if (mParams->enable_instant_mode && mParams->config_instant_mode_channel + && mParams->instant_mode_channel) { + result = request.put_u32(NAN_ATTRIBUTE_INSTANT_COMM_CHAN, + mParams->instant_mode_channel); + if (result < 0) { + ALOGE("%s: Failing in config instant channel, result = %d\n", __func__, result); + return result; + } + ALOGI("%s: instant mode channel = %d\n", __func__, mParams->instant_mode_channel); + } + request.attr_end(data); NAN_DBG_EXIT(); return WIFI_SUCCESS; @@ -3186,6 +3340,10 @@ class NanMacControl : public WifiCommand return NL_SKIP; } + if (mChreNan) { + return NL_SKIP; + } + rsp_vndr_data = (nan_hal_resp_t *)reply.get_vendor_data(); ALOGI("NanMacControl::handleResponse\n"); if (mType == NAN_VERSION_INFO) { @@ -3251,7 +3409,6 @@ class NanMacControl : public WifiCommand } int handleEvent(WifiEvent& event) { - u16 inst_id; u32 ndp_instance_id = 0; int event_id = event.get_vendor_subcmd(); nlattr *vendor_data = event.get_attribute(NL80211_ATTR_VENDOR_DATA); @@ -3266,11 +3423,14 @@ class NanMacControl : public WifiCommand return NL_SKIP; } + if (mChreNan) { + return NL_SKIP; + } + for (nl_iterator it(vendor_data); it.has_next(); it.next()) { attr_type = it.get_type(); if (it.get_type() == NAN_ATTRIBUTE_HANDLE) { - inst_id = it.get_u8(); } else if (it.get_type() == NAN_ATTRIBUTE_NDP_ID) { ndp_instance_id = it.get_u32(); ALOGI("handleEvent: ndp_instance_id = [%d]\n", ndp_instance_id); @@ -3736,7 +3896,6 @@ static int get_svc_hash(unsigned char *svc_name, return WIFI_SUCCESS; } -#ifdef CONFIG_BRCM static int dump_NanEnableRequest(NanEnableRequest* msg) { ALOGI("%s: Dump NanEnableRequest msg:\n", __func__); @@ -3830,10 +3989,19 @@ static int dump_NanEnableRequest(NanEnableRequest* msg) if (msg->config_disc_mac_addr_randomization) { ALOGI("disc_mac_addr_rand_interval_sec =%u\n", msg->disc_mac_addr_rand_interval_sec); } + ALOGI("config_enable_instant_mode =%u\n", msg->config_enable_instant_mode); + if (msg->config_enable_instant_mode) { + ALOGI("enable_instant_mode =%u\n", msg->enable_instant_mode); + } + ALOGI("config_instant_mode_channel=%u\n", msg->config_instant_mode_channel); + if (msg->config_instant_mode_channel) { + ALOGI("instant_mode_channel=%u\n", msg->instant_mode_channel); + } return WIFI_SUCCESS; } +#ifdef CONFIG_BRCM static int dump_NanConfigRequestRequest(NanConfigRequest* msg) { ALOGI("%s: Dump NanConfigRequest msg:\n", __func__); @@ -3895,6 +4063,15 @@ static int dump_NanConfigRequestRequest(NanConfigRequest* msg) if (msg->config_disc_mac_addr_randomization) { ALOGI("disc_mac_addr_rand_interval_sec =%u\n", msg->disc_mac_addr_rand_interval_sec); } + ALOGI("config_enable_instant_mode =%u\n", msg->config_enable_instant_mode); + if (msg->config_enable_instant_mode) { + ALOGI("enable_instant_mode =%u\n", msg->enable_instant_mode); + } + ALOGI("config_instant_mode_channel=%u\n", msg->config_instant_mode_channel); + if (msg->config_instant_mode_channel) { + ALOGI("instant_mode_channel=%u\n", msg->instant_mode_channel); + } + return WIFI_SUCCESS; } @@ -3914,17 +4091,21 @@ static int dump_NanPublishRequest(NanPublishRequest* msg) ALOGI("publish_match_indicator=%u\n", msg->publish_match_indicator); ALOGI("service_responder_policy=%u\n", msg->service_responder_policy); ALOGI("service_name_len=%u\n", msg->service_name_len); - if (msg->service_name_len) + if (msg->service_name_len) { ALOGI("service_name=%s\n", msg->service_name); + } ALOGI("service_specific_info_len=%u\n", msg->service_specific_info_len); - if (msg->service_specific_info_len) + if (msg->service_specific_info_len) { ALOGI("service_specific_info=%s\n", msg->service_specific_info); + } ALOGI("rx_match_filter_len=%u\n", msg->rx_match_filter_len); - if (msg->rx_match_filter_len) + if (msg->rx_match_filter_len) { prhex("rx_match_filter", msg->rx_match_filter, msg->rx_match_filter_len); + } ALOGI("tx_match_filter_len=%u\n", msg->tx_match_filter_len); - if (msg->tx_match_filter_len) + if (msg->tx_match_filter_len) { prhex("tx_match_filter", msg->tx_match_filter, msg->tx_match_filter_len); + } ALOGI("rssi_threshold_flag=%u\n", msg->rssi_threshold_flag); ALOGI("connmap=%u\n", msg->connmap); ALOGI("recv_indication_cfg=%u\n", msg->recv_indication_cfg); @@ -3933,8 +4114,9 @@ static int dump_NanPublishRequest(NanPublishRequest* msg) ALOGI("key_info: pmk info=%s\n", msg->key_info.body.pmk_info.pmk); ALOGI("key_info: passphrase_info=%s\n", msg->key_info.body.passphrase_info.passphrase); ALOGI("scid_len=%u\n", msg->scid_len); - if (msg->scid_len) + if (msg->scid_len) { ALOGI("scid=%s\n", msg->scid); + } ALOGI("NanSdeaCtrlParams NdpType=%u\n", msg->sdea_params.ndp_type); ALOGI("NanSdeaCtrlParams security_cfg=%u\n", msg->sdea_params.security_cfg); ALOGI("NanSdeaCtrlParams ranging_state=%u\n", msg->sdea_params.ranging_state); @@ -3947,8 +4129,9 @@ static int dump_NanPublishRequest(NanPublishRequest* msg) ALOGI("range_response_cfg=%u\n", msg->range_response_cfg.ranging_response); ALOGI("sdea_service_specific_info_len=%u\n", msg->sdea_service_specific_info_len); - if (msg->sdea_service_specific_info_len) + if (msg->sdea_service_specific_info_len) { ALOGI("sdea_service_specific_info=%s\n", msg->sdea_service_specific_info); + } return WIFI_SUCCESS; } @@ -3997,8 +4180,9 @@ static int dump_NanSubscribeRequest(NanSubscribeRequest* msg) ALOGI("key_info: pmk info=%s\n", msg->key_info.body.pmk_info.pmk); ALOGI("key_info: passphrase_info=%s\n", msg->key_info.body.passphrase_info.passphrase); ALOGI("scid_len=%u\n", msg->scid_len); - if (msg->scid_len) + if (msg->scid_len) { ALOGI("scid=%s\n", msg->scid); + } ALOGI("NanSdeaCtrlParams NdpType=%u\n", msg->sdea_params.ndp_type); ALOGI("NanSdeaCtrlParams security_cfg=%u\n", msg->sdea_params.security_cfg); ALOGI("NanSdeaCtrlParams ranging_state=%u\n", msg->sdea_params.ranging_state); @@ -4065,6 +4249,10 @@ static int dump_NanDataPathInitiatorRequest(NanDataPathInitiatorRequest* msg) ALOGI("key_info: key_type =%u\n", msg->key_info.key_type); ALOGI("key_info: pmk info=%s\n", msg->key_info.body.pmk_info.pmk); ALOGI("key_info: passphrase_info=%s\n", msg->key_info.body.passphrase_info.passphrase); + ALOGI("scid_len=%u\n", msg->scid_len); + if (msg->scid_len) { + ALOGI("scid=%s\n", msg->scid); + } if (msg->service_name_len) { ALOGI("service_name=%s\n", msg->service_name); } @@ -4095,6 +4283,10 @@ static int dump_NanDataPathIndicationResponse(NanDataPathIndicationResponse* msg ALOGI("key_info: pmk info=%s\n", msg->key_info.body.pmk_info.pmk); ALOGI("key_info: passphrase_info=%s\n", msg->key_info.body.passphrase_info.passphrase); ALOGI("service_name_len=%u\n", msg->service_name_len); + ALOGI("scid_len=%u\n", msg->scid_len); + if (msg->scid_len) { + ALOGI("scid=%s\n", msg->scid); + } if (msg->service_name_len) { ALOGI("service_name=%s\n", msg->service_name); } @@ -4108,32 +4300,66 @@ void nan_reset_dbg_counters() } /////////////////////////////////////////////////////////////////////////////// -wifi_error nan_enable_request(transaction_id id, - wifi_interface_handle iface, NanEnableRequest* msg) +wifi_error nan_cmn_enabe_request(transaction_id id, + NanMacControl *cmd, NanEnableRequest* msg) { wifi_error ret = WIFI_SUCCESS; - wifi_handle handle = getWifiHandle(iface); - NanRequestType cmdType = NAN_REQUEST_ENABLE; - - ALOGI("Enabling Nan, Handle = %p\n", handle); - #ifdef CONFIG_BRCM // check up nan enable params from Nan manager level dump_NanEnableRequest(msg); #endif /* CONFIG_BRCM */ nan_reset_dbg_counters(); - /* XXX: WAR posting async enable response */ - //NanMacControl *cmd = new NanMacControl(iface, id, (void *)msg, cmdType); - NanMacControl *cmd = (NanMacControl*)(info.nan_mac_control); - NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY); - cmd->setType(cmdType); + + cmd->setType(NAN_REQUEST_ENABLE); cmd->setId(id); cmd->setMsg((void *)msg); + ret = (wifi_error)cmd->start(); if (ret != WIFI_SUCCESS) { ALOGE("%s : failed in start, error = %d\n", __func__, ret); } - //cmd->releaseRef(); + + return ret; +} + +wifi_error nan_enable_request(transaction_id id, + wifi_interface_handle iface, NanEnableRequest* msg) +{ + wifi_error ret = WIFI_SUCCESS; + hal_info *h_info = getHalInfo(iface); + + ALOGE("nan_enable_request: nan_state = %d\n", h_info->nan_state); + +#ifdef CHRE_NAN + //check if host NAN is pre-empting CHRE NAN + if (h_info->nan_state == NAN_STATE_CHRE) { + /* notify pre-empt to chre */ + if (h_info->chre_nan_cb.on_chre_nan_rtt_change != NULL) { + h_info->chre_nan_cb.on_chre_nan_rtt_change(CHRE_PREMPTED); + } + /* first disable NAN for chre */ + ret = nan_chre_disable_request(1, iface); + if (ret != WIFI_SUCCESS) { + ALOGE("Failed to disable NAN for CHRE ret %d\n", ret); + return ret; + } + } + + /* notify unavailable status to chre */ + if (h_info->chre_nan_cb.on_chre_nan_rtt_change != NULL) { + h_info->chre_nan_cb.on_chre_nan_rtt_change(CHRE_UNAVAILABLE); + } +#endif /* CHRE_NAN */ + + NanMacControl *cmd = (NanMacControl*)(info.nan_mac_control); + NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY); + cmd->setChreNan(0); + ret = nan_cmn_enabe_request(id, cmd, msg); + + if (ret == WIFI_SUCCESS) { + h_info->nan_state = NAN_STATE_AP; + } + return ret; } @@ -4148,16 +4374,40 @@ void nan_dump_dbg_counters() ALOGI("Num Transmit Success %d\n", counters.transmit_txs); } +wifi_error nan_cmn_disable_request(transaction_id id, NanMacControl *mac) +{ + wifi_error ret = WIFI_SUCCESS; + + nan_dump_dbg_counters(); + + mac->setType(NAN_REQUEST_DISABLE); + ret = (wifi_error)mac->cancel(); + if (ret != WIFI_SUCCESS) { + ALOGE("cancel failed, error = %d\n", ret); + } else { + ALOGE("Deinitializing Nan Mac Control = %p\n", mac); + } + mac->releaseRef(); + + return ret; +} wifi_error nan_disable_request(transaction_id id, wifi_interface_handle iface) { - wifi_handle handle = getWifiHandle(iface); - NanRequestType cmdType = NAN_REQUEST_DISABLE; wifi_error ret = WIFI_SUCCESS; + hal_info *h_info = getHalInfo(iface); + + ALOGE("nan_disable_request: nan_state %d\n", h_info->nan_state); + + if (h_info->nan_state == NAN_STATE_CHRE) { + ALOGE("nan_disable_request: Not enabled for AP.. return\n"); + return ret; + } - ALOGI("Disabling Nan, Handle = %p\n", handle); - NanMacControl *cmd = new NanMacControl(iface, id, NULL, cmdType); NanMacControl *mac_prim = (NanMacControl*)(info.nan_mac_control); + NanMacControl *cmd = new NanMacControl(iface, id, NULL, NAN_REQUEST_LAST); + + NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY); if (id != NAN_MAC_INVALID_TRANSID) { ALOGE("Disable NAN MAC transId= %d\n", id); @@ -4166,17 +4416,15 @@ wifi_error nan_disable_request(transaction_id id, ALOGE("Invalid transId= %d cur= %d\n", id, mac_prim->getId()); } - NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY); - - nan_dump_dbg_counters(); - - ret = (wifi_error)cmd->cancel(); - if (ret != WIFI_SUCCESS) { - ALOGE("cancel failed, error = %d\n", ret); - } else { - ALOGE("Deinitializing Nan Mac Control = %p\n", cmd); + cmd->setChreNan(0); + ret = nan_cmn_disable_request(id, cmd); + if (ret == WIFI_SUCCESS) { + h_info->nan_state = NAN_STATE_DISABLED; + /* notify pre-empt / unavailable status to chre */ + if (h_info->chre_nan_cb.on_chre_nan_rtt_change != NULL) { + h_info->chre_nan_cb.on_chre_nan_rtt_change(CHRE_AVAILABLE); + } } - cmd->releaseRef(); return ret; } @@ -4905,6 +5153,15 @@ class NanEventCap : public WifiCommand ndp_request_event.app_info.ndp_app_info[ndp_ind_app_info_len] = '\0'; ALOGI("service info: %s\n", ndp_request_event.app_info.ndp_app_info); + } else if (attr_type == NAN_ATTRIBUTE_SCID_LEN) { + ALOGI("scid length %d\n", it.get_u32()); + ndp_request_event.scid_len= it.get_u32(); + + } else if (attr_type == NAN_ATTRIBUTE_SCID) { + memcpy(ndp_request_event.scid, it.get_data(), + ndp_request_event.scid_len); + ndp_request_event.scid[ndp_request_event.scid_len] = '\0'; + ALOGI("scid: %s\n", ndp_request_event.scid); } } @@ -5264,3 +5521,89 @@ wifi_error nan_data_end(transaction_id id, NAN_DBG_EXIT(); return ret; } + +wifi_error nan_chre_enable_request(transaction_id id, + wifi_interface_handle iface, NanEnableRequest* msg) +{ + wifi_error ret = WIFI_SUCCESS; + NanEnableRequest def_msg; + hal_info *h_info = getHalInfo(iface); + + ALOGI("nan_chre_enable_request: nan_state %d\n", h_info->nan_state); + + if (h_info->nan_state == NAN_STATE_CHRE) { + return WIFI_SUCCESS; + } else if (h_info->nan_state == NAN_STATE_AP) { + ALOGE("nan_chre_enable_request: Nan is enabled for AP. Fail CHRE request\n"); + return WIFI_ERROR_BUSY; + } + + NanMacControl *mac = new NanMacControl(iface, 0, NULL, NAN_REQUEST_LAST); + NULL_CHECK_RETURN(mac, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY); + + mac->setChreNan(1); + if (msg == NULL) { + /* default enable params */ + ALOGI("Input Enable config is NULL, use default config\n"); + memset(&def_msg, 0, sizeof(def_msg)); + def_msg.hop_count_limit_val = 5; + def_msg.config_2dot4g_support = 1; + def_msg.support_2dot4g_val = 1; + def_msg.config_2dot4g_beacons = 1; + def_msg.beacon_2dot4g_val = 1; + def_msg.config_2dot4g_sdf = 1; + def_msg.sdf_2dot4g_val = 1; + def_msg.config_disc_mac_addr_randomization = true; + def_msg.disc_mac_addr_rand_interval_sec = 0; + def_msg.config_ndpe_attr = false; + ret = nan_cmn_enabe_request(id, mac, &def_msg); + } else { + ret = nan_cmn_enabe_request(id, mac, msg); + } + + if (ret == WIFI_SUCCESS) { + h_info->nan_state = NAN_STATE_CHRE; + } + + return ret; +} + +wifi_error nan_chre_disable_request(transaction_id id, + wifi_interface_handle iface) +{ + wifi_error ret = WIFI_SUCCESS; + hal_info *h_info = getHalInfo(iface); + + ALOGI("nan_chre_disable_request: nan_state %d\n", h_info->nan_state); + + if (h_info->nan_state == NAN_STATE_AP) { + ALOGE("nan_chre_disable_request: Not enabled for CHRE.. return\n"); + return ret; + } + + NanMacControl *cmd = new NanMacControl(iface, id, NULL, NAN_REQUEST_LAST); + NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY); + + cmd->setChreNan(1); + ret = nan_cmn_disable_request(id, cmd); + + if (ret == WIFI_SUCCESS) { + h_info->nan_state = NAN_STATE_DISABLED; + } + + return ret; +} + +wifi_error nan_chre_register_handler(wifi_interface_handle iface, + wifi_chre_handler handler) +{ + wifi_error ret = WIFI_SUCCESS; + hal_info *h_info = getHalInfo(iface); + + if (h_info) { + ALOGE("Registering CHRE handler for Nan Status %p\n", handler.on_chre_nan_rtt_change); + h_info->chre_nan_cb = handler; + } + + return ret; +} |