diff --git a/Makefile b/Makefile index ce506a7..42e18f4 100644 --- a/Makefile +++ b/Makefile @@ -26,7 +26,7 @@ endif # Linker extra options here. ifeq ($(USE_LDOPT),) - USE_LDOPT = + USE_LDOPT = --print-memory-usage endif # Enable this if you want link time optimizations (LTO). @@ -121,7 +121,7 @@ include $(CHIBIOS)/os/various/lwip_bindings/lwip.mk #include $(CHIBIOS)/ext/STM32F4xx_StdPeriph_Driver/stcrypt.mk #include $(CHIBIOS)/ext/STM32_Cryptographic_Library/stcryptolib.mk #include $(CHIBIOS)/os/various/wolfssl_bindings/wolfssl.mk -#include $(CHIBIOS)/ext/mbedtls/mbedtls.mk +include $(CHIBIOS)/ext/mbedtls/mbedtls.mk # Define linker script file here LDSCRIPT= $(CONFDIR)/STM32F437xG.ld diff --git a/lwipopts.h b/lwipopts.h index 15bc2c0..728e82d 100644 --- a/lwipopts.h +++ b/lwipopts.h @@ -190,6 +190,8 @@ //#define MDNS_DEBUG LWIP_DBG_ON // MQTT //#define MQTT_DEBUG LWIP_DBG_ON +// HTTP Client +//#define HTTPC_DEBUG LWIP_DBG_ON // SNTP #define SNTP_SERVER_DNS 1 @@ -212,6 +214,16 @@ #define LWIP_NETIF_HOSTNAME 1 +// MBED TLS +/* +#define LWIP_ALTCP 1 +#define LWIP_ALTCP_TLS 1 +#define LWIP_ALTCP_TLS_MBEDTLS 1 +#define MBEDTLS_PLATFORM_MEMORY 1 +#define ALTCP_MBEDTLS_RNG_FN mbedtls_entropy_func +//#define MEMP_MEM_MALLOC 1 +*/ + /* * new SNTP_SET_SYSTEM_TIME function * diff --git a/main.c b/main.c index 53713be..c7444b4 100644 --- a/main.c +++ b/main.c @@ -100,15 +100,31 @@ char gprsSmsText[128] __attribute__((section(".ram4"))); #include "lwip/apps/sntp.h" #include "lwip/apps/smtp.h" #include "lwip/apps/mdns.h" + +#include "lwip/inet.h" +#include "lwip/apps/http_client.h" + #include "ohs_httpdhandler.h" // MQTT -#include "lwip/apps/mqtt_priv.h" // Needed to conf.mqtt +#include "lwip/apps/mqtt_priv.h" // Needed for conf.mqtt #include "lwip/apps/mqtt.h" #include "ohs_mqtt_functions.h" // Shell functions #include "ohs_shell.h" +// MBEDTLS +/* +#include "config.h" +#include "mbedtls/platform.h" +#include "mbedtls/net_sockets.h" +#include "mbedtls/ssl.h" +#include "mbedtls/entropy.h" +#include "mbedtls/ctr_drbg.h" +#include "mbedtls/error.h" +#include "mbedtls/certs.h" +*/ + // #ifdef OHS_WOLFSSL #include "crypto.h" @@ -164,6 +180,50 @@ static void mdns_example_report(struct netif* netif, u8_t result, s8_t service){ } #endif +/* +uint8_t httpcGo = 1; +err_t httpcHeaderDone (httpc_state_t *connection, void *arg, struct pbuf *hdr, u16_t hdr_len, u32_t content_len){ + LWIP_UNUSED_ARG(connection); + LWIP_UNUSED_ARG(arg); + + chprintf(console, ">httpcHeaderDone: %d;%d;%s\r\n", hdr_len, content_len, hdr->payload); + return ERR_OK; +} + +void httpcFinished (void *arg, httpc_result_t httpc_result, u32_t rx_content_len, u32_t srv_res, err_t err){ + LWIP_UNUSED_ARG(arg); + + chprintf(console, ">httpcFinished err: %d; httpc_result: %d, rx_content_len: %d, srv_res: %d\r\n", err, httpc_result,rx_content_len,srv_res); + httpcGo = 1; +} + +err_t httpcGetResult (void *arg, struct altcp_pcb *conn, struct pbuf *p, err_t err){ + LWIP_UNUSED_ARG(arg); + LWIP_UNUSED_ARG(conn); + + chprintf(console, ">httpcGetResult: %d;%s\r\n", err, p->payload); + + // Free pbuf + if (p != NULL) pbuf_free(p); + return ERR_OK; +} + +static void mydebug(void *ctx, int level, const char *file, int line, + const char *str) { + const char *p, *basename; + (void) ctx; + + // Extract basename from file + for(p = basename = file; *p != '\0'; p++) { + if(*p == '/' || *p == '\\') { + basename = p + 1; + } + } + + chprintf(console, "%s:%04d: |%d| %s", basename, line, level, str); +} +*/ + /* * Application entry point. */ @@ -203,7 +263,7 @@ int main(void) { struct lwipthread_opts lwip_opts = { &macAddr[0], 0, 0, 0, NET_ADDRESS_DHCP #if LWIP_NETIF_HOSTNAME - , OHS_NAME + , OHS_NAME "2" #endif ,NULL, NULL }; @@ -230,7 +290,7 @@ int main(void) { memset(&gprsSmsText[0], 0, sizeof(gprsSmsText)); memset(&gprsSystemInfo[0], 0, sizeof(gprsSystemInfo)); memset(&logText[0], 0, LOG_TEXT_LENGTH); - memset(&alertMsg[0], 0 , HTTP_ALERT_MSG_SIZE); // Empty alert message + memset(&httpAlertMsg[0], 0 , HTTP_ALERT_MSG_SIZE); // Empty alert message shellInit(); @@ -319,17 +379,19 @@ int main(void) { chprintf(console, "Size of conf: %u, group: %u\r\n", sizeof(conf), sizeof(group)); // Check if we have 1.3 -> 1.4 version update - if ((conf.versionMajor == 1) && (conf.versionMinor == 3) && (OHS_MINOR == 4)) { + if ((conf.versionMajor == 1) && (conf.versionMinor == 3) && (OHS_MINOR == 4)) { // Set new version conf struct changes // Save the changes conf.versionMajor = OHS_MAJOR; conf.versionMinor = OHS_MINOR; writeToBkpSRAM((uint8_t*)&conf, sizeof(config_t), 0); - } else if (OHS_MINOR != conf.versionMinor) { + } else if (OHS_MINOR != conf.versionMinor) { // Unknown version change, clear all setConfDefault(); // Save the changes + conf.versionMajor = OHS_MAJOR; + conf.versionMinor = OHS_MINOR; writeToBkpSRAM((uint8_t*)&conf, sizeof(config_t), 0); // Init and save runtime variables initRuntimeGroups(); // Initialize runtime variables @@ -351,6 +413,8 @@ int main(void) { UNLOCK_TCPIP_CORE(); // MQTT CLEAR_CONF_MQTT_ADDRESS_ERROR(conf.mqtt.setting); // Force resolve address on start + // Set HTTPD connection ID to be "unique", to disallow Id=NULL as vaild + authorizedConn.id = STM32_UUID[0] + rand(); // Start startTime = getTimeUnixSec(); @@ -366,6 +430,57 @@ int main(void) { wolfSSL_Init(); #endif + /* + mbedtls_entropy_context entropy; + mbedtls_ctr_drbg_context ctr_drbg; + mbedtls_ssl_context ssl; + mbedtls_x509_crt cacert; + mbedtls_ssl_config conf; + mbedtls_net_context server_fd; + + char buf[512]; + int ret, flags, len; + mbedtls_ssl_init(&ssl); + mbedtls_x509_crt_init(&cacert); + mbedtls_ctr_drbg_init(&ctr_drbg); + + mbedtls_ssl_config_init(&conf); + + mbedtls_entropy_init(&entropy); + if((ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, + NULL, 0)) != 0) { + chprintf(console, "mbedtls_ctr_drbg_seed returned %d", ret); + } + */ + + // MBEDTLS client + /* + mbedtls_entropy_context entropy; + mbedtls_ctr_drbg_context ctr_drbg; + mbedtls_ssl_context ssl; + mbedtls_x509_crt cacert; + mbedtls_ssl_config conf; + int ret; + + mbedtls_ssl_init(&ssl); + mbedtls_ssl_config_init(&conf); + mbedtls_x509_crt_init(&cacert); + mbedtls_ctr_drbg_init(&ctr_drbg); + mbedtls_entropy_init(&entropy); + if((ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, + NULL, 0)) != 0) { + chprintf(console, ">mbedtls_ctr_drbg_seed: %d", ret); + } + + httpc_connection_t httpClientConn; + httpClientConn.result_fn = httpcFinished; + httpClientConn.headers_done_fn = httpcHeaderDone; + httpClientConn.use_proxy = 0; + ip_addr_t httpcAddr;// = IPADDR4_INIT_BYTES(10,10,10,127); + httpc_state_t* http_state; + err_t err; + */ + //size_t n, total, largest; // Idle runner while (true) { @@ -378,7 +493,7 @@ int main(void) { chThdWait(shelltp); // Waiting termination. } - //chThdSleepMilliseconds(10000); + /* n = chHeapStatus(NULL, &total, &largest); chprintf(console, "core free memory : %u bytes" SHELL_NEWLINE_STR, chCoreGetStatusX()); @@ -390,5 +505,19 @@ int main(void) { //chThdSleepMilliseconds(10000); //int ret = wolfSSL_get_ciphers(&tclOutput[0], (int)sizeof(tclOutput)); //https_client(); + + /* + chThdSleepMilliseconds(20000); + err = inet_aton("10.10.10.127", &httpcAddr); + chprintf(console, ">inet_aton: %d\r\n", err); + + if (httpcGo) { + LOCK_TCPIP_CORE(); + err = httpc_get_file_dns("www.seznam.cz", 80, "/#/login", &httpClientConn, httpcGetResult, NULL, &http_state); + if (!err) httpcGo = 0; + chprintf(console, ">httpc_get_file: %d\r\n", err); + UNLOCK_TCPIP_CORE(); + } + */ } } diff --git a/ohs_conf.h b/ohs_conf.h index 5dbe3a6..86c0bce 100644 --- a/ohs_conf.h +++ b/ohs_conf.h @@ -21,8 +21,8 @@ #define OHS_NAME "OHS" #define OHS_MAJOR 1 -#define OHS_MINOR 3 -#define OHS_MOD 10 +#define OHS_MINOR 4 +#define OHS_MOD 0 #define BACKUP_SRAM_SIZE 0x1000 // 4kB SRAM size @@ -751,20 +751,20 @@ typedef struct { char type; //= 'K/S/I'; char function;//= ' '; uint8_t number; //= 0; - // |- MQTT publish - // ||- Free - // |||- Battery low flag, for battery type node - // |||||||- Group number - // |||||||- 0 .. 15 - // |||||||- - // |||||||- - // ||||||||- Enabled - // 76543210 - uint16_t setting;// = B00011110; // 2 bytes to store also zone setting - float value; // = 0; - time_t lastOK; // = 0; - uint8_t queue; // = DUMMY_NO_VALUE 255; // No queue - char name[NAME_LENGTH]; // = ""; + float value; // = 0; + time_t lastOK; // = 0; + void *queue; // + // |- MQTT publish + // ||- Free + // |||- Battery low flag, for battery type node + // |||||||- Group number + // |||||||- 0 .. 15 + // |||||||- + // |||||||- + // ||||||||- Enabled + // 76543210 + uint16_t setting;// = B00011110; // 2 bytes to store also zone setting + char name[NAME_LENGTH]; // = ""; } node_t; node_t node[NODE_SIZE] __attribute__((section(".ram4"))); @@ -778,7 +778,7 @@ void initRuntimeNodes(void){ node[i].lastOK = 0; node[i].name[0] = '\0'; node[i].number = 0; - node[i].queue = DUMMY_NO_VALUE; + node[i].queue = NULL; node[i].setting = 0b00011110; node[i].type = '\0'; node[i].value = 0; @@ -832,7 +832,7 @@ void initRuntimeZones(void){ /* * Write to backup SRAM */ -int16_t writeToBkpSRAM(uint8_t *data, uint16_t size, uint16_t offset){ +uint16_t writeToBkpSRAM(uint8_t *data, uint16_t size, uint16_t offset){ osalDbgAssert(((size + offset) < BACKUP_SRAM_SIZE), "BkpSRAM out of region"); uint16_t i = 0; uint8_t *baseAddress = (uint8_t *) BKPSRAM_BASE; @@ -844,7 +844,7 @@ int16_t writeToBkpSRAM(uint8_t *data, uint16_t size, uint16_t offset){ /* * Read from backup SRAM */ -int16_t readFromBkpSRAM(uint8_t *data, uint16_t size, uint16_t offset){ +uint16_t readFromBkpSRAM(uint8_t *data, uint16_t size, uint16_t offset){ osalDbgAssert(((size + offset) < BACKUP_SRAM_SIZE), "BkpSRAM out of region"); uint16_t i = 0; uint8_t *baseAddress = (uint8_t *) BKPSRAM_BASE; @@ -856,7 +856,7 @@ int16_t readFromBkpSRAM(uint8_t *data, uint16_t size, uint16_t offset){ /* * Write to backup RTC */ -int16_t writeToBkpRTC(uint8_t *data, uint8_t size, uint8_t offset){ +uint8_t writeToBkpRTC(uint8_t *data, uint8_t size, uint8_t offset){ osalDbgAssert(((size + offset) < STM32_RTC_STORAGE_SIZE), "BkpRTC out of region"); osalDbgAssert(!(offset % 4), "BkpRTC misaligned"); // Offset is not aligned to to unint32_t registers uint8_t i = 0; @@ -874,7 +874,7 @@ int16_t writeToBkpRTC(uint8_t *data, uint8_t size, uint8_t offset){ /* * Read from backup RTC */ -int16_t readFromBkpRTC(uint8_t *data, uint8_t size, uint8_t offset){ +uint8_t readFromBkpRTC(uint8_t *data, uint8_t size, uint8_t offset){ osalDbgAssert(((size + offset) < STM32_RTC_STORAGE_SIZE), "BkpRTC out of region"); osalDbgAssert(!(offset % 4), "BkpRTC misaligned"); // Offset is not aligned to to unint32_t registers uint8_t i = 0; diff --git a/ohs_functions.h b/ohs_functions.h index ba04fd2..e1579af 100644 --- a/ohs_functions.h +++ b/ohs_functions.h @@ -94,19 +94,21 @@ int8_t sendData(uint8_t address, const uint8_t *data, uint8_t length){ if (address <= RADIO_UNIT_OFFSET) { RS485Msg_t rs485Data; - chprintf(console, "RS485 Send data to address: %d\r\n", address); + chprintf(console, "RS485 data to: %d\r\n", address); rs485Data.address = address; rs485Data.length = length; memcpy(&rs485Data.data[0], data, length); + /* for(uint8_t ii = 0; ii < length; ii++) { chprintf(console, "%d-%x, ", ii, rs485Data.data[ii]); } chprintf(console, "\r\n"); + */ if (rs485SendMsgWithACK(&RS485D2, &rs485Data, 5) == MSG_OK) resp = 1; else resp = -1; } // Radio if (address >= RADIO_UNIT_OFFSET) { - chprintf(console, "Radio Send data to address: %d\r\n", address - RADIO_UNIT_OFFSET); + chprintf(console, "Radio data to: %d\r\n", address - RADIO_UNIT_OFFSET); resp = rfm69SendWithRetry(address - RADIO_UNIT_OFFSET, data, length, 5); } return resp; @@ -121,7 +123,7 @@ int8_t sendCmd(uint8_t address, uint8_t command) { if (address <= RADIO_UNIT_OFFSET) { RS485Cmd_t rs485Cmd; - chprintf(console, "RS485 send cmd: %d to address: %d\r\n", command, address); + chprintf(console, "RS485 cmd: %d to: %d\r\n", command, address); rs485Cmd.address = address; rs485Cmd.length = command; if (rs485SendCmdWithACK(&RS485D2, &rs485Cmd, 3) == MSG_OK) resp = 1; @@ -132,10 +134,10 @@ int8_t sendCmd(uint8_t address, uint8_t command) { char radioCmd[] = {'C', command}; if (address == RADIO_UNIT_OFFSET) { - chprintf(console, "Radio send cmd: %d to broadcast.\r\n", command); + chprintf(console, "Radio cmd: %d to broadcast.\r\n", command); resp = rfm69Send(255, radioCmd, sizeof(radioCmd), false); } else { - chprintf(console, "Radio send cmd: %d to address: %d\r\n", command, address - RADIO_UNIT_OFFSET); + chprintf(console, "Radio cmd: %d to: %d\r\n", command, address - RADIO_UNIT_OFFSET); resp = rfm69Send(address - RADIO_UNIT_OFFSET, radioCmd, sizeof(radioCmd), true); } } diff --git a/ohs_httpdhandler.h b/ohs_httpdhandler.h index 221707f..4244fa7 100644 --- a/ohs_httpdhandler.h +++ b/ohs_httpdhandler.h @@ -53,7 +53,7 @@ static void *currentConn; char current_uri[LWIP_HTTPD_MAX_REQUEST_URI_LEN] __attribute__((section(".ram4"))); char postData[HTTP_POST_DATA_SIZE] __attribute__((section(".ram4"))); -char alertMsg[HTTP_ALERT_MSG_SIZE] __attribute__((section(".ram4"))); +char httpAlertMsg[HTTP_ALERT_MSG_SIZE] __attribute__((section(".ram4"))); char setCookie[HTTP_SET_COOKIE_SIZE] __attribute__((section(".ram4"))); void *verifiedConn = NULL; typedef struct { @@ -175,11 +175,11 @@ int fs_open_custom(struct fs_file *file, const char *name){ // Main Body chprintf(chp, "
\r\n"); // Alert div - if (strlen(alertMsg)) { + if (strlen(httpAlertMsg)) { chprintf(chp, "
×"); chprintf(chp, "Error!

"); - chprintf(chp, "%s.%s", alertMsg, html_div_e); - memset(alertMsg, 0 , HTTP_ALERT_MSG_SIZE); // Empty alert message + chprintf(chp, "%s.%s", httpAlertMsg, html_div_e); + memset(httpAlertMsg, 0 , HTTP_ALERT_MSG_SIZE); // Empty alert message } // Header chprintf(chp, "

%s

\r\n", webPage[htmlPage].name); @@ -714,6 +714,8 @@ int fs_open_custom(struct fs_file *file, const char *name){ chprintf(chp, "%s%s", html_e_td_e_tr, html_e_table); // Buttons chprintf(chp, "%s%s", html_LoadDefault, html_Save); + // TODO OHS add configuration download/upload + //chprintf(chp, ""); break; case PAGE_SETTING: // Information table @@ -1988,19 +1990,19 @@ void httpd_post_finished(void *connection, char *response_uri, u16_t response_ur case 'e': // save if (webScript == DUMMY_NO_VALUE) { if (!strlen(scriptName)) { - chsnprintf(alertMsg, HTTP_ALERT_MSG_SIZE, "Not allowed to save empty name"); + chsnprintf(httpAlertMsg, HTTP_ALERT_MSG_SIZE, "Not allowed to save empty name"); break; } // For new script append linked list scriptp = umm_malloc(sizeof(struct scriptLL_t)); if (scriptp == NULL) { - chsnprintf(alertMsg, HTTP_ALERT_MSG_SIZE, "%s%s", text_error_free, text_heap); + chsnprintf(httpAlertMsg, HTTP_ALERT_MSG_SIZE, "%s%s", text_error_free, text_heap); } else { //if (checkPointer(scriptp, html_noSpace)) {} scriptp->name = umm_malloc(NAME_LENGTH); if (scriptp->name == NULL) { umm_free(scriptp); - chsnprintf(alertMsg, HTTP_ALERT_MSG_SIZE, "%s%s", text_error_free, text_heap); + chsnprintf(httpAlertMsg, HTTP_ALERT_MSG_SIZE, "%s%s", text_error_free, text_heap); } else { strncpy(scriptp->name, &scriptName[0], NAME_LENGTH); number = strlen(tclCmd); @@ -2008,7 +2010,7 @@ void httpd_post_finished(void *connection, char *response_uri, u16_t response_ur if (scriptp->cmd == NULL) { umm_free(scriptp->name); umm_free(scriptp); - chsnprintf(alertMsg, HTTP_ALERT_MSG_SIZE, "%s%s", text_error_free, text_heap); + chsnprintf(httpAlertMsg, HTTP_ALERT_MSG_SIZE, "%s%s", text_error_free, text_heap); } else { strncpy(scriptp->cmd, &tclCmd[0], number); memset(scriptp->cmd + number, 0, 1); @@ -2016,7 +2018,7 @@ void httpd_post_finished(void *connection, char *response_uri, u16_t response_ur scriptLL = scriptp; // uBS if (uBSWrite(&scriptName[0], NAME_LENGTH, &tclCmd[0], strlen(tclCmd)) != UBS_RSLT_OK) { - chsnprintf(alertMsg, HTTP_ALERT_MSG_SIZE, "%s%s", text_error_free, text_storage); + chsnprintf(httpAlertMsg, HTTP_ALERT_MSG_SIZE, "%s%s", text_error_free, text_storage); } // new script is added to top of linked list, no need to do pointer check webScript = 1; @@ -2037,14 +2039,14 @@ void httpd_post_finished(void *connection, char *response_uri, u16_t response_ur umm_free(scriptp->cmd); scriptp->cmd = umm_malloc(number + 1); if (scriptp->cmd == NULL) { - chsnprintf(alertMsg, HTTP_ALERT_MSG_SIZE, "%s%s", text_error_free, text_heap); + chsnprintf(httpAlertMsg, HTTP_ALERT_MSG_SIZE, "%s%s", text_error_free, text_heap); } else { strncpy(scriptp->cmd, &tclCmd[0], number); memset(scriptp->cmd + number, 0, 1); for (int i = 0; i < UBS_NAME_SIZE; i++) { DBG_HTTP("%x;", scriptName[i]); } DBG_HTTP("\r\n"); if (uBSWrite(&scriptName[0], NAME_LENGTH, &tclCmd[0], strlen(tclCmd)) != UBS_RSLT_OK) { - chsnprintf(alertMsg, HTTP_ALERT_MSG_SIZE, "%s%s", text_error_free, text_storage); + chsnprintf(httpAlertMsg, HTTP_ALERT_MSG_SIZE, "%s%s", text_error_free, text_storage); } } } @@ -2232,7 +2234,7 @@ void httpd_post_finished(void *connection, char *response_uri, u16_t response_ur authorizedConn.id = STM32_UUID[0] + rand(); authorizedConn.conn = (void *)connection; } else { - chsnprintf(alertMsg, HTTP_ALERT_MSG_SIZE, "User or password not valid!"); + chsnprintf(httpAlertMsg, HTTP_ALERT_MSG_SIZE, "User or password not valid!"); } break; } diff --git a/ohs_th_radio.h b/ohs_th_radio.h index f1ef5cf..e5995b1 100644 --- a/ohs_th_radio.h +++ b/ohs_th_radio.h @@ -177,6 +177,22 @@ static THD_FUNCTION(RadioThread, arg) { DBG_RADIO("\r\n"); break; } // switch case + + // Data queue for sleeping nodes + for (nodeIndex = 0; nodeIndex < NODE_SIZE; nodeIndex++) { + if ((node[nodeIndex].address == (rfm69Data.senderId + RADIO_UNIT_OFFSET)) && + (node[nodeIndex].queue != NULL)) { + // Do copy of node[].queue to rfm69Data.data, UMM in CCM not accessible by DMA + memcpy(&rfm69Data.data[0], node[nodeIndex].queue, REG_PACKET_SIZE + 1); + resp = sendData(node[nodeIndex].address, &rfm69Data.data[0], REG_PACKET_SIZE + 1); + DBG_RADIO("Send Q 0x%x, resp %d\r\n", (const uint8_t *)node[nodeIndex].queue, resp); + // Sent ? + if (resp == 1) { + umm_free(node[nodeIndex].queue); + node[nodeIndex].queue = NULL; + } + } + } } // received } } diff --git a/ohs_th_service.h b/ohs_th_service.h index 24280c9..20e2d67 100644 --- a/ohs_th_service.h +++ b/ohs_th_service.h @@ -49,15 +49,21 @@ static THD_FUNCTION(ServiceThread, arg) { // Get current time to prevent multiple queries timeNow = getTimeUnixSec(); - // Remove zombie nodes + // Node housekeeping for (uint8_t nodeIndex=0; nodeIndex < NODE_SIZE; nodeIndex++) { + // Remove zombie nodes if ((node[nodeIndex].address != 0) && (node[nodeIndex].lastOK + SECONDS_PER_HOUR < timeNow)) { DBG_SERVICE("Zombie node: %u,A %u,T %u,F %u,N %u\r\n", nodeIndex, node[nodeIndex].address, node[nodeIndex].type, node[nodeIndex].function, node[nodeIndex].number); + // Log this event tmpLog[0] = 'N'; tmpLog[1] = 'Z'; tmpLog[2] = node[nodeIndex].address; tmpLog[3] = node[nodeIndex].type; tmpLog[4] = node[nodeIndex].function; tmpLog[5] = node[nodeIndex].number; pushToLog(tmpLog, 6); + // Free queue if any + if (node[nodeIndex].queue != NULL) { + umm_free(node[webNode].queue); + } // Set whole struct to 0 memset(&node[nodeIndex].address, 0, sizeof(node[0])); //0, '\0', '\0', 0, 0b00011110, 0, 0, DUMMY_NO_VALUE, "" @@ -68,7 +74,7 @@ static THD_FUNCTION(ServiceThread, arg) { //node[nodeIndex].setting = 0; //node[nodeIndex].value = 0; //node[nodeIndex].last_OK = 0; - node[nodeIndex].queue = DUMMY_NO_VALUE; + //node[nodeIndex].queue = NULL; //memset(&node[nodeIndex].name, 0, NAME_LENGTH); } } diff --git a/source/rfm69.c b/source/rfm69.c index 8c5807f..6d6451a 100644 --- a/source/rfm69.c +++ b/source/rfm69.c @@ -35,6 +35,7 @@ * OF SUCH DAMAGE. */ +#include #include #include #include @@ -200,7 +201,7 @@ static int8_t rfm69ReadRSSI(void) { * RF69_RSLT_OK - Sent. */ #define RFM69_SEND_HEADER_SIZE 5 -static int8_t rfm69SendFrame(uint16_t toAddress, const void* buffer, uint8_t bufferSize, +static int8_t rfm69SendFrame(uint16_t toAddress, const void* data, uint8_t dataSize, bool requestACK, bool sendACK, bool sendRssi) { uint8_t CTLbyte; uint16_t temp; @@ -238,7 +239,7 @@ static int8_t rfm69SendFrame(uint16_t toAddress, const void* buffer, uint8_t buf //writeReg(REG_DIOMAPPING1, RF_DIOMAPPING1_DIO0_00); // DIO0 is "Packet Sent" // Force maximum size - if (bufferSize > RF69_MAX_DATA_LEN) bufferSize = RF69_MAX_DATA_LEN; + if (dataSize > RF69_MAX_DATA_LEN) dataSize = RF69_MAX_DATA_LEN; // Force flags if (toAddress == RF69_BROADCAST_ADDR) { requestACK = false; @@ -257,21 +258,23 @@ static int8_t rfm69SendFrame(uint16_t toAddress, const void* buffer, uint8_t buf if (rfm69Config.nodeID > 0xFF) CTLbyte |= (rfm69Config.nodeID & 0x300) >> 8; //assign last 2 bits of address if > 255 txBuffer[0] = REG_FIFO | 0x80; - txBuffer[1] = bufferSize + 3; + txBuffer[1] = dataSize + 3 + ((sendACK && sendRssi)?1:0); // If sending ACK with RSSI add one to size txBuffer[2] = (uint8_t)toAddress; txBuffer[3] = (uint8_t)rfm69Config.nodeID; txBuffer[4] = CTLbyte; if ((sendACK) && (sendRssi)) { - txBuffer[txBufferSize++] = ~rfm69Data.rssi; - DBG("RFM SendFrame ATC RSSI: %d\r\n", txBuffer[txBufferSize - 1]); + txBufferSize++; + txBuffer[5] = abs(rfm69Data.rssi); + DBG("RFM SendFrame ATC RSSI: %d\r\n", txBuffer[5]); } + // Transfer header spiAcquireBus(rfm69Config.spidp); spiSelect(rfm69Config.spidp); spiSend(rfm69Config.spidp, txBufferSize, txBuffer); // Transfer data - if (bufferSize > 0) spiSend(rfm69Config.spidp, bufferSize, buffer); + if (dataSize > 0) spiSend(rfm69Config.spidp, dataSize, data); spiUnselect(rfm69Config.spidp); spiReleaseBus(rfm69Config.spidp); @@ -376,8 +379,9 @@ int8_t rfm69GetData(void) { DBG("RFM GD: F:%u, T:%u, PL:%u\r\n", rfm69Data.senderId, rfm69Data.targetId, rfm69Data.packetLength); - // Match this node's address, or broadcast address - if (!(rfm69Data.targetId == rfm69Config.nodeID || rfm69Data.targetId == RF69_BROADCAST_ADDR) || + // Not our address, or broadcast address, or length < 3 + if (!(rfm69Data.targetId == rfm69Config.nodeID || + rfm69Data.targetId == RF69_BROADCAST_ADDR) || (rfm69Data.packetLength < 3)) { spiUnselect(rfm69Config.spidp); spiReleaseBus(rfm69Config.spidp); @@ -399,13 +403,12 @@ int8_t rfm69GetData(void) { rfm69Data.ackReceived = rxBuffer[3] & RF69_CTL_SENDACK; // extract ACK-received flag rfm69Data.ackRequested = rxBuffer[3] & RF69_CTL_REQACK; // extract ACK-requested flag rfm69Data.ackRssiRequested = rxBuffer[3] & RF69_CTL_RESERVE1; // extract the ACK RSSI request flag - DBG("RFM GD: dl:%u, are:%u, arq:%u, AckRssi: %u\r\n", + DBG("RFM GD: dl:%u, aRe:%u, aRq:%u, aRssi: %u\r\n", rfm69Data.length, rfm69Data.ackReceived, rfm69Data.ackRequested, rfm69Data.ackRssiRequested); // Get data, if they are present if (rfm69Data.length > 0) { spiReceive(rfm69Config.spidp, rfm69Data.length, rfm69Data.data); - rfm69Data.data[rfm69Data.length] = 0; // Add null at end of string } spiUnselect(rfm69Config.spidp); @@ -430,7 +433,7 @@ int8_t rfm69GetData(void) { DBG("RFM GD sending ACK\r\n"); // Send the frame and return chBSemSignal(&rfm69Lock); - return rfm69SendFrame(rfm69Data.senderId, "", 0, false, true, rfm69Data.ackRssiRequested); + return rfm69SendFrame(rfm69Data.senderId, NULL, 0, false, true, rfm69Data.ackRssiRequested); } // ATC @@ -467,12 +470,12 @@ int8_t rfm69GetData(void) { * RF69_RSLT_OK - OK * RF69_RSLT_NOK - Data not acked. */ -int8_t rfm69Send(uint16_t toAddress, const void* buffer, uint8_t bufferSize, bool requestAck) { +int8_t rfm69Send(uint16_t toAddress, const void* data, uint8_t dataSize, bool requestAck) { msg_t resp; DBG("RFM Send start\r\n"); // Send the frame - resp = rfm69SendFrame(toAddress, buffer, bufferSize, requestAck, false, rfm69TargetRssi); + resp = rfm69SendFrame(toAddress, data, dataSize, requestAck, false, rfm69TargetRssi); // If BUSY or NOK then return if (resp != RF69_RSLT_OK) return resp; @@ -508,10 +511,10 @@ int8_t rfm69Send(uint16_t toAddress, const void* buffer, uint8_t bufferSize, boo * Send packet with retry * Replies usually take only 5..8ms at 50kbps@915MHz */ -int8_t rfm69SendWithRetry(uint16_t toAddress, const void* buffer, uint8_t bufferSize, uint8_t retries) { +int8_t rfm69SendWithRetry(uint16_t toAddress, const void* data, uint8_t dataSize, uint8_t retries) { for (uint8_t i = 0; i < retries; i++) { - if (rfm69Send( toAddress, buffer, bufferSize, true) == RF69_RSLT_OK) return RF69_RSLT_OK; + if (rfm69Send( toAddress, data, dataSize, true) == RF69_RSLT_OK) return RF69_RSLT_OK; } return RF69_RSLT_NOK; } diff --git a/source/rfm69.h b/source/rfm69.h index a286962..36a26d6 100644 --- a/source/rfm69.h +++ b/source/rfm69.h @@ -64,7 +64,7 @@ typedef enum { } rfm69Transceiver_t; typedef struct { - uint8_t data[RF69_MAX_DATA_LEN+1]; + uint8_t data[RF69_MAX_DATA_LEN]; uint8_t length; uint16_t senderId; uint16_t targetId; @@ -89,8 +89,8 @@ void rfm69SetPowerLevel(uint8_t powerLevel); void rfm69AutoPower(int8_t targetRssi); void rfm69SetSensBoost(bool onOff); int8_t rfm69GetData(void); -int8_t rfm69Send(uint16_t toAddress, const void* buffer, uint8_t bufferSize, bool requestAck); -int8_t rfm69SendWithRetry(uint16_t toAddress, const void* buffer, uint8_t bufferSize, uint8_t retries); +int8_t rfm69Send(uint16_t toAddress, const void* data, uint8_t dataSize, bool requestAck); +int8_t rfm69SendWithRetry(uint16_t toAddress, const void* data, uint8_t dataSize, uint8_t retries); void rfm69Sleep(void); int8_t rfm69ReadTemperature(uint8_t calFactor); void rfm69SetHighPower(bool onOff);