diff --git a/apps/aqhome-mqttlog/0BUILD b/apps/aqhome-mqttlog/0BUILD index 519c03f..0373131 100644 --- a/apps/aqhome-mqttlog/0BUILD +++ b/apps/aqhome-mqttlog/0BUILD @@ -37,12 +37,15 @@ - + mqtt.h + messages.h $(local/typefiles) main.c + mqtt.c + messages.c diff --git a/apps/aqhome-mqttlog/main.c b/apps/aqhome-mqttlog/main.c index bfc870e..ed7c1a3 100644 --- a/apps/aqhome-mqttlog/main.c +++ b/apps/aqhome-mqttlog/main.c @@ -11,44 +11,25 @@ #endif #include "./item.h" +#include "./mqtt.h" +#include "./messages.h" -#include -#include - -#include -#include -#include -#include "aqhome/mqtt/endpoint_mqttc.h" -#include -#include -#include -#include -#include +#include "aqhome/aqhome.h" +#include "aqhome/mqtt/msg_mqtt.h" +#include "aqhome/mqtt/msg_mqtt_publish.h" #include -#include -#include #include #include #include #include #include #include -#include -#include #ifdef HAVE_SIGNAL_H # include #endif -#ifdef HAVE_SYS_TYPES_H -# include -#endif - -#ifdef HAVE_SYS_STAT_H -# include -#endif - #include #include #include @@ -57,31 +38,27 @@ #include + +/* ------------------------------------------------------------------------------------------------ + * defines + * ------------------------------------------------------------------------------------------------ + */ + #define I18N(msg) msg #define I18S(msg) msg //#define FULL_DEBUG + +/* ------------------------------------------------------------------------------------------------ + * forward declarations + * ------------------------------------------------------------------------------------------------ + */ + static int _serve(GWEN_DB_NODE *dbArgs); -static GWEN_MSG_ENDPOINT *_createMqttEndpoint(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_DB_NODE *dbArgs); static int _readArgs(int argc, char **argv, GWEN_DB_NODE *dbArgs); static int _createPidFile(const char *pidFilename); -static ITEM_LIST *_readItems(GWEN_DB_NODE *dbArgs); - -static const ITEM *_getItemForTopic(const ITEM_LIST *itemList, const char *topic); -int _subscribe(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ENDPOINT *epTcp, const char *topicFilter); -int _mqttConnect(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ENDPOINT *epTcp); -GWEN_MSG *_awaitPacket(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ENDPOINT *epTcp, uint8_t expectedPacketType); - -void _handlePublishMsg(const char *baseFolder, const ITEM_LIST *itemList, const GWEN_MSG *msg); -void _handlePublish(const char *baseFolder, const ITEM_LIST *itemList, const char *topic, const char *value); -void _handleRawMsgForItem(const char *baseFolder, const ITEM *item, const char *value); -void _handleJsonMsgForItem(const char *baseFolder, const ITEM *item, const char *value); -void _handleJsonItemVar(const char *baseFolder, const ITEM *item, const ITEMVAR *itemVar, GWEN_JSON_ELEM *jeRoot); -void _writeValueAccordingToItem(const char *baseFolder, const ITEM *item, const ITEMVAR *itemVar, const char *value); -void _writeToFile(const char *filename, const char *txt); - #ifdef HAVE_SIGNAL_H static int _setSignalHandlers(void); @@ -90,10 +67,21 @@ static void _signalHandler(int s); static struct sigaction saINT,saTERM, saHUP, saTSTP, saCONT; #endif + + +/* ------------------------------------------------------------------------------------------------ + * static vars + * ------------------------------------------------------------------------------------------------ + */ + static int stopService=0; +/* ------------------------------------------------------------------------------------------------ + * implementations + * ------------------------------------------------------------------------------------------------ + */ int main(int argc, char **argv) { @@ -153,8 +141,7 @@ int main(int argc, char **argv) int _serve(GWEN_DB_NODE *dbArgs) { const char *pidFile; - GWEN_MSG_ENDPOINT_MGR *emgr; - GWEN_MSG_ENDPOINT *epTcp; + GWEN_MSG_ENDPOINT2 *epTcp; ITEM_LIST *itemList; int rv; int timeout; @@ -163,7 +150,7 @@ int _serve(GWEN_DB_NODE *dbArgs) startTime=time(NULL); - itemList=_readItems(dbArgs); + itemList=AqHomeMqttLog_ReadItems(dbArgs); if (itemList==NULL) { DBG_ERROR(NULL, "No items to listen to, aborting."); return GWEN_ERROR_GENERIC; @@ -186,39 +173,39 @@ int _serve(GWEN_DB_NODE *dbArgs) } } - emgr=GWEN_MsgEndpointMgr_new(); - epTcp=_createMqttEndpoint(emgr, dbArgs); + epTcp=AqHomeMqttLog_CreateMqttEndpoint(dbArgs); if (epTcp==NULL) { DBG_INFO(NULL, "here"); - GWEN_MsgEndpointMgr_free(emgr); + Item_List_free(itemList); return GWEN_ERROR_GENERIC; } - rv=_mqttConnect(emgr, epTcp); + rv=AqHomeMqttLog_MqttConnect(epTcp); if (rv<0) { DBG_INFO(NULL, "here (%d)", rv); - GWEN_MsgEndpointMgr_free(emgr); + GWEN_MsgEndpoint2_free(epTcp); + Item_List_free(itemList); return rv; } - rv=_subscribe(emgr, epTcp, "#"); + rv=AqHomeMqttLog_Subscribe(epTcp, "#"); if (rv<0) { DBG_INFO(NULL, "here (%d)", rv); - GWEN_MsgEndpointMgr_free(emgr); + GWEN_MsgEndpoint2_free(epTcp); + Item_List_free(itemList); return rv; } while(!stopService) { DBG_DEBUG(NULL, "Next loop"); - GWEN_MsgEndpointMgr_IoLoopOnce(emgr); - GWEN_MsgEndpointMgr_RunAllEndpoints(emgr); - if (GWEN_ConnectableMsgEndpoint_GetState(epTcp) +#endif + +#include "./messages.h" + +#include "aqhome/mqtt/msg_mqtt_publish.h" + +#include +#include +#include +#include +#include + + + +static const ITEM *_getItemForTopic(const ITEM_LIST *itemList, const char *topic); + +void _handlePublishMsg(const char *baseFolder, const ITEM_LIST *itemList, const GWEN_MSG *msg); +void _handlePublish(const char *baseFolder, const ITEM_LIST *itemList, const char *topic, const char *value); +void _handleRawMsgForItem(const char *baseFolder, const ITEM *item, const char *value); +void _handleJsonMsgForItem(const char *baseFolder, const ITEM *item, const char *value); +void _handleJsonItemVar(const char *baseFolder, const ITEM *item, const ITEMVAR *itemVar, GWEN_JSON_ELEM *jeRoot); +void _writeValueAccordingToItem(const char *baseFolder, const ITEM *item, const ITEMVAR *itemVar, const char *value); +void _writeToFile(const char *filename, const char *txt); + + + + +ITEM_LIST *AqHomeMqttLog_ReadItems(GWEN_DB_NODE *dbArgs) +{ + const char *itemFile; + + itemFile=GWEN_DB_GetCharValue(dbArgs, "itemfile", 0, NULL); + if (itemFile && *itemFile) { + ITEM_LIST *itemList; + GWEN_DB_NODE *dbItemList; + GWEN_DB_NODE *dbItem; + int rv; + + dbItemList=GWEN_DB_Group_new("items"); + rv=GWEN_DB_ReadFile(dbItemList, itemFile, + GWEN_DB_FLAGS_DEFAULT | + GWEN_PATH_FLAGS_CREATE_GROUP | + GWEN_DB_FLAGS_ALLOW_EMPTY_STREAM); + if (rv<0) { + DBG_ERROR(NULL, "Error reading item file \"%s\" (%d)", itemFile, rv); + GWEN_DB_Group_free(dbItemList); + return NULL; + } + itemList=Item_List_new(); + dbItem=GWEN_DB_FindFirstGroup(dbItemList, "item"); + while(dbItem) { + ITEM *item; + + item=Item_fromDb(dbItem); + Item_List_Add(item, itemList); + dbItem=GWEN_DB_FindNextGroup(dbItem, "item"); + } + GWEN_DB_Group_free(dbItemList); + + if (Item_List_GetCount(itemList)==0) { + DBG_INFO(NULL, "No items in file"); + Item_List_free(itemList); + return NULL; + } + + return itemList; + } + + return NULL; +} + + + +void AqHomeMqttLog_HandlePublishMsg(const char *baseFolder, const ITEM_LIST *itemList, const GWEN_MSG *msg) +{ + char *topic; + char *value; + + topic=AQH_PublishMqttMsg_ExtractTopic(msg); + value=AQH_PublishMqttMsg_ExtractValue(msg); + + if (topic && value) + _handlePublish(baseFolder, itemList, topic, value); + else { + DBG_ERROR(NULL, "Either topic or value missing in PUBLISH msg"); + } + free(value); + free(topic); +} + + + +void _handlePublish(const char *baseFolder, const ITEM_LIST *itemList, const char *topic, const char *value) +{ + const ITEM *item; + + item=_getItemForTopic(itemList, topic); + if (item) { + const char *t; + + DBG_INFO(NULL, "HANDLING topic \"%s\"", topic); + t=Item_GetDataType(item); + if (t && strcasecmp(t, "json")==0) + _handleJsonMsgForItem(baseFolder, item, value); + else + _handleRawMsgForItem(baseFolder, item, value); + } + else { + DBG_INFO(NULL, "ignoring topic \"%s\"", topic); + } +} + + + +void _handleJsonMsgForItem(const char *baseFolder, const ITEM *item, const char *value) +{ + GWEN_JSON_ELEM *jeRoot; + + jeRoot=GWEN_JsonElement_fromString(value); + if (jeRoot==NULL) { + DBG_INFO(NULL, "Could not parse JSON value: %s", value); + } + else { + const ITEMVAR_LIST *itemVarList; + + itemVarList=Item_GetVarList(item); + if (itemVarList) { + ITEMVAR *itemVar; + + itemVar=ItemVar_List_First(itemVarList); + while(itemVar) { + _handleJsonItemVar(baseFolder, item, itemVar, jeRoot); + itemVar=ItemVar_List_Next(itemVar); + } + } + GWEN_JsonElement_free(jeRoot); + } +} + + + +void _handleJsonItemVar(const char *baseFolder, const ITEM *item, const ITEMVAR *itemVar, GWEN_JSON_ELEM *jeRoot) +{ + const char *path; + + path=ItemVar_GetPath(itemVar); + if (path) { + GWEN_JSON_ELEM *je; + + je=GWEN_JsonElement_GetElementByPath(jeRoot, path, 0); + if (je) { + const char *s; + + s=GWEN_JsonElement_GetData(je); + if (s && *s) + _writeValueAccordingToItem(baseFolder, item, itemVar, s); + else { + DBG_ERROR(NULL, "Path \"%s\" in JSON data contains no data", path); + } + } + else { + DBG_ERROR(NULL, "Path \"%s\" not found in JSON data", path); + } + } +} + + + +void _handleRawMsgForItem(const char *baseFolder, const ITEM *item, const char *value) +{ + const ITEMVAR_LIST *itemVarList; + + itemVarList=Item_GetVarList(item); + if (itemVarList) { + ITEMVAR *itemVar; + + itemVar=ItemVar_List_First(itemVarList); + while(itemVar) { + _writeValueAccordingToItem(baseFolder, item, itemVar, value); + itemVar=ItemVar_List_Next(itemVar); + } + } +} + + + +void _writeValueAccordingToItem(const char *baseFolder, const ITEM *item, const ITEMVAR *itemVar, const char *value) +{ + const char *id; + const char *name; + + id=Item_GetId(item); + name=ItemVar_GetName(itemVar); + if (id && *id && name && *name) { + GWEN_BUFFER *fnameBuf; + + fnameBuf=GWEN_Buffer_new(0, 256, 0, 1); + GWEN_Buffer_AppendString(fnameBuf, baseFolder); + GWEN_Buffer_AppendString(fnameBuf, GWEN_DIR_SEPARATOR_S); + GWEN_Buffer_AppendArgs(fnameBuf, "%s_%s", id, name); + _writeToFile(GWEN_Buffer_GetStart(fnameBuf), value); + GWEN_Buffer_free(fnameBuf); + } + else { + DBG_ERROR(NULL, "Either id or name missing in item list file"); + } +} + + + +void _writeToFile(const char *filename, const char *txt) +{ + if (txt && *txt) { + GWEN_BUFFER *tmpNameBuf; + int rv; + + tmpNameBuf=GWEN_Buffer_new(0, 256, 0, 1); + GWEN_Buffer_AppendString(tmpNameBuf, filename); + GWEN_Buffer_AppendString(tmpNameBuf, ".tmp"); + + rv=GWEN_Directory_GetPath(GWEN_Buffer_GetStart(tmpNameBuf), GWEN_PATH_FLAGS_VARIABLE); + if (rv<0) { + DBG_INFO(AQH_LOGDOMAIN, "Error getting path for %s (%d)", GWEN_Buffer_GetStart(tmpNameBuf), rv); + } + else { + FILE *f; + + f=fopen(GWEN_Buffer_GetStart(tmpNameBuf), "w"); + if (f) { + if (1!=fwrite(txt, strlen(txt), 1, f)) { + DBG_ERROR(AQH_LOGDOMAIN, "Error writing."); + fclose(f); + } + else { + fclose(f); + rename(GWEN_Buffer_GetStart(tmpNameBuf), filename); + } + } + } + GWEN_Buffer_free(tmpNameBuf); + } +} + + + +const ITEM *_getItemForTopic(const ITEM_LIST *itemList, const char *topic) +{ + const ITEM *item; + + item=Item_List_First(itemList); + while(item) { + const char *s; + + s=Item_GetTopic(item); + if (s && GWEN_Text_ComparePattern(topic, s, 0)!=-1) + return item; + item=Item_List_Next(item); + } + + return NULL; +} + + + diff --git a/aqhome/msg/endpoint_node_p.h b/apps/aqhome-mqttlog/messages.h similarity index 58% rename from aqhome/msg/endpoint_node_p.h rename to apps/aqhome-mqttlog/messages.h index 895ad4e..a191b27 100644 --- a/aqhome/msg/endpoint_node_p.h +++ b/apps/aqhome-mqttlog/messages.h @@ -6,25 +6,20 @@ * should have received along with this file. ****************************************************************************/ -#ifndef AQH_MSGENDPOINT_NODE_P_H -#define AQH_MSGENDPOINT_NODE_P_H +#ifndef AQHOME_TOOL_MESSAGES_H +#define AQHOME_TOOL_MESSAGES_H -#include +#include "./item.h" -#include "aqhome/msg/endpoint_node.h" - -#include +#include - - -typedef struct AQH_MSG_ENDPOINT_NODE AQH_MSG_ENDPOINT_NODE; -struct AQH_MSG_ENDPOINT_NODE { - uint32_t acceptedMsgGroups; -}; - +ITEM_LIST *AqHomeMqttLog_ReadItems(GWEN_DB_NODE *dbArgs); +void AqHomeMqttLog_HandlePublishMsg(const char *baseFolder, const ITEM_LIST *itemList, const GWEN_MSG *msg); #endif + + diff --git a/apps/aqhome-mqttlog/mqtt.c b/apps/aqhome-mqttlog/mqtt.c new file mode 100644 index 0000000..fd861f4 --- /dev/null +++ b/apps/aqhome-mqttlog/mqtt.c @@ -0,0 +1,179 @@ +/**************************************************************************** + * This file is part of the project AqHome. + * AqHome (c) by 2023 Martin Preuss, all rights reserved. + * + * The license for this file can be found in the file COPYING which you + * should have received along with this file. + ****************************************************************************/ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "./mqtt.h" + +#include +#include + +#include "aqhome/mqtt/endpoint2_mqttc.h" +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + + + +/* ------------------------------------------------------------------------------------------------ + * defines + * ------------------------------------------------------------------------------------------------ + */ + +#define AQHOME_MQTTLOG_DEFAULT_CMDTIMEOUT 10000 + + + +/* ------------------------------------------------------------------------------------------------ + * forward declarations + * ------------------------------------------------------------------------------------------------ + */ + +static GWEN_MSG *_awaitPacket(GWEN_MSG_ENDPOINT2 *epTcp, uint8_t expectedPacketType, int timeoutInSeconds); + + + +/* ------------------------------------------------------------------------------------------------ + * implementations + * ------------------------------------------------------------------------------------------------ + */ + +GWEN_MSG_ENDPOINT2 *AqHomeMqttLog_CreateMqttEndpoint(GWEN_DB_NODE *dbArgs) +{ + const char *mqttAddress; + int mqttPort; + const char *mqttClientId; + const char *mqttTopicPrefix; + int mqttKeepAlive; + + mqttAddress=GWEN_DB_GetCharValue(dbArgs, "mqttAddress", 0, NULL); + mqttPort=GWEN_DB_GetIntValue(dbArgs, "mqttPort", 0, 1883); + mqttClientId=GWEN_DB_GetCharValue(dbArgs, "mqttClientId", 0, "aqhome-mqttlog"); + mqttTopicPrefix=GWEN_DB_GetCharValue(dbArgs, "mqttTopicPrefix", 0, "aqhome/sensors"); + mqttKeepAlive=GWEN_DB_GetIntValue(dbArgs, "mqttKeepAlive", 0, 600); + + if (mqttAddress && *mqttAddress && mqttPort) { + GWEN_MSG_ENDPOINT2 *epMqtt; + + DBG_INFO(AQH_LOGDOMAIN, "Connecting to %s (port %d)", mqttAddress, mqttPort); + epMqtt=AQH_MqttClientEndpoint2_new(mqttClientId, mqttAddress, mqttPort, NULL, 0); + if (epMqtt==NULL) { + DBG_ERROR(AQH_LOGDOMAIN, "Error creating endpoint TCP"); + return NULL; + } + if (mqttTopicPrefix && *mqttTopicPrefix) + AQH_MqttClientEndpoint2_SetTopicPrefix(epMqtt, mqttTopicPrefix); + AQH_MqttClientEndpoint2_SetKeepAliveTime(epMqtt, mqttKeepAlive); + + return epMqtt; + } + + return NULL; +} + + + +int AqHomeMqttLog_MqttConnect(GWEN_MSG_ENDPOINT2 *epTcp) +{ + if (GWEN_MsgEndpoint2_GetState(epTcp)==GWEN_MSG_ENDPOINT_STATE_UNCONNECTED) { + int rv; + + rv=AQH_MqttClientEndpoint2_StartConnect(epTcp); + if (rv<0) { + DBG_ERROR(NULL, "Error starting to connect (%d)", rv); + return rv; + } + } + + while(GWEN_MsgEndpoint2_GetState(epTcp)!=GWEN_MSG_ENDPOINT_STATE_CONNECTED) { + DBG_DEBUG(NULL, "Next loop"); + GWEN_MsgEndpoint2_IoLoop(epTcp, 2000); /* 2000 ms */ + } + return 0; +} + + + +int AqHomeMqttLog_Subscribe(GWEN_MSG_ENDPOINT2 *epTcp, const char *topicFilter) +{ + uint16_t pckId; + GWEN_MSG *msgOut; + GWEN_MSG *msgIn; + + DBG_INFO(NULL, "Sending SUBSCRIBE %s", topicFilter); + pckId=AQH_MqttClientEndpoint2_GetNextPacketId(epTcp); + msgOut=GWEN_SubscribeMqttMsg_new(AQH_MQTTMSG_MSGTYPE_SUBSCRIBE, pckId, topicFilter, 0); + if (msgOut==NULL) { + DBG_ERROR(NULL, "Error creating message"); + return GWEN_ERROR_INTERNAL; + } + DBG_ERROR(NULL, "Sending this message:"); + GWEN_Text_DumpString((const char*) GWEN_Msg_GetConstBuffer(msgOut), GWEN_Msg_GetBytesInBuffer(msgOut), 2); + + GWEN_MsgEndpoint2_AddSendMessage(epTcp, msgOut); + + DBG_INFO(NULL, "Waiting for response"); + msgIn=_awaitPacket(epTcp, AQH_MQTTMSG_MSGTYPE_SUBACK, AQHOME_MQTTLOG_DEFAULT_CMDTIMEOUT); + if (msgIn) { + GWEN_BUFFER *buf; + + buf=GWEN_Buffer_new(0, 256, 0, 1); + AQH_SubAckMqttMsg_DumpToBuffer(msgIn, buf, "received"); + DBG_INFO(NULL, "%s", GWEN_Buffer_GetStart(buf)); + GWEN_Buffer_free(buf); + GWEN_Msg_free(msgIn); + } + + return 0; +} + + + +GWEN_MSG *_awaitPacket(GWEN_MSG_ENDPOINT2 *epTcp, uint8_t expectedPacketType, int timeoutInSeconds) +{ + time_t startTime; + + startTime=time(NULL); + + for (;;) { + GWEN_MSG *msg; + time_t now; + + GWEN_MsgEndpoint2_IoLoop(epTcp, 2000); /* 2000 ms */ + msg=GWEN_MsgEndpoint2_TakeFirstReceivedMessage(epTcp); + if (msg) { + if ((AQH_MqttMsg_GetMsgTypeAndFlags(msg) & 0xf0)==(expectedPacketType & 0xf0)) { + return msg; + } + else { + DBG_ERROR(NULL, "Received this message:"); + GWEN_Text_DumpString((const char*) GWEN_Msg_GetConstBuffer(msg), GWEN_Msg_GetBytesInBuffer(msg), 2); + } + GWEN_Msg_free(msg); + } + now=time(NULL); + if (now-startTime>timeoutInSeconds) { + DBG_INFO(NULL, "Timeout"); + break; + } + } + + return NULL; +} + + diff --git a/aqhome/ipc/endpoint_ipc_tcpc_p.h b/apps/aqhome-mqttlog/mqtt.h similarity index 54% rename from aqhome/ipc/endpoint_ipc_tcpc_p.h rename to apps/aqhome-mqttlog/mqtt.h index 638d662..7ff84bb 100644 --- a/aqhome/ipc/endpoint_ipc_tcpc_p.h +++ b/apps/aqhome-mqttlog/mqtt.h @@ -6,23 +6,19 @@ * should have received along with this file. ****************************************************************************/ -#ifndef AQH_ENDPOINT_IPCC_TCPC_P_H -#define AQH_ENDPOINT_IPCC_TCPC_P_H +#ifndef AQHOME_TOOL_MQTT_H +#define AQHOME_TOOL_MQTT_H -#include +#include "aqhome/mqtt/endpoint2_mqttc.h" -#include - -#include "aqhome/ipc/endpoint_ipc_tcpc.h" +#include -typedef struct AQH_ENDPOINT_IPCC AQH_ENDPOINT_IPCC; -struct AQH_ENDPOINT_IPCC { - - GWEN_MSG_ENDPOINT_RUN_FN previousRunFn; -}; +GWEN_MSG_ENDPOINT2 *AqHomeMqttLog_CreateMqttEndpoint(GWEN_DB_NODE *dbArgs); +int AqHomeMqttLog_MqttConnect(GWEN_MSG_ENDPOINT2 *epTcp); +int AqHomeMqttLog_Subscribe(GWEN_MSG_ENDPOINT2 *epTcp, const char *topicFilter); @@ -30,10 +26,3 @@ struct AQH_ENDPOINT_IPCC { #endif - - - - - - - diff --git a/apps/aqhome-tool/flash.c b/apps/aqhome-tool/flash.c index 409df75..ecb557f 100644 --- a/apps/aqhome-tool/flash.c +++ b/apps/aqhome-tool/flash.c @@ -13,9 +13,9 @@ #include "./flash.h" #include "./utils.h" +#include "aqhome/ipc/endpoint2_ipc.h" #include "aqhome/ipc/msg_ipc_setaccmsggrps.h" #include "aqhome/ipc/msg_ipc_forward.h" -#include "aqhome/ipc/endpoint_ipc_tcpc.h" #include "aqhome/msg/msg_node.h" #include "aqhome/msg/msg_flashready.h" #include "aqhome/msg/msg_flashstart.h" @@ -29,7 +29,6 @@ #include #include #include -#include #include #include @@ -48,30 +47,28 @@ static int _doFlash(GWEN_DB_NODE *dbArgs); static AQH_FLASHRECORD_LIST *_readHexfileIntoFlashRecordList(const char *hexFilename); -static int _rebootNode(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ENDPOINT *epTcp, unsigned int uid, int timeoutInSeconds); -static int _performFlashProcedure(GWEN_MSG_ENDPOINT_MGR *emgr, - GWEN_MSG_ENDPOINT *epTcp, +static int _rebootNode(GWEN_MSG_ENDPOINT2 *epTcp, unsigned int uid, int timeoutInSeconds); +static int _performFlashProcedure(GWEN_MSG_ENDPOINT2 *epTcp, unsigned int uid, const AQH_FLASHRECORD_LIST *flashRecordList, int pageSize, int timeoutInSeconds); -static int _flashStart(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ENDPOINT *epTcp, unsigned int uid, int timeoutInSeconds); +static int _flashStart(GWEN_MSG_ENDPOINT2 *epTcp, unsigned int uid, int timeoutInSeconds); -static GWEN_MSG *_waitForFlashReadyMessageForUid(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ENDPOINT *epTcp, +static GWEN_MSG *_waitForFlashReadyMessageForUid(GWEN_MSG_ENDPOINT2 *epTcp, unsigned int uid, int timeoutInSeconds); -static int _sendRebootRequest(GWEN_MSG_ENDPOINT *epTcp, unsigned int uid); -static int _sendFlashStart(GWEN_MSG_ENDPOINT *epTcp, unsigned int uid); -static int _waitForFlashResponseMessage(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ENDPOINT *epTcp, int timeoutInSeconds); -static int _waitForRebootResponseMessage(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ENDPOINT *epTcp, int timeoutInSeconds); -static int _sendFlashRecord(GWEN_MSG_ENDPOINT_MGR *emgr, - GWEN_MSG_ENDPOINT *epTcp, +static int _sendRebootRequest(GWEN_MSG_ENDPOINT2 *epTcp, unsigned int uid); +static int _sendFlashStart(GWEN_MSG_ENDPOINT2 *epTcp, unsigned int uid); +static int _waitForFlashResponseMessage(GWEN_MSG_ENDPOINT2 *epTcp, int timeoutInSeconds); +static int _waitForRebootResponseMessage(GWEN_MSG_ENDPOINT2 *epTcp, int timeoutInSeconds); +static int _sendFlashRecord(GWEN_MSG_ENDPOINT2 *epTcp, const AQH_FLASHRECORD *flashRecord, uint16_t pageSize, int timeoutInSeconds); -static int _sendFlashEnd(GWEN_MSG_ENDPOINT *epTcp, int reason); +static int _sendFlashEnd(GWEN_MSG_ENDPOINT2 *epTcp, int reason); @@ -188,8 +185,7 @@ int AQH_Tool_Flash(GWEN_DB_NODE *dbGlobalArgs, int argc, char **argv) int _doFlash(GWEN_DB_NODE *dbArgs) { - GWEN_MSG_ENDPOINT_MGR *emgr; - GWEN_MSG_ENDPOINT *epTcp; + GWEN_MSG_ENDPOINT2 *epTcp; int rv; int timeoutInSeconds; int doReboot; @@ -216,28 +212,26 @@ int _doFlash(GWEN_DB_NODE *dbArgs) } /* setup client connection */ - emgr=GWEN_MsgEndpointMgr_new(); - - epTcp=Utils_SetupIpcEndpoint(emgr, dbArgs); + epTcp=Utils_SetupIpcEndpoint(dbArgs); if (epTcp==NULL) { DBG_ERROR(NULL, "ERROR creating TCP connection"); return 3; } - GWEN_MsgEndpointMgr_AddEndpoint(emgr, epTcp); /* declare accepted message type groups */ rv=Utils_SendAcceptedMsgGroups(epTcp, AQH_MSG_TYPEGROUP_FLASH); if (rv<0) { DBG_INFO(NULL, "here (%d)", rv); + GWEN_MsgEndpoint2_free(epTcp); return 3; } if (doReboot) { fprintf(stdout, "Sending REBOOT request\n"); - rv=_rebootNode(emgr, epTcp, uid, timeoutInSeconds); + rv=_rebootNode(epTcp, uid, timeoutInSeconds); if (rv<0) { DBG_INFO(NULL, "here (%d)", rv); - GWEN_MsgEndpointMgr_free(emgr); + GWEN_MsgEndpoint2_free(epTcp); return 3; } fprintf(stdout, "Reboot in progress\n"); @@ -245,10 +239,10 @@ int _doFlash(GWEN_DB_NODE *dbArgs) /* wait for FLASH_READY message */ fprintf(stdout, "Waiting for node to become ready for flashing\n"); - msg=_waitForFlashReadyMessageForUid(emgr, epTcp, uid, timeoutInSeconds); + msg=_waitForFlashReadyMessageForUid(epTcp, uid, timeoutInSeconds); if (msg==NULL) { DBG_INFO(NULL, "No FLASH_READY message received."); - GWEN_MsgEndpointMgr_free(emgr); + GWEN_MsgEndpoint2_free(epTcp); return 3; } DBG_INFO(NULL, "FLASH_READY message received"); @@ -257,18 +251,18 @@ int _doFlash(GWEN_DB_NODE *dbArgs) GWEN_Msg_free(msg); /* perform flash */ - rv=_performFlashProcedure(emgr, epTcp, uid, flashRecordList, pageSize, timeoutInSeconds); + rv=_performFlashProcedure(epTcp, uid, flashRecordList, pageSize, timeoutInSeconds); if (rv<0) { if (rv<0) { DBG_INFO(NULL, "here (%d)", rv); - GWEN_MsgEndpointMgr_free(emgr); + GWEN_MsgEndpoint2_free(epTcp); AQH_FlashRecord_List_free(flashRecordList); return 4; } } AQH_FlashRecord_List_free(flashRecordList); - GWEN_MsgEndpointMgr_free(emgr); + GWEN_MsgEndpoint2_free(epTcp); return 0; } @@ -299,7 +293,7 @@ AQH_FLASHRECORD_LIST *_readHexfileIntoFlashRecordList(const char *hexFilename) -int _rebootNode(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ENDPOINT *epTcp, unsigned int uid, int timeoutInSeconds) +int _rebootNode(GWEN_MSG_ENDPOINT2 *epTcp, unsigned int uid, int timeoutInSeconds) { int rv; @@ -311,7 +305,7 @@ int _rebootNode(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ENDPOINT *epTcp, unsigned return rv; } - rv=_waitForRebootResponseMessage(emgr, epTcp, timeoutInSeconds); + rv=_waitForRebootResponseMessage(epTcp, timeoutInSeconds); if (rv!=0) { DBG_INFO(NULL, "Bad or no reboot response received (%d).", rv); return rv; @@ -322,8 +316,7 @@ int _rebootNode(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ENDPOINT *epTcp, unsigned -int _performFlashProcedure(GWEN_MSG_ENDPOINT_MGR *emgr, - GWEN_MSG_ENDPOINT *epTcp, +int _performFlashProcedure(GWEN_MSG_ENDPOINT2 *epTcp, unsigned int uid, const AQH_FLASHRECORD_LIST *flashRecordList, int pageSize, @@ -333,7 +326,7 @@ int _performFlashProcedure(GWEN_MSG_ENDPOINT_MGR *emgr, const AQH_FLASHRECORD *flashRecord; fprintf(stdout, "Sending FLASH_START\n"); - rv=_flashStart(emgr, epTcp, uid, timeoutInSeconds); + rv=_flashStart(epTcp, uid, timeoutInSeconds); if (rv<0) { DBG_INFO(NULL, "here (%d)", rv); return rv; @@ -343,7 +336,7 @@ int _performFlashProcedure(GWEN_MSG_ENDPOINT_MGR *emgr, flashRecord=AQH_FlashRecord_List_First(flashRecordList); while(flashRecord) { DBG_ERROR(NULL, "Sending flash record at %08x", AQH_FlashRecord_GetAddress(flashRecord)); - rv=_sendFlashRecord(emgr, epTcp, flashRecord, pageSize, timeoutInSeconds); + rv=_sendFlashRecord(epTcp, flashRecord, pageSize, timeoutInSeconds); if (rv!=0) { DBG_ERROR(NULL, "Error sending flash data (%d)", rv); return rv; @@ -357,7 +350,7 @@ int _performFlashProcedure(GWEN_MSG_ENDPOINT_MGR *emgr, return rv; } - rv=Utils_FlushOutMessageQueue(emgr, epTcp, timeoutInSeconds); + rv=Utils_FlushOutMessageQueue(epTcp, timeoutInSeconds); if (rv<0) { DBG_INFO(NULL, "here (%d)", rv); return rv; @@ -368,7 +361,7 @@ int _performFlashProcedure(GWEN_MSG_ENDPOINT_MGR *emgr, -int _flashStart(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ENDPOINT *epTcp, unsigned int uid, int timeoutInSeconds) +int _flashStart(GWEN_MSG_ENDPOINT2 *epTcp, unsigned int uid, int timeoutInSeconds) { int rv; int i; @@ -385,7 +378,7 @@ int _flashStart(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ENDPOINT *epTcp, unsigned } /* wait for response */ - rv=_waitForFlashResponseMessage(emgr, epTcp, timeoutInSeconds); + rv=_waitForFlashResponseMessage(epTcp, timeoutInSeconds); if (rv!=0) { DBG_INFO(NULL, "Bad or no response received (%d).", rv); return rv; @@ -406,8 +399,7 @@ int _flashStart(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ENDPOINT *epTcp, unsigned -GWEN_MSG *_waitForFlashReadyMessageForUid(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ENDPOINT *epTcp, - unsigned int uid, int timeoutInSeconds) +GWEN_MSG *_waitForFlashReadyMessageForUid(GWEN_MSG_ENDPOINT2 *epTcp, unsigned int uid, int timeoutInSeconds) { int i; @@ -415,7 +407,7 @@ GWEN_MSG *_waitForFlashReadyMessageForUid(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ GWEN_MSG *msg; unsigned int receivedUid; - msg=Utils_WaitForSpecificNodeMessage(emgr, epTcp, AQH_MSG_TYPE_FLASH_READY, 0, timeoutInSeconds); + msg=Utils_WaitForSpecificNodeMessage(epTcp, AQH_MSG_TYPE_FLASH_READY, 0, timeoutInSeconds); if (msg==NULL) { DBG_INFO(NULL, "No FLASH_READY message received."); return NULL; @@ -436,11 +428,11 @@ GWEN_MSG *_waitForFlashReadyMessageForUid(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ -int _waitForRebootResponseMessage(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ENDPOINT *epTcp, int timeoutInSeconds) +int _waitForRebootResponseMessage(GWEN_MSG_ENDPOINT2 *epTcp, int timeoutInSeconds) { GWEN_MSG *msg; - msg=Utils_WaitForSpecificNodeMessage(emgr, epTcp, AQH_MSG_TYPE_REBOOT_RSP, 0, timeoutInSeconds); + msg=Utils_WaitForSpecificNodeMessage(epTcp, AQH_MSG_TYPE_REBOOT_RSP, 0, timeoutInSeconds); if (msg==NULL) { DBG_INFO(NULL, "No REBOOT_RSP message received."); return GWEN_ERROR_IO; @@ -451,12 +443,12 @@ int _waitForRebootResponseMessage(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ENDPOINT -int _waitForFlashResponseMessage(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ENDPOINT *epTcp, int timeoutInSeconds) +int _waitForFlashResponseMessage(GWEN_MSG_ENDPOINT2 *epTcp, int timeoutInSeconds) { GWEN_MSG *msg; int responseCode; - msg=Utils_WaitForSpecificNodeMessage(emgr, epTcp, AQH_MSG_TYPE_FLASH_RSP, 0, timeoutInSeconds); + msg=Utils_WaitForSpecificNodeMessage(epTcp, AQH_MSG_TYPE_FLASH_RSP, 0, timeoutInSeconds); if (msg==NULL) { DBG_INFO(NULL, "No FLASH_RSP message received."); return GWEN_ERROR_IO; @@ -468,7 +460,7 @@ int _waitForFlashResponseMessage(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ENDPOINT -int _sendRebootRequest(GWEN_MSG_ENDPOINT *epTcp, unsigned int uid) +int _sendRebootRequest(GWEN_MSG_ENDPOINT2 *epTcp, unsigned int uid) { GWEN_MSG *msgNode; GWEN_MSG *msgOut; @@ -480,14 +472,14 @@ int _sendRebootRequest(GWEN_MSG_ENDPOINT *epTcp, unsigned int uid) } msgOut=AQH_ForwardIpcMsg_new(AQH_MSGTYPE_IPC_FORWARD, GWEN_Msg_GetConstBuffer(msgNode), GWEN_Msg_GetBytesInBuffer(msgNode)); - GWEN_MsgEndpoint_AddSendMessage(epTcp, msgOut); + GWEN_MsgEndpoint2_AddSendMessage(epTcp, msgOut); GWEN_Msg_free(msgNode); return 0; } -int _sendFlashStart(GWEN_MSG_ENDPOINT *epTcp, unsigned int uid) +int _sendFlashStart(GWEN_MSG_ENDPOINT2 *epTcp, unsigned int uid) { GWEN_MSG *msgNode; GWEN_MSG *msgOut; @@ -499,14 +491,14 @@ int _sendFlashStart(GWEN_MSG_ENDPOINT *epTcp, unsigned int uid) } msgOut=AQH_ForwardIpcMsg_new(AQH_MSGTYPE_IPC_FORWARD, GWEN_Msg_GetConstBuffer(msgNode), GWEN_Msg_GetBytesInBuffer(msgNode)); - GWEN_MsgEndpoint_AddSendMessage(epTcp, msgOut); + GWEN_MsgEndpoint2_AddSendMessage(epTcp, msgOut); GWEN_Msg_free(msgNode); return 0; } -int _sendFlashEnd(GWEN_MSG_ENDPOINT *epTcp, int reason) +int _sendFlashEnd(GWEN_MSG_ENDPOINT2 *epTcp, int reason) { GWEN_MSG *msgNode; GWEN_MSG *msgOut; @@ -518,15 +510,14 @@ int _sendFlashEnd(GWEN_MSG_ENDPOINT *epTcp, int reason) } msgOut=AQH_ForwardIpcMsg_new(AQH_MSGTYPE_IPC_FORWARD, GWEN_Msg_GetConstBuffer(msgNode), GWEN_Msg_GetBytesInBuffer(msgNode)); - GWEN_MsgEndpoint_AddSendMessage(epTcp, msgOut); + GWEN_MsgEndpoint2_AddSendMessage(epTcp, msgOut); GWEN_Msg_free(msgNode); return 0; } -int _sendFlashRecord(GWEN_MSG_ENDPOINT_MGR *emgr, - GWEN_MSG_ENDPOINT *epTcp, +int _sendFlashRecord(GWEN_MSG_ENDPOINT2 *epTcp, const AQH_FLASHRECORD *flashRecord, uint16_t pageSize, int timeoutInSeconds) @@ -565,10 +556,10 @@ int _sendFlashRecord(GWEN_MSG_ENDPOINT_MGR *emgr, } msgOut=AQH_ForwardIpcMsg_new(AQH_MSGTYPE_IPC_FORWARD, GWEN_Msg_GetConstBuffer(msgNode), GWEN_Msg_GetBytesInBuffer(msgNode)); - GWEN_MsgEndpoint_AddSendMessage(epTcp, msgOut); + GWEN_MsgEndpoint2_AddSendMessage(epTcp, msgOut); GWEN_Msg_free(msgNode); - rv=_waitForFlashResponseMessage(emgr, epTcp, timeoutInSeconds); + rv=_waitForFlashResponseMessage(epTcp, timeoutInSeconds); if (rv==0) break; else { diff --git a/apps/aqhome-tool/getdevices.c b/apps/aqhome-tool/getdevices.c index 7d6499e..fb4ab1d 100644 --- a/apps/aqhome-tool/getdevices.c +++ b/apps/aqhome-tool/getdevices.c @@ -13,10 +13,10 @@ #include "./getdevices.h" #include "./utils.h" +#include "aqhome/ipc/endpoint2_ipc.h" #include "aqhome/ipc/msg_ipc_getdevices_req.h" #include "aqhome/ipc/msg_ipc_getdevices_rsp.h" #include "aqhome/ipc/msg_ipc_error.h" -#include "aqhome/ipc/endpoint_ipc_tcpc.h" #include "aqhome/msg/msg_node.h" #include @@ -35,7 +35,7 @@ static int _doGetDevices(GWEN_DB_NODE *dbArgs); -static int _sendGetDevices(GWEN_MSG_ENDPOINT *epTcp); +static int _sendGetDevices(GWEN_MSG_ENDPOINT2 *epTcp); @@ -119,19 +119,15 @@ int AQH_Tool_GetDevices(GWEN_DB_NODE *dbGlobalArgs, int argc, char **argv) int _doGetDevices(GWEN_DB_NODE *dbArgs) { - GWEN_MSG_ENDPOINT_MGR *emgr; - GWEN_MSG_ENDPOINT *epTcp; + GWEN_MSG_ENDPOINT2 *epTcp; int rv; int timeoutInSeconds; - emgr=GWEN_MsgEndpointMgr_new(); - - epTcp=Utils_SetupIpcEndpoint(emgr, dbArgs); + epTcp=Utils_SetupIpcEndpoint(dbArgs); if (epTcp==NULL) { DBG_ERROR(NULL, "ERROR creating TCP connection"); return 2; } - GWEN_MsgEndpointMgr_AddEndpoint(emgr, epTcp); timeoutInSeconds=GWEN_DB_GetIntValue(dbArgs, "timeout", 0, 5); @@ -151,10 +147,10 @@ int _doGetDevices(GWEN_DB_NODE *dbArgs) GWEN_MSG *msg; uint16_t code; - msg=Utils_WaitForSpecificIpcMessage(emgr, epTcp, AQH_MSGTYPE_IPC_GETDEVICES_RSP, timeoutInSeconds); + msg=Utils_WaitForSpecificIpcMessage(epTcp, AQH_MSGTYPE_IPC_GETDEVICES_RSP, timeoutInSeconds); if (msg==NULL) { DBG_INFO(NULL, "No GET_DEVICE response received."); - GWEN_MsgEndpointMgr_free(emgr); + GWEN_MsgEndpoint2_free(epTcp); return 2; } code=GWEN_IpcMsg_GetCode(msg); @@ -201,13 +197,13 @@ int _doGetDevices(GWEN_DB_NODE *dbArgs) } } - GWEN_MsgEndpointMgr_free(emgr); + GWEN_MsgEndpoint2_free(epTcp); return 0; } -int _sendGetDevices(GWEN_MSG_ENDPOINT *epTcp) +int _sendGetDevices(GWEN_MSG_ENDPOINT2 *epTcp) { GWEN_MSG *msgOut; @@ -216,7 +212,7 @@ int _sendGetDevices(GWEN_MSG_ENDPOINT *epTcp) DBG_ERROR(NULL, "Error creating message"); return GWEN_ERROR_GENERIC; } - GWEN_MsgEndpoint_AddSendMessage(epTcp, msgOut); + GWEN_MsgEndpoint2_AddSendMessage(epTcp, msgOut); return 0; } diff --git a/apps/aqhome-tool/ping.c b/apps/aqhome-tool/ping.c index e1a35da..95a4fda 100644 --- a/apps/aqhome-tool/ping.c +++ b/apps/aqhome-tool/ping.c @@ -16,7 +16,7 @@ #include "aqhome/ipc/msg_ipc_setaccmsggrps.h" #include "aqhome/ipc/msg_ipc_ping.h" #include "aqhome/ipc/msg_ipc_forward.h" -#include "aqhome/ipc/endpoint_ipc_tcpc.h" +#include "aqhome/ipc/endpoint2_ipc.h" #include "aqhome/msg/msg_node.h" #include @@ -35,7 +35,7 @@ static int _doPing(GWEN_DB_NODE *dbArgs); -static int _sendPing(GWEN_MSG_ENDPOINT *epTcp, int nodeAddr); +static int _sendPing(GWEN_MSG_ENDPOINT2 *epTcp, int nodeAddr); @@ -130,21 +130,17 @@ int AQH_Tool_Ping(GWEN_DB_NODE *dbGlobalArgs, int argc, char **argv) int _doPing(GWEN_DB_NODE *dbArgs) { - GWEN_MSG_ENDPOINT_MGR *emgr; - GWEN_MSG_ENDPOINT *epTcp; + GWEN_MSG_ENDPOINT2 *epTcp; int rv; int nodeAddr; int timeoutInSeconds; GWEN_MSG *msg; - emgr=GWEN_MsgEndpointMgr_new(); - - epTcp=Utils_SetupIpcEndpoint(emgr, dbArgs); + epTcp=Utils_SetupIpcEndpoint(dbArgs); if (epTcp==NULL) { DBG_ERROR(NULL, "ERROR creating TCP connection"); return 2; } - GWEN_MsgEndpointMgr_AddEndpoint(emgr, epTcp); nodeAddr=GWEN_DB_GetIntValue(dbArgs, "nodeAddr", 0, 0); timeoutInSeconds=GWEN_DB_GetIntValue(dbArgs, "timeout", 0, 5); @@ -163,21 +159,20 @@ int _doPing(GWEN_DB_NODE *dbArgs) return 2; } - msg=Utils_WaitForSpecificNodeMessage(emgr, epTcp, AQH_MSG_TYPE_PONG, nodeAddr, timeoutInSeconds); + msg=Utils_WaitForSpecificNodeMessage(epTcp, AQH_MSG_TYPE_PONG, nodeAddr, timeoutInSeconds); if (msg==NULL) { DBG_INFO(NULL, "No PONG response received."); - GWEN_MsgEndpointMgr_free(emgr); return 2; } fprintf(stdout, "PONG response received\n"); - GWEN_MsgEndpointMgr_free(emgr); + GWEN_MsgEndpoint2_free(epTcp); return 0; } -int _sendPing(GWEN_MSG_ENDPOINT *epTcp, int nodeAddr) +int _sendPing(GWEN_MSG_ENDPOINT2 *epTcp, int nodeAddr) { GWEN_MSG *msgOut; @@ -186,7 +181,7 @@ int _sendPing(GWEN_MSG_ENDPOINT *epTcp, int nodeAddr) DBG_ERROR(NULL, "Error creating message"); return GWEN_ERROR_GENERIC; } - GWEN_MsgEndpoint_AddSendMessage(epTcp, msgOut); + GWEN_MsgEndpoint2_AddSendMessage(epTcp, msgOut); return 0; } diff --git a/apps/aqhome-tool/utils.c b/apps/aqhome-tool/utils.c index 3fb5973..f936ed2 100644 --- a/apps/aqhome-tool/utils.c +++ b/apps/aqhome-tool/utils.c @@ -13,10 +13,11 @@ #include "./utils.h" -#include "aqhome/ipc/endpoint_ipc_tcpc.h" +#include "aqhome/ipc/endpoint2_ipc.h" #include "aqhome/ipc/msg_ipc_setaccmsggrps.h" #include "aqhome/ipc/msg_ipc_forward.h" +#include #include #include @@ -25,28 +26,35 @@ -GWEN_MSG_ENDPOINT *Utils_SetupIpcEndpoint(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_DB_NODE *dbArgs) +GWEN_MSG_ENDPOINT2 *Utils_SetupIpcEndpoint(GWEN_DB_NODE *dbArgs) { - GWEN_MSG_ENDPOINT *epTcp; + GWEN_MSG_ENDPOINT2 *epTcp; const char *tcpAddress; int tcpPort; + int rv; tcpAddress=GWEN_DB_GetCharValue(dbArgs, "tcpAddress", 0, "127.0.0.1"); tcpPort=GWEN_DB_GetIntValue(dbArgs, "tcpPort", 0, 45454); DBG_INFO(NULL, "Setup tcp client endpoint to %s:%d", tcpAddress, tcpPort); - epTcp=AQH_IpcTcpClientEndpoint_new(tcpAddress, tcpPort, "aqhome-tool-IPC", 0); + epTcp=AQH_IpcEndpoint2_CreateIpcTcpClient(tcpAddress, tcpPort, "aqhome-tool-IPC", 0); if (epTcp==NULL) { DBG_ERROR(NULL, "Error creating endpoint TCPc"); return NULL; } + rv=GWEN_TcpcEndpoint2_StartConnect(epTcp); + if (rv<0 && rv!=GWEN_ERROR_IN_PROGRESS) { + DBG_ERROR(NULL, "Error connecting (%d)", rv); + GWEN_MsgEndpoint2_free(epTcp); + return NULL; + } return epTcp; } -GWEN_MSG *Utils_WaitForSpecificNodeMessage(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ENDPOINT *epTcp, +GWEN_MSG *Utils_WaitForSpecificNodeMessage(GWEN_MSG_ENDPOINT2 *epTcp, int msgCode, int nodeAddr, int timeoutInSeconds) @@ -59,9 +67,8 @@ GWEN_MSG *Utils_WaitForSpecificNodeMessage(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG GWEN_MSG *msg; time_t now; - GWEN_MsgEndpointMgr_RunAllEndpoints(emgr); - GWEN_MsgEndpointMgr_IoLoopOnce(emgr); - msg=GWEN_MsgEndpoint_TakeFirstReceivedMessage(epTcp); + GWEN_MsgEndpoint2_IoLoop(epTcp, 2000); /* 2000 ms */ + msg=GWEN_MsgEndpoint2_TakeFirstReceivedMessage(epTcp); if (msg) { if (GWEN_IpcMsg_GetCode(msg)==AQH_MSGTYPE_IPC_FORWARD) { GWEN_MSG *nodeMsg; @@ -79,6 +86,9 @@ GWEN_MSG *Utils_WaitForSpecificNodeMessage(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG } } } + else { + DBG_INFO(NULL, "Received IPC message %d, ignoring", GWEN_IpcMsg_GetCode(msg)); + } GWEN_Msg_free(msg); } now=time(NULL); @@ -93,7 +103,7 @@ GWEN_MSG *Utils_WaitForSpecificNodeMessage(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG -GWEN_MSG *Utils_WaitForSpecificIpcMessage(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ENDPOINT *epTcp, +GWEN_MSG *Utils_WaitForSpecificIpcMessage(GWEN_MSG_ENDPOINT2 *epTcp, int msgCode, int timeoutInSeconds) { @@ -105,9 +115,8 @@ GWEN_MSG *Utils_WaitForSpecificIpcMessage(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ GWEN_MSG *msg; time_t now; - GWEN_MsgEndpointMgr_RunAllEndpoints(emgr); - GWEN_MsgEndpointMgr_IoLoopOnce(emgr); - msg=GWEN_MsgEndpoint_TakeFirstReceivedMessage(epTcp); + GWEN_MsgEndpoint2_IoLoop(epTcp, 2000); /* 2000 ms */ + msg=GWEN_MsgEndpoint2_TakeFirstReceivedMessage(epTcp); if (msg) { uint16_t code; @@ -134,17 +143,16 @@ GWEN_MSG *Utils_WaitForSpecificIpcMessage(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ -int Utils_FlushOutMessageQueue(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ENDPOINT *epTcp, int timeoutInSeconds) +int Utils_FlushOutMessageQueue(GWEN_MSG_ENDPOINT2 *epTcp, int timeoutInSeconds) { time_t startTime; startTime=time(NULL); - while(GWEN_MsgEndpoint_HaveMessageToSend(epTcp)) { + while(GWEN_MsgEndpoint2_HaveMessageToSend(epTcp)) { time_t now; - GWEN_MsgEndpointMgr_RunAllEndpoints(emgr); - GWEN_MsgEndpointMgr_IoLoopOnce(emgr); + GWEN_MsgEndpoint2_IoLoop(epTcp, 2000); /* 2000 ms */ now=time(NULL); if (now-startTime>timeoutInSeconds) { DBG_INFO(NULL, "Timeout"); @@ -157,7 +165,7 @@ int Utils_FlushOutMessageQueue(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ENDPOINT *e -int Utils_SendAcceptedMsgGroups(GWEN_MSG_ENDPOINT *epTcp, uint32_t groups) +int Utils_SendAcceptedMsgGroups(GWEN_MSG_ENDPOINT2 *epTcp, uint32_t groups) { GWEN_MSG *msgOut; @@ -166,7 +174,7 @@ int Utils_SendAcceptedMsgGroups(GWEN_MSG_ENDPOINT *epTcp, uint32_t groups) DBG_ERROR(NULL, "Error creating message"); return GWEN_ERROR_GENERIC; } - GWEN_MsgEndpoint_AddSendMessage(epTcp, msgOut); + GWEN_MsgEndpoint2_AddSendMessage(epTcp, msgOut); return 0; } diff --git a/apps/aqhome-tool/utils.h b/apps/aqhome-tool/utils.h index dcffd0c..86bc5dd 100644 --- a/apps/aqhome-tool/utils.h +++ b/apps/aqhome-tool/utils.h @@ -11,24 +11,24 @@ #include -#include +#include -GWEN_MSG_ENDPOINT *Utils_SetupIpcEndpoint(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_DB_NODE *dbArgs); +GWEN_MSG_ENDPOINT2 *Utils_SetupIpcEndpoint(GWEN_DB_NODE *dbArgs); -GWEN_MSG *Utils_WaitForSpecificNodeMessage(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ENDPOINT *epTcp, +GWEN_MSG *Utils_WaitForSpecificNodeMessage(GWEN_MSG_ENDPOINT2 *epTcp, int msgCode, int nodeAddr, int timeoutInSeconds); -GWEN_MSG *Utils_WaitForSpecificIpcMessage(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ENDPOINT *epTcp, +GWEN_MSG *Utils_WaitForSpecificIpcMessage(GWEN_MSG_ENDPOINT2 *epTcp, int msgCode, int timeoutInSeconds); -int Utils_FlushOutMessageQueue(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ENDPOINT *epTcp, int timeoutInSeconds); +int Utils_FlushOutMessageQueue(GWEN_MSG_ENDPOINT2 *epTcp, int timeoutInSeconds); -int Utils_SendAcceptedMsgGroups(GWEN_MSG_ENDPOINT *epTcp, uint32_t groups); +int Utils_SendAcceptedMsgGroups(GWEN_MSG_ENDPOINT2 *epTcp, uint32_t groups); #endif diff --git a/apps/aqhomed/0BUILD b/apps/aqhomed/0BUILD index c5fc923..63e6a6e 100644 --- a/apps/aqhomed/0BUILD +++ b/apps/aqhomed/0BUILD @@ -38,6 +38,10 @@ init.h fini.h loop.h + loop_tty.h + loop_tty_ipc.h + loop_tty_mqtt.h + loop_ipc.h db.h tty_log.h tty_write.h @@ -50,6 +54,10 @@ init.c fini.c loop.c + loop_tty.c + loop_tty_ipc.c + loop_tty_mqtt.c + loop_ipc.c db.c tty_log.c tty_write.c diff --git a/apps/aqhomed/aqhomed.c b/apps/aqhomed/aqhomed.c index 2d10c68..233a162 100644 --- a/apps/aqhomed/aqhomed.c +++ b/apps/aqhomed/aqhomed.c @@ -74,6 +74,7 @@ void AqHomed_free(AQHOMED *aqh) free(aqh->writeFolder); free(aqh->pidFile); free(aqh->dbFile); + free(aqh->mqttTopicPrefix); GWEN_FREE_OBJECT(aqh); } @@ -177,7 +178,20 @@ void AqHomed_SetDbFile(AQHOMED *aqh, const char *s) - +const char *AqHomed_GetMqttTopicPrefix(const AQHOMED *aqh) +{ + return aqh?aqh->mqttTopicPrefix:NULL; +} + + + +void AqHomed_SetMqttTopicPrefix(AQHOMED *aqh, const char *s) +{ + if (aqh) { + free(aqh->mqttTopicPrefix); + aqh->mqttTopicPrefix=s?strdup(s):NULL; + } +} diff --git a/apps/aqhomed/aqhomed.h b/apps/aqhomed/aqhomed.h index c4e48c0..cf3f65e 100644 --- a/apps/aqhomed/aqhomed.h +++ b/apps/aqhomed/aqhomed.h @@ -42,6 +42,8 @@ void AqHomed_SetPidFile(AQHOMED *aqh, const char *s); const char *AqHomed_GetDbFile(const AQHOMED *aqh); void AqHomed_SetDbFile(AQHOMED *aqh, const char *s); +const char *AqHomed_GetMqttTopicPrefix(const AQHOMED *aqh); +void AqHomed_SetMqttTopicPrefix(AQHOMED *aqh, const char *s); #endif diff --git a/apps/aqhomed/aqhomed_p.h b/apps/aqhomed/aqhomed_p.h index 60c3258..aabcdff 100644 --- a/apps/aqhomed/aqhomed_p.h +++ b/apps/aqhomed/aqhomed_p.h @@ -44,6 +44,7 @@ struct AQHOMED { char *pidFile; int nodeAddress; + char *mqttTopicPrefix; }; #endif diff --git a/apps/aqhomed/init.c b/apps/aqhomed/init.c index 7461657..5078a29 100644 --- a/apps/aqhomed/init.c +++ b/apps/aqhomed/init.c @@ -185,6 +185,7 @@ void _setupMqtt(AQHOMED *aqh, GWEN_DB_NODE *dbArgs) int rv; ep=AQH_MqttClientEndpoint2_new(mqttClientId, mqttAddress, mqttPort, NULL, AQHOME_ENDPOINTGROUP_MQTT); + AqHomed_SetMqttTopicPrefix(aqh, mqttTopicPrefix); AQH_MqttClientEndpoint2_SetTopicPrefix(ep, mqttTopicPrefix); AQH_MqttClientEndpoint2_SetKeepAliveTime(ep, mqttKeepAlive); diff --git a/aqhome/msg/endpoint_log.h b/apps/aqhomed/ipc.h similarity index 69% rename from aqhome/msg/endpoint_log.h rename to apps/aqhomed/ipc.h index 9d08b77..091934b 100644 --- a/aqhome/msg/endpoint_log.h +++ b/apps/aqhomed/ipc.h @@ -6,18 +6,18 @@ * should have received along with this file. ****************************************************************************/ -#ifndef AQH_ENDPOINT_LOG_H -#define AQH_ENDPOINT_LOG_H +#ifndef AQHOMED_LOOP_IPC_H +#define AQHOMED_LOOP_IPC_H -#include "aqhome/msg/endpoint_node.h" +#include "./aqhomed.h" -AQHOME_API GWEN_MSG_ENDPOINT *AQH_LogEndpoint_new(const char *filename, int groupId); - +void AqHomed_ForwardTtyMsgToIpcClients(AQHOMED *aqh, const GWEN_MSG *msg); #endif + diff --git a/apps/aqhomed/loop.c b/apps/aqhomed/loop.c index 430618a..800e410 100644 --- a/apps/aqhomed/loop.c +++ b/apps/aqhomed/loop.c @@ -12,6 +12,8 @@ #include "./loop.h" +#include "./loop_tty.h" +#include "./loop_ipc.h" #include "./aqhomed_p.h" #include "./tty_log.h" #include "./tty_write.h" @@ -47,11 +49,6 @@ * ------------------------------------------------------------------------------------------------ */ -static void _readTtyMessages(AQHOMED *aqh); -static void _handleTtyMsg(AQHOMED *aqh, const GWEN_MSG *msg); -static void _forwardTtyMsgToIpcClients(AQHOMED *aqh, const GWEN_MSG *msg); -static void _forwardValue2MsgToIpc(GWEN_MSG_ENDPOINT2 *ep, const GWEN_MSG *nodeMsg); -static void _forwardAnyMsgToIpc(GWEN_MSG_ENDPOINT2 *ep, const GWEN_MSG *nodeMsg); @@ -64,7 +61,8 @@ void AqHomed_Loop(AQHOMED *aqh, int timeoutInMsecs) { if (aqh) { GWEN_MsgEndpoint2_ChildrenIoLoop(aqh->rootEndpoint, timeoutInMsecs); - _readTtyMessages(aqh); + AqHomed_ReadAndHandleTtyMessages(aqh); + AqHomed_ReadAndHandleIpcMessages(aqh); if (AQH_NodeDb_IsModified(aqh->nodeDb)) { if (aqh->dbFile) { @@ -81,88 +79,3 @@ void AqHomed_Loop(AQHOMED *aqh, int timeoutInMsecs) -void _readTtyMessages(AQHOMED *aqh) -{ - GWEN_MSG *msg; - - while( (msg=GWEN_MsgEndpoint2_TakeFirstReceivedMessage(aqh->ttyEndpoint)) ) { - _handleTtyMsg(aqh, msg); - GWEN_Msg_free(msg); - } -} - - - -void _handleTtyMsg(AQHOMED *aqh, const GWEN_MSG *msg) -{ - if (aqh->logFile) - AqHomed_LogTtyMsg(aqh, msg); - if (aqh->writeFolder) - AqHomed_WriteTtyMsg(aqh, msg); - if (aqh->nodeDb) - AqHomed_NodeMsgToDb(aqh, msg); - if (aqh->ipcdEndpoint) - _forwardTtyMsgToIpcClients(aqh, msg); -} - - - -void _forwardTtyMsgToIpcClients(AQHOMED *aqh, const GWEN_MSG *msg) -{ - uint32_t msgGroup; - - msgGroup=AQH_NodeMsg_GetMsgGroup(AQH_NodeMsg_GetMsgType(msg)); - if (msgGroup) { - GWEN_MSG_ENDPOINT2 *ep; - - ep=GWEN_MsgEndpoint2_Tree2_GetFirstChild(aqh->ipcdEndpoint); - while(ep) { - if (msgGroup & AQH_IpcEndpoint2_GetAcceptedMsgGroups(ep)) { - DBG_INFO(NULL, "Endpoint accepts msg group %d", msgGroup); - switch(AQH_NodeMsg_GetMsgType(msg)) { - case AQH_MSG_TYPE_VALUE2: - _forwardValue2MsgToIpc(ep, msg); - break; - default: - _forwardAnyMsgToIpc(ep, msg); - break; - } - - } - ep=GWEN_MsgEndpoint2_Tree2_GetNext(ep); - } - } - else { - DBG_ERROR(NULL, "Message type %d not in any message group, ignoring message", AQH_NodeMsg_GetMsgType(msg)); - } -} - - - -void _forwardValue2MsgToIpc(GWEN_MSG_ENDPOINT2 *ep, const GWEN_MSG *nodeMsg) -{ - GWEN_MSG *ipcMsg; - - ipcMsg=AQH_ValueIpcMsg_new(AQH_MSGTYPE_IPC_VALUE, - AQH_Value2Msg_GetUid(nodeMsg), - AQH_Value2Msg_GetValueId(nodeMsg), - AQH_Value2Msg_GetValueType(nodeMsg), - AQH_Value2Msg_GetValueNom(nodeMsg), - AQH_Value2Msg_GetValueDenom(nodeMsg)); - GWEN_MsgEndpoint2_AddSendMessage(ep, ipcMsg); -} - - - -void _forwardAnyMsgToIpc(GWEN_MSG_ENDPOINT2 *ep, const GWEN_MSG *nodeMsg) -{ - GWEN_MSG *ipcMsg; - - ipcMsg=AQH_ForwardIpcMsg_new(AQH_MSGTYPE_IPC_FORWARD, GWEN_Msg_GetConstBuffer(nodeMsg), GWEN_Msg_GetBytesInBuffer(nodeMsg)); - GWEN_MsgEndpoint2_AddSendMessage(ep, ipcMsg); -} - - - - - diff --git a/apps/aqhomed/loop_ipc.c b/apps/aqhomed/loop_ipc.c new file mode 100644 index 0000000..10cdb71 --- /dev/null +++ b/apps/aqhomed/loop_ipc.c @@ -0,0 +1,188 @@ +/**************************************************************************** + * This file is part of the project AqHome. + * AqHome (c) by 2023 Martin Preuss, all rights reserved. + * + * The license for this file can be found in the file COPYING which you + * should have received along with this file. + ****************************************************************************/ + +#ifdef HAVE_CONFIG_H +# include +#endif + + +#include "./loop_ipc.h" +#include "./aqhomed_p.h" +#include "./tty_log.h" +#include "./tty_write.h" +#include "./db.h" + +#include "aqhome/msg/endpoint2_tty.h" +#include "aqhome/msg/msg_node.h" +#include "aqhome/msg/msg_value2.h" +#include "aqhome/msg/msg_ping.h" +#include "aqhome/ipc/endpoint2_ipc.h" +#include "aqhome/ipc/msg_ipc.h" +#include "aqhome/ipc/msg_ipc_forward.h" +#include "aqhome/ipc/msg_ipc_value.h" +#include "aqhome/ipc/msg_ipc_ping.h" +#include "aqhome/ipc/msg_ipc_setaccmsggrps.h" +#include "aqhome/ipc/msg_ipc_getdevices_rsp.h" +#include "aqhome/ipc/msg_ipc_error.h" + +#include +#include +#include +#include + + + +/* ------------------------------------------------------------------------------------------------ + * defines + * ------------------------------------------------------------------------------------------------ + */ + +#define I18N(msg) msg +#define I18S(msg) msg + + + +/* ------------------------------------------------------------------------------------------------ + * forward declarations + * ------------------------------------------------------------------------------------------------ + */ + +static void _handleIpcEndpoint(AQHOMED *aqh, GWEN_MSG_ENDPOINT2 *ep); +static void _handleIpcMsg(AQHOMED *aqh, GWEN_MSG_ENDPOINT2 *ep, const GWEN_MSG *msg); +void _handleIpcMsgPing(AQHOMED *aqh, GWEN_MSG_ENDPOINT2 *ep, const GWEN_MSG *msg); +void _handleIpcMsgSetAccMsgGrps(AQHOMED *aqh, GWEN_MSG_ENDPOINT2 *ep, const GWEN_MSG *msg); +void _handleIpcMsgForward(AQHOMED *aqh, GWEN_MSG_ENDPOINT2 *ep, const GWEN_MSG *msg); +void _handleIpcMsgGetDevicesReq(AQHOMED *aqh, GWEN_MSG_ENDPOINT2 *ep, const GWEN_MSG *msg); + + + +/* ------------------------------------------------------------------------------------------------ + * implementations + * ------------------------------------------------------------------------------------------------ + */ + + +void AqHomed_ReadAndHandleIpcMessages(AQHOMED *aqh) +{ + if (aqh->ipcdEndpoint) { + GWEN_MSG_ENDPOINT2 *ep; + + ep=GWEN_MsgEndpoint2_Tree2_GetFirstChild(aqh->ipcdEndpoint); + while(ep) { + _handleIpcEndpoint(aqh, ep); + ep=GWEN_MsgEndpoint2_Tree2_GetNext(ep); + } + } +} + + + +void _handleIpcEndpoint(AQHOMED *aqh, GWEN_MSG_ENDPOINT2 *ep) +{ + GWEN_MSG *msg; + + while( (msg=GWEN_MsgEndpoint2_TakeFirstReceivedMessage(ep)) ) { + _handleIpcMsg(aqh, ep, msg); + GWEN_Msg_free(msg); + } +} + + + +void _handleIpcMsg(AQHOMED *aqh, GWEN_MSG_ENDPOINT2 *ep, const GWEN_MSG *msg) +{ + uint16_t code; + + /* exec IPC message */ + code=GWEN_IpcMsg_GetCode(msg); + DBG_ERROR(AQH_LOGDOMAIN, "Received IPC packet"); + switch(code) { + case AQH_MSGTYPE_IPC_PING: _handleIpcMsgPing(aqh, ep, msg); break; + case AQH_MSGTYPE_IPC_SETACCMSGGRPS: _handleIpcMsgSetAccMsgGrps(aqh, ep, msg); break; + case AQH_MSGTYPE_IPC_FORWARD: _handleIpcMsgForward(aqh, ep, msg); break; + case AQH_MSGTYPE_IPC_GETDEVICES_REQ: _handleIpcMsgGetDevicesReq(aqh, ep, msg); break; + default: break; + } +} + + + +void _handleIpcMsgPing(AQHOMED *aqh, GWEN_MSG_ENDPOINT2 *ep, const GWEN_MSG *msg) +{ + if (aqh->ttyEndpoint && GWEN_MsgEndpoint2_GetState(aqh->ttyEndpoint)==GWEN_MSG_ENDPOINT_STATE_CONNECTED) { + GWEN_MSG *msgOut; + + DBG_ERROR(AQH_LOGDOMAIN, "Received IPC PING message"); + msgOut=AQH_PingMsg_new(aqh->nodeAddress, AQH_PingIpcMsg_GetDestAddr(msg), AQH_MSG_TYPE_PING); + GWEN_MsgEndpoint2_AddSendMessage(aqh->ttyEndpoint, msgOut); + } +} + + + +void _handleIpcMsgSetAccMsgGrps(AQHOMED *aqh, GWEN_MSG_ENDPOINT2 *ep, const GWEN_MSG *msg) +{ + uint32_t groups; + + DBG_ERROR(AQH_LOGDOMAIN, "Received IPC SET_ACCEPTED_MSG_GROUPS message"); + groups=AQH_SetAcceptedMsgGroupsIpcMsg_GetMsgGroups(msg); + AQH_IpcEndpoint2_SetAcceptedMsgGroups(ep, groups); + // TODO: send response? +} + + + +void _handleIpcMsgForward(AQHOMED *aqh, GWEN_MSG_ENDPOINT2 *ep, const GWEN_MSG *msg) +{ + if (aqh->ttyEndpoint && GWEN_MsgEndpoint2_GetState(aqh->ttyEndpoint)==GWEN_MSG_ENDPOINT_STATE_CONNECTED) { + GWEN_MSG *msgOut; + + DBG_ERROR(AQH_LOGDOMAIN, "Received IPC FORWARD message"); + msgOut=AQH_ForwardIpcMsg_GetCopyOfNodeMsg(msg); + if (msgOut) + GWEN_MsgEndpoint2_AddSendMessage(aqh->ttyEndpoint, msgOut); + } +} + + + +void _handleIpcMsgGetDevicesReq(AQHOMED *aqh, GWEN_MSG_ENDPOINT2 *ep, const GWEN_MSG *msg) +{ + AQH_NODE_INFO_LIST *nodeInfoList; + + DBG_ERROR(AQH_LOGDOMAIN, "Received IPC GetDevicesRequest message"); + nodeInfoList=AQH_NodeDb_GetAllNodeInfos(aqh->nodeDb); + if (nodeInfoList && AQH_NodeInfo_List_GetCount(nodeInfoList)) { + const AQH_NODE_INFO *ni; + + ni=AQH_NodeInfo_List_First(nodeInfoList); + while(ni) { + const AQH_NODE_INFO *niNext; + GWEN_MSG *msgOut; + + niNext=AQH_NodeInfo_List_Next(ni); + DBG_INFO(AQH_LOGDOMAIN, "Sending response for node %02x (%08x)", AQH_NodeInfo_GetBusAddress(ni), AQH_NodeInfo_GetUid(ni)); + msgOut=AQH_GetDevicesResponseIpcMsg_new(AQH_MSGTYPE_IPC_GETDEVICES_RSP, niNext?0:AQH_MSGIPC_GETDEVICES_RSP_FLAGS_LAST, ni); + GWEN_MsgEndpoint2_AddSendMessage(ep, msgOut); + ni=niNext; + } + } + else { + GWEN_MSG *msgOut; + + DBG_INFO(AQH_LOGDOMAIN, "No nodes"); + msgOut=AQH_ErrorIpcMsg_new(AQH_MSGTYPE_IPC_ERROR, AQH_MSG_IPC_ERROR_NODATA); + GWEN_MsgEndpoint2_AddSendMessage(ep, msgOut); + } +} + + + + + + diff --git a/aqhome/msg/endpoint_write.h b/apps/aqhomed/loop_ipc.h similarity index 68% rename from aqhome/msg/endpoint_write.h rename to apps/aqhomed/loop_ipc.h index 26288d0..fab747e 100644 --- a/aqhome/msg/endpoint_write.h +++ b/apps/aqhomed/loop_ipc.h @@ -6,18 +6,18 @@ * should have received along with this file. ****************************************************************************/ -#ifndef AQH_ENDPOINT_WRITE_H -#define AQH_ENDPOINT_WRITE_H +#ifndef AQHOMED_LOOP_IPC_H +#define AQHOMED_LOOP_IPC_H -#include "aqhome/msg/endpoint_node.h" +#include "./aqhomed.h" -AQHOME_API GWEN_MSG_ENDPOINT *AQH_WriteEndpoint_new(const char *folder, int groupId); - +void AqHomed_ReadAndHandleIpcMessages(AQHOMED *aqh); #endif + diff --git a/apps/aqhomed/loop_tty.c b/apps/aqhomed/loop_tty.c new file mode 100644 index 0000000..507e66f --- /dev/null +++ b/apps/aqhomed/loop_tty.c @@ -0,0 +1,89 @@ +/**************************************************************************** + * This file is part of the project AqHome. + * AqHome (c) by 2023 Martin Preuss, all rights reserved. + * + * The license for this file can be found in the file COPYING which you + * should have received along with this file. + ****************************************************************************/ + +#ifdef HAVE_CONFIG_H +# include +#endif + + +#include "./loop_tty.h" +#include "./loop_tty_ipc.h" +#include "./loop_tty_mqtt.h" +#include "./aqhomed_p.h" +#include "./tty_log.h" +#include "./tty_write.h" +#include "./db.h" + +#include "aqhome/msg/endpoint2_tty.h" +#include "aqhome/msg/msg_node.h" +#include "aqhome/msg/msg_value2.h" +#include "aqhome/ipc/endpoint2_ipc.h" +#include "aqhome/ipc/msg_ipc_forward.h" +#include "aqhome/ipc/msg_ipc_value.h" +#include "aqhome/mqtt/endpoint2_mqttc.h" + +#include +#include +#include +#include + + + +/* ------------------------------------------------------------------------------------------------ + * defines + * ------------------------------------------------------------------------------------------------ + */ + +#define I18N(msg) msg +#define I18S(msg) msg + + + +/* ------------------------------------------------------------------------------------------------ + * forward declarations + * ------------------------------------------------------------------------------------------------ + */ + +static void _handleTtyMsg(AQHOMED *aqh, const GWEN_MSG *msg); + + + +/* ------------------------------------------------------------------------------------------------ + * implementations + * ------------------------------------------------------------------------------------------------ + */ + + +void AqHomed_ReadAndHandleTtyMessages(AQHOMED *aqh) +{ + GWEN_MSG *msg; + + while( (msg=GWEN_MsgEndpoint2_TakeFirstReceivedMessage(aqh->ttyEndpoint)) ) { + _handleTtyMsg(aqh, msg); + GWEN_Msg_free(msg); + } +} + + + +void _handleTtyMsg(AQHOMED *aqh, const GWEN_MSG *msg) +{ + if (aqh->logFile) + AqHomed_LogTtyMsg(aqh, msg); + if (aqh->writeFolder) + AqHomed_WriteTtyMsg(aqh, msg); + if (aqh->nodeDb) + AqHomed_NodeMsgToDb(aqh, msg); + if (aqh->ipcdEndpoint) + AqHomed_ForwardTtyMsgToIpcClients(aqh, msg); + if (aqh->mqttEndpoint) + AqHomed_ForwardTtyMsgToMqttServer(aqh, msg); +} + + + diff --git a/aqhome/msg/endpointmgr_p.h b/apps/aqhomed/loop_tty.h similarity index 62% rename from aqhome/msg/endpointmgr_p.h rename to apps/aqhomed/loop_tty.h index b2261f1..f5aac57 100644 --- a/aqhome/msg/endpointmgr_p.h +++ b/apps/aqhomed/loop_tty.h @@ -6,24 +6,18 @@ * should have received along with this file. ****************************************************************************/ -#ifndef AQH_MSG_ENDPOINT_MGR_P_H -#define AQH_MSG_ENDPOINT_MGR_P_H +#ifndef AQHOMED_LOOP_TTY_H +#define AQHOMED_LOOP_TTY_H -#include - -#include "aqhome/msg/endpointmgr.h" +#include "./aqhomed.h" - - -typedef struct AQH_MSG_ENDPOINT_MGR AQH_MSG_ENDPOINT_MGR; -struct AQH_MSG_ENDPOINT_MGR { - uint8_t busAddr; -}; - +void AqHomed_ReadAndHandleTtyMessages(AQHOMED *aqh); #endif + + diff --git a/apps/aqhomed/loop_tty_ipc.c b/apps/aqhomed/loop_tty_ipc.c new file mode 100644 index 0000000..4e440c3 --- /dev/null +++ b/apps/aqhomed/loop_tty_ipc.c @@ -0,0 +1,118 @@ +/**************************************************************************** + * This file is part of the project AqHome. + * AqHome (c) by 2023 Martin Preuss, all rights reserved. + * + * The license for this file can be found in the file COPYING which you + * should have received along with this file. + ****************************************************************************/ + +#ifdef HAVE_CONFIG_H +# include +#endif + + +#include "./loop_tty_ipc.h" +#include "./aqhomed_p.h" +#include "./tty_log.h" +#include "./tty_write.h" +#include "./db.h" + +#include "aqhome/msg/endpoint2_tty.h" +#include "aqhome/msg/msg_node.h" +#include "aqhome/msg/msg_value2.h" +#include "aqhome/ipc/endpoint2_ipc.h" +#include "aqhome/ipc/msg_ipc_forward.h" +#include "aqhome/ipc/msg_ipc_value.h" +#include "aqhome/mqtt/endpoint2_mqttc.h" + +#include +#include +#include +#include + + + +/* ------------------------------------------------------------------------------------------------ + * defines + * ------------------------------------------------------------------------------------------------ + */ + +#define I18N(msg) msg +#define I18S(msg) msg + + + +/* ------------------------------------------------------------------------------------------------ + * forward declarations + * ------------------------------------------------------------------------------------------------ + */ + +static void _forwardValue2MsgToIpc(GWEN_MSG_ENDPOINT2 *ep, const GWEN_MSG *nodeMsg); +static void _forwardAnyMsgToIpc(GWEN_MSG_ENDPOINT2 *ep, const GWEN_MSG *nodeMsg); + + + +/* ------------------------------------------------------------------------------------------------ + * implementations + * ------------------------------------------------------------------------------------------------ + */ + +void AqHomed_ForwardTtyMsgToIpcClients(AQHOMED *aqh, const GWEN_MSG *msg) +{ + uint32_t msgGroup; + + msgGroup=AQH_NodeMsg_GetMsgGroup(AQH_NodeMsg_GetMsgType(msg)); + if (msgGroup) { + GWEN_MSG_ENDPOINT2 *ep; + + ep=GWEN_MsgEndpoint2_Tree2_GetFirstChild(aqh->ipcdEndpoint); + while(ep) { + if (msgGroup & AQH_IpcEndpoint2_GetAcceptedMsgGroups(ep)) { + DBG_INFO(NULL, "Endpoint accepts msg group %d", msgGroup); + switch(AQH_NodeMsg_GetMsgType(msg)) { + case AQH_MSG_TYPE_VALUE2: + _forwardValue2MsgToIpc(ep, msg); + break; + default: + _forwardAnyMsgToIpc(ep, msg); + break; + } + + } + ep=GWEN_MsgEndpoint2_Tree2_GetNext(ep); + } + } + else { + DBG_ERROR(NULL, "Message type %d not in any message group, ignoring message", AQH_NodeMsg_GetMsgType(msg)); + } +} + + + +void _forwardValue2MsgToIpc(GWEN_MSG_ENDPOINT2 *ep, const GWEN_MSG *nodeMsg) +{ + GWEN_MSG *ipcMsg; + + ipcMsg=AQH_ValueIpcMsg_new(AQH_MSGTYPE_IPC_VALUE, + AQH_Value2Msg_GetUid(nodeMsg), + AQH_Value2Msg_GetValueId(nodeMsg), + AQH_Value2Msg_GetValueType(nodeMsg), + AQH_Value2Msg_GetValueNom(nodeMsg), + AQH_Value2Msg_GetValueDenom(nodeMsg)); + GWEN_MsgEndpoint2_AddSendMessage(ep, ipcMsg); +} + + + +void _forwardAnyMsgToIpc(GWEN_MSG_ENDPOINT2 *ep, const GWEN_MSG *nodeMsg) +{ + GWEN_MSG *ipcMsg; + + ipcMsg=AQH_ForwardIpcMsg_new(AQH_MSGTYPE_IPC_FORWARD, GWEN_Msg_GetConstBuffer(nodeMsg), GWEN_Msg_GetBytesInBuffer(nodeMsg)); + GWEN_MsgEndpoint2_AddSendMessage(ep, ipcMsg); +} + + + + + diff --git a/apps/aqhomed/loop_tty_ipc.h b/apps/aqhomed/loop_tty_ipc.h new file mode 100644 index 0000000..39e4c0e --- /dev/null +++ b/apps/aqhomed/loop_tty_ipc.h @@ -0,0 +1,23 @@ +/**************************************************************************** + * This file is part of the project AqHome. + * AqHome (c) by 2023 Martin Preuss, all rights reserved. + * + * The license for this file can be found in the file COPYING which you + * should have received along with this file. + ****************************************************************************/ + +#ifndef AQHOMED_LOOP_TTY_IPC_H +#define AQHOMED_LOOP_TTY_IPC_H + + +#include "./aqhomed.h" + + + +void AqHomed_ForwardTtyMsgToIpcClients(AQHOMED *aqh, const GWEN_MSG *msg); + + + +#endif + + diff --git a/apps/aqhomed/loop_tty_mqtt.c b/apps/aqhomed/loop_tty_mqtt.c new file mode 100644 index 0000000..865799b --- /dev/null +++ b/apps/aqhomed/loop_tty_mqtt.c @@ -0,0 +1,215 @@ +/**************************************************************************** + * This file is part of the project AqHome. + * AqHome (c) by 2023 Martin Preuss, all rights reserved. + * + * The license for this file can be found in the file COPYING which you + * should have received along with this file. + ****************************************************************************/ + +#ifdef HAVE_CONFIG_H +# include +#endif + + +#include "./loop_tty_mqtt.h" +#include "./aqhomed_p.h" +#include "./tty_log.h" +#include "./tty_write.h" +#include "./db.h" + +#include "aqhome/msg/endpoint2_tty.h" +#include "aqhome/msg/msg_node.h" +#include "aqhome/msg/msg_value2.h" +#include "aqhome/msg/msg_sendstats.h" +#include "aqhome/msg/msg_recvstats.h" +#include "aqhome/ipc/endpoint2_ipc.h" +#include "aqhome/ipc/msg_ipc_forward.h" +#include "aqhome/ipc/msg_ipc_value.h" +#include "aqhome/mqtt/endpoint2_mqttc.h" +#include "aqhome/mqtt/msg_mqtt_publish.h" + +#include +#include +#include +#include + + + +/* ------------------------------------------------------------------------------------------------ + * defines + * ------------------------------------------------------------------------------------------------ + */ + +#define I18N(msg) msg +#define I18S(msg) msg + + + +/* ------------------------------------------------------------------------------------------------ + * forward declarations + * ------------------------------------------------------------------------------------------------ + */ + +static void _processValue2Message(AQHOMED *aqh, const GWEN_MSG *nodeMsg); +static void _processSendStatsMessage(AQHOMED *aqh, const GWEN_MSG *nodeMsg); +static void _processRecvStatsMessage(AQHOMED *aqh, const GWEN_MSG *nodeMsg); +static void _publishDouble(AQHOMED *aqh, uint32_t uid, int valueId, const char *valuePath, double v); +static void _publishInt(AQHOMED *aqh, uint32_t uid, int valueId, const char *valuePath, int v); +static void _publishString(AQHOMED *aqh, uint32_t uid, int valueId, const char *valuePath, const char *v); + + + + +/* ------------------------------------------------------------------------------------------------ + * implementations + * ------------------------------------------------------------------------------------------------ + */ + + + +void AqHomed_ForwardTtyMsgToMqttServer(AQHOMED *aqh, const GWEN_MSG *nodeMsg) +{ + if (GWEN_MsgEndpoint2_GetState(aqh->mqttEndpoint)==GWEN_MSG_ENDPOINT_STATE_CONNECTED) { + DBG_DEBUG(AQH_LOGDOMAIN, "Processing output message"); + switch(AQH_NodeMsg_GetMsgType(nodeMsg)) { + case AQH_MSG_TYPE_VALUE2: + _processValue2Message(aqh, nodeMsg); + break; + case AQH_MSG_TYPE_COMSENDSTATS: + _processSendStatsMessage(aqh, nodeMsg); + break; + case AQH_MSG_TYPE_COMRECVSTATS: + _processRecvStatsMessage(aqh, nodeMsg); + break; + default: + break; + } + } +} + + + +void _processValue2Message(AQHOMED *aqh, const GWEN_MSG *nodeMsg) +{ + if (AQH_Value2Msg_GetValueType(nodeMsg)==AQH_MSG_VALUE2_TYPE_DOOR) + _publishString(aqh, + AQH_Value2Msg_GetUid(nodeMsg), + AQH_Value2Msg_GetValueId(nodeMsg), + AQH_Value2Msg_GetValueTypeName(nodeMsg), + AQH_Value2Msg_GetValueAsWindowStateString(nodeMsg)); + else + _publishDouble(aqh, + AQH_Value2Msg_GetUid(nodeMsg), + AQH_Value2Msg_GetValueId(nodeMsg), + AQH_Value2Msg_GetValueTypeName(nodeMsg), + AQH_Value2Msg_GetValue(nodeMsg)); +} + + + +void _processSendStatsMessage(AQHOMED *aqh, const GWEN_MSG *nodeMsg) +{ + uint16_t packetsOutInt; + + packetsOutInt=AQH_SendStatsMsg_GetPacketsOut(nodeMsg); + if (packetsOutInt) { + double packetsOut; + double collisions; + double busy; + double collisionsPercentage=0.0; + double busyPercentage=0.0; + + packetsOut=(double) packetsOutInt; + collisions=(double)AQH_SendStatsMsg_GetCollisions(nodeMsg); + busy=(double)AQH_SendStatsMsg_GetBusyErrors(nodeMsg); + + collisionsPercentage=collisions*100.0/packetsOut; + busyPercentage=busy*100.0/packetsOut; + + _publishInt(aqh, AQH_SendStatsMsg_GetUid(nodeMsg), 0, "net/packetsOut", packetsOutInt); + _publishInt(aqh, AQH_SendStatsMsg_GetUid(nodeMsg), 0, "net/collisions", (int) AQH_SendStatsMsg_GetCollisions(nodeMsg)); + _publishDouble(aqh, AQH_SendStatsMsg_GetUid(nodeMsg), 0, "net/collisionsPercent", collisionsPercentage); + _publishDouble(aqh, AQH_SendStatsMsg_GetUid(nodeMsg), 0, "net/busyPercent", busyPercentage); + } +} + + + +void _processRecvStatsMessage(AQHOMED *aqh, const GWEN_MSG *nodeMsg) +{ + uint16_t packetsInInt; + + packetsInInt=AQH_RecvStatsMsg_GetPacketsIn(nodeMsg); + if (packetsInInt) { + double packetsIn; + double crcErrors; + double ioErrors; + double crcErrorsPercentage=0.0; + double ioErrorsPercentage=0.0; + + packetsIn=(double) packetsInInt; + crcErrors=(double)AQH_RecvStatsMsg_GetCrcErrors(nodeMsg); + ioErrors=(double)AQH_RecvStatsMsg_GetIoErrors(nodeMsg); + + crcErrorsPercentage=crcErrors*100.0/packetsIn; + ioErrorsPercentage=ioErrors*100.0/packetsIn; + + _publishInt(aqh, AQH_RecvStatsMsg_GetUid(nodeMsg), 0, "net/packetsIn", packetsInInt); + _publishInt(aqh, AQH_RecvStatsMsg_GetUid(nodeMsg), 0, "net/crcerrors", (int) AQH_RecvStatsMsg_GetCrcErrors(nodeMsg)); + _publishInt(aqh, AQH_RecvStatsMsg_GetUid(nodeMsg), 0, "net/ioerrors", (int) AQH_RecvStatsMsg_GetIoErrors(nodeMsg)); + _publishDouble(aqh, AQH_RecvStatsMsg_GetUid(nodeMsg), 0, "net/crcerrorsPercent", crcErrorsPercentage); + _publishDouble(aqh, AQH_RecvStatsMsg_GetUid(nodeMsg), 0, "net/ioerrorsPercent", ioErrorsPercentage); + } +} + + + +void _publishDouble(AQHOMED *aqh, uint32_t uid, int valueId, const char *valuePath, double v) +{ + char numBuf[16]; + + snprintf(numBuf, sizeof(numBuf)-1, "%f", v); + numBuf[sizeof(numBuf)-1]=0; + _publishString(aqh, uid, valueId, valuePath, numBuf); +} + + + +void _publishInt(AQHOMED *aqh, uint32_t uid, int valueId, const char *valuePath, int v) +{ + char numBuf[16]; + + snprintf(numBuf, sizeof(numBuf)-1, "%d", v); + numBuf[sizeof(numBuf)-1]=0; + _publishString(aqh, uid, valueId, valuePath, numBuf); +} + + + +void _publishString(AQHOMED *aqh, uint32_t uid, int valueId, const char *valuePath, const char *v) +{ + GWEN_BUFFER *bufTopic; + GWEN_MSG *pubMsg; + + bufTopic=GWEN_Buffer_new(0, 64, 0, 1); + if (valueId>0) + GWEN_Buffer_AppendArgs(bufTopic, "%s/%08x/%d/%s", + aqh->mqttTopicPrefix, + uid, + valueId, + valuePath); + else + GWEN_Buffer_AppendArgs(bufTopic, "%s/%08x/%s", + aqh->mqttTopicPrefix, + uid, + valuePath); + + pubMsg=AQH_PublishMqttMsg_new(0, 0, GWEN_Buffer_GetStart(bufTopic), (const uint8_t*) v, strlen(v)); + if (pubMsg) { + DBG_INFO(AQH_LOGDOMAIN, "MQTT PUBLISH %s: %s", GWEN_Buffer_GetStart(bufTopic), v); + GWEN_MsgEndpoint2_AddSendMessage(aqh->mqttEndpoint, pubMsg); + } + GWEN_Buffer_free(bufTopic); +} + + diff --git a/apps/aqhomed/loop_tty_mqtt.h b/apps/aqhomed/loop_tty_mqtt.h new file mode 100644 index 0000000..ab62bd2 --- /dev/null +++ b/apps/aqhomed/loop_tty_mqtt.h @@ -0,0 +1,23 @@ +/**************************************************************************** + * This file is part of the project AqHome. + * AqHome (c) by 2023 Martin Preuss, all rights reserved. + * + * The license for this file can be found in the file COPYING which you + * should have received along with this file. + ****************************************************************************/ + +#ifndef AQHOMED_LOOP_TTY_MQTT_H +#define AQHOMED_LOOP_TTY_MQTT_H + + +#include "./aqhomed.h" + + + +void AqHomed_ForwardTtyMsgToMqttServer(AQHOMED *aqh, const GWEN_MSG *msg); + + + +#endif + + diff --git a/aqhome-mqttlog.sh b/aqhome-mqttlog.sh new file mode 100755 index 0000000..0786e6b --- /dev/null +++ b/aqhome-mqttlog.sh @@ -0,0 +1,2 @@ + +AQHOME_LOGLEVEL=info LD_LIBRARY_PATH="../../aqhome/:$LD_LIBRARY_PATH" ./aqhome-mqttlog -ma 192.168.117.192 -mp 1883 -t 127.0.0.1 -W /tmp/aqhome diff --git a/aqhome-tool.sh b/aqhome-tool.sh index 5a803a0..815dfb3 100755 --- a/aqhome-tool.sh +++ b/aqhome-tool.sh @@ -1,2 +1,8 @@ +#!/bin/bash + +export AQHOME_LOGLEVEL=info +export LD_LIBRARY_PATH="0-build/aqhome/:$LD_LIBRARY_PATH" + +# 0-build/apps/aqhome-tool/aqhome-tool ping -n 2 -T 5 +0-build/apps/aqhome-tool/aqhome-tool $* -AQHOME_LOGLEVEL=info LD_LIBRARY_PATH="../../aqhome/:$LD_LIBRARY_PATH" ./aqhome-tool ping -n 2 -T 5 diff --git a/aqhome/0BUILD b/aqhome/0BUILD index ae9f7c8..a2eb2d2 100644 --- a/aqhome/0BUILD +++ b/aqhome/0BUILD @@ -46,19 +46,16 @@ api.h aqhome.h - msgmanager.h - msgmanager_p.h $(local/typefiles) aqhome.c - msgmanager.c @@ -66,6 +63,7 @@ ipc nodes mqtt + http hexfile @@ -75,6 +73,7 @@ aqhipc aqhnodes aqhmqtt + aqhhttp aqhhexfile diff --git a/aqhome/http/0BUILD b/aqhome/http/0BUILD new file mode 100644 index 0000000..a12c16e --- /dev/null +++ b/aqhome/http/0BUILD @@ -0,0 +1,76 @@ + + + + + + + + $(gwenhywfar_cflags) + -I$(topsrcdir) + -I$(topbuilddir) + + + + --include=$(builddir) + --include=$(srcdir) + + + + + + $(visibility_cflags) + + + + --api=AQHOME_API + + + + + + + + + + + + + + + + + + $(local/built_headers_pub) + + + + + endpoint_http.h + + + + + endpoint_http_p.h + + + + + $(local/typefiles) + + endpoint_http.c + + + + + + + + + + + + + + + + diff --git a/aqhome/http/endpoint_http.c b/aqhome/http/endpoint_http.c new file mode 100644 index 0000000..de94970 --- /dev/null +++ b/aqhome/http/endpoint_http.c @@ -0,0 +1,302 @@ +#if 0 + +/**************************************************************************** + * This file is part of the project AqHome. + * AqHome (c) by 2023 Martin Preuss, all rights reserved. + * + * The license for this file can be found in the file COPYING which you + * should have received along with this file. + ****************************************************************************/ + +#ifdef HAVE_CONFIG_H +# include +#endif + + +#include "aqhome/http/endpoint_http_p.h" + + +#include +#include + +#include +#include +#include + + + +#define AQH_ENDPOINT_HTTP_NAME "http" +#define AQH_ENDPOINT_HTTP_BUFFERSIZE 1024 + +#define AQH_ENDPOINT_HTTP_BOOKMARK_HEADER 0 +#define AQH_ENDPOINT_HTTP_BOOKMARK_BODY 1 + + + +GWEN_INHERIT(GWEN_MSG_ENDPOINT, AQH_ENDPOINT_HTTP) + + + +static void GWENHYWFAR_CB _freeData(void *bp, void *p); +static int _handleReadable(GWEN_MSG_ENDPOINT *ep, GWEN_UNUSED GWEN_MSG_ENDPOINT_MGR *emgr); +static int _readCommand(GWEN_MSG_ENDPOINT *ep, const uint8_t **pPtr, int *pLen); +static int _readHeader(GWEN_MSG_ENDPOINT *ep, const uint8_t **pPtr, int *pLen); +static int _readBody(GWEN_MSG_ENDPOINT *ep, const uint8_t **pPtr, int *pLen); +static int _readLineCheckEmpty(GWEN_MSG_ENDPOINT *ep, const uint8_t **pPtr, int *pLen); +static int _calcCurrentLineLength(const GWEN_MSG_ENDPOINT *ep); +static int _parseCommandLineCheckIfHeaderNeeded(char *buffer, GWEN_DB_NODE *dbCurrentReadCommand); + + + + +GWEN_MSG_ENDPOINT *AQH_HttpEndpoint_new(const char *host, int port, const char *name, int groupId) +{ + GWEN_MSG_ENDPOINT *ep; + AQH_ENDPOINT_HTTP *xep; + + ep=GWEN_TcpcEndpoint_new(host, port, name?name:AQH_ENDPOINT_HTTP_NAME, groupId); + if (ep==NULL) { + DBG_INFO(AQH_LOGDOMAIN, "here"); + return NULL; + } + + GWEN_NEW_OBJECT(AQH_ENDPOINT_HTTP, xep); + GWEN_INHERIT_SETDATA(GWEN_MSG_ENDPOINT, AQH_ENDPOINT_HTTP, ep, xep, _freeData); + + xep->currentReadBuffer=GWEN_Buffer_new(0, 256, 0, 1); + xep->currentReadHeader=GWEN_DB_Group_new("header"); + xep->currentReadCommand=GWEN_DB_Group_new("cmd"); + + GWEN_MsgEndpoint_SetDefaultBufferSize(ep, AQH_ENDPOINT_HTTP_BUFFERSIZE); +// GWEN_MsgEndpoint_SetIsMsgCompleteFn(ep, _isMsgComplete); + GWEN_MsgEndpoint_SetHandleReadableFn(ep, _handleReadable); + + return ep; +} + + + +void _freeData(void *bp, void *p) +{ + AQH_ENDPOINT_HTTP *xep; + + xep=(AQH_ENDPOINT_HTTP*) p; + + GWEN_DB_Group_free(xep->currentReadHeader); + GWEN_DB_Group_free(xep->currentReadCommand); + GWEN_Buffer_free(xep->currentReadBuffer); + + + GWEN_FREE_OBJECT(xep); +} + + + +int _handleReadable(GWEN_MSG_ENDPOINT *ep, GWEN_UNUSED GWEN_MSG_ENDPOINT_MGR *emgr) +{ + AQH_ENDPOINT_HTTP *xep; + int rv; + uint8_t buffer[AQH_ENDPOINT_HTTP_BUFFERSIZE]; + const uint8_t *ptr; + int len; + + DBG_DEBUG(GWEN_LOGDOMAIN, "Reading from endpoint %s", GWEN_MsgEndpoint_GetName(ep)); + xep=GWEN_INHERIT_GETDATA(GWEN_MSG_ENDPOINT, AQH_ENDPOINT_HTTP, ep); + do { + rv=read(GWEN_MsgEndpoint_GetFd(ep), buffer, sizeof(buffer)); + } while( (rv<0) && errno==EINTR); + if (rv<0) { + if (errno==EAGAIN || errno==EWOULDBLOCK) + return GWEN_ERROR_TRY_AGAIN; + DBG_INFO(GWEN_LOGDOMAIN, "Error on read(): %s (%d)", strerror(errno), errno); + return GWEN_ERROR_IO; + } + else if (rv==0) { + DBG_INFO(GWEN_LOGDOMAIN, "EOF met on read()"); + return GWEN_ERROR_IO; + } + len=rv; + ptr=buffer; + + /* len=number of bytes read into buffer */ + while(len) { + switch(xep->readMode) { + case AQH_EndpointHttpd_ReadMode_Command: + rv=_readCommand(ep, &ptr, &len); + break; + case AQH_EndpointHttpd_ReadMode_Headers: + rv=_readHeader(ep, &ptr, &len); + break; + case AQH_EndpointHttpd_ReadMode_Body: + rv=_readBody(ep, &ptr, &len); + break; + default: + DBG_ERROR(AQH_LOGDOMAIN, "Unexpected read mode %d", xep->readMode); + return GWEN_ERROR_INTERNAL; + } + } + + return 0; +} + + + +/* rv: 1 if packet complete, <0 on error, 0 if packet not complete */ +int _readCommand(GWEN_MSG_ENDPOINT *ep, const uint8_t **pPtr, int *pLen) +{ + AQH_ENDPOINT_HTTP *xep; + int rv; + + xep=GWEN_INHERIT_GETDATA(GWEN_MSG_ENDPOINT, AQH_ENDPOINT_HTTP, ep); + rv=_readLineCheckEmpty(ep, pPtr, pLen); + if (rv>=0) { + if (rv==1) { + DBG_ERROR(AQH_LOGDOMAIN, "Empty command line received"); + return GWEN_ERROR_BAD_DATA; + } + + /* line complete, parse command */ + rv=_parseCommandLineCheckIfHeaderNeeded(GWEN_Buffer_GetStart(xep->currentReadBuffer), xep->currentReadCommand); + if (rv==0) { + /* no header follows, stay in readMode AQH_EndpointHttpd_ReadMode_Command for next command */ + DBG_INFO(AQH_LOGDOMAIN, "No header expected, packet finished"); + return 1; + } + + /* line complete, set bookmark 0=pos of header begin, advance readMode */ + GWEN_Buffer_SetBookmark(xep->currentReadBuffer, AQH_ENDPOINT_HTTP_BOOKMARK_HEADER, GWEN_Buffer_GetPos(xep->currentReadBuffer)); + xep->readMode=AQH_EndpointHttpd_ReadMode_Headers; + DBG_INFO(AQH_LOGDOMAIN, "Start reading headers"); + } + + return 0; +} + + + +int _readHeader(GWEN_MSG_ENDPOINT *ep, const uint8_t **pPtr, int *pLen) +{ + AQH_ENDPOINT_HTTP *xep; + int rv; + + xep=GWEN_INHERIT_GETDATA(GWEN_MSG_ENDPOINT, AQH_ENDPOINT_HTTP, ep); + rv=_readLineCheckEmpty(ep, pPtr, pLen); + if (rv==1) { + /* line complete and empty */ + // TODO: parse header + GWEN_Buffer_SetBookmark(xep->currentReadBuffer, AQH_ENDPOINT_HTTP_BOOKMARK_BODY, GWEN_Buffer_GetPos(xep->currentReadBuffer)); + xep->readMode=AQH_EndpointHttpd_ReadMode_Body; + } + return 0; +} + + + +int _readBody(GWEN_MSG_ENDPOINT *ep, const uint8_t **pPtr, int *pLen) +{ +} + + + +/* ret: -1 if line not complete, 1 if line complete and empty, 0 if line complete and not empty */ +int _readLineCheckEmpty(GWEN_MSG_ENDPOINT *ep, const uint8_t **pPtr, int *pLen) +{ + AQH_ENDPOINT_HTTP *xep; + const uint8_t *ptr=*pPtr; + int len=*pLen; + const uint8_t *p2; + int rv; + + xep=GWEN_INHERIT_GETDATA(GWEN_MSG_ENDPOINT, AQH_ENDPOINT_HTTP, ep); + + p2=memchr(ptr, 10, len); + if (p2) { + int l2; + uint32_t pos; + int currentLineLength; + + l2=p2-ptr+1; /* also count the LF byte itself */ + GWEN_Buffer_AppendBytes(xep->currentReadBuffer, (const char*) ptr, l2); + currentLineLength=_calcCurrentLineLength(ep); + pos=GWEN_Buffer_GetPos(xep->currentReadBuffer); + /* set bookmark 0: pos of header begin */ + GWEN_Buffer_SetBookmark(xep->currentReadBuffer, 0, pos); + xep->lastLineStartPos=pos; + ptr+=l2; + len-=l2; + rv=(currentLineLength==0)?1:0; + } + else { + GWEN_Buffer_AppendBytes(xep->currentReadBuffer, (const char*) ptr, len); + ptr+=len; + len=0; + rv=-1; + } + + *pPtr=ptr; + *pLen=len; + return rv; +} + + + +int _calcCurrentLineLength(const GWEN_MSG_ENDPOINT *ep) +{ + AQH_ENDPOINT_HTTP *xep; + const uint8_t *ptr; + int len=0; + + xep=GWEN_INHERIT_GETDATA(GWEN_MSG_ENDPOINT, AQH_ENDPOINT_HTTP, ep); + ptr=(const uint8_t*) (GWEN_Buffer_GetStart(xep->currentReadBuffer)+xep->lastLineStartPos); + while(*ptr && *ptr!=10 && *ptr!=13) + len++; + return len; +} + + + +int _parseCommandLineCheckIfHeaderNeeded(char *buffer, GWEN_DB_NODE *dbCurrentReadCommand) +{ + char *p; + char *s; + + s=buffer; + + /* read command */ + p=strchr(s, ' '); + if (!p) { + DBG_ERROR(AQH_LOGDOMAIN, "Bad format of HTTP request (%s)", buffer); + return GWEN_ERROR_INVALID; + } + *p=0; + GWEN_DB_SetCharValue(dbCurrentReadCommand, GWEN_DB_FLAGS_OVERWRITE_VARS, "command", s); + *p=' '; /* restore buffer */ + p++; + s=p; + + /* read URL */ + p=strchr(s, ' '); + if (!p) { + DBG_ERROR(AQH_LOGDOMAIN, "Bad format of HTTP request (%s)", buffer); + return GWEN_ERROR_INVALID; + } + *p=0; + GWEN_DB_SetCharValue(dbCurrentReadCommand, GWEN_DB_FLAGS_OVERWRITE_VARS, "url", s); + *p=' '; /* restore buffer */ + p++; + s=p; + + if (*s==0) { + /* no protocol information follows, so we assume HTTP/0.9 */ + return 0; + } + else { + GWEN_DB_SetCharValue(dbCurrentReadCommand, GWEN_DB_FLAGS_OVERWRITE_VARS, "protocol", s); + } + + return 1; +} + + + +#endif diff --git a/aqhome/ipc/endpoint_ipc_tcpc.h b/aqhome/http/endpoint_http.h similarity index 70% rename from aqhome/ipc/endpoint_ipc_tcpc.h rename to aqhome/http/endpoint_http.h index 1a7c095..7821c7b 100644 --- a/aqhome/ipc/endpoint_ipc_tcpc.h +++ b/aqhome/http/endpoint_http.h @@ -6,9 +6,8 @@ * should have received along with this file. ****************************************************************************/ - -#ifndef AQH_ENDPOINT_IPCC_TCPC_H -#define AQH_ENDPOINT_IPCC_TCPC_H +#ifndef AQH_ENDPOINT_HTTP_H +#define AQH_ENDPOINT_HTTP_H #include @@ -19,9 +18,5 @@ - -AQHOME_API GWEN_MSG_ENDPOINT *AQH_IpcTcpClientEndpoint_new(const char *host, int port, const char *name, int groupId); - - #endif diff --git a/aqhome/http/endpoint_http_p.h b/aqhome/http/endpoint_http_p.h new file mode 100644 index 0000000..456b797 --- /dev/null +++ b/aqhome/http/endpoint_http_p.h @@ -0,0 +1,42 @@ +/**************************************************************************** + * This file is part of the project AqHome. + * AqHome (c) by 2023 Martin Preuss, all rights reserved. + * + * The license for this file can be found in the file COPYING which you + * should have received along with this file. + ****************************************************************************/ + +#ifndef AQH_ENDPOINT_HTTP_P_H +#define AQH_ENDPOINT_HTTP_P_H + + + +#include "aqhome/http/endpoint_http.h" + +#include +#include + + +enum { + AQH_EndpointHttpd_ReadMode_Command=0, + AQH_EndpointHttpd_ReadMode_Headers, + AQH_EndpointHttpd_ReadMode_Body +}; + + + +typedef struct AQH_ENDPOINT_HTTP AQH_ENDPOINT_HTTP; +struct AQH_ENDPOINT_HTTP { + int readMode; + GWEN_BUFFER *currentReadBuffer; + GWEN_DB_NODE *currentReadCommand; + GWEN_DB_NODE *currentReadHeader; + int currentBodyPos; + int currentBodySize; + int lastLineStartPos; +}; + + + +#endif + diff --git a/aqhome/ipc/0BUILD b/aqhome/ipc/0BUILD index 71d3962..cb5ff6b 100644 --- a/aqhome/ipc/0BUILD +++ b/aqhome/ipc/0BUILD @@ -46,10 +46,6 @@ endpoint2_ipc.h - endpoint_node_ipc.h - endpoint_node_ipc_tcpd.h - endpoint_ipc_tcpc.h - endpoint_ipc_tcpc_p.h msg_ipc.h msg_ipc_forward.h msg_ipc_value.h @@ -70,9 +66,6 @@ $(local/typefiles) endpoint2_ipc.c - endpoint_node_ipc.c - endpoint_node_ipc_tcpd.c - endpoint_ipc_tcpc.c msg_ipc.c msg_ipc_forward.c msg_ipc_value.c diff --git a/aqhome/ipc/endpoint2_ipc.h b/aqhome/ipc/endpoint2_ipc.h index 3203a63..a342a28 100644 --- a/aqhome/ipc/endpoint2_ipc.h +++ b/aqhome/ipc/endpoint2_ipc.h @@ -12,7 +12,7 @@ #include -#include +#include diff --git a/aqhome/ipc/endpoint_ipc_tcpc.c b/aqhome/ipc/endpoint_ipc_tcpc.c deleted file mode 100644 index 7f9fd40..0000000 --- a/aqhome/ipc/endpoint_ipc_tcpc.c +++ /dev/null @@ -1,84 +0,0 @@ -/**************************************************************************** - * This file is part of the project AqHome. - * AqHome (c) by 2023 Martin Preuss, all rights reserved. - * - * The license for this file can be found in the file COPYING which you - * should have received along with this file. - ****************************************************************************/ - -#ifdef HAVE_CONFIG_H -# include -#endif - - -#include "aqhome/ipc/endpoint_ipc_tcpc_p.h" - -#include -#include -#include - - - - -#define AQH_MSG_ENDPOINT_IPCC_NAME "ipc_tcpc" - - -GWEN_INHERIT(GWEN_MSG_ENDPOINT, AQH_ENDPOINT_IPCC) - - -static void GWENHYWFAR_CB _freeData(void *bp, void *p); -static void _run(GWEN_MSG_ENDPOINT *ep); - - - - - - -GWEN_MSG_ENDPOINT *AQH_IpcTcpClientEndpoint_new(const char *host, int port, const char *name, int groupId) -{ - GWEN_MSG_ENDPOINT *ep; - AQH_ENDPOINT_IPCC *xep; - - ep=GWEN_TcpcEndpoint_new(host, port, name?name:AQH_MSG_ENDPOINT_IPCC_NAME, groupId); - if (ep==NULL) { - DBG_INFO(AQH_LOGDOMAIN, "here"); - return NULL; - } - GWEN_IpcEndpoint_Extend(ep); - - GWEN_NEW_OBJECT(AQH_ENDPOINT_IPCC, xep); - GWEN_INHERIT_SETDATA(GWEN_MSG_ENDPOINT, AQH_ENDPOINT_IPCC, ep, xep, _freeData); - - xep->previousRunFn=GWEN_MsgEndpoint_SetRunFn(ep, _run); - - return ep; -} - - - -void _freeData(void *bp, void *p) -{ - AQH_ENDPOINT_IPCC *xep; - - xep=(AQH_ENDPOINT_IPCC*) p; - GWEN_FREE_OBJECT(xep); -} - - - -void _run(GWEN_MSG_ENDPOINT *ep) -{ - AQH_ENDPOINT_IPCC *xep; - - xep=GWEN_INHERIT_GETDATA(GWEN_MSG_ENDPOINT, AQH_ENDPOINT_IPCC, ep); - if (xep) { - if (xep->previousRunFn) - xep->previousRunFn(ep); - /* TODO: send CONNECT_REQ message, check for CONNECT_RSP */ - } -} - - - - - diff --git a/aqhome/ipc/endpoint_node_ipc.c b/aqhome/ipc/endpoint_node_ipc.c deleted file mode 100644 index 68544f8..0000000 --- a/aqhome/ipc/endpoint_node_ipc.c +++ /dev/null @@ -1,97 +0,0 @@ -/**************************************************************************** - * This file is part of the project AqHome. - * AqHome (c) by 2023 Martin Preuss, all rights reserved. - * - * The license for this file can be found in the file COPYING which you - * should have received along with this file. - ****************************************************************************/ - -#ifdef HAVE_CONFIG_H -# include -#endif - - -#include "aqhome/ipc/endpoint_node_ipc.h" -#include "aqhome/msg/endpoint_node.h" -#include "aqhome/msg/msg_node.h" -#include "aqhome/msg/msg_value2.h" -#include "aqhome/ipc/msg_ipc_forward.h" -#include "aqhome/ipc/msg_ipc_value.h" - -#include -#include -#include -#include - - -#define AQH_MSG_ENDPOINT_NODEIPC_NAME "nodeipc" - - - -static void _processOutMessage(GWEN_MSG_ENDPOINT *ep, GWEN_MSG *m); -static void _processValue2Message(GWEN_MSG_ENDPOINT *ep, GWEN_MSG *nodeMsg); -static void _forwardAnyMessage(GWEN_MSG_ENDPOINT *ep, GWEN_MSG *nodeMsg); - - - - - -GWEN_MSG_ENDPOINT *AQH_IpcNodeEndpoint_new(const char *name, int groupId) -{ - GWEN_MSG_ENDPOINT *ep; - - ep=GWEN_IpcEndpoint_new(name?name:AQH_MSG_ENDPOINT_NODEIPC_NAME, groupId); - AQH_NodeEndpoint_Extend(ep); - GWEN_MsgEndpoint_SetProcessOutMsgFn(ep, _processOutMessage); - -// AQH_NodeEndpoint_SetAcceptedMsgGroups(ep, AQH_MSG_TYPEGROUP_ALL); - - return ep; -} - - - -void _processOutMessage(GWEN_MSG_ENDPOINT *ep, GWEN_MSG *nodeMsg) -{ - switch(AQH_NodeMsg_GetMsgType(nodeMsg)) { - case AQH_MSG_TYPE_VALUE2: - _processValue2Message(ep, nodeMsg); - break; - default: - _forwardAnyMessage(ep, nodeMsg); - break; - } - - GWEN_Msg_free(nodeMsg); -} - - - -void _processValue2Message(GWEN_MSG_ENDPOINT *ep, GWEN_MSG *nodeMsg) -{ - GWEN_MSG *ipcMsg; - - ipcMsg=AQH_ValueIpcMsg_new(AQH_MSGTYPE_IPC_VALUE, - AQH_Value2Msg_GetUid(nodeMsg), - AQH_Value2Msg_GetValueId(nodeMsg), - AQH_Value2Msg_GetValueType(nodeMsg), - AQH_Value2Msg_GetValueNom(nodeMsg), - AQH_Value2Msg_GetValueDenom(nodeMsg)); - GWEN_MsgEndpoint_AddSendMessage(ep, ipcMsg); -} - - - -void _forwardAnyMessage(GWEN_MSG_ENDPOINT *ep, GWEN_MSG *nodeMsg) -{ - GWEN_MSG *ipcMsg; - - ipcMsg=AQH_ForwardIpcMsg_new(AQH_MSGTYPE_IPC_FORWARD, GWEN_Msg_GetConstBuffer(nodeMsg), GWEN_Msg_GetBytesInBuffer(nodeMsg)); - GWEN_MsgEndpoint_AddSendMessage(ep, ipcMsg); -} - - - - - - diff --git a/aqhome/ipc/endpoint_node_ipc.h b/aqhome/ipc/endpoint_node_ipc.h deleted file mode 100644 index f473c57..0000000 --- a/aqhome/ipc/endpoint_node_ipc.h +++ /dev/null @@ -1,24 +0,0 @@ -/**************************************************************************** - * This file is part of the project AqHome. - * AqHome (c) by 2023 Martin Preuss, all rights reserved. - * - * The license for this file can be found in the file COPYING which you - * should have received along with this file. - ****************************************************************************/ - -#ifndef AQH_ENDPOINT_NODE_IPC_H -#define AQH_ENDPOINT_NODE_IPC_H - - -#include - -#include - - - -AQHOME_API GWEN_MSG_ENDPOINT *AQH_IpcNodeEndpoint_new(const char *name, int groupId); - -AQHOME_API int AQH_IpcNodeEndpointMgr_LoopOnce(GWEN_MSG_ENDPOINT_MGR *emgr); - - -#endif diff --git a/aqhome/ipc/endpoint_node_ipc_tcpd.c b/aqhome/ipc/endpoint_node_ipc_tcpd.c deleted file mode 100644 index 0afbbe2..0000000 --- a/aqhome/ipc/endpoint_node_ipc_tcpd.c +++ /dev/null @@ -1,69 +0,0 @@ -/**************************************************************************** - * This file is part of the project AqHome. - * AqHome (c) by 2023 Martin Preuss, all rights reserved. - * - * The license for this file can be found in the file COPYING which you - * should have received along with this file. - ****************************************************************************/ - -#ifdef HAVE_CONFIG_H -# include -#endif - - -#include "aqhome/ipc/endpoint_node_ipc_tcpd.h" -#include "aqhome/ipc/endpoint_node_ipc.h" -#include "aqhome/msg/endpoint_node.h" -#include "aqhome/msg/msg_node.h" -#include "aqhome/msgmanager.h" - -#include -#include -#include -#include - - - -#define AQH_MSG_ENDPOINT_NODEIPCTCP_NAME "node_ipc_tcpd" - - - -static GWEN_MSG_ENDPOINT *_createChild(GWEN_MSG_ENDPOINT *ep); - - - - - -GWEN_MSG_ENDPOINT *AQH_TcpdIpcNodeEndpoint_new(const char *host, int port, const char *name, int groupId) -{ - GWEN_MSG_ENDPOINT *ep; - - ep=GWEN_IpcTcpdEndpoint_new(host, port, name?name:AQH_MSG_ENDPOINT_NODEIPCTCP_NAME, groupId); - AQH_NodeEndpoint_Extend(ep); - GWEN_MsgEndpoint_AddFlags(ep, AQH_MSGEP_NODE_FLAGS_NOMESSAGES); - GWEN_MsgEndpoint_SetCreateChildFn(ep, _createChild); - - return ep; -} - - - -GWEN_MSG_ENDPOINT *_createChild(GWEN_MSG_ENDPOINT *ep) -{ - GWEN_MSG_ENDPOINT *epNew; - - DBG_INFO(AQH_LOGDOMAIN, "Creating child endpoint for %s", GWEN_MsgEndpoint_GetName(ep)); - epNew=AQH_IpcNodeEndpoint_new(NULL, AQH_MSGMGR_ENDPOINTGROUP_IPC); - GWEN_MsgEndpoint_AddFlags(epNew, GWEN_MSG_ENDPOINT_FLAGS_DELONDISCONNECT); - GWEN_MsgEndpoint_SetAcceptedGroupIds(epNew, GWEN_MsgEndpoint_GetAcceptedGroupIds(ep)); - return epNew; -} - - - - - - - - - diff --git a/aqhome/ipc/endpoint_node_ipc_tcpd.h b/aqhome/ipc/endpoint_node_ipc_tcpd.h deleted file mode 100644 index 4a1f3b9..0000000 --- a/aqhome/ipc/endpoint_node_ipc_tcpd.h +++ /dev/null @@ -1,22 +0,0 @@ -/**************************************************************************** - * This file is part of the project AqHome. - * AqHome (c) by 2023 Martin Preuss, all rights reserved. - * - * The license for this file can be found in the file COPYING which you - * should have received along with this file. - ****************************************************************************/ - -#ifndef AQH_ENDPOINT_NODE_IPC_TCPD_H -#define AQH_ENDPOINT_NODE_IPC_TCPD_H - - -#include - -#include - - - -AQHOME_API GWEN_MSG_ENDPOINT *AQH_TcpdIpcNodeEndpoint_new(const char *host, int port, const char *name, int groupId); - - -#endif diff --git a/aqhome/libtest.c b/aqhome/libtest.c index 194ba2c..10faf66 100644 --- a/aqhome/libtest.c +++ b/aqhome/libtest.c @@ -4,16 +4,9 @@ #endif #include "aqhome/msg/msg_ping.h" -#include "aqhome/msg/endpointmgr.h" -#include "aqhome/msg/endpoint_node.h" -#include "aqhome/msg/endpoint_log.h" -#include "aqhome/msg/endpoint_tty.h" -#include "aqhome/ipc/endpoint_node_ipc_tcpd.h" -#include "aqhome/ipc/endpoint_ipc_tcpc.h" #include "aqhome/ipc/msg_ipc_ping.h" #include "aqhome/ipc/msg_ipc_forward.h" #include "aqhome/ipc/msg_ipc_setaccmsggrps.h" -#include "aqhome/mqtt/endpoint_mqttc.h" #include "aqhome/mqtt/endpoint2_mqttc.h" #include "aqhome/mqtt/msg_mqtt_connect.h" #include "aqhome/mqtt/msg_mqtt_connack.h" @@ -21,7 +14,6 @@ #include "aqhome/mqtt/msg_mqtt_pubresponse.h" #include "aqhome/mqtt/msg_mqtt_subscribe.h" #include "aqhome/mqtt/msg_mqtt_suback.h" -#include "aqhome/msgmanager.h" #include "aqhome/hexfile/hexfile.h" #include "aqhome/hexfile/flashrecord.h" @@ -31,9 +23,6 @@ #include #include #include -#include -#include -#include #include #include @@ -116,143 +105,6 @@ GWEN_MSG *createPingMsg(uint8_t destAddr, uint8_t srcAddr) -int testEndpoints() -{ - int rv; - GWEN_MSG_ENDPOINT_MGR *emgr; - GWEN_MSG_ENDPOINT *epTty; - GWEN_MSG_ENDPOINT *epLog; - GWEN_MSG_ENDPOINT *epTcp; - - rv=AQH_Init(); - if (rv<0) { - } - - emgr=AQH_MsgManager_new(0xc0); - epTty=AQH_TtyNodeEndpoint_new("/dev/ttyUSB0", AQH_MSGMGR_ENDPOINTGROUP_NODE); - if (epTty==NULL) { - DBG_ERROR(NULL, "Error creating endpoint TTY"); - return 2; - } - GWEN_MsgEndpointMgr_AddEndpoint(emgr, epTty); - - epLog=AQH_LogEndpoint_new("endpoints.log", AQH_MSGMGR_ENDPOINTGROUP_NODE); - if (epLog==NULL) { - DBG_ERROR(AQH_LOGDOMAIN, "Error creating endpoint LOG"); - return 2; - } - GWEN_MsgEndpointMgr_AddEndpoint(emgr, epLog); - - epTcp=AQH_TcpdIpcNodeEndpoint_new("127.0.0.1", 45454, NULL, AQH_MSGMGR_ENDPOINTGROUP_IPC); - if (epTcp==NULL) { - DBG_ERROR(AQH_LOGDOMAIN, "Error creating endpoint TCP"); - return 2; - } - GWEN_MsgEndpointMgr_AddEndpoint(emgr, epTcp); - - for (;;) { - DBG_DEBUG(AQH_LOGDOMAIN, "Next loop"); - AQH_MsgManager_LoopOnce(emgr); - } - return 0; -} - - - -int testMsgMqttConnect() -{ - GWEN_MSG *msg; - GWEN_BUFFER *dbuf; - - msg=GWEN_ConnectMqttMsg_new("MQTT", 4, - AQH_MQTTMSG_CONNECT_FLAGS_USERNAME | AQH_MQTTMSG_CONNECT_FLAGS_PASSWD, - 512, - "CLIENTID123", - "USER123", - "PASSWD123"); - if (msg==NULL) { - DBG_ERROR(NULL, "Error creating message"); - return 2; - } - dbuf=GWEN_Buffer_new(0, 256, 0, 1); - AQH_ConnectMqttMsg_DumpToBuffer(msg, dbuf, "created"); - fprintf(stdout, "%s\n", GWEN_Buffer_GetStart(dbuf)); - GWEN_Buffer_free(dbuf); - - GWEN_Text_DumpString((const char*) GWEN_Msg_GetConstBuffer(msg), GWEN_Msg_GetBytesInBuffer(msg), 2); - - return 0; -} - - - -int testMqttConnection() -{ - int rv; - GWEN_MSG_ENDPOINT_MGR *emgr; - GWEN_MSG_ENDPOINT *epTcp; - GWEN_MSG *msgOut; - - rv=AQH_Init(); - if (rv<0) { - } - - emgr=GWEN_MsgEndpointMgr_new(); - - epTcp=AQH_MqttClientEndpoint_new("127.0.0.1", 1883, "MQTTClient", 0); - if (epTcp==NULL) { - DBG_ERROR(NULL, "Error creating endpoint TCPc"); - return 2; - } - GWEN_MsgEndpointMgr_AddEndpoint(emgr, epTcp); - - rv=_mqttConnect(emgr, epTcp); - if (rv!=0) { - DBG_ERROR(NULL, "Error connecting"); - return 2; - } - - fprintf(stdout, "Sending PUBLISH\n"); - //msgOut=GWEN_PublishMqttMsg_new(AQH_MQTTMSG_FLAGS_QOS1, 1, "test/subject1", (const uint8_t*) "29.9", 4); - msgOut=GWEN_PublishMqttMsg_new(0, 0, "test/subject1", (const uint8_t*) "29.9", 4); - if (msgOut==NULL) { - DBG_ERROR(NULL, "Error creating message"); - return 2; - } - GWEN_MsgEndpoint_AddSendMessage(epTcp, msgOut); - - fprintf(stdout, "Waiting for response\n"); - for (;;) { - GWEN_MSG *msg; - - DBG_DEBUG(AQH_LOGDOMAIN, "Next loop"); - //GWEN_MsgManager_LoopOnce(emgr); - GWEN_MsgEndpointMgr_IoLoopOnce(emgr); - msg=GWEN_MsgEndpoint_TakeFirstReceivedMessage(epTcp); - if (msg) { - if (AQH_MqttMsg_GetMsgTypeAndFlags(msg)==AQH_MQTTMSG_MSGTYPE_PUBACK) { - GWEN_BUFFER *buf; - - buf=GWEN_Buffer_new(0, 256, 0, 1); - AQH_PubResponseMqttMsg_DumpToBuffer(msg, buf, "received"); - fprintf(stdout, "%s\n", GWEN_Buffer_GetStart(buf)); - GWEN_Buffer_free(buf); - } - else { - DBG_ERROR(NULL, "Received this message:"); - GWEN_Text_DumpString((const char*) GWEN_Msg_GetConstBuffer(msg), GWEN_Msg_GetBytesInBuffer(msg), 2); - } - GWEN_Msg_free(msg); - break; - } - } - - - return 0; -} - - - int testMqttConnection2() { GWEN_MSG_ENDPOINT2 *epClient; @@ -276,94 +128,6 @@ int testMqttConnection2() -int testMqttSubscribe(int argc, char **argv) -{ - int rv; - GWEN_MSG_ENDPOINT_MGR *emgr; - GWEN_MSG_ENDPOINT *epTcp; - GWEN_MSG *msgOut; - GWEN_MSG *msgIn; - uint16_t pckId; - const char *host="127.0.0.1"; - - if (argc>1) - host=argv[1]; - - rv=AQH_Init(); - if (rv<0) { - } - - //emgr=AQH_MsgManager_new(0xc0); - emgr=GWEN_MsgEndpointMgr_new(); - - epTcp=AQH_MqttClientEndpoint_new(host, 1883, "MQTTClient", 0); - if (epTcp==NULL) { - DBG_ERROR(NULL, "Error creating endpoint TCPc"); - return 2; - } - AQH_MqttClientEndpoint_SetClientId(epTcp, "CLIENTID123"); - GWEN_MsgEndpointMgr_AddEndpoint(emgr, epTcp); - - rv=_mqttConnect(emgr, epTcp); - if (rv!=0) { - DBG_ERROR(NULL, "Error connecting"); - return 2; - } - - fprintf(stdout, "Sending SUBSCRIBE\n"); - pckId=AQH_MqttClientEndpoint_GetNextPacketId(epTcp); - //msgOut=GWEN_PublishMqttMsg_new(AQH_MQTTMSG_FLAGS_QOS1, 1, "test/subject1", (const uint8_t*) "29.9", 4); - msgOut=GWEN_SubscribeMqttMsg_new(AQH_MQTTMSG_MSGTYPE_SUBSCRIBE, pckId, "aqhome/#", 0); - if (msgOut==NULL) { - DBG_ERROR(NULL, "Error creating message"); - return 2; - } - DBG_ERROR(NULL, "Sending this message:"); - GWEN_Text_DumpString((const char*) GWEN_Msg_GetConstBuffer(msgOut), GWEN_Msg_GetBytesInBuffer(msgOut), 2); - - GWEN_MsgEndpoint_AddSendMessage(epTcp, msgOut); - - fprintf(stdout, "Waiting for response\n"); - msgIn=_awaitPacket(emgr, epTcp, AQH_MQTTMSG_MSGTYPE_SUBACK); - if (msgIn) { - GWEN_BUFFER *buf; - - buf=GWEN_Buffer_new(0, 256, 0, 1); - AQH_SubAckMqttMsg_DumpToBuffer(msgIn, buf, "received"); - fprintf(stdout, "%s\n", GWEN_Buffer_GetStart(buf)); - GWEN_Buffer_free(buf); - GWEN_Msg_free(msgIn); - } - - for (;;) { - GWEN_MSG *msg; - - //GWEN_MsgManager_LoopOnce(emgr); - GWEN_MsgEndpointMgr_IoLoopOnce(emgr); - msg=GWEN_MsgEndpoint_TakeFirstReceivedMessage(epTcp); - if (msg) { - if ((AQH_MqttMsg_GetMsgTypeAndFlags(msg) & 0xf0)==(AQH_MQTTMSG_MSGTYPE_PUBLISH & 0xf0)) { - GWEN_BUFFER *buf; - - buf=GWEN_Buffer_new(0, 256, 0, 1); - AQH_PublishMqttMsg_DumpToBuffer(msg, buf, "received"); - fprintf(stdout, "%s\n", GWEN_Buffer_GetStart(buf)); - GWEN_Buffer_free(buf); - } - else { - DBG_ERROR(NULL, "Received this message:"); - GWEN_Text_DumpString((const char*) GWEN_Msg_GetConstBuffer(msg), GWEN_Msg_GetBytesInBuffer(msg), 2); - } - GWEN_Msg_free(msg); - } - } - - - return 0; -} - - - int testMqttSubscribe2(int argc, char **argv) { GWEN_MSG_ENDPOINT2 *epClient; @@ -387,7 +151,7 @@ int testMqttSubscribe2(int argc, char **argv) } pckId=AQH_MqttClientEndpoint2_GetNextPacketId(epClient); - //msgOut=GWEN_PublishMqttMsg_new(AQH_MQTTMSG_FLAGS_QOS1, 1, "test/subject1", (const uint8_t*) "29.9", 4); + //msgOut=AQH_PublishMqttMsg_new(AQH_MQTTMSG_FLAGS_QOS1, 1, "test/subject1", (const uint8_t*) "29.9", 4); //msgOut=GWEN_SubscribeMqttMsg_new(AQH_MQTTMSG_MSGTYPE_SUBSCRIBE, pckId, "aqhome/#", 0); msgOut=GWEN_SubscribeMqttMsg_new(AQH_MQTTMSG_MSGTYPE_SUBSCRIBE, pckId, "#", 0); if (msgOut==NULL) { @@ -483,120 +247,6 @@ GWEN_MSG *_awaitPacket2(GWEN_MSG_ENDPOINT2 *epClient, uint8_t expectedPacketType - - - -int _mqttConnect(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ENDPOINT *epTcp) -{ - while(GWEN_ConnectableMsgEndpoint_GetState(epTcp) - endpoint_mqttc.h endpoint2_mqtt.h endpoint2_mqttc.h msg_mqtt.h @@ -66,7 +65,6 @@ $(local/typefiles) - endpoint_mqttc.c endpoint2_mqtt.c endpoint2_mqttc.c msg_mqtt.c diff --git a/aqhome/mqtt/endpoint2_mqtt.c b/aqhome/mqtt/endpoint2_mqtt.c index ae334a3..4002b38 100644 --- a/aqhome/mqtt/endpoint2_mqtt.c +++ b/aqhome/mqtt/endpoint2_mqtt.c @@ -305,7 +305,7 @@ GWEN_MSG *AQH_MqttEndpoint2_CreateMsgPublishString(GWEN_MSG_ENDPOINT2 *ep, valuePath); DBG_INFO(AQH_LOGDOMAIN, "MQTT PUBLISH %s: %s", GWEN_Buffer_GetStart(bufTopic), v); - pubMsg=GWEN_PublishMqttMsg_new(0, 0, GWEN_Buffer_GetStart(bufTopic), (const uint8_t*) v, strlen(v)); + pubMsg=AQH_PublishMqttMsg_new(0, 0, GWEN_Buffer_GetStart(bufTopic), (const uint8_t*) v, strlen(v)); GWEN_Buffer_free(bufTopic); if (pubMsg==NULL) { DBG_INFO(AQH_LOGDOMAIN, "here"); diff --git a/aqhome/mqtt/endpoint2_mqtt_p.h b/aqhome/mqtt/endpoint2_mqtt_p.h index 85c0c3d..2eca1f0 100644 --- a/aqhome/mqtt/endpoint2_mqtt_p.h +++ b/aqhome/mqtt/endpoint2_mqtt_p.h @@ -12,7 +12,6 @@ #include "aqhome/mqtt/endpoint2_mqtt.h" -#include typedef struct AQH_ENDPOINT2_MQTT AQH_ENDPOINT2_MQTT; diff --git a/aqhome/mqtt/endpoint_mqttc.c b/aqhome/mqtt/endpoint_mqttc.c deleted file mode 100644 index a2dd7c8..0000000 --- a/aqhome/mqtt/endpoint_mqttc.c +++ /dev/null @@ -1,503 +0,0 @@ -/**************************************************************************** - * This file is part of the project AqHome. - * AqHome (c) by 2023 Martin Preuss, all rights reserved. - * - * The license for this file can be found in the file COPYING which you - * should have received along with this file. - ****************************************************************************/ - -#ifdef HAVE_CONFIG_H -# include -#endif - - -#include "aqhome/mqtt/endpoint_mqttc_p.h" -#include "aqhome/mqtt/msg_mqtt.h" -#include "aqhome/mqtt/msg_mqtt_connect.h" -#include "aqhome/mqtt/msg_mqtt_publish.h" -#include "aqhome/msg/endpoint_node.h" -#include "aqhome/msg/msg_node.h" -#include "aqhome/msg/msg_value2.h" -#include "aqhome/msg/msg_sendstats.h" -#include "aqhome/msg/msg_recvstats.h" - -#include -#include - - - -#define GWEN_MSG_ENDPOINT_MQTTC_NAME "mqttc" -#define GWEN_ENDPOINT_MQTTC_BUFFERSIZE 1024 - - - -GWEN_INHERIT(GWEN_MSG_ENDPOINT, AQH_ENDPOINT_MQTTC) - - -static void GWENHYWFAR_CB _freeData(void *bp, void *p); -static int _connect(GWEN_MSG_ENDPOINT *ep); -static void _sendConnectMsg(GWEN_MSG_ENDPOINT *ep); -static void _checkForConnAckMsg(GWEN_MSG_ENDPOINT *ep); -static void _processOutMessage(GWEN_MSG_ENDPOINT *ep, GWEN_MSG *nodeMsg); -static void _processValue2Message(GWEN_MSG_ENDPOINT *ep, GWEN_MSG *nodeMsg); -static void _processSendStatsMessage(GWEN_MSG_ENDPOINT *ep, GWEN_MSG *nodeMsg); -static void _processRecvStatsMessage(GWEN_MSG_ENDPOINT *ep, GWEN_MSG *nodeMsg); -static void _publishDouble(GWEN_MSG_ENDPOINT *ep, uint32_t uid, int valueId, const char *valuePath, double v); -static void _publishInt(GWEN_MSG_ENDPOINT *ep, uint32_t uid, int valueId, const char *valuePath, int v); -static void _publishString(GWEN_MSG_ENDPOINT *ep, uint32_t uid, int valueId, const char *valuePath, const char *v); -static int _isMsgComplete(GWEN_MSG_ENDPOINT *ep, GWEN_MSG *msg); -static int _calcAndSetPayloadSizeAndOffset(GWEN_MSG *msg); - - - - -GWEN_MSG_ENDPOINT *AQH_MqttClientEndpoint_new(const char *host, int port, const char *name, int groupId) -{ - GWEN_MSG_ENDPOINT *ep; - AQH_ENDPOINT_MQTTC *xep; - - ep=GWEN_TcpcEndpoint_new(host, port, name?name:GWEN_MSG_ENDPOINT_MQTTC_NAME, groupId); - if (ep==NULL) { - DBG_INFO(AQH_LOGDOMAIN, "here"); - return NULL; - } - AQH_NodeEndpoint_Extend(ep); - AQH_NodeEndpoint_SetAcceptedMsgGroups(ep, AQH_MSG_TYPEGROUP_ALL); - - GWEN_NEW_OBJECT(AQH_ENDPOINT_MQTTC, xep); - GWEN_INHERIT_SETDATA(GWEN_MSG_ENDPOINT, AQH_ENDPOINT_MQTTC, ep, xep, _freeData); - - GWEN_MsgEndpoint_SetDefaultBufferSize(ep, GWEN_ENDPOINT_MQTTC_BUFFERSIZE); - GWEN_MsgEndpoint_SetIsMsgCompleteFn(ep, _isMsgComplete); - GWEN_MsgEndpoint_SetProcessOutMsgFn(ep, _processOutMessage); - xep->previousConnectFn=GWEN_ConnectableMsgEndpoint_SetConnectFn(ep, _connect); - GWEN_ConnectableMsgEndpoint_SetFullyConnectedState(ep, GWEN_ENDPOINT_MQTTC_STATE_ESTABLISHED); - - return ep; -} - - - -void _freeData(void *bp, void *p) -{ - AQH_ENDPOINT_MQTTC *xep; - - xep=(AQH_ENDPOINT_MQTTC*) p; - free(xep->clientId); - free(xep->topicPrefix); - GWEN_FREE_OBJECT(xep); -} - - - -uint16_t AQH_MqttClientEndpoint_GetNextPacketId(GWEN_MSG_ENDPOINT *ep) -{ - if (ep) { - AQH_ENDPOINT_MQTTC *xep; - - xep=GWEN_INHERIT_GETDATA(GWEN_MSG_ENDPOINT, AQH_ENDPOINT_MQTTC, ep); - if (xep) - return ++(xep->lastPacketId); - } - return 0; -} - - - -uint16_t AQH_MqttClientEndpoint_GetKeepAliveTime(const GWEN_MSG_ENDPOINT *ep) -{ - if (ep) { - AQH_ENDPOINT_MQTTC *xep; - - xep=GWEN_INHERIT_GETDATA(GWEN_MSG_ENDPOINT, AQH_ENDPOINT_MQTTC, ep); - if (xep) - return xep->keepAliveTime; - } - return 0; -} - - - -void AQH_MqttClientEndpoint_SetKeepAliveTime(GWEN_MSG_ENDPOINT *ep, uint16_t i) -{ - if (ep) { - AQH_ENDPOINT_MQTTC *xep; - - xep=GWEN_INHERIT_GETDATA(GWEN_MSG_ENDPOINT, AQH_ENDPOINT_MQTTC, ep); - if (xep) - xep->keepAliveTime=i; - } -} - - - -const char *AQH_MqttClientEndpoint_GetClientId(const GWEN_MSG_ENDPOINT *ep) -{ - if (ep) { - AQH_ENDPOINT_MQTTC *xep; - - xep=GWEN_INHERIT_GETDATA(GWEN_MSG_ENDPOINT, AQH_ENDPOINT_MQTTC, ep); - if (xep) - return xep->clientId; - } - return NULL; -} - - - -void AQH_MqttClientEndpoint_SetClientId(GWEN_MSG_ENDPOINT *ep, const char *s) -{ - if (ep) { - AQH_ENDPOINT_MQTTC *xep; - - xep=GWEN_INHERIT_GETDATA(GWEN_MSG_ENDPOINT, AQH_ENDPOINT_MQTTC, ep); - if (xep) { - free(xep->clientId); - xep->clientId=s?strdup(s):NULL; - } - } -} - - - -const char *AQH_MqttClientEndpoint_GetTopicPrefix(const GWEN_MSG_ENDPOINT *ep) -{ - if (ep) { - AQH_ENDPOINT_MQTTC *xep; - - xep=GWEN_INHERIT_GETDATA(GWEN_MSG_ENDPOINT, AQH_ENDPOINT_MQTTC, ep); - if (xep) - return xep->topicPrefix; - } - return NULL; -} - - - -void AQH_MqttClientEndpoint_SetTopicPrefix(GWEN_MSG_ENDPOINT *ep, const char *s) -{ - if (ep) { - AQH_ENDPOINT_MQTTC *xep; - - xep=GWEN_INHERIT_GETDATA(GWEN_MSG_ENDPOINT, AQH_ENDPOINT_MQTTC, ep); - if (xep) { - free(xep->topicPrefix); - xep->topicPrefix=s?strdup(s):NULL; - } - } -} - - - -int _connect(GWEN_MSG_ENDPOINT *ep) -{ - AQH_ENDPOINT_MQTTC *xep; - - DBG_DEBUG(AQH_LOGDOMAIN, "Called CONNECT"); - xep=GWEN_INHERIT_GETDATA(GWEN_MSG_ENDPOINT, AQH_ENDPOINT_MQTTC, ep); - if (xep) { - int state; - - state=GWEN_ConnectableMsgEndpoint_GetState(ep); - if (statepreviousConnectFn) { - int rv; - - rv=xep->previousConnectFn(ep); - if (rv<0) { - if (rv==GWEN_ERROR_TRY_AGAIN) { - DBG_DEBUG(AQH_LOGDOMAIN, "Still connecting..."); - } - else { - DBG_INFO(AQH_LOGDOMAIN, "here (%d)", rv); - } - return rv; - } - state=GWEN_ConnectableMsgEndpoint_GetState(ep); - } - } - else { - DBG_DEBUG(AQH_LOGDOMAIN, "Physically connected, checking further."); - } - - if (statekeepAliveTime, xep->clientId, NULL, NULL); - if (msg) { - DBG_DEBUG(AQH_LOGDOMAIN, "Sending MQTT CONNECT request."); - GWEN_MsgEndpoint_AddSendMessage(ep, msg); - GWEN_ConnectableMsgEndpoint_SetState(ep, GWEN_ENDPOINT_MQTTC_STATE_WAITFORCONNACK); - } -} - - - -void _checkForConnAckMsg(GWEN_MSG_ENDPOINT *ep) -{ - GWEN_MSG *msg; - - DBG_DEBUG(AQH_LOGDOMAIN, "Checking for connect response"); - msg=GWEN_MsgEndpoint_TakeFirstReceivedMessage(ep); - if (msg) { - uint8_t msgType; - - msgType=AQH_MqttMsg_GetMsgTypeAndFlags(msg) & 0xf0; - if (msgType==AQH_MQTTMSG_MSGTYPE_CONNACK) { - DBG_INFO(AQH_LOGDOMAIN, "MQTT CONNACK received, logical connection established."); - GWEN_ConnectableMsgEndpoint_SetState(ep, GWEN_ENDPOINT_MQTTC_STATE_ESTABLISHED); - } - else { - DBG_ERROR(AQH_LOGDOMAIN, "Unexpected message received (%s)", AQH_MqttMsg_MsgTypeToString(msgType)); - } - GWEN_Msg_free(msg); - } -} - - - -void _processOutMessage(GWEN_MSG_ENDPOINT *ep, GWEN_MSG *nodeMsg) -{ - if (GWEN_ConnectableMsgEndpoint_GetState(ep)==GWEN_ENDPOINT_MQTTC_STATE_ESTABLISHED) { - DBG_DEBUG(AQH_LOGDOMAIN, "Processing output message"); - switch(AQH_NodeMsg_GetMsgType(nodeMsg)) { - case AQH_MSG_TYPE_VALUE2: - _processValue2Message(ep, nodeMsg); - break; - case AQH_MSG_TYPE_COMSENDSTATS: - _processSendStatsMessage(ep, nodeMsg); - break; - case AQH_MSG_TYPE_COMRECVSTATS: - _processRecvStatsMessage(ep, nodeMsg); - break; - default: - break; - } - GWEN_Msg_free(nodeMsg); - } -} - - - -void _processValue2Message(GWEN_MSG_ENDPOINT *ep, GWEN_MSG *nodeMsg) -{ - if (AQH_Value2Msg_GetValueType(nodeMsg)==AQH_MSG_VALUE2_TYPE_DOOR) - _publishString(ep, - AQH_Value2Msg_GetUid(nodeMsg), - AQH_Value2Msg_GetValueId(nodeMsg), - AQH_Value2Msg_GetValueTypeName(nodeMsg), - AQH_Value2Msg_GetValueAsWindowStateString(nodeMsg)); - else - _publishDouble(ep, - AQH_Value2Msg_GetUid(nodeMsg), - AQH_Value2Msg_GetValueId(nodeMsg), - AQH_Value2Msg_GetValueTypeName(nodeMsg), - AQH_Value2Msg_GetValue(nodeMsg)); -} - - - -void _processSendStatsMessage(GWEN_MSG_ENDPOINT *ep, GWEN_MSG *nodeMsg) -{ - uint16_t packetsOutInt; - - packetsOutInt=AQH_SendStatsMsg_GetPacketsOut(nodeMsg); - if (packetsOutInt) { - double packetsOut; - double collisions; - double busy; - double collisionsPercentage=0.0; - double busyPercentage=0.0; - - packetsOut=(double) packetsOutInt; - collisions=(double)AQH_SendStatsMsg_GetCollisions(nodeMsg); - busy=(double)AQH_SendStatsMsg_GetBusyErrors(nodeMsg); - - collisionsPercentage=collisions*100.0/packetsOut; - busyPercentage=busy*100.0/packetsOut; - - _publishInt(ep, AQH_SendStatsMsg_GetUid(nodeMsg), 0, "net/packetsOut", packetsOutInt); - _publishInt(ep, AQH_SendStatsMsg_GetUid(nodeMsg), 0, "net/collisions", (int) AQH_SendStatsMsg_GetCollisions(nodeMsg)); - _publishDouble(ep, AQH_SendStatsMsg_GetUid(nodeMsg), 0, "net/collisionsPercent", collisionsPercentage); - _publishDouble(ep, AQH_SendStatsMsg_GetUid(nodeMsg), 0, "net/busyPercent", busyPercentage); - } -} - - - -void _processRecvStatsMessage(GWEN_MSG_ENDPOINT *ep, GWEN_MSG *nodeMsg) -{ - uint16_t packetsInInt; - - packetsInInt=AQH_RecvStatsMsg_GetPacketsIn(nodeMsg); - if (packetsInInt) { - double packetsIn; - double crcErrors; - double ioErrors; - double crcErrorsPercentage=0.0; - double ioErrorsPercentage=0.0; - - packetsIn=(double) packetsInInt; - crcErrors=(double)AQH_RecvStatsMsg_GetCrcErrors(nodeMsg); - ioErrors=(double)AQH_RecvStatsMsg_GetIoErrors(nodeMsg); - - crcErrorsPercentage=crcErrors*100.0/packetsIn; - ioErrorsPercentage=ioErrors*100.0/packetsIn; - - _publishInt(ep, AQH_RecvStatsMsg_GetUid(nodeMsg), 0, "net/packetsIn", packetsInInt); - _publishInt(ep, AQH_RecvStatsMsg_GetUid(nodeMsg), 0, "net/crcerrors", (int) AQH_RecvStatsMsg_GetCrcErrors(nodeMsg)); - _publishInt(ep, AQH_RecvStatsMsg_GetUid(nodeMsg), 0, "net/ioerrors", (int) AQH_RecvStatsMsg_GetIoErrors(nodeMsg)); - _publishDouble(ep, AQH_RecvStatsMsg_GetUid(nodeMsg), 0, "net/crcerrorsPercent", crcErrorsPercentage); - _publishDouble(ep, AQH_RecvStatsMsg_GetUid(nodeMsg), 0, "net/ioerrorsPercent", ioErrorsPercentage); - } -} - - - -void _publishDouble(GWEN_MSG_ENDPOINT *ep, uint32_t uid, int valueId, const char *valuePath, double v) -{ - char numBuf[16]; - - snprintf(numBuf, sizeof(numBuf)-1, "%f", v); - numBuf[sizeof(numBuf)-1]=0; - _publishString(ep, uid, valueId, valuePath, numBuf); -} - - - -void _publishInt(GWEN_MSG_ENDPOINT *ep, uint32_t uid, int valueId, const char *valuePath, int v) -{ - char numBuf[16]; - - snprintf(numBuf, sizeof(numBuf)-1, "%d", v); - numBuf[sizeof(numBuf)-1]=0; - _publishString(ep, uid, valueId, valuePath, numBuf); -} - - - -void _publishString(GWEN_MSG_ENDPOINT *ep, uint32_t uid, int valueId, const char *valuePath, const char *v) -{ - AQH_ENDPOINT_MQTTC *xep; - GWEN_BUFFER *bufTopic; - GWEN_MSG *pubMsg; - - xep=GWEN_INHERIT_GETDATA(GWEN_MSG_ENDPOINT, AQH_ENDPOINT_MQTTC, ep); - - bufTopic=GWEN_Buffer_new(0, 64, 0, 1); - if (valueId>0) - GWEN_Buffer_AppendArgs(bufTopic, "%s/%08x/%d/%s", - xep->topicPrefix, - uid, - valueId, - valuePath); - else - GWEN_Buffer_AppendArgs(bufTopic, "%s/%08x/%s", - xep->topicPrefix, - uid, - valuePath); - - pubMsg=GWEN_PublishMqttMsg_new(0, 0, GWEN_Buffer_GetStart(bufTopic), (const uint8_t*) v, strlen(v)); - if (pubMsg) { - DBG_INFO(AQH_LOGDOMAIN, "MQTT PUBLISH %s: %s", GWEN_Buffer_GetStart(bufTopic), v); - GWEN_MsgEndpoint_AddSendMessage(ep, pubMsg); - } - GWEN_Buffer_free(bufTopic); -} - - - -int _isMsgComplete(GWEN_UNUSED GWEN_MSG_ENDPOINT *ep, GWEN_MSG *msg) -{ - int rv; - - if (!(GWEN_Msg_GetFlags(msg) & GWEN_MSG_FLAGS_PAYLOADINFO_SET)) { - rv=_calcAndSetPayloadSizeAndOffset(msg); - if (rv<0) { - DBG_INFO(AQH_LOGDOMAIN, "here (%d)", rv); - return rv; - } - } - rv=AQH_MqttMsg_IsMsgComplete(msg); - if (rv<0) { - DBG_INFO(AQH_LOGDOMAIN, "here (%d)", rv); - return rv; - } - - return rv; -} - - - -int _calcAndSetPayloadSizeAndOffset(GWEN_MSG *msg) -{ - int remainingBytesInBuffer; - uint32_t mqttRemainingLength=0; - - remainingBytesInBuffer=GWEN_Msg_GetBytesInBuffer(msg); - if (remainingBytesInBuffer>1) { - const uint8_t *ptr; - int idx; - int shift=0; - - ptr=GWEN_Msg_GetConstBuffer(msg); - idx=1; - remainingBytesInBuffer--; - while(remainingBytesInBuffer) { - uint8_t len; - - len=ptr[idx]; - mqttRemainingLength+=(len & 0x7f)< - -#include - -#define GWEN_ENDPOINT_MQTTC_STATE_WAITFORCONNACK (GWEN_MSG_ENDPOINT_CONN_STATE_NEXTFREE+0) -#define GWEN_ENDPOINT_MQTTC_STATE_ESTABLISHED (GWEN_MSG_ENDPOINT_CONN_STATE_NEXTFREE+1) - - -AQHOME_API GWEN_MSG_ENDPOINT *AQH_MqttClientEndpoint_new(const char *host, int port, const char *name, int groupId); - -AQHOME_API uint16_t AQH_MqttClientEndpoint_GetNextPacketId(GWEN_MSG_ENDPOINT *ep); -AQHOME_API uint16_t AQH_MqttClientEndpoint_GetKeepAliveTime(const GWEN_MSG_ENDPOINT *ep); -AQHOME_API void AQH_MqttClientEndpoint_SetKeepAliveTime(GWEN_MSG_ENDPOINT *ep, uint16_t i); - -AQHOME_API const char *AQH_MqttClientEndpoint_GetClientId(const GWEN_MSG_ENDPOINT *ep); -AQHOME_API void AQH_MqttClientEndpoint_SetClientId(GWEN_MSG_ENDPOINT *ep, const char *s); - -AQHOME_API const char *AQH_MqttClientEndpoint_GetTopicPrefix(const GWEN_MSG_ENDPOINT *ep); -AQHOME_API void AQH_MqttClientEndpoint_SetTopicPrefix(GWEN_MSG_ENDPOINT *ep, const char *s); - - - -#endif - diff --git a/aqhome/mqtt/endpoint_mqttc_p.h b/aqhome/mqtt/endpoint_mqttc_p.h deleted file mode 100644 index ea0082b..0000000 --- a/aqhome/mqtt/endpoint_mqttc_p.h +++ /dev/null @@ -1,33 +0,0 @@ -/**************************************************************************** - * This file is part of the project AqHome. - * AqHome (c) by 2023 Martin Preuss, all rights reserved. - * - * The license for this file can be found in the file COPYING which you - * should have received along with this file. - ****************************************************************************/ - -#ifndef AQH_ENDPOINT_MQTTC_P_H -#define AQH_ENDPOINT_MQTTC_P_H - - -#include "aqhome/mqtt/endpoint_mqttc.h" - -#include - - -typedef struct AQH_ENDPOINT_MQTTC AQH_ENDPOINT_MQTTC; -struct AQH_ENDPOINT_MQTTC { - char *clientId; - char *topicPrefix; - uint16_t lastPacketId; - uint16_t keepAliveTime; - - GWEN_CONN_ENDPOINT_CONNECT_FN previousConnectFn; -}; - - - - - -#endif - diff --git a/aqhome/mqtt/msg_mqtt_publish.c b/aqhome/mqtt/msg_mqtt_publish.c index 28afac7..245d3e5 100644 --- a/aqhome/mqtt/msg_mqtt_publish.c +++ b/aqhome/mqtt/msg_mqtt_publish.c @@ -23,7 +23,7 @@ static int _dumpPayload(uint8_t flags, const uint8_t *payloadPtr, uint32_t paylo -GWEN_MSG *GWEN_PublishMqttMsg_new(uint8_t flags, uint16_t packetId, const char *sTopic, const uint8_t *messagePtr, uint32_t messageLen) +GWEN_MSG *AQH_PublishMqttMsg_new(uint8_t flags, uint16_t packetId, const char *sTopic, const uint8_t *messagePtr, uint32_t messageLen) { if (sTopic && *sTopic && messagePtr && messageLen) { GWEN_MSG *msg; diff --git a/aqhome/mqtt/msg_mqtt_publish.h b/aqhome/mqtt/msg_mqtt_publish.h index 14c5328..fc84fdc 100644 --- a/aqhome/mqtt/msg_mqtt_publish.h +++ b/aqhome/mqtt/msg_mqtt_publish.h @@ -18,9 +18,9 @@ -AQHOME_API GWEN_MSG *GWEN_PublishMqttMsg_new(uint8_t flags, uint16_t packetId, - const char *sTopic, - const uint8_t *messagePtr, uint32_t messageLen); +AQHOME_API GWEN_MSG *AQH_PublishMqttMsg_new(uint8_t flags, uint16_t packetId, + const char *sTopic, + const uint8_t *messagePtr, uint32_t messageLen); AQHOME_API void AQH_PublishMqttMsg_DumpToBuffer(const GWEN_MSG *msg, GWEN_BUFFER *dbuf, const char *sText); diff --git a/aqhome/msg/0BUILD b/aqhome/msg/0BUILD index 00f5da1..d76353b 100644 --- a/aqhome/msg/0BUILD +++ b/aqhome/msg/0BUILD @@ -45,11 +45,6 @@ - endpointmgr.h - endpoint_node.h - endpoint_log.h - endpoint_write.h - endpoint_tty.h endpoint2_tty.h msg_node.h msg_ping.h @@ -75,24 +70,14 @@ - endpointmgr_p.h - endpoint_node_p.h - endpoint_log_p.h - endpoint_tty_p.h endpoint2_tty_p.h - endpoint_write_p.h $(local/typefiles) - endpointmgr.c - endpoint_node.c - endpoint_log.c - endpoint_tty.c endpoint2_tty.c - endpoint_write.c msg_node.c msg_ping.c msg_pong.c diff --git a/aqhome/msg/endpoint_log.c b/aqhome/msg/endpoint_log.c deleted file mode 100644 index 30c4e78..0000000 --- a/aqhome/msg/endpoint_log.c +++ /dev/null @@ -1,185 +0,0 @@ -/**************************************************************************** - * This file is part of the project AqHome. - * AqHome (c) by 2023 Martin Preuss, all rights reserved. - * - * The license for this file can be found in the file COPYING which you - * should have received along with this file. - ****************************************************************************/ - -#ifdef HAVE_CONFIG_H -# include -#endif - - -#include "aqhome/msg/endpoint_log_p.h" -#include "aqhome/msg/endpoint_node.h" - -#include "aqhome/msg/msg_value.h" -#include "aqhome/msg/msg_value2.h" -#include "aqhome/msg/msg_sendstats.h" -#include "aqhome/msg/msg_recvstats.h" -#include "aqhome/msg/msg_memstats.h" -#include "aqhome/msg/msg_sysstats.h" -#include "aqhome/msg/msg_ping.h" -#include "aqhome/msg/msg_pong.h" -#include "aqhome/msg/msg_needaddr.h" -#include "aqhome/msg/msg_claimaddr.h" -#include "aqhome/msg/msg_haveaddr.h" -#include "aqhome/msg/msg_denyaddr.h" -#include "aqhome/msg/msg_device.h" -#include "aqhome/msg/msg_flashready.h" -#include "aqhome/msg/msg_flashstart.h" -#include "aqhome/msg/msg_flashresponse.h" -#include "aqhome/msg/msg_flashend.h" -#include "aqhome/msg/msg_flashdata.h" -#include "aqhome/msg/msg_reboot.h" - -#include -#include -#include -#include -#include - - -#define AQH_MSG_ENDPOINT_LOG_NAME "log" - - - -GWEN_INHERIT(GWEN_MSG_ENDPOINT, AQH_MSG_ENDPOINT_LOG) - - -static void GWENHYWFAR_CB _freeData(void *bp, void *p); -static void _run(GWEN_MSG_ENDPOINT *ep); -static void _logMessage(GWEN_MSG_ENDPOINT *ep, const GWEN_MSG *msg); -static void _writeToLogFile(const char *filename, const char *txt); - - - - - -GWEN_MSG_ENDPOINT *AQH_LogEndpoint_new(const char *filename, int groupId) -{ - GWEN_MSG_ENDPOINT *ep; - AQH_MSG_ENDPOINT_LOG *xep; - - ep=AQH_NodeEndpoint_new(AQH_MSG_ENDPOINT_LOG_NAME, groupId); - GWEN_NEW_OBJECT(AQH_MSG_ENDPOINT_LOG, xep); - xep->filename=strdup(filename); - GWEN_INHERIT_SETDATA(GWEN_MSG_ENDPOINT, AQH_MSG_ENDPOINT_LOG, ep, xep, _freeData); - AQH_NodeEndpoint_SetAcceptedMsgGroups(ep, AQH_MSG_TYPEGROUP_ALL); - GWEN_MsgEndpoint_AddFlags(ep, GWEN_MSG_ENDPOINT_FLAGS_NOIO); - GWEN_MsgEndpoint_SetRunFn(ep, _run); - - return ep; -} - - - -void _freeData(void *bp, void *p) -{ - AQH_MSG_ENDPOINT_LOG *xep; - - xep=(AQH_MSG_ENDPOINT_LOG*) p; - free(xep->filename); - GWEN_FREE_OBJECT(xep); -} - - - -void _run(GWEN_MSG_ENDPOINT *ep) -{ - GWEN_MSG_LIST *msgList; - - msgList=GWEN_MsgEndpoint_GetSendMessageList(ep); - if (msgList && GWEN_Msg_List_GetCount(msgList)) { - GWEN_MSG *msg; - - msg=GWEN_Msg_List_First(msgList); - while(msg) { - GWEN_MSG *next; - - next=GWEN_Msg_List_Next(msg); - if (GWEN_Msg_GetGroupId(msg)==GWEN_MsgEndpoint_GetGroupId(ep)) - _logMessage(ep, msg); - GWEN_Msg_free(msg); - msg=next; - } - } -} - - - -void _logMessage(GWEN_MSG_ENDPOINT *ep, const GWEN_MSG *msg) -{ - AQH_MSG_ENDPOINT_LOG *xep; - uint8_t msgType; - int msgIsValid; - GWEN_BUFFER *dbuf; - GWEN_TIME *ti; - - xep=GWEN_INHERIT_GETDATA(GWEN_MSG_ENDPOINT, AQH_MSG_ENDPOINT_LOG, ep); - assert(xep); - dbuf=GWEN_Buffer_new(0, 256, 0, 1); - ti=GWEN_CurrentTime(); - GWEN_Time_toString(ti, "YYYY-MM-DD hh:mm:ss ", dbuf); - GWEN_Time_free(ti); - ti=NULL; - - msgIsValid=(AQH_NodeMsg_IsChecksumValid(msg) && AQH_NodeMsg_IsMsgComplete(msg)); - msgType=AQH_NodeMsg_GetMsgType(msg); - - if (msgIsValid) { - switch(msgType) { - case AQH_MSG_TYPE_PING: AQH_PingMsg_DumpToBuffer(msg, dbuf, "received"); break; - case AQH_MSG_TYPE_PONG: AQH_PongMsg_DumpToBuffer(msg, dbuf, "received"); break; - case AQH_MSG_TYPE_COMSENDSTATS: AQH_SendStatsMsg_DumpToBuffer(msg, dbuf, "received"); break; - case AQH_MSG_TYPE_COMRECVSTATS: AQH_RecvStatsMsg_DumpToBuffer(msg, dbuf, "received"); break; - case AQH_MSG_TYPE_TWIBUSMEMBER: AQH_NodeMsg_DumpToBuffer(msg, dbuf, "received"); break; - case AQH_MSG_TYPE_DEBUG: AQH_NodeMsg_DumpToBuffer(msg, dbuf, "received"); break; - case AQH_MSG_TYPE_VALUE: AQH_ValueMsg_DumpToBuffer(msg, dbuf, "received"); break; - case AQH_MSG_TYPE_VALUE2: AQH_Value2Msg_DumpToBuffer(msg, dbuf, "received"); break; - case AQH_MSG_TYPE_NEED_ADDRESS: AQH_NeedAddrMsg_DumpToBuffer(msg, dbuf, "received"); break; - case AQH_MSG_TYPE_CLAIM_ADDRESS: AQH_ClaimAddrMsg_DumpToBuffer(msg, dbuf, "received"); break; - case AQH_MSG_TYPE_HAVE_ADDRESS: AQH_HaveAddrMsg_DumpToBuffer(msg, dbuf, "received"); break; - case AQH_MSG_TYPE_DENY_ADDRESS: AQH_DenyAddrMsg_DumpToBuffer(msg, dbuf, "received"); break; - case AQH_MSG_TYPE_DEVICE: AQH_DeviceMsg_DumpToBuffer(msg, dbuf, "received"); break; - case AQH_MSG_TYPE_MEMSTATS: AQH_MemStatsMsg_DumpToBuffer(msg, dbuf, "received"); break; - case AQH_MSG_TYPE_SYSSTATS: AQH_SysStatsMsg_DumpToBuffer(msg, dbuf, "received"); break; - case AQH_MSG_TYPE_FLASH_READY: AQH_FlashReadyMsg_DumpToBuffer(msg, dbuf, "received"); break; - case AQH_MSG_TYPE_FLASH_START: AQH_FlashStartMsg_DumpToBuffer(msg, dbuf, "received"); break; - case AQH_MSG_TYPE_FLASH_RSP: AQH_FlashResponseMsg_DumpToBuffer(msg, dbuf, "received"); break; - case AQH_MSG_TYPE_FLASH_END: AQH_FlashEndMsg_DumpToBuffer(msg, dbuf, "received"); break; - case AQH_MSG_TYPE_FLASH_DATA: AQH_FlashDataMsg_DumpToBuffer(msg, dbuf, "received"); break; - case AQH_MSG_TYPE_REBOOT_REQ: AQH_RebootRequestMsg_DumpToBuffer(msg, dbuf, "received"); break; - case AQH_MSG_TYPE_REBOOT_RSP: AQH_RebootResponseMsg_DumpToBuffer(msg, dbuf, "received"); break; - default: AQH_NodeMsg_DumpToBuffer(msg, dbuf, "received"); break; - } - } - else { - AQH_NodeMsg_DumpToBuffer(msg, dbuf, "(invalid) received"); - } - _writeToLogFile(xep->filename, GWEN_Buffer_GetStart(dbuf)); - GWEN_Buffer_free(dbuf); -} - - - -void _writeToLogFile(const char *filename, const char *txt) -{ - if (txt && *txt) { - FILE *f; - - f=fopen(filename, "a+"); - if (f) { - if (1!=fwrite(txt, strlen(txt), 1, f)) { - DBG_ERROR(AQH_LOGDOMAIN, "Error logging."); - } - fclose(f); - } - } -} - - - - - diff --git a/aqhome/msg/endpoint_log_p.h b/aqhome/msg/endpoint_log_p.h deleted file mode 100644 index d5d643c..0000000 --- a/aqhome/msg/endpoint_log_p.h +++ /dev/null @@ -1,29 +0,0 @@ -/**************************************************************************** - * This file is part of the project AqHome. - * AqHome (c) by 2023 Martin Preuss, all rights reserved. - * - * The license for this file can be found in the file COPYING which you - * should have received along with this file. - ****************************************************************************/ - -#ifndef AQH_ENDPOINT_LOG_P_H -#define AQH_ENDPOINT_LOG_P_H - - -#include - -#include "aqhome/msg/endpoint_log.h" - -#include -#include - - -typedef struct AQH_MSG_ENDPOINT_LOG AQH_MSG_ENDPOINT_LOG; -struct AQH_MSG_ENDPOINT_LOG { - char *filename; -}; - - - -#endif - diff --git a/aqhome/msg/endpoint_node.c b/aqhome/msg/endpoint_node.c deleted file mode 100644 index 581fecd..0000000 --- a/aqhome/msg/endpoint_node.c +++ /dev/null @@ -1,118 +0,0 @@ -/**************************************************************************** - * This file is part of the project AqHome. - * AqHome (c) by 2023 Martin Preuss, all rights reserved. - * - * The license for this file can be found in the file COPYING which you - * should have received along with this file. - ****************************************************************************/ - -#ifdef HAVE_CONFIG_H -# include -#endif - - -#include "aqhome/msg/endpoint_node_p.h" -#include "aqhome/msg/msg_node.h" - -#include -#include -#include - - - -#define AQH_MSG_ENDPOINT_NODE_NAME "node" - - - - -GWEN_INHERIT(GWEN_MSG_ENDPOINT, AQH_MSG_ENDPOINT_NODE) - - - - -static void GWENHYWFAR_CB _freeData(void *bp, void *p); - - - - - -GWEN_MSG_ENDPOINT *AQH_NodeEndpoint_new(const char *name, int groupId) -{ - GWEN_MSG_ENDPOINT *ep; - - ep=GWEN_MsgEndpoint_new(name?name:AQH_MSG_ENDPOINT_NODE_NAME, groupId); - AQH_NodeEndpoint_Extend(ep); - return ep; -} - - - -void AQH_NodeEndpoint_Extend(GWEN_MSG_ENDPOINT *ep) -{ - AQH_MSG_ENDPOINT_NODE *xep; - - GWEN_NEW_OBJECT(AQH_MSG_ENDPOINT_NODE, xep); - GWEN_INHERIT_SETDATA(GWEN_MSG_ENDPOINT, AQH_MSG_ENDPOINT_NODE, ep, xep, _freeData); -} - - - -void _freeData(void *bp, void *p) -{ - AQH_MSG_ENDPOINT_NODE *xep; - - xep=(AQH_MSG_ENDPOINT_NODE*) p; - GWEN_FREE_OBJECT(xep); -} - - - -uint32_t AQH_NodeEndpoint_GetAcceptedMsgGroups(const GWEN_MSG_ENDPOINT *ep) -{ - const AQH_MSG_ENDPOINT_NODE *xep; - - xep=GWEN_INHERIT_GETDATA(GWEN_MSG_ENDPOINT, AQH_MSG_ENDPOINT_NODE, ep); - assert(xep); - if (xep) - return xep->acceptedMsgGroups; - return 0; -} - - - -void AQH_NodeEndpoint_SetAcceptedMsgGroups(GWEN_MSG_ENDPOINT *ep, uint32_t f) -{ - AQH_MSG_ENDPOINT_NODE *xep; - - xep=GWEN_INHERIT_GETDATA(GWEN_MSG_ENDPOINT, AQH_MSG_ENDPOINT_NODE, ep); - assert(xep); - if (xep) - xep->acceptedMsgGroups=f; -} - - - -void AQH_NodeEndpoint_AddAcceptedMsgGroups(GWEN_MSG_ENDPOINT *ep, uint32_t f) -{ - AQH_MSG_ENDPOINT_NODE *xep; - - xep=GWEN_INHERIT_GETDATA(GWEN_MSG_ENDPOINT, AQH_MSG_ENDPOINT_NODE, ep); - assert(xep); - if (xep) - xep->acceptedMsgGroups|=f; -} - - - -void AQH_NodeEndpoint_DelAcceptedMsgGroups(GWEN_MSG_ENDPOINT *ep, uint32_t f) -{ - AQH_MSG_ENDPOINT_NODE *xep; - - xep=GWEN_INHERIT_GETDATA(GWEN_MSG_ENDPOINT, AQH_MSG_ENDPOINT_NODE, ep); - assert(xep); - if (xep) - xep->acceptedMsgGroups&=~f; -} - - - diff --git a/aqhome/msg/endpoint_node.h b/aqhome/msg/endpoint_node.h deleted file mode 100644 index 3c8fdda..0000000 --- a/aqhome/msg/endpoint_node.h +++ /dev/null @@ -1,32 +0,0 @@ -/**************************************************************************** - * This file is part of the project AqHome. - * AqHome (c) by 2023 Martin Preuss, all rights reserved. - * - * The license for this file can be found in the file COPYING which you - * should have received along with this file. - ****************************************************************************/ - -#ifndef AQH_MSGENDPOINT_NODE_H -#define AQH_MSGENDPOINT_NODE_H - - -#include - -#include - - -#define AQH_MSGEP_NODE_FLAGS_NOMESSAGES 0x0002 - - - -AQHOME_API GWEN_MSG_ENDPOINT *AQH_NodeEndpoint_new(const char *name, int groupId); -AQHOME_API void AQH_NodeEndpoint_Extend(GWEN_MSG_ENDPOINT *ep); - -AQHOME_API uint32_t AQH_NodeEndpoint_GetAcceptedMsgGroups(const GWEN_MSG_ENDPOINT *ep); -AQHOME_API void AQH_NodeEndpoint_SetAcceptedMsgGroups(GWEN_MSG_ENDPOINT *ep, uint32_t f); -AQHOME_API void AQH_NodeEndpoint_AddAcceptedMsgGroups(GWEN_MSG_ENDPOINT *ep, uint32_t f); -AQHOME_API void AQH_NodeEndpoint_DelAcceptedMsgGroups(GWEN_MSG_ENDPOINT *ep, uint32_t f); - - - -#endif diff --git a/aqhome/msg/endpoint_tty.c b/aqhome/msg/endpoint_tty.c deleted file mode 100644 index e567d23..0000000 --- a/aqhome/msg/endpoint_tty.c +++ /dev/null @@ -1,449 +0,0 @@ -/**************************************************************************** - * This file is part of the project AqHome. - * AqHome (c) by 2023 Martin Preuss, all rights reserved. - * - * The license for this file can be found in the file COPYING which you - * should have received along with this file. - ****************************************************************************/ - -#ifdef HAVE_CONFIG_H -# include -#endif - - -#include "aqhome/msg/endpoint_tty_p.h" -#include "aqhome/msg/endpoint_node.h" -#include "aqhome/msg/msg_node.h" - -#include -#include -#include -#include - -#include -#include -#include -#include -#include - - -#define AQH_MSG_ENDPOINT_TTY_BAUDRATE B19200 -#define AQH_MSG_ENDPOINT_TTY_BYTE_MICROSECS 520 - -#define AQH_MSG_ENDPOINT_TTY_BUFFERSIZE 128 - - - -GWEN_INHERIT(GWEN_MSG_ENDPOINT, AQH_MSG_ENDPOINT_TTY) - - - - -static int _handleReadable(GWEN_MSG_ENDPOINT *ep, GWEN_UNUSED GWEN_MSG_ENDPOINT_MGR *emgr); -static int _handleWritable(GWEN_MSG_ENDPOINT *ep, GWEN_UNUSED GWEN_MSG_ENDPOINT_MGR *emgr); - -static void GWENHYWFAR_CB _freeData(void *bp, void *p); - -static int _connect(GWEN_MSG_ENDPOINT *ep); -static int _startMsg(GWEN_MSG_ENDPOINT *ep); -static int _endMsg(GWEN_MSG_ENDPOINT *ep); -static int _isLineBusy(GWEN_MSG_ENDPOINT *ep); - -static int _openDevice(GWEN_MSG_ENDPOINT *ep); -static int _attnLow(GWEN_MSG_ENDPOINT *ep); -static int _attnHigh(GWEN_MSG_ENDPOINT *ep); -static int _isAttnLow(GWEN_MSG_ENDPOINT *ep); - - - - - -GWEN_MSG_ENDPOINT *AQH_TtyNodeEndpoint_new(const char *devicePath, int groupId) -{ - GWEN_MSG_ENDPOINT *ep; - AQH_MSG_ENDPOINT_TTY *xep; - - ep=AQH_NodeEndpoint_new(AQH_MSG_ENDPOINT_TTY_NAME, groupId); - - GWEN_ConnectableMsgEndpoint_Extend(ep); - GWEN_ConnectableMsgEndpoint_SetReconnectWaitTime(ep, 5); - - GWEN_NEW_OBJECT(AQH_MSG_ENDPOINT_TTY, xep); - GWEN_INHERIT_SETDATA(GWEN_MSG_ENDPOINT, AQH_MSG_ENDPOINT_TTY, ep, xep, _freeData); - - AQH_NodeEndpoint_SetAcceptedMsgGroups(ep, AQH_MSG_TYPEGROUP_ALL); - - GWEN_MsgEndpoint_SetHandleReadableFn(ep, _handleReadable); - GWEN_MsgEndpoint_SetHandleWritableFn(ep, _handleWritable); - GWEN_ConnectableMsgEndpoint_SetConnectFn(ep, _connect); - - xep->deviceName=strdup(devicePath); - - return ep; -} - - - -void _freeData(void *bp, void *p) -{ - AQH_MSG_ENDPOINT_TTY *xep; - - xep=(AQH_MSG_ENDPOINT_TTY*) p; - free(xep->deviceName); - GWEN_FREE_OBJECT(xep); -} - - - -int _connect(GWEN_MSG_ENDPOINT *ep) -{ - AQH_MSG_ENDPOINT_TTY *xep; - - xep=GWEN_INHERIT_GETDATA(GWEN_MSG_ENDPOINT, AQH_MSG_ENDPOINT_TTY, ep); - if (xep) { - int state; - - state=GWEN_ConnectableMsgEndpoint_GetState(ep); - if (statedeviceName); - fd=_openDevice(ep); - if (fd<0) { - DBG_INFO(NULL, "here (%d)", fd); - return fd; - } - GWEN_MsgEndpoint_SetFd(ep, fd); - GWEN_ConnectableMsgEndpoint_SetState(ep, GWEN_MSG_ENDPOINT_CONN_STATE_CONNECTED); - _attnHigh(ep); - } - return 0; - } - - return GWEN_ERROR_GENERIC; -} - - - -int _handleReadable(GWEN_MSG_ENDPOINT *ep, GWEN_UNUSED GWEN_MSG_ENDPOINT_MGR *emgr) -{ - int rv; - uint8_t buffer[AQH_MSG_ENDPOINT_TTY_BUFFERSIZE]; - int len; - int i; - - DBG_DEBUG(GWEN_LOGDOMAIN, "Reading from endpoint %s", GWEN_MsgEndpoint_GetName(ep)); - do { - rv=read(GWEN_MsgEndpoint_GetFd(ep), buffer, sizeof(buffer)); - } while( (rv<0) && errno==EINTR); - if (rv<0) { - if (errno==EAGAIN || errno==EWOULDBLOCK) - return GWEN_ERROR_TRY_AGAIN; - DBG_INFO(GWEN_LOGDOMAIN, "Error on read(): %s (%d)", strerror(errno), errno); - return GWEN_ERROR_IO; - } - else if (rv==0) { - DBG_INFO(GWEN_LOGDOMAIN, "EOF met on read()"); - return GWEN_ERROR_IO; - } - len=rv; - - for (i=0; i0) { - /* complete msg received, add to list */ - if (!AQH_NodeMsg_IsChecksumValid(msg)) { - DBG_ERROR(AQH_LOGDOMAIN, "Invalid checksum, discarding message"); - GWEN_Text_DumpString((const char*) GWEN_Msg_GetBuffer(msg), GWEN_Msg_GetBytesInBuffer(msg), 6); - GWEN_MsgEndpoint_SetCurrentlyReceivedMsg(ep, NULL); - rv=GWEN_MsgEndpoint_DiscardInput(ep); - if (rv<0) { - DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); - return rv; - } - } - else { - GWEN_Msg_Attach(msg); - GWEN_MsgEndpoint_SetCurrentlyReceivedMsg(ep, NULL); - GWEN_MsgEndpoint_AddReceivedMessage(ep, msg); - } - } - } /* for */ - - return 0; -} - - - -int _handleWritable(GWEN_MSG_ENDPOINT *ep, GWEN_UNUSED GWEN_MSG_ENDPOINT_MGR *emgr) -{ - GWEN_MSG *msg; - - DBG_DEBUG(AQH_LOGDOMAIN, "Writing to endpoint %s", GWEN_MsgEndpoint_GetName(ep)); - msg=GWEN_MsgEndpoint_GetFirstSendMessage(ep); - if (msg) { - uint8_t pos; - int remaining; - int rv; - - pos=GWEN_Msg_GetCurrentPos(msg); - remaining=GWEN_Msg_GetRemainingBytes(msg); - if (remaining>0) { - const uint8_t *buf; - int fd; - - if (pos==0) { - /* start new message */ - rv=_isLineBusy(ep); - if (rv<0 || rv==1) { - DBG_INFO(AQH_LOGDOMAIN, "Line busy, not sending"); - usleep(100); - return 0; - } - rv=_startMsg(ep); - if (rv<0) { - DBG_INFO(AQH_LOGDOMAIN, "here (%d)", rv); - return rv; - } - } - - fd=GWEN_MsgEndpoint_GetFd(ep); - /* start new message */ - buf=GWEN_Msg_GetBuffer(msg)+pos; - do { - rv=write(fd, buf, remaining); - } while(rv<0 && errno==EINTR); - if (rv<0) { - if (errno==EAGAIN || errno==EWOULDBLOCK) - return GWEN_ERROR_TRY_AGAIN; - DBG_INFO(GWEN_LOGDOMAIN, "Error on write(): %s (%d)", strerror(errno), errno); - return GWEN_ERROR_IO; - } - GWEN_Msg_IncCurrentPos(msg, rv); - if (rv==remaining) { - /* end current message */ - rv=_endMsg(ep); - GWEN_Msg_List_Del(msg); - GWEN_Msg_free(msg); - if (rv<0) { - DBG_INFO(AQH_LOGDOMAIN, "here (%d)", rv); - return rv; - } - } - } - else { - DBG_INFO(AQH_LOGDOMAIN, "No remaining bytes in msg"); - } - } - return 0; -} - - - -int _openDevice(GWEN_MSG_ENDPOINT *ep) -{ - AQH_MSG_ENDPOINT_TTY *xep; - int fd; - struct termios options; - int rv; - - xep=GWEN_INHERIT_GETDATA(GWEN_MSG_ENDPOINT, AQH_MSG_ENDPOINT_TTY, ep); - assert(xep); - fd=open(xep->deviceName, O_NOCTTY | O_NDELAY | O_RDWR); - if (fd<0) { - DBG_ERROR(AQH_LOGDOMAIN, "Error on open(%s): %s (%d)", xep->deviceName, strerror(errno), errno); - return GWEN_ERROR_IO; - } - rv=tcgetattr(fd, &(xep->previousOptions)); - if (rv<0) { - DBG_ERROR(AQH_LOGDOMAIN, "Error on tcgetattr(%s): %s (%d)", xep->deviceName, strerror(errno), errno); - return GWEN_ERROR_IO; - } - memset(&options, 0, sizeof(options)); /* preset */ - - options.c_cflag=CLOCAL | CREAD | CS8; - options.c_iflag=IGNPAR | IGNBRK; - options.c_oflag=0; - options.c_lflag=0; - cfmakeraw(&options); - options.c_cc[VTIME]=0; /* read timeout in deciseconds */ - options.c_cc[VMIN]=0; /* no minimum number of receive bytes */ - - rv=cfsetispeed(&options, AQH_MSG_ENDPOINT_TTY_BAUDRATE); - if (rv<0) { - DBG_ERROR(AQH_LOGDOMAIN, "Error on cfsetispeed(%s): %s (%d)", xep->deviceName, strerror(errno), errno); - return GWEN_ERROR_IO; - } - rv=cfsetospeed(&options, AQH_MSG_ENDPOINT_TTY_BAUDRATE); - if (rv<0) { - DBG_ERROR(AQH_LOGDOMAIN, "Error on cfsetospeed(%s): %s (%d)", xep->deviceName, strerror(errno), errno); - return GWEN_ERROR_IO; - } - - rv=tcflush(fd, TCIOFLUSH); - if (rv<0) { - DBG_ERROR(AQH_LOGDOMAIN, "Error on tcflush(%s): %s (%d)", xep->deviceName, strerror(errno), errno); - return GWEN_ERROR_IO; - } - - rv=tcsetattr(fd, TCSANOW, &options); - if (rv<0) { - DBG_ERROR(AQH_LOGDOMAIN, "Error on tcsetattr(%s): %s (%d)", xep->deviceName, strerror(errno), errno); - return GWEN_ERROR_IO; - } - - return fd; -} - - - -int _startMsg(GWEN_MSG_ENDPOINT *ep) -{ - AQH_MSG_ENDPOINT_TTY *xep; - - xep=GWEN_INHERIT_GETDATA(GWEN_MSG_ENDPOINT, AQH_MSG_ENDPOINT_TTY, ep); - assert(xep); - if (xep->intendedAttnState==1) { - int rv; - - rv=_attnLow(ep); - if (rv<0) { - DBG_ERROR(AQH_LOGDOMAIN, "here (%d)", rv); - return rv; - } - usleep(AQH_MSG_ENDPOINT_TTY_BYTE_MICROSECS/5); - } - - return 0; -} - - - -int _endMsg(GWEN_MSG_ENDPOINT *ep) -{ - /* TODO: flush before releasing ATTN */ - _attnHigh(ep); - return 0; -} - - - -int _isLineBusy(GWEN_MSG_ENDPOINT *ep) -{ - AQH_MSG_ENDPOINT_TTY *xep; - - xep=GWEN_INHERIT_GETDATA(GWEN_MSG_ENDPOINT, AQH_MSG_ENDPOINT_TTY, ep); - assert(xep); - if (xep->intendedAttnState==0) { - /* we pulled the line low ourselves, and because of the circuitry nobody can pull it high */ - return 0; - } - return _isAttnLow(ep); -} - - - -int _attnLow(GWEN_MSG_ENDPOINT *ep) -{ - AQH_MSG_ENDPOINT_TTY *xep; - int status; - int rv; - int fd; - - xep=GWEN_INHERIT_GETDATA(GWEN_MSG_ENDPOINT, AQH_MSG_ENDPOINT_TTY, ep); - assert(xep); - fd=GWEN_MsgEndpoint_GetFd(ep); - rv=ioctl(fd, TIOCMGET, &status); /* GET the State of MODEM bits in Status */ - if (rv<0) { - DBG_ERROR(AQH_LOGDOMAIN, "Error on ioctl(%s): %s (%d)", xep->deviceName, strerror(errno), errno); - return GWEN_ERROR_IO; - } - status |= TIOCM_DTR | TIOCM_RTS; /* clear the DTR pin (cave: signals inverted!) */ - rv=ioctl(fd, TIOCMSET, &status); - if (rv<0) { - DBG_ERROR(AQH_LOGDOMAIN, "Error on ioctl(%s): %s (%d)", xep->deviceName, strerror(errno), errno); - return GWEN_ERROR_IO; - } - xep->intendedAttnState=0; - return 0; -} - - - -int _attnHigh(GWEN_MSG_ENDPOINT *ep) -{ - AQH_MSG_ENDPOINT_TTY *xep; - int status; - int rv; - int fd; - - xep=GWEN_INHERIT_GETDATA(GWEN_MSG_ENDPOINT, AQH_MSG_ENDPOINT_TTY, ep); - assert(xep); - fd=GWEN_MsgEndpoint_GetFd(ep); - rv=ioctl(fd, TIOCMGET, &status); - if (rv<0) { - DBG_ERROR(AQH_LOGDOMAIN, "Error on ioctl(%s): %s (%d)", xep->deviceName, strerror(errno), errno); - return GWEN_ERROR_IO; - } - status |= TIOCM_DTR; /* Set the DTR pin */ - status &= ~ (TIOCM_DTR | TIOCM_RTS); /* clear the DTR pin (cave: signals inverted!) */ - rv=ioctl(fd, TIOCMSET, &status); - if (rv<0) { - DBG_ERROR(AQH_LOGDOMAIN, "Error on ioctl(%s): %s (%d)", xep->deviceName, strerror(errno), errno); - return GWEN_ERROR_IO; - } - - xep->intendedAttnState=1; - return 0; -} - - - -int _isAttnLow(GWEN_MSG_ENDPOINT *ep) -{ - AQH_MSG_ENDPOINT_TTY *xep; - int status; - int rv; - int fd; - - xep=GWEN_INHERIT_GETDATA(GWEN_MSG_ENDPOINT, AQH_MSG_ENDPOINT_TTY, ep); - assert(xep); - fd=GWEN_MsgEndpoint_GetFd(ep); - rv=ioctl(fd, TIOCMGET, &status); - if (rv<0) { - DBG_ERROR(AQH_LOGDOMAIN, "Error on ioctl(%s): %s (%d)", xep->deviceName, strerror(errno), errno); - return GWEN_ERROR_IO; - } - return (status & TIOCM_CTS)?1:0; -} - - - - - - - diff --git a/aqhome/msg/endpoint_tty.h b/aqhome/msg/endpoint_tty.h deleted file mode 100644 index a7a47db..0000000 --- a/aqhome/msg/endpoint_tty.h +++ /dev/null @@ -1,24 +0,0 @@ -/**************************************************************************** - * This file is part of the project AqHome. - * AqHome (c) by 2023 Martin Preuss, all rights reserved. - * - * The license for this file can be found in the file COPYING which you - * should have received along with this file. - ****************************************************************************/ - -#ifndef AQH_MSGENDPOINT_TTY_H -#define AQH_MSGENDPOINT_TTY_H - - -#include - -#include - - -#define AQH_MSG_ENDPOINT_TTY_NAME "tty" - - -AQHOME_API GWEN_MSG_ENDPOINT *AQH_TtyNodeEndpoint_new(const char *devicePath, int groupId); - - -#endif diff --git a/aqhome/msg/endpoint_tty_p.h b/aqhome/msg/endpoint_tty_p.h deleted file mode 100644 index c6d84ef..0000000 --- a/aqhome/msg/endpoint_tty_p.h +++ /dev/null @@ -1,32 +0,0 @@ -/**************************************************************************** - * This file is part of the project AqHome. - * AqHome (c) by 2023 Martin Preuss, all rights reserved. - * - * The license for this file can be found in the file COPYING which you - * should have received along with this file. - ****************************************************************************/ - -#ifndef AQH_MSGENDPOINT_TTY_P_H -#define AQH_MSGENDPOINT_TTY_P_H - - -#include - -#include "aqhome/msg/endpoint_tty.h" - -#include - - - - -typedef struct AQH_MSG_ENDPOINT_TTY AQH_MSG_ENDPOINT_TTY; -struct AQH_MSG_ENDPOINT_TTY { - char *deviceName; - struct termios previousOptions; - int intendedAttnState; -}; - - - - -#endif diff --git a/aqhome/msg/endpoint_write.c b/aqhome/msg/endpoint_write.c deleted file mode 100644 index 2dcac2a..0000000 --- a/aqhome/msg/endpoint_write.c +++ /dev/null @@ -1,268 +0,0 @@ -/**************************************************************************** - * This file is part of the project AqHome. - * AqHome (c) by 2023 Martin Preuss, all rights reserved. - * - * The license for this file can be found in the file COPYING which you - * should have received along with this file. - ****************************************************************************/ - -#ifdef HAVE_CONFIG_H -# include -#endif - - -#include "aqhome/msg/endpoint_write_p.h" -#include "aqhome/msg/endpoint_node.h" - -#include "aqhome/msg/msg_value2.h" -#include "aqhome/msg/msg_sendstats.h" -#include "aqhome/msg/msg_recvstats.h" -#include "aqhome/msg/msg_memstats.h" -#include "aqhome/msg/msg_sysstats.h" - -#include -#include -#include -#include -#include -#include - -#include -#include - - - -#define AQH_MSG_ENDPOINT_WRITE_NAME "write" - - - -GWEN_INHERIT(GWEN_MSG_ENDPOINT, AQH_MSG_ENDPOINT_WRITE) - - -static void GWENHYWFAR_CB _freeData(void *bp, void *p); -static void _processOutMessage(GWEN_MSG_ENDPOINT *ep, GWEN_MSG *nodeMsg); -static void _processValue2Message(GWEN_MSG_ENDPOINT *ep, GWEN_MSG *nodeMsg); -static void _processSendStatsMessage(GWEN_MSG_ENDPOINT *ep, GWEN_MSG *nodeMsg); -static void _processRecvStatsMessage(GWEN_MSG_ENDPOINT *ep, GWEN_MSG *nodeMsg); -static void _writeDouble(GWEN_MSG_ENDPOINT *ep, uint32_t uid, int valueId, const char *valuePath, double v); -static void _writeInt(GWEN_MSG_ENDPOINT *ep, uint32_t uid, int valueId, const char *valuePath, int v); -static void _writeString(GWEN_MSG_ENDPOINT *ep, uint32_t uid, int valueId, const char *valuePath, const char *v); -static void _writeToFile(const char *filename, const char *txt); - - - - - -GWEN_MSG_ENDPOINT *AQH_WriteEndpoint_new(const char *folder, int groupId) -{ - GWEN_MSG_ENDPOINT *ep; - AQH_MSG_ENDPOINT_WRITE *xep; - - ep=AQH_NodeEndpoint_new(AQH_MSG_ENDPOINT_WRITE_NAME, groupId); - GWEN_NEW_OBJECT(AQH_MSG_ENDPOINT_WRITE, xep); - xep->folder=strdup(folder); - GWEN_INHERIT_SETDATA(GWEN_MSG_ENDPOINT, AQH_MSG_ENDPOINT_WRITE, ep, xep, _freeData); - AQH_NodeEndpoint_SetAcceptedMsgGroups(ep, AQH_MSG_TYPEGROUP_INFO | AQH_MSG_TYPEGROUP_VALUES); - GWEN_MsgEndpoint_AddFlags(ep, GWEN_MSG_ENDPOINT_FLAGS_NOIO); - GWEN_MsgEndpoint_SetProcessOutMsgFn(ep, _processOutMessage); - - return ep; -} - - - -void _freeData(void *bp, void *p) -{ - AQH_MSG_ENDPOINT_WRITE *xep; - - xep=(AQH_MSG_ENDPOINT_WRITE*) p; - free(xep->folder); - GWEN_FREE_OBJECT(xep); -} - - - -void _processOutMessage(GWEN_MSG_ENDPOINT *ep, GWEN_MSG *nodeMsg) -{ - DBG_DEBUG(AQH_LOGDOMAIN, "Processing output message"); - switch(AQH_NodeMsg_GetMsgType(nodeMsg)) { - case AQH_MSG_TYPE_VALUE2: - _processValue2Message(ep, nodeMsg); - break; - case AQH_MSG_TYPE_COMSENDSTATS: - _processSendStatsMessage(ep, nodeMsg); - break; - case AQH_MSG_TYPE_COMRECVSTATS: - _processRecvStatsMessage(ep, nodeMsg); - break; - default: - break; - } - GWEN_Msg_free(nodeMsg); -} - - - - -void _processValue2Message(GWEN_MSG_ENDPOINT *ep, GWEN_MSG *nodeMsg) -{ - const char *sType; - - sType=AQH_Value2Msg_GetValueTypeName(nodeMsg); - if (sType && *sType) { - if (AQH_Value2Msg_GetValueType(nodeMsg)==AQH_MSG_VALUE2_TYPE_DOOR) - _writeString(ep, - AQH_Value2Msg_GetUid(nodeMsg), - AQH_Value2Msg_GetValueId(nodeMsg), - sType, - AQH_Value2Msg_GetValueAsWindowStateString(nodeMsg)); - else - _writeDouble(ep, - AQH_Value2Msg_GetUid(nodeMsg), - AQH_Value2Msg_GetValueId(nodeMsg), - sType, - AQH_Value2Msg_GetValue(nodeMsg)); - } - _writeDouble(ep, - AQH_Value2Msg_GetUid(nodeMsg), - AQH_Value2Msg_GetValueId(nodeMsg), - "value", - AQH_Value2Msg_GetValue(nodeMsg)); -} - - - -void _processSendStatsMessage(GWEN_MSG_ENDPOINT *ep, GWEN_MSG *nodeMsg) -{ - uint16_t packetsOutInt; - - packetsOutInt=AQH_SendStatsMsg_GetPacketsOut(nodeMsg); - if (packetsOutInt) { - double packetsOut; - double collisions; - double busy; - double collisionsPercentage=0.0; - double busyPercentage=0.0; - - packetsOut=(double) packetsOutInt; - collisions=(double)AQH_SendStatsMsg_GetCollisions(nodeMsg); - busy=(double)AQH_SendStatsMsg_GetBusyErrors(nodeMsg); - - collisionsPercentage=collisions*100.0/packetsOut; - busyPercentage=busy*100.0/packetsOut; - - _writeInt(ep, AQH_SendStatsMsg_GetUid(nodeMsg), 0, "net/packetsOut", packetsOutInt); - _writeInt(ep, AQH_SendStatsMsg_GetUid(nodeMsg), 0, "net/collisions", (int) AQH_SendStatsMsg_GetCollisions(nodeMsg)); - _writeDouble(ep, AQH_SendStatsMsg_GetUid(nodeMsg), 0, "net/collisionsPercent", collisionsPercentage); - _writeDouble(ep, AQH_SendStatsMsg_GetUid(nodeMsg), 0, "net/busyPercent", busyPercentage); - } -} - - - -void _processRecvStatsMessage(GWEN_MSG_ENDPOINT *ep, GWEN_MSG *nodeMsg) -{ - uint16_t packetsInInt; - - packetsInInt=AQH_RecvStatsMsg_GetPacketsIn(nodeMsg); - if (packetsInInt) { - double packetsIn; - double crcErrors; - double ioErrors; - double crcErrorsPercentage=0.0; - double ioErrorsPercentage=0.0; - - packetsIn=(double) packetsInInt; - crcErrors=(double)AQH_RecvStatsMsg_GetCrcErrors(nodeMsg); - ioErrors=(double)AQH_RecvStatsMsg_GetIoErrors(nodeMsg); - - crcErrorsPercentage=crcErrors*100.0/packetsIn; - ioErrorsPercentage=ioErrors*100.0/packetsIn; - - _writeInt(ep, AQH_RecvStatsMsg_GetUid(nodeMsg), 0, "net/packetsIn", packetsInInt); - _writeInt(ep, AQH_RecvStatsMsg_GetUid(nodeMsg), 0, "net/crcerrors", (int) AQH_RecvStatsMsg_GetCrcErrors(nodeMsg)); - _writeInt(ep, AQH_RecvStatsMsg_GetUid(nodeMsg), 0, "net/ioerrors", (int) AQH_RecvStatsMsg_GetIoErrors(nodeMsg)); - _writeDouble(ep, AQH_RecvStatsMsg_GetUid(nodeMsg), 0, "net/crcerrorsPercent", crcErrorsPercentage); - _writeDouble(ep, AQH_RecvStatsMsg_GetUid(nodeMsg), 0, "net/ioerrorsPercent", ioErrorsPercentage); - } -} - - - -void _writeDouble(GWEN_MSG_ENDPOINT *ep, uint32_t uid, int valueId, const char *valuePath, double v) -{ - char numBuf[16]; - - snprintf(numBuf, sizeof(numBuf)-1, "%f", v); - numBuf[sizeof(numBuf)-1]=0; - _writeString(ep, uid, valueId, valuePath, numBuf); -} - - - -void _writeInt(GWEN_MSG_ENDPOINT *ep, uint32_t uid, int valueId, const char *valuePath, int v) -{ - char numBuf[16]; - - snprintf(numBuf, sizeof(numBuf)-1, "%d", v); - numBuf[sizeof(numBuf)-1]=0; - _writeString(ep, uid, valueId, valuePath, numBuf); -} - - - -void _writeString(GWEN_MSG_ENDPOINT *ep, uint32_t uid, int valueId, const char *valuePath, const char *v) -{ - AQH_MSG_ENDPOINT_WRITE *xep; - GWEN_BUFFER *bufFilename; - - xep=GWEN_INHERIT_GETDATA(GWEN_MSG_ENDPOINT, AQH_MSG_ENDPOINT_WRITE, ep); - - bufFilename=GWEN_Buffer_new(0, 64, 0, 1); - if (valueId>0) - GWEN_Buffer_AppendArgs(bufFilename, "%s/%08x/%d/%s", xep->folder, uid, valueId, valuePath); - else - GWEN_Buffer_AppendArgs(bufFilename, "%s/%08x/%s", xep->folder, uid, valuePath); - _writeToFile(GWEN_Buffer_GetStart(bufFilename), v); - GWEN_Buffer_free(bufFilename); -} - - - -void _writeToFile(const char *filename, const char *txt) -{ - if (txt && *txt) { - GWEN_BUFFER *tmpNameBuf; - int rv; - - tmpNameBuf=GWEN_Buffer_new(0, 256, 0, 1); - GWEN_Buffer_AppendString(tmpNameBuf, filename); - GWEN_Buffer_AppendString(tmpNameBuf, ".tmp"); - - rv=GWEN_Directory_GetPath(GWEN_Buffer_GetStart(tmpNameBuf), GWEN_PATH_FLAGS_VARIABLE); - if (rv<0) { - DBG_INFO(AQH_LOGDOMAIN, "Error getting path for %s (%d)", GWEN_Buffer_GetStart(tmpNameBuf), rv); - } - else { - FILE *f; - - f=fopen(GWEN_Buffer_GetStart(tmpNameBuf), "w"); - if (f) { - if (1!=fwrite(txt, strlen(txt), 1, f)) { - DBG_ERROR(AQH_LOGDOMAIN, "Error writing."); - fclose(f); - } - else { - fclose(f); - rename(GWEN_Buffer_GetStart(tmpNameBuf), filename); - } - } - } - GWEN_Buffer_free(tmpNameBuf); - } -} - - - - - diff --git a/aqhome/msg/endpoint_write_p.h b/aqhome/msg/endpoint_write_p.h deleted file mode 100644 index 57639cd..0000000 --- a/aqhome/msg/endpoint_write_p.h +++ /dev/null @@ -1,29 +0,0 @@ -/**************************************************************************** - * This file is part of the project AqHome. - * AqHome (c) by 2023 Martin Preuss, all rights reserved. - * - * The license for this file can be found in the file COPYING which you - * should have received along with this file. - ****************************************************************************/ - -#ifndef AQH_ENDPOINT_WRITE_P_H -#define AQH_ENDPOINT_WRITE_P_H - - -#include - -#include "aqhome/msg/endpoint_write.h" - -#include -#include - - -typedef struct AQH_MSG_ENDPOINT_WRITE AQH_MSG_ENDPOINT_WRITE; -struct AQH_MSG_ENDPOINT_WRITE { - char *folder; -}; - - - -#endif - diff --git a/aqhome/msg/endpointmgr.c b/aqhome/msg/endpointmgr.c deleted file mode 100644 index 5df57cd..0000000 --- a/aqhome/msg/endpointmgr.c +++ /dev/null @@ -1,138 +0,0 @@ -/**************************************************************************** - * This file is part of the project AqHome. - * AqHome (c) by 2023 Martin Preuss, all rights reserved. - * - * The license for this file can be found in the file COPYING which you - * should have received along with this file. - ****************************************************************************/ - -#ifdef HAVE_CONFIG_H -# include -#endif - - -#include "aqhome/msg/endpointmgr_p.h" -#include "aqhome/msg/msg_node.h" -#include "aqhome/msg/endpoint_node.h" - -#include -#include - - - - -GWEN_INHERIT(GWEN_MSG_ENDPOINT_MGR, AQH_MSG_ENDPOINT_MGR); - - - -static void GWENHYWFAR_CB _freeData(void *bp, void *p); - - - - - -GWEN_MSG_ENDPOINT_MGR *AQH_MsgEndpointMgr_new(uint8_t busAddr) -{ - GWEN_MSG_ENDPOINT_MGR *mgr; - AQH_MSG_ENDPOINT_MGR *xmgr; - - mgr=GWEN_MsgEndpointMgr_new(); - GWEN_NEW_OBJECT(AQH_MSG_ENDPOINT_MGR, xmgr); - GWEN_INHERIT_SETDATA(GWEN_MSG_ENDPOINT_MGR, AQH_MSG_ENDPOINT_MGR, mgr, xmgr, _freeData); - xmgr->busAddr=busAddr; - - return mgr; -} - - - -void _freeData(void *bp, void *p) -{ - AQH_MSG_ENDPOINT_MGR *xmgr; - - xmgr=(AQH_MSG_ENDPOINT_MGR*) p; - GWEN_FREE_OBJECT(xmgr); -} - - - -uint8_t AQH_MsgEndpointMgr_GetBusAddr(GWEN_MSG_ENDPOINT_MGR *emgr) -{ - AQH_MSG_ENDPOINT_MGR *xmgr; - - xmgr=GWEN_INHERIT_GETDATA(GWEN_MSG_ENDPOINT_MGR, AQH_MSG_ENDPOINT_MGR, emgr); - if (xmgr) - return xmgr->busAddr; - return 0; -} - - - -void AQH_MsgEndpointMgr_DistributeMsgFromNodeEndpoint(GWEN_MSG_ENDPOINT_MGR *emgr, - GWEN_MSG_ENDPOINT *srcEp, - const GWEN_MSG *msg, - int groupId, - const char *wantedTypeName) -{ - GWEN_MSG_ENDPOINT_LIST *endpointList; - - endpointList=GWEN_MsgEndpointMgr_GetEndpointList(emgr); - if (endpointList) { - GWEN_MSG_ENDPOINT *ep; - uint32_t msgGroup; - - msgGroup=AQH_NodeMsg_GetMsgGroup(AQH_NodeMsg_GetMsgType(msg)); - - ep=GWEN_MsgEndpoint_List_First(endpointList); - while(ep) { - if (ep!=srcEp) { - const char *epTypeName; - - epTypeName=GWEN_MsgEndpoint_GetName(ep); - if (wantedTypeName==NULL || (wantedTypeName && epTypeName && strcasecmp(epTypeName, wantedTypeName)==0)) { - if (!(GWEN_MsgEndpoint_GetFlags(ep) & AQH_MSGEP_NODE_FLAGS_NOMESSAGES)) { - int acceptedGroupIds; - uint32_t acceptedMsgGroups; - - acceptedGroupIds=GWEN_MsgEndpoint_GetAcceptedGroupIds(ep); - acceptedMsgGroups=AQH_NodeEndpoint_GetAcceptedMsgGroups(ep); - - DBG_DEBUG(AQH_LOGDOMAIN, "- checking endpoint %s (msgGroup=%08x, accept: %08x, flags: %08x)", - GWEN_MsgEndpoint_GetName(ep), - msgGroup, acceptedMsgGroups, - GWEN_MsgEndpoint_GetFlags(ep)); - if (acceptedGroupIds & groupId) { - if ((msgGroup & acceptedMsgGroups)) { - /* endpoint accepts this message */ - DBG_DEBUG(AQH_LOGDOMAIN, " - endpoint %s accepts message", GWEN_MsgEndpoint_GetName(ep)); - GWEN_MsgEndpoint_ProcessOutMessage(ep, GWEN_Msg_dup(msg)); - } - else { - DBG_DEBUG(AQH_LOGDOMAIN, " - endpoint %s does not accept message", GWEN_MsgEndpoint_GetName(ep)); - } - } /* if (acceptedGroupIds & groupId) */ - else { - DBG_DEBUG(AQH_LOGDOMAIN, "Endpoint %s does not contain groupId %d (%d)", - GWEN_MsgEndpoint_GetName(ep), groupId, acceptedGroupIds); - } - } /* !(GWEN_MsgEndpoint_GetFlags(ep) & AQH_MSGEP_NODE_FLAGS_NOMESSAGES) */ - else { - DBG_DEBUG(AQH_LOGDOMAIN, "Not checking endpoint %s (NOMSG set)", epTypeName); - } - } /* if wantedTypeName matches */ - else { - DBG_DEBUG(AQH_LOGDOMAIN, "Endpoint %s doesn't match", epTypeName); - } - } /* if (ep!=srcEp) */ - ep=GWEN_MsgEndpoint_List_Next(ep); - } /* while */ - } -} - - - - - - - - diff --git a/aqhome/msg/endpointmgr.h b/aqhome/msg/endpointmgr.h deleted file mode 100644 index 0461d4f..0000000 --- a/aqhome/msg/endpointmgr.h +++ /dev/null @@ -1,32 +0,0 @@ -/**************************************************************************** - * This file is part of the project AqHome. - * AqHome (c) by 2023 Martin Preuss, all rights reserved. - * - * The license for this file can be found in the file COPYING which you - * should have received along with this file. - ****************************************************************************/ - -#ifndef AQH_MSG_ENDPOINT_MGR_H -#define AQH_MSG_ENDPOINT_MGR_H - - -#include - -#include - - - -AQHOME_API GWEN_MSG_ENDPOINT_MGR *AQH_MsgEndpointMgr_new(uint8_t busAddr); - -AQHOME_API uint8_t AQH_MsgEndpointMgr_GetBusAddr(GWEN_MSG_ENDPOINT_MGR *emgr); - -AQHOME_API void AQH_MsgEndpointMgr_DistributeMsgFromNodeEndpoint(GWEN_MSG_ENDPOINT_MGR *emgr, - GWEN_MSG_ENDPOINT *srcEp, - const GWEN_MSG *msg, - int groupId, - const char *wantedTypeName); - - - - -#endif diff --git a/aqhome/msgmanager.c b/aqhome/msgmanager.c deleted file mode 100644 index dc59701..0000000 --- a/aqhome/msgmanager.c +++ /dev/null @@ -1,588 +0,0 @@ -/**************************************************************************** - * This file is part of the project AqHome. - * AqHome (c) by 2023 Martin Preuss, all rights reserved. - * - * The license for this file can be found in the file COPYING which you - * should have received along with this file. - ****************************************************************************/ - -#ifdef HAVE_CONFIG_H -# include -#endif - - -#include "aqhome/msgmanager_p.h" -#include "aqhome/msg/endpointmgr.h" -#include "aqhome/msg/msg_node.h" -#include "aqhome/msg/msg_sendstats.h" -#include "aqhome/msg/msg_recvstats.h" -#include "aqhome/msg/msg_value2.h" -#include "aqhome/msg/msg_needaddr.h" -#include "aqhome/msg/msg_claimaddr.h" -#include "aqhome/msg/msg_haveaddr.h" -#include "aqhome/msg/msg_device.h" -#include "aqhome/msg/msg_ping.h" -#include "aqhome/msg/msg_flashready.h" -#include "aqhome/msg/endpoint_tty.h" -#include "aqhome/msg/endpoint_node.h" -#include "aqhome/mqtt/endpoint_mqttc.h" -#include "aqhome/ipc/msg_ipc.h" -#include "aqhome/ipc/msg_ipc_ping.h" -#include "aqhome/ipc/msg_ipc_setaccmsggrps.h" -#include "aqhome/ipc/msg_ipc_forward.h" -#include "aqhome/ipc/msg_ipc_getdevices_rsp.h" -#include "aqhome/ipc/msg_ipc_error.h" - -#include -#include -#include -#include -#include - - -GWEN_INHERIT(GWEN_MSG_ENDPOINT_MGR, AQH_MSG_MANAGER) - - - -static void GWENHYWFAR_CB _freeData(void *bp, void *p); -static void _loopOnceOverEndpoints(GWEN_MSG_ENDPOINT_MGR *emgr); -static void _handleEndpoint(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ENDPOINT *ep); -static void _handleNodeMsg(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ENDPOINT *ep, const GWEN_MSG *msg); -static void _handleIpcMsg(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ENDPOINT *ep, const GWEN_MSG *msg); -static void _handleMqttMsg(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ENDPOINT *ep, const GWEN_MSG *msg); -static void _handleMsgValue2(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ENDPOINT *ep, const GWEN_MSG *msg); -static void _handleMsgNeedAddress(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ENDPOINT *ep, const GWEN_MSG *msg); -static void _handleMsgClaimAddress(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ENDPOINT *ep, const GWEN_MSG *msg); -static void _handleMsgHaveAddress(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ENDPOINT *ep, const GWEN_MSG *msg); -static void _handleMsgComSendStat(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ENDPOINT *ep, const GWEN_MSG *msg); -static void _handleMsgComRecvStat(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ENDPOINT *ep, const GWEN_MSG *msg); -static void _handleMsgDevice(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ENDPOINT *ep, const GWEN_MSG *msg); -static void _handleMsgFlashReady(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ENDPOINT *ep, const GWEN_MSG *msg); - -static void _handleIpcMsgPing(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ENDPOINT *ep, const GWEN_MSG *msg); -static void _handleIpcMsgSetAccMsgGrps(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ENDPOINT *ep, const GWEN_MSG *msg); -static void _handleIpcMsgForward(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ENDPOINT *ep, const GWEN_MSG *msg); -static void _handleIpcMsgGetDevicesReq(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ENDPOINT *ep, const GWEN_MSG *msg); - -static AQH_NODE_INFO *_getOrCreateNodeAndUpdateUidAddr(GWEN_MSG_ENDPOINT_MGR *emgr, const GWEN_MSG *msg, uint32_t uid); -static void _updateTimestampLastChange(AQH_NODE_INFO *ni); - - - - - -GWEN_MSG_ENDPOINT_MGR *AQH_MsgManager_new(uint8_t busAddr) -{ - GWEN_MSG_ENDPOINT_MGR *mgr; - AQH_MSG_MANAGER *xmgr; - - mgr=AQH_MsgEndpointMgr_new(busAddr); - GWEN_NEW_OBJECT(AQH_MSG_MANAGER, xmgr); - GWEN_INHERIT_SETDATA(GWEN_MSG_ENDPOINT_MGR, AQH_MSG_MANAGER, mgr, xmgr, _freeData); - xmgr->nodeDb=AQH_NodeDb_new(); - - return mgr; -} - - - -void _freeData(void *bp, void *p) -{ - AQH_MSG_MANAGER *xmgr; - - xmgr=(AQH_MSG_MANAGER*) p; - AQH_NodeDb_free(xmgr->nodeDb); - free(xmgr->dbFilename); - GWEN_FREE_OBJECT(xmgr); -} - - - -const char *AQH_MsgManager_GetDbFilename(const GWEN_MSG_ENDPOINT_MGR *emgr) -{ - AQH_MSG_MANAGER *xmgr; - - xmgr=GWEN_INHERIT_GETDATA(GWEN_MSG_ENDPOINT_MGR, AQH_MSG_MANAGER, emgr); - if (xmgr) - return xmgr->dbFilename; - return NULL; -} - - - -void AQH_MsgManager_SetDbFilename(GWEN_MSG_ENDPOINT_MGR *emgr, const char *s) -{ - AQH_MSG_MANAGER *xmgr; - - xmgr=GWEN_INHERIT_GETDATA(GWEN_MSG_ENDPOINT_MGR, AQH_MSG_MANAGER, emgr); - if (xmgr) { - free(xmgr->dbFilename); - xmgr->dbFilename=s?strdup(s):NULL; - if (xmgr->dbFilename) { - GWEN_DB_NODE *dbNodeDb; - int rv; - - dbNodeDb=GWEN_DB_Group_new("dbNodes"); - rv=GWEN_DB_ReadFile(dbNodeDb, xmgr->dbFilename, GWEN_DB_FLAGS_DEFAULT); - if (rv==0) { - AQH_NodeDb_fromDb(xmgr->nodeDb, dbNodeDb); - } - GWEN_DB_Group_free(dbNodeDb); - } - } -} - - - -int AQH_MsgManager_LoopOnce(GWEN_MSG_ENDPOINT_MGR *emgr) -{ - int rv; - - rv=GWEN_MsgEndpointMgr_IoLoopOnce(emgr); - _loopOnceOverEndpoints(emgr); - GWEN_MsgEndpointMgr_RunAllEndpoints(emgr); - return rv; -} - - - -void _loopOnceOverEndpoints(GWEN_MSG_ENDPOINT_MGR *emgr) -{ - AQH_MSG_MANAGER *xmgr; - GWEN_MSG_ENDPOINT_LIST *endpointList; - - DBG_DEBUG(AQH_LOGDOMAIN, "Handle endpoint messages"); - xmgr=GWEN_INHERIT_GETDATA(GWEN_MSG_ENDPOINT_MGR, AQH_MSG_MANAGER, emgr); - endpointList=GWEN_MsgEndpointMgr_GetEndpointList(emgr); - if (endpointList) { - GWEN_MSG_ENDPOINT *ep; - - ep=GWEN_MsgEndpoint_List_First(endpointList); - while(ep) { - if (GWEN_MsgEndpoint_GetGroupId(ep) & AQH_MSGMGR_ENDPOINTGROUP_MQTT) { - if (GWEN_ConnectableMsgEndpoint_GetState(ep)>=GWEN_ENDPOINT_MQTTC_STATE_ESTABLISHED) - _handleEndpoint(emgr, ep); - else { - DBG_INFO(AQH_LOGDOMAIN, "Not handling MQTT endpoint right now (not fully connected: %d)", - GWEN_ConnectableMsgEndpoint_GetState(ep)); - } - } - else - _handleEndpoint(emgr, ep); - ep=GWEN_MsgEndpoint_List_Next(ep); - } /* while */ - } - - if (AQH_NodeDb_IsModified(xmgr->nodeDb)) { - if (xmgr->dbFilename) { - GWEN_DB_NODE *dbNodeDb; - - dbNodeDb=GWEN_DB_Group_new("nodeDb"); - AQH_NodeDb_toDb(xmgr->nodeDb, dbNodeDb); - GWEN_DB_WriteFile(dbNodeDb, xmgr->dbFilename, GWEN_DB_FLAGS_DEFAULT); - GWEN_DB_Group_free(dbNodeDb); - } - } -} - - - -void _handleEndpoint(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ENDPOINT *ep) -{ - GWEN_MSG *msg; - - while( (msg=GWEN_MsgEndpoint_TakeFirstReceivedMessage(ep)) ) { - int groupId; - - groupId=GWEN_Msg_GetGroupId(msg); - switch(groupId) { - case AQH_MSGMGR_ENDPOINTGROUP_NODE: _handleNodeMsg(emgr, ep, msg); break; - case AQH_MSGMGR_ENDPOINTGROUP_IPC: _handleIpcMsg(emgr, ep, msg); break; - case AQH_MSGMGR_ENDPOINTGROUP_MQTT: _handleMqttMsg(emgr, ep, msg); break; - default: - DBG_ERROR(AQH_LOGDOMAIN, "unhandled groupId %d (%02x), ignoring message", groupId, groupId); - break; - } - - GWEN_Msg_free(msg); - } -} - - - -void _handleNodeMsg(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ENDPOINT *ep, const GWEN_MSG *msg) -{ - int msgIsValid; - uint8_t msgType; - - DBG_INFO(AQH_LOGDOMAIN, - " - msg %d (%s) from %d to %d", - AQH_NodeMsg_GetMsgType(msg), - AQH_NodeMsg_MsgTypeToChar(AQH_NodeMsg_GetMsgType(msg)), - AQH_NodeMsg_GetSourceAddress(msg), - AQH_NodeMsg_GetDestAddress(msg)); - - - AQH_MsgEndpointMgr_DistributeMsgFromNodeEndpoint(emgr, ep, msg, AQH_MSGMGR_ENDPOINTGROUP_NODE, NULL); - - msgIsValid=(AQH_NodeMsg_IsChecksumValid(msg) && AQH_NodeMsg_IsMsgComplete(msg)); - msgType=AQH_NodeMsg_GetMsgType(msg); - - if (msgIsValid) { - switch(msgType) { - case AQH_MSG_TYPE_COMSENDSTATS: _handleMsgComSendStat(emgr, ep, msg); break; - case AQH_MSG_TYPE_COMRECVSTATS: _handleMsgComRecvStat(emgr, ep, msg); break; - case AQH_MSG_TYPE_VALUE2: _handleMsgValue2(emgr, ep, msg); break; - case AQH_MSG_TYPE_NEED_ADDRESS: _handleMsgNeedAddress(emgr, ep, msg); break; - case AQH_MSG_TYPE_CLAIM_ADDRESS: _handleMsgClaimAddress(emgr, ep, msg); break; - case AQH_MSG_TYPE_HAVE_ADDRESS: _handleMsgHaveAddress(emgr, ep, msg); break; - case AQH_MSG_TYPE_DEVICE: _handleMsgDevice(emgr, ep, msg); break; - case AQH_MSG_TYPE_FLASH_READY: _handleMsgFlashReady(emgr, ep, msg); break; - default: break; - } - } -} - - - -void _handleIpcMsg(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ENDPOINT *ep, const GWEN_MSG *msg) -{ - uint16_t code; - - /* exec IPC message */ - code=GWEN_IpcMsg_GetCode(msg); - DBG_ERROR(AQH_LOGDOMAIN, "Received IPC packet"); - switch(code) { - case AQH_MSGTYPE_IPC_PING: _handleIpcMsgPing(emgr, ep, msg); break; - case AQH_MSGTYPE_IPC_SETACCMSGGRPS: _handleIpcMsgSetAccMsgGrps(emgr, ep, msg); break; - case AQH_MSGTYPE_IPC_FORWARD: _handleIpcMsgForward(emgr, ep, msg); break; - case AQH_MSGTYPE_IPC_GETDEVICES_REQ: _handleIpcMsgGetDevicesReq(emgr, ep, msg); break; - default: break; - } -} - - - -void _handleMqttMsg(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ENDPOINT *ep, const GWEN_MSG *msg) -{ - /* exec MQTT message */ -} - - - -void _handleIpcMsgPing(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ENDPOINT *ep, const GWEN_MSG *msg) -{ - GWEN_MSG *msgOut; - - DBG_ERROR(AQH_LOGDOMAIN, "Received IPC PING message"); - msgOut=AQH_PingMsg_new(AQH_MsgEndpointMgr_GetBusAddr(emgr), - AQH_PingIpcMsg_GetDestAddr(msg), - AQH_MSG_TYPE_PING); - AQH_MsgEndpointMgr_DistributeMsgFromNodeEndpoint(emgr, ep, msgOut, AQH_MSGMGR_ENDPOINTGROUP_NODE, AQH_MSG_ENDPOINT_TTY_NAME); - GWEN_Msg_free(msgOut); -} - - - -void _handleIpcMsgSetAccMsgGrps(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ENDPOINT *ep, const GWEN_MSG *msg) -{ - uint32_t groups; - - DBG_ERROR(AQH_LOGDOMAIN, "Received IPC SET_ACCEPTED_MSG_GROUPS message"); - groups=AQH_SetAcceptedMsgGroupsIpcMsg_GetMsgGroups(msg); - AQH_NodeEndpoint_SetAcceptedMsgGroups(ep, groups); - // TODO: send response? -} - - - -void _handleIpcMsgForward(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ENDPOINT *ep, const GWEN_MSG *msg) -{ - GWEN_MSG *msgOut; - - DBG_ERROR(AQH_LOGDOMAIN, "Received IPC FORWARD message"); - msgOut=AQH_ForwardIpcMsg_GetCopyOfNodeMsg(msg); - if (msgOut) { - AQH_MsgEndpointMgr_DistributeMsgFromNodeEndpoint(emgr, ep, msgOut, AQH_MSGMGR_ENDPOINTGROUP_NODE, AQH_MSG_ENDPOINT_TTY_NAME); - GWEN_Msg_free(msgOut); - } -} - - - -void _handleIpcMsgGetDevicesReq(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ENDPOINT *ep, const GWEN_MSG *msg) -{ - AQH_MSG_MANAGER *xmgr; - - xmgr=GWEN_INHERIT_GETDATA(GWEN_MSG_ENDPOINT_MGR, AQH_MSG_MANAGER, emgr); - if (xmgr) { - AQH_NODE_INFO_LIST *nodeInfoList; - - DBG_ERROR(AQH_LOGDOMAIN, "Received IPC GetDevicesRequest message"); - nodeInfoList=AQH_NodeDb_GetAllNodeInfos(xmgr->nodeDb); - if (nodeInfoList && AQH_NodeInfo_List_GetCount(nodeInfoList)) { - const AQH_NODE_INFO *ni; - - ni=AQH_NodeInfo_List_First(nodeInfoList); - while(ni) { - const AQH_NODE_INFO *niNext; - GWEN_MSG *msgOut; - - niNext=AQH_NodeInfo_List_Next(ni); - DBG_INFO(AQH_LOGDOMAIN, "Sending response for node %02x (%08x)", AQH_NodeInfo_GetBusAddress(ni), AQH_NodeInfo_GetUid(ni)); - msgOut=AQH_GetDevicesResponseIpcMsg_new(AQH_MSGTYPE_IPC_GETDEVICES_RSP, niNext?0:AQH_MSGIPC_GETDEVICES_RSP_FLAGS_LAST, ni); - GWEN_MsgEndpoint_AddSendMessage(ep, msgOut); - ni=niNext; - } - } - else { - GWEN_MSG *msgOut; - - DBG_INFO(AQH_LOGDOMAIN, "No nodes"); - msgOut=AQH_ErrorIpcMsg_new(AQH_MSGTYPE_IPC_ERROR, AQH_MSG_IPC_ERROR_NODATA); - GWEN_MsgEndpoint_AddSendMessage(ep, msgOut); - } - } -} - - - - - - -void _handleMsgValue2(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ENDPOINT *ep, const GWEN_MSG *msg) -{ - AQH_MSG_MANAGER *xmgr; - - xmgr=GWEN_INHERIT_GETDATA(GWEN_MSG_ENDPOINT_MGR, AQH_MSG_MANAGER, emgr); - if (xmgr) { - AQH_NODE_INFO *ni; - uint32_t uid; - - uid=AQH_Value2Msg_GetUid(msg); - ni=_getOrCreateNodeAndUpdateUidAddr(emgr, msg, uid); - if (ni==NULL) { - DBG_INFO(AQH_LOGDOMAIN, "Error handling message"); - } - } -} - - - -void _handleMsgNeedAddress(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ENDPOINT *ep, const GWEN_MSG *msg) -{ - AQH_MSG_MANAGER *xmgr; - - xmgr=GWEN_INHERIT_GETDATA(GWEN_MSG_ENDPOINT_MGR, AQH_MSG_MANAGER, emgr); - if (xmgr) { - AQH_NODE_INFO *ni; - uint32_t uid; - - uid=AQH_NeedAddrMsg_GetUid(msg); - ni=_getOrCreateNodeAndUpdateUidAddr(emgr, msg, uid); - if (ni==NULL) { - DBG_INFO(AQH_LOGDOMAIN, "Error handling message"); - } - } -} - - - -void _handleMsgClaimAddress(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ENDPOINT *ep, const GWEN_MSG *msg) -{ - AQH_MSG_MANAGER *xmgr; - - xmgr=GWEN_INHERIT_GETDATA(GWEN_MSG_ENDPOINT_MGR, AQH_MSG_MANAGER, emgr); - if (xmgr) { - AQH_NODE_INFO *ni; - uint32_t uid; - - uid=AQH_ClaimAddrMsg_GetUid(msg); - ni=_getOrCreateNodeAndUpdateUidAddr(emgr, msg, uid); - if (ni==NULL) { - DBG_INFO(AQH_LOGDOMAIN, "Error handling message"); - } - } -} - - - -void _handleMsgHaveAddress(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ENDPOINT *ep, const GWEN_MSG *msg) -{ - AQH_MSG_MANAGER *xmgr; - - xmgr=GWEN_INHERIT_GETDATA(GWEN_MSG_ENDPOINT_MGR, AQH_MSG_MANAGER, emgr); - if (xmgr) { - AQH_NODE_INFO *ni; - uint32_t uid; - - uid=AQH_HaveAddrMsg_GetUid(msg); - ni=_getOrCreateNodeAndUpdateUidAddr(emgr, msg, uid); - if (ni==NULL) { - DBG_INFO(AQH_LOGDOMAIN, "Error handling message"); - } - } -} - - - -void _handleMsgComSendStat(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ENDPOINT *ep, const GWEN_MSG *msg) -{ - AQH_MSG_MANAGER *xmgr; - - xmgr=GWEN_INHERIT_GETDATA(GWEN_MSG_ENDPOINT_MGR, AQH_MSG_MANAGER, emgr); - if (xmgr) { - AQH_NODE_INFO *ni; - uint32_t uid; - - uid=AQH_SendStatsMsg_GetUid(msg); - ni=_getOrCreateNodeAndUpdateUidAddr(emgr, msg, uid); - if (ni==NULL) { - DBG_INFO(AQH_LOGDOMAIN, "Error handling message"); - } - AQH_NodeInfo_SetStatsPacketsOut(ni, AQH_SendStatsMsg_GetPacketsOut(msg)); - AQH_NodeInfo_SetStatsCollisions(ni, AQH_SendStatsMsg_GetCollisions(msg)); - AQH_NodeInfo_SetStatsBusy(ni, AQH_SendStatsMsg_GetBusyErrors(msg)); - AQH_NodeDb_SetModified(xmgr->nodeDb); - _updateTimestampLastChange(ni); - } -} - - - -void _handleMsgComRecvStat(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ENDPOINT *ep, const GWEN_MSG *msg) -{ - AQH_MSG_MANAGER *xmgr; - - xmgr=GWEN_INHERIT_GETDATA(GWEN_MSG_ENDPOINT_MGR, AQH_MSG_MANAGER, emgr); - if (xmgr) { - AQH_NODE_INFO *ni; - uint32_t uid; - - uid=AQH_RecvStatsMsg_GetUid(msg); - ni=_getOrCreateNodeAndUpdateUidAddr(emgr, msg, uid); - if (ni==NULL) { - DBG_INFO(AQH_LOGDOMAIN, "Error handling message"); - } - AQH_NodeInfo_SetStatsPacketsIn(ni, AQH_RecvStatsMsg_GetPacketsIn(msg)); - AQH_NodeInfo_SetStatsCrcErrors(ni, AQH_RecvStatsMsg_GetCrcErrors(msg)); - AQH_NodeInfo_SetStatsIoErrors(ni, AQH_RecvStatsMsg_GetIoErrors(msg)); - AQH_NodeDb_SetModified(xmgr->nodeDb); - _updateTimestampLastChange(ni); - } -} - - - -void _handleMsgDevice(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ENDPOINT *ep, const GWEN_MSG *msg) -{ - AQH_MSG_MANAGER *xmgr; - - xmgr=GWEN_INHERIT_GETDATA(GWEN_MSG_ENDPOINT_MGR, AQH_MSG_MANAGER, emgr); - if (xmgr) { - AQH_NODE_INFO *ni; - uint32_t uid; - - uid=AQH_DeviceMsg_GetUid(msg); - ni=_getOrCreateNodeAndUpdateUidAddr(emgr, msg, uid); - if (ni) { - AQH_NodeInfo_SetFirmwareType(ni, AQH_DeviceMsg_GetFirmwareType(msg)); - AQH_NodeInfo_SetFirmwareVersion(ni, (AQH_DeviceMsg_GetFirmwareHigh(msg)<<8) | AQH_DeviceMsg_GetFirmwareLow(msg)); - AQH_NodeInfo_SetModules(ni, AQH_DeviceMsg_GetModuleMask(msg)); - _updateTimestampLastChange(ni); - AQH_NodeDb_SetModified(xmgr->nodeDb); - } - else { - DBG_INFO(AQH_LOGDOMAIN, "Error handling message"); - } - } -} - - - -void _handleMsgFlashReady(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ENDPOINT *ep, const GWEN_MSG *msg) -{ - AQH_MSG_MANAGER *xmgr; - - xmgr=GWEN_INHERIT_GETDATA(GWEN_MSG_ENDPOINT_MGR, AQH_MSG_MANAGER, emgr); - if (xmgr) { - AQH_NODE_INFO *ni; - uint32_t uid; - - uid=AQH_FlashReadyMsg_GetUid(msg); - ni=_getOrCreateNodeAndUpdateUidAddr(emgr, msg, uid); - if (ni) { - AQH_NodeInfo_SetFirmwareType(ni, AQH_FlashReadyMsg_GetFirmwareType(msg)); - AQH_NodeInfo_SetFirmwareVersion(ni, AQH_FlashReadyMsg_GetFirmwareVersion(msg)); - _updateTimestampLastChange(ni); - AQH_NodeDb_SetModified(xmgr->nodeDb); - } - else { - DBG_INFO(AQH_LOGDOMAIN, "Error handling message"); - } - } -} - - - -AQH_NODE_INFO *_getOrCreateNodeAndUpdateUidAddr(GWEN_MSG_ENDPOINT_MGR *emgr, const GWEN_MSG *msg, uint32_t uid) -{ - AQH_MSG_MANAGER *xmgr; - - xmgr=GWEN_INHERIT_GETDATA(GWEN_MSG_ENDPOINT_MGR, AQH_MSG_MANAGER, emgr); - if (xmgr) { - uint8_t busAddr; - AQH_NODE_INFO *ni; - - busAddr=AQH_NodeMsg_GetSourceAddress(msg); - ni=AQH_NodeDb_GetNodeInfoByUid(xmgr->nodeDb, uid); - if (ni) { - uint8_t storedBusAddr; - - storedBusAddr=AQH_NodeInfo_GetBusAddress(ni); - if (busAddr!=0 && storedBusAddr!=busAddr) { - DBG_INFO(AQH_LOGDOMAIN, "Changed busaddr for %08x from %02x to %02x", uid, storedBusAddr, busAddr); - AQH_NodeInfo_SetBusAddress(ni, busAddr); - _updateTimestampLastChange(ni); - AQH_NodeDb_SetModified(xmgr->nodeDb); - } - } - else { - int rv; - - ni=AQH_NodeInfo_new(); - AQH_NodeInfo_SetBusAddress(ni, busAddr); - AQH_NodeInfo_SetUid(ni, uid); - _updateTimestampLastChange(ni); - rv=AQH_NodeDb_AddNodeInfo(xmgr->nodeDb, ni); - if (rv<0) { - DBG_INFO(AQH_LOGDOMAIN, "here (%d)", rv); - AQH_NodeInfo_free(ni); - return NULL; - } - else { - DBG_INFO(AQH_LOGDOMAIN, "Added node %08x (%02x)", uid, busAddr); - } - } - return ni; - } - return NULL; -} - - - -void _updateTimestampLastChange(AQH_NODE_INFO *ni) -{ - GWEN_TIMESTAMP *t; - - t=GWEN_Timestamp_NowInLocalTime(); - AQH_NodeInfo_SetTimestampLastChange(ni, t); - GWEN_Timestamp_free(t); -} - - - - - - - diff --git a/aqhome/msgmanager.h b/aqhome/msgmanager.h deleted file mode 100644 index 883e7d0..0000000 --- a/aqhome/msgmanager.h +++ /dev/null @@ -1,36 +0,0 @@ -/**************************************************************************** - * This file is part of the project AqHome. - * AqHome (c) by 2023 Martin Preuss, all rights reserved. - * - * The license for this file can be found in the file COPYING which you - * should have received along with this file. - ****************************************************************************/ - -#ifndef AQH_MSG_MANAGER_H -#define AQH_MSG_MANAGER_H - - -#include - -#include - - - -#define AQH_MSGMGR_ENDPOINTGROUP_NODE 1 -#define AQH_MSGMGR_ENDPOINTGROUP_IPC 2 -#define AQH_MSGMGR_ENDPOINTGROUP_MQTT 4 - - - -AQHOME_API GWEN_MSG_ENDPOINT_MGR *AQH_MsgManager_new(uint8_t busAddr); -AQHOME_API int AQH_MsgManager_LoopOnce(GWEN_MSG_ENDPOINT_MGR *emgr); - -AQHOME_API const char *AQH_MsgManager_GetDbFilename(const GWEN_MSG_ENDPOINT_MGR *emgr); -AQHOME_API void AQH_MsgManager_SetDbFilename(GWEN_MSG_ENDPOINT_MGR *emgr, const char *s); - - - - - - -#endif diff --git a/aqhome/msgmanager_p.h b/aqhome/msgmanager_p.h deleted file mode 100644 index 089b505..0000000 --- a/aqhome/msgmanager_p.h +++ /dev/null @@ -1,29 +0,0 @@ -/**************************************************************************** - * This file is part of the project AqHome. - * AqHome (c) by 2023 Martin Preuss, all rights reserved. - * - * The license for this file can be found in the file COPYING which you - * should have received along with this file. - ****************************************************************************/ - -#ifndef AQH_MSG_MANAGER_P_H -#define AQH_MSG_MANAGER_P_H - - -#include - -#include -#include - - - -typedef struct AQH_MSG_MANAGER AQH_MSG_MANAGER; -struct AQH_MSG_MANAGER { - AQH_NODE_DB *nodeDb; - char *dbFilename; -}; - - - - -#endif diff --git a/aqhomed.sh b/aqhomed.sh index e99e099..8adb472 100755 --- a/aqhomed.sh +++ b/aqhomed.sh @@ -5,6 +5,8 @@ export AQHOME_LOGLEVEL=info export LD_LIBRARY_PATH="0-build/aqhome/:$LD_LIBRARY_PATH" -0-build/apps/aqhomed/aqhomed -l aqhome.log -db aqhome.db -ma 192.168.117.192 -mp 1883 -t 127.0.0.1 - # aqhomed -l /var/log/aqhome.log -db /var/cache/aqhome/nodes.db -ma 192.168.117.192 -mp 1883 -t 127.0.0.1 -W /var/cache/aqhome + +# 0-build/apps/aqhomed/aqhomed -l aqhome.log -db aqhome.db -ma 192.168.117.192 -mp 1883 -t 127.0.0.1 -p aqhomed.pid + +0-build/apps/aqhomed/aqhomed -l aqhome.log -db aqhome.db -p aqhomed.pid -W /tmp/aqhome -ma 192.168.117.192 -mp 1883 -t 127.0.0.1 diff --git a/libtest.sh b/libtest.sh new file mode 100755 index 0000000..89dd307 --- /dev/null +++ b/libtest.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +# AQHOME_LOGLEVEL=info LD_LIBRARY_PATH="../../aqhome/:$LD_LIBRARY_PATH" ./aqhomed -l aqhome.log -db aqhome.db -ma 127.0.0.1 + +export AQHOME_LOGLEVEL=info +export LD_LIBRARY_PATH="0-build/aqhome/:$LD_LIBRARY_PATH" + +0-build/aqhome/libtest $* +