/* * The MySensors Arduino library handles the wireless radio link and protocol * between your home built sensors/actuators and HA controller of choice. * The sensors forms a self healing radio network with optional repeaters. Each * repeater and gateway builds a routing tables in EEPROM which keeps track of the * network topology allowing messages to be routed to nodes. * * Created by Henrik Ekblad * Copyright (C) 2013-2018 Sensnology AB * Full contributor list: https://github.com/mysensors/MySensors/graphs/contributors * * Documentation: http://www.mysensors.org * Support Forum: http://forum.mysensors.org * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * version 2 as published by the Free Software Foundation. */ #include "MyOTALogging.h" #ifdef MY_OTA_LOG_SENDER_FEATURE // global variables static bool inOTALog = false; void OTALog(uint8_t logNode, bool enableAck, const char *fmt, ... ) { // Avoid recursion if (inOTALog==true) { return; } inOTALog = true; MyMessage msg(NODE_SENSOR_ID, I_LOG_MESSAGE); char fmtBuffer[MY_SERIAL_OUTPUT_SIZE]; va_list args; // create message va_start (args, fmt ); int n = vsnprintf_P(fmtBuffer, sizeof(fmtBuffer), fmt, args); va_end (args); // Check number of chars if (n<1) { // Nothing to send inOTALog = false; return; } // Add \n to the end of string if (n>(int)(sizeof(fmtBuffer)-2)) { // String is truncated n = sizeof(fmtBuffer)-2; } // add LF if not set if (fmtBuffer[n-1]!='\n') { fmtBuffer[n++]='\n'; fmtBuffer[n++]=0; } // Configure message msg.sender = getNodeId(); msg.setDestination(logNode); mSetCommand(msg, C_INTERNAL); mSetRequestAck(msg, enableAck); // Send package for (int pos = 0; posMAX_PAYLOAD) { length = MAX_PAYLOAD; } (void)_sendRoute(msg.set((char*)&fmtBuffer[pos])); } inOTALog = false; } #endif #ifdef MY_OTA_LOG_RECEIVER_FEATURE // Global variables char OTALogfmtBuffer[MY_SERIAL_OUTPUT_SIZE]; int OTALogfmtBufferPos = 0; uint8_t OTALogBufferNode = BROADCAST_ADDRESS; uint8_t OTALogBufferSensor = 0; void OTALogPrintPrefix() { char prefix[37]; // prepend debug message to be handled correctly by controller (C_INTERNAL, I_LOG_MESSAGE) snprintf_P(prefix, sizeof(prefix), PSTR("%" PRId8 ";%" PRId8 ";%" PRId8 ";0;%" PRId8 ";%" PRIu32 " "), OTALogBufferNode, OTALogBufferSensor, C_INTERNAL, I_LOG_MESSAGE, hwMillis()); MY_SERIALDEVICE.print(prefix); } void OTALogFlushBuffer() { OTALogfmtBuffer[0] = 0; OTALogfmtBufferPos = 0; OTALogBufferNode = BROADCAST_ADDRESS; } inline void OTALogPrint(const MyMessage &message) { // Ignore log messages via broadcast if (message.destination == BROADCAST_ADDRESS) { return; } // FLush buffer, when node id changes if ((OTALogBufferNode!=BROADCAST_ADDRESS) && ((OTALogBufferNode != message.sender) || (OTALogBufferSensor != message.sensor))) { OTALogPrintPrefix(); MY_SERIALDEVICE.print(OTALogfmtBuffer); MY_SERIALDEVICE.println("..."); OTALogFlushBuffer(); } // Add data to buffer const char *str = message.getString(); strncpy(&OTALogfmtBuffer[OTALogfmtBufferPos], str, sizeof(OTALogfmtBuffer)-OTALogfmtBufferPos); OTALogfmtBufferPos += strlen(str); // Store node ID and sensor ID OTALogBufferNode = message.sender; OTALogBufferSensor = message.sensor; // Print out buffered lines ending with \n char *EOLpos; while (EOLpos = strchr(OTALogfmtBuffer,'\n'), EOLpos != NULL) { // Add end of string EOLpos[0]=0; // Print out line OTALogPrintPrefix(); MY_SERIALDEVICE.println(OTALogfmtBuffer); // Check if more content in buffer int lenAfterEOL = (size_t)&OTALogfmtBuffer[OTALogfmtBufferPos]-(size_t)EOLpos-2; if (lenAfterEOL>0) { // More lines, move string to the beginning of the buffer strcpy((char*)&OTALogfmtBuffer[0], (char*)&EOLpos[1]); // calculate OTALogfmtBufferPos OTALogfmtBufferPos -= (size_t)EOLpos-(size_t)&OTALogfmtBuffer[0]+2; // Security check if ((OTALogfmtBufferPos<=0) || (OTALogfmtBufferPos>=(int)sizeof(OTALogfmtBuffer))) { MY_SERIALDEVICE.print("Sec:"); MY_SERIALDEVICE.println(OTALogfmtBufferPos); OTALogFlushBuffer(); } } else { // End of message, prepare new one OTALogFlushBuffer(); } } } #endif