arduino-audio-tools
Loading...
Searching...
No Matches
WiFiZephyr.h
Go to the documentation of this file.
1#pragma once
2#include <string.h>
3#include <zephyr/kernel.h>
4#include <zephyr/net/net_event.h>
5#include <zephyr/net/net_if.h>
6#include <zephyr/net/net_ip.h>
7#include <zephyr/net/wifi_mgmt.h>
8#include <zephyr/sys/util.h>
9#include <zephyr/version.h>
10
11#include "AudioLogger.h"
12
13// ---------------------------------------------------------------------------
14// Kconfig guard — fail at compile time if prerequisites are missing
15// ---------------------------------------------------------------------------
16BUILD_ASSERT(IS_ENABLED(CONFIG_NETWORKING),
17 "WiFiZephyr requires CONFIG_NETWORKING=y");
18BUILD_ASSERT(IS_ENABLED(CONFIG_NET_L2_WIFI_MGMT),
19 "WiFiZephyr requires CONFIG_NET_L2_WIFI_MGMT=y");
20BUILD_ASSERT(IS_ENABLED(CONFIG_WIFI), "WiFiZephyr requires CONFIG_WIFI=y");
21BUILD_ASSERT(IS_ENABLED(CONFIG_NET_DHCPV4),
22 "WiFiZephyr requires CONFIG_NET_DHCPV4=y");
23
24namespace audio_tools {
25
35
50 public:
51 bool begin(const char* ssid, const char* password) {
52 TRACEI();
53 if (_is_open) return true;
54 if (!setupWIFI(ssid, password)) {
55 LOGE("setupWIFI failed");
56 return false;
57 }
58 return true;
59 }
60
61 void end() {
62 TRACED();
63 if (_is_open) {
64 TRACEI();
66 if (iface) {
69 }
72 }
73 _is_open = false;
74 }
75
81 void setPowerSave(enum wifi_ps mode) { _power_save = mode; }
82
83 bool isConnected() { return _is_open; }
84
86
88 const struct in_addr& ip() const { return _ip; }
89
90 const char* localIP() {
91 static char address_str[NET_IPV4_ADDR_LEN];
93 return address_str;
94 }
95
96 protected:
97 volatile bool _is_open = false;
98 struct in_addr _ip = {};
100
101 // net_mgmt callback handles — kept so we can unregister on end()
104
105 // ----------------------------------------------------------------
106 // Setup
107 // ----------------------------------------------------------------
108
109 bool setupWIFI(const char* ssid, const char* password) {
110 assert(ssid != nullptr);
111 assert(password != nullptr);
112 LOGI("setupWIFI: %s", ssid);
113
114 struct net_if* iface = net_if_get_default();
115 if (!iface) {
116 LOGE("No default network interface");
117 return false;
118 }
119
120 // Register event callbacks
125
129
130 // Store 'this' so static callbacks can reach the instance
131 _instance = this;
132
133 // Apply power-save before connecting
134 struct wifi_ps_params ps_params = {};
135 ps_params.enabled = _power_save;
137
138 // Build connection parameters
140 params.ssid = (const uint8_t*)ssid;
141 params.ssid_length = (uint8_t)strlen(ssid);
142 params.psk = (const uint8_t*)password;
143 params.psk_length = (uint8_t)strlen(password);
144 params.channel = WIFI_CHANNEL_ANY;
145 params.security = WIFI_SECURITY_TYPE_PSK; // WPA/WPA2-PSK
146
148 if (rc != 0) {
149 LOGE("NET_REQUEST_WIFI_CONNECT failed: %d", rc);
150 return false;
151 }
152
153 return true;
154 }
155
156 // ----------------------------------------------------------------
157 // Static event handlers
158 // ----------------------------------------------------------------
159
162 uint64_t mgmt_event, struct net_if* iface) {
163 WiFiZephyr* self = _instance;
164 if (!self) return;
165
167 const struct wifi_status* status = (const struct wifi_status*)cb->info;
168 if (status && status->status == 0) {
169 LOGI("WiFi connected — waiting for IP...");
170 // is_open is set in ip_event_handler once DHCP completes
171 } else {
172 LOGE("WiFi connection failed (status=%d)",
173 status ? status->status : -1);
174 // Auto-retry, mirroring ESP32 behavior
176 }
178 LOGI("WiFi disconnected — reconnecting...");
179 self->_is_open = false;
180 // Auto-reconnect (mirrors WIFI_EVENT_STA_DISCONNECTED handler)
182 }
183 }
184
187 uint64_t mgmt_event, struct net_if* iface) {
188 WiFiZephyr* self = _instance;
189 if (!self) return;
190
192 // Walk the interface's IPv4 address list to find the assigned addr
193 struct net_if_ipv4* ipv4 = iface->config.ip.ipv4;
194 if (!ipv4) return;
195
196 for (int i = 0; i < NET_IF_MAX_IPV4_ADDR; i++) {
197#if KERNEL_VERSION_NUMBER >= ZEPHYR_VERSION(3,4,0)
198 // New Zephyr: unicast[] is net_if_addr_ipv4, which wraps a net_if_addr
199 // in its .ipv4 member (plus a .netmask). All the original fields
200 // (is_used, addr_type, address) are accessed via .ipv4.
201 struct net_if_addr_ipv4* entry = &ipv4->unicast[i];
202 struct net_if_addr* addr = &entry->ipv4;
203#else
204 // Old Zephyr: unicast[] is net_if_addr directly
205 struct net_if_addr* addr = &ipv4->unicast[i];
206#endif
207 if (addr->is_used && addr->addr_type == NET_ADDR_DHCP &&
208 addr->address.family == AF_INET) {
209 self->_ip = addr->address.in_addr;
210 self->_is_open = true;
211
213 net_addr_ntop(AF_INET, &self->_ip, ip_str, sizeof(ip_str));
214 LOGI("==> Station connected with IP: %s", ip_str);
215 break;
216 }
217 }
218 }
219 }
220
221 // Single-instance pointer for static callbacks (same pattern as ESP32's
222 // `arg`)
224};
225
226// Out-of-line definition of the static member
227inline WiFiZephyr* WiFiZephyr::_instance = nullptr;
228
229// Global instance — mirrors `IDF_WIFI`
231
232} // namespace audio_tools
#define TRACEI()
Definition AudioLoggerIDF.h:32
#define TRACED()
Definition AudioLoggerIDF.h:31
#define LOGI(...)
Definition AudioLoggerIDF.h:28
#define LOGE(...)
Definition AudioLoggerIDF.h:30
BUILD_ASSERT(IS_ENABLED(CONFIG_NETWORKING), "WiFiZephyr requires CONFIG_NETWORKING=y")
#define assert(T)
Definition avr.h:10
Login to WiFi using Zephyr's wifi_mgmt / net_mgmt API. Access via the global object ZEPHYR_WIFI.
Definition WiFiZephyr.h:49
bool begin(const char *ssid, const char *password)
Definition WiFiZephyr.h:51
const struct in_addr & ip() const
Definition WiFiZephyr.h:88
struct in_addr _ip
Definition WiFiZephyr.h:98
bool isConnected()
Definition WiFiZephyr.h:83
struct net_mgmt_event_callback _wifi_cb
Definition WiFiZephyr.h:102
static void wifi_event_handler(struct net_mgmt_event_callback *cb, uint64_t mgmt_event, struct net_if *iface)
Definition WiFiZephyr.h:161
static void ip_event_handler(struct net_mgmt_event_callback *cb, uint64_t mgmt_event, struct net_if *iface)
Definition WiFiZephyr.h:186
bool setupWIFI(const char *ssid, const char *password)
Definition WiFiZephyr.h:109
void end()
Definition WiFiZephyr.h:61
void setPowerSave(enum wifi_ps mode)
Definition WiFiZephyr.h:81
volatile bool _is_open
Definition WiFiZephyr.h:97
enum wifi_ps _power_save
Definition WiFiZephyr.h:99
struct net_mgmt_event_callback _ip_cb
Definition WiFiZephyr.h:103
static WiFiZephyr * _instance
Definition WiFiZephyr.h:223
wifi_status_t status()
Definition WiFiZephyr.h:85
const char * localIP()
Definition WiFiZephyr.h:90
Generic Implementation of sound input and output for desktop environments using portaudio.
Definition AudioCodecsBase.h:10
wifi_status_t
Definition WiFiZephyr.h:26
@ WL_SCAN_COMPLETED
Definition WiFiZephyr.h:29
@ WL_IDLE_STATUS
Definition WiFiZephyr.h:27
@ WL_CONNECTED
Definition WiFiZephyr.h:30
@ WL_DISCONNECTED
Definition WiFiZephyr.h:33
@ WL_CONNECT_FAILED
Definition WiFiZephyr.h:31
@ WL_CONNECTION_LOST
Definition WiFiZephyr.h:32
@ WL_NO_SSID_AVAIL
Definition WiFiZephyr.h:28
static WiFiZephyr WiFi
Definition WiFiZephyr.h:230
size_t writeData(Print *p_out, T *data, int samples, int maxSamples=512)
Definition AudioTypes.h:508