SDK for TESAIoT Dev Kit
API reference & tutorials (ModusToolbox)
Loading...
Searching...
No Matches
WiFi overridables (implement, don't call)

The five WEAK hooks the consumer implements — and never calls. Compiled only with ENABLE_PAGE_BENTO_BUDDY=1 (default 0, proj_cm33_ns/Makefile:64, :305); rebuild after make getlibs — Flag gate (read first).

Variant
mtb-mpy and mtb-only

These five names are exactly template/lib/ble_nus/overridable.txt. The archive exports them WEAK; bento_secure_undeclared.h records "Define your own; yours wins at link time." The consumer implements them and never calls them — the archived radio scheduler calls into them. No shipped dist/ble_nus/include header declares them; the prototypes below are from template/proj_cm33_ns/wifi_init.h, and the strong definitions are in template/proj_cm33_ns/wifi_init.c (ships in both zips). Line mapping of those definitions, adjudicated in design review: :193 = app_wifi_connect_direct, :248 = app_wifi_disconnect, :256 = app_wifi_get_ipv4, :261 = lfs_save_wifi_creds, :304 = lfs_load_wifi_creds (numbers as of that review; the marker tags below are the durable reference). "0 template call sites" for all five is correct and expected.

app_wifi_connect_direct

int app_wifi_connect_direct(const char *ssid,
const char *password,
const char *security); /* wifi_init.h */

Contract (what your definition must do). Initialise WCM if needed, then cy_wcm_connect_ap with 3 retries; return 0 on success, non-zero (cy_rslt_t) on failure. The shipped override prints [wifi-glue] lines on each attempt — a live observable (wifi_init.c has no printf mute).

Template definition
(proj_cm33_ns/wifi_init.c):
int app_wifi_connect_direct(const char *ssid, const char *password, const char *security)
{
cy_rslt_t r = app_wifi_init();
if (CY_RSLT_SUCCESS != r) return (int)r;
cy_wcm_connect_params_t params;
memset(&params, 0, sizeof(params));
memset(&s_last_ip, 0, sizeof(s_last_ip));
size_t ssid_len = strlen(ssid);
if (ssid_len > sizeof(params.ap_credentials.SSID) - 1)
ssid_len = sizeof(params.ap_credentials.SSID) - 1;
memcpy(params.ap_credentials.SSID, ssid, ssid_len);
if (password != NULL) {
size_t pass_len = strlen(password);
if (pass_len > sizeof(params.ap_credentials.password) - 1)
pass_len = sizeof(params.ap_credentials.password) - 1;
memcpy(params.ap_credentials.password, password, pass_len);
}
/* Security mapping. Empty password → OPEN; explicit "WPA3" / "OPEN"
* supported per Desktop Buddy's wifi.connect verb. Default WPA2. */
if (security != NULL && strcmp(security, "WPA3") == 0) {
params.ap_credentials.security = CY_WCM_SECURITY_WPA3_SAE;
} else if ((security != NULL && strcmp(security, "OPEN") == 0)
|| params.ap_credentials.password[0] == '\0') {
params.ap_credentials.security = CY_WCM_SECURITY_OPEN;
} else {
params.ap_credentials.security = CY_WCM_SECURITY_WPA2_AES_PSK;
}
/* ...context: inside app_wifi_connect_direct() ... */
printf("[wifi-glue] connecting SSID=%s sec=%d\r\n",
params.ap_credentials.SSID, (int)params.ap_credentials.security);
/* Retry 3x with a 2s backoff — matches the modwifi.c policy and gives
* the AP time to ARM during a freshly-booted router. */
for (int attempt = 1; attempt <= 3; attempt++) {
r = cy_wcm_connect_ap(&params, &s_last_ip);
if (CY_RSLT_SUCCESS == r) {
uint32_t v4 = s_last_ip.ip.v4;
printf("[wifi-glue] connected, IP=%lu.%lu.%lu.%lu\r\n",
(unsigned long)(v4 & 0xFF),
(unsigned long)((v4 >> 8) & 0xFF),
(unsigned long)((v4 >> 16) & 0xFF),
(unsigned long)((v4 >> 24) & 0xFF));
return 0;
}
printf("[wifi-glue] attempt %d/3 failed (0x%08lX)\r\n",
attempt, (unsigned long)r);
if (attempt < 3) vTaskDelay(pdMS_TO_TICKS(2000));
}
return (int)r;
}
Retry-loop observables
(wifi_init.c:225-242):
/* ...context: inside app_wifi_connect_direct() ... */
printf("[wifi-glue] connecting SSID=%s sec=%d\r\n",
params.ap_credentials.SSID, (int)params.ap_credentials.security);
/* Retry 3x with a 2s backoff — matches the modwifi.c policy and gives
* the AP time to ARM during a freshly-booted router. */
for (int attempt = 1; attempt <= 3; attempt++) {
r = cy_wcm_connect_ap(&params, &s_last_ip);
if (CY_RSLT_SUCCESS == r) {
uint32_t v4 = s_last_ip.ip.v4;
printf("[wifi-glue] connected, IP=%lu.%lu.%lu.%lu\r\n",
(unsigned long)(v4 & 0xFF),
(unsigned long)((v4 >> 8) & 0xFF),
(unsigned long)((v4 >> 16) & 0xFF),
(unsigned long)((v4 >> 24) & 0xFF));
return 0;
}
printf("[wifi-glue] attempt %d/3 failed (0x%08lX)\r\n",
attempt, (unsigned long)r);

app_wifi_disconnect

int app_wifi_disconnect(void); /* wifi_init.h */

Contract. Tear down the active link; 0 on success; must be safe when not connected.

Template definition
int app_wifi_disconnect(void)
{
if (!wifi_ready) return 0;
cy_rslt_t r = cy_wcm_disconnect_ap();
memset(&s_last_ip, 0, sizeof(s_last_ip));
return (CY_RSLT_SUCCESS == r) ? 0 : (int)r;
}

app_wifi_get_ipv4

unsigned int app_wifi_get_ipv4(void); /* wifi_init.h */

Contract. Current IPv4 in network byte order, 0 if no link — the scheduler copies it into radio_status_t::ipv4.

Template definition
unsigned int app_wifi_get_ipv4(void)
{
return (unsigned int)s_last_ip.ip.v4;
}

lfs_save_wifi_creds

int lfs_save_wifi_creds(const char *ssid,
const char *password,
const char *security); /* wifi_init.h */

Contract. Save credentials to LittleFS; 0 on success, non-zero on write failure; existing credentials for the same SSID are overwritten. Locking caveat: the shipped definition is a read-modify-write of the LFS file directly, with no wifi_creds_lock — it bypasses g_boot_wifi_creds and can race a concurrent lfs_wifi_creds_write on the same file (there is no file-level lock outside mtb-only's bs_lock()). Called by the archived radio_scheduler_set_wifi_creds().

Template definition
(wifi_init.c, the :261 entry of the mapping):
int lfs_save_wifi_creds(const char *ssid, const char *password, const char *security)
{
if (!lfs_wifi_creds_ready()) return -1;
qspi_wifi_entry_t saved[QSPI_WIFI_CREDS_MAX];
int count = lfs_wifi_creds_read(saved, QSPI_WIFI_CREDS_MAX);
if (count < 0) count = 0;
/* Upsert: find existing slot for this SSID, else append (LRU eviction
* when full). */
int idx = -1;
for (int i = 0; i < count; i++) {
if (strncmp(saved[i].ssid, ssid, sizeof(saved[i].ssid)) == 0) {
idx = i;
break;
}
}
if (idx < 0) {
idx = (count < QSPI_WIFI_CREDS_MAX) ? count : 0;
if (count < QSPI_WIFI_CREDS_MAX) count++;
}
memset(&saved[idx], 0, sizeof(qspi_wifi_entry_t));
strncpy(saved[idx].ssid, ssid, sizeof(saved[idx].ssid) - 1);
if (password != NULL) {
strncpy(saved[idx].password, password, sizeof(saved[idx].password) - 1);
}
/* security field is uint8_t — store the low byte of the cy_wcm enum so
* we stay binary-compatible with modwifi.c's saved entries (which also
* writes the truncated enum). The low byte distinguishes the common
* cases: 0=OPEN, 4=WPA2_AES (also matches WPA3_SAE's low byte — WPA3
* is treated as WPA2 on the load path for now; explicit WPA3 storage
* requires bumping the struct format). */
bool is_open = (security != NULL && strcmp(security, "OPEN") == 0)
|| (password == NULL || password[0] == '\0');
saved[idx].security = is_open
? (uint8_t)(CY_WCM_SECURITY_OPEN & 0xFFu)
: (uint8_t)(CY_WCM_SECURITY_WPA2_AES_PSK & 0xFFu);
saved[idx].flags = 0x01; /* auto_connect */
return lfs_wifi_creds_write(saved, count) ? 0 : -2;
}

lfs_load_wifi_creds

bool lfs_load_wifi_creds(char *ssid_out, size_t ssid_cap,
char *pass_out, size_t pass_cap,
char *sec_out, size_t sec_cap); /* wifi_init.h */

Contract. true if credentials are present and non-empty, filling the output buffers NUL-terminated and truncated to cap - 1. In mtb-only this resolves against the C credential store. Read by the scheduler's boot decision (Wi-Fi if saved credentials exist under RADIO_BOOT_AUTO).

Template definition
(wifi_init.c, the :304 entry of the mapping):
bool lfs_load_wifi_creds(char *ssid_out, size_t ssid_cap,
char *pass_out, size_t pass_cap,
char *sec_out, size_t sec_cap)
{
if (!lfs_wifi_creds_ready()) return false;
qspi_wifi_entry_t entries[QSPI_WIFI_CREDS_MAX];
int count = lfs_wifi_creds_read(entries, QSPI_WIFI_CREDS_MAX);
if (count <= 0) return false;
/* Pick the most recently saved (last entry) for now — future work
* could try each in order until one connects. */
const qspi_wifi_entry_t *pick = &entries[count - 1];
if (pick->ssid[0] == '\0') return false;
if (ssid_out && ssid_cap > 0) {
strncpy(ssid_out, pick->ssid, ssid_cap - 1);
ssid_out[ssid_cap - 1] = '\0';
}
if (pass_out && pass_cap > 0) {
strncpy(pass_out, pick->password, pass_cap - 1);
pass_out[pass_cap - 1] = '\0';
}
if (sec_out && sec_cap > 0) {
/* security is the truncated low byte of the cy_wcm enum. 0=OPEN
* is the only case we need to distinguish on load; everything
* else maps to WPA2 (WPA3 storage isn't supported yet). */
const char *s = (pick->security == (uint8_t)(CY_WCM_SECURITY_OPEN & 0xFFu))
? "OPEN" : "WPA2";
strncpy(sec_out, s, sec_cap - 1);
sec_out[sec_cap - 1] = '\0';
}
return true;
}