From 96233d2ae5ad3190e237faba68a019c040246514 Mon Sep 17 00:00:00 2001 From: Kostas Drakontidis Date: Tue, 19 May 2026 23:02:09 +0300 Subject: [PATCH 1/2] Scanner config management code --- src/officesense_scanner/platformio.ini | 1 + src/officesense_scanner/src/main.cpp | 246 ++++++++++++++++++++++--- src/officesense_scanner/src/main.hpp | 61 +++++- 3 files changed, 281 insertions(+), 27 deletions(-) diff --git a/src/officesense_scanner/platformio.ini b/src/officesense_scanner/platformio.ini index e2ceb56..aa7b0ca 100644 --- a/src/officesense_scanner/platformio.ini +++ b/src/officesense_scanner/platformio.ini @@ -18,6 +18,7 @@ board_build.partitions = default.csv build_flags = -DARDUINO_USB_CDC_ON_BOOT=1 -DBOARD_HAS_PSRAM + -DCORE_DEBUG_LEVEL=0 lib_deps = h2zero/NimBLE-Arduino diff --git a/src/officesense_scanner/src/main.cpp b/src/officesense_scanner/src/main.cpp index 51084da..92871fb 100644 --- a/src/officesense_scanner/src/main.cpp +++ b/src/officesense_scanner/src/main.cpp @@ -5,9 +5,14 @@ #include "freertos/queue.h" #include #include +#include +#include "esp_system.h" +Preferences prefs; +Config config; CB cb; -char MQTT_PUB_TOPIC[sizeof(MQTT_TOPIC) + sizeof(DEV_NAME) - 1]; +String MQTT_PUB_TOPIC; +String serial_buffer = ""; std::unordered_map tags; std::unordered_map uuid_cache; SemaphoreHandle_t uuid_mtx; @@ -27,7 +32,7 @@ void cleanupCache() { uint32_t age = now - it->second.last_check; - if (age > UUID_CACHE_CLEAN_TIMEOUT) + if (age > config.interval.uuid_cache_clean_timeout) { Serial.printf("Erasing %s from cache after being inactive for %dms.\n", it->first.c_str(), @@ -47,7 +52,7 @@ void cleanupTags() for (auto it = tags.begin(); it != tags.end();) { - if ((now - it->second.getLastSeen()) >= TAG_TIMEOUT) + if ((now - it->second.getLastSeen()) >= config.interval.tag_timeout) { Serial.printf("Erasing %s from memory after being inactive for %dms.\n", it->first.c_str(), @@ -69,7 +74,7 @@ void httpTask(void *) { HTTPClient http; - String url = UUID_CHECK_ENDPOINT + String(ev.uuid); + String url = config.api.url + config.api.uuid_check_endpoint + String("/") + String(ev.uuid); http.setTimeout(3000); http.setReuse(false); @@ -82,6 +87,19 @@ void httpTask(void *) int code = http.GET(); + if (code < 0) + { + xSemaphoreTake(uuid_mtx, portMAX_DELAY); + uuid_cache[ev.uuid] = { + UUIDState::RETRY, + millis()}; + + xSemaphoreGive(uuid_mtx); + + http.end(); + continue; + } + bool valid = (code == 200); http.end(); @@ -110,8 +128,8 @@ void mqttTask(void *) { while (!mqtt.connected()) { - Serial.printf("MQTT Disconnected. Connecting to %s:%d\n", MQTT_HOST, MQTT_PORT); - if (mqtt.connect(DEV_NAME, MQTT_USER, MQTT_PASS)) + Serial.printf("MQTT Disconnected. Connecting to %s:%d\n", config.mqtt.host.c_str(), config.mqtt.port); + if (mqtt.connect(config.dev_name.c_str(), config.mqtt.username.c_str(), config.mqtt.password.c_str())) Serial.println("MQTT connected."); vTaskDelay(pdMS_TO_TICKS(1000)); } @@ -125,7 +143,7 @@ void mqttTask(void *) ev.uuid, ev.ema); - bool ok = mqtt.publish(MQTT_PUB_TOPIC, payload); + bool ok = mqtt.publish(MQTT_PUB_TOPIC.c_str(), payload); if (!ok) Serial.println("Failed to publish on MQTT."); @@ -143,7 +161,7 @@ void processEvent(const BleEvent &event) uint32_t now = millis(); - if (it == uuid_cache.end()) + if (it == uuid_cache.end() || (it->second.state == UUIDState::RETRY)) { uuid_cache[event.uuid] = {UUIDState::PENDING, now}; @@ -158,7 +176,7 @@ void processEvent(const BleEvent &event) } if (it->second.state == UUIDState::INVALID && - now - it->second.last_check > UUID_CACHE_RETRY_TIMEOUT) + now - it->second.last_check > config.interval.uuid_cache_retry_timeout) { it->second.state = UUIDState::PENDING; it->second.last_check = now; @@ -202,9 +220,9 @@ void CB::onResult(const NimBLEAdvertisedDevice *d) return; NimBLEUUID uuid = d->getServiceUUID(0); - const std::string &name = d->getName(); + const String name(d->getName().c_str()); - if ((uuid.bitSize() != 128) || (name != TAG_NAME)) + if ((uuid.bitSize() != 128) || (name != config.tag_name)) return; BleEvent event; @@ -215,23 +233,170 @@ void CB::onResult(const NimBLEAdvertisedDevice *d) xQueueSend(ble_queue, &event, pdMS_TO_TICKS(5)); } +void saveConfig() +{ + prefs.begin("config", false); + + prefs.putUInt(CLEANUP_INTERVAL_CONFIG_KEY, config.interval.cleanup); + prefs.putUInt(TAG_TIMEOUT_CONFIG_KEY, config.interval.tag_timeout); + prefs.putUInt(UUID_CACHE_RETRY_TIMEOUT_CONFIG_KEY, config.interval.uuid_cache_retry_timeout); + prefs.putUInt(UUID_CACHE_CLEAN_TIMEOUT_CONFIG_KEY, config.interval.uuid_cache_clean_timeout); + + prefs.putString(API_URL_CONFIG_KEY, config.api.url); + prefs.putString(UUID_CHECK_ENDPOINT_CONFIG_KEY, config.api.uuid_check_endpoint); + + prefs.putString(MQTT_HOST_CONFIG_KEY, config.mqtt.host); + prefs.putUShort(MQTT_PORT_CONFIG_KEY, config.mqtt.port); + prefs.putString(MQTT_USER_CONFIG_KEY, config.mqtt.username); + prefs.putString(MQTT_PASS_CONFIG_KEY, config.mqtt.password); + prefs.putString(MQTT_TOPIC_CONFIG_KEY, config.mqtt.topic); + + prefs.putString(WIFI_SSID_CONFIG_KEY, config.wifi.ssid); + prefs.putString(WIFI_PASS_CONFIG_KEY, config.wifi.password); + + prefs.putString(DEV_NAME_CONFIG_KEY, config.dev_name); + prefs.putString(TAG_NAME_CONFIG_KEY, config.tag_name); + + prefs.end(); +} + +void loadConfig() +{ + prefs.begin("config", true); + + config.interval.cleanup = prefs.getUInt(CLEANUP_INTERVAL_CONFIG_KEY, CLEANUP_INTERVAL); + config.interval.tag_timeout = prefs.getUInt(TAG_TIMEOUT_CONFIG_KEY, TAG_TIMEOUT); + config.interval.uuid_cache_retry_timeout = prefs.getUInt(UUID_CACHE_RETRY_TIMEOUT_CONFIG_KEY, UUID_CACHE_RETRY_TIMEOUT); + config.interval.uuid_cache_clean_timeout = prefs.getUInt(UUID_CACHE_CLEAN_TIMEOUT_CONFIG_KEY, UUID_CACHE_CLEAN_TIMEOUT); + + config.api.url = prefs.getString(API_URL_CONFIG_KEY, API_URL); + config.api.uuid_check_endpoint = prefs.getString(UUID_CHECK_ENDPOINT_CONFIG_KEY, UUID_CHECK_ENDPOINT); + + config.mqtt.host = prefs.getString(MQTT_HOST_CONFIG_KEY, MQTT_HOST); + config.mqtt.port = prefs.getUShort(MQTT_PORT_CONFIG_KEY, MQTT_PORT); + config.mqtt.username = prefs.getString(MQTT_USER_CONFIG_KEY, MQTT_USER); + config.mqtt.password = prefs.getString(MQTT_PASS_CONFIG_KEY, MQTT_PASS); + config.mqtt.topic = prefs.getString(MQTT_TOPIC_CONFIG_KEY, MQTT_TOPIC); + + config.wifi.ssid = prefs.getString(WIFI_SSID_CONFIG_KEY, WIFI_SSID); + config.wifi.password = prefs.getString(WIFI_PASS_CONFIG_KEY, WIFI_PASS); + + config.dev_name = prefs.getString(DEV_NAME_CONFIG_KEY, DEV_NAME); + config.tag_name = prefs.getString(TAG_NAME_CONFIG_KEY, TAG_NAME); + + prefs.end(); +} + +void handleCommand(String line) +{ + if (line.startsWith("set ")) + { + int p1 = line.indexOf(' ', 4); + String key = line.substring(4, p1); + String value = line.substring(p1 + 1); + + if (key.length() == 0 || value.length() == 0) + return; + + if (key == CLEANUP_INTERVAL_CONFIG_KEY) + config.interval.cleanup = (uint32_t)value.toInt(); + else if (key == TAG_TIMEOUT_CONFIG_KEY) + config.interval.tag_timeout = (uint32_t)value.toInt(); + else if (key == UUID_CACHE_RETRY_TIMEOUT_CONFIG_KEY) + config.interval.uuid_cache_retry_timeout = (uint32_t)value.toInt(); + else if (key == UUID_CACHE_CLEAN_TIMEOUT_CONFIG_KEY) + config.interval.uuid_cache_clean_timeout = (uint32_t)value.toInt(); + else if (key == API_URL_CONFIG_KEY) + config.api.url = value; + else if (key == UUID_CHECK_ENDPOINT_CONFIG_KEY) + config.api.uuid_check_endpoint = value; + else if (key == MQTT_HOST_CONFIG_KEY) + config.mqtt.host = value; + else if (key == MQTT_PORT_CONFIG_KEY) + config.mqtt.port = value.toInt(); + else if (key == MQTT_USER_CONFIG_KEY) + config.mqtt.username = value; + else if (key == MQTT_PASS_CONFIG_KEY) + config.mqtt.password = value; + else if (key == MQTT_TOPIC_CONFIG_KEY) + config.mqtt.topic = value; + else if (key == WIFI_SSID_CONFIG_KEY) + config.wifi.ssid = value; + else if (key == WIFI_PASS_CONFIG_KEY) + config.wifi.password = value; + else if (key == DEV_NAME_CONFIG_KEY) + config.dev_name = value; + else if (key == TAG_NAME_CONFIG_KEY) + config.tag_name = value; + } + else if (line == "save") + saveConfig(); + else if (line.startsWith("show ")) + { + String key = line.substring(5); + + if (key.length() == 0) + return; + + if (key == CLEANUP_INTERVAL_CONFIG_KEY) + Serial.println(config.interval.cleanup); + else if (key == TAG_TIMEOUT_CONFIG_KEY) + Serial.println(config.interval.tag_timeout); + else if (key == UUID_CACHE_RETRY_TIMEOUT_CONFIG_KEY) + Serial.println(config.interval.uuid_cache_retry_timeout); + else if (key == UUID_CACHE_CLEAN_TIMEOUT_CONFIG_KEY) + Serial.println(config.interval.uuid_cache_clean_timeout); + else if (key == API_URL_CONFIG_KEY) + Serial.println(config.api.url); + else if (key == UUID_CHECK_ENDPOINT_CONFIG_KEY) + Serial.println(config.api.uuid_check_endpoint); + else if (key == MQTT_HOST_CONFIG_KEY) + Serial.println(config.mqtt.host); + else if (key == MQTT_PORT_CONFIG_KEY) + Serial.println(config.mqtt.port); + else if (key == MQTT_USER_CONFIG_KEY) + Serial.println(config.mqtt.username); + else if (key == MQTT_PASS_CONFIG_KEY) + Serial.println(config.mqtt.password); + else if (key == MQTT_TOPIC_CONFIG_KEY) + Serial.println(config.mqtt.topic); + else if (key == WIFI_SSID_CONFIG_KEY) + Serial.println(config.wifi.ssid); + else if (key == WIFI_PASS_CONFIG_KEY) + Serial.println(config.wifi.password); + else if (key == DEV_NAME_CONFIG_KEY) + Serial.println(config.dev_name); + else if (key == TAG_NAME_CONFIG_KEY) + Serial.println(config.tag_name); + } + else if (line == "reboot") + { + Serial.println("Rebooting..."); + Serial.flush(); + esp_restart(); + } + else if (line == "help") + { + Serial.println("Commands:"); + Serial.println(" set - Set a configuration value"); + Serial.println(" show - Show a configuration value"); + Serial.println(" save - Save configuration to non-volatile storage"); + Serial.println(" reboot - Reboot the device"); + Serial.println(" help - Show this help message"); + } +} + void setup() { Serial.begin(115200); - WiFi.begin(WIFI_SSID, WIFI_PASS); + loadConfig(); - while (WiFi.status() != WL_CONNECTED) - { - delay(500); - Serial.print("."); - } + WiFi.begin(config.wifi.ssid.c_str(), config.wifi.password.c_str()); - Serial.println("\nWiFi connected"); + MQTT_PUB_TOPIC = config.mqtt.topic + config.dev_name; - snprintf(MQTT_PUB_TOPIC, sizeof(MQTT_PUB_TOPIC), "%s%s", MQTT_TOPIC, DEV_NAME); - - mqtt.setServer(MQTT_HOST, MQTT_PORT); + mqtt.setServer(config.mqtt.host.c_str(), config.mqtt.port); mqtt.setKeepAlive(60); mqtt.setSocketTimeout(5); @@ -244,7 +409,7 @@ void setup() xTaskCreatePinnedToCore(mqttTask, "mqtt", 4096, NULL, 1, NULL, 1); xTaskCreatePinnedToCore(httpTask, "http", 4096, NULL, 1, NULL, 1); - NimBLEDevice::init(DEV_NAME); + NimBLEDevice::init(config.dev_name.c_str()); NimBLEScan *scan = NimBLEDevice::getScan(); @@ -264,10 +429,45 @@ void loop() static uint32_t last_cleanup = 0; - if (millis() - last_cleanup >= CLEANUP_INTERVAL) + if (millis() - last_cleanup >= config.interval.cleanup) { cleanupTags(); cleanupCache(); last_cleanup = millis(); } + + while (Serial.available()) + { + char c = Serial.read(); + + if (c == '\r') + continue; + + if (c == '\n') + { + Serial.print(c); + serial_buffer.trim(); + + if (serial_buffer.length() > 0) + handleCommand(serial_buffer); + + serial_buffer = ""; + + Serial.printf("%s> ", config.dev_name.c_str()); + } + else if (c == '\b') + { + if (serial_buffer.length() > 0) + { + serial_buffer.remove(serial_buffer.length() - 1); + + Serial.print("\b \b"); + } + } + else + { + Serial.print(c); + serial_buffer += c; + } + } } diff --git a/src/officesense_scanner/src/main.hpp b/src/officesense_scanner/src/main.hpp index 1c48f80..e9e449b 100644 --- a/src/officesense_scanner/src/main.hpp +++ b/src/officesense_scanner/src/main.hpp @@ -5,12 +5,29 @@ #include #include -#define CLEANUP_INTERVAL 5 * 1000 // ms -#define TAG_TIMEOUT 60 * 1000 // ms -#define UUID_CACHE_RETRY_TIMEOUT 5 * 60 * 1000 // ms +#define CLEANUP_INTERVAL_CONFIG_KEY "int.cln" +#define TAG_TIMEOUT_CONFIG_KEY "int.tagto" +#define UUID_CACHE_RETRY_TIMEOUT_CONFIG_KEY "int.urtry" +#define UUID_CACHE_CLEAN_TIMEOUT_CONFIG_KEY "int.ucclean" +#define API_URL_CONFIG_KEY "api.url" +#define UUID_CHECK_ENDPOINT_CONFIG_KEY "api.uuidchk" +#define MQTT_HOST_CONFIG_KEY "mq.host" +#define MQTT_PORT_CONFIG_KEY "mq.port" +#define MQTT_USER_CONFIG_KEY "mq.user" +#define MQTT_PASS_CONFIG_KEY "mq.pass" +#define MQTT_TOPIC_CONFIG_KEY "mq.topic" +#define WIFI_SSID_CONFIG_KEY "wf.ssid" +#define WIFI_PASS_CONFIG_KEY "wf.pass" +#define DEV_NAME_CONFIG_KEY "dev.name" +#define TAG_NAME_CONFIG_KEY "tag.name" + +#define CLEANUP_INTERVAL 5 * 1000 // ms +#define TAG_TIMEOUT 60 * 1000 // ms +#define UUID_CACHE_RETRY_TIMEOUT 5 * 60 * 1000 // ms #define UUID_CACHE_CLEAN_TIMEOUT 60 * 60 * 1000 // ms +#define API_URL "http://192.168.1.2" +#define UUID_CHECK_ENDPOINT "/check" #define TAG_NAME "X6TAG" -#define UUID_CHECK_ENDPOINT "http://192.168.1.2/check/" #define MQTT_HOST "192.168.1.2" #define MQTT_PORT 1883 #define MQTT_USER "user" @@ -20,6 +37,41 @@ #define WIFI_PASS "x32hbh54673ngccdsfa9" #define DEV_NAME "Scanner_Room_A" +struct Config +{ + struct Interval + { + uint32_t cleanup; + uint32_t tag_timeout; + uint32_t uuid_cache_retry_timeout; + uint32_t uuid_cache_clean_timeout; + } interval; + + struct API + { + String url; + String uuid_check_endpoint; + } api; + + struct MQTT + { + String host; + uint16_t port; + String username; + String password; + String topic; + } mqtt; + + struct WiFi + { + String ssid; + String password; + } wifi; + + String dev_name; + String tag_name; +}; + struct BleEvent { char uuid[37]; @@ -40,6 +92,7 @@ struct HttpEvent enum class UUIDState { PENDING, + RETRY, VALID, INVALID }; From 3977e8d17b2db24afbcc0ba14b8e15612f9b5790 Mon Sep 17 00:00:00 2001 From: Kostas Drakontidis Date: Wed, 20 May 2026 17:44:46 +0300 Subject: [PATCH 2/2] Tag config management code --- src/officesense_tag/main/main.c | 265 +++++++++++++++++++++++++++++--- src/officesense_tag/main/main.h | 18 +++ 2 files changed, 264 insertions(+), 19 deletions(-) create mode 100644 src/officesense_tag/main/main.h diff --git a/src/officesense_tag/main/main.c b/src/officesense_tag/main/main.c index 8e4a099..4cd492a 100644 --- a/src/officesense_tag/main/main.c +++ b/src/officesense_tag/main/main.c @@ -1,21 +1,13 @@ #include #include #include "nvs_flash.h" - #include "nimble/nimble_port.h" #include "nimble/nimble_port_freertos.h" - -#include "host/ble_hs.h" #include "services/gap/ble_svc_gap.h" +#include "driver/usb_serial_jtag.h" +#include "main.h" -static const char *TAG = "BLE"; - -static const ble_uuid128_t service_uuid = - BLE_UUID128_INIT( - 0xF0, 0xDE, 0xBC, 0x9A, - 0x78, 0x56, 0x34, 0x12, - 0xF0, 0xDE, 0xBC, 0x9A, - 0x78, 0x56, 0x34, 0x12); +static config_t config; static void start_adv(void) { @@ -24,19 +16,18 @@ static void start_adv(void) fields.flags = BLE_HS_ADV_F_DISC_GEN | BLE_HS_ADV_F_BREDR_UNSUP; - const char *name = "X6TAG"; - fields.name = (uint8_t *)name; - fields.name_len = strlen(name); + fields.name = (uint8_t *)config.name; + fields.name_len = strlen(config.name); fields.name_is_complete = 1; - fields.uuids128 = (ble_uuid128_t *)&service_uuid; + fields.uuids128 = (ble_uuid128_t *)&config.uuid; fields.num_uuids128 = 1; fields.uuids128_is_complete = 1; int rc = ble_gap_adv_set_fields(&fields); if (rc != 0) { - ESP_LOGE(TAG, "adv set fields failed: %d", rc); + ESP_LOGE(config.name, "adv set fields failed: %d", rc); return; } @@ -58,17 +49,17 @@ static void start_adv(void) if (rc != 0) { - ESP_LOGE(TAG, "adv start failed: %d", rc); + ESP_LOGE(config.name, "adv start failed: %d", rc); } else { - ESP_LOGI(TAG, "advertising started"); + ESP_LOGI(config.name, "advertising started"); } } static void on_sync(void) { - ESP_LOGI(TAG, "BLE synced"); + ESP_LOGI(config.name, "BLE synced"); start_adv(); } @@ -78,9 +69,237 @@ static void host_task(void *param) nimble_port_run(); } +static bool uuid_from_string(const char *str, ble_uuid128_t *uuid) +{ + unsigned int b[16]; + + int rc = sscanf(str, + "%02x%02x%02x%02x-" + "%02x%02x-" + "%02x%02x-" + "%02x%02x-" + "%02x%02x%02x%02x%02x%02x", + + &b[15], &b[14], &b[13], &b[12], + &b[11], &b[10], + &b[9], &b[8], + &b[7], &b[6], + &b[5], &b[4], &b[3], + &b[2], &b[1], &b[0]); + + if (rc != 16) + return false; + + uuid->u.type = BLE_UUID_TYPE_128; + + for (int i = 0; i < 16; i++) + uuid->value[i] = (uint8_t)b[i]; + + return true; +} + +static esp_err_t reset_config() +{ + nvs_handle_t nvs; + + esp_err_t err = nvs_open("config", NVS_READWRITE, &nvs); + + if (err != ESP_OK) + return err; + + err = nvs_erase_all(nvs); + + if (err != ESP_OK) + goto exit; + + err = nvs_commit(nvs); + +exit: + nvs_close(nvs); + + return err; +} + +static esp_err_t save_config() +{ + nvs_handle_t nvs; + + esp_err_t err = nvs_open("config", NVS_READWRITE, &nvs); + + if (err != ESP_OK) + return err; + + err = nvs_set_str(nvs, "uuid", config.uuid_str); + + if (err != ESP_OK) + goto exit; + + err = nvs_set_str(nvs, "name", config.name); + + if (err != ESP_OK) + goto exit; + + err = nvs_set_u32(nvs, "adv_int", config.adv_interval); + + if (err != ESP_OK) + goto exit; + + err = nvs_commit(nvs); + +exit: + nvs_close(nvs); + + return err; +} + +static esp_err_t load_config() +{ + nvs_handle_t nvs; + + esp_err_t err = nvs_open("config", NVS_READONLY, &nvs); + + strcpy(config.uuid_str, DEFAULT_UUID); + strcpy(config.name, DEFAULT_NAME); + config.adv_interval = DEFAULT_ADV_INTERVAL; + + uuid_from_string(config.uuid_str, &config.uuid); + + if (err != ESP_OK) + return err; + + size_t len; + + len = sizeof(config.uuid_str); + + nvs_get_str(nvs, "uuid", config.uuid_str, &len); + + len = sizeof(config.name); + + nvs_get_str(nvs, "name", config.name, &len); + + nvs_get_u32(nvs, "adv_int", &config.adv_interval); + + nvs_close(nvs); + + uuid_from_string(config.uuid_str, &config.uuid); + + return ESP_OK; +} + +void serial_task(void *arg) +{ + char line[128]; + char buf[64]; + int pos = 0; + + while (1) + { + uint8_t ch; + + int len = usb_serial_jtag_read_bytes(&ch, 1, portMAX_DELAY); + + if (len > 0) + { + if (ch == '\n' || ch == '\r') + { + usb_serial_jtag_write_bytes("\n", 1, 20 / portTICK_PERIOD_MS); + line[pos] = '\0'; + + if (pos > 0) + { + if (strncmp(line, "set uuid ", 9) == 0) + { + if (uuid_from_string(line + 9, &config.uuid)) + strcpy(config.uuid_str, line + 9); + } + else if (strncmp(line, "set name ", 9) == 0) + { + strncpy(config.name, line + 9, sizeof(config.name) - 1); + config.name[sizeof(config.name) - 1] = '\0'; + } + else if (strncmp(line, "set adv_interval ", 17) == 0) + { + uint32_t interval = atoi(line + 17); + if (interval > 0) + config.adv_interval = interval; + } + else if (strcmp(line, "show uuid") == 0) + { + usb_serial_jtag_write_bytes(config.uuid_str, strlen(config.uuid_str), 20 / portTICK_PERIOD_MS); + usb_serial_jtag_write_bytes("\n", 1, 20 / portTICK_PERIOD_MS); + } + else if (strcmp(line, "show name") == 0) + { + usb_serial_jtag_write_bytes(config.name, strlen(config.name), 20 / portTICK_PERIOD_MS); + usb_serial_jtag_write_bytes("\n", 1, 20 / portTICK_PERIOD_MS); + } + else if (strcmp(line, "show adv_interval") == 0) + { + int len = snprintf(buf, sizeof(buf), "%lu\n", (unsigned long)config.adv_interval); + usb_serial_jtag_write_bytes(buf, len, 20 / portTICK_PERIOD_MS); + } + else if (strcmp(line, "save") == 0) + save_config(); + else if (strcmp(line, "reset") == 0) + { + reset_config(); + esp_restart(); + } + else if (strcmp(line, "reboot") == 0) + { + usb_serial_jtag_write_bytes("Rebooting...\n", 13, 20 / portTICK_PERIOD_MS); + esp_restart(); + } + else if (strcmp(line, "help") == 0) + { + usb_serial_jtag_write_bytes("Commands:\n" + " set uuid \n" + " set name \n" + " set adv_interval \n" + " show uuid\n" + " show name\n" + " show adv_interval\n" + " save\n" + " reset\n" + " reboot\n" + " help\n", + 145, 20 / portTICK_PERIOD_MS); + } + } + + pos = 0; + int len = snprintf(buf, sizeof(buf), "%s> ", config.name); + usb_serial_jtag_write_bytes(buf, len, 20 / portTICK_PERIOD_MS); + } + else if (ch == 0x08) + { + if (pos > 0) + { + pos--; + usb_serial_jtag_write_bytes("\b \b", 3, 20 / portTICK_PERIOD_MS); + } + } + else + { + if (pos < sizeof(line) - 1) + { + line[pos++] = ch; + usb_serial_jtag_write_bytes((char *)&ch, 1, 20 / portTICK_PERIOD_MS); + } + } + } + } +} + void app_main(void) { ESP_ERROR_CHECK(nvs_flash_init()); + + usb_serial_jtag_driver_config_t cfg = USB_SERIAL_JTAG_DRIVER_CONFIG_DEFAULT(); + usb_serial_jtag_driver_install(&cfg); + + load_config(); + nimble_port_init(); ble_svc_gap_init(); @@ -88,5 +307,13 @@ void app_main(void) ble_hs_cfg.sync_cb = on_sync; + xTaskCreate( + serial_task, + "serial_task", + 4096, + NULL, + 5, + NULL); + nimble_port_freertos_init(host_task); } diff --git a/src/officesense_tag/main/main.h b/src/officesense_tag/main/main.h new file mode 100644 index 0000000..6f81ad7 --- /dev/null +++ b/src/officesense_tag/main/main.h @@ -0,0 +1,18 @@ +#ifndef MAIN_H +#define MAIN_H + +#include "host/ble_hs.h" + +#define DEFAULT_UUID "12345678-9abc-def0-1234-56789abcdef0" +#define DEFAULT_NAME "X6TAG" +#define DEFAULT_ADV_INTERVAL 0x80 + +typedef struct +{ + ble_uuid128_t uuid; + char uuid_str[37]; + char name[32]; + uint32_t adv_interval; +} config_t; + +#endif \ No newline at end of file