diff --git a/aqhome/msg/node/0BUILD b/aqhome/msg/node/0BUILD index 43d0bc1..5737c40 100644 --- a/aqhome/msg/node/0BUILD +++ b/aqhome/msg/node/0BUILD @@ -63,6 +63,7 @@ m_flashready.h m_flashresponse.h m_range.h + m_time.h @@ -91,6 +92,7 @@ m_flashready.c m_flashresponse.c m_range.c + m_time.c diff --git a/aqhome/msg/node/m_node.c b/aqhome/msg/node/m_node.c index f345b4a..8871d8c 100644 --- a/aqhome/msg/node/m_node.c +++ b/aqhome/msg/node/m_node.c @@ -230,6 +230,9 @@ const char *AQH_NodeMessage_MsgTypeToChar(uint8_t i) case AQH_MSG_TYPE_VALUE_SET: return "ValueSet"; case AQH_MSG_TYPE_VALUE_SET_ACK: return "ValueSetAck"; case AQH_MSG_TYPE_VALUE_SET_NACK: return "ValueSetNack"; + case AQH_MSG_TYPE_TIME_ANNOUNCE: return "TimeAnnounce"; + case AQH_MSG_TYPE_TIME_REQSET: return "TimeSetRequest"; + case AQH_MSG_TYPE_TIME_RSPSET: return "TimeSetResponse"; default: return "(unknown)"; } } @@ -268,6 +271,10 @@ void AQH_NodeMessage_DumpSpecificToBuffer(const AQH_MESSAGE *msg, GWEN_BUFFER *d case AQH_MSG_TYPE_VALUE_SET_ACK: AQH_ValueMessage_DumpToBuffer(msg, dbuf, sText); break; case AQH_MSG_TYPE_VALUE_SET_NACK: AQH_ValueMessage_DumpToBuffer(msg, dbuf, sText); break; + case AQH_MSG_TYPE_TIME_ANNOUNCE: AQH_TimeMessage_DumpToBuffer(msg, dbuf, sText); break; + case AQH_MSG_TYPE_TIME_REQSET: AQH_TimeMessage_DumpToBuffer(msg, dbuf, sText); break; + case AQH_MSG_TYPE_TIME_RSPSET: AQH_TimeMessage_DumpToBuffer(msg, dbuf, sText); break; + case AQH_MSG_TYPE_DEBUG: case AQH_MSG_TYPE_TWIBUSMEMBER: default: AQH_NodeMessage_DumpToBuffer(msg, dbuf, sText); break; @@ -299,6 +306,11 @@ uint32_t AQH_NodeMessage_GetMsgGroup(uint8_t msgType) case AQH_MSG_TYPE_VALUE_SET_NACK: return AQH_MSG_TYPEGROUP_VALUES; + case AQH_MSG_TYPE_TIME_ANNOUNCE: + case AQH_MSG_TYPE_TIME_REQSET: + case AQH_MSG_TYPE_TIME_RSPSET: + return AQH_MSG_TYPEGROUP_TIME; + case AQH_MSG_TYPE_NEED_ADDRESS: case AQH_MSG_TYPE_HAVE_ADDRESS: case AQH_MSG_TYPE_CLAIM_ADDRESS: diff --git a/aqhome/msg/node/m_node.h b/aqhome/msg/node/m_node.h index 954d7c7..0f6b356 100644 --- a/aqhome/msg/node/m_node.h +++ b/aqhome/msg/node/m_node.h @@ -60,6 +60,10 @@ #define AQH_MSG_TYPE_VALUE_SET_ACK 102 #define AQH_MSG_TYPE_VALUE_SET_NACK 103 +#define AQH_MSG_TYPE_TIME_ANNOUNCE 120 +#define AQH_MSG_TYPE_TIME_REQSET 121 +#define AQH_MSG_TYPE_TIME_RSPSET 122 + /* internal msg types via NET interface */ #define AQH_MSG_TYPE_NET_SET_ACCEPTED_MSGGROUPS 200 @@ -70,6 +74,7 @@ #define AQH_MSG_TYPEGROUP_ADDRESS 0x00000004 #define AQH_MSG_TYPEGROUP_FLASH 0x00000008 #define AQH_MSG_TYPEGROUP_ADMIN 0x00000010 +#define AQH_MSG_TYPEGROUP_TIME 0x00000020 #define AQH_MSG_TYPEGROUP_ALL 0xffffffff diff --git a/aqhome/msg/node/m_time.c b/aqhome/msg/node/m_time.c new file mode 100644 index 0000000..662aa70 --- /dev/null +++ b/aqhome/msg/node/m_time.c @@ -0,0 +1,177 @@ +/**************************************************************************** + * This file is part of the project AqHome. + * AqHome (c) by 2026 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/aqhome.h" +#include "aqhome/msg/node/m_time.h" +#include "aqhome/msg/node/m_node.h" + +#include +#include + + + +#define AQH_MSG_OFFS_TIME_UID 0 /* 4 bytes */ +#define AQH_MSG_OFFS_TIME_MSGID 4 /* 2 bytes */ +#define AQH_MSG_OFFS_TIME_YEAR 6 /* 2 bytes */ +#define AQH_MSG_OFFS_TIME_MONTH 8 /* 1 byte */ +#define AQH_MSG_OFFS_TIME_DAYOFMONTH 9 /* 1 byte */ +#define AQH_MSG_OFFS_TIME_DAYOFWEEK 10 /* 1 byte */ +#define AQH_MSG_OFFS_TIME_HOUR 11 /* 1 byte */ +#define AQH_MSG_OFFS_TIME_MINUTE 12 /* 1 byte */ +#define AQH_MSG_OFFS_TIME_SECOND 13 /* 1 byte */ + + + +AQH_MESSAGE *AQH_TimeMessage_new(uint8_t destAddr, uint8_t srcAddr, uint8_t code, uint16_t msgId, const GWEN_TIMESTAMP *ts) +{ + uint8_t payload[14]; + uint8_t *ptr; + int i; + + ptr=payload; + *(ptr++)=0; /* uid (empty) */ + *(ptr++)=0; + *(ptr++)=0; + *(ptr++)=0; + + *(ptr++)=msgId & 0xff; /* msgid */ + *(ptr++)=(msgId>>8) & 0xff; + + i=GWEN_Timestamp_GetYear(ts); /* year */ + *(ptr++)=i & 0xff; + *(ptr++)=(i>>8) & 0xff; + + *(ptr++)=GWEN_Timestamp_GetMonth(ts) & 0xff; /* month */ + *(ptr++)=GWEN_Timestamp_GetDay(ts) & 0xff; /* day of month */ + *(ptr++)=GWEN_Timestamp_GetWeekDay(ts) & 0xff; /* day of week */ + *(ptr++)=GWEN_Timestamp_GetHour(ts) & 0xff; /* hour */ + *(ptr++)=GWEN_Timestamp_GetMinute(ts) & 0xff; /* minute */ + *(ptr++)=GWEN_Timestamp_GetSecond(ts) & 0xff; /* second */ + + return AQH_NodeMessage_new(destAddr, srcAddr, code, sizeof(payload), payload); +} + + + +uint32_t AQH_TimeMessage_GetUid(const AQH_MESSAGE *msg) +{ + return AQH_Message_ReadUint32At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_TIME_UID, 0); +} + + + +uint16_t AQH_TimeMessage_GetMsgId(const AQH_MESSAGE *msg) +{ + return AQH_Message_ReadUint16At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_TIME_MSGID, 0); +} + + + +uint16_t AQH_TimeMessage_GetYear(const AQH_MESSAGE *msg) +{ + return AQH_Message_ReadUint16At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_TIME_YEAR, 0); +} + + + +uint8_t AQH_TimeMessage_GetMonth(const AQH_MESSAGE *msg) +{ + return AQH_Message_ReadUint8At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_TIME_MONTH, 0); +} + + + +uint8_t AQH_TimeMessage_GetDayOfMonth(const AQH_MESSAGE *msg) +{ + return AQH_Message_ReadUint8At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_TIME_DAYOFMONTH, 0); +} + + + +uint8_t AQH_TimeMessage_GetDayOfWeek(const AQH_MESSAGE *msg) +{ + return AQH_Message_ReadUint8At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_TIME_DAYOFWEEK, 0); +} + + + +uint8_t AQH_TimeMessage_GetHour(const AQH_MESSAGE *msg) +{ + return AQH_Message_ReadUint8At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_TIME_HOUR, 0); +} + + + +uint8_t AQH_TimeMessage_GetMinute(const AQH_MESSAGE *msg) +{ + return AQH_Message_ReadUint8At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_TIME_MINUTE, 0); +} + + + +uint8_t AQH_TimeMessage_GetSecond(const AQH_MESSAGE *msg) +{ + return AQH_Message_ReadUint8At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_TIME_SECOND, 0); +} + + + +GWEN_TIMESTAMP *AQH_TimeMessage_GetTime(const AQH_MESSAGE *msg) +{ + return GWEN_Timestamp_new(AQH_TimeMessage_GetYear(msg), + AQH_TimeMessage_GetMonth(msg), + AQH_TimeMessage_GetDayOfMonth(msg), + AQH_TimeMessage_GetHour(msg), + AQH_TimeMessage_GetMinute(msg), + AQH_TimeMessage_GetSecond(msg)); +} + + + + +void AQH_TimeMessage_DumpToBuffer(const AQH_MESSAGE *msg, GWEN_BUFFER *dbuf, const char *sText) +{ + const char *sCmd; + + switch(AQH_NodeMessage_GetMsgType(msg)) { + case AQH_MSG_TYPE_TIME_ANNOUNCE: sCmd="announce"; break; + case AQH_MSG_TYPE_TIME_REQSET: sCmd="set"; break; + case AQH_MSG_TYPE_TIME_RSPSET: sCmd="ack"; break; + default: sCmd="unknown"; break; + } + + GWEN_Buffer_AppendArgs(dbuf, + "0x%02x->0x%02x: TIME(%s) %s (uid=0x%08x, msgId=%u, %04d/%02d/%02d-%02d:%02d:%02d (%d))\n", + AQH_NodeMessage_GetSourceAddress(msg), + AQH_NodeMessage_GetDestAddress(msg), + sCmd, + sText, + (unsigned int) AQH_TimeMessage_GetUid(msg), + (unsigned int)AQH_TimeMessage_GetMsgId(msg), + AQH_TimeMessage_GetYear(msg), + AQH_TimeMessage_GetMonth(msg), + AQH_TimeMessage_GetDayOfMonth(msg), + AQH_TimeMessage_GetHour(msg), + AQH_TimeMessage_GetMinute(msg), + AQH_TimeMessage_GetSecond(msg), + AQH_TimeMessage_GetDayOfWeek(msg)); +} + + + + + + + + diff --git a/aqhome/msg/node/m_time.h b/aqhome/msg/node/m_time.h new file mode 100644 index 0000000..ad7f5cb --- /dev/null +++ b/aqhome/msg/node/m_time.h @@ -0,0 +1,34 @@ +/**************************************************************************** + * This file is part of the project AqHome. + * AqHome (c) by 2026 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_TIME_H +#define AQH_M_TIME_H + + +#include +#include + +#include +#include + + + +AQHOME_API AQH_MESSAGE *AQH_TimeMessage_new(uint8_t destAddr, uint8_t srcAddr, uint8_t code, uint16_t msgId, const GWEN_TIMESTAMP *ts); +AQHOME_API uint32_t AQH_TimeMessage_GetUid(const AQH_MESSAGE *msg); +AQHOME_API uint16_t AQH_TimeMessage_GetMsgId(const AQH_MESSAGE *msg); +AQHOME_API uint16_t AQH_TimeMessage_GetYear(const AQH_MESSAGE *msg); +AQHOME_API uint8_t AQH_TimeMessage_GetMonth(const AQH_MESSAGE *msg); +AQHOME_API uint8_t AQH_TimeMessage_GetDayOfMonth(const AQH_MESSAGE *msg); +AQHOME_API uint8_t AQH_TimeMessage_GetDayOfWeek(const AQH_MESSAGE *msg); +AQHOME_API uint8_t AQH_TimeMessage_GetHour(const AQH_MESSAGE *msg); +AQHOME_API uint8_t AQH_TimeMessage_GetMinute(const AQH_MESSAGE *msg); +AQHOME_API uint8_t AQH_TimeMessage_GetSecond(const AQH_MESSAGE *msg); +AQHOME_API GWEN_TIMESTAMP *AQH_TimeMessage_GetTime(const AQH_MESSAGE *msg); +AQHOME_API void AQH_TimeMessage_DumpToBuffer(const AQH_MESSAGE *msg, GWEN_BUFFER *dbuf, const char *sText); + +#endif