summaryrefslogtreecommitdiff
path: root/mqtt-test/main
diff options
context:
space:
mode:
authorTrygve Laugstøl <trygvis@inamo.no>2018-06-03 12:39:57 +0200
committerTrygve Laugstøl <trygvis@inamo.no>2018-06-03 12:39:57 +0200
commit934bbf7d019e561209802f6a679b3672ce58ef1a (patch)
treea558a8344aabfdf98d4a8bf0a1776bcc500bad39 /mqtt-test/main
parent1ab751428b65cab4d31f323eb3c31789321a0db6 (diff)
downloadmodern-esp-sandbox-934bbf7d019e561209802f6a679b3672ce58ef1a.tar.gz
modern-esp-sandbox-934bbf7d019e561209802f6a679b3672ce58ef1a.tar.bz2
modern-esp-sandbox-934bbf7d019e561209802f6a679b3672ce58ef1a.tar.xz
modern-esp-sandbox-934bbf7d019e561209802f6a679b3672ce58ef1a.zip
wip. Making room for other apps.
Diffstat (limited to 'mqtt-test/main')
-rw-r--r--mqtt-test/main/Kconfig46
-rw-r--r--mqtt-test/main/component.mk14
-rw-r--r--mqtt-test/main/main.cpp488
-rw-r--r--mqtt-test/main/misc.c52
4 files changed, 600 insertions, 0 deletions
diff --git a/mqtt-test/main/Kconfig b/mqtt-test/main/Kconfig
new file mode 100644
index 0000000..11b89dc
--- /dev/null
+++ b/mqtt-test/main/Kconfig
@@ -0,0 +1,46 @@
+menu "Main"
+
+config MAIN_FLASH_SIZE_KB
+ int "Size of flash file system. In kilobytes."
+ range 1 1024
+ default 128
+
+config MAIN_FLASH_FLASH_ADDR_KB
+ int "Start address for flash file system. In kilobytes."
+ default 1024
+
+config MAIN_FLASH_SECTOR_SIZE_KB
+ int "Sector size. In kilobytes"
+ default 4
+ range 1 16
+
+config MAIN_FLASH_LOG_BLOCK_SIZE_KB
+ int "Log block size. In kilobytes"
+ default 4
+ range 1 16
+
+config MAIN_FLASH_LOG_PAGE_SIZE
+ int "Log page"
+ default 128
+
+config MAIN_FLASH_FD_BUF_SIZE
+ int "FD buf size. Default: 32*4"
+ default 128
+
+config MAIN_DEFAULT_WIFI_SSID
+ string "Default Wi-Fi SSID"
+ default "espressif"
+
+config MAIN_DEFAULT_WIFI_PASSWORD
+ string "Default Wi-Fi password"
+ default "12345678"
+
+config MAIN_DEFAULT_MQTT_HOST
+ string "Default MQTT host"
+ default "iot.eclipse.org"
+
+config MAIN_DEFAULT_MQTT_PORT
+ int "Default MQTT port"
+ default 1883
+
+endmenu
diff --git a/mqtt-test/main/component.mk b/mqtt-test/main/component.mk
new file mode 100644
index 0000000..e102e7e
--- /dev/null
+++ b/mqtt-test/main/component.mk
@@ -0,0 +1,14 @@
+define FIX =
+ifdef $(1)
+CFLAGS += '-D$(1)="$$($(1))"'
+CPPFLAGS += '-D$(1)="$$($(1))"'
+#$$(info USING $(1)=$$($(1)))
+endif
+endef
+
+$(eval $(call FIX,WIFI_SSID))
+$(eval $(call FIX,WIFI_PASSWORD))
+$(eval $(call FIX,MQTT_HOST))
+$(eval $(call FIX,MQTT_PORT))
+
+fix:
diff --git a/mqtt-test/main/main.cpp b/mqtt-test/main/main.cpp
new file mode 100644
index 0000000..952982e
--- /dev/null
+++ b/mqtt-test/main/main.cpp
@@ -0,0 +1,488 @@
+#include "esp_misc.h"
+#include "esp_sta.h"
+#include "esp_system.h"
+#include "esp_wifi.h"
+#include "esp_spiffs.h"
+#include "spiffs.h"
+#include "spiffs.h"
+#include "sdkconfig.h"
+
+#include "MQTTClient.h"
+
+#include <assert.h>
+
+// Allow overriding configuration from Kconfig.
+#ifndef WIFI_SSID
+#define WIFI_SSID CONFIG_MAIN_DEFAULT_WIFI_SSID
+#endif
+#ifndef WIFI_PASSWORD
+#define WIFI_PASSWORD CONFIG_MAIN_DEFAULT_WIFI_PASSWORD
+#endif
+#ifndef MQTT_HOST
+#define MQTT_HOST CONFIG_MAIN_DEFAULT_MQTT_HOST
+#endif
+#ifndef MQTT_PORT
+#define MQTT_PORT CONFIG_MAIN_DEFAULT_MQTT_PORT
+#endif
+
+extern "C"
+uint32_t user_rf_cal_sector_set();
+
+extern "C"
+void user_init();
+
+enum events {
+ EVENTS_GOT_IP = (1 << 0),
+ EVENTS_LOST_IP = (1 << 1),
+};
+
+struct config {
+ int loaded;
+ int ok_count;
+ char wifi_ssid[20];
+ char wifi_password[20];
+
+ char mqtt_host[20];
+ int mqtt_port;
+
+ // Generated field
+ char mqtt_client_id[20];
+};
+struct config main_config;
+
+struct _reent fs_reent;
+#define open(...) _spiffs_open_r(&fs_reent, __VA_ARGS__)
+#define close(...) _spiffs_close_r(&fs_reent, __VA_ARGS__)
+#define read(...) _spiffs_read_r(&fs_reent, __VA_ARGS__)
+#define write(...) _spiffs_write_r(&fs_reent, __VA_ARGS__)
+#define lseek(...) _spiffs_lseek_r(&fs_reent, __VA_ARGS__)
+
+xTaskHandle main_task_handle = 0;
+
+static const char *failok(int ret) {
+ return ret ? "FAIL" : "OK";
+}
+
+static int on_config_item(void *ctx, const char* key, const char* value) {
+ struct config *config = (struct config *)ctx;
+
+ if (strcmp(key, "wifi-ssid") == 0) {
+ strncpy(config->wifi_ssid, value, sizeof(config->wifi_ssid));
+ } else if (strcmp(key, "wifi-password") == 0) {
+ strncpy(config->wifi_password, value, sizeof(config->wifi_password));
+ } else if (strcmp(key, "mqtt-host") == 0) {
+ strncpy(config->mqtt_host, value, sizeof(config->mqtt_host));
+ } else if (strcmp(key, "mqtt-port") == 0) {
+ config->mqtt_port = atoi(value);
+ } else {
+ printf("Unknown key: %s\n", key);
+ return -1;
+ }
+
+ config->ok_count++;
+
+ return 0;
+}
+
+typedef int (kv_event_handler)(void *ctx, const char *key, const char *value);
+
+static int config_read_on_line(kv_event_handler *event_handler, void *ctx, const char* line, size_t sz) {
+ // printf("Handling line: #%d, %s\n", sz, line);
+ char *ptr = strchr(line, '=');
+ if (ptr == NULL) {
+ printf("Could not find '='\n");
+ return -1;
+ }
+
+ *ptr = '\0';
+ const char *key = line, *value = ++ptr;
+
+ return event_handler(ctx, key, value);
+}
+
+static int config_read(kv_event_handler *event_handler, void *ctx)
+{
+ int ret = 0;
+ int pos = 0;
+
+ int fd = open("config", O_RDONLY, 0);
+ // printf("fd=%d\n", fd);
+ if (fd < 0) {
+ ret = -1;
+ goto fail;
+ }
+
+ while (1) {
+ char buf[100];
+ ret = lseek(fd, pos, SEEK_SET);
+ if (ret == -1) {
+ printf("lseek failed: pos=%d, res=%d\n", pos, ret);
+ break;
+ }
+ if (pos > 200) {
+ break; // fail safe for now
+ }
+
+ ret = read(fd, buf, sizeof(buf));
+ // printf("read: pos=%d, ret=%d\n", (int) pos, ret);
+ if (ret > 0) {
+ char *end = (char *)memchr(buf, 0, ret);
+ if (end == NULL) {
+ printf("could not find newline\n");
+ ret = -1;
+ goto fail;
+ } else {
+ *end = '\0';
+ size_t line_sz = end - buf;
+ // printf("line_sz=%d\n", line_sz);
+ pos += line_sz + 1;
+
+ ret = config_read_on_line(event_handler, ctx, buf, line_sz);
+ if (ret) {
+ goto fail;
+ }
+ }
+ } else {
+ break;
+ }
+ }
+
+fail:
+ if (fd != -1) {
+ close(fd);
+ }
+
+ // printf("%s: ret=%d\n", __FUNCTION__, ret);
+
+ return ret;
+}
+
+static int config_write_kv(int fd, const char *key, const char *value) {
+ int ret;
+ char c;
+ // printf("Writing %s=%s\n", key, value);
+
+ size_t sz = strlen(key);
+ ret = write(fd, (char *)key, sz);
+ if (ret != sz) {
+ return ret;
+ }
+
+ c = '=';
+ ret = write(fd, &c, 1);
+ if (ret != 1) {
+ return ret;
+ }
+
+ sz = strlen(value);
+ ret = write(fd, (char *)value, sz);
+ if (ret != sz) {
+ return ret;
+ }
+
+ c = 0;
+ return write(fd, &c, 1) != 1;
+}
+
+static int config_write_kv(int fd, const char *key, int value) {
+ char buf[100];
+ itoa(value, buf, 10);
+
+ return config_write_kv(fd, key, buf);
+}
+
+static int config_write(struct config &config) {
+ int ret = 0;
+
+ int fd = open("config", O_WRONLY | O_CREAT, 0);
+
+ if (fd == -1) {
+ ret = -1;
+ goto fail;
+ }
+
+ ret = config_write_kv(fd, "mqtt-host", config.mqtt_host);
+ if (ret) {
+ goto fail;
+ }
+
+ ret = config_write_kv(fd, "mqtt-port", config.mqtt_port);
+ if (ret) {
+ goto fail;
+ }
+
+fail:
+ if (fd != -1) {
+ close(fd);
+ }
+
+ // printf("%s: ret=%d\n", __FUNCTION__, ret);
+ return ret;
+}
+
+void wifi_event_handler_cb(System_Event_t *event)
+{
+ if (event == NULL) {
+ os_printf("NULL event\n");
+ return;
+ }
+
+ if (event->event_id == EVENT_STAMODE_GOT_IP) {
+ // printf("STA GOT IP\n");
+ if (main_task_handle) {
+ xTaskNotify(main_task_handle, EVENTS_GOT_IP, eSetBits);
+ }
+ } else if (event->event_id == EVENT_STAMODE_CONNECTED) {
+ os_printf("STA CONNECTED\n");
+ } else if (event->event_id == EVENT_STAMODE_DISCONNECTED) {
+ if (main_task_handle) {
+ xTaskNotify(main_task_handle, EVENTS_LOST_IP, eSetBits);
+ }
+ wifi_station_connect();
+ } else {
+ os_printf("unhandled event=%d\n", event->event_id);
+ }
+}
+
+static int fs_init()
+{
+ struct esp_spiffs_config config;
+
+ uint32_t log_page_size = CONFIG_MAIN_FLASH_LOG_PAGE_SIZE;
+
+ config.phys_size = CONFIG_MAIN_FLASH_SIZE_KB * 1024;
+ config.phys_addr = CONFIG_MAIN_FLASH_FLASH_ADDR_KB * 1024;
+ config.phys_erase_block = CONFIG_MAIN_FLASH_SECTOR_SIZE_KB * 1024;
+ config.log_block_size = CONFIG_MAIN_FLASH_LOG_BLOCK_SIZE_KB * 1024;
+ config.log_page_size = log_page_size;
+ config.fd_buf_size = CONFIG_MAIN_FLASH_FD_BUF_SIZE * 2;
+ config.cache_buf_size = (log_page_size + 32) * 8;
+
+ return esp_spiffs_init(&config);
+}
+
+static MQTTClient mqtt_client;
+static Network mqtt_network;
+unsigned char mqtt_tx_buf[80], mqtt_rx_buf[80];
+
+static int mqtt_connect() {
+ int ret;
+ MQTTPacket_connectData cd = MQTTPacket_connectData_initializer;
+ cd.keepAliveInterval = 15;
+ cd.willFlag = 1;
+ cd.will.retained = 1;
+ cd.will.topicName = MQTTString_initializer;
+ cd.will.topicName.cstring = (char *)"esp/esp-245398/online";
+ cd.will.message = MQTTString_initializer;
+ cd.will.message.cstring = (char *)"0";
+
+ NetworkInit(&mqtt_network);
+
+ unsigned int command_timeout_ms = 3000;
+ MQTTClientInit(&mqtt_client, &mqtt_network, command_timeout_ms,
+ mqtt_tx_buf, sizeof(mqtt_tx_buf), mqtt_rx_buf, sizeof(mqtt_rx_buf));
+
+ if ((ret = NetworkConnect(&mqtt_network, main_config.mqtt_host, main_config.mqtt_port)) != 0) {
+ printf("%s: NetworkConnect:%d\n", __FUNCTION__, ret);
+ goto fail;
+ }
+
+ // printf("%s: network connected\n", __FUNCTION__);
+
+ cd.MQTTVersion = 4;
+ cd.clientID.cstring = main_config.mqtt_client_id;
+
+ if ((ret = MQTTConnect(&mqtt_client, &cd)) != 0) {
+ printf("%s: MQTTConnect:%d\n", __FUNCTION__, ret);
+ goto fail;
+ }
+ // printf("%s: mqtt connected\n", __FUNCTION__);
+
+#if defined(MQTT_TASK)
+ if ((ret = MQTTStartTask(&mqtt_client)) != pdPASS) {
+ printf("%s: MQTTStartTask:%d\n", __FUNCTION__, ret);
+ goto fail;
+ }
+#endif
+
+ return 0;
+
+fail:
+ return ret;
+}
+
+static int mqtt_disconnect() {
+ printf("%s\n", __FUNCTION__);
+
+ // TODO: start timer to reconnect to mqtt
+
+ return 0;
+}
+
+char topic_ota[100];
+
+static int format_topic(char *buf, size_t sz, const char *suffix)
+{
+ uint32_t chip_id = system_get_chip_id();
+ int count = snprintf(buf, sz, "esp/esp-%02x%02x%02x/%s",
+ (chip_id >> 16) & 0xff, (chip_id >> 8) & 0xff, chip_id & 0xff, suffix);
+ return count >= sz;
+}
+
+static int mqtt_init() {
+ int ret = format_topic(topic_ota, sizeof(topic_ota), "ota");
+
+ return ret;
+}
+
+static void on_ota(MessageData *data) {
+ char buf[100];
+
+ int bz = sizeof(buf) - 1;
+ int sz = data->message->payloadlen <= bz ? data->message->payloadlen : bz;
+ memcpy(buf, data->message->payload, sz);
+ buf[sz] = 0;
+
+ printf("%s: len=%d, str=%p\n", __FUNCTION__, sz, buf);
+}
+
+static int mqtt_subscribe(const char *topic, messageHandler callback) {
+ printf("%s: %s\n", __FUNCTION__, topic);
+ return MQTTSubscribe(&mqtt_client, topic, QOS2, callback);
+}
+
+static int mqtt_publish(const char *topic, const char *value) {
+ uint32_t chip_id = system_get_chip_id();
+ char buf[100];
+ snprintf(buf, sizeof(buf), "esp/esp-%02x%02x%02x/%s", (chip_id >> 16) & 0xff, (chip_id >> 8) & 0xff, chip_id & 0xff, topic);
+
+ printf("%s: %s: %s\n", __FUNCTION__, buf, value);
+
+ MQTTMessage m;
+ bzero(&m, sizeof(m));
+ m.qos = QOS1;
+ m.payloadlen = strlen(value);
+ m.payload = (void *)value;
+ m.retained = 1;
+ return MQTTPublish(&mqtt_client, buf, &m);
+}
+
+static void set_station_mode(struct config &config) {
+ // printf("STATION_MODE\n");
+ if (wifi_get_opmode_default() != NULL_MODE) {
+ printf("Setting default station mode");
+ wifi_set_opmode(NULL_MODE);
+ }
+
+ wifi_set_opmode_current(STATION_MODE);
+
+ struct station_config sc;
+ bzero(&sc, sizeof(struct station_config));
+ sprintf((char *)sc.ssid, config.wifi_ssid);
+ sprintf((char *)sc.password, config.wifi_password);
+ wifi_station_set_config(&sc);
+
+ wifi_set_event_handler_cb(wifi_event_handler_cb);
+
+ wifi_station_connect();
+}
+
+void main_task(void* ctx) {
+ (void) ctx;
+
+ int count = 0;
+ int ret;
+ uint32_t notification_value;
+ while (1) {
+ int timeout = xTaskNotifyWait(0, UINT32_MAX, &notification_value, pdMS_TO_TICKS(1000)) == pdFALSE;
+
+ if (notification_value & EVENTS_GOT_IP) {
+ struct ip_info info;
+ wifi_get_ip_info(STATION_IF, &info);
+ printf("ip=" IPSTR ", nm=" IPSTR ", gw=" IPSTR "\n", IP2STR(&info.ip), IP2STR(&info.netmask), IP2STR(&info.gw));
+ if (mqtt_connect()) {
+ printf("mqtt_connect failed\n");
+ mqtt_disconnect();
+ } else {
+ ret = mqtt_subscribe(topic_ota, on_ota);
+ printf("%s: mqtt_subscribe: %s\n", __FUNCTION__, failok(ret));
+ vTaskDelay(pdMS_TO_TICKS(500));
+
+ ret = mqtt_publish("online", "1");
+ printf("%s: mqtt_publish: %s\n", __FUNCTION__, failok(ret));
+ vTaskDelay(pdMS_TO_TICKS(500));
+ }
+ }
+ if (notification_value & EVENTS_LOST_IP) {
+ mqtt_disconnect();
+ }
+
+ if (timeout) {
+ if (count % 10 == 0)
+ printf("Hello World! connected=%d\n", mqtt_client.isconnected);
+ /*
+ if (count == 2) {
+ // pvShowMalloc();
+ }
+
+ if (count == 5) {
+ // set_station_mode();
+ }
+
+ */
+ count++;
+ }
+
+ // vTaskDelay(pdMS_TO_TICKS(500));
+ }
+}
+
+#define THREAD_NAME "main"
+#define THREAD_STACK_WORDS 2048
+#define THREAD_PRIO 8
+
+void user_init() {
+ int ret;
+
+ os_printf("SDK version: %s, free: %d, app build: %s\n", system_get_sdk_version(), system_get_free_heap_size(), __TIMESTAMP__);
+
+ fs_init();
+
+ assert(mqtt_init() == 0);
+
+ bzero(&main_config, sizeof(struct config));
+ ret = config_read(on_config_item, &main_config);
+ if (ret) {
+ printf("Loading file failed, errno=%d\n", fs_reent._errno);
+ }
+ if (main_config.ok_count != 4) {
+ printf("Loading file failed, loaded bad number of items=%d\n", main_config.ok_count);
+ } else {
+ main_config.loaded = 1;
+ }
+
+ if (!main_config.loaded) {
+ printf("No config loaded, writing new\n");
+ strncpy(main_config.wifi_ssid, WIFI_SSID, sizeof(((struct config*)0)->wifi_ssid));
+ strncpy(main_config.wifi_password, WIFI_PASSWORD, sizeof(((struct config*)0)->wifi_password));
+ strncpy(main_config.mqtt_host, MQTT_HOST, sizeof(((struct config*)0)->mqtt_host));
+ main_config.mqtt_port = MQTT_PORT;
+ ret = config_write(main_config);
+ if (ret) {
+ printf("Writing file failed, errno=%d\n", fs_reent._errno);
+ }
+ }
+
+ uint32_t chip_id = system_get_chip_id();
+ snprintf(main_config.mqtt_client_id, sizeof(main_config.mqtt_client_id), "esp-%02x%02x%02x",
+ (chip_id >> 16) & 0xff, (chip_id >> 8) & 0xff, chip_id & 0xff);
+
+ printf("Configuration:\n");
+ printf(" wifi-ssid=%s\n wifi-password=%s\n\n", main_config.wifi_ssid, main_config.wifi_password);
+ printf(" mqtt-host=%s\n mqtt-port=%d\n mqtt-client-id=%s\n\n", main_config.mqtt_host, main_config.mqtt_port, main_config.mqtt_client_id);
+
+ set_station_mode(main_config);
+
+ ret = xTaskCreate(main_task, THREAD_NAME, THREAD_STACK_WORDS, NULL, THREAD_PRIO, &main_task_handle);
+ assert(ret == pdPASS);
+}
diff --git a/mqtt-test/main/misc.c b/mqtt-test/main/misc.c
new file mode 100644
index 0000000..1b5119b
--- /dev/null
+++ b/mqtt-test/main/misc.c
@@ -0,0 +1,52 @@
+#include <esp_system.h>
+
+/******************************************************************************
+ * FunctionName : user_rf_cal_sector_set
+ * Description : SDK just reversed 4 sectors, used for rf init data and paramters.
+ * We add this function to force users to set rf cal sector, since
+ * we don't know which sector is free in user's application.
+ * sector map for last several sectors : ABCCC
+ * A : rf cal
+ * B : rf init data
+ * C : sdk parameters
+ * Parameters : none
+ * Returns : rf cal sector
+*******************************************************************************/
+uint32_t user_rf_cal_sector_set()
+{
+ flash_size_map size_map = system_get_flash_size_map();
+ uint32_t rf_cal_sec = 0;
+
+ switch (size_map) {
+ case FLASH_SIZE_4M_MAP_256_256:
+ rf_cal_sec = 128 - 5;
+ break;
+
+ case FLASH_SIZE_8M_MAP_512_512:
+ rf_cal_sec = 256 - 5;
+ break;
+
+ case FLASH_SIZE_16M_MAP_512_512:
+ case FLASH_SIZE_16M_MAP_1024_1024:
+ rf_cal_sec = 512 - 5;
+ break;
+
+ case FLASH_SIZE_32M_MAP_512_512:
+ case FLASH_SIZE_32M_MAP_1024_1024:
+ rf_cal_sec = 1024 - 5;
+ break;
+ case FLASH_SIZE_64M_MAP_1024_1024:
+ rf_cal_sec = 2048 - 5;
+ break;
+ case FLASH_SIZE_128M_MAP_1024_1024:
+ rf_cal_sec = 4096 - 5;
+ break;
+ default:
+ rf_cal_sec = 0;
+ break;
+ }
+
+ return rf_cal_sec;
+}
+
+