diff --git a/aqhome/ipc2/message.c b/aqhome/ipc2/message.c
index 27439f9..6a9ff84 100644
--- a/aqhome/ipc2/message.c
+++ b/aqhome/ipc2/message.c
@@ -138,62 +138,6 @@ void AQH_Message_IncUsedSize(AQH_MESSAGE *msg, uint32_t i)
-int AQH_Message_GetMsgType(const AQH_MESSAGE *msg)
-{
- return (msg && msg->refCount)?msg->msgType:0;
-}
-
-
-
-void AQH_Message_SetMsgType(AQH_MESSAGE *msg, int i)
-{
- if (msg && msg->refCount)
- msg->msgType=i;
-}
-
-
-int AQH_Message_GetMsgProtoId(const AQH_MESSAGE *msg)
-{
- return (msg && msg->refCount)?msg->msgProtoId:0;
-}
-
-
-
-void AQH_Message_SetMsgProtoId(AQH_MESSAGE *msg, int i)
-{
- if (msg && msg->refCount)
- msg->msgProtoId=i;
-}
-
-
-
-int AQH_Message_GetMsgProtoVer(const AQH_MESSAGE *msg)
-{
- return (msg && msg->refCount)?msg->msgProtoVer:0;
-}
-
-
-
-void AQH_Message_SetMsgProtoVer(AQH_MESSAGE *msg, int i)
-{
- if (msg && msg->refCount)
- msg->msgProtoVer=i;
-}
-
-
-
-int AQH_Message_GetMsgCommand(const AQH_MESSAGE *msg)
-{
- return (msg && msg->refCount)?msg->msgCommand:0;
-}
-
-
-
-void AQH_Message_SetMsgCommand(AQH_MESSAGE *msg, int i)
-{
- if (msg && msg->refCount)
- msg->msgCommand=i;
-}
diff --git a/aqhome/ipc2/message.h b/aqhome/ipc2/message.h
index 6d0b8e7..3c3c76a 100644
--- a/aqhome/ipc2/message.h
+++ b/aqhome/ipc2/message.h
@@ -37,19 +37,6 @@ AQHOME_API uint32_t AQH_Message_GetUsedSize(const AQH_MESSAGE *msg);
AQHOME_API void AQH_Message_SetUsedSize(AQH_MESSAGE *msg, uint32_t i);
AQHOME_API void AQH_Message_IncUsedSize(AQH_MESSAGE *msg, uint32_t i);
-/* parsed header data */
-AQHOME_API int AQH_Message_GetMsgType(const AQH_MESSAGE *msg);
-AQHOME_API void AQH_Message_SetMsgType(AQH_MESSAGE *msg, int i);
-
-AQHOME_API int AQH_Message_GetMsgProtoId(const AQH_MESSAGE *msg);
-AQHOME_API void AQH_Message_SetMsgProtoId(AQH_MESSAGE *msg, int i);
-
-AQHOME_API int AQH_Message_GetMsgProtoVer(const AQH_MESSAGE *msg);
-AQHOME_API void AQH_Message_SetMsgProtoVer(AQH_MESSAGE *msg, int i);
-
-AQHOME_API int AQH_Message_GetMsgCommand(const AQH_MESSAGE *msg);
-AQHOME_API void AQH_Message_SetMsgCommand(AQH_MESSAGE *msg, int i);
-
/* helper functions for parsing */
AQHOME_API void AQH_Message_WriteUint8At(AQH_MESSAGE *msg, uint32_t pos, uint8_t d);
AQHOME_API uint8_t AQH_Message_ReadUint8At(const AQH_MESSAGE *msg, uint32_t pos, uint8_t defaultValue);
diff --git a/aqhome/ipc2/message_p.h b/aqhome/ipc2/message_p.h
index 235af32..125dedf 100644
--- a/aqhome/ipc2/message_p.h
+++ b/aqhome/ipc2/message_p.h
@@ -23,12 +23,6 @@ struct AQH_MESSAGE {
uint8_t *msgPointer;
uint32_t msgSize;
uint32_t usedSize;
-
- /* parsed header data */
- int msgType;
- int msgProtoId;
- int msgProtoVer;
- int msgCommand;
};
diff --git a/aqhome/ipc2/msgwriter.c b/aqhome/ipc2/msgwriter.c
index 55bc4f4..0108518 100644
--- a/aqhome/ipc2/msgwriter.c
+++ b/aqhome/ipc2/msgwriter.c
@@ -212,7 +212,7 @@ void _resetBuffer(AQH_OBJECT *o)
void _cbEnable(AQH_OBJECT *o)
{
- if (o && !(AQH_Object_GetFlags(o) & AQH_OBJECT_FLAGS_ENABLED)) {
+ if (o) {
AQH_MSG_WRITER *xo;
xo=GWEN_INHERIT_GETDATA(AQH_OBJECT, AQH_MSG_WRITER, o);
@@ -225,7 +225,7 @@ void _cbEnable(AQH_OBJECT *o)
void _cbDisable(AQH_OBJECT *o)
{
- if (o && (AQH_Object_GetFlags(o) & AQH_OBJECT_FLAGS_ENABLED)) {
+ if (o) {
AQH_MSG_WRITER *xo;
xo=GWEN_INHERIT_GETDATA(AQH_OBJECT, AQH_MSG_WRITER, o);
diff --git a/aqhome/ipc2/nodeendpoint.c b/aqhome/ipc2/nodeendpoint.c
index 9adc10a..f873652 100644
--- a/aqhome/ipc2/nodeendpoint.c
+++ b/aqhome/ipc2/nodeendpoint.c
@@ -222,12 +222,7 @@ void _dumpMsg(const AQH_MESSAGE *msg, const char *sText)
GWEN_BUFFER *mbuf;
mbuf=GWEN_Buffer_new(0, 256, 0, 1);
- switch(AQH_NodeMessage_GetMsgType(msg)) {
- case AQH_MSG_TYPE_DEVICE: AQH_DeviceMessage_DumpToBuffer(msg, mbuf, sText); break;
- case AQH_MSG_TYPE_COMRECVSTATS: AQH_RecvStatsMessage_DumpToBuffer(msg, mbuf, sText); break;
- case AQH_MSG_TYPE_COMSENDSTATS: AQH_SendStatsMessage_DumpToBuffer(msg, mbuf, sText); break;
- default: AQH_NodeMessage_DumpToBuffer(msg, mbuf, sText); break;
- }
+ AQH_NodeMessage_DumpSpecificToBuffer(msg, mbuf, sText);
DBG_ERROR(AQH_LOGDOMAIN, "%s", GWEN_Buffer_GetStart(mbuf));
GWEN_Buffer_free(mbuf);
}
diff --git a/aqhome/ipc2/tcpd_object.c b/aqhome/ipc2/tcpd_object.c
index 1eee026..d748871 100644
--- a/aqhome/ipc2/tcpd_object.c
+++ b/aqhome/ipc2/tcpd_object.c
@@ -48,7 +48,6 @@ static void GWENHYWFAR_CB _freeData(void *bp, void *p);
static int _handleSignal(AQH_OBJECT *o, uint32_t slotId, AQH_OBJECT *senderObject, int param1, void *param2);
static int _handleSocketReady(AQH_OBJECT *o);
-static int _createListeningSocket(const char *addr, int port);
static int _socketSetReuseAddress(int sk, int fl);
static int _socketSetBlocking(int sk, int fl);
static int _translateHError(int herr);
@@ -63,7 +62,7 @@ static int _acceptConnection(int serverSocket);
* ------------------------------------------------------------------------------------------------
*/
-AQH_OBJECT *AQH_TcpdObject_new(AQH_EVENT_LOOP *eventLoop)
+AQH_OBJECT *AQH_TcpdObject_new(AQH_EVENT_LOOP *eventLoop, AQH_OBJECT *fdObject)
{
AQH_OBJECT *o;
AQH_TCPD_OBJECT *xo;
@@ -71,10 +70,18 @@ AQH_OBJECT *AQH_TcpdObject_new(AQH_EVENT_LOOP *eventLoop)
o=AQH_Object_new(eventLoop);
GWEN_NEW_OBJECT(AQH_TCPD_OBJECT, xo);
GWEN_INHERIT_SETDATA(AQH_OBJECT, AQH_TCPD_OBJECT, o, xo, _freeData);
- xo->fdSocket=-1;
-
AQH_Object_SetSignalHandlerFn(o, _handleSignal);
+ xo->fdObject=fdObject;
+ xo->fdSocket=AQH_FdObject_GetFd(fdObject);
+
+#if 0
+ /* create object for readable socket, connect to THIS, enable */
+ xo->fdObject=AQH_FdObject_new(AQH_Object_GetEventLoop(o), rv, AQH_FDOBJECT_FDMODE_READ);
+ AQH_Object_AddLink(xo->fdObject, AQH_FDOBJECT_SIGNAL_ISREADY, AQH_TCPD_OBJECT_SLOT_SOCKETREADY, o);
+ AQH_Object_Enable(xo->fdObject);
+#endif
+
return o;
}
@@ -85,111 +92,13 @@ void GWENHYWFAR_CB _freeData(GWEN_UNUSED void *bp, void *p)
AQH_TCPD_OBJECT *xo;
xo=(AQH_TCPD_OBJECT*) p;
- if (xo->fdObject)
- AQH_Object_free(xo->fdObject);
- if (xo->fdSocket)
- close(xo->fdSocket);
GWEN_FREE_OBJECT(xo);
}
-int AQH_TcpdObject_StartListening(AQH_OBJECT *o, const char *addr, int port)
-{
- if (o) {
- AQH_TCPD_OBJECT *xo;
-
- xo=GWEN_INHERIT_GETDATA(AQH_OBJECT, AQH_TCPD_OBJECT, o);
- if (xo) {
- if (xo->fdSocket<0) {
- int rv;
-
- rv=_createListeningSocket(addr, port);
- if (rv<0) {
- DBG_INFO(AQH_LOGDOMAIN, "here (%d)", rv);
- return rv;
- }
- xo->fdSocket=rv;
-
- /* create object for readable socket, connect to THIS, enable */
- xo->fdObject=AQH_FdObject_new(AQH_Object_GetEventLoop(o), rv, AQH_FDOBJECT_FDMODE_READ);
- AQH_Object_AddLink(xo->fdObject, AQH_FDOBJECT_SIGNAL_ISREADY, AQH_TCPD_OBJECT_SLOT_SOCKETREADY, o);
- AQH_Object_Enable(xo->fdObject);
- }
- }
- }
-
- return GWEN_ERROR_GENERIC;
-}
-
-
-
-void AQH_TcpdObject_StopListening(AQH_OBJECT *o)
-{
- if (o) {
- AQH_TCPD_OBJECT *xo;
-
- xo=GWEN_INHERIT_GETDATA(AQH_OBJECT, AQH_TCPD_OBJECT, o);
- if (xo) {
- if (xo->fdObject) {
- AQH_Object_Disable(xo->fdObject);
- AQH_Object_free(xo->fdObject);
- xo->fdObject=NULL;
- }
- if (xo->fdSocket<0) {
- close(xo->fdSocket);
- xo->fdSocket=-1;
- }
- }
- }
-}
-
-
-
-int _handleSignal(AQH_OBJECT *o,
- uint32_t slotId,
- GWEN_UNUSED AQH_OBJECT *senderObject,
- GWEN_UNUSED int param1,
- GWEN_UNUSED void *param2)
-{
- switch(slotId) {
- case AQH_TCPD_OBJECT_SLOT_SOCKETREADY: return _handleSocketReady(o);
- default:
- break;
- }
-
- return 0; /* not handled */
-}
-
-
-
-int _handleSocketReady(AQH_OBJECT *o)
-{
- AQH_TCPD_OBJECT *xo;
-
- xo=GWEN_INHERIT_GETDATA(AQH_OBJECT, AQH_TCPD_OBJECT, o);
- if (xo) {
- int clientSk;
-
- clientSk=_acceptConnection(xo->fdSocket);
- if (clientSk<0) {
- DBG_INFO(AQH_LOGDOMAIN, "here (%d)", clientSk);
- }
- else {
- if (0==AQH_Object_EmitSignal(o, AQH_TCPD_OBJECT_SIGNAL_NEWCONN, clientSk, NULL)) {
- DBG_INFO(AQH_LOGDOMAIN, "New connection not handled");
- close(clientSk);
- }
- }
- return 1; /* handled */
- }
- return 0; /* not handled */
-}
-
-
-
-int _createListeningSocket(const char *addr, int port)
+int AQH_TcpdObject_CreateListeningSocket(const char *addr, int port)
{
int sk;
struct sockaddr_in inetAddr;
@@ -245,6 +154,48 @@ int _createListeningSocket(const char *addr, int port)
+int _handleSignal(AQH_OBJECT *o,
+ uint32_t slotId,
+ GWEN_UNUSED AQH_OBJECT *senderObject,
+ GWEN_UNUSED int param1,
+ GWEN_UNUSED void *param2)
+{
+ switch(slotId) {
+ case AQH_TCPD_OBJECT_SLOT_SOCKETREADY: return _handleSocketReady(o);
+ default:
+ break;
+ }
+
+ return 0; /* not handled */
+}
+
+
+
+int _handleSocketReady(AQH_OBJECT *o)
+{
+ AQH_TCPD_OBJECT *xo;
+
+ xo=GWEN_INHERIT_GETDATA(AQH_OBJECT, AQH_TCPD_OBJECT, o);
+ if (xo) {
+ int clientSk;
+
+ clientSk=_acceptConnection(xo->fdSocket);
+ if (clientSk<0) {
+ DBG_INFO(AQH_LOGDOMAIN, "here (%d)", clientSk);
+ }
+ else {
+ if (0==AQH_Object_EmitSignal(o, AQH_TCPD_OBJECT_SIGNAL_NEWCONN, clientSk, NULL)) {
+ DBG_INFO(AQH_LOGDOMAIN, "New connection not handled");
+ close(clientSk);
+ }
+ }
+ return 1; /* handled */
+ }
+ return 0; /* not handled */
+}
+
+
+
int _setHostAddr(struct in_addr *inetAddr, const char *sAddr)
{
inetAddr->s_addr=0;
diff --git a/aqhome/ipc2/tcpd_object.h b/aqhome/ipc2/tcpd_object.h
index cb4e254..99623a5 100644
--- a/aqhome/ipc2/tcpd_object.h
+++ b/aqhome/ipc2/tcpd_object.h
@@ -17,9 +17,18 @@ enum {
};
-AQHOME_API AQH_OBJECT *AQH_TcpdObject_new(AQH_EVENT_LOOP *eventLoop);
-AQHOME_API int AQH_TcpdObject_StartListening(AQH_OBJECT *o, const char *addr, int port);
-AQHOME_API void AQH_TcpdObject_StopListening(AQH_OBJECT *o);
+/**
+ * Start listening to the given fdObject which represents a tcp network socket.
+ * The socket for that fdObject can be created by @ref AQH_TcpdObject_CreateListeningSocket().
+ *
+ */
+AQHOME_API AQH_OBJECT *AQH_TcpdObject_new(AQH_EVENT_LOOP *eventLoop, AQH_OBJECT *fdObject);
+
+
+/**
+ * Helper function to create a listening TCP socket.
+ */
+AQHOME_API int AQH_TcpdObject_CreateListeningSocket(const char *addr, int port);
diff --git a/aqhome/msg/ipc/0BUILD b/aqhome/msg/ipc/0BUILD
index 765cd13..84e7fcb 100644
--- a/aqhome/msg/ipc/0BUILD
+++ b/aqhome/msg/ipc/0BUILD
@@ -70,10 +70,12 @@
aqhmsg_ipcd
+ aqhmsg_ipcn
data
+ nodes
diff --git a/aqhome/msg/ipc/data/m_ipcd.c b/aqhome/msg/ipc/data/m_ipcd.c
index effdc30..8d3eca7 100644
--- a/aqhome/msg/ipc/data/m_ipcd.c
+++ b/aqhome/msg/ipc/data/m_ipcd.c
@@ -54,3 +54,5 @@ const char *AQH_IpcdMessage_MsgTypeToChar(uint16_t i)
+
+
diff --git a/aqhome/msg/ipc/data/m_ipcd.h b/aqhome/msg/ipc/data/m_ipcd.h
index aea5535..b52818b 100644
--- a/aqhome/msg/ipc/data/m_ipcd.h
+++ b/aqhome/msg/ipc/data/m_ipcd.h
@@ -13,6 +13,9 @@
#include
#include
+#include
+
+
#define AQH_IPC_PROTOCOL_DATA_ID 2
#define AQH_IPC_PROTOCOL_DATA_VERSION 1
diff --git a/aqhome/msg/ipc/data/m_ipcd_devices.c b/aqhome/msg/ipc/data/m_ipcd_devices.c
index 3634503..1089a60 100644
--- a/aqhome/msg/ipc/data/m_ipcd_devices.c
+++ b/aqhome/msg/ipc/data/m_ipcd_devices.c
@@ -59,6 +59,30 @@ AQH_MESSAGE *AQH_IpcdMessageDevices_new(uint16_t code, uint32_t msgId, uint32_t
+AQH_MESSAGE *AQH_IpcdMessageDevices_newForOneDevice(uint16_t code, uint32_t msgId, uint32_t refMsgId,
+ uint32_t flags, const AQH_DEVICE *device)
+{
+ AQH_MESSAGE *msg;
+ GWEN_BUFFER *buf;
+ int rv;
+
+ buf=GWEN_Buffer_new(0, 256, 0, 1);
+ GWEN_Tag16_WriteUint32TagToBuffer(AQH_MSGDATA_DEVICES_TAGS_FLAGS, flags, buf);
+ rv=AQH_Tag16_WriteDeviceAsTagToBuffer(AQH_MSGDATA_DEVICES_TAGS_DEVICE, device, buf);
+ if (rv<0) {
+ DBG_INFO(AQH_LOGDOMAIN, "here (%d)", rv);
+ GWEN_Buffer_free(buf);
+ return NULL;
+ }
+
+ msg=AQH_IpcMessage_new(AQH_IPC_PROTOCOL_DATA_ID, AQH_IPC_PROTOCOL_DATA_VERSION, code, msgId, refMsgId,
+ GWEN_Buffer_GetUsedBytes(buf), (const uint8_t*) GWEN_Buffer_GetStart(buf));
+ GWEN_Buffer_free(buf);
+ return msg;
+}
+
+
+
AQH_DEVICE_LIST *AQH_IpcdMessageDevices_ReadDeviceList(const GWEN_TAG16_LIST *tagList)
{
if (tagList) {
diff --git a/aqhome/msg/ipc/data/m_ipcd_devices.h b/aqhome/msg/ipc/data/m_ipcd_devices.h
index 81d59c1..c7aa642 100644
--- a/aqhome/msg/ipc/data/m_ipcd_devices.h
+++ b/aqhome/msg/ipc/data/m_ipcd_devices.h
@@ -29,6 +29,9 @@
AQHOME_API AQH_MESSAGE *AQH_IpcdMessageDevices_new(uint16_t code, uint32_t msgId, uint32_t refMsgId,
uint32_t flags, const AQH_DEVICE_LIST *deviceList);
+AQHOME_API AQH_MESSAGE *AQH_IpcdMessageDevices_newForOneDevice(uint16_t code, uint32_t msgId, uint32_t refMsgId,
+ uint32_t flags, const AQH_DEVICE *device);
+
AQHOME_API AQH_DEVICE_LIST *AQH_IpcdMessageDevices_ReadDeviceList(const GWEN_TAG16_LIST *tagList);
AQHOME_API AQH_DEVICE *AQH_IpcdMessageDevices_ReadFirstDevice(const GWEN_TAG16_LIST *tagList);
AQHOME_API uint32_t AQH_IpcdMessageDevices_GetFlags(const GWEN_TAG16_LIST *tagList);
diff --git a/aqhome/msg/ipc/m_ipc.c b/aqhome/msg/ipc/m_ipc.c
index 70f2586..7832106 100644
--- a/aqhome/msg/ipc/m_ipc.c
+++ b/aqhome/msg/ipc/m_ipc.c
@@ -132,6 +132,17 @@ uint8_t *AQH_IpcMessage_GetPayloadPointer(const AQH_MESSAGE *msg)
+void AQH_IpcMessage_DumpToBuffer(const AQH_MESSAGE *msg, GWEN_BUFFER *dbuf, const char *sText)
+{
+ GWEN_Buffer_AppendArgs(dbuf, "IPC message %s (code=%d, protocol=%d, protocol version=%d)\n",
+ sText?sText:"",
+ AQH_IpcMessage_GetCode(msg),
+ AQH_IpcMessage_GetProtoId(msg),
+ AQH_IpcMessage_GetProtoVersion(msg));
+}
+
+
+
const char *AQH_IpcMessage_MsgTypeToChar(uint16_t i)
{
switch(i) {
diff --git a/aqhome/msg/ipc/m_ipc.h b/aqhome/msg/ipc/m_ipc.h
index 739256b..35af1de 100644
--- a/aqhome/msg/ipc/m_ipc.h
+++ b/aqhome/msg/ipc/m_ipc.h
@@ -13,6 +13,8 @@
#include
#include
+#include
+
#define AQH_IPCMSG_OFFS_SIZE 0 /* 4 bytes: number of all bytes including size, protoid, protover and code */
#define AQH_IPCMSG_OFFS_PROTOID 4 /* 1 byte: protocol id (free to use) */
@@ -75,6 +77,8 @@ AQHOME_API uint32_t AQH_IpcMessage_GetRefMsgId(const AQH_MESSAGE *msg);
AQHOME_API uint32_t AQH_IpcMessage_GetPayloadLength(const AQH_MESSAGE *msg);
AQHOME_API uint8_t *AQH_IpcMessage_GetPayloadPointer(const AQH_MESSAGE *msg);
+AQHOME_API void AQH_IpcMessage_DumpToBuffer(const AQH_MESSAGE *msg, GWEN_BUFFER *dbuf, const char *sText);
+
AQHOME_API const char *AQH_IpcMessage_MsgTypeToChar(uint16_t i);
diff --git a/aqhome/msg/ipc/m_ipc_tag16.c b/aqhome/msg/ipc/m_ipc_tag16.c
index b8f1010..a7a2e6d 100644
--- a/aqhome/msg/ipc/m_ipc_tag16.c
+++ b/aqhome/msg/ipc/m_ipc_tag16.c
@@ -49,6 +49,20 @@
#define AQH_IPCDATA_DEVICE_TAGS_MANUFACTURER 0x0a
#define AQH_IPCDATA_DEVICE_TAGS_TIMEOFCREATION 0x0b
+#define AQH_IPCDATA_NODE_TAGS_BUSADDR 0x01 /* uint8_t */
+#define AQH_IPCDATA_NODE_TAGS_UID 0x02 /* uint32_t */
+#define AQH_IPCDATA_NODE_TAGS_MANUFACTURER 0x03 /* uint32_t */
+#define AQH_IPCDATA_NODE_TAGS_DEVICETYPE 0x04 /* uint16_t */
+#define AQH_IPCDATA_NODE_TAGS_DEVICEVERSION 0x05 /* uint16_t */
+#define AQH_IPCDATA_NODE_TAGS_FIRMWAREVERSION 0x06 /* uint32_t */
+#define AQH_IPCDATA_NODE_TAGS_LASTCHANGE 0x07 /* uint64_t */
+#define AQH_IPCDATA_NODE_TAGS_STATSPACKETSOUT 0x08 /* uint16_t */
+#define AQH_IPCDATA_NODE_TAGS_STATSPACKETSIN 0x09 /* uint16_t */
+#define AQH_IPCDATA_NODE_TAGS_STATSCOLLISIONS 0x0a /* uint16_t */
+#define AQH_IPCDATA_NODE_TAGS_STATSBUSY 0x0b /* uint16_t */
+#define AQH_IPCDATA_NODE_TAGS_STATSCRCERRORS 0x0c /* uint16_t */
+#define AQH_IPCDATA_NODE_TAGS_STATSIOERRORS 0x0d /* uint16_t */
+
/* ------------------------------------------------------------------------------------------------
@@ -60,6 +74,8 @@ static void _writeValueFieldsAsTagsToBuffer(const AQH_VALUE *value, GWEN_BUFFER
static AQH_VALUE *_readValueFromTag(const uint8_t *ptr, uint32_t len);
static void _writeDeviceFieldsAsTagsToBuffer(const AQH_DEVICE *device, GWEN_BUFFER *buf);
static AQH_DEVICE *_readDeviceFromTag(const uint8_t *ptr, uint32_t len);
+static void _writeNodeInfoFieldsAsTagsToBuffer(const AQH_NODE_INFO *ni, GWEN_BUFFER *buf);
+static AQH_NODE_INFO *_readNodeInfoFromTag(const uint8_t *ptr, uint32_t len);
@@ -578,5 +594,201 @@ AQH_DEVICE *_readDeviceFromTag(const uint8_t *ptr, uint32_t len)
+int AQH_Tag16_WriteNodeInfoListAsTagsToBuffer(unsigned int tagType, const AQH_NODE_INFO_LIST *nodeInfoList, GWEN_BUFFER *buf)
+{
+ if (nodeInfoList) {
+ const AQH_NODE_INFO *nodeInfo;
+
+ nodeInfo=AQH_NodeInfo_List_First(nodeInfoList);
+ while(nodeInfo) {
+ int rv;
+
+ rv=AQH_Tag16_WriteNodeInfoAsTagToBuffer(tagType, nodeInfo, buf);
+ if (rv<0) {
+ DBG_INFO(AQH_LOGDOMAIN, "here (%d)", rv);
+ GWEN_Buffer_free(buf);
+ return rv;
+ }
+
+ nodeInfo=AQH_NodeInfo_List_Next(nodeInfo);
+ }
+ }
+ return 0;
+}
+
+
+
+
+int AQH_Tag16_WriteNodeInfoAsTagToBuffer(unsigned int tagType, const AQH_NODE_INFO *ni, GWEN_BUFFER *buf)
+{
+ int startPos;
+ int rv;
+
+ startPos=GWEN_Tag16_StartTagInBuffer(tagType, buf);
+ if (startPos<0) {
+ DBG_INFO(AQH_LOGDOMAIN, "here (%d)", startPos);
+ return startPos;
+ }
+
+ _writeNodeInfoFieldsAsTagsToBuffer(ni, buf);
+
+ rv=GWEN_Tag16_EndTagInBuffer(startPos, buf);
+ if (rv<0) {
+ DBG_INFO(AQH_LOGDOMAIN, "here (%d)", rv);
+ return rv;
+ }
+
+ return 0;
+}
+
+
+
+void _writeNodeInfoFieldsAsTagsToBuffer(const AQH_NODE_INFO *ni, GWEN_BUFFER *buf)
+{
+ const GWEN_TIMESTAMP *t;
+
+ GWEN_Tag16_WriteUint8TagToBuffer(AQH_IPCDATA_NODE_TAGS_BUSADDR, AQH_NodeInfo_GetBusAddress(ni), buf);
+ GWEN_Tag16_WriteUint32TagToBuffer(AQH_IPCDATA_NODE_TAGS_UID, AQH_NodeInfo_GetUid(ni), buf);
+ GWEN_Tag16_WriteUint32TagToBuffer(AQH_IPCDATA_NODE_TAGS_MANUFACTURER, AQH_NodeInfo_GetManufacturer(ni), buf);
+ GWEN_Tag16_WriteUint16TagToBuffer(AQH_IPCDATA_NODE_TAGS_DEVICETYPE, AQH_NodeInfo_GetDeviceType(ni), buf);
+ GWEN_Tag16_WriteUint16TagToBuffer(AQH_IPCDATA_NODE_TAGS_DEVICEVERSION, AQH_NodeInfo_GetDeviceVersion(ni), buf);
+ GWEN_Tag16_WriteUint32TagToBuffer(AQH_IPCDATA_NODE_TAGS_FIRMWAREVERSION, AQH_NodeInfo_GetFirmwareVersion(ni), buf);
+ t=AQH_NodeInfo_GetTimestampLastChange(ni);
+ GWEN_Tag16_WriteUint64TagToBuffer(AQH_IPCDATA_NODE_TAGS_LASTCHANGE, t?((uint64_t)GWEN_Timestamp_toInt64(t)):0L, buf);
+
+ GWEN_Tag16_WriteUint16TagToBuffer(AQH_IPCDATA_NODE_TAGS_STATSPACKETSOUT, AQH_NodeInfo_GetStatsPacketsOut(ni), buf);
+ GWEN_Tag16_WriteUint16TagToBuffer(AQH_IPCDATA_NODE_TAGS_STATSPACKETSIN, AQH_NodeInfo_GetStatsPacketsIn(ni), buf);
+ GWEN_Tag16_WriteUint16TagToBuffer(AQH_IPCDATA_NODE_TAGS_STATSCOLLISIONS, AQH_NodeInfo_GetStatsCollisions(ni), buf);
+ GWEN_Tag16_WriteUint16TagToBuffer(AQH_IPCDATA_NODE_TAGS_STATSBUSY, AQH_NodeInfo_GetStatsBusy(ni), buf);
+ GWEN_Tag16_WriteUint16TagToBuffer(AQH_IPCDATA_NODE_TAGS_STATSCRCERRORS, AQH_NodeInfo_GetStatsCrcErrors(ni), buf);
+ GWEN_Tag16_WriteUint16TagToBuffer(AQH_IPCDATA_NODE_TAGS_STATSIOERRORS, AQH_NodeInfo_GetStatsIoErrors(ni), buf);
+}
+
+
+
+AQH_NODE_INFO_LIST *AQH_Tag16_ReadNodeInfosFromTagList(const GWEN_TAG16_LIST *tagList, unsigned int wantedTagType)
+{
+ AQH_NODE_INFO_LIST *nodeInfoList;
+ const GWEN_TAG16 *tag;
+
+ nodeInfoList=AQH_NodeInfo_List_new();
+ tag=GWEN_Tag16_List_First(tagList);
+ while(tag) {
+ unsigned int tagType;
+
+ tagType=GWEN_Tag16_GetTagType(tag);
+ if (tagType==wantedTagType) {
+ AQH_NODE_INFO *nodeInfo;
+
+ nodeInfo=_readNodeInfoFromTag((const uint8_t*) GWEN_Tag16_GetTagData(tag), (uint32_t) GWEN_Tag16_GetTagLength(tag));
+ if (nodeInfo)
+ AQH_NodeInfo_List_Add(nodeInfo, nodeInfoList);
+ }
+
+ tag=GWEN_Tag16_List_Next(tag);
+ }
+
+ if (AQH_NodeInfo_List_GetCount(nodeInfoList)<1) {
+ AQH_NodeInfo_List_free(nodeInfoList);
+ return NULL;
+ }
+
+ return nodeInfoList;
+}
+
+
+
+AQH_NODE_INFO *AQH_Tag16_ReadNodeInfoFromTagList(const GWEN_TAG16_LIST *tagList, unsigned int wantedTagType)
+{
+ if (tagList) {
+ const GWEN_TAG16 *tag;
+
+ tag=GWEN_Tag16_List_FindFirstByTagType(tagList, wantedTagType);
+ return tag?_readNodeInfoFromTag((const uint8_t*) GWEN_Tag16_GetTagData(tag), (uint32_t) GWEN_Tag16_GetTagLength(tag)):NULL;
+ }
+ return NULL;
+}
+
+
+
+AQH_NODE_INFO *_readNodeInfoFromTag(const uint8_t *ptr, uint32_t len)
+{
+ GWEN_TAG16_LIST *tagList;
+
+ tagList=GWEN_Tag16_List_fromBuffer(ptr, len, 0);
+ if (tagList) {
+ GWEN_TAG16 *tag;
+ AQH_NODE_INFO *ni;
+
+ ni=AQH_NodeInfo_new();
+ tag=GWEN_Tag16_List_First(tagList);
+ while(tag) {
+ unsigned int tagType;
+ uint64_t u64;
+
+ tagType=GWEN_Tag16_GetTagType(tag);
+ switch(tagType) {
+ case AQH_IPCDATA_NODE_TAGS_BUSADDR:
+ AQH_NodeInfo_SetBusAddress(ni, GWEN_Tag16_GetTagDataAsUint8(tag, 0));
+ break;
+ case AQH_IPCDATA_NODE_TAGS_UID:
+ AQH_NodeInfo_SetUid(ni, GWEN_Tag16_GetTagDataAsUint32(tag, 0));
+ break;
+ case AQH_IPCDATA_NODE_TAGS_MANUFACTURER:
+ AQH_NodeInfo_SetManufacturer(ni, GWEN_Tag16_GetTagDataAsUint32(tag, 0));
+ break;
+ case AQH_IPCDATA_NODE_TAGS_DEVICETYPE:
+ AQH_NodeInfo_SetDeviceType(ni, GWEN_Tag16_GetTagDataAsUint16(tag, 0));
+ break;
+ case AQH_IPCDATA_NODE_TAGS_DEVICEVERSION:
+ AQH_NodeInfo_SetDeviceVersion(ni, GWEN_Tag16_GetTagDataAsUint16(tag, 0));
+ break;
+ case AQH_IPCDATA_NODE_TAGS_FIRMWAREVERSION:
+ AQH_NodeInfo_SetFirmwareVersion(ni, GWEN_Tag16_GetTagDataAsUint32(tag, 0));
+ break;
+ case AQH_IPCDATA_NODE_TAGS_LASTCHANGE:
+ u64=GWEN_Tag16_GetTagDataAsUint64(tag, 0);
+ if (u64>0) {
+ GWEN_TIMESTAMP *t;
+
+ t=GWEN_Timestamp_fromInt64((int64_t) u64);
+ if (t) {
+ AQH_NodeInfo_SetTimestampLastChange(ni, t);
+ GWEN_Timestamp_free(t);
+ }
+ }
+ break;
+ case AQH_IPCDATA_NODE_TAGS_STATSPACKETSOUT:
+ AQH_NodeInfo_SetStatsPacketsOut(ni, GWEN_Tag16_GetTagDataAsUint16(tag, 0));
+ break;
+ case AQH_IPCDATA_NODE_TAGS_STATSPACKETSIN:
+ AQH_NodeInfo_SetStatsPacketsIn(ni, GWEN_Tag16_GetTagDataAsUint16(tag, 0));
+ break;
+ case AQH_IPCDATA_NODE_TAGS_STATSCOLLISIONS:
+ AQH_NodeInfo_SetStatsCollisions(ni, GWEN_Tag16_GetTagDataAsUint16(tag, 0));
+ break;
+ case AQH_IPCDATA_NODE_TAGS_STATSBUSY:
+ AQH_NodeInfo_SetStatsBusy(ni, GWEN_Tag16_GetTagDataAsUint16(tag, 0));
+ break;
+ case AQH_IPCDATA_NODE_TAGS_STATSCRCERRORS:
+ AQH_NodeInfo_SetStatsCrcErrors(ni, GWEN_Tag16_GetTagDataAsUint16(tag, 0));
+ break;
+ case AQH_IPCDATA_NODE_TAGS_STATSIOERRORS:
+ AQH_NodeInfo_SetStatsIoErrors(ni, GWEN_Tag16_GetTagDataAsUint16(tag, 0));
+ break;
+ default:
+ DBG_INFO(AQH_LOGDOMAIN, "Unhandled tag typ %d (%02x)", tagType, tagType);
+ break;
+ }
+ tag=GWEN_Tag16_List_Next(tag);
+ }
+ GWEN_Tag16_List_free(tagList);
+ return ni;
+ }
+
+ return NULL;
+}
+
+
diff --git a/aqhome/msg/ipc/m_ipc_tag16.h b/aqhome/msg/ipc/m_ipc_tag16.h
index 7c74c50..044169a 100644
--- a/aqhome/msg/ipc/m_ipc_tag16.h
+++ b/aqhome/msg/ipc/m_ipc_tag16.h
@@ -15,6 +15,7 @@
#include
#include
#include
+#include
#include
@@ -38,6 +39,12 @@ AQHOME_API int AQH_Tag16_WriteDeviceAsTagToBuffer(unsigned int tagType, const AQ
AQHOME_API AQH_DEVICE_LIST *AQH_Tag16_ReadDevicesFromTagList(const GWEN_TAG16_LIST *tagList, unsigned int wantedTagType);
AQHOME_API AQH_DEVICE *AQH_Tag16_ReadDeviceFromTagList(const GWEN_TAG16_LIST *tagList, unsigned int wantedTagType);
+AQHOME_API int AQH_Tag16_WriteNodeInfoListAsTagsToBuffer(unsigned int tagType, const AQH_NODE_INFO_LIST *nodeInfoList, GWEN_BUFFER *buf);
+AQHOME_API int AQH_Tag16_WriteNodeInfoAsTagToBuffer(unsigned int tagType, const AQH_NODE_INFO *ni, GWEN_BUFFER *buf);
+
+AQHOME_API AQH_NODE_INFO_LIST *AQH_Tag16_ReadNodeInfosFromTagList(const GWEN_TAG16_LIST *tagList, unsigned int wantedTagType);
+AQHOME_API AQH_NODE_INFO *AQH_Tag16_ReadNodeInfoFromTagList(const GWEN_TAG16_LIST *tagList, unsigned int wantedTagType);
+
#endif
diff --git a/aqhome/msg/ipc/nodes/0BUILD b/aqhome/msg/ipc/nodes/0BUILD
new file mode 100644
index 0000000..3149e6f
--- /dev/null
+++ b/aqhome/msg/ipc/nodes/0BUILD
@@ -0,0 +1,84 @@
+
+
+
+
+
+
+
+ $(gwenhywfar_cflags)
+ -I$(topsrcdir)
+ -I$(topbuilddir)
+
+
+
+ --include=$(builddir)
+ --include=$(srcdir)
+
+
+
+
+
+ $(visibility_cflags)
+
+
+
+ --api=AQHOME_API
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ $(local/built_headers_pub)
+
+
+
+
+ m_ipcn.h
+ m_ipcn_forward.h
+ m_ipcn_getdevices_req.h
+ m_ipcn_getdevices_rsp.h
+
+
+
+
+
+
+
+
+ $(local/typefiles)
+
+ m_ipcn.c
+ m_ipcn_forward.c
+ m_ipcn_getdevices_req.c
+ m_ipcn_getdevices_rsp.c
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/aqhome/msg/ipc/nodes/m_ipcn.c b/aqhome/msg/ipc/nodes/m_ipcn.c
new file mode 100644
index 0000000..82887bc
--- /dev/null
+++ b/aqhome/msg/ipc/nodes/m_ipcn.c
@@ -0,0 +1,46 @@
+/****************************************************************************
+ * This file is part of the project AqHome.
+ * AqHome (c) by 2025 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/ipc/nodes/m_ipcn.h"
+#include "aqhome/msg/ipc/m_ipc.h"
+
+#include
+
+
+/* ------------------------------------------------------------------------------------------------
+ * forward declarations
+ * ------------------------------------------------------------------------------------------------
+ */
+
+
+
+/* ------------------------------------------------------------------------------------------------
+ * implementation
+ * ------------------------------------------------------------------------------------------------
+ */
+
+const char *AQH_IpcnMessage_MsgTypeToChar(uint16_t i)
+{
+ switch(i) {
+ case AQH_MSGTYPE_IPC_NODES_RESULT: return "Result";
+ case AQH_MSGTYPE_IPC_NODES_FORWARD: return "Forward";
+ case AQH_MSGTYPE_IPC_NODES_VALUE: return "Value";
+ case AQH_MSGTYPE_IPC_NODES_PING: return "Ping";
+ case AQH_MSGTYPE_IPC_NODES_SETACCMSGGRPS: return "SetAccMsgGroups";
+ case AQH_MSGTYPE_IPC_NODES_GETDEVICES_REQ: return "GetDevices(Req)";
+ case AQH_MSGTYPE_IPC_NODES_GETDEVICES_RSP: return "GetDevices(Rsp)";
+ default: return "(unknown)";
+ }
+}
+
+
+
diff --git a/aqhome/msg/ipc/nodes/m_ipcn.h b/aqhome/msg/ipc/nodes/m_ipcn.h
new file mode 100644
index 0000000..5d45bc7
--- /dev/null
+++ b/aqhome/msg/ipc/nodes/m_ipcn.h
@@ -0,0 +1,43 @@
+/****************************************************************************
+ * This file is part of the project AqHome.
+ * AqHome (c) by 2025 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_IPC_NODES_M_IPCN_H
+#define AQH_MSG_IPC_NODES_M_IPCN_H
+
+
+#include
+
+#include
+#include
+
+#include
+
+
+
+#define AQH_IPC_PROTOCOL_NODES_ID 1
+#define AQH_IPC_PROTOCOL_NODES_VERSION 1
+
+
+#define AQH_MSGTYPE_IPC_NODES_RESULT 0xf001
+
+#define AQH_MSGTYPE_IPC_NODES_FORWARD 0xf100
+#define AQH_MSGTYPE_IPC_NODES_VALUE 0xf200
+#define AQH_MSGTYPE_IPC_NODES_PING 0xf300
+#define AQH_MSGTYPE_IPC_NODES_SETACCMSGGRPS 0xf400
+#define AQH_MSGTYPE_IPC_NODES_GETDEVICES_REQ 0xf500
+#define AQH_MSGTYPE_IPC_NODES_GETDEVICES_RSP 0xf600
+
+
+AQHOME_API const char *AQH_IpcnMessage_MsgTypeToChar(uint16_t i);
+
+
+
+#endif
+
+
+
diff --git a/aqhome/msg/ipc/nodes/m_ipcn_forward.c b/aqhome/msg/ipc/nodes/m_ipcn_forward.c
new file mode 100644
index 0000000..dedbe64
--- /dev/null
+++ b/aqhome/msg/ipc/nodes/m_ipcn_forward.c
@@ -0,0 +1,80 @@
+/****************************************************************************
+ * This file is part of the project AqHome.
+ * AqHome (c) by 2025 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/ipc/nodes/m_ipcn_forward.h"
+#include "aqhome/msg/ipc/m_ipc_tag16.h"
+#include "aqhome/msg/ipc/nodes/m_ipcn.h"
+#include "aqhome/msg/ipc/m_ipc.h"
+
+#include
+#include
+#include
+
+
+
+/* ------------------------------------------------------------------------------------------------
+ * forward declarations
+ * ------------------------------------------------------------------------------------------------
+ */
+
+
+
+/* ------------------------------------------------------------------------------------------------
+ * implementation
+ * ------------------------------------------------------------------------------------------------
+ */
+
+AQH_MESSAGE *AQH_IpcnMessageForward_new(uint16_t code, uint32_t msgId, uint32_t refMsgId,
+ const uint8_t *ptr, uint32_t len)
+{
+ AQH_MESSAGE *msg;
+ GWEN_BUFFER *buf;
+
+ buf=GWEN_Buffer_new(0, 256, 0, 1);
+
+ GWEN_Tag16_WriteTagToBuffer(AQH_MSGNODE_FORWARD_TAGS_MSG, ptr, len, buf);
+
+ msg=AQH_IpcMessage_new(AQH_IPC_PROTOCOL_NODES_ID, AQH_IPC_PROTOCOL_NODES_VERSION, code, msgId, refMsgId,
+ GWEN_Buffer_GetUsedBytes(buf), (const uint8_t*) GWEN_Buffer_GetStart(buf));
+ GWEN_Buffer_free(buf);
+ return msg;
+}
+
+
+
+void AQH_IpcnMessageForward_DumpToBuffer(const AQH_MESSAGE *msg, const GWEN_TAG16_LIST *tagList, GWEN_BUFFER *dbuf, const char *sText)
+{
+ const GWEN_TAG16 *tag;
+ const uint8_t *ptr;
+ uint32_t len;
+
+ tag=tagList?GWEN_Tag16_List_FindFirstByTagType(tagList, AQH_MSGNODE_FORWARD_TAGS_MSG):NULL;
+ ptr=tag?GWEN_Tag16_GetTagData(tag):NULL;
+ len=tag?GWEN_Tag16_GetTagLength(tag):0;
+
+ GWEN_Buffer_AppendArgs(dbuf, "FORWARD(%s) %s (code=%d, protocol=%d, protocol version=%d)\n",
+ AQH_IpcnMessage_MsgTypeToChar(AQH_IpcMessage_GetCode(msg)),
+ sText?sText:"",
+ AQH_IpcMessage_GetCode(msg),
+ AQH_IpcMessage_GetProtoId(msg),
+ AQH_IpcMessage_GetProtoVersion(msg));
+ if (ptr && len) {
+ GWEN_Text_DumpString2Buffer((const char*)ptr, len, dbuf, 2);
+ GWEN_Buffer_AppendByte(dbuf, '\n');
+ }
+}
+
+
+
+
+
+
diff --git a/aqhome/msg/ipc/nodes/m_ipcn_forward.h b/aqhome/msg/ipc/nodes/m_ipcn_forward.h
new file mode 100644
index 0000000..2738820
--- /dev/null
+++ b/aqhome/msg/ipc/nodes/m_ipcn_forward.h
@@ -0,0 +1,37 @@
+/****************************************************************************
+ * This file is part of the project AqHome.
+ * AqHome (c) by 2025 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_M_IPCN_M_FORWARD_H
+#define AQH_M_IPCN_M_FORWARD_H
+
+
+
+#include
+#include
+#include
+
+#include
+#include
+
+
+
+#define AQH_MSGNODE_FORWARD_TAGS_MSG 0x01
+
+
+
+AQHOME_API AQH_MESSAGE *AQH_IpcnMessageForward_new(uint16_t code, uint32_t msgId, uint32_t refMsgId,
+ const uint8_t *ptr, uint32_t len);
+
+AQHOME_API void AQH_IpcnMessageForward_DumpToBuffer(const AQH_MESSAGE *msg, const GWEN_TAG16_LIST *tagList,
+ GWEN_BUFFER *dbuf, const char *sText);
+
+
+
+
+
+#endif
diff --git a/aqhome/msg/ipc/nodes/m_ipcn_getdevices_req.c b/aqhome/msg/ipc/nodes/m_ipcn_getdevices_req.c
new file mode 100644
index 0000000..ed058bc
--- /dev/null
+++ b/aqhome/msg/ipc/nodes/m_ipcn_getdevices_req.c
@@ -0,0 +1,57 @@
+/****************************************************************************
+ * This file is part of the project AqHome.
+ * AqHome (c) by 2025 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/ipc/nodes/m_ipcn_getdevices_req.h"
+#include "aqhome/msg/ipc/m_ipc_tag16.h"
+#include "aqhome/msg/ipc/nodes/m_ipcn.h"
+#include "aqhome/msg/ipc/m_ipc.h"
+
+#include
+#include
+#include
+
+
+
+/* ------------------------------------------------------------------------------------------------
+ * forward declarations
+ * ------------------------------------------------------------------------------------------------
+ */
+
+
+
+/* ------------------------------------------------------------------------------------------------
+ * implementation
+ * ------------------------------------------------------------------------------------------------
+ */
+
+AQH_MESSAGE *AQH_IpcnMessageGetDevicesReq_new(uint16_t code, uint32_t msgId, uint32_t refMsgId)
+{
+ return AQH_IpcMessage_new(AQH_IPC_PROTOCOL_NODES_ID, AQH_IPC_PROTOCOL_NODES_VERSION, code, msgId, refMsgId, 0, NULL);
+}
+
+
+
+void AQH_IpcnMessageGetDevicesReq_DumpToBuffer(const AQH_MESSAGE *msg, GWEN_BUFFER *dbuf, const char *sText)
+{
+ GWEN_Buffer_AppendArgs(dbuf, "GETDEVICESREQ(%s) %s (code=%d, protocol=%d, protocol version=%d)\n",
+ AQH_IpcnMessage_MsgTypeToChar(AQH_IpcMessage_GetCode(msg)),
+ sText?sText:"",
+ AQH_IpcMessage_GetCode(msg),
+ AQH_IpcMessage_GetProtoId(msg),
+ AQH_IpcMessage_GetProtoVersion(msg));
+}
+
+
+
+
+
+
diff --git a/aqhome/msg/ipc/nodes/m_ipcn_getdevices_req.h b/aqhome/msg/ipc/nodes/m_ipcn_getdevices_req.h
new file mode 100644
index 0000000..f264ece
--- /dev/null
+++ b/aqhome/msg/ipc/nodes/m_ipcn_getdevices_req.h
@@ -0,0 +1,30 @@
+/****************************************************************************
+ * This file is part of the project AqHome.
+ * AqHome (c) by 2025 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_M_IPCN_M_GETDEVICES_REQ_H
+#define AQH_M_IPCN_M_GETDEVICES_REQ_H
+
+
+
+#include
+#include
+#include
+
+#include
+#include
+
+
+
+AQHOME_API AQH_MESSAGE *AQH_IpcnMessageGetDevicesReq_new(uint16_t code, uint32_t msgId, uint32_t refMsgId);
+AQHOME_API void AQH_IpcnMessageGetDevicesReq_DumpToBuffer(const AQH_MESSAGE *msg, GWEN_BUFFER *dbuf, const char *sText);
+
+
+
+
+
+#endif
diff --git a/aqhome/msg/ipc/nodes/m_ipcn_getdevices_rsp.c b/aqhome/msg/ipc/nodes/m_ipcn_getdevices_rsp.c
new file mode 100644
index 0000000..36920da
--- /dev/null
+++ b/aqhome/msg/ipc/nodes/m_ipcn_getdevices_rsp.c
@@ -0,0 +1,100 @@
+/****************************************************************************
+ * This file is part of the project AqHome.
+ * AqHome (c) by 2025 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/ipc/nodes/m_ipcn_getdevices_rsp.h"
+#include "aqhome/msg/ipc/m_ipc_tag16.h"
+#include "aqhome/msg/ipc/nodes/m_ipcn.h"
+#include "aqhome/msg/ipc/m_ipc.h"
+
+#include
+#include
+#include
+#include
+
+
+
+/* ------------------------------------------------------------------------------------------------
+ * forward declarations
+ * ------------------------------------------------------------------------------------------------
+ */
+
+
+
+/* ------------------------------------------------------------------------------------------------
+ * implementation
+ * ------------------------------------------------------------------------------------------------
+ */
+
+AQH_MESSAGE *AQH_IpcnMessageGetDevicesRsp_new(uint16_t code, uint32_t msgId, uint32_t refMsgId, uint32_t flags, const AQH_NODE_INFO *ni)
+{
+ AQH_MESSAGE *msg;
+ GWEN_BUFFER *buf;
+
+ buf=GWEN_Buffer_new(0, 256, 0, 1);
+
+ GWEN_Tag16_WriteUint32TagToBuffer(AQH_MSGNODE_GETDEVICES_RSP_TAGS_FLAGS, flags, buf);
+ AQH_Tag16_WriteNodeInfoAsTagToBuffer(AQH_MSGNODE_GETDEVICES_RSP_TAGS_NODEINFO, ni, buf);
+
+ msg=AQH_IpcMessage_new(AQH_IPC_PROTOCOL_NODES_ID, AQH_IPC_PROTOCOL_NODES_VERSION, code, msgId, refMsgId,
+ GWEN_Buffer_GetUsedBytes(buf), (const uint8_t*) GWEN_Buffer_GetStart(buf));
+ GWEN_Buffer_free(buf);
+ return msg;
+}
+
+
+
+AQH_NODE_INFO *AQH_IpcnMessageGetDevicesRsp_ReadNodeInfo(const GWEN_TAG16_LIST *tagList)
+{
+ if (tagList) {
+ AQH_NODE_INFO *ni;
+
+ ni=AQH_Tag16_ReadNodeInfoFromTagList(tagList, AQH_MSGNODE_GETDEVICES_RSP_TAGS_NODEINFO);
+ if (ni==NULL) {
+ DBG_INFO(AQH_LOGDOMAIN, "No node info received");
+ }
+ return ni;
+ }
+ return NULL;
+}
+
+
+
+void AQH_IpcnMessageGetDevicesRsp_DumpToBuffer(const AQH_MESSAGE *msg, const GWEN_TAG16_LIST *tagList,
+ GWEN_BUFFER *dbuf, const char *sText)
+{
+ AQH_NODE_INFO *ni;
+ uint8_t busAddr;
+ uint32_t uid;
+ uint32_t flags;
+
+ ni=tagList?AQH_IpcnMessageGetDevicesRsp_ReadNodeInfo(tagList):NULL;
+ busAddr=ni?AQH_NodeInfo_GetBusAddress(ni):0;
+ uid=ni?AQH_NodeInfo_GetUid(ni):0;
+ flags=tagList?AQH_Tag16_GetTagDataAsUint32(tagList, AQH_MSGNODE_GETDEVICES_RSP_TAGS_FLAGS, 0):0;
+
+ GWEN_Buffer_AppendArgs(dbuf, "GETDEVICESRSP(%s) %s (code=%d, protocol=%d/%d, flags=%04x, addr=%d, uid=%08x)\n",
+ AQH_IpcnMessage_MsgTypeToChar(AQH_IpcMessage_GetCode(msg)),
+ sText?sText:"",
+ AQH_IpcMessage_GetCode(msg),
+ AQH_IpcMessage_GetProtoId(msg),
+ AQH_IpcMessage_GetProtoVersion(msg),
+ flags,
+ busAddr,
+ uid);
+ AQH_NodeInfo_free(ni);
+}
+
+
+
+
+
+
diff --git a/aqhome/msg/ipc/nodes/m_ipcn_getdevices_rsp.h b/aqhome/msg/ipc/nodes/m_ipcn_getdevices_rsp.h
new file mode 100644
index 0000000..d74389f
--- /dev/null
+++ b/aqhome/msg/ipc/nodes/m_ipcn_getdevices_rsp.h
@@ -0,0 +1,40 @@
+/****************************************************************************
+ * This file is part of the project AqHome.
+ * AqHome (c) by 2025 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_M_IPCN_M_GETDEVICES_RSP_H
+#define AQH_M_IPCN_M_GETDEVICES_RSP_H
+
+
+
+#include
+#include
+#include
+#include
+
+#include
+#include
+
+
+
+#define AQH_MSGNODE_GETDEVICES_RSP_TAGS_FLAGS 0x01
+#define AQH_MSGNODE_GETDEVICES_RSP_TAGS_NODEINFO 0xc2
+
+
+
+AQHOME_API AQH_MESSAGE *AQH_IpcnMessageGetDevicesRsp_new(uint16_t code, uint32_t msgId, uint32_t refMsgId,
+ uint32_t flags, const AQH_NODE_INFO *ni);
+AQHOME_API AQH_NODE_INFO *AQH_IpcnMessageGetDevicesRsp_ReadNodeInfo(const GWEN_TAG16_LIST *tagList);
+
+AQHOME_API void AQH_IpcnMessageGetDevicesRsp_DumpToBuffer(const AQH_MESSAGE *msg, const GWEN_TAG16_LIST *tagList,
+ GWEN_BUFFER *dbuf, const char *sText);
+
+
+
+
+
+#endif
diff --git a/aqhome/msg/node/0BUILD b/aqhome/msg/node/0BUILD
index 26497d0..595ef36 100644
--- a/aqhome/msg/node/0BUILD
+++ b/aqhome/msg/node/0BUILD
@@ -49,6 +49,19 @@
m_device.h
m_recvstats.h
m_sendstats.h
+ m_memstats.h
+ m_sysstats.h
+ m_addr.h
+ m_needaddr.h
+ m_ping.h
+ m_pong.h
+ m_reboot.h
+ m_value.h
+ m_flashstart.h
+ m_flashdata.h
+ m_flashend.h
+ m_flashready.h
+ m_flashresponse.h
@@ -63,6 +76,19 @@
m_device.c
m_recvstats.c
m_sendstats.c
+ m_memstats.c
+ m_sysstats.c
+ m_addr.c
+ m_needaddr.c
+ m_ping.c
+ m_pong.c
+ m_reboot.c
+ m_value.c
+ m_flashstart.c
+ m_flashdata.c
+ m_flashend.c
+ m_flashready.c
+ m_flashresponse.c
diff --git a/aqhome/msg/node/m_addr.c b/aqhome/msg/node/m_addr.c
new file mode 100644
index 0000000..62fa54b
--- /dev/null
+++ b/aqhome/msg/node/m_addr.c
@@ -0,0 +1,52 @@
+/****************************************************************************
+ * 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/node/m_addr.h"
+#include "aqhome/msg/node/m_node.h"
+
+#include
+
+
+#define AQH_MSG_OFFS_ADDR_UID 0 /* 4 bytes */
+#define AQH_MSG_OFFS_ADDR_ADDR 4 /* 1 bytes */
+
+
+
+uint32_t AQH_AddrMessage_GetUid(const AQH_MESSAGE *msg)
+{
+ return AQH_Message_ReadUint32At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_ADDR_UID, 0);
+}
+
+
+
+uint8_t AQH_AddrMessage_GetAddr(const AQH_MESSAGE *msg)
+{
+ return AQH_Message_ReadUint8At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_ADDR_ADDR, 0);
+}
+
+
+
+void AQH_AddrMessage_DumpToBuffer(const AQH_MESSAGE *msg, GWEN_BUFFER *dbuf, const char *sText)
+{
+ GWEN_Buffer_AppendArgs(dbuf,
+ "0x%02x->0x%02x: ADDR(%s) %s (uid=0x%08x, addr=%d)\n",
+ AQH_NodeMessage_GetSourceAddress(msg),
+ AQH_NodeMessage_GetDestAddress(msg),
+ AQH_NodeMessage_MsgTypeToChar(AQH_NodeMessage_GetMsgType(msg)),
+ sText,
+ (unsigned int) AQH_AddrMessage_GetUid(msg),
+ AQH_AddrMessage_GetAddr(msg));
+}
+
+
diff --git a/aqhome/msg/node/m_addr.h b/aqhome/msg/node/m_addr.h
new file mode 100644
index 0000000..f341c1a
--- /dev/null
+++ b/aqhome/msg/node/m_addr.h
@@ -0,0 +1,28 @@
+/****************************************************************************
+ * This file is part of the project AqHome.
+ * AqHome (c) by 2025 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_M_ADDR_H
+#define AQH_M_ADDR_H
+
+
+#include
+#include
+
+#include
+
+
+/* This message is used for message types ClaimAddr, DenyAddr, HaveAddr */
+
+AQHOME_API uint32_t AQH_AddrMessage_GetUid(const AQH_MESSAGE *msg);
+AQHOME_API uint8_t AQH_AddrMessage_GetAddr(const AQH_MESSAGE *msg);
+
+AQHOME_API void AQH_AddrMessage_DumpToBuffer(const AQH_MESSAGE *msg, GWEN_BUFFER *dbuf, const char *sText);
+
+
+
+#endif
diff --git a/aqhome/msg/node/m_flashdata.c b/aqhome/msg/node/m_flashdata.c
new file mode 100644
index 0000000..2560f20
--- /dev/null
+++ b/aqhome/msg/node/m_flashdata.c
@@ -0,0 +1,99 @@
+/****************************************************************************
+ * This file is part of the project AqHome.
+ * AqHome (c) by 2025 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/node/m_flashdata.h"
+#include "aqhome/msg/node/m_node.h"
+
+#include
+#include
+
+
+
+
+#define AQH_MSG_OFFS_FLASHDATA_ADDRESS 0 /* 4 bytes */
+#define AQH_MSG_OFFS_FLASHDATA_DATA 4 /* x bytes */
+
+#define AQH_MSG_FLASHDATA_MINSIZE (AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_FLASHDATA_DATA)
+
+
+
+AQH_MESSAGE *AQH_FlashDataMessage_new(uint8_t srcAddr, uint8_t destAddr, uint8_t code, uint32_t addr,
+ const uint8_t *dataPtr, uint32_t dataLen)
+{
+ AQH_MESSAGE *msg;
+ uint8_t *ptr;
+ uint32_t i;
+
+ msg=AQH_NodeMessage_prepare(destAddr, srcAddr, code, dataLen+4);
+
+ ptr=AQH_NodeMessage_GetPayloadPointer(msg);
+ *(ptr++)=addr & 0xff;
+ *(ptr++)=(addr>>8) & 0xff;
+ *(ptr++)=(addr>>16) & 0xff;
+ *(ptr++)=(addr>>24) & 0xff;
+
+ for (i=0; i=4)
+ return payloadLen-4; /* subtract uid bytes */
+ }
+ return 0;
+}
+
+
+
+const uint8_t *AQH_FlashDataMessage_GetDataPtr(const AQH_MESSAGE *msg)
+{
+ if (msg && AQH_FlashDataMessage_GetDataLen(msg))
+ return AQH_NodeMessage_GetPayloadPointer(msg)+4;
+ return NULL;
+}
+
+
+
+void AQH_FlashDataMessage_DumpToBuffer(const AQH_MESSAGE *msg, GWEN_BUFFER *dbuf, const char *sText)
+{
+ GWEN_Buffer_AppendArgs(dbuf, "0x%02x->0x%02x: FLASHDATA(%s) %s (data address=0x%04x, data length=%d)\n",
+ AQH_NodeMessage_GetSourceAddress(msg),
+ AQH_NodeMessage_GetDestAddress(msg),
+ AQH_NodeMessage_MsgTypeToChar(AQH_NodeMessage_GetMsgType(msg)),
+ sText,
+ AQH_FlashDataMessage_GetAddress(msg),
+ AQH_FlashDataMessage_GetDataLen(msg));
+}
+
+
+
+
diff --git a/aqhome/msg/node/m_flashdata.h b/aqhome/msg/node/m_flashdata.h
new file mode 100644
index 0000000..90ec4bc
--- /dev/null
+++ b/aqhome/msg/node/m_flashdata.h
@@ -0,0 +1,31 @@
+/****************************************************************************
+ * This file is part of the project AqHome.
+ * AqHome (c) by 2025 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_M_FLASHDATA_H
+#define AQH_M_FLASHDATA_H
+
+
+#include
+#include
+
+#include
+
+
+AQHOME_API AQH_MESSAGE *AQH_FlashDataMessage_new(uint8_t srcAddr, uint8_t destAddr, uint8_t code, uint32_t addr,
+ const uint8_t *dataPtr, uint32_t dataLen);
+AQHOME_API uint32_t AQH_FlashDataMessage_GetAddress(const AQH_MESSAGE *msg);
+AQHOME_API uint8_t AQH_FlashDataMessage_GetDataLen(const AQH_MESSAGE *msg);
+AQHOME_API const uint8_t *AQH_FlashDataMessage_GetDataPtr(const AQH_MESSAGE *msg);
+
+AQHOME_API void AQH_FlashDataMessage_DumpToBuffer(const AQH_MESSAGE *msg, GWEN_BUFFER *dbuf, const char *sText);
+
+
+
+
+
+#endif
diff --git a/aqhome/msg/node/m_flashend.c b/aqhome/msg/node/m_flashend.c
new file mode 100644
index 0000000..9758de5
--- /dev/null
+++ b/aqhome/msg/node/m_flashend.c
@@ -0,0 +1,62 @@
+/****************************************************************************
+ * This file is part of the project AqHome.
+ * AqHome (c) by 2025 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/node/m_flashend.h"
+#include "aqhome/msg/node/m_node.h"
+
+#include
+#include
+
+
+
+#define AQH_MSG_OFFS_FLASHEND_REASON 0 /* 1 byte */
+
+
+
+AQH_MESSAGE *AQH_FlashEndMessage_new(uint8_t srcAddr, uint8_t destAddr, uint8_t code, uint8_t reason)
+{
+ AQH_MESSAGE *msg;
+ uint8_t *ptr;
+
+ msg=AQH_NodeMessage_prepare(destAddr, srcAddr, code, 1);
+
+ ptr=AQH_NodeMessage_GetPayloadPointer(msg);
+ *(ptr++)=reason & 0xff;
+ AQH_NodeMessage_AddChecksum(msg);
+
+ return msg;
+}
+
+
+
+uint8_t AQH_FlashEndMessage_GetReason(const AQH_MESSAGE *msg)
+{
+ return AQH_Message_ReadUint8At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_FLASHEND_REASON, 0);
+}
+
+
+
+void AQH_FlashEndMessage_DumpToBuffer(const AQH_MESSAGE *msg, GWEN_BUFFER *dbuf, const char *sText)
+{
+ GWEN_Buffer_AppendArgs(dbuf, "0x%02x->0x%02x: FLASHEND(%s) %s (reason=%d)\n",
+ AQH_NodeMessage_GetSourceAddress(msg),
+ AQH_NodeMessage_GetDestAddress(msg),
+ AQH_NodeMessage_MsgTypeToChar(AQH_NodeMessage_GetMsgType(msg)),
+ sText,
+ AQH_FlashEndMessage_GetReason(msg));
+}
+
+
+
+
diff --git a/aqhome/msg/node/m_flashend.h b/aqhome/msg/node/m_flashend.h
new file mode 100644
index 0000000..0cbfe93
--- /dev/null
+++ b/aqhome/msg/node/m_flashend.h
@@ -0,0 +1,26 @@
+/****************************************************************************
+ * This file is part of the project AqHome.
+ * AqHome (c) by 2025 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_M_FLASHEND_H
+#define AQH_M_FLASHEND_H
+
+
+#include
+#include
+
+#include
+
+
+AQHOME_API AQH_MESSAGE *AQH_FlashEndMessage_new(uint8_t srcAddr, uint8_t destAddr, uint8_t code, uint8_t reason);
+AQHOME_API uint8_t AQH_FlashEndMessage_GetReason(const AQH_MESSAGE *msg);
+
+AQHOME_API void AQH_FlashEndMessage_DumpToBuffer(const AQH_MESSAGE *msg, GWEN_BUFFER *dbuf, const char *sText);
+
+
+
+#endif
diff --git a/aqhome/msg/node/m_flashready.c b/aqhome/msg/node/m_flashready.c
new file mode 100644
index 0000000..9f41c9e
--- /dev/null
+++ b/aqhome/msg/node/m_flashready.c
@@ -0,0 +1,126 @@
+/****************************************************************************
+ * This file is part of the project AqHome.
+ * AqHome (c) by 2025 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/node/m_flashready.h"
+#include "aqhome/msg/node/m_node.h"
+
+#include
+//#include
+
+
+
+#define AQH_MSG_OFFS_FLASHREADY_UID 0 /* 4 bytes */
+#define AQH_MSG_OFFS_FLASHREADY_MANUF 4 /* 4 bytes */
+#define AQH_MSG_OFFS_FLASHREADY_DEVTYPE 8 /* 2 bytes */
+#define AQH_MSG_OFFS_FLASHREADY_DEVVERSION 10 /* 1 byte */
+#define AQH_MSG_OFFS_FLASHREADY_DEVREVISION 11 /* 1 byte */
+#define AQH_MSG_OFFS_FLASHREADY_FWVARIANT 12 /* 1 byte */
+#define AQH_MSG_OFFS_FLASHREADY_FWVMAJOR 13 /* 1 byte */
+#define AQH_MSG_OFFS_FLASHREADY_FWVMINOR 14 /* 1 byte */
+#define AQH_MSG_OFFS_FLASHREADY_FWVPATCH 15 /* 1 byte */
+#define AQH_MSG_OFFS_FLASHREADY_PAGESIZE 16 /* 2 bytes */
+
+
+
+uint32_t AQH_FlashReadyMessage_GetUid(const AQH_MESSAGE *msg)
+{
+ return AQH_Message_ReadUint32At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_FLASHREADY_UID, 0);
+}
+
+
+
+uint32_t AQH_FlashReadyMessage_GetManufacturer(const AQH_MESSAGE *msg)
+{
+ return AQH_Message_ReadUint32At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_FLASHREADY_MANUF, 0);
+}
+
+
+
+uint16_t AQH_FlashReadyMessage_GetDeviceType(const AQH_MESSAGE *msg)
+{
+ return AQH_Message_ReadUint16At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_FLASHREADY_DEVTYPE, 0);
+}
+
+
+
+uint8_t AQH_FlashReadyMessage_GetDeviceVersion(const AQH_MESSAGE *msg)
+{
+ return AQH_Message_ReadUint8At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_FLASHREADY_DEVVERSION, 0);
+}
+
+
+
+uint8_t AQH_FlashReadyMessage_GetDeviceRevision(const AQH_MESSAGE *msg)
+{
+ return AQH_Message_ReadUint8At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_FLASHREADY_DEVREVISION, 0);
+}
+
+
+
+uint8_t AQH_FlashReadyMessage_GetFirmwareVariant(const AQH_MESSAGE *msg)
+{
+ return AQH_Message_ReadUint8At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_FLASHREADY_FWVARIANT, 0);
+}
+
+
+uint8_t AQH_FlashReadyMessage_GetFirmwareVersionMajor(const AQH_MESSAGE *msg)
+{
+ return AQH_Message_ReadUint8At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_FLASHREADY_FWVMAJOR, 0);
+}
+
+
+
+uint8_t AQH_FlashReadyMessage_GetFirmwareVersionMinor(const AQH_MESSAGE *msg)
+{
+ return AQH_Message_ReadUint8At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_FLASHREADY_FWVMINOR, 0);
+}
+
+
+
+uint8_t AQH_FlashReadyMessage_GetFirmwareVersionPatchlevel(const AQH_MESSAGE *msg)
+{
+ return AQH_Message_ReadUint8At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_FLASHREADY_FWVPATCH, 0);
+}
+
+
+
+uint16_t AQH_FlashReadyMessage_GetPagesize(const AQH_MESSAGE *msg)
+{
+ return AQH_Message_ReadUint16At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_FLASHREADY_PAGESIZE, 0);
+}
+
+
+
+void AQH_FlashReadyMessage_DumpToBuffer(const AQH_MESSAGE *msg, GWEN_BUFFER *dbuf, const char *sText)
+{
+ GWEN_Buffer_AppendArgs(dbuf,
+ "0x%02x->0x%02x: FLASHREADY(%s) %s (uid=0x%08x, dev=%08x:%04x v%d.%d, fw=%d.%d.%d (%d) pagesize=%d)\n",
+ AQH_NodeMessage_GetSourceAddress(msg),
+ AQH_NodeMessage_GetDestAddress(msg),
+ AQH_NodeMessage_MsgTypeToChar(AQH_NodeMessage_GetMsgType(msg)),
+ sText,
+ (unsigned int) AQH_FlashReadyMessage_GetUid(msg),
+ AQH_FlashReadyMessage_GetManufacturer(msg),
+ AQH_FlashReadyMessage_GetDeviceType(msg),
+ AQH_FlashReadyMessage_GetDeviceVersion(msg),
+ AQH_FlashReadyMessage_GetDeviceRevision(msg),
+ AQH_FlashReadyMessage_GetFirmwareVersionMajor(msg),
+ AQH_FlashReadyMessage_GetFirmwareVersionMinor(msg),
+ AQH_FlashReadyMessage_GetFirmwareVersionPatchlevel(msg),
+ AQH_FlashReadyMessage_GetFirmwareVariant(msg),
+ AQH_FlashReadyMessage_GetPagesize(msg));
+}
+
+
+
diff --git a/aqhome/msg/node/m_flashready.h b/aqhome/msg/node/m_flashready.h
new file mode 100644
index 0000000..06129b3
--- /dev/null
+++ b/aqhome/msg/node/m_flashready.h
@@ -0,0 +1,34 @@
+/****************************************************************************
+ * This file is part of the project AqHome.
+ * AqHome (c) by 2025 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_M_FLASHREADY_H
+#define AQH_M_FLASHREADY_H
+
+
+#include
+#include
+
+#include
+
+
+AQHOME_API uint32_t AQH_FlashReadyMessage_GetUid(const AQH_MESSAGE *msg);
+AQHOME_API uint32_t AQH_FlashReadyMessage_GetManufacturer(const AQH_MESSAGE *msg);
+AQHOME_API uint16_t AQH_FlashReadyMessage_GetDeviceType(const AQH_MESSAGE *msg);
+AQHOME_API uint8_t AQH_FlashReadyMessage_GetDeviceVersion(const AQH_MESSAGE *msg);
+AQHOME_API uint8_t AQH_FlashReadyMessage_GetDeviceRevision(const AQH_MESSAGE *msg);
+AQHOME_API uint8_t AQH_FlashReadyMessage_GetFirmwareVariant(const AQH_MESSAGE *msg);
+AQHOME_API uint8_t AQH_FlashReadyMessage_GetFirmwareVersionMajor(const AQH_MESSAGE *msg);
+AQHOME_API uint8_t AQH_FlashReadyMessage_GetFirmwareVersionMinor(const AQH_MESSAGE *msg);
+AQHOME_API uint8_t AQH_FlashReadyMessage_GetFirmwareVersionPatchlevel(const AQH_MESSAGE *msg);
+AQHOME_API uint16_t AQH_FlashReadyMessage_GetPagesize(const AQH_MESSAGE *msg);
+
+AQHOME_API void AQH_FlashReadyMessage_DumpToBuffer(const AQH_MESSAGE *msg, GWEN_BUFFER *dbuf, const char *sText);
+
+
+
+#endif
diff --git a/aqhome/msg/node/m_flashresponse.c b/aqhome/msg/node/m_flashresponse.c
new file mode 100644
index 0000000..a99a3a5
--- /dev/null
+++ b/aqhome/msg/node/m_flashresponse.c
@@ -0,0 +1,45 @@
+/****************************************************************************
+ * This file is part of the project AqHome.
+ * AqHome (c) by 2025 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/node/m_flashresponse.h"
+#include "aqhome/msg/node/m_node.h"
+
+#include
+
+
+
+#define AQH_MSG_OFFS_FLASHRESPONSE_CODE 0 /* 1 byte */
+
+
+
+uint8_t AQH_FlashResponseMessage_GetCode(const AQH_MESSAGE *msg)
+{
+ return AQH_Message_ReadUint8At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_FLASHRESPONSE_CODE, 0);
+}
+
+
+
+void AQH_FlashResponseMessage_DumpToBuffer(const AQH_MESSAGE *msg, GWEN_BUFFER *dbuf, const char *sText)
+{
+ GWEN_Buffer_AppendArgs(dbuf, "0x%02x->0x%02x: FLASHRESPONSE(%s) %s (code=%d)\n",
+ AQH_NodeMessage_GetSourceAddress(msg),
+ AQH_NodeMessage_GetDestAddress(msg),
+ AQH_NodeMessage_MsgTypeToChar(AQH_NodeMessage_GetMsgType(msg)),
+ sText,
+ AQH_FlashResponseMessage_GetCode(msg));
+}
+
+
+
+
diff --git a/aqhome/msg/node/m_flashresponse.h b/aqhome/msg/node/m_flashresponse.h
new file mode 100644
index 0000000..1698dc1
--- /dev/null
+++ b/aqhome/msg/node/m_flashresponse.h
@@ -0,0 +1,26 @@
+/****************************************************************************
+ * This file is part of the project AqHome.
+ * AqHome (c) by 2025 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_M_FLASHRESPONSE_H
+#define AQH_M_FLASHRESPONSE_H
+
+
+#include
+#include
+
+#include
+
+
+AQHOME_API uint8_t AQH_FlashResponseMessage_GetCode(const AQH_MESSAGE *msg);
+
+AQHOME_API void AQH_FlashResponseMessage_DumpToBuffer(const AQH_MESSAGE *msg, GWEN_BUFFER *dbuf, const char *sText);
+
+
+
+
+#endif
diff --git a/aqhome/msg/node/m_flashstart.c b/aqhome/msg/node/m_flashstart.c
new file mode 100644
index 0000000..37ad10f
--- /dev/null
+++ b/aqhome/msg/node/m_flashstart.c
@@ -0,0 +1,55 @@
+/****************************************************************************
+ * This file is part of the project AqHome.
+ * AqHome (c) by 2025 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/node/m_flashstart.h"
+#include "aqhome/msg/node/m_node.h"
+
+#include
+#include
+
+
+
+#define AQH_MSG_OFFS_FLASHSTART_UID 0 /* 4 bytes */
+
+
+
+AQH_MESSAGE *AQH_FlashStartMessage_new(uint8_t destAddr, uint8_t srcAddr, uint8_t code, uint32_t uid)
+{
+ uint32_t payload;
+
+ payload=GWEN_ENDIAN_HTOLE32(uid);
+ return AQH_NodeMessage_new(destAddr, srcAddr, code, sizeof(payload), (const uint8_t*)&payload);
+}
+
+
+
+uint32_t AQH_FlashStartMessage_GetUid(const AQH_MESSAGE *msg)
+{
+ return AQH_Message_ReadUint32At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_FLASHSTART_UID, 0);
+}
+
+
+
+void AQH_FlashStartMessage_DumpToBuffer(const AQH_MESSAGE *msg, GWEN_BUFFER *dbuf, const char *sText)
+{
+ GWEN_Buffer_AppendArgs(dbuf,
+ "0x%02x->0x%02x: FLASHSTART(%s) %s (uid=0x%08x)\n",
+ AQH_NodeMessage_GetSourceAddress(msg),
+ AQH_NodeMessage_GetDestAddress(msg),
+ AQH_NodeMessage_MsgTypeToChar(AQH_NodeMessage_GetMsgType(msg)),
+ sText,
+ (unsigned int) AQH_FlashStartMessage_GetUid(msg));
+}
+
+
diff --git a/aqhome/msg/node/m_flashstart.h b/aqhome/msg/node/m_flashstart.h
new file mode 100644
index 0000000..f9ac84e
--- /dev/null
+++ b/aqhome/msg/node/m_flashstart.h
@@ -0,0 +1,31 @@
+/****************************************************************************
+ * This file is part of the project AqHome.
+ * AqHome (c) by 2025 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_M_FLASHSTART_H
+#define AQH_M_FLASHSTART_H
+
+
+#include
+#include
+
+#include
+
+
+AQHOME_API AQH_MESSAGE *AQH_FlashStartMessage_new(uint8_t destAddr, uint8_t srcAddr, uint8_t code, uint32_t uid);
+AQHOME_API uint32_t AQH_FlashStartMessage_GetUid(const AQH_MESSAGE *msg);
+
+AQHOME_API void AQH_FlashStartMessage_DumpToBuffer(const AQH_MESSAGE *msg, GWEN_BUFFER *dbuf, const char *sText);
+
+
+
+
+
+
+
+
+#endif
diff --git a/aqhome/msg/node/m_memstats.c b/aqhome/msg/node/m_memstats.c
new file mode 100644
index 0000000..bbbf073
--- /dev/null
+++ b/aqhome/msg/node/m_memstats.c
@@ -0,0 +1,89 @@
+/****************************************************************************
+ * This file is part of the project AqHome.
+ * AqHome (c) by 2025 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/node/m_memstats.h"
+#include "aqhome/msg/node/m_node.h"
+
+#include
+
+
+
+#define AQH_MSG_OFFS_MEMSTATS_SECONDS 0 /* 4 bytes */
+#define AQH_MSG_OFFS_MEMSTATS_UID 4 /* 4 bytes */
+#define AQH_MSG_OFFS_MEMSTATS_STACKUSAGE 8 /* 2 bytes */
+#define AQH_MSG_OFFS_MEMSTATS_BUFFERSUSED 10 /* 1 byte */
+#define AQH_MSG_OFFS_MEMSTATS_MAXBUFFERSUSED 11 /* 1 byte */
+#define AQH_MSG_OFFS_MEMSTATS_RECVNOBUFFER 12 /* 2 bytes */
+
+
+
+uint32_t AQH_MemStatsMessage_GetUid(const AQH_MESSAGE *msg)
+{
+ return AQH_Message_ReadUint32At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_MEMSTATS_UID, 0);
+}
+
+
+
+uint32_t AQH_MemStatsMessage_GetSeconds(const AQH_MESSAGE *msg)
+{
+ return AQH_Message_ReadUint32At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_MEMSTATS_SECONDS, 0);
+}
+
+
+uint16_t AQH_MemStatsMessage_GetStackUsage(const AQH_MESSAGE *msg)
+{
+ return AQH_Message_ReadUint16At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_MEMSTATS_STACKUSAGE, 0);
+}
+
+
+
+uint8_t AQH_MemStatsMessage_GetBuffersUsed(const AQH_MESSAGE *msg)
+{
+ return AQH_Message_ReadUint8At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_MEMSTATS_BUFFERSUSED, 0);
+}
+
+
+
+uint8_t AQH_MemStatsMessage_GetMaxBuffersUsed(const AQH_MESSAGE *msg)
+{
+ return AQH_Message_ReadUint8At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_MEMSTATS_MAXBUFFERSUSED, 0);
+}
+
+
+
+uint16_t AQH_MemStatsMessage_GetRecvNoBufferErrors(const AQH_MESSAGE *msg)
+{
+ return AQH_Message_ReadUint16At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_MEMSTATS_RECVNOBUFFER, 0);
+}
+
+
+
+void AQH_MemStatsMessage_DumpToBuffer(const AQH_MESSAGE *msg, GWEN_BUFFER *dbuf, const char *sText)
+{
+ GWEN_Buffer_AppendArgs(dbuf,
+ "0x%02x->0x%02x: MEMSTATS(%s) %s (uid=0x%08x, uptime=%d, stack used=%d, buffers used=%d(max=%d), no recvbuf=%d)\n",
+ AQH_NodeMessage_GetSourceAddress(msg),
+ AQH_NodeMessage_GetDestAddress(msg),
+ AQH_NodeMessage_MsgTypeToChar(AQH_NodeMessage_GetMsgType(msg)),
+ sText,
+ (unsigned int) AQH_MemStatsMessage_GetUid(msg),
+ AQH_MemStatsMessage_GetSeconds(msg),
+ AQH_MemStatsMessage_GetStackUsage(msg),
+ AQH_MemStatsMessage_GetBuffersUsed(msg),
+ AQH_MemStatsMessage_GetMaxBuffersUsed(msg),
+ AQH_MemStatsMessage_GetRecvNoBufferErrors(msg));
+}
+
+
+
diff --git a/aqhome/msg/node/m_memstats.h b/aqhome/msg/node/m_memstats.h
new file mode 100644
index 0000000..a461112
--- /dev/null
+++ b/aqhome/msg/node/m_memstats.h
@@ -0,0 +1,38 @@
+/****************************************************************************
+ * This file is part of the project AqHome.
+ * AqHome (c) by 2025 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_M_MEMSTATS_H
+#define AQH_M_MEMSTATS_H
+
+
+#include
+#include
+
+#include
+
+
+AQHOME_API uint32_t AQH_MemStatsMessage_GetUid(const AQH_MESSAGE *msg);
+AQHOME_API uint32_t AQH_MemStatsMessage_GetSeconds(const AQH_MESSAGE *msg);
+AQHOME_API uint16_t AQH_MemStatsMessage_GetStackUsage(const AQH_MESSAGE *msg);
+AQHOME_API uint8_t AQH_MemStatsMessage_GetBuffersUsed(const AQH_MESSAGE *msg);
+AQHOME_API uint8_t AQH_MemStatsMessage_GetMaxBuffersUsed(const AQH_MESSAGE *msg);
+AQHOME_API uint16_t AQH_MemStatsMessage_GetRecvNoBufferErrors(const AQH_MESSAGE *msg);
+
+AQHOME_API void AQH_MemStatsMessage_DumpToBuffer(const AQH_MESSAGE *msg, GWEN_BUFFER *dbuf, const char *sText);
+
+
+
+
+
+
+
+
+
+
+
+#endif
diff --git a/aqhome/msg/node/m_needaddr.c b/aqhome/msg/node/m_needaddr.c
new file mode 100644
index 0000000..a479723
--- /dev/null
+++ b/aqhome/msg/node/m_needaddr.c
@@ -0,0 +1,43 @@
+/****************************************************************************
+ * This file is part of the project AqHome.
+ * AqHome (c) by 2025 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/node/m_needaddr.h"
+#include "aqhome/msg/node/m_node.h"
+
+#include
+
+
+#define AQH_MSG_OFFS_NEEDADDR_UID 0 /* 4 bytes */
+
+
+
+uint32_t AQH_NeedAddrMessage_GetUid(const AQH_MESSAGE *msg)
+{
+ return AQH_Message_ReadUint32At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_NEEDADDR_UID, 0);
+}
+
+
+
+void AQH_NeedAddrMessage_DumpToBuffer(const AQH_MESSAGE *msg, GWEN_BUFFER *dbuf, const char *sText)
+{
+ GWEN_Buffer_AppendArgs(dbuf,
+ "0x%02x->0x%02x: NEEDADDR(%s) %s (uid=0x%08x)\n",
+ AQH_NodeMessage_GetSourceAddress(msg),
+ AQH_NodeMessage_GetDestAddress(msg),
+ AQH_NodeMessage_MsgTypeToChar(AQH_NodeMessage_GetMsgType(msg)),
+ sText,
+ (unsigned int) AQH_NeedAddrMessage_GetUid(msg));
+}
+
+
diff --git a/aqhome/msg/node/m_needaddr.h b/aqhome/msg/node/m_needaddr.h
new file mode 100644
index 0000000..14d5fbb
--- /dev/null
+++ b/aqhome/msg/node/m_needaddr.h
@@ -0,0 +1,25 @@
+/****************************************************************************
+ * This file is part of the project AqHome.
+ * AqHome (c) by 2025 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_M_NEEDADDR_H
+#define AQH_M_NEEDADDR_H
+
+
+#include
+#include
+
+#include
+
+
+AQHOME_API uint32_t AQH_NeedAddrMessage_GetUid(const AQH_MESSAGE *msg);
+
+AQHOME_API void AQH_NeedAddrMessage_DumpToBuffer(const AQH_MESSAGE *msg, GWEN_BUFFER *dbuf, const char *sText);
+
+
+
+#endif
diff --git a/aqhome/msg/node/m_node.c b/aqhome/msg/node/m_node.c
index a0b0e6c..7db1b76 100644
--- a/aqhome/msg/node/m_node.c
+++ b/aqhome/msg/node/m_node.c
@@ -10,9 +10,25 @@
# include
#endif
-
#include "aqhome/msg/node/m_node.h"
+#include "aqhome/msg/node/m_device.h"
+#include "aqhome/msg/node/m_recvstats.h"
+#include "aqhome/msg/node/m_sendstats.h"
+#include "aqhome/msg/node/m_memstats.h"
+#include "aqhome/msg/node/m_sysstats.h"
+#include "aqhome/msg/node/m_addr.h"
+#include "aqhome/msg/node/m_needaddr.h"
+#include "aqhome/msg/node/m_ping.h"
+#include "aqhome/msg/node/m_pong.h"
+#include "aqhome/msg/node/m_reboot.h"
+#include "aqhome/msg/node/m_value.h"
+#include "aqhome/msg/node/m_flashstart.h"
+#include "aqhome/msg/node/m_flashdata.h"
+#include "aqhome/msg/node/m_flashend.h"
+#include "aqhome/msg/node/m_flashready.h"
+#include "aqhome/msg/node/m_flashresponse.h"
+
#include
@@ -49,7 +65,7 @@ AQH_MESSAGE *AQH_NodeMessage_new(uint8_t destAddr, uint8_t srcAddr, uint8_t code
if (payloadLen && payload)
memmove(ptr+AQH_MSG_OFFS_ALL_DATA_BEGIN, payload, payloadLen);
- AQH_Message_SetUsedSize(msg, len);
+ AQH_Message_SetUsedSize(msg, len-1);
AQH_NodeMessage_AddChecksum(msg);
return msg;
@@ -57,6 +73,29 @@ AQH_MESSAGE *AQH_NodeMessage_new(uint8_t destAddr, uint8_t srcAddr, uint8_t code
+AQH_MESSAGE *AQH_NodeMessage_prepare(uint8_t destAddr, uint8_t srcAddr, uint8_t code, uint8_t payloadLen)
+{
+ AQH_MESSAGE *msg;
+ uint8_t *ptr;
+ uint32_t len;
+
+ len=AQH_MSG_OFFS_ALL_DATA_BEGIN+payloadLen+1; /* dest, len, code, src, payload, crc8 */
+ msg=AQH_Message_new();
+ AQH_Message_SetData(msg, NULL, len); /* auto-malloc len bytes */
+
+ ptr=AQH_Message_GetMsgPointer(msg);
+ ptr[AQH_MSG_OFFS_ALL_DEST_ADDRESS]=destAddr & 0xff;
+ ptr[AQH_MSG_OFFS_ALL_PAYLOAD_LEN]=payloadLen+2; /* code, src, payload */
+ ptr[AQH_MSG_OFFS_ALL_MSG_TYPE]=code;
+ ptr[AQH_MSG_OFFS_ALL_SRC_ADDRESS]=srcAddr;
+
+ AQH_Message_SetUsedSize(msg, len-1);
+
+ return msg;
+}
+
+
+
AQH_MESSAGE *AQH_NodeMessage_fromBuffer(const uint8_t *ptr, uint32_t len)
{
if (ptr && len) {
@@ -191,6 +230,42 @@ const char *AQH_NodeMessage_MsgTypeToChar(uint8_t i)
+void AQH_NodeMessage_DumpSpecificToBuffer(const AQH_MESSAGE *msg, GWEN_BUFFER *dbuf, const char *sText)
+{
+ if (msg && dbuf) {
+ switch(AQH_NodeMessage_GetMsgType(msg)) {
+ case AQH_MSG_TYPE_PING: AQH_PingMessage_DumpToBuffer(msg, dbuf, sText); break;
+ case AQH_MSG_TYPE_PONG: AQH_PongMessage_DumpToBuffer(msg, dbuf, sText); break;
+ case AQH_MSG_TYPE_COMSENDSTATS: AQH_SendStatsMessage_DumpToBuffer(msg, dbuf, sText); break;
+ case AQH_MSG_TYPE_COMRECVSTATS: AQH_RecvStatsMessage_DumpToBuffer(msg, dbuf, sText); break;
+ case AQH_MSG_TYPE_VALUE: AQH_ValueMessage_DumpToBuffer(msg, dbuf, sText); break;
+ case AQH_MSG_TYPE_NEED_ADDRESS: AQH_AddrMessage_DumpToBuffer(msg, dbuf, sText); break;
+ case AQH_MSG_TYPE_HAVE_ADDRESS: AQH_AddrMessage_DumpToBuffer(msg, dbuf, sText); break;
+ case AQH_MSG_TYPE_CLAIM_ADDRESS: AQH_AddrMessage_DumpToBuffer(msg, dbuf, sText); break;
+ case AQH_MSG_TYPE_DENY_ADDRESS: AQH_AddrMessage_DumpToBuffer(msg, dbuf, sText); break;
+
+ case AQH_MSG_TYPE_FLASH_START: AQH_FlashStartMessage_DumpToBuffer(msg, dbuf, sText); break;
+ case AQH_MSG_TYPE_FLASH_END: AQH_FlashEndMessage_DumpToBuffer(msg, dbuf, sText); break;
+ case AQH_MSG_TYPE_FLASH_READY: AQH_FlashReadyMessage_DumpToBuffer(msg, dbuf, sText); break;
+ case AQH_MSG_TYPE_FLASH_DATA: AQH_FlashDataMessage_DumpToBuffer(msg, dbuf, sText); break;
+ case AQH_MSG_TYPE_FLASH_RSP: AQH_FlashResponseMessage_DumpToBuffer(msg, dbuf, sText); break;
+
+ case AQH_MSG_TYPE_DEVICE: AQH_DeviceMessage_DumpToBuffer(msg, dbuf, sText); break;
+ case AQH_MSG_TYPE_MEMSTATS: AQH_MemStatsMessage_DumpToBuffer(msg, dbuf, sText); break;
+ case AQH_MSG_TYPE_SYSSTATS: AQH_SysStatsMessage_DumpToBuffer(msg, dbuf, sText); break;
+ case AQH_MSG_TYPE_REBOOT_REQ: AQH_RebootMessage_DumpToBuffer(msg, dbuf, sText); break;
+ case AQH_MSG_TYPE_REBOOT_RSP: AQH_RebootMessage_DumpToBuffer(msg, dbuf, sText); break;
+
+ case AQH_MSG_TYPE_DEBUG:
+ case AQH_MSG_TYPE_TWIBUSMEMBER:
+ case AQH_MSG_TYPE_ADDRESS_RANGE:
+ default: AQH_NodeMessage_DumpToBuffer(msg, dbuf, sText); break;
+ }
+ }
+}
+
+
+
uint32_t AQH_NodeMessage_GetMsgGroup(uint8_t msgType)
{
switch(msgType) {
diff --git a/aqhome/msg/node/m_node.h b/aqhome/msg/node/m_node.h
index 3b2676a..ba9acb2 100644
--- a/aqhome/msg/node/m_node.h
+++ b/aqhome/msg/node/m_node.h
@@ -72,19 +72,11 @@
#define AQH_MSG_TYPEGROUP_ALL 0xffffffff
-#if 0
-#define AQH_MSG_MODULES_MASK_TIMER 0x02
-#define AQH_MSG_MODULES_MASK_COM 0x04
-#define AQH_MSG_MODULES_MASK_LED 0x08
-#define AQH_MSG_MODULES_MASK_TWIMASTER 0x10
-#define AQH_MSG_MODULES_MASK_LCD 0x20
-#define AQH_MSG_MODULES_MASK_SI7021 0x40
-#define AQH_MSG_MODULES_MASK_STATS 0x80
-#endif
-
AQHOME_API AQH_MESSAGE *AQH_NodeMessage_new(uint8_t destAddr, uint8_t srcAddr, uint8_t code, uint8_t payloadLen, const uint8_t *payload);
-AQH_MESSAGE *AQH_NodeMessage_fromBuffer(const uint8_t *ptr, uint32_t len);
+AQHOME_API AQH_MESSAGE *AQH_NodeMessage_prepare(uint8_t destAddr, uint8_t srcAddr, uint8_t code, uint8_t payloadLen);
+
+AQHOME_API AQH_MESSAGE *AQH_NodeMessage_fromBuffer(const uint8_t *ptr, uint32_t len);
AQHOME_API uint8_t AQH_NodeMessage_GetDestAddress(const AQH_MESSAGE *msg);
AQHOME_API uint8_t AQH_NodeMessage_GetMsgType(const AQH_MESSAGE *msg);
@@ -117,5 +109,10 @@ AQHOME_API uint32_t AQH_NodeMessage_GetMsgGroup(uint8_t msgType);
AQHOME_API void AQH_NodeMessage_DumpToBuffer(const AQH_MESSAGE *msg, GWEN_BUFFER *dbuf, const char *sText);
+/**
+ * Calls the dump function of the given message according to its message type.
+ */
+AQHOME_API void AQH_NodeMessage_DumpSpecificToBuffer(const AQH_MESSAGE *msg, GWEN_BUFFER *dbuf, const char *sText);
#endif
+
diff --git a/aqhome/msg/node/m_ping.c b/aqhome/msg/node/m_ping.c
new file mode 100644
index 0000000..98b83a8
--- /dev/null
+++ b/aqhome/msg/node/m_ping.c
@@ -0,0 +1,55 @@
+/****************************************************************************
+ * This file is part of the project AqHome.
+ * AqHome (c) by 2025 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/node/m_ping.h"
+#include "aqhome/msg/node/m_node.h"
+
+#include
+#include
+
+
+
+#define AQH_MSG_OFFS_PING_TIMESTAMP 0 /* 4 bytes */
+
+
+
+AQH_MESSAGE *AQH_PingMessage_new(uint8_t destAddr, uint8_t srcAddr, uint8_t code, uint32_t timestamp)
+{
+ uint32_t payload;
+
+ payload=GWEN_ENDIAN_HTOLE32(timestamp);
+ return AQH_NodeMessage_new(destAddr, srcAddr, code, sizeof(payload), (const uint8_t*)&payload);
+}
+
+
+
+uint32_t AQH_PingMessage_GetTimestamp(const AQH_MESSAGE *msg)
+{
+ return AQH_Message_ReadUint32At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_PING_TIMESTAMP, 0);
+}
+
+
+
+void AQH_PingMessage_DumpToBuffer(const AQH_MESSAGE *msg, GWEN_BUFFER *dbuf, const char *sText)
+{
+ GWEN_Buffer_AppendArgs(dbuf,
+ "0x%02x->0x%02x: PING(%s) %s (timestamp=0x%08x)\n",
+ AQH_NodeMessage_GetSourceAddress(msg),
+ AQH_NodeMessage_GetDestAddress(msg),
+ AQH_NodeMessage_MsgTypeToChar(AQH_NodeMessage_GetMsgType(msg)),
+ sText,
+ (unsigned int) AQH_PingMessage_GetTimestamp(msg));
+}
+
+
diff --git a/aqhome/msg/node/m_ping.h b/aqhome/msg/node/m_ping.h
new file mode 100644
index 0000000..8b61b54
--- /dev/null
+++ b/aqhome/msg/node/m_ping.h
@@ -0,0 +1,28 @@
+/****************************************************************************
+ * This file is part of the project AqHome.
+ * AqHome (c) by 2025 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_M_PING_H
+#define AQH_M_PING_H
+
+
+#include
+#include
+
+#include
+
+
+AQHOME_API AQH_MESSAGE *AQH_PingMessage_new(uint8_t destAddr, uint8_t srcAddr, uint8_t code, uint32_t timestamp);
+AQHOME_API uint32_t AQH_PingMessage_GetTimestamp(const AQH_MESSAGE *msg);
+
+AQHOME_API void AQH_PingMessage_DumpToBuffer(const AQH_MESSAGE *msg, GWEN_BUFFER *dbuf, const char *sText);
+
+
+
+
+
+#endif
diff --git a/aqhome/msg/node/m_pong.c b/aqhome/msg/node/m_pong.c
new file mode 100644
index 0000000..1bfeb6a
--- /dev/null
+++ b/aqhome/msg/node/m_pong.c
@@ -0,0 +1,55 @@
+/****************************************************************************
+ * This file is part of the project AqHome.
+ * AqHome (c) by 2025 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/node/m_pong.h"
+#include "aqhome/msg/node/m_node.h"
+
+#include
+#include
+
+
+
+#define AQH_MSG_OFFS_PONG_TIMESTAMP 0 /* 4 bytes */
+
+
+
+AQH_MESSAGE *AQH_PongMessage_new(uint8_t destAddr, uint8_t srcAddr, uint8_t code, uint32_t timestamp)
+{
+ uint32_t payload;
+
+ payload=GWEN_ENDIAN_HTOLE32(timestamp);
+ return AQH_NodeMessage_new(destAddr, srcAddr, code, sizeof(payload), (const uint8_t*)&payload);
+}
+
+
+
+uint32_t AQH_PongMessage_GetTimestamp(const AQH_MESSAGE *msg)
+{
+ return AQH_Message_ReadUint32At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_PONG_TIMESTAMP, 0);
+}
+
+
+
+void AQH_PongMessage_DumpToBuffer(const AQH_MESSAGE *msg, GWEN_BUFFER *dbuf, const char *sText)
+{
+ GWEN_Buffer_AppendArgs(dbuf,
+ "0x%02x->0x%02x: PONG(%s) %s (uid=0x%08x)\n",
+ AQH_NodeMessage_GetSourceAddress(msg),
+ AQH_NodeMessage_GetDestAddress(msg),
+ AQH_NodeMessage_MsgTypeToChar(AQH_NodeMessage_GetMsgType(msg)),
+ sText,
+ (unsigned int) AQH_PongMessage_GetTimestamp(msg));
+}
+
+
diff --git a/aqhome/msg/node/m_pong.h b/aqhome/msg/node/m_pong.h
new file mode 100644
index 0000000..c3ea72e
--- /dev/null
+++ b/aqhome/msg/node/m_pong.h
@@ -0,0 +1,28 @@
+/****************************************************************************
+ * This file is part of the project AqHome.
+ * AqHome (c) by 2025 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_M_PONG_H
+#define AQH_M_PONG_H
+
+
+#include
+#include
+
+#include
+
+
+AQHOME_API AQH_MESSAGE *AQH_PongMessage_new(uint8_t destAddr, uint8_t srcAddr, uint8_t code, uint32_t timestamp);
+AQHOME_API uint32_t AQH_PongMessage_GetTimestamp(const AQH_MESSAGE *msg);
+
+AQHOME_API void AQH_PongMessage_DumpToBuffer(const AQH_MESSAGE *msg, GWEN_BUFFER *dbuf, const char *sText);
+
+
+
+
+
+#endif
diff --git a/aqhome/msg/node/m_reboot.c b/aqhome/msg/node/m_reboot.c
new file mode 100644
index 0000000..8994c08
--- /dev/null
+++ b/aqhome/msg/node/m_reboot.c
@@ -0,0 +1,56 @@
+/****************************************************************************
+ * 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/node/m_reboot.h"
+#include "aqhome/msg/node/m_node.h"
+
+#include
+#include
+
+
+
+#define AQH_MSG_OFFS_REBOOT_UID 0 /* 4 bytes */
+
+
+
+AQH_MESSAGE *AQH_RebootMessage_new(uint8_t destAddr, uint8_t srcAddr, uint8_t code, uint32_t uid)
+{
+ uint32_t payload;
+
+ payload=GWEN_ENDIAN_HTOLE32(uid);
+ return AQH_NodeMessage_new(destAddr, srcAddr, code, sizeof(payload), (const uint8_t*)&payload);
+}
+
+
+
+uint32_t AQH_RebootMessage_GetUid(const AQH_MESSAGE *msg)
+{
+ return AQH_Message_ReadUint32At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_REBOOT_UID, 0);
+}
+
+
+
+void AQH_RebootMessage_DumpToBuffer(const AQH_MESSAGE *msg, GWEN_BUFFER *dbuf, const char *sText)
+{
+ GWEN_Buffer_AppendArgs(dbuf,
+ "0x%02x->0x%02x: REBOOT(%s) %s (uid=0x%08x)\n",
+ AQH_NodeMessage_GetSourceAddress(msg),
+ AQH_NodeMessage_GetDestAddress(msg),
+ AQH_NodeMessage_MsgTypeToChar(AQH_NodeMessage_GetMsgType(msg)),
+ sText,
+ (unsigned int) AQH_RebootMessage_GetUid(msg));
+}
+
+
+
diff --git a/aqhome/msg/node/m_reboot.h b/aqhome/msg/node/m_reboot.h
new file mode 100644
index 0000000..94cfef8
--- /dev/null
+++ b/aqhome/msg/node/m_reboot.h
@@ -0,0 +1,29 @@
+/****************************************************************************
+ * This file is part of the project AqHome.
+ * AqHome (c) by 2025 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_M_REBOOT_H
+#define AQH_M_REBOOT_H
+
+
+#include
+#include
+
+#include
+
+
+AQHOME_API AQH_MESSAGE *AQH_RebootMessage_new(uint8_t destAddr, uint8_t srcAddr, uint8_t code, uint32_t uid);
+AQHOME_API uint32_t AQH_RebootMessage_GetUid(const AQH_MESSAGE *msg);
+
+AQHOME_API void AQH_RebootMessage_DumpToBuffer(const AQH_MESSAGE *msg, GWEN_BUFFER *dbuf, const char *sText);
+
+
+
+
+
+
+#endif
diff --git a/aqhome/msg/node/m_sysstats.c b/aqhome/msg/node/m_sysstats.c
new file mode 100644
index 0000000..2357a6b
--- /dev/null
+++ b/aqhome/msg/node/m_sysstats.c
@@ -0,0 +1,71 @@
+/****************************************************************************
+ * 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/node/m_sysstats.h"
+#include "aqhome/msg/node/m_node.h"
+
+#include
+
+
+
+#define AQH_MSG_OFFS_SYSSTATS_SECONDS 0 /* 4 bytes */
+#define AQH_MSG_OFFS_SYSSTATS_UID 4 /* 4 bytes */
+#define AQH_MSG_OFFS_SYSSTATS_COMIRQS 8 /* 2 bytes */
+#define AQH_MSG_OFFS_SYSSTATS_TIMERIRQS 10 /* 2 bytes */
+
+
+
+uint32_t AQH_SysStatsMessage_GetUid(const AQH_MESSAGE *msg)
+{
+ return AQH_Message_ReadUint32At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_SYSSTATS_UID, 0);
+}
+
+
+
+uint32_t AQH_SysStatsMessage_GetSeconds(const AQH_MESSAGE *msg)
+{
+ return AQH_Message_ReadUint32At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_SYSSTATS_SECONDS, 0);
+}
+
+
+
+uint16_t AQH_SysStatsMessage_GetComInterrupts(const AQH_MESSAGE *msg)
+{
+ return AQH_Message_ReadUint16At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_SYSSTATS_COMIRQS, 0);
+}
+
+
+
+uint16_t AQH_SysStatsMessage_GetTimerInterrupts(const AQH_MESSAGE *msg)
+{
+ return AQH_Message_ReadUint16At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_SYSSTATS_TIMERIRQS, 0);
+}
+
+
+
+void AQH_SysStatsMessage_DumpToBuffer(const AQH_MESSAGE *msg, GWEN_BUFFER *dbuf, const char *sText)
+{
+ GWEN_Buffer_AppendArgs(dbuf,
+ "0x%02x->0x%02x: SYSSTATS(%s) %s (uid=0x%08x, uptime=%d, com irqs=%d, timer irqs=%d)\n",
+ AQH_NodeMessage_GetSourceAddress(msg),
+ AQH_NodeMessage_GetDestAddress(msg),
+ AQH_NodeMessage_MsgTypeToChar(AQH_NodeMessage_GetMsgType(msg)),
+ sText,
+ (unsigned int) AQH_SysStatsMessage_GetUid(msg),
+ AQH_SysStatsMessage_GetSeconds(msg),
+ AQH_SysStatsMessage_GetComInterrupts(msg),
+ AQH_SysStatsMessage_GetTimerInterrupts(msg));
+}
+
+
diff --git a/aqhome/msg/node/m_sysstats.h b/aqhome/msg/node/m_sysstats.h
new file mode 100644
index 0000000..435ccac
--- /dev/null
+++ b/aqhome/msg/node/m_sysstats.h
@@ -0,0 +1,29 @@
+/****************************************************************************
+ * This file is part of the project AqHome.
+ * AqHome (c) by 2025 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_M_SYSSTATS_H
+#define AQH_M_SYSSTATS_H
+
+
+#include
+#include
+
+#include
+
+
+
+AQHOME_API uint32_t AQH_SysStatsMessage_GetUid(const AQH_MESSAGE *msg);
+AQHOME_API uint32_t AQH_SysStatsMessage_GetSeconds(const AQH_MESSAGE *msg);
+AQHOME_API uint16_t AQH_SysStatsMessage_GetComInterrupts(const AQH_MESSAGE *msg);
+AQHOME_API uint16_t AQH_SysStatsMessage_GetTimerInterrupts(const AQH_MESSAGE *msg);
+
+AQHOME_API void AQH_SysStatsMessage_DumpToBuffer(const AQH_MESSAGE *msg, GWEN_BUFFER *dbuf, const char *sText);
+
+
+
+#endif
diff --git a/aqhome/msg/node/m_value.c b/aqhome/msg/node/m_value.c
new file mode 100644
index 0000000..01a0f58
--- /dev/null
+++ b/aqhome/msg/node/m_value.c
@@ -0,0 +1,218 @@
+/****************************************************************************
+ * This file is part of the project AqHome.
+ * AqHome (c) by 2025 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/node/m_value.h"
+#include "aqhome/msg/node/m_node.h"
+
+#include
+#include
+
+
+
+#define AQH_MSG_OFFS_VALUE_UID 0 /* 4 bytes */
+#define AQH_MSG_OFFS_VALUE_MSGID 4 /* 2 bytes */
+#define AQH_MSG_OFFS_VALUE_VALUEID 6 /* 1 byte */
+#define AQH_MSG_OFFS_VALUE_VALUETYPE 7 /* 1 byte */
+#define AQH_MSG_OFFS_VALUE_VALUE 8 /* 2 bytes */
+#define AQH_MSG_OFFS_VALUE_DENOM 10 /* 2 bytes */
+
+
+
+AQH_MESSAGE *AQH_ValueMessage_new(uint8_t destAddr, uint8_t srcAddr, uint8_t code,
+ uint16_t msgId, uint8_t valueId, uint16_t value, uint16_t denom)
+{
+ uint8_t payload[12];
+ uint8_t *ptr;
+
+ ptr=payload;
+ *(ptr++)=0; /* uid (empty) */
+ *(ptr++)=0;
+ *(ptr++)=0;
+ *(ptr++)=0;
+
+ *(ptr++)=msgId & 0xff; /* msgid */
+ *(ptr++)=(msgId>>8) & 0xff;
+
+ *(ptr++)=valueId; /* valueid */
+ *(ptr++)=0; /* valuetype (empty) */
+
+ *(ptr++)=value & 0xff; /* value */
+ *(ptr++)=(value>>8) & 0xff;
+
+ *(ptr++)=denom & 0xff; /* denom */
+ *(ptr++)=(denom>>8) & 0xff;
+
+ return AQH_NodeMessage_new(destAddr, srcAddr, code, sizeof(payload), payload);
+}
+
+
+
+uint32_t AQH_ValueMessage_GetUid(const AQH_MESSAGE *msg)
+{
+ return AQH_Message_ReadUint32At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_VALUE_UID, 0);
+}
+
+
+
+uint16_t AQH_ValueMessage_GetMsgId(const AQH_MESSAGE *msg)
+{
+ return AQH_Message_ReadUint16At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_VALUE_MSGID, 0);
+}
+
+
+
+uint8_t AQH_ValueMessage_GetValueId(const AQH_MESSAGE *msg)
+{
+ return AQH_Message_ReadUint8At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_VALUE_VALUEID, 0);
+}
+
+
+
+uint8_t AQH_ValueMessage_GetValueType(const AQH_MESSAGE *msg)
+{
+ return AQH_Message_ReadUint8At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_VALUE_VALUETYPE, 0);
+}
+
+
+
+uint16_t AQH_ValueMessage_GetValueNom(const AQH_MESSAGE *msg)
+{
+ return AQH_Message_ReadUint16At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_VALUE_VALUE, 0);
+}
+
+
+
+uint16_t AQH_ValueMessage_GetValueDenom(const AQH_MESSAGE *msg)
+{
+ return AQH_Message_ReadUint16At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_VALUE_DENOM, 0);
+}
+
+
+
+const char *AQH_ValueMessage_GetValueTypeName(const AQH_MESSAGE *msg)
+{
+ uint8_t t;
+
+ t=AQH_ValueMessage_GetValueType(msg);
+ switch(t) {
+ case AQH_MSG_VALUE_TYPE_TEMP: return "temperature";
+ case AQH_MSG_VALUE_TYPE_HUMIDITY: return "humidity";
+ case AQH_MSG_VALUE_TYPE_DOOR: return "door_window";
+ case AQH_MSG_VALUE_TYPE_MOTION: return "motion";
+ case AQH_MSG_VALUE_TYPE_CO2: return "CO2";
+ case AQH_MSG_VALUE_TYPE_TVOC: return "TVOC";
+ default: break;
+ }
+ return "unknown";
+}
+
+
+
+const char *AQH_ValueMessage_GetValueAsWindowStateString(const AQH_MESSAGE *msg)
+{
+ switch(AQH_ValueMessage_GetValueNom(msg)) {
+ case 0: return "closed";
+ case 128: return "tilted";
+ case 255: return "open";
+ default: break;
+ }
+ return "unknown";
+}
+
+
+
+const char *AQH_ValueMessage_GetValueTypeUnits(const AQH_MESSAGE *msg)
+{
+ uint8_t t;
+
+ t=AQH_ValueMessage_GetValueType(msg);
+ switch(t) {
+ case AQH_MSG_VALUE_TYPE_TEMP: return "Celsius";
+ case AQH_MSG_VALUE_TYPE_HUMIDITY: return "%";
+ case AQH_MSG_VALUE_TYPE_DOOR: return NULL;
+ case AQH_MSG_VALUE_TYPE_CO2: return "ppm";
+ case AQH_MSG_VALUE_TYPE_TVOC: return "ppb";
+ default: break;
+ }
+ return NULL;
+}
+
+
+
+double AQH_ValueMessage_GetValue(const AQH_MESSAGE *msg)
+{
+ double value;
+ double denom;
+ uint16_t intDenom;
+
+ value=AQH_ValueMessage_GetValueNom(msg);
+ intDenom=AQH_ValueMessage_GetValueDenom(msg);
+ if (intDenom==0)
+ denom=1.0;
+ else
+ denom=(double) intDenom;
+ return (double)(value/denom);
+}
+
+
+
+void AQH_ValueMessage_DumpToBuffer(const AQH_MESSAGE *msg, GWEN_BUFFER *dbuf, const char *sText)
+{
+ const char *sCmd;
+
+ switch(AQH_NodeMessage_GetMsgType(msg)) {
+ case AQH_MSG_TYPE_VALUE_REPORT: sCmd="report"; break;
+ case AQH_MSG_TYPE_VALUE_SET: sCmd="set"; break;
+ case AQH_MSG_TYPE_VALUE_SET_ACK: sCmd="ack"; break;
+ case AQH_MSG_TYPE_VALUE_SET_NACK: sCmd="nack"; break;
+ default: sCmd="unknown"; break;
+ }
+
+ if (AQH_ValueMessage_GetValueType(msg)==AQH_MSG_VALUE_TYPE_DOOR)
+ GWEN_Buffer_AppendArgs(dbuf,
+ "0x%02x->0x%02x: VALUE(%s) %s (uid=0x%08x, msgId=%u, value_id=0x%02x type=%s value=%s [%04x/%04x])\n",
+ AQH_NodeMessage_GetSourceAddress(msg),
+ AQH_NodeMessage_GetDestAddress(msg),
+ sCmd,
+ sText,
+ (unsigned int) AQH_ValueMessage_GetUid(msg),
+ (unsigned int)AQH_ValueMessage_GetMsgId(msg),
+ AQH_ValueMessage_GetValueId(msg),
+ AQH_ValueMessage_GetValueTypeName(msg),
+ AQH_ValueMessage_GetValueAsWindowStateString(msg),
+ AQH_ValueMessage_GetValueNom(msg),
+ AQH_ValueMessage_GetValueDenom(msg));
+ else
+ GWEN_Buffer_AppendArgs(dbuf,
+ "0x%02x->0x%02x: VALUE(%s) %s (uid=0x%08x, msgId=%u, value_id=0x%02x type=%s value=%f [%04x/%04x])\n",
+ AQH_NodeMessage_GetSourceAddress(msg),
+ AQH_NodeMessage_GetDestAddress(msg),
+ sCmd,
+ sText,
+ (unsigned int) AQH_ValueMessage_GetUid(msg),
+ (unsigned int)AQH_ValueMessage_GetMsgId(msg),
+ AQH_ValueMessage_GetValueId(msg),
+ AQH_ValueMessage_GetValueTypeName(msg),
+ AQH_ValueMessage_GetValue(msg),
+ AQH_ValueMessage_GetValueNom(msg),
+ AQH_ValueMessage_GetValueDenom(msg));
+}
+
+
+
+
+
+
+
+
diff --git a/aqhome/msg/node/m_value.h b/aqhome/msg/node/m_value.h
new file mode 100644
index 0000000..3a507a8
--- /dev/null
+++ b/aqhome/msg/node/m_value.h
@@ -0,0 +1,46 @@
+/****************************************************************************
+ * This file is part of the project AqHome.
+ * AqHome (c) by 2025 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_M_VALUE_H
+#define AQH_M_VALUE_H
+
+
+#include
+#include
+
+#include
+
+
+
+#define AQH_MSG_VALUE_TYPE_TEMP 1
+#define AQH_MSG_VALUE_TYPE_HUMIDITY 2
+#define AQH_MSG_VALUE_TYPE_DOOR 3
+#define AQH_MSG_VALUE_TYPE_MOTION 6
+#define AQH_MSG_VALUE_TYPE_CO2 7
+#define AQH_MSG_VALUE_TYPE_TVOC 8
+
+
+
+AQHOME_API AQH_MESSAGE *AQH_ValueMessage_new(uint8_t destAddr, uint8_t srcAddr, uint8_t code,
+ uint16_t msgId, uint8_t valueId, uint16_t value, uint16_t denom);
+AQHOME_API uint32_t AQH_ValueMessage_GetUid(const AQH_MESSAGE *msg);
+AQHOME_API uint16_t AQH_ValueMessage_GetMsgId(const AQH_MESSAGE *msg);
+AQHOME_API uint8_t AQH_ValueMessage_GetValueId(const AQH_MESSAGE *msg);
+AQHOME_API uint8_t AQH_ValueMessage_GetValueType(const AQH_MESSAGE *msg);
+AQHOME_API uint16_t AQH_ValueMessage_GetValueNom(const AQH_MESSAGE *msg);
+AQHOME_API uint16_t AQH_ValueMessage_GetValueDenom(const AQH_MESSAGE *msg);
+AQHOME_API const char *AQH_ValueMessage_GetValueTypeName(const AQH_MESSAGE *msg);
+AQHOME_API const char *AQH_ValueMessage_GetValueAsWindowStateString(const AQH_MESSAGE *msg);
+AQHOME_API const char *AQH_ValueMessage_GetValueTypeUnits(const AQH_MESSAGE *msg);
+AQHOME_API double AQH_ValueMessage_GetValue(const AQH_MESSAGE *msg);
+
+AQHOME_API void AQH_ValueMessage_DumpToBuffer(const AQH_MESSAGE *msg, GWEN_BUFFER *dbuf, const char *sText);
+
+
+
+#endif