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

Functions

bool wifi_saved_probe_start (void)
 ส่ง probe ตรวจการมีอยู่ของ OPTIGA; ต้องเรียงลำดับ start → ready → finish อย่างเคร่งครัด
bool wifi_saved_probe_ready (void)
 อาจเป็น true ทันทีหลัง probe_start() — ต้องรองรับเส้นทางลัดที่มาจากผลที่แคชไว้
void wifi_saved_probe_finish (void)
 เรียกเพียงครั้งเดียวต่อหนึ่ง probe และเฉพาะหลัง probe_ready() เท่านั้น; เป็นตัวตั้งสถานะ OPTIGA / RAM-fallback
bool wifi_saved_read_start (int index)
 มีการอ่าน slot ค้างอยู่ได้ครั้งละหนึ่งรายการเท่านั้น; การคืนค่า false หมายถึงข้าม slot นั้นไป
bool wifi_saved_read_ready (void)
 ยังไม่พร้อมหมายถึงให้ลองใหม่ใน tick ถัดไป
bool wifi_saved_read_result (wifi_saved_entry_t *out)
 เติมข้อมูลลงในรายการที่ผู้เรียกเป็นเจ้าของ; false หมายถึงไม่มีข้อมูลใน slot นั้น
int wifi_saved_find (const char *ssid)
 Find a saved network by SSID.
bool wifi_saved_erase (int index)
 Erase a saved network from OPTIGA slot.
bool wifi_saved_add (const char *ssid, const char *password, uint8_t security)
 Add or update a network in saved list. If SSID already exists, updates in-place. If not, uses the first empty slot (or overwrites slot 0 if full).
int wifi_saved_load_all (wifi_saved_entry_t *entries)
 Load all saved networks into an array.
bool wifi_saved_load (int index, wifi_saved_entry_t *out)
 Load a saved network from OPTIGA slot.
bool wifi_saved_store (int index, const wifi_saved_entry_t *entry)
 Store a network entry to OPTIGA slot.
int wifi_saved_count (void)
 Count number of valid saved networks.

Detailed Description

Header: wifi_saved.h ตัวโค้ดจริง: wifi_saved.c ที่อยู่ใน archive (libbento_cm55.a) เก็บได้สูงสุด WIFI_SAVED_MAX (6) รายการ รายการละ 106 ไบต์แบบ packed หนึ่งรายการต่อหนึ่ง OPTIGA Type 3 data object พร้อม LRU eviction (การไล่รายการที่ไม่ได้ใช้นานที่สุดออก) และมี RAM fallback เมื่อไม่มี OPTIGA อยู่ รูปแบบการเข้าถึงมี 2 แบบ และเทมเพลตใช้ทั้ง 2 แบบโดยเจตนา ได้แก่ wifi_saved_load_all() แบบ synchronous (~1.5 s ใช้สำหรับการรีเฟรชหลังการแก้ข้อมูล) และกลไก probe + การอ่าน slot แบบ asynchronous (ใช้ตอนโหลดหน้าครั้งแรกเพื่อไม่ให้หน้าจอบล็อก) ผู้เรียกฝั่งเทมเพลตของทุกอย่างในหัวข้อนี้คือ proj_cm55/modules/page-components/wifi_connect/demo/wifi_connect_native/wifi_connect_native.c และ callback ของมันทุกตัวจะตรวจ s_ctx.ui == NULL ซ้ำก่อนเสมอ เพราะหน้านี้อาจถูกทำลายไปแล้วขณะที่ IPC ยังทำงานค้างอยู่

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

Function Documentation

◆ wifi_saved_probe_start()

bool wifi_saved_probe_start ( void )

ส่ง probe ตรวจการมีอยู่ของ OPTIGA; ต้องเรียงลำดับ start → ready → finish อย่างเคร่งครัด

ข้อกำหนดการเรียกใช้
ส่ง probe ตรวจการมีอยู่ของ OPTIGA แล้วคืนค่ากลับทันที ลำดับที่ต้องทำตามอย่างเคร่งครัด: probe_start() แล้ววนถาม probe_ready() แล้วจึง probe_finish() ผู้เรียกวนถามทุก 100 ms และลบ timer ของตัวเองก่อนเดินไปขั้นถัดไป ทำงานใน LVGL timer / GFX-task context
variant ที่ใช้ได้
mtb-mpy และ mtb-only
/* Phase 3b: Probe poll — fires every 100ms until OPTIGA probe completes */
static void wifi_native_saved_probe_poll_cb(lv_timer_t *timer)
{
if (!wifi_saved_probe_ready()) return;
lv_timer_delete(timer);
/* Start async slot loading — state machine: send → poll → next */
s_saved_count = 0;
s_saved_load_idx = 0;
s_slot_state = SLOT_SEND;
lv_timer_create(wifi_native_saved_slot_cb, 50, NULL);
}
/* Phase 3a: Start async OPTIGA probe */
static void wifi_native_deferred_load_saved_cb(lv_timer_t *timer)
{
lv_timer_delete(timer);
if (s_ctx.ui == NULL) return;
/* Already probed (cached) — skip poll, go straight to slot loading */
s_saved_count = 0;
s_saved_load_idx = 0;
s_slot_state = SLOT_SEND;
lv_timer_create(wifi_native_saved_slot_cb, 50, NULL);
} else {
/* Probe IPC in flight — poll until ready */
lv_timer_create(wifi_native_saved_probe_poll_cb, 100, NULL);
}
}

◆ wifi_saved_probe_ready()

bool wifi_saved_probe_ready ( void )

อาจเป็น true ทันทีหลัง probe_start() — ต้องรองรับเส้นทางลัดที่มาจากผลที่แคชไว้

ข้อกำหนดการเรียกใช้
อาจเป็น true ทันทีหลัง probe_start() (เป็นผลที่แคชไว้) — ผู้เรียกต้องรองรับเส้นทางลัดนั้น แทนที่จะตั้ง timer สำหรับวนถามโดยไม่มีเงื่อนไข ซึ่งเป็นเหตุผลที่เทมเพลตมี call site (จุดที่มีการเรียกจริง) 2 จุด ทำงานใน GFX-task context
variant ที่ใช้ได้
mtb-mpy และ mtb-only
/* Phase 3b: Probe poll — fires every 100ms until OPTIGA probe completes */
static void wifi_native_saved_probe_poll_cb(lv_timer_t *timer)
{
if (!wifi_saved_probe_ready()) return;
lv_timer_delete(timer);
/* Start async slot loading — state machine: send → poll → next */
s_saved_count = 0;
s_saved_load_idx = 0;
s_slot_state = SLOT_SEND;
lv_timer_create(wifi_native_saved_slot_cb, 50, NULL);
}
/* Phase 3a: Start async OPTIGA probe */
static void wifi_native_deferred_load_saved_cb(lv_timer_t *timer)
{
lv_timer_delete(timer);
if (s_ctx.ui == NULL) return;
/* Already probed (cached) — skip poll, go straight to slot loading */
s_saved_count = 0;
s_saved_load_idx = 0;
s_slot_state = SLOT_SEND;
lv_timer_create(wifi_native_saved_slot_cb, 50, NULL);
} else {
/* Probe IPC in flight — poll until ready */
lv_timer_create(wifi_native_saved_probe_poll_cb, 100, NULL);
}
}

◆ wifi_saved_probe_finish()

void wifi_saved_probe_finish ( void )

เรียกเพียงครั้งเดียวต่อหนึ่ง probe และเฉพาะหลัง probe_ready() เท่านั้น; เป็นตัวตั้งสถานะ OPTIGA / RAM-fallback

ข้อกำหนดการเรียกใช้
เรียกเพียงครั้งเดียวต่อหนึ่ง probe และเฉพาะหลังจาก probe_ready() คืนค่า true แล้วเท่านั้น ฟังก์ชันนี้เป็นตัวตั้งสถานะ OPTIGA / RAM-fallback ที่การอ่านทั้งหมดต้องอาศัย หลังจากเรียกแล้ว wifi_saved_load() จะข้ามขั้น probe ไป ทำงานใน GFX-task context
variant ที่ใช้ได้
mtb-mpy และ mtb-only
/* Phase 3b: Probe poll — fires every 100ms until OPTIGA probe completes */
static void wifi_native_saved_probe_poll_cb(lv_timer_t *timer)
{
if (!wifi_saved_probe_ready()) return;
lv_timer_delete(timer);
/* Start async slot loading — state machine: send → poll → next */
s_saved_count = 0;
s_saved_load_idx = 0;
s_slot_state = SLOT_SEND;
lv_timer_create(wifi_native_saved_slot_cb, 50, NULL);
}
/* Phase 3a: Start async OPTIGA probe */
static void wifi_native_deferred_load_saved_cb(lv_timer_t *timer)
{
lv_timer_delete(timer);
if (s_ctx.ui == NULL) return;
/* Already probed (cached) — skip poll, go straight to slot loading */
s_saved_count = 0;
s_saved_load_idx = 0;
s_slot_state = SLOT_SEND;
lv_timer_create(wifi_native_saved_slot_cb, 50, NULL);
} else {
/* Probe IPC in flight — poll until ready */
lv_timer_create(wifi_native_saved_probe_poll_cb, 100, NULL);
}
}

◆ wifi_saved_read_start()

bool wifi_saved_read_start ( int index)

มีการอ่าน slot ค้างอยู่ได้ครั้งละหนึ่งรายการเท่านั้น; การคืนค่า false หมายถึงข้าม slot นั้นไป

ข้อกำหนดการเรียกใช้
มีการอ่านค้างอยู่ได้ครั้งละหนึ่งรายการเท่านั้น: เป็น state machine แบบ SEND แล้วจึง POLL อย่างชัดเจน อ่านหนึ่ง slot ต่อหนึ่ง tick ขนาด 50 ms ห้ามสั่งอ่านซ้ำก่อน read_ready() การคืนค่า false เป็นเส้นทางข้อผิดพลาดจริง — เทมเพลตจะข้าม slot นั้นแล้วเดินหน้าต่อ ไม่ลองใหม่และไม่ยกเลิกทั้งกระบวนการ เรียกได้เฉพาะหลังลำดับ probe เสร็จสิ้นแล้ว (callback ของ slot ถูกสร้างขึ้นหลัง probe_finish() เท่านั้น) ทำงานใน GFX-task context
variant ที่ใช้ได้
mtb-mpy และ mtb-only
/* Phase 3c: Async slot read — state machine: SEND (instant) → POLL (instant) */
static void wifi_native_saved_slot_cb(lv_timer_t *timer)
{
if (s_ctx.ui == NULL) { lv_timer_delete(timer); return; }
if (s_slot_state == SLOT_SEND) {
if (s_saved_load_idx >= WIFI_SAVED_MAX) {
lv_timer_delete(timer);
aic_wifi_set_saved_networks(s_ctx.ui, s_saved_buf, s_saved_count);
return;
}
/* Send IPC for this slot — returns instantly */
if (wifi_saved_read_start(s_saved_load_idx)) {
s_slot_state = SLOT_POLL;
} else {
/* Send failed — skip this slot */
s_saved_load_idx++;
}
return;
}
/* SLOT_POLL: check if IPC response is ready */
if (!wifi_saved_read_ready()) return; /* Not ready — try next tick */
memcpy(&s_saved_buf[s_saved_count], &tmp, sizeof(tmp));
s_saved_count++;
}
s_saved_load_idx++;
s_slot_state = SLOT_SEND; /* Next tick: send for next slot */
}

◆ wifi_saved_read_ready()

bool wifi_saved_read_ready ( void )

ยังไม่พร้อมหมายถึงให้ลองใหม่ใน tick ถัดไป

ข้อกำหนดการเรียกใช้
ยังไม่พร้อมหมายถึงให้ลองใหม่ใน tick ถัดไป — ให้คืนค่าออกจาก callback ของ timer และปล่อย state machine ค้างไว้ที่สถานะ POLL ทำงานใน GFX-task context
variant ที่ใช้ได้
mtb-mpy และ mtb-only
/* Phase 3c: Async slot read — state machine: SEND (instant) → POLL (instant) */
static void wifi_native_saved_slot_cb(lv_timer_t *timer)
{
if (s_ctx.ui == NULL) { lv_timer_delete(timer); return; }
if (s_slot_state == SLOT_SEND) {
if (s_saved_load_idx >= WIFI_SAVED_MAX) {
lv_timer_delete(timer);
aic_wifi_set_saved_networks(s_ctx.ui, s_saved_buf, s_saved_count);
return;
}
/* Send IPC for this slot — returns instantly */
if (wifi_saved_read_start(s_saved_load_idx)) {
s_slot_state = SLOT_POLL;
} else {
/* Send failed — skip this slot */
s_saved_load_idx++;
}
return;
}
/* SLOT_POLL: check if IPC response is ready */
if (!wifi_saved_read_ready()) return; /* Not ready — try next tick */
memcpy(&s_saved_buf[s_saved_count], &tmp, sizeof(tmp));
s_saved_count++;
}
s_saved_load_idx++;
s_slot_state = SLOT_SEND; /* Next tick: send for next slot */
}

◆ wifi_saved_read_result()

bool wifi_saved_read_result ( wifi_saved_entry_t * out)

เติมข้อมูลลงในรายการที่ผู้เรียกเป็นเจ้าของ; false หมายถึงไม่มีข้อมูลใน slot นั้น

ข้อกำหนดการเรียกใช้
เติมข้อมูลลงใน wifi_saved_entry_t บน stack ที่ผู้เรียกเป็นเจ้าของ ให้คัดลอกออกมาทันที การคืนค่า false ไม่ใช่ความผิดพลาดร้ายแรง — เพียงแต่ slot นั้นไม่ปรากฏในผลลัพธ์ และดัชนีจะเดินต่อไป ทำงานใน GFX-task context
variant ที่ใช้ได้
mtb-mpy และ mtb-only
/* Phase 3c: Async slot read — state machine: SEND (instant) → POLL (instant) */
static void wifi_native_saved_slot_cb(lv_timer_t *timer)
{
if (s_ctx.ui == NULL) { lv_timer_delete(timer); return; }
if (s_slot_state == SLOT_SEND) {
if (s_saved_load_idx >= WIFI_SAVED_MAX) {
lv_timer_delete(timer);
aic_wifi_set_saved_networks(s_ctx.ui, s_saved_buf, s_saved_count);
return;
}
/* Send IPC for this slot — returns instantly */
if (wifi_saved_read_start(s_saved_load_idx)) {
s_slot_state = SLOT_POLL;
} else {
/* Send failed — skip this slot */
s_saved_load_idx++;
}
return;
}
/* SLOT_POLL: check if IPC response is ready */
if (!wifi_saved_read_ready()) return; /* Not ready — try next tick */
memcpy(&s_saved_buf[s_saved_count], &tmp, sizeof(tmp));
s_saved_count++;
}
s_saved_load_idx++;
s_slot_state = SLOT_SEND; /* Next tick: send for next slot */
}

◆ wifi_saved_find()

int wifi_saved_find ( const char * ssid)

Find a saved network by SSID.

แปลง SSID เป็น slot ในที่เก็บ — ดัชนีในรายการบน UI ไม่ใช่ดัชนีของ slot

Parameters
ssidSSID to search for
Returns
Slot index 0..5 if found, -1 if not found
ข้อกำหนดการเรียกใช้
ดัชนีในรายการบน UI ไม่ใช่ดัชนีของ slot ในที่เก็บ (store) — เป็นข้อเท็จจริงที่สำคัญที่สุดข้อเดียวในหัวข้อนี้ ให้ใช้ฟังก์ชันนี้แปลง SSID เป็น slot ก่อนสั่งลบทุกครั้ง และคืนค่า < 0 เมื่อหาไม่พบ ภายในขับเคลื่อนด้วย wifi_saved_load() ชั้นที่เก็บ (probe) จึงต้องพร้อมทำงานอยู่ก่อนแล้ว
variant ที่ใช้ได้
mtb-mpy และ mtb-only
static void wifi_native_on_saved_delete(int saved_index)
{
/* Find the OPTIGA slot index for this entry */
if (!s_ctx.ui) return;
if (saved_index < 0 || saved_index >= s_ctx.ui->saved_count) return;
/* Find the matching slot by SSID (saved_index is UI order, need OPTIGA slot) */
const char *ssid = s_ctx.ui->saved_entries[saved_index].ssid;
int slot = wifi_saved_find(ssid);
if (slot >= 0) {
}
/* Refresh saved networks UI */
wifi_native_refresh_saved();
}

◆ wifi_saved_erase()

bool wifi_saved_erase ( int index)

Erase a saved network from OPTIGA slot.

ลบข้อมูลใน slot เดียวที่หาได้จาก wifi_saved_find(); การกู้คืนคือการรีเฟรชทั้งหมด

Parameters
indexSlot index 0..5
Returns
true on success
ข้อกำหนดการเรียกใช้
มีตัวกัน (guard) เป็นเงื่อนไข slot >= 0 ที่ได้จาก wifi_saved_find() ผู้เรียกที่มีอยู่จริงในของที่ส่งมอบละเลยค่า bool ที่คืนกลับมาโดยเจตนา เพราะการกู้คืนคือการรีเฟรช UI ทั้งหมดผ่าน wifi_saved_load_all()
variant ที่ใช้ได้
mtb-mpy และ mtb-only
static void wifi_native_on_saved_delete(int saved_index)
{
/* Find the OPTIGA slot index for this entry */
if (!s_ctx.ui) return;
if (saved_index < 0 || saved_index >= s_ctx.ui->saved_count) return;
/* Find the matching slot by SSID (saved_index is UI order, need OPTIGA slot) */
const char *ssid = s_ctx.ui->saved_entries[saved_index].ssid;
int slot = wifi_saved_find(ssid);
if (slot >= 0) {
}
/* Refresh saved networks UI */
wifi_native_refresh_saved();
}

◆ wifi_saved_add()

bool wifi_saved_add ( const char * ssid,
const char * password,
uint8_t security )

Add or update a network in saved list. If SSID already exists, updates in-place. If not, uses the first empty slot (or overwrites slot 0 if full).

บันทึกข้อมูลรับรองเฉพาะหลังยืนยันแล้วว่าการเชื่อมโยง (association) สำเร็จเท่านั้น

Parameters
ssidNetwork SSID
passwordNetwork password
securitySecurity type
Returns
true on success
ข้อกำหนดการเรียกใช้
เรียกได้เฉพาะหลังจากยืนยันแล้วว่าการเชื่อมโยง (association) สำเร็จเท่านั้น — ห้ามเรียกในเส้นทางกรอกข้อมูลรับรอง และห้ามเรียกล่วงหน้าแบบเดาไว้ก่อน การเชื่อมต่อจะถูกลองใหม่เพียงครั้งเดียวก่อน (เป็นพฤติกรรมแปลกของการเปลี่ยนสถานะใน WCM หลังการ scan) ผู้เรียกไม่ได้เตรียมข้อมูลลงในรายการล่วงหน้า เพราะการ dedupe ผ่าน find, การเติมศูนย์, การปิดท้ายด้วย NUL ที่ ssid[32] / password[64], flags = 0x01 (auto-connect) และ last_used ล้วนเป็นงานภายในทั้งหมด (wifi_saved.c:266-304) และการเขียนลงที่เก็บทำผ่าน wifi_saved_store() ผู้เรียกที่มีอยู่จริงในของที่ส่งมอบไม่ตรวจค่าที่คืนกลับมา การรีเฟรชที่ตามมาจึงเป็นการตรวจสอบโดยพฤตินัย
variant ที่ใช้ได้
mtb-mpy และ mtb-only
/* ...context: inside the deferred connect callback, after a confirmed association ... */
/* Auto-retry: cy_wcm_connect_ap() often fails on the first attempt
* after a scan due to internal WCM state transition. Retry once. */
bool ok = wifi_manager_connect(s_ctx.pending_ssid, s_ctx.pending_password);
if (!ok) {
ok = wifi_manager_connect(s_ctx.pending_ssid, s_ctx.pending_password);
}
if (!ok) {
aic_wifi_set_state(s_ctx.ui, WIFI_STATE_ERROR);
aic_wifi_show_error(s_ctx.ui, WIFI_ERR_AUTH_FAILED, "Connect failed");
return;
}
/* Auto-save credentials on successful connect */
wifi_saved_add(s_ctx.pending_ssid, s_ctx.pending_password, s_ctx.pending_security);
wifi_native_refresh_saved();
wifi_native_scan_and_update();
}

◆ wifi_saved_load_all()

int wifi_saved_load_all ( wifi_saved_entry_t * entries)

Load all saved networks into an array.

อ่านทั้งหมดแบบ synchronous (~1.5 s) ลงใน wifi_saved_entry_t[WIFI_SAVED_MAX]

Parameters
entriesOutput array (must have WIFI_SAVED_MAX elements)
Returns
Number of valid entries loaded (0..6)
ข้อกำหนดการเรียกใช้
บัฟเฟอร์ต้องเป็น wifi_saved_entry_t[WIFI_SAVED_MAX] เพราะไม่มีอาร์กิวเมนต์บอกความจุ คืนค่าเป็นจำนวนรายการที่เติมได้ (บีบให้ต่อเนื่องกันแล้ว) ไม่ใช่สถานะ นี่คือเส้นทางแบบ synchronous (วนเรียก wifi_saved_load() ใช้เวลา ~1.5 s — ดูคอมเมนต์ที่ wifi_connect_native.c:136-143) ใช้สำหรับการรีเฟรชหลังการแก้ข้อมูล ส่วนการโหลดหน้าครั้งแรกใช้กลไก probe + การอ่านแบบ async แทน ให้คงการแยกนี้ไว้
variant ที่ใช้ได้
mtb-mpy และ mtb-only
static void wifi_native_refresh_saved(void)
{
if (!s_ctx.ui) return;
int count = wifi_saved_load_all(entries);
aic_wifi_set_saved_networks(s_ctx.ui, entries, count);
}

◆ wifi_saved_load()

bool wifi_saved_load ( int index,
wifi_saved_entry_t * out )

Load a saved network from OPTIGA slot.

อ่าน slot เดียวแบบ synchronous; เป็นฟังก์ชันภายใน — ผู้ใช้ไลบรารีให้ใช้ load_all()/find()

Parameters
indexSlot index 0..5
outOutput entry (filled on success)
Returns
true if a valid entry was read, false if empty/error
ข้อกำหนดการเรียกใช้
อ่าน slot เดียวแบบ synchronous มีผู้เรียก 5 จุด อยู่ภายใน wifi_saved.c ทั้งหมด (:252, :271, :282, :312, :325) ผู้ใช้ไลบรารีให้ใช้ wifi_saved_load_all() หรือ wifi_saved_find() ตัวอย่างที่เขียนขึ้นเองระบุไว้เช่นนั้น และแสดงเหตุผลอันชอบธรรมข้อเดียวที่จะหยิบฟังก์ชันนี้มาใช้
variant ที่ใช้ได้
mtb-mpy และ mtb-only
ตัวอย่าง (เขียนขึ้นเอง — ไม่มี call site ในของที่ส่งมอบจริง)
static void bento_ex_wifi_saved_load(void)
{
/* Supported consumer path: whole-table load + SSID resolve. */
wifi_saved_entry_t table[WIFI_SAVED_MAX]; /* exact size — no cap arg */
int n = wifi_saved_load_all(table); /* populated count 0..6 */
int slot = wifi_saved_find("MyNetwork"); /* -1 on miss; slot != UI
* list index */
(void)n;
/* The primitive underneath (internal to wifi_saved.c in shipped
* firmware) — false means empty slot or read error, same as absent: */
if (slot >= 0) {
if (!wifi_saved_load(slot, &one)) {
return; /* slot empty since find */
}
(void)one;
}
}

◆ wifi_saved_store()

bool wifi_saved_store ( int index,
const wifi_saved_entry_t * entry )

Store a network entry to OPTIGA slot.

เขียน slot เดียว; เป็นฟังก์ชันภายในของ wifi_saved_add() — การเรียกโดยตรงจะข้ามการ dedupe

Parameters
indexSlot index 0..5
entryEntry to write
Returns
true on success
ข้อกำหนดการเรียกใช้
เขียน slot เดียว ผู้เรียกเพียงรายเดียวอยู่ภายใน — wifi_saved.c:304 จากภายใน wifi_saved_add() หลังจากฟังก์ชันนั้นประกอบรายการเสร็จแล้ว ผู้ใช้ไลบรารีให้ใช้ wifi_saved_add() การเรียกฟังก์ชันนี้โดยตรงจะข้ามการ dedupe, การปิดท้ายด้วย NUL และการประทับเวลาแบบ LRU
variant ที่ใช้ได้
mtb-mpy และ mtb-only
ตัวอย่าง (เขียนขึ้นเอง — ไม่มี call site ในของที่ส่งมอบจริง)
static void bento_ex_wifi_saved_store(void)
{
/* RIGHT — after the connect succeeded (retried once, per the shipped
* UI path), let add() place the entry: */
if (!wifi_saved_add("MyNetwork", "correct-horse", 3u /* WPA2 */)) {
return; /* slot machinery refused */
}
/* The primitive underneath is store(index, entry) — internal in
* shipped firmware. Shown for completeness only; if you find
* yourself filling a wifi_saved_entry_t by hand, you are
* re-implementing add() without its dedupe/LRU. */
}

◆ wifi_saved_count()

int wifi_saved_count ( void )

Count number of valid saved networks.

คืนค่า 0..6; ไม่มีผู้เรียกเลยทั้ง workspace

Returns
Count 0..6
ข้อกำหนดการเรียกใช้
คืนค่า 0..6 ไม่มีผู้เรียกเลยทั้ง workspace — มีนิยามที่เหมือนกัน 14 ชุดกระจายอยู่ในบอร์ดพี่น้องกัน และไม่เคยมีการเรียกเลย UI ที่ส่งมอบจริงหาจำนวนรายการจากค่าที่ wifi_saved_load_all() คืนกลับมาแทน เป็นตัวอย่างที่เขียนขึ้นเอง
variant ที่ใช้ได้
mtb-mpy และ mtb-only
ตัวอย่าง (เขียนขึ้นเอง — ไม่มี call site ในของที่ส่งมอบจริง)
static void bento_ex_wifi_saved_count(void)
{
/* Quick has-any-credentials decision (e.g. skip a "saved networks"
* section entirely when empty): */
if (wifi_saved_count() == 0) {
return; /* nothing saved — hide the list */
}
/* If you are about to render the entries, prefer one load_all() —
* its return value IS the count. */
}