ESPHome  2023.5.5
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 
11 #include "esphome/core/hal.h"
12 #include "esphome/core/helpers.h"
13 #include "esphome/core/log.h"
14 #include "esphome/core/util.h"
15 
16 namespace esphome {
17 namespace wifi {
18 
19 static const char *const TAG = "wifi_pico_w";
20 
21 bool WiFiComponent::wifi_mode_(optional<bool> sta, optional<bool> ap) {
22  if (sta.has_value()) {
23  if (sta.value()) {
24  cyw43_wifi_set_up(&cyw43_state, CYW43_ITF_STA, true, CYW43_COUNTRY_WORLDWIDE);
25  }
26  }
27  if (ap.has_value()) {
28  if (ap.value()) {
29  cyw43_wifi_set_up(&cyw43_state, CYW43_ITF_AP, true, CYW43_COUNTRY_WORLDWIDE);
30  }
31  }
32  return true;
33 }
34 
36  uint32_t pm;
37  switch (this->power_save_) {
39  pm = CYW43_PERFORMANCE_PM;
40  break;
42  pm = CYW43_DEFAULT_PM;
43  break;
45  pm = CYW43_AGGRESSIVE_PM;
46  break;
47  }
48  int ret = cyw43_wifi_pm(&cyw43_state, pm);
49  return ret == 0;
50 }
51 
52 // TODO: The driver doesnt seem to have an API for this
53 bool WiFiComponent::wifi_apply_output_power_(float output_power) { return true; }
54 
55 bool WiFiComponent::wifi_sta_connect_(const WiFiAP &ap) {
56  if (!this->wifi_sta_ip_config_(ap.get_manual_ip()))
57  return false;
58 
59  auto ret = WiFi.begin(ap.get_ssid().c_str(), ap.get_password().c_str());
60  if (ret != WL_CONNECTED)
61  return false;
62 
63  return true;
64 }
65 
66 bool WiFiComponent::wifi_sta_pre_setup_() { return this->wifi_mode_(true, {}); }
67 
68 bool WiFiComponent::wifi_sta_ip_config_(optional<ManualIP> manual_ip) {
69  if (!manual_ip.has_value()) {
70  return true;
71  }
72 
73  IPAddress ip_address = IPAddress(manual_ip->static_ip);
74  IPAddress gateway = IPAddress(manual_ip->gateway);
75  IPAddress subnet = IPAddress(manual_ip->subnet);
76 
77  IPAddress dns = IPAddress(manual_ip->dns1);
78 
79  WiFi.config(ip_address, dns, gateway, subnet);
80  return true;
81 }
82 
84  WiFi.setHostname(App.get_name().c_str());
85  return true;
86 }
87 const char *get_auth_mode_str(uint8_t mode) {
88  // TODO:
89  return "UNKNOWN";
90 }
91 const char *get_disconnect_reason_str(uint8_t reason) {
92  // TODO:
93  return "UNKNOWN";
94 }
95 
97  int status = cyw43_tcpip_link_status(&cyw43_state, CYW43_ITF_STA);
98  switch (status) {
99  case CYW43_LINK_JOIN:
100  case CYW43_LINK_NOIP:
102  case CYW43_LINK_UP:
104  case CYW43_LINK_FAIL:
105  case CYW43_LINK_BADAUTH:
107  case CYW43_LINK_NONET:
109  }
111 }
112 
113 int WiFiComponent::s_wifi_scan_result(void *env, const cyw43_ev_scan_result_t *result) {
115  return 0;
116 }
117 
118 void WiFiComponent::wifi_scan_result(void *env, const cyw43_ev_scan_result_t *result) {
119  bssid_t bssid;
120  std::copy(result->bssid, result->bssid + 6, bssid.begin());
121  std::string ssid(reinterpret_cast<const char *>(result->ssid));
122  WiFiScanResult res(bssid, ssid, result->channel, result->rssi, result->auth_mode != CYW43_AUTH_OPEN, ssid.empty());
123  if (std::find(this->scan_result_.begin(), this->scan_result_.end(), res) == this->scan_result_.end()) {
124  this->scan_result_.push_back(res);
125  }
126 }
127 
128 bool WiFiComponent::wifi_scan_start_(bool passive) {
129  this->scan_result_.clear();
130  this->scan_done_ = false;
131  cyw43_wifi_scan_options_t scan_options = {0};
132  scan_options.scan_type = passive ? 1 : 0;
133  int err = cyw43_wifi_scan(&cyw43_state, &scan_options, nullptr, &s_wifi_scan_result);
134  if (err) {
135  ESP_LOGV(TAG, "cyw43_wifi_scan failed!");
136  }
137  return err == 0;
138  return true;
139 }
140 
142  // TODO:
143  return false;
144 }
145 
146 bool WiFiComponent::wifi_start_ap_(const WiFiAP &ap) {
147  if (!this->wifi_mode_({}, true))
148  return false;
149 
150  WiFi.beginAP(ap.get_ssid().c_str(), ap.get_password().c_str(), ap.get_channel().value_or(1));
151 
152  return true;
153 }
154 network::IPAddress WiFiComponent::wifi_soft_ap_ip() { return {WiFi.localIP()}; }
155 
157  int err = cyw43_wifi_leave(&cyw43_state, CYW43_ITF_STA);
158  return err == 0;
159 }
160 
162  bssid_t bssid{};
163  uint8_t raw_bssid[6];
164  WiFi.BSSID(raw_bssid);
165  for (size_t i = 0; i < bssid.size(); i++)
166  bssid[i] = raw_bssid[i];
167  return bssid;
168 }
169 std::string WiFiComponent::wifi_ssid() { return WiFi.SSID().c_str(); }
170 int8_t WiFiComponent::wifi_rssi() { return WiFi.RSSI(); }
171 int32_t WiFiComponent::wifi_channel_() { return WiFi.channel(); }
172 
173 network::IPAddress WiFiComponent::wifi_sta_ip() { return {WiFi.localIP()}; }
174 network::IPAddress WiFiComponent::wifi_subnet_mask_() { return {WiFi.subnetMask()}; }
175 network::IPAddress WiFiComponent::wifi_gateway_ip_() { return {WiFi.gatewayIP()}; }
177  const ip_addr_t *dns_ip = dns_getserver(num);
178  return {dns_ip->addr};
179 }
180 
182  if (this->state_ == WIFI_COMPONENT_STATE_STA_SCANNING && !cyw43_wifi_scan_active(&cyw43_state)) {
183  this->scan_done_ = true;
184  ESP_LOGV(TAG, "Scan done!");
185  }
186 }
187 
189 
190 } // namespace wifi
191 } // namespace esphome
192 
193 #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 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:143
uint8_t status
Definition: bl0942.h:23
const char * get_auth_mode_str(uint8_t mode)
Definition: a4988.cpp:4
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)