ESPHome  2024.7.2
wifi_component_pico_w.cpp
Go to the documentation of this file.
1 
2 #include "wifi_component.h"
3 
4 #ifdef USE_RP2040
5 
6 #include "lwip/dns.h"
7 #include "lwip/err.h"
8 #include "lwip/netif.h"
9 #include <AddrList.h>
10 
12 #include "esphome/core/hal.h"
13 #include "esphome/core/helpers.h"
14 #include "esphome/core/log.h"
15 #include "esphome/core/util.h"
16 
17 namespace esphome {
18 namespace wifi {
19 
20 static const char *const TAG = "wifi_pico_w";
21 
22 bool WiFiComponent::wifi_mode_(optional<bool> sta, optional<bool> ap) {
23  if (sta.has_value()) {
24  if (sta.value()) {
25  cyw43_wifi_set_up(&cyw43_state, CYW43_ITF_STA, true, CYW43_COUNTRY_WORLDWIDE);
26  }
27  }
28  if (ap.has_value()) {
29  if (ap.value()) {
30  cyw43_wifi_set_up(&cyw43_state, CYW43_ITF_AP, true, CYW43_COUNTRY_WORLDWIDE);
31  }
32  }
33  return true;
34 }
35 
37  uint32_t pm;
38  switch (this->power_save_) {
40  pm = CYW43_PERFORMANCE_PM;
41  break;
43  pm = CYW43_DEFAULT_PM;
44  break;
46  pm = CYW43_AGGRESSIVE_PM;
47  break;
48  }
49  int ret = cyw43_wifi_pm(&cyw43_state, pm);
50  return ret == 0;
51 }
52 
53 // TODO: The driver doesnt seem to have an API for this
54 bool WiFiComponent::wifi_apply_output_power_(float output_power) { return true; }
55 
56 bool WiFiComponent::wifi_sta_connect_(const WiFiAP &ap) {
57  if (!this->wifi_sta_ip_config_(ap.get_manual_ip()))
58  return false;
59 
60  auto ret = WiFi.begin(ap.get_ssid().c_str(), ap.get_password().c_str());
61  if (ret != WL_CONNECTED)
62  return false;
63 
64  return true;
65 }
66 
67 bool WiFiComponent::wifi_sta_pre_setup_() { return this->wifi_mode_(true, {}); }
68 
69 bool WiFiComponent::wifi_sta_ip_config_(optional<ManualIP> manual_ip) {
70  if (!manual_ip.has_value()) {
71  return true;
72  }
73 
74  IPAddress ip_address = manual_ip->static_ip;
75  IPAddress gateway = manual_ip->gateway;
76  IPAddress subnet = manual_ip->subnet;
77 
78  IPAddress dns = manual_ip->dns1;
79 
80  WiFi.config(ip_address, dns, gateway, subnet);
81  return true;
82 }
83 
85  WiFi.setHostname(App.get_name().c_str());
86  return true;
87 }
88 const char *get_auth_mode_str(uint8_t mode) {
89  // TODO:
90  return "UNKNOWN";
91 }
92 const char *get_disconnect_reason_str(uint8_t reason) {
93  // TODO:
94  return "UNKNOWN";
95 }
96 
98  int status = cyw43_tcpip_link_status(&cyw43_state, CYW43_ITF_STA);
99  switch (status) {
100  case CYW43_LINK_JOIN:
101  case CYW43_LINK_NOIP:
103  case CYW43_LINK_UP:
105  case CYW43_LINK_FAIL:
106  case CYW43_LINK_BADAUTH:
108  case CYW43_LINK_NONET:
110  }
112 }
113 
114 int WiFiComponent::s_wifi_scan_result(void *env, const cyw43_ev_scan_result_t *result) {
116  return 0;
117 }
118 
119 void WiFiComponent::wifi_scan_result(void *env, const cyw43_ev_scan_result_t *result) {
120  bssid_t bssid;
121  std::copy(result->bssid, result->bssid + 6, bssid.begin());
122  std::string ssid(reinterpret_cast<const char *>(result->ssid));
123  WiFiScanResult res(bssid, ssid, result->channel, result->rssi, result->auth_mode != CYW43_AUTH_OPEN, ssid.empty());
124  if (std::find(this->scan_result_.begin(), this->scan_result_.end(), res) == this->scan_result_.end()) {
125  this->scan_result_.push_back(res);
126  }
127 }
128 
129 bool WiFiComponent::wifi_scan_start_(bool passive) {
130  this->scan_result_.clear();
131  this->scan_done_ = false;
132  cyw43_wifi_scan_options_t scan_options = {0};
133  scan_options.scan_type = passive ? 1 : 0;
134  int err = cyw43_wifi_scan(&cyw43_state, &scan_options, nullptr, &s_wifi_scan_result);
135  if (err) {
136  ESP_LOGV(TAG, "cyw43_wifi_scan failed!");
137  }
138  return err == 0;
139  return true;
140 }
141 
142 #ifdef USE_WIFI_AP
144  esphome::network::IPAddress ip_address, gateway, subnet, dns;
145  if (manual_ip.has_value()) {
146  ip_address = manual_ip->static_ip;
147  gateway = manual_ip->gateway;
148  subnet = manual_ip->subnet;
149  dns = manual_ip->static_ip;
150  } else {
151  ip_address = network::IPAddress(192, 168, 4, 1);
152  gateway = network::IPAddress(192, 168, 4, 1);
153  subnet = network::IPAddress(255, 255, 255, 0);
154  dns = network::IPAddress(192, 168, 4, 1);
155  }
156  WiFi.config(ip_address, dns, gateway, subnet);
157  return true;
158 }
159 
160 bool WiFiComponent::wifi_start_ap_(const WiFiAP &ap) {
161  if (!this->wifi_mode_({}, true))
162  return false;
163  if (!this->wifi_ap_ip_config_(ap.get_manual_ip())) {
164  ESP_LOGV(TAG, "wifi_ap_ip_config_ failed!");
165  return false;
166  }
167 
168  WiFi.beginAP(ap.get_ssid().c_str(), ap.get_password().c_str(), ap.get_channel().value_or(1));
169 
170  return true;
171 }
172 
173 network::IPAddress WiFiComponent::wifi_soft_ap_ip() { return {(const ip_addr_t *) WiFi.localIP()}; }
174 #endif // USE_WIFI_AP
175 
177  int err = cyw43_wifi_leave(&cyw43_state, CYW43_ITF_STA);
178  return err == 0;
179 }
180 
182  bssid_t bssid{};
183  uint8_t raw_bssid[6];
184  WiFi.BSSID(raw_bssid);
185  for (size_t i = 0; i < bssid.size(); i++)
186  bssid[i] = raw_bssid[i];
187  return bssid;
188 }
189 std::string WiFiComponent::wifi_ssid() { return WiFi.SSID().c_str(); }
190 int8_t WiFiComponent::wifi_rssi() { return WiFi.RSSI(); }
191 int32_t WiFiComponent::wifi_channel_() { return WiFi.channel(); }
192 
194  network::IPAddresses addresses;
195  uint8_t index = 0;
196  for (auto addr : addrList) {
197  addresses[index++] = addr.ipFromNetifNum();
198  }
199  return addresses;
200 }
201 network::IPAddress WiFiComponent::wifi_subnet_mask_() { return {(const ip_addr_t *) WiFi.subnetMask()}; }
202 network::IPAddress WiFiComponent::wifi_gateway_ip_() { return {(const ip_addr_t *) WiFi.gatewayIP()}; }
204  const ip_addr_t *dns_ip = dns_getserver(num);
205  return network::IPAddress(dns_ip);
206 }
207 
209  if (this->state_ == WIFI_COMPONENT_STATE_STA_SCANNING && !cyw43_wifi_scan_active(&cyw43_state)) {
210  this->scan_done_ = true;
211  ESP_LOGV(TAG, "Scan done!");
212  }
213 }
214 
216 
217 } // namespace wifi
218 } // namespace esphome
219 
220 #endif
std::array< uint8_t, 6 > bssid_t
const std::string & get_password() const
WiFiPowerSaveMode power_save_
network::IPAddress wifi_dns_ip_(int num)
bool wifi_mode_(optional< bool > sta, optional< bool > ap)
bool wifi_apply_output_power_(float output_power)
bool wifi_sta_ip_config_(optional< ManualIP > manual_ip)
bool has_value() const
Definition: optional.h:87
std::vector< WiFiScanResult > scan_result_
WiFi is in STA-only mode and currently scanning for APs.
const char *const TAG
Definition: spi.cpp:8
const optional< ManualIP > & get_manual_ip() const
const optional< uint8_t > & get_channel() const
BedjetMode mode
BedJet operating mode.
Definition: bedjet_codec.h:181
Application App
Global storage of Application pointer - only one Application can exist.
bool wifi_ap_ip_config_(optional< ManualIP > manual_ip)
WiFiComponent * global_wifi_component
const std::string & get_name() const
Get the name of this Application set by pre_setup().
Definition: application.h:202
std::array< IPAddress, 5 > IPAddresses
Definition: ip_address.h:139
uint8_t status
Definition: bl0942.h:23
const char * get_auth_mode_str(uint8_t mode)
in_addr ip_addr_t
Definition: ip_address.h:20
Implementation of SPI Controller mode.
Definition: a01nyub.cpp:7
const std::string & get_ssid() const
const char * get_disconnect_reason_str(uint8_t reason)
static int s_wifi_scan_result(void *env, const cyw43_ev_scan_result_t *result)
value_type value_or(U const &v) const
Definition: optional.h:93
void wifi_scan_result(void *env, const cyw43_ev_scan_result_t *result)