SDK สำหรับ TESAIoT Dev Kit
คู่มืออ้างอิง API และ Tutorial (MTB & µPython)
Loading...
Searching...
No Matches
WiFi overridables (นิยามเอง ห้ามเรียก)

WEAK hook 5 ตัวที่ผู้ใช้ไลบรารีเป็นฝ่ายนิยาม — และห้ามเรียก คอมไพล์เฉพาะเมื่อ ENABLE_PAGE_BENTO_BUDDY=1 (ค่าตั้งต้นคือ 0, proj_cm33_ns/Makefile:64, :305) ให้ build ใหม่หลังจาก make getlibs — ดู Flag gate (อ่านก่อน)

variant ที่ใช้ได้
mtb-mpy และ mtb-only

ชื่อทั้งห้านี้คือรายการใน template/lib/ble_nus/overridable.txt ทั้งหมดพอดี archive ส่งออกชื่อเหล่านี้เป็นแบบ WEAK และ bento_secure_undeclared.h บันทึกไว้ว่า "Define your own; yours wins at link time." ผู้ใช้ไลบรารีเป็นฝ่าย นิยาม ชื่อเหล่านี้ และห้ามเรียกมัน — radio scheduler ที่อยู่ใน archive เป็นฝ่ายเรียกเข้ามาเอง ไม่มี header ใน dist/ble_nus/include ที่ส่งมอบจริงตัวใดประกาศชื่อเหล่านี้ prototype ด้านล่างมาจาก template/proj_cm33_ns/wifi_init.h และนิยามแบบ strong อยู่ใน template/proj_cm33_ns/wifi_init.c (มีอยู่ในทั้งสอง zip) การจับคู่หมายเลขบรรทัดของนิยามเหล่านั้น ตามที่ตัดสินไว้ในการทบทวนแบบ: :193 = app_wifi_connect_direct, :248 = app_wifi_disconnect, :256 = app_wifi_get_ipv4, :261 = lfs_save_wifi_creds, :304 = lfs_load_wifi_creds (ตัวเลขเป็นค่า ณ การทบทวนครั้งนั้น marker tag ด้านล่างคือการอ้างอิงที่คงทนกว่า) การที่ทั้งห้าชื่อมี "0 template call sites" เป็นค่าที่ถูกต้องและเป็นไปตามที่คาดไว้

app_wifi_connect_direct

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

ข้อกำหนดการเรียกใช้ (สิ่งที่นิยามของผู้ใช้ไลบรารีต้องทำ) เริ่มต้น WCM ถ้าจำเป็น แล้วเรียก cy_wcm_connect_ap โดยลองซ้ำ 3 ครั้ง คืน 0 เมื่อสำเร็จ คืนค่าที่ไม่ใช่ศูนย์ (cy_rslt_t) เมื่อล้มเหลว การเขียนทับที่ส่งมอบจริงพิมพ์บรรทัด [wifi-glue] ออกมาทุกครั้งที่ลอง — เป็นสิ่งที่สังเกตได้จริง (wifi_init.c ไม่ได้ถูกปิดเสียง printf)

นิยามในเทมเพลต
(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
(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 */

ข้อกำหนดการเรียกใช้ รื้อ link ที่ทำงานอยู่ทิ้ง คืน 0 เมื่อสำเร็จ และต้องปลอดภัยเมื่อไม่ได้เชื่อมต่ออยู่

นิยามในเทมเพลต
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 */

ข้อกำหนดการเรียกใช้ ค่า IPv4 ปัจจุบันเรียงแบบ network byte order คืน 0 เมื่อไม่มี link — scheduler คัดลอกค่านี้ไปไว้ใน radio_status_t::ipv4

นิยามในเทมเพลต
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 */

ข้อกำหนดการเรียกใช้ บันทึกข้อมูลรับรองลง LittleFS คืน 0 เมื่อสำเร็จ คืนค่าที่ไม่ใช่ศูนย์เมื่อการเขียนล้มเหลว ข้อมูลรับรองเดิมของ SSID เดียวกันจะถูกเขียนทับ ข้อควรระวังเรื่อง lock: นิยามที่ส่งมอบจริงเป็น read-modify-write บนไฟล์ LFS โดยตรง โดยไม่มี wifi_creds_lock — มันข้าม g_boot_wifi_creds ไป และอาจชิงกับ lfs_wifi_creds_write ที่ทำงานพร้อมกันบนไฟล์เดียวกันได้ (ไม่มี lock ระดับไฟล์อยู่เลยนอกเหนือจาก bs_lock() ของ mtb-only) ถูกเรียกโดย radio_scheduler_set_wifi_creds() ที่อยู่ใน archive

นิยามในเทมเพลต
(wifi_init.c รายการที่ :261 ของการจับคู่ข้างต้น):
int lfs_save_wifi_creds(const char *ssid, const char *password, const char *security)
{
if (!lfs_wifi_creds_ready()) return -1;
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 */

ข้อกำหนดการเรียกใช้ คืน true เมื่อมีข้อมูลรับรองอยู่และไม่ว่างเปล่า พร้อมกับเติมบัฟเฟอร์ผลลัพธ์ให้ปิดท้ายด้วย NUL และตัดสั้นลงเหลือ cap - 1 บน mtb-only ชื่อนี้คลี่ไปยังที่เก็บข้อมูลรับรองฝั่ง C การตัดสินตอนบูตของ scheduler อ่านค่านี้ (เลือก Wi-Fi ถ้ามีข้อมูลรับรองบันทึกไว้ ภายใต้ RADIO_BOOT_AUTO)

นิยามในเทมเพลต
(wifi_init.c รายการที่ :304 ของการจับคู่ข้างต้น):
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;
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;
}