Merge commit '2268d748b893f82330f1be50b09d699cb8e7f9d3' into HEAD

Change-Id: I00331c122f55594e36d3766504a2da5ca4aa4fed
diff --git a/qcwcn/wifi_hal/nan.cpp b/qcwcn/wifi_hal/nan.cpp
index f3a7457..524bacb 100644
--- a/qcwcn/wifi_hal/nan.cpp
+++ b/qcwcn/wifi_hal/nan.cpp
@@ -21,6 +21,7 @@
 #include "common.h"
 #include "cpp_bindings.h"
 #include <utils/Log.h>
+#include <errno.h>
 #include "nancommand.h"
 #include "vendor_definitions.h"
 
@@ -32,6 +33,8 @@
 #define STRUCT_PACKED
 #endif
 
+#define OUT_OF_BAND_SERVICE_INSTANCE_ID 0
+
 //Singleton Static Instance
 NanCommand* NanCommand::mNanCommandInstance  = NULL;
 
@@ -592,9 +595,10 @@
 }
 
 /*  Function to get NAN capabilities */
-wifi_error nan_availability_config(transaction_id id,
+wifi_error nan_debug_command_config(transaction_id id,
                                    wifi_interface_handle iface,
-                                   NanAvailabilityDebug debug)
+                                   NanDebugParams debug,
+                                   int debug_msg_length)
 {
     int ret = 0;
     NanCommand *nanCommand = NULL;
@@ -610,6 +614,12 @@
         return WIFI_ERROR_UNKNOWN;
     }
 
+    if (debug_msg_length <= 0) {
+        ALOGE("%s: Invalid debug message length = %d", __FUNCTION__,
+                                                       debug_msg_length);
+        return WIFI_ERROR_UNKNOWN;
+    }
+
     ret = nanCommand->create();
     if (ret < 0)
         goto cleanup;
@@ -619,9 +629,9 @@
     if (ret < 0)
         goto cleanup;
 
-    ret = nanCommand->putNanAvailabilityDebug(debug);
+    ret = nanCommand->putNanDebugCommand(debug, debug_msg_length);
     if (ret != 0) {
-        ALOGE("%s: putNanAvailabilityDebug Error:%d",__FUNCTION__, ret);
+        ALOGE("%s: putNanDebugCommand Error:%d",__FUNCTION__, ret);
         goto cleanup;
     }
 
@@ -674,6 +684,7 @@
                                      wifi_interface_handle iface,
                                      char* iface_name)
 {
+    ALOGV("NAN_DP_INTERFACE_CREATE");
     int ret = WIFI_SUCCESS;
     struct nlattr *nlData;
     NanCommand *nanCommand = NULL;
@@ -721,6 +732,7 @@
                                      wifi_interface_handle iface,
                                      char* iface_name)
 {
+    ALOGV("NAN_DP_INTERFACE_DELETE");
     int ret = WIFI_SUCCESS;
     struct nlattr *nlData;
     NanCommand *nanCommand = NULL;
@@ -768,6 +780,7 @@
                                       wifi_interface_handle iface,
                                       NanDataPathInitiatorRequest* msg)
 {
+    ALOGV("NAN_DP_REQUEST_INITIATOR");
     int ret = WIFI_SUCCESS;
     struct nlattr *nlData, *nlCfgSecurity, *nlCfgQos;
     NanCommand *nanCommand = NULL;
@@ -782,6 +795,22 @@
         return (wifi_error)ret;
     }
 
+    if ((msg->cipher_type != NAN_CIPHER_SUITE_SHARED_KEY_NONE) &&
+        (msg->key_info.body.pmk_info.pmk_len == 0) &&
+        (msg->key_info.body.passphrase_info.passphrase_len == 0)) {
+        ALOGE("%s: Failed-Initiator req, missing pmk and passphrase",
+               __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+
+    if ((msg->cipher_type != NAN_CIPHER_SUITE_SHARED_KEY_NONE) &&
+        (msg->requestor_instance_id == OUT_OF_BAND_SERVICE_INSTANCE_ID) &&
+        (msg->service_name_len == 0)) {
+        ALOGE("%s: Failed-Initiator req, missing service name for out of band request",
+              __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+
     /* Add the vendor specific attributes for the NL command. */
     nlData = nanCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
     if (!nlData)
@@ -849,11 +878,30 @@
         if (nanCommand->put_u32(QCA_WLAN_VENDOR_ATTR_NDP_CSID,
                 msg->cipher_type))
             goto cleanup;
-    }
-    if (msg->pmk_len == NAN_PMK_INFO_LEN) {
-        if (nanCommand->put_bytes(QCA_WLAN_VENDOR_ATTR_NDP_PMK,
-            (char *)msg->pmk, msg->pmk_len))
-            goto cleanup;
+
+        if ( msg->key_info.key_type == NAN_SECURITY_KEY_INPUT_PMK &&
+             msg->key_info.body.pmk_info.pmk_len == NAN_PMK_INFO_LEN) {
+            if (nanCommand->put_bytes(QCA_WLAN_VENDOR_ATTR_NDP_PMK,
+                (char *)msg->key_info.body.pmk_info.pmk,
+                msg->key_info.body.pmk_info.pmk_len))
+                goto cleanup;
+        } else if (msg->key_info.key_type ==
+            NAN_SECURITY_KEY_INPUT_PASSPHRASE &&
+            msg->key_info.body.passphrase_info.passphrase_len >=
+            NAN_SECURITY_MIN_PASSPHRASE_LEN &&
+            msg->key_info.body.passphrase_info.passphrase_len <=
+            NAN_SECURITY_MAX_PASSPHRASE_LEN) {
+            if (nanCommand->put_bytes(QCA_WLAN_VENDOR_ATTR_NDP_PASSPHRASE,
+                (char *)msg->key_info.body.passphrase_info.passphrase,
+                msg->key_info.body.passphrase_info.passphrase_len))
+                goto cleanup;
+        }
+
+        if (msg->service_name_len) {
+            if (nanCommand->put_bytes(QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_NAME,
+                (char *)msg->service_name, msg->service_name_len))
+                goto cleanup;
+        }
     }
     nanCommand->attr_end(nlData);
 
@@ -870,6 +918,7 @@
                                         wifi_interface_handle iface,
                                         NanDataPathIndicationResponse* msg)
 {
+    ALOGV("NAN_DP_INDICATION_RESPONSE");
     int ret = WIFI_SUCCESS;
     struct nlattr *nlData, *nlCfgSecurity, *nlCfgQos;
     NanCommand *nanCommand = NULL;
@@ -884,6 +933,14 @@
         return (wifi_error)ret;
     }
 
+    if ((msg->cipher_type != NAN_CIPHER_SUITE_SHARED_KEY_NONE) &&
+        (msg->key_info.body.pmk_info.pmk_len == 0) &&
+        (msg->key_info.body.passphrase_info.passphrase_len == 0)) {
+        ALOGE("%s: Failed-Initiator req, missing pmk and passphrase",
+               __FUNCTION__);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+
     /* Add the vendor specific attributes for the NL command. */
     nlData = nanCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
     if (!nlData)
@@ -940,11 +997,29 @@
         if (nanCommand->put_u32(QCA_WLAN_VENDOR_ATTR_NDP_CSID,
                 msg->cipher_type))
             goto cleanup;
-    }
-    if (msg->pmk_len == NAN_PMK_INFO_LEN) {
-        if (nanCommand->put_bytes(QCA_WLAN_VENDOR_ATTR_NDP_PMK,
-            (char *)msg->pmk, msg->pmk_len))
-            goto cleanup;
+
+        if ( msg->key_info.key_type == NAN_SECURITY_KEY_INPUT_PMK &&
+             msg->key_info.body.pmk_info.pmk_len == NAN_PMK_INFO_LEN) {
+            if (nanCommand->put_bytes(QCA_WLAN_VENDOR_ATTR_NDP_PMK,
+                (char *)msg->key_info.body.pmk_info.pmk,
+                msg->key_info.body.pmk_info.pmk_len))
+                goto cleanup;
+        } else if (msg->key_info.key_type == NAN_SECURITY_KEY_INPUT_PASSPHRASE &&
+            msg->key_info.body.passphrase_info.passphrase_len >=
+            NAN_SECURITY_MIN_PASSPHRASE_LEN &&
+            msg->key_info.body.passphrase_info.passphrase_len <=
+            NAN_SECURITY_MAX_PASSPHRASE_LEN) {
+            if (nanCommand->put_bytes(QCA_WLAN_VENDOR_ATTR_NDP_PASSPHRASE,
+                (char *)msg->key_info.body.passphrase_info.passphrase,
+                msg->key_info.body.passphrase_info.passphrase_len))
+                goto cleanup;
+        }
+
+        if (msg->service_name_len) {
+            if (nanCommand->put_bytes(QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_NAME,
+                (char *)msg->service_name, msg->service_name_len))
+                goto cleanup;
+        }
     }
     nanCommand->attr_end(nlData);
 
@@ -961,6 +1036,7 @@
                         wifi_interface_handle iface,
                         NanDataPathEndRequest* msg)
 {
+    ALOGV("NAN_DP_END");
     int ret = WIFI_SUCCESS;
     struct nlattr *nlData;
     NanCommand *nanCommand = NULL;
diff --git a/qcwcn/wifi_hal/nan_cert.h b/qcwcn/wifi_hal/nan_cert.h
index 51945c2..d84b806 100644
--- a/qcwcn/wifi_hal/nan_cert.h
+++ b/qcwcn/wifi_hal/nan_cert.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
 
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -36,6 +36,9 @@
 {
 #endif /* __cplusplus */
 
+#define NAN_CERT_VERSION                        2
+#define NAN_MAX_DEBUG_MESSAGE_DATA_LEN          100
+
 typedef struct {
     /* NAN master rank being advertised by DE */
     u64 master_rank;
@@ -50,28 +53,123 @@
     u32 ndp_channel_freq;
 } NanStaParameter;
 
-typedef struct PACKED
-{
+/* NAN Data Path Supported Band */
+typedef enum {
+    NAN_DATA_PATH_SUPPORTED_BAND_2G = 1,
+    NAN_DATA_PATH_SUPPORTED_BAND_5G = 2,
+    NAN_DATA_PATH_SUPPORT_DUAL_BAND = 3
+} NdpSupportedBand;
+
+/* NAN Responder mode policy */
+typedef enum {
+    NAN_DATA_RESPONDER_MODE_AUTO    = 0,
+    NAN_DATA_RESPONDER_MODE_ACCEPT  = 1,
+    NAN_DATA_RESPONDER_MODE_REJECT  = 2,
+    NAN_DATA_RESPONDER_MODE_COUNTER = 3,
+    NAN_DATA_RESPONDER_MODE_COUNTER_NO_CHANNEL_CHANGE = 4
+} NanDataResponderMode;
+
+/* NAN Data Path M4 response type */
+typedef enum {
+    NAN_DATA_PATH_M4_RESPONSE_ACCEPT = 1,
+    NAN_DATA_PATH_M4_RESPONSE_REJECT = 2,
+    NAN_DATA_PATH_M4_RESPONSE_BADMIC = 3
+} NdpM4ResponseType;
+
+/* NAN NMF Security Clear type */
+typedef enum {
+    NAN_NMF_CLEAR_DISABLE = 0,
+    NAN_NMF_CLEAR_ENABLE = 1
+} NanNmfClearConfig;
+
+/* NAN Schedule type */
+typedef enum {
+    NAN_SCHED_VALID = 0,
+    NAN_SCHED_INVALID_BAD_FA = 1,
+    NAN_SCHED_INVALID_BAD_NDC = 2,
+    NAN_SCHED_INVALID_BAD_IMMU = 3
+} NanSchedType;
+
+ /*
+  * Definitions of debug subcommand type for the
+  * generic debug command.
+  */
+typedef enum {
+    NAN_TEST_MODE_CMD_NAN_AVAILABILITY = 1,
+    NAN_TEST_MODE_CMD_NDP_INCLUDE_IMMUTABLE = 2,
+    NAN_TEST_MODE_CMD_NDP_AVOID_CHANNEL = 3,
+    NAN_TEST_MODE_CMD_NAN_SUPPORTED_BANDS = 4,
+    NAN_TEST_MODE_CMD_AUTO_RESPONDER_MODE = 5,
+    NAN_TEST_MODE_CMD_M4_RESPONSE_TYPE = 6,
+    NAN_TEST_MODE_CMD_NAN_SCHED_TYPE = 7,
+    NAN_TEST_MODE_CMD_NAN_NMF_CLEAR_CONFIG = 8,
+    NAN_TEST_MODE_CMD_NAN_SCHED_UPDATE_ULW_NOTIFY = 9,
+    NAN_TEST_MODE_CMD_NAN_SCHED_UPDATE_NDL_NEGOTIATE = 10,
+    NAN_TEST_MODE_CMD_NAN_SCHED_UPDATE_NDL_NOTIFY = 11,
+    NAN_TEST_MODE_CMD_NAN_AVAILABILITY_MAP_ORDER = 12
+} NanDebugModeCmd;
+
+/*
+ * This debug command carries any one command type
+ * followed by corresponding command data content
+ * as indicated below.
+ *
+ * command: NAN_TEST_MODE_CMD_NAN_AVAILABILITY
+ * content: NAN Avaiability attribute blob
+ *
+ * command: NAN_TEST_MODE_CMD_NDP_INCLUDE_IMMUTABLE
+ * content: u32 value (0 - Ignore 1 - Include immuatable,
+ *                     2 - Don't include immutable)
+ *
+ * command: NAN_TEST_MODE_CMD_NDP_AVOID_CHANNEL
+ * content: u32 channel_frequency; (0 - Ignore)
+ *
+ * command: NAN_TEST_MODE_CMD_NAN_SUPPORTED_BANDS
+ * content: u32 supported_bands; (0 . Ignore, 1 . 2g,
+ *                                2 . 5g, 3 . 2g & 5g)
+ *
+ * command: NAN_TEST_MODE_CMD_AUTO_RESPONDER_MODE
+ * content: u32 auto_resp_mode; (0 . Auto, 1 . Accept,
+ *                               2 . Reject, 3 . Counter)
+ *
+ * command: NAN_TEST_MODE_CMD_M4_RESPONSE_TYPE
+ * content: u32 m4_response_type; (0.Ignore, 1.Accept,
+ *                                 2.Reject, 3.BadMic)
+ *
+ * command: NAN_TEST_MODE_CMD_NAN_SCHED_TYPE
+ * content: u32 invalid_nan_schedule; (0. Valid sched,
+ *                                     1.Invalid Sched bad FA,
+ *                                     2.Invalid schedbad NDC,
+ *                                     3.Invalid sched bad Immutable)
+ *
+ * command: NAN_TEST_MODE_CMD_NAN_NMF_CLEAR_CONFIG
+ * content: u32 nmf_security_config_val;(0:NAN_NMF_CLEAR_DISABLE,
+ *                                       1:NAN_NMF_CLEAR_ENABLE)
+ *
+ * command: NAN_TEST_MODE_CMD_NAN_SCHED_UPDATE_ULW_NOTIFY
+ * content: u32 channel_availability;(0/1)
+ *
+ * command: NAN_TEST_MODE_CMD_NAN_SCHED_UPDATE_NDL_NEGOTIATE
+ * content: responder_nmi_mac (Responder NMI Mac Address)
+ *
+ * command: NAN_TEST_MODE_CMD_NAN_SCHED_UPDATE_NDL_NOTIFY
+ * content: NONE
+ *
+ * command: NAN_TEST_MODE_CMD_NAN_AVAILABILITY_MAP_ORDER
+ * content: u32 map_order_val; (0/1)
+ *
+ */
+typedef struct PACKED {
     /*
-      Valid bit values:
-      0 - Invalidates any current and previous configuration of nan availability
-      1 - Current configuration is valid
-    */
-    u32 valid:1;
+     * To indicate the debug command type.
+     */
+    u32 cmd;
     /*
-      2g_band_availability bit values
-      0 - 2G band all channel and all slots not available
-      1 - 2G band all channel and all slots available
-    */
-    u32 band_availability_2g:1;
-    /*
-      5g_band_availability bit values
-      0 - 5G band all channel and all slots not available
-      1 - 5G band all channel and all slots available
-    */
-    u32 band_availability_5g:1;
-    u32 reserved:29;
-} NanAvailabilityDebug;
+     * To hold the data for the above command
+     * type.
+     */
+    u8 debug_cmd_data[NAN_MAX_DEBUG_MESSAGE_DATA_LEN];
+} NanDebugParams;
 
 /*
    Function to get the sta_parameter expected by Sigma
@@ -81,9 +179,10 @@
                                  wifi_interface_handle iface,
                                  NanStaParameter* msg);
 
-wifi_error nan_availability_config(transaction_id id,
+wifi_error nan_debug_command_config(transaction_id id,
                                    wifi_interface_handle iface,
-                                   NanAvailabilityDebug msg);
+                                   NanDebugParams msg,
+                                   int debug_msg_length);
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
diff --git a/qcwcn/wifi_hal/nan_i.h b/qcwcn/wifi_hal/nan_i.h
index abc3069..7202751 100644
--- a/qcwcn/wifi_hal/nan_i.h
+++ b/qcwcn/wifi_hal/nan_i.h
@@ -62,7 +62,26 @@
 #define BIT_29              0x20000000
 #define BIT_30              0x40000000
 #define BIT_31              0x80000000
-typedef u8 SirMacAddr[NAN_MAC_ADDR_LEN];
+
+/** macro to convert FW MAC address from WMI word format to User Space MAC char array */
+#define FW_MAC_ADDR_TO_CHAR_ARRAY(fw_mac_addr, mac_addr) do { \
+     (mac_addr)[0] =    ((fw_mac_addr).mac_addr31to0) & 0xff; \
+     (mac_addr)[1] =  (((fw_mac_addr).mac_addr31to0) >> 8) & 0xff; \
+     (mac_addr)[2] =  (((fw_mac_addr).mac_addr31to0) >> 16) & 0xff; \
+     (mac_addr)[3] =  (((fw_mac_addr).mac_addr31to0) >> 24) & 0xff; \
+     (mac_addr)[4] =    ((fw_mac_addr).mac_addr47to32) & 0xff; \
+     (mac_addr)[5] =  (((fw_mac_addr).mac_addr47to32) >> 8) & 0xff; \
+} while (0)
+
+/** macro to convert User space MAC address from char array to FW WMI word format */
+#define CHAR_ARRAY_TO_MAC_ADDR(mac_addr, fw_mac_addr)  do { \
+    (fw_mac_addr).mac_addr31to0  =                   \
+         ((mac_addr)[0] | ((mac_addr)[1] << 8)            \
+           | ((mac_addr)[2] << 16) | ((mac_addr)[3] << 24));          \
+    (fw_mac_addr).mac_addr47to32  =                  \
+         ((mac_addr)[4] | ((mac_addr)[5] << 8));          \
+} while (0)
+
 /*---------------------------------------------------------------------------
 * WLAN NAN CONSTANTS
 *--------------------------------------------------------------------------*/
@@ -105,6 +124,8 @@
     NAN_MSG_ID_CAPABILITIES_REQ             = 33,
     NAN_MSG_ID_CAPABILITIES_RSP             = 34,
     NAN_MSG_ID_SELF_TRANSMIT_FOLLOWUP_IND   = 35,
+    NAN_MSG_ID_RANGING_REQUEST_RECEVD_IND   = 36,
+    NAN_MSG_ID_RANGING_RESULT_IND           = 37,
     NAN_MSG_ID_TESTMODE_REQ                 = 1025,
     NAN_MSG_ID_TESTMODE_RSP                 = 1026
 } NanMsgId;
@@ -143,6 +164,11 @@
     NAN_TLV_TYPE_SDEA_CTRL_PARAMS = 21,
     NAN_TLV_TYPE_NAN_RANGING_CFG = 22,
     NAN_TLV_TYPE_CONFIG_DISCOVERY_INDICATIONS = 23,
+    NAN_TLV_TYPE_NAN20_RANGING_REQUEST = 24,
+    NAN_TLV_TYPE_NAN20_RANGING_RESULT = 25,
+    NAN_TLV_TYPE_NAN20_RANGING_REQUEST_RECEIVED = 26,
+    NAN_TLV_TYPE_NAN_PASSPHRASE = 27,
+    NAN_TLV_TYPE_SDEA_SERVICE_SPECIFIC_INFO = 28,
     NAN_TLV_TYPE_SDF_LAST = 4095,
 
     /* Configuration types */
@@ -185,7 +211,6 @@
     NAN_TLV_TYPE_5G_CHANNEL,
     NAN_TLV_TYPE_DISC_MAC_ADDR_RANDOM_INTERVAL,
     NAN_TLV_TYPE_RANGING_AUTO_RESPONSE_CFG = 4134,
-    NAN_TLV_TYPE_NAN_RANGE_RESULT,
     NAN_TLV_TYPE_CONFIG_LAST = 8191,
 
     /* Attributes types */
@@ -225,7 +250,7 @@
 
     /* Testmode types */
     NAN_TLV_TYPE_TESTMODE_FIRST = 36864,
-    NAN_TLV_TYPE_TM_NAN_AVAILABILITY = NAN_TLV_TYPE_TESTMODE_FIRST,
+    NAN_TLV_TYPE_TESTMODE_GENERIC_CMD = NAN_TLV_TYPE_TESTMODE_FIRST,
     NAN_TLV_TYPE_TESTMODE_LAST = 37000,
 
     NAN_TLV_TYPE_LAST = 65535
@@ -959,6 +984,8 @@
     NAN_INDICATION_TCA                     =8,
     NAN_INDICATION_BEACON_SDF_PAYLOAD      =9,
     NAN_INDICATION_SELF_TRANSMIT_FOLLOWUP  =10,
+    NAN_INDICATION_RANGING_REQUEST_RECEIVED =11,
+    NAN_INDICATION_RANGING_RESULT           =12,
     NAN_INDICATION_UNKNOWN                 =0xFFFF
 } NanIndicationType;
 
@@ -988,9 +1015,13 @@
     u32 max_ndp_sessions;
     u32 max_app_info_len;
     u32 max_queued_transmit_followup_msgs;
+    u32 ndp_supported_bands;
     u32 cipher_suites_supported;
+    u32 max_scid_len;
+    u32 is_ndp_security_supported:1;
+    u32 max_sdea_service_specific_info_len:16;
+    u32 reserved:15;
     u32 max_subscribe_address;
-    u32 max_sdea_service_specific_info_len;
 } NanCapabilitiesRspMsg, *pNanCapabilitiesRspMsg;
 
 /* NAN Self Transmit Followup */
@@ -1018,7 +1049,8 @@
     u32 security_required:1;
     u32 ranging_required:1;
     u32 range_limit_present:1;
-    u32 reserved:23;
+    u32 range_report:1;
+    u32 reserved:22;
 } NanFWSdeaCtrlParams;
 
 /* NAN Ranging Configuration params */
@@ -1139,6 +1171,61 @@
     NDP_I_VENDOR_SPECIFIC_ERROR = 9500
 } NanInternalStatusType;
 
+/* This is the TLV used for range report */
+typedef struct PACKED
+{
+    u32 publish_id;
+    u32 event_type;
+    u32 range_measurement;
+} NanFWRangeReportParams;
+
+typedef struct PACKED
+{
+    NanMsgHeader fwHeader;
+    /*TLV Required:
+        MANDATORY
+            1. MAC_ADDRESS
+            2. NanFWRangeReportParams
+        OPTIONAL:
+            1. A_UINT32 event type
+    */
+    u8 ptlv[1];
+} NanFWRangeReportInd, *pNanFWRangeReportInd;
+
+/** 2 word representation of MAC addr */
+typedef struct {
+    /** upper 4 bytes of  MAC address */
+    u32 mac_addr31to0;
+    /** lower 2 bytes of  MAC address */
+    u32 mac_addr47to32;
+} fw_mac_addr;
+
+/* This is the TLV used to trigger ranging requests*/
+typedef struct PACKED
+{
+    fw_mac_addr  range_mac_addr;
+    u32 range_id; //Match handle in match_ind, publish_id in result ind
+    u32 ranging_accept:1;
+    u32 ranging_reject:1;
+    u32 ranging_cancel:1;
+    u32 reserved:29;
+} NanFWRangeReqMsg, *pNanFWRangeReqMsg;
+
+typedef struct PACKED
+{
+    fw_mac_addr  range_mac_addr;
+    u32 range_id;//This will publish_id in case of receiving publish.
+} NanFWRangeReqRecvdMsg, *pNanFWRangeReqRecvdMsg;
+
+typedef struct PACKED
+{
+    NanMsgHeader fwHeader;
+    /*TLV Required
+       1. t_nan_range_req_recvd_msg
+    */
+    u8 ptlv[1];
+} NanFWRangeReqRecvdInd, *pNanFWRangeReqRecvdInd;
+
 /* Function for NAN error translation
    For NanResponse, NanPublishTerminatedInd, NanSubscribeTerminatedInd,
    NanDisabledInd, NanTransmitFollowupInd:
diff --git a/qcwcn/wifi_hal/nan_ind.cpp b/qcwcn/wifi_hal/nan_ind.cpp
index 026928d..f2adf61 100644
--- a/qcwcn/wifi_hal/nan_ind.cpp
+++ b/qcwcn/wifi_hal/nan_ind.cpp
@@ -125,6 +125,24 @@
         }
         break;
 
+    case NAN_INDICATION_RANGING_REQUEST_RECEIVED:
+        NanRangeRequestInd rangeRequestInd;
+        memset(&rangeRequestInd, 0, sizeof(NanRangeRequestInd));
+        res = getNanRangeRequestReceivedInd(&rangeRequestInd);
+        if (!res && mHandler.EventRangeRequest) {
+            (*mHandler.EventRangeRequest)(&rangeRequestInd);
+        }
+        break;
+
+    case NAN_INDICATION_RANGING_RESULT:
+        NanRangeReportInd rangeReportInd;
+        memset(&rangeReportInd, 0, sizeof(NanRangeReportInd));
+        res = getNanRangeReportInd(&rangeReportInd);
+        if (!res && mHandler.EventRangeReport) {
+            (*mHandler.EventRangeReport)(&rangeReportInd);
+        }
+        break;
+
     default:
         ALOGE("handleNanIndication error invalid msg_id:%u", msg_id);
         res = (int)WIFI_ERROR_INVALID_REQUEST_ID;
@@ -168,6 +186,10 @@
         return NAN_INDICATION_BEACON_SDF_PAYLOAD;
     case NAN_MSG_ID_SELF_TRANSMIT_FOLLOWUP_IND:
         return NAN_INDICATION_SELF_TRANSMIT_FOLLOWUP;
+    case NAN_MSG_ID_RANGING_REQUEST_RECEVD_IND:
+        return NAN_INDICATION_RANGING_REQUEST_RECEIVED;
+    case NAN_MSG_ID_RANGING_RESULT_IND:
+        return NAN_INDICATION_RANGING_RESULT;
     default:
         return NAN_INDICATION_UNKNOWN;
     }
@@ -319,12 +341,20 @@
             getNanReceiveSdeaCtrlParams(outputTlv.value,
                                              &event->peer_sdea_params);
             break;
-        case NAN_TLV_TYPE_NAN_RANGE_RESULT:
+        case NAN_TLV_TYPE_NAN20_RANGING_RESULT:
             if (outputTlv.length > sizeof(event->range_info)) {
                 outputTlv.length = sizeof(event->range_info);
             }
             memcpy(&event->range_info, outputTlv.value, outputTlv.length);
             break;
+        case NAN_TLV_TYPE_SDEA_SERVICE_SPECIFIC_INFO:
+            if (outputTlv.length > NAN_MAX_SDEA_SERVICE_SPECIFIC_INFO_LEN) {
+                outputTlv.length = NAN_MAX_SDEA_SERVICE_SPECIFIC_INFO_LEN;
+            }
+            event->sdea_service_specific_info_len = outputTlv.length;
+            memcpy(event->sdea_service_specific_info, outputTlv.value,
+                   outputTlv.length);
+            break;
         default:
             ALOGV("Unknown TLV type skipped");
             break;
@@ -411,6 +441,14 @@
             }
             memcpy(event->addr, outputTlv.value, outputTlv.length);
             break;
+        case NAN_TLV_TYPE_SDEA_SERVICE_SPECIFIC_INFO:
+            if (outputTlv.length > NAN_MAX_SDEA_SERVICE_SPECIFIC_INFO_LEN) {
+                outputTlv.length = NAN_MAX_SDEA_SERVICE_SPECIFIC_INFO_LEN;
+            }
+            event->sdea_service_specific_info_len = outputTlv.length;
+            memcpy(event->sdea_service_specific_info, outputTlv.value,
+                   outputTlv.length);
+            break;
         default:
             ALOGV("Unknown TLV type skipped");
             break;
@@ -796,22 +834,14 @@
     int ret = WIFI_ERROR_NONE;
     int res = -1;
     transaction_id id = 1;
-    NanCommand *nanCommand = NULL;
     interface_info *ifaceInfo = getIfaceInfo(iface);
-    wifi_handle wifiHandle = getWifiHandle(iface);
 
-    nanCommand = NanCommand::instance(wifiHandle);
-    if (nanCommand == NULL) {
-        ALOGE("%s: Error NanCommand NULL", __func__);
-        return WIFI_ERROR_UNKNOWN;
-    }
-
-    ret = nanCommand->create();
+    ret = create();
     if (ret < 0)
         goto cleanup;
 
     /* Set the interface Id of the message. */
-    ret = nanCommand->set_iface_id(ifaceInfo->name);
+    ret = set_iface_id(ifaceInfo->name);
     if (ret < 0)
         goto cleanup;
 
@@ -1015,3 +1045,109 @@
     }
     return WIFI_SUCCESS;
 }
+
+int NanCommand::getNanRangeRequestReceivedInd(NanRangeRequestInd *event)
+{
+    if (event == NULL || mNanVendorEvent == NULL) {
+        ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p",
+              __func__, event, mNanVendorEvent);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+
+    pNanFWRangeReqRecvdInd pRsp = (pNanFWRangeReqRecvdInd)mNanVendorEvent;
+
+    u8 *pInputTlv = pRsp->ptlv;
+    NanTlv outputTlv;
+    u16 readLen = 0;
+
+    int remainingLen = (mNanDataLen -  \
+        (sizeof(NanMsgHeader)));
+
+    if (remainingLen <= 0) {
+        ALOGE("%s: No TLV's present",__func__);
+        return WIFI_SUCCESS;
+    }
+
+    ALOGV("%s: TLV remaining Len:%d",__func__, remainingLen);
+    while ((remainingLen > 0) &&
+           (0 != (readLen = NANTLV_ReadTlv(pInputTlv, &outputTlv)))) {
+        ALOGV("%s: Remaining Len:%d readLen:%d type:%d length:%d",
+              __func__, remainingLen, readLen, outputTlv.type,
+              outputTlv.length);
+        switch (outputTlv.type) {
+        case NAN_TLV_TYPE_NAN20_RANGING_REQUEST_RECEIVED:
+            NanFWRangeReqRecvdMsg fwRangeReqRecvd;
+            if (outputTlv.length > sizeof(fwRangeReqRecvd)) {
+                outputTlv.length = sizeof(fwRangeReqRecvd);
+            }
+            memcpy(&fwRangeReqRecvd, outputTlv.value, outputTlv.length);
+            FW_MAC_ADDR_TO_CHAR_ARRAY(fwRangeReqRecvd.range_mac_addr, event->range_req_intf_addr);
+            event->publish_id = fwRangeReqRecvd.range_id;
+            break;
+        default:
+            ALOGV("Unhandled TLV type:%d", outputTlv.type);
+            break;
+        }
+        remainingLen -= readLen;
+        pInputTlv += readLen;
+        memset(&outputTlv,0, sizeof(outputTlv));
+    }
+    return WIFI_SUCCESS;
+}
+
+int NanCommand::getNanRangeReportInd(NanRangeReportInd *event)
+{
+    if (event == NULL || mNanVendorEvent == NULL) {
+        ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p",
+              __func__, event, mNanVendorEvent);
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+
+    pNanFWRangeReportInd pRsp = (pNanFWRangeReportInd)mNanVendorEvent;
+
+    u8 *pInputTlv = pRsp->ptlv;
+    NanTlv outputTlv;
+    u16 readLen = 0;
+
+    int remainingLen = (mNanDataLen -  \
+        (sizeof(NanMsgHeader)));
+
+    if (remainingLen <= 0) {
+        ALOGE("%s: No TLV's present",__func__);
+        return WIFI_SUCCESS;
+    }
+
+    ALOGV("%s: TLV remaining Len:%d",__func__, remainingLen);
+    while ((remainingLen > 0) &&
+           (0 != (readLen = NANTLV_ReadTlv(pInputTlv, &outputTlv)))) {
+        ALOGV("%s: Remaining Len:%d readLen:%d type:%d length:%d",
+              __func__, remainingLen, readLen, outputTlv.type,
+              outputTlv.length);
+        switch (outputTlv.type) {
+        case NAN_TLV_TYPE_MAC_ADDRESS:
+            if (outputTlv.length > NAN_MAC_ADDR_LEN) {
+                outputTlv.length = NAN_MAC_ADDR_LEN;
+            }
+            memcpy(event->range_req_intf_addr, outputTlv.value, outputTlv.length);
+            break;
+
+        case NAN_TLV_TYPE_NAN20_RANGING_RESULT:
+            NanFWRangeReportParams range_params;
+            if (outputTlv.length > sizeof(NanFWRangeReportParams)) {
+                outputTlv.length = sizeof(NanFWRangeReportParams);
+            }
+            memcpy(&range_params, outputTlv.value, outputTlv.length);
+            event->range_measurement_cm = range_params.range_measurement;
+            event->publish_id = range_params.publish_id;
+//          event->event_type = range_params.event_type;
+            break;
+        default:
+            ALOGV("Unhandled TLV type:%d", outputTlv.type);
+            break;
+        }
+        remainingLen -= readLen;
+        pInputTlv += readLen;
+        memset(&outputTlv,0, sizeof(outputTlv));
+    }
+    return WIFI_SUCCESS;
+}
diff --git a/qcwcn/wifi_hal/nan_req.cpp b/qcwcn/wifi_hal/nan_req.cpp
index dbf6411..2868ffb 100644
--- a/qcwcn/wifi_hal/nan_req.cpp
+++ b/qcwcn/wifi_hal/nan_req.cpp
@@ -568,13 +568,27 @@
         (pReq->tx_match_filter_len ? SIZEOF_TLV_HDR + pReq->tx_match_filter_len : 0) +
         (SIZEOF_TLV_HDR + sizeof(NanServiceAcceptPolicy)) +
         (pReq->cipher_type ? SIZEOF_TLV_HDR + sizeof(NanCsidType) : 0) +
-        (pReq->pmk_len ? SIZEOF_TLV_HDR + NAN_PMK_INFO_LEN : 0) +
         ((pReq->sdea_params.config_nan_data_path || pReq->sdea_params.security_cfg ||
-          pReq->sdea_params.ranging_state) ?
+          pReq->sdea_params.ranging_state || pReq->sdea_params.range_report) ?
           SIZEOF_TLV_HDR + sizeof(NanFWSdeaCtrlParams) : 0) +
         ((pReq->ranging_cfg.ranging_interval_msec || pReq->ranging_cfg.config_ranging_indications ||
           pReq->ranging_cfg.distance_ingress_cm || pReq->ranging_cfg.distance_egress_cm) ?
-          SIZEOF_TLV_HDR + sizeof(NanRangingCfg) : 0);
+          SIZEOF_TLV_HDR + sizeof(NanFWRangeConfigParams) : 0) +
+        ((pReq->range_response_cfg.publish_id ||
+          pReq->range_response_cfg.ranging_response) ?
+          SIZEOF_TLV_HDR + sizeof(NanFWRangeReqMsg) : 0)  +
+        (pReq->sdea_service_specific_info_len ? SIZEOF_TLV_HDR + pReq->sdea_service_specific_info_len : 0);
+
+    if ((pReq->key_info.key_type ==  NAN_SECURITY_KEY_INPUT_PMK) &&
+        (pReq->key_info.body.pmk_info.pmk_len == NAN_PMK_INFO_LEN))
+        message_len += SIZEOF_TLV_HDR + NAN_PMK_INFO_LEN;
+    else if ((pReq->key_info.key_type ==  NAN_SECURITY_KEY_INPUT_PASSPHRASE) &&
+             (pReq->key_info.body.passphrase_info.passphrase_len >=
+              NAN_SECURITY_MIN_PASSPHRASE_LEN) &&
+             (pReq->key_info.body.passphrase_info.passphrase_len <=
+              NAN_SECURITY_MAX_PASSPHRASE_LEN))
+        message_len += SIZEOF_TLV_HDR +
+                       pReq->key_info.body.passphrase_info.passphrase_len;
 
     pNanPublishServiceReqMsg pFwReq = (pNanPublishServiceReqMsg)malloc(message_len);
     if (pFwReq == NULL) {
@@ -641,13 +655,27 @@
         tlvs = addTlv(NAN_TLV_TYPE_NAN_CSID, sizeof(NanCsidType),
                         (const u8*)&pNanCsidType, tlvs);
     }
-    if (pReq->pmk_len) {
-        tlvs = addTlv(NAN_TLV_TYPE_NAN_PMK, pReq->pmk_len,
-                      (const u8*)&pReq->pmk[0], tlvs);
+
+    if ((pReq->key_info.key_type ==  NAN_SECURITY_KEY_INPUT_PMK) &&
+        (pReq->key_info.body.pmk_info.pmk_len == NAN_PMK_INFO_LEN)) {
+        tlvs = addTlv(NAN_TLV_TYPE_NAN_PMK,
+                      pReq->key_info.body.pmk_info.pmk_len,
+                      (const u8*)&pReq->key_info.body.pmk_info.pmk[0], tlvs);
+    } else if ((pReq->key_info.key_type == NAN_SECURITY_KEY_INPUT_PASSPHRASE) &&
+        (pReq->key_info.body.passphrase_info.passphrase_len >=
+         NAN_SECURITY_MIN_PASSPHRASE_LEN) &&
+        (pReq->key_info.body.passphrase_info.passphrase_len <=
+         NAN_SECURITY_MAX_PASSPHRASE_LEN)) {
+        tlvs = addTlv(NAN_TLV_TYPE_NAN_PASSPHRASE,
+                  pReq->key_info.body.passphrase_info.passphrase_len,
+                  (const u8*)&pReq->key_info.body.passphrase_info.passphrase[0],
+                  tlvs);
     }
+
     if (pReq->sdea_params.config_nan_data_path ||
         pReq->sdea_params.security_cfg ||
-        pReq->sdea_params.ranging_state) {
+        pReq->sdea_params.ranging_state ||
+        pReq->sdea_params.range_report) {
         NanFWSdeaCtrlParams pNanFWSdeaCtrlParams;
         memset(&pNanFWSdeaCtrlParams, 0, sizeof(NanFWSdeaCtrlParams));
 
@@ -667,19 +695,29 @@
             pNanFWSdeaCtrlParams.ranging_required =
                                          pReq->sdea_params.ranging_state;
         }
+        if (pReq->sdea_params.range_report) {
+            pNanFWSdeaCtrlParams.range_report =
+                (((pReq->sdea_params.range_report & NAN_ENABLE_RANGE_REPORT) >> 1) ? 1 : 0);
+        }
         tlvs = addTlv(NAN_TLV_TYPE_SDEA_CTRL_PARAMS, sizeof(NanFWSdeaCtrlParams),
                         (const u8*)&pNanFWSdeaCtrlParams, tlvs);
     }
 
-    if (pReq->ranging_cfg.ranging_interval_msec || pReq->ranging_cfg.config_ranging_indications) {
+    if (pReq->ranging_cfg.ranging_interval_msec ||
+        pReq->ranging_cfg.config_ranging_indications ||
+        pReq->ranging_cfg.distance_ingress_cm ||
+        pReq->ranging_cfg.distance_ingress_cm) {
         NanFWRangeConfigParams pNanFWRangingCfg;
+
         memset(&pNanFWRangingCfg, 0, sizeof(NanFWRangeConfigParams));
         pNanFWRangingCfg.range_interval =
                                 pReq->ranging_cfg.ranging_interval_msec;
         pNanFWRangingCfg.ranging_indication_event =
-                                         ((pReq->ranging_cfg.config_ranging_indications & NAN_RANGING_INDICATE_CONTINUOUS_MASK) |
-                                          (pReq->ranging_cfg.config_ranging_indications & NAN_RANGING_INDICATE_INGRESS_MET_MASK) |
-                                          (pReq->ranging_cfg.config_ranging_indications & NAN_RANGING_INDICATE_EGRESS_MET_MASK));
+            ((pReq->ranging_cfg.config_ranging_indications & NAN_RANGING_INDICATE_CONTINUOUS_MASK) |
+            (pReq->ranging_cfg.config_ranging_indications & NAN_RANGING_INDICATE_INGRESS_MET_MASK) |
+            (pReq->ranging_cfg.config_ranging_indications & NAN_RANGING_INDICATE_EGRESS_MET_MASK));
+
+        pNanFWRangingCfg.ranging_indication_event = pReq->ranging_cfg.config_ranging_indications;
         if (pReq->ranging_cfg.config_ranging_indications & NAN_RANGING_INDICATE_INGRESS_MET_MASK)
             pNanFWRangingCfg.geo_fence_threshold.inner_threshold =
                                         pReq->ranging_cfg.distance_ingress_cm;
@@ -690,6 +728,28 @@
                                                     (const u8*)&pNanFWRangingCfg, tlvs);
     }
 
+    if (pReq->sdea_service_specific_info_len) {
+        tlvs = addTlv(NAN_TLV_TYPE_SDEA_SERVICE_SPECIFIC_INFO, pReq->sdea_service_specific_info_len,
+                      (const u8*)&pReq->sdea_service_specific_info[0], tlvs);
+    }
+
+    if (pReq->range_response_cfg.publish_id || pReq->range_response_cfg.ranging_response) {
+
+        NanFWRangeReqMsg pNanFWRangeReqMsg;
+        memset(&pNanFWRangeReqMsg, 0, sizeof(NanFWRangeReqMsg));
+        pNanFWRangeReqMsg.range_id =
+                                (u16)pReq->range_response_cfg.publish_id;
+        CHAR_ARRAY_TO_MAC_ADDR(pReq->range_response_cfg.peer_addr, pNanFWRangeReqMsg.range_mac_addr);
+        pNanFWRangeReqMsg.ranging_accept =
+            ((pReq->range_response_cfg.ranging_response == NAN_RANGE_REQUEST_ACCEPT) ? 1 : 0);
+        pNanFWRangeReqMsg.ranging_reject =
+            ((pReq->range_response_cfg.ranging_response == NAN_RANGE_REQUEST_REJECT) ? 1 : 0);
+        pNanFWRangeReqMsg.ranging_cancel =
+            ((pReq->range_response_cfg.ranging_response == NAN_RANGE_REQUEST_CANCEL) ? 1 : 0);
+        tlvs = addTlv(NAN_TLV_TYPE_NAN20_RANGING_REQUEST, sizeof(NanFWRangeReqMsg),
+                                                    (const u8*)&pNanFWRangeReqMsg, tlvs);
+    }
+
     mVendorData = (char *)pFwReq;
     mDataLen = message_len;
 
@@ -757,17 +817,33 @@
         (pReq->rx_match_filter_len ? SIZEOF_TLV_HDR + pReq->rx_match_filter_len : 0) +
         (pReq->tx_match_filter_len ? SIZEOF_TLV_HDR + pReq->tx_match_filter_len : 0) +
         (pReq->cipher_type ? SIZEOF_TLV_HDR + sizeof(NanCsidType) : 0) +
-        (pReq->pmk_len ? SIZEOF_TLV_HDR + NAN_PMK_INFO_LEN : 0) +
         ((pReq->sdea_params.config_nan_data_path || pReq->sdea_params.security_cfg ||
-          pReq->sdea_params.ranging_state) ?
+          pReq->sdea_params.ranging_state || pReq->sdea_params.range_report) ?
           SIZEOF_TLV_HDR + sizeof(NanFWSdeaCtrlParams) : 0) +
         ((pReq->ranging_cfg.ranging_interval_msec || pReq->ranging_cfg.config_ranging_indications ||
           pReq->ranging_cfg.distance_ingress_cm || pReq->ranging_cfg.distance_egress_cm) ?
-          SIZEOF_TLV_HDR + sizeof(NanRangingCfg) : 0);
+          SIZEOF_TLV_HDR + sizeof(NanFWRangeConfigParams) : 0) +
+        ((pReq->range_response_cfg.requestor_instance_id ||
+          pReq->range_response_cfg.ranging_response) ?
+          SIZEOF_TLV_HDR + sizeof(NanFWRangeReqMsg) : 0) +
+        (pReq->sdea_service_specific_info_len ? SIZEOF_TLV_HDR + pReq->sdea_service_specific_info_len : 0);
 
     message_len += \
         (pReq->num_intf_addr_present * (SIZEOF_TLV_HDR + NAN_MAC_ADDR_LEN));
 
+
+    if ((pReq->key_info.key_type ==  NAN_SECURITY_KEY_INPUT_PMK) &&
+        (pReq->key_info.body.pmk_info.pmk_len == NAN_PMK_INFO_LEN))
+        message_len += SIZEOF_TLV_HDR + NAN_PMK_INFO_LEN;
+    else if ((pReq->key_info.key_type ==  NAN_SECURITY_KEY_INPUT_PASSPHRASE) &&
+             (pReq->key_info.body.passphrase_info.passphrase_len >=
+              NAN_SECURITY_MIN_PASSPHRASE_LEN) &&
+             (pReq->key_info.body.passphrase_info.passphrase_len <=
+              NAN_SECURITY_MAX_PASSPHRASE_LEN))
+        message_len += SIZEOF_TLV_HDR +
+                       pReq->key_info.body.passphrase_info.passphrase_len;
+
+
     pNanSubscribeServiceReqMsg pFwReq = (pNanSubscribeServiceReqMsg)malloc(message_len);
     if (pFwReq == NULL) {
         cleanup();
@@ -837,13 +913,27 @@
         tlvs = addTlv(NAN_TLV_TYPE_NAN_CSID, sizeof(NanCsidType),
                         (const u8*)&pNanCsidType, tlvs);
     }
-    if (pReq->pmk_len) {
-        tlvs = addTlv(NAN_TLV_TYPE_NAN_PMK, pReq->pmk_len,
-                      (const u8*)&pReq->pmk[0], tlvs);
+
+    if ((pReq->key_info.key_type ==  NAN_SECURITY_KEY_INPUT_PMK) &&
+        (pReq->key_info.body.pmk_info.pmk_len == NAN_PMK_INFO_LEN)) {
+        tlvs = addTlv(NAN_TLV_TYPE_NAN_PMK,
+                      pReq->key_info.body.pmk_info.pmk_len,
+                      (const u8*)&pReq->key_info.body.pmk_info.pmk[0], tlvs);
+    } else if ((pReq->key_info.key_type == NAN_SECURITY_KEY_INPUT_PASSPHRASE) &&
+        (pReq->key_info.body.passphrase_info.passphrase_len >=
+         NAN_SECURITY_MIN_PASSPHRASE_LEN) &&
+        (pReq->key_info.body.passphrase_info.passphrase_len <=
+         NAN_SECURITY_MAX_PASSPHRASE_LEN)) {
+        tlvs = addTlv(NAN_TLV_TYPE_NAN_PASSPHRASE,
+                  pReq->key_info.body.passphrase_info.passphrase_len,
+                  (const u8*)&pReq->key_info.body.passphrase_info.passphrase[0],
+                  tlvs);
     }
+
     if (pReq->sdea_params.config_nan_data_path ||
         pReq->sdea_params.security_cfg ||
-        pReq->sdea_params.ranging_state) {
+        pReq->sdea_params.ranging_state ||
+        pReq->sdea_params.range_report) {
         NanFWSdeaCtrlParams pNanFWSdeaCtrlParams;
         memset(&pNanFWSdeaCtrlParams, 0, sizeof(NanFWSdeaCtrlParams));
 
@@ -863,20 +953,28 @@
             pNanFWSdeaCtrlParams.ranging_required =
                                          pReq->sdea_params.ranging_state;
         }
+        if (pReq->sdea_params.range_report) {
+            pNanFWSdeaCtrlParams.range_report =
+                ((pReq->sdea_params.range_report & NAN_ENABLE_RANGE_REPORT >> 1) ? 1 : 0);
+        }
         tlvs = addTlv(NAN_TLV_TYPE_SDEA_CTRL_PARAMS, sizeof(NanFWSdeaCtrlParams),
                         (const u8*)&pNanFWSdeaCtrlParams, tlvs);
 
     }
 
-    if (pReq->ranging_cfg.ranging_interval_msec || pReq->ranging_cfg.config_ranging_indications) {
+    if (pReq->ranging_cfg.ranging_interval_msec || pReq->ranging_cfg.config_ranging_indications || pReq->ranging_cfg.distance_ingress_cm
+        || pReq->ranging_cfg.distance_ingress_cm) {
         NanFWRangeConfigParams pNanFWRangingCfg;
         memset(&pNanFWRangingCfg, 0, sizeof(NanFWRangeConfigParams));
         pNanFWRangingCfg.range_interval =
                                 pReq->ranging_cfg.ranging_interval_msec;
         pNanFWRangingCfg.ranging_indication_event =
-                                         ((pReq->ranging_cfg.config_ranging_indications & NAN_RANGING_INDICATE_CONTINUOUS_MASK) |
-                                          (pReq->ranging_cfg.config_ranging_indications & NAN_RANGING_INDICATE_INGRESS_MET_MASK) |
-                                          (pReq->ranging_cfg.config_ranging_indications & NAN_RANGING_INDICATE_EGRESS_MET_MASK));
+            ((pReq->ranging_cfg.config_ranging_indications & NAN_RANGING_INDICATE_CONTINUOUS_MASK) |
+            (pReq->ranging_cfg.config_ranging_indications & NAN_RANGING_INDICATE_INGRESS_MET_MASK) |
+            (pReq->ranging_cfg.config_ranging_indications & NAN_RANGING_INDICATE_EGRESS_MET_MASK));
+
+        pNanFWRangingCfg.ranging_indication_event =
+                                          pReq->ranging_cfg.config_ranging_indications;
         if (pReq->ranging_cfg.config_ranging_indications & NAN_RANGING_INDICATE_INGRESS_MET_MASK)
             pNanFWRangingCfg.geo_fence_threshold.inner_threshold =
                                         pReq->ranging_cfg.distance_ingress_cm;
@@ -887,6 +985,27 @@
                                                     (const u8*)&pNanFWRangingCfg, tlvs);
     }
 
+    if (pReq->sdea_service_specific_info_len) {
+        tlvs = addTlv(NAN_TLV_TYPE_SDEA_SERVICE_SPECIFIC_INFO, pReq->sdea_service_specific_info_len,
+                      (const u8*)&pReq->sdea_service_specific_info[0], tlvs);
+    }
+
+    if (pReq->range_response_cfg.requestor_instance_id || pReq->range_response_cfg.ranging_response) {
+        NanFWRangeReqMsg pNanFWRangeReqMsg;
+        memset(&pNanFWRangeReqMsg, 0, sizeof(NanFWRangeReqMsg));
+        pNanFWRangeReqMsg.range_id =
+                                pReq->range_response_cfg.requestor_instance_id;
+        memcpy(&pNanFWRangeReqMsg.range_mac_addr, &pReq->range_response_cfg.peer_addr, NAN_MAC_ADDR_LEN);
+        pNanFWRangeReqMsg.ranging_accept =
+            ((pReq->range_response_cfg.ranging_response == NAN_RANGE_REQUEST_ACCEPT) ? 1 : 0);
+        pNanFWRangeReqMsg.ranging_reject =
+            ((pReq->range_response_cfg.ranging_response == NAN_RANGE_REQUEST_REJECT) ? 1 : 0);
+        pNanFWRangeReqMsg.ranging_cancel =
+            ((pReq->range_response_cfg.ranging_response == NAN_RANGE_REQUEST_CANCEL) ? 1 : 0);
+        tlvs = addTlv(NAN_TLV_TYPE_NAN20_RANGING_REQUEST, sizeof(NanFWRangeReqMsg),
+                                                    (const u8*)&pNanFWRangeReqMsg, tlvs);
+    }
+
     mVendorData = (char *)pFwReq;
     mDataLen = message_len;
     int ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen);
@@ -948,7 +1067,8 @@
     size_t message_len =
         sizeof(NanMsgHeader) + sizeof(NanTransmitFollowupReqParams) +
         (pReq->service_specific_info_len ? SIZEOF_TLV_HDR +
-         pReq->service_specific_info_len : 0);
+         pReq->service_specific_info_len : 0) +
+        (pReq->sdea_service_specific_info_len ? SIZEOF_TLV_HDR + pReq->sdea_service_specific_info_len : 0);
 
     /* Mac address needs to be added in TLV */
     message_len += (SIZEOF_TLV_HDR + sizeof(pReq->addr));
@@ -990,6 +1110,11 @@
                       (const u8*)&pReq->service_specific_info[0], tlvs);
     }
 
+    if (pReq->sdea_service_specific_info_len) {
+        tlvs = addTlv(NAN_TLV_TYPE_SDEA_SERVICE_SPECIFIC_INFO, pReq->sdea_service_specific_info_len,
+                      (const u8*)&pReq->sdea_service_specific_info[0], tlvs);
+    }
+
     mVendorData = (char *)pFwReq;
     mDataLen = message_len;
 
@@ -1393,6 +1518,7 @@
 
 int NanCommand::putNanCapabilities(transaction_id id)
 {
+    ALOGV("NAN_CAPABILITIES");
     size_t message_len = sizeof(NanCapabilitiesReqMsg);
 
     pNanCapabilitiesReqMsg pFwReq = (pNanCapabilitiesReqMsg)malloc(message_len);
@@ -1420,22 +1546,25 @@
     return ret;
 }
 
-int NanCommand::putNanAvailabilityDebug(NanAvailabilityDebug debug)
+int NanCommand::putNanDebugCommand(NanDebugParams debug,
+                                   int debug_msg_length)
 {
-
+    ALOGV("NAN_AVAILABILITY_DEBUG");
     size_t message_len = sizeof(NanTestModeReqMsg);
-    ALOGV("Message Len %zu", message_len);
 
-    message_len += (SIZEOF_TLV_HDR + sizeof(NanAvailabilityDebug));
+    message_len += (SIZEOF_TLV_HDR + debug_msg_length);
     pNanTestModeReqMsg pFwReq = (pNanTestModeReqMsg)malloc(message_len);
     if (pFwReq == NULL) {
         cleanup();
         return WIFI_ERROR_OUT_OF_MEMORY;
     }
 
-    ALOGV("Message Len %zu", message_len);
-    ALOGV("Valid %d 2g %d 5g %d", debug.valid, debug.band_availability_2g,
-                                               debug.band_availability_5g);
+    ALOGV("Message Len %zu\n", message_len);
+    ALOGV("%s: Debug Command Type = 0x%x \n", __func__, debug.cmd);
+    ALOGV("%s: ** Debug Command Data Start **", __func__);
+    hexdump(debug.debug_cmd_data, debug_msg_length);
+    ALOGV("%s: ** Debug Command Data End **", __func__);
+
     memset (pFwReq, 0, message_len);
     pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1;
     pFwReq->fwHeader.msgId = NAN_MSG_ID_TESTMODE_REQ;
@@ -1443,7 +1572,7 @@
     pFwReq->fwHeader.transactionId = 0;
 
     u8* tlvs = pFwReq->ptlv;
-    tlvs = addTlv(NAN_TLV_TYPE_TM_NAN_AVAILABILITY, sizeof(NanAvailabilityDebug),
+    tlvs = addTlv(NAN_TLV_TYPE_TESTMODE_GENERIC_CMD, debug_msg_length,
                   (const u8*)&debug, tlvs);
 
     mVendorData = (char*)pFwReq;
diff --git a/qcwcn/wifi_hal/nan_rsp.cpp b/qcwcn/wifi_hal/nan_rsp.cpp
index f7d786d..5e614e4 100644
--- a/qcwcn/wifi_hal/nan_rsp.cpp
+++ b/qcwcn/wifi_hal/nan_rsp.cpp
@@ -341,27 +341,36 @@
                                      u32 valueRcvd,
                                      void* pResponse)
 {
-    int i = 0;
+    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];
 
     if (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);
-                        break;
+            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", __FUNCTION__, pRsp->status);
-        ALOGD("%s: Value : %s", __FUNCTION__, pRsp->nan_error);
+        ALOGD("%s: Status: %d Error Info[value %d]: %s", __FUNCTION__, pRsp->status, valueRcvd, pRsp->nan_error);
     } else {
         msg_id = getIndicationType();
 
@@ -381,8 +390,7 @@
                         pRspInd->reason =  NAN_STATUS_INTERNAL_FAILURE;
                         strlcpy(pRspInd->nan_reason, "NAN Discovery engine failure", NAN_ERROR_STR_LEN);
                 }
-                ALOGD("%s: Status : %d", __FUNCTION__, pRspInd->reason);
-                ALOGD("%s: Value : %s", __FUNCTION__, pRspInd->nan_reason);
+                ALOGD("%s: Status: %d Error Info[value %d]: %s", __FUNCTION__, pRspInd->reason, valueRcvd, pRspInd->nan_reason);
                 break;
         case NAN_INDICATION_DISABLED:
                 pRspdInd = (NanDisabledInd*)pResponse;
@@ -397,8 +405,7 @@
                         pRspdInd->reason =  NAN_STATUS_INTERNAL_FAILURE;
                         strlcpy(pRspdInd->nan_reason, "NAN Discovery engine failure", NAN_ERROR_STR_LEN);
                 }
-                ALOGD("%s: Status : %d", __FUNCTION__, pRspdInd->reason);
-                ALOGD("%s: Value : %s", __FUNCTION__, pRspdInd->nan_reason);
+                ALOGD("%s: Status: %d Error Info[value %d]: %s", __FUNCTION__, pRspdInd->reason, valueRcvd, pRspdInd->nan_reason);
                 break;
         }
     }
@@ -512,7 +519,8 @@
                     sizeof(pRsp->body.stats_response.data)) {
                     handleNanStatsResponse(pRsp->body.stats_response.stats_type,
                                            (char *)outputTlv.value,
-                                           &pRsp->body.stats_response);
+                                           &pRsp->body.stats_response,
+                                           outputTlv.length);
                 }
             } else
                 ALOGV("%s: No TLV's present",__func__);
@@ -587,12 +595,18 @@
                        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_subscribe_address = \
-                       pFwRsp->max_subscribe_address;
+            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;
             break;
         }
         default:
@@ -633,6 +647,10 @@
         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
@@ -644,10 +662,16 @@
 
 void NanCommand::handleNanStatsResponse(NanStatsType stats_type,
                                        char *rspBuf,
-                                       NanStatsResponse *pRsp)
+                                       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 =
@@ -680,6 +704,11 @@
         memcpy(&pRsp->data, &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 =
@@ -718,6 +747,11 @@
         memcpy(&pRsp->data, &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;
@@ -742,6 +776,11 @@
         memcpy(&pRsp->data, &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;
@@ -771,6 +810,11 @@
         memcpy(&pRsp->data, &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;
@@ -826,6 +870,11 @@
         memcpy(&pRsp->data, &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;
diff --git a/qcwcn/wifi_hal/nancommand.h b/qcwcn/wifi_hal/nancommand.h
index 46a6b18..6b2624f 100644
--- a/qcwcn/wifi_hal/nancommand.h
+++ b/qcwcn/wifi_hal/nancommand.h
@@ -91,7 +91,8 @@
                                      NanFurtherAvailabilityChannel *pFac);
     void handleNanStatsResponse(NanStatsType stats_type,
                                 char* rspBuf,
-                                NanStatsResponse *pRsp);
+                                NanStatsResponse *pRsp,
+                                u32 message_len);
 
     //Function which unparses the data and calls the NotifyResponse
     int handleNdpResponse(NanResponseType ndpCmdtyp, struct nlattr **tb_vendor);
@@ -100,6 +101,8 @@
     int getNdpConfirm(struct nlattr **tb_vendor, NanDataPathConfirmInd *event);
     int getNdpEnd(struct nlattr **tb_vendor, NanDataPathEndInd *event);
     int getNanTransmitFollowupInd(NanTransmitFollowupInd *event);
+    int getNanRangeRequestReceivedInd(NanRangeRequestInd *event);
+    int getNanRangeReportInd(NanRangeReportInd *event);
 public:
     NanCommand(wifi_handle handle, int id, u32 vendor_id, u32 subcmd);
     static NanCommand* instance(wifi_handle handle);
@@ -128,7 +131,7 @@
     int putNanBeaconSdfPayload(transaction_id id, const NanBeaconSdfPayloadRequest *pReq);
     int getNanStaParameter(wifi_interface_handle iface, NanStaParameter *pRsp);
     int putNanCapabilities(transaction_id id);
-    int putNanAvailabilityDebug(NanAvailabilityDebug debug);
+    int putNanDebugCommand(NanDebugParams debug, int debug_msg_length);
 
     /* Functions for NAN error translation
        For NanResponse, NanPublishTerminatedInd, NanSubscribeTerminatedInd,
diff --git a/qcwcn/wifi_hal/vendor_definitions.h b/qcwcn/wifi_hal/vendor_definitions.h
index ac8afcd..ea105fa 100644
--- a/qcwcn/wifi_hal/vendor_definitions.h
+++ b/qcwcn/wifi_hal/vendor_definitions.h
@@ -364,6 +364,12 @@
     QCA_WLAN_VENDOR_ATTR_NDP_CSID,
     /* Array of u8: len = NAN_PMK_INFO_LEN */
     QCA_WLAN_VENDOR_ATTR_NDP_PMK,
+    QCA_WLAN_VENDOR_ATTR_NDP_SCID,
+    /* Array of u8: len = NAN_SECURITY_MAX_PASSPHRASE_LEN*/
+    QCA_WLAN_VENDOR_ATTR_NDP_PASSPHRASE,
+    /* Array of u8: len = NAN_MAX_SERVICE_NAME_LEN */
+    QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_NAME,
+
 
     /* KEEP LAST */
     QCA_WLAN_VENDOR_ATTR_NDP_AFTER_LAST,