From ebfea5acb66a68a0b8bd6050fcff191da1be23bf Mon Sep 17 00:00:00 2001 From: "Paul D.Smith" Date: Tue, 19 Dec 2023 18:36:15 +0000 Subject: [PATCH] Checkpoint --- esp32/cloudsmets/main/cs_cfg.c | 33 +++++++---- esp32/cloudsmets/main/cs_cfg.h | 24 ++++---- esp32/cloudsmets/main/cs_mqtt.c | 99 ++++++++++++--------------------- esp32/cloudsmets/main/cs_ota.c | 13 ++--- esp32/cloudsmets/main/cs_web.c | 22 ++++---- esp32/cloudsmets/main/cs_wifi.c | 8 +-- 6 files changed, 90 insertions(+), 109 deletions(-) diff --git a/esp32/cloudsmets/main/cs_cfg.c b/esp32/cloudsmets/main/cs_cfg.c index fc219d9..e0b1804 100644 --- a/esp32/cloudsmets/main/cs_cfg.c +++ b/esp32/cloudsmets/main/cs_cfg.c @@ -97,14 +97,14 @@ const char cs_cfg_ota_rev_url[] = "otaRevUrl"; const char cs_cfg_ota_img_url[] = "otaImgUrl"; const char cs_cfg_ota_accept[] = "otaAccept"; -// /* -// * Azure -// */ -// const char *cs_cfg_az_func = "azFunc"; -// const char *cs_cfg_az_iotHub = "azIotHub"; -// const char *cs_cfg_az_device = "azDevice"; -// const char *cs_cfg_az_cnct1 = "azCnct1"; -// const char *cs_cfg_az_cnct2 = "azCnct2"; +/* + * Azure + */ +const char *cs_cfg_az_ena = "azEna"; +const char *cs_cfg_az_iotHub = "azIotHub"; +const char *cs_cfg_az_device = "azDevice"; +const char *cs_cfg_az_key1 = "azKey1"; +const char *cs_cfg_az_key2 = "azKey2"; /* * Web server helper definitions. @@ -245,12 +245,23 @@ void cs_cfg_read_uint32(const char *ns, const char *key, uint32_t *value) nvs_close(handle); } -void cs_cfg_read_str(const char *ns, const char *key, char *value, size_t *length) +void cs_cfg_read_str(const char *ns, const char *key, char **value, size_t *length) { ESP_LOGV(TAG, "Read str value: %s, %s", ns, key); ESP_ERROR_CHECK(nvs_open(ns, NVS_READWRITE, &handle)); - ESP_ERROR_CHECK(nvs_get_str(handle, key, value, length)); - ESP_LOGV(TAG, "Value: %s", value); + (*length) = 0; + ESP_ERROR_CHECK(nvs_get_str(handle, key, NULL, length)); + if ((*length) && (*value) == NULL)) + { + (*value) = (char *)malloc(*length); + if ((*value) == NULL) + { + ESP_LOGE(TAG, "malloc failed: %u", (*length)); + ESP_ERROR_CHECK(ESP_FAIL); + } + } + ESP_ERROR_CHECK(nvs_get_str(handle, key, *value, length)); + ESP_LOGV(TAG, "Value: %s", *value); nvs_close(handle); } diff --git a/esp32/cloudsmets/main/cs_cfg.h b/esp32/cloudsmets/main/cs_cfg.h index db3db57..38868ca 100644 --- a/esp32/cloudsmets/main/cs_cfg.h +++ b/esp32/cloudsmets/main/cs_cfg.h @@ -33,7 +33,7 @@ extern const char *cs_ota_task_name; #define CS_CFG_NMSP_WEB cs_web_task_name // #define CS_CFG_NMSP_DBG cfgDbg #define CS_CFG_NMSP_OTA cs_ota_task_name -// #define CS_CFG_NMSP_AZURE cfgAz +#define CS_CFG_NMSP_AZURE cfgAz /* * Keys @@ -57,11 +57,11 @@ extern const char cs_cfg_ota_dev[]; extern const char cs_cfg_ota_rev_url[]; extern const char cs_cfg_ota_img_url[]; extern const char cs_cfg_ota_accept[]; -// extern const char cfgAzFunc[]; -// extern const char cfgAzIotHub[]; -// extern const char cfgAzDevice[]; -// extern const char cfgAzCnct1[]; -// extern const char cfgAzCnct2[]; +extern const char cfgAzEna[]; +extern const char cfgAzIotHub[]; +extern const char cfgAzDevice[]; +extern const char cfgAzKey1[]; +extern const char cfgAzKey2[]; #define CS_CFG_KEY_WIFI_AP_CHNL cs_cfg_wifi_ap_chnl #define CS_CFG_KEY_WIFI_AP_SSID cs_cfg_wifi_ap_ssid @@ -83,11 +83,11 @@ extern const char cs_cfg_ota_accept[]; #define CS_CFG_KEY_OTA_REV_URL cs_cfg_ota_rev_url #define CS_CFG_KEY_OTA_ACCEPT cs_cfg_ota_accept -// #define CS_CFG_KEY_AZURE_FUNC cfgAzFunc -// #define CS_CFG_KEY_AZURE_IOTHUB cfgAzIotHub -// #define CS_CFG_KEY_AZURE_DEVICE cfgAzDevice -// #define CS_CFG_KEY_AZURE_CON1 cfgAzCnct1 -// #define CS_CFG_KEY_AZURE_CON2 cfgAzCnct2 +#define CS_CFG_KEY_AZURE_FUNC cfgAzFunc +#define CS_CFG_KEY_AZURE_IOTHUB cfgAzIotHub +#define CS_CFG_KEY_AZURE_DEVICE cfgAzDevice +#define CS_CFG_KEY_AZURE_KEY1 cfgAzCnct1 +#define CS_CFG_KEY_AZURE_KEY2 cfgAzCnct2 /* * Define some structures to make writing the web server simpler. @@ -118,7 +118,7 @@ extern void cs_cfg_default_str(const char *ns, const char *key, const char * def extern void cs_cfg_read_uint8(const char *ns, const char *key, uint8_t *value); extern void cs_cfg_read_uint16(const char *ns, const char *key, uint16_t *value); extern void cs_cfg_read_uint32(const char *ns, const char *key, uint32_t *value); -extern void cs_cfg_read_str(const char *ns, const char *key, char *value, size_t *length); +extern void cs_cfg_read_str(const char *ns, const char *key, char **value, size_t *length); extern void cs_cfg_write_uint8(const char *ns, const char *key, uint8_t value); extern void cs_cfg_write_uint16(const char *ns, const char *key, uint16_t value); extern void cs_cfg_write_uint32(const char *ns, const char *key, uint32_t value); diff --git a/esp32/cloudsmets/main/cs_mqtt.c b/esp32/cloudsmets/main/cs_mqtt.c index e38cb48..fbf2c2f 100644 --- a/esp32/cloudsmets/main/cs_mqtt.c +++ b/esp32/cloudsmets/main/cs_mqtt.c @@ -102,10 +102,10 @@ uint8_t url_quote_plus_hex_map[] = "0123456789ABCDEF"; static const char *TAG = "IoThub"; -char *url_quote_plus(char *string) +char *url_quote_plus(char *in_url) { - char *escaped; - uint8_t *sptr = query->s; + char *out_url; + uint8_t *sptr = in_url; uint8_t *tptr; size_t in_len = strlen(string); size_t out_len = strlen(string); @@ -123,13 +123,18 @@ char *url_quote_plus(char *string) if (out_len == in_len) { // No escaping required. - return string; + return in_url; } - escaped = (char *)malloc(len); + out_url = (char *)malloc(out_len); + if (out_url == NULL) + { + ESP_LOGE(TAG, "Cannot malloc out_url: %d", out_len); + ESP_ERROR_CHECK(ESP_FAIL); + } - sptr = string; - tptr = escaped; + sptr = in_url; + tptr = out_url; for (ii = 0; ii < in_len; ii++) { if (NULL != memchr(url_quote_plus_esc_chars, (int)(*sptr), sizeof(url_quote_plus_esc_chars))) @@ -146,60 +151,10 @@ char *url_quote_plus(char *string) *tptr++ = *sptr++; } } - free(url); + free(in_url); return escaped; } -// Convert a string which might contain extended ASCII characters to utf-8. -coap_string_t *_coap_to_utf_8(coap_string_t *input) -{ - size_t ii; - size_t len; - uint8_t *sptr = input->s; - uint8_t *tptr = input->s; - coap_string_t *utf8; - - // First count the number of bytes that are in the range 0x80 to 0xff as - // each of these will be expanded to two bytes. - len = input->length; - for (ii = 0; ii < input->length; ii++) - { - if (*sptr++ >= 0x80) - { - len++; - } - } - if (len == input->length) - { - // No extended-ASCII so just return the original string. - return input; - } - utf8 = coap_new_string(len); - utf8->length = len; - sptr = input->s; - tptr = utf8->s; - for (ii = 0; ii < input->length; ii++) - { - if (*sptr >= 0x80) - { - // Encode this extended ASCII byte into 2 UTF-8 bytes. - *tptr++ = 0b11000000 | (*sptr >> 6); - *tptr++ = 0b10000000 | (*sptr & 0b00111111); - sptr++; - } - else - { - // Standard ASCII. - *tptr++ = *sptr++; - } - } - coap_delete_string(input); - return(utf8); -} - - - - static void generate_sas_token(char *url, char *base64_key) { uint8_t key[64]; @@ -224,7 +179,7 @@ static void generate_sas_token(char *url, char *base64_key) ttl_len = ssprintf(ttl, "%lu", expiry); /* The URL has to be escaped. */ - url = url_escape_url(url); + url = url_quote_plus(url); // The SHA256 digest of an HMAC is a 32 byte string. HMAC_digest(key, signed_key, hmac_sig) @@ -237,9 +192,6 @@ static void generate_sas_token(char *url, char *base64_key) return; } - - - token_length = 2 + 1 strlen(uri) + 1 + 3 + 1 + b64_len + 1 + 2 + 1 + ttl_len + 1; token = (char *)malloc(token_length); ssprintf(token, "sr=%s&sig=%s&se=%s", uri, sig, ttl); @@ -255,6 +207,24 @@ static void cs_mqtt_connect() { } +static char *access_keys[2] = {NULL, NULL}; +static char *iothub_url = NULL; +static char *device = NULL; + + +// TODO: Anyway to avoid global variables? +static void read_configuration() +{ + size_t len; + uint8_t enabled; + + cs_cfg_read_uint8(CS_CFS_NMSP_AZURE, CFS_CFG_KEY_AZURE_ENA, &enabled); + cs_cfg_read_str(CS_CFS_NMSP_AZURE, CFS_CFG_KEY_AZURE_IOTHUB, &iothub_url, &len); + cs_cfg_read_str(CS_CFS_NMSP_AZURE, CFS_CFG_KEY_AZURE_DEVICE, &device, &len); + cs_cfg_read_str(CS_CFS_NMSP_AZURE, CFS_CFG_KEY_AZURE_KEY1, &access_keys[0], &len); + cs_cfg_read_str(CS_CFS_NMSP_AZURE, CFS_CFG_KEY_AZURE_KEY2, &access_keys[1], &len); +} + static void mqtt_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data) @@ -286,6 +256,11 @@ static void mqtt_event_handler(void *arg, esp_event_base_t event_base, break; } } + else if (event_base == CS_CONFIG) + { + // Config change so relearn all configuration. + read_configuration(); + } else if (event_base == CS_TIME) { ESP_LOGI(TAG, "Time is now set"); diff --git a/esp32/cloudsmets/main/cs_ota.c b/esp32/cloudsmets/main/cs_ota.c index 560d1dd..719dc0b 100644 --- a/esp32/cloudsmets/main/cs_ota.c +++ b/esp32/cloudsmets/main/cs_ota.c @@ -160,12 +160,8 @@ bool determine_release(ota_version_t *version) esp_http_client_handle_t esp_http_client_handle; esp_err_t esp_rc; -#define OTA_MAX_URL_LENGTH 1024 - buffer = (char *)malloc(OTA_MAX_URL_LENGTH); - len = OTA_MAX_URL_LENGTH; - // If there is a specific release requested then we just try for that. - cs_cfg_read_str(CS_CFG_NMSP_OTA, CS_CFG_KEY_OTA_REL, buffer, &len); + cs_cfg_read_str(CS_CFG_NMSP_OTA, CS_CFG_KEY_OTA_REL, &buffer, &len); if (len > 0) { // TODO: Common code here? @@ -176,6 +172,7 @@ bool determine_release(ota_version_t *version) &version->minor, &version->revision, &version->dev); + free(buffer); if (ss_rc == 3) { version->dev = 0; @@ -193,7 +190,7 @@ bool determine_release(ota_version_t *version) cs_cfg_read_uint8(CS_CFG_NMSP_OTA, CS_CFG_KEY_OTA_DEV, &allow_dev); len = OTA_MAX_URL_LENGTH; - cs_cfg_read_str(CS_CFG_NMSP_OTA, CS_CFG_KEY_OTA_REV_URL, buffer, &len); + cs_cfg_read_str(CS_CFG_NMSP_OTA, CS_CFG_KEY_OTA_REV_URL, &buffer, &len); if (allow_dev) { @@ -232,9 +229,7 @@ bool upgrade_to(ota_version_t *version) bool success = true; esp_err_t esp_rc; - url = (char *)malloc(1024); - - cs_cfg_read_str(CS_CFG_NMSP_OTA, CS_CFG_KEY_OTA_IMG_URL, url, &len); + cs_cfg_read_str(CS_CFG_NMSP_OTA, CS_CFG_KEY_OTA_IMG_URL, &url, &len); // Now add the version. if (version->dev) diff --git a/esp32/cloudsmets/main/cs_web.c b/esp32/cloudsmets/main/cs_web.c index 6f725db..14df17d 100644 --- a/esp32/cloudsmets/main/cs_web.c +++ b/esp32/cloudsmets/main/cs_web.c @@ -111,7 +111,7 @@ static esp_err_t get_tools_js_handler(httpd_req_t *req) return httpd_resp_send(req, (char *)tools_js_start, tools_js_len); } -size_t write_field(char *ptr, size_t available, const char *ns, const cs_cfg_definitions_t *definition) +size_t read_field(char **ptr, size_t available, const char *ns, const cs_cfg_definitions_t *definition) { size_t outlen = 0; size_t s_length; @@ -123,42 +123,42 @@ size_t write_field(char *ptr, size_t available, const char *ns, const cs_cfg_def switch (definition->type) { case NVS_TYPE_STR: - outlen = snprintf(ptr, available, "\"%s\":\"", definition->key); + outlen = snprintf(*ptr, available, "\"%s\":\"", definition->key); if (outlen > available) { break; } available -= outlen; - ptr += outlen; + *ptr += outlen; s_length = available; - cs_cfg_read_str(ns, definition->key, ptr, &s_length); + cs_cfg_read_str(ns, definition->key, *ptr, &s_length); // Length returned out includes the NULL. s_length--; available -= s_length; - ptr+= s_length; + *ptr+= s_length; outlen += s_length; if (available < 1) { break; } - *ptr = '"'; + **ptr = '"'; outlen++; break; case NVS_TYPE_U8: cs_cfg_read_uint8(ns, definition->key, &u8_value); - outlen = snprintf(ptr, available, "\"%s\":%hu", definition->key, (unsigned short)u8_value); + outlen = snprintf(*ptr, available, "\"%s\":%hu", definition->key, (unsigned short)u8_value); break; case NVS_TYPE_U16: cs_cfg_read_uint16(ns, definition->key, &u16_value); - outlen = snprintf(ptr, available, "\"%s\":%hu", definition->key, u16_value); + outlen = snprintf(*ptr, available, "\"%s\":%hu", definition->key, u16_value); break; case NVS_TYPE_U32: cs_cfg_read_uint32(ns, definition->key, &u32_value); - outlen = snprintf(ptr, available, "\"%s\":%lu", definition->key, u32_value); + outlen = snprintf(*ptr, available, "\"%s\":%lu", definition->key, u32_value); break; default: @@ -190,7 +190,7 @@ static esp_err_t get_json_handler( *ptr++ = '{'; available--; - outlen = write_field(ptr, available, ns, definition); + outlen = read_field(&ptr, available, ns, definition); while ((available > outlen) && ((++definition)->key != NULL)) { @@ -198,7 +198,7 @@ static esp_err_t get_json_handler( ptr += outlen; *ptr++ = ','; available--; - outlen = write_field(ptr, available, ns, definition); + outlen = read_field(&ptr, available, ns, definition); } if (available > outlen) diff --git a/esp32/cloudsmets/main/cs_wifi.c b/esp32/cloudsmets/main/cs_wifi.c index 980ba63..32f7a8a 100644 --- a/esp32/cloudsmets/main/cs_wifi.c +++ b/esp32/cloudsmets/main/cs_wifi.c @@ -67,13 +67,13 @@ static bool wifi_config_sta() length = sizeof(wifi_sta_config.ap.ssid); ESP_LOGV(TAG, "B SSID: %d", length); - cs_cfg_read_str(CS_CFG_NMSP_WIFI, CS_CFG_KEY_WIFI_STA_SSID, (char *)wifi_sta_config.sta.ssid, &length); + cs_cfg_read_str(CS_CFG_NMSP_WIFI, CS_CFG_KEY_WIFI_STA_SSID, (char **)&wifi_sta_config.sta.ssid, &length); ESP_LOGV(TAG, "A SSID: %d", length); wifi_sta_config.sta.ssid[length] = 0; rc = length > 8 ? rc : false; length = sizeof(wifi_sta_config.ap.password); ESP_LOGV(TAG, "B PWD: %d", length); - cs_cfg_read_str(CS_CFG_NMSP_WIFI, CS_CFG_KEY_WIFI_STA_PWD, (char *)wifi_sta_config.sta.password, &length); + cs_cfg_read_str(CS_CFG_NMSP_WIFI, CS_CFG_KEY_WIFI_STA_PWD, (char **)&wifi_sta_config.sta.password, &length); ESP_LOGV(TAG, "A PWD: %d", length); wifi_sta_config.sta.password[length] = 0; rc = length > 8 ? rc : false; @@ -226,10 +226,10 @@ static void wifi_init_softap() // Read SoftAP configuration. cs_cfg_read_uint8(CS_CFG_NMSP_WIFI, CS_CFG_KEY_WIFI_AP_CHNL, &wifi_ap_config.ap.channel); length = sizeof(wifi_ap_config.ap.ssid); - cs_cfg_read_str(CS_CFG_NMSP_WIFI, CS_CFG_KEY_WIFI_AP_SSID, (char *)wifi_ap_config.ap.ssid, &length); + cs_cfg_read_str(CS_CFG_NMSP_WIFI, CS_CFG_KEY_WIFI_AP_SSID, (char **)&wifi_ap_config.ap.ssid, &length); wifi_ap_config.ap.ssid_len = (uint8_t)length; length = sizeof(wifi_ap_config.ap.password); - cs_cfg_read_str(CS_CFG_NMSP_WIFI, CS_CFG_KEY_WIFI_AP_PWD, (char *)wifi_ap_config.ap.password, &length); + cs_cfg_read_str(CS_CFG_NMSP_WIFI, CS_CFG_KEY_WIFI_AP_PWD, (char **)&wifi_ap_config.ap.password, &length); ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_AP, &wifi_ap_config)); ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_AP));