ci / verify (push) Canceled after 0s
Add customer and operator login, BLE provisioning, device fleet controls, call memory, memoir generation, and refreshed family and maintenance portals. Include API contracts, migrations, firmware sources, tests, assets, and deployment documentation.
209 lines
9.8 KiB
C
209 lines
9.8 KiB
C
// Host SDK shim: only SDK calls are mocked; the driver lifecycle under test is
|
|
// inserted verbatim from main/ble_wifi.c by ble-wifi-host.cjs.
|
|
#include <assert.h>
|
|
#include <stdbool.h>
|
|
#include <stdint.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
typedef int esp_err_t;
|
|
#define ESP_OK 0
|
|
#define ESP_ERR_NO_MEM 1
|
|
#define ESP_ERR_INVALID_STATE 2
|
|
#define ESP_ERR_INVALID_ARG 3
|
|
#define ESP_ERR_TIMEOUT 4
|
|
#define ESP_FAIL 5
|
|
#define BIT0 1
|
|
#define BIT1 2
|
|
#define BIT2 4
|
|
#define pdFALSE 0
|
|
#define pdMS_TO_TICKS(x) (x)
|
|
#define MALLOC_CAP_INTERNAL 1
|
|
#define ESP_EVENT_ANY_ID (-1)
|
|
#define WIFI_EVENT 1
|
|
#define IP_EVENT 2
|
|
#define IP_EVENT_STA_GOT_IP 1
|
|
#define WIFI_EVENT_STA_DISCONNECTED 2
|
|
#define WIFI_EVENT_STA_STOP 3
|
|
#define WIFI_STORAGE_RAM 1
|
|
#define WIFI_MODE_STA 1
|
|
#define WIFI_IF_STA 0
|
|
#define WIFI_AUTH_WPA2_PSK 3
|
|
#define WIFI_ALL_CHANNEL_SCAN 1
|
|
#define WIFI_CONNECT_AP_BY_SIGNAL 1
|
|
typedef int esp_event_base_t;
|
|
typedef int *esp_event_handler_instance_t;
|
|
typedef unsigned EventBits_t;
|
|
typedef EventBits_t *EventGroupHandle_t;
|
|
typedef struct { int placeholder; } esp_netif_t;
|
|
typedef struct { int placeholder; } esp_netif_config_t;
|
|
#define ESP_NETIF_DEFAULT_WIFI_STA() ((esp_netif_config_t){0})
|
|
typedef struct { unsigned reason; } wifi_event_sta_disconnected_t;
|
|
typedef struct {
|
|
int static_rx_buf_num, dynamic_rx_buf_num, static_tx_buf_num, cache_tx_buf_num;
|
|
int ampdu_rx_enable, ampdu_tx_enable, amsdu_tx_enable;
|
|
} wifi_init_config_t;
|
|
#define WIFI_INIT_CONFIG_DEFAULT() ((wifi_init_config_t){16,32,16,32,1,1,0})
|
|
typedef struct { struct {
|
|
char ssid[32], password[64];
|
|
struct { int authmode; } threshold;
|
|
int scan_method, sort_method;
|
|
} sta; } wifi_config_t;
|
|
static void mock_log(const char *tag, const char *format, ...) {(void)tag; (void)format;}
|
|
#define ESP_LOGI(...) mock_log(__VA_ARGS__)
|
|
#define ESP_LOGW(...) mock_log(__VA_ARGS__)
|
|
#define ESP_LOGE(...) mock_log(__VA_ARGS__)
|
|
static const char *esp_err_to_name(esp_err_t err) {(void)err; return "mock";}
|
|
static unsigned heap_caps_get_free_size(int cap) {(void)cap; return 50000;}
|
|
static unsigned heap_caps_get_largest_free_block(int cap) {(void)cap; return 30000;}
|
|
|
|
enum point { NONE, GROUP, NEW_NETIF, ATTACH, DEFAULT_HANDLERS, DRIVER,
|
|
WIFI_HANDLER, IP_HANDLER, STORAGE, MODE, CONFIG, START, CONNECT, STOP, POINTS };
|
|
static int calls[POINTS], fail_point, failures, destroys, foreign;
|
|
static bool should_connect, emit_disconnect, stop_ack;
|
|
static EventBits_t bits;
|
|
static esp_netif_t mock_station, other_station;
|
|
static int handler_handles[2];
|
|
static wifi_config_t last_config;
|
|
static void (*callback)(void *, esp_event_base_t, int32_t, void *);
|
|
static bool fail(enum point point) {
|
|
calls[point]++;
|
|
if (fail_point == (int)point && failures) {failures--; return true;}
|
|
return false;
|
|
}
|
|
static EventGroupHandle_t xEventGroupCreate(void) {return fail(GROUP) ? NULL : &bits;}
|
|
static EventBits_t xEventGroupGetBits(EventGroupHandle_t e) {assert(e); return *e;}
|
|
static EventBits_t xEventGroupSetBits(EventGroupHandle_t e, EventBits_t b) {return *e |= b;}
|
|
static EventBits_t xEventGroupClearBits(EventGroupHandle_t e, EventBits_t b) {EventBits_t old=*e; *e &= ~b; return old;}
|
|
static EventBits_t xEventGroupWaitBits(EventGroupHandle_t e, EventBits_t b, int clear, int all, int ticks) {
|
|
(void)b; (void)clear; (void)all; (void)ticks; return *e;
|
|
}
|
|
static void vTaskDelay(int ticks) {(void)ticks;}
|
|
static esp_netif_t *esp_netif_get_handle_from_ifkey(const char *key) {
|
|
assert(!strcmp(key, "WIFI_STA")); return foreign ? &other_station : NULL;
|
|
}
|
|
static esp_netif_t *esp_netif_new(const esp_netif_config_t *c) {
|
|
(void)c; return fail(NEW_NETIF) ? NULL : &mock_station;
|
|
}
|
|
static esp_err_t esp_netif_attach_wifi_station(esp_netif_t *n) {assert(n); return fail(ATTACH) ? ESP_FAIL : ESP_OK;}
|
|
static esp_err_t esp_wifi_set_default_wifi_sta_handlers(void) {return fail(DEFAULT_HANDLERS) ? ESP_FAIL : ESP_OK;}
|
|
static void esp_netif_destroy_default_wifi(esp_netif_t *n) {assert(n == &mock_station); destroys++;}
|
|
static esp_err_t esp_wifi_init(const wifi_init_config_t *c) {
|
|
assert(c->static_rx_buf_num == 4 && c->static_tx_buf_num == 4);
|
|
assert(c->dynamic_rx_buf_num >= c->static_rx_buf_num && c->cache_tx_buf_num == 4);
|
|
assert(!c->ampdu_rx_enable && !c->ampdu_tx_enable && !c->amsdu_tx_enable);
|
|
return fail(DRIVER) ? ESP_ERR_NO_MEM : ESP_OK;
|
|
}
|
|
static esp_err_t esp_event_handler_instance_register(esp_event_base_t base, int id,
|
|
void (*cb)(void *, esp_event_base_t, int32_t, void *), void *arg, esp_event_handler_instance_t *instance) {
|
|
(void)id; (void)arg;
|
|
if (fail(base == WIFI_EVENT ? WIFI_HANDLER : IP_HANDLER)) return ESP_ERR_NO_MEM;
|
|
callback = cb; *instance = &handler_handles[base == WIFI_EVENT ? 0 : 1]; return ESP_OK;
|
|
}
|
|
static esp_err_t esp_wifi_set_storage(int storage) {assert(storage == WIFI_STORAGE_RAM); return fail(STORAGE) ? ESP_FAIL : ESP_OK;}
|
|
static esp_err_t esp_wifi_set_mode(int mode) {assert(mode == WIFI_MODE_STA); return fail(MODE) ? ESP_FAIL : ESP_OK;}
|
|
static esp_err_t esp_wifi_set_config(int iface, const wifi_config_t *c) {
|
|
assert(iface == WIFI_IF_STA); last_config = *c; return fail(CONFIG) ? ESP_FAIL : ESP_OK;
|
|
}
|
|
static esp_err_t esp_wifi_start(void) {return fail(START) ? ESP_ERR_NO_MEM : ESP_OK;}
|
|
static esp_err_t esp_wifi_connect(void) {
|
|
if (fail(CONNECT)) return ESP_FAIL;
|
|
if (should_connect) callback(NULL, IP_EVENT, IP_EVENT_STA_GOT_IP, NULL);
|
|
else if (emit_disconnect) {wifi_event_sta_disconnected_t e = {201}; callback(NULL, WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED, &e);}
|
|
return ESP_OK;
|
|
}
|
|
static esp_err_t esp_wifi_stop(void) {
|
|
if (fail(STOP)) return ESP_FAIL;
|
|
if (stop_ack) callback(NULL, WIFI_EVENT, WIFI_EVENT_STA_STOP, NULL);
|
|
return ESP_OK;
|
|
}
|
|
|
|
/* PRODUCTION_SOURCE */
|
|
|
|
static void reset(void) {
|
|
station=NULL; events=NULL; wifi_handler=NULL; ip_handler=NULL;
|
|
driver_ready=false; prepared=false; started=false; stopping=false;
|
|
memset(calls,0,sizeof(calls)); memset(&last_config,0,sizeof(last_config));
|
|
fail_point=NONE; failures=0; destroys=0; foreign=0; bits=0;
|
|
should_connect=true; emit_disconnect=false; stop_ack=true; callback=NULL;
|
|
}
|
|
int main(void) {
|
|
unsigned tests=0;
|
|
reset();
|
|
assert(!ble_wifi_connected());
|
|
assert(ble_wifi_prepare()==ESP_OK && ble_wifi_prepare()==ESP_OK);
|
|
assert(calls[DRIVER]==1 && calls[NEW_NETIF]==1 && calls[GROUP]==1);
|
|
assert(calls[START]==0 && calls[CONNECT]==0); tests++;
|
|
|
|
// Every initialization failure is recoverable, without duplicate owners.
|
|
for (enum point p=GROUP; p<=MODE; ++p) {
|
|
reset(); fail_point=p; failures=1;
|
|
assert(ble_wifi_prepare()!=ESP_OK);
|
|
assert(ble_wifi_prepare()==ESP_OK);
|
|
assert(ble_wifi_prepare()==ESP_OK);
|
|
assert(calls[NEW_NETIF] <= ((p==NEW_NETIF || p==ATTACH || p==DEFAULT_HANDLERS) ? 2 : 1));
|
|
assert(calls[GROUP] == (p==GROUP ? 2 : 1));
|
|
assert(calls[DRIVER] == (p==DRIVER ? 2 : 1));
|
|
assert(destroys == (p==ATTACH || p==DEFAULT_HANDLERS ? 1 : 0));
|
|
tests++;
|
|
}
|
|
reset(); fail_point=DRIVER; failures=10;
|
|
for (int i=0; i<10; ++i) assert(ble_wifi_prepare()==ESP_ERR_NO_MEM);
|
|
assert(ble_wifi_prepare()==ESP_OK);
|
|
assert(calls[NEW_NETIF]==1 && calls[GROUP]==1 && calls[DEFAULT_HANDLERS]==1); tests++;
|
|
|
|
reset(); foreign=1;
|
|
assert(ble_wifi_prepare()==ESP_ERR_INVALID_STATE);
|
|
assert(calls[NEW_NETIF]==0 && destroys==0); tests++;
|
|
|
|
reset(); assert(ble_wifi_connect("test-network","test-password")==ESP_OK);
|
|
assert(ble_wifi_connected());
|
|
assert(!strcmp(last_config.sta.ssid,"test-network"));
|
|
assert(!strcmp(last_config.sta.password,"test-password"));
|
|
assert(last_config.sta.threshold.authmode==WIFI_AUTH_WPA2_PSK);
|
|
assert(ble_wifi_connect("new-network","new-password")==ESP_OK);
|
|
assert(calls[DRIVER]==1 && calls[NEW_NETIF]==1 && calls[STOP]==1);
|
|
assert(!strcmp(last_config.sta.ssid,"new-network")); tests++;
|
|
|
|
for (enum point p=CONFIG; p<=CONNECT; ++p) {
|
|
reset(); fail_point=p; failures=3;
|
|
while(failures) assert(ble_wifi_connect("test-network","test-password")!=ESP_OK);
|
|
assert(ble_wifi_connect("test-network","test-password")==ESP_OK);
|
|
assert(calls[DRIVER]==1 && calls[NEW_NETIF]==1 && calls[GROUP]==1); tests++;
|
|
}
|
|
for (int disconnect=0; disconnect<2; ++disconnect) {
|
|
reset(); should_connect=false; emit_disconnect=disconnect;
|
|
assert(ble_wifi_connect("test-network","test-password")==ESP_ERR_TIMEOUT);
|
|
assert(!ble_wifi_connected() && calls[START]==3 && calls[STOP]==3);
|
|
should_connect=true;
|
|
assert(ble_wifi_connect("test-network","test-password")==ESP_OK);
|
|
assert(calls[NEW_NETIF]==1 && calls[DRIVER]==1); tests++;
|
|
}
|
|
reset(); assert(ble_wifi_connect("test-network","test-password")==ESP_OK);
|
|
wifi_event_sta_disconnected_t e={201};
|
|
callback(NULL,WIFI_EVENT,WIFI_EVENT_STA_DISCONNECTED,&e);
|
|
assert(!ble_wifi_connected()); tests++;
|
|
|
|
reset(); assert(ble_wifi_connect("test-network","test-password")==ESP_OK);
|
|
fail_point=STOP; failures=1;
|
|
assert(ble_wifi_connect("test-network","test-password")==ESP_FAIL);
|
|
assert(ble_wifi_connect("test-network","test-password")==ESP_OK);
|
|
assert(calls[DRIVER]==1); tests++;
|
|
|
|
reset(); assert(ble_wifi_connect("test-network","test-password")==ESP_OK);
|
|
stop_ack=false;
|
|
assert(ble_wifi_connect("test-network","test-password")==ESP_ERR_TIMEOUT);
|
|
assert(ble_wifi_connect("test-network","test-password")==ESP_ERR_TIMEOUT);
|
|
assert(calls[STOP]==1);
|
|
assert(calls[CONNECT]==1);
|
|
callback(NULL,WIFI_EVENT,WIFI_EVENT_STA_STOP,NULL); stop_ack=true;
|
|
assert(ble_wifi_connect("test-network","test-password")==ESP_OK); tests++;
|
|
|
|
reset(); assert(ble_wifi_connect(NULL,"password")==ESP_ERR_INVALID_ARG);
|
|
assert(ble_wifi_connect("","password")==ESP_ERR_INVALID_ARG);
|
|
assert(ble_wifi_connect("network",NULL)==ESP_ERR_INVALID_ARG);
|
|
assert(calls[NEW_NETIF]==0); tests++;
|
|
printf("PASS: %u Wi-Fi lifecycle/fault-injection cases (production C)\n",tests);
|
|
return 0;
|
|
}
|