diff options
Diffstat (limited to 'legacy/qcwcn/wifi_hal/nan_rsp.cpp')
-rw-r--r-- | legacy/qcwcn/wifi_hal/nan_rsp.cpp | 965 |
1 files changed, 965 insertions, 0 deletions
diff --git a/legacy/qcwcn/wifi_hal/nan_rsp.cpp b/legacy/qcwcn/wifi_hal/nan_rsp.cpp new file mode 100644 index 0000000..f0b9b1c --- /dev/null +++ b/legacy/qcwcn/wifi_hal/nan_rsp.cpp @@ -0,0 +1,965 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "sync.h" +#include <utils/Log.h> +#include "wifi_hal.h" +#include "nan_i.h" +#include "nancommand.h" + + +int NanCommand::isNanResponse() +{ + if (mNanVendorEvent == NULL) { + ALOGE("NULL check failed"); + return WIFI_ERROR_INVALID_ARGS; + } + + NanMsgHeader *pHeader = (NanMsgHeader *)mNanVendorEvent; + + switch (pHeader->msgId) { + case NAN_MSG_ID_ERROR_RSP: + case NAN_MSG_ID_CONFIGURATION_RSP: + case NAN_MSG_ID_PUBLISH_SERVICE_CANCEL_RSP: + case NAN_MSG_ID_PUBLISH_SERVICE_RSP: + case NAN_MSG_ID_SUBSCRIBE_SERVICE_RSP: + case NAN_MSG_ID_SUBSCRIBE_SERVICE_CANCEL_RSP: + case NAN_MSG_ID_TRANSMIT_FOLLOWUP_RSP: + case NAN_MSG_ID_STATS_RSP: + case NAN_MSG_ID_ENABLE_RSP: + case NAN_MSG_ID_DISABLE_RSP: + case NAN_MSG_ID_TCA_RSP: + case NAN_MSG_ID_BEACON_SDF_RSP: + case NAN_MSG_ID_CAPABILITIES_RSP: + case NAN_MSG_ID_TESTMODE_RSP: + return 1; + default: + return 0; + } +} + +struct verboseTlv { + NanTlvType tlvType; + char strTlv[NAN_ERROR_STR_LEN]; +}; + +struct verboseTlv tlvToStr[] = { + {NAN_TLV_TYPE_SDF_MATCH_FILTER, " SDF match filter"}, + {NAN_TLV_TYPE_TX_MATCH_FILTER, " Tx match filter"}, + {NAN_TLV_TYPE_RX_MATCH_FILTER, " Rx match filter"}, + {NAN_TLV_TYPE_SERVICE_SPECIFIC_INFO, + " Service specific info"}, + {NAN_TLV_TYPE_EXT_SERVICE_SPECIFIC_INFO, + " Extended Service specific info"}, + {NAN_TLV_TYPE_VENDOR_SPECIFIC_ATTRIBUTE_TRANSMIT, + " Vendor specific attribute transmit"}, + {NAN_TLV_TYPE_VENDOR_SPECIFIC_ATTRIBUTE_RECEIVE, + " Vendor specific attribute receive"}, + {NAN_TLV_TYPE_POST_NAN_CONNECTIVITY_CAPABILITIES_RECEIVE, + " Post Nan connectivity capability receive"}, + {NAN_TLV_TYPE_POST_NAN_DISCOVERY_ATTRIBUTE_RECEIVE, + " Post Nan discovery attribute receive"}, + {NAN_TLV_TYPE_BEACON_SDF_PAYLOAD_RECEIVE, + " Beacon SDF payload receive"}, + + /* Configuration types */ + {NAN_TLV_TYPE_CONFIG_FIRST, " Config first"}, + {NAN_TLV_TYPE_24G_SUPPORT, " 2.4G support"}, + {NAN_TLV_TYPE_24G_BEACON, " 2.4G beacon"}, + {NAN_TLV_TYPE_24G_SDF, " 2.4G SDF"}, + {NAN_TLV_TYPE_24G_RSSI_CLOSE, " 2.4G RSSI close"}, + {NAN_TLV_TYPE_24G_RSSI_MIDDLE, " 2.4G RSSI middle"}, + {NAN_TLV_TYPE_24G_RSSI_CLOSE_PROXIMITY, + " 2.4G RSSI close proximity"}, + {NAN_TLV_TYPE_5G_SUPPORT, " 5G support"}, + {NAN_TLV_TYPE_5G_BEACON, " 5G beacon"}, + {NAN_TLV_TYPE_5G_SDF, " 5G SDF"}, + {NAN_TLV_TYPE_5G_RSSI_CLOSE, " 5G RSSI close"}, + {NAN_TLV_TYPE_5G_RSSI_MIDDLE, " 5G RSSI middle"}, + {NAN_TLV_TYPE_5G_RSSI_CLOSE_PROXIMITY, + " 5G RSSI close proximity"}, + {NAN_TLV_TYPE_SID_BEACON, " SID beacon"}, + {NAN_TLV_TYPE_HOP_COUNT_LIMIT, " Hop count limit"}, + {NAN_TLV_TYPE_MASTER_PREFERENCE, " Master preference"}, + {NAN_TLV_TYPE_CLUSTER_ID_LOW, " Cluster ID low"}, + {NAN_TLV_TYPE_CLUSTER_ID_HIGH, " Cluster ID high"}, + {NAN_TLV_TYPE_RSSI_AVERAGING_WINDOW_SIZE, + " RSSI averaging window size"}, + {NAN_TLV_TYPE_CLUSTER_OUI_NETWORK_ID, + " Cluster OUI network ID"}, + {NAN_TLV_TYPE_SOURCE_MAC_ADDRESS, + " Source MAC address"}, + {NAN_TLV_TYPE_CLUSTER_ATTRIBUTE_IN_SDF, + " Cluster attribute in SDF"}, + {NAN_TLV_TYPE_SOCIAL_CHANNEL_SCAN_PARAMS, + " Social channel scan params"}, + {NAN_TLV_TYPE_DEBUGGING_FLAGS, " Debugging flags"}, + {NAN_TLV_TYPE_POST_NAN_CONNECTIVITY_CAPABILITIES_TRANSMIT, + " Post nan connectivity capabilities transmit"}, + {NAN_TLV_TYPE_POST_NAN_DISCOVERY_ATTRIBUTE_TRANSMIT, + " Post nan discovery attribute transmit"}, + {NAN_TLV_TYPE_FURTHER_AVAILABILITY_MAP, + " Further availability map"}, + {NAN_TLV_TYPE_HOP_COUNT_FORCE, " Hop count force"}, + {NAN_TLV_TYPE_RANDOM_FACTOR_FORCE, + " Random factor force"}, + {NAN_TLV_TYPE_RANDOM_UPDATE_TIME, + " Random update time"}, + {NAN_TLV_TYPE_EARLY_WAKEUP, " Early wakeup"}, + {NAN_TLV_TYPE_PERIODIC_SCAN_INTERVAL, + " Periodic scan interval"}, + {NAN_TLV_TYPE_DW_INTERVAL, " DW interval"}, + {NAN_TLV_TYPE_DB_INTERVAL, " DB interval"}, + {NAN_TLV_TYPE_FURTHER_AVAILABILITY, + " Further availability"}, + {NAN_TLV_TYPE_24G_CHANNEL, " 2.4G channel"}, + {NAN_TLV_TYPE_5G_CHANNEL, " 5G channel"}, + {NAN_TLV_TYPE_CONFIG_LAST, " Config last"}, + + /* Attributes types */ + {NAN_TLV_TYPE_ATTRS_FIRST, " Attributes first"}, + {NAN_TLV_TYPE_AVAILABILITY_INTERVALS_MAP, + " Availability intervals map"}, + {NAN_TLV_TYPE_WLAN_MESH_ID, " WLAN mesh ID"}, + {NAN_TLV_TYPE_MAC_ADDRESS, " MAC address"}, + {NAN_TLV_TYPE_RECEIVED_RSSI_VALUE, + " Received RSSI value"}, + {NAN_TLV_TYPE_CLUSTER_ATTRIBUTE, + " Cluster attribute"}, + {NAN_TLV_TYPE_WLAN_INFRA_SSID, " WLAN infra SSID"}, + {NAN_TLV_TYPE_ATTRS_LAST, " Attributes last"}, + + /* Events Type */ + {NAN_TLV_TYPE_EVENTS_FIRST, " Events first"}, + {NAN_TLV_TYPE_EVENT_SELF_STATION_MAC_ADDRESS, + " Event Self station MAC address"}, + {NAN_TLV_TYPE_EVENT_STARTED_CLUSTER, + " Event started cluster"}, + {NAN_TLV_TYPE_EVENT_JOINED_CLUSTER, + " Event joined cluster"}, + {NAN_TLV_TYPE_EVENT_CLUSTER_SCAN_RESULTS, + " Event cluster scan results"}, + {NAN_TLV_TYPE_FAW_MEM_AVAIL, + " FAW memory availability"}, + {NAN_TLV_TYPE_EVENTS_LAST, " Events last"}, + + /* TCA types */ + {NAN_TLV_TYPE_TCA_FIRST, " TCA-Threshold Crossing Alert first"}, + {NAN_TLV_TYPE_CLUSTER_SIZE_REQ, + " Cluster size request"}, + {NAN_TLV_TYPE_CLUSTER_SIZE_RSP, + " Cluster size response"}, + {NAN_TLV_TYPE_TCA_LAST, " TCA last"}, + + /* Statistics types */ + {NAN_TLV_TYPE_STATS_FIRST, " Stats first"}, + {NAN_TLV_TYPE_DE_PUBLISH_STATS, + " Discovery engine publish stats"}, + {NAN_TLV_TYPE_DE_SUBSCRIBE_STATS, + " Discovery engine subscribe stats"}, + {NAN_TLV_TYPE_DE_MAC_STATS, + " Discovery engine MAC stats"}, + {NAN_TLV_TYPE_DE_TIMING_SYNC_STATS, + " Discovery engine timing sync stats"}, + {NAN_TLV_TYPE_DE_DW_STATS, + " Discovery engine DW stats"}, + {NAN_TLV_TYPE_DE_STATS, " Discovery engine stats"}, + {NAN_TLV_TYPE_STATS_LAST, " Stats last"}, + + {NAN_TLV_TYPE_LAST, " Last"} +}; + +struct errorCode { + NanStatusType frameworkError; + NanInternalStatusType firmwareError; + char nan_error[NAN_ERROR_STR_LEN]; +}; + +struct errorCode errorCodeTranslation[] = { + {NAN_STATUS_SUCCESS, NAN_I_STATUS_SUCCESS, + "NAN status success"}, + + {NAN_STATUS_INTERNAL_FAILURE, NAN_I_STATUS_DE_FAILURE, + "NAN Discovery engine failure"}, + + {NAN_STATUS_INVALID_PUBLISH_SUBSCRIBE_ID, NAN_I_STATUS_INVALID_HANDLE, + "Invalid Publish/Subscribe ID"}, + + {NAN_STATUS_NO_RESOURCE_AVAILABLE, NAN_I_STATUS_NO_SPACE_AVAILABLE, + "No space available"}, + + {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_PUBLISH_TYPE, + "Invalid Publish type, can be 0 or 1"}, + {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_TX_TYPE, + "Invalid Tx type"}, + {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_MSG_VERSION, + "Invalid internal message version"}, + {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_MSG_LEN, + "Invalid message length"}, + {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_MSG_ID, + "Invalid message ID"}, + {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_MATCH_ALGORITHM, + "Invalid matching algorithm, can be 0(match once), 1(match continuous) or 2(match never)"}, + {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_TLV_LEN, + "Invalid TLV length"}, + {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_TLV_TYPE, + "Invalid TLV type"}, + {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_MISSING_TLV_TYPE, + "Missing TLV type"}, + {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_TOTAL_TLVS_LEN, + "Invalid total TLV length"}, + {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_TLV_VALUE, + "Invalid TLV value"}, + {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_TX_PRIORITY, + "Invalid Tx priority"}, + {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_CONNECTION_MAP, + "Invalid connection map"}, + {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_THRESHOLD_CROSSING_ALERT_ID, + "Invalid TCA-Threshold Crossing Alert ID"}, + {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_STATS_ID, + "Invalid STATS ID"}, + + {NAN_STATUS_PROTOCOL_FAILURE, NAN_I_STATUS_TX_FAIL, + "Tx Fail"}, + + {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_RSSI_CLOSE_VALUE, + "Invalid RSSI close value range is 20dbm to 60dbm"}, + {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_RSSI_MIDDLE_VALUE, + "Invalid RSSI middle value range is 20dbm to 75dbm"}, + {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_HOP_COUNT_LIMIT, + "Invalid hop count limit, max hop count limit is 5"}, + {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_HIGH_CLUSTER_ID_VALUE, + "Invalid cluster ID value. Please set the cluster id high greater than the cluster id low"}, + {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_BACKGROUND_SCAN_PERIOD, + "Invalid background scan period. The range is 10 to 30 milliseconds"}, + {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_SCAN_CHANNEL, + "Invalid scan channel. Only valid channels are the NAN social channels"}, + {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_POST_NAN_CONNECTIVITY_CAPABILITIES_BITMAP, + "Invalid post nan connectivity bitmap"}, + {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_FURTHER_AVAILABILITY_MAP_NUMCHAN_VALUE, + "Invalid further availability map number of channel value"}, + {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_FURTHER_AVAILABILITY_MAP_DURATION_VALUE, + "Invalid further availability map duration value"}, + {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_FURTHER_AVAILABILITY_MAP_CLASS_VALUE, + "Invalid further availability map class value"}, + {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_FURTHER_AVAILABILITY_MAP_CHANNEL_VALUE, + "Invalid further availability map channel value"}, + {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_FURTHER_AVAILABILITY_MAP_AVAILABILITY_INTERVAL_BITMAP_VALUE, + "Invalid further availability map availability interval bitmap value"}, + {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_FURTHER_AVAILABILITY_MAP_MAP_ID, + "Invalid further availability map map ID"}, + {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_POST_NAN_DISCOVERY_CONN_TYPE_VALUE, + "Invalid post nan discovery connection type value"}, + {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_POST_NAN_DISCOVERY_DEVICE_ROLE_VALUE, + "Invalid post nan discovery device role value"}, + {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_POST_NAN_DISCOVERY_DURATION_VALUE, + "Invalid post nan discovery duration value"}, + {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_POST_NAN_DISCOVERY_BITMAP_VALUE, + "Invalid post nan discovery bitmap value"}, + {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_MISSING_FUTHER_AVAILABILITY_MAP, + "Missing further availability map"}, + {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_BAND_CONFIG_FLAGS, + "Invalid band configuration flags"}, + {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_RANDOM_FACTOR_UPDATE_TIME_VALUE, + "Invalid random factor update time value"}, + {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_ONGOING_SCAN_PERIOD, + "Invalid ongoing scan period"}, + {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_DW_INTERVAL_VALUE, + "Invalid DW interval value"}, + {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_DB_INTERVAL_VALUE, + "Invalid DB interval value"}, + + {NAN_STATUS_SUCCESS, NAN_I_PUBLISH_SUBSCRIBE_TERMINATED_REASON_TIMEOUT, + "Terminated Reason: Timeout"}, + {NAN_STATUS_SUCCESS, NAN_I_PUBLISH_SUBSCRIBE_TERMINATED_REASON_USER_REQUEST, + "Terminated Reason: User Request"}, + {NAN_STATUS_SUCCESS, NAN_I_PUBLISH_SUBSCRIBE_TERMINATED_REASON_COUNT_REACHED, + "Terminated Reason: Count Reached"}, + + {NAN_STATUS_INVALID_REQUESTOR_INSTANCE_ID, NAN_I_STATUS_INVALID_REQUESTER_INSTANCE_ID, + "Invalid match handle"}, + {NAN_STATUS_NAN_NOT_ALLOWED, NAN_I_STATUS_NAN_NOT_ALLOWED, + "Nan not allowed"}, + {NAN_STATUS_NO_OTA_ACK, NAN_I_STATUS_NO_OTA_ACK, + "No OTA ack"}, + {NAN_STATUS_ALREADY_ENABLED, NAN_I_STATUS_NAN_ALREADY_ENABLED, + "NAN is Already enabled"}, + {NAN_STATUS_FOLLOWUP_QUEUE_FULL, NAN_I_STATUS_FOLLOWUP_QUEUE_FULL, + "Follow-up queue full"}, + + {NAN_STATUS_UNSUPPORTED_CONCURRENCY_NAN_DISABLED, NDP_I_UNSUPPORTED_CONCURRENCY, + "Unsupported Concurrency"}, + + {NAN_STATUS_INTERNAL_FAILURE, NDP_I_NAN_DATA_IFACE_CREATE_FAILED, + "NAN data interface create failed"}, + {NAN_STATUS_INTERNAL_FAILURE, NDP_I_NAN_DATA_IFACE_DELETE_FAILED, + "NAN data interface delete failed"}, + {NAN_STATUS_INTERNAL_FAILURE, NDP_I_DATA_INITIATOR_REQUEST_FAILED, + "NAN data initiator request failed"}, + {NAN_STATUS_INTERNAL_FAILURE, NDP_I_DATA_RESPONDER_REQUEST_FAILED, + "NAN data responder request failed"}, + + {NAN_STATUS_INVALID_NDP_ID, NDP_I_INVALID_NDP_INSTANCE_ID, + "Invalid NDP instance ID"}, + + {NAN_STATUS_INVALID_PARAM, NDP_I_INVALID_RESPONSE_CODE, + "Invalid response code"}, + {NAN_STATUS_INVALID_PARAM, NDP_I_INVALID_APP_INFO_LEN, + "Invalid app info length"}, + + {NAN_STATUS_PROTOCOL_FAILURE, NDP_I_MGMT_FRAME_REQUEST_FAILED, + "Management frame request failed"}, + {NAN_STATUS_PROTOCOL_FAILURE, NDP_I_MGMT_FRAME_RESPONSE_FAILED, + "Management frame response failed"}, + {NAN_STATUS_PROTOCOL_FAILURE, NDP_I_MGMT_FRAME_CONFIRM_FAILED, + "Management frame confirm failed"}, + + {NAN_STATUS_INTERNAL_FAILURE, NDP_I_END_FAILED, + "NDP end failed"}, + + {NAN_STATUS_PROTOCOL_FAILURE, NDP_I_MGMT_FRAME_END_REQUEST_FAILED, + "Management frame end request failed"}, + + {NAN_STATUS_INTERNAL_FAILURE, NDP_I_VENDOR_SPECIFIC_ERROR, + "Vendor specific error"} +}; + +void NanCommand::NanErrorTranslation(NanInternalStatusType firmwareErrorRecvd, + u32 valueRcvd, + void* pResponse, + bool is_ndp_rsp) +{ + int i = 0, j = 0; + u16 msg_id; /* Based on the message_id in the header determine the Indication type */ + NanResponseMsg *pRsp; + NanPublishTerminatedInd* pRspInd; + NanDisabledInd* pRspdInd; + char tlvInfo[NAN_ERROR_STR_LEN]; + tlvInfo[0] = '\0'; + + if ((is_ndp_rsp == true) || isNanResponse()) { + pRsp = (NanResponseMsg*)pResponse; + for (i = 0; i < (int)(sizeof(errorCodeTranslation)/ sizeof(errorCode)); i++) { + if (errorCodeTranslation[i].firmwareError == firmwareErrorRecvd) { + pRsp->status = errorCodeTranslation[i].frameworkError; + strlcpy(pRsp->nan_error, errorCodeTranslation[i].nan_error, NAN_ERROR_STR_LEN); + if (NAN_I_STATUS_INVALID_TLV_TYPE == firmwareErrorRecvd) { + for (j = 0; j < (int)(sizeof(tlvToStr)/sizeof(verboseTlv)); j++) { + if (tlvToStr[j].tlvType == valueRcvd) { + strlcpy(tlvInfo, tlvToStr[i].strTlv, NAN_ERROR_STR_LEN); + break; + } + } + } + strlcat(pRsp->nan_error, tlvInfo, sizeof(pRsp->nan_error)); + break; + } + } + if (i == (int)(sizeof(errorCodeTranslation)/sizeof(errorCode))) { + pRsp->status = NAN_STATUS_INTERNAL_FAILURE; + strlcpy(pRsp->nan_error, "NAN Discovery engine failure", NAN_ERROR_STR_LEN); + } + ALOGD("%s: Status: %d Error Info[value %d]: %s", __FUNCTION__, pRsp->status, valueRcvd, pRsp->nan_error); + } else { + msg_id = getIndicationType(); + + switch(msg_id) { + case NAN_INDICATION_PUBLISH_TERMINATED: + case NAN_INDICATION_SUBSCRIBE_TERMINATED: + case NAN_INDICATION_SELF_TRANSMIT_FOLLOWUP: + pRspInd = (NanPublishTerminatedInd*)pResponse; + for (i = 0; i < (int)(sizeof(errorCodeTranslation)/ sizeof(errorCode)); i++) { + if (errorCodeTranslation[i].firmwareError == firmwareErrorRecvd) { + pRspInd->reason = errorCodeTranslation[i].frameworkError; + strlcpy(pRspInd->nan_reason, errorCodeTranslation[i].nan_error, NAN_ERROR_STR_LEN); + break; + } + } + if (i == (int)(sizeof(errorCodeTranslation)/sizeof(errorCode))) { + pRspInd->reason = NAN_STATUS_INTERNAL_FAILURE; + strlcpy(pRspInd->nan_reason, "NAN Discovery engine failure", NAN_ERROR_STR_LEN); + } + ALOGD("%s: Status: %d Error Info[value %d]: %s", __FUNCTION__, pRspInd->reason, valueRcvd, pRspInd->nan_reason); + break; + case NAN_INDICATION_DISABLED: + pRspdInd = (NanDisabledInd*)pResponse; + for (i = 0; i < (int)(sizeof(errorCodeTranslation)/ sizeof(errorCode)); i++) { + if (errorCodeTranslation[i].firmwareError == firmwareErrorRecvd) { + pRspdInd->reason = errorCodeTranslation[i].frameworkError; + strlcpy(pRspdInd->nan_reason, errorCodeTranslation[i].nan_error, NAN_ERROR_STR_LEN); + break; + } + } + if (i == (int)(sizeof(errorCodeTranslation)/sizeof(errorCode))) { + pRspdInd->reason = NAN_STATUS_INTERNAL_FAILURE; + strlcpy(pRspdInd->nan_reason, "NAN Discovery engine failure", NAN_ERROR_STR_LEN); + } + ALOGD("%s: Status: %d Error Info[value %d]: %s", __FUNCTION__, pRspdInd->reason, valueRcvd, pRspdInd->nan_reason); + break; + } + } +} + +int NanCommand::getNanResponse(transaction_id *id, NanResponseMsg *pRsp) +{ + if (mNanVendorEvent == NULL || pRsp == NULL) { + ALOGE("NULL check failed"); + return WIFI_ERROR_INVALID_ARGS; + } + + NanMsgHeader *pHeader = (NanMsgHeader *)mNanVendorEvent; + + switch (pHeader->msgId) { + case NAN_MSG_ID_ERROR_RSP: + { + pNanErrorRspMsg pFwRsp = \ + (pNanErrorRspMsg)mNanVendorEvent; + *id = (transaction_id)pFwRsp->fwHeader.transactionId; + NanErrorTranslation((NanInternalStatusType)pFwRsp->status, pFwRsp->value, pRsp, false); + pRsp->response_type = NAN_RESPONSE_ERROR; + break; + } + case NAN_MSG_ID_CONFIGURATION_RSP: + { + pNanConfigurationRspMsg pFwRsp = \ + (pNanConfigurationRspMsg)mNanVendorEvent; + *id = (transaction_id)pFwRsp->fwHeader.transactionId; + NanErrorTranslation((NanInternalStatusType)pFwRsp->status, pFwRsp->value, pRsp, false); + pRsp->response_type = NAN_RESPONSE_CONFIG; + } + break; + case NAN_MSG_ID_PUBLISH_SERVICE_CANCEL_RSP: + { + pNanPublishServiceCancelRspMsg pFwRsp = \ + (pNanPublishServiceCancelRspMsg)mNanVendorEvent; + *id = (transaction_id)pFwRsp->fwHeader.transactionId; + NanErrorTranslation((NanInternalStatusType)pFwRsp->status, pFwRsp->value, pRsp, false); + pRsp->response_type = NAN_RESPONSE_PUBLISH_CANCEL; + pRsp->body.publish_response.publish_id = \ + pFwRsp->fwHeader.handle; + break; + } + case NAN_MSG_ID_PUBLISH_SERVICE_RSP: + { + pNanPublishServiceRspMsg pFwRsp = \ + (pNanPublishServiceRspMsg)mNanVendorEvent; + *id = (transaction_id)pFwRsp->fwHeader.transactionId; + NanErrorTranslation((NanInternalStatusType)pFwRsp->status, pFwRsp->value, pRsp, false); + pRsp->response_type = NAN_RESPONSE_PUBLISH; + pRsp->body.publish_response.publish_id = \ + pFwRsp->fwHeader.handle; + break; + } + case NAN_MSG_ID_SUBSCRIBE_SERVICE_RSP: + { + pNanSubscribeServiceRspMsg pFwRsp = \ + (pNanSubscribeServiceRspMsg)mNanVendorEvent; + *id = (transaction_id)pFwRsp->fwHeader.transactionId; + NanErrorTranslation((NanInternalStatusType)pFwRsp->status, pFwRsp->value, pRsp, false); + pRsp->response_type = NAN_RESPONSE_SUBSCRIBE; + pRsp->body.subscribe_response.subscribe_id = \ + pFwRsp->fwHeader.handle; + } + break; + case NAN_MSG_ID_SUBSCRIBE_SERVICE_CANCEL_RSP: + { + pNanSubscribeServiceCancelRspMsg pFwRsp = \ + (pNanSubscribeServiceCancelRspMsg)mNanVendorEvent; + *id = (transaction_id)pFwRsp->fwHeader.transactionId; + NanErrorTranslation((NanInternalStatusType)pFwRsp->status, pFwRsp->value, pRsp, false); + pRsp->response_type = NAN_RESPONSE_SUBSCRIBE_CANCEL; + pRsp->body.subscribe_response.subscribe_id = \ + pFwRsp->fwHeader.handle; + break; + } + case NAN_MSG_ID_TRANSMIT_FOLLOWUP_RSP: + { + pNanTransmitFollowupRspMsg pFwRsp = \ + (pNanTransmitFollowupRspMsg)mNanVendorEvent; + *id = (transaction_id)pFwRsp->fwHeader.transactionId; + NanErrorTranslation((NanInternalStatusType)pFwRsp->status, pFwRsp->value, pRsp, false); + pRsp->response_type = NAN_RESPONSE_TRANSMIT_FOLLOWUP; + break; + } + case NAN_MSG_ID_STATS_RSP: + { + pNanStatsRspMsg pFwRsp = \ + (pNanStatsRspMsg)mNanVendorEvent; + *id = (transaction_id)pFwRsp->fwHeader.transactionId; + NanErrorTranslation((NanInternalStatusType)pFwRsp->statsRspParams.status, + pFwRsp->statsRspParams.value, pRsp, false); + pRsp->response_type = NAN_RESPONSE_STATS; + pRsp->body.stats_response.stats_type = \ + (NanStatsType)pFwRsp->statsRspParams.statsType; + ALOGV("%s: stats_type:%d",__func__, + pRsp->body.stats_response.stats_type); + u8 *pInputTlv = pFwRsp->ptlv; + NanTlv outputTlv; + memset(&outputTlv, 0, sizeof(outputTlv)); + u16 readLen = 0; + int remainingLen = (mNanDataLen - \ + (sizeof(NanMsgHeader) + sizeof(NanStatsRspParams))); + if (remainingLen > 0) { + readLen = NANTLV_ReadTlv(pInputTlv, &outputTlv); + ALOGV("%s: Remaining Len:%d readLen:%d type:%d length:%d", + __func__, remainingLen, readLen, outputTlv.type, + outputTlv.length); + if (outputTlv.length <= \ + sizeof(pRsp->body.stats_response.data)) { + handleNanStatsResponse(pRsp->body.stats_response.stats_type, + (char *)outputTlv.value, + &pRsp->body.stats_response, + outputTlv.length); + } + } else + ALOGV("%s: No TLV's present",__func__); + break; + } + case NAN_MSG_ID_ENABLE_RSP: + { + pNanEnableRspMsg pFwRsp = \ + (pNanEnableRspMsg)mNanVendorEvent; + *id = (transaction_id)pFwRsp->fwHeader.transactionId; + NanErrorTranslation((NanInternalStatusType)pFwRsp->status, pFwRsp->value, pRsp, false); + pRsp->response_type = NAN_RESPONSE_ENABLED; + break; + } + case NAN_MSG_ID_DISABLE_RSP: + { + pNanDisableRspMsg pFwRsp = \ + (pNanDisableRspMsg)mNanVendorEvent; + *id = (transaction_id)pFwRsp->fwHeader.transactionId; + NanErrorTranslation((NanInternalStatusType)pFwRsp->status, 0, pRsp, false); + pRsp->response_type = NAN_RESPONSE_DISABLED; + break; + } + case NAN_MSG_ID_TCA_RSP: + { + pNanTcaRspMsg pFwRsp = \ + (pNanTcaRspMsg)mNanVendorEvent; + *id = (transaction_id)pFwRsp->fwHeader.transactionId; + NanErrorTranslation((NanInternalStatusType)pFwRsp->status, pFwRsp->value, pRsp, false); + pRsp->response_type = NAN_RESPONSE_TCA; + break; + } + case NAN_MSG_ID_BEACON_SDF_RSP: + { + pNanBeaconSdfPayloadRspMsg pFwRsp = \ + (pNanBeaconSdfPayloadRspMsg)mNanVendorEvent; + *id = (transaction_id)pFwRsp->fwHeader.transactionId; + NanErrorTranslation((NanInternalStatusType)pFwRsp->status, 0, pRsp, false); + pRsp->response_type = NAN_RESPONSE_BEACON_SDF_PAYLOAD; + break; + } + case NAN_MSG_ID_CAPABILITIES_RSP: + { + pNanCapabilitiesRspMsg pFwRsp = \ + (pNanCapabilitiesRspMsg)mNanVendorEvent; + *id = (transaction_id)pFwRsp->fwHeader.transactionId; + NanErrorTranslation((NanInternalStatusType)pFwRsp->status, pFwRsp->value, pRsp, false); + pRsp->response_type = NAN_GET_CAPABILITIES; + pRsp->body.nan_capabilities.max_concurrent_nan_clusters = \ + pFwRsp->max_concurrent_nan_clusters; + pRsp->body.nan_capabilities.max_publishes = \ + pFwRsp->max_publishes; + pRsp->body.nan_capabilities.max_subscribes = \ + pFwRsp->max_subscribes; + pRsp->body.nan_capabilities.max_service_name_len = \ + pFwRsp->max_service_name_len; + pRsp->body.nan_capabilities.max_match_filter_len = \ + pFwRsp->max_match_filter_len; + pRsp->body.nan_capabilities.max_total_match_filter_len = \ + pFwRsp->max_total_match_filter_len; + pRsp->body.nan_capabilities.max_service_specific_info_len = \ + pFwRsp->max_service_specific_info_len; + pRsp->body.nan_capabilities.max_vsa_data_len = \ + pFwRsp->max_vsa_data_len; + pRsp->body.nan_capabilities.max_mesh_data_len = \ + pFwRsp->max_mesh_data_len; + pRsp->body.nan_capabilities.max_ndi_interfaces = \ + pFwRsp->max_ndi_interfaces; + pRsp->body.nan_capabilities.max_ndp_sessions = \ + pFwRsp->max_ndp_sessions; + pRsp->body.nan_capabilities.max_app_info_len = \ + pFwRsp->max_app_info_len; + pRsp->body.nan_capabilities.max_queued_transmit_followup_msgs = \ + pFwRsp->max_queued_transmit_followup_msgs; + pRsp->body.nan_capabilities.ndp_supported_bands = \ + pFwRsp->ndp_supported_bands; + pRsp->body.nan_capabilities.cipher_suites_supported = \ + pFwRsp->cipher_suites_supported; + pRsp->body.nan_capabilities.max_scid_len = \ + pFwRsp->max_scid_len; + pRsp->body.nan_capabilities.is_ndp_security_supported = \ + pFwRsp->is_ndp_security_supported; + pRsp->body.nan_capabilities.max_sdea_service_specific_info_len = \ + pFwRsp->max_sdea_service_specific_info_len; + pRsp->body.nan_capabilities.max_subscribe_address = \ + pFwRsp->max_subscribe_address; + pRsp->body.nan_capabilities.ndpe_attr_supported = \ + pFwRsp->ndpe_attr_supported; + break; + } + default: + return -1; + } + return 0; +} + +int NanCommand::handleNanResponse() +{ + //parse the data and call + //the response callback handler with the populated + //NanResponseMsg + NanResponseMsg rsp_data; + int ret; + transaction_id id; + + ALOGV("handleNanResponse called %p", this); + memset(&rsp_data, 0, sizeof(rsp_data)); + //get the rsp_data + ret = getNanResponse(&id, &rsp_data); + + ALOGI("handleNanResponse ret:%d status:%u value:%s response_type:%u", + ret, rsp_data.status, rsp_data.nan_error, rsp_data.response_type); + if (ret == 0 && (rsp_data.response_type == NAN_RESPONSE_STATS) && + (mStaParam != NULL) && + (rsp_data.body.stats_response.stats_type == NAN_STATS_ID_DE_TIMING_SYNC)) { + /* + Fill the staParam with appropriate values and return from here. + No need to call NotifyResponse as the request is for getting the + STA response + */ + NanSyncStats *pSyncStats = &rsp_data.body.stats_response.data.sync_stats; + mStaParam->master_rank = pSyncStats->myRank; + mStaParam->master_pref = (pSyncStats->myRank & 0xFF00000000000000) >> 56; + mStaParam->random_factor = (pSyncStats->myRank & 0x00FF000000000000) >> 48; + mStaParam->hop_count = pSyncStats->currAmHopCount; + mStaParam->beacon_transmit_time = pSyncStats->currAmBTT; + mStaParam->ndp_channel_freq = pSyncStats->ndpChannelFreq; + + ALOGI("%s:0x%02x master_pref 0x%02x random_factor 0x%02x hop_count %u Channel", + __func__, mStaParam->master_pref, mStaParam->random_factor, + mStaParam->hop_count, mStaParam->ndp_channel_freq); + + return ret; + } + //Call the NotifyResponse Handler + if (ret == 0 && mHandler.NotifyResponse) { + (*mHandler.NotifyResponse)(id, &rsp_data); + } + return ret; +} + +void NanCommand::handleNanStatsResponse(NanStatsType stats_type, + char *rspBuf, + NanStatsResponse *pRsp, + u32 message_len) +{ + if (stats_type == NAN_STATS_ID_DE_PUBLISH) { + NanPublishStats publish_stats; + if (message_len != sizeof(NanPublishStats)) { + ALOGE("%s: stats_type = %d invalid stats length = %u expected length = %zu\n", + __func__, stats_type, message_len, sizeof(NanPublishStats)); + return; + } + FwNanPublishStats *pPubStats = (FwNanPublishStats *)rspBuf; + + publish_stats.validPublishServiceReqMsgs = + pPubStats->validPublishServiceReqMsgs; + publish_stats.validPublishServiceRspMsgs = + pPubStats->validPublishServiceRspMsgs; + publish_stats.validPublishServiceCancelReqMsgs = + pPubStats->validPublishServiceCancelReqMsgs; + publish_stats.validPublishServiceCancelRspMsgs = + pPubStats->validPublishServiceCancelRspMsgs; + publish_stats.validPublishRepliedIndMsgs = + pPubStats->validPublishRepliedIndMsgs; + publish_stats.validPublishTerminatedIndMsgs = + pPubStats->validPublishTerminatedIndMsgs; + publish_stats.validActiveSubscribes = pPubStats->validActiveSubscribes; + publish_stats.validMatches = pPubStats->validMatches; + publish_stats.validFollowups = pPubStats->validFollowups; + publish_stats.invalidPublishServiceReqMsgs = + pPubStats->invalidPublishServiceReqMsgs; + publish_stats.invalidPublishServiceCancelReqMsgs = + pPubStats->invalidPublishServiceCancelReqMsgs; + publish_stats.invalidActiveSubscribes = + pPubStats->invalidActiveSubscribes; + publish_stats.invalidMatches = pPubStats->invalidMatches; + publish_stats.invalidFollowups = pPubStats->invalidFollowups; + publish_stats.publishCount = pPubStats->publishCount; + publish_stats.publishNewMatchCount = pPubStats->publishNewMatchCount; + publish_stats.pubsubGlobalNewMatchCount = + pPubStats->pubsubGlobalNewMatchCount; + memcpy(&pRsp->data.publish_stats, &publish_stats, sizeof(NanPublishStats)); + } else if (stats_type == NAN_STATS_ID_DE_SUBSCRIBE) { + NanSubscribeStats sub_stats; + if (message_len != sizeof(NanSubscribeStats)) { + ALOGE("%s: stats_type = %d invalid stats length = %u expected length = %zu\n", + __func__, stats_type, message_len, sizeof(NanSubscribeStats)); + return; + } + FwNanSubscribeStats *pSubStats = (FwNanSubscribeStats *)rspBuf; + + sub_stats.validSubscribeServiceReqMsgs = + pSubStats->validSubscribeServiceReqMsgs; + sub_stats.validSubscribeServiceRspMsgs = + pSubStats->validSubscribeServiceRspMsgs; + sub_stats.validSubscribeServiceCancelReqMsgs = + pSubStats->validSubscribeServiceCancelReqMsgs; + sub_stats.validSubscribeServiceCancelRspMsgs = + pSubStats->validSubscribeServiceCancelRspMsgs; + sub_stats.validSubscribeTerminatedIndMsgs = + pSubStats->validSubscribeTerminatedIndMsgs; + sub_stats.validSubscribeMatchIndMsgs = + pSubStats->validSubscribeMatchIndMsgs; + sub_stats.validSubscribeUnmatchIndMsgs = + pSubStats->validSubscribeUnmatchIndMsgs; + sub_stats.validSolicitedPublishes = + pSubStats->validSolicitedPublishes; + sub_stats.validMatches = pSubStats->validMatches; + sub_stats.validFollowups = pSubStats->validFollowups; + sub_stats.invalidSubscribeServiceReqMsgs = + pSubStats->invalidSubscribeServiceReqMsgs; + sub_stats.invalidSubscribeServiceCancelReqMsgs = + pSubStats->invalidSubscribeServiceCancelReqMsgs; + sub_stats.invalidSubscribeFollowupReqMsgs = + pSubStats->invalidSubscribeFollowupReqMsgs; + sub_stats.invalidSolicitedPublishes = + pSubStats->invalidSolicitedPublishes; + sub_stats.invalidMatches = pSubStats->invalidMatches; + sub_stats.invalidFollowups = pSubStats->invalidFollowups; + sub_stats.subscribeCount = pSubStats->subscribeCount; + sub_stats.bloomFilterIndex = pSubStats->bloomFilterIndex; + sub_stats.subscribeNewMatchCount = pSubStats->subscribeNewMatchCount; + sub_stats.pubsubGlobalNewMatchCount = + pSubStats->pubsubGlobalNewMatchCount; + memcpy(&pRsp->data.subscribe_stats, &sub_stats, sizeof(NanSubscribeStats)); + } else if (stats_type == NAN_STATS_ID_DE_DW) { + NanDWStats dw_stats; + if (message_len != sizeof(NanDWStats)) { + ALOGE("%s: stats_type = %d invalid stats length = %u expected length = %zu\n", + __func__, stats_type, message_len, sizeof(NanDWStats)); + return; + } + FwNanMacStats *pMacStats = (FwNanMacStats *)rspBuf; + + dw_stats.validFrames = pMacStats->validFrames; + dw_stats.validActionFrames = pMacStats->validActionFrames; + dw_stats.validBeaconFrames = pMacStats->validBeaconFrames; + dw_stats.ignoredActionFrames = pMacStats->ignoredActionFrames; + dw_stats.ignoredBeaconFrames = pMacStats->ignoredBeaconFrames; + dw_stats.invalidFrames = pMacStats->invalidFrames; + dw_stats.invalidActionFrames = pMacStats->invalidActionFrames; + dw_stats.invalidBeaconFrames = pMacStats->invalidBeaconFrames; + dw_stats.invalidMacHeaders = pMacStats->invalidMacHeaders; + dw_stats.invalidPafHeaders = pMacStats->invalidPafHeaders; + dw_stats.nonNanBeaconFrames = pMacStats->nonNanBeaconFrames; + dw_stats.earlyActionFrames = pMacStats->earlyActionFrames; + dw_stats.inDwActionFrames = pMacStats->inDwActionFrames; + dw_stats.lateActionFrames = pMacStats->lateActionFrames; + dw_stats.framesQueued = pMacStats->framesQueued; + dw_stats.totalTRSpUpdates = pMacStats->totalTRSpUpdates; + dw_stats.completeByTRSp = pMacStats->completeByTRSp; + dw_stats.completeByTp75DW = pMacStats->completeByTp75DW; + dw_stats.completeByTendDW = pMacStats->completeByTendDW; + dw_stats.lateActionFramesTx = pMacStats->lateActionFramesTx; + memcpy(&pRsp->data.dw_stats, &dw_stats, sizeof(NanDWStats)); + } else if (stats_type == NAN_STATS_ID_DE_MAC) { + NanMacStats mac_stats; + if (message_len != sizeof(NanMacStats)) { + ALOGE("%s: stats_type = %d invalid stats length = %u expected length = %zu\n", + __func__, stats_type, message_len, sizeof(NanMacStats)); + return; + } + FwNanMacStats *pMacStats = (FwNanMacStats *)rspBuf; + + mac_stats.validFrames = pMacStats->validFrames; + mac_stats.validActionFrames = pMacStats->validActionFrames; + mac_stats.validBeaconFrames = pMacStats->validBeaconFrames; + mac_stats.ignoredActionFrames = pMacStats->ignoredActionFrames; + mac_stats.ignoredBeaconFrames = pMacStats->ignoredBeaconFrames; + mac_stats.invalidFrames = pMacStats->invalidFrames; + mac_stats.invalidActionFrames = pMacStats->invalidActionFrames; + mac_stats.invalidBeaconFrames = pMacStats->invalidBeaconFrames; + mac_stats.invalidMacHeaders = pMacStats->invalidMacHeaders; + mac_stats.invalidPafHeaders = pMacStats->invalidPafHeaders; + mac_stats.nonNanBeaconFrames = pMacStats->nonNanBeaconFrames; + mac_stats.earlyActionFrames = pMacStats->earlyActionFrames; + mac_stats.inDwActionFrames = pMacStats->inDwActionFrames; + mac_stats.lateActionFrames = pMacStats->lateActionFrames; + mac_stats.framesQueued = pMacStats->framesQueued; + mac_stats.totalTRSpUpdates = pMacStats->totalTRSpUpdates; + mac_stats.completeByTRSp = pMacStats->completeByTRSp; + mac_stats.completeByTp75DW = pMacStats->completeByTp75DW; + mac_stats.completeByTendDW = pMacStats->completeByTendDW; + mac_stats.lateActionFramesTx = pMacStats->lateActionFramesTx; + mac_stats.twIncreases = pMacStats->twIncreases; + mac_stats.twDecreases = pMacStats->twDecreases; + mac_stats.twChanges = pMacStats->twChanges; + mac_stats.twHighwater = pMacStats->twHighwater; + mac_stats.bloomFilterIndex = pMacStats->bloomFilterIndex; + memcpy(&pRsp->data.mac_stats, &mac_stats, sizeof(NanMacStats)); + } else if (stats_type == NAN_STATS_ID_DE_TIMING_SYNC) { + NanSyncStats sync_stats; + if (message_len != sizeof(NanSyncStats)) { + ALOGE("%s: stats_type = %d invalid stats length = %u expected length = %zu\n", + __func__, stats_type, message_len, sizeof(NanSyncStats)); + return; + } + FwNanSyncStats *pSyncStats = (FwNanSyncStats *)rspBuf; + + sync_stats.currTsf = pSyncStats->currTsf; + sync_stats.myRank = pSyncStats->myRank; + sync_stats.currAmRank = pSyncStats->currAmRank; + sync_stats.lastAmRank = pSyncStats->lastAmRank; + sync_stats.currAmBTT = pSyncStats->currAmBTT; + sync_stats.lastAmBTT = pSyncStats->lastAmBTT; + sync_stats.currAmHopCount = pSyncStats->currAmHopCount; + sync_stats.currRole = pSyncStats->currRole; + sync_stats.currClusterId = pSyncStats->currClusterId; + + sync_stats.timeSpentInCurrRole = pSyncStats->timeSpentInCurrRole; + sync_stats.totalTimeSpentAsMaster = pSyncStats->totalTimeSpentAsMaster; + sync_stats.totalTimeSpentAsNonMasterSync = + pSyncStats->totalTimeSpentAsNonMasterSync; + sync_stats.totalTimeSpentAsNonMasterNonSync = + pSyncStats->totalTimeSpentAsNonMasterNonSync; + sync_stats.transitionsToAnchorMaster = + pSyncStats->transitionsToAnchorMaster; + sync_stats.transitionsToMaster = + pSyncStats->transitionsToMaster; + sync_stats.transitionsToNonMasterSync = + pSyncStats->transitionsToNonMasterSync; + sync_stats.transitionsToNonMasterNonSync = + pSyncStats->transitionsToNonMasterNonSync; + sync_stats.amrUpdateCount = pSyncStats->amrUpdateCount; + sync_stats.amrUpdateRankChangedCount = + pSyncStats->amrUpdateRankChangedCount; + sync_stats.amrUpdateBTTChangedCount = + pSyncStats->amrUpdateBTTChangedCount; + sync_stats.amrUpdateHcChangedCount = + pSyncStats->amrUpdateHcChangedCount; + sync_stats.amrUpdateNewDeviceCount = + pSyncStats->amrUpdateNewDeviceCount; + sync_stats.amrExpireCount = pSyncStats->amrExpireCount; + sync_stats.mergeCount = pSyncStats->mergeCount; + sync_stats.beaconsAboveHcLimit = pSyncStats->beaconsAboveHcLimit; + sync_stats.beaconsBelowRssiThresh = pSyncStats->beaconsBelowRssiThresh; + sync_stats.beaconsIgnoredNoSpace = pSyncStats->beaconsIgnoredNoSpace; + sync_stats.beaconsForOurCluster = pSyncStats->beaconsForOtherCluster; + sync_stats.beaconsForOtherCluster = pSyncStats->beaconsForOtherCluster; + sync_stats.beaconCancelRequests = pSyncStats->beaconCancelRequests; + sync_stats.beaconCancelFailures = pSyncStats->beaconCancelFailures; + sync_stats.beaconUpdateRequests = pSyncStats->beaconUpdateRequests; + sync_stats.beaconUpdateFailures = pSyncStats->beaconUpdateFailures; + sync_stats.syncBeaconTxAttempts = pSyncStats->syncBeaconTxAttempts; + sync_stats.syncBeaconTxFailures = pSyncStats->syncBeaconTxFailures; + sync_stats.discBeaconTxAttempts = pSyncStats->discBeaconTxAttempts; + sync_stats.discBeaconTxFailures = pSyncStats->discBeaconTxFailures; + sync_stats.amHopCountExpireCount = pSyncStats->amHopCountExpireCount; + sync_stats.ndpChannelFreq = pSyncStats->ndpChannelFreq; + sync_stats.ndpChannelFreq2 = pSyncStats->ndpChannelFreq2; + sync_stats.schedUpdateChannelFreq = pSyncStats->schedUpdateChannelFreq; + memcpy(&pRsp->data.sync_stats, &sync_stats, sizeof(NanSyncStats)); + } else if (stats_type == NAN_STATS_ID_DE) { + NanDeStats de_stats; + if (message_len != sizeof(NanDeStats)) { + ALOGE("%s: stats_type = %d invalid stats length = %u expected length = %zu\n", + __func__, stats_type, message_len, sizeof(NanDeStats)); + return; + } + FwNanDeStats *pDeStats = (FwNanDeStats *)rspBuf; + + de_stats.validErrorRspMsgs = pDeStats->validErrorRspMsgs; + de_stats.validTransmitFollowupReqMsgs = + pDeStats->validTransmitFollowupReqMsgs; + de_stats.validTransmitFollowupRspMsgs = + pDeStats->validTransmitFollowupRspMsgs; + de_stats.validFollowupIndMsgs = + pDeStats->validFollowupIndMsgs; + de_stats.validConfigurationReqMsgs = + pDeStats->validConfigurationReqMsgs; + de_stats.validConfigurationRspMsgs = + pDeStats->validConfigurationRspMsgs; + de_stats.validStatsReqMsgs = pDeStats->validStatsReqMsgs; + de_stats.validStatsRspMsgs = pDeStats->validStatsRspMsgs; + de_stats.validEnableReqMsgs = pDeStats->validEnableReqMsgs; + de_stats.validEnableRspMsgs = pDeStats->validEnableRspMsgs; + de_stats.validDisableReqMsgs = pDeStats->validDisableReqMsgs; + de_stats.validDisableRspMsgs = pDeStats->validDisableRspMsgs; + de_stats.validDisableIndMsgs = pDeStats->validDisableIndMsgs; + de_stats.validEventIndMsgs = pDeStats->validEventIndMsgs; + de_stats.validTcaReqMsgs = pDeStats->validTcaReqMsgs; + de_stats.validTcaRspMsgs = pDeStats->validTcaRspMsgs; + de_stats.validTcaIndMsgs = pDeStats->validTcaIndMsgs; + de_stats.invalidTransmitFollowupReqMsgs = + pDeStats->invalidTransmitFollowupReqMsgs; + de_stats.invalidConfigurationReqMsgs = + pDeStats->invalidConfigurationReqMsgs; + de_stats.invalidStatsReqMsgs = pDeStats->invalidStatsReqMsgs; + de_stats.invalidEnableReqMsgs = pDeStats->invalidEnableReqMsgs; + de_stats.invalidDisableReqMsgs = pDeStats->invalidDisableReqMsgs; + de_stats.invalidTcaReqMsgs = pDeStats->invalidTcaReqMsgs; + memcpy(&pRsp->data.de_stats, &de_stats, sizeof(NanDeStats)); + } else { + ALOGE("Unknown stats_type:%d\n", stats_type); + } +} + +int NanCommand::handleNdpResponse(NanResponseType ndpCmdType, + struct nlattr **tb_vendor) +{ + //parse the data and call + //the response callback handler with the populated + //NanResponseMsg + NanResponseMsg rsp_data; + transaction_id id; + + memset(&rsp_data, 0, sizeof(rsp_data)); + + if ((!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) || + (!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE]) || + (!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE])) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_NDP not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + + id = nla_get_u16(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]); + ALOGD("%s: Transaction id : val %d", __FUNCTION__, id); + + NanErrorTranslation((NanInternalStatusType)nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE]), + nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE]), &rsp_data, true); + rsp_data.response_type = ndpCmdType; + + if (ndpCmdType == NAN_DP_INITIATOR_RESPONSE) + { + if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_NDP not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + rsp_data.body.data_request_response.ndp_instance_id = + nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID]); + } + //Call the NotifyResponse Handler + if (mHandler.NotifyResponse) { + (*mHandler.NotifyResponse)(id, &rsp_data); + } + return WIFI_SUCCESS; +} |