70 lines
4.2 KiB
JavaScript
70 lines
4.2 KiB
JavaScript
// Test the actual physical confirmation and expired-window recovery functions.
|
|||
|
|
const fs = require('node:fs'), path = require('node:path');
|
||
|
|
const src = fs.readFileSync(path.join(__dirname, '../main/ble_setup.c'), 'utf8');
|
||
|
|
const globals = src.slice(src.indexOf('typedef struct { uint32_t version;'), src.indexOf('static void show('));
|
||
|
|
const functions = src.slice(src.indexOf('bool ble_setup_confirm('), src.indexOf('static bool valid_password('));
|
||
|
|
process.stdout.write(`#include <assert.h>
|
||
|
|
#include <stdbool.h>
|
||
|
|
#include <stdint.h>
|
||
|
|
#include <stdio.h>
|
||
|
|
#include <string.h>
|
||
|
|
#include <stdatomic.h>
|
||
|
|
#define portMAX_DELAY 0
|
||
|
|
#define ESP_OK 0
|
||
|
|
#define ESP_FAIL 1
|
||
|
|
#define ESP_ERR_NVS_NOT_FOUND 2
|
||
|
|
#define NVS_READONLY 0
|
||
|
|
#define NVS_READWRITE 1
|
||
|
|
typedef int esp_err_t;
|
||
|
|
typedef int nvs_handle_t;
|
||
|
|
static int state_mutex,binding_task;
|
||
|
|
static atomic_bool enabled;
|
||
|
|
static int64_t now,window_end;
|
||
|
|
static int restarted,notified,setup_requested,commits;
|
||
|
|
static bool pending,storage_error;
|
||
|
|
static void xSemaphoreTake(int m,int t){(void)m;(void)t;}
|
||
|
|
static void xSemaphoreGive(int m){(void)m;}
|
||
|
|
static int64_t esp_timer_get_time(void){return now;}
|
||
|
|
static void ble_random_uuid(char *out){strcpy(out,"40000000-0000-4000-8000-000000000001");}
|
||
|
|
static void xTaskNotifyGive(int t){(void)t;notified++;}
|
||
|
|
static esp_err_t nvs_open(const char *name,int mode,nvs_handle_t *out){(void)mode;*out=!strcmp(name,"ble_setup")?1:2;return storage_error?ESP_FAIL:ESP_OK;}
|
||
|
|
static esp_err_t nvs_get_blob(nvs_handle_t n,const char *key,void *out,size_t *len){assert(n==1&&!strcmp(key,"pending")&&!out);*len=pending?100:0;return pending?ESP_OK:ESP_ERR_NVS_NOT_FOUND;}
|
||
|
|
static esp_err_t nvs_set_u8(nvs_handle_t n,const char *key,uint8_t value){assert(n==2&&!strcmp(key,"setup_requested"));setup_requested=value;return ESP_OK;}
|
||
|
|
static esp_err_t nvs_commit(nvs_handle_t n){assert(n==2);commits++;return ESP_OK;}
|
||
|
|
static void nvs_close(nvs_handle_t n){(void)n;}
|
||
|
|
static void show(const char *text){(void)text;}
|
||
|
|
static void esp_restart(void){restarted++;}
|
||
|
|
static const char *esp_err_to_name(esp_err_t err){(void)err;return "mock";}
|
||
|
|
static const char *TAG="ble_setup";
|
||
|
|
static void mock_log(const char *tag,const char *format,...){(void)tag;(void)format;}
|
||
|
|
#define ESP_LOGI(...) mock_log(__VA_ARGS__)
|
||
|
|
#define ESP_LOGE(...) mock_log(__VA_ARGS__)
|
||
|
|
` + globals + functions + `
|
||
|
|
static void reset(void){
|
||
|
|
memset(&job,0,sizeof(job));enabled=true;recover_saved_wifi=true;timeout_handled=false;
|
||
|
|
now=1;window_end=300000000;confirm_until=60000000;state=IDLE;failure_message="";
|
||
|
|
pending=storage_error=false;restarted=notified=commits=0;setup_requested=1;
|
||
|
|
}
|
||
|
|
int main(void){
|
||
|
|
reset();recover_wifi_after_timeout();assert(!restarted&&setup_requested==1);
|
||
|
|
now=window_end;recover_wifi_after_timeout();assert(restarted==1&&setup_requested==0&&commits==1);
|
||
|
|
recover_wifi_after_timeout();assert(restarted==1);
|
||
|
|
reset();state=RECEIVED;now=confirm_until;assert(ble_setup_confirm()&&state==FAILED&&!notified);
|
||
|
|
now=window_end;assert(!ble_setup_confirm());recover_wifi_after_timeout();assert(restarted==1);
|
||
|
|
reset();state=RECEIVED;assert(ble_setup_confirm()&&state==WIFI_CONNECTING&¬ified==1&&strlen(job.press)==36);
|
||
|
|
now=window_end;recover_wifi_after_timeout();assert(!restarted&&setup_requested==1);
|
||
|
|
const state_t busy[]={RECEIVED,WIFI_CONNECTING,BINDING,SUCCESS};
|
||
|
|
for(size_t i=0;i<sizeof(busy)/sizeof(busy[0]);i++){
|
||
|
|
reset();state=busy[i];confirm_until=window_end+60000000;now=window_end;recover_wifi_after_timeout();assert(!restarted&&!timeout_handled&&setup_requested==1);
|
||
|
|
}
|
||
|
|
reset();pending=true;now=window_end;recover_wifi_after_timeout();assert(!restarted&&setup_requested==1);
|
||
|
|
reset();recover_saved_wifi=false;now=window_end;recover_wifi_after_timeout();assert(!restarted&&setup_requested==1);
|
||
|
|
reset();storage_error=true;now=window_end;recover_wifi_after_timeout();assert(!restarted&&setup_requested==1);
|
||
|
|
reset();enabled=false;now=window_end;recover_wifi_after_timeout();assert(!restarted&&!timeout_handled);
|
||
|
|
reset();state=BINDING;now=window_end;recover_wifi_after_timeout();assert(!restarted);
|
||
|
|
state=FAILED;recover_wifi_after_timeout();assert(restarted==1&&setup_requested==0);
|
||
|
|
puts("PASS production BLE: confirmation timeout/reopen, unattended window restores saved WiFi, pending/first-time/storage/busy guards, one restart");
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
`);
|