tmedicci commented on code in PR #12337:
URL: https://github.com/apache/nuttx/pull/12337#discussion_r1599716572


##########
arch/risc-v/src/common/espressif/esp_wifi_utils.c:
##########
@@ -0,0 +1,643 @@
+/****************************************************************************
+ * arch/risc-v/src/common/espressif/esp_wifi_utils.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <assert.h>
+#include <errno.h>
+#include <debug.h>
+#include <netinet/arp.h>
+#include <sys/param.h>
+
+#include <nuttx/kmalloc.h>
+#include <nuttx/wireless/wireless.h>
+
+#include "esp_wifi_adapter.h"
+
+#include "esp_log.h"
+#include "esp_mac.h"
+#include "esp_private/phy.h"
+#include "esp_private/wifi.h"
+#include "esp_random.h"
+#include "esp_timer.h"
+#include "esp_wpa.h"
+#include "rom/ets_sys.h"
+#include "soc/soc_caps.h"
+
+#include "esp_wifi_utils.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Helper to get iw_event size */
+
+#define ESP_IW_EVENT_SIZE(field) \
+  (offsetof(struct iw_event, u) + sizeof(((union iwreq_data *)0)->field))
+
+#ifdef CONFIG_ESPRESSIF_WIFI_SCAN_RESULT_SIZE
+#  define WIFI_SCAN_RESULT_SIZE      CONFIG_ESPRESSIF_WIFI_SCAN_RESULT_SIZE
+#else
+#  define WIFI_SCAN_RESULT_SIZE      (4096)
+#endif
+
+#define SCAN_TIME_SEC                (5)
+
+/* Maximum number of channels for Wi-Fi 2.4Ghz */
+
+#define CHANNEL_MAX_NUM              (14)
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+enum scan_status_e
+{
+  ESP_SCAN_DISABLED = 0,
+  ESP_SCAN_RUN,
+  ESP_SCAN_DONE
+};
+
+/* Wi-Fi scan result information */
+
+struct wifi_scan_result
+{
+  enum scan_status_e scan_status;      /* Scan status */
+  sem_t scan_signal;                   /* Scan notification signal */
+  uint8_t *scan_result;                /* Temp buffer that holds results */
+  unsigned int scan_result_size;       /* Current size of temp buffer */
+};
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static struct wifi_scan_result g_scan_priv =
+{
+  .scan_signal = SEM_INITIALIZER(0),
+};
+static uint8_t g_channel_num = 0;
+static uint8_t g_channel_list[CHANNEL_MAX_NUM];
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: esp_wifi_start_scan
+ *
+ * Description:
+ *   Scan all available APs.
+ *
+ * Input Parameters:
+ *   iwr - The argument of the ioctl cmd
+ *
+ * Returned Value:
+ *   OK on success (positive non-zero values are cmd-specific)
+ *   Negated errno returned on failure.
+ *
+ ****************************************************************************/
+
+int esp_wifi_start_scan(struct iwreq *iwr)
+{
+  struct wifi_scan_result *priv = &g_scan_priv;
+  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];
+  memset(target_ssid, 0x0, sizeof(SSID_MAX_LEN + 1));
+
+  if (iwr == NULL)
+    {
+      wlerr("ERROR: Invalid ioctl cmd.\n");
+      return -EINVAL;
+    }
+
+  if (g_scan_priv.scan_status != ESP_SCAN_DISABLED)
+    {
+      return OK;
+    }
+
+  config = kmm_calloc(1, sizeof(wifi_scan_config_t));
+  if (config == NULL)
+    {
+      wlerr("ERROR: Cannot allocate result buffer\n");
+      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))
+    {
+      req = (struct iw_scan_req *)iwr->u.data.pointer;
+      config->scan_type = (req->scan_type == IW_SCAN_TYPE_ACTIVE ?
+            WIFI_SCAN_TYPE_ACTIVE : WIFI_SCAN_TYPE_PASSIVE);
+      if (iwr->u.data.flags & IW_SCAN_THIS_ESSID &&
+          req->essid_len < sizeof(target_ssid))
+        {
+          /* Scan specific ESSID */
+
+          config->show_hidden = true;
+          config->bssid = NULL;
+          memcpy(&target_ssid[0], req->essid, req->essid_len);
+          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
+    {
+      /* Default scan parameters */
+
+      wlinfo("INFO: Use default scan parameters\n");
+      config->scan_type = WIFI_SCAN_TYPE_ACTIVE; /* Active scan */
+    }
+
+  esp_wifi_start();
+  ret = esp_wifi_scan_start(config, false);
+  if (ret != OK)
+    {
+      wlerr("ERROR: Scan error, ret: %d\n", ret);
+    }
+  else
+    {
+      /* Allocate buffer to store scan result */
+
+      if (priv->scan_result == NULL)
+        {
+          priv->scan_result = kmm_malloc(WIFI_SCAN_RESULT_SIZE);
+          if (priv->scan_result == NULL)
+            {
+              wlerr("ERROR: Cannot allocate result buffer\n");
+              ret = -ENOMEM;
+            }
+          else
+            {
+              memset(priv->scan_result, 0x0, WIFI_SCAN_RESULT_SIZE);
+            }
+        }
+    }
+
+  if (config)
+    {
+      kmm_free(config);
+      config = NULL;
+      wlinfo("INFO: start scan\n");
+    }
+
+  g_scan_priv.scan_status = ESP_SCAN_RUN;
+
+  return ret;
+}
+
+/****************************************************************************
+ * Name: esp_wifi_get_scan_results
+ *
+ * Description:
+ *   Get scan result
+ *
+ * Input Parameters:
+ *   iwr - The argument of the ioctl cmd
+ *
+ * Returned Value:
+ *   OK on success (positive non-zero values are cmd-specific)
+ *   Negated errno returned on failure.
+ *
+ ****************************************************************************/
+
+int esp_wifi_get_scan_results(struct iwreq *iwr)
+{
+  int ret = OK;
+  static bool scan_block = false;
+  struct wifi_scan_result *priv = &g_scan_priv;
+
+  if (g_scan_priv.scan_status == ESP_SCAN_RUN)
+    {
+      irqstate_t irqstate = enter_critical_section();
+      if (scan_block == false)
+        {
+          scan_block = true;
+          leave_critical_section(irqstate);
+          nxsem_tickwait(&priv->scan_signal, SEC2TICK(SCAN_TIME_SEC));
+          scan_block = false;
+        }
+      else
+        {
+          leave_critical_section(irqstate);
+          ret = -EINVAL;
+          goto exit_failed;
+        }
+    }
+  else if (g_scan_priv.scan_status == ESP_SCAN_DISABLED)
+    {
+      return -EINVAL;
+    }
+
+  if ((iwr == NULL) || (g_scan_priv.scan_status != ESP_SCAN_DONE))
+    {
+      ret = -EINVAL;
+      goto exit_failed;
+    }
+
+  if (priv->scan_result == NULL)
+    {
+      /* Result have already been requested */
+
+      ret = OK;
+      iwr->u.data.length = 0;
+      goto exit_failed;
+    }
+
+  if (iwr->u.data.pointer == NULL ||
+      iwr->u.data.length < priv->scan_result_size)
+    {
+      /* Stat request, return scan_result_size */
+
+      ret = -E2BIG;
+      iwr->u.data.pointer = NULL;
+      iwr->u.data.length = priv->scan_result_size;
+      goto exit_failed;
+    }
+
+  if (priv->scan_result_size <= 0)
+    {
+      ret = OK;
+      iwr->u.data.length = 0;
+      goto exit_free_buffer;
+    }
+
+  /* Copy result to user buffer */
+
+  if (iwr->u.data.length > priv->scan_result_size)
+    {
+      iwr->u.data.length = priv->scan_result_size;
+    }
+
+  memcpy(iwr->u.data.pointer, priv->scan_result, iwr->u.data.length);
+
+exit_free_buffer:
+
+  /* Free scan result buffer */
+
+  kmm_free(priv->scan_result);
+  priv->scan_result = NULL;
+  priv->scan_result_size = 0;
+  g_scan_priv.scan_status = ESP_SCAN_DISABLED;
+
+exit_failed:
+  if (ret < 0)
+    {
+      iwr->u.data.length = 0;
+    }
+
+  return ret;
+}
+
+/****************************************************************************
+ * Name: esp_wifi_scan_event_parse
+ *
+ * Description:
+ *   Parse scan information
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+void esp_wifi_scan_event_parse(void)
+{
+  struct wifi_scan_result *priv = &g_scan_priv;
+  wifi_ap_record_t *ap_list_buffer = NULL;
+  uint16_t bss_total = 0;
+  uint8_t bss_count = 0;
+  bool parse_done = false;
+
+  if (priv->scan_status != ESP_SCAN_RUN)
+    {
+      return;
+    }
+
+  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");
+      nxsem_post(&priv->scan_signal);
+      return;
+    }
+
+  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");
+      nxsem_post(&priv->scan_signal);
+      return;
+    }
+
+  if (esp_wifi_scan_get_ap_records(&bss_total,
+              (wifi_ap_record_t *)ap_list_buffer) == OK)
+    {
+      struct iw_event *iwe;
+      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++)
+        {
+          if (g_channel_num > 1)
+            {
+              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;
+                    }
+                }
+            }
+          else
+            {
+              is_target_channel = true;
+            }
+
+          if (is_target_channel == true)
+            {
+              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 = (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);
+            }
+        }
+
+      parse_done = true;
+    }
+
+scan_result_full:
+
+  /* Continue instead of break to log dropped AP results */
+
+  if (parse_done == false)
+    {
+      wlerr("ERROR: No more space in scan_result buffer\n");
+    }
+
+  if (ap_list_buffer)
+    {
+      kmm_free(ap_list_buffer);
+      ap_list_buffer = NULL;
+    }
+
+  priv->scan_status = ESP_SCAN_DONE;
+  nxsem_post(&priv->scan_signal);
+}
+
+/****************************************************************************
+ * Name: esp_wifi_to_errno
+ *
+ * Description:
+ *   Transform from ESP Wi-Fi error code to NuttX error code
+ *
+ * Input Parameters:
+ *   ret - ESP Wi-Fi error code
+ *
+ * Returned Value:
+ *   NuttX error code defined in errno.h
+ *
+ ****************************************************************************/
+
+int32_t esp_wifi_to_errno(int ret)
+{
+  int err;
+
+  /* Unmask component error bits */
+
+  err = ret & 0xfff;
+
+  if (ret < ESP_ERR_WIFI_BASE)
+    {
+      if (err == ESP_OK)
+        {
+          return OK;
+        }
+      else
+        {
+          wlerr("ERROR: %s\n", esp_err_to_name(ret));
+          if (err == ESP_ERR_NO_MEM)
+            {
+              return -ENOMEM;
+            }
+          else if (err == ESP_ERR_INVALID_ARG)
+            {
+              return -EINVAL;
+            }
+          else if (err == ESP_ERR_INVALID_STATE)
+            {
+              return -EIO;
+            }
+          else if (err == ESP_ERR_INVALID_SIZE)
+            {
+              return -EINVAL;
+            }
+          else if (err == ESP_ERR_NOT_FOUND)
+            {
+              return -ENOSYS;
+            }
+          else if (err == ESP_ERR_NOT_SUPPORTED)
+            {
+              return -ENOSYS;
+            }
+          else if (err == ESP_ERR_TIMEOUT)
+            {
+              return -ETIMEDOUT;
+            }
+          else if (err == ESP_ERR_INVALID_MAC)
+            {
+              return -EINVAL;
+            }
+          else
+            {
+              return ERROR;
+            }

Review Comment:
   I didn't get the proposed changes... even copying and pasting it doesn't 
seem to contain any differences.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to