Wifi-Hal: Add support for NAN debug commands

Modify NAN Availability debug command to make it a
generic debug command.

Change-Id: I1210ed1ad0d8a865b69fbb3d8a183f2cdc2b03e9
diff --git a/qcwcn/wifi_hal/nan.cpp b/qcwcn/wifi_hal/nan.cpp
index 73cdc75..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"
 
@@ -594,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;
@@ -612,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;
@@ -621,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;
     }
 
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 26f6b2b..7202751 100644
--- a/qcwcn/wifi_hal/nan_i.h
+++ b/qcwcn/wifi_hal/nan_i.h
@@ -250,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
diff --git a/qcwcn/wifi_hal/nan_ind.cpp b/qcwcn/wifi_hal/nan_ind.cpp
index 0f6167c..f2adf61 100644
--- a/qcwcn/wifi_hal/nan_ind.cpp
+++ b/qcwcn/wifi_hal/nan_ind.cpp
@@ -834,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;
 
diff --git a/qcwcn/wifi_hal/nan_req.cpp b/qcwcn/wifi_hal/nan_req.cpp
index 7f96568..2868ffb 100644
--- a/qcwcn/wifi_hal/nan_req.cpp
+++ b/qcwcn/wifi_hal/nan_req.cpp
@@ -1546,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;
@@ -1569,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 b24c296..5e614e4 100644
--- a/qcwcn/wifi_hal/nan_rsp.cpp
+++ b/qcwcn/wifi_hal/nan_rsp.cpp
@@ -519,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__);
@@ -646,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
@@ -657,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 =
@@ -693,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 =
@@ -731,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;
@@ -755,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;
@@ -784,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;
@@ -839,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 535fe83..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);
@@ -130,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,