You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by ag...@apache.org on 2021/05/31 10:09:31 UTC

[incubator-nuttx] branch master updated: esp32&esp32c3/wifi: Support specific channel and bssid scan

This is an automated email from the ASF dual-hosted git repository.

aguettouche pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git


The following commit(s) were added to refs/heads/master by this push:
     new 1d1dd85  esp32&esp32c3/wifi: Support specific channel and bssid scan
1d1dd85 is described below

commit 1d1dd8512f8155d696762a34dd1db94ba1d03be3
Author: chenwen <ch...@espressif.com>
AuthorDate: Wed May 26 20:52:38 2021 +0800

    esp32&esp32c3/wifi: Support specific channel and bssid scan
---
 arch/risc-v/src/esp32c3/esp32c3_wifi_adapter.c |   6 +-
 arch/risc-v/src/esp32c3/esp32c3_wifi_adapter.h |   1 +
 arch/risc-v/src/esp32c3/esp32c3_wifi_utils.c   | 294 +++++++++++++++----------
 arch/risc-v/src/esp32c3/esp32c3_wlan.c         |   2 -
 arch/xtensa/src/esp32/esp32_wifi_adapter.c     |   8 +-
 arch/xtensa/src/esp32/esp32_wifi_adapter.h     |   2 +
 arch/xtensa/src/esp32/esp32_wifi_utils.c       | 284 +++++++++++++++---------
 7 files changed, 366 insertions(+), 231 deletions(-)

diff --git a/arch/risc-v/src/esp32c3/esp32c3_wifi_adapter.c b/arch/risc-v/src/esp32c3/esp32c3_wifi_adapter.c
index 542fdcf..cdf7db8 100644
--- a/arch/risc-v/src/esp32c3/esp32c3_wifi_adapter.c
+++ b/arch/risc-v/src/esp32c3/esp32c3_wifi_adapter.c
@@ -2575,7 +2575,7 @@ esp_err_t esp_read_mac(uint8_t *mac, esp_mac_type_t type)
   regval[0] = getreg32(MAC_ADDR0_REG);
   regval[1] = getreg32(MAC_ADDR1_REG);
 
-  for (i = 0; i < 6; i++)
+  for (i = 0; i < MAC_LEN; i++)
     {
       mac[i] = data[5 - i];
     }
@@ -5409,7 +5409,7 @@ int esp_wifi_sta_bssid(struct iwreq *iwr, bool set)
   if (set)
     {
       wifi_cfg.sta.bssid_set = true;
-      memcpy(wifi_cfg.sta.bssid, pdata, 6);
+      memcpy(wifi_cfg.sta.bssid, pdata, MAC_LEN);
 
       ret = esp_wifi_set_config(WIFI_IF_STA, &wifi_cfg);
       if (ret)
@@ -5420,7 +5420,7 @@ int esp_wifi_sta_bssid(struct iwreq *iwr, bool set)
     }
   else
     {
-      memcpy(pdata, wifi_cfg.sta.bssid, 6);
+      memcpy(pdata, wifi_cfg.sta.bssid, MAC_LEN);
     }
 
   return OK;
diff --git a/arch/risc-v/src/esp32c3/esp32c3_wifi_adapter.h b/arch/risc-v/src/esp32c3/esp32c3_wifi_adapter.h
index 237c249..159dc49 100644
--- a/arch/risc-v/src/esp32c3/esp32c3_wifi_adapter.h
+++ b/arch/risc-v/src/esp32c3/esp32c3_wifi_adapter.h
@@ -62,6 +62,7 @@ extern "C"
 
 #define SSID_MAX_LEN                (32)
 #define PWD_MAX_LEN                 (64)
+#define MAC_LEN                     (6)
 
 /* Wi-Fi event ID */
 
diff --git a/arch/risc-v/src/esp32c3/esp32c3_wifi_utils.c b/arch/risc-v/src/esp32c3/esp32c3_wifi_utils.c
index 5fd5c31..d91b9f2 100644
--- a/arch/risc-v/src/esp32c3/esp32c3_wifi_utils.c
+++ b/arch/risc-v/src/esp32c3/esp32c3_wifi_utils.c
@@ -53,6 +53,10 @@
 #  define MIN(a,b) ((a) < (b) ? (a) : (b))
 #endif
 
+/* Maximum number of channels for Wi-Fi 2.4Ghz */
+
+#define CHANNEL_MAX_NUM              (14)
+
 /****************************************************************************
  * Private Types
  ****************************************************************************/
@@ -79,6 +83,8 @@ struct wifi_scan_result_s
  ****************************************************************************/
 
 static struct wifi_scan_result_s g_scan_priv;
+static uint8_t g_channel_num = 0;
+static uint8_t g_channel_list[CHANNEL_MAX_NUM];
 
 /****************************************************************************
  * Public Functions
@@ -105,6 +111,8 @@ int esp_wifi_start_scan(struct iwreq *iwr)
   wifi_scan_config_t *config = NULL;
   struct iw_scan_req *req;
   int ret = 0;
+  int i;
+  uint8_t target_mac[MAC_LEN];
   uint8_t target_ssid[SSID_MAX_LEN + 1] =
     {
       0
@@ -128,6 +136,9 @@ int esp_wifi_start_scan(struct iwreq *iwr)
       return -ENOMEM;
     }
 
+  g_channel_num = 0;
+  memset(g_channel_list, 0x0, CHANNEL_MAX_NUM);
+
   if (iwr->u.data.pointer &&
       iwr->u.data.length >= sizeof(struct iw_scan_req))
     {
@@ -143,6 +154,35 @@ int esp_wifi_start_scan(struct iwreq *iwr)
           config->ssid = &target_ssid[0];
           config->ssid[req->essid_len] = '\0';
         }
+
+      if (iwr->u.data.flags & IW_SCAN_THIS_FREQ &&
+          req->num_channels > 0)
+        {
+          /* Scan specific channels */
+
+          DEBUGASSERT(req->num_channels <= CHANNEL_MAX_NUM);
+          g_channel_num = req->num_channels;
+          if (req->num_channels == 1)
+            {
+              config->channel = req->channel_list[0].m;
+            }
+          else
+            {
+              for (i = 0; i < req->num_channels; i++)
+                {
+                  g_channel_list[i] = req->channel_list[i].m;
+                }
+            }
+        }
+
+      memset(target_mac, 0xff, MAC_LEN);
+      if (memcmp(req->bssid.sa_data, target_mac, MAC_LEN) != 0)
+        {
+          /* Scan specific bssid */
+
+          memcpy(target_mac, req->bssid.sa_data, MAC_LEN);
+          config->bssid = &target_mac[0];
+        }
     }
   else
     {
@@ -319,6 +359,7 @@ void esp_wifi_scan_event_parse(void)
   esp_wifi_scan_get_ap_num(&bss_total);
   if (bss_total == 0)
     {
+      priv->scan_status = ESP_SCAN_DONE;
       wlinfo("INFO: None AP is scanned\n");
       return;
     }
@@ -326,6 +367,7 @@ void esp_wifi_scan_event_parse(void)
   ap_list_buffer = kmm_calloc(bss_total, sizeof(wifi_ap_record_t));
   if (ap_list_buffer == NULL)
     {
+      priv->scan_status = ESP_SCAN_DONE;
       wlerr("ERROR: Failed to calloc buffer to print scan results");
       return;
     }
@@ -337,127 +379,153 @@ void esp_wifi_scan_event_parse(void)
       unsigned int result_size;
       size_t essid_len;
       size_t essid_len_aligned;
+      bool is_target_channel = true;
+      int i;
+
       for (bss_count = 0; bss_count < bss_total; bss_count++)
         {
-          result_size = WIFI_SCAN_RESULT_SIZE - priv->scan_result_size;
-
-          /* Copy BSSID */
-
-          if (result_size < ESP_IW_EVENT_SIZE(ap_addr))
-            {
-              goto scan_result_full;
-            }
-
-          iwe = (struct iw_event *)
-                        &priv->scan_result[priv->scan_result_size];
-          iwe->len = ESP_IW_EVENT_SIZE(ap_addr);
-          iwe->cmd = SIOCGIWAP;
-          memcpy(&iwe->u.ap_addr.sa_data, ap_list_buffer[bss_count].bssid,
-                sizeof(ap_list_buffer[bss_count].bssid));
-          iwe->u.ap_addr.sa_family = ARPHRD_ETHER;
-          priv->scan_result_size += ESP_IW_EVENT_SIZE(ap_addr);
-          result_size -= ESP_IW_EVENT_SIZE(ap_addr);
-
-          /* Copy ESSID */
-
-          essid_len = MIN(strlen((const char *)
-                          ap_list_buffer[bss_count].ssid), SSID_MAX_LEN);
-          essid_len_aligned = (essid_len + 3) & -4;
-          if (result_size < ESP_IW_EVENT_SIZE(essid) + essid_len_aligned)
-            {
-              goto scan_result_full;
-            }
-
-          iwe = (struct iw_event *)
-                 &priv->scan_result[priv->scan_result_size];
-          iwe->len = ESP_IW_EVENT_SIZE(essid) + essid_len_aligned;
-          iwe->cmd = SIOCGIWESSID;
-          iwe->u.essid.flags = 0;
-          iwe->u.essid.length = essid_len;
-
-          /* Special processing for iw_point, set offset in pointer field */
-
-          iwe->u.essid.pointer = (FAR void *)sizeof(iwe->u.essid);
-          memcpy(&iwe->u.essid + 1,
-                 ap_list_buffer[bss_count].ssid, essid_len);
-
-          wlinfo("INFO: ssid %s\n", ap_list_buffer[bss_count].ssid);
-
-          priv->scan_result_size +=
-                ESP_IW_EVENT_SIZE(essid) + essid_len_aligned;
-          result_size -= ESP_IW_EVENT_SIZE(essid) + essid_len_aligned;
-
-          /* Copy link quality info */
-
-          if (result_size < ESP_IW_EVENT_SIZE(qual))
-            {
-              goto scan_result_full;
-            }
-
-          iwe = (struct iw_event *)
-                 &priv->scan_result[priv->scan_result_size];
-          iwe->len = ESP_IW_EVENT_SIZE(qual);
-          iwe->cmd = IWEVQUAL;
-          iwe->u.qual.qual = 0x00;
-
-          wlinfo("INFO: signal %d\n", ap_list_buffer[bss_count].rssi);
-
-          iwe->u.qual.level = ap_list_buffer[bss_count].rssi;
-          iwe->u.qual.noise = 0x00;
-          iwe->u.qual.updated = IW_QUAL_DBM | IW_QUAL_ALL_UPDATED;
-
-          priv->scan_result_size += ESP_IW_EVENT_SIZE(qual);
-          result_size -= ESP_IW_EVENT_SIZE(qual);
-
-          /* Copy AP mode */
-
-          if (result_size < ESP_IW_EVENT_SIZE(mode))
+          if (g_channel_num > 1)
             {
-              goto scan_result_full;
+              is_target_channel = false;
+              for (i = 0; i < g_channel_num; i++)
+                {
+                  if (g_channel_list[i] == ap_list_buffer[bss_count].primary)
+                    {
+                      is_target_channel = true;
+                      break;
+                    }
+                }
             }
-
-          iwe = (struct iw_event *)
-                 &priv->scan_result[priv->scan_result_size];
-          iwe->len = ESP_IW_EVENT_SIZE(mode);
-          iwe->cmd = SIOCGIWMODE;
-          iwe->u.mode = IW_MODE_MASTER;
-          priv->scan_result_size += ESP_IW_EVENT_SIZE(mode);
-          result_size -= ESP_IW_EVENT_SIZE(mode);
-
-          /* Copy AP encryption mode */
-
-          if (result_size < ESP_IW_EVENT_SIZE(data))
+          else
             {
-              goto scan_result_full;
+              is_target_channel = true;
             }
 
-          iwe = (struct iw_event *)
-                 &priv->scan_result[priv->scan_result_size];
-          iwe->len = ESP_IW_EVENT_SIZE(data);
-          iwe->cmd = SIOCGIWENCODE;
-          iwe->u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
-          iwe->u.data.length = 0;
-          iwe->u.essid.pointer = NULL;
-
-          priv->scan_result_size += ESP_IW_EVENT_SIZE(data);
-          result_size -= ESP_IW_EVENT_SIZE(data);
-
-          /* Copy AP channel */
-
-          if (result_size < ESP_IW_EVENT_SIZE(freq))
+          if (is_target_channel == true)
             {
-              goto scan_result_full;
+              result_size = WIFI_SCAN_RESULT_SIZE - priv->scan_result_size;
+
+              /* Copy BSSID */
+
+              if (result_size < ESP_IW_EVENT_SIZE(ap_addr))
+                {
+                  goto scan_result_full;
+                }
+
+              iwe = (struct iw_event *)
+                            &priv->scan_result[priv->scan_result_size];
+              iwe->len = ESP_IW_EVENT_SIZE(ap_addr);
+              iwe->cmd = SIOCGIWAP;
+              memcpy(&iwe->u.ap_addr.sa_data,
+                     ap_list_buffer[bss_count].bssid,
+                     sizeof(ap_list_buffer[bss_count].bssid));
+              iwe->u.ap_addr.sa_family = ARPHRD_ETHER;
+              priv->scan_result_size += ESP_IW_EVENT_SIZE(ap_addr);
+              result_size -= ESP_IW_EVENT_SIZE(ap_addr);
+
+              /* Copy ESSID */
+
+              essid_len = MIN(strlen((const char *)
+                              ap_list_buffer[bss_count].ssid), SSID_MAX_LEN);
+              essid_len_aligned = (essid_len + 3) & -4;
+              if (result_size < ESP_IW_EVENT_SIZE(essid) + essid_len_aligned)
+                {
+                  goto scan_result_full;
+                }
+
+              iwe = (struct iw_event *)
+                    &priv->scan_result[priv->scan_result_size];
+              iwe->len = ESP_IW_EVENT_SIZE(essid) + essid_len_aligned;
+              iwe->cmd = SIOCGIWESSID;
+              iwe->u.essid.flags = 0;
+              iwe->u.essid.length = essid_len;
+
+              /* Special processing for iw_point, set offset
+               * in pointer field.
+               */
+
+              iwe->u.essid.pointer = (FAR void *)sizeof(iwe->u.essid);
+              memcpy(&iwe->u.essid + 1,
+                    ap_list_buffer[bss_count].ssid, essid_len);
+
+              wlinfo("INFO: ssid %s\n", ap_list_buffer[bss_count].ssid);
+
+              priv->scan_result_size +=
+                    ESP_IW_EVENT_SIZE(essid) + essid_len_aligned;
+              result_size -= ESP_IW_EVENT_SIZE(essid) + essid_len_aligned;
+
+              /* Copy link quality info */
+
+              if (result_size < ESP_IW_EVENT_SIZE(qual))
+                {
+                  goto scan_result_full;
+                }
+
+              iwe = (struct iw_event *)
+                    &priv->scan_result[priv->scan_result_size];
+              iwe->len = ESP_IW_EVENT_SIZE(qual);
+              iwe->cmd = IWEVQUAL;
+              iwe->u.qual.qual = 0x00;
+
+              wlinfo("INFO: signal %d\n", ap_list_buffer[bss_count].rssi);
+
+              iwe->u.qual.level = ap_list_buffer[bss_count].rssi;
+              iwe->u.qual.noise = 0x00;
+              iwe->u.qual.updated = IW_QUAL_DBM | IW_QUAL_ALL_UPDATED;
+
+              priv->scan_result_size += ESP_IW_EVENT_SIZE(qual);
+              result_size -= ESP_IW_EVENT_SIZE(qual);
+
+              /* Copy AP mode */
+
+              if (result_size < ESP_IW_EVENT_SIZE(mode))
+                {
+                  goto scan_result_full;
+                }
+
+              iwe = (struct iw_event *)
+                    &priv->scan_result[priv->scan_result_size];
+              iwe->len = ESP_IW_EVENT_SIZE(mode);
+              iwe->cmd = SIOCGIWMODE;
+              iwe->u.mode = IW_MODE_MASTER;
+              priv->scan_result_size += ESP_IW_EVENT_SIZE(mode);
+              result_size -= ESP_IW_EVENT_SIZE(mode);
+
+              /* Copy AP encryption mode */
+
+              if (result_size < ESP_IW_EVENT_SIZE(data))
+                {
+                  goto scan_result_full;
+                }
+
+              iwe = (struct iw_event *)
+                    &priv->scan_result[priv->scan_result_size];
+              iwe->len = ESP_IW_EVENT_SIZE(data);
+              iwe->cmd = SIOCGIWENCODE;
+              iwe->u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
+              iwe->u.data.length = 0;
+              iwe->u.essid.pointer = NULL;
+
+              priv->scan_result_size += ESP_IW_EVENT_SIZE(data);
+              result_size -= ESP_IW_EVENT_SIZE(data);
+
+              /* Copy AP channel */
+
+              if (result_size < ESP_IW_EVENT_SIZE(freq))
+                {
+                  goto scan_result_full;
+                }
+
+              iwe = (struct iw_event *)
+                    &priv->scan_result[priv->scan_result_size];
+              iwe->len = ESP_IW_EVENT_SIZE(freq);
+              iwe->cmd = SIOCGIWFREQ;
+              iwe->u.freq.e = 0;
+              iwe->u.freq.m = ap_list_buffer[bss_count].primary;
+
+              priv->scan_result_size += ESP_IW_EVENT_SIZE(freq);
+              result_size -= ESP_IW_EVENT_SIZE(freq);
             }
-
-          iwe = (struct iw_event *)
-                 &priv->scan_result[priv->scan_result_size];
-          iwe->len = ESP_IW_EVENT_SIZE(freq);
-          iwe->cmd = SIOCGIWFREQ;
-          iwe->u.freq.e = 0;
-          iwe->u.freq.m = ap_list_buffer[bss_count].primary;
-
-          priv->scan_result_size += ESP_IW_EVENT_SIZE(freq);
-          result_size -= ESP_IW_EVENT_SIZE(freq);
         }
 
       parse_done = true;
@@ -478,7 +546,7 @@ scan_result_full:
       ap_list_buffer = NULL;
     }
 
-  g_scan_priv.scan_status = ESP_SCAN_DONE;
+  priv->scan_status = ESP_SCAN_DONE;
   nxsem_post(&priv->scan_signal);
 }
 
diff --git a/arch/risc-v/src/esp32c3/esp32c3_wlan.c b/arch/risc-v/src/esp32c3/esp32c3_wlan.c
index 295d0df..59970d0 100644
--- a/arch/risc-v/src/esp32c3/esp32c3_wlan.c
+++ b/arch/risc-v/src/esp32c3/esp32c3_wlan.c
@@ -92,8 +92,6 @@
 #  endif
 #endif
 
-#define MAC_LEN                   (6)
-
 /****************************************************************************
  * Private Types
  ****************************************************************************/
diff --git a/arch/xtensa/src/esp32/esp32_wifi_adapter.c b/arch/xtensa/src/esp32/esp32_wifi_adapter.c
index eba234e..a562ea8 100644
--- a/arch/xtensa/src/esp32/esp32_wifi_adapter.c
+++ b/arch/xtensa/src/esp32/esp32_wifi_adapter.c
@@ -2619,12 +2619,12 @@ int32_t esp_read_mac(uint8_t *mac, esp_mac_type_t type)
   regval[1] = getreg32(MAC_ADDR1_REG);
 
   crc = data[6];
-  for (i = 0; i < 6; i++)
+  for (i = 0; i < MAC_LEN; i++)
     {
       mac[i] = data[5 - i];
     }
 
-  if (crc != esp_crc8(mac, 6))
+  if (crc != esp_crc8(mac, MAC_LEN))
     {
       wlerr("Failed to check MAC address CRC\n");
       return -1;
@@ -5431,7 +5431,7 @@ int esp_wifi_sta_bssid(struct iwreq *iwr, bool set)
   if (set)
     {
       wifi_cfg.sta.bssid_set = true;
-      memcpy(wifi_cfg.sta.bssid, pdata, 6);
+      memcpy(wifi_cfg.sta.bssid, pdata, MAC_LEN);
 
       ret = esp_wifi_set_config(WIFI_IF_STA, &wifi_cfg);
       if (ret)
@@ -5442,7 +5442,7 @@ int esp_wifi_sta_bssid(struct iwreq *iwr, bool set)
     }
   else
     {
-      memcpy(pdata, wifi_cfg.sta.bssid, 6);
+      memcpy(pdata, wifi_cfg.sta.bssid, MAC_LEN);
     }
 
   return OK;
diff --git a/arch/xtensa/src/esp32/esp32_wifi_adapter.h b/arch/xtensa/src/esp32/esp32_wifi_adapter.h
index ac298d2..f25ad05 100644
--- a/arch/xtensa/src/esp32/esp32_wifi_adapter.h
+++ b/arch/xtensa/src/esp32/esp32_wifi_adapter.h
@@ -60,6 +60,8 @@ extern "C"
 #  define ESP32_WLAN_DEVS         2
 #endif
 
+#define MAC_LEN                     (6)
+
 /* WiFi event ID */
 
 enum wifi_adpt_evt_e
diff --git a/arch/xtensa/src/esp32/esp32_wifi_utils.c b/arch/xtensa/src/esp32/esp32_wifi_utils.c
index 62ce65b..5290cfe 100644
--- a/arch/xtensa/src/esp32/esp32_wifi_utils.c
+++ b/arch/xtensa/src/esp32/esp32_wifi_utils.c
@@ -54,6 +54,10 @@
 #  define MIN(a,b) ((a) < (b) ? (a) : (b))
 #endif
 
+/* Maximum number of channels for Wi-Fi 2.4Ghz */
+
+#define CHANNEL_MAX_NUM              (14)
+
 /****************************************************************************
  * Private Types
  ****************************************************************************/
@@ -80,6 +84,8 @@ struct wifi_scan_result
  ****************************************************************************/
 
 static struct wifi_scan_result g_scan_priv;
+static uint8_t g_channel_num = 0;
+static uint8_t g_channel_list[CHANNEL_MAX_NUM];
 
 /****************************************************************************
  * Public Functions
@@ -107,6 +113,8 @@ int esp_wifi_start_scan(struct iwreq *iwr)
   uint8_t target_ssid[SSID_LEN];
   struct iw_scan_req *req;
   int ret = 0;
+  int i;
+  uint8_t target_mac[MAC_LEN];
 
   memset(target_ssid, 0x0, sizeof(SSID_LEN));
   if (iwr == NULL)
@@ -127,6 +135,8 @@ int esp_wifi_start_scan(struct iwreq *iwr)
       return -ENOMEM;
     }
 
+  g_channel_num = 0;
+  memset(g_channel_list, 0x0, CHANNEL_MAX_NUM);
   memset(config, 0x0, sizeof(wifi_scan_config_t));
   if (iwr->u.data.pointer &&
       iwr->u.data.length >= sizeof(struct iw_scan_req))
@@ -143,6 +153,35 @@ int esp_wifi_start_scan(struct iwreq *iwr)
           config->ssid = &target_ssid[0];
           config->ssid[req->essid_len] = '\0';
         }
+
+      if (iwr->u.data.flags & IW_SCAN_THIS_FREQ &&
+          req->num_channels > 0)
+        {
+          /* Scan specific channels */
+
+          DEBUGASSERT(req->num_channels <= CHANNEL_MAX_NUM);
+          g_channel_num = req->num_channels;
+          if (req->num_channels == 1)
+            {
+              config->channel = req->channel_list[0].m;
+            }
+          else
+            {
+              for (i = 0; i < req->num_channels; i++)
+                {
+                  g_channel_list[i] = req->channel_list[i].m;
+                }
+            }
+        }
+
+      memset(target_mac, 0xff, MAC_LEN);
+      if (memcmp(req->bssid.sa_data, target_mac, MAC_LEN) != 0)
+        {
+          /* Scan specific bssid */
+
+          memcpy(target_mac, req->bssid.sa_data, MAC_LEN);
+          config->bssid = &target_mac[0];
+        }
     }
   else
     {
@@ -315,6 +354,7 @@ void esp_wifi_scan_event_parse(void)
   esp_wifi_scan_get_ap_num(&bss_total);
   if (bss_total == 0)
     {
+      priv->scan_status = ESP_SCAN_DONE;
       wlinfo("INFO: None AP is scanned\n");
       return;
     }
@@ -322,6 +362,7 @@ void esp_wifi_scan_event_parse(void)
   ap_list_buffer = kmm_malloc(bss_total * sizeof(wifi_ap_record_t));
   if (ap_list_buffer == NULL)
     {
+      priv->scan_status = ESP_SCAN_DONE;
       wlerr("ERROR: Failed to malloc buffer to print scan results");
       return;
     }
@@ -334,123 +375,148 @@ void esp_wifi_scan_event_parse(void)
       unsigned int result_size;
       size_t essid_len;
       size_t essid_len_aligned;
+      bool is_target_channel = true;
+      int i;
       for (bss_count = 0; bss_count < bss_total; bss_count++)
         {
-          result_size = WIFI_SCAN_RESULT_SIZE - priv->scan_result_size;
-
-          /* Copy BSSID */
-
-          if (result_size < ESP_IW_EVENT_SIZE(ap_addr))
-            {
-              goto scan_result_full;
-            }
-
-          iwe = (struct iw_event *)
-                        &priv->scan_result[priv->scan_result_size];
-          iwe->len = ESP_IW_EVENT_SIZE(ap_addr);
-          iwe->cmd = SIOCGIWAP;
-          memcpy(&iwe->u.ap_addr.sa_data, ap_list_buffer[bss_count].bssid,
-                sizeof(ap_list_buffer[bss_count].bssid));
-          iwe->u.ap_addr.sa_family = ARPHRD_ETHER;
-          priv->scan_result_size += ESP_IW_EVENT_SIZE(ap_addr);
-          result_size -= ESP_IW_EVENT_SIZE(ap_addr);
-
-          /* Copy ESSID */
-
-          essid_len = MIN(strlen((const char *)
-                                 ap_list_buffer[bss_count].ssid), 32);
-          essid_len_aligned = (essid_len + 3) & -4;
-          if (result_size < ESP_IW_EVENT_SIZE(essid)+essid_len_aligned)
-            {
-              goto scan_result_full;
-            }
-
-          iwe = (struct iw_event *)
-                 &priv->scan_result[priv->scan_result_size];
-          iwe->len = ESP_IW_EVENT_SIZE(essid)+essid_len_aligned;
-          iwe->cmd = SIOCGIWESSID;
-          iwe->u.essid.flags = 0;
-          iwe->u.essid.length = essid_len;
-
-          /* Special processing for iw_point, set offset in pointer field */
-
-          iwe->u.essid.pointer = (FAR void *)sizeof(iwe->u.essid);
-          memcpy(&iwe->u.essid + 1,
-                 ap_list_buffer[bss_count].ssid, essid_len);
-          wlinfo("INFO: ssid %s\n", ap_list_buffer[bss_count].ssid);
-          priv->scan_result_size +=
-                ESP_IW_EVENT_SIZE(essid)+essid_len_aligned;
-          result_size -= ESP_IW_EVENT_SIZE(essid)+essid_len_aligned;
-
-          /* Copy link quality info */
-
-          if (result_size < ESP_IW_EVENT_SIZE(qual))
+          if (g_channel_num > 1)
             {
-              goto scan_result_full;
+              is_target_channel = false;
+              for (i = 0; i < g_channel_num; i++)
+                {
+                  if (g_channel_list[i] == ap_list_buffer[bss_count].primary)
+                    {
+                      is_target_channel = true;
+                      break;
+                    }
+                }
             }
-
-          iwe = (struct iw_event *)
-                 &priv->scan_result[priv->scan_result_size];
-          iwe->len = ESP_IW_EVENT_SIZE(qual);
-          iwe->cmd = IWEVQUAL;
-          iwe->u.qual.qual = 0x00;
-          wlinfo("INFO: signal %d\n", ap_list_buffer[bss_count].rssi);
-          iwe->u.qual.level = ap_list_buffer[bss_count].rssi;
-          iwe->u.qual.noise = 0x00;
-          iwe->u.qual.updated = IW_QUAL_DBM | IW_QUAL_ALL_UPDATED;
-
-          priv->scan_result_size += ESP_IW_EVENT_SIZE(qual);
-          result_size -= ESP_IW_EVENT_SIZE(qual);
-
-          /* Copy AP mode */
-
-          if (result_size < ESP_IW_EVENT_SIZE(mode))
-            {
-              goto scan_result_full;
-            }
-
-          iwe = (struct iw_event *)
-                 &priv->scan_result[priv->scan_result_size];
-          iwe->len = ESP_IW_EVENT_SIZE(mode);
-          iwe->cmd = SIOCGIWMODE;
-          iwe->u.mode = IW_MODE_MASTER;
-          priv->scan_result_size += ESP_IW_EVENT_SIZE(mode);
-          result_size -= ESP_IW_EVENT_SIZE(mode);
-
-          /* Copy AP encryption mode */
-
-          if (result_size < ESP_IW_EVENT_SIZE(data))
+          else
             {
-              goto scan_result_full;
+              is_target_channel = true;
             }
 
-          iwe = (struct iw_event *)
-                 &priv->scan_result[priv->scan_result_size];
-          iwe->len = ESP_IW_EVENT_SIZE(data);
-          iwe->cmd = SIOCGIWENCODE;
-          iwe->u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
-          iwe->u.data.length = 0;
-          iwe->u.essid.pointer = NULL;
-
-          priv->scan_result_size += ESP_IW_EVENT_SIZE(data);
-          result_size -= ESP_IW_EVENT_SIZE(data);
-
-          /* Copy AP channel */
-
-          if (result_size < ESP_IW_EVENT_SIZE(freq))
+          if (is_target_channel == true)
             {
-              goto scan_result_full;
+              result_size = WIFI_SCAN_RESULT_SIZE - priv->scan_result_size;
+
+              /* Copy BSSID */
+
+              if (result_size < ESP_IW_EVENT_SIZE(ap_addr))
+                {
+                  goto scan_result_full;
+                }
+
+              iwe = (struct iw_event *)
+                            &priv->scan_result[priv->scan_result_size];
+              iwe->len = ESP_IW_EVENT_SIZE(ap_addr);
+              iwe->cmd = SIOCGIWAP;
+              memcpy(&iwe->u.ap_addr.sa_data,
+                     ap_list_buffer[bss_count].bssid,
+                     sizeof(ap_list_buffer[bss_count].bssid));
+              iwe->u.ap_addr.sa_family = ARPHRD_ETHER;
+              priv->scan_result_size += ESP_IW_EVENT_SIZE(ap_addr);
+              result_size -= ESP_IW_EVENT_SIZE(ap_addr);
+
+              /* Copy ESSID */
+
+              essid_len = MIN(strlen((const char *)
+                                    ap_list_buffer[bss_count].ssid), 32);
+              essid_len_aligned = (essid_len + 3) & -4;
+              if (result_size < ESP_IW_EVENT_SIZE(essid)+essid_len_aligned)
+                {
+                  goto scan_result_full;
+                }
+
+              iwe = (struct iw_event *)
+                    &priv->scan_result[priv->scan_result_size];
+              iwe->len = ESP_IW_EVENT_SIZE(essid)+essid_len_aligned;
+              iwe->cmd = SIOCGIWESSID;
+              iwe->u.essid.flags = 0;
+              iwe->u.essid.length = essid_len;
+
+              /* Special processing for iw_point, set offset
+               * in pointer field.
+               */
+
+              iwe->u.essid.pointer = (FAR void *)sizeof(iwe->u.essid);
+              memcpy(&iwe->u.essid + 1,
+                    ap_list_buffer[bss_count].ssid, essid_len);
+              wlinfo("INFO: ssid %s\n", ap_list_buffer[bss_count].ssid);
+              priv->scan_result_size +=
+                    ESP_IW_EVENT_SIZE(essid)+essid_len_aligned;
+              result_size -= ESP_IW_EVENT_SIZE(essid)+essid_len_aligned;
+
+              /* Copy link quality info */
+
+              if (result_size < ESP_IW_EVENT_SIZE(qual))
+                {
+                  goto scan_result_full;
+                }
+
+              iwe = (struct iw_event *)
+                    &priv->scan_result[priv->scan_result_size];
+              iwe->len = ESP_IW_EVENT_SIZE(qual);
+              iwe->cmd = IWEVQUAL;
+              iwe->u.qual.qual = 0x00;
+              wlinfo("INFO: signal %d\n", ap_list_buffer[bss_count].rssi);
+              iwe->u.qual.level = ap_list_buffer[bss_count].rssi;
+              iwe->u.qual.noise = 0x00;
+              iwe->u.qual.updated = IW_QUAL_DBM | IW_QUAL_ALL_UPDATED;
+
+              priv->scan_result_size += ESP_IW_EVENT_SIZE(qual);
+              result_size -= ESP_IW_EVENT_SIZE(qual);
+
+              /* Copy AP mode */
+
+              if (result_size < ESP_IW_EVENT_SIZE(mode))
+                {
+                  goto scan_result_full;
+                }
+
+              iwe = (struct iw_event *)
+                    &priv->scan_result[priv->scan_result_size];
+              iwe->len = ESP_IW_EVENT_SIZE(mode);
+              iwe->cmd = SIOCGIWMODE;
+              iwe->u.mode = IW_MODE_MASTER;
+              priv->scan_result_size += ESP_IW_EVENT_SIZE(mode);
+              result_size -= ESP_IW_EVENT_SIZE(mode);
+
+              /* Copy AP encryption mode */
+
+              if (result_size < ESP_IW_EVENT_SIZE(data))
+                {
+                  goto scan_result_full;
+                }
+
+              iwe = (struct iw_event *)
+                    &priv->scan_result[priv->scan_result_size];
+              iwe->len = ESP_IW_EVENT_SIZE(data);
+              iwe->cmd = SIOCGIWENCODE;
+              iwe->u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
+              iwe->u.data.length = 0;
+              iwe->u.essid.pointer = NULL;
+
+              priv->scan_result_size += ESP_IW_EVENT_SIZE(data);
+              result_size -= ESP_IW_EVENT_SIZE(data);
+
+              /* Copy AP channel */
+
+              if (result_size < ESP_IW_EVENT_SIZE(freq))
+                {
+                  goto scan_result_full;
+                }
+
+              iwe = (struct iw_event *)
+                    &priv->scan_result[priv->scan_result_size];
+              iwe->len = ESP_IW_EVENT_SIZE(freq);
+              iwe->cmd = SIOCGIWFREQ;
+              iwe->u.freq.e = 0;
+              iwe->u.freq.m = ap_list_buffer[bss_count].primary;
+
+              priv->scan_result_size += ESP_IW_EVENT_SIZE(freq);
+              result_size -= ESP_IW_EVENT_SIZE(freq);
             }
-
-          iwe = (struct iw_event *)
-                 &priv->scan_result[priv->scan_result_size];
-          iwe->len = ESP_IW_EVENT_SIZE(freq);
-          iwe->cmd = SIOCGIWFREQ;
-          iwe->u.freq.e = 0;
-          iwe->u.freq.m = ap_list_buffer[bss_count].primary;
-
-          priv->scan_result_size += ESP_IW_EVENT_SIZE(freq);
-          result_size -= ESP_IW_EVENT_SIZE(freq);
         }
 
       parse_done = true;
@@ -471,7 +537,7 @@ scan_result_full:
       ap_list_buffer = NULL;
     }
 
-  g_scan_priv.scan_status = ESP_SCAN_DONE;
+  priv->scan_status = ESP_SCAN_DONE;
   nxsem_post(&priv->scan_signal);
 }