ESPHome  2024.4.0
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  // TODO:
145  return false;
146 }
147 
148 bool WiFiComponent::wifi_start_ap_(const WiFiAP &ap) {
149  if (!this->wifi_mode_({}, true))
150  return false;
151 
152  WiFi.beginAP(ap.get_ssid().c_str(), ap.get_password().c_str(), ap.get_channel().value_or(1));
153 
154  return true;
155 }
156 
157 network::IPAddress WiFiComponent::wifi_soft_ap_ip() { return {(const ip_addr_t *) WiFi.localIP()}; }
158 #endif // USE_WIFI_AP
159 
161  int err = cyw43_wifi_leave(&cyw43_state, CYW43_ITF_STA);
162  return err == 0;
163 }
164 
166  bssid_t bssid{};
167  uint8_t raw_bssid[6];
168  WiFi.BSSID(raw_bssid);
169  for (size_t i = 0; i < bssid.size(); i++)
170  bssid[i] = raw_bssid[i];
171  return bssid;
172 }
173 std::string WiFiComponent::wifi_ssid() { return WiFi.SSID().c_str(); }
174 int8_t WiFiComponent::wifi_rssi() { return WiFi.RSSI(); }
175 int32_t WiFiComponent::wifi_channel_() { return WiFi.channel(); }
176 
178  network::IPAddresses addresses;
179  uint8_t index = 0;
180  for (auto addr : addrList) {
181  addresses[index++] = addr.ipFromNetifNum();
182  }
183  return addresses;
184 }
185 network::IPAddress WiFiComponent::wifi_subnet_mask_() { return {(const ip_addr_t *) WiFi.subnetMask()}; }
186 network::IPAddress WiFiComponent::wifi_gateway_ip_() { return {(const ip_addr_t *) WiFi.gatewayIP()}; }
188  const ip_addr_t *dns_ip = dns_getserver(num);
189  return network::IPAddress(dns_ip);
190 }
191 
193  if (this->state_ == WIFI_COMPONENT_STATE_STA_SCANNING && !cyw43_wifi_scan_active(&cyw43_state)) {
194  this->scan_done_ = true;
195  ESP_LOGV(TAG, "Scan done!");
196  }
197 }
198 
200 
201 } // namespace wifi
202 } // namespace esphome
203 
204 #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)
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< uint8_t > & get_channel() const
BedjetMode mode
BedJet operating mode.
Definition: bedjet_codec.h:151
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:174
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
This is a workaround until we can figure out a way to get the tflite-micro idf component code availab...
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)