@mikrojs/firmware 0.6.0-pr-72.g464c29c → 0.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/mikrojs/CMakeLists.txt +2 -1
- package/components/mikrojs/mik_wifi.cpp +33 -42
- package/components/mikrojs/test/wifi_test.cpp +25 -11
- package/package.json +3 -3
- package/prebuilds/esp32/bootloader/bootloader.bin +0 -0
- package/prebuilds/esp32/mikrojs.bin +0 -0
- package/prebuilds/esp32c3/bootloader/bootloader.bin +0 -0
- package/prebuilds/esp32c3/mikrojs.bin +0 -0
- package/prebuilds/esp32c5/bootloader/bootloader.bin +0 -0
- package/prebuilds/esp32c5/mikrojs.bin +0 -0
- package/prebuilds/esp32c6/bootloader/bootloader.bin +0 -0
- package/prebuilds/esp32c6/mikrojs.bin +0 -0
- package/prebuilds/esp32s3/bootloader/bootloader.bin +0 -0
- package/prebuilds/esp32s3/mikrojs.bin +0 -0
- package/sdkconfig.defaults +0 -10
|
@@ -65,6 +65,7 @@ idf_component_register(
|
|
|
65
65
|
"${MIK_SRC_DIR}/mik_cbor.cpp"
|
|
66
66
|
"${MIK_SRC_DIR}/mik_result.cpp"
|
|
67
67
|
"${MIK_SRC_DIR}/mik_udp.cpp"
|
|
68
|
+
"${MIK_SRC_DIR}/mik_observable.cpp"
|
|
68
69
|
"${MIK_SRC_DIR}/mikrojs.cpp"
|
|
69
70
|
# nanocbor CBOR codec
|
|
70
71
|
"${MIK_NANOCBOR_DIR}/src/encoder.c"
|
|
@@ -131,7 +132,7 @@ include("${MIK_BYTECODE_CMAKE}")
|
|
|
131
132
|
|
|
132
133
|
# Force linker to include self-registering native modules
|
|
133
134
|
set(_MIK_MODULES cbor pin i2c spi http wifi rtc nvs_kv sntp sleep neopixel pwm uart)
|
|
134
|
-
set(_MIK_BYTECODE_MODULES cbor env result schema fs http/helpers http/request i2c kv/nvs kv/rtc kv/shared neopixel pin pwm reader sleep spi sntp stdio stream sys test uart udp wifi)
|
|
135
|
+
set(_MIK_BYTECODE_MODULES cbor env result schema fs http/helpers http/request i2c kv/nvs kv/rtc kv/shared neopixel observable observable/lazy observable/operators pin pwm reader sleep spi sntp stdio stream sys test uart udp wifi)
|
|
135
136
|
if(CONFIG_BT_ENABLED)
|
|
136
137
|
list(APPEND _MIK_MODULES ble)
|
|
137
138
|
list(APPEND _MIK_BYTECODE_MODULES ble)
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
#include "freertos/FreeRTOS.h"
|
|
10
10
|
#include "freertos/queue.h"
|
|
11
11
|
#include "nvs_flash.h"
|
|
12
|
+
#include "mikrojs/platform.h"
|
|
12
13
|
#include "private.h"
|
|
13
14
|
#include "utils.h"
|
|
14
15
|
|
|
@@ -251,7 +252,29 @@ static void mik__wifi_event_handler(void* arg, esp_event_base_t event_base, int3
|
|
|
251
252
|
}
|
|
252
253
|
}
|
|
253
254
|
|
|
254
|
-
|
|
255
|
+
/* Pick the DHCP hostname for the STA netif: configured `wifi.hostname` from
|
|
256
|
+
* mikro.config.json takes priority; otherwise default to `mikrojs-<device-id>`.
|
|
257
|
+
* Returns true if a hostname was applied. */
|
|
258
|
+
static bool mik__wifi_apply_hostname(JSContext* ctx) {
|
|
259
|
+
if (!s_sta_netif) return false;
|
|
260
|
+
char buf[64];
|
|
261
|
+
const char* hostname = nullptr;
|
|
262
|
+
if (ctx) {
|
|
263
|
+
MIKRuntime* mik_rt = MIK_GetRuntime(ctx);
|
|
264
|
+
if (mik_rt && mik_rt->config.wifi_hostname[0] != '\0') {
|
|
265
|
+
hostname = mik_rt->config.wifi_hostname;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
if (!hostname) {
|
|
269
|
+
const char* dev_id = MIK_GetPlatform()->get_device_id();
|
|
270
|
+
if (!dev_id || !dev_id[0]) return false;
|
|
271
|
+
snprintf(buf, sizeof(buf), "mikrojs-%s", dev_id);
|
|
272
|
+
hostname = buf;
|
|
273
|
+
}
|
|
274
|
+
return esp_netif_set_hostname(s_sta_netif, hostname) == ESP_OK;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
esp_err_t mik__wifi_ensure_initialized(JSContext* ctx) {
|
|
255
278
|
if (s_wifi_initialized) return ESP_OK;
|
|
256
279
|
|
|
257
280
|
esp_err_t err = nvs_flash_init();
|
|
@@ -272,6 +295,7 @@ esp_err_t mik__wifi_ensure_initialized() {
|
|
|
272
295
|
* asserting in esp_netif_create_default_wifi_sta. */
|
|
273
296
|
if (!s_sta_netif) {
|
|
274
297
|
s_sta_netif = esp_netif_create_default_wifi_sta();
|
|
298
|
+
if (s_sta_netif) mik__wifi_apply_hostname(ctx);
|
|
275
299
|
}
|
|
276
300
|
if (!s_sta_netif) return ESP_FAIL;
|
|
277
301
|
|
|
@@ -310,8 +334,8 @@ fail_after_init:
|
|
|
310
334
|
|
|
311
335
|
/* Start the WiFi radio. Deferred from init so the radio is not active
|
|
312
336
|
* until connect() or scan() is actually called. */
|
|
313
|
-
static esp_err_t mik__wifi_ensure_started() {
|
|
314
|
-
esp_err_t err = mik__wifi_ensure_initialized();
|
|
337
|
+
static esp_err_t mik__wifi_ensure_started(JSContext* ctx) {
|
|
338
|
+
esp_err_t err = mik__wifi_ensure_initialized(ctx);
|
|
315
339
|
if (err != ESP_OK) return err;
|
|
316
340
|
if (s_wifi_started) return ESP_OK;
|
|
317
341
|
|
|
@@ -374,7 +398,7 @@ static JSClassDef mik_wifi_classdef = {
|
|
|
374
398
|
};
|
|
375
399
|
|
|
376
400
|
static JSValue mik__wifi_constructor(JSContext* ctx, JSValue new_target, int argc, JSValue* argv) {
|
|
377
|
-
esp_err_t err = mik__wifi_ensure_initialized();
|
|
401
|
+
esp_err_t err = mik__wifi_ensure_initialized(ctx);
|
|
378
402
|
if (err != ESP_OK) {
|
|
379
403
|
return JS_ThrowInternalError(ctx, "WiFi init failed: %s", esp_err_to_name(err));
|
|
380
404
|
}
|
|
@@ -386,7 +410,7 @@ static JSValue mik__wifi_connect(JSContext* ctx, JSValue this_val, int argc, JSV
|
|
|
386
410
|
return mik__result_err_tag(ctx, "CountryNotSet");
|
|
387
411
|
}
|
|
388
412
|
|
|
389
|
-
esp_err_t start_err = mik__wifi_ensure_started();
|
|
413
|
+
esp_err_t start_err = mik__wifi_ensure_started(ctx);
|
|
390
414
|
if (start_err != ESP_OK) {
|
|
391
415
|
return mik__result_err_named(ctx, "StartFailed",
|
|
392
416
|
"Failed to start WiFi radio: %s", esp_err_to_name(start_err));
|
|
@@ -478,7 +502,7 @@ static JSValue mik__wifi_scan(JSContext* ctx, JSValue this_val, int argc, JSValu
|
|
|
478
502
|
return mik__result_err_tag(ctx, "CountryNotSet");
|
|
479
503
|
}
|
|
480
504
|
|
|
481
|
-
esp_err_t start_err = mik__wifi_ensure_started();
|
|
505
|
+
esp_err_t start_err = mik__wifi_ensure_started(ctx);
|
|
482
506
|
if (start_err != ESP_OK) {
|
|
483
507
|
return mik__result_err_named(ctx, "StartFailed",
|
|
484
508
|
"Failed to start WiFi radio: %s", esp_err_to_name(start_err));
|
|
@@ -631,22 +655,6 @@ static JSValue mik__wifi_get_hostname(JSContext* ctx, JSValue this_val, int argc
|
|
|
631
655
|
return JS_NewString(ctx, hostname);
|
|
632
656
|
}
|
|
633
657
|
|
|
634
|
-
static JSValue mik__wifi_set_hostname(JSContext* ctx, JSValue this_val, int argc, JSValue* argv) {
|
|
635
|
-
if (!s_sta_netif) {
|
|
636
|
-
return mik__result_err_tag(ctx, "NotInitialized");
|
|
637
|
-
}
|
|
638
|
-
const char* hostname = JS_ToCString(ctx, argv[0]);
|
|
639
|
-
if (!hostname) return JS_EXCEPTION;
|
|
640
|
-
|
|
641
|
-
esp_err_t err = esp_netif_set_hostname(s_sta_netif, hostname);
|
|
642
|
-
JS_FreeCString(ctx, hostname);
|
|
643
|
-
if (err != ESP_OK) {
|
|
644
|
-
return mik__result_err_named(ctx, "SetFailed",
|
|
645
|
-
"Failed to set hostname: %s", esp_err_to_name(err));
|
|
646
|
-
}
|
|
647
|
-
return mik__result_ok_void(ctx);
|
|
648
|
-
}
|
|
649
|
-
|
|
650
658
|
static JSValue mik__wifi_get_ip_config(JSContext* ctx, JSValue this_val, int argc, JSValue* argv) {
|
|
651
659
|
if (!s_sta_netif) {
|
|
652
660
|
return JS_UNDEFINED;
|
|
@@ -746,7 +754,7 @@ static JSValue mik__wifi_ap_start(JSContext* ctx, JSValue this_val, int argc, JS
|
|
|
746
754
|
return mik__result_err_tag(ctx, "CountryNotSet");
|
|
747
755
|
}
|
|
748
756
|
|
|
749
|
-
esp_err_t err = mik__wifi_ensure_started();
|
|
757
|
+
esp_err_t err = mik__wifi_ensure_started(ctx);
|
|
750
758
|
if (err != ESP_OK) {
|
|
751
759
|
return mik__result_err_named(ctx, "StartFailed",
|
|
752
760
|
"Failed to start WiFi radio: %s", esp_err_to_name(err));
|
|
@@ -952,26 +960,11 @@ static JSValue mik__wifi_get_country(JSContext* ctx, JSValue this_val, int argc,
|
|
|
952
960
|
return JS_NewStringLen(ctx, cc, 2);
|
|
953
961
|
}
|
|
954
962
|
|
|
955
|
-
static JSValue mik__wifi_set_country(JSContext* ctx, JSValue this_val, int argc, JSValue* argv) {
|
|
956
|
-
const char* cc = JS_ToCString(ctx, argv[0]);
|
|
957
|
-
if (!cc) return JS_EXCEPTION;
|
|
958
|
-
|
|
959
|
-
esp_err_t err = esp_wifi_set_country_code(cc, true);
|
|
960
|
-
JS_FreeCString(ctx, cc);
|
|
961
|
-
|
|
962
|
-
if (err != ESP_OK) {
|
|
963
|
-
return mik__result_err_named(ctx, "SetFailed",
|
|
964
|
-
"Failed to set WiFi country code: %s", esp_err_to_name(err));
|
|
965
|
-
}
|
|
966
|
-
s_country_configured = true;
|
|
967
|
-
return mik__result_ok_void(ctx);
|
|
968
|
-
}
|
|
969
|
-
|
|
970
963
|
/* ── TX power ──────────────────────────────────────────────────────── */
|
|
971
964
|
|
|
972
965
|
static JSValue mik__wifi_get_tx_power(JSContext* ctx, JSValue this_val, int argc, JSValue* argv) {
|
|
973
966
|
/* esp_wifi_get_max_tx_power requires the radio to be started. */
|
|
974
|
-
esp_err_t start_err = mik__wifi_ensure_started();
|
|
967
|
+
esp_err_t start_err = mik__wifi_ensure_started(ctx);
|
|
975
968
|
if (start_err != ESP_OK) {
|
|
976
969
|
return mik__result_err_named(ctx, "GetFailed",
|
|
977
970
|
"Failed to get TX power: %s", esp_err_to_name(start_err));
|
|
@@ -988,7 +981,7 @@ static JSValue mik__wifi_get_tx_power(JSContext* ctx, JSValue this_val, int argc
|
|
|
988
981
|
static JSValue mik__wifi_set_tx_power(JSContext* ctx, JSValue this_val, int argc, JSValue* argv) {
|
|
989
982
|
double dbm;
|
|
990
983
|
if (JS_ToFloat64(ctx, &dbm, argv[0])) return JS_EXCEPTION;
|
|
991
|
-
esp_err_t start_err = mik__wifi_ensure_started();
|
|
984
|
+
esp_err_t start_err = mik__wifi_ensure_started(ctx);
|
|
992
985
|
if (start_err != ESP_OK) {
|
|
993
986
|
return mik__result_err_named(ctx, "SetFailed",
|
|
994
987
|
"Failed to set TX power: %s", esp_err_to_name(start_err));
|
|
@@ -1097,7 +1090,6 @@ static const JSCFunctionListEntry mik__wifi_proto_funcs[] = {
|
|
|
1097
1090
|
MIK_CFUNC_DEF("off", 2, mik__wifi_off),
|
|
1098
1091
|
MIK_CFUNC_DEF("mac", 0, mik__wifi_mac),
|
|
1099
1092
|
MIK_CFUNC_DEF("getHostname", 0, mik__wifi_get_hostname),
|
|
1100
|
-
MIK_CFUNC_DEF("setHostname", 1, mik__wifi_set_hostname),
|
|
1101
1093
|
MIK_CFUNC_DEF("getIpConfig", 0, mik__wifi_get_ip_config),
|
|
1102
1094
|
MIK_CFUNC_DEF("setIpConfig", 1, mik__wifi_set_ip_config),
|
|
1103
1095
|
MIK_CFUNC_DEF("apStart", 1, mik__wifi_ap_start),
|
|
@@ -1108,7 +1100,6 @@ static const JSCFunctionListEntry mik__wifi_proto_funcs[] = {
|
|
|
1108
1100
|
MIK_CFUNC_DEF("getPowerSave", 0, mik__wifi_get_power_save),
|
|
1109
1101
|
MIK_CFUNC_DEF("setPowerSave", 1, mik__wifi_set_power_save),
|
|
1110
1102
|
MIK_CFUNC_DEF("getCountry", 0, mik__wifi_get_country),
|
|
1111
|
-
MIK_CFUNC_DEF("setCountry", 1, mik__wifi_set_country),
|
|
1112
1103
|
MIK_CFUNC_DEF("getTxPower", 0, mik__wifi_get_tx_power),
|
|
1113
1104
|
MIK_CFUNC_DEF("setTxPower", 1, mik__wifi_set_tx_power),
|
|
1114
1105
|
MIK_CFUNC_DEF("getRssiThreshold", 0, mik__wifi_get_rssi_threshold),
|
|
@@ -28,11 +28,15 @@ static void setup() {
|
|
|
28
28
|
vTaskDelay(pdMS_TO_TICKS(100));
|
|
29
29
|
rt = MIK_NewRuntime();
|
|
30
30
|
ctx = MIK_GetJSContext(rt);
|
|
31
|
+
/* Country is config-only — populate it directly so wifi ops that gate on
|
|
32
|
+
* mik__wifi_try_auto_country can proceed. */
|
|
33
|
+
MIKConfig cfg;
|
|
34
|
+
MIK_DefaultConfig(&cfg);
|
|
35
|
+
snprintf(cfg.wifi_country, sizeof(cfg.wifi_country), "US");
|
|
36
|
+
MIK_SetConfig(rt, &cfg);
|
|
31
37
|
/* WiFi module is self-registered and lazily initialized.
|
|
32
|
-
* The import below triggers init + loop consumer registration.
|
|
33
|
-
|
|
34
|
-
const char* init_code =
|
|
35
|
-
"import { Wifi } from \"native:wifi\"; new Wifi().setCountry(\"US\");";
|
|
38
|
+
* The import below triggers init + loop consumer registration. */
|
|
39
|
+
const char* init_code = "import { Wifi } from \"native:wifi\"; new Wifi();";
|
|
36
40
|
JSValue ret = MIK_EvalModuleContent(ctx, "mikrojs/test-setup", init_code, strlen(init_code));
|
|
37
41
|
if (!JS_IsException(ret)) {
|
|
38
42
|
JS_FreeValue(ctx, ret);
|
|
@@ -332,14 +336,22 @@ TEST_CASE("Wifi mac returns a valid MAC address format", "[wifi]") {
|
|
|
332
336
|
teardown();
|
|
333
337
|
}
|
|
334
338
|
|
|
335
|
-
TEST_CASE("Wifi hostname
|
|
336
|
-
setup()
|
|
339
|
+
TEST_CASE("Wifi hostname reflects configured wifi.hostname", "[wifi]") {
|
|
340
|
+
/* Custom setup with wifi.hostname populated. Mirrors setup() but injects
|
|
341
|
+
* a hostname before the lazy netif init runs. */
|
|
342
|
+
esp_wifi_disconnect();
|
|
343
|
+
vTaskDelay(pdMS_TO_TICKS(100));
|
|
344
|
+
rt = MIK_NewRuntime();
|
|
345
|
+
ctx = MIK_GetJSContext(rt);
|
|
346
|
+
MIKConfig cfg;
|
|
347
|
+
MIK_DefaultConfig(&cfg);
|
|
348
|
+
snprintf(cfg.wifi_country, sizeof(cfg.wifi_country), "US");
|
|
349
|
+
snprintf(cfg.wifi_hostname, sizeof(cfg.wifi_hostname), "test-device");
|
|
350
|
+
MIK_SetConfig(rt, &cfg);
|
|
337
351
|
|
|
338
352
|
JSValue ret = eval_module(R"(
|
|
339
353
|
import { Wifi } from "native:wifi";
|
|
340
|
-
|
|
341
|
-
wifi.setHostname("test-device");
|
|
342
|
-
globalThis.__hostname = wifi.getHostname();
|
|
354
|
+
globalThis.__hostname = new Wifi().getHostname();
|
|
343
355
|
)");
|
|
344
356
|
TEST_ASSERT_FALSE_MESSAGE(JS_IsException(ret), "Module eval should not throw");
|
|
345
357
|
|
|
@@ -446,13 +458,15 @@ TEST_CASE("Wifi power save get/set round-trips", "[wifi]") {
|
|
|
446
458
|
teardown();
|
|
447
459
|
}
|
|
448
460
|
|
|
449
|
-
TEST_CASE("Wifi country
|
|
461
|
+
TEST_CASE("Wifi country reflects configured wifi.country", "[wifi]") {
|
|
450
462
|
setup();
|
|
451
463
|
|
|
464
|
+
/* setup() populated wifi_country = "US"; trigger a wifi op so
|
|
465
|
+
* mik__wifi_try_auto_country applies it, then read back via getCountry. */
|
|
452
466
|
JSValue ret = eval_module(R"(
|
|
453
467
|
import { Wifi } from "native:wifi";
|
|
454
468
|
const wifi = new Wifi();
|
|
455
|
-
wifi.
|
|
469
|
+
wifi.scan();
|
|
456
470
|
globalThis.__cc = wifi.getCountry();
|
|
457
471
|
)");
|
|
458
472
|
TEST_ASSERT_FALSE_MESSAGE(JS_IsException(ret), "Module eval should not throw");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mikrojs/firmware",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.1",
|
|
4
4
|
"description": "Mikro.js ESP32 firmware: ESP-IDF component, build tools, and project template",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"esp-idf",
|
|
@@ -51,8 +51,8 @@
|
|
|
51
51
|
},
|
|
52
52
|
"dependencies": {
|
|
53
53
|
"esbuild": "^0.28.0",
|
|
54
|
-
"@mikrojs/
|
|
55
|
-
"@mikrojs/
|
|
54
|
+
"@mikrojs/quickjs": "0.6.1",
|
|
55
|
+
"@mikrojs/native": "0.6.1"
|
|
56
56
|
},
|
|
57
57
|
"engines": {
|
|
58
58
|
"node": ">=24.0.0"
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/sdkconfig.defaults
CHANGED
|
@@ -132,13 +132,3 @@ CONFIG_MBEDTLS_ECP_DP_BP512R1_ENABLED=n
|
|
|
132
132
|
CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_CMN=y
|
|
133
133
|
CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_CROSS_SIGNED_VERIFY=y
|
|
134
134
|
|
|
135
|
-
# TLS record buffers must come from internal SRAM. The ESP-IDF default for
|
|
136
|
-
# the inbound buffer is 16 KB, which competes with QuickJS heap allocations
|
|
137
|
-
# for contiguous internal SRAM and causes HTTPS handshake failures (error
|
|
138
|
-
# 0x7002) on apps with significant retained JS state. Halving it to 8 KB
|
|
139
|
-
# leaves enough room for typical TLS records (handshake fragments are well
|
|
140
|
-
# under 4 KB; modern servers rarely send >4 KB application records, and
|
|
141
|
-
# mbedTLS will fragment larger records). The outbound buffer was already
|
|
142
|
-
# 4 KB via CONFIG_MBEDTLS_ASYMMETRIC_CONTENT_LEN=y.
|
|
143
|
-
CONFIG_MBEDTLS_SSL_IN_CONTENT_LEN=8192
|
|
144
|
-
|