Merge "Merge 24Q3 to AOSP main" into main
diff --git a/bcmdhd/halutil/Android.mk b/bcmdhd/halutil/Android.mk
index ead3fe9..b75616c 100644
--- a/bcmdhd/halutil/Android.mk
+++ b/bcmdhd/halutil/Android.mk
@@ -56,3 +56,4 @@
 LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
 LOCAL_LICENSE_CONDITIONS := notice
 include $(BUILD_EXECUTABLE)
+
diff --git a/bcmdhd/halutil/halutil.cpp b/bcmdhd/halutil/halutil.cpp
index c5c46b7..906ec64 100644
--- a/bcmdhd/halutil/halutil.cpp
+++ b/bcmdhd/halutil/halutil.cpp
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) 2023 The Android Open Source Project
  *
- * Portions copyright (C) 2022 Broadcom Limited
+ * Portions copyright (C) 2024 Broadcom Limited
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -24,7 +24,8 @@
 
 #define LOG_TAG  "WifiHAL"
 
-#define NAN_MAX_SIDS_IN_BEACONS 127
+#define NAN_MAX_SIDS_IN_BEACONS 127u
+#define MAX_WIFI_USABLE_CHANNELS 256u
 #include <utils/Log.h>
 #ifndef ANDROID
 #include <cutils/memory.h>
@@ -48,11 +49,9 @@
 #endif
 #include <sys/ioctl.h>
 #include <linux/netlink.h>
-#include "wifi_hal.h"
-#include "wifi_nan.h"
-#include "wifi_twt.h"
-#include "hal_tool.h"
-#include "interface_tool.h"
+#include <hardware_legacy/wifi_hal.h>
+#include <hardware_legacy/wifi_nan.h>
+#include <hardware_legacy/wifi_twt.h>
 
 #include "common.h"
 
@@ -64,6 +63,8 @@
 #define NMRSTR "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x"
 #define NAN_DISC_MAC_RAND_INTVL 30
 pthread_mutex_t printMutex;
+static u8 enab_for_chre = 0;
+static u8 disab_for_chre = 0;
 
 static wifi_hal_fn hal_fn;
 static char* frequency_to_channel(int center_freq);
@@ -76,6 +77,7 @@
 wifi_error twt_event_check_request(transaction_id id,
         wifi_interface_handle handle);
 static int set_interface_params(char *p_info, char *val_p, int len);
+static wifi_interface_handle wifi_get_iface_handle_by_iface_name(char *val_p);
 static void printApfUsage();
 static void printTxPowerUsage();
 
@@ -90,6 +92,46 @@
     pthread_mutex_unlock(&printMutex);
 }
 
+/* pretty hex print a contiguous buffer */
+static void prhex_msg(const char *msg, u8 *buf, u32 nbytes)
+{
+    char line[128];
+    char *p;
+    int len = sizeof(line);
+    int nchar;
+    u32 i;
+
+    if (msg && (msg[0] != '\0')) {
+        printf("%s: len %d\n", msg, nbytes);
+    }
+
+    p = line;
+    for (i = 0; i < nbytes; i++) {
+        if (i % 16 == 0) {
+            nchar = snprintf(p, len, "  %04d: ", i);    /* line prefix */
+            p += nchar;
+            len -= nchar;
+        }
+
+        if (len > 0) {
+            nchar = snprintf(p, len, "%02x ", buf[i]);
+            p += nchar;
+            len -= nchar;
+        }
+
+        if (i % 16 == 15) {
+            printf("%s\n", line);       /* flush line */
+            p = line;
+            len = sizeof(line);
+        }
+    }
+
+    /* flush last partial line */
+    if (p != line) {
+        printf("%s\n", line);
+    }
+}
+
 template<typename T, unsigned N>
 unsigned countof(T (&rgt)[N]) {
     return N;
@@ -274,7 +316,8 @@
 static wifi_interface_handle wlan0Handle;
 static wifi_interface_handle p2p0Handle;
 static int numIfaceHandles;
-static int cmdId = 0;
+static int cmdId = 1; /* Start with TxId of 1 */
+static int ioctl_sock = 0;
 static int max_event_wait = 5;
 static int stest_max_ap = 10;
 static int stest_base_period = 5000;
@@ -488,16 +531,65 @@
 /* 18-bytes of Ethernet address buffer length */
 #define ETHER_ADDR_STR_LEN      18
 #define ETHER_ADDR_LEN          6
+static const char *RttTypeToString(wifi_rtt_type type)
+{
+    switch (type) {
+        C2S(RTT_TYPE_1_SIDED)
+        C2S(RTT_TYPE_2_SIDED)
+        /* C2S(RTT_TYPE_2_SIDED_11MC) is same as above */
+        C2S(RTT_TYPE_2_SIDED_11AZ_NTB)
+        default:
+            return "UNKNOWN TYPE";
+    }
+}
+
+wifi_rtt_bw convert_channel_width_to_rtt_bw(int channel_width)
+{
+    wifi_rtt_bw rtt_bw = WIFI_RTT_BW_5;
+
+    switch (channel_width) {
+        case WIFI_CHAN_WIDTH_20:
+            rtt_bw = WIFI_RTT_BW_20;
+            break;
+        case WIFI_CHAN_WIDTH_40:
+            rtt_bw = WIFI_RTT_BW_40;
+            break;
+        case WIFI_CHAN_WIDTH_80:
+            rtt_bw = WIFI_RTT_BW_80;
+            break;
+        case WIFI_CHAN_WIDTH_160:
+            rtt_bw = WIFI_RTT_BW_160;
+            break;
+        case WIFI_CHAN_WIDTH_5:
+            rtt_bw = WIFI_RTT_BW_5;
+            break;
+        case WIFI_CHAN_WIDTH_10:
+            rtt_bw = WIFI_RTT_BW_10;
+            break;
+        case WIFI_CHAN_WIDTH_80P80:
+            rtt_bw = WIFI_RTT_BW_5;
+            break;
+        default:
+	    ALOGE("Unsupported channel_width: %d\n", channel_width);
+            break;
+    }
+    ALOGI("rtt_bw: %x, channel_width: %d\n", rtt_bw, channel_width);
+    return rtt_bw;
+}
 
 #define DEFAULT_RTT_FILE "/data/rtt-ap.list"
 static int rtt_from_file = 0;
 static int rtt_to_file = 0;
 static wifi_band band = WIFI_BAND_UNSPECIFIED;
+static wifi_interface_handle ifHandle = NULL;
 static int max_ap = 256; // the maximum count of  ap for RTT test
 static char rtt_aplist[FILE_NAME_LEN] = DEFAULT_RTT_FILE;
 static mac_addr responder_addr;
 static wifi_channel responder_channel;
 static int channel_width = 0;
+static wifi_rtt_type type = RTT_TYPE_2_SIDED;
+static u64 ntb_min_meas_time = 0;
+static u64 ntb_max_meas_time = 0;
 static bool rtt_sta = false;
 static bool rtt_nan = false;
 static bool is_6g = false;
@@ -514,7 +606,15 @@
     u8 bw;
     wifi_rtt_type type;
 };
+
+struct rtt_params_v3 {
+    u64 ntb_min_measurement_time;
+    u64 ntb_max_measurement_time;
+    u32 num_frames_per_burst;
+};
+
 struct rtt_params default_rtt_param = {0, 0, 0, 0, 0, 15, 0, 0, 0, 0, RTT_TYPE_2_SIDED};
+struct rtt_params_v3 default_rtt_param_v3 = {5000, 500, 5};
 
 mac_addr hotlist_bssids[16];
 mac_addr blacklist_bssids[16];
@@ -595,19 +695,27 @@
 
 
 static int init() {
-    android::wifi_system::HalTool hal_tool;
-    if (!hal_tool.InitFunctionTable(&hal_fn)) {
-        printMsg("Could not initialize the function table!\n");
+
+    wifi_error res = init_wifi_vendor_hal_func_table(&hal_fn);
+    if (res != WIFI_SUCCESS) {
+        ALOGD("Can not initialize the vendor function pointer table");
         return -1;
     }
 
-    android::wifi_system::InterfaceTool if_tool;
-    if (!if_tool.SetWifiUpState(true)) {
-        printMsg("Failed to set the interface state to up.\n");
-        return -1;
+    ioctl_sock = socket(PF_INET, SOCK_DGRAM, 0);
+    if (ioctl_sock < 0) {
+        printMsg("Bad socket: %d\n", ioctl_sock);
+        return errno;
+    } else {
+        ALOGD("Good socket: %d\n", ioctl_sock);
     }
 
-    wifi_error res = hal_fn.wifi_initialize(&halHandle);
+    int ret = linux_set_iface_flags(ioctl_sock, "wlan0", 1);
+    if (ret < 0) {
+        return ret;
+    }
+
+    res = hal_fn.wifi_initialize(&halHandle);
     if (res < 0) {
         return res;
     }
@@ -780,6 +888,10 @@
     EVENT_TYPE_NAN_TRANSMIT_FOLLOWUP_INDICATION   = 1022,
     EVENT_TYPE_RTT_RESULTS_DETAIL                 = 1023,
     EVENT_TYPE_CHRE_NAN_RTT_STATE_UPDATED         = 1024,
+    EVENT_TYPE_NAN_PAIRING_REQUEST_INDICATION     = 1025,
+    EVENT_TYPE_NAN_PAIRING_CONFIRMATION           = 1026,
+    EVENT_TYPE_NAN_BOOTSTRAP_REQUEST_INDICATION   = 1027,
+    EVENT_TYPE_NAN_BOOTSTRAP_CONFIRMATION         = 1028,
 
 } EventType;
 
@@ -1123,33 +1235,75 @@
     return num_results;
 }
 
-static void onRTTResults (wifi_request_id id, unsigned num_results, wifi_rtt_result *result[]) {
+static void onRTTResultsV3(wifi_request_id id, unsigned num_results,
+    wifi_rtt_result_v3 *result[]) {
 
-    printMsg("RTT results\n");
-    wifi_rtt_result *rtt_result;
+    printMsg("RTT results: num_results %d\n", num_results);
+    wifi_rtt_result_v3 *rtt_result_v3;
     mac_addr addr = {0};
+
     for (unsigned i = 0; i < num_results; i++) {
-        rtt_result = result[i];
-        if (memcmp(addr, rtt_result->addr, sizeof(mac_addr))) {
+        rtt_result_v3 = result[i];
+        if (memcmp(addr, rtt_result_v3->rtt_result.rtt_result.addr, sizeof(mac_addr))) {
             printMsg("Target mac : %02x:%02x:%02x:%02x:%02x:%02x\n",
-                    rtt_result->addr[0],
-                    rtt_result->addr[1],
-                    rtt_result->addr[2],
-                    rtt_result->addr[3],
-                    rtt_result->addr[4],
-                    rtt_result->addr[5]);
-            memcpy(addr, rtt_result->addr, sizeof(mac_addr));
+                    rtt_result_v3->rtt_result.rtt_result.addr[0],
+                    rtt_result_v3->rtt_result.rtt_result.addr[1],
+                    rtt_result_v3->rtt_result.rtt_result.addr[2],
+                    rtt_result_v3->rtt_result.rtt_result.addr[3],
+                    rtt_result_v3->rtt_result.rtt_result.addr[4],
+                    rtt_result_v3->rtt_result.rtt_result.addr[5]);
+            memcpy(addr, rtt_result_v3->rtt_result.rtt_result.addr, sizeof(mac_addr));
         }
-        printMsg("\tburst_num : %d, measurement_number : %d, success_number : %d\n"
-                "\tnumber_per_burst_peer : %d, status : %d, retry_after_duration : %d s\n"
-                "\trssi : %d dbm, rx_rate : %d Kbps, rtt : %llu ns, rtt_sd : %llu\n"
-                "\tdistance : %d cm, burst_duration : %d ms, negotiated_burst_num : %d\n",
-                rtt_result->burst_num, rtt_result->measurement_number,
-                rtt_result->success_number, rtt_result->number_per_burst_peer,
-                rtt_result->status, rtt_result->retry_after_duration,
-                rtt_result->rssi, rtt_result->rx_rate.bitrate * 100,
-                rtt_result->rtt/1000, rtt_result->rtt_sd, rtt_result->distance_mm / 10,
-                rtt_result->burst_duration, rtt_result->negotiated_burst_num);
+
+        printMsg("\tburst_num : %d, measurement_number : %d,\n"
+                "\tsuccess_number : %d, number_per_burst_peer : %d,\n"
+                "\tstatus : %d, retry_after_duration : %ds,\n"
+                "\ttype : %d, rssi : %d dbm, rx_rate : %d Kbps, rtt : %lu ps,\n"
+                "\trtt_sd : %lu ps, distance : %d mm, burst_duration : %d ms,\n"
+                "\tnegotiated_burst_num : %d, frequency : %d, packet_bw : %d\n",
+                rtt_result_v3->rtt_result.rtt_result.burst_num,
+                rtt_result_v3->rtt_result.rtt_result.measurement_number,
+                rtt_result_v3->rtt_result.rtt_result.success_number,
+                rtt_result_v3->rtt_result.rtt_result.number_per_burst_peer,
+                rtt_result_v3->rtt_result.rtt_result.status,
+                rtt_result_v3->rtt_result.rtt_result.retry_after_duration,
+                rtt_result_v3->rtt_result.rtt_result.type,
+                rtt_result_v3->rtt_result.rtt_result.rssi,
+                rtt_result_v3->rtt_result.rtt_result.rx_rate.bitrate * 100,
+                (unsigned long)rtt_result_v3->rtt_result.rtt_result.rtt,
+                (unsigned long)rtt_result_v3->rtt_result.rtt_result.rtt_sd,
+                rtt_result_v3->rtt_result.rtt_result.distance_mm,
+                rtt_result_v3->rtt_result.rtt_result.burst_duration,
+                rtt_result_v3->rtt_result.rtt_result.negotiated_burst_num,
+                rtt_result_v3->rtt_result.frequency,
+                rtt_result_v3->rtt_result.packet_bw);
+
+        if (rtt_result_v3->rtt_result.rtt_result.LCI) {
+            printMsg("LCI id %d\n", rtt_result_v3->rtt_result.rtt_result.LCI->id);
+            printMsg("LCI Len %d\n", rtt_result_v3->rtt_result.rtt_result.LCI->len);
+            prhex_msg("LCI data",
+                    rtt_result_v3->rtt_result.rtt_result.LCI->data,
+                    rtt_result_v3->rtt_result.rtt_result.LCI->len);
+        }
+
+        if (rtt_result_v3->rtt_result.rtt_result.LCR) {
+            printMsg("LCR id %d\n", rtt_result_v3->rtt_result.rtt_result.LCR->id);
+            printMsg("LCR Len %d\n", rtt_result_v3->rtt_result.rtt_result.LCR->len);
+            prhex_msg("LCR data",
+                    rtt_result_v3->rtt_result.rtt_result.LCR->data,
+                    rtt_result_v3->rtt_result.rtt_result.LCR->len);
+        }
+
+        if (rtt_result_v3->rtt_result.rtt_result.type == RTT_TYPE_2_SIDED_11AZ_NTB) {
+            printMsg("\t i2r_tx_ltf_repetition_cnt: %u,\n"
+                    " \t r2i_tx_ltf_repetition_cnt: %u,\n"
+                    " \t ntb min meas_time: %lu units of 100us,\n"
+                    " \t ntb max meas_time: %lu units of 10ms\n",
+                    rtt_result_v3->i2r_tx_ltf_repetition_count,
+                    rtt_result_v3->r2i_tx_ltf_repetition_count,
+                    rtt_result_v3->ntb_min_measurement_time,
+                    rtt_result_v3->ntb_max_measurement_time);
+        }
     }
 
     putEventInCache(EVENT_TYPE_RTT_RESULTS, "RTT results");
@@ -1194,7 +1348,6 @@
     putEventInCache(EVENT_TYPE_RSSI_MONITOR, "RSSI monitor Event");
 }
 
-
 static const u8 *bss_get_ie(u8 id, const char* ie, const s32 ie_len)
 {
     const u8 *end, *pos;
@@ -1212,6 +1365,7 @@
 
     return NULL;
 }
+
 static bool is11mcAP(const char* ie, const s32 ie_len)
 {
     const u8 *ext_cap_ie, *ptr_ie;
@@ -1345,7 +1499,7 @@
     memset(&chan_info, 0, sizeof(wifi_channel_info));
     vht_op = read_vht_oper_ie(ie, ie_len);
     if ((vht_op = read_vht_oper_ie(ie, ie_len)) &&
-            (ht_op = read_ht_oper_ie(ie, ie_len))) {
+            ((ht_op = (read_ht_oper_ie(ie, ie_len))))) {
         /* VHT mode */
         if (vht_op->chan_width == VHT_OP_CHAN_WIDTH_80) {
             chan_info.width = WIFI_CHAN_WIDTH_80;
@@ -1356,7 +1510,7 @@
             return chan_info;
         }
     }
-    if (ht_op = read_ht_oper_ie(ie, ie_len)){
+    if ((ht_op = (read_ht_oper_ie(ie, ie_len)))) {
         /* HT mode */
         /* control channel */
         chan_info.center_freq = channel2mhz(ht_op->ctl_ch);
@@ -1392,7 +1546,8 @@
     int result = 0;
     /* Run by a provided rtt-ap-list file */
     FILE* w_fp = NULL;
-    wifi_rtt_config params[max_ap];
+    wifi_rtt_config_v3 params[max_ap];
+
     if (!rtt_from_file && !rtt_sta && !rtt_nan) {
         /* band filter for a specific band */
         if (band == WIFI_BAND_UNSPECIFIED)
@@ -1412,6 +1567,7 @@
         for (int i = 0; i < num_results; i++) {
             printScanResult(*results[i]);
         }
+
         if (rtt_to_file) {
             /* Write a RTT AP list to a file */
             w_fp = fopen(rtt_aplist, "w");
@@ -1419,43 +1575,93 @@
                 printMsg("failed to open the file : %s\n", rtt_aplist);
                 return;
             }
-            fprintf(w_fp, "|SSID|BSSID|Primary Freq|Center Freq|Channel BW(0=20MHZ,1=40MZ,2=80MHZ)"
-                    "|rtt_type(1=1WAY,2=2WAY,3=auto)|Peer Type(STA=0, AP=1)|burst period|"
-                    "Num of Burst|FTM retry count|FTMR retry count|LCI|LCR|Burst Duration|Preamble|BW\n");
+            fprintf(w_fp, "|SSID|BSSID|Primary Freq|Center Freq|Channel BW(0=20MHZ,1=40MZ,2=80MHZ)\n"
+                    "|rtt_type(1=1WAY,2=2WAY,3=auto)|Peer Type(STA=0, AP=1)|burst period|\n"
+                    "Num of Burst|FTM retry count|FTMR retry count|LCI|LCR|\n"
+                    "Burst Duration|Preamble|BW||NTB Min Meas Time in units of 100us|\n"
+                    "NTB Max Meas Time in units of 10ms\n");
         }
+
         for (int i = 0; i < min(num_results, max_ap); i++) {
             scan_param = results[i];
             if(is11mcAP(&scan_param->ie_data[0], scan_param->ie_length)) {
-                memcpy(params[num_ap].addr, scan_param->bssid, sizeof(mac_addr));
-                mac_addr &addr = params[num_ap].addr;
-                printMsg("Adding %s(%02x:%02x:%02x:%02x:%02x:%02x) on Freq (%d) for 11mc RTT\n",
+                memcpy(params[num_ap].rtt_config.addr, scan_param->bssid,
+                        sizeof(mac_addr));
+                mac_addr &addr = params[num_ap].rtt_config.addr;
+                printMsg("Adding %s(%02x:%02x:%02x:%02x:%02x:%02x) on Freq (%d) for %s type RTT\n",
                         scan_param->ssid, addr[0], addr[1],
                         addr[2], addr[3], addr[4], addr[5],
-                        scan_param->channel);
-                params[num_ap].type = default_rtt_param.type;
-                params[num_ap].channel = get_channel_of_ie(&scan_param->ie_data[0],
+                        scan_param->channel, RttTypeToString(type));
+                params[num_ap].rtt_config.type = type;
+                params[num_ap].rtt_config.channel = get_channel_of_ie(&scan_param->ie_data[0],
                         scan_param->ie_length);
-                params[num_ap].peer = RTT_PEER_AP;
-                params[num_ap].num_burst = default_rtt_param.num_burst;
-                params[num_ap].num_frames_per_burst = default_rtt_param.num_frames_per_burst;
-                params[num_ap].num_retries_per_rtt_frame =
-                    default_rtt_param.num_retries_per_ftm;
-                params[num_ap].num_retries_per_ftmr = default_rtt_param.num_retries_per_ftmr;
-                params[num_ap].burst_period = default_rtt_param.burst_period;
-                params[num_ap].burst_duration = default_rtt_param.burst_duration;
-                params[num_ap].LCI_request = default_rtt_param.LCI_request;
-                params[num_ap].LCR_request = default_rtt_param.LCR_request;
-                params[num_ap].preamble = (wifi_rtt_preamble)default_rtt_param.preamble;
-                params[num_ap].bw = (wifi_rtt_bw)default_rtt_param.bw;
+                params[num_ap].rtt_config.peer = RTT_PEER_AP;
+                params[num_ap].rtt_config.num_burst = default_rtt_param.num_burst;
+                params[num_ap].rtt_config.num_frames_per_burst =
+                        default_rtt_param.num_frames_per_burst;
+                params[num_ap].rtt_config.num_retries_per_rtt_frame =
+                        default_rtt_param.num_retries_per_ftm;
+                params[num_ap].rtt_config.num_retries_per_ftmr =
+                        default_rtt_param.num_retries_per_ftmr;
+                params[num_ap].rtt_config.burst_period = default_rtt_param.burst_period;
+                params[num_ap].rtt_config.burst_duration = default_rtt_param.burst_duration;
+                params[num_ap].rtt_config.LCI_request = default_rtt_param.LCI_request;
+                params[num_ap].rtt_config.LCR_request = default_rtt_param.LCR_request;
+                params[num_ap].rtt_config.preamble = (wifi_rtt_preamble)default_rtt_param.preamble;
+                params[num_ap].rtt_config.bw = convert_channel_width_to_rtt_bw(channel_width);
+                if (params[num_ap].rtt_config.bw == WIFI_RTT_BW_5) {
+                    printf("Unsupported rtt bw %x \n",
+                            params[num_ap].rtt_config.bw);
+                    return;
+                }
+                if (params[num_ap].rtt_config.type == RTT_TYPE_2_SIDED_11AZ_NTB) {
+                    params[num_ap].rtt_config.num_frames_per_burst =
+                            default_rtt_param_v3.num_frames_per_burst;
+                    printf("num_frames_per_burst %d \n",
+                            params[num_ap].rtt_config.num_frames_per_burst);
+                    if (!ntb_min_meas_time) {
+                        params[num_ap].ntb_min_measurement_time =
+                                default_rtt_param_v3.ntb_min_measurement_time;
+                    } else {
+                        params[num_ap].ntb_min_measurement_time =
+                                ntb_min_meas_time;
+                    }
+                    if (!ntb_max_meas_time) {
+                         params[num_ap].ntb_max_measurement_time =
+                                default_rtt_param_v3.ntb_max_measurement_time;
+                    } else {
+                        params[num_ap].ntb_max_measurement_time =
+                                ntb_max_meas_time;
+                    }
+                }
                 if (rtt_to_file) {
-                    fprintf(w_fp, "%s %02x:%02x:%02x:%02x:%02x:%02x %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n", scan_param->ssid,
-                            params[num_ap].addr[0], params[num_ap].addr[1], params[num_ap].addr[2], params[num_ap].addr[3],
-                            params[num_ap].addr[4], params[num_ap].addr[5],params[num_ap].channel.center_freq,
-                            params[num_ap].channel.center_freq0, params[num_ap].channel.width, params[num_ap].type,params[num_ap].peer,
-                            params[num_ap].burst_period, params[num_ap].num_burst, params[num_ap].num_frames_per_burst,
-                            params[num_ap].num_retries_per_rtt_frame, params[num_ap].num_retries_per_ftmr,
-                            params[num_ap].LCI_request, params[num_ap].LCR_request, params[num_ap].burst_duration,
-                            params[num_ap].preamble, params[num_ap].bw);
+                    fprintf(w_fp, "%s %02x:%02x:%02x:%02x:%02x:%02x"
+                            " %d %d %d %d %d %d %d %d %d "
+                            "%d %d %d %d %d %d %lu %lu\n",
+                            scan_param->ssid,
+                            params[num_ap].rtt_config.addr[0],
+                            params[num_ap].rtt_config.addr[1],
+                            params[num_ap].rtt_config.addr[2],
+                            params[num_ap].rtt_config.addr[3],
+                            params[num_ap].rtt_config.addr[4],
+                            params[num_ap].rtt_config.addr[5],
+                            params[num_ap].rtt_config.channel.center_freq,
+                            params[num_ap].rtt_config.channel.center_freq0,
+                            params[num_ap].rtt_config.channel.width,
+                            params[num_ap].rtt_config.type,
+                            params[num_ap].rtt_config.peer,
+                            params[num_ap].rtt_config.burst_period,
+                            params[num_ap].rtt_config.num_burst,
+                            params[num_ap].rtt_config.num_frames_per_burst,
+                            params[num_ap].rtt_config.num_retries_per_rtt_frame,
+                            params[num_ap].rtt_config.num_retries_per_ftmr,
+                            params[num_ap].rtt_config.LCI_request,
+                            params[num_ap].rtt_config.LCR_request,
+                            params[num_ap].rtt_config.burst_duration,
+                            params[num_ap].rtt_config.preamble,
+                            params[num_ap].rtt_config.bw,
+                            params[num_ap].ntb_min_measurement_time,
+                            params[num_ap].ntb_max_measurement_time);
                 }
                 num_ap++;
             } else {
@@ -1471,36 +1677,64 @@
             fclose(w_fp);
     } else if (rtt_sta || rtt_nan) {
         printf(" Run initiator rtt sta/nan, rtt_sta = %d, rtt_nan = %d \n",
-            rtt_sta, rtt_nan);
+                rtt_sta, rtt_nan);
         /* As we have only one target */
-        memcpy(params[num_sta].addr, responder_addr, sizeof(mac_addr));
-        params[num_sta].channel = convert_channel(responder_channel, channel_width, is_6g);
-        printMsg("Adding(" MACSTR ") on Freq (%d),(%d) for 11mc RTT\n",
-                 MAC2STR(responder_addr),
-                 params[num_sta].channel.center_freq,
-                 params[num_sta].channel.center_freq0);
+        memcpy(params[num_sta].rtt_config.addr, responder_addr, sizeof(mac_addr));
+        params[num_sta].rtt_config.channel =
+                convert_channel(responder_channel, channel_width, is_6g);
+        printMsg("Adding(" MACSTR ") on Freq (%d) for %s RTT\n",
+                MAC2STR(responder_addr),
+                params[num_sta].rtt_config.channel.center_freq,
+                RttTypeToString(type));
         /*As we are doing STA-STA RTT */
-        params[num_sta].type = default_rtt_param.type;
+        params[num_sta].rtt_config.type = type;
         if (rtt_nan) {
-            params[num_sta].peer = RTT_PEER_NAN;
+            params[num_sta].rtt_config.peer = RTT_PEER_NAN;
         } else if (rtt_sta) {
-            params[num_sta].peer = RTT_PEER_STA;
+            params[num_sta].rtt_config.peer = RTT_PEER_STA;
         }
-        params[num_sta].num_burst = default_rtt_param.num_burst;
-        params[num_sta].num_frames_per_burst = default_rtt_param.num_frames_per_burst;
-        params[num_sta].num_retries_per_rtt_frame =
+        params[num_sta].rtt_config.num_burst = default_rtt_param.num_burst;
+        params[num_sta].rtt_config.num_frames_per_burst = default_rtt_param.num_frames_per_burst;
+        params[num_sta].rtt_config.num_retries_per_rtt_frame =
             default_rtt_param.num_retries_per_ftm;
-        params[num_sta].num_retries_per_ftmr = default_rtt_param.num_retries_per_ftmr;
-        params[num_sta].burst_period = default_rtt_param.burst_period;
-        params[num_sta].burst_duration = default_rtt_param.burst_duration;
-        params[num_sta].LCI_request = default_rtt_param.LCI_request;
-        params[num_sta].LCR_request = default_rtt_param.LCR_request;
-        params[num_sta].preamble = (wifi_rtt_preamble)default_rtt_param.preamble;
-        params[num_sta].bw = (wifi_rtt_bw)default_rtt_param.bw;
+        params[num_sta].rtt_config.num_retries_per_ftmr = default_rtt_param.num_retries_per_ftmr;
+        params[num_sta].rtt_config.burst_period = default_rtt_param.burst_period;
+        params[num_sta].rtt_config.burst_duration = default_rtt_param.burst_duration;
+        params[num_sta].rtt_config.LCI_request = default_rtt_param.LCI_request;
+        params[num_sta].rtt_config.LCR_request = default_rtt_param.LCR_request;
+        params[num_sta].rtt_config.preamble = (wifi_rtt_preamble)default_rtt_param.preamble;
+        params[num_sta].rtt_config.bw = convert_channel_width_to_rtt_bw(channel_width);
+        if (params[num_sta].rtt_config.bw == WIFI_RTT_BW_5) {
+            printf("Unsupported rtt bw %x \n",
+                    params[num_sta].rtt_config.bw);
+            return;
+        }
+
+        if (params[num_sta].rtt_config.type == RTT_TYPE_2_SIDED_11AZ_NTB) {
+            params[num_sta].rtt_config.num_frames_per_burst =
+                    default_rtt_param_v3.num_frames_per_burst;
+
+            printf("num_frames_per_burst %d \n",
+                    params[num_sta].rtt_config.num_frames_per_burst);
+            if (!ntb_min_meas_time) {
+                params[num_sta].ntb_min_measurement_time =
+                        default_rtt_param_v3.ntb_min_measurement_time;
+                } else {
+                    params[num_sta].ntb_min_measurement_time =
+                            ntb_min_meas_time;
+                }
+                if (!ntb_max_meas_time) {
+                    params[num_sta].ntb_max_measurement_time =
+                            default_rtt_param_v3.ntb_max_measurement_time;
+                } else {
+                    params[num_sta].ntb_max_measurement_time =
+                            ntb_max_meas_time;
+                }
+        }
+
         num_sta++;
 
     } else {
-
         /* Run by a provided rtt-ap-list file */
         FILE* fp;
         char bssid[ETHER_ADDR_STR_LEN];
@@ -1508,69 +1742,126 @@
         char first_char;
         memset(bssid, 0, sizeof(bssid));
         memset(ssid, 0, sizeof(ssid));
+        memset(params, 0, sizeof(params));
+
         /* Read a RTT AP list from a file */
         fp = fopen(rtt_aplist, "r");
         if (fp == NULL) {
             printMsg("\nRTT AP list file does not exist on %s.\n"
                     "Please specify correct full path or use default one, %s, \n"
                     "  by following order in file, such as:\n"
-                    "|SSID|BSSID|chan_num|Channel BW(0=20MHZ,1=40MZ,2=80MHZ)|"
-                    "RTT_Type(1=1WAY,2=2WAY,3=auto)|Peer Type(STA=0, AP=1)|Burst Period|"
-                    "No of Burst|No of FTM Burst|FTM Retry Count|FTMR Retry Count|LCI|LCR|"
-                    "Burst Duration|Preamble|Bandwith\n",
+                    "SSID | BSSID | chan_num |Channel BW(0=20MHZ,1=40MZ,2=80MHZ)|"
+                    " RTT_Type(1=1WAY,2=2WAY,3=auto) |Peer Type(STA=0, AP=1)| Burst Period|"
+                    " No of Burst| No of FTM Burst| FTM Retry Count| FTMR Retry Count| LCI| LCR|"
+                    " Burst Duration| Preamble|Channel_Bandwith|"
+                    " NTB Min Meas Time in units of 100us|\n",
+                    " NTB Max Meas Time in units of 10ms\n",
                     rtt_aplist, DEFAULT_RTT_FILE);
             return;
         }
-        printMsg("    %-16s%-20s%-8s%-12s%-10s%-10s%-16s%-10s%-14s%-11s%-12s%-5s%-5s%-15s%-10s\n",
-                "SSID", "BSSID", "chan", "Bandwidth", "RTT_Type", "RTT_Peer",
-                "Burst_Period", "No_Burst", "No_FTM_Burst", "FTM_Retry",
-                "FTMR_Retry", "LCI", "LCR", "Burst_duration", "Preamble", "Bandwidth");
         int i = 0;
         while (!feof(fp)) {
             if ((fscanf(fp, "%c", &first_char) == 1) && (first_char != '|')) {
-                fseek(fp, -1, SEEK_CUR);
-                result = fscanf(fp, "%s %s %u %u %u %u %u %u %u %u %u %hhu %hhu %u %hhu %hhu\n",
-                        ssid, bssid, (unsigned int*)&responder_channel,
-                        (unsigned int*)&channel_width,
-                        (unsigned int*)&params[i].type, (unsigned int*)&params[i].peer,
-                        &params[i].burst_period, &params[i].num_burst,
-                        &params[i].num_frames_per_burst,
-                        &params[i].num_retries_per_rtt_frame,
-                        &params[i].num_retries_per_ftmr,
-                        (unsigned char*)&params[i].LCI_request,
-                        (unsigned char*)&params[i].LCR_request,
-                        (unsigned int*)&params[i].burst_duration,
-                        (unsigned char*)&params[i].preamble,
-                        (unsigned char*)&params[i].bw);
-
-                if (result != 16) {
-                    printMsg("fscanf failed %d\n", result);
+                result = fseek(fp, -1, SEEK_CUR);
+                if (result != 0) {
+                    printMsg("fseek failed %d\n", result);
                     break;
                 }
-                params[i].channel = convert_channel(responder_channel, channel_width, is_6g);
-                parseMacAddress(bssid, params[i].addr);
 
-                printMsg("[%d] %-16s%-20s%-8u%-14u%-12d%-10d%-10u%-16u%-10u%-14u%-11u%-12u%-5hhu%-5hhu%-15u%-10hhu-10hhu\n",
-                        i+1, ssid, bssid, params[i].channel.center_freq,
-                        params[i].channel.center_freq0, params[i].channel.width,
-                        params[i].type, params[i].peer, params[i].burst_period,
-                        params[i].num_burst, params[i].num_frames_per_burst,
-                        params[i].num_retries_per_rtt_frame,
-                        params[i].num_retries_per_ftmr, params[i].LCI_request,
-                        params[i].LCR_request, params[i].burst_duration, params[i].preamble, params[i].bw);
+                result = fscanf(fp,"%s %s %u %u %u\n",
+                        ssid, bssid, (unsigned int*)&responder_channel,
+                        (unsigned int*)&channel_width,
+                        (unsigned int*)&params[i].rtt_config.type);
+                if (result != 5) {
+                    printMsg("fscanf failed to read ssid, bssid, channel, type: %d\n", result);
+                    break;
+                }
+
+                result = fscanf(fp, "%u %u %u %u %u %u %hhu %hhu %u %hhu %u\n",
+                        (unsigned int*)&params[i].rtt_config.peer,
+                        &params[i].rtt_config.burst_period,
+                        &params[i].rtt_config.num_burst,
+                        &params[i].rtt_config.num_frames_per_burst,
+                        (unsigned int*)&params[i].rtt_config.num_retries_per_rtt_frame,
+                        (unsigned int*)&params[i].rtt_config.num_retries_per_ftmr,
+                        (unsigned char*)&params[i].rtt_config.LCI_request,
+                        (unsigned char*)&params[i].rtt_config.LCR_request,
+                        (unsigned int*)&params[i].rtt_config.burst_duration,
+                        (unsigned char*)&params[i].rtt_config.preamble, &channel_width);
+                if (result != 11) {
+                    printMsg("fscanf failed to read mc params %d\n", result);
+                    break;
+                }
+                params[i].rtt_config.bw = convert_channel_width_to_rtt_bw(channel_width);
+                if (params[i].rtt_config.bw == WIFI_RTT_BW_5) {
+                    printf("Unsupported rtt bw %x \n", params[i].rtt_config.bw);
+                    break;
+                }
+
+                if (params[i].rtt_config.type == RTT_TYPE_2_SIDED_11AZ_NTB) {
+                    result = fscanf(fp, "%14lu %14lu\n",
+                            &params[i].ntb_min_measurement_time,
+                            &params[i].ntb_max_measurement_time);
+                    if (result != 2) {
+                        printMsg("fscanf failed to read az params %d\n", result);
+                        break;
+                    }
+                }
+
+                params[i].rtt_config.channel = convert_channel(responder_channel,
+                        channel_width, is_6g);
+                parseMacAddress(bssid, params[i].rtt_config.addr);
+
+                printMsg("Target: [%d]: ssid: %-16s\n"
+                        " BSSID:%-20s\n"
+                        " center freq: %-8u\n"
+                        " center freq0:%-14u\n"
+                        " channel_width: %-12d\n"
+                        " Type:%-15s\n"
+                        " peer:%-10u\n"
+                        " burst_period:%-16u\n"
+                        " num_burst:%-10u\n"
+                        " num_frames_per_burst:%-14u\n"
+                        " num_retries_per_rtt_frame:%-11u\n"
+                        " num_retries_per_ftmr:%-5hhu\n"
+                        " LCI_request: %-5hhu\n"
+                        " LCR_request: %-15u\n"
+                        " burst_duration: %-10hhu\n"
+                        " preamble:%-10hhu\n"
+                        " bw:%-10hhu\n"
+                        " ntb_min_measurement_time: %-14lu\n"
+                        " ntb_max_measurement_time: %-14lu\n",
+                        i+1, ssid, bssid,
+                        params[i].rtt_config.channel.center_freq,
+                        params[i].rtt_config.channel.center_freq0,
+                        params[i].rtt_config.channel.width,
+                        RttTypeToString(params[i].rtt_config.type),
+                        params[i].rtt_config.peer,
+                        params[i].rtt_config.burst_period,
+                        params[i].rtt_config.num_burst,
+                        params[i].rtt_config.num_frames_per_burst,
+                        params[i].rtt_config.num_retries_per_rtt_frame,
+                        params[i].rtt_config.num_retries_per_ftmr,
+                        params[i].rtt_config.LCI_request,
+                        params[i].rtt_config.LCR_request,
+                        params[i].rtt_config.burst_duration,
+                        params[i].rtt_config.preamble,
+                        params[i].rtt_config.bw,
+                        params[i].ntb_min_measurement_time,
+                        params[i].ntb_max_measurement_time);
 
                 i++;
             } else {
                 /* Ignore the rest of the line. */
                 result = fscanf(fp, "%*[^\n]");
                 if (result != 1) {
-                    printMsg("fscanf failed %d\n", result);
+                    printMsg("fscanf failed to read the next line %d\n", result);
                     break;
                 }
 
                 result = fscanf(fp, "\n");
                 if (result != 1) {
-                    printMsg("fscanf failed %d\n", result);
+                    printMsg("fscanf failed after reading next line%d\n", result);
                     break;
                 }
             }
@@ -1580,16 +1871,20 @@
         fp = NULL;
     }
 
-    wifi_rtt_event_handler handler;
-    handler.on_rtt_results = &onRTTResults;
+    wifi_rtt_event_handler_v3 handler;
+    memset(&handler, 0, sizeof(handler));
+    handler.on_rtt_results_v3 = &onRTTResultsV3;
+
     if (!rtt_to_file || rtt_sta || rtt_nan)  {
         if (num_ap || num_sta) {
             if (num_ap) {
                 printMsg("Configuring RTT for %d APs\n", num_ap);
-                result = hal_fn.wifi_rtt_range_request(rttCmdId, wlan0Handle, num_ap, params, handler);
+                result = hal_fn.wifi_rtt_range_request_v3(rttCmdId, wlan0Handle,
+                        num_ap, params, handler);
             } else if (num_sta) {
                 printMsg("Configuring RTT for %d sta \n", num_sta);
-                result = hal_fn.wifi_rtt_range_request(rttCmdId, wlan0Handle, num_sta, params, handler);
+                result = hal_fn.wifi_rtt_range_request_v3(rttCmdId, wlan0Handle,
+                        num_sta, params, handler);
             }
 
             if (result == WIFI_SUCCESS) {
@@ -1627,32 +1922,48 @@
 static void getRTTCapability()
 {
     int ret;
-    wifi_rtt_capabilities rtt_capability;
-    ret = hal_fn.wifi_get_rtt_capabilities(wlan0Handle, &rtt_capability);
+    wifi_rtt_capabilities_v3 rtt_capability;
+    ret = hal_fn.wifi_get_rtt_capabilities_v3(wlan0Handle, &rtt_capability);
     if (ret == WIFI_SUCCESS) {
         printMsg("Supported Capabilites of RTT :\n");
-        if (rtt_capability.rtt_one_sided_supported)
+        if (rtt_capability.rtt_capab.rtt_one_sided_supported)
             printMsg("One side RTT is supported\n");
-        if (rtt_capability.rtt_ftm_supported)
+        if (rtt_capability.rtt_capab.rtt_ftm_supported)
             printMsg("FTM(11mc) RTT is supported\n");
-        if (rtt_capability.lci_support)
+        if (rtt_capability.rtt_capab.lci_support)
             printMsg("LCI is supported\n");
-        if (rtt_capability.lcr_support)
+        if (rtt_capability.rtt_capab.lcr_support)
             printMsg("LCR is supported\n");
-        if (rtt_capability.bw_support) {
+        if (rtt_capability.rtt_capab.bw_support) {
             printMsg("BW(%s %s %s %s) are supported\n",
-                    (rtt_capability.bw_support & BW_20_SUPPORT) ? "20MHZ" : "",
-                    (rtt_capability.bw_support & BW_40_SUPPORT) ? "40MHZ" : "",
-                    (rtt_capability.bw_support & BW_80_SUPPORT) ? "80MHZ" : "",
-                    (rtt_capability.bw_support & BW_160_SUPPORT) ? "160MHZ" : "");
+                    (rtt_capability.rtt_capab.bw_support & BW_20_SUPPORT) ? "20MHZ" : "",
+                    (rtt_capability.rtt_capab.bw_support & BW_40_SUPPORT) ? "40MHZ" : "",
+                    (rtt_capability.rtt_capab.bw_support & BW_80_SUPPORT) ? "80MHZ" : "",
+                    (rtt_capability.rtt_capab.bw_support & BW_160_SUPPORT) ? "160MHZ" : "");
         }
-        if (rtt_capability.preamble_support) {
+        if (rtt_capability.rtt_capab.preamble_support) {
             printMsg("Preamble(%s %s %s) are supported\n",
-                    (rtt_capability.preamble_support & PREAMBLE_LEGACY) ? "Legacy" : "",
-                    (rtt_capability.preamble_support & PREAMBLE_HT) ? "HT" : "",
-                    (rtt_capability.preamble_support & PREAMBLE_VHT) ? "VHT" : "");
+                    (rtt_capability.rtt_capab.preamble_support & PREAMBLE_LEGACY) ? "Legacy" : "",
+                    (rtt_capability.rtt_capab.preamble_support & PREAMBLE_HT) ? "HT" : "",
+                    (rtt_capability.rtt_capab.preamble_support & PREAMBLE_VHT) ? "VHT" : "");
 
         }
+
+        if (rtt_capability.az_preamble_support) {
+            printMsg("AZ preamble is supported\n");
+        }
+
+        if (rtt_capability.az_bw_support) {
+            printMsg("AZ bw is supported\n");
+        }
+
+        if (rtt_capability.ntb_initiator_supported) {
+            printMsg("NTB initiator is supported\n");
+        }
+
+        if (rtt_capability.ntb_responder_supported) {
+            printMsg("NTB responder is supported\n");
+        }
     } else {
         printMsg("Could not get the rtt capabilities : %d\n", ret);
     }
@@ -1683,7 +1994,9 @@
             ret = WIFI_ERROR_NOT_SUPPORTED;
             goto exit;
         }
-        if (strcmp(param, "-config_id") == 0) {
+        if (strcmp(param, "-iface") == 0) {
+            ifHandle = wifi_get_iface_handle_by_iface_name(val_p);
+        } else if (strcmp(param, "-config_id") == 0) {
             msg.config_id = atoi(val_p);
         } else if (strcmp(param, "-neg_type") == 0) {
             msg.negotiation_type = atoi(val_p);
@@ -1714,12 +2027,19 @@
         }
     }
 
+    if (ifHandle == NULL) {
+        printMsg("-iface <> is mandatory\n");
+        goto exit;
+    }
+
     ret = twt_init_handlers();
     if (ret != WIFI_SUCCESS) {
         printMsg("Failed to initialize twt handlers %d\n", ret);
         goto exit;
     }
-    ret = twt_setup_request(wlan0Handle, &msg);
+
+    ret = twt_setup_request(ifHandle, &msg);
+
 exit:
     printMsg("%s:ret = %d\n", __FUNCTION__, ret);
     return;
@@ -1748,7 +2068,9 @@
             ret = WIFI_ERROR_NOT_SUPPORTED;
             goto exit;
         }
-        if (strcmp(param, "-config_id") == 0) {
+        if (strcmp(param, "-iface") == 0) {
+            ifHandle = wifi_get_iface_handle_by_iface_name(val_p);
+        } else if (strcmp(param, "-config_id") == 0) {
             msg.config_id = atoi(val_p);
         } else if (strcmp(param, "-all_twt") == 0) {
             msg.all_twt = atoi(val_p);
@@ -1761,12 +2083,19 @@
         }
     }
 
+    if (ifHandle == NULL) {
+        printMsg("-iface <> is mandatory\n");
+        goto exit;
+    }
+
     ret = twt_init_handlers();
     if (ret != WIFI_SUCCESS) {
         printMsg("Failed to initialize twt handlers %d\n", ret);
         goto exit;
     }
-    ret = twt_teardown_request(wlan0Handle, &msg);
+
+    ret = twt_teardown_request(ifHandle, &msg);
+
 exit:
     printMsg("%s:ret = %d\n", __FUNCTION__, ret);
     return;
@@ -1795,7 +2124,9 @@
             ret = WIFI_ERROR_NOT_SUPPORTED;
             goto exit;
         }
-        if (strcmp(param, "-config_id") == 0) {
+        if (strcmp(param, "-iface") == 0) {
+            ifHandle = wifi_get_iface_handle_by_iface_name(val_p);
+        } else if (strcmp(param, "-config_id") == 0) {
             msg.config_id = atoi(val_p);
         } else if (strcmp(param, "-all_twt") == 0) {
             msg.all_twt = atoi(val_p);
@@ -1808,12 +2139,19 @@
         }
     }
 
+    if (ifHandle == NULL) {
+        printMsg("-iface <> is mandatory\n");
+        goto exit;
+    }
+
     ret = twt_init_handlers();
     if (ret != WIFI_SUCCESS) {
         printMsg("Failed to initialize twt handlers %d\n", ret);
         goto exit;
     }
-    ret = twt_info_frame_request(wlan0Handle, &msg);
+
+    ret = twt_info_frame_request(ifHandle, &msg);
+
 exit:
     printMsg("%s:ret = %d\n", __FUNCTION__, ret);
     return;
@@ -1836,11 +2174,13 @@
     while ((param = *argv++) != NULL) {
         val_p = *argv++;
         if (!val_p || *val_p == '-') {
-            printMsg("%s: Need value following %s\n", __FUNCTION__, param);
+            printMsg("%s:Need value following %s\n", __FUNCTION__, param);
             ret = WIFI_ERROR_NOT_SUPPORTED;
             goto exit;
         }
-        if (strcmp(param, "-config_id") == 0) {
+        if (strcmp(param, "-iface") == 0) {
+            ifHandle = wifi_get_iface_handle_by_iface_name(val_p);
+        } else if (strcmp(param, "-config_id") == 0) {
             config_id = atoi(val_p);
         } else {
             printMsg("%s:Unsupported Parameter for get stats request\n", __FUNCTION__);
@@ -1849,8 +2189,15 @@
         }
     }
 
+    if (ifHandle == NULL) {
+        printMsg("-iface <> is mandatory\n");
+        goto exit;
+    }
+
     memset(&twt_stats, 0, sizeof(twt_stats));
-    ret = twt_get_stats(wlan0Handle, config_id, &twt_stats);
+
+    ret = twt_get_stats(ifHandle, config_id, &twt_stats);
+
     if (ret == WIFI_SUCCESS) {
         printMsg("TWT stats :\n");
         if (twt_stats.config_id)
@@ -1895,7 +2242,9 @@
             ret = WIFI_ERROR_NOT_SUPPORTED;
             goto exit;
         }
-        if (strcmp(param, "-config_id") == 0) {
+        if (strcmp(param, "-iface") == 0) {
+            ifHandle = wifi_get_iface_handle_by_iface_name(val_p);
+        } else if (strcmp(param, "-config_id") == 0) {
             config_id = atoi(val_p);
         } else {
             printMsg("%s:Unsupported Parameter for twt info request\n", __FUNCTION__);
@@ -1904,22 +2253,56 @@
         }
     }
 
+    if (ifHandle == NULL) {
+        printMsg("-iface <> is mandatory\n");
+        goto exit;
+    }
+
     ret = twt_init_handlers();
     if (ret != WIFI_SUCCESS) {
         printMsg("Failed to initialize twt handlers %d\n", ret);
         goto exit;
     }
-    ret = twt_clear_stats(wlan0Handle, config_id);
+    ret = twt_clear_stats(ifHandle, config_id);
+
 exit:
     printMsg("%s:ret = %d\n", __FUNCTION__, ret);
     return;
 }
 
-static void getTWTCapability() {
-    int ret;
+static void getTWTCapability(char *argv[]) {
+    wifi_error ret = WIFI_SUCCESS;
+    char *param, *val_p;
+
+    /* skip utility */
+    argv++;
+    /* skip command */
+    argv++;
+
+    while ((param = *argv++) != NULL) {
+        val_p = *argv++;
+        if (!val_p || *val_p == '-') {
+            printMsg("%s: Need value following %s\n", __FUNCTION__, param);
+            ret = WIFI_ERROR_NOT_SUPPORTED;
+            goto exit;
+        }
+        if (strcmp(param, "-iface") == 0) {
+            ifHandle = wifi_get_iface_handle_by_iface_name(val_p);
+        } else {
+            printMsg("%s:Unsupported Parameter for twt capability request\n", __FUNCTION__);
+            ret = WIFI_ERROR_INVALID_ARGS;
+            goto exit;
+        }
+    }
+
+    if (ifHandle == NULL) {
+        printMsg("-iface <> is mandatory\n");
+        goto exit;
+    }
+
     TwtCapabilitySet twt_capability;
 
-    ret = twt_get_capability(wlan0Handle, &twt_capability);
+    ret = twt_get_capability(ifHandle, &twt_capability);
     if (ret == WIFI_SUCCESS) {
         printMsg("Supported Capabilites of TWT :\n");
         if (twt_capability.device_capability.requester_supported)
@@ -1941,6 +2324,7 @@
     } else {
         printMsg("Could not get the twt capabilities : %d\n", ret);
     }
+exit:
     return;
 }
 
@@ -2007,53 +2391,6 @@
     return ret;
 }
 
-/* CHRA NAN RTT related */
-static void OnChreNanRttStateChanged(chre_nan_rtt_state state) {
-    printMsg("CHRE NAN RTT state update : %d\n", state);
-    putEventInCache(EVENT_TYPE_CHRE_NAN_RTT_STATE_UPDATED, "CHRE NAN RTT state updated");
-}
-
-static void enableChreNanRtt() {
-    wifi_error ret = WIFI_SUCCESS;
-    ret = hal_fn.wifi_nan_rtt_chre_enable_request(0, wlan0Handle, NULL);
-    if (ret != WIFI_SUCCESS) {
-        printMsg("Failed to enable CHRE NAN RTT: %d\n", ret);
-    }
-
-    return;
-}
-
-static void disableChreNanRtt() {
-    wifi_error ret = WIFI_SUCCESS;
-    ret = hal_fn.wifi_nan_rtt_chre_disable_request(0, wlan0Handle);
-    if (ret != WIFI_SUCCESS) {
-        printMsg("Failed to disable CHRE NAN RTT: %d\n", ret);
-    }
-
-    return;
-}
-
-static void registerChreCallback() {
-    wifi_error ret = WIFI_SUCCESS;
-    EventInfo info;
-    wifi_chre_handler handler;
-    handler.on_chre_nan_rtt_change = OnChreNanRttStateChanged;
-    ret = hal_fn.wifi_chre_register_handler(wlan0Handle, handler);
-    if (ret != WIFI_SUCCESS) {
-        printMsg("Failed to register CHRE callback: %d\n", ret);
-    } else {
-        while (true) {
-            memset(&info, 0, sizeof(info));
-            getEventFromCache(info);
-            if (info.type == EVENT_TYPE_CHRE_NAN_RTT_STATE_UPDATED) {
-                printMsg("Received CHRE NAN RTT state, end the CHRE NAN RTT monitor!!\n");
-                break;
-            }
-        }
-    }
-    return;
-}
-
 static void printCachedScanResults(wifi_cached_scan_report *cache_report) {
     int scanned_channel[MAX_CH_BUF_SIZE] = {0};
     wifi_cached_scan_result cached_results[MAX_CACHED_SCAN_RESULT];
@@ -2126,6 +2463,52 @@
     return;
 }
 
+/* CHRA NAN RTT related */
+static void OnChreNanRttStateChanged(chre_nan_rtt_state state) {
+    printMsg("CHRE NAN RTT state update : %d\n", state);
+    putEventInCache(EVENT_TYPE_CHRE_NAN_RTT_STATE_UPDATED, "CHRE NAN RTT state updated");
+}
+
+static void enableChreNanRtt() {
+    wifi_error ret = WIFI_SUCCESS;
+    ret = hal_fn.wifi_nan_rtt_chre_enable_request(0, wlan0Handle, NULL);
+    if (ret != WIFI_SUCCESS) {
+        printMsg("Failed to enable CHRE NAN RTT: %d\n", ret);
+    }
+
+    return;
+}
+
+static void disableChreNanRtt() {
+    wifi_error ret = WIFI_SUCCESS;
+    ret = hal_fn.wifi_nan_rtt_chre_disable_request(0, wlan0Handle);
+    if (ret != WIFI_SUCCESS) {
+        printMsg("Failed to disable CHRE NAN RTT: %d\n", ret);
+    }
+
+    return;
+}
+
+static void registerChreCallback() {
+    wifi_error ret = WIFI_SUCCESS;
+    EventInfo info;
+    wifi_chre_handler handler;
+    handler.on_chre_nan_rtt_change = OnChreNanRttStateChanged;
+    ret = hal_fn.wifi_chre_register_handler(wlan0Handle, handler);
+    if (ret != WIFI_SUCCESS) {
+        printMsg("Failed to register CHRE callback: %d\n", ret);
+    } else {
+        while (true) {
+            memset(&info, 0, sizeof(info));
+            getEventFromCache(info);
+            if (info.type == EVENT_TYPE_CHRE_NAN_RTT_STATE_UPDATED) {
+                printMsg("Received CHRE NAN RTT state, end the CHRE NAN RTT monitor!!\n");
+                break;
+            }
+        }
+    }
+    return;
+}
 static int GetCachedGScanResults(int max, wifi_scan_result *results, int *num)
 {
     int num_results = 64;
@@ -2604,15 +2987,15 @@
                 case WIFI_TAG_CHANNEL_SPEC:
                 {
                     wifi_channel_info *ch_spec = (wifi_channel_info *) tlv_data->value;
-                    printMsg("Channel Info: center_freq=%d, freq0=%d, freq1=%d, width=%s (%d)\n",
-                        RBchanWidthToString(ch_spec->width), ch_spec->center_freq,
-                        ch_spec->center_freq0, ch_spec->center_freq1);
+                    printMsg("Channel Info: center_freq=%d, freq0=%d, freq1=%d, width=%s\n",
+                        ch_spec->center_freq, ch_spec->center_freq0,
+                        ch_spec->center_freq1, RBchanWidthToString(ch_spec->width));
                     break;
                 }
 
                 case WIFI_TAG_WAKE_LOCK_EVENT:
                 {
-                    printMsg("Wake lock event = \"TO BE DONE LATER\"\n", tlv_data->value);
+                    printMsg("Wake lock event = \"TO BE DONE LATER\"\n");
                     break;
                 }
 
@@ -2620,7 +3003,7 @@
                 {
                     u64 tsf = 0;
                     memcpy(&tsf, tlv_data->value, tlv_data->length);
-                    printMsg("TSF value = %d\n", tsf);
+                    printMsg("TSF value = %llu\n", tsf);
                     break;
                 }
 
@@ -2809,10 +3192,15 @@
     char buffer[BSIZE];
     memset(buffer, 0, BSIZE);
 
-    ret = hal_fn.wifi_get_firmware_version(wlan0Handle, buffer, buffer_size);
+    if (ifHandle == NULL) {
+        printMsg("-iface <> is mandatory\n");
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+
+    ret = hal_fn.wifi_get_firmware_version(ifHandle, buffer, buffer_size);
 
     if (ret == WIFI_SUCCESS)
-        printMsg("FW version (len=%d):\n%s\n", strlen(buffer), buffer);
+        printMsg("FW version (len=%lu):\n%s\n", strlen(buffer), buffer);
     else
         printMsg("Failed to get FW version\n");
 
@@ -2828,10 +3216,15 @@
     char buffer[BSIZE];
     memset(buffer, 0, BSIZE);
 
-    ret = hal_fn.wifi_get_driver_version(wlan0Handle, buffer, buffer_size);
+    if (ifHandle == NULL) {
+        printMsg("-iface <> is mandatory\n");
+        return WIFI_ERROR_INVALID_ARGS;
+    }
+
+    ret = hal_fn.wifi_get_driver_version(ifHandle, buffer, buffer_size);
 
     if (ret == WIFI_SUCCESS)
-        printMsg("Driver version (len=%d):\n%s\n", strlen(buffer), buffer);
+        printMsg("Driver version (len=%lu):\n%s\n", strlen(buffer), buffer);
     else
         printMsg("Failed to get driver version\n");
 
@@ -3005,7 +3398,13 @@
     }
     memset(tx_report, 0, n_requested_pkt_fate * sizeof(*tx_report));
 
-    result = hal_fn.wifi_get_tx_pkt_fates(wlan0Handle, tx_report,
+    if (ifHandle == NULL) {
+        printMsg("-iface <> is mandatory\n");
+        result = WIFI_ERROR_INVALID_ARGS;
+        goto exit;
+    }
+
+    result = hal_fn.wifi_get_tx_pkt_fates(ifHandle, tx_report,
             n_requested_pkt_fate, &n_provided_fates);
     if (result != WIFI_SUCCESS) {
         printMsg("Logger get tx pkt fate command failed, err = %d\n", result);
@@ -3018,7 +3417,7 @@
         goto exit;
     }
 
-    printMsg("No: of tx pkt fates provided = %d\n", n_provided_fates);
+    printMsg("No: of tx pkt fates provided = %zu\n", n_provided_fates);
 
     w_fp = fopen(tx_pkt_fate_file, "w");
     if (!w_fp) {
@@ -3091,7 +3490,13 @@
     }
     memset(rx_report, 0, n_requested_pkt_fate * sizeof(*rx_report));
 
-    result = hal_fn.wifi_get_rx_pkt_fates(wlan0Handle, rx_report,
+    if (ifHandle == NULL) {
+        printMsg("-iface <> is mandatory\n");
+        result = WIFI_ERROR_INVALID_ARGS;
+        goto exit;
+    }
+
+    result = hal_fn.wifi_get_rx_pkt_fates(ifHandle, rx_report,
             n_requested_pkt_fate, &n_provided_fates);
     if (result != WIFI_SUCCESS) {
         printMsg("Logger get rx pkt fate command failed, err = %d\n", result);
@@ -3104,7 +3509,7 @@
         goto exit;
     }
 
-    printMsg("No: of rx pkt fates provided = %d\n", n_provided_fates);
+    printMsg("No: of rx pkt fates provided = %zu\n", n_provided_fates);
 
     w_fp = fopen(rx_pkt_fate_file, "w");
     if (!w_fp) {
@@ -3131,14 +3536,14 @@
         fprintf(w_fp, "Firmware Timestamp         :  %u\n", report_ptr->frame_inf.firmware_timestamp_usec);
         if (report_ptr->frame_inf.payload_type == FRAME_TYPE_ETHERNET_II) {
             frame_len = min(report_ptr->frame_inf.frame_len, (size_t)MAX_FRAME_LEN_ETHERNET);
-			fprintf(w_fp, "Frame Content (%04zu bytes) :  \n", frame_len);
-			fprhex(w_fp, report_ptr->frame_inf.frame_content.ethernet_ii_bytes, frame_len,
-				true);
+            fprintf(w_fp, "Frame Content (%04zu bytes) :  \n", frame_len);
+            fprhex(w_fp, report_ptr->frame_inf.frame_content.ethernet_ii_bytes, frame_len,
+                true);
         } else {
             frame_len = min(report_ptr->frame_inf.frame_len, (size_t)MAX_FRAME_LEN_80211_MGMT);
-			fprintf(w_fp, "Frame Content (%04zu bytes) :  \n", frame_len);
-			fprhex(w_fp, report_ptr->frame_inf.frame_content.ieee_80211_mgmt_bytes, frame_len,
-				true);
+            fprintf(w_fp, "Frame Content (%04zu bytes) :  \n", frame_len);
+            fprhex(w_fp, report_ptr->frame_inf.frame_content.ieee_80211_mgmt_bytes, frame_len,
+                true);
         }
         fprintf(w_fp, "\n--- END OF REPORT ---\n\n");
 
@@ -3348,6 +3753,8 @@
                 band = WIFI_BAND_ABG;
             }
             j++;
+        } else if ((strcmp(argv[j], "-iface") == 0)) {
+            ifHandle = wifi_get_iface_handle_by_iface_name(argv[j + 1]);
         } else if (strcmp(argv[j], "-scan_mac_oui") == 0 && isxdigit(argv[j+1][0])) {
             parseMacOUI(argv[++j], mac_oui);
         } else if ((strcmp(argv[j], "-ssid") == 0)) {
@@ -3410,33 +3817,30 @@
                printf(" flags %d\n", epno_ssid[epno_cfg.num_networks].flags);
             }
             j++;
-        } else if ((strcmp(argv[j], "-blacklist_bssids") == 0 && isxdigit(argv[j+1][0])) ||
-            (strcmp(argv[j], "-whitelist_ssids") == 0)) {
-            if (strcmp(argv[j], "-blacklist_bssids") == 0 && isxdigit(argv[j+1][0])) {
-                j++;
-                for (num_blacklist_bssids = 0;
-                    j < argc && isxdigit(argv[j][0]) &&
-                    num_blacklist_bssids < MAX_BLACKLIST_BSSID;
-                    j++, num_blacklist_bssids++) {
-                    parseMacAddress(argv[j], blacklist_bssids[num_blacklist_bssids]);
-                }
+        } else if (strcmp(argv[j], "-blacklist_bssids") == 0 && isxdigit(argv[j+1][0])) {
+            j++;
+            for (num_blacklist_bssids = 0;
+                j < argc && isxdigit(argv[j][0]) &&
+                num_blacklist_bssids < MAX_BLACKLIST_BSSID;
+                j++, num_blacklist_bssids++) {
+                parseMacAddress(argv[j], blacklist_bssids[num_blacklist_bssids]);
             }
-            if (strcmp(argv[j], "-whitelist_ssids") == 0) {
-                j++;
-                for (num_whitelist_ssids = 0;
-                    j < argc && (num_whitelist_ssids < MAX_WHITELIST_SSID);
-                    j++, num_whitelist_ssids++) {
-                        if ((strcmp(argv[j], "-blacklist_bssids") == 0) ||
-                            isxdigit(argv[j][0])) {
-                            num_whitelist_ssids--;
-                            continue;
-                        }
-                    strncpy(whitelist_ssids[num_whitelist_ssids], argv[j],
-                    min(strlen(argv[j]), (size_t)(MAX_SSID_LEN-1)));
-                }
-                /* Setting this flag to true here as -blacklist_bssids has already existing explicit handler */
-                set_roaming_configuration = true;
+            j -= 1;
+        } else if (strcmp(argv[j], "-whitelist_ssids") == 0) {
+            j++;
+            for (num_whitelist_ssids = 0;
+                j < argc && (num_whitelist_ssids < MAX_WHITELIST_SSID);
+                j++, num_whitelist_ssids++) {
+                   if ((strcmp(argv[j], "-blacklist_bssids") == 0) ||
+                        isxdigit(argv[j][0])) {
+                        num_whitelist_ssids--;
+                        continue;
+                    }
+                strncpy(whitelist_ssids[num_whitelist_ssids], argv[j],
+                min(strlen(argv[j]), (size_t)(MAX_SSID_LEN-1)));
             }
+            /* Setting this flag to true here as -blacklist_bssids has already existing explicit handler */
+            set_roaming_configuration = true;
             j -= 1;
         } else if (strcmp(argv[j], "-rssi_monitor") == 0 && isdigit(argv[j+1][0])) {
             rssi_monitor = atoi(argv[++j]);
@@ -3499,7 +3903,7 @@
             u8 rtt_type = atoi(argv[++j]);
             if (rtt_type == 1) {
                 printf("RTT Type is ONE-SIDED\n");
-                default_rtt_param.type = RTT_TYPE_1_SIDED;
+                type = RTT_TYPE_1_SIDED;
             }
         } else if ((strcmp(argv[j], "-o") == 0)) {
             /*
@@ -3548,6 +3952,33 @@
                         }
                     }
                 }
+
+                /* Read rtt_type if present */
+                if (argv[j+1]) {
+                    if (isdigit(argv[j+1][0])) {
+                        j++;
+                        type = (wifi_rtt_type)atoi(argv[j]);
+                        printf("rtt_type %d \n", type);
+                    }
+                }
+
+                /* Read ntb_min_meas_time if present */
+                if (argv[j+1] && (type == RTT_TYPE_2_SIDED_11AZ_NTB)) {
+                    if (isdigit(argv[j+1][0])) {
+                        j++;
+                        ntb_min_meas_time = atoi(argv[j]);
+                        printf("ntb_min_meas_time as %lu \n", ntb_min_meas_time);
+                    }
+                }
+
+                /* Read ntb_max_meas_time if present */
+                if (argv[j+1] && (type == RTT_TYPE_2_SIDED_11AZ_NTB)) {
+                    if (isdigit(argv[j+1][0])) {
+                        j++;
+                        ntb_max_meas_time = atoi(argv[j]);
+                        printf("ntb_max_meas_time as %lu \n", ntb_max_meas_time);
+                    }
+                }
             }
         }
     }
@@ -3590,8 +4021,28 @@
     } else if ((strcmp(argv[j], "-get") == 0) && (argc > 3)) {
         if ((strcmp(argv[j+1], "fw") == 0)) {
             log_cmd = LOG_GET_FW_VER;
+            j++;
+            while (j+1 < argc-1) {
+                if (strcmp(argv[j+1], "-iface") == 0) {
+                    j++;
+                    if (j+1 < argc-1) {
+                        ifHandle = wifi_get_iface_handle_by_iface_name(argv[j+1]);
+                    }
+                }
+                j++;
+            }
         } else if ((strcmp(argv[j+1], "driver") == 0)) {
             log_cmd = LOG_GET_DRV_VER;
+            j++;
+            while (j+1 < argc-1) {
+                if (strcmp(argv[j+1], "-iface") == 0) {
+                    j++;
+                    if (j+1 < argc-1) {
+                        ifHandle = wifi_get_iface_handle_by_iface_name(argv[j+1]);
+                    }
+                }
+                j++;
+            }
         } else if ((strcmp(argv[j+1], "memdump") == 0)) {
             log_cmd = LOG_GET_MEMDUMP;
             j++;
@@ -3629,6 +4080,11 @@
                         strncpy(tx_pkt_fate_file, argv[j+1], len);
                         tx_pkt_fate_file[len] = '\0';
                     }
+                } else if (strcmp(argv[j+1], "-iface") == 0) {
+                    j++;
+                    if (j+1 < argc-1) {
+                        ifHandle = wifi_get_iface_handle_by_iface_name(argv[j+1]);
+                    }
                 }
                 j++;
             }
@@ -3648,6 +4104,11 @@
                         strncpy(rx_pkt_fate_file, argv[j+1], len);
                         rx_pkt_fate_file[len] = '\0';
                     }
+                } else if (strcmp(argv[j+1], "-iface") == 0) {
+                    j++;
+                    if (j+1 < argc-1) {
+                        ifHandle = wifi_get_iface_handle_by_iface_name(argv[j+1]);
+                    }
                 }
                 j++;
             }
@@ -3885,11 +4346,12 @@
     "HT N/A   | VHT/HE MCS11 NSS2",
 };
 
-#define NUM_EHT_RATES (sizeof(eht_rates)/sizeof(eht_rates[0]))
+/* Legacy rates */
 #define NUM_RATES (sizeof(rates)/sizeof(rates[0]))
+#define NUM_EHT_RATES (sizeof(eht_rates)/sizeof(eht_rates[0]))
 
-#define RATE_SPEC_STR_LEN 10
-#define RATE_SPEC_CHECK_INDEX 27
+#define RATE_SPEC_STR_LEN       10
+#define RATE_SPEC_CHECK_INDEX   27
 const char rate_stat_preamble[][RATE_SPEC_STR_LEN] = {
     "OFDM",
     "CCK",
@@ -3961,9 +4423,9 @@
         return;
     }
 
-    printPeerinfoStats(local_peer_ptr);
-
-    if (local_peer_ptr->num_rate) {
+    if ((local_peer_ptr->num_rate == NUM_RATES) ||
+        (local_peer_ptr->num_rate == NUM_EHT_RATES)) {
+        printPeerinfoStats(local_peer_ptr);
         *buf += offsetof(wifi_peer_info, rate_stats);
         if (!*buf) {
             ALOGE("No valid rate_stats\n");
@@ -3976,10 +4438,11 @@
 void printPerLinkStats(wifi_link_stat *local_link_ptr, int link_id) {
     printMsg("Printing link statistics of the link:%d\n", link_id);
     printMsg("Identifier for the link = %d\n", local_link_ptr->link_id);
+    printMsg("State of the link = %d\n", local_link_ptr->state);
     printMsg("Radio on which link stats are sampled. = %d\n", local_link_ptr->radio);
     printMsg("Frequency on which link is operating. = %d MHz\n", local_link_ptr->frequency);
     printMsg("beacon_rx = %d\n", local_link_ptr->beacon_rx);
-    printMsg("average_tsf_offset= %d\n", local_link_ptr->average_tsf_offset);
+    printMsg("average_tsf_offset= %llu\n", local_link_ptr->average_tsf_offset);
     printMsg("leaky_ap_detected= %d\n", local_link_ptr->leaky_ap_detected);
     printMsg("leaky_ap_avg_num_frames_leaked= %d\n",
         local_link_ptr->leaky_ap_avg_num_frames_leaked);
@@ -4020,7 +4483,8 @@
 
     printPerLinkStats(local_link_ptr, link_id);
 
-    if (local_link_ptr->num_peers) {
+    /* For STA, peer would be only one - AP. */
+    if (local_link_ptr->num_peers == NUM_PEER_AP) {
         for (int j = 0; j < local_link_ptr->num_peers; j++) {
             *buf += offsetof(wifi_link_stat, peer_info);
             if (!*buf) {
@@ -4039,7 +4503,7 @@
     int channel_size = 0, num_channels = 0;
     int cca_avail_size = MAX_CH_BUF_SIZE;
 
-    if (!num_radios || !iface_ml_stat || !radio_stat) {
+    if (!num_radios || !radio_stat) {
         ALOGE("No valid radio stat data\n");
         return;
     }
@@ -4049,21 +4513,26 @@
     local_cca_ptr = (u8*)cca_stat;
 
     for (int i = 0; i < num_radios; i++) {
-        memset(&rx_stat[i], 0, sizeof(&rx_stat[i]));
+        memset(&rx_stat[i], 0, sizeof(wifi_radio_stat));
         memcpy(&rx_stat[i], (u8*)local_rx_ptr, offsetof(wifi_radio_stat, channels));
         local_rx_ptr += offsetof(wifi_radio_stat, channels);
         num_channels = rx_stat[i].num_channels;
-        if (num_channels) {
-            channel_size = sizeof(wifi_channel_stat)*num_channels;
-	    if (cca_avail_size > num_channels) {
-                memcpy(local_cca_ptr, (u8*)local_rx_ptr, channel_size);
-                cca_avail_size -= num_channels;
-            } else {
-                ALOGE("No space left for chan_stat!!: cca_avail: %d, req: %d\n",
+
+        if (num_channels >= MAX_WIFI_USABLE_CHANNELS) {
+            ALOGE("Invalid num_channels value %d\n", num_channels);
+            break;
+        }
+
+        channel_size = sizeof(wifi_channel_stat)*num_channels;
+        if (cca_avail_size > num_channels) {
+	    memcpy(local_cca_ptr, (u8*)local_rx_ptr, channel_size);
+            cca_avail_size -= num_channels;
+        } else {
+	    ALOGE("No space left for chan_stat!!: cca_avail: %d, req: %d\n",
                 cca_avail_size, num_channels);
-                break;
-	    }
-	}
+            break;
+        }
+
         if (i == (num_radios - 1)) {
             break;
         }
@@ -4071,11 +4540,15 @@
         local_cca_ptr += channel_size;
     }
     /* radio stat data and channel stats data is printed in printMultiLinkStats */
+    if (!iface_ml_stat) {
+        ALOGE("No valid ml stats data\n");
+        return;
+    }
 
     buf_ptr = (u8*)iface_ml_stat;
     ml_links = iface_ml_stat->num_links;
 
-    if (ml_links) {
+    if (ml_links < MAX_MLO_LINK) {
         buf_ptr += offsetof(wifi_iface_ml_stat, links);
         for (int i = 0; i < ml_links; i++) {
             if (!buf_ptr) {
@@ -4085,6 +4558,8 @@
             printMsg("-----------------------------------------------------\n\n");
             update_per_link_data(&buf_ptr, i);
         }
+    } else {
+        ALOGE("Invalid ml links %d\n", ml_links);
     }
 }
 
@@ -4103,7 +4578,7 @@
     int channel_size = 0, num_channels = 0;
     int cca_avail_size = MAX_CH_BUF_SIZE;
 
-    if (!num_radios || !iface_stat || !radio_stat) {
+    if (!num_radios || !radio_stat) {
         ALOGE("No valid radio stat data\n");
         return;
     }
@@ -4112,7 +4587,7 @@
     local_rx_stat_ptr = (u8*)radio_stat;
     local_cca_ptr = (u8*)cca_stat;
     for (int i = 0; i < num_radios; i++) {
-        memset(&rx_stat[i], 0, sizeof(&rx_stat[i]));
+        memset(&rx_stat[i], 0, sizeof(wifi_radio_stat));
         memcpy(&rx_stat[i], (u8*)local_rx_stat_ptr, offsetof(wifi_radio_stat, channels));
         local_rx_stat_ptr += offsetof(wifi_radio_stat, channels);
         num_channels = rx_stat[i].num_channels;
@@ -4123,7 +4598,7 @@
                 cca_avail_size -= num_channels;
             } else {
                 ALOGE("No space left for chan_stat!!: cca_avail: %d, req: %d\n",
-                cca_avail_size, num_channels);
+                    cca_avail_size, num_channels);
                 break;
             }
         }
@@ -4134,6 +4609,11 @@
         local_cca_ptr += channel_size;
     }
 
+    if (!iface_stat) {
+        ALOGE("No valid iface stats data\n");
+        return;
+    }
+
     num_peer = iface_stat->num_peers;
     printMsg("onLinkStatsResults num_peer = %d \n", num_peer);
     memset(&link_stat, 0, sizeof(wifi_iface_stat));
@@ -4181,10 +4661,12 @@
     printMsg("WIFI_FEATURE_TX_TRANSMIT_POWER  0x000400000 - apture Tx transmit power levels\n");
     printMsg("WIFI_FEATURE_CONTROL_ROAMING    0x000800000 - Enable/Disable firmware roaming\n");
     printMsg("WIFI_FEATURE_IE_WHITELIST       0x001000000 - Support Probe IE white listing\n");
-    printMsg("WIFI_FEATURE_SCAN_RAND          0x002000000 - Support MAC & Probe Sequence Number randomization\n");
+    printMsg("WIFI_FEATURE_SCAN_RAND          0x002000000 - "
+        "Support MAC & Probe Sequence Number randomization\n");
     printMsg("WIFI_FEATURE_SET_TX_POWER_LIMIT 0x004000000 - Support Tx Power Limit setting\n");
     printMsg("WIFI_FEATURE_USE_BODY_HEAD_SAR  0x008000000 - Support Using Body/Head Proximity for SAR\n");
-    printMsg("WIFI_FEATURE_DYNAMIC_SET_MAC    0x010000000 - Support changing MAC address without iface reset(down and up)\n");
+    printMsg("WIFI_FEATURE_DYNAMIC_SET_MAC    0x010000000 - Support changing MAC address without"
+        " iface reset(down and up)\n");
     printMsg("WIFI_FEATURE_SET_LATENCY_MODE   0x040000000 - Support Latency mode setting\n");
     printMsg("WIFI_FEATURE_P2P_RAND_MAC       0x080000000 - Support P2P MAC randomization\n");
     printMsg("WIFI_FEATURE_INFRA_60G          0x100000000 - Support for 60GHz Band\n");
@@ -4215,9 +4697,6 @@
         }
         radio_combinations = (wifi_radio_combination *)((u8*)radio_combinations + sizeof(u32) +
             (num_radio_configurations * sizeof(wifi_radio_configuration)));
-        if (!radio_combinations) {
-            break;
-        }
     }
     return;
 }
@@ -4258,6 +4737,7 @@
     printMsg("\nPrinting radio statistics of multi link\n");
     printMsg("--------------------------------------\n");
     for (int i = 0; i < radios; i++) {
+        printMsg("--------------------------------------\n");
         printMsg("radio = %d\n", rx_stat[i].radio);
         printMsg("on time = %d\n", rx_stat[i].on_time);
         printMsg("tx time = %d\n", rx_stat[i].tx_time);
@@ -4271,12 +4751,13 @@
         printMsg("on_time_pno_scan(duration)= %d\n", rx_stat[i].on_time_pno_scan);
         printMsg("on_time_hs20 = %d\n", rx_stat[i].on_time_hs20);
         printMsg("cca channel statistics: (num_channels: %d)\n", rx_stat[i].num_channels);
-        for (int j = new_chan_base; j < (new_chan_base + rx_stat[i].num_channels); j++) {
-            printMsg("center_freq=%d (%8s), radio_on_time %10d, cca_busytime %10d\n",
+        printMsg("--------------------------------------\n");
+            for (int j = new_chan_base; j < (new_chan_base + rx_stat[i].num_channels); j++) {
+                printMsg("center_freq=%d (%8s), radio_on_time %10d, cca_busytime %10d\n",
                 cca_stat[j].channel.center_freq,
                 frequency_to_channel(cca_stat[j].channel.center_freq),
                 cca_stat[j].on_time, cca_stat[j].cca_busy_time);
-        }
+            }
         new_chan_base += rx_stat[i].num_channels;
     }
     printMsg("\n");
@@ -4358,7 +4839,7 @@
             printMsg("%-28s  %10d   %10d     %10d      %10d\n",
                 eht_rates[i], eht_rate_stat[i].tx_mpdu, eht_rate_stat[i].rx_mpdu,
                 eht_rate_stat[i].mpdu_lost, eht_rate_stat[i].retries);
-	} else if (num_rate == NUM_RATES) {
+        } else if (num_rate == NUM_RATES) {
             printMsg("%-28s  %10d   %10d     %10d      %10d\n",
                 rates[i], rate_stat[i].tx_mpdu, rate_stat[i].rx_mpdu,
                 rate_stat[i].mpdu_lost, rate_stat[i].retries);
@@ -4391,7 +4872,12 @@
     wifi_channel channel[MAX_CH_BUF_SIZE] =  {0, };
     int num_channels = 0, i = 0;
 
-    int result = hal_fn.wifi_get_valid_channels(wlan0Handle, band, MAX_CH_BUF_SIZE,
+    if (ifHandle == NULL) {
+        printMsg("-iface <> is mandatory\n");
+        return;
+    }
+
+    int result = hal_fn.wifi_get_valid_channels(ifHandle, band, MAX_CH_BUF_SIZE,
             channel, &num_channels);
     if (result < 0) {
         printMsg("failed to get valid channels %d\n", result);
@@ -4409,11 +4895,11 @@
     int result = hal_fn.wifi_get_supported_feature_set(wlan0Handle, &set);
 
     if (result < 0) {
-        printMsg("Error %d\n",result);
+        printMsg("Error %d\n", result);
         return;
     }
     printFeatureListBitMask();
-    printMsg("Supported feature set bit mask - %x\n", set);
+    printMsg("Supported feature set bit mask - %lx\n", set);
     return;
 }
 
@@ -4430,7 +4916,7 @@
     }
     printFeatureListBitMask();
     for (int i = 0; i < size; i++)
-        printMsg("Concurrent feature set - %x\n", set[i]);
+        printMsg("Concurrent feature set - %lx\n", set[i]);
     return;
 }
 
@@ -4478,8 +4964,15 @@
         return WIFI_ERROR_OUT_OF_MEMORY;
     }
     memset(wake_reason_cnt, 0 , sizeof(WLAN_DRIVER_WAKE_REASON_CNT));
+
     wake_reason_cnt->cmd_event_wake_cnt_sz = EVENT_COUNT;
     wake_reason_cnt->cmd_event_wake_cnt = (int*)malloc(EVENT_COUNT * sizeof(int));
+    if (!wake_reason_cnt->cmd_event_wake_cnt) {
+        printMsg("%s:Malloc failed\n",__FUNCTION__);
+        free(wake_reason_cnt);
+        return WIFI_ERROR_OUT_OF_MEMORY;
+    }
+    memset(wake_reason_cnt->cmd_event_wake_cnt, 0 , EVENT_COUNT * sizeof(int));
 
     int result = hal_fn.wifi_get_wake_reason_stats(wlan0Handle, wake_reason_cnt);
     if (result < 0) {
@@ -4569,12 +5062,40 @@
     return ret;
 }
 
-static wifi_error getRoamingCapabilities()
+static wifi_error getRoamingCapabilities(char *argv[])
 {
     wifi_error ret;
     wifi_roaming_capabilities roam_capability;
+    char *param, *val_p;
 
-    ret = hal_fn.wifi_get_roaming_capabilities(wlan0Handle, &roam_capability);
+    /* skip utility */
+    argv++;
+    /* skip command */
+    argv++;
+
+    while ((param = *argv++) != NULL) {
+        val_p = *argv++;
+        if (!val_p || *val_p == '-') {
+            printMsg("%s: Need value following %s\n", __FUNCTION__, param);
+            ret = WIFI_ERROR_NOT_SUPPORTED;
+            goto exit;
+        }
+        if (strcmp(param, "-iface") == 0) {
+            ifHandle = wifi_get_iface_handle_by_iface_name(val_p);
+        } else {
+            printMsg("%s:Unsupported Param to get roaming capabilites request\n", __FUNCTION__);
+            ret = WIFI_ERROR_INVALID_ARGS;
+            goto exit;
+        }
+    }
+
+    if (ifHandle == NULL) {
+        printMsg("-iface <> is mandatory\n");
+        ret = WIFI_ERROR_INVALID_ARGS;
+        goto exit;
+    }
+
+    ret = hal_fn.wifi_get_roaming_capabilities(ifHandle, &roam_capability);
     if (ret == WIFI_SUCCESS) {
         printMsg("Roaming Capabilities\n"
             "max_blacklist_size = %d\n"
@@ -4583,12 +5104,18 @@
     } else {
         printMsg("Failed to get Roaming capabilities\n");
     }
+exit:
     return ret;
 }
 
 static wifi_error setFWRoamingState(fw_roaming_state_t state)
 {
     wifi_error ret = WIFI_SUCCESS;
+    ret = hal_fn.wifi_enable_firmware_roaming(wlan0Handle,
+            state);
+    if (ret != WIFI_SUCCESS) {
+        printMsg("Failed to set Firmware Roaming state %d\n", state);
+    }
 
     return ret;
 }
@@ -4737,6 +5264,8 @@
     wifi_error ret;
     wifi_interface_handle ifHandle = NULL;
 
+    memset(iface_name, 0, sizeof(iface_name));
+
     argv++; /* skip utility */
     argv++; /* skip -apf command */
 
@@ -4749,6 +5278,10 @@
             ret = WIFI_ERROR_INVALID_ARGS;
             goto usage;
         }
+    } else {
+        printMsg("argv is null\n");
+        ret = WIFI_ERROR_INVALID_ARGS;
+        goto usage;
     }
 
     ifHandle = wifi_get_iface_handle(halHandle, iface_name);
@@ -4758,11 +5291,6 @@
         goto usage;
     } else {
         while ((val_p = *argv++) != NULL) {
-            if (!val_p) {
-                printMsg("%s: Need value following %s\n", __FUNCTION__, val_p);
-                ret = WIFI_ERROR_NOT_SUPPORTED;
-                goto usage;
-            }
             if (strcmp(val_p, "-set") == 0) {
                 val_p = *argv++;
                 if (strcmp(val_p, "program") == 0) {
@@ -4866,7 +5394,7 @@
 
     if ((argc > 2) && (strcmp(argv[1], "enable") == 0)) {
         scenario = atoi(argv[2]);
-        if ((scenario < WIFI_POWER_SCENARIO_DEFAULT) || (scenario > SAR_CONFIG_SCENARIO_COUNT)) {
+        if ((scenario < WIFI_POWER_SCENARIO_INVALID) || (scenario > SAR_CONFIG_SCENARIO_COUNT)) {
             printMsg("Unsupported tx power value:%d: Allowed range -1 to 99\n", scenario);
             return;
         }
@@ -5011,18 +5539,18 @@
 
 static void printTwtUsage() {
     printf("Usage: halutil [OPTION]\n");
-    printf("halutil -twt -setup -config_id <> -neg_type <0 for individual TWT, 1 for broadcast TWT> "
+    printf("halutil -twt -setup -iface <> -config_id <> -neg_type <0 for individual TWT, 1 for broadcast TWT> "
             "-trigger_type <0 for non-triggered TWT, 1 for triggered TWT> "
             "-wake_dur_us <> -wake_int_us <> -wake_int_min_us <> "
             "-wake_int_max_us <> -wake_dur_min_us <> -wake_dur_max_us <> "
             "-avg_pkt_size <> -avg_pkt_num <> -wake_time_off_us <>\n");
-    printf("halutil -twt -info_frame -config_id <>"
+    printf("halutil -twt -info_frame -iface <> -config_id <>"
             " -all_twt <0 for individual setp request, 1 for all TWT> -resume_time_us <>\n");
-    printf("halutil -twt -teardown -config_id <> -all_twt <> "
+    printf("halutil -twt -teardown -iface <> -config_id <> -all_twt <> "
             " -neg_type <0 for individual TWT, 1 for broadcast TWT>\n");
-    printf("halutil -twt -get_stats -config_id <>\n");
-    printf("halutil -twt -clear_stats -config_id <>\n");
-    printf("halutil -get_capa_twt\n");
+    printf("halutil -twt -get_stats -iface <> -config_id <>\n");
+    printf("halutil -twt -clear_stats -iface <> -config_id <>\n");
+    printf("halutil -get_capa_twt -iface <>\n");
     printf("halutil -twt -event_chk\n");
     return;
 }
@@ -5152,7 +5680,7 @@
 }
 
 void
-ifacestr_to_wifi_interface_mode(char *iface_str, u8 *mode)
+ifacestr_to_wifi_interface_mode(char *iface_str, wifi_interface_mode *mode)
 {
    if (!strcasecmp(iface_str, "sta")) {
        *mode = WIFI_INTERFACE_STA;
@@ -5198,10 +5726,10 @@
 {
     char *delim_end;
     char *delim = strtok_r(val_p, ",", &delim_end);
-    u8 iface_mode;
+    wifi_interface_mode iface_mode = WIFI_INTERFACE_UNKNOWN;
     u32 iface_mode_mask = 0;
+
     while (delim != NULL) {
-        iface_mode = 0;
         ifacestr_to_wifi_interface_mode(delim, &iface_mode);
         if (iface_mode != WIFI_INTERFACE_UNKNOWN) {
             iface_mode_mask |= (1 << iface_mode);
@@ -5215,11 +5743,11 @@
 {
     char *param;
     char *val_p;
-    u32 band_mask;
-    u32 iface_mode_mask;
-    u32 filter_mask;
+    u32 band_mask = 0;
+    u32 iface_mode_mask = 0;
+    u32 filter_mask = 0;
     u32 max_size = 0;
-    u32 size;
+    u32 size = 0;
     wifi_error ret;
     wifi_usable_channel* channels = NULL;
 
@@ -5243,15 +5771,16 @@
         }
     }
 
-    printMsg("Usable channel param BAND:%d IFACE:%d FILTER:%d MAX_SIZE:%d\n", band_mask, iface_mode_mask, filter_mask, max_size);
-    if (max_size == 0) {
-        printMsg("Max size should be bigger than 0\n");
+    if ((max_size == 0) || (max_size > MAX_WIFI_USABLE_CHANNELS)) {
+        printMsg("Max size should be non-zero and less than MAX_WIFI_USABLE_CHANNELS\n");
         return WIFI_ERROR_INVALID_ARGS;
     }
+
     if (band_mask == 0) {
         printMsg("Band mask should be bigger than 0\n");
         return WIFI_ERROR_INVALID_ARGS;
     }
+    printMsg("Usable channel param BAND:%d IFACE:%d FILTER:%d MAX_SIZE:%d\n", band_mask, iface_mode_mask, filter_mask, max_size);
 
     channels = (wifi_usable_channel *)malloc(sizeof(wifi_usable_channel) * max_size);
     if (!channels) {
@@ -5378,15 +5907,17 @@
     printf(" -blacklist_bssids blacklist bssids\n");
     printf(" -whitelist_ssids set whitelist ssids\n"
            " -whitelist_ssids ssid1 ssid2 ...\n");
-    printf(" -get_roaming_capabilities get roaming capabilities\n");
+    printf(" -get_roaming_capabilities -iface <iface name> get roaming capabilities\n");
     printf(" -set_fw_roaming_state set FW roaming state\n");
     printf(" -logger [-start] [-d <debug_level> -f <flags> -i <max_interval_sec>\n"
            "                   -s <min_data_size> -n <ring_name>]\n"
            "                  [pktmonitor]\n"
-           "         [-get]   [fw] [driver] [feature] [memdump -o <filename>]\n"
+           "         [-get]   [fw] [-iface <iface name>]"
+           "         [-get]   [driver] [-iface <iface name>]\n"
+           "         [-get]   [feature] [memdump -o <filename>]\n"
            "                  [ringstatus] [ringdata -n <ring_name>]\n"
-           "                  [txfate -n <no of pkts> -f <filename>]\n"
-           "                  [rxfate -n <no of pkts> -f <filename>]\n"
+           "                  [txfate -n <no of pkts> -f <filename>] -iface <iface name>\n"
+           "                  [rxfate -n <no of pkts> -f <filename>] -iface <iface name>\n"
            "         [-set]   [loghandler] [alerthandler]\n");
     printf(" -rssi_monitor enable/disable\n");
     printf(" -max_rssi max rssi threshold for RSSI monitor\n");
@@ -5444,72 +5975,109 @@
             "                [-instant_mode <0-disable, 1-enable>]\n"
             "                [-instant_chan <2.4/5GHz channel in MHz >]\n");
     printf(" -nan [-publish] [-svc <svc_name>] [-info <svc info>\n"
-            "                [-pub_type <0/1/2>] [-pub_count <val>] [-rssi_thresh_flag <0/1>]\n"
-            "                [-tx_type <0/1>] [-ttl <val>] [-svc_awake_dw <val>] [-match_ind <0/1/2>]\n"
-            "                [-match_rx <0/ascii str>] [-match_tx <0/ascii str>]  [-passphrase <Passphrase value, len must not be less than 8 or greater than 63>]\n"
-            "                [-recv_flag <0 to 15>] [-csid <cipher suite type 0/1/2/4/8>] [-key_type <1 or 2>] [-pmk <PMK value>]\n"
-            "                [-scid <scid value>] [-dp_type <0-Unicast, 1-multicast>]\n"
-            "                [-secure_dp <0-No security, 1-Security>] [-ranging <0-disable, 1-enable>)]\n"
-            "                [-ranging_intvl [intrvl in ms betw two ranging measurements] -ranging_ind \n"
-            "                [BIT0 - Continuous Ranging event notification, BIT1 - Ingress distance is <=, BIT2 - Egress distance is >=.]\n"
-            "                [-ingress [Ingress distance in centimeters] \n"
-            "                [ -egress [Egress distance in centimeters] \n"
-            "                [-auto_dp_accept [0 - User response required to accept dp, 1 - User response not required to accept dp] \n");
-    printf(" -nan [-subscribe] [-svc <svc_name>] [-info <svc info>\n"
-            "                [-sub_type <0/1>] [-sub_count <val>] [-pub_ssi <0/1>]\n"
-            "                [-ttl <val>] [-svc_awake_dw <val>] [-match_ind <0/1/2>]\n"
-            "                [-match_rx <0/ascii str>] [-match_tx <0/ascii str>]\n"
-            "                [-mac_list <addr>] [-srf_use <0/1>] [-rssi_thresh_flag <0/1>]]\n"
-            "                [-srf_include <0/1>] [-srf_type <0/1>] [-recv_flag <0 to 7>]\n"
-            "                [-csid <cipher suite type 0/1/2/4/8>]  [-key_type <1 or 2>]\n"
-            "                [-scid <scid value>] [-dp_type <0-Unicast,1-multicast>]\n"
-            "                [-secure_dp <0-No security, 1-Security>] [-ranging <0-disable, 1-enable>)]\n"
-            "                [-ranging_intvl [intrvl in ms betw two ranging measurements] -ranging_ind \n"
-            "                [BIT0 - Continuous Ranging event notification, BIT1 - Ingress distance is <=, BIT2 - Egress distance is >=.]\n"
-            "                [-ingress [Ingress distance in centimeters] \n"
-            "                [ -egress [Egress distance in centimeters] \n");
+            "    [-pub_type <0/1/2>] [-pub_count <val>] [-rssi_thresh_flag <0/1>]\n"
+            "    [-tx_type <0/1>] [-ttl <val>] [-svc_awake_dw <val>] [-match_ind <0/1/2>]\n"
+            "    [-match_rx <0/ascii str>] [-match_tx <0/ascii str>]"
+            "    [-passphrase <Passphrase value, len must not be less than 8 or greater than 63>]\n"
+            "    [-recv_flag <0 to 15>] [-csid <cipher suite type 0/1/2/4/8>]"
+            "    [-key_type <1 or 2>] [-pmk <PMK value>]\n"
+            "    [-scid <scid value>] [-dp_type <0-Unicast, 1-multicast>]\n"
+            "    [-secure_dp <0-No security, 1-Security>] [-ranging <0-disable, 1-enable>)]\n"
+            "    [-ranging_intvl [intrvl in ms betw two ranging measurements] -ranging_ind \n"
+            "    [BIT0 - Continuous Ranging event notification, "
+            "    BIT1 - Ingress distance is <=, BIT2 - Egress distance is >=.]\n"
+            "    [-ingress [Ingress distance in centimeters] \n"
+            "    [ -egress [Egress distance in centimeters] \n"
+            "    [-auto_dp_accept [0 - User response required to accept dp,"
+            "    1 - User response not required to accept dp] \n"
+            "    [-suspendable <0/1>] [-nik <local nik of 16 chars>]\n"
+            "    [-bs_methods <supported bootstrapping methods>] \n"
+            "    [-pairing_setup <supported 0/1>] [-pairing_cache <supported 0/1]"
+            "    [-pairing_verification <supported 0/1>] \n");
+    printf(" -nan [-subscribe] [-svc <svc_name>] [-info <svc info>]\n"
+            "    [-sub_type <0/1>] [-sub_count <val>] [-pub_ssi <0/1>]\n"
+            "    [-ttl <val>] [-svc_awake_dw <val>] [-match_ind <0/1/2>]\n"
+            "    [-match_rx <0/ascii str>] [-match_tx <0/ascii str>]\n"
+            "    [-mac_list <addr>] [-srf_use <0/1>] [-rssi_thresh_flag <0/1>]]\n"
+            "    [-srf_include <0/1>] [-srf_type <0/1>] [-recv_flag <0 to 7>]\n"
+            "    [-csid <cipher suite type 0/1/2/4/8>]  [-key_type <1 or 2>]\n"
+            "    [-scid <scid value>] [-dp_type <0-Unicast,1-multicast>]\n"
+            "    [-secure_dp <0-No security, 1-Security>] [-ranging <0-disable, 1-enable>)]\n"
+            "    [-ranging_intvl [intrvl in ms betw two ranging measurements] -ranging_ind \n"
+            "    [BIT0 - Continuous Ranging event notification, "
+            "    BIT1 - Ingress distance is <=, BIT2 - Egress distance is >=.]\n"
+            "    [-ingress [Ingress distance in centimeters] \n"
+            "    [ -egress [Egress distance in centimeters] \n"
+            "    [-suspendable <0/1>] [-nik <local nik of 16 chars>]\n"
+            "    [-bs_methods <supported bootstrapping methods>] \n"
+            "    [-pairing_setup <supported 0/1>] [-pairing_cache <supported 0/1]"
+            "    [-pairing_verification <supported 0/1>] \n");
     printf(" -nan [-cancel_pub <publish id>]\n");
     printf(" -nan [-cancel_sub <subscribe id>\n");
     printf(" -nan [-transmit] [-src_id <instance id>] [-dest_id <instance id>]\n"
-            "                [-peer_addr <mac addr>] [-info <svc info>] \n"
-            "                [-recv_flag <1-Disable followUp response, 0-Enable followup response from FW>]\n");
+            "    [-peer_addr <mac addr>] [-info <svc info>] \n"
+            "    [-recv_flag <1-Disable followUp response, 0-Enable followup response from FW>]\n");
     printf(" -nan [-get_capabilities]\n");
     printf("\n ****** Nan Data Path Commands ***** \n");
     printf(" -nan [-create] [-iface <iface name>]\n");
     printf(" -nan [-delete] [-iface <iface name>]\n");
     printf(" -nan [-init] [-pub_id <pub id>] [-disc_mac <discovery mac addr>]\n"
-            "                [-chan_req_type <NAN DP channel config options>]\n"
-            "                [-chan <channel in mhz>] [-iface <iface>] [-sec <security>]  [-key_type <1 or 2>\n"
-            "                [-qos <qos>] [-info <seq of values in the frame body>]  [-passphrase <Passphrase value, len must not be less than 8 or greater than 63>]\n"
-            "                [-csid <cipher suite type 0/1/2/4/8>] [-key_type <1 or 2>]  [-pmk <PMK value>] [-svc <svc_name>]\n");
+            "    [-chan_req_type <NAN DP channel config options>]\n"
+            "    [-chan <channel in mhz>] [-iface <iface>] [-sec <security>] [-key_type <1 or 2>\n"
+            "    [-qos <qos>] [-info <seq of values in the frame body>]"
+            "    [-passphrase <Passphrase value, len must not be less than 8 or greater than 63>]\n"
+            "    [-csid <cipher suite type 0/1/2/4/8>] [-key_type <1 or 2>]"
+            "    [-pmk <PMK value>] [-svc <svc_name>]\n"
+            "    [-lcl_svc_id <local service id>] \n");
     printf(" -nan [-resp] [-ndp_id <NDP id>] [-iface <NDP iface name>]\n"
-            "                [-resp_code <accept = 0, reject = 1>] [-qos <qos>]  [-key_type <1 or 2>] \n"
-            "                [-info <seq of values in the frame body>]  [-passphrase <Passphrase value, len must not be less than 8 or greater than 63>]\n"
-            "                [-csid <cipher suite type 0/1/2/4/8>] [-key_type <1 or 2>] [-pmk <PMK value>] [-svc <svc_name>]\n");
+            "    [-resp_code <accept = 0, reject = 1>] [-qos <qos>]  [-key_type <1 or 2>] \n"
+            "    [-info <seq of values in the frame body>] "
+            "    [-passphrase <Passphrase value, len must not be less than 8 or greater than 63>]\n"
+            "    [-csid <cipher suite type 0/1/2/4/8>]"
+            "    [-key_type <1 or 2>] [-pmk <PMK value>] [-svc <svc_name>]\n"
+            "    [-lcl_svc_id <local service id>] \n");
     printf(" -nan [-end] [-inst_count <count>] [-inst_id <NDP id>\n");
     printf(" -nan [-up] [-iface <iface name>] [-ip <ip>]\n");
     printf(" -nan [-addr]\n");
     printf(" -nan [-event_chk]\n");
     printf(" -nan [-ver]\n");
     printf(" -nan [-exit]\n");
+    printf(" -nan [-suspend] -svc_id [service_id]\n");
+    printf(" -nan [-resume] -svc_id [service_id]\n");
+    printf(" -nan [-pairing_req] [-pub_id <instance id>]\n"
+           "      [-type <0-setup, 1-verification>] [-peer_addr <mac addr>]\n"
+           "      [-password <password>] [-csid <cipher suite - 64/128>] [-akm <0-SAE, 1-PASN] \n"
+           "      [-nik <local nik>] [-pairing_cache <1-Enable , 0-Disable pairing cache>]\n"
+           "      [-pmk <32 byte PMK value>]\n");
+    printf(" -nan [-pairing_resp] [-pairing_id <pairing instance id>]\n"
+           "      [-rsp_code <0-ACCEPT,1-REJECT>] [-type <0-setup, 1-verification>]\n"
+           "      [-password <password>] [-csid <cipher suite - 64/128>] [-akm <0-SAE, 1-PASN] \n"
+           "      [-nik <local nik>] [-pairing_cache <1-Enable , 0-Disable pairing cache>]\n"
+           "      [-pmk <32 byte PMK value>]\n");
+    printf(" -nan [-pairing_end] -pid <pairing_instance_id>\n");
+    printf(" -nan [-bs_req] -dest_id <peer inst id> -lcl_id <local inst id> -peer_addr <mac addr>\n"
+           "      [-bs_methods <supported bootstrapping methods>] [-comeback <is it comeback BS req>]\n"
+           "      [-cookie <cookie info>] [-info <svc info>] [-sdea_info <sdea svc info>]\n");
+    printf(" -nan [-bs_resp] -dest_id <peer inst id> -lcl_id <local inst id> -peer_addr <macaddr>\n"
+           "      [-rsp_code <0-ACCEPT, 1-REJECT, 2- COMEBACK>] [-comeback_delay]\n"
+           "      [-cookie <cookie info>] [-info <svc info>] [-sdea_info <sdea svc info>]\n");
     printf(" -dscp [-set] [-s <start>] [-e <end>] [-ac <access_category>]\n");
     printf(" -dscp [-reset] \n");
-    printf(" -ch_avoid [-unsafe <band type, a,b>,<channel number>,<power capacity, maximum output for the channel in dBm>]\n"
-            "               -unsafe can be used multiple times\n"
-            "               b for BAND_24GHZ\n"
-            "               a for BAND_5GHZ\n"
-            "          [-m <mandatory flag as decimal>]\n"
-            "               1 << 0 for FLAG_UNSPECIFIED \n"
-            "               1 << 1 for FLAG_WIFI_DIRECT\n"
-            "               1 << 2 for FLAG_SOFTAP\n"
-            "               1 << 4 for FLAG_WIFI_AWARE\n");
-    printf(" -usable_ch [-b <band_mask>], [-i <iface_mask>], [-f <filter_mask>], [-m <max_size of channel>]\n"
-            "           [-b 2g,5g,6g]\n"
-            "           [-i sta,nan,softap,p2p_go,p2p_cli]\n");
+    printf(" -ch_avoid [-unsafe <band type, a,b>,<channel number>,"
+            "   <power capacity, maximum output for the channel in dBm>]\n"
+            "   -unsafe can be used multiple times b for BAND_24GHZ\n"
+            "   a for BAND_5GHZ [-m <mandatory flag as decimal>]\n"
+            "   1 << 0 for FLAG_UNSPECIFIED \n"
+            "   1 << 1 for FLAG_WIFI_DIRECT\n"
+            "   1 << 2 for FLAG_SOFTAP\n"
+            "   1 << 4 for FLAG_WIFI_AWARE\n");
+    printf(" -usable_ch [-b <band_mask>], [-i <iface_mask>], [-f <filter_mask>], "
+            "   [-m <max_size of channel>] [-b 2g,5g,6g]\n"
+            "   [-i sta,nan,softap,p2p_go,p2p_cli]\n");
     printf("-ifadd -name <virtual iface name to be created>"
            " -type <0 for STA, 1 for AP, 2 for P2P, 3 for NAN>\n");
     printf("-ifdel -name <virtual iface name to be deleted>\n");
-    printf(" -voip_mode <interface_name> <0|1>    voip mode off/on on particular interface\n");
+    printf(" -voip_mode <interface_name> <0|1> voip mode off/on on particular interface\n");
     printf(" -dtim_multiplier <dtim count>  Set suspend bcn_li_dtim.\n");
     printf(" -on_ssr  cmd to trigger sub system restart.\n");
     printf(" -getSupportedRadioMatrix  cmd to get the supported radio combo matrix.\n");
@@ -5535,9 +6103,29 @@
     return WIFI_SUCCESS;
 }
 
+static wifi_interface_handle wifi_get_iface_handle_by_iface_name(char *val_p) {
+    /* Interface name */
+    char iface_name[IFNAMSIZ+1];
+    wifi_interface_handle ifHandle = NULL;
+
+    memset(iface_name, 0, sizeof(iface_name));
+
+    if (!set_interface_params(iface_name, val_p, (IFNAMSIZ - 1))) {
+        printMsg("set interface name successfull %s\n", iface_name);
+    } else {
+        printMsg("Invalid iface name\n");
+        return ifHandle;
+    }
+    ifHandle = wifi_get_iface_handle(halHandle, iface_name);
+    if (ifHandle == NULL) {
+        printMsg("Invalid iface handle for the requested interface\n");
+    }
+    return ifHandle;
+}
+
 void OnNanNotifyResponse(transaction_id id, NanResponseMsg* rsp_data) {
-    if(rsp_data) {
-    switch(rsp_data->response_type) {
+    if (rsp_data) {
+    switch (rsp_data->response_type) {
     case NAN_RESPONSE_ENABLED:
         printMsg("Nan Enable Response Received, status = %d\n", rsp_data->status);
         break;
@@ -5582,6 +6170,31 @@
     case NAN_DP_END:
         printMsg("Nan Data Path End Response Received, status = %d\n", rsp_data->status);
         break;
+    case NAN_SUSPEND_REQUEST_RESPONSE:
+        printMsg("Nan Suspend Response Received, status = %d\n", rsp_data->status);
+        break;
+    case NAN_RESUME_REQUEST_RESPONSE:
+        printMsg("Nan Resume Response Received, status = %d\n", rsp_data->status);
+        break;
+    case NAN_PAIRING_INITIATOR_RESPONSE:
+        printMsg("Pairing init response received, pairing_instance_id = %d, status = %d\n",
+                rsp_data->body.pairing_request_response.paring_instance_id, rsp_data->status);
+        break;
+    case NAN_PAIRING_RESPONDER_RESPONSE:
+        printMsg("Pairing Response Received, status = %d\n", rsp_data->status);
+        break;
+    case NAN_PAIRING_END:
+        printMsg("Pairing End Response Received, status = %d\n", rsp_data->status);
+        break;
+    case NAN_BOOTSTRAPPING_INITIATOR_RESPONSE:
+        printMsg("Bootstrapping init response received, Bootstrapping_instance_id = %d,"
+                "status = %d\n",
+                rsp_data->body.bootstrapping_request_response.bootstrapping_instance_id,
+                rsp_data->status);
+        break;
+    case NAN_BOOTSTRAPPING_RESPONDER_RESPONSE:
+        printMsg("Bootstrapping Response Received, status = %d\n", rsp_data->status);
+        break;
     case NAN_GET_CAPABILITIES:
         printMsg("Nan Get Capabilities Response Received, status = %d\n", rsp_data->status);
         printMsg("max_concurrent_nan_clusters = %d\n",
@@ -5614,6 +6227,10 @@
             rsp_data->body.nan_capabilities.max_sdea_service_specific_info_len);
         printMsg("ndpe_attr_supported = %d\n",
             rsp_data->body.nan_capabilities.ndpe_attr_supported);
+        printMsg("suspension_supported = %d\n",
+            rsp_data->body.nan_capabilities.is_suspension_supported);
+        printMsg("pairing_supported = %d\n",
+            rsp_data->body.nan_capabilities.is_pairing_supported);
         break;
     default:
         printMsg("Unknown Response Received, %d\n",
@@ -5668,14 +6285,22 @@
             event->sdea_service_specific_info_len,
             event->sdea_service_specific_info);
     }
+    printMsg("Enable Pairing cache: %d\n", event->peer_pairing_config.enable_pairing_cache);
+    printMsg("Enable Pairing setup: %d\n", event->peer_pairing_config.enable_pairing_setup);
+    printMsg("Enable Pairing verification: %d\n",
+        event->peer_pairing_config.enable_pairing_verification);
+    printMsg("Peer Bootstrapping methods: %d\n",
+        event->peer_pairing_config.supported_bootstrapping_methods);
+    prhex_msg("NIRA nonce", event->nira.nonce, NAN_IDENTITY_NONCE_LEN);
+    prhex_msg("NIRA tag", event->nira.tag, NAN_IDENTITY_TAG_LEN);
     /* Event enabled is not available in android-m */
     putEventInCache(EVENT_TYPE_SUBSCRIBE_MATCHED,
         "SubscribeMatched");
 }
 void OnNanEventMatchExpired (NanMatchExpiredInd* event) {
     printMsg("NanMatchExpired between publish_subscribe_id = %u "
-        "and peer_instance_id = %u\n",
-        event->publish_subscribe_id, event->requestor_instance_id);
+            "and peer_instance_id = %u\n",
+            event->publish_subscribe_id, event->requestor_instance_id);
 }
 void OnNanEventSubscribeTerminated (NanSubscribeTerminatedInd* event) {
     char msg_buf[MAX_NAN_MSG_BUF_SIZE] = {'\0'};
@@ -5803,6 +6428,61 @@
 void OnNanDataPathScheduleUpdateInd (NanDataPathScheduleUpdateInd *event) {
     printMsg("\n Received NanDataPathScheduleUpdateInd\n");
 }
+void OnNanSuspensionStatus (NanSuspensionModeChangeInd *event) {
+    printMsg("\n Received NanSuspensionModeChangeInd\n");
+}
+void OnNanEventPairingIndication(NanPairingRequestInd* event) {
+    printMsg("\n Local service id = %d\n", event->publish_subscribe_id);
+    printMsg(" Discovery MAC addr of the peer/initiator(" MACSTR ")\n",
+        MAC2STR(event->peer_disc_mac_addr));
+    printMsg(" pairing id = %d\n", event->pairing_instance_id);
+    printMsg(" request type = %d\n", event->nan_pairing_request_type);
+    printMsg(" pairing cache enabled = %d\n", event->enable_pairing_cache);
+    prhex_msg(" NIRA nonce", (u8 *)event->nira.nonce, NAN_IDENTITY_NONCE_LEN);
+    prhex_msg(" NIRA tag", (u8 *)event->nira.tag, NAN_IDENTITY_TAG_LEN);
+    putEventInCache(EVENT_TYPE_NAN_PAIRING_REQUEST_INDICATION,
+        "NanPairingEventIndication");
+}
+
+void OnNanEventPairingConfirmation(NanPairingConfirmInd* event) {
+    printMsg("\n pairing id = %d\n", event->pairing_instance_id);
+    printMsg(" rsp_code = %d\n", event->rsp_code);
+    printMsg(" reason = %s\n", event->reason_code);
+    printMsg(" request type = %d\n", event->nan_pairing_request_type);
+    printMsg(" pairing cache enabled = %d\n", event->enable_pairing_cache);
+    prhex_msg(" Peer NIK", event->npk_security_association.peer_nan_identity_key,
+        NAN_IDENTITY_KEY_LEN);
+    prhex_msg(" Local NIK", event->npk_security_association.local_nan_identity_key,
+        NAN_IDENTITY_KEY_LEN);
+    printMsg(" akm = %d\n", event->npk_security_association.akm);
+    printMsg(" csid = %d\n", event->npk_security_association.cipher_type);
+    prhex_msg(" NPK", (u8 *)event->npk_security_association.npk.pmk,
+        event->npk_security_association.npk.pmk_len);
+
+    putEventInCache(EVENT_TYPE_NAN_PAIRING_CONFIRMATION, "NanPairingEventConfirmation");
+}
+void OnNanEventBootstrappingIndication(NanBootstrappingRequestInd* event) {
+    printMsg("\n Requestor service id = %d\n", event->requestor_instance_id);
+    printMsg(" Local service id = %d\n", event->publish_subscribe_id);
+    printMsg(" Discovery MAC addr of the peer/initiator(" MACSTR ")\n",
+        MAC2STR(event->peer_disc_mac_addr));
+    printMsg(" Peer bootstrapping methods = %d\n", event->request_bootstrapping_method);
+    printMsg(" Bootstrapping instance id = %d\n", event->bootstrapping_instance_id);
+    putEventInCache(EVENT_TYPE_NAN_BOOTSTRAP_REQUEST_INDICATION,
+        "NanBootstrappingEventIndication");
+}
+
+void OnNanEventBootstrappingConfirmation(NanBootstrappingConfirmInd* event) {
+    printMsg("\n Bootstrapping instance id = %d\n", event->bootstrapping_instance_id);
+    printMsg(" rsp_code = %d\n", event->rsp_code);
+    printMsg(" reason = %d\n", event->reason_code);
+    printMsg(" come_back_delay = %d\n", event->come_back_delay);
+    if (event->cookie_length) {
+        prhex_msg("Cookie: ", event->cookie, event->cookie_length);
+    }
+    putEventInCache(EVENT_TYPE_NAN_BOOTSTRAP_CONFIRMATION,
+        "NanBootstrappingEventCOnfirmation");
+}
 
 wifi_error nan_init_handlers(void) {
     wifi_error ret = WIFI_SUCCESS;
@@ -5826,7 +6506,12 @@
     handlers.EventRangeRequest = OnNanRangeRequestInd;
     handlers.EventRangeReport = OnNanRangeReportInd;
     handlers.EventScheduleUpdate = OnNanDataPathScheduleUpdateInd;
-    ret = nan_register_handler(wlan0Handle , handlers);
+    handlers.EventSuspensionModeChange = OnNanSuspensionStatus;
+    handlers.EventPairingRequest = OnNanEventPairingIndication;
+    handlers.EventPairingConfirm = OnNanEventPairingConfirmation;
+    handlers.EventBootstrappingRequest = OnNanEventBootstrappingIndication;
+    handlers.EventBootstrappingConfirm = OnNanEventBootstrappingConfirmation;
+    ret = nan_register_handler(wlan0Handle, handlers);
     printMsg("%s: ret = %d\n", __FUNCTION__, ret);
     return ret;
 }
@@ -6023,7 +6708,7 @@
     int sid_flag = 0xff, sid_count = 0xff;
     int sub_sid_flag = 0xff, sub_sid_count = 0xff;
     u8 val;
-    u16 clust_range;
+    u16 clust_range = 0;
 
     /* Set Default enable params */
     memset(&msg, 0, sizeof(msg));
@@ -6040,6 +6725,8 @@
     msg.cluster_low = 0;
     msg.cluster_high = NAN_MAX_CLUST_VALUE_RANGE;
 
+    enab_for_chre = 0;
+
     /* Parse args for nan params */
     /* skip utility */
     argv++;
@@ -6128,7 +6815,8 @@
         } else if (strcmp(param, "-sub_sid_count") == 0) {
             sub_sid_count = atoi(val_p);
             if (sub_sid_count < 0 || sub_sid_count > NAN_MAX_SIDS_IN_BEACONS) {
-                printMsg("%s:Invalid Subscribe Service ID Count Limit. Setting to Default\n", __FUNCTION__);
+                printMsg("%s:Invalid Subscribe Service ID Count Limit. Setting to Default\n",
+                    __FUNCTION__);
                 sub_sid_count = 0;
             } else  {
                 msg.subscribe_sid_beacon_val = ((sub_sid_count << 1) | sub_sid_flag);
@@ -6388,7 +7076,6 @@
             if (msg.enable_dw_termination) {
                 msg.config_dw_early_termination = true;
             }
-#ifdef NAN_3_1_SUPPORT
         } else if (strcmp(param, "-instant_mode") == 0) {
             msg.enable_instant_mode = atoi(val_p);
             msg.config_enable_instant_mode = true;
@@ -6402,7 +7089,8 @@
                 ret = WIFI_ERROR_INVALID_ARGS;
                 goto exit;
             }
-#endif /* NAN_3_1_SUPPORT */
+        } else if (strcmp(param, "-chre") == 0) {
+            enab_for_chre = atoi(val_p);
         } else {
             printMsg("%s:Unsupported Parameter for Nan Enable\n", __FUNCTION__);
             ret = WIFI_ERROR_INVALID_ARGS;
@@ -6411,27 +7099,76 @@
     }
 
     nanCmdId = getNewCmdId();
-    ret = nan_init_handlers();
-    if (ret != WIFI_SUCCESS) {
-        printMsg("Failed to initialize handlers %d\n", ret);
-        goto exit;
+
+    if (enab_for_chre) {
+#ifdef CHRE_NAN
+        ret = nan_chre_enable_request(nanCmdId, wlan0Handle, NULL);
+        if (ret != WIFI_SUCCESS) {
+            printMsg("Failed to enable NAN for CHRE %d\n", ret);
+            goto exit;
+        }
+#endif /* CHRE_NAN */
+    } else {
+        ret = nan_init_handlers();
+        if (ret != WIFI_SUCCESS) {
+            printMsg("Failed to initialize handlers %d\n", ret);
+            goto exit;
+        }
+        ret = nan_enable_request(nanCmdId, wlan0Handle, &msg);
+        if (ret != WIFI_SUCCESS) {
+            printMsg("Failed to enable NAN %d\n", ret);
+            goto exit;
+        }
     }
-    ret = nan_enable_request(nanCmdId, wlan0Handle, &msg);
 exit:
     printMsg("%s:ret = %d\n", __FUNCTION__, ret);
     return;
 }
 
-void disableNan(void) {
+void disableNan(char *argv[]) {
     wifi_error ret = WIFI_SUCCESS;
-    nanCmdId = getNewCmdId();
-    ret = nan_init_handlers();
-    if (ret != WIFI_SUCCESS) {
-        printMsg("Failed to initialize handlers %d\n", ret);
-        return;
+    char *param, *val_p;
+
+    /* Parse args for nan params */
+    /* skip utility */
+    argv++;
+    /* skip command */
+    argv++;
+    /* skip command */
+    argv++;
+
+    disab_for_chre = 0;
+
+    while ((param = *argv++) != NULL) {
+        val_p = *argv++;
+        if (!val_p || *val_p == '-') {
+            printMsg("%s: Need value following %s\n", __FUNCTION__, param);
+            ret = WIFI_ERROR_NOT_SUPPORTED;
+            goto exit;
+        }
+        if (strcmp(param, "-chre") == 0) {
+            disab_for_chre = atoi(val_p);
+        }
     }
-    ret = nan_disable_request(nanCmdId, wlan0Handle);
+
+    nanCmdId = getNewCmdId();
+
+    if (disab_for_chre) {
+#ifdef CHRE_NAN
+        ret = nan_chre_disable_request(nanCmdId, wlan0Handle);
+#endif /* CHRE_NAN */
+    } else {
+        ret = nan_init_handlers();
+        if (ret != WIFI_SUCCESS) {
+            printMsg("Failed to initialize handlers %d\n", ret);
+            return;
+        }
+        ret = nan_disable_request(nanCmdId, wlan0Handle);
+    }
+
+exit:
     printMsg("%s:ret = %d\n", __FUNCTION__, ret);
+    return;
 }
 
 void configNan(char *argv[]) {
@@ -6485,7 +7222,8 @@
             if (sub_sid_flag) {
                 msg.config_subscribe_sid_beacon = true;
             } else {
-                printMsg("%s:Invalid Subscribe Service Id Flag. Setting to Default\n", __FUNCTION__);
+                printMsg("%s:Invalid Subscribe Service Id Flag. Setting to Default\n",
+                    __FUNCTION__);
                 msg.config_subscribe_sid_beacon = false;
                 ret = WIFI_ERROR_INVALID_ARGS;
                 goto exit;
@@ -6493,7 +7231,8 @@
         } else if (strcmp(param, "-sub_sid_count") == 0) {
             sub_sid_count = atoi(val_p);
             if (sub_sid_count < 0 || sub_sid_count > NAN_MAX_SIDS_IN_BEACONS) {
-                printMsg("%s:Invalid Subscribe Service ID Count Limit. Setting to Default\n", __FUNCTION__);
+                printMsg("%s:Invalid Subscribe Service ID Count Limit. Setting to Default\n",
+                    __FUNCTION__);
                 sub_sid_count = 0;
             } else  {
                 msg.subscribe_sid_beacon_val = ((sub_sid_count << 1) | sub_sid_flag);
@@ -6616,7 +7355,7 @@
             }
         } else if (strcmp(param, "-numchans") == 0) {
             numchans = atoi(val_p);
-            if (numchans) {
+            if (numchans && (numchans < NAN_MAX_FAM_CHANNELS)) {
                 msg.config_fam = true;
                 msg.fam_val.numchans = numchans;
             } else {
@@ -6676,7 +7415,8 @@
             }
         } else if (strcmp(param, "-avail_interval_bitmap") == 0) {
             msg.fam_val.famchan[numchans].avail_interval_bitmap = atoi(val_p);
-            printMsg("avail_interval_bitmap = %d\n", msg.fam_val.famchan[numchans].avail_interval_bitmap);
+            printMsg("avail_interval_bitmap = %d\n",
+                msg.fam_val.famchan[numchans].avail_interval_bitmap);
             if (msg.fam_val.famchan[numchans].avail_interval_bitmap) {
                 msg.config_fam = true;
             } else {
@@ -6729,7 +7469,6 @@
             if (msg.enable_dw_termination) {
                 msg.config_dw_early_termination = true;
             }
-#ifdef NAN_3_1_SUPPORT
         } else if (strcmp(param, "-instant_mode") == 0) {
             msg.enable_instant_mode = atoi(val_p);
             msg.config_enable_instant_mode = true;
@@ -6743,7 +7482,6 @@
                 ret = WIFI_ERROR_INVALID_ARGS;
                 goto exit;
             }
-#endif /* NAN_3_1_SUPPORT */
         } else {
             printMsg("%s:Unsupported Parameter for Nan Config\n", __FUNCTION__);
             ret = WIFI_ERROR_INVALID_ARGS;
@@ -6770,13 +7508,6 @@
     u32 val = 0;
     u8 *match_rxtmp = NULL, *match_txtmp = NULL;
 
-    /* skip utility */
-    argv++;
-    /* skip command */
-    argv++;
-    /* skip command */
-    argv++;
-
     memset(&msg, 0, sizeof(msg));
     msg.publish_id = 0;
     msg.publish_type = NAN_PUBLISH_TYPE_UNSOLICITED_SOLICITED;
@@ -6786,6 +7517,13 @@
     msg.service_responder_policy = NAN_SERVICE_ACCEPT_POLICY_NONE;
     msg.period = 1;
 
+    /* skip utility */
+    argv++;
+    /* skip command */
+    argv++;
+    /* skip command */
+    argv++;
+
     while ((param = *argv++) != NULL) {
         val_p = *argv++;
         if (!val_p || *val_p == '-') {
@@ -6862,16 +7600,16 @@
                     msg.tx_match_filter_len++;
                 }
             } else {
-            if (m_len < (NAN_MAX_MATCH_FILTER_LEN - msg.tx_match_filter_len)) {
-                *match_txtmp++ = strlen(val_p);
-                msg.tx_match_filter_len++;
-                strncpy((char *)match_txtmp, val_p, strlen(val_p));
-                match_txtmp += m_len;
-                msg.tx_match_filter_len += m_len;
-            } else {
-                printMsg("Invalid match filter len\n");
-                ret = WIFI_ERROR_INVALID_ARGS;
-                goto exit;
+                if (m_len < (NAN_MAX_MATCH_FILTER_LEN - msg.tx_match_filter_len)) {
+                    *match_txtmp++ = strlen(val_p);
+                    msg.tx_match_filter_len++;
+                    strncpy((char *)match_txtmp, val_p, strlen(val_p));
+                    match_txtmp += m_len;
+                    msg.tx_match_filter_len += m_len;
+                } else {
+                    printMsg("Invalid match filter len\n");
+                    ret = WIFI_ERROR_INVALID_ARGS;
+                    goto exit;
                 }
             }
         } else if (strcmp(param, "-match_rx") == 0) {
@@ -6925,14 +7663,18 @@
                 case NAN_CIPHER_SUITE_SHARED_KEY_256_MASK:
                     msg.cipher_type = NAN_CIPHER_SUITE_SHARED_KEY_256_MASK;
                     break;
-#ifdef NAN_3_1_SUPPORT
                 case NAN_CIPHER_SUITE_PUBLIC_KEY_2WDH_128_MASK:
                     msg.cipher_type = NAN_CIPHER_SUITE_PUBLIC_KEY_2WDH_128_MASK;
                     break;
                 case NAN_CIPHER_SUITE_PUBLIC_KEY_2WDH_256_MASK:
                     msg.cipher_type = NAN_CIPHER_SUITE_PUBLIC_KEY_2WDH_256_MASK;
                     break;
-#endif /* NAN_3_1_SUPPORT */
+                case NAN_CIPHER_SUITE_PUBLIC_KEY_PASN_128_MASK:
+                    msg.cipher_type = NAN_CIPHER_SUITE_PUBLIC_KEY_PASN_128_MASK;
+                    break;
+                case NAN_CIPHER_SUITE_PUBLIC_KEY_PASN_256_MASK:
+                    msg.cipher_type = NAN_CIPHER_SUITE_PUBLIC_KEY_PASN_256_MASK;
+                    break;
                 default:
                     msg.cipher_type = NAN_CIPHER_SUITE_SHARED_KEY_NONE;
                     break;
@@ -6977,7 +7719,8 @@
                 (strlen((const char*)val_p));
                 if (!set_interface_params((char*)msg.key_info.body.passphrase_info.passphrase,
                     val_p, msg.key_info.body.passphrase_info.passphrase_len)) {
-                    printMsg("Set passphrase successfull, len = %d\n", msg.key_info.body.passphrase_info.passphrase_len);
+                    printMsg("Set passphrase successfull, len = %d\n",
+                        msg.key_info.body.passphrase_info.passphrase_len);
                 } else {
                     printMsg("Invalid passphrase\n");
                     ret = WIFI_ERROR_INVALID_ARGS;
@@ -7066,9 +7809,32 @@
                 msg.service_responder_policy = NAN_SERVICE_ACCEPT_POLICY_NONE;
                 break;
             }
+        } else if (strcmp(param, "-suspendable") == 0) {
+            val = atoi(val_p);
+            if (val) {
+                msg.enable_suspendability = true;
+            }
+        } else if (strcmp(param, "-nik") == 0) {
+            int len = str2hex(val_p, (char*)msg.nan_identity_key);
+
+            if (len != NAN_IDENTITY_KEY_LEN) {
+                printMsg("Invalid local NIK info, len %d expected 16 bytes \n", len);
+                ret = WIFI_ERROR_INVALID_ARGS;
+                goto exit;
+            } else {
+                prhex_msg("NIK", msg.nan_identity_key, NAN_IDENTITY_KEY_LEN);
+            }
+        } else if (strcmp(param, "-bs_methods") == 0) {
+            msg.nan_pairing_config.supported_bootstrapping_methods = atoi(val_p);
+        } else if (strcmp(param, "-pairing_setup") == 0) {
+            msg.nan_pairing_config.enable_pairing_setup = atoi(val_p);
+        } else if (strcmp(param, "-pairing_cache") == 0) {
+            msg.nan_pairing_config.enable_pairing_cache = atoi(val_p);
+        } else if (strcmp(param, "-pairing_verification") == 0) {
+            msg.nan_pairing_config.enable_pairing_verification = atoi(val_p);
         } else {
-           printMsg("%s:Unsupported Parameter for Nan Publish\n", __FUNCTION__);
-           goto exit;
+            printMsg("%s:Unsupported Parameter for Nan Publish\n", __FUNCTION__);
+            goto exit;
         }
     }
     if (!msg.service_name_len) {
@@ -7096,13 +7862,6 @@
     u32 val = 0;
     u8 *match_rxtmp = NULL, *match_txtmp = NULL;
 
-    /* skip utility */
-    argv++;
-    /* skip command */
-    argv++;
-    /* skip command */
-    argv++;
-
     memset(&msg, 0, sizeof(msg));
 
     /* set mandatory default values */
@@ -7119,6 +7878,13 @@
     msg.tx_match_filter_len = 0;
     msg.period = 1;
 
+    /* skip utility */
+    argv++;
+    /* skip command */
+    argv++;
+    /* skip command */
+    argv++;
+
     while ((param = *argv++) != NULL) {
         val_p = *argv++;
         if (!val_p || *val_p == '-') {
@@ -7310,14 +8076,18 @@
                 case NAN_CIPHER_SUITE_SHARED_KEY_256_MASK:
                     msg.cipher_type = NAN_CIPHER_SUITE_SHARED_KEY_256_MASK;
                     break;
-#ifdef NAN_3_1_SUPPORT
                 case NAN_CIPHER_SUITE_PUBLIC_KEY_2WDH_128_MASK:
                     msg.cipher_type = NAN_CIPHER_SUITE_PUBLIC_KEY_2WDH_128_MASK;
                     break;
                 case NAN_CIPHER_SUITE_PUBLIC_KEY_2WDH_256_MASK:
                     msg.cipher_type = NAN_CIPHER_SUITE_PUBLIC_KEY_2WDH_256_MASK;
                     break;
-#endif /* NAN_3_1_SUPPORT */
+                case NAN_CIPHER_SUITE_PUBLIC_KEY_PASN_128_MASK:
+                    msg.cipher_type = NAN_CIPHER_SUITE_PUBLIC_KEY_PASN_128_MASK;
+                    break;
+                case NAN_CIPHER_SUITE_PUBLIC_KEY_PASN_256_MASK:
+                    msg.cipher_type = NAN_CIPHER_SUITE_PUBLIC_KEY_PASN_256_MASK;
+                    break;
                 default:
                     msg.cipher_type = NAN_CIPHER_SUITE_SHARED_KEY_NONE;
                     break;
@@ -7362,7 +8132,8 @@
                 (strlen((const char*)val_p));
                 if (!set_interface_params((char*)msg.key_info.body.passphrase_info.passphrase,
                     val_p, msg.key_info.body.passphrase_info.passphrase_len)) {
-                    printMsg("Set passphrase successfull, len = %d\n", msg.key_info.body.passphrase_info.passphrase_len);
+                    printMsg("Set passphrase successfull, len = %d\n",
+                        msg.key_info.body.passphrase_info.passphrase_len);
                 } else {
                     printMsg("Invalid passphrase\n");
                     ret = WIFI_ERROR_INVALID_ARGS;
@@ -7440,6 +8211,29 @@
                     printMsg("Set SDEA service specific info successfull\n");
                 }
             }
+        } else if (strcmp(param, "-suspendable") == 0) {
+            val = atoi(val_p);
+            if (val) {
+                msg.enable_suspendability = true;
+            }
+        } else if (strcmp(param, "-nik") == 0) {
+            int len = str2hex(val_p, (char*)msg.nan_identity_key);
+
+            if (len != NAN_IDENTITY_KEY_LEN) {
+                printMsg("Invalid local NIK info, len %d expected 16 bytes \n", len);
+                ret = WIFI_ERROR_INVALID_ARGS;
+                goto exit;
+            } else {
+                prhex_msg("NIK", msg.nan_identity_key, NAN_IDENTITY_KEY_LEN);
+            }
+        } else if (strcmp(param, "-bs_methods") == 0) {
+            msg.nan_pairing_config.supported_bootstrapping_methods = atoi(val_p);
+        } else if (strcmp(param, "-pairing_setup") == 0) {
+            msg.nan_pairing_config.enable_pairing_setup = atoi(val_p);
+        } else if (strcmp(param, "-pairing_cache") == 0) {
+            msg.nan_pairing_config.enable_pairing_cache = atoi(val_p);
+        } else if (strcmp(param, "-pairing_verification") == 0) {
+            msg.nan_pairing_config.enable_pairing_verification = atoi(val_p);
         } else {
             printMsg("%s:Unsupported Parameter for Nan Subscribe\n", __FUNCTION__);
             goto exit;
@@ -7516,6 +8310,94 @@
     return;
 }
 
+void nanSuspendRequest(char *argv[]) {
+    NanSuspendRequest msg;
+    wifi_error ret = WIFI_SUCCESS;
+    char *param = NULL, *val_p = NULL, *endptr = NULL;
+    u16 svc_id = 0;
+    /* skip utility */
+    argv++;
+    /* skip command */
+    argv++;
+    /* skip command */
+    argv++;
+
+    if ((param = *argv++) != NULL) {
+        val_p = *argv++;
+        if (!val_p || *val_p == '-') {
+            printMsg("%s: Need value following %s\n", __FUNCTION__, param);
+            ret = WIFI_ERROR_NOT_SUPPORTED;
+            goto exit;
+        }
+        if (strcmp(param, "-svc_id") == 0) {
+            svc_id = strtoul(val_p, &endptr, 0);
+            msg.publish_subscribe_id = svc_id;
+        } else {
+            printMsg("%s:Unsupported Parameter for Nan Suspend Request\n", __FUNCTION__);
+            goto exit;
+        }
+    } else {
+        printMsg("%s: Additional -svc_id required for Nan Suspend Request\n", __FUNCTION__);
+        goto exit;
+    }
+
+    printMsg("nan Suspend svc_id %d \n", svc_id);
+    nanCmdId = getNewCmdId();
+    ret = nan_init_handlers();
+    if (ret != WIFI_SUCCESS) {
+        printMsg("Failed to initialize handlers %d\n", ret);
+        goto exit;
+    }
+    ret = hal_fn.wifi_nan_suspend_request(nanCmdId, wlan0Handle, &msg);
+exit:
+    printMsg("%s:ret = %d\n", __FUNCTION__, ret);
+    return;
+}
+
+void nanResumeRequest(char *argv[]) {
+    NanResumeRequest msg ;
+    wifi_error ret = WIFI_SUCCESS;
+    char *param = NULL, *val_p = NULL, *endptr = NULL;
+    u16 svc_id = 0;
+    /* skip utility */
+    argv++;
+    /* skip command */
+    argv++;
+    /* skip command */
+    argv++;
+
+    if ((param = *argv++) != NULL) {
+        val_p = *argv++;
+        if (!val_p || *val_p == '-') {
+            printMsg("%s: Need value following %s\n", __FUNCTION__, param);
+            ret = WIFI_ERROR_NOT_SUPPORTED;
+            goto exit;
+        }
+        if (strcmp(param, "-svc_id") == 0) {
+            svc_id = strtoul(val_p, &endptr, 0);
+            msg.publish_subscribe_id = svc_id;
+        } else {
+            printMsg("%s:Unsupported Parameter for Nan Resume Request\n", __FUNCTION__);
+            goto exit;
+        }
+    } else {
+        printMsg("%s: Additional -svc_id required for Nan Resume Request\n", __FUNCTION__);
+        goto exit;
+    }
+
+    printMsg("nan Resume: svc_id %d \n", svc_id);
+    nanCmdId = getNewCmdId();
+    ret = nan_init_handlers();
+    if (ret != WIFI_SUCCESS) {
+        printMsg("Failed to initialize handlers %d\n", ret);
+        goto exit;
+    }
+    ret = hal_fn.wifi_nan_resume_request(nanCmdId, wlan0Handle, &msg);
+exit:
+    printMsg("%s:ret = %d\n", __FUNCTION__, ret);
+    return;
+}
+
 void transmitNan(int argc, char *argv[]) {
     NanTransmitFollowupRequest msg;
     wifi_error ret = WIFI_SUCCESS;
@@ -7524,6 +8406,8 @@
     u32 dest_id = 0;
     u8 *mac_addr = NULL;
 
+    memset(&msg, 0, sizeof(msg));
+
     /* skip utility */
     argv++;
     /* skip command */
@@ -7531,7 +8415,6 @@
     /* skip command */
     argv++;
 
-    memset(&msg, 0, sizeof(msg));
     while ((param = *argv++) != NULL) {
         val_p = *argv++;
         if (!val_p || *val_p == '-') {
@@ -7610,6 +8493,505 @@
     return;
 }
 
+void nanPairingRequest(int argc, char *argv[])
+{
+    NanPairingRequest msg;
+    wifi_error ret = WIFI_SUCCESS;
+    char *param = NULL, *val_p = NULL;
+    u32 pub_id = 0;
+    u8 *mac_addr = NULL;
+    u32 val = 0;
+    u32 len = 0;
+
+    memset(&msg, 0, sizeof(msg));
+
+    /* skip utility */
+    argv++;
+    /* skip command */
+    argv++;
+    /* skip command */
+    argv++;
+
+    msg.is_opportunistic = 1;
+    while ((param = *argv++) != NULL) {
+        val_p = *argv++;
+        if (!val_p || *val_p == '-') {
+            printMsg("%s: Need value following %s\n", __FUNCTION__, param);
+            ret = WIFI_ERROR_NOT_SUPPORTED;
+            goto exit;
+        }
+        if (strcmp(param, "-pub_id") == 0) {
+            msg.requestor_instance_id = atoi(val_p);
+            pub_id = msg.requestor_instance_id;
+        } else if (strcmp(param, "-peer_addr") == 0) {
+            if (!ether_atoe(val_p, msg.peer_disc_mac_addr)) {
+                printMsg("bad peer mac addr !!\n");
+                ret = WIFI_ERROR_INVALID_ARGS;
+                goto exit;
+            }
+            mac_addr = msg.peer_disc_mac_addr;
+        } else if (strcmp(param, "-type") == 0) {
+            msg.nan_pairing_request_type = (NanPairingRequestType)atoi(val_p);
+            if ((msg.nan_pairing_request_type < NAN_PAIRING_SETUP) ||
+                    (msg.nan_pairing_request_type > NAN_PAIRING_VERIFICATION)) {
+                printMsg("Invalid type \n");
+                ret = WIFI_ERROR_INVALID_ARGS;
+                goto exit;
+            }
+        } else if (strcmp(param, "-password") == 0) {
+            if (strlen((const char*)val_p) < NAN_SECURITY_MIN_PASSPHRASE_LEN ||
+                    strlen((const char*)val_p) > NAN_SECURITY_MAX_PASSPHRASE_LEN) {
+                printMsg("passphrase must be between %d and %d characters long\n",
+                        NAN_SECURITY_MIN_PASSPHRASE_LEN, NAN_SECURITY_MAX_PASSPHRASE_LEN);
+                ret = WIFI_ERROR_INVALID_ARGS;
+                goto exit;
+            } else {
+                msg.key_info.body.passphrase_info.passphrase_len = (strlen((const char*)val_p));
+                if (!set_interface_params((char*)msg.key_info.body.passphrase_info.passphrase,
+                        val_p, msg.key_info.body.passphrase_info.passphrase_len)) {
+                    printMsg("Set passphrase successfull, len = %d\n",
+                            msg.key_info.body.passphrase_info.passphrase_len);
+                    msg.key_info.key_type = NAN_SECURITY_KEY_INPUT_PASSPHRASE;
+                    msg.is_opportunistic = 0;
+                } else {
+                    printMsg("Invalid passphrase\n");
+                    ret = WIFI_ERROR_INVALID_ARGS;
+                    goto exit;
+                }
+            }
+        } else if (strcmp(param, "-pmk") == 0) {
+            len = str2hex(val_p, (char*)msg.key_info.body.pmk_info.pmk);
+
+            if (len != NAN_PMK_INFO_LEN) {
+                printMsg("Invalid NPK info, len %d expected 32 bytes \n", len);
+                ret = WIFI_ERROR_INVALID_ARGS;
+                goto exit;
+            } else {
+                prhex_msg("NPK successfull", msg.key_info.body.pmk_info.pmk, len);
+                msg.key_info.body.pmk_info.pmk_len = NAN_PMK_INFO_LEN;
+                msg.key_info.key_type = NAN_SECURITY_KEY_INPUT_PMK;
+                msg.is_opportunistic = 0;
+            }
+        } else if (strcmp(param, "-csid") == 0) {
+            val = atoi(val_p);
+            switch (val) {
+                case NAN_CIPHER_SUITE_PUBLIC_KEY_PASN_128_MASK:
+                    msg.cipher_type = NAN_CIPHER_SUITE_PUBLIC_KEY_PASN_128_MASK;
+                    break;
+                case NAN_CIPHER_SUITE_PUBLIC_KEY_PASN_256_MASK:
+                    msg.cipher_type = NAN_CIPHER_SUITE_PUBLIC_KEY_PASN_256_MASK;
+                    break;
+                default:
+                    printMsg("%s:Unsupported csid, only PASN csids are supported\n", __FUNCTION__);
+                    ret = WIFI_ERROR_INVALID_ARGS;
+                    goto exit;
+            }
+        } else if (strcmp(param, "-akm") == 0) {
+            msg.akm = (NanAkm)atoi(val_p);
+            if ((msg.akm < SAE) || (msg.akm > PASN)) {
+                printMsg("Invalid akm \n");
+                ret = WIFI_ERROR_INVALID_ARGS;
+                goto exit;
+            }
+        } else if (strcmp(param, "-nik") == 0) {
+            len = str2hex(val_p, (char*)msg.nan_identity_key);
+
+            if (len != NAN_IDENTITY_KEY_LEN) {
+                printMsg("Invalid local NIK info, len %d expected 16 bytes \n", len);
+                ret = WIFI_ERROR_INVALID_ARGS;
+                goto exit;
+            } else {
+                prhex_msg("NIK", msg.nan_identity_key, NAN_IDENTITY_KEY_LEN);
+            }
+        } else if (strcmp(param, "-pairing_cache") == 0) {
+            msg.enable_pairing_cache = atoi(val_p);
+        } else {
+            printMsg("%s:Unsupported Parameter for nan pairing request \n", __FUNCTION__);
+            goto exit;
+        }
+    }
+
+    if (!pub_id) {
+        printMsg("Destination Instance Id is mandatory !!\n");
+        goto exit;
+    }
+    if (!mac_addr) {
+        printMsg("Peer MAC Address is mandatory !!\n");
+        goto exit;
+    }
+    nanCmdId = getNewCmdId();
+    ret = nan_init_handlers();
+    if (ret != WIFI_SUCCESS) {
+        printMsg("Failed to initialize handlers %d\n", ret);
+        goto exit;
+    }
+    ret = nan_pairing_request(nanCmdId, wlan0Handle, &msg);
+exit:
+    printMsg("%s:ret = %d\n", __FUNCTION__, ret);
+    return;
+}
+
+void nanPairingResponse(int argc, char *argv[])
+{
+    NanPairingIndicationResponse msg;
+    wifi_error ret = WIFI_SUCCESS;
+    char *param = NULL, *val_p = NULL;
+    u32 val = 0;
+    u32 len = 0;
+
+    memset(&msg, 0, sizeof(msg));
+
+    /* skip utility */
+    argv++;
+    /* skip command */
+    argv++;
+    /* skip command */
+    argv++;
+
+    msg.is_opportunistic = 1;
+    while ((param = *argv++) != NULL) {
+        val_p = *argv++;
+        if (!val_p || *val_p == '-') {
+            printMsg("%s: Need value following %s\n", __FUNCTION__, param);
+            ret = WIFI_ERROR_NOT_SUPPORTED;
+            goto exit;
+        }
+        if (strcmp(param, "-pairing_id") == 0) {
+            msg.pairing_instance_id = atoi(val_p);
+        } else if (strcmp(param, "-rsp_code") == 0) {
+            msg.rsp_code = (NanPairingResponseCode)atoi(val_p);
+        } else if (strcmp(param, "-type") == 0) {
+            msg.nan_pairing_request_type = (NanPairingRequestType)atoi(val_p);
+            if ((msg.nan_pairing_request_type < NAN_PAIRING_SETUP) ||
+                    (msg.nan_pairing_request_type > NAN_PAIRING_VERIFICATION)) {
+                printMsg("Invalid type \n");
+                ret = WIFI_ERROR_INVALID_ARGS;
+                goto exit;
+            }
+        } else if (strcmp(param, "-password") == 0) {
+            if (strlen((const char*)val_p) < NAN_SECURITY_MIN_PASSPHRASE_LEN ||
+                    strlen((const char*)val_p) > NAN_SECURITY_MAX_PASSPHRASE_LEN) {
+                printMsg("passphrase must be between %d and %d characters long\n",
+                        NAN_SECURITY_MIN_PASSPHRASE_LEN, NAN_SECURITY_MAX_PASSPHRASE_LEN);
+                ret = WIFI_ERROR_INVALID_ARGS;
+                goto exit;
+            } else {
+                msg.key_info.body.passphrase_info.passphrase_len = (strlen((const char*)val_p));
+                if (!set_interface_params((char*)msg.key_info.body.passphrase_info.passphrase,
+                        val_p, msg.key_info.body.passphrase_info.passphrase_len)) {
+                    printMsg("Set passphrase successfull, len = %d\n",
+                            msg.key_info.body.passphrase_info.passphrase_len);
+                    msg.key_info.key_type = NAN_SECURITY_KEY_INPUT_PASSPHRASE;
+                    msg.is_opportunistic = 0;
+                } else {
+                    printMsg("Invalid passphrase\n");
+                    ret = WIFI_ERROR_INVALID_ARGS;
+                    goto exit;
+                }
+            }
+        } else if (strcmp(param, "-pmk") == 0) {
+            len = str2hex(val_p, (char*)msg.key_info.body.pmk_info.pmk);
+
+            if (len != NAN_PMK_INFO_LEN) {
+                printMsg("Invalid NPK info, len %d expected 32 bytes \n", len);
+                ret = WIFI_ERROR_INVALID_ARGS;
+                goto exit;
+            } else {
+                prhex_msg("NPK successfull", msg.key_info.body.pmk_info.pmk, len);
+                msg.key_info.body.pmk_info.pmk_len = NAN_PMK_INFO_LEN;
+                msg.key_info.key_type = NAN_SECURITY_KEY_INPUT_PMK;
+                msg.is_opportunistic = 0;
+            }
+        } else if (strcmp(param, "-csid") == 0) {
+            val = atoi(val_p);
+            switch (val) {
+                case NAN_CIPHER_SUITE_PUBLIC_KEY_PASN_128_MASK:
+                    msg.cipher_type = NAN_CIPHER_SUITE_PUBLIC_KEY_PASN_128_MASK;
+                    break;
+                case NAN_CIPHER_SUITE_PUBLIC_KEY_PASN_256_MASK:
+                    msg.cipher_type = NAN_CIPHER_SUITE_PUBLIC_KEY_PASN_256_MASK;
+                    break;
+                default:
+                    printMsg("%s:Unsupported csid, only PASN csids are supported\n", __FUNCTION__);
+                    ret = WIFI_ERROR_INVALID_ARGS;
+                    goto exit;
+            }
+        } else if (strcmp(param, "-akm") == 0) {
+            msg.akm = (NanAkm)atoi(val_p);
+            if ((msg.akm < SAE) || (msg.akm > PASN)) {
+                printMsg("Invalid akm \n");
+                ret = WIFI_ERROR_INVALID_ARGS;
+                goto exit;
+            }
+        } else if (strcmp(param, "-nik") == 0) {
+            int len = str2hex(val_p, (char*)msg.nan_identity_key);
+
+            if (len != NAN_IDENTITY_KEY_LEN) {
+                printMsg("Invalid local NIK info, len %d expected 16 bytes \n", len);
+                ret = WIFI_ERROR_INVALID_ARGS;
+                goto exit;
+            } else {
+                prhex_msg("NIK", msg.nan_identity_key, NAN_IDENTITY_KEY_LEN);
+            }
+        } else if (strcmp(param, "-pairing_cache") == 0) {
+            msg.enable_pairing_cache = atoi(val_p);
+        } else {
+            printMsg("%s:Unsupported Parameter for nan pairing response \n", __FUNCTION__);
+            goto exit;
+        }
+    }
+
+    nanCmdId = getNewCmdId();
+    ret = nan_init_handlers();
+    if (ret != WIFI_SUCCESS) {
+        printMsg("Failed to initialize handlers %d\n", ret);
+        goto exit;
+    }
+    ret = nan_pairing_indication_response(nanCmdId, wlan0Handle, &msg);
+exit:
+    printMsg("%s:ret = %d\n", __FUNCTION__, ret);
+    return;
+}
+
+void nanPairingEnd(int argc, char *argv[])
+{
+    NanPairingEndRequest msg;
+    wifi_error ret = WIFI_SUCCESS;
+    char *param = NULL, *val_p = NULL;
+
+    /* skip utility */
+    argv++;
+    /* skip command */
+    argv++;
+    /* skip command */
+    argv++;
+
+
+    while ((param = *argv++) != NULL) {
+        val_p = *argv++;
+        if (!val_p || *val_p == '-') {
+            printMsg("%s: Need value following %s\n", __FUNCTION__, param);
+            ret = WIFI_ERROR_NOT_SUPPORTED;
+            goto exit;
+        }
+        if (strcmp(param, "-pid") == 0) {
+            msg.pairing_instance_id = atoi(val_p);
+        } else {
+            printMsg("%s:Unsupported Parameter for Pairing End Request\n", __FUNCTION__);
+            goto exit;
+        }
+    }
+
+    nanCmdId = getNewCmdId();
+    ret = nan_init_handlers();
+    if (ret != WIFI_SUCCESS) {
+        printMsg("Failed to initialize handlers %d\n", ret);
+        goto exit;
+    }
+    ret = nan_pairing_end(nanCmdId, wlan0Handle, &msg);
+exit:
+    printMsg("%s:ret = %d\n", __FUNCTION__, ret);
+    return;
+}
+
+void nanBootstrappingReq(int argc, char *argv[])
+{
+    NanBootstrappingRequest msg;
+    wifi_error ret = WIFI_SUCCESS;
+    char *param = NULL, *val_p = NULL;
+    u32 dest_id = 0, lcl_id = 0;
+
+    memset(&msg, 0, sizeof(msg));
+
+    /* skip utility */
+    argv++;
+    /* skip command */
+    argv++;
+    /* skip command */
+    argv++;
+
+    while ((param = *argv++) != NULL) {
+        val_p = *argv++;
+        if (!val_p || *val_p == '-') {
+            printMsg("%s: Need value following %s\n", __FUNCTION__, param);
+            ret = WIFI_ERROR_NOT_SUPPORTED;
+            goto exit;
+        }
+        if (strcmp(param, "-dest_id") == 0) {
+            msg.requestor_instance_id = atoi(val_p);
+            dest_id = msg.requestor_instance_id;
+        } else if (strcmp(param, "-lcl_id") == 0) {
+            msg.publish_subscribe_id = atoi(val_p);
+            lcl_id = msg.publish_subscribe_id;
+        } else if (strcmp(param, "-peer_addr") == 0) {
+            if (!ether_atoe(val_p, msg.peer_disc_mac_addr)) {
+                printMsg("bad peer mac addr !!\n");
+                ret = WIFI_ERROR_INVALID_ARGS;
+                goto exit;
+            }
+        } else if (strcmp(param, "-bs_methods") == 0) {
+            msg.request_bootstrapping_method = atoi(val_p);
+        } else if (strcmp(param, "-sdea_info") == 0) {
+            if (strlen((const char*)val_p) > NAN_MAX_SDEA_SERVICE_SPECIFIC_INFO_LEN) {
+                printMsg("Invalid SDEA service specific info\n");
+                ret = WIFI_ERROR_INVALID_ARGS;
+                goto exit;
+            } else {
+                msg.sdea_service_specific_info_len = strlen((const char*)val_p);
+                if (!set_interface_params((char*)msg.sdea_service_specific_info,
+                    val_p, msg.sdea_service_specific_info_len)) {
+                        printMsg("Set SDEA service specific info successfull\n");
+                }
+            }
+        } else if (strcmp(param, "-info") == 0) {
+            if (strlen((const char*)val_p) > NAN_MAX_SERVICE_SPECIFIC_INFO_LEN) {
+                printMsg("Invalid  service specific info\n");
+                ret = WIFI_ERROR_INVALID_ARGS;
+                goto exit;
+            } else {
+                msg.service_specific_info_len = strlen((const char*)val_p);
+                if (!set_interface_params((char*)msg.service_specific_info,
+                    val_p, msg.service_specific_info_len)) {
+                    printMsg("Set service specific info successfull\n");
+                }
+            }
+        } else if (strcmp(param, "-cookie") == 0) {
+            if (strlen((const char*)val_p) > NAN_MAX_COOKIE_LEN) {
+                printMsg("Invalid cookie info\n");
+                ret = WIFI_ERROR_INVALID_ARGS;
+                goto exit;
+            } else {
+                msg.cookie_length = strlen((const char*)val_p);
+                if (!set_interface_params((char*)msg.cookie, val_p, msg.cookie_length)) {
+                    printMsg("Set cookie info successfull\n");
+                }
+            }
+        } else {
+            printMsg("%s:Unsupported Parameter for nan bootstrapping request \n", __FUNCTION__);
+            goto exit;
+        }
+    }
+
+    if (!dest_id) {
+        printMsg("Destination Instance Id is mandatory !!\n");
+        goto exit;
+    }
+    if (!lcl_id) {
+        printMsg("Local Instance Id is mandatory !!\n");
+        goto exit;
+    }
+    nanCmdId = getNewCmdId();
+    ret = nan_init_handlers();
+    if (ret != WIFI_SUCCESS) {
+        printMsg("Failed to initialize handlers %d\n", ret);
+        goto exit;
+    }
+    ret = nan_bootstrapping_request(nanCmdId, wlan0Handle, &msg);
+exit:
+    printMsg("%s:ret = %d\n", __FUNCTION__, ret);
+    return;
+}
+
+void nanBootstrappingResp(int argc, char *argv[])
+{
+    NanBootstrappingIndicationResponse msg;
+    wifi_error ret = WIFI_SUCCESS;
+    char *param = NULL, *val_p = NULL;
+    u32 dest_id = 0, lcl_id = 0;
+
+    memset(&msg, 0, sizeof(msg));
+
+    /* skip utility */
+    argv++;
+    /* skip command */
+    argv++;
+    /* skip command */
+    argv++;
+
+    while ((param = *argv++) != NULL) {
+        val_p = *argv++;
+        if (!val_p || *val_p == '-') {
+            printMsg("%s: Need value following %s\n", __FUNCTION__, param);
+            ret = WIFI_ERROR_NOT_SUPPORTED;
+            goto exit;
+        }
+        if (strcmp(param, "-dest_id") == 0) {
+            msg.service_instance_id = atoi(val_p);
+            dest_id = msg.service_instance_id;
+        } else if (strcmp(param, "-lcl_id") == 0) {
+            msg.publish_subscribe_id = atoi(val_p);
+            lcl_id = msg.publish_subscribe_id;
+        } else if (strcmp(param, "-peer_addr") == 0) {
+            if (!ether_atoe(val_p, msg.peer_disc_mac_addr)) {
+                printMsg("bad peer mac addr !!\n");
+                ret = WIFI_ERROR_INVALID_ARGS;
+                goto exit;
+            }
+        } else if (strcmp(param, "-rsp_code") == 0) {
+            msg.rsp_code = (NanBootstrappingResponseCode)atoi(val_p);
+        } else if (strcmp(param, "-comeback_delay") == 0) {
+            msg.come_back_delay = atoi(val_p);
+        } else if (strcmp(param, "-sdea_info") == 0) {
+            if (strlen((const char*)val_p) > NAN_MAX_SDEA_SERVICE_SPECIFIC_INFO_LEN) {
+                printMsg("Invalid SDEA service specific info\n");
+                ret = WIFI_ERROR_INVALID_ARGS;
+                goto exit;
+            } else {
+                msg.sdea_service_specific_info_len = strlen((const char*)val_p);
+                if (!set_interface_params((char*)msg.sdea_service_specific_info,
+                    val_p, msg.sdea_service_specific_info_len)) {
+                        printMsg("Set SDEA service specific info successfull\n");
+                }
+            }
+        } else if (strcmp(param, "-info") == 0) {
+            if (strlen((const char*)val_p) > NAN_MAX_SERVICE_SPECIFIC_INFO_LEN) {
+                printMsg("Invalid  service specific info\n");
+                ret = WIFI_ERROR_INVALID_ARGS;
+                goto exit;
+            } else {
+                msg.service_specific_info_len = strlen((const char*)val_p);
+                if (!set_interface_params((char*)msg.service_specific_info,
+                    val_p, msg.service_specific_info_len)) {
+                    printMsg("Set service specific info successfull\n");
+                }
+            }
+        } else if (strcmp(param, "-cookie") == 0) {
+            if (strlen((const char*)val_p) > NAN_MAX_COOKIE_LEN) {
+                printMsg("Invalid cookie info\n");
+                ret = WIFI_ERROR_INVALID_ARGS;
+                goto exit;
+            } else {
+                msg.cookie_length = strlen((const char*)val_p);
+                if (!set_interface_params((char*)msg.cookie, val_p, msg.cookie_length)) {
+                    printMsg("Set cookie info successfull\n");
+                }
+            }
+        } else {
+            printMsg("%s:Unsupported Parameter for nan bootstrapping response  %s \n", __FUNCTION__, param);
+            goto exit;
+        }
+    }
+
+    if (!dest_id) {
+        printMsg("Destination Instance Id is mandatory !!\n");
+        goto exit;
+    }
+    if (!lcl_id) {
+        printMsg("Local Instance Id is mandatory !!\n");
+        goto exit;
+    }
+    nanCmdId = getNewCmdId();
+    ret = nan_init_handlers();
+    if (ret != WIFI_SUCCESS) {
+        printMsg("Failed to initialize handlers %d\n", ret);
+        goto exit;
+    }
+    ret = nan_bootstrapping_indication_response(nanCmdId, wlan0Handle, &msg);
+exit:
+    printMsg("%s:ret = %d\n", __FUNCTION__, ret);
+    return;
+}
+
 void getNanCapabilities(void) {
     nanCmdId = getNewCmdId();
     wifi_error ret = nan_init_handlers();
@@ -7623,14 +9005,17 @@
 void nanDataPathIfaceCreate(char *argv[]) {
     wifi_error ret = WIFI_SUCCESS;
     char *param = NULL, *val_p = NULL;
+    /* Interface name */
+    char ndp_iface[IFNAMSIZ+1];
+
+    memset(ndp_iface, 0, sizeof(ndp_iface));
+
     /* skip utility */
     argv++;
     /* skip command */
     argv++;
     /* skip command */
     argv++;
-    /* Interface name */
-    char ndp_iface[IFNAMSIZ+1];
 
     while ((param = *argv++) != NULL) {
         val_p = *argv++;
@@ -7668,14 +9053,17 @@
 void nanDataPathIfaceDelete(char *argv[]) {
     wifi_error ret = WIFI_SUCCESS;
     char *param = NULL, *val_p = NULL;
+    /* Interface name */
+    char ndp_iface[IFNAMSIZ+1];
+
+    memset(ndp_iface, 0, sizeof(ndp_iface));
+
     /* skip utility */
     argv++;
     /* skip command */
     argv++;
     /* skip command */
     argv++;
-    /* Interface name */
-    char ndp_iface[IFNAMSIZ+1];
 
     while ((param = *argv++) != NULL) {
         val_p = *argv++;
@@ -7710,12 +9098,16 @@
     return;
 }
 
-
 void nanDataInitRequest(int argc, char *argv[]) {
     NanDataPathInitiatorRequest msg;
     wifi_error ret = WIFI_SUCCESS;
     char *param = NULL, *val_p = NULL;
     u32 val = 0;
+
+    memset(&msg, 0, sizeof(msg));
+    msg.ndp_cfg.security_cfg = NAN_DP_CONFIG_NO_SECURITY;
+    msg.ndp_cfg.qos_cfg = NAN_DP_CONFIG_NO_QOS;
+
     /* skip utility */
     argv++;
     /* skip command */
@@ -7723,10 +9115,6 @@
     /* skip command */
     argv++;
 
-    memset(&msg, 0, sizeof(msg));
-    msg.ndp_cfg.security_cfg = NAN_DP_CONFIG_NO_SECURITY;
-    msg.ndp_cfg.qos_cfg = NAN_DP_CONFIG_NO_QOS;
-
     while ((param = *argv++) != NULL) {
         val_p = *argv++;
         if (!val_p || *val_p == '-') {
@@ -7813,14 +9201,18 @@
                 case NAN_CIPHER_SUITE_SHARED_KEY_256_MASK:
                     msg.cipher_type = NAN_CIPHER_SUITE_SHARED_KEY_256_MASK;
                     break;
-#ifdef NAN_3_1_SUPPORT
                 case NAN_CIPHER_SUITE_PUBLIC_KEY_2WDH_128_MASK:
                     msg.cipher_type = NAN_CIPHER_SUITE_PUBLIC_KEY_2WDH_128_MASK;
                     break;
                 case NAN_CIPHER_SUITE_PUBLIC_KEY_2WDH_256_MASK:
                     msg.cipher_type = NAN_CIPHER_SUITE_PUBLIC_KEY_2WDH_256_MASK;
                     break;
-#endif /* NAN_3_1_SUPPORT */
+                case NAN_CIPHER_SUITE_PUBLIC_KEY_PASN_128_MASK:
+                    msg.cipher_type = NAN_CIPHER_SUITE_PUBLIC_KEY_PASN_128_MASK;
+                    break;
+                case NAN_CIPHER_SUITE_PUBLIC_KEY_PASN_256_MASK:
+                    msg.cipher_type = NAN_CIPHER_SUITE_PUBLIC_KEY_PASN_256_MASK;
+                    break;
                 default:
                     msg.cipher_type = NAN_CIPHER_SUITE_SHARED_KEY_NONE;
                     break;
@@ -7865,14 +9257,14 @@
                 (strlen((const char*)val_p));
                 if (!set_interface_params((char*)msg.key_info.body.passphrase_info.passphrase,
                     val_p, msg.key_info.body.passphrase_info.passphrase_len)) {
-                    printMsg("Set passphrase successfull, len = %d\n", msg.key_info.body.passphrase_info.passphrase_len);
+                    printMsg("Set passphrase successfull, len = %d\n",
+                        msg.key_info.body.passphrase_info.passphrase_len);
                 } else {
                     printMsg("Invalid passphrase\n");
                     ret = WIFI_ERROR_INVALID_ARGS;
                     goto exit;
                 }
             }
-#ifdef NAN_3_1_SUPPORT
         } else if (strcmp(param, "-scid") == 0) {
             if (strlen((const char*)val_p) > NAN_MAX_SCID_BUF_LEN) {
                 printMsg("Invalid SCID\n");
@@ -7886,7 +9278,6 @@
                     printMsg("Set SCID successfull\n");
                 }
             }
-#endif /* NAN_3_1_SUPPORT */
         } else if (strcmp(param, "-svc") == 0) {
             if (strlen((const char *)val_p) > NAN_MAX_SERVICE_NAME_LEN) {
                 printMsg("Invalid service name\n");
@@ -7900,6 +9291,8 @@
                     printMsg("Set service name successfull\n");
                 }
             }
+        } else if (strcmp(param, "-lcl_svc_id") == 0) {
+            msg.publish_subscribe_id = atoi(val_p);
         } else {
             printMsg("%s:Unsupported Parameter for Nan Data Path Request\n", __FUNCTION__);
             goto exit;
@@ -7923,6 +9316,11 @@
     wifi_error ret = WIFI_SUCCESS;
     char *param = NULL, *val_p = NULL;
     u32 val = 0;
+
+    memset(&msg, 0, sizeof(msg));
+    msg.ndp_cfg.security_cfg = NAN_DP_CONFIG_NO_SECURITY;
+    msg.ndp_cfg.qos_cfg = NAN_DP_CONFIG_NO_QOS;
+
     /* skip utility */
     argv++;
     /* skip command */
@@ -7930,9 +9328,6 @@
     /* skip command */
     argv++;
 
-    memset(&msg, 0, sizeof(msg));
-    msg.ndp_cfg.security_cfg = NAN_DP_CONFIG_NO_SECURITY;
-    msg.ndp_cfg.qos_cfg = NAN_DP_CONFIG_NO_QOS;
     while ((param = *argv++) != NULL) {
         val_p = *argv++;
         if (!val_p || *val_p == '-') {
@@ -8009,14 +9404,18 @@
                 case NAN_CIPHER_SUITE_SHARED_KEY_256_MASK:
                     msg.cipher_type = NAN_CIPHER_SUITE_SHARED_KEY_256_MASK;
                     break;
-#ifdef NAN_3_1_SUPPORT
                 case NAN_CIPHER_SUITE_PUBLIC_KEY_2WDH_128_MASK:
                     msg.cipher_type = NAN_CIPHER_SUITE_PUBLIC_KEY_2WDH_128_MASK;
                     break;
                 case NAN_CIPHER_SUITE_PUBLIC_KEY_2WDH_256_MASK:
                     msg.cipher_type = NAN_CIPHER_SUITE_PUBLIC_KEY_2WDH_256_MASK;
                     break;
-#endif /* NAN_3_1_SUPPORT */
+                case NAN_CIPHER_SUITE_PUBLIC_KEY_PASN_128_MASK:
+                    msg.cipher_type = NAN_CIPHER_SUITE_PUBLIC_KEY_PASN_128_MASK;
+                    break;
+                case NAN_CIPHER_SUITE_PUBLIC_KEY_PASN_256_MASK:
+                    msg.cipher_type = NAN_CIPHER_SUITE_PUBLIC_KEY_PASN_256_MASK;
+                    break;
                 default:
                     msg.cipher_type = NAN_CIPHER_SUITE_SHARED_KEY_NONE;
                     break;
@@ -8061,14 +9460,14 @@
                     (strlen((const char*)val_p));
                 if (!set_interface_params((char*)msg.key_info.body.passphrase_info.passphrase,
                     val_p, msg.key_info.body.passphrase_info.passphrase_len)) {
-                    printMsg("Set passphrase successfull, len = %d\n", msg.key_info.body.passphrase_info.passphrase_len);
+                    printMsg("Set passphrase successfull, len = %d\n",
+                        msg.key_info.body.passphrase_info.passphrase_len);
                 } else {
                     printMsg("Invalid passphrase\n");
                     ret = WIFI_ERROR_INVALID_ARGS;
                     goto exit;
                 }
             }
-#ifdef NAN_3_1_SUPPORT
         } else if (strcmp(param, "-scid") == 0) {
             if (strlen((const char*)val_p) > NAN_MAX_SCID_BUF_LEN) {
                 printMsg("Invalid SCID\n");
@@ -8080,7 +9479,6 @@
                     printMsg("Set SCID successfull\n");
                 }
             }
-#endif /* NAN_3_1_SUPPORT */
         } else if (strcmp(param, "-svc") == 0) {
             if (strlen((const char *)val_p) > NAN_MAX_SERVICE_NAME_LEN) {
                 printMsg("Invalid service name\n");
@@ -8094,6 +9492,8 @@
                     printMsg("Set service name successfull\n");
                 }
             }
+        } else if (strcmp(param, "-lcl_svc_id") == 0) {
+            msg.publish_subscribe_id = atoi(val_p);
         } else {
             printMsg("%s:Unsupported Parameter for Nan Data Path Request\n", __FUNCTION__);
             goto exit;
@@ -8117,6 +9517,7 @@
     char *param = NULL, *val_p = NULL, *endptr = NULL;
     u8 count = 0, i = 0;
     NanDataPathId ndp_id = 0;
+
     /* skip utility */
     argv++;
     /* skip command */
@@ -8178,23 +9579,27 @@
 void VirtualIfaceAdd(char *argv[]) {
     wifi_error ret = WIFI_SUCCESS;
     char *param = NULL, *val_p = NULL;
+    /* Interface name */
+    char iface_name[IFNAMSIZ+1];
+    wifi_interface_type iface_type = WIFI_INTERFACE_TYPE_STA;
+    bool set_iface = false;
+
+    memset(iface_name, 0, sizeof(iface_name));
+
     /* skip utility */
     argv++;
     /* skip command */
     argv++;
-    /* Interface name */
-    char iface_name[IFNAMSIZ+1];
-    wifi_interface_type iface_type;
 
     while ((param = *argv++) != NULL) {
-    val_p = *argv++;
-    if (!val_p || *val_p == '-') {
-        printMsg("%s: Need value following %s\n", __FUNCTION__, param);
-        ret = WIFI_ERROR_NOT_SUPPORTED;
-        goto exit;
-    }
-    if (strcmp(param, "-name") == 0) {
-        if (!set_interface_params(iface_name, val_p, (IFNAMSIZ - 1))) {
+        val_p = *argv++;
+        if (!val_p || *val_p == '-') {
+            printMsg("%s: Need value following %s\n", __FUNCTION__, param);
+            ret = WIFI_ERROR_NOT_SUPPORTED;
+            goto exit;
+        }
+        if (strcmp(param, "-name") == 0) {
+            if (!set_interface_params(iface_name, val_p, (IFNAMSIZ - 1))) {
                 printMsg("set interface name successfull\n");
             } else {
                 printMsg("Invalid Iface name\n");
@@ -8203,12 +9608,18 @@
             }
         } else if (strcmp(param, "-type") == 0) {
             iface_type = (wifi_interface_type)atoi(val_p);
+            set_iface = true;
         } else {
             printMsg("Unsupported Parameter for virtual iface delete\n");
             goto exit;
         }
     }
 
+    if (!set_iface) {
+        printMsg("Error, Mandatory iface type is not set\n");
+        goto exit;
+    }
+
     ret = hal_fn.wifi_virtual_interface_create(halHandle, iface_name, iface_type);
     if (ret == WIFI_ERROR_NONE) {
         printMsg("Successful to add virtual iface\n");
@@ -8224,12 +9635,14 @@
 void VirtualIfaceDelete(char *argv[]) {
     wifi_error ret = WIFI_SUCCESS;
     char *param = NULL, *val_p = NULL;
+    /* Interface name */
+    char iface_name[IFNAMSIZ+1];
+    memset(iface_name, 0, sizeof(iface_name));
+
     /* skip utility */
     argv++;
     /* skip command */
     argv++;
-    /* Interface name */
-    char iface_name[IFNAMSIZ+1];
 
     while ((param = *argv++) != NULL) {
         val_p = *argv++;
@@ -8267,13 +9680,16 @@
 MultiStaSetPrimaryConnection(char *argv[]) {
     wifi_error ret = WIFI_SUCCESS;
     char *param = NULL;
+    /* Interface name */
+    char iface_name[IFNAMSIZ+1];
+    wifi_interface_handle ifHandle = NULL;
+
+    memset(iface_name, 0, sizeof(iface_name));
+
     /* skip utility */
     argv++;
     /* skip command */
     argv++;
-    /* Interface name */
-    char iface_name[IFNAMSIZ+1];
-    wifi_interface_handle ifHandle = NULL;
 
     while ((param = *argv++) != NULL) {
         if (!set_interface_params(iface_name, param, (IFNAMSIZ - 1))) {
@@ -8304,7 +9720,7 @@
 static void
 MultiStaSetUsecase(char *argv[]) {
     wifi_error ret = WIFI_SUCCESS;
-    uint use_case;
+    uint use_case = 0;
     wifi_multi_sta_use_case mMultiStaUsecase;
 
     /* skip utility */
@@ -8313,8 +9729,8 @@
     argv++;
 
     use_case = (uint)atoi(*argv);
-    if (use_case >= WIFI_DUAL_STA_TRANSIENT_PREFER_PRIMARY &&
-        use_case <= WIFI_DUAL_STA_NON_TRANSIENT_UNBIASED) {
+    if ((use_case == WIFI_DUAL_STA_TRANSIENT_PREFER_PRIMARY) ||
+        (use_case == WIFI_DUAL_STA_NON_TRANSIENT_UNBIASED)) {
         mMultiStaUsecase = (wifi_multi_sta_use_case)use_case;
     } else {
         printMsg("Invalid  multi_sta usecase\n");
@@ -8337,13 +9753,16 @@
 SetLatencyMode(char *argv[]) {
     wifi_error ret = WIFI_SUCCESS;
     char *param = NULL;
+    /* Interface name */
+    char iface_name[IFNAMSIZ+1];
+    wifi_interface_handle ifHandle = NULL;
+
+    memset(iface_name, 0, sizeof(iface_name));
+
     /* skip utility */
     argv++;
     /* skip command */
     argv++;
-    /* Interface name */
-    char iface_name[IFNAMSIZ+1];
-    wifi_interface_handle ifHandle = NULL;
 
     param = *argv++;
     if (param != NULL) {
@@ -8354,6 +9773,10 @@
             ret = WIFI_ERROR_INVALID_ARGS;
             goto exit;
         }
+    } else {
+        printMsg("argv is null\n");
+        ret = WIFI_ERROR_INVALID_ARGS;
+        goto exit;
     }
 
     ifHandle = wifi_get_iface_handle(halHandle, iface_name);
@@ -8379,13 +9802,16 @@
 SetVoipMode(char *argv[]) {
     wifi_error ret = WIFI_SUCCESS;
     char *param = NULL;
+    /* Interface name */
+    char iface_name[IFNAMSIZ+1];
+    wifi_interface_handle ifHandle = NULL;
+
+    memset(iface_name, 0, sizeof(iface_name));
+
     /* skip utility */
     argv++;
     /* skip command */
     argv++;
-    /* Interface name */
-    char iface_name[IFNAMSIZ+1];
-    wifi_interface_handle ifHandle = NULL;
 
     param = *argv++;
     if (param != NULL) {
@@ -8396,6 +9822,10 @@
             ret = WIFI_ERROR_INVALID_ARGS;
             goto exit;
         }
+    } else {
+        printMsg("argv is null\n");
+        ret = WIFI_ERROR_INVALID_ARGS;
+        goto exit;
     }
 
     ifHandle = wifi_get_iface_handle(halHandle, iface_name);
@@ -8451,7 +9881,7 @@
         if ((strcmp(argv[2], "-enable") == 0)) {
             enableNan(argv);
         } else if ((strcmp(argv[2], "-disable") == 0)) {
-            disableNan();
+            disableNan(argv);
         } else if ((strcmp(argv[2], "-config") == 0)) {
             configNan(argv);
         } else if ((strcmp(argv[2], "-publish") == 0)) {
@@ -8460,17 +9890,26 @@
                     "    [-pub_type <0/1/2>] [-pub_count <val>] [-rssi_thresh_flag <0/1>]\n"
                     "    [-tx_type <0/1>] [-ttl <val>] [-svc_awake_dw <val>]\n"
                     "    [-match_rx <0/ascii str>] [-match_tx <0/ascii str>]] [-match_ind <1/2>]\n"
-                    "    [-csid <cipher suite type 0/1/2/4/8>] [-key_type <1 or 2>] [-pmk <PMK value>]\n"
-                    "    [-passphrase <Passphrase value, len must not be less than 8 or greater than 63>]\n"
-                    "    [-scid <scid value>] [-dp_type <0-Unicast, 1-multicast>]\n"
-                    "    [-secure_dp <0-No security, 1-Security>] -ranging <0-disable, 1-enable>)\n"
-                    "    [-ranging_intvl [intrvl in ms betw two ranging measurements] -ranging_ind \n"
-                    "    [ BIT0 - Continuous Ranging event notification, BIT1 - Ingress distance is <=, BIT2 - Egress distance is >=.]\n"
+                    "    [-csid <cipher suite type 0/1/2/4/8>] [-key_type <1 or 2>]"
+                    "    [-pmk <PMK value>] [-passphrase <Passphrase value, len must "
+                    "    not be less than 8 or greater than 63>] [-scid <scid value>]"
+                    "    [-dp_type <0-Unicast, 1-multicast>]\n"
+                    "    [-secure_dp <0-No security, 1-Security>]"
+                    "    -ranging <0-disable, 1-enable>)\n"
+                    "    [-ranging_intvl [intrvl in ms betw"
+                    "    two ranging measurements] -ranging_ind [ BIT0 -"
+                    "    Continuous Ranging event notification,"
+                    "    BIT1 - Ingress distance is <=, BIT2 - Egress distance is >=.]\n"
                     "    [-ingress [Ingress distance in centimeters] \n"
                     "    [ -egress [Egress distance in centimeters] \n"
-                    "    [-auto_dp_accept [0 - User response required to accept dp, 1 - User response not required to accept dp] \n"
-                    "    [-recv_flag <0 to 15>]");
-                printMsg("\n *Set/Enable corresponding bits to disable any indications that follow a publish"
+                    "    [-auto_dp_accept [0 - User response required to accept dp,"
+                    "    1 - User response not required to accept dp] \n"
+                    "    [-recv_flag <0 to 15>] [-suspendable <0/1>] \n"
+                    "    [-bs_methods <supported bootstrapping methods]>\n"
+                    "    [-pairing_setup <supported 0/1>] [-pairing_cache <supported 0/1]"
+                    "    [-pairing_verification <supported 0/1>] [-nik <local nik of 16 char>]\n");
+                printMsg("\n *Set/Enable corresponding bits to disable any"
+                    "    indications that follow a publish"
                     "\n *BIT0 - Disable publish termination indication."
                     "\n *BIT1 - Disable match expired indication."
                     "\n *BIT2 - Disable followUp indication received (OTA)");
@@ -8484,16 +9923,22 @@
                     "    [-ttl <val>] [-svc_awake_dw <val>] [-match_ind <1/2>]\n"
                     "    [-match_rx <0/ascii str>] [-match_tx <0/ascii str>]\n"
                     "    [-mac_list <addr>] [-srf_include <0/1>] [-rssi_thresh_flag <0/1>]]\n"
-                    "    [-csid <cipher suite type 0/1/2/4/8>] [-key_type <1 or 2>]  [-pmk <PMK value>]\n"
-                    "    [-passphrase <Passphrase value, len must not be less than 8 or greater than 63>]\n"
+                    "    [-csid <cipher suite type 0/1/2/4/8>] [-key_type <1 or 2>]"
+                    "    [-pmk <PMK value>] [-passphrase <Passphrase value,"
+                    "    len must not be less than 8 or greater than 63>]\n"
                     "    [-scid <scid value>] [-dp_type <0-Unicast, 1-multicast>]\n"
                     "    [-secure_dp <0-No security, 1-Security>] -ranging <0-disable, 1-enable>)\n"
                     "    [-ranging_intvl [intrvl in ms betw two ranging measurements] -ranging_ind \n"
-                    "    [BIT0 - Continuous Ranging event notification, BIT1 - Ingress distance is <=, BIT2 - Egress distance is >=.]\n"
+                    "    [BIT0 - Continuous Ranging event notification,"
+                    "    BIT1 - Ingress distance is <=, BIT2 - Egress distance is >=.]\n"
                     "    [-ingress [Ingress distance in centimeters] \n"
                     "    [ -egress [Egress distance in centimeters] \n"
-                    "    [-recv_flag <0 to 7>]");
-                printMsg("\n *Set/Enable corresponding bits to disable any indications that follow a publish"
+                    "    [-recv_flag <0 to 7>] [-suspendable <0/1>] \n"
+                    "    [-bs_methods <supported bootstrapping methods]>\n"
+                    "    [-pairing_setup <supported 0/1>] [-pairing_cache <supported 0/1]"
+                    "    [-pairing_verification <supported 0/1>]  [-nik <local nik of 16 char>]\n");
+                printMsg("\n *Set/Enable corresponding bits to disable any indications that"
+                    "    follow a publish"
                     "\n *BIT0 - Disable publish termination indication."
                     "\n *BIT1 - Disable match expired indication."
                     "\n *BIT2 - Disable followUp indication received (OTA)");
@@ -8543,7 +9988,7 @@
                     "    [-chan <channel in mhz>] [-iface <iface>] [-sec <security>]\n"
                     "    [-qos <qos>] [-info <seq of values in the frame body>]\n"
                     "    [-csid <cipher suite type 0/1/2/4/8>]\n"
-                    "    [-scid <scid value>] [-svc <svc_name>]\n");
+                    "    [-scid <scid value>] [-svc <svc_name>] [-lcl_svc_id <service id>] \n");
                 goto cleanup;
             }
             nanDataInitRequest(argc, argv);
@@ -8554,10 +9999,22 @@
                     "    [-resp_code <accept = 0, accept = 1>] [-qos <qos>]\n"
                     "    [-info <seq of values in the frame body>]\n"
                     "    [-csid <cipher suite type 0/1/2/4/8>]\n"
-                    "    [-scid <scid value>] [-svc <svc_name>] \n");
+                    "    [-scid <scid value>] [-svc <svc_name>] [-lcl_svc_id <service id>] \n");
                 goto cleanup;
             }
             nanDataIndResponse(argc, argv);
+        } else if ((strcmp(argv[2], "-suspend") == 0)) {
+            if(argc < 3) {
+                printMsg(" -nan [-suspend] -svc_id [service_id]\n");
+                goto cleanup;
+            }
+            nanSuspendRequest(argv);
+        } else if ((strcmp(argv[2], "-resume") == 0)) {
+            if(argc < 3) {
+                printMsg(" -nan [-resume] -svc_id [service_id]\n");
+                goto cleanup;
+            }
+            nanResumeRequest(argv);
         } else if ((strcmp(argv[2], "-end") == 0)) {
             if(argc < 3) {
                 printMsg("\n Mandatory fields are not present\n");
@@ -8565,6 +10022,55 @@
                 goto cleanup;
             }
             nanDataPathEnd(argc, argv);
+        } else if ((strcmp(argv[2], "-pairing_req") == 0)) {
+            if (argc < 5) {
+                printf(" -nan [-pairing_req] -pub_id <instance id>\n"
+                    "  -type <0-setup, 1-verification> -peer_addr <mac addr>\n"
+                    "  -password <password> -csid <cipher suite> [-akm <0-SAE, 1-PASN] \n"
+                    "  [-nik <local nik>] [-pairing_cache <1-Enable , 0-Disable pairing cache>]\n"
+                    "  [-pmk <32 byte PMK value>]\n");
+                printMsg("\n Mandatory fields are not present\n");
+                goto cleanup;
+            }
+            nanPairingRequest(argc, argv);
+        } else if ((strcmp(argv[2], "-pairing_resp") == 0)) {
+            if (argc < 5) {
+                printf(" -nan [-pairing_resp] [-pairing_id <pairing instance id>]\n"
+                    "     [-rsp_code <0-ACCEPT,1-REJECT>] [-type <0-setup, 1-verification>]\n"
+                    "     [-password <password>] [-csid <cipher suite>] [-akm <0-SAE, 1-PASN] \n"
+                    "     [-nik <local nik>] [-pairing_cache <1-Enable, 0-Disable pairing cache>]\n"
+                    "     [-pmk <32 byte PMK value>]\n");
+                printMsg("\n Mandatory fields are not present\n");
+                goto cleanup;
+            }
+            nanPairingResponse(argc, argv);
+        } else if ((strcmp(argv[2], "-pairing_end") == 0)) {
+            if (argc < 3) {
+                printMsg("\n Mandatory fields are not present\n");
+                printf(" -nan [-pairing_end] -pairing_id <pairing_instance_id>\n");
+                goto cleanup;
+            }
+            nanPairingEnd(argc, argv);
+        } else if ((strcmp(argv[2], "-bs_req") == 0)) {
+            if (argc < 5) {
+                printf(" -nan [-bs_req] -dest_id <peer inst id> -lcl_id <local inst id>\n"
+                   "     -peer_addr <mac addr> -bs_methods <supported bootstrapping methiods>\n"
+                   "     [-comeback <is it comeback BS req>] [-sdea_info <sdea svc info>]\n"
+                   "     [-cookie <cookie info>] [-info <svc info>]\n");
+                printMsg("\n Mandatory fields are not present\n");
+                goto cleanup;
+            }
+            nanBootstrappingReq(argc, argv);
+        } else if ((strcmp(argv[2], "-bs_resp") == 0)) {
+            if (argc < 5) {
+                printf(" -nan [-bs_resp] dest_id <peer inst id> -lcl_id <local inst id> \n"
+                   "     -peer_addr <mac addr> -rsp_code <0-ACCEPT, 1-REJECT, 2- COMEBACK>\n"
+                   "     [-comeback_delay] [-cookie <cookie info>] [-info <svc info>] \n"
+                   "     [-sdea_info <sdea svcinfo>]\n");
+                printMsg("\n Mandatory fields are not present\n");
+                goto cleanup;
+            }
+            nanBootstrappingResp(argc, argv);
         } else if ((strcmp(argv[2], "-event_chk") == 0)) {
             nanEventCheck();
         } else if ((strcmp(argv[2], "-ver") == 0)) {
@@ -8667,7 +10173,7 @@
             setBlacklist(((num_blacklist_bssids == -1) ? true: false));
         }
     } else if ((strcmp(argv[1], "-get_roaming_capabilities") == 0)) {
-        getRoamingCapabilities();
+        getRoamingCapabilities(argv);
     } else if ((strcmp(argv[1], "-set_fw_roaming_state") == 0)) {
         fw_roaming_state_t roamState = (fw_roaming_state_t)(atoi)(argv[2]);
         setFWRoamingState(roamState);
@@ -8746,7 +10252,7 @@
             return WIFI_SUCCESS;
         }
     } else if (strcmp(argv[1], "-get_capa_twt") == 0) {
-        getTWTCapability();
+        getTWTCapability(argv);
     } else if ((strcmp(argv[1], "-dtim_multiplier") == 0) && (argc > 2)) {
         int dtim_multiplier = (atoi)(argv[2]);
         hal_fn.wifi_set_dtim_config(wlan0Handle, dtim_multiplier);
diff --git a/bcmdhd/wifi_hal/common.cpp b/bcmdhd/wifi_hal/common.cpp
index 7f164ab..ea28e11 100755
--- a/bcmdhd/wifi_hal/common.cpp
+++ b/bcmdhd/wifi_hal/common.cpp
@@ -307,3 +307,42 @@
 {
     return halutil_mode;
 }
+/* pretty hex print a contiguous buffer */
+void prhex(const char *msg, u8 *buf, u32 nbytes)
+{
+    char line[128];
+    char *p;
+    int len = sizeof(line);
+    int nchar;
+    u32 i;
+
+    if (msg && (msg[0] != '\0')) {
+        ALOGE("%s: len %d\n", msg, nbytes);
+    }
+
+    p = line;
+    for (i = 0; i < nbytes; i++) {
+        if (i % 16 == 0) {
+            nchar = snprintf(p, len, "  %04d: ", i);    /* line prefix */
+            p += nchar;
+            len -= nchar;
+        }
+
+        if (len > 0) {
+            nchar = snprintf(p, len, "%02x ", buf[i]);
+            p += nchar;
+            len -= nchar;
+        }
+
+        if (i % 16 == 15) {
+            ALOGE("%s\n", line);       /* flush line */
+            p = line;
+            len = sizeof(line);
+        }
+    }
+
+    /* flush last partial line */
+    if (p != line) {
+        ALOGE("%s\n", line);
+    }
+}
diff --git a/bcmdhd/wifi_hal/common.h b/bcmdhd/wifi_hal/common.h
index acb649f..21bdafd 100644
--- a/bcmdhd/wifi_hal/common.h
+++ b/bcmdhd/wifi_hal/common.h
@@ -26,6 +26,7 @@
 #include <log/log.h>
 #include "nl80211_copy.h"
 #include "sync.h"
+#include <unistd.h>
 
 #define SOCKET_BUFFER_SIZE      (32768U)
 #define RECV_BUF_SIZE           (4096)
@@ -48,21 +49,44 @@
 const uint32_t BRCM_OUI =  0x001018;
 /* TODO: define vendor OUI here */
 
-
 #define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
 #define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x"
 
 #define NMR2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5], (a)[6], (a)[7]
 #define NMRSTR "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x"
-#define NAN_MASTER_RANK_LEN 8
-#define NAN_SCID_INFO_LEN   16
-#define NAN_MAX_NDP_PEER 8u
-#define NAN_MAX_NDP_COUNT_SIZE NAN_MAX_NDP_PEER * sizeof(NanDataPathId)
+#define NAN_MAX_SVC_INFO_LEN            255u
+#define NAN_MASTER_RANK_LEN             8u
+#define NAN_SCID_INFO_LEN               16u
 
-#define SAR_CONFIG_SCENARIO_COUNT      100
-#define MAX_NUM_RADIOS 3
-#define MAX_CMD_RESP_BUF_LEN 8192
-#define MAX_MLO_LINK 3
+#define NAN_MAX_NDP_PEER                8u
+#define NAN_MAX_NDP_COUNT_SIZE          NAN_MAX_NDP_PEER * sizeof(NanDataPathId)
+#define SAR_CONFIG_SCENARIO_COUNT       100
+#define MAX_NUM_RADIOS                  3u
+#define MAX_CMD_RESP_BUF_LEN            8192u
+#define MAX_MLO_LINK                    3u
+/* For STA, peer would be only one - AP.*/
+#define NUM_PEER_AP                     1u
+/* 11n/HT:   OFDM(12) + HT(16) rates = 28 (MCS0 ~ MCS15)
+ * 11ac/VHT: OFDM(12) + VHT(12) x 2 nss = 36 (MCS0 ~ MCS11)
+ * 11ax/HE:  OFDM(12) + HE(12) x 2 nss = 36 (MCS0 ~ MCS11)
+ * 11be/EHT:  OFDM(12) + EHT(16) x 2 nss = 44 (MCS0 ~ MCS15)
+ */
+#define NUM_RATE                        44u
+#define NUM_RATE_NON_BE                 36u
+
+#define NL_MSG_MAX_LEN                  5120u
+
+/* nl_msg->nm_nlh->nlmsg_len is added by data len of the attributes
+ * NL80211_ATTR_VENDOR_ID, NL80211_ATTR_VENDOR_SUBCMD,
+ * NL80211_ATTR_IFINDEX, APF_PROGRAM_LEN by 56u
+ * To keep the additioanl room and aligned,
+ * keeping the overhead of 128u
+ */
+#define NL_MSG_HDR_OVERHEAD_LEN		128u
+#define NL_MSG_DEFAULT_LEN		(getpagesize() - NL_MSG_HDR_OVERHEAD_LEN)
+
+#define NAN_MAX_PAIRING_CNT             8u
+#define NAN_MAX_COOKIE_LEN              255u
 
 /*
  This enum defines ranges for various commands; commands themselves
@@ -146,10 +170,11 @@
     ANDROID_NL80211_SUBCMD_INIT_DEINIT_RANGE_START = 0x2160,
     ANDROID_NL80211_SUBCMD_INIT_DEINIT_RANGE_END   = 0x216F,
 
-    /* define scan related commands between 0x2170 and 0x2175 */
+   /* define scan related commands between 0x2170 and 0x2175 */
     ANDROID_NL80211_SUBCMD_SCAN_START = 0x2170,
     ANDROID_NL80211_SUBCMD_SCAN_END = 0x2175,
-    /* This is reserved for future usage */
+
+   /* This is reserved for future usage */
 
 } ANDROID_VENDOR_SUB_COMMAND;
 
@@ -194,7 +219,7 @@
     WIFI_SUBCMD_SET_MULTISTA_PRIMARY_CONNECTION,         /* 0x101c */
     WIFI_SUBCMD_SET_MULTISTA_USE_CASE,                   /* 0x101d */
     WIFI_SUBCMD_SET_DTIM_CONFIG,                         /* 0x101e */
-    WIFI_SUBCMD_CHANNEL_POLICY,                          /* 0x101f */
+    WIFI_SUBCMD_CHANNEL_POLICY,                         /* 0x101f */
 
     GSCAN_SUBCMD_MAX,
 
@@ -220,13 +245,18 @@
     NAN_SUBCMD_ENABLE_MERGE,                            /* 0x1712 */
     NAN_SUBCMD_SUSPEND,                                 /* 0x1713 */
     NAN_SUBCMD_RESUME,                                  /* 0x1714 */
+    NAN_SUBCMD_PAIRING_REQUEST,                         /* 0x1715 */
+    NAN_SUBCMD_PAIRING_RESPONSE,                        /* 0x1716 */
+    NAN_SUBCMD_PAIRING_END,                             /* 0x1717 */
+    NAN_SUBCMD_BOOTSTRAPPING_REQUEST,                   /* 0x1718 */
+    NAN_SUBCMD_BOOTSTRAPPING_RESPONSE,                  /* 0x1719 */
     APF_SUBCMD_GET_CAPABILITIES = ANDROID_NL80211_SUBCMD_PKT_FILTER_RANGE_START,
     APF_SUBCMD_SET_FILTER,
     APF_SUBCMD_READ_FILTER,
     WIFI_SUBCMD_TX_POWER_SCENARIO = ANDROID_NL80211_SUBCMD_TX_POWER_RANGE_START,
     WIFI_SUBCMD_THERMAL_MITIGATION = ANDROID_NL80211_SUBCMD_MITIGATION_RANGE_START,
     DSCP_SUBCMD_SET_TABLE = ANDROID_NL80211_SUBCMD_DSCP_RANGE_START,
-    DSCP_SUBCMD_RESET_TABLE,			    	/* 0x2001 */
+    DSCP_SUBCMD_RESET_TABLE,                            /* 0x2001 */
     CHAVOID_SUBCMD_SET_CONFIG = ANDROID_NL80211_SUBCMD_CHAVOID_RANGE_START,
 
     TWT_SUBCMD_GETCAPABILITY	= ANDROID_NL80211_SUBCMD_TWT_START,
@@ -248,51 +278,58 @@
 } WIFI_SUB_COMMAND;
 
 typedef enum {
-    BRCM_RESERVED1				= 0,
-    BRCM_RESERVED2				= 1,
+    BRCM_RESERVED1                          = 0,
+    BRCM_RESERVED2                          = 1,
     GSCAN_EVENT_SIGNIFICANT_CHANGE_RESULTS	= 2,
-    GSCAN_EVENT_HOTLIST_RESULTS_FOUND		= 3,
-    GSCAN_EVENT_SCAN_RESULTS_AVAILABLE		= 4,
-    GSCAN_EVENT_FULL_SCAN_RESULTS		= 5,
-    RTT_EVENT_COMPLETE				= 6,
-    GSCAN_EVENT_COMPLETE_SCAN			= 7,
-    GSCAN_EVENT_HOTLIST_RESULTS_LOST		= 8,
-    GSCAN_EVENT_EPNO_EVENT			= 9,
-    GOOGLE_DEBUG_RING_EVENT			= 10,
-    GOOGLE_DEBUG_MEM_DUMP_EVENT			= 11,
-    GSCAN_EVENT_ANQPO_HOTSPOT_MATCH		= 12,
-    GOOGLE_RSSI_MONITOR_EVENT			= 13,
-    GOOGLE_MKEEP_ALIVE				= 14,
+    GSCAN_EVENT_HOTLIST_RESULTS_FOUND       = 3,
+    GSCAN_EVENT_SCAN_RESULTS_AVAILABLE      = 4,
+    GSCAN_EVENT_FULL_SCAN_RESULTS           = 5,
+    RTT_EVENT_COMPLETE                      = 6,
+    GSCAN_EVENT_COMPLETE_SCAN               = 7,
+    GSCAN_EVENT_HOTLIST_RESULTS_LOST        = 8,
+    GSCAN_EVENT_EPNO_EVENT                  = 9,
+    GOOGLE_DEBUG_RING_EVENT                 = 10,
+    GOOGLE_DEBUG_MEM_DUMP_EVENT             = 11,
+    GSCAN_EVENT_ANQPO_HOTSPOT_MATCH         = 12,
+    GOOGLE_RSSI_MONITOR_EVENT               = 13,
+    GOOGLE_MKEEP_ALIVE                      = 14,
 
     /*
      * BRCM specific events should be placed after the Generic events
      * in order to match between the DHD and HAL
      */
-    NAN_EVENT_ENABLED				= 15,
-    NAN_EVENT_DISABLED				= 16,
-    NAN_EVENT_SUBSCRIBE_MATCH			= 17,
-    NAN_EVENT_PUBLISH_REPLIED_IND		= 18,
-    NAN_EVENT_PUBLISH_TERMINATED		= 19,
-    NAN_EVENT_SUBSCRIBE_TERMINATED		= 20,
-    NAN_EVENT_DE_EVENT				= 21,
-    NAN_EVENT_FOLLOWUP				= 22,
-    NAN_EVENT_TRANSMIT_FOLLOWUP_IND		= 23,
-    NAN_EVENT_DATA_REQUEST			= 24,
-    NAN_EVENT_DATA_CONFIRMATION			= 25,
-    NAN_EVENT_DATA_END				= 26,
-    NAN_EVENT_BEACON				= 27,
-    NAN_EVENT_SDF				= 28,
-    NAN_EVENT_TCA				= 29,
-    NAN_EVENT_SUBSCRIBE_UNMATCH			= 30,
-    NAN_EVENT_UNKNOWN				= 31,
-    BRCM_VENDOR_EVENT_HANGED			= 33,
+    NAN_EVENT_ENABLED                      = 15,
+    NAN_EVENT_DISABLED                     = 16,
+    NAN_EVENT_SUBSCRIBE_MATCH              = 17,
+    NAN_EVENT_PUBLISH_REPLIED_IND          = 18,
+    NAN_EVENT_PUBLISH_TERMINATED           = 19,
+    NAN_EVENT_SUBSCRIBE_TERMINATED         = 20,
+    NAN_EVENT_DE_EVENT                     = 21,
+    NAN_EVENT_FOLLOWUP                     = 22,
+    NAN_EVENT_TRANSMIT_FOLLOWUP_IND        = 23,
+    NAN_EVENT_DATA_REQUEST                 = 24,
+    NAN_EVENT_DATA_CONFIRMATION            = 25,
+    NAN_EVENT_DATA_END                     = 26,
+    NAN_EVENT_BEACON                       = 27,
+    NAN_EVENT_SDF                          = 28,
+    NAN_EVENT_TCA                          = 29,
+    NAN_EVENT_SUBSCRIBE_UNMATCH            = 30,
+    NAN_EVENT_UNKNOWN                      = 31,
+    BRCM_VENDOR_EVENT_HANGED               = 33,
+ 
     ROAM_EVENT_START,
-    GOOGLE_FILE_DUMP_EVENT			= 37,
-    NAN_ASYNC_RESPONSE_DISABLED			= 40,
-    BRCM_VENDOR_EVENT_TWT			= 43,
-    BRCM_TPUT_DUMP_EVENT			= 44,
-    NAN_EVENT_MATCH_EXPIRY			= 45,
-    NAN_EVENT_SUSPENSION_STATUS                 = 49
+    GOOGLE_FILE_DUMP_EVENT                 = 37,
+    NAN_ASYNC_RESPONSE_DISABLED            = 40,
+    BRCM_VENDOR_EVENT_TWT                  = 43,
+    BRCM_TPUT_DUMP_EVENT                   = 44,
+    NAN_EVENT_MATCH_EXPIRY                 = 45,
+    NAN_EVENT_SUSPENSION_STATUS            = 49,
+    NAN_EVENT_PAIRING_REQUEST              = 50,
+    NAN_EVENT_PAIRING_CONFIRMATION         = 51,
+    NAN_EVENT_PAIRING_END                  = 52,
+    NAN_EVENT_BOOTSTRAPPING_REQUEST        = 53,
+    NAN_EVENT_BOOTSTRAPPING_CONFIRMATION   = 54
+    /* Add more events from here */
 } WIFI_EVENT;
 
 typedef void (*wifi_internal_event_handler) (wifi_handle handle, int events);
@@ -320,9 +357,9 @@
 } interface_info;
 
 typedef enum {
-	NAN_STATE_DISABLED = 0,
-	NAN_STATE_AP = 1,
-	NAN_STATE_CHRE = 2,
+    NAN_STATE_DISABLED = 0,
+    NAN_STATE_AP = 1,
+    NAN_STATE_CHRE = 2,
 } nan_enab_state_t;
 
 typedef struct {
@@ -354,6 +391,8 @@
 
     wifi_chre_handler chre_nan_cb;                  // chre CB for nan status
     nan_enab_state_t nan_state;                     // Nan enable state
+    bool nan_pairing_supported;                     // Nan Pairing capability
+    bool nan_suspend_supported;                     // Nan suspend/resume capability
 
     // add other details
 } hal_info;
@@ -585,6 +624,7 @@
 
 // some common macros
 
+void prhex(const char *msg, u8 *buf, u32 nbytes);
 #define min(x, y)       ((x) < (y) ? (x) : (y))
 #define max(x, y)       ((x) > (y) ? (x) : (y))
 
diff --git a/bcmdhd/wifi_hal/cpp_bindings.cpp b/bcmdhd/wifi_hal/cpp_bindings.cpp
index 8ef0ca8..da6ed0e 100755
--- a/bcmdhd/wifi_hal/cpp_bindings.cpp
+++ b/bcmdhd/wifi_hal/cpp_bindings.cpp
@@ -565,14 +565,23 @@
     return result;
 }
 
-int WifiRequest::create(int family, uint8_t cmd, int flags, int hdrlen) {
+int WifiRequest::create(int family, uint8_t cmd, int flags, int data_len) {
 
     destroy();
 
-    mMsg = nlmsg_alloc();
+    /* If data_len is 0, default msg size will be used
+     * (nlmsg_alloc uses PAGE_SIZE by default).
+     * data_len is requested specifically for cases where len needs
+     * to be greater than default_size.
+     */
+    if (data_len) {
+        mMsg = nlmsg_alloc_size(data_len);
+    } else {
+        mMsg = nlmsg_alloc();
+    }
     if (mMsg != NULL) {
         genlmsg_put(mMsg, /* pid = */ 0, /* seq = */ 0, family,
-                hdrlen, flags, cmd, /* version = */ 0);
+                0, flags, cmd, /* version = */ 0);
         return WIFI_SUCCESS;
     } else {
         return WIFI_ERROR_OUT_OF_MEMORY;
@@ -611,6 +620,29 @@
     return ret;
 }
 
+int WifiRequest::create_custom_len(uint32_t id, int subcmd, int data_len) {
+    int res = create_custom_len(NL80211_CMD_VENDOR, data_len);
+    if (res < 0) {
+        return mapErrorCodes(res);
+    }
+
+    res = put_u32(NL80211_ATTR_VENDOR_ID, id);
+    if (res < 0) {
+        return mapErrorCodes(res);
+    }
+
+    res = put_u32(NL80211_ATTR_VENDOR_SUBCMD, subcmd);
+    if (res < 0) {
+        return mapErrorCodes(res);
+    }
+
+    if (mIface != -1) {
+        res = set_iface_id(mIface);
+    }
+
+    return mapErrorCodes(res);
+}
+
 int WifiRequest::create(uint32_t id, int subcmd) {
     int res = create(NL80211_CMD_VENDOR);
     if (res < 0) {
@@ -650,7 +682,7 @@
 }
 
 int WifiCommand::requestResponse(WifiRequest& request) {
-    int err = 0;
+    int err = 0, res = 0;
 
     struct nl_cb *cb = nl_cb_alloc(NL_CB_DEFAULT);
     if (!cb) {
@@ -676,7 +708,7 @@
     nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, response_handler, this);
 
     while (err > 0) {                   /* wait for reply */
-        int res = nl_recvmsgs(mInfo->cmd_sock, cb);
+        res = nl_recvmsgs(mInfo->cmd_sock, cb);
         if (res) {
             ALOGE("nl80211: %s->nl_recvmsgs failed: %d", __func__, res);
         }
diff --git a/bcmdhd/wifi_hal/cpp_bindings.h b/bcmdhd/wifi_hal/cpp_bindings.h
index 69b699c..e006775 100755
--- a/bcmdhd/wifi_hal/cpp_bindings.h
+++ b/bcmdhd/wifi_hal/cpp_bindings.h
@@ -189,12 +189,17 @@
     }
 
     /* Command assembly helpers */
-    int create(int family, uint8_t cmd, int flags, int hdrlen);
+    int create(int family, uint8_t cmd, int flags, int data_len);
     int create(uint8_t cmd) {
         return create(mFamily, cmd, 0, 0);
     }
 
+    int create_custom_len(uint8_t cmd, int data_len) {
+        return create(mFamily, cmd, 0, data_len);
+    }
+
     int create(uint32_t id, int subcmd);
+    int create_custom_len(uint32_t id, int subcmd, int data_len);
 
     int put(int attribute, void *ptr, unsigned len) {
         return nla_put(mMsg, attribute, len, ptr);
diff --git a/bcmdhd/wifi_hal/gscan.cpp b/bcmdhd/wifi_hal/gscan.cpp
index eaddc53..4b7fb15 100755
--- a/bcmdhd/wifi_hal/gscan.cpp
+++ b/bcmdhd/wifi_hal/gscan.cpp
@@ -321,11 +321,15 @@
             if (it.get_type() == GSCAN_ATTRIBUTE_NUM_CHANNELS) {
                 num_channels_to_copy = it.get_u32();
                 ALOGI("Got channel list with %d channels", num_channels_to_copy);
-                if(num_channels_to_copy > max_channels)
+                if(num_channels_to_copy > max_channels) {
                     num_channels_to_copy = max_channels;
+                }
                 *num_channels = num_channels_to_copy;
             } else if (it.get_type() == GSCAN_ATTRIBUTE_CHANNEL_LIST && num_channels_to_copy) {
-                memcpy(channels, it.get_data(), sizeof(int) * num_channels_to_copy);
+                memcpy(channels, it.get_data(), sizeof(wifi_channel) * num_channels_to_copy);
+                for (int i = 0; i < num_channels_to_copy; i++) {
+                        ALOGD("count %d: channel %d MHz\n", i, channels[i]);
+                }
             } else {
                 ALOGW("Ignoring invalid attribute type = %d, size = %d",
                         it.get_type(), it.get_len());
@@ -455,6 +459,7 @@
     { }
 
     int createSetupRequest(WifiRequest& request) {
+        int i;
         int result = request.create(GOOGLE_OUI, GSCAN_SUBCMD_SET_CONFIG);
         if (result < 0) {
             return result;
@@ -471,7 +476,7 @@
             return result;
         }
 
-        for (int i = 0; i < mParams->num_buckets; i++) {
+        for (i = 0; i < (int)mParams->num_buckets; i++) {
             nlattr * bucket = request.attr_start(i);    // next bucket
             result = request.put_u32(GSCAN_ATTRIBUTE_BUCKET_ID, mParams->buckets[i].bucket);
             if (result < 0) {
@@ -1956,7 +1961,16 @@
         if (!mResult) {
             return NL_SKIP;
         }
+
         wifi_gscan_full_result_t *drv_res = (wifi_gscan_full_result_t *)event.get_vendor_data();
+        /* To protect against corrupted data, put a ceiling */
+        int ie_len = min(MAX_PROBE_RESP_IE_LEN, drv_res->ie_length);
+        if ((ie_len + offsetof(wifi_gscan_full_result_t, ie_data)) > len) {
+            ALOGE("BAD event data, len %d ie_len %d fixed length %lu!\n", len,
+                ie_len, offsetof(wifi_gscan_full_result_t, ie_data));
+            return NL_SKIP;
+        }
+
         wifi_gscan_result_t *fixed = &drv_res->fixed;
         convert_to_hal_result(mResult, fixed);
 
diff --git a/bcmdhd/wifi_hal/link_layer_stats.cpp b/bcmdhd/wifi_hal/link_layer_stats.cpp
index c17b3b8..580fc9c 100644
--- a/bcmdhd/wifi_hal/link_layer_stats.cpp
+++ b/bcmdhd/wifi_hal/link_layer_stats.cpp
@@ -94,16 +94,16 @@
 protected:
     virtual int handleResponse(WifiEvent& reply) {
         bool ml_data = false;
-        wifi_radio_stat *radio_stat_ptr = NULL;
         wifi_iface_ml_stat *iface_ml_stat_ptr = NULL;
         u8 *radioStatsBuf = NULL, *ifaceMlStatsBuf = NULL, *outbuf = NULL, *data_ptr = NULL;
         u8 *data = NULL, *iface_stat = NULL;
-        uint32_t offset = 0, per_radio_size = 0, data_len = 0, outbuf_rem_len = 0, data_rem_len = 0;
-        int ret = 0, num_radios = 0, id = 0, subcmd = 0, len = 0;
+        uint32_t offset = 0, num_radios = 0, per_radio_size = 0, data_len = 0;
+        uint32_t outbuf_rem_len = 0, data_rem_len = 0;
+        int ret = 0, id = 0, subcmd = 0, len = 0;
         u32 fixed_iface_ml_stat_size = 0, all_links_stat_size = 0;
         u8 num_links = 0;
 
-        ALOGI("In GetLinkStatsCommand::handleResponse");
+        // ALOGI("In GetLinkStatsCommand::handleResponse");
 
         if (reply.get_cmd() != NL80211_CMD_VENDOR) {
             ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());
@@ -134,134 +134,157 @@
             } else {
                 ALOGW("Ignoring invalid attribute type = %d, size = %d",
                 it.get_type(), it.get_len());
-            }
-        }
-
-        if (num_radios) {
-            outbuf_rem_len = MAX_CMD_RESP_BUF_LEN;
-            radioStatsBuf = (u8 *)malloc(MAX_CMD_RESP_BUF_LEN);
-            if (!radioStatsBuf) {
-                ALOGE("No memory\n");
                 return NL_SKIP;
             }
-            memset(radioStatsBuf, 0, MAX_CMD_RESP_BUF_LEN);
-            outbuf = radioStatsBuf;
+        }
 
-            if (!data || !data_len) {
-                ALOGE("%s: null data\n", __func__);
+        if (num_radios > MAX_NUM_RADIOS) {
+            ALOGE("Invalid num radios :%d\n", num_radios);
+            ret = WIFI_ERROR_INVALID_ARGS;
+            goto exit;
+        }
+
+        outbuf_rem_len = MAX_CMD_RESP_BUF_LEN;
+        radioStatsBuf = (u8 *)malloc(MAX_CMD_RESP_BUF_LEN);
+        if (!radioStatsBuf) {
+            ALOGE("No memory\n");
+            return NL_SKIP;
+        }
+        memset(radioStatsBuf, 0, MAX_CMD_RESP_BUF_LEN);
+        outbuf = radioStatsBuf;
+
+        if (!data || !data_len) {
+            ALOGE("%s: null data\n", __func__);
+            ret = WIFI_ERROR_INVALID_ARGS;
+            goto exit;
+        }
+
+        data_ptr = data;
+        for (int i = 0; i < num_radios; i++) {
+            outbuf_rem_len -= per_radio_size;
+            if (outbuf_rem_len < per_radio_size) {
+                ALOGE("No data left for radio %d\n", i);
+                ret = WIFI_ERROR_INVALID_ARGS;
                 goto exit;
             }
-            data_ptr = data;
-            for (int i = 0; i < num_radios; i++) {
-                outbuf_rem_len -= per_radio_size;
-                if (outbuf_rem_len < per_radio_size) {
-                    ALOGE("No data left for radio %d\n", i);
-                    goto exit;
-                }
 
-                data_ptr = data + offset;
+            data_ptr = data + offset;
+            if (!data_ptr) {
+                ALOGE("Invalid data for radio index = %d\n", i);
+                ret = WIFI_ERROR_INVALID_ARGS;
+                goto exit;
+            }
+            ret = convertToExternalRadioStatStructure((wifi_radio_stat*)data_ptr,
+                &per_radio_size, &outbuf, &outbuf_rem_len);
+            if (ret < 0) {
+                ALOGE(("Failed to map data radioStat struct\n"));
+                goto exit;
+            }
+            if (!per_radio_size) {
+                ALOGE("No data for radio %d\n", i);
+                continue;
+            }
+            outbuf += per_radio_size;
+            /* Accounted size of all the radio data len */
+            offset += per_radio_size;
+        }
+
+        if (ml_data) {
+            outbuf = NULL;
+            data_rem_len = data_len - offset;
+            fixed_iface_ml_stat_size = offsetof(wifi_iface_ml_stat, links);
+
+            /* Allocate vendor hal buffer, instead of using the nlmsg allocated buffer */
+            ifaceMlStatsBuf = (u8 *)malloc(MAX_CMD_RESP_BUF_LEN);
+            if (!ifaceMlStatsBuf) {
+                ALOGE("No memory\n");
+                ret = WIFI_ERROR_OUT_OF_MEMORY;
+                goto exit;
+            }
+            outbuf_rem_len = MAX_CMD_RESP_BUF_LEN;
+            memset(ifaceMlStatsBuf, 0, MAX_CMD_RESP_BUF_LEN);
+            outbuf = ifaceMlStatsBuf;
+
+            if (data_rem_len >= fixed_iface_ml_stat_size) {
+                data_ptr = (data + offset);
                 if (!data_ptr) {
-                    ALOGE("Invalid data for radio index = %d\n", i);
-                    goto exit;
-                }
-                radio_stat_ptr =
-                    convertToExternalRadioStatStructure((wifi_radio_stat*)data_ptr,
-                        &per_radio_size);
-                if (!radio_stat_ptr || !per_radio_size) {
-                    ALOGE("No data for radio %d\n", i);
-                    continue;
-                }
-                memcpy(outbuf, radio_stat_ptr, per_radio_size);
-                outbuf += per_radio_size;
-                /* Accounted size of all the radio data len */
-                offset += per_radio_size;
-            }
-
-            if (ml_data) {
-                outbuf = NULL;
-                data_rem_len = data_len - offset;
-                fixed_iface_ml_stat_size = offsetof(wifi_iface_ml_stat, links);
-
-                /* Allocate vendor hal buffer, instead of using the nlmsg allocated buffer */
-                ifaceMlStatsBuf = (u8 *)malloc(MAX_CMD_RESP_BUF_LEN);
-                if (!ifaceMlStatsBuf) {
-                    ALOGE("No memory\n");
-                    goto exit;
-                }
-                outbuf_rem_len = MAX_CMD_RESP_BUF_LEN;
-                memset(ifaceMlStatsBuf, 0, MAX_CMD_RESP_BUF_LEN);
-                outbuf = ifaceMlStatsBuf;
-
-                if (data_rem_len >= fixed_iface_ml_stat_size) {
-                    data_ptr = (data + offset);
-                    if (!data_ptr) {
-                        ALOGE("No iface ml stats fixed data!!, data_len = %d, offset = %d\n",
-                            data_len, offset);
-                        ret = WIFI_ERROR_INVALID_ARGS;
-                        goto exit;
-                    }
-
-                    if (outbuf_rem_len < fixed_iface_ml_stat_size) {
-                        ALOGE("No space to copy fixed iface ml stats!, rem_len %d, req_len %d\n",
-                            outbuf_rem_len, fixed_iface_ml_stat_size);
-                        ret = WIFI_ERROR_OUT_OF_MEMORY;
-                        goto exit;
-                    }
-
-                    memcpy(outbuf, data_ptr, fixed_iface_ml_stat_size);
-                    data_rem_len -= fixed_iface_ml_stat_size;
-                    outbuf_rem_len -= fixed_iface_ml_stat_size;
-                    outbuf += fixed_iface_ml_stat_size;
-                    offset += fixed_iface_ml_stat_size;
-
-                    iface_ml_stat_ptr = (wifi_iface_ml_stat *)ifaceMlStatsBuf;
-                    if (!iface_ml_stat_ptr) {
-                        ALOGE("No iface ml stats data!!");
-                        goto exit;
-                    }
-
-                    num_links = iface_ml_stat_ptr->num_links;
-                    all_links_stat_size = (num_links * offsetof(wifi_link_stat, peer_info));
-
-                    if (num_links >= MAX_MLO_LINK) {
-                        ALOGE("Invalid num links :%d\n", num_links);
-                        goto exit;
-                    }
-                    if (num_links && (data_rem_len >= all_links_stat_size)) {
-                        ret = convertToExternalIfaceMlstatStructure(&data, &offset, &outbuf,
-                            &data_rem_len, num_links, &outbuf_rem_len);
-                        if (ret < 0) {
-                            ALOGE(("Failed to map data to iface ml struct\n"));
-                            goto exit;
-                        }
-                    } else {
-                        ALOGE("num_links %d, Required data not found: expected len %d,"
-                            " data_rem_len %d\n", num_links, all_links_stat_size, data_rem_len);
-                    }
-                    (*mHandler.on_multi_link_stats_results)(id,
-                        (wifi_iface_ml_stat *)ifaceMlStatsBuf, num_radios,
-                        (wifi_radio_stat *)radioStatsBuf);
-                }
-            } else if ((data_len >= (offset + sizeof(wifi_iface_stat)))) {
-                iface_stat = (data + offset);
-                if (!iface_stat) {
-                    ALOGE("No data for legacy iface stats!!, data_len = %d, offset = %d\n",
+                    ALOGE("No iface ml stats fixed data!!, data_len = %d, offset = %d\n",
                         data_len, offset);
+                    ret = WIFI_ERROR_INVALID_ARGS;
                     goto exit;
                 }
-                (*mHandler.on_link_stats_results)(id, (wifi_iface_stat *)iface_stat,
-                    num_radios, (wifi_radio_stat *)radioStatsBuf);
-            } else {
-                ALOGE("No data for iface stats!!, data_len = %d, offset = %d\n",
-                    data_len, offset);
+
+                if (outbuf_rem_len < fixed_iface_ml_stat_size) {
+                    ALOGE("No space to copy fixed iface ml stats!, rem_len %d, req_len %d\n",
+                        outbuf_rem_len, fixed_iface_ml_stat_size);
+                    ret = WIFI_ERROR_OUT_OF_MEMORY;
+                    goto exit;
+                }
+
+                memcpy(outbuf, data_ptr, fixed_iface_ml_stat_size);
+                data_rem_len -= fixed_iface_ml_stat_size;
+                outbuf_rem_len -= fixed_iface_ml_stat_size;
+                outbuf += fixed_iface_ml_stat_size;
+                offset += fixed_iface_ml_stat_size;
+
+                iface_ml_stat_ptr = (wifi_iface_ml_stat *)ifaceMlStatsBuf;
+                if (!iface_ml_stat_ptr) {
+                    ALOGE("No iface ml stats data!!");
+                    ret = WIFI_ERROR_INVALID_ARGS;
+                    goto exit;
+                }
+
+                num_links = iface_ml_stat_ptr->num_links;
+                all_links_stat_size = (num_links * offsetof(wifi_link_stat, peer_info));
+                if (num_links > MAX_MLO_LINK) {
+                    ALOGE("Invalid num links :%d\n", num_links);
+                    ret = WIFI_ERROR_INVALID_ARGS;
+                    goto exit;
+                }
+
+                if (num_links && (data_rem_len >= all_links_stat_size)) {
+                    ret = convertToExternalIfaceMlstatStructure(&data, &offset, &outbuf,
+                            &data_rem_len, num_links, &outbuf_rem_len);
+                    if (ret < 0) {
+                        ALOGE(("Failed to map data to iface ml struct\n"));
+                        goto exit;
+                    }
+                } else {
+                    ALOGE("num_links %d, Required data not found: expected len %d,"
+                            " data_rem_len %d\n", num_links, all_links_stat_size, data_rem_len);
+                    ret = WIFI_ERROR_INVALID_ARGS;
+                    goto exit;
+                }
+                (*mHandler.on_multi_link_stats_results)(id,
+                    (wifi_iface_ml_stat *)ifaceMlStatsBuf, num_radios,
+                    (wifi_radio_stat *)radioStatsBuf);
+            }
+        } else if ((data_len >= (offset + sizeof(wifi_iface_stat)))) {
+            iface_stat = (data + offset);
+            if (!iface_stat) {
+                ALOGE("No data for legacy iface stats!!, data_len = %d, offset = %d\n",
+                        data_len, offset);
+                ret = WIFI_ERROR_INVALID_ARGS;
                 goto exit;
             }
+            (*mHandler.on_link_stats_results)(id, (wifi_iface_stat *)iface_stat,
+                num_radios, (wifi_radio_stat *)radioStatsBuf);
+        } else {
+            ALOGE("No data for iface stats!!, data_len = %d, offset = %d\n",
+                    data_len, offset);
+            ret = WIFI_ERROR_INVALID_ARGS;
+            goto exit;
         }
+
 exit:
-        if (radio_stat_ptr) {
-            free(radio_stat_ptr);
-            radio_stat_ptr = NULL;
+        /* report valid radiostat eventhough there is no linkstat info
+         * (non assoc/error case)
+         */
+        if ((ret != WIFI_SUCCESS) && num_radios && per_radio_size) {
+            (*mHandler.on_link_stats_results)(id, NULL,
+                    num_radios, (wifi_radio_stat *)radioStatsBuf);
         }
+
         if (radioStatsBuf) {
             free(radioStatsBuf);
             radioStatsBuf = NULL;
@@ -274,37 +297,25 @@
     }
 
 private:
-    wifi_radio_stat *convertToExternalRadioStatStructure(wifi_radio_stat *internal_stat_ptr,
-        uint32_t *per_radio_size)
+    int convertToExternalRadioStatStructure(wifi_radio_stat *internal_stat_ptr,
+        uint32_t *per_radio_size, u8 **outbuf, uint32_t *outbuf_rem_len)
     {
-        wifi_radio_stat *external_stat_ptr = NULL;
+        int ret = 0;
         if (!internal_stat_ptr) {
             ALOGE("Incoming data is null\n");
+            ret = WIFI_ERROR_INVALID_ARGS;
         } else {
             uint32_t channel_size = internal_stat_ptr->num_channels * sizeof(wifi_channel_stat);
             *per_radio_size = offsetof(wifi_radio_stat, channels) + channel_size;
-            external_stat_ptr = (wifi_radio_stat *)malloc(*per_radio_size);
-            if (external_stat_ptr) {
-                external_stat_ptr->radio = internal_stat_ptr->radio;
-                external_stat_ptr->on_time = internal_stat_ptr->on_time;
-                external_stat_ptr->tx_time = internal_stat_ptr->tx_time;
-                external_stat_ptr->num_tx_levels = internal_stat_ptr->num_tx_levels;
-                external_stat_ptr->tx_time_per_levels = NULL;
-                external_stat_ptr->rx_time = internal_stat_ptr->rx_time;
-                external_stat_ptr->on_time_scan = internal_stat_ptr->on_time_scan;
-                external_stat_ptr->on_time_nbd = internal_stat_ptr->on_time_nbd;
-                external_stat_ptr->on_time_gscan = internal_stat_ptr->on_time_gscan;
-                external_stat_ptr->on_time_roam_scan = internal_stat_ptr->on_time_roam_scan;
-                external_stat_ptr->on_time_pno_scan = internal_stat_ptr->on_time_pno_scan;
-                external_stat_ptr->on_time_hs20 = internal_stat_ptr->on_time_hs20;
-                external_stat_ptr->num_channels = internal_stat_ptr->num_channels;
-                if (internal_stat_ptr->num_channels) {
-                    memcpy(&(external_stat_ptr->channels), &(internal_stat_ptr->channels),
-                        channel_size);
-                }
+            if (*outbuf_rem_len >= *per_radio_size) {
+                memcpy(*outbuf, internal_stat_ptr, *per_radio_size);
+            } else {
+                ALOGE("Insufficient buf size to copy. rem len %d, req size %d\n",
+                    *outbuf_rem_len, *per_radio_size);
+                ret = WIFI_ERROR_OUT_OF_MEMORY;
             }
         }
-        return external_stat_ptr;
+        return ret;
     }
 
     int convertToExternalRatestatsStructure(u8 **data, u32 *offset, u8 **outbuf,
@@ -403,19 +414,27 @@
             }
 
             num_rate = peer_info_ptr->num_rate;
-            all_rate_stats_per_peer_per_link_size = num_rate*sizeof(wifi_rate_stat);
-            if (num_rate && (*data_rem_len >= all_rate_stats_per_peer_per_link_size)) {
-                ret = convertToExternalRatestatsStructure(data, offset, outbuf, data_rem_len,
-                    peer_info_ptr, num_rate, outbuf_rem_len);
-                if (ret != WIFI_SUCCESS) {
-                    ALOGE(("Failed to convert it to rate stats\n"));
-                    goto exit;
+            if ((num_rate == NUM_RATE) || (num_rate == NUM_RATE_NON_BE)) {
+                all_rate_stats_per_peer_per_link_size = num_rate * sizeof(wifi_rate_stat);
+                if (num_rate && (*data_rem_len >= all_rate_stats_per_peer_per_link_size)) {
+                    ret = convertToExternalRatestatsStructure(data, offset, outbuf, data_rem_len,
+                        peer_info_ptr, num_rate, outbuf_rem_len);
+                    if (ret != WIFI_SUCCESS) {
+                        ALOGE(("Failed to convert it to rate stats\n"));
+                        goto exit;
+                    }
+                } else {
+                    ALOGI("num_rate %d, Required rate_stats not found: expected len %d,"
+                        " data_rem_len %d\n", num_rate, all_rate_stats_per_peer_per_link_size,
+                        *data_rem_len);
+                    continue;
                 }
+            } else if (num_rate == 0) {
+                ALOGI("Sta is not associated, num rate :%d\n", num_rate);
             } else {
-                ALOGI("num_rate %d, Required rate_stats not found: expected len %d,"
-                    " data_rem_len %d\n", num_rate, all_rate_stats_per_peer_per_link_size,
-                    *data_rem_len);
-                continue;
+                ALOGE("Invalid num rate :%d\n", num_rate);
+                ret = WIFI_ERROR_INVALID_ARGS;
+                goto exit;
             }
         }
 
@@ -469,9 +488,21 @@
                 goto exit;
             }
 
+            if (!links_ptr->num_peers) {
+                ALOGI("no peers in unassoc case, skip processing peer stats\n");
+                ret = WIFI_SUCCESS;
+                continue;
+            }
+
+            if (links_ptr->num_peers != NUM_PEER_AP) {
+                ALOGE("Invalid num peer :%d\n", links_ptr->num_peers);
+                ret = WIFI_ERROR_INVALID_ARGS;
+                goto exit;
+            }
+
             num_peers = links_ptr->num_peers;
             all_peers_per_link_size = num_peers * offsetof(wifi_peer_info, rate_stats);
-            if (num_peers && (*data_rem_len >= all_peers_per_link_size)) {
+            if ((num_peers == NUM_PEER_AP) && (*data_rem_len >= all_peers_per_link_size)) {
                 ret = convertToExternalIfaceLinkstatStructure(data, offset, outbuf,
                     data_rem_len, num_peers, links_ptr, outbuf_rem_len);
                 if (ret != WIFI_SUCCESS) {
diff --git a/bcmdhd/wifi_hal/nan.cpp b/bcmdhd/wifi_hal/nan.cpp
index d0f7b5a..c8ce0be 100644
--- a/bcmdhd/wifi_hal/nan.cpp
+++ b/bcmdhd/wifi_hal/nan.cpp
@@ -67,6 +67,7 @@
 #define INVALID 0xFF
 #define NAN_MAX_PERIOD 16
 #define ISGREATER(i, x) (i > x) ? 1 : 0
+#define ISLESS_OR_EQUAL(i, x) (i <= x) ? 1 : 0
 #define NAN_MAX_RSSI 90
 #define NAN_SECURITY_SALT_SIZE	14
 #define NAN_MAC_INVALID_TRANSID 0xFFFF
@@ -84,6 +85,15 @@
             ((u8 *)(ea))[4] |		\
             ((u8 *)(ea))[5]) == 0)
 
+#define NIK_ISNULL(nik) ((((u8 *)(nik))[0] |		\
+            ((u8 *)(nik))[1] |		\
+            ((u8 *)(nik))[2] |		\
+            ((u8 *)(nik))[3] |		\
+            ((u8 *)(nik))[4] |		\
+            ((u8 *)(nik))[5] |		\
+            ((u8 *)(nik))[6] |		\
+            ((u8 *)(nik))[7]) == 0)
+
 /* NAN structs versioning b/w DHD and HAL
  * TODO:add versions for each struct*/
 #define NAN_HAL_VERSION_1	0x2
@@ -113,23 +123,23 @@
 {
     switch (status) {
         C2S(NAN_STATUS_SUCCESS)
-            C2S(NAN_STATUS_INTERNAL_FAILURE)
-            C2S(NAN_STATUS_PROTOCOL_FAILURE)
-            C2S(NAN_STATUS_INVALID_PUBLISH_SUBSCRIBE_ID)
-            C2S(NAN_STATUS_NO_RESOURCE_AVAILABLE)
-            C2S(NAN_STATUS_INVALID_PARAM)
-            C2S(NAN_STATUS_INVALID_REQUESTOR_INSTANCE_ID)
-            C2S(NAN_STATUS_INVALID_NDP_ID)
-            C2S(NAN_STATUS_NAN_NOT_ALLOWED)
-            C2S(NAN_STATUS_NO_OTA_ACK)
-            C2S(NAN_STATUS_ALREADY_ENABLED)
-            C2S(NAN_STATUS_FOLLOWUP_QUEUE_FULL)
-            C2S(NAN_STATUS_UNSUPPORTED_CONCURRENCY_NAN_DISABLED)
-            C2S(NAN_STATUS_INVALID_PAIRING_ID)
-            C2S(NAN_STATUS_INVALID_BOOTSTRAPPING_ID)
-            C2S(NAN_STATUS_REDUNDANT_REQUEST)
-            C2S(NAN_STATUS_NOT_SUPPORTED)
-            C2S(NAN_STATUS_NO_CONNECTION)
+        C2S(NAN_STATUS_INTERNAL_FAILURE)
+        C2S(NAN_STATUS_PROTOCOL_FAILURE)
+        C2S(NAN_STATUS_INVALID_PUBLISH_SUBSCRIBE_ID)
+        C2S(NAN_STATUS_NO_RESOURCE_AVAILABLE)
+        C2S(NAN_STATUS_INVALID_PARAM)
+        C2S(NAN_STATUS_INVALID_REQUESTOR_INSTANCE_ID)
+        C2S(NAN_STATUS_INVALID_NDP_ID)
+        C2S(NAN_STATUS_NAN_NOT_ALLOWED)
+        C2S(NAN_STATUS_NO_OTA_ACK)
+        C2S(NAN_STATUS_ALREADY_ENABLED)
+        C2S(NAN_STATUS_FOLLOWUP_QUEUE_FULL)
+        C2S(NAN_STATUS_UNSUPPORTED_CONCURRENCY_NAN_DISABLED)
+        C2S(NAN_STATUS_INVALID_PAIRING_ID)
+        C2S(NAN_STATUS_INVALID_BOOTSTRAPPING_ID)
+        C2S(NAN_STATUS_REDUNDANT_REQUEST)
+        C2S(NAN_STATUS_NOT_SUPPORTED)
+        C2S(NAN_STATUS_NO_CONNECTION)
 
         default:
             return "NAN_STATUS_INTERNAL_FAILURE";
@@ -297,7 +307,22 @@
     NAN_ATTRIBUTE_INSTANT_MODE_ENABLE               = 230,
     NAN_ATTRIBUTE_INSTANT_COMM_CHAN                 = 231,
     NAN_ATTRIBUTE_CHRE_REQUEST                      = 232,
-    NAN_ATTRIBUTE_SVC_CFG_SUPENDABLE                = 233
+    NAN_ATTRIBUTE_SVC_CFG_SUPENDABLE                = 233,
+    NAN_ATTRIBUTE_REQUEST_TYPE                      = 234,
+    NAN_ATTRIBUTE_AKM                               = 235,
+    NAN_ATTRIBUTE_PAIRING_CACHE                     = 236,
+    NAN_ATTRIBUTE_OPPURTUNISTIC                     = 237,
+    NAN_ATTRIBUTE_BS_METHODS                        = 238,
+    NAN_ATTRIBUTE_COOKIE_LEN                        = 239,
+    NAN_ATTRIBUTE_COOKIE                            = 240,
+    NAN_ATTRIBUTE_COME_BACK_DELAY                   = 241,
+    NAN_ATTRIBUTE_NIRA_NONCE                        = 242,
+    NAN_ATTRIBUTE_NIRA_TAG                          = 243,
+    NAN_ATTRIBUTE_PEER_NIK                          = 244,
+    NAN_ATTRIBUTE_LOCAL_NIK                         = 245,
+    NAN_ATTRIBUTE_ENAB_PAIRING_SETUP                = 246,
+    NAN_ATTRIBUTE_ENAB_PAIRING_VERIFICATION         = 247,
+    NAN_ATTRIBUTE_KEY_DATA_PASSPHRASE               = 248
 } NAN_ATTRIBUTE;
 
 typedef enum {
@@ -324,6 +349,11 @@
     NAN_REQUEST_ENABLE_MERGE                    = 20,
     NAN_REQUEST_SUSPEND                         = 21,
     NAN_REQUEST_RESUME                          = 22,
+    NAN_PAIRING_REQUEST                         = 23,
+    NAN_PAIRING_IND_RESPONSE                    = 24,
+    NAN_PAIRING_END_REQUEST                     = 25,
+    NAN_BOOTSTRAPPING_REQUEST                   = 26,
+    NAN_BOOTSTRAPPING_IND_RESPONSE              = 27,
     NAN_REQUEST_LAST                            = 0xFFFF
 } NanRequestType;
 
@@ -357,7 +387,7 @@
     NAN_EVENT_START       = 1,
     NAN_EVENT_JOIN        = 2,
     NAN_EVENT_ROLE_CHANGE = 3,
-    NAN_EVENT_MERGE       = 4
+    NAN_EVENT_MERGE       = 10
 };
 
 typedef struct _nan_hal_resp {
@@ -383,12 +413,14 @@
     void *nan_mac_control;
     void *nan_disc_control;
     void *nan_dp_control;
+    void *nan_pairing_control;
 } nan_hal_info_t;
 
 u8 mNmi[NAN_MAC_ADDR_LEN];
 /* Static functions */
 static int is_de_event(int cmd);
 static int is_dp_event(int cmd);
+static int is_pairing_event(int cmd);
 static int is_cmd_response(int cmd);
 
 static int get_svc_hash(unsigned char *svc_name, u16 svc_name_len,
@@ -436,6 +468,25 @@
     return is_dp_evt;
 }
 
+/* Function to separate NAN4.0 pairing specific events */
+static int is_pairing_event(int cmd) {
+    bool is_pairing_evt = false;
+
+    switch (cmd) {
+        case NAN_EVENT_PAIRING_REQUEST:
+        case NAN_EVENT_PAIRING_CONFIRMATION:
+        case NAN_EVENT_PAIRING_END:
+        case NAN_EVENT_BOOTSTRAPPING_REQUEST:
+        case NAN_EVENT_BOOTSTRAPPING_CONFIRMATION:
+            is_pairing_evt = true;
+            break;
+        default:
+            /* Not used */
+            break;
+    }
+    return is_pairing_evt;
+}
+
 static int is_cmd_response(int cmd) {
     bool is_cmd_resp = false;
 
@@ -497,7 +548,6 @@
     return hal_status;
 }
 
-static void prhex(const char *msg, u8 *buf, u32 nbytes);
 static const char *NanAttrToString(u16 cmd);
 static const char *NanCmdToString(int cmd);
 static const char *NanRspToString(int cmd);
@@ -523,7 +573,7 @@
         return WIFI_ERROR_INVALID_ARGS;
     }
     if (key_info->body.passphrase_info.passphrase_len < NAN_SECURITY_MIN_PASSPHRASE_LEN ||
-            key_info->body.passphrase_info.passphrase_len > NAN_SECURITY_MAX_PASSPHRASE_LEN) {
+                key_info->body.passphrase_info.passphrase_len > NAN_SECURITY_MAX_PASSPHRASE_LEN) {
         ALOGE("passphrase must be between %d and %d characters long\n",
                 NAN_SECURITY_MIN_PASSPHRASE_LEN,
                 NAN_SECURITY_MAX_PASSPHRASE_LEN);
@@ -531,10 +581,10 @@
     }
 
     result = PKCS5_PBKDF2_HMAC((const char *) key_info->body.passphrase_info.passphrase,
-            key_info->body.passphrase_info.passphrase_len, salt, sizeof(salt),
-            4096, ((cipher_type == NAN_CIPHER_SUITE_SHARED_KEY_128_MASK) ?
-                (const EVP_MD *)EVP_sha256():(const EVP_MD *)EVP_sha384()), NAN_PMK_INFO_LEN,  pmk_hex);
-    prhex("PMK_HEX", pmk_hex, 32);
+                key_info->body.passphrase_info.passphrase_len, salt, sizeof(salt),
+                4096, ((cipher_type == NAN_CIPHER_SUITE_SHARED_KEY_128_MASK) ?
+                (const EVP_MD *)EVP_sha256():(const EVP_MD *)EVP_sha384()),
+                        NAN_PMK_INFO_LEN,  pmk_hex);
     NAN_DBG_EXIT();
     return result;
 }
@@ -549,6 +599,10 @@
 #define NAN_HANDLE(info)                  ((info).nan_handle)
 #define GET_NAN_HANDLE(info)              ((NanHandle *)info.nan_handle)
 #define NAN_MAC_CONTROL(info)             ((info).nan_mac_control)
+#define GET_NAN_PAIRING_CAP(h_info)       (h_info && (h_info->nan_pairing_supported))
+#define GET_NAN_SUSPEND_CAP(h_info)       (h_info && (h_info->nan_suspend_supported))
+#define SET_NAN_PAIRING_CAP(h_info, val)  (h_info && (h_info->nan_pairing_supported = val))
+#define SET_NAN_SUSPEND_CAP(h_info, val)  (h_info && (h_info->nan_suspend_supported = val))
 
 ///////////////////////////////////////////////////////////////////////////////
 class NanHandle
@@ -574,8 +628,9 @@
             expired_event.publish_subscribe_id);
         } else if (attr_type == NAN_ATTRIBUTE_PUBLISH_ID) {
             expired_event.requestor_instance_id = it.get_u32();
-            ALOGI("req_inst id = %u\n", expired_event.requestor_instance_id);
-       }
+            ALOGI("req_inst id = %u\n",
+                expired_event.requestor_instance_id);
+        }
     }
 
     if (expired_event.requestor_instance_id && expired_event.publish_subscribe_id) {
@@ -586,6 +641,1016 @@
 }
 
 ///////////////////////////////////////////////////////////////////////////////
+class NanPairingPrimitive : public WifiCommand
+{
+    NanRequest mParams;
+    NanRequestType mType;
+    u16 mInstId;
+    u32 mPeerId;
+    u16 mTxId;
+
+    public:
+    NanPairingPrimitive(wifi_interface_handle iface, int id,
+            NanRequest params, NanRequestType cmdType)
+        : WifiCommand("NanCommand", iface, id), mParams(params), mType(cmdType)
+    {
+        mInstId = 0;
+        mPeerId = 0;
+        setTransactionId(id);
+    }
+
+    ~NanPairingPrimitive() {
+        ALOGE("NanPairingPrimitive destroyed\n");
+    }
+
+    void setType(NanRequestType type) {
+        mType = type;
+    }
+
+    void setTransactionId(u16 tx_id) {
+        mTxId = tx_id;
+    }
+
+    int getTransactionId() {
+        return mTxId;
+    }
+
+    int createRequest(WifiRequest& request)
+    {
+        if (mType == NAN_PAIRING_REQUEST) {
+            return createPairingRequest(request, (NanPairingRequest *)mParams);
+        } else if (mType == NAN_PAIRING_IND_RESPONSE) {
+            return createPairingIndResponse(request, (NanPairingIndicationResponse *)mParams);
+        } else if (mType == NAN_PAIRING_END_REQUEST) {
+            return createPairingEndRequest(request, (NanPairingEndRequest *)mParams);
+        } else if (mType == NAN_BOOTSTRAPPING_REQUEST) {
+            return createBootstrappingRequest(request, (NanBootstrappingRequest *)mParams);
+        } else if (mType == NAN_BOOTSTRAPPING_IND_RESPONSE) {
+            return createBootstrappingIndResponse(request,
+                    (NanBootstrappingIndicationResponse *)mParams);
+        } else {
+            ALOGE("%s Unknown Nan request in PairingPrimitive\n", __func__);
+        }
+        return WIFI_SUCCESS;
+    }
+
+    int createPairingRequest(WifiRequest& request, NanPairingRequest *mParams)
+    {
+        mTxId = getTransactionId();
+        int result = request.create(GOOGLE_OUI, NAN_SUBCMD_PAIRING_REQUEST);
+        if (result < 0) {
+            ALOGE("%s Failed to create pairing request\n", __func__);
+            return result;
+        }
+
+        NAN_DBG_ENTER();
+
+        nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
+
+        result = request.put_u32(NAN_ATTRIBUTE_PEER_ID, mParams->requestor_instance_id);
+        if (result < 0) {
+            ALOGE("%s: Failed to fill svc id, result = %d\n", __func__, result);
+            return result;
+        }
+
+        result = request.put_u16(NAN_ATTRIBUTE_TRANSAC_ID, mTxId);
+        if (result < 0) {
+            ALOGE("%s: Failed to fill NAN_ATTRIBUTE_TRANSAC_ID, result = %d\n",
+                    __func__, result);
+            return result;
+        }
+
+        result = request.put_addr(NAN_ATTRIBUTE_MAC_ADDR, mParams->peer_disc_mac_addr);
+        if (result < 0) {
+            ALOGE("%s: Failed to fill mac addr, result = %d\n", __func__, result);
+            return result;
+        }
+
+        if ((mParams->nan_pairing_request_type < NAN_PAIRING_SETUP) ||
+                (mParams->nan_pairing_request_type > NAN_PAIRING_VERIFICATION)) {
+            ALOGE("%s: Invalid pairing request type :%u\n", __func__,
+                    mParams->nan_pairing_request_type);
+            return WIFI_ERROR_INVALID_ARGS;
+        } else {
+            result = request.put_u16(NAN_ATTRIBUTE_REQUEST_TYPE, mParams->nan_pairing_request_type);
+            if (result < 0) {
+                ALOGE("%s: Failed to fill request type:%u, result = %d\n", __func__,
+                        mParams->nan_pairing_request_type, result);
+                return result;
+            }
+        }
+
+        result = request.put_u16(NAN_ATTRIBUTE_OPPURTUNISTIC, mParams->is_opportunistic);
+        if (result < 0) {
+            ALOGE("%s: Failed to fill is_opputunistic, result = %d\n", __func__, result);
+            return result;
+        }
+
+        if ((mParams->akm < SAE) || (mParams->akm > PASN)) {
+            ALOGE("%s: invalid AKM type:%u \n", __func__, mParams->akm);
+            return WIFI_ERROR_INVALID_ARGS;
+        } else {
+            result = request.put_u8(NAN_ATTRIBUTE_AKM, mParams->akm);
+            if (result < 0) {
+                ALOGE("%s: Failed to fill AKM type:%u, result = %d\n", __func__,
+                        mParams->akm, result);
+                return result;
+            }
+        }
+
+        result = request.put_u32(NAN_ATTRIBUTE_PAIRING_CACHE, mParams->enable_pairing_cache);
+        if (result < 0) {
+            ALOGE("%s: Failed to fill enable pairing cache, result = %d\n", __func__, result);
+            return result;
+        }
+
+        if ((mParams->cipher_type != NAN_CIPHER_SUITE_PUBLIC_KEY_PASN_128_MASK) &&
+                (mParams->cipher_type != NAN_CIPHER_SUITE_PUBLIC_KEY_PASN_256_MASK)) {
+            ALOGE("%s: Invalid cipher_type :%u, \n", __func__, mParams->cipher_type);
+            return WIFI_ERROR_INVALID_ARGS;
+        }
+
+        result = request.put_u8(NAN_ATTRIBUTE_CIPHER_SUITE_TYPE, mParams->cipher_type);
+        if (result < 0) {
+            ALOGE("%s: Failed to fill cipher_type type:%u, result = %d\n", __func__,
+                    mParams->cipher_type, result);
+            return result;
+        }
+
+        result = request.put_u8(NAN_ATTRIBUTE_KEY_TYPE, mParams->key_info.key_type);
+        if (result < 0) {
+            ALOGE("%s: Failed to fill NAN_ATTRIBUTE_KEY_TYPE, result = %d\n",
+                    __func__, result);
+            return result;
+        }
+
+        if (mParams->key_info.key_type == NAN_SECURITY_KEY_INPUT_PASSPHRASE) {
+            if ((mParams->key_info.body.passphrase_info.passphrase_len <
+                    NAN_SECURITY_MIN_PASSPHRASE_LEN) ||
+                    (mParams->key_info.body.passphrase_info.passphrase_len >
+                    NAN_SECURITY_MAX_PASSPHRASE_LEN)) {
+                ALOGE("password must be between %d and %d characters long\n",
+                        NAN_SECURITY_MIN_PASSPHRASE_LEN,
+                        NAN_SECURITY_MAX_PASSPHRASE_LEN);
+                return NAN_STATUS_INVALID_PARAM;
+            } else {
+                if (mParams->key_info.body.passphrase_info.passphrase_len) {
+                    result = request.put_u32(NAN_ATTRIBUTE_KEY_LEN,
+                            mParams->key_info.body.passphrase_info.passphrase_len);
+                    if (result < 0) {
+                        ALOGE("%s: Failed to fill password len, result = %d\n", __func__, result);
+                        return result;
+                    }
+                    result = request.put(NAN_ATTRIBUTE_KEY_DATA_PASSPHRASE,
+                            (void *)mParams->key_info.body.passphrase_info.passphrase,
+                            mParams->key_info.body.passphrase_info.passphrase_len);
+                    if (result < 0) {
+                        ALOGE("%s: Failed to fill passphrase, result = %d\n", __func__, result);
+                        return result;
+                    }
+                }
+            }
+        } else if (mParams->key_info.key_type == NAN_SECURITY_KEY_INPUT_PMK) {
+            if ((!mParams->key_info.body.pmk_info.pmk_len) ||
+                    (mParams->key_info.body.pmk_info.pmk_len != NAN_PMK_INFO_LEN)) {
+                ALOGE("%s: Invalid pmk len: %d, result = %d\n", __func__,
+                        mParams->key_info.body.pmk_info.pmk_len, result);
+                return WIFI_ERROR_INVALID_ARGS;
+            }
+            result = request.put_u32(NAN_ATTRIBUTE_KEY_LEN,
+                    mParams->key_info.body.pmk_info.pmk_len);
+            if (result < 0) {
+                ALOGE("%s: Failed to fill pmk len, result = %d\n", __func__, result);
+                return result;
+            }
+            result = request.put(NAN_ATTRIBUTE_KEY_DATA,
+                    (void *)mParams->key_info.body.pmk_info.pmk,
+                    mParams->key_info.body.pmk_info.pmk_len);
+            if (result < 0) {
+                ALOGE("%s: Failed to fill pmk, result = %d\n", __func__, result);
+                return result;
+            }
+        } else {
+            if (!mParams->is_opportunistic) {
+                ALOGE("%s: Unexpected Key_type received: %u  (no PASSPHRASE/PMK), result = %d\n",
+                        __func__, mParams->key_info.key_type, result);
+                return WIFI_ERROR_INVALID_ARGS;
+            }
+        }
+
+        if (NIK_ISNULL(mParams->nan_identity_key)) {
+            ALOGI("NIK is NULL");
+        } else {
+            result = request.put(NAN_ATTRIBUTE_LOCAL_NIK, mParams->nan_identity_key,
+                    NAN_IDENTITY_KEY_LEN);
+            if (result < 0) {
+                return result;
+            }
+        }
+
+        request.attr_end(data);
+        NAN_DBG_EXIT();
+        return WIFI_SUCCESS;
+    }
+
+    int createPairingIndResponse(WifiRequest& request, NanPairingIndicationResponse *mParams)
+    {
+        mTxId = getTransactionId();
+        int result = request.create(GOOGLE_OUI, NAN_SUBCMD_PAIRING_RESPONSE);
+        if (result < 0) {
+            ALOGE("%s Failed to create pairing indication response \n", __func__);
+            return result;
+        }
+
+        NAN_DBG_ENTER();
+
+        nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
+
+        mInstId = mParams->pairing_instance_id;
+        if (ISGREATER(mInstId, NAN_MAX) || (ISLESS_OR_EQUAL(mInstId, NAN_MIN))) {
+            ALOGE("%s:Invalid Pairing ID: %u \n", __func__, mInstId);
+            return WIFI_ERROR_NOT_SUPPORTED;
+        }
+
+        result = request.put_u16(NAN_ATTRIBUTE_INST_ID, mParams->pairing_instance_id);
+        if (result < 0) {
+            ALOGE("%s: Failed to fill pairing id, result = %d\n", __func__, result);
+            return result;
+        }
+
+        result = request.put_u16(NAN_ATTRIBUTE_TRANSAC_ID, mTxId);
+        if (result < 0) {
+            ALOGE("%s: Failed to fill NAN_ATTRIBUTE_TRANSAC_ID, result = %d\n",
+                    __func__, result);
+            return result;
+        }
+
+        result = request.put_u8(NAN_ATTRIBUTE_RSP_CODE, mParams->rsp_code);
+        if (result < 0) {
+            ALOGE("%s: Failed to fill Response code, result = %d\n", __func__, result);
+            return result;
+        }
+
+        if ((mParams->nan_pairing_request_type < NAN_PAIRING_SETUP) ||
+                (mParams->nan_pairing_request_type > NAN_PAIRING_VERIFICATION)) {
+            ALOGE("%s: Invalid pairing request type :%u\n", __func__,
+                    mParams->nan_pairing_request_type);
+            return WIFI_ERROR_INVALID_ARGS;
+        } else {
+            result = request.put_u16(NAN_ATTRIBUTE_REQUEST_TYPE, mParams->nan_pairing_request_type);
+            if (result < 0) {
+                ALOGE("%s: Failed to fill request type:%u, result = %d\n", __func__,
+                        mParams->nan_pairing_request_type, result);
+                return result;
+            }
+        }
+
+        result = request.put_u16(NAN_ATTRIBUTE_OPPURTUNISTIC, mParams->is_opportunistic);
+        if (result < 0) {
+            ALOGE("%s: Failed to fill is_opputunistic, result = %d\n", __func__, result);
+            return result;
+        }
+
+        if ((mParams->akm < SAE) || (mParams->akm > PASN)) {
+            ALOGE("%s: invalid AKM type:%u \n", __func__, mParams->akm);
+            return WIFI_ERROR_INVALID_ARGS;
+        } else {
+            result = request.put_u8(NAN_ATTRIBUTE_AKM, mParams->akm);
+            if (result < 0) {
+                ALOGE("%s: Failed to fill AKM type:%u, result = %d\n", __func__,
+                        mParams->akm, result);
+                return result;
+            }
+        }
+
+        result = request.put_u32(NAN_ATTRIBUTE_PAIRING_CACHE, mParams->enable_pairing_cache);
+        if (result < 0) {
+            ALOGE("%s: Failed to fill enable pairing cache, result = %d\n", __func__, result);
+            return result;
+        }
+
+        if ((mParams->cipher_type != NAN_CIPHER_SUITE_PUBLIC_KEY_PASN_128_MASK) &&
+                (mParams->cipher_type != NAN_CIPHER_SUITE_PUBLIC_KEY_PASN_256_MASK)) {
+            ALOGE("%s: Invalid cipher_type :%u, \n", __func__, mParams->cipher_type);
+            return WIFI_ERROR_INVALID_ARGS;
+        }
+
+        result = request.put_u8(NAN_ATTRIBUTE_CIPHER_SUITE_TYPE, mParams->cipher_type);
+        if (result < 0) {
+            ALOGE("%s: Failed to fill cipher_type type:%u, result = %d\n", __func__,
+                    mParams->cipher_type, result);
+            return result;
+        }
+
+        result = request.put_u8(NAN_ATTRIBUTE_KEY_TYPE, mParams->key_info.key_type);
+        if (result < 0) {
+            ALOGE("%s: Failed to fill NAN_ATTRIBUTE_KEY_TYPE, result = %d\n",
+                    __func__, result);
+            return result;
+        }
+
+        if (mParams->key_info.key_type == NAN_SECURITY_KEY_INPUT_PASSPHRASE) {
+            if ((mParams->key_info.body.passphrase_info.passphrase_len <
+                    NAN_SECURITY_MIN_PASSPHRASE_LEN) ||
+                    (mParams->key_info.body.passphrase_info.passphrase_len >
+                    NAN_SECURITY_MAX_PASSPHRASE_LEN)) {
+                ALOGE("password must be between %d and %d characters long\n",
+                        NAN_SECURITY_MIN_PASSPHRASE_LEN, NAN_SECURITY_MAX_PASSPHRASE_LEN);
+                return NAN_STATUS_INVALID_PARAM;
+            } else {
+                if (mParams->key_info.body.passphrase_info.passphrase_len) {
+                    result = request.put_u32(NAN_ATTRIBUTE_KEY_LEN,
+                            mParams->key_info.body.passphrase_info.passphrase_len);
+                    if (result < 0) {
+                        ALOGE("%s: Failed to fill password len, result = %d\n", __func__, result);
+                        return result;
+                    }
+                    result = request.put(NAN_ATTRIBUTE_KEY_DATA_PASSPHRASE,
+                            (void *)mParams->key_info.body.passphrase_info.passphrase,
+                            mParams->key_info.body.passphrase_info.passphrase_len);
+                    if (result < 0) {
+                        ALOGE("%s: Failed to fill passphrase, result = %d\n", __func__, result);
+                        return result;
+                    }
+                }
+            }
+        } else if (mParams->key_info.key_type == NAN_SECURITY_KEY_INPUT_PMK) {
+            if ((!mParams->key_info.body.pmk_info.pmk_len) ||
+                    (mParams->key_info.body.pmk_info.pmk_len != NAN_PMK_INFO_LEN)) {
+                ALOGE("%s: Invalid pmk len: %d, result = %d\n", __func__,
+                        mParams->key_info.body.pmk_info.pmk_len, result);
+                return NAN_STATUS_INVALID_PARAM;
+            }
+            result = request.put_u32(NAN_ATTRIBUTE_KEY_LEN,
+                    mParams->key_info.body.pmk_info.pmk_len);
+            if (result < 0) {
+                ALOGE("%s: Failed to fill pmk len, result = %d\n", __func__, result);
+                return result;
+            }
+            result = request.put(NAN_ATTRIBUTE_KEY_DATA,
+                    (void *)mParams->key_info.body.pmk_info.pmk,
+                    mParams->key_info.body.pmk_info.pmk_len);
+            if (result < 0) {
+                ALOGE("%s: Failed to fill pmk, result = %d\n", __func__, result);
+                return result;
+            }
+        } else {
+            if (!mParams->is_opportunistic) {
+                ALOGE("%s: Unexpected Key_type received: %u  (no PASSPHRASE/PMK), result = %d\n",
+                        __func__, mParams->key_info.key_type, result);
+                return WIFI_ERROR_INVALID_ARGS;
+            }
+        }
+
+        if (NIK_ISNULL(mParams->nan_identity_key)) {
+            ALOGI("NIK is NULL");
+        } else {
+            result = request.put(NAN_ATTRIBUTE_LOCAL_NIK, mParams->nan_identity_key,
+                    NAN_IDENTITY_KEY_LEN);
+            if (result < 0) {
+                return result;
+            }
+        }
+
+        request.attr_end(data);
+        NAN_DBG_EXIT();
+        return WIFI_SUCCESS;
+    }
+
+    int createPairingEndRequest(WifiRequest& request, NanPairingEndRequest *mParams)
+    {
+        int result = request.create(GOOGLE_OUI, NAN_SUBCMD_PAIRING_END);
+        if (result < 0) {
+            ALOGE("%s Failed to create Pairing End request\n", __func__);
+            return result;
+        }
+
+        NAN_DBG_ENTER();
+
+        nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
+
+        mInstId = mParams->pairing_instance_id;
+        if (ISGREATER(mInstId, NAN_MAX) || (ISLESS_OR_EQUAL(mInstId, NAN_MIN))) {
+            ALOGE("%s:Invalid Pairing ID: %u \n", __func__, mInstId);
+            return WIFI_ERROR_NOT_SUPPORTED;
+        }
+
+        result = request.put_u16(NAN_ATTRIBUTE_INST_ID, mInstId);
+        if (result < 0) {
+            ALOGE("%s: Failed to fill pairing id, result = %d\n", __func__, result);
+            return result;
+        }
+
+        request.attr_end(data);
+        NAN_DBG_EXIT();
+        return WIFI_SUCCESS;
+    }
+
+    int createBootstrappingIndResponse(WifiRequest& request,
+            NanBootstrappingIndicationResponse *mParams)
+    {
+        mTxId = getTransactionId();
+        int result = request.create(GOOGLE_OUI, NAN_SUBCMD_BOOTSTRAPPING_RESPONSE);
+        if (result < 0) {
+            ALOGE("%s Failed to create Bootstrapping response \n", __func__);
+            return result;
+        }
+
+        NAN_DBG_ENTER();
+
+        nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
+
+        result = request.put_u32(NAN_ATTRIBUTE_PEER_ID, mParams->service_instance_id);
+        if (result < 0) {
+            ALOGE("%s: Failed to fill Requested Instance id, result = %d\n", __func__, result);
+            return result;
+        }
+
+        result = request.put_u16(NAN_ATTRIBUTE_INST_ID, mParams->publish_subscribe_id);
+        if (result < 0) {
+            ALOGE("%s Failed to fill local inst id= %d\n", __func__, mParams->publish_subscribe_id);
+            return result;
+        }
+
+        result = request.put_addr(NAN_ATTRIBUTE_MAC_ADDR, mParams->peer_disc_mac_addr);
+        if (result < 0) {
+            ALOGE("%s: Failed to fill mac addr, result = %d\n", __func__, result);
+            return result;
+        }
+
+        result = request.put_u16(NAN_ATTRIBUTE_TRANSAC_ID, mTxId);
+        if (result < 0) {
+            ALOGE("%s: Failed to fill NAN_ATTRIBUTE_TRANSAC_ID, result = %d\n",
+                    __func__, result);
+            return result;
+        }
+
+        if (mParams->service_specific_info_len) {
+            result = request.put_u16(NAN_ATTRIBUTE_SERVICE_SPECIFIC_INFO_LEN,
+                    mParams->service_specific_info_len);
+            if (result < 0) {
+                ALOGE("%s: Failed to fill svc info len, result = %d\n", __func__, result);
+                return result;
+            }
+
+            result = request.put(NAN_ATTRIBUTE_SERVICE_SPECIFIC_INFO,
+                    (void *)mParams->service_specific_info, mParams->service_specific_info_len);
+            if (result < 0) {
+                ALOGE("%s: Failed to fill svc info, result = %d\n", __func__, result);
+                return result;
+            }
+        }
+
+        if (mParams->sdea_service_specific_info_len) {
+            result = request.put_u16(NAN_ATTRIBUTE_SDEA_SERVICE_SPECIFIC_INFO_LEN,
+                    mParams->sdea_service_specific_info_len);
+            if (result < 0) {
+                ALOGE("%s: Failed to fill sdea svc info len, result = %d\n", __func__, result);
+                return result;
+            }
+
+            prhex(NULL, mParams->sdea_service_specific_info,
+                    mParams->sdea_service_specific_info_len);
+            result = request.put(NAN_ATTRIBUTE_SDEA_SERVICE_SPECIFIC_INFO,
+                    (void *)mParams->sdea_service_specific_info,
+                    mParams->sdea_service_specific_info_len);
+            if (result < 0) {
+                ALOGE("%s: Failed to fill sdea svc info, result = %d\n", __func__, result);
+                return result;
+            }
+        }
+
+        if (mParams->cookie_length) {
+            if (mParams->cookie_length > NAN_MAX_COOKIE_LEN) {
+                ALOGE("%s: Failed to fill cookie len, Invalid cookie len = %d\n", __func__,
+                       mParams->cookie_length);
+                return WIFI_ERROR_INVALID_ARGS;
+            }
+            result = request.put_u32(NAN_ATTRIBUTE_COOKIE_LEN, mParams->cookie_length);
+            if (result < 0) {
+                ALOGE("%s: Failed to fill cookie len, result = %d\n", __func__, result);
+                return result;
+            }
+
+            prhex("Cookie:", mParams->cookie, mParams->cookie_length);
+            result = request.put(NAN_ATTRIBUTE_COOKIE,
+                    (void *)mParams->cookie, mParams->cookie_length);
+            if (result < 0) {
+                ALOGE("%s: Failed to fill cookie info, result = %d\n", __func__, result);
+                return result;
+            }
+        }
+
+        result = request.put_u8(NAN_ATTRIBUTE_RSP_CODE, mParams->rsp_code);
+        if (result < 0) {
+            ALOGE("%s: Failed to fill Response code, result = %d\n", __func__, result);
+            return result;
+        }
+
+        result = request.put_u32(NAN_ATTRIBUTE_COME_BACK_DELAY, mParams->come_back_delay);
+        if (result < 0) {
+            ALOGE("%s: Failed to fill comeback delay, result = %d\n", __func__, result);
+            return result;
+        }
+
+        request.attr_end(data);
+        NAN_DBG_EXIT();
+        return WIFI_SUCCESS;
+    }
+
+    int createBootstrappingRequest(WifiRequest& request, NanBootstrappingRequest *mParams)
+    {
+        mTxId = getTransactionId();
+        int result = request.create(GOOGLE_OUI, NAN_SUBCMD_BOOTSTRAPPING_REQUEST);
+        if (result < 0) {
+            ALOGE("%s Failed to create Bootstrapping request \n", __func__);
+            return result;
+        }
+
+        NAN_DBG_ENTER();
+
+        /* If handle is 0xFFFF, then update instance_id in response of this request
+         * otherwise, update not needed
+         */
+        nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
+
+        result = request.put_u32(NAN_ATTRIBUTE_PEER_ID, mParams->requestor_instance_id);
+        if (result < 0) {
+            ALOGE("%s: Failed to fill Requestor Instance id, result = %d\n", __func__, result);
+            return result;
+        }
+
+        result = request.put_u16(NAN_ATTRIBUTE_INST_ID, mParams->publish_subscribe_id);
+        if (result < 0) {
+            ALOGE("%s Failed to fill local inst id= %d\n", __func__, mParams->publish_subscribe_id);
+            return result;
+        }
+
+        result = request.put_addr(NAN_ATTRIBUTE_MAC_ADDR, mParams->peer_disc_mac_addr);
+        if (result < 0) {
+            ALOGE("%s: Failed to fill mac addr, result = %d\n", __func__, result);
+            return result;
+        }
+
+        result = request.put_u16(NAN_ATTRIBUTE_BS_METHODS, mParams->request_bootstrapping_method);
+        if (result < 0) {
+            ALOGE("%s: Failed to fill Supported BS methods, result = %d\n", __func__, result);
+            return result;
+        }
+
+        result = request.put_u16(NAN_ATTRIBUTE_TRANSAC_ID, mTxId);
+        if (result < 0) {
+            ALOGE("%s: Failed to fill NAN_ATTRIBUTE_TRANSAC_ID, result = %d\n",
+                    __func__, result);
+            return result;
+        }
+
+        if (mParams->service_specific_info_len) {
+            result = request.put_u16(NAN_ATTRIBUTE_SERVICE_SPECIFIC_INFO_LEN,
+                    mParams->service_specific_info_len);
+            if (result < 0) {
+                ALOGE("%s: Failed to fill svc info len, result = %d\n", __func__, result);
+                return result;
+            }
+
+            result = request.put(NAN_ATTRIBUTE_SERVICE_SPECIFIC_INFO,
+                    (void *)mParams->service_specific_info, mParams->service_specific_info_len);
+            if (result < 0) {
+                ALOGE("%s: Failed to fill svc info, result = %d\n", __func__, result);
+                return result;
+            }
+        }
+
+        if (mParams->sdea_service_specific_info_len) {
+            result = request.put_u16(NAN_ATTRIBUTE_SDEA_SERVICE_SPECIFIC_INFO_LEN,
+                    mParams->sdea_service_specific_info_len);
+            if (result < 0) {
+                ALOGE("%s: Failed to fill sdea svc info len, result = %d\n", __func__, result);
+                return result;
+            }
+
+            prhex(NULL, mParams->sdea_service_specific_info,
+                    mParams->sdea_service_specific_info_len);
+            result = request.put(NAN_ATTRIBUTE_SDEA_SERVICE_SPECIFIC_INFO,
+                    (void *)mParams->sdea_service_specific_info,
+                    mParams->sdea_service_specific_info_len);
+            if (result < 0) {
+                ALOGE("%s: Failed to fill sdea svc info, result = %d\n", __func__, result);
+                return result;
+            }
+        }
+
+        if (mParams->cookie_length) {
+            if (mParams->cookie_length > NAN_MAX_COOKIE_LEN) {
+                ALOGE("%s: Failed to fill cookie len, Invalid cookie len = %d\n", __func__,
+                       mParams->cookie_length);
+                return WIFI_ERROR_INVALID_ARGS;
+            }
+            result = request.put_u32(NAN_ATTRIBUTE_COOKIE_LEN, mParams->cookie_length);
+            if (result < 0) {
+                ALOGE("%s: Failed to fill cookie len, result = %d\n", __func__, result);
+                return result;
+            }
+
+            prhex("Cookie:", mParams->cookie, mParams->cookie_length);
+            result = request.put(NAN_ATTRIBUTE_COOKIE,
+                    (void *)mParams->cookie, mParams->cookie_length);
+            if (result < 0) {
+                ALOGE("%s: Failed to fill cookie, result = %d\n", __func__, result);
+                return result;
+            }
+        }
+
+        if (result < 0) {
+          return result;
+        }
+
+        request.attr_end(data);
+        NAN_DBG_EXIT();
+        return WIFI_SUCCESS;
+    }
+
+    int start()
+    {
+        int result = 0;
+        WifiRequest request(familyId(), ifaceId());
+        result = createRequest(request);
+        if (result != WIFI_SUCCESS) {
+            ALOGE("%s: Failed to create setup request; result = %d\n", __func__, result);
+            return result;
+        }
+
+        result = requestResponse(request);
+        if (result != WIFI_SUCCESS) {
+            ALOGE("%s: Failed to configure setup; result = %d\n", __func__, result);
+            return result;
+        }
+
+        request.destroy();
+        return WIFI_SUCCESS;
+    }
+
+    virtual bool valid_pairing_response_type(int response_type) {
+        bool valid = false;
+        switch (response_type) {
+            case NAN_PAIRING_INITIATOR_RESPONSE:
+            case NAN_PAIRING_RESPONDER_RESPONSE:
+            case NAN_PAIRING_END:
+            case NAN_BOOTSTRAPPING_INITIATOR_RESPONSE:
+            case NAN_BOOTSTRAPPING_RESPONDER_RESPONSE:
+                valid = true;
+                break;
+            default:
+                ALOGE("NanPairingPrimitive:Unknown cmd Response: %d\n", response_type);
+                break;
+        }
+        return valid;
+    }
+
+    int handleResponse(WifiEvent& reply)
+    {
+        nan_hal_resp_t *rsp_vndr_data = NULL;
+        NanResponseMsg rsp_data;
+        if (reply.get_cmd() != NL80211_CMD_VENDOR || reply.get_vendor_data() == NULL) {
+            ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());
+            return NL_SKIP;
+        }
+        rsp_vndr_data = (nan_hal_resp_t *)reply.get_vendor_data();
+        ALOGI("NanDiscEnginePrmitive::handle response\n");
+        memset(&rsp_data, 0, sizeof(NanResponseMsg));
+        rsp_data.response_type = get_response_type((WIFI_SUB_COMMAND)rsp_vndr_data->subcmd);
+        if (!valid_pairing_response_type(rsp_data.response_type))
+            return NL_SKIP;
+
+        rsp_data.status = nan_map_response_status(rsp_vndr_data->status);
+        ALOGE("Mapped hal status = %d\n", rsp_data.status);
+        if (rsp_vndr_data->nan_reason[0] == '\0') {
+            memcpy(rsp_data.nan_error, NanStatusToString(rsp_data.status),
+                    strlen(NanStatusToString(rsp_data.status)));
+            rsp_data.nan_error[strlen(NanStatusToString(rsp_data.status))] = '\0';
+        }
+        rsp_data.nan_error[NAN_ERROR_STR_LEN - 1] = '\0';
+        ALOGI("\n Received nan_error string %s\n", (u8*)rsp_data.nan_error);
+
+        if (rsp_data.response_type == NAN_PAIRING_INITIATOR_RESPONSE) {
+            rsp_data.body.pairing_request_response.paring_instance_id =
+	            rsp_vndr_data->instance_id;
+            ALOGI("Received Pairing instance_id %d\n", rsp_vndr_data->instance_id);
+        } else if (rsp_data.response_type == NAN_BOOTSTRAPPING_INITIATOR_RESPONSE) {
+            rsp_data.body.bootstrapping_request_response.bootstrapping_instance_id =
+                    rsp_vndr_data->instance_id;
+            ALOGI("Received BS instance_id %d\n", rsp_vndr_data->instance_id);
+        }
+
+        GET_NAN_HANDLE(info)->mHandlers.NotifyResponse(id(), &rsp_data);
+        ALOGI("NanPairingPrimitive: Received response for cmd [%s], ret %d\n",
+                NanRspToString(rsp_data.response_type), rsp_data.status);
+
+        return NL_SKIP;
+    }
+
+    int handleEvent(WifiEvent& event)
+    {
+        int cmd = event.get_vendor_subcmd();
+        u16 attr_type;
+
+        ALOGI("Received NanPairingPrimitive event: %d\n", event.get_cmd());
+        nlattr *vendor_data = event.get_attribute(NL80211_ATTR_VENDOR_DATA);
+
+        switch (cmd) {
+            case NAN_EVENT_PAIRING_REQUEST:
+                NanPairingRequestInd pairing_request_event;
+                memset(&pairing_request_event, 0, sizeof(NanPairingRequestInd));
+                ALOGI("Received NAN_EVENT_PAIRING_REQUEST\n");
+
+                for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
+                    attr_type = it.get_type();
+
+                    if (attr_type == NAN_ATTRIBUTE_PUBLISH_ID) {
+                        ALOGI("publish_subscribe_id: %u\n", it.get_u16());
+                        pairing_request_event.publish_subscribe_id = it.get_u16();
+
+                    } else if (attr_type == NAN_ATTRIBUTE_SUBSCRIBE_ID) {
+                        ALOGI("Requestor instance id: %u\n", it.get_u32());
+                        pairing_request_event.requestor_instance_id = it.get_u32();
+
+                    } else if (attr_type == NAN_ATTRIBUTE_MAC_ADDR) {
+                        memcpy(pairing_request_event.peer_disc_mac_addr,
+                                it.get_data(), NAN_MAC_ADDR_LEN);
+                        ALOGI("Discovery MAC addr of the peer/initiator: " MACSTR "\n",
+                                MAC2STR(pairing_request_event.peer_disc_mac_addr));
+
+                    } else if (attr_type == NAN_ATTRIBUTE_INST_ID) {
+                        u32 pairing_id = it.get_u32();
+                        ALOGI("pairing instance id: %u\n", pairing_id);
+
+                        if (ISGREATER(pairing_id, NAN_MAX) ||
+                                  (ISLESS_OR_EQUAL(pairing_id, NAN_MIN))) {
+                            ALOGE("%s:Invalid Pairing ID: %u \n", __func__, pairing_id);
+                            goto fail;
+                        }
+                        pairing_request_event.pairing_instance_id = pairing_id;
+
+                    } else if (attr_type == NAN_ATTRIBUTE_REQUEST_TYPE) {
+                        ALOGI("Pairing request type: %u\n", it.get_u16());
+                        pairing_request_event.nan_pairing_request_type =
+                                (NanPairingRequestType)it.get_u16();
+                        if ((pairing_request_event.nan_pairing_request_type >
+                                NAN_PAIRING_VERIFICATION) ||
+                                (pairing_request_event.nan_pairing_request_type <
+                                NAN_PAIRING_SETUP)) {
+                            ALOGI("INVALID Pairing request type %u\n",
+                                    pairing_request_event.nan_pairing_request_type);
+                        }
+
+                    } else if (attr_type == NAN_ATTRIBUTE_PAIRING_CACHE) {
+                        ALOGI("Pairing cache enabled: %u\n", (u8)it.get_u32());
+                        pairing_request_event.enable_pairing_cache = (u8)it.get_u32();
+
+                    } else if (attr_type == NAN_ATTRIBUTE_NIRA_TAG) {
+                        memcpy(pairing_request_event.nira.tag, it.get_data(), NAN_IDENTITY_TAG_LEN);
+                        prhex("NIRA tag", pairing_request_event.nira.tag, NAN_IDENTITY_TAG_LEN);
+
+                    } else if (attr_type == NAN_ATTRIBUTE_NIRA_NONCE) {
+                        memcpy(pairing_request_event.nira.nonce, it.get_data(),
+                                NAN_IDENTITY_NONCE_LEN);
+                        prhex("NIRA nonce", pairing_request_event.nira.nonce,
+                                NAN_IDENTITY_NONCE_LEN);
+                    }
+
+                }
+
+                if (!pairing_request_event.publish_subscribe_id ||
+                        !pairing_request_event.pairing_instance_id) {
+                    ALOGE("Check invalid params received pub_sub_id: 0x%x pairing_id: %u\n",
+                            pairing_request_event.publish_subscribe_id,
+                            pairing_request_event.pairing_instance_id);
+                    goto fail;
+                }
+
+                GET_NAN_HANDLE(info)->mHandlers.EventPairingRequest(&pairing_request_event);
+                break;
+            case NAN_EVENT_PAIRING_CONFIRMATION: {
+                NanPairingConfirmInd pairing_confirm_event;
+                u32 pmk_len = 0;
+                memset(&pairing_confirm_event, 0, sizeof(NanPairingConfirmInd));
+                ALOGI("Received NAN_EVENT_PAIRING_CONFIRMATION\n");
+
+                for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
+                    attr_type = it.get_type();
+
+                    if (attr_type == NAN_ATTRIBUTE_INST_ID) {
+                        ALOGI("pairing instance id: %u\n", it.get_u32());
+                        pairing_confirm_event.pairing_instance_id = it.get_u32();
+                        if ((pairing_confirm_event.pairing_instance_id <= NAN_MIN) ||
+                                (pairing_confirm_event.pairing_instance_id > NAN_MAX)) {
+                            ALOGE("INVALID Pairing instance id: %u\n",
+                                    pairing_confirm_event.pairing_instance_id);
+                            goto fail;
+                        }
+
+                    } else if (attr_type == NAN_ATTRIBUTE_RSP_CODE) {
+                        ALOGI("response code: %u\n", (NanPairingResponseCode)it.get_u8());
+                        pairing_confirm_event.rsp_code = (NanPairingResponseCode)it.get_u8();
+
+                    } else if (attr_type == NAN_ATTRIBUTE_STATUS) {
+                        ALOGI("reason_code: %u\n", (NanStatusType)it.get_u8());
+                        pairing_confirm_event.reason_code = (NanStatusType)it.get_u8();
+
+                    } else if (attr_type == NAN_ATTRIBUTE_REQUEST_TYPE) {
+                        ALOGI("Pairing request type: %u\n", (NanPairingRequestType)it.get_u16());
+                        pairing_confirm_event.nan_pairing_request_type =
+                                (NanPairingRequestType)it.get_u16();
+                        if ((pairing_confirm_event.nan_pairing_request_type >
+                                NAN_PAIRING_VERIFICATION) ||
+                                (pairing_confirm_event.nan_pairing_request_type <
+                                NAN_PAIRING_SETUP)) {
+                            ALOGI("INVALID Pairing request type %u\n",
+                                    pairing_confirm_event.nan_pairing_request_type);
+                            goto fail;
+                        }
+
+                    } else if (attr_type == NAN_ATTRIBUTE_PAIRING_CACHE) {
+                        ALOGI("Pairing cache enabled: %u\n", (u8)it.get_u32());
+                        pairing_confirm_event.enable_pairing_cache = (u8)it.get_u32();
+
+                    } else if (attr_type == NAN_ATTRIBUTE_PEER_NIK) {
+                        memcpy(pairing_confirm_event.npk_security_association.peer_nan_identity_key,
+                                it.get_data(), NAN_IDENTITY_KEY_LEN);
+                        prhex("Peer NIK:",
+                            pairing_confirm_event.npk_security_association.peer_nan_identity_key,
+                            NAN_IDENTITY_KEY_LEN);
+
+                    } else if (attr_type == NAN_ATTRIBUTE_LOCAL_NIK) {
+                        memcpy(pairing_confirm_event.npk_security_association.local_nan_identity_key,
+                                it.get_data(), NAN_IDENTITY_KEY_LEN);
+                        prhex("Local NIK:",
+                            pairing_confirm_event.npk_security_association.local_nan_identity_key,
+                            NAN_IDENTITY_KEY_LEN);
+
+                    } else if (attr_type == NAN_ATTRIBUTE_AKM) {
+                        ALOGI("akm: %u\n", (NanAkm)it.get_u8());
+                        pairing_confirm_event.npk_security_association.akm = (NanAkm)it.get_u8();
+                        if ((pairing_confirm_event.npk_security_association.akm >
+                                PASN) || (pairing_confirm_event.npk_security_association.akm <
+                                SAE)) {
+                            ALOGI("INVALID Pairing AKM type %u\n",
+                                    pairing_confirm_event.npk_security_association.akm);
+                            goto fail;
+                        }
+
+                    } else if (attr_type == NAN_ATTRIBUTE_CIPHER_SUITE_TYPE) {
+                        u32 csid = it.get_u32();
+                        ALOGI("csid: 0x%x\n", csid);
+                        pairing_confirm_event.npk_security_association.cipher_type = csid;
+                        if ((csid != NAN_CIPHER_SUITE_PUBLIC_KEY_PASN_128_MASK) &&
+                                (csid != NAN_CIPHER_SUITE_PUBLIC_KEY_PASN_256_MASK)) {
+                            ALOGE("%s: Invalid cipher_type received :0x%x \n", __func__, csid);
+                            goto fail;
+                        }
+
+                    } else if (attr_type == NAN_ATTRIBUTE_KEY_LEN) {
+                        ALOGI("pmk len: %u\n", it.get_u32());
+                        pmk_len = it.get_u32();
+                        pairing_confirm_event.npk_security_association.npk.pmk_len = pmk_len;
+
+                    } else if (attr_type == NAN_ATTRIBUTE_KEY_DATA) {
+                        memcpy(&pairing_confirm_event.npk_security_association.npk.pmk,
+                                it.get_data(),
+                                pairing_confirm_event.npk_security_association.npk.pmk_len);
+                        prhex("NPK", (u8 *)pairing_confirm_event.npk_security_association.npk.pmk,
+                                pairing_confirm_event.npk_security_association.npk.pmk_len);
+
+                    }
+                }
+
+                if (!pairing_confirm_event.npk_security_association.cipher_type ||
+                        !pairing_confirm_event.npk_security_association.npk.pmk_len ||
+                        !pairing_confirm_event.pairing_instance_id) {
+                    ALOGE("Check invalid params received csid: 0x%x pmk_len: %u pairing_id: %u\n",
+                            pairing_confirm_event.npk_security_association.cipher_type,
+                            pairing_confirm_event.npk_security_association.npk.pmk_len,
+                            pairing_confirm_event.pairing_instance_id);
+                    goto fail;
+                }
+
+                GET_NAN_HANDLE(info)->mHandlers.EventPairingConfirm(&pairing_confirm_event);
+                break;
+            }
+            case NAN_EVENT_BOOTSTRAPPING_REQUEST:
+                NanBootstrappingRequestInd bs_request_event;
+                memset(&bs_request_event, 0, sizeof(NanBootstrappingRequestInd));
+                ALOGI("Received NAN_EVENT_BOOTSTRAPPING_REQUEST\n");
+
+                for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
+                    attr_type = it.get_type();
+
+                    if (attr_type == NAN_ATTRIBUTE_SUBSCRIBE_ID) {
+                        ALOGI("publish_subscribe_id: %u\n", it.get_u16());
+                        bs_request_event.publish_subscribe_id = it.get_u16();
+
+                    } else if (attr_type == NAN_ATTRIBUTE_PUBLISH_ID) {
+                        ALOGI("requestor_instance_id: %u\n", it.get_u32());
+                        bs_request_event.requestor_instance_id = it.get_u32();
+
+                    } else if (attr_type == NAN_ATTRIBUTE_MAC_ADDR) {
+                        memcpy(bs_request_event.peer_disc_mac_addr,
+                                it.get_data(), NAN_MAC_ADDR_LEN);
+                        ALOGI("Discovery MAC addr of the peer/initiator: " MACSTR "\n",
+                                MAC2STR(bs_request_event.peer_disc_mac_addr));
+
+                    } else if (attr_type == NAN_ATTRIBUTE_INST_ID) {
+                        ALOGI("BS instance id: %u\n", it.get_u32());
+                        bs_request_event.bootstrapping_instance_id = it.get_u32();
+                        if ((bs_request_event.bootstrapping_instance_id <= NAN_MIN) ||
+                                (bs_request_event.bootstrapping_instance_id > NAN_MAX)) {
+                            ALOGE("INVALID bootstrapping instance id: %u\n",
+                                    bs_request_event.bootstrapping_instance_id);
+                            goto fail;
+                        }
+
+                    } else if (attr_type == NAN_ATTRIBUTE_BS_METHODS) {
+                        ALOGI("Peer BS methods: 0x%x\n", it.get_u16());
+                        bs_request_event.request_bootstrapping_method = it.get_u16();
+
+                    }
+                }
+
+                if (!bs_request_event.publish_subscribe_id ||
+                        !bs_request_event.requestor_instance_id ||
+                        !bs_request_event.bootstrapping_instance_id ||
+                        !bs_request_event.request_bootstrapping_method) {
+                    ALOGE("Check invalid params recvd pub_sub_id: 0x%x req_inst_id: %u"
+                            "bootstrapping_id: %u bs_methods 0x%x\n",
+                            bs_request_event.publish_subscribe_id,
+                            bs_request_event.requestor_instance_id,
+                            bs_request_event.bootstrapping_instance_id,
+                            bs_request_event.request_bootstrapping_method);
+                    goto fail;
+                }
+
+                GET_NAN_HANDLE(info)->mHandlers.EventBootstrappingRequest(&bs_request_event);
+                break;
+            case NAN_EVENT_BOOTSTRAPPING_CONFIRMATION:
+                NanBootstrappingConfirmInd bs_confirm_event;
+                memset(&bs_confirm_event, 0, sizeof(NanBootstrappingConfirmInd));
+                ALOGI("Received NAN_EVENT_BOOTSTRAPPING_CONFIRMATION\n");
+
+                for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
+                    attr_type = it.get_type();
+
+                    if (attr_type == NAN_ATTRIBUTE_INST_ID) {
+                        ALOGI("bootstrapping instance id: %u\n", it.get_u32());
+                        bs_confirm_event.bootstrapping_instance_id = it.get_u32();
+
+                        if ((bs_confirm_event.bootstrapping_instance_id <= NAN_MIN) ||
+                               (bs_confirm_event.bootstrapping_instance_id > NAN_MAX)) {
+                            ALOGE("INVALID bootstrapping instance id: %u\n",
+                                   bs_confirm_event.bootstrapping_instance_id);
+                            goto fail;
+                        }
+
+                    } else if (attr_type == NAN_ATTRIBUTE_RSP_CODE) {
+                        ALOGI("response code: %u\n", (NanBootstrappingResponseCode)it.get_u8());
+                        bs_confirm_event.rsp_code = (NanBootstrappingResponseCode)it.get_u8();
+
+                    } else if (attr_type == NAN_ATTRIBUTE_STATUS) {
+                        ALOGI("reason_code: %u\n", (NanStatusType)it.get_u8());
+                        bs_confirm_event.reason_code = (NanStatusType)it.get_u8();
+
+                    } else if (attr_type == NAN_ATTRIBUTE_COME_BACK_DELAY) {
+                        ALOGI("comeback delay: %u\n", it.get_u32());
+                        bs_confirm_event.come_back_delay = it.get_u32();
+
+                    } else if (attr_type == NAN_ATTRIBUTE_COOKIE_LEN) {
+                        ALOGI("cookie len: %u\n", it.get_u32());
+                        bs_confirm_event.cookie_length = it.get_u32();
+
+                    } else if (attr_type == NAN_ATTRIBUTE_COOKIE) {
+                        memcpy(bs_confirm_event.cookie, it.get_data(),
+                                bs_confirm_event.cookie_length);
+                        prhex("cookie", bs_confirm_event.cookie,
+                                bs_confirm_event.cookie_length);
+                    }
+                }
+
+                if (!bs_confirm_event.bootstrapping_instance_id) {
+                    ALOGE("Check invalid bootstrapping_id: %u recvd\n",
+                            bs_confirm_event.bootstrapping_instance_id);
+                    goto fail;
+                }
+
+                GET_NAN_HANDLE(info)->mHandlers.EventBootstrappingConfirm(&bs_confirm_event);
+                break;
+        } // end-of-switch-case
+        return NL_SKIP;
+fail:
+    ALOGE("Dropping Pairing Event %d, invalid params received \n", cmd);
+    return NL_STOP;
+    }
+};
+
+///////////////////////////////////////////////////////////////////////////////
 class NanDiscEnginePrimitive : public WifiCommand
 {
     NanRequest mParams;
@@ -593,6 +1658,7 @@
     u16 mInstId;
     u32 mPeerId;
     u16 mTxId;
+    wifi_interface_handle mIface;
 
     public:
     NanDiscEnginePrimitive(wifi_interface_handle iface, int id,
@@ -602,6 +1668,7 @@
         mInstId = 0;
         mPeerId = 0;
         setTransactionId(id);
+        setIface(iface);
     }
 
     ~NanDiscEnginePrimitive() {
@@ -632,6 +1699,10 @@
         mParams = params;
     }
 
+    void setIface(wifi_interface_handle iface) {
+        mIface = iface;
+    }
+
     int createRequest(WifiRequest& request)
     {
         ALOGI("NAN CMD: %s\n", NanCmdToString(mType));
@@ -673,6 +1744,7 @@
          */
         mInstId = mParams->publish_id;
         nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
+        hal_info *h_info = getHalInfo(mIface);
 
         result = request.put_u32(NAN_ATTRIBUTE_PUBLISH_ID, mInstId);
         if (result < 0) {
@@ -715,6 +1787,11 @@
         }
 
         if (mParams->service_name_len) {
+            if (mParams->service_name_len > NAN_MAX_SERVICE_NAME_LEN) {
+                ALOGE("%s: Invalid svc len %d\n", __func__, mParams->service_name_len);
+                return WIFI_ERROR_INVALID_ARGS;
+            }
+
             u8 svc_hash[NAN_SVC_HASH_SIZE];
 
             result = get_svc_hash(mParams->service_name, mParams->service_name_len,
@@ -742,6 +1819,11 @@
         }
 
         if (mParams->service_specific_info_len) {
+            if (mParams->service_specific_info_len > NAN_MAX_SVC_INFO_LEN) {
+                ALOGE("%s: Invalid svc info len = %d\n",
+                        __func__, mParams->service_specific_info_len);
+                return WIFI_ERROR_INVALID_ARGS;
+            }
             result = request.put_u16(NAN_ATTRIBUTE_SERVICE_SPECIFIC_INFO_LEN,
                     mParams->service_specific_info_len);
             if (result < 0) {
@@ -758,6 +1840,11 @@
         }
 
         if (mParams->rx_match_filter_len) {
+            if (mParams->rx_match_filter_len > NAN_MAX_MATCH_FILTER_LEN) {
+                ALOGE("%s: Invalid rx match filter len = %d\n",
+                        __func__, mParams->rx_match_filter_len);
+                return WIFI_ERROR_INVALID_ARGS;
+            }
             result = request.put_u16(NAN_ATTRIBUTE_RX_MATCH_FILTER_LEN,
                     mParams->rx_match_filter_len);
             if (result < 0) {
@@ -766,7 +1853,7 @@
                 return result;
             }
 
-            prhex(NULL, mParams->rx_match_filter, mParams->rx_match_filter_len);
+            prhex("rx match: ", mParams->rx_match_filter, mParams->rx_match_filter_len);
             result = request.put(NAN_ATTRIBUTE_RX_MATCH_FILTER,
                     (void *)mParams->rx_match_filter, mParams->rx_match_filter_len);
             if (result < 0) {
@@ -776,6 +1863,11 @@
         }
 
         if (mParams->tx_match_filter_len) {
+            if (mParams->tx_match_filter_len > NAN_MAX_MATCH_FILTER_LEN) {
+                ALOGE("%s: Invalid tx match filter len = %d\n",
+                        __func__, mParams->tx_match_filter_len);
+                return WIFI_ERROR_INVALID_ARGS;
+            }
             result = request.put_u16(NAN_ATTRIBUTE_TX_MATCH_FILTER_LEN,
                     mParams->tx_match_filter_len);
             if (result < 0) {
@@ -783,7 +1875,7 @@
                 return result;
             }
 
-            prhex(NULL, mParams->tx_match_filter, mParams->tx_match_filter_len);
+            prhex("tx match: ", mParams->tx_match_filter, mParams->tx_match_filter_len);
             result = request.put(NAN_ATTRIBUTE_TX_MATCH_FILTER,
                     (void *)mParams->tx_match_filter, mParams->tx_match_filter_len);
             if (result < 0) {
@@ -830,6 +1922,11 @@
 
         if (mParams->key_info.key_type == NAN_SECURITY_KEY_INPUT_PMK) {
             if (mParams->key_info.body.pmk_info.pmk_len) {
+                if (mParams->key_info.body.pmk_info.pmk_len > NAN_PMK_INFO_LEN) {
+                    ALOGE("%s: Invalid pmk len len = %d\n",
+                            __func__, mParams->key_info.body.pmk_info.pmk_len);
+                    return WIFI_ERROR_INVALID_ARGS;
+                }
                 result = request.put_u32(NAN_ATTRIBUTE_KEY_LEN,
                         mParams->key_info.body.pmk_info.pmk_len);
                 if (result < 0) {
@@ -847,8 +1944,10 @@
         }
 
         if (mParams->key_info.key_type == NAN_SECURITY_KEY_INPUT_PASSPHRASE) {
-            if (mParams->key_info.body.passphrase_info.passphrase_len < NAN_SECURITY_MIN_PASSPHRASE_LEN ||
-                    mParams->key_info.body.passphrase_info.passphrase_len > NAN_SECURITY_MAX_PASSPHRASE_LEN) {
+            if ((mParams->key_info.body.passphrase_info.passphrase_len <
+                    NAN_SECURITY_MIN_PASSPHRASE_LEN) ||
+                    (mParams->key_info.body.passphrase_info.passphrase_len >
+                    NAN_SECURITY_MAX_PASSPHRASE_LEN)) {
                 ALOGE("passphrase must be between %d and %d characters long\n",
                         NAN_SECURITY_MIN_PASSPHRASE_LEN,
                         NAN_SECURITY_MAX_PASSPHRASE_LEN);
@@ -858,7 +1957,8 @@
                 result = passphrase_to_pmk(mNmi, mParams->cipher_type,
                         mParams->service_name, &mParams->key_info, pmk_hex);
                 if (result < 0) {
-                    ALOGE("%s: Failed to convert passphrase to key data, result = %d\n", __func__, result);
+                    ALOGE("%s: Failed to convert passphrase to key data, result = %d\n",
+                            __func__, result);
                     return result;
                 }
                 result = request.put_u32(NAN_ATTRIBUTE_KEY_LEN, NAN_PMK_INFO_LEN);
@@ -887,7 +1987,7 @@
                 return result;
             }
 
-            prhex(NULL, mParams->scid, mParams->scid_len);
+            prhex("SCID: ", mParams->scid, mParams->scid_len);
             result = request.put(NAN_ATTRIBUTE_SCID,
                     (void *)mParams->scid, mParams->scid_len);
             if (result < 0) {
@@ -900,28 +2000,32 @@
                 mParams->sdea_params.config_nan_data_path);
 
         if (result < 0) {
-            ALOGE("%s: Failed to fill NAN_ATTRIBUTE_SDE_CONTROL_CONFIG_DP, result = %d\n", __func__, result);
+            ALOGE("%s: Failed to fill NAN_ATTRIBUTE_SDE_CONTROL_CONFIG_DP, result = %d\n",
+                    __func__, result);
             return result;
         }
 
         result = request.put_u8(NAN_ATTRIBUTE_SDE_CONTROL_SECURITY,
                 mParams->sdea_params.security_cfg);
         if (result < 0) {
-            ALOGE("%s: Failed to fill NAN_ATTRIBUTE_SDE_CONTROL_SECURITY, result = %d\n", __func__, result);
+            ALOGE("%s: Failed to fill NAN_ATTRIBUTE_SDE_CONTROL_SECURITY, result = %d\n",
+                    __func__, result);
             return result;
         }
 
         result = request.put_u8(NAN_ATTRIBUTE_SDE_CONTROL_DP_TYPE,
                 mParams->sdea_params.ndp_type);
         if (result < 0) {
-            ALOGE("%s: Failed to fill NAN_ATTRIBUTE_SDE_CONTROL_DP_TYPE, result = %d\n", __func__, result);
+            ALOGE("%s: Failed to fill NAN_ATTRIBUTE_SDE_CONTROL_DP_TYPE, result = %d\n",
+                    __func__, result);
             return result;
         }
 
         result = request.put_u8(NAN_ATTRIBUTE_SDE_CONTROL_RANGE_SUPPORT,
                 mParams->sdea_params.ranging_state);
         if (result < 0) {
-            ALOGE("%s: Failed to fill NAN_ATTRIBUTE_SDE_CONTROL_RANGE_SUPPORT, result = %d\n", __func__, result);
+            ALOGE("%s: Failed to fill NAN_ATTRIBUTE_SDE_CONTROL_RANGE_SUPPORT, result = %d\n",
+                    __func__, result);
             return result;
         }
 
@@ -934,6 +2038,11 @@
         }
 
         if (mParams->sdea_service_specific_info_len) {
+            if (mParams->sdea_service_specific_info_len > NAN_MAX_SDEA_SERVICE_SPECIFIC_INFO_LEN) {
+                ALOGE("%s: Invalid sdea info len = %d\n",
+                        __func__, mParams->sdea_service_specific_info_len);
+                return WIFI_ERROR_INVALID_ARGS;
+            }
             result = request.put_u16(NAN_ATTRIBUTE_SDEA_SERVICE_SPECIFIC_INFO_LEN,
                     mParams->sdea_service_specific_info_len);
             if (result < 0) {
@@ -941,9 +2050,11 @@
                 return result;
             }
 
-            prhex(NULL, mParams->sdea_service_specific_info, mParams->sdea_service_specific_info_len);
+            prhex("SDEA INFO: ", mParams->sdea_service_specific_info,
+                    mParams->sdea_service_specific_info_len);
             result = request.put(NAN_ATTRIBUTE_SDEA_SERVICE_SPECIFIC_INFO,
-                    (void *)mParams->sdea_service_specific_info, mParams->sdea_service_specific_info_len);
+                    (void *)mParams->sdea_service_specific_info,
+                    mParams->sdea_service_specific_info_len);
             if (result < 0) {
                 ALOGE("%s: Failed to fill sdea svc info, result = %d\n", __func__, result);
                 return result;
@@ -958,13 +2069,62 @@
             return result;
         }
 
-        result = request.put_u8(NAN_ATTRIBUTE_SVC_CFG_SUPENDABLE, mParams->enable_suspendability);
-        if (result < 0) {
-            ALOGE("%s: Failed to fill NAN_ATTRIBUTE_SVC_CFG_SUPENDABLE, result = %d\n", __func__, result);
-            return result;
+        ALOGI("createPublishRequest: Cached pairing %d suspend %d, mode %d\n",
+                GET_NAN_PAIRING_CAP(h_info), GET_NAN_SUSPEND_CAP(h_info), get_halutil_mode());
+
+        if (get_halutil_mode() || GET_NAN_SUSPEND_CAP(h_info)) {
+            result = request.put_u8(NAN_ATTRIBUTE_SVC_CFG_SUPENDABLE,
+                     mParams->enable_suspendability);
+            if (result < 0) {
+                ALOGE("%s: Failed to fill NAN_ATTRIBUTE_SVC_CFG_SUPENDABLE, result = %d\n",
+                        __func__, result);
+                return result;
+            }
         }
-	/* To be removed */
-        ALOGE("Publish enable_suspendability=%u\n", mParams->enable_suspendability);
+
+        if (get_halutil_mode() || GET_NAN_PAIRING_CAP(h_info)) {
+            if (NIK_ISNULL(mParams->nan_identity_key)) {
+                ALOGI("NIK is NULL");
+            } else {
+                result = request.put(NAN_ATTRIBUTE_LOCAL_NIK, mParams->nan_identity_key,
+                        NAN_IDENTITY_KEY_LEN);
+                if (result < 0) {
+                    return result;
+                }
+            }
+
+            result = request.put_u32(NAN_ATTRIBUTE_ENAB_PAIRING_SETUP,
+                    mParams->nan_pairing_config.enable_pairing_setup);
+            if (result < 0) {
+                ALOGE("%s: Failed to fill NAN_ATTRIBUTE_ENAB_PAIRING_SETUP, result = %d\n",
+                        __func__, result);
+                return result;
+            }
+
+            result = request.put_u32(NAN_ATTRIBUTE_ENAB_PAIRING_VERIFICATION,
+                    mParams->nan_pairing_config.enable_pairing_verification);
+            if (result < 0) {
+                ALOGE("%s: Failed to fill NAN_ATTRIBUTE_ENAB_PAIRING_VERIFICATION, result = %d\n",
+                        __func__, result);
+                return result;
+            }
+
+            result = request.put_u32(NAN_ATTRIBUTE_PAIRING_CACHE,
+                    mParams->nan_pairing_config.enable_pairing_cache);
+            if (result < 0) {
+                ALOGE("%s: Failed to fill NAN_ATTRIBUTE_PAIRING_CACHE, result = %d\n",
+                        __func__, result);
+                return result;
+            }
+
+            result = request.put_u16(NAN_ATTRIBUTE_BS_METHODS,
+                    mParams->nan_pairing_config.supported_bootstrapping_methods);
+            if (result < 0) {
+                ALOGE("%s: Failed to fill NAN_ATTRIBUTE_BS_METHODS, result = %d\n",
+                        __func__, result);
+                return result;
+            }
+        }
 
         request.attr_end(data);
 
@@ -1016,6 +2176,7 @@
          */
         mInstId = mParams->subscribe_id;
         nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
+        hal_info *h_info = getHalInfo(mIface);
 
         result = request.put_u16(NAN_ATTRIBUTE_SUBSCRIBE_ID, mInstId);
         if (result < 0) {
@@ -1087,7 +2248,12 @@
         }
 
         if (mParams->service_name_len) {
+            if (mParams->service_name_len > NAN_MAX_SERVICE_NAME_LEN) {
+                ALOGE("%s: Invalid svc len %d\n", __func__, mParams->service_name_len);
+                return WIFI_ERROR_INVALID_ARGS;
+            }
             u8 svc_hash[NAN_SVC_HASH_SIZE];
+
             result = get_svc_hash(mParams->service_name, mParams->service_name_len,
                     svc_hash, NAN_SVC_HASH_SIZE);
             if (result < 0) {
@@ -1100,8 +2266,7 @@
 
             result = request.put_u16(NAN_ATTRIBUTE_SERVICE_NAME_LEN, mParams->service_name_len);
             if (result < 0) {
-                ALOGE("%s: Failed to fill svc hash len, result = %d\n",
-                        __func__, result);
+                ALOGE("%s: Failed to fill svc hash len, result = %d\n", __func__, result);
                 return result;
             }
 
@@ -1114,6 +2279,11 @@
         }
 
         if (mParams->service_specific_info_len) {
+            if (mParams->service_specific_info_len > NAN_MAX_SVC_INFO_LEN) {
+                ALOGE("%s: Invalid svc info len = %d\n",
+                        __func__, mParams->service_specific_info_len);
+                return WIFI_ERROR_INVALID_ARGS;
+            }
             result = request.put_u16(NAN_ATTRIBUTE_SERVICE_SPECIFIC_INFO_LEN,
                     mParams->service_specific_info_len);
             if (result < 0) {
@@ -1130,6 +2300,11 @@
         }
 
         if (mParams->rx_match_filter_len) {
+            if (mParams->rx_match_filter_len > NAN_MAX_MATCH_FILTER_LEN) {
+                ALOGE("%s: Invalid rx match filter len = %d\n",
+                        __func__, mParams->rx_match_filter_len);
+                return WIFI_ERROR_INVALID_ARGS;
+            }
             result = request.put_u16(NAN_ATTRIBUTE_RX_MATCH_FILTER_LEN,
                     mParams->rx_match_filter_len);
             if (result < 0) {
@@ -1137,7 +2312,7 @@
                 return result;
             }
 
-            prhex(NULL, mParams->rx_match_filter, mParams->rx_match_filter_len);
+            prhex("rx match: ", mParams->rx_match_filter, mParams->rx_match_filter_len);
             result = request.put(NAN_ATTRIBUTE_RX_MATCH_FILTER,
                     (void *)mParams->rx_match_filter, mParams->rx_match_filter_len);
             if (result < 0) {
@@ -1147,6 +2322,11 @@
         }
 
         if (mParams->tx_match_filter_len) {
+            if (mParams->tx_match_filter_len > NAN_MAX_MATCH_FILTER_LEN) {
+                ALOGE("%s: Invalid tx match filter len = %d\n",
+                        __func__, mParams->tx_match_filter_len);
+                return WIFI_ERROR_INVALID_ARGS;
+            }
             result = request.put_u16(NAN_ATTRIBUTE_TX_MATCH_FILTER_LEN,
                     mParams->tx_match_filter_len);
             if (result < 0) {
@@ -1154,7 +2334,7 @@
                 return result;
             }
 
-            prhex(NULL, mParams->tx_match_filter, mParams->tx_match_filter_len);
+            prhex("tx match: ", mParams->tx_match_filter, mParams->tx_match_filter_len);
             result = request.put(NAN_ATTRIBUTE_TX_MATCH_FILTER,
                     (void *)mParams->tx_match_filter, mParams->tx_match_filter_len);
             if (result < 0) {
@@ -1176,8 +2356,6 @@
                 return result;
             }
 
-            prhex(NULL, (u8 *)mParams->intf_addr,
-                    (mParams->num_intf_addr_present * NAN_MAC_ADDR_LEN));
             result = request.put(NAN_ATTRIBUTE_MAC_ADDR_LIST, (void *)mParams->intf_addr,
                     (mParams->num_intf_addr_present * NAN_MAC_ADDR_LEN));
             if (result < 0) {
@@ -1210,12 +2388,17 @@
                 mParams->key_info.key_type);
         if (result < 0) {
             ALOGE("%s: Failed to fill NAN_ATTRIBUTE_KEY_TYPE, result = %d\n",
-                    __func__, result);
+                        __func__, result);
             return result;
         }
 
         if (mParams->key_info.key_type == NAN_SECURITY_KEY_INPUT_PMK) {
             if (mParams->key_info.body.pmk_info.pmk_len) {
+                if (mParams->key_info.body.pmk_info.pmk_len > NAN_PMK_INFO_LEN) {
+                    ALOGE("%s: Invalid pmk len len = %d\n",
+                            __func__, mParams->key_info.body.pmk_info.pmk_len);
+                    return WIFI_ERROR_INVALID_ARGS;
+                }
                 result = request.put_u32(NAN_ATTRIBUTE_KEY_LEN,
                         mParams->key_info.body.pmk_info.pmk_len);
                 if (result < 0) {
@@ -1298,7 +2481,8 @@
             result = request.put_u32(NAN_ATTRIBUTE_RANGING_INDICATION,
                     mParams->ranging_cfg.config_ranging_indications);
             if (result < 0) {
-                ALOGE("%s: Failed to fill config_ranging_indications, result = %d\n", __func__, result);
+                ALOGE("%s: Failed to fill config_ranging_indications, result = %d\n",
+                        __func__, result);
                 return result;
             }
 
@@ -1320,6 +2504,11 @@
         }
 
         if (mParams->sdea_service_specific_info_len) {
+            if (mParams->sdea_service_specific_info_len > NAN_MAX_SDEA_SERVICE_SPECIFIC_INFO_LEN) {
+                ALOGE("%s: Invalid sdea info len = %d\n",
+                        __func__, mParams->sdea_service_specific_info_len);
+                return WIFI_ERROR_INVALID_ARGS;
+            }
             result = request.put_u16(NAN_ATTRIBUTE_SDEA_SERVICE_SPECIFIC_INFO_LEN,
                     mParams->sdea_service_specific_info_len);
             if (result < 0) {
@@ -1327,22 +2516,72 @@
                 return result;
             }
 
-            prhex(NULL, mParams->sdea_service_specific_info, mParams->sdea_service_specific_info_len);
+            prhex("SDEA INFO: ", mParams->sdea_service_specific_info,
+                    mParams->sdea_service_specific_info_len);
             result = request.put(NAN_ATTRIBUTE_SDEA_SERVICE_SPECIFIC_INFO,
-                    (void *)mParams->sdea_service_specific_info, mParams->sdea_service_specific_info_len);
+                    (void *)mParams->sdea_service_specific_info,
+                    mParams->sdea_service_specific_info_len);
             if (result < 0) {
                 ALOGE("%s: Failed to fill sdea svc info, result = %d\n", __func__, result);
                 return result;
             }
         }
 
-        result = request.put_u8(NAN_ATTRIBUTE_SVC_CFG_SUPENDABLE, mParams->enable_suspendability);
-        if (result < 0) {
-            ALOGE("%s: Failed to fill NAN_ATTRIBUTE_SVC_CFG_SUPENDABLE, result = %d\n", __func__, result);
-            return result;
+        ALOGI("createSubscribeRequest: Cached pairing %d suspend %d, mode %d\n",
+                GET_NAN_PAIRING_CAP(h_info), GET_NAN_SUSPEND_CAP(h_info), get_halutil_mode());
+        if (get_halutil_mode() || GET_NAN_SUSPEND_CAP(h_info)) {
+            result = request.put_u8(NAN_ATTRIBUTE_SVC_CFG_SUPENDABLE,
+                    mParams->enable_suspendability);
+            if (result < 0) {
+                ALOGE("%s: Failed to fill NAN_ATTRIBUTE_SVC_CFG_SUPENDABLE, result = %d\n",
+                        __func__, result);
+                return result;
+            }
         }
-	/* To be removed */
-        ALOGE("Subscribe enable_suspendability=%u\n", mParams->enable_suspendability);
+
+        if (get_halutil_mode() || GET_NAN_PAIRING_CAP(h_info)) {
+            if (NIK_ISNULL(mParams->nan_identity_key)) {
+                ALOGI("NIK is NULL");
+            } else {
+                result = request.put(NAN_ATTRIBUTE_LOCAL_NIK, mParams->nan_identity_key,
+                        NAN_IDENTITY_KEY_LEN);
+                if (result < 0) {
+                    return result;
+                }
+            }
+
+            result = request.put_u32(NAN_ATTRIBUTE_ENAB_PAIRING_SETUP,
+                    mParams->nan_pairing_config.enable_pairing_setup);
+            if (result < 0) {
+                ALOGE("%s: Failed to fill NAN_ATTRIBUTE_ENAB_PAIRING_SETUP, result = %d\n",
+                        __func__, result);
+                return result;
+            }
+
+            result = request.put_u32(NAN_ATTRIBUTE_ENAB_PAIRING_VERIFICATION,
+                    mParams->nan_pairing_config.enable_pairing_verification);
+            if (result < 0) {
+                ALOGE("%s: Failed to fill NAN_ATTRIBUTE_ENAB_PAIRING_VERIFICATION, result = %d\n",
+                        __func__, result);
+                return result;
+            }
+
+            result = request.put_u32(NAN_ATTRIBUTE_PAIRING_CACHE,
+                    mParams->nan_pairing_config.enable_pairing_cache);
+            if (result < 0) {
+                ALOGE("%s: Failed to fill NAN_ATTRIBUTE_PAIRING_CACHE, result = %d\n",
+                        __func__, result);
+                return result;
+            }
+
+            result = request.put_u16(NAN_ATTRIBUTE_BS_METHODS,
+                    mParams->nan_pairing_config.supported_bootstrapping_methods);
+            if (result < 0) {
+                ALOGE("%s: Failed to fill NAN_ATTRIBUTE_BS_METHODS, result = %d\n",
+                        __func__, result);
+                return result;
+            }
+        }
 
         request.attr_end(data);
         NAN_DBG_EXIT();
@@ -1414,7 +2653,12 @@
             return result;
         }
 
-        if (mParams->service_specific_info_len > 0) {
+        if (mParams->service_specific_info_len) {
+            if (mParams->service_specific_info_len > NAN_MAX_SVC_INFO_LEN) {
+                ALOGE("%s: Invalid svc info len = %d\n",
+                        __func__, mParams->service_specific_info_len);
+                return WIFI_ERROR_INVALID_ARGS;
+            }
             result = request.put_u16(NAN_ATTRIBUTE_SERVICE_SPECIFIC_INFO_LEN,
                     mParams->service_specific_info_len);
             if (result < 0) {
@@ -1422,7 +2666,8 @@
                 return result;
             }
 
-            prhex(NULL, mParams->service_specific_info, mParams->service_specific_info_len);
+            prhex("service info: ", mParams->service_specific_info,
+                    mParams->service_specific_info_len);
             result = request.put(NAN_ATTRIBUTE_SERVICE_SPECIFIC_INFO,
                     (void *)mParams->service_specific_info, mParams->service_specific_info_len);
             if (result < 0) {
@@ -1451,6 +2696,11 @@
         }
 
         if (mParams->sdea_service_specific_info_len) {
+            if (mParams->sdea_service_specific_info_len > NAN_MAX_SDEA_SERVICE_SPECIFIC_INFO_LEN) {
+                ALOGE("%s: Invalid sdea info len = %d\n",
+                        __func__, mParams->sdea_service_specific_info_len);
+                return WIFI_ERROR_INVALID_ARGS;
+            }
             result = request.put_u16(NAN_ATTRIBUTE_SDEA_SERVICE_SPECIFIC_INFO_LEN,
                     mParams->sdea_service_specific_info_len);
             if (result < 0) {
@@ -1458,9 +2708,11 @@
                 return result;
             }
 
-            prhex(NULL, mParams->sdea_service_specific_info, mParams->sdea_service_specific_info_len);
+            prhex("SDEA INFO: ", mParams->sdea_service_specific_info,
+                    mParams->sdea_service_specific_info_len);
             result = request.put(NAN_ATTRIBUTE_SDEA_SERVICE_SPECIFIC_INFO,
-                    (void *)mParams->sdea_service_specific_info, mParams->sdea_service_specific_info_len);
+                    (void *)mParams->sdea_service_specific_info,
+                    mParams->sdea_service_specific_info_len);
             if (result < 0) {
                 ALOGE("%s: Failed to fill sdea svc info, result = %d\n", __func__, result);
                 return result;
@@ -1511,7 +2763,7 @@
 
     virtual bool valid_disc_response_type(int response_type) {
         bool valid = false;
-        switch(response_type) {
+        switch (response_type) {
             case NAN_RESPONSE_PUBLISH:
             case NAN_RESPONSE_SUBSCRIBE:
             case NAN_GET_CAPABILITIES:
@@ -1531,13 +2783,13 @@
     {
         nan_hal_resp_t *rsp_vndr_data = NULL;
         NanResponseMsg rsp_data;
-        u32 len;
+        hal_info *h_info = getHalInfo(mIface);
+
         if (reply.get_cmd() != NL80211_CMD_VENDOR || reply.get_vendor_data() == NULL) {
             ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());
             return NL_SKIP;
         }
         rsp_vndr_data = (nan_hal_resp_t *)reply.get_vendor_data();
-        len = reply.get_vendor_data_len();
         ALOGI("NanDiscEnginePrmitive::handle response\n");
         memset(&rsp_data, 0, sizeof(NanResponseMsg));
         rsp_data.response_type = get_response_type((WIFI_SUB_COMMAND)rsp_vndr_data->subcmd);
@@ -1589,7 +2841,22 @@
             desc->is_instant_mode_supported = src->is_instant_mode_supported;
             desc->ndpe_attr_supported = src->ndpe_attr_supported;
             desc->is_suspension_supported = src->is_suspension_supported;
-            ALOGE(" suspend capability %d \n", rsp_vndr_data->capabilities.is_suspension_supported); //Remove
+            /* Temporarily disable NAN pairing feature capability */
+            //desc->is_pairing_supported = src->is_pairing_supported;
+            ALOGI("Capabilities pairing %u, local pairing %u csid 0x%x", desc->is_pairing_supported,
+                    src->is_pairing_supported, desc->cipher_suites_supported);
+
+            if (!get_halutil_mode()) {
+                SET_NAN_SUSPEND_CAP(h_info, desc->is_suspension_supported);
+                SET_NAN_PAIRING_CAP(h_info, desc->is_pairing_supported);
+                ALOGI("Capabilities Cached pairing %d suspend %d\n", GET_NAN_PAIRING_CAP(h_info),
+                        GET_NAN_SUSPEND_CAP(h_info));
+
+                if (!id()) {
+                    ALOGE("Skip to send the nan cap cmd response, id() %d\n", id());
+                    return NL_SKIP;
+                }
+            }
         }
 
         GET_NAN_HANDLE(info)->mHandlers.NotifyResponse(id(), &rsp_data);
@@ -1626,7 +2893,7 @@
                         memcpy(pub_term_event.nan_reason, it.get_data(), len);
                         pub_term_event.nan_reason[len] = '\0';
                         ALOGI("pub termination reason: %s, len = %d\n",
-                            pub_term_event.nan_reason, len);
+                                pub_term_event.nan_reason, len);
                     } else {
                         ALOGE("Unknown attr: %u\n", attr_type);
                     }
@@ -1660,25 +2927,25 @@
                         subscribe_event.service_specific_info_len = it.get_u16();
                     } else if (attr_type == NAN_ATTRIBUTE_SERVICE_SPECIFIC_INFO) {
                         u16 len = min(subscribe_event.service_specific_info_len,
-                                      sizeof(subscribe_event.service_specific_info));
+                                  sizeof(subscribe_event.service_specific_info));
                         memcpy(subscribe_event.service_specific_info, it.get_data(), len);
                     } else if (attr_type == NAN_ATTRIBUTE_TX_MATCH_FILTER_LEN) {
                         subscribe_event.sdf_match_filter_len = it.get_u16();
                         ALOGI("sdf match filter length: %d\n",
-                            subscribe_event.sdf_match_filter_len);
+                                subscribe_event.sdf_match_filter_len);
                     } else if (attr_type == NAN_ATTRIBUTE_TX_MATCH_FILTER) {
                         u16 len = min(subscribe_event.sdf_match_filter_len,
-                                      sizeof(subscribe_event.sdf_match_filter));
+                                sizeof(subscribe_event.sdf_match_filter));
                         memcpy(subscribe_event.sdf_match_filter, it.get_data(), len);
                     } else if (attr_type == NAN_ATTRIBUTE_CIPHER_SUITE_TYPE) {
                         ALOGI("Peer Cipher suite type: %u", it.get_u8());
                         subscribe_event.peer_cipher_type = it.get_u8();
                     } else if (attr_type == NAN_ATTRIBUTE_SCID_LEN) {
                         ALOGI("scid length %d", it.get_u32());
-                        subscribe_event.scid_len= it.get_u32();
+                                subscribe_event.scid_len = it.get_u32();
                     } else if (attr_type == NAN_ATTRIBUTE_SCID) {
                         u16 len = min(subscribe_event.scid_len,
-                                      sizeof(subscribe_event.scid));
+                                sizeof(subscribe_event.scid));
                         memcpy(subscribe_event.scid, it.get_data(), len);
                     } else if (attr_type == NAN_ATTRIBUTE_RANGING_INDICATION) {
                         subscribe_event.range_info.ranging_event_type = it.get_u32();
@@ -1694,7 +2961,7 @@
                         subscribe_event.sdea_service_specific_info_len = it.get_u16();
                     } else if (attr_type == NAN_ATTRIBUTE_SDEA_SERVICE_SPECIFIC_INFO) {
                         u16 len = min(subscribe_event.sdea_service_specific_info_len,
-                                      sizeof(subscribe_event.sdea_service_specific_info));
+                                sizeof(subscribe_event.sdea_service_specific_info));
                         memcpy(subscribe_event.sdea_service_specific_info, it.get_data(), len);
                     } else if (attr_type == NAN_ATTRIBUTE_MATCH_OCCURRED_FLAG) {
                         ALOGI("match occurred flag: %u", it.get_u8());
@@ -1711,10 +2978,32 @@
                     } else if (attr_type == NAN_ATTRIBUTE_SDE_CONTROL_SECURITY) {
                         ALOGI("Security configuration: %u", it.get_u8());
                         subscribe_event.peer_sdea_params.security_cfg =
-                            (NanDataPathSecurityCfgStatus)it.get_u8();
+                                (NanDataPathSecurityCfgStatus)it.get_u8();
                     } else if (attr_type == NAN_ATTRIBUTE_SDE_CONTROL_RANGE_SUPPORT) {
                         ALOGI("Ranging report state: %u", it.get_u8());
                         subscribe_event.peer_sdea_params.range_report = (NanRangeReport)it.get_u8();
+                    } else if (attr_type == NAN_ATTRIBUTE_ENAB_PAIRING_SETUP) {
+                        ALOGI("Enabe pairing setup: %u", it.get_u32());
+                        subscribe_event.peer_pairing_config.enable_pairing_setup = it.get_u32();
+                    } else if (attr_type == NAN_ATTRIBUTE_ENAB_PAIRING_VERIFICATION) {
+                        ALOGI("Enabe pairing Verification: %u", it.get_u32());
+                        subscribe_event.peer_pairing_config.enable_pairing_verification =
+                                it.get_u32();
+                    } else if (attr_type == NAN_ATTRIBUTE_PAIRING_CACHE) {
+                        ALOGI("Enabe pairing cache: %u", it.get_u32());
+                        subscribe_event.peer_pairing_config.enable_pairing_cache = it.get_u32();
+                    } else if (attr_type == NAN_ATTRIBUTE_BS_METHODS) {
+                        ALOGI("Supported bootstrapping methods : %u", it.get_u16());
+                        subscribe_event.peer_pairing_config.supported_bootstrapping_methods =
+                                it.get_u32();
+
+                    } else if (attr_type == NAN_ATTRIBUTE_NIRA_TAG) {
+                        memcpy(subscribe_event.nira.tag, it.get_data(), NAN_IDENTITY_TAG_LEN);
+                        prhex("NIRA tag", subscribe_event.nira.tag, NAN_IDENTITY_TAG_LEN);
+
+                    } else if (attr_type == NAN_ATTRIBUTE_NIRA_NONCE) {
+                        memcpy(subscribe_event.nira.nonce, it.get_data(), NAN_IDENTITY_NONCE_LEN);
+                        prhex("NIRA nonce", subscribe_event.nira.nonce, NAN_IDENTITY_NONCE_LEN);
                     }
                 }
 
@@ -1743,7 +3032,7 @@
                         memcpy(sub_term_event.nan_reason, it.get_data(), len);
                         sub_term_event.nan_reason[len] = '\0';
                         ALOGI("sub termination nan reason: %s, len = %d\n",
-                            sub_term_event.nan_reason, len);
+                                sub_term_event.nan_reason, len);
                     } else {
                         ALOGI("Unknown attr: %d\n", attr_type);
                     }
@@ -1771,11 +3060,11 @@
                         followup_event.service_specific_info_len = it.get_u16();
                     } else if (attr_type == NAN_ATTRIBUTE_SERVICE_SPECIFIC_INFO) {
                         u16 len = min(followup_event.service_specific_info_len,
-                                      sizeof(followup_event.service_specific_info));
+                                sizeof(followup_event.service_specific_info));
                         memcpy(followup_event.service_specific_info, it.get_data(), len);
                     } else if (attr_type == NAN_ATTRIBUTE_SDEA_SERVICE_SPECIFIC_INFO) {
                         u16 len = min(followup_event.sdea_service_specific_info_len,
-                                      sizeof(followup_event.sdea_service_specific_info));
+                                sizeof(followup_event.sdea_service_specific_info));
                         memcpy(followup_event.sdea_service_specific_info, it.get_data(), len);
                     }
                 }
@@ -1798,7 +3087,7 @@
                         memcpy(followup_ind.nan_reason, it.get_data(), len);
                         followup_ind.nan_reason[len] = '\0';
                         ALOGI("nan transmit followup ind: reason: %s, len = %d\n",
-                            followup_ind.nan_reason, len);
+                                followup_ind.nan_reason, len);
                     }
                 }
                 GET_NAN_HANDLE(info)->mHandlers.EventTransmitFollowup(&followup_ind);
@@ -1899,7 +3188,7 @@
         /* Do not create interface if already exist. */
         if (if_nametoindex(iface_name)) {
             ALOGD("%s: if_nametoindex(%s) = %d already exists, skip create \n",
-                __FUNCTION__, iface_name, if_nametoindex(iface_name));
+                    __FUNCTION__, iface_name, if_nametoindex(iface_name));
             return WIFI_SUCCESS;
         }
 
@@ -1943,7 +3232,7 @@
         result = request.put_u32(NL80211_ATTR_IFINDEX, if_nametoindex(iface_name));
         if (result < 0) {
             ALOGE("failed to put NL80211_ATTR_IFINDEX = %d; result = %d",
-                if_nametoindex(iface_name), result);
+                    if_nametoindex(iface_name), result);
             return result;
         }
 
@@ -2042,6 +3331,11 @@
         }
 
         if (mParams->app_info.ndp_app_info_len) {
+            if (mParams->app_info.ndp_app_info_len > NAN_DP_MAX_APP_INFO_LEN) {
+                ALOGE("%s: Invalid ndp app_info len = %d\n",
+                        __func__, mParams->app_info.ndp_app_info_len);
+                return WIFI_ERROR_INVALID_ARGS;
+            }
             result = request.put_u16(NAN_ATTRIBUTE_SERVICE_SPECIFIC_INFO_LEN,
                     mParams->app_info.ndp_app_info_len);
             if (result < 0) {
@@ -2076,15 +3370,20 @@
 
 
         if (mParams->service_name_len) {
+            if (mParams->service_name_len > NAN_MAX_SERVICE_NAME_LEN) {
+                ALOGE("%s: Invalid svc name len = %d\n",
+                        __func__, mParams->service_name_len);
+                return WIFI_ERROR_INVALID_ARGS;
+            }
             result = request.put_u16(NAN_ATTRIBUTE_SERVICE_NAME_LEN, mParams->service_name_len);
             if (result < 0) {
                 ALOGE("%s: Failed to fill svc name len, result = %d\n", __func__, result);
                 return result;
             }
 
-            prhex(NULL, mParams->service_name, mParams->service_name_len);
+            prhex("SVC NAME: ", mParams->service_name, mParams->service_name_len);
             result = request.put(NAN_ATTRIBUTE_SERVICE_NAME, (void *)mParams->service_name,
-                    mParams->service_name_len);
+                        mParams->service_name_len);
             if (result < 0) {
                 ALOGE("%s: Failed to fill svc name, result = %d\n", __func__, result);
                 return result;
@@ -2093,6 +3392,12 @@
 
         if (mParams->key_info.key_type == NAN_SECURITY_KEY_INPUT_PMK) {
             if (mParams->key_info.body.pmk_info.pmk_len) {
+                if (mParams->key_info.body.pmk_info.pmk_len > NAN_PMK_INFO_LEN) {
+                    ALOGE("%s: Invalid pmk len len = %d\n",
+                            __func__, mParams->key_info.body.pmk_info.pmk_len);
+                    return WIFI_ERROR_INVALID_ARGS;
+                }
+
                 result = request.put_u32(NAN_ATTRIBUTE_KEY_LEN,
                         mParams->key_info.body.pmk_info.pmk_len);
                 if (result < 0) {
@@ -2121,7 +3426,8 @@
                 result = passphrase_to_pmk(mParams->peer_disc_mac_addr, mParams->cipher_type,
                         mParams->service_name, &mParams->key_info, pmk_hex);
                 if (result < 0) {
-                    ALOGE("%s: Failed to convert passphrase to key data, result = %d\n", __func__, result);
+                    ALOGE("%s: Failed to convert passphrase to key data, result = %d\n",
+                            __func__, result);
                     return result;
                 }
                 result = request.put_u32(NAN_ATTRIBUTE_KEY_LEN, NAN_PMK_INFO_LEN);
@@ -2134,7 +3440,6 @@
                     ALOGE("%s: Failed to fill passphrase, result = %d\n", __func__, result);
                     return result;
                 }
-                prhex("PMK", pmk_hex, NAN_PMK_INFO_LEN);
             }
         }
 
@@ -2162,7 +3467,7 @@
             result = request.put_u16(NAN_ATTRIBUTE_INST_ID, mParams->publish_subscribe_id);
             if (result < 0) {
                 ALOGE("%s: Failed to fill sub id = %d, result = %d\n",
-                    __func__, mParams->publish_subscribe_id, result);
+                        __func__, mParams->publish_subscribe_id, result);
                 return result;
             }
         }
@@ -2211,6 +3516,11 @@
         }
 
         if (mParams->app_info.ndp_app_info_len) {
+            if (mParams->app_info.ndp_app_info_len > NAN_DP_MAX_APP_INFO_LEN) {
+                ALOGE("%s: Invalid ndp app_info len = %d\n",
+                        __func__, mParams->app_info.ndp_app_info_len);
+                return WIFI_ERROR_INVALID_ARGS;
+            }
             result = request.put_u16(NAN_ATTRIBUTE_SERVICE_SPECIFIC_INFO_LEN,
                     mParams->app_info.ndp_app_info_len);
             if (result < 0) {
@@ -2251,13 +3561,18 @@
         }
 
         if (mParams->service_name_len) {
+            if (mParams->service_name_len > NAN_MAX_SERVICE_NAME_LEN) {
+                ALOGE("%s: Invalid svc name len = %d\n",
+                        __func__, mParams->service_name_len);
+                return WIFI_ERROR_INVALID_ARGS;
+            }
             result = request.put_u16(NAN_ATTRIBUTE_SERVICE_NAME_LEN, mParams->service_name_len);
             if (result < 0) {
                 ALOGE("%s: Failed to fill svc name len, result = %d\n", __func__, result);
                 return result;
             }
 
-            prhex(NULL, mParams->service_name, mParams->service_name_len);
+            prhex("SVC NAME: ", mParams->service_name, mParams->service_name_len);
             result = request.put(NAN_ATTRIBUTE_SERVICE_NAME, (void *)mParams->service_name,
                     mParams->service_name_len);
             if (result < 0) {
@@ -2268,6 +3583,11 @@
 
         if (mParams->key_info.key_type == NAN_SECURITY_KEY_INPUT_PMK) {
             if (mParams->key_info.body.pmk_info.pmk_len) {
+                if (mParams->key_info.body.pmk_info.pmk_len > NAN_PMK_INFO_LEN) {
+                    ALOGE("%s: Invalid pmk len len = %d\n",
+                            __func__, mParams->key_info.body.pmk_info.pmk_len);
+                    return WIFI_ERROR_INVALID_ARGS;
+                }
                 result = request.put_u32(NAN_ATTRIBUTE_KEY_LEN,
                         mParams->key_info.body.pmk_info.pmk_len);
                 if (result < 0) {
@@ -2296,7 +3616,8 @@
                 result = passphrase_to_pmk(mPubNmi, mParams->cipher_type,
                         mParams->service_name, &mParams->key_info, pmk_hex);
                 if (result < 0) {
-                    ALOGE("%s: Failed to convert passphrase to key data, result = %d\n", __func__, result);
+                    ALOGE("%s: Failed to convert passphrase to key data, result = %d\n",
+                            __func__, result);
                     return result;
                 }
                 result = request.put_u32(NAN_ATTRIBUTE_KEY_LEN, NAN_PMK_INFO_LEN);
@@ -2324,7 +3645,7 @@
                 return result;
             }
 
-            prhex(NULL, mParams->scid, mParams->scid_len);
+            prhex("SCID: ", mParams->scid, mParams->scid_len);
             result = request.put(NAN_ATTRIBUTE_SCID,
                     (void *)mParams->scid, mParams->scid_len);
             if (result < 0) {
@@ -2337,7 +3658,7 @@
             result = request.put_u16(NAN_ATTRIBUTE_INST_ID, mParams->publish_subscribe_id);
             if (result < 0) {
                 ALOGE("%s: Failed to fill sub id = %d, result = %d\n",
-                    __func__, mParams->publish_subscribe_id, result);
+                        __func__, mParams->publish_subscribe_id, result);
                 return result;
             }
         }
@@ -2404,13 +3725,12 @@
             /* Return success even for no dev case also, nothing to do */
             rsp_data.status = NAN_STATUS_SUCCESS;
             memcpy(rsp_data.nan_error, NanStatusToString(rsp_data.status),
-                strlen(NanStatusToString(rsp_data.status)));
+                    strlen(NanStatusToString(rsp_data.status)));
             rsp_data.nan_error[strlen(NanStatusToString(rsp_data.status))] = '\0';
             rsp_data.nan_error[NAN_ERROR_STR_LEN - 1] = '\0';
-            ALOGI("Mapped hal status = %d\n", rsp_data.status);
-            ALOGI("Received nan_error string %s\n", (u8*)rsp_data.nan_error);
+            ALOGI("hal status = %d, resp_string %s\n",
+                    rsp_data.status, (u8*)rsp_data.nan_error);
             GET_NAN_HANDLE(info)->mHandlers.NotifyResponse(id(), &rsp_data);
-            ALOGE("Notified by cmd ret!!");
         }
         request.destroy();
         return WIFI_SUCCESS;
@@ -2448,14 +3768,9 @@
               * mimicking the NanResponseMsg for iface create and delete nan cmds
               */
              rsp_data.response_type = get_response_type_frm_req_type((NanRequestType)mType);
-             /* Return success even for no dev case also, nothing to do */
-             if (result == WIFI_SUCCESS || result == WIFI_ERROR_NOT_AVAILABLE) {
-                 rsp_data.status = NAN_STATUS_SUCCESS;
-             } else {
-                 rsp_data.status = NAN_STATUS_INTERNAL_FAILURE;
-             }
+             rsp_data.status = NAN_STATUS_SUCCESS;
         } else if (reply.get_cmd() != NL80211_CMD_VENDOR ||
-                    reply.get_vendor_data() == NULL ||
+            reply.get_vendor_data() == NULL ||
                     reply.get_vendor_data_len() != sizeof(nan_hal_resp_t)) {
             ALOGD("Ignoring reply with cmd = %d mType = %d len = %d\n",
                     reply.get_cmd(), mType, reply.get_vendor_data_len());
@@ -2474,9 +3789,9 @@
 
             if (rsp_data.response_type == NAN_DP_INITIATOR_RESPONSE) {
                 ALOGI("received ndp instance_id %d and ret = %d\n",
-                    rsp_vndr_data->ndp_instance_id, result);
+                        rsp_vndr_data->ndp_instance_id, result);
                 rsp_data.body.data_request_response.ndp_instance_id =
-                    rsp_vndr_data->ndp_instance_id;
+                        rsp_vndr_data->ndp_instance_id;
                 mNdpId = rsp_vndr_data->ndp_instance_id;
             } else if ((WIFI_SUB_COMMAND)rsp_vndr_data->subcmd == NAN_SUBCMD_DATA_PATH_SEC_INFO) {
                 memcpy(mPubNmi, rsp_vndr_data->pub_nmi, NAN_MAC_ADDR_LEN);
@@ -2486,14 +3801,14 @@
         }
 
         memcpy(rsp_data.nan_error, NanStatusToString(rsp_data.status),
-            strlen(NanStatusToString(rsp_data.status)));
+                strlen(NanStatusToString(rsp_data.status)));
         rsp_data.nan_error[strlen(NanStatusToString(rsp_data.status))] = '\0';
         rsp_data.nan_error[NAN_ERROR_STR_LEN - 1] = '\0';
 
         ALOGI("Mapped hal status = %d\n", rsp_data.status);
         ALOGI("Received nan_error string %s\n", (u8*)rsp_data.nan_error);
         ALOGI("NanDataPathPrmitive:Received response for cmd [%s], ret %d\n",
-            NanRspToString(rsp_data.response_type), rsp_data.status);
+                NanRspToString(rsp_data.response_type), rsp_data.status);
         GET_NAN_HANDLE(info)->mHandlers.NotifyResponse(id(), &rsp_data);
         ALOGE("Notified by cmd reply!!");
         return NL_SKIP;
@@ -2536,7 +3851,7 @@
                         ALOGI("security: %u\n",
                                 (NanDataPathSecurityCfgStatus)it.get_u8());
                         ndp_request_event.ndp_cfg.security_cfg =
-                            (NanDataPathSecurityCfgStatus)it.get_u8();
+                                (NanDataPathSecurityCfgStatus)it.get_u8();
 
                     } else if (attr_type == NAN_ATTRIBUTE_QOS) {
                         ALOGI("QoS: %u\n", (NanDataPathQosCfg)it.get_u8());
@@ -2548,16 +3863,15 @@
 
                     } else if (attr_type == NAN_ATTRIBUTE_SERVICE_SPECIFIC_INFO) {
                         u16 len = min(ndp_ind_app_info_len,
-                                      sizeof(ndp_request_event.app_info.ndp_app_info));
+                                sizeof(ndp_request_event.app_info.ndp_app_info));
                         memcpy(ndp_request_event.app_info.ndp_app_info, it.get_data(), len);
-
                     } else if (attr_type == NAN_ATTRIBUTE_SCID_LEN) {
                         ALOGI("scid len: %u\n", it.get_u32());
                         ndp_request_event.scid_len = it.get_u32();
 
                     } else if (attr_type == NAN_ATTRIBUTE_SCID) {
                         u16 len = min(ndp_request_event.scid_len,
-                                      sizeof(ndp_request_event.scid));
+                                sizeof(ndp_request_event.scid));
                         memcpy(ndp_request_event.scid, it.get_data(), len);
                     }
                 }
@@ -2590,38 +3904,36 @@
                         ALOGI("service info len: %d", it.get_u16());
                         ndp_create_confirmation_event.app_info.ndp_app_info_len = it.get_u16();
                         ndp_conf_app_info_len =
-                            ndp_create_confirmation_event.app_info.ndp_app_info_len;
+                                ndp_create_confirmation_event.app_info.ndp_app_info_len;
                     } else if (attr_type == NAN_ATTRIBUTE_SERVICE_SPECIFIC_INFO) {
                         u16 len = min(ndp_conf_app_info_len,
-                                 sizeof(ndp_create_confirmation_event.app_info.ndp_app_info));
+                                sizeof(ndp_create_confirmation_event.app_info.ndp_app_info));
                         memcpy(ndp_create_confirmation_event.app_info.ndp_app_info,
                                 it.get_data(), len);
 
                     } else if (attr_type == NAN_ATTRIBUTE_RSP_CODE) {
                         ALOGI("response code: %u", (NanDataPathResponseCode)it.get_u8());
                         ndp_create_confirmation_event.rsp_code =
-                            (NanDataPathResponseCode)it.get_u8();
+                                (NanDataPathResponseCode)it.get_u8();
                     } else if (attr_type == NAN_ATTRIBUTE_STATUS) {
                         ALOGI("reason code %u", (NanDataPathResponseCode)it.get_u8());
                         ndp_create_confirmation_event.rsp_code =
-                            (NanDataPathResponseCode)it.get_u8();
+                                (NanDataPathResponseCode)it.get_u8();
                     } else if (attr_type == NAN_ATTRIBUTE_NUM_CHANNELS) {
                         ALOGI("num channels %u", it.get_u32());
                         if (it.get_u32() <= NAN_MAX_CHANNEL_INFO_SUPPORTED) {
                             ndp_create_confirmation_event.num_channels = it.get_u32();
                         } else {
                             ndp_create_confirmation_event.num_channels =
-                                NAN_MAX_CHANNEL_INFO_SUPPORTED;
+                                    NAN_MAX_CHANNEL_INFO_SUPPORTED;
                             ALOGE("num channels reset to max allowed %u",
-                                ndp_create_confirmation_event.num_channels);
+                                    ndp_create_confirmation_event.num_channels);
                         }
                     } else if (attr_type == NAN_ATTRIBUTE_CHANNEL_INFO) {
                         ALOGI("Channel info \n");
-                        u16 len = min(
-                            ndp_create_confirmation_event.num_channels * sizeof(NanChannelInfo),
-                            it.get_len());
-                        memcpy((u8 *)ndp_create_confirmation_event.channel_info,
-                            it.get_data(), len);
+                        u16 len = min(ndp_create_confirmation_event.num_channels * sizeof(NanChannelInfo),
+                                it.get_len());
+                        memcpy((u8 *)ndp_create_confirmation_event.channel_info, it.get_data(), len);
                         while (chan_idx < ndp_create_confirmation_event.num_channels) {
                             ALOGI("channel: %u, Bandwidth: %u, nss: %u\n",
                                 ndp_create_confirmation_event.channel_info[chan_idx].channel,
@@ -2640,14 +3952,14 @@
 
                 ndp_end_event =
                     (NanDataPathEndInd *)malloc(NAN_MAX_NDP_COUNT_SIZE +
-                    sizeof(ndp_end_event->num_ndp_instances));
+                            sizeof(ndp_end_event->num_ndp_instances));
                 if (!ndp_end_event) {
                     ALOGE("Failed to alloc for end request event\n");
                     break;
                 }
 
                 memset(ndp_end_event, 0, (NAN_MAX_NDP_COUNT_SIZE +
-                    sizeof(ndp_end_event->num_ndp_instances)));
+                        sizeof(ndp_end_event->num_ndp_instances)));
                 ALOGI("Received NAN_EVENT_DATA_END\n");
 
                 for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
@@ -2705,6 +4017,7 @@
         mVersion = 0;
         setIface(iface);
         setId(id);
+        mChreNan = 0;
     }
     ~NanMacControl() {
         ALOGE("NanMacControl destroyed\n");
@@ -3006,7 +4319,8 @@
         }
 
         if (mParams->config_dw.config_2dot4g_dw_band) {
-            result = request.put_u32(NAN_ATTRIBUTE_2G_AWAKE_DW, mParams->config_dw.dw_2dot4g_interval_val);
+            result = request.put_u32(NAN_ATTRIBUTE_2G_AWAKE_DW,
+                    mParams->config_dw.dw_2dot4g_interval_val);
             if (result < 0) {
                 ALOGE("%s: Failing in 2dot4g awake dw, result = %d\n", __func__, result);
                 return result;
@@ -3014,7 +4328,8 @@
         }
 
         if (mParams->config_dw.config_5g_dw_band) {
-            result = request.put_u32(NAN_ATTRIBUTE_5G_AWAKE_DW, mParams->config_dw.dw_5g_interval_val);
+            result = request.put_u32(NAN_ATTRIBUTE_5G_AWAKE_DW,
+                    mParams->config_dw.dw_5g_interval_val);
             if (result < 0) {
                 ALOGE("%s: Failing in 5g awake dw, result = %d\n", __func__, result);
                 return result;
@@ -3074,7 +4389,8 @@
             result = request.put_u32(NAN_ATTRIBUTE_RANDOMIZATION_INTERVAL,
                     mParams->disc_mac_addr_rand_interval_sec);
             if (result < 0) {
-                ALOGE("%s: Failing to fill rand mac address interval, result = %d\n", __func__, result);
+                ALOGE("%s: Failing to fill rand mac address interval, result = %d\n",
+                        __func__, result);
                 return result;
             }
         }
@@ -3296,14 +4612,15 @@
         }
 
         if (mParams->config_cluster_attribute_val) {
-            result = request.put_u8(NAN_ATTRIBUTE_CONF_CLUSTER_VAL, mParams->config_cluster_attribute_val);
+            result = request.put_u8(NAN_ATTRIBUTE_CONF_CLUSTER_VAL,
+                    mParams->config_cluster_attribute_val);
             if (result < 0) {
                 ALOGE("%s: Failing in config_cluster_attribute_val, result = %d\n", __func__, result);
                 return result;
             }
         }
 
-        if (mParams->config_fam) {
+        if (mParams->config_fam && (mParams->fam_val.numchans < NAN_MAX_FAM_CHANNELS)) {
             while (mParams->fam_val.numchans) {
                 result = request.put_u8(NAN_ATTRIBUTE_ENTRY_CONTROL,
                         mParams->fam_val.famchan[mParams->fam_val.numchans].entry_control);
@@ -3530,8 +4847,9 @@
             rsp_data.response_type = get_response_type((WIFI_SUB_COMMAND)rsp_vndr_data->subcmd);
             rsp_data.status = nan_map_response_status(rsp_vndr_data->status);
 
-            ALOGI("NanMacControl:Received response for cmd [%s], TxID %d ret %d\n",
-                    NanRspToString(rsp_data.response_type), id(), rsp_data.status);
+            ALOGI("NanMacControl:Received response [%s] for cmd [%d], TxID %d ret %d\n",
+                    NanRspToString(rsp_data.response_type), rsp_vndr_data->subcmd, id(),
+                    rsp_data.status);
 
             GET_NAN_HANDLE(info)->mHandlers.NotifyResponse(id(), &rsp_data);
         }
@@ -3541,13 +4859,15 @@
             rsp_data.response_type = get_response_type((WIFI_SUB_COMMAND)rsp_vndr_data->subcmd);
             rsp_data.status = nan_map_response_status(rsp_vndr_data->status);
 
-            ALOGI("NanMacControl:Received response for cmd [%s], TxID %d ret %d\n",
-                  NanRspToString(rsp_data.response_type), mId, rsp_data.status);
+            ALOGI("NanMacControl:Received response [%s] for cmd [%d], TxID %d ret %d\n",
+                    NanRspToString(rsp_data.response_type), rsp_vndr_data->subcmd, id(),
+                    rsp_data.status);
 
-            if( rsp_data.status != NAN_STATUS_SUCCESS) {
+            if (rsp_data.status != NAN_STATUS_SUCCESS) {
                 GET_NAN_HANDLE(info)->mHandlers.NotifyResponse(mId, &rsp_data);
             }
         }
+
         if ((rsp_vndr_data->subcmd == NAN_SUBCMD_SUSPEND) ||
                 (rsp_vndr_data->subcmd == NAN_SUBCMD_RESUME)) {
             NanResponseMsg rsp_data;
@@ -3555,10 +4875,13 @@
             rsp_data.response_type = get_response_type((WIFI_SUB_COMMAND)rsp_vndr_data->subcmd);
             rsp_data.status = (NanStatusType)rsp_vndr_data->status;
 
-            ALOGI("NanMacControl:Received response for cmd [%s], TxID %d ret %d\n",
-                    NanRspToString(rsp_data.response_type), id(), rsp_data.status);
+            ALOGI("NanMacControl:Received response [%s] for cmd [%d], TxID %d ret %d\n",
+	            NanRspToString(rsp_data.response_type), rsp_vndr_data->subcmd, id(),
+                    rsp_data.status);
 
-            GET_NAN_HANDLE(info)->mHandlers.NotifyResponse(id(), &rsp_data);
+            if (rsp_data.status != NAN_STATUS_SUCCESS) {
+                GET_NAN_HANDLE(info)->mHandlers.NotifyResponse(id(), &rsp_data);
+            }
         }
         return NL_SKIP;
     }
@@ -3614,9 +4937,7 @@
 
         for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
             attr_type = it.get_type();
-
-            if (it.get_type() == NAN_ATTRIBUTE_HANDLE) {
-            } else if (it.get_type() == NAN_ATTRIBUTE_NDP_ID) {
+            if (it.get_type() == NAN_ATTRIBUTE_NDP_ID) {
                 ndp_instance_id = it.get_u32();
                 ALOGI("handleEvent: ndp_instance_id = [%d]\n", ndp_instance_id);
             } else if (attr_type == NAN_ATTRIBUTE_CMD_RESP_DATA) {
@@ -3646,7 +4967,7 @@
         } else if (is_dp_event(event_id)) {
 
             NanDataPathPrimitive *dp_prim =
-                (NanDataPathPrimitive *)(info.nan_dp_control);
+                    (NanDataPathPrimitive *)(info.nan_dp_control);
             ALOGI("ndp_instance_id = [%d]\n", ndp_instance_id);
             if (dp_prim != NULL) {
                 dp_prim->handleEvent(event);
@@ -3654,6 +4975,16 @@
                 ALOGE("%s: dp_primitive is no more available\n", __func__);
             }
             return NL_SKIP;
+        } else if (is_pairing_event(event_id)) {
+
+            NanPairingPrimitive *pairing_prim =
+                (NanPairingPrimitive *)(info.nan_pairing_control);
+            if (pairing_prim != NULL) {
+                pairing_prim->handleEvent(event);
+            } else {
+                ALOGE("%s: pairing_primitive is no more available\n", __func__);
+            }
+            return NL_SKIP;
         } else {
             if (is_cmd_response(event_id)) {
                 ALOGE("Handling cmd response asynchronously\n");
@@ -3666,7 +4997,7 @@
             }
         }
 
-        switch(event_id) {
+        switch (event_id) {
             case NAN_EVENT_DE_EVENT:
                 NanDiscEngEventInd de_event;
                 memset(&de_event, 0, sizeof(de_event));
@@ -3742,7 +5073,7 @@
                         memcpy(disabled_ind.nan_reason, it.get_data(), len);
                         disabled_ind.nan_reason[len] = '\0';
                         ALOGI("Disabled nan reason: %s, len = %d\n",
-                            disabled_ind.nan_reason, len);
+                                disabled_ind.nan_reason, len);
                     }
                 }
 
@@ -3813,6 +5144,10 @@
         unregisterVendorHandler(GOOGLE_OUI, NAN_ASYNC_RESPONSE_DISABLED);
         unregisterVendorHandler(GOOGLE_OUI, NAN_EVENT_MATCH_EXPIRY);
         unregisterVendorHandler(GOOGLE_OUI, NAN_EVENT_SUSPENSION_STATUS);
+        unregisterVendorHandler(GOOGLE_OUI, NAN_EVENT_BOOTSTRAPPING_REQUEST);
+        unregisterVendorHandler(GOOGLE_OUI, NAN_EVENT_BOOTSTRAPPING_CONFIRMATION);
+        unregisterVendorHandler(GOOGLE_OUI, NAN_EVENT_PAIRING_REQUEST);
+        unregisterVendorHandler(GOOGLE_OUI, NAN_EVENT_PAIRING_CONFIRMATION);
     }
     void registerNanVendorEvents()
     {
@@ -3823,71 +5158,39 @@
         registerVendorHandler(GOOGLE_OUI, NAN_ASYNC_RESPONSE_DISABLED);
         registerVendorHandler(GOOGLE_OUI, NAN_EVENT_MATCH_EXPIRY);
         registerVendorHandler(GOOGLE_OUI, NAN_EVENT_SUSPENSION_STATUS);
+        registerVendorHandler(GOOGLE_OUI, NAN_EVENT_BOOTSTRAPPING_REQUEST);
+        registerVendorHandler(GOOGLE_OUI, NAN_EVENT_BOOTSTRAPPING_CONFIRMATION);
+        registerVendorHandler(GOOGLE_OUI, NAN_EVENT_PAIRING_REQUEST);
+        registerVendorHandler(GOOGLE_OUI, NAN_EVENT_PAIRING_CONFIRMATION);
     }
 };
 
-/* pretty hex print a contiguous buffer */
-static void prhex(const char *msg, u8 *buf, u32 nbytes)
-{
-    char line[128];
-    char *p;
-    int len = sizeof(line);
-    int nchar;
-    u32 i;
-
-    if (msg && (msg[0] != '\0')) {
-        printf("%s:\n", msg);
-    }
-
-    p = line;
-    for (i = 0; i < nbytes; i++) {
-        if (i % 16 == 0) {
-            nchar = snprintf(p, len, "  %04d: ", i);    /* line prefix */
-            p += nchar;
-            len -= nchar;
-        }
-
-        if (len > 0) {
-            nchar = snprintf(p, len, "%02x ", buf[i]);
-            p += nchar;
-            len -= nchar;
-        }
-
-        if (i % 16 == 15) {
-            ALOGE("%s\n", line);       /* flush line */
-            p = line;
-            len = sizeof(line);
-        }
-    }
-
-    /* flush last partial line */
-    if (p != line) {
-        ALOGE("%s\n", line);
-    }
-}
-
-
 static const char *NanRspToString(int cmd_resp)
 {
     switch (cmd_resp) {
         C2S(NAN_RESPONSE_ENABLED)
-            C2S(NAN_RESPONSE_DISABLED)
-            C2S(NAN_RESPONSE_PUBLISH)
-            C2S(NAN_RESPONSE_SUBSCRIBE)
-            C2S(NAN_RESPONSE_PUBLISH_CANCEL)
-            C2S(NAN_RESPONSE_SUBSCRIBE_CANCEL)
-            C2S(NAN_RESPONSE_TRANSMIT_FOLLOWUP)
-            C2S(NAN_RESPONSE_CONFIG)
-            C2S(NAN_RESPONSE_TCA)
-            C2S(NAN_RESPONSE_STATS)
-            C2S(NAN_DP_INTERFACE_CREATE)
-            C2S(NAN_DP_INTERFACE_DELETE)
-            C2S(NAN_DP_INITIATOR_RESPONSE)
-            C2S(NAN_DP_RESPONDER_RESPONSE)
-            C2S(NAN_DP_END)
-            C2S(NAN_GET_CAPABILITIES)
-            C2S(NAN_SUSPEND_REQUEST_RESPONSE)
-            C2S(NAN_RESUME_REQUEST_RESPONSE)
+        C2S(NAN_RESPONSE_DISABLED)
+        C2S(NAN_RESPONSE_PUBLISH)
+        C2S(NAN_RESPONSE_SUBSCRIBE)
+        C2S(NAN_RESPONSE_PUBLISH_CANCEL)
+        C2S(NAN_RESPONSE_SUBSCRIBE_CANCEL)
+        C2S(NAN_RESPONSE_TRANSMIT_FOLLOWUP)
+        C2S(NAN_RESPONSE_CONFIG)
+        C2S(NAN_RESPONSE_TCA)
+        C2S(NAN_RESPONSE_STATS)
+        C2S(NAN_DP_INTERFACE_CREATE)
+        C2S(NAN_DP_INTERFACE_DELETE)
+        C2S(NAN_DP_INITIATOR_RESPONSE)
+        C2S(NAN_DP_RESPONDER_RESPONSE)
+        C2S(NAN_DP_END)
+        C2S(NAN_GET_CAPABILITIES)
+        C2S(NAN_SUSPEND_REQUEST_RESPONSE)
+        C2S(NAN_RESUME_REQUEST_RESPONSE)
+        C2S(NAN_PAIRING_INITIATOR_RESPONSE)
+        C2S(NAN_PAIRING_RESPONDER_RESPONSE)
+        C2S(NAN_PAIRING_END)
+        C2S(NAN_BOOTSTRAPPING_INITIATOR_RESPONSE)
+        C2S(NAN_BOOTSTRAPPING_RESPONDER_RESPONSE)
 
         default:
             return "UNKNOWN_NAN_CMD_RESPONSE";
@@ -3898,27 +5201,33 @@
 {
     switch (cmd) {
         C2S(NAN_REQUEST_ENABLE)
-            C2S(NAN_REQUEST_DISABLE)
-            C2S(NAN_REQUEST_PUBLISH)
-            C2S(NAN_REQUEST_PUBLISH_CANCEL)
-            C2S(NAN_REQUEST_TRANSMIT_FOLLOWUP)
-            C2S(NAN_REQUEST_SUBSCRIBE)
-            C2S(NAN_REQUEST_SUBSCRIBE_CANCEL)
-            C2S(NAN_REQUEST_STATS)
-            C2S(NAN_REQUEST_CONFIG)
-            C2S(NAN_REQUEST_TCA)
-            C2S(NAN_REQUEST_EVENT_CHECK)
-            C2S(NAN_REQUEST_GET_CAPABILTIES)
-            C2S(NAN_DATA_PATH_IFACE_CREATE)
-            C2S(NAN_DATA_PATH_IFACE_DELETE)
-            C2S(NAN_DATA_PATH_INIT_REQUEST)
-            C2S(NAN_DATA_PATH_IND_RESPONSE)
-            C2S(NAN_DATA_PATH_END)
-            C2S(NAN_DATA_PATH_IFACE_UP)
-            C2S(NAN_DATA_PATH_SEC_INFO)
-            C2S(NAN_VERSION_INFO)
-            C2S(NAN_REQUEST_SUSPEND)
-            C2S(NAN_REQUEST_RESUME)
+        C2S(NAN_REQUEST_DISABLE)
+        C2S(NAN_REQUEST_PUBLISH)
+        C2S(NAN_REQUEST_PUBLISH_CANCEL)
+        C2S(NAN_REQUEST_TRANSMIT_FOLLOWUP)
+        C2S(NAN_REQUEST_SUBSCRIBE)
+        C2S(NAN_REQUEST_SUBSCRIBE_CANCEL)
+        C2S(NAN_REQUEST_STATS)
+        C2S(NAN_REQUEST_CONFIG)
+        C2S(NAN_REQUEST_TCA)
+        C2S(NAN_REQUEST_EVENT_CHECK)
+        C2S(NAN_REQUEST_GET_CAPABILTIES)
+        C2S(NAN_DATA_PATH_IFACE_CREATE)
+        C2S(NAN_DATA_PATH_IFACE_DELETE)
+        C2S(NAN_DATA_PATH_INIT_REQUEST)
+        C2S(NAN_DATA_PATH_IND_RESPONSE)
+        C2S(NAN_DATA_PATH_END)
+        C2S(NAN_DATA_PATH_IFACE_UP)
+        C2S(NAN_DATA_PATH_SEC_INFO)
+        C2S(NAN_VERSION_INFO)
+        C2S(NAN_REQUEST_SUSPEND)
+        C2S(NAN_REQUEST_RESUME)
+        C2S(NAN_PAIRING_REQUEST)
+        C2S(NAN_PAIRING_IND_RESPONSE)
+        C2S(NAN_PAIRING_END_REQUEST)
+        C2S(NAN_BOOTSTRAPPING_REQUEST)
+        C2S(NAN_BOOTSTRAPPING_IND_RESPONSE)
+
         default:
             return "UNKNOWN_NAN_CMD";
     }
@@ -3928,83 +5237,97 @@
 {
     switch (cmd) {
         C2S(NAN_ATTRIBUTE_HEADER)
-            C2S(NAN_ATTRIBUTE_HANDLE)
-            C2S(NAN_ATTRIBUTE_TRANSAC_ID)
-            C2S(NAN_ATTRIBUTE_5G_SUPPORT)
-            C2S(NAN_ATTRIBUTE_CLUSTER_LOW)
-            C2S(NAN_ATTRIBUTE_CLUSTER_HIGH)
-            C2S(NAN_ATTRIBUTE_SID_BEACON)
-            C2S(NAN_ATTRIBUTE_SYNC_DISC_5G_BEACON)
-            C2S(NAN_ATTRIBUTE_RSSI_CLOSE)
-            C2S(NAN_ATTRIBUTE_RSSI_MIDDLE)
-            C2S(NAN_ATTRIBUTE_RSSI_PROXIMITY)
-            C2S(NAN_ATTRIBUTE_HOP_COUNT_LIMIT)
-            C2S(NAN_ATTRIBUTE_RANDOM_FACTOR)
-            C2S(NAN_ATTRIBUTE_MASTER_PREF)
-            C2S(NAN_ATTRIBUTE_PERIODIC_SCAN_INTERVAL)
-            C2S(NAN_ATTRIBUTE_PUBLISH_ID)
-            C2S(NAN_ATTRIBUTE_TTL)
-            C2S(NAN_ATTRIBUTE_PERIOD)
-            C2S(NAN_ATTRIBUTE_REPLIED_EVENT_FLAG)
-            C2S(NAN_ATTRIBUTE_PUBLISH_TYPE)
-            C2S(NAN_ATTRIBUTE_TX_TYPE)
-            C2S(NAN_ATTRIBUTE_PUBLISH_COUNT)
-            C2S(NAN_ATTRIBUTE_SERVICE_NAME_LEN)
-            C2S(NAN_ATTRIBUTE_SERVICE_NAME)
-            C2S(NAN_ATTRIBUTE_SERVICE_SPECIFIC_INFO_LEN)
-            C2S(NAN_ATTRIBUTE_SERVICE_SPECIFIC_INFO)
-            C2S(NAN_ATTRIBUTE_RX_MATCH_FILTER_LEN)
-            C2S(NAN_ATTRIBUTE_RX_MATCH_FILTER)
-            C2S(NAN_ATTRIBUTE_TX_MATCH_FILTER_LEN)
-            C2S(NAN_ATTRIBUTE_TX_MATCH_FILTER)
-            C2S(NAN_ATTRIBUTE_SUBSCRIBE_ID)
-            C2S(NAN_ATTRIBUTE_SUBSCRIBE_TYPE)
-            C2S(NAN_ATTRIBUTE_SERVICERESPONSEFILTER)
-            C2S(NAN_ATTRIBUTE_SERVICERESPONSEINCLUDE)
-            C2S(NAN_ATTRIBUTE_USESERVICERESPONSEFILTER)
-            C2S(NAN_ATTRIBUTE_SSIREQUIREDFORMATCHINDICATION)
-            C2S(NAN_ATTRIBUTE_SUBSCRIBE_MATCH)
-            C2S(NAN_ATTRIBUTE_SUBSCRIBE_COUNT)
-            C2S(NAN_ATTRIBUTE_MAC_ADDR)
-            C2S(NAN_ATTRIBUTE_MAC_ADDR_LIST)
-            C2S(NAN_ATTRIBUTE_MAC_ADDR_LIST_NUM_ENTRIES)
-            C2S(NAN_ATTRIBUTE_PUBLISH_MATCH)
-            C2S(NAN_ATTRIBUTE_ENABLE_STATUS)
-            C2S(NAN_ATTRIBUTE_JOIN_STATUS)
-            C2S(NAN_ATTRIBUTE_ROLE)
-            C2S(NAN_ATTRIBUTE_MASTER_RANK)
-            C2S(NAN_ATTRIBUTE_ANCHOR_MASTER_RANK)
-            C2S(NAN_ATTRIBUTE_CNT_PEND_TXFRM)
-            C2S(NAN_ATTRIBUTE_CNT_BCN_TX)
-            C2S(NAN_ATTRIBUTE_CNT_BCN_RX)
-            C2S(NAN_ATTRIBUTE_CNT_SVC_DISC_TX)
-            C2S(NAN_ATTRIBUTE_CNT_SVC_DISC_RX)
-            C2S(NAN_ATTRIBUTE_AMBTT)
-            C2S(NAN_ATTRIBUTE_CLUSTER_ID)
-            C2S(NAN_ATTRIBUTE_INST_ID)
-            C2S(NAN_ATTRIBUTE_OUI)
-            C2S(NAN_ATTRIBUTE_STATUS)
-            C2S(NAN_ATTRIBUTE_DE_EVENT_TYPE)
-            C2S(NAN_ATTRIBUTE_MERGE)
-            C2S(NAN_ATTRIBUTE_IFACE)
-            C2S(NAN_ATTRIBUTE_CHANNEL)
-            C2S(NAN_ATTRIBUTE_PEER_ID)
-            C2S(NAN_ATTRIBUTE_NDP_ID)
-            C2S(NAN_ATTRIBUTE_SECURITY)
-            C2S(NAN_ATTRIBUTE_QOS)
-            C2S(NAN_ATTRIBUTE_RSP_CODE)
-            C2S(NAN_ATTRIBUTE_INST_COUNT)
-            C2S(NAN_ATTRIBUTE_PEER_DISC_MAC_ADDR)
-            C2S(NAN_ATTRIBUTE_PEER_NDI_MAC_ADDR)
-            C2S(NAN_ATTRIBUTE_IF_ADDR)
-            C2S(NAN_ATTRIBUTE_WARMUP_TIME)
-            C2S(NAN_ATTRIBUTE_RANGING_RESULT)
-            C2S(NAN_ATTRIBUTE_RANGING_INDICATION)
-            C2S(NAN_ATTRIBUTE_SDEA_SERVICE_SPECIFIC_INFO_LEN)
-            C2S(NAN_ATTRIBUTE_SDEA_SERVICE_SPECIFIC_INFO)
-            C2S(NAN_ATTRIBUTE_RANDOMIZATION_INTERVAL)
-            C2S(NAN_ATTRIBUTE_ENABLE_MERGE)
-            C2S(NAN_ATTRIBUTE_SVC_CFG_SUPENDABLE)
+        C2S(NAN_ATTRIBUTE_HANDLE)
+        C2S(NAN_ATTRIBUTE_TRANSAC_ID)
+        C2S(NAN_ATTRIBUTE_5G_SUPPORT)
+        C2S(NAN_ATTRIBUTE_CLUSTER_LOW)
+        C2S(NAN_ATTRIBUTE_CLUSTER_HIGH)
+        C2S(NAN_ATTRIBUTE_SID_BEACON)
+        C2S(NAN_ATTRIBUTE_SYNC_DISC_5G_BEACON)
+        C2S(NAN_ATTRIBUTE_RSSI_CLOSE)
+        C2S(NAN_ATTRIBUTE_RSSI_MIDDLE)
+        C2S(NAN_ATTRIBUTE_RSSI_PROXIMITY)
+        C2S(NAN_ATTRIBUTE_HOP_COUNT_LIMIT)
+        C2S(NAN_ATTRIBUTE_RANDOM_FACTOR)
+        C2S(NAN_ATTRIBUTE_MASTER_PREF)
+        C2S(NAN_ATTRIBUTE_PERIODIC_SCAN_INTERVAL)
+        C2S(NAN_ATTRIBUTE_PUBLISH_ID)
+        C2S(NAN_ATTRIBUTE_TTL)
+        C2S(NAN_ATTRIBUTE_PERIOD)
+        C2S(NAN_ATTRIBUTE_REPLIED_EVENT_FLAG)
+        C2S(NAN_ATTRIBUTE_PUBLISH_TYPE)
+        C2S(NAN_ATTRIBUTE_TX_TYPE)
+        C2S(NAN_ATTRIBUTE_PUBLISH_COUNT)
+        C2S(NAN_ATTRIBUTE_SERVICE_NAME_LEN)
+        C2S(NAN_ATTRIBUTE_SERVICE_NAME)
+        C2S(NAN_ATTRIBUTE_SERVICE_SPECIFIC_INFO_LEN)
+        C2S(NAN_ATTRIBUTE_SERVICE_SPECIFIC_INFO)
+        C2S(NAN_ATTRIBUTE_RX_MATCH_FILTER_LEN)
+        C2S(NAN_ATTRIBUTE_RX_MATCH_FILTER)
+        C2S(NAN_ATTRIBUTE_TX_MATCH_FILTER_LEN)
+        C2S(NAN_ATTRIBUTE_TX_MATCH_FILTER)
+        C2S(NAN_ATTRIBUTE_SUBSCRIBE_ID)
+        C2S(NAN_ATTRIBUTE_SUBSCRIBE_TYPE)
+        C2S(NAN_ATTRIBUTE_SERVICERESPONSEFILTER)
+        C2S(NAN_ATTRIBUTE_SERVICERESPONSEINCLUDE)
+        C2S(NAN_ATTRIBUTE_USESERVICERESPONSEFILTER)
+        C2S(NAN_ATTRIBUTE_SSIREQUIREDFORMATCHINDICATION)
+        C2S(NAN_ATTRIBUTE_SUBSCRIBE_MATCH)
+        C2S(NAN_ATTRIBUTE_SUBSCRIBE_COUNT)
+        C2S(NAN_ATTRIBUTE_MAC_ADDR)
+        C2S(NAN_ATTRIBUTE_MAC_ADDR_LIST)
+        C2S(NAN_ATTRIBUTE_MAC_ADDR_LIST_NUM_ENTRIES)
+        C2S(NAN_ATTRIBUTE_PUBLISH_MATCH)
+        C2S(NAN_ATTRIBUTE_ENABLE_STATUS)
+        C2S(NAN_ATTRIBUTE_JOIN_STATUS)
+        C2S(NAN_ATTRIBUTE_ROLE)
+        C2S(NAN_ATTRIBUTE_MASTER_RANK)
+        C2S(NAN_ATTRIBUTE_ANCHOR_MASTER_RANK)
+        C2S(NAN_ATTRIBUTE_CNT_PEND_TXFRM)
+        C2S(NAN_ATTRIBUTE_CNT_BCN_TX)
+        C2S(NAN_ATTRIBUTE_CNT_BCN_RX)
+        C2S(NAN_ATTRIBUTE_CNT_SVC_DISC_TX)
+        C2S(NAN_ATTRIBUTE_CNT_SVC_DISC_RX)
+        C2S(NAN_ATTRIBUTE_AMBTT)
+        C2S(NAN_ATTRIBUTE_CLUSTER_ID)
+        C2S(NAN_ATTRIBUTE_INST_ID)
+        C2S(NAN_ATTRIBUTE_OUI)
+        C2S(NAN_ATTRIBUTE_STATUS)
+        C2S(NAN_ATTRIBUTE_DE_EVENT_TYPE)
+        C2S(NAN_ATTRIBUTE_MERGE)
+        C2S(NAN_ATTRIBUTE_IFACE)
+        C2S(NAN_ATTRIBUTE_CHANNEL)
+        C2S(NAN_ATTRIBUTE_PEER_ID)
+        C2S(NAN_ATTRIBUTE_NDP_ID)
+        C2S(NAN_ATTRIBUTE_SECURITY)
+        C2S(NAN_ATTRIBUTE_QOS)
+        C2S(NAN_ATTRIBUTE_RSP_CODE)
+        C2S(NAN_ATTRIBUTE_INST_COUNT)
+        C2S(NAN_ATTRIBUTE_PEER_DISC_MAC_ADDR)
+        C2S(NAN_ATTRIBUTE_PEER_NDI_MAC_ADDR)
+        C2S(NAN_ATTRIBUTE_IF_ADDR)
+        C2S(NAN_ATTRIBUTE_WARMUP_TIME)
+        C2S(NAN_ATTRIBUTE_RANGING_RESULT)
+        C2S(NAN_ATTRIBUTE_RANGING_INDICATION)
+        C2S(NAN_ATTRIBUTE_SDEA_SERVICE_SPECIFIC_INFO_LEN)
+        C2S(NAN_ATTRIBUTE_SDEA_SERVICE_SPECIFIC_INFO)
+        C2S(NAN_ATTRIBUTE_RANDOMIZATION_INTERVAL)
+        C2S(NAN_ATTRIBUTE_ENABLE_MERGE)
+        C2S(NAN_ATTRIBUTE_SVC_CFG_SUPENDABLE)
+        C2S(NAN_ATTRIBUTE_REQUEST_TYPE)
+        C2S(NAN_ATTRIBUTE_AKM)
+        C2S(NAN_ATTRIBUTE_PAIRING_CACHE)
+        C2S(NAN_ATTRIBUTE_OPPURTUNISTIC)
+        C2S(NAN_ATTRIBUTE_COOKIE_LEN)
+        C2S(NAN_ATTRIBUTE_COOKIE)
+        C2S(NAN_ATTRIBUTE_COME_BACK_DELAY)
+        C2S(NAN_ATTRIBUTE_NIRA_NONCE)
+        C2S(NAN_ATTRIBUTE_NIRA_TAG)
+        C2S(NAN_ATTRIBUTE_PEER_NIK)
+        C2S(NAN_ATTRIBUTE_LOCAL_NIK)
+        C2S(NAN_ATTRIBUTE_ENAB_PAIRING_SETUP)
+        C2S(NAN_ATTRIBUTE_ENAB_PAIRING_VERIFICATION)
+        C2S(NAN_ATTRIBUTE_BS_METHODS)
 
         default:
             return "NAN_ATTRIBUTE_UNKNOWN";
@@ -4070,6 +5393,21 @@
         case NAN_SUBCMD_RESUME:
             response_type = NAN_RESUME_REQUEST_RESPONSE;
             break;
+        case NAN_SUBCMD_PAIRING_REQUEST:
+            response_type = NAN_PAIRING_INITIATOR_RESPONSE;
+            break;
+        case NAN_SUBCMD_PAIRING_RESPONSE:
+            response_type = NAN_PAIRING_RESPONDER_RESPONSE;
+            break;
+        case NAN_SUBCMD_PAIRING_END:
+            response_type = NAN_PAIRING_END;
+            break;
+        case NAN_SUBCMD_BOOTSTRAPPING_REQUEST:
+            response_type = NAN_BOOTSTRAPPING_INITIATOR_RESPONSE;
+            break;
+        case NAN_SUBCMD_BOOTSTRAPPING_RESPONSE:
+            response_type = NAN_BOOTSTRAPPING_RESPONDER_RESPONSE;
+            break;
         default:
             /* unknown response for a command */
             response_type = NAN_RESPONSE_ERROR;
@@ -4132,6 +5470,7 @@
     return WIFI_SUCCESS;
 }
 
+#ifdef CONFIG_BRCM
 static int dump_NanEnableRequest(NanEnableRequest* msg)
 {
     ALOGI("%s: Dump NanEnableRequest msg:\n", __func__);
@@ -4237,7 +5576,6 @@
     return WIFI_SUCCESS;
 }
 
-#ifdef CONFIG_BRCM
 static int dump_NanConfigRequestRequest(NanConfigRequest* msg)
 {
     ALOGI("%s: Dump NanConfigRequest msg:\n", __func__);
@@ -4264,7 +5602,8 @@
     ALOGI("fam_val.famchan[0].class_val=%u\n", msg->fam_val.famchan[0].class_val);
     ALOGI("fam_val.famchan[0].channel=%u\n", msg->fam_val.famchan[0].channel);
     ALOGI("fam_val.famchan[0].mapid=%u\n", msg->fam_val.famchan[0].mapid);
-    ALOGI("fam_val.famchan[0].avail_interval_bitmap=%u\n", msg->fam_val.famchan[0].avail_interval_bitmap);
+    ALOGI("fam_val.famchan[0].avail_interval_bitmap=%u\n",
+            msg->fam_val.famchan[0].avail_interval_bitmap);
     ALOGI("config_dw.config_2dot4g_dw_band=%u\n", msg->config_dw.config_2dot4g_dw_band);
     if (msg->config_dw.config_2dot4g_dw_band) {
         ALOGI("dw_2dot4g_interval_val=%u\n", msg->config_dw.dw_2dot4g_interval_val);
@@ -4313,7 +5652,7 @@
 
 static int dump_NanPublishRequest(NanPublishRequest* msg)
 {
-    ALOGI("%s: Dump NanPublishRequest msg:\n", __func__);
+    ALOGI("%s:Dump NanPublishRequest msg:\n", __func__);
     if (msg == NULL) {
         ALOGE("Invalid msg\n");
         return WIFI_ERROR_UNKNOWN;
@@ -4326,21 +5665,34 @@
     ALOGI("publish_count=%u\n", msg->publish_count);
     ALOGI("publish_match_indicator=%u\n", msg->publish_match_indicator);
     ALOGI("service_responder_policy=%u\n", msg->service_responder_policy);
-    ALOGI("service_name_len=%u\n", msg->service_name_len);
     if (msg->service_name_len) {
-        ALOGI("service_name=%s\n", msg->service_name);
+        if (msg->service_name_len > NAN_MAX_SERVICE_NAME_LEN) {
+           ALOGE("Invalid service_name len %d\n", msg->service_name_len);
+        } else {
+            ALOGI("service_name_len=%u\n", msg->service_name_len);
+            ALOGI("service_name=%s\n", msg->service_name);
+        }
     }
-    ALOGI("service_specific_info_len=%u\n", msg->service_specific_info_len);
     if (msg->service_specific_info_len) {
-        prhex("service_specific_info",
-            msg->service_specific_info, msg->service_specific_info_len);
+        if (msg->service_specific_info_len > NAN_MAX_SVC_INFO_LEN) {
+            ALOGE("Invalid svc specific info len %d\n",
+                msg->service_specific_info_len);
+        } else {
+            ALOGI("service_specific_info_len=%u\n", msg->service_specific_info_len);
+            prhex("service_specific_info",
+                    msg->service_specific_info, msg->service_specific_info_len);
+        }
     }
-    ALOGI("rx_match_filter_len=%u\n", msg->rx_match_filter_len);
     if (msg->rx_match_filter_len) {
+        if (msg->rx_match_filter_len > NAN_MAX_MATCH_FILTER_LEN) {
+            ALOGE("%s Invalid rx match filter len %d\n", __func__, msg->rx_match_filter_len);
+        }
         prhex("rx_match_filter", msg->rx_match_filter, msg->rx_match_filter_len);
     }
-    ALOGI("tx_match_filter_len=%u\n", msg->tx_match_filter_len);
     if (msg->tx_match_filter_len) {
+        if (msg->tx_match_filter_len > NAN_MAX_MATCH_FILTER_LEN) {
+            ALOGE("%s Invalid tx match filter len %d\n", __func__, msg->tx_match_filter_len);
+        }
         prhex("tx_match_filter", msg->tx_match_filter, msg->tx_match_filter_len);
     }
     ALOGI("rssi_threshold_flag=%u\n", msg->rssi_threshold_flag);
@@ -4360,8 +5712,21 @@
     ALOGI("NanRangingAutoResponse = %u\n", msg->ranging_auto_response);
     ALOGI("range_response_cfg=%u\n", msg->range_response_cfg.ranging_response);
 
-    ALOGI("sdea_service_specific_info_len=%u\n", msg->sdea_service_specific_info_len);
-
+    if (msg->sdea_service_specific_info_len) {
+        if (msg->sdea_service_specific_info_len > NAN_MAX_SDEA_SERVICE_SPECIFIC_INFO_LEN) {
+            ALOGE("%s Invalid sdea svc specific info %d\n",
+                    __func__, msg->sdea_service_specific_info_len);
+        } else {
+            ALOGE("%s sdea svc specific info %d\n",
+                    __func__, msg->sdea_service_specific_info_len);
+        }
+    }
+    ALOGI("enable_suspendability=%u\n", msg->enable_suspendability);
+    ALOGI("enable_pairing_setup=%u\n", msg->nan_pairing_config.enable_pairing_setup);
+    ALOGI("enable_pairing_verification=%u\n", msg->nan_pairing_config.enable_pairing_verification);
+    ALOGI("enable_pairing_cache=%u\n", msg->nan_pairing_config.enable_pairing_cache);
+    ALOGI("Supported BS methods=%u\n", msg->nan_pairing_config.supported_bootstrapping_methods);
+    prhex("NIK:", msg->nan_identity_key, NAN_IDENTITY_KEY_LEN);
     return WIFI_SUCCESS;
 }
 
@@ -4383,16 +5748,35 @@
     ALOGI("ssiRequiredForMatchIndication=%u\n", msg->ssiRequiredForMatchIndication);
     ALOGI("subscribe_count=%u\n", msg->subscribe_count);
     ALOGI("subscribe_match_indicator=%u\n", msg->subscribe_match_indicator);
-    ALOGI("service_name_len=%u\n", msg->service_name_len);
-    if (msg->service_name_len)
-        ALOGI("service_name=%s\n", msg->service_name);
-    ALOGI("service_specific_info_len=%u\n", msg->service_specific_info_len);
-    ALOGI("rx_match_filter_len=%u\n", msg->rx_match_filter_len);
-    if (msg->rx_match_filter_len)
+    if (msg->service_name_len) {
+        if (msg->service_name_len > NAN_MAX_SERVICE_NAME_LEN) {
+            ALOGE("Invalid service_name len %d\n", msg->service_name_len);
+        } else {
+            ALOGI("service_name_len=%u\n", msg->service_name_len);
+            ALOGI("service_name=%s\n", msg->service_name);
+        }
+    }
+    if (msg->service_specific_info_len) {
+        if (msg->service_specific_info_len > NAN_MAX_SVC_INFO_LEN) {
+            ALOGE("Invalid svc specific info len %d\n", msg->service_specific_info_len);
+        } else {
+            ALOGI("service_specific_info_len=%u\n", msg->service_specific_info_len);
+            prhex("service_specific_info",
+                    msg->service_specific_info, msg->service_specific_info_len);
+        }
+    }
+    if (msg->rx_match_filter_len) {
+        if (msg->rx_match_filter_len > NAN_MAX_MATCH_FILTER_LEN) {
+            ALOGE("%s Invalid rx match filter len %d\n", __func__, msg->rx_match_filter_len);
+        }
         prhex("rx_match_filter", msg->rx_match_filter, msg->rx_match_filter_len);
-    ALOGI("tx_match_filter_len=%u\n", msg->tx_match_filter_len);
-    if (msg->tx_match_filter_len)
-        prhex("tx_match_filter", msg->tx_match_filter, msg->tx_match_filter_len);
+    }
+    if (msg->tx_match_filter_len) {
+        if (msg->tx_match_filter_len > NAN_MAX_MATCH_FILTER_LEN) {
+            ALOGE("%s Invalid tx match filter len %d\n", __func__, msg->tx_match_filter_len);
+        }
+        prhex("tx_match_filter", msg->rx_match_filter, msg->tx_match_filter_len);
+    }
     ALOGI("rssi_threshold_flag=%u\n", msg->rssi_threshold_flag);
     ALOGI("connmap=%u\n", msg->connmap);
     ALOGI("num_intf_addr_present=%u\n", msg->num_intf_addr_present);
@@ -4416,7 +5800,21 @@
     ALOGI("NanRangingAutoResponse = %u\n", msg->ranging_auto_response);
     ALOGI("range_response = %u\n", msg->range_response_cfg.ranging_response);
 
-    ALOGI("sdea_service_specific_info_len=%u\n", msg->sdea_service_specific_info_len);
+    if (msg->sdea_service_specific_info_len) {
+        if (msg->sdea_service_specific_info_len > NAN_MAX_SDEA_SERVICE_SPECIFIC_INFO_LEN) {
+            ALOGE("%s Invalid sdea svc specific info %d\n",
+                    __func__, msg->sdea_service_specific_info_len);
+        } else {
+            ALOGE("%s sdea svc specific info %d\n",
+                    __func__, msg->sdea_service_specific_info_len);
+        }
+    }
+    ALOGI("enable_suspendability=%u\n", msg->enable_suspendability);
+    ALOGI("enable_pairing_setup=%u\n", msg->nan_pairing_config.enable_pairing_setup);
+    ALOGI("enable_pairing_verification=%u\n", msg->nan_pairing_config.enable_pairing_verification);
+    ALOGI("enable_pairing_cache=%u\n", msg->nan_pairing_config.enable_pairing_cache);
+    ALOGI("Supported BS methods=%u\n", msg->nan_pairing_config.supported_bootstrapping_methods);
+    prhex("NIK:", msg->nan_identity_key, NAN_IDENTITY_KEY_LEN);
 
     return WIFI_SUCCESS;
 }
@@ -4433,10 +5831,26 @@
     ALOGI("addr=" MACSTR "\n", MAC2STR(msg->addr));
     ALOGI("priority=%u\n", msg->priority);
     ALOGI("dw_or_faw=%u\n", msg->dw_or_faw);
-    ALOGI("service_specific_info_len=%u\n", msg->service_specific_info_len);
+    if (msg->service_specific_info_len) {
+        if (msg->service_specific_info_len > NAN_MAX_SVC_INFO_LEN) {
+            ALOGE("Invalid svc specific info len %d\n",
+                    msg->service_specific_info_len);
+        } else {
+            ALOGI("service_specific_info_len=%u\n", msg->service_specific_info_len);
+            prhex("service_specific_info",
+                    msg->service_specific_info, msg->service_specific_info_len);
+        }
+    }
     ALOGI("recv_indication_cfg=%u\n", msg->recv_indication_cfg);
-    ALOGI("sdea_service_specific_info_len=%u\n", msg->sdea_service_specific_info_len);
-
+    if (msg->sdea_service_specific_info_len) {
+        if (msg->sdea_service_specific_info_len > NAN_MAX_SDEA_SERVICE_SPECIFIC_INFO_LEN) {
+            ALOGE("%s Invalid sdea svc specific info %d\n",
+                    __func__, msg->sdea_service_specific_info_len);
+        } else {
+            ALOGE("%s sdea svc specific info %d\n",
+                    __func__, msg->sdea_service_specific_info_len);
+        }
+    }
     return WIFI_SUCCESS;
 }
 
@@ -4465,7 +5879,12 @@
     ALOGI("key_info: key_type =%u\n", msg->key_info.key_type);
     ALOGI("scid_len=%u\n", msg->scid_len);
     if (msg->service_name_len) {
-        ALOGI("service_name=%s\n", msg->service_name);
+        if (msg->service_name_len > NAN_MAX_SERVICE_NAME_LEN) {
+            ALOGE("Invalid service_name len %d\n", msg->service_name_len);
+        } else {
+            ALOGI("service_name_len=%u\n", msg->service_name_len);
+            ALOGI("service_name=%s\n", msg->service_name);
+        }
     }
     return WIFI_SUCCESS;
 }
@@ -4491,15 +5910,114 @@
     }
     ALOGI("cipher_type=%u\n", msg->cipher_type);
     ALOGI("key_info: key_type =%u\n", msg->key_info.key_type);
-    ALOGI("service_name_len=%u\n", msg->service_name_len);
     ALOGI("scid_len=%u\n", msg->scid_len);
     if (msg->service_name_len) {
-        ALOGI("service_name=%s\n", msg->service_name);
+        if (msg->service_name_len > NAN_MAX_SERVICE_NAME_LEN) {
+            ALOGE("Invalid service_name len %d\n", msg->service_name_len);
+        } else {
+            ALOGI("service_name_len=%u\n", msg->service_name_len);
+            ALOGI("service_name=%s\n", msg->service_name);
+        }
     }
     return WIFI_SUCCESS;
 }
 #endif /* CONFIG_BRCM */
 
+static int dump_NanPairingRequest(NanPairingRequest* msg)
+{
+    ALOGI("%s: Dump NanpairingRequest msg:\n", __func__);
+    if (msg == NULL) {
+        ALOGE("Invalid msg\n");
+        return WIFI_ERROR_UNKNOWN;
+    }
+    ALOGI("requestor instance id=%u\n", msg->requestor_instance_id);
+    ALOGI("peer_disc_mac_addr=" MACSTR "\n", MAC2STR(msg->peer_disc_mac_addr));
+    ALOGI("pairing request type=%u\n", msg->nan_pairing_request_type);
+    ALOGI("is_oportunistic=%u\n", msg->is_opportunistic);
+    ALOGI("akm=%u\n", msg->akm);
+    ALOGI("enable_pairing_cache=%u\n", msg->enable_pairing_cache);
+    ALOGI("cipher_type=%u\n", msg->cipher_type);
+    ALOGI("key_info: key_type =%u\n", msg->key_info.key_type);
+    prhex("key_info:", msg->key_info.body.passphrase_info.passphrase,
+            msg->key_info.body.passphrase_info.passphrase_len);
+    prhex("NIK:", msg->nan_identity_key, NAN_IDENTITY_KEY_LEN);
+    return WIFI_SUCCESS;
+}
+
+static int dump_NanPairingIndResponse(NanPairingIndicationResponse* msg)
+{
+    ALOGI("%s: Dump NanPairingIndicationResponse msg:\n", __func__);
+    if (msg == NULL) {
+        ALOGE("Invalid msg\n");
+        return WIFI_ERROR_UNKNOWN;
+    }
+    ALOGI("Pairing instance id=%u\n", msg->pairing_instance_id);
+    ALOGI("pairing request type=%u\n", msg->nan_pairing_request_type);
+    ALOGI("response_code=%u\n", msg->rsp_code);
+    ALOGI("is_oportunistic=%u\n", msg->is_opportunistic);
+    ALOGI("akm=%u\n", msg->akm);
+    ALOGI("enable_pairing_cache=%u\n", msg->enable_pairing_cache);
+    ALOGI("cipher_type=%u\n", msg->cipher_type);
+    ALOGI("key_info: key_type =%u\n", msg->key_info.key_type);
+    prhex("key_info:", msg->key_info.body.passphrase_info.passphrase,
+            msg->key_info.body.passphrase_info.passphrase_len);
+    prhex("NIK:", msg->nan_identity_key, NAN_IDENTITY_KEY_LEN);
+    return WIFI_SUCCESS;
+}
+
+static int dump_NanBootstrapingRequest(NanBootstrappingRequest* msg)
+{
+    ALOGI("%s: Dump NanBootstrappingRequest msg:\n", __func__);
+    if (msg == NULL) {
+        ALOGE("Invalid msg\n");
+        return WIFI_ERROR_UNKNOWN;
+    }
+    ALOGI("publish_subscribe_id=%u\n", msg->publish_subscribe_id);
+    ALOGI("peer requestor instance id=%u\n", msg->requestor_instance_id);
+    ALOGI("peer_disc_mac_addr=" MACSTR "\n", MAC2STR(msg->peer_disc_mac_addr));
+    ALOGI("request_bootstrapping_method=%u\n", msg->request_bootstrapping_method);
+    ALOGI("cookie_length=%u\n", msg->cookie_length);
+    if (msg->cookie_length) {
+        prhex(NULL, msg->cookie, msg->cookie_length);
+    }
+    ALOGI("service_specific_info_len=%u\n", msg->service_specific_info_len);
+    if (msg->service_specific_info_len) {
+        ALOGI("service_specific_info=%s\n", msg->service_specific_info);
+    }
+    ALOGI("sdea_service_specific_info_len=%u\n", msg->sdea_service_specific_info_len);
+    if (msg->sdea_service_specific_info_len) {
+        ALOGI("sdea_service_specific_info=%s\n", msg->sdea_service_specific_info);
+    }
+    return WIFI_SUCCESS;
+}
+
+static int dump_NanBootstrapingIndResponse(NanBootstrappingIndicationResponse* msg)
+{
+    ALOGI("%s: Dump NanBootstrappingIndicationResponse msg:\n", __func__);
+    if (msg == NULL) {
+        ALOGE("Invalid msg\n");
+        return WIFI_ERROR_UNKNOWN;
+    }
+    ALOGI("publish_subscribe_id=%u\n", msg->publish_subscribe_id);
+    ALOGI("peer service_instance_id=%u\n", msg->service_instance_id);
+    ALOGI("peer_disc_mac_addr=" MACSTR "\n", MAC2STR(msg->peer_disc_mac_addr));
+    ALOGI("response_code=%u\n", msg->rsp_code);
+    ALOGI("come_back_delay=%u\n", msg->come_back_delay);
+    ALOGI("cookie_length=%u\n", msg->cookie_length);
+    if (msg->cookie_length) {
+        prhex(NULL, msg->cookie, msg->cookie_length);
+    }
+    ALOGI("service_specific_info_len=%u\n", msg->service_specific_info_len);
+    if (msg->service_specific_info_len) {
+        ALOGI("service_specific_info=%s\n", msg->service_specific_info);
+    }
+    ALOGI("sdea_service_specific_info_len=%u\n", msg->sdea_service_specific_info_len);
+    if (msg->sdea_service_specific_info_len) {
+        ALOGI("sdea_service_specific_info=%s\n", msg->sdea_service_specific_info);
+    }
+    return WIFI_SUCCESS;
+}
+
 void nan_reset_dbg_counters()
 {
     memset(&counters, 0, sizeof(counters));
@@ -4532,9 +6050,9 @@
         wifi_interface_handle iface, NanEnableRequest* msg)
 {
     wifi_error ret = WIFI_SUCCESS;
-   hal_info *h_info = getHalInfo(iface);
+    hal_info *h_info = getHalInfo(iface);
 
-	ALOGE("nan_enable_request: nan_state = %d\n", h_info->nan_state);
+    ALOGE("nan_enable_request: nan_state = %d\n", h_info->nan_state);
 
 #ifdef CHRE_NAN
     //check if host NAN is pre-empting CHRE NAN
@@ -4597,6 +6115,7 @@
 
     return ret;
 }
+
 wifi_error nan_disable_request(transaction_id id,
         wifi_interface_handle iface)
 {
@@ -4619,8 +6138,7 @@
         ALOGE("Disable NAN MAC transId= %d\n", id);
         mac_prim->setId(id);
     } else {
-        ALOGE("Invalid transId= %d cur= %d\n", id,
-              mac_prim ? mac_prim->getId() : -1);
+        ALOGE("Invalid transId= %d cur= %d\n", id, mac_prim->getId());
     }
 
     cmd->setChreNan(0);
@@ -4748,6 +6266,77 @@
     return ret;
 }
 
+/* Function to prepare cmd request to wifi driver for the cmd received from upper layers/Halutil */
+wifi_error nan_create_pairing_bootstrap_cmd_request(transaction_id id,
+        wifi_interface_handle iface, void* msg, NanRequestType cmdType)
+{
+    wifi_error ret = WIFI_SUCCESS;
+    wifi_handle handle = getWifiHandle(iface);
+    NanPairingPrimitive *cmd;
+
+    ALOGI("Nan Pairing bootstrapping cmd %d , halHandle = %p TxId %d ", cmdType, handle, id);
+    cmd = new NanPairingPrimitive(iface, id, msg, cmdType);
+    NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
+    cmd->setTransactionId(id);
+
+    ret = (wifi_error)cmd->start();
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("%s : failed in start, error = %d\n", __func__, ret);
+    }
+    cmd->releaseRef();
+    return ret;
+
+}
+
+/* Function to send NAN pairing request to the wifi driver */
+wifi_error nan_pairing_request(transaction_id id,
+        wifi_interface_handle iface, NanPairingRequest* msg)
+{
+    NanRequestType cmdType = NAN_PAIRING_REQUEST;
+    dump_NanPairingRequest(msg);
+
+    return nan_create_pairing_bootstrap_cmd_request(id, iface, (void *)msg, cmdType);
+}
+
+/* Function to send NAN pairing indication response to the wifi driver */
+wifi_error nan_pairing_indication_response(transaction_id id,
+        wifi_interface_handle iface, NanPairingIndicationResponse* msg)
+{
+    NanRequestType cmdType = NAN_PAIRING_IND_RESPONSE;
+    dump_NanPairingIndResponse(msg);
+
+    return nan_create_pairing_bootstrap_cmd_request(id, iface, (void *)msg, cmdType);
+}
+
+/* Function to send NAN pairing end request to the wifi driver */
+wifi_error nan_pairing_end(transaction_id id,
+        wifi_interface_handle iface, NanPairingEndRequest* msg)
+{
+    NanRequestType cmdType = NAN_PAIRING_END_REQUEST;
+
+    return nan_create_pairing_bootstrap_cmd_request(id, iface, (void *)msg, cmdType);
+}
+
+/* Function to send NAN bootstrapping request to the wifi driver */
+wifi_error nan_bootstrapping_request(transaction_id id,
+        wifi_interface_handle iface, NanBootstrappingRequest* msg)
+{
+    NanRequestType cmdType = NAN_BOOTSTRAPPING_REQUEST;
+    dump_NanBootstrapingRequest(msg);
+
+    return nan_create_pairing_bootstrap_cmd_request(id, iface, (void *)msg, cmdType);
+}
+
+/* Function to send NAN bootstrapping indication response to the wifi driver */
+wifi_error nan_bootstrapping_indication_response(transaction_id id,
+        wifi_interface_handle iface, NanBootstrappingIndicationResponse* msg)
+{
+    NanRequestType cmdType = NAN_BOOTSTRAPPING_IND_RESPONSE;
+    dump_NanBootstrapingIndResponse(msg);
+
+    return nan_create_pairing_bootstrap_cmd_request(id, iface, (void *)msg, cmdType);
+}
+
 /* Function to send NAN statistics request to the wifi driver */
 wifi_error nan_stats_request(transaction_id id,
         wifi_interface_handle iface, NanStatsRequest* msg)
@@ -4756,20 +6345,7 @@
 
     ALOGI("Nan Stats, halHandle = %p", handle);
 
-#ifdef NOT_SUPPORTED
-    NanRequestType cmdType = NAN_REQUEST_STATS;
-    wifi_error ret = WIFI_SUCCESS;
-    NanCommand *cmd = new NanCommand(iface, id, (void *)msg, cmdType);
-    NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
-    ret = (wifi_error)cmd->start();
-    if (ret != WIFI_SUCCESS) {
-        ALOGE("%s : failed in start, error = %d\n", __func__, ret);
-    }
-    cmd->releaseRef();
-    return ret;
-#else
     return WIFI_ERROR_NOT_SUPPORTED;
-#endif
 }
 
 /* Function to send NAN configuration request to the wifi driver */
@@ -4901,6 +6477,10 @@
         delete (NanDataPathPrimitive*)info.nan_dp_control;
         info.nan_dp_control = NULL;
     }
+    if (info.nan_pairing_control) {
+        delete(NanPairingPrimitive*)info.nan_pairing_control;
+        info.nan_pairing_control = NULL;
+    }
     if (NAN_HANDLE(info)) {
         delete GET_NAN_HANDLE(info);
         NAN_HANDLE(info) = NULL;
@@ -4934,7 +6514,12 @@
         (void*)new NanDataPathPrimitive(iface, 0, NULL, NAN_REQUEST_LAST);
     NULL_CHECK_RETURN(info.nan_dp_control, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
 
-    /* register for Nan vendor events with info mac class*/
+    info.nan_pairing_control =
+            (void*)new NanPairingPrimitive(iface, 0, NULL, NAN_REQUEST_LAST);
+    NULL_CHECK_RETURN(info.nan_pairing_control, "memory allocation failure",
+            WIFI_ERROR_OUT_OF_MEMORY);
+
+    /* register for Nan vendor events with info mac class */
     NanMacControl *cmd_event = (NanMacControl*)(info.nan_mac_control);
     cmd_event->registerNanVendorEvents();
     return WIFI_SUCCESS;
@@ -5022,6 +6607,10 @@
             unregisterVendorHandler(GOOGLE_OUI, NAN_ASYNC_RESPONSE_DISABLED);
             unregisterVendorHandler(GOOGLE_OUI, NAN_EVENT_MATCH_EXPIRY);
             unregisterVendorHandler(GOOGLE_OUI, NAN_EVENT_SUSPENSION_STATUS);
+            unregisterVendorHandler(GOOGLE_OUI, NAN_EVENT_PAIRING_REQUEST);
+            unregisterVendorHandler(GOOGLE_OUI, NAN_EVENT_PAIRING_CONFIRMATION);
+            unregisterVendorHandler(GOOGLE_OUI, NAN_EVENT_BOOTSTRAPPING_REQUEST);
+            unregisterVendorHandler(GOOGLE_OUI, NAN_EVENT_BOOTSTRAPPING_CONFIRMATION);
         }
         void registerNanVendorEvents()
         {
@@ -5032,6 +6621,10 @@
             registerVendorHandler(GOOGLE_OUI, NAN_ASYNC_RESPONSE_DISABLED);
             registerVendorHandler(GOOGLE_OUI, NAN_EVENT_MATCH_EXPIRY);
             registerVendorHandler(GOOGLE_OUI, NAN_EVENT_SUSPENSION_STATUS);
+            registerVendorHandler(GOOGLE_OUI, NAN_EVENT_PAIRING_REQUEST);
+            registerVendorHandler(GOOGLE_OUI, NAN_EVENT_PAIRING_CONFIRMATION);
+            registerVendorHandler(GOOGLE_OUI, NAN_EVENT_BOOTSTRAPPING_REQUEST);
+            registerVendorHandler(GOOGLE_OUI, NAN_EVENT_BOOTSTRAPPING_CONFIRMATION);
         }
 
         int handleEvent(WifiEvent& event) {
@@ -5073,7 +6666,7 @@
                             } else if (de_type == NAN_EVENT_MERGE) {
                                 ALOGI("received Merge Event\n");
                             } else {
-                                ALOGI("received unknown DE event, [%d]\n", de_type);
+                                ALOGI("EventCap: received unknown DE event, [%d]\n", de_type);
                             }
                         } else if (attr_type == NAN_ATTRIBUTE_MAC_ADDR) {
                             memcpy(&de_event.data.cluster.addr, it.get_data(), NAN_MAC_ADDR_LEN);
@@ -5219,7 +6812,31 @@
                                 (NanDataPathSecurityCfgStatus)it.get_u8();
                         } else if (attr_type == NAN_ATTRIBUTE_SDE_CONTROL_RANGE_SUPPORT) {
                             ALOGI("Ranging report state: %u", it.get_u8());
-                            subscribe_event.peer_sdea_params.range_report = (NanRangeReport)it.get_u8();
+                            subscribe_event.peer_sdea_params.range_report =
+                                    (NanRangeReport)it.get_u8();
+                        } else if (attr_type == NAN_ATTRIBUTE_ENAB_PAIRING_SETUP) {
+                            ALOGI("Enabe pairing setup: %u", it.get_u32());
+                            subscribe_event.peer_pairing_config.enable_pairing_setup = it.get_u32();
+                        } else if (attr_type == NAN_ATTRIBUTE_ENAB_PAIRING_VERIFICATION) {
+                            ALOGI("Enabe pairing Verification: %u", it.get_u32());
+                            subscribe_event.peer_pairing_config.enable_pairing_verification =
+                                    it.get_u32();
+                        } else if (attr_type == NAN_ATTRIBUTE_PAIRING_CACHE) {
+                            ALOGI("Enabe pairing cache: %u", it.get_u32());
+                            subscribe_event.peer_pairing_config.enable_pairing_cache = it.get_u32();
+                        } else if (attr_type == NAN_ATTRIBUTE_BS_METHODS) {
+                            ALOGI("Supported bootstrapping methods : %u", it.get_u16());
+                            subscribe_event.peer_pairing_config.supported_bootstrapping_methods =
+                                    it.get_u32();
+
+                        } else if (attr_type == NAN_ATTRIBUTE_NIRA_TAG) {
+                            memcpy(subscribe_event.nira.tag, it.get_data(), NAN_IDENTITY_TAG_LEN);
+                            prhex("NIRA tag", subscribe_event.nira.tag, NAN_IDENTITY_TAG_LEN);
+
+                        } else if (attr_type == NAN_ATTRIBUTE_NIRA_NONCE) {
+                            memcpy(subscribe_event.nira.nonce, it.get_data(),
+                                    NAN_IDENTITY_NONCE_LEN);
+                            prhex("NIRA nonce", subscribe_event.nira.nonce, NAN_IDENTITY_NONCE_LEN);
                         }
                     }
 
@@ -5498,11 +7115,11 @@
                         } else if (attr_type == NAN_ATTRIBUTE_STATUS) {
                             followup_ind.reason = (NanStatusType)it.get_u8();
                         } else if (attr_type == NAN_ATTRIBUTE_REASON) {
-                            u8 len = min(it.get_len(), (sizeof(followup_ind.nan_reason) - 1));
+                            u8 len = min(it.get_len(), sizeof(followup_ind.nan_reason) - 1);
                             memcpy(followup_ind.nan_reason, it.get_data(), len);
                             followup_ind.nan_reason[len] = '\0';
                             ALOGI("nan transmit followup ind: reason: %s, len = %d\n",
-                               followup_ind.nan_reason, len);
+                                   followup_ind.nan_reason, len);
                         }
                     }
 
@@ -5524,6 +7141,296 @@
                     GET_NAN_HANDLE(info)->mHandlers.EventSuspensionModeChange(&suspend_ind);
                     break;
                 }
+                case NAN_EVENT_PAIRING_REQUEST: {
+                    NanPairingRequestInd pairing_request_event;
+                    memset(&pairing_request_event, 0, sizeof(NanPairingRequestInd));
+                    ALOGI("Received NAN_EVENT_PAIRING_REQUEST\n");
+
+                    for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
+                        attr_type = it.get_type();
+
+                        if (attr_type == NAN_ATTRIBUTE_PUBLISH_ID) {
+                            ALOGI("publish_subscribe_id: %u\n", it.get_u16());
+                            pairing_request_event.publish_subscribe_id = it.get_u16();
+
+                        } else if (attr_type == NAN_ATTRIBUTE_MAC_ADDR) {
+                            memcpy(pairing_request_event.peer_disc_mac_addr,
+                                    it.get_data(), NAN_MAC_ADDR_LEN);
+                            ALOGI("Discovery MAC addr of the peer/initiator: " MACSTR "\n",
+                                    MAC2STR(pairing_request_event.peer_disc_mac_addr));
+
+                        } else if (attr_type == NAN_ATTRIBUTE_INST_ID) {
+                            u32 pairing_id = it.get_u32();
+                            ALOGI("pairing instance id: %u\n", pairing_id);
+
+                            if (ISGREATER(pairing_id, NAN_MAX) ||
+                                    (ISLESS_OR_EQUAL(pairing_id, NAN_MIN))) {
+                                ALOGE("%s:Invalid Pairing ID: %u \n", __func__, pairing_id);
+                                goto fail;
+                            }
+                            pairing_request_event.pairing_instance_id = pairing_id;
+
+                        } else if (attr_type == NAN_ATTRIBUTE_REQUEST_TYPE) {
+                            ALOGI("Pairing request type: %u\n", it.get_u16());
+                            pairing_request_event.nan_pairing_request_type =
+                                    (NanPairingRequestType)it.get_u16();
+                            if ((pairing_request_event.nan_pairing_request_type >
+                                    NAN_PAIRING_VERIFICATION) ||
+                                    (pairing_request_event.nan_pairing_request_type <
+                                    NAN_PAIRING_SETUP)) {
+                                ALOGE("INVALID Pairing request type %u\n",
+                                        pairing_request_event.nan_pairing_request_type);
+                                goto fail;
+                            }
+
+                        } else if (attr_type == NAN_ATTRIBUTE_PAIRING_CACHE) {
+                            ALOGI("Pairing cache enabled: %u\n", (u8)it.get_u32());
+                            pairing_request_event.enable_pairing_cache = (u8)it.get_u32();
+
+                        } else if (attr_type == NAN_ATTRIBUTE_NIRA_TAG) {
+                            memcpy(pairing_request_event.nira.tag, it.get_data(),
+                                    NAN_IDENTITY_TAG_LEN);
+                            prhex("NIRA tag", pairing_request_event.nira.tag,
+                                    NAN_IDENTITY_TAG_LEN);
+
+                        } else if (attr_type == NAN_ATTRIBUTE_NIRA_NONCE) {
+                            memcpy(pairing_request_event.nira.nonce, it.get_data(),
+                                    NAN_IDENTITY_NONCE_LEN);
+                            prhex("NIRA nonce", pairing_request_event.nira.nonce,
+                                    NAN_IDENTITY_NONCE_LEN);
+
+                        }
+                    }
+
+                    if (!pairing_request_event.publish_subscribe_id ||
+                            !pairing_request_event.pairing_instance_id) {
+                        ALOGE("Check invalid params received pub_sub_id: 0x%x pairing_id: %u\n",
+                                pairing_request_event.publish_subscribe_id,
+                                pairing_request_event.pairing_instance_id);
+                        goto fail;
+                    }
+
+                    GET_NAN_HANDLE(info)->mHandlers.EventPairingRequest(&pairing_request_event);
+                    break;
+                }
+                case NAN_EVENT_PAIRING_CONFIRMATION: {
+                    NanPairingConfirmInd pairing_confirm_event;
+                    u32 pmk_len = 0;
+                    memset(&pairing_confirm_event, 0, sizeof(NanPairingConfirmInd));
+                    ALOGI("Received NAN_EVENT_PAIRING_CONFIRMATION\n");
+
+                    for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
+                        attr_type = it.get_type();
+
+                        if (attr_type == NAN_ATTRIBUTE_INST_ID) {
+                            ALOGI("pairing instance id: %u\n", it.get_u32());
+                            pairing_confirm_event.pairing_instance_id = it.get_u32();
+                            if ((pairing_confirm_event.pairing_instance_id <= NAN_MIN) ||
+                                    (pairing_confirm_event.pairing_instance_id > NAN_MAX)) {
+                                ALOGE("INVALID Pairing instance id: %u\n",
+                                        pairing_confirm_event.pairing_instance_id);
+                                goto fail;
+                            }
+
+                        } else if (attr_type == NAN_ATTRIBUTE_RSP_CODE) {
+                            ALOGI("response code: %u\n", (NanPairingResponseCode)it.get_u8());
+                            pairing_confirm_event.rsp_code = (NanPairingResponseCode)it.get_u8();
+
+                        } else if (attr_type == NAN_ATTRIBUTE_STATUS) {
+                            ALOGI("reason_code: %u\n", (NanStatusType)it.get_u8());
+                            pairing_confirm_event.reason_code = (NanStatusType)it.get_u8();
+
+                        } else if (attr_type == NAN_ATTRIBUTE_REQUEST_TYPE) {
+                            ALOGI("Pairing request type: %u\n",
+                                    (NanPairingRequestType)it.get_u16());
+                            pairing_confirm_event.nan_pairing_request_type =
+                                    (NanPairingRequestType)it.get_u16();
+                            if ((pairing_confirm_event.nan_pairing_request_type >
+                                    NAN_PAIRING_VERIFICATION) ||
+                                    (pairing_confirm_event.nan_pairing_request_type <
+                                    NAN_PAIRING_SETUP)) {
+                                ALOGE("INVALID Pairing request type %u\n",
+                                        pairing_confirm_event.nan_pairing_request_type);
+                                goto fail;
+                            }
+
+                        } else if (attr_type == NAN_ATTRIBUTE_PAIRING_CACHE) {
+                            ALOGI("Pairing cache enabled: %u\n", (u8)it.get_u32());
+                            pairing_confirm_event.enable_pairing_cache = (u8)it.get_u32();
+
+                        } else if (attr_type == NAN_ATTRIBUTE_PEER_NIK) {
+                            memcpy(pairing_confirm_event.npk_security_association.peer_nan_identity_key,
+                                    it.get_data(), NAN_IDENTITY_KEY_LEN);
+                            prhex("Peer NIK:",
+                                pairing_confirm_event.npk_security_association.peer_nan_identity_key,
+                                NAN_IDENTITY_KEY_LEN);
+
+                        } else if (attr_type == NAN_ATTRIBUTE_LOCAL_NIK) {
+                            memcpy(pairing_confirm_event.npk_security_association.local_nan_identity_key,
+                                    it.get_data(), NAN_IDENTITY_KEY_LEN);
+                            prhex("Local NIK:",
+                                pairing_confirm_event.npk_security_association.local_nan_identity_key,
+                                NAN_IDENTITY_KEY_LEN);
+
+                        } else if (attr_type == NAN_ATTRIBUTE_AKM) {
+                            ALOGI("akm: %u\n", (NanAkm)it.get_u8());
+                            pairing_confirm_event.npk_security_association.akm =
+                                    (NanAkm)it.get_u8();
+                            if ((pairing_confirm_event.npk_security_association.akm >
+                                    PASN) || (pairing_confirm_event.npk_security_association.akm <
+                                    SAE)) {
+                                ALOGI("INVALID Pairing AKM type %u\n",
+                                        pairing_confirm_event.npk_security_association.akm);
+                                goto fail;
+                            }
+
+                        } else if (attr_type == NAN_ATTRIBUTE_CIPHER_SUITE_TYPE) {
+                            u32 csid = it.get_u32();
+                            ALOGI("csid: 0x%x\n", csid);
+                            if ((csid != NAN_CIPHER_SUITE_PUBLIC_KEY_PASN_128_MASK) &&
+                                    (csid != NAN_CIPHER_SUITE_PUBLIC_KEY_PASN_256_MASK)) {
+                                ALOGE("%s: Invalid cipher_type received :0x%x \n", __func__, csid);
+                                goto fail;
+                            }
+
+                            pairing_confirm_event.npk_security_association.cipher_type = csid;
+
+                        } else if (attr_type == NAN_ATTRIBUTE_KEY_LEN) {
+                            ALOGI("pmk len: %u\n", it.get_u32());
+                            pmk_len = it.get_u32();
+                            pairing_confirm_event.npk_security_association.npk.pmk_len = pmk_len;
+
+                        } else if (attr_type == NAN_ATTRIBUTE_KEY_DATA) {
+                            memcpy(pairing_confirm_event.npk_security_association.npk.pmk,
+                                    it.get_data(),
+                                    pairing_confirm_event.npk_security_association.npk.pmk_len);
+                            prhex("NPK:",
+                                    (u8 *)pairing_confirm_event.npk_security_association.npk.pmk,
+                                    pairing_confirm_event.npk_security_association.npk.pmk_len);
+                        }
+                    }
+
+                    if (!pairing_confirm_event.npk_security_association.cipher_type ||
+                            !pairing_confirm_event.npk_security_association.npk.pmk_len ||
+                            !pairing_confirm_event.pairing_instance_id) {
+                        ALOGE("Check invalid params received csid:0x%x pmk_len:%u pairing_id: %u\n",
+                                pairing_confirm_event.npk_security_association.cipher_type,
+                                pairing_confirm_event.npk_security_association.npk.pmk_len,
+                                pairing_confirm_event.pairing_instance_id);
+                        goto fail;
+                    }
+
+                    GET_NAN_HANDLE(info)->mHandlers.EventPairingConfirm(&pairing_confirm_event);
+                    break;
+                }
+                case NAN_EVENT_BOOTSTRAPPING_REQUEST: {
+                    NanBootstrappingRequestInd bs_request_event;
+                    memset(&bs_request_event, 0, sizeof(NanBootstrappingRequestInd));
+                    ALOGI("Received NAN_EVENT_BOOTSTRAPPING_REQUEST\n");
+
+                    for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
+                        attr_type = it.get_type();
+
+                        if (attr_type == NAN_ATTRIBUTE_SUBSCRIBE_ID) {
+                            ALOGI("publish_subscribe_id: %u\n", it.get_u16());
+                            bs_request_event.publish_subscribe_id = it.get_u16();
+
+                        } else if (attr_type == NAN_ATTRIBUTE_PUBLISH_ID) {
+                            ALOGI("requestor_instance_id: %u\n", it.get_u32());
+                            bs_request_event.requestor_instance_id = it.get_u32();
+
+                        } else if (attr_type == NAN_ATTRIBUTE_MAC_ADDR) {
+                            memcpy(bs_request_event.peer_disc_mac_addr,
+                                    it.get_data(), NAN_MAC_ADDR_LEN);
+                            ALOGI("Discovery MAC addr of the peer/initiator: " MACSTR "\n",
+                                    MAC2STR(bs_request_event.peer_disc_mac_addr));
+
+                        } else if (attr_type == NAN_ATTRIBUTE_INST_ID) {
+                            ALOGI("BS instance id: %u\n", it.get_u32());
+                            bs_request_event.bootstrapping_instance_id = it.get_u32();
+                            if ((bs_request_event.bootstrapping_instance_id <= NAN_MIN) ||
+                                    (bs_request_event.bootstrapping_instance_id > NAN_MAX)) {
+                                ALOGE("INVALID bootstrapping instance id: %u\n",
+                                        bs_request_event.bootstrapping_instance_id);
+                                goto fail;
+                            }
+
+                        } else if (attr_type == NAN_ATTRIBUTE_BS_METHODS) {
+                            ALOGI("Peer BS methods: %u\n", it.get_u16());
+                            bs_request_event.request_bootstrapping_method = it.get_u16();
+
+                        }
+                    }
+
+                    if (!bs_request_event.publish_subscribe_id ||
+                            !bs_request_event.requestor_instance_id ||
+                            !bs_request_event.bootstrapping_instance_id ||
+                            !bs_request_event.request_bootstrapping_method) {
+                        ALOGE("Check invalid params recvd pub_sub_id: 0x%x req_inst_id: %u"
+                                "bootstrapping_id: %u bs_methods 0x%x\n",
+                                bs_request_event.publish_subscribe_id,
+                                bs_request_event.requestor_instance_id,
+                                bs_request_event.bootstrapping_instance_id,
+                                bs_request_event.request_bootstrapping_method);
+                        goto fail;
+                    }
+
+                    GET_NAN_HANDLE(info)->mHandlers.EventBootstrappingRequest(&bs_request_event);
+                    break;
+                }
+                case NAN_EVENT_BOOTSTRAPPING_CONFIRMATION: {
+                    NanBootstrappingConfirmInd bs_confirm_event;
+                    memset(&bs_confirm_event, 0, sizeof(NanBootstrappingConfirmInd));
+                    ALOGI("Received NAN_EVENT_BOOTSTRAPPING_CONFIRMATION\n");
+
+                    for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
+                        attr_type = it.get_type();
+
+                        if (attr_type == NAN_ATTRIBUTE_INST_ID) {
+                            ALOGI("bootstrapping instance id: %u\n", it.get_u32());
+                            bs_confirm_event.bootstrapping_instance_id = it.get_u32();
+
+                            if ((bs_confirm_event.bootstrapping_instance_id <= NAN_MIN) ||
+                                    (bs_confirm_event.bootstrapping_instance_id > NAN_MAX)) {
+                                ALOGE("INVALID bootstrapping instance id: %u\n",
+                                        bs_confirm_event.bootstrapping_instance_id);
+                                goto fail;
+                            }
+
+                        } else if (attr_type == NAN_ATTRIBUTE_RSP_CODE) {
+                            ALOGI("response code: %u\n", (NanBootstrappingResponseCode)it.get_u8());
+                            bs_confirm_event.rsp_code = (NanBootstrappingResponseCode)it.get_u8();
+
+                        } else if (attr_type == NAN_ATTRIBUTE_STATUS) {
+                            ALOGI("reason_code: %u\n", (NanStatusType)it.get_u8());
+                            bs_confirm_event.reason_code = (NanStatusType)it.get_u8();
+
+                        } else if (attr_type == NAN_ATTRIBUTE_COME_BACK_DELAY) {
+                            ALOGI("comeback delay: %u\n", it.get_u32());
+                            bs_confirm_event.come_back_delay = it.get_u32();
+
+                        } else if (attr_type == NAN_ATTRIBUTE_COOKIE_LEN) {
+                            ALOGI("cookie len: %u\n", it.get_u32());
+                            bs_confirm_event.cookie_length = it.get_u32();
+
+                        } else if (attr_type == NAN_ATTRIBUTE_COOKIE) {
+                            memcpy(bs_confirm_event.cookie, it.get_data(),
+                                    bs_confirm_event.cookie_length);
+                            prhex("cookie :", bs_confirm_event.cookie,
+                                    bs_confirm_event.cookie_length);
+
+                        }
+                    }
+
+                    if (!bs_confirm_event.bootstrapping_instance_id) {
+                        ALOGE("Check invalid bootstrapping_id: %u recvd\n",
+                                bs_confirm_event.bootstrapping_instance_id);
+                        goto fail;
+                    }
+
+                    GET_NAN_HANDLE(info)->mHandlers.EventBootstrappingConfirm(&bs_confirm_event);
+                    break;
+                }
 
                 case NAN_EVENT_UNKNOWN:
                     ALOGI("Received NAN_EVENT_UNKNOWN\n");
@@ -5534,6 +7441,12 @@
                 free(ndp_end_event);
             }
             return NL_SKIP;
+fail:
+            ALOGE("Dropping Pairing Event %d, invalid params received \n", cmd);
+            if (ndp_end_event) {
+                free(ndp_end_event);
+            }
+            return NL_STOP;
         }
 };
 
@@ -5562,7 +7475,12 @@
     ret = (wifi_error)cmd->open();
     if (ret != WIFI_SUCCESS) {
         ALOGE("%s : failed in open, error = %d\n", __func__, ret);
+    } else if (!get_halutil_mode()) {
+        /* WAR to cache the nan capabilities */
+        ALOGI("get nan capabilities\n");
+        nan_get_capabilities(0, iface);
     }
+
     cmd->releaseRef();
 
     NAN_DBG_EXIT();
@@ -5606,6 +7524,10 @@
 #endif /* CONFIG_BRCM */
     counters.dp_req++;
     if (msg->service_name_len) {
+        if (msg->service_name_len > NAN_MAX_SERVICE_NAME_LEN) {
+            ALOGE("%s: Invalid svc len %d\n", __func__, msg->service_name_len);
+            goto done;
+        }
         if (strncmp(NAN_OOB_INTEROP_SVC_NAME,
                     (char*)msg->service_name, msg->service_name_len) == 0) {
             ALOGI("Use Hardcoded svc_hash\n");
@@ -5691,6 +7613,11 @@
 #endif /* CONFIG_BRCM */
     counters.dp_resp++;
     if (msg->service_name_len) {
+        if (msg->service_name_len > NAN_MAX_SERVICE_NAME_LEN) {
+            ALOGE("%s: Invalid svc len %d\n", __func__, msg->service_name_len);
+            goto done;
+        }
+
         if (strncmp(NAN_OOB_INTEROP_SVC_NAME,
                     (char*)msg->service_name, msg->service_name_len) == 0) {
             ALOGI("Use Hardcoded svc_hash\n");
diff --git a/bcmdhd/wifi_hal/rtt.cpp b/bcmdhd/wifi_hal/rtt.cpp
index 4546f4d..c4adace 100644
--- a/bcmdhd/wifi_hal/rtt.cpp
+++ b/bcmdhd/wifi_hal/rtt.cpp
@@ -46,8 +46,10 @@
 #include "cpp_bindings.h"
 
 using namespace android;
+#define RTT_RESULT_V3_SIZE (sizeof(wifi_rtt_result_v3))
 #define RTT_RESULT_V2_SIZE (sizeof(wifi_rtt_result_v2))
 #define RTT_RESULT_V1_SIZE (sizeof(wifi_rtt_result))
+#define UNSPECIFIED -1 // wifi HAL common definition for unspecified value
 typedef enum {
 
     RTT_SUBCMD_SET_CONFIG = ANDROID_NL80211_SUBCMD_RTT_RANGE_START,
@@ -76,6 +78,9 @@
     RTT_ATTRIBUTE_TARGET_BURST_DURATION     = 14,
     RTT_ATTRIBUTE_TARGET_PREAMBLE           = 15,
     RTT_ATTRIBUTE_TARGET_BW                 = 16,
+    RTT_ATTRIBUTE_TARGET_NTB_MIN_MEAS_TIME  = 17,
+    RTT_ATTRIBUTE_TARGET_NTB_MAX_MEAS_TIME  = 18,
+    /* Add Attributes related to the event */
     RTT_ATTRIBUTE_RESULTS_COMPLETE          = 30,
     RTT_ATTRIBUTE_RESULTS_PER_TARGET        = 31,
     RTT_ATTRIBUTE_RESULT_CNT                = 32,
@@ -83,6 +88,10 @@
     RTT_ATTRIBUTE_RESUTL_DETAIL             = 34,
     RTT_ATTRIBUTE_RESULT_FREQ               = 35,
     RTT_ATTRIBUTE_RESULT_BW                 = 36,
+    RTT_ATTRIBUTE_RESULT_I2R_TX_LTF_RPT_CNT = 37,
+    RTT_ATTRIBUTE_RESULT_R2I_TX_LTF_RPT_CNT = 38,
+    RTT_ATTRIBUTE_RESULT_NTB_MIN_MEAS_TIME  = 39,
+    RTT_ATTRIBUTE_RESULT_NTB_MAX_MEAS_TIME  = 40,
     /* Add any new RTT_ATTRIBUTE prior to RTT_ATTRIBUTE_MAX */
     RTT_ATTRIBUTE_MAX
 } RTT_ATTRIBUTE;
@@ -140,9 +149,9 @@
 
 class GetRttCapabilitiesCommand : public WifiCommand
 {
-    wifi_rtt_capabilities *mCapabilities;
+    wifi_rtt_capabilities_v3 *mCapabilities;
 public:
-    GetRttCapabilitiesCommand(wifi_interface_handle iface, wifi_rtt_capabilities *capabitlites)
+    GetRttCapabilitiesCommand(wifi_interface_handle iface, wifi_rtt_capabilities_v3 *capabitlites)
         : WifiCommand("GetRttCapabilitiesCommand", iface, 0), mCapabilities(capabitlites)
     {
         memset(mCapabilities, 0, sizeof(*mCapabilities));
@@ -237,14 +246,16 @@
 {
     wifi_channel_info  mChannelInfo;
     wifi_rtt_responder* mResponderInfo;
-    unsigned m_max_duration_sec;
+    unsigned int m_max_duration_sec;
 public:
     EnableResponderCommand(wifi_interface_handle iface, int id, wifi_channel_info channel_hint,
             unsigned max_duration_seconds, wifi_rtt_responder *responderInfo)
             : WifiCommand("EnableResponderCommand", iface, 0), mChannelInfo(channel_hint),
-            m_max_duration_sec(max_duration_seconds), mResponderInfo(responderInfo)
+            mResponderInfo(responderInfo), m_max_duration_sec(max_duration_seconds)
     {
         memset(mResponderInfo, 0, sizeof(*mResponderInfo));
+        memset(&mChannelInfo, 0, sizeof(mChannelInfo));
+        m_max_duration_sec = 0;
     }
 
     virtual int create() {
@@ -318,31 +329,42 @@
 {
     unsigned numRttParams;
     int mCompleted;
-    int currentIdx;
-    int currDtlIdx;
-    int totalCnt;
+    int currentIdx = 0;
+    int totalCnt = 0;
     static const int MAX_RESULTS = 1024;
-    wifi_rtt_result_v2 *rttResults[MAX_RESULTS];
-    wifi_rtt_config *rttParams;
-    wifi_rtt_event_handler rttHandler;
-    int nextidx = 0;
     wifi_rtt_result *rttResultsV1[MAX_RESULTS];
-    wifi_channel channel;
-    wifi_rtt_bw bw = WIFI_RTT_BW_UNSPECIFIED;
-    int result_size;
-    int opt_result_size;
+    wifi_rtt_result_v2 *rttResultsV2[MAX_RESULTS];
+    wifi_rtt_result_v3 *rttResultsV3[MAX_RESULTS];
+    wifi_rtt_config_v3 *rttParams;
+    wifi_rtt_event_handler_v3 rttHandler;
+    int nextidx = 0;
+    wifi_channel channel = 0;
+    wifi_rtt_bw bw;
+    int result_size = 0;
+    int opt_result_size = 0;
+    u8 i2r_tx_ltf_repetition_count = 0;
+    u8 r2i_tx_ltf_repetition_count = 0;
+    u32 ntb_min_measurement_time = 0;
+    u32 ntb_max_measurement_time = 0;
+
 public:
     RttCommand(wifi_interface_handle iface, int id, unsigned num_rtt_config,
-            wifi_rtt_config rtt_config[], wifi_rtt_event_handler handler)
+            wifi_rtt_config_v3 rtt_config[], wifi_rtt_event_handler_v3 handler)
         : WifiCommand("RttCommand", iface, id), numRttParams(num_rtt_config), rttParams(rtt_config),
         rttHandler(handler)
     {
-        memset(rttResults, 0, sizeof(rttResults));
         memset(rttResultsV1, 0, sizeof(rttResultsV1));
+        memset(rttResultsV2, 0, sizeof(rttResultsV2));
+        memset(rttResultsV3, 0, sizeof(rttResultsV3));
         currentIdx = 0;
         mCompleted = 0;
         totalCnt = 0;
-        currDtlIdx = 0;
+        channel = 0;
+        result_size = 0;
+        opt_result_size = 0;
+        channel = 0;
+        result_size = 0;
+        opt_result_size = 0;
     }
 
     RttCommand(wifi_interface_handle iface, int id)
@@ -351,12 +373,15 @@
         currentIdx = 0;
         mCompleted = 0;
         totalCnt = 0;
-        currDtlIdx = 0;
         numRttParams = 0;
-        memset(rttResults, 0, sizeof(rttResults));
         memset(rttResultsV1, 0, sizeof(rttResultsV1));
+        memset(rttResultsV2, 0, sizeof(rttResultsV2));
+        memset(rttResultsV3, 0, sizeof(rttResultsV3));
         rttParams = NULL;
-        rttHandler.on_rtt_results_v2 = NULL;
+        rttHandler.on_rtt_results_v3 = NULL;
+        channel = 0;
+        result_size = 0;
+        opt_result_size = 0;
     }
 
     int createSetupRequest(WifiRequest& request) {
@@ -377,85 +402,102 @@
                 return WIFI_ERROR_OUT_OF_MEMORY;
             }
 
-            result = request.put_addr(RTT_ATTRIBUTE_TARGET_MAC, rttParams[i].addr);
+            result = request.put_addr(RTT_ATTRIBUTE_TARGET_MAC, rttParams[i].rtt_config.addr);
             if (result < 0) {
                 return result;
             }
 
-            result = request.put_u8(RTT_ATTRIBUTE_TARGET_TYPE, rttParams[i].type);
+            result = request.put_u8(RTT_ATTRIBUTE_TARGET_TYPE, rttParams[i].rtt_config.type);
             if (result < 0) {
                 return result;
             }
 
-            result = request.put_u8(RTT_ATTRIBUTE_TARGET_PEER, rttParams[i].peer);
+            result = request.put_u8(RTT_ATTRIBUTE_TARGET_PEER, rttParams[i].rtt_config.peer);
             if (result < 0) {
                 return result;
             }
 
-            result = request.put(RTT_ATTRIBUTE_TARGET_CHAN, &rttParams[i].channel,
+            result = request.put(RTT_ATTRIBUTE_TARGET_CHAN, &rttParams[i].rtt_config.channel,
                     sizeof(wifi_channel_info));
             if (result < 0) {
                 return result;
             }
 
-            result = request.put_u32(RTT_ATTRIBUTE_TARGET_NUM_BURST, rttParams[i].num_burst);
+            result = request.put_u32(RTT_ATTRIBUTE_TARGET_NUM_BURST,
+                    rttParams[i].rtt_config.num_burst);
             if (result < 0) {
                 return result;
             }
 
             result = request.put_u32(RTT_ATTRIBUTE_TARGET_NUM_FTM_BURST,
-                    rttParams[i].num_frames_per_burst);
+                    rttParams[i].rtt_config.num_frames_per_burst);
             if (result < 0) {
                 return result;
             }
 
             result = request.put_u32(RTT_ATTRIBUTE_TARGET_NUM_RETRY_FTM,
-                    rttParams[i].num_retries_per_rtt_frame);
+                    rttParams[i].rtt_config.num_retries_per_rtt_frame);
             if (result < 0) {
                 return result;
             }
 
             result = request.put_u32(RTT_ATTRIBUTE_TARGET_NUM_RETRY_FTMR,
-                    rttParams[i].num_retries_per_ftmr);
+                    rttParams[i].rtt_config.num_retries_per_ftmr);
             if (result < 0) {
                 return result;
             }
 
             result = request.put_u32(RTT_ATTRIBUTE_TARGET_PERIOD,
-                    rttParams[i].burst_period);
+                    rttParams[i].rtt_config.burst_period);
             if (result < 0) {
                 return result;
             }
 
             result = request.put_u32(RTT_ATTRIBUTE_TARGET_BURST_DURATION,
-                    rttParams[i].burst_duration);
+                    rttParams[i].rtt_config.burst_duration);
             if (result < 0) {
                 return result;
             }
 
             result = request.put_u8(RTT_ATTRIBUTE_TARGET_LCI,
-                    rttParams[i].LCI_request);
+                    rttParams[i].rtt_config.LCI_request);
             if (result < 0) {
                 return result;
             }
 
             result = request.put_u8(RTT_ATTRIBUTE_TARGET_LCR,
-                    rttParams[i].LCR_request);
+                    rttParams[i].rtt_config.LCR_request);
             if (result < 0) {
                 return result;
             }
 
             result = request.put_u8(RTT_ATTRIBUTE_TARGET_BW,
-                    rttParams[i].bw);
+                    rttParams[i].rtt_config.bw);
             if (result < 0) {
                 return result;
             }
 
             result = request.put_u8(RTT_ATTRIBUTE_TARGET_PREAMBLE,
-                    rttParams[i].preamble);
+                    rttParams[i].rtt_config.preamble);
             if (result < 0) {
                 return result;
             }
+
+            /* Below params are applicable for only 11az ranging */
+            if (rttParams[i].rtt_config.type == RTT_TYPE_2_SIDED_11AZ_NTB) {
+                result = request.put_u32(RTT_ATTRIBUTE_TARGET_NTB_MIN_MEAS_TIME,
+                        rttParams[i].ntb_min_measurement_time);
+                if (result < 0) {
+                    return result;
+                }
+
+                result = request.put_u32(RTT_ATTRIBUTE_TARGET_NTB_MAX_MEAS_TIME,
+                        rttParams[i].ntb_max_measurement_time);
+                if (result < 0) {
+                    return result;
+                }
+            }
+
             request.attr_end(attr2);
         }
 
@@ -471,11 +513,11 @@
         }
 
         nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
-	result = request.put_u8(RTT_ATTRIBUTE_TARGET_CNT, num_devices);
+        result = request.put_u8(RTT_ATTRIBUTE_TARGET_CNT, num_devices);
 
-	if (result < 0) {
-		return result;
-	}
+        if (result < 0) {
+            return result;
+        }
         for(unsigned i = 0; i < num_devices; i++) {
             result = request.put_addr(RTT_ATTRIBUTE_TARGET_MAC, addr[i]);
             if (result < 0) {
@@ -485,6 +527,7 @@
         request.attr_end(data);
         return result;
     }
+
     int start() {
         ALOGD("Setting RTT configuration");
         WifiRequest request(familyId(), ifaceId());
@@ -495,6 +538,7 @@
         }
 
         registerVendorHandler(GOOGLE_OUI, RTT_EVENT_COMPLETE);
+
         result = requestResponse(request);
         if (result != WIFI_SUCCESS) {
             unregisterVendorHandler(GOOGLE_OUI, RTT_EVENT_COMPLETE);
@@ -521,6 +565,7 @@
         }
 
         unregisterVendorHandler(GOOGLE_OUI, RTT_EVENT_COMPLETE);
+        ALOGD("Stopped RTT");
         return WIFI_SUCCESS;
     }
 
@@ -555,53 +600,95 @@
             ALOGI("No rtt results found");
             return NL_STOP;
         }
+
         for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
             if (it.get_type() == RTT_ATTRIBUTE_RESULTS_COMPLETE) {
                 mCompleted = it.get_u32();
-                ALOGI("retrieved completed flag : %d\n", mCompleted);
+                ALOGI("Completed flag : %d\n", mCompleted);
             } else if (it.get_type() == RTT_ATTRIBUTE_RESULTS_PER_TARGET) {
                 int result_cnt = 0;
                 mac_addr bssid;
                 for (nl_iterator it2(it.get()); it2.has_next(); it2.next()) {
                     if (it2.get_type() == RTT_ATTRIBUTE_TARGET_MAC) {
                         memcpy(bssid, it2.get_data(), sizeof(mac_addr));
-                        ALOGI("retrived target mac : %02x:%02x:%02x:%02x:%02x:%02x\n",
-                                bssid[0],
-                                bssid[1],
-                                bssid[2],
-                                bssid[3],
-                                bssid[4],
-                                bssid[5]);
+                        ALOGI("target mac : %02x:%02x:%02x:%02x:%02x:%02x\n",
+                                bssid[0], bssid[1], bssid[2], bssid[3],
+                                bssid[4], bssid[5]);
                     } else if (it2.get_type() == RTT_ATTRIBUTE_RESULT_FREQ) {
                         channel = it2.get_u32();
-                        if (rttResults[currentIdx] == NULL) {
+                        if (rttResultsV3[currentIdx] == NULL) {
                             ALOGE("Not allocated, currentIdx %d\n", currentIdx);
                             break;
                         }
                         if (!channel) {
-                            rttResults[currentIdx]->frequency = UNSPECIFIED;
+                            rttResultsV3[currentIdx]->rtt_result.frequency =
+                                    UNSPECIFIED;
                         } else {
-                            rttResults[currentIdx]->frequency = channel;
+                            rttResultsV3[currentIdx]->rtt_result.frequency =
+                                    channel;
                         }
-                        ALOGI("retrieved rtt_result : \n\tchannel :%d",
-                            rttResults[currentIdx]->frequency);
+
+                        ALOGI("rtt_resultV3 : \n\tchannel :%d",
+                                rttResultsV3[currentIdx]->rtt_result.frequency);
                     } else if (it2.get_type() == RTT_ATTRIBUTE_RESULT_BW) {
                         bw = (wifi_rtt_bw)it2.get_u32();
-                        if (rttResults[currentIdx] == NULL) {
+                        if (rttResultsV3[currentIdx] == NULL) {
                             ALOGE("Not allocated, currentIdx %d\n", currentIdx);
                             break;
                         }
-                        rttResults[currentIdx]->packet_bw = bw;
-                        ALOGI("retrieved rtt_result : \n\tpacket_bw :%d",
-                            rttResults[currentIdx]->packet_bw);
+                        rttResultsV3[currentIdx]->rtt_result.packet_bw =
+                                bw;
+
+                        ALOGI("rtt_resultV3 : \n\tpacket_bw :%d",
+                               rttResultsV3[currentIdx]->rtt_result.packet_bw);
                     } else if (it2.get_type() == RTT_ATTRIBUTE_RESULT_CNT) {
                         result_cnt = it2.get_u32();
-                        ALOGI("retrieved result_cnt : %d\n", result_cnt);
+                        ALOGI("result_cnt : %d\n", result_cnt);
+                    } else if (it2.get_type() == RTT_ATTRIBUTE_RESULT_I2R_TX_LTF_RPT_CNT) {
+                        i2r_tx_ltf_repetition_count = it2.get_u8();
+                        if (rttResultsV3[currentIdx] == NULL) {
+                            ALOGE("Not allocated, currentIdx %d\n", currentIdx);
+                            break;
+                        }
+                        rttResultsV3[currentIdx]->i2r_tx_ltf_repetition_count =
+                                i2r_tx_ltf_repetition_count;
+                        ALOGI("rtt_resultv3 : \n\ti2r_tx_ltf_repetition_count :%d",
+                                rttResultsV3[currentIdx]->i2r_tx_ltf_repetition_count);
+                    } else if (it2.get_type() == RTT_ATTRIBUTE_RESULT_R2I_TX_LTF_RPT_CNT) {
+                        r2i_tx_ltf_repetition_count = it2.get_u8();
+                        if (rttResultsV3[currentIdx] == NULL) {
+                            ALOGE("Not allocated, currentIdx %d\n", currentIdx);
+                            break;
+                        }
+                        rttResultsV3[currentIdx]->r2i_tx_ltf_repetition_count =
+                                r2i_tx_ltf_repetition_count;
+                        ALOGI("rtt_resultv3 : \n\tr2i_tx_ltf_repetition_count :%d",
+                                rttResultsV3[currentIdx]->r2i_tx_ltf_repetition_count);
+                    } else if (it2.get_type() == RTT_ATTRIBUTE_RESULT_NTB_MIN_MEAS_TIME) {
+                        ntb_min_measurement_time = it2.get_u32();
+                        if (rttResultsV3[currentIdx] == NULL) {
+                            ALOGE("Not allocated, currentIdx %d\n", currentIdx);
+                            break;
+                        }
+                        rttResultsV3[currentIdx]->ntb_min_measurement_time =
+                                ntb_min_measurement_time;
+                        ALOGI("rtt_resultv3 : \n\t ntb_min_measurement_time :%lu units of 100 us",
+                                rttResultsV3[currentIdx]->ntb_min_measurement_time);
+                    } else if (it2.get_type() == RTT_ATTRIBUTE_RESULT_NTB_MAX_MEAS_TIME) {
+                        ntb_max_measurement_time = it2.get_u32();
+                        if (rttResultsV3[currentIdx] == NULL) {
+                            ALOGE("Not allocated, currentIdx %d\n", currentIdx);
+                            break;
+                        }
+                        rttResultsV3[currentIdx]->ntb_max_measurement_time =
+                                ntb_max_measurement_time;
+                        ALOGI("rtt_resultv3 : \n\t ntb_max_measurement_time:%lu units of 10ms",
+                                rttResultsV3[currentIdx]->ntb_max_measurement_time);
                     } else if (it2.get_type() == RTT_ATTRIBUTE_RESULT) {
                         currentIdx = nextidx;
                         int result_len = it2.get_len();
                         rttResultsV1[currentIdx] =
-                            (wifi_rtt_result *)malloc(it2.get_len());
+                                (wifi_rtt_result *)malloc(it2.get_len());
                         wifi_rtt_result *rtt_results_v1 = rttResultsV1[currentIdx];
                         if (rtt_results_v1 == NULL) {
                             mCompleted = 1;
@@ -633,7 +720,7 @@
                                             rtt_results_v1->LCR = (wifi_information_element *)ele_2;
                                         }
                                     }
-                                } else if (ele_1->type == DOT11_MEASURE_TYPE_CIVICLOC){
+                                } else if (ele_1->type == DOT11_MEASURE_TYPE_CIVICLOC) {
                                     rtt_results_v1->LCR = (wifi_information_element *)ele_1;
                                     result_len -= (ele_1->len + DOT11_HDR_LEN);
                                     opt_result_size += (ele_1->len + DOT11_HDR_LEN);
@@ -650,79 +737,105 @@
                             }
                         }
 
-                        /* Alloc new struct including new elements, reserve for new elements */
-                        rttResults[currentIdx] =
-                            (wifi_rtt_result_v2 *)malloc(RTT_RESULT_V2_SIZE + opt_result_size);
-                        wifi_rtt_result_v2 *rtt_result_v2 = rttResults[currentIdx];
+                        /* Alloc struct v2 including new elements of ver2 */
+                        rttResultsV2[currentIdx] =
+                                (wifi_rtt_result_v2 *)malloc(RTT_RESULT_V2_SIZE + opt_result_size);
+                        wifi_rtt_result_v2 *rtt_result_v2 = rttResultsV2[currentIdx];
                         if (rtt_result_v2 == NULL) {
                             ALOGE("failed to allocate the rtt_result\n");
                             break;
                         }
 
-                        /* Populate the new struct as per the legacy struct elements */
+                        /* Populate the v2 result struct as per the v1 result struct elements */
                         memcpy(&rtt_result_v2->rtt_result,
-                            (wifi_rtt_result *)rtt_results_v1, RTT_RESULT_V1_SIZE);
+                                (wifi_rtt_result *)rtt_results_v1, RTT_RESULT_V1_SIZE);
                         if (!channel) {
                             rtt_result_v2->frequency = UNSPECIFIED;
                         }
 
-                        /* Copy the optional data to new struct */
+                        /* Copy the optional v1 data to v2 struct */
                         if (opt_result_size &&
                             (opt_result_size == (it2.get_len() - RTT_RESULT_V1_SIZE))) {
 
-                            wifi_rtt_result_v2 *opt_rtt_result = NULL;
-                            /* Intersect the optional data from legacy rtt result struct */
-                            wifi_rtt_result *opt_legacy_rtt_result =
-                                (wifi_rtt_result *)(rtt_results_v1 + RTT_RESULT_V1_SIZE);
+                            wifi_rtt_result_v2 *opt_rtt_result_v2 = NULL;
+                            /* Intersect the optional data from v1 rtt result struct */
+                            wifi_rtt_result *opt_rtt_result_v1 =
+                                    (wifi_rtt_result *)(rtt_results_v1 + 1);
 
-                            /* shift dest buf by size of new rtt result struct */
-                            opt_rtt_result =
-                                (wifi_rtt_result_v2 *)rtt_result_v2 + RTT_RESULT_V2_SIZE;
+                            /* Move to v2 ptr to the start of the optional params */
+                            opt_rtt_result_v2 =
+                                    (wifi_rtt_result_v2 *)(rtt_result_v2 + 1);
 
-                            /* Append optional rtt_result_v1 data to rtt_result_v2 */
-                            memcpy(opt_rtt_result, opt_legacy_rtt_result,
-                                (it2.get_len() - RTT_RESULT_V1_SIZE));
+                            /* Append optional rtt_result_v1 data to optional rtt_result_v2 */
+                            memcpy(opt_rtt_result_v2, opt_rtt_result_v1,
+                                    (it2.get_len() - RTT_RESULT_V1_SIZE));
                         } else {
                            ALOGI("Optional rtt result elements missing, skip processing\n");
                         }
 
+                        /* Alloc struct v3 including new elements, reserve for new elements */
+                        rttResultsV3[currentIdx] =
+                                (wifi_rtt_result_v3 *)malloc(RTT_RESULT_V3_SIZE + opt_result_size);
+                        wifi_rtt_result_v3 *rtt_result_v3 = rttResultsV3[currentIdx];
+                        if (rtt_result_v3 == NULL) {
+                            ALOGE("failed to allocate the rtt_result ver3\n");
+                            break;
+                        }
+
+                        /* Populate the v3 struct with v1 struct, v1 struct opt + v2 struct + v2 struct opt */
+                        memcpy(&rtt_result_v3->rtt_result,
+                                (wifi_rtt_result_v2 *)rtt_result_v2,
+                                RTT_RESULT_V2_SIZE + opt_result_size);
+
                         totalCnt++;
-                        ALOGI("retrieved rtt_result : \n\tburst_num :%d, measurement_number : %d"
-                                ", success_number : %d \tnumber_per_burst_peer : %d, status : %s,"
-                                " retry_after_duration : %d s\n \trssi : %d dbm,"
-                                " rx_rate : %d Kbps, rtt : %lu ns, rtt_sd : %lu\n"
-                                "\tdistance : %d cm, burst_duration : %d ms,"
-                                " negotiated_burst_num : %d\n",
-                                rtt_results_v1->burst_num, rtt_results_v1->measurement_number,
-                                rtt_results_v1->success_number,
-                                rtt_results_v1->number_per_burst_peer,
-                                get_err_info(rtt_results_v1->status),
-                                rtt_results_v1->retry_after_duration,
-                                rtt_results_v1->rssi, rtt_results_v1->rx_rate.bitrate * 100,
-                                (unsigned long)rtt_results_v1->rtt/1000,
-                                (unsigned long)rtt_results_v1->rtt_sd,
-                                rtt_results_v1->distance_mm / 10,
-                                rtt_results_v1->burst_duration,
-                                rtt_results_v1->negotiated_burst_num);
                         nextidx = currentIdx;
                         nextidx++;
                     }
                 }
+                ALOGI("Current Id: %d: retrieved rtt_resultv3 :\n"
+                            " burst_num : %d, measurement_number : %d,\n"
+                            " success_number : %d, number_per_burst_peer : %d, status : %s,\n"
+                            " retry_after_duration : %d rssi : %d dbm,\n"
+                            " rx_rate : %d Kbps, rtt : %lu pss, rtt_sd : %lu ps,\n"
+                            " distance : %d mm, burst_duration : %d ms, freq : %d,\n"
+                            " packet_bw : %d, negotiated_burst_num : %d\n",
+                            currentIdx,
+                            rttResultsV3[currentIdx]->rtt_result.rtt_result.burst_num,
+                            rttResultsV3[currentIdx]->rtt_result.rtt_result.measurement_number,
+                            rttResultsV3[currentIdx]->rtt_result.rtt_result.success_number,
+                            rttResultsV3[currentIdx]->rtt_result.rtt_result.number_per_burst_peer,
+                            get_err_info(rttResultsV3[currentIdx]->rtt_result.rtt_result.status),
+                            rttResultsV3[currentIdx]->rtt_result.rtt_result.retry_after_duration,
+                            rttResultsV3[currentIdx]->rtt_result.rtt_result.rssi,
+                            rttResultsV3[currentIdx]->rtt_result.rtt_result.rx_rate.bitrate * 100,
+                            (unsigned long)rttResultsV3[currentIdx]->rtt_result.rtt_result.rtt,
+                            (unsigned long)rttResultsV3[currentIdx]->rtt_result.rtt_result.rtt_sd,
+                            rttResultsV3[currentIdx]->rtt_result.rtt_result.distance_mm,
+                            rttResultsV3[currentIdx]->rtt_result.rtt_result.burst_duration,
+                            rttResultsV3[currentIdx]->rtt_result.frequency,
+                            rttResultsV3[currentIdx]->rtt_result.packet_bw,
+                            rttResultsV3[currentIdx]->rtt_result.rtt_result.negotiated_burst_num);
+
             }
         }
+
         if (mCompleted) {
             unregisterVendorHandler(GOOGLE_OUI, RTT_EVENT_COMPLETE);
             {
-                if (*rttHandler.on_rtt_results_v2) {
-                    (*rttHandler.on_rtt_results_v2)(id(), totalCnt, rttResults);
+                if (*rttHandler.on_rtt_results_v3) {
+                    (*rttHandler.on_rtt_results_v3)(id(), totalCnt, rttResultsV3);
                 }
             }
-            for (int i = 0; i < currentIdx; i++) {
-                free(rttResults[i]);
-                rttResults[i] = NULL;
 
+            for (int i = 0; i < currentIdx; i++) {
                 free(rttResultsV1[i]);
                 rttResultsV1[i] = NULL;
+
+                free(rttResultsV2[i]);
+                rttResultsV2[i] = NULL;
+
+                free(rttResultsV3[i]);
+                rttResultsV3[i] = NULL;
             }
             totalCnt = currentIdx = nextidx = 0;
             WifiCommand *cmd = wifi_unregister_cmd(wifiHandle(), id());
@@ -735,18 +848,19 @@
 
 
 /* API to request RTT measurement */
-wifi_error wifi_rtt_range_request(wifi_request_id id, wifi_interface_handle iface,
-        unsigned num_rtt_config, wifi_rtt_config rtt_config[], wifi_rtt_event_handler handler)
+wifi_error wifi_rtt_range_request_v3(wifi_request_id id, wifi_interface_handle iface,
+        unsigned num_rtt_config, wifi_rtt_config_v3 rtt_config[],
+        wifi_rtt_event_handler_v3 handler)
 {
     if (iface == NULL) {
-        ALOGE("wifi_rtt_range_request: NULL iface pointer provided."
-            " Exit.");
+        ALOGE("wifi_rtt_range_request_v3: NULL iface pointer provided."
+                " Exit.");
         return WIFI_ERROR_INVALID_ARGS;
     }
 
     wifi_handle handle = getWifiHandle(iface);
     if (handle == NULL) {
-        ALOGE("wifi_rtt_range_request: NULL handle pointer provided."
+        ALOGE("wifi_rtt_range_request_v3: NULL handle pointer provided."
             " Exit.");
         return WIFI_ERROR_INVALID_ARGS;
     }
@@ -795,19 +909,19 @@
 }
 
 /* API to get RTT capability */
-wifi_error wifi_get_rtt_capabilities(wifi_interface_handle iface,
-        wifi_rtt_capabilities *capabilities)
+wifi_error wifi_get_rtt_capabilities_v3(wifi_interface_handle iface,
+        wifi_rtt_capabilities_v3 *capabilities)
 {
     if (iface == NULL) {
-	ALOGE("wifi_get_rtt_capabilities: NULL iface pointer provided."
-		" Exit.");
-	return WIFI_ERROR_INVALID_ARGS;
+        ALOGE("wifi_get_rtt_capabilities_v3: NULL iface pointer provided."
+                " Exit.");
+        return WIFI_ERROR_INVALID_ARGS;
     }
 
     if (capabilities == NULL) {
-	ALOGE("wifi_get_rtt_capabilities: NULL capabilities pointer provided."
-		" Exit.");
-	return WIFI_ERROR_INVALID_ARGS;
+        ALOGE("wifi_get_rtt_capabilities_v3: NULL capabilities pointer provided."
+                " Exit.");
+        return WIFI_ERROR_INVALID_ARGS;
     }
 
     GetRttCapabilitiesCommand command(iface, capabilities);
diff --git a/bcmdhd/wifi_hal/sync.h b/bcmdhd/wifi_hal/sync.h
index 91c017f..acc9e70 100644
--- a/bcmdhd/wifi_hal/sync.h
+++ b/bcmdhd/wifi_hal/sync.h
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) 2017 The Android Open Source Project
  *
- * Portions copyright (C) 2023 Broadcom Limited
+ * Portions copyright (C) 2024 Broadcom Limited
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/bcmdhd/wifi_hal/twt.cpp b/bcmdhd/wifi_hal/twt.cpp
index 087c17a..8a55ec0 100755
--- a/bcmdhd/wifi_hal/twt.cpp
+++ b/bcmdhd/wifi_hal/twt.cpp
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) 2017 The Android Open Source Project
  *
- * Portions copyright (C) 2023 Broadcom Limited
+ * Portions copyright (C) 2024 Broadcom Limited
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -73,7 +73,6 @@
 
 };
 
-
 static const char *TwtCmdToString(int cmd)
 {
     switch (cmd) {
@@ -81,7 +80,7 @@
         C2S(TWT_INFO_FRAME_REQUEST);
         C2S(TWT_TEAR_DOWN_REQUEST);
         default:
-    return "UNKNOWN_NAN_CMD";
+        return "UNKNOWN_NAN_CMD";
     }
 }
 
@@ -163,7 +162,7 @@
                         ALOGI("status = %u\n", teardown_event.status);
                         break;
                     case TWT_ATTRIBUTE_ALL_TWT:
-                        teardown_event.all_twt = it.get_u8();
+                        teardown_event.all_twt = it.get_u32();
                         ALOGI("all_twt = %d\n", teardown_event.all_twt);
                         break;
                     case TWT_ATTRIBUTE_REASON_CODE:
@@ -197,7 +196,7 @@
                         ALOGI("status = %u\n", info_frame_event.status);
                         break;
                     case TWT_ATTRIBUTE_ALL_TWT:
-                        info_frame_event.all_twt = it.get_u8();
+                        info_frame_event.all_twt = it.get_u32();
                         ALOGI("all_twt = %d\n", info_frame_event.all_twt);
                         break;
                     case TWT_ATTRIBUTE_RESUMED:
@@ -362,12 +361,12 @@
 
         int id = reply.get_vendor_id();
         int subcmd = reply.get_vendor_subcmd();
-        uint32_t twt_device_cap, twt_peer_cap;
+        uint32_t twt_device_cap = 0, twt_peer_cap = 0, twt_num_stats = 0;
 
         nlattr *data = reply.get_attribute(NL80211_ATTR_VENDOR_DATA);
         int len = reply.get_vendor_data_len();
 
-        ALOGD("Id = %0x, subcmd = %d, len = %d", id, subcmd, len);
+        ALOGD("Id = %0x, subcmd = %d, len = %d, expected len = %d", id, subcmd, len);
         if (data == NULL || len == 0) {
             ALOGE("no vendor data in GetTwtCapabilitiesCommand response; ignoring it\n");
             return NL_SKIP;
@@ -377,12 +376,18 @@
             switch (it.get_type()) {
                 case TWT_ATTRIBUTE_DEVICE_CAP:
                     twt_device_cap = it.get_u32();
+                    ALOGI("TWT device cap %04x\n", twt_device_cap);
                     mCapabilities->device_capability = parseTwtCap(twt_device_cap);
                     break;
                 case TWT_ATTRIBUTE_PEER_CAP:
                     twt_peer_cap = it.get_u32();
+                    ALOGI("TWT peer cap %04x\n", twt_peer_cap);
                     mCapabilities->peer_capability = parseTwtCap(twt_peer_cap);
                     break;
+                case TWT_ATTRIBUTE_NUM_PEER_STATS:
+                    twt_num_stats = it.get_u32();
+                    ALOGI("TWT num stats %04x\n", twt_num_stats);
+                    break;
                 default:
                     ALOGE("Ignoring invalid attribute type = %d, size = %d\n",
                             it.get_type(), it.get_len());
@@ -425,6 +430,7 @@
         : WifiCommand("GetTwtStatsCommand", iface, 0), mConfig_id(config_id), mStats(stats)
     {
         memset(mStats, 0, sizeof(*mStats));
+        mConfig_id = 0;
     }
 
     virtual int create() {
@@ -463,7 +469,7 @@
         nlattr *data = reply.get_attribute(NL80211_ATTR_VENDOR_DATA);
         int len = reply.get_vendor_data_len();
 
-        ALOGD("Id = %0x, subcmd = %d, len = %d", id, subcmd, len);
+        ALOGD("Id = %0x, subcmd = %d, len = %d, expected len = %d", id, subcmd, len);
         if (data == NULL || len == 0) {
             ALOGE("no vendor data in GetTwtStatsCommand response; ignoring it\n");
             return NL_SKIP;
@@ -533,6 +539,7 @@
     ClearTwtStatsCommand(wifi_interface_handle iface, u8 config_id)
         : WifiCommand("ClearTwtStatsCommand", iface, 0), mConfig_id(config_id)
     {
+        mConfig_id = 0;
     }
 
     virtual int create() {
@@ -590,6 +597,10 @@
     {
     }
 
+    void setType(TwtRequestType type ) {
+        mType = type;
+    }
+
     int createRequest(WifiRequest& request)
     {
         ALOGI("TWT CMD: %s\n", TwtCmdToString(mType));
diff --git a/bcmdhd/wifi_hal/wifi_hal.cpp b/bcmdhd/wifi_hal/wifi_hal.cpp
index af9b06c..c057019 100644
--- a/bcmdhd/wifi_hal/wifi_hal.cpp
+++ b/bcmdhd/wifi_hal/wifi_hal.cpp
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) 2017 The Android Open Source Project
  *
- * Portions copyright (C) 2023 Broadcom Limited
+ * Portions copyright (C) 2024 Broadcom Limited
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -65,7 +65,7 @@
 
 #define WIFI_HAL_CMD_SOCK_PORT       644
 #define WIFI_HAL_EVENT_SOCK_PORT     645
-#define MAX_VIRTUAL_IFACES           5
+#define MAX_VIRTUAL_IFACES           6
 #define WIFI_HAL_EVENT_BUFFER_NOT_AVAILABLE 105
 
 /*
@@ -282,9 +282,9 @@
     fn->wifi_set_link_stats = wifi_set_link_stats;
     fn->wifi_clear_link_stats = wifi_clear_link_stats;
     fn->wifi_get_valid_channels = wifi_get_valid_channels;
-    fn->wifi_rtt_range_request = wifi_rtt_range_request;
+    fn->wifi_rtt_range_request_v3 = wifi_rtt_range_request_v3;
     fn->wifi_rtt_range_cancel = wifi_rtt_range_cancel;
-    fn->wifi_get_rtt_capabilities = wifi_get_rtt_capabilities;
+    fn->wifi_get_rtt_capabilities_v3 = wifi_get_rtt_capabilities_v3;
     fn->wifi_rtt_get_responder_info = wifi_rtt_get_responder_info;
     fn->wifi_enable_responder = wifi_enable_responder;
     fn->wifi_disable_responder = wifi_disable_responder;
@@ -369,6 +369,11 @@
     fn->wifi_enable_sta_channel_for_peer_network = wifi_enable_sta_channel_for_peer_network;
     fn->wifi_nan_suspend_request = wifi_nan_suspend_request;
     fn->wifi_nan_resume_request = wifi_nan_resume_request;
+    fn->wifi_nan_pairing_request = nan_pairing_request;
+    fn->wifi_nan_pairing_indication_response = nan_pairing_indication_response;
+    fn->wifi_nan_bootstrapping_request = nan_bootstrapping_request;
+    fn->wifi_nan_bootstrapping_indication_response = nan_bootstrapping_indication_response;
+    fn->wifi_nan_pairing_end = nan_pairing_end;
     return WIFI_SUCCESS;
 }
 #ifdef GOOGLE_WIFI_FW_CONFIG_VERSION_C_WRAPPER
@@ -707,11 +712,12 @@
         cmd_info *cmdi = &(info->cmd[bad_commands]);
         WifiCommand *cmd = cmdi->cmd;
         if (cmd != NULL) {
-            ALOGI("Cancelling command %p:%s", cmd, cmd->getType());
+            ALOGI("Cancelling command %p: %s", cmd, cmd->getType());
             pthread_mutex_unlock(&info->cb_lock);
             cmd->cancel();
             if (num_cmd == info->num_cmd) {
-                ALOGI("Cancelling command %p:%s did not work", cmd, (cmd ? cmd->getType(): ""));
+                ALOGI("Cancelling command %p: %s did not work",
+                    cmd, (cmd ? cmd->getType(): ""));
                 bad_commands++;
             }
             /* release reference added when command is saved */
@@ -753,7 +759,9 @@
     hal_info *info = getHalInfo(handle);
     struct nl_cb *cb = nl_socket_get_cb(info->event_sock);
     int res = nl_recvmsgs(info->event_sock, cb);
-    // ALOGD("nl_recvmsgs returned %d", res);
+    if (res) {
+        ALOGE("nl_recvmsgs returned %d", res);
+    }
     nl_cb_put(cb);
     return res;
 }
@@ -1237,6 +1245,7 @@
         {
             mProgram = NULL;
             mProgramLen = 0;
+            mReadProgram = NULL;
         }
 
         AndroidPktFilterCommand(wifi_interface_handle handle,
@@ -1247,6 +1256,7 @@
         {
             mVersion = NULL;
             mMaxLen = NULL;
+            mReadProgram = NULL;
         }
 
         AndroidPktFilterCommand(wifi_interface_handle handle,
@@ -1255,20 +1265,23 @@
                 mReadProgram(host_dst), mProgramLen(length),
                 mReqType(READ_APF_PROGRAM)
         {
+            mProgram = NULL;
+            mVersion = NULL;
+            mMaxLen = NULL;
         }
 
     int createRequest(WifiRequest& request) {
         if (mReqType == SET_APF_PROGRAM) {
-            ALOGI("\n%s: APF set program request\n", __FUNCTION__);
+            ALOGI("%s: APF set program request\n", __FUNCTION__);
             return createSetPktFilterRequest(request);
         } else if (mReqType == GET_APF_CAPABILITIES) {
-            ALOGI("\n%s: APF get capabilities request\n", __FUNCTION__);
+            ALOGI("%s: APF get capabilities request\n", __FUNCTION__);
 	    return createGetPktFilterCapabilitesRequest(request);
         } else if (mReqType == READ_APF_PROGRAM) {
-            ALOGI("\n%s: APF read packet filter request\n", __FUNCTION__);
+            ALOGI("%s: APF read packet filter request\n", __FUNCTION__);
             return createReadPktFilterRequest(request);
         } else {
-            ALOGE("\n%s Unknown APF request\n", __FUNCTION__);
+            ALOGE("%s Unknown APF request\n", __FUNCTION__);
             return WIFI_ERROR_NOT_SUPPORTED;
         }
         return WIFI_SUCCESS;
@@ -1276,9 +1289,17 @@
 
     int createSetPktFilterRequest(WifiRequest& request) {
         u8 *program = new u8[mProgramLen];
+        int result;
+
         NULL_CHECK_RETURN(program, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
-        ALOGE("Success to allocate program of len: %d\n", mProgramLen);
-        int result = request.create(GOOGLE_OUI, APF_SUBCMD_SET_FILTER);
+
+        ALOGI("mProgramLen : %d\n", mProgramLen);
+        if (mProgramLen > NL_MSG_DEFAULT_LEN) {
+            result = request.create_custom_len(GOOGLE_OUI, APF_SUBCMD_SET_FILTER,
+                    NL_MSG_MAX_LEN);
+        } else {
+            result = request.create(GOOGLE_OUI, APF_SUBCMD_SET_FILTER);
+        }
         if (result < 0) {
             ALOGE("Failed to create cmd: %d, err %d\n", APF_SUBCMD_SET_FILTER, result);
             delete[] program;
@@ -1335,7 +1356,6 @@
             ALOGI("Request Response failed for APF, result = %d", result);
             return result;
         }
-        ALOGI("Done!");
         return result;
     }
 
@@ -1969,7 +1989,7 @@
 {
     ALOGI("Stopping RSSI monitor %d", id);
 
-    if(id == -1) {
+    if (id == -1) {
         wifi_rssi_event_handler handler;
         s8 max_rssi = 0, min_rssi = 0;
         memset(&handler, 0, sizeof(handler));
@@ -2352,6 +2372,9 @@
             : WifiCommand("DscpCommand", handle, 0),
                     mReqType(RESET_DSCP_TABLE)
         {
+            mStart = 0;
+            mEnd = 0;
+            mAc = 0;
         }
 
     int createRequest(WifiRequest& request) {
@@ -2648,8 +2671,8 @@
             type = NL80211_IFTYPE_P2P_DEVICE;
             break;
         case WIFI_INTERFACE_TYPE_NAN:
-            type = NL80211_IFTYPE_NAN;
-            break;
+            ALOGE("%s: Unsupported interface type %u\n", __FUNCTION__, iface_type);
+            return WIFI_ERROR_NOT_SUPPORTED;
         default:
             ALOGE("%s: Wrong interface type %u\n", __FUNCTION__, iface_type);
             return WIFI_ERROR_UNKNOWN;
@@ -2729,6 +2752,7 @@
     MultiStaConfig(wifi_interface_handle handle)
     : WifiCommand("MultiStaConfig", handle, 0), mReqType(SET_PRIMARY_CONNECTION)
     {
+        mUseCase = WIFI_DUAL_STA_TRANSIENT_PREFER_PRIMARY;
     }
     MultiStaConfig(wifi_interface_handle handle, wifi_multi_sta_use_case use_case)
     : WifiCommand("MultiStaConfig", handle, 0), mUseCase(use_case), mReqType(SET_USE_CASE)
@@ -2875,11 +2899,11 @@
         ret = mMsg.put_u32(ANDR_WIFI_ATTRIBUTE_VOIP_MODE, mMode);
         ALOGE("mMode - %d", mMode);
         if (ret < 0) {
-	    ALOGE("Failed to set voip mode %d\n", mMode);
-	    return ret;
+             ALOGE("Failed to set voip mode %d\n", mMode);
+             return ret;
         }
 
-	ALOGI("Successfully configured voip mode %d\n", mMode);
+        ALOGI("Successfully configured voip mode %d\n", mMode);
         mMsg.attr_end(data);
         return WIFI_SUCCESS;
     }
diff --git a/bcmdhd/wifi_hal/wifi_logger.cpp b/bcmdhd/wifi_hal/wifi_logger.cpp
index 710054f..83431f6 100755
--- a/bcmdhd/wifi_hal/wifi_logger.cpp
+++ b/bcmdhd/wifi_hal/wifi_logger.cpp
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) 2017 The Android Open Source Project
  *
- * Portions copyright (C) 2023 Broadcom Limited
+ * Portions copyright (C) 2024 Broadcom Limited
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -195,6 +195,23 @@
     OTA_DOWNLOAD_TXCAP_BLOB_ATTR           = 0x0008,
 } OTA_DOWNLOAD_ATTRIBUTE;
 
+#define C2S(x)  case x: return #x;
+static const char *DebugDumpToString(int mType);
+static const char *DebugDumpToString(int mType)
+{
+    switch (mType) {
+        C2S(GET_FW_VER)
+        C2S(GET_DRV_VER)
+        C2S(GET_RING_DATA)
+        C2S(GET_RING_STATUS)
+        C2S(GET_FEATURE)
+        C2S(START_RING_LOG)
+        C2S(GET_BUF_RING_MAP)
+        default:
+            return "DUMP_TYPE_INVALID";
+    }
+}
+
 #define HAL_START_REQUEST_ID 2
 #define HAL_RESTART_ID 3
 #define FILE_NAME_LEN 256
@@ -204,7 +221,7 @@
 #define DUMP_DEBUG(x)
 #define DUMP_INFO(x) ALOGI x
 #define FILE_DUMP_REQUEST_ID 2
-#define C2S(x)  case x: return #x;
+
 static const char *EWP_EventAttrToString(int len_attr);
 static const char *EWP_CmdAttrToString(int data_attr);
 
@@ -263,8 +280,9 @@
     DUMP_LEN_ATTR_EWP_HW_INIT_LOG               = 42,
     DUMP_LEN_ATTR_EWP_HW_MOD_DUMP               = 43,
     DUMP_LEN_ATTR_EWP_HW_REG_DUMP               = 44,
+    DUMP_LEN_ATTR_WRAPPER_REG_DUMP              = 45,
     /*  Please add new attributes from here to sync up old DHD */
-    DUMP_EVENT_ATTR_MAX                         = 45,
+    DUMP_EVENT_ATTR_MAX                         = 46,
 } EWP_DUMP_EVENT_ATTRIBUTE;
 
 /* Attributes associated with DEBUG_GET_DUMP_BUF */
@@ -300,8 +318,9 @@
     DUMP_BUF_ATTR_EWP_HW_INIT_LOG       = 28,
     DUMP_BUF_ATTR_EWP_HW_MOD_DUMP       = 29,
     DUMP_BUF_ATTR_EWP_HW_REG_DUMP       = 30,
+    DUMP_BUF_ATTR_WRAPPER_REG_DUMP      = 31,
     /*  Please add new attributes from here to sync up old DHD */
-    DUMP_BUF_ATTR_MAX		        = 31,
+    DUMP_BUF_ATTR_MAX                   = 32,
 } EWP_DUMP_CMD_ATTRIBUTE;
 
 typedef enum {
@@ -379,6 +398,7 @@
     {DUMP_LEN_ATTR_EWP_HW_INIT_LOG, DUMP_BUF_ATTR_EWP_HW_INIT_LOG, DUMP_TYPE_DEBUG_DUMP},
     {DUMP_LEN_ATTR_EWP_HW_MOD_DUMP, DUMP_BUF_ATTR_EWP_HW_MOD_DUMP, DUMP_TYPE_DEBUG_DUMP},
     {DUMP_LEN_ATTR_EWP_HW_REG_DUMP, DUMP_BUF_ATTR_EWP_HW_REG_DUMP, DUMP_TYPE_DEBUG_DUMP},
+    {DUMP_LEN_ATTR_WRAPPER_REG_DUMP, DUMP_BUF_ATTR_WRAPPER_REG_DUMP, DUMP_TYPE_DEBUG_DUMP},
 
     /* PKT log dump block */
     {DUMP_FILENAME_ATTR_PKTLOG_DUMP, 0, DUMP_TYPE_PKTLOG_DUMP},
@@ -441,6 +461,7 @@
         C2S(DUMP_LEN_ATTR_EWP_HW_INIT_LOG)
         C2S(DUMP_LEN_ATTR_EWP_HW_MOD_DUMP)
         C2S(DUMP_LEN_ATTR_EWP_HW_REG_DUMP)
+        C2S(DUMP_LEN_ATTR_WRAPPER_REG_DUMP)
         default:
             return "DUMP_LEN_ATTR_INVALID";
     }
@@ -479,6 +500,7 @@
         C2S(DUMP_BUF_ATTR_EWP_HW_INIT_LOG)
         C2S(DUMP_BUF_ATTR_EWP_HW_MOD_DUMP)
         C2S(DUMP_BUF_ATTR_EWP_HW_REG_DUMP)
+        C2S(DUMP_BUF_ATTR_WRAPPER_REG_DUMP)
         default:
             return "DUMP_BUF_ATTR_INVALID";
     }
@@ -590,6 +612,8 @@
         mMinDataSize = 0;
         mRingName = NULL;
         memset(mBuff, 0, *mBuffSize);
+        mNumMaps = NULL;
+        mMaps = NULL;
     }
 
     // constructor for ring data
@@ -605,6 +629,8 @@
         mFlags = 0;
         mMaxIntervalSec = 0;
         mMinDataSize = 0;
+        mNumMaps = NULL;
+        mMaps = NULL;
     }
 
     // constructor for ring status
@@ -621,6 +647,8 @@
         mMinDataSize = 0;
         mRingName = NULL;
         memset(mStatus, 0, sizeof(wifi_ring_buffer_status) * (*mNumRings));
+        mNumMaps = NULL;
+        mMaps = NULL;
     }
 
     // constructor for feature set
@@ -636,6 +664,8 @@
         mMaxIntervalSec = 0;
         mMinDataSize = 0;
         mRingName = NULL;
+        mMaps = NULL;
+        mNumMaps = NULL;
     }
 
     // constructor for buf ring map
@@ -644,6 +674,16 @@
         : WifiCommand("DebugCommand", iface, 0), mNumMaps(num_maps), mMaps(map), mType(cmdType)
     {
         memset(mMaps, 0, sizeof(wifi_buf_ring_map_entry_t) * (*mNumMaps));
+        mBuff = NULL;
+        mBuffSize = NULL;
+        mNumRings =  NULL;
+        mStatus = NULL;
+        mVerboseLevel = 0;
+        mFlags = 0;
+        mMaxIntervalSec = 0;
+        mMinDataSize = 0;
+        mRingName = NULL;
+        mSupport = NULL;
     }
 
     // constructor for ring params
@@ -658,6 +698,8 @@
         mNumRings =  NULL;
         mStatus = NULL;
         mSupport = NULL;
+        mMaps = NULL;
+        mNumMaps = NULL;
     }
 
     int createRingRequest(WifiRequest& request) {
@@ -702,6 +744,7 @@
     int createRequest(WifiRequest &request) {
         int result;
 
+        ALOGI("CreateRequest mType = %s", DebugDumpToString(mType));
         switch (mType) {
             case GET_FW_VER:
             {
@@ -760,6 +803,7 @@
                     ALOGE("Failed to put ring data request; result = %d", result);
                     return result;
                 }
+                ALOGI("Success to put ring data request for RingName %s", mRingName);
                 request.attr_end(data);
                 break;
             }
@@ -806,7 +850,7 @@
     }
 
     int start() {
-        ALOGD("Start debug command");
+        ALOGD("Start debug command: mType %s", DebugDumpToString(mType));
         WifiRequest request(familyId(), ifaceId());
         int result = createRequest(request);
         if (result != WIFI_SUCCESS) {
@@ -822,7 +866,7 @@
     }
 
     virtual int handleResponse(WifiEvent& reply) {
-        ALOGD("In DebugCommand::handleResponse, mType:%d\n", mType);
+        ALOGD("In DebugCommand::handleResponse, mType:%s\n", DebugDumpToString(mType));
 
         if (reply.get_cmd() != NL80211_CMD_VENDOR) {
             ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());
@@ -1590,7 +1634,7 @@
             ALOGE("Failed to register set hal start response; result = %d", result);
         }
         wifi_unregister_cmd(wifiHandle(), id());
-	ALOGV("Stop HAL Successfully Completed, mErrCode = %d\n", mErrCode);
+        ALOGE("Stop HAL Successfully Completed, mErrCode = %d\n", mErrCode);
         return result;
     }
 
@@ -1663,11 +1707,16 @@
         : WifiCommand("RingDump", iface, id), mLargestBuffSize(0), mBuff(NULL),
         mErrCode(0)
     {
+        mMap = NULL;
+        mNumMaps = 0;
         memset(&mHandle, 0, sizeof(wifi_ring_buffer_data_handler));
+        for (int i = 0; i < DUMP_BUF_ATTR_MAX; i++) {
+            ring_name[i] = NULL;
+        }
     }
 
     int start() {
-        DUMP_INFO(("Start Ring Dump Map_cnt:%d\n", mNumMaps));
+        DUMP_INFO(("Start Ring Dump Map_cnt %d, register the event\n", mNumMaps));
         registerVendorHandler(GOOGLE_OUI, GOOGLE_FILE_DUMP_EVENT);
 
         //Set ringname to buf hashmap
@@ -1687,7 +1736,7 @@
         if (mBuff) {
             free(mBuff);
             mBuff = NULL;
-            DUMP_INFO(("freed allocated memory\n"));
+            DUMP_INFO(("freed allocated memory and the handler\n"));
         }
         return WIFI_SUCCESS;
     }
@@ -1777,7 +1826,11 @@
                         /* Skip msg header. Retrieved log */
                         (*mHandle.on_ring_buffer_data)(ring_name[buf_attr], mBuff,
                             attr_type_len[len_attr], &status);
+                    } else {
+                        DUMP_INFO(("RingDump: Retrieved Invalid mHandle\n"));
+                        break;
                     }
+                    ALOGI("Notified RingDump data of buf attr = %s\n", EWP_CmdAttrToString(buf_attr));
                     if (mBuff) {
                         memset(mBuff, 0, mLargestBuffSize);
                     }
@@ -1819,7 +1872,7 @@
                 EWP_CmdAttrToString(buf_attr), index);
             return WIFI_ERROR_UNKNOWN;
         }
-        DUMP_INFO(("Trigger get dump for buf attr = %s\n",
+        DUMP_INFO(("Trigger get ring dump for buf attr = %s\n",
                 EWP_CmdAttrToString(buf_attr)));
 
         request.attr_end(data);
@@ -1873,18 +1926,19 @@
                         mActualBuffSize = it.get_u32();
                         DUMP_DEBUG(("len attr %s, len %d\n",
                             EWP_EventAttrToString(attr), mActualBuffSize));
-                        if (mActualBuffSize > mLargestBuffSize)
+                        if (mActualBuffSize > mLargestBuffSize) {
                             mLargestBuffSize = mActualBuffSize;
-                            attr_type_len[attr] = mActualBuffSize;
+                        }
+                        attr_type_len[attr] = mActualBuffSize;
 
-                            /* Store the order in which attributes are received
-                             * so that file dump can be done in the same order
-                             */
-                            req_attr[req_attr_cnt++] = attr;
-                            break;
+                        /* Store the order in which attributes are received
+                         * so that file dump can be done in the same order
+                         */
+                        req_attr[req_attr_cnt++] = attr;
+                        break;
                     }
                     default: {
-                        ALOGE("Ignoring invalid attribute type = %d, size = %d",
+                        ALOGE("RingDump: Ignoring invalid attribute type = %d, size = %d",
                             attr, it.get_len());
                             break;
                         }
@@ -1918,6 +1972,11 @@
                 }
 
                 index = logger_attr_lookup(attr);
+                if (index == -1) {
+                    ALOGE("Invalid index\n");
+                    return WIFI_ERROR_UNKNOWN;
+                }
+
                 buf_attr = attr_lookup_tbl[index].buf_attr;
                 if (!ring_name[buf_attr]) {
                     ALOGE("Failed to find ringname index:%d buf_attr:%d", index, buf_attr);
@@ -1931,27 +1990,33 @@
                 result = request_logger_dump(request, &buf, attr);
                 if (result != WIFI_SUCCESS) {
                     /* Proceeding further for other attributes */
-                    ALOGE("Failed to request the logger dump for attr = %s; result = %d",
+                    ALOGE("Failed to request the ring dump for attr = %s; result = %d",
                         EWP_EventAttrToString(attr), result);
                     continue;
                 }
                 result = requestResponse(request);
                 if (result != WIFI_SUCCESS) {
-                    ALOGE("Failed to register get memory dump response for attr = %s; result = %d",
+                    ALOGE("Failed to register get ring dump response for attr = %s; result = %d",
                         EWP_EventAttrToString(attr), result);
                         /* Proceeding further for other attributes */
                         continue;
                 }
+                ALOGI("Success to send up the ring dump response for attr = %s; result = %d",
+                    EWP_EventAttrToString(attr), result);
             }
 
+            ALOGI("RingDump response is sent, proceed to done indication");
             WifiRequest request2(familyId(), ifaceId());
             result = request2.create(GOOGLE_OUI, LOGGER_FILE_DUMP_DONE_IND);
             if (result != WIFI_SUCCESS) {
-                ALOGE("Failed to trigger dev close; result = %d", result);
+                ALOGE("Failed to indicate FILE_DUMP_DONE_IND; result = %d", result);
                 freeup();
                 goto exit;
             }
-            requestResponse(request2);
+            result = requestResponse(request2);
+            if (result != WIFI_SUCCESS) {
+                ALOGE("Failed to register file done ind response; result = %d", result);
+            }
             freeup();
         } else {
             ALOGE("dump event missing dump length attribute");
@@ -1981,7 +2046,7 @@
     }
     result = (wifi_error)cmd->start();
     if (result != WIFI_SUCCESS) {
-        wifi_unregister_cmd(handle,HAL_START_REQUEST_ID);
+        wifi_unregister_cmd(handle, HAL_START_REQUEST_ID);
         cmd->releaseRef();
         return result;
     }
@@ -2002,7 +2067,7 @@
     }
     result = (wifi_error)cmd->preInit();
     if (result != WIFI_SUCCESS) {
-        wifi_unregister_cmd(handle,HAL_START_REQUEST_ID);
+        wifi_unregister_cmd(handle, HAL_START_REQUEST_ID);
         cmd->releaseRef();
         return result;
     }
@@ -2014,7 +2079,7 @@
     wifi_ring_buffer_data_handler ring_handle)
 {
     wifi_handle handle = getWifiHandle(iface);
-    DUMP_INFO(("start ring dump, handle = %p", handle));
+    DUMP_INFO(("start ring dump, handle = %p, ring_handle = %p", handle, ring_handle));
     wifi_buf_ring_map_entry_t map[DUMP_BUF_ATTR_MAX];
     unsigned int num_maps = DUMP_BUF_ATTR_MAX;
     wifi_error result;
@@ -2026,6 +2091,7 @@
     debug_cmd->releaseRef();
 
     /* Set ringname to corresponding buf attr */
+    DUMP_INFO(("Cached ring_handle: %p for RingDump", ring_handle));
     RingDump *cmd = new RingDump(iface, FILE_DUMP_REQUEST_ID, num_maps, map, ring_handle);
     NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
     result = wifi_register_cmd(handle, FILE_DUMP_REQUEST_ID, cmd);
@@ -2091,7 +2157,7 @@
     }
 
     /* Cache the handler to use it for trigger subsystem restart */
-    ALOGI("Register SSR handler:%p", handler);
+    ALOGI("Register SSR handler");
     info->restart_handler = handler;
     return result;
 }
@@ -2656,10 +2722,11 @@
 ///////////////////////////////////////////////////////////////////////////////
 class OtaUpdateCommand : public WifiCommand
 {
+    int mErrCode;
 
     public:
     OtaUpdateCommand(wifi_interface_handle iface)
-        : WifiCommand("OtaUpdateCommand", iface, 0)
+        : WifiCommand("OtaUpdateCommand", iface, 0), mErrCode(0)
     { }
 
     int start() {
@@ -2744,7 +2811,7 @@
 
         result = requestResponse(request);
         if (result != WIFI_SUCCESS) {
-            ALOGE("Failed to register set otaDownload; result = %d\n", result);
+            ALOGE("Failed to register set otaDownload; result = %d, %d\n", result, mErrCode);
         }
 
         return result;
@@ -2794,10 +2861,10 @@
 wifi_error read_ota_file(char* file, char** buffer, uint32_t* size)
 {
     FILE* fp = NULL;
-    int file_size;
+    int file_size, count;
     char* buf;
-    fp = fopen(file, "r");
 
+    fp = fopen(file, "r");
     if (fp == NULL) {
         ALOGI("File [%s] doesn't exist.", file);
         return WIFI_ERROR_NOT_AVAILABLE;
@@ -2805,6 +2872,11 @@
 
     fseek(fp, 0, SEEK_END);
     file_size = ftell(fp);
+    if (file_size == -1L) {
+        ALOGI("File [%s] size error not valid");
+        fclose(fp);
+        return WIFI_ERROR_NOT_AVAILABLE;
+    }
 
     buf = (char *)malloc(file_size + 1);
     if (buf == NULL) {
@@ -2813,7 +2885,13 @@
     }
     memset(buf, 0, file_size + 1);
     fseek(fp, 0, SEEK_SET);
-    fread(buf, file_size, 1, fp);
+    count = fread(buf, file_size, 1, fp);
+    if (!count) {
+        ALOGE("fread fail.");
+        free(buf);
+        fclose(fp);
+        return WIFI_ERROR_UNKNOWN;
+    }
 
     *buffer = (char*) buf;
     *size = file_size;
diff --git a/bcmdhd/wifi_hal/wifi_offload.cpp b/bcmdhd/wifi_hal/wifi_offload.cpp
index d07fdb0..f4a7556 100644
--- a/bcmdhd/wifi_hal/wifi_offload.cpp
+++ b/bcmdhd/wifi_hal/wifi_offload.cpp
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) 2017 The Android Open Source Project
  *
- * Portions copyright (C) 2023 Broadcom Limited
+ * Portions copyright (C) 2024 Broadcom Limited
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -50,9 +50,9 @@
 } WIFI_OFFLOAD_SUB_COMMAND;
 
 typedef enum {
-    MKEEP_ALIVE_ATTRIBUTE_INVALID		= 0,
-    MKEEP_ALIVE_ATTRIBUTE_ID			= 1,
-    MKEEP_ALIVE_ATTRIBUTE_IP_PKT		= 2,
+    MKEEP_ALIVE_ATTRIBUTE_INVALID               = 0,
+    MKEEP_ALIVE_ATTRIBUTE_ID                    = 1,
+    MKEEP_ALIVE_ATTRIBUTE_IP_PKT                = 2,
     MKEEP_ALIVE_ATTRIBUTE_IP_PKT_LEN		= 3,
     MKEEP_ALIVE_ATTRIBUTE_SRC_MAC_ADDR		= 4,
     MKEEP_ALIVE_ATTRIBUTE_DST_MAC_ADDR		= 5,