aqhome: started reworking message code to use gwen's new msgio code.
This commit is contained in:
@@ -93,11 +93,13 @@
|
|||||||
</sources>
|
</sources>
|
||||||
|
|
||||||
<subdirs>
|
<subdirs>
|
||||||
|
msg
|
||||||
nodes
|
nodes
|
||||||
</subdirs>
|
</subdirs>
|
||||||
|
|
||||||
|
|
||||||
<useTargets>
|
<useTargets>
|
||||||
|
aqhmsg
|
||||||
aqhnodes
|
aqhnodes
|
||||||
</useTargets>
|
</useTargets>
|
||||||
|
|
||||||
|
|||||||
@@ -388,24 +388,24 @@ int testEndpoints()
|
|||||||
if (rv<0) {
|
if (rv<0) {
|
||||||
}
|
}
|
||||||
|
|
||||||
emgr=AQH_MsgEndpointMgr_new(0xc0);
|
emgr=AQH_MsgEndpointManager_new(0xc0);
|
||||||
epTty=AQH_MsgEndpointTty_new("/dev/ttyUSB0");
|
epTty=AQH_MsgEndpointTty_new("/dev/ttyUSB0");
|
||||||
if (epTty==NULL) {
|
if (epTty==NULL) {
|
||||||
DBG_ERROR(NULL, "Error creating endpoint TTY");
|
DBG_ERROR(NULL, "Error creating endpoint TTY");
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
AQH_MsgEndpointMgr_AddEndpoint(emgr, epTty);
|
AQH_MsgEndpointManager_AddEndpoint(emgr, epTty);
|
||||||
|
|
||||||
epLog=AQH_MsgEndpointLog_new("endpoints.log");
|
epLog=AQH_MsgEndpointLog_new("endpoints.log");
|
||||||
if (epLog==NULL) {
|
if (epLog==NULL) {
|
||||||
DBG_ERROR(AQH_LOGDOMAIN, "Error creating endpoint LOG");
|
DBG_ERROR(AQH_LOGDOMAIN, "Error creating endpoint LOG");
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
AQH_MsgEndpointMgr_AddEndpoint(emgr, epLog);
|
AQH_MsgEndpointManager_AddEndpoint(emgr, epLog);
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
DBG_DEBUG(AQH_LOGDOMAIN, "Next loop");
|
DBG_DEBUG(AQH_LOGDOMAIN, "Next loop");
|
||||||
AQH_MsgEndpointMgr_LoopOnce(emgr);
|
AQH_MsgEndpointManager_LoopOnce(emgr);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
104
aqhome/msg/0BUILD
Normal file
104
aqhome/msg/0BUILD
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
<?xml?>
|
||||||
|
|
||||||
|
<gwbuild>
|
||||||
|
|
||||||
|
<target type="ConvenienceLibrary" name="aqhmsg" >
|
||||||
|
|
||||||
|
<includes type="c" >
|
||||||
|
$(gwenhywfar_cflags)
|
||||||
|
-I$(topsrcdir)
|
||||||
|
-I$(topbuilddir)
|
||||||
|
</includes>
|
||||||
|
|
||||||
|
<includes type="tm2" >
|
||||||
|
--include=$(builddir)
|
||||||
|
--include=$(srcdir)
|
||||||
|
</includes>
|
||||||
|
|
||||||
|
|
||||||
|
<define name="BUILDING_AQHOME" />
|
||||||
|
|
||||||
|
<setVar name="local/cflags">$(visibility_cflags)</setVar>
|
||||||
|
|
||||||
|
|
||||||
|
<setVar name="tm2flags" >
|
||||||
|
--api=AQHOME_API
|
||||||
|
</setVar>
|
||||||
|
|
||||||
|
<setVar name="local/typefiles" >
|
||||||
|
</setVar>
|
||||||
|
|
||||||
|
<setVar name="local/built_sources" >
|
||||||
|
</setVar>
|
||||||
|
|
||||||
|
<setVar name="local/built_headers_pub">
|
||||||
|
</setVar>
|
||||||
|
|
||||||
|
|
||||||
|
<setVar name="local/built_headers_priv" >
|
||||||
|
</setVar>
|
||||||
|
|
||||||
|
|
||||||
|
<headers dist="false" install="$(pkgincludedir)/nodes" >
|
||||||
|
$(local/built_headers_pub)
|
||||||
|
</headers>
|
||||||
|
|
||||||
|
|
||||||
|
<headers dist="true" install="$(pkgincludedir)/nodes" >
|
||||||
|
endpointmgr.h
|
||||||
|
endpoint_node.h
|
||||||
|
endpoint_log.h
|
||||||
|
msg_node.h
|
||||||
|
msg_ping.h
|
||||||
|
msg_pong.h
|
||||||
|
msg_claimaddr.h
|
||||||
|
msg_denyaddr.h
|
||||||
|
msg_haveaddr.h
|
||||||
|
msg_needaddr.h
|
||||||
|
msg_sendstats.h
|
||||||
|
msg_value.h
|
||||||
|
</headers>
|
||||||
|
|
||||||
|
|
||||||
|
<headers dist="true" >
|
||||||
|
endpointmgr_p.h
|
||||||
|
endpoint_node_p.h
|
||||||
|
endpoint_log_p.h
|
||||||
|
msg_node_p.h
|
||||||
|
</headers>
|
||||||
|
|
||||||
|
|
||||||
|
<sources>
|
||||||
|
$(local/typefiles)
|
||||||
|
|
||||||
|
endpointmgr.c
|
||||||
|
endpoint_node.c
|
||||||
|
endpoint_log.c
|
||||||
|
msg_node.c
|
||||||
|
msg_ping.c
|
||||||
|
msg_pong.c
|
||||||
|
msg_claimaddr.c
|
||||||
|
msg_denyaddr.c
|
||||||
|
msg_haveaddr.c
|
||||||
|
msg_needaddr.c
|
||||||
|
msg_sendstats.c
|
||||||
|
msg_value.c
|
||||||
|
</sources>
|
||||||
|
|
||||||
|
|
||||||
|
<extradist>
|
||||||
|
</extradist>
|
||||||
|
|
||||||
|
|
||||||
|
<useTargets>
|
||||||
|
</useTargets>
|
||||||
|
|
||||||
|
<subdirs>
|
||||||
|
</subdirs>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</target>
|
||||||
|
|
||||||
|
</gwbuild>
|
||||||
159
aqhome/msg/endpoint_log.c
Normal file
159
aqhome/msg/endpoint_log.c
Normal file
@@ -0,0 +1,159 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* 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 <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#include "aqhome/msg/endpoint_log_p.h"
|
||||||
|
|
||||||
|
#include "aqhome/msg/msg_value.h"
|
||||||
|
#include "aqhome/msg/msg_sendstats.h"
|
||||||
|
#include "aqhome/msg/msg_ping.h"
|
||||||
|
#include "aqhome/msg/msg_pong.h"
|
||||||
|
#include "aqhome/msg/msg_needaddr.h"
|
||||||
|
#include "aqhome/msg/msg_claimaddr.h"
|
||||||
|
#include "aqhome/msg/msg_haveaddr.h"
|
||||||
|
#include "aqhome/msg/msg_denyaddr.h"
|
||||||
|
|
||||||
|
#include <gwenhywfar/list.h>
|
||||||
|
#include <gwenhywfar/inherit.h>
|
||||||
|
#include <gwenhywfar/debug.h>
|
||||||
|
#include <gwenhywfar/gwentime.h>
|
||||||
|
|
||||||
|
|
||||||
|
#define AQH_MSG_ENDPOINT_LOG_NAME "log"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
GWEN_INHERIT(GWEN_MSG_ENDPOINT, AQH_MSG_ENDPOINT_LOG)
|
||||||
|
|
||||||
|
|
||||||
|
static void GWENHYWFAR_CB _freeData(void *bp, void *p);
|
||||||
|
static void _run(GWEN_MSG_ENDPOINT *ep);
|
||||||
|
static void _logMessage(GWEN_MSG_ENDPOINT *ep, const GWEN_MSG *msg);
|
||||||
|
static void _writeToLogFile(const char *filename, const char *txt);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
GWEN_MSG_ENDPOINT *AQH_LogEndpoint_new(const char *filename, int groupId)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
GWEN_MSG_ENDPOINT *ep;
|
||||||
|
AQH_MSG_ENDPOINT_LOG *xep;
|
||||||
|
|
||||||
|
ep=GWEN_MsgEndpoint_new(AQH_MSG_ENDPOINT_LOG_NAME, groupId);
|
||||||
|
GWEN_NEW_OBJECT(AQH_MSG_ENDPOINT_LOG, xep);
|
||||||
|
xep->filename=strdup(filename);
|
||||||
|
GWEN_INHERIT_SETDATA(GWEN_MSG_ENDPOINT, AQH_MSG_ENDPOINT_LOG, ep, xep, _freeData);
|
||||||
|
AQH_NodeEndpoint_SetAcceptedMsgGroups(ep, AQH_MSG_TYPEGROUP_ALL);
|
||||||
|
GWEN_MsgEndpoint_AddFlags(ep, GWEN_MSG_ENDPOINT_FLAGS_NOIO);
|
||||||
|
GWEN_MsgEndpoint_SetRunFn(ep, _run);
|
||||||
|
|
||||||
|
return ep;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void _freeData(void *bp, void *p)
|
||||||
|
{
|
||||||
|
AQH_MSG_ENDPOINT_LOG *xep;
|
||||||
|
|
||||||
|
xep=(AQH_MSG_ENDPOINT_LOG*) p;
|
||||||
|
free(xep->filename);
|
||||||
|
GWEN_FREE_OBJECT(xep);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void _run(GWEN_MSG_ENDPOINT *ep)
|
||||||
|
{
|
||||||
|
GWEN_MSG_LIST *msgList;
|
||||||
|
|
||||||
|
msgList=GWEN_MsgEndpoint_GetSendMessageList(ep);
|
||||||
|
if (msgList && GWEN_Msg_List_GetCount(msgList)) {
|
||||||
|
GWEN_MSG *msg;
|
||||||
|
|
||||||
|
msg=GWEN_Msg_List_First(msgList);
|
||||||
|
while(msg) {
|
||||||
|
GWEN_MSG *next;
|
||||||
|
|
||||||
|
next=GWEN_Msg_List_Next(msg);
|
||||||
|
if (GWEN_Msg_GetGroupId(msg)==GWEN_MsgEndpoint_GetGroupId(ep))
|
||||||
|
_logMessage(ep, msg);
|
||||||
|
GWEN_Msg_free(msg);
|
||||||
|
msg=next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void _logMessage(GWEN_MSG_ENDPOINT *ep, const GWEN_MSG *msg)
|
||||||
|
{
|
||||||
|
AQH_MSG_ENDPOINT_LOG *xep;
|
||||||
|
const uint8_t *ptr;
|
||||||
|
uint8_t len;
|
||||||
|
uint8_t msgType;
|
||||||
|
int msgIsValid;
|
||||||
|
GWEN_BUFFER *dbuf;
|
||||||
|
GWEN_TIME *ti;
|
||||||
|
|
||||||
|
xep=GWEN_INHERIT_GETDATA(GWEN_MSG_ENDPOINT, AQH_MSG_ENDPOINT_LOG, ep);
|
||||||
|
dbuf=GWEN_Buffer_new(0, 256, 0, 1);
|
||||||
|
ti=GWEN_CurrentTime();
|
||||||
|
GWEN_Time_toString(ti, "YYYY-MM-DD hh:mm:ss ", dbuf);
|
||||||
|
GWEN_Time_free(ti);
|
||||||
|
ti=NULL;
|
||||||
|
|
||||||
|
msgIsValid=(AQH_NodeMsg_IsChecksumValid(msg) && AQH_NodeMsg_IsMsgComplete(msg));
|
||||||
|
ptr=GWEN_Msg_GetConstBuffer(msg);
|
||||||
|
len=GWEN_Msg_GetBytesInBuffer(msg);
|
||||||
|
msgType=AQH_NodeMsg_GetMsgType(msg);
|
||||||
|
|
||||||
|
switch(msgType) {
|
||||||
|
case AQH_MSG_TYPE_PING: AQH_PingMsg_DumpToBuffer(msg, dbuf, "received"); break;
|
||||||
|
case AQH_MSG_TYPE_PONG: AQH_PongMsg_DumpToBuffer(msg, dbuf, "received"); break;
|
||||||
|
case AQH_MSG_TYPE_COMSENDSTATS: AQH_SendStatsMsg_DumpToBuffer(msg, dbuf, "received"); break;
|
||||||
|
case AQH_MSG_TYPE_TWIBUSMEMBER: AQH_NodeMsg_DumpToBuffer(msg, dbuf, "received"); break;
|
||||||
|
case AQH_MSG_TYPE_DEBUG: AQH_NodeMsg_DumpToBuffer(msg, dbuf, "received"); break;
|
||||||
|
case AQH_MSG_TYPE_VALUE: AQH_ValueMsg_DumpToBuffer(msg, dbuf, "received"); break;
|
||||||
|
case AQH_MSG_TYPE_NEED_ADDRESS: AQH_NeedAddrMsg_DumpToBuffer(msg, dbuf, "received"); break;
|
||||||
|
case AQH_MSG_TYPE_CLAIM_ADDRESS: AQH_ClaimAddrMsg_DumpToBuffer(msg, dbuf, "received"); break;
|
||||||
|
case AQH_MSG_TYPE_HAVE_ADDRESS: AQH_HaveAddrMsg_DumpToBuffer(msg, dbuf, "received"); break;
|
||||||
|
case AQH_MSG_TYPE_DENY_ADDRESS: AQH_DenyAddrMsg_DumpToBuffer(msg, dbuf, "received"); break;
|
||||||
|
default: AQH_ValueMsg_DumpToBuffer(msg, dbuf, "received"); break;
|
||||||
|
}
|
||||||
|
_writeToLogFile(xep->filename, GWEN_Buffer_GetStart(dbuf));
|
||||||
|
GWEN_Buffer_free(dbuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void _writeToLogFile(const char *filename, const char *txt)
|
||||||
|
{
|
||||||
|
if (txt && *txt) {
|
||||||
|
FILE *f;
|
||||||
|
|
||||||
|
f=fopen(filename, "a+");
|
||||||
|
if (f) {
|
||||||
|
if (1!=fwrite(txt, strlen(txt), 1, f)) {
|
||||||
|
DBG_ERROR(AQH_LOGDOMAIN, "Error logging.");
|
||||||
|
}
|
||||||
|
fclose(f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
23
aqhome/msg/endpoint_log.h
Normal file
23
aqhome/msg/endpoint_log.h
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* This file is part of the project AqHome.
|
||||||
|
* AqHome (c) by 2023 Martin Preuss, all rights reserved.
|
||||||
|
*
|
||||||
|
* The license for this file can be found in the file COPYING which you
|
||||||
|
* should have received along with this file.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef AQH_ENDPOINT_LOG_H
|
||||||
|
#define AQH_ENDPOINT_LOG_H
|
||||||
|
|
||||||
|
|
||||||
|
#include "aqhome/msg/endpoint_node.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
AQHOME_API GWEN_MSG_ENDPOINT *AQH_LogEndpoint_new(const char *filename, int groupId);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
29
aqhome/msg/endpoint_log_p.h
Normal file
29
aqhome/msg/endpoint_log_p.h
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* This file is part of the project AqHome.
|
||||||
|
* AqHome (c) by 2023 Martin Preuss, all rights reserved.
|
||||||
|
*
|
||||||
|
* The license for this file can be found in the file COPYING which you
|
||||||
|
* should have received along with this file.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef AQH_ENDPOINT_LOG_P_H
|
||||||
|
#define AQH_ENDPOINT_LOG_P_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <aqhome/api.h>
|
||||||
|
|
||||||
|
#include "aqhome/msg/endpoint_log.h"
|
||||||
|
|
||||||
|
#include <gwenhywfar/list.h>
|
||||||
|
#include <gwenhywfar/inherit.h>
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct AQH_MSG_ENDPOINT_LOG AQH_MSG_ENDPOINT_LOG;
|
||||||
|
struct AQH_MSG_ENDPOINT_LOG {
|
||||||
|
char *filename;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
475
aqhome/msg/endpoint_node.c
Normal file
475
aqhome/msg/endpoint_node.c
Normal file
@@ -0,0 +1,475 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* 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 <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#include "aqhome/msg/endpoint_node_p.h"
|
||||||
|
#include "aqhome/msg/msg_node.h"
|
||||||
|
|
||||||
|
#include <gwenhywfar/inherit.h>
|
||||||
|
#include <gwenhywfar/debug.h>
|
||||||
|
#include <gwenhywfar/text.h>
|
||||||
|
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <termios.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
|
||||||
|
#define AQH_MSG_ENDPOINT_NODE_NAME "node"
|
||||||
|
|
||||||
|
#define AQH_MSG_ENDPOINT_NODE_BAUDRATE B19200
|
||||||
|
#define AQH_MSG_ENDPOINT_NODE_BYTE_MICROSECS 520
|
||||||
|
|
||||||
|
#define AQH_MSG_ENDPOINT_NODE_BUFFERSIZE 128
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
GWEN_INHERIT(GWEN_MSG_ENDPOINT, AQH_MSG_ENDPOINT_NODE)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static int _getReadFd(GWEN_MSG_ENDPOINT *ep);
|
||||||
|
static int _getWriteFd(GWEN_MSG_ENDPOINT *ep);
|
||||||
|
static int _handleReadable(GWEN_MSG_ENDPOINT *ep, GWEN_UNUSED GWEN_MSG_ENDPOINT_MGR *emgr);
|
||||||
|
static int _handleWritable(GWEN_MSG_ENDPOINT *ep, GWEN_UNUSED GWEN_MSG_ENDPOINT_MGR *emgr);
|
||||||
|
|
||||||
|
static void GWENHYWFAR_CB _freeData(void *bp, void *p);
|
||||||
|
|
||||||
|
static int _startMsg(GWEN_MSG_ENDPOINT *ep);
|
||||||
|
static int _endMsg(GWEN_MSG_ENDPOINT *ep);
|
||||||
|
static int _isLineBusy(GWEN_MSG_ENDPOINT *ep);
|
||||||
|
|
||||||
|
static int _openDevice(GWEN_MSG_ENDPOINT *ep);
|
||||||
|
static int _attnLow(GWEN_MSG_ENDPOINT *ep);
|
||||||
|
static int _attnHigh(GWEN_MSG_ENDPOINT *ep);
|
||||||
|
static int _isAttnLow(GWEN_MSG_ENDPOINT *ep);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
GWEN_MSG_ENDPOINT *AQH_MsgEndpointNode_new(const char *devicePath, int groupId)
|
||||||
|
{
|
||||||
|
GWEN_MSG_ENDPOINT *ep;
|
||||||
|
AQH_MSG_ENDPOINT_NODE *xep;
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
ep=GWEN_MsgEndpoint_new(AQH_MSG_ENDPOINT_NODE_NAME, groupId);
|
||||||
|
GWEN_NEW_OBJECT(AQH_MSG_ENDPOINT_NODE, xep);
|
||||||
|
GWEN_INHERIT_SETDATA(GWEN_MSG_ENDPOINT, AQH_MSG_ENDPOINT_NODE, ep, xep, _freeData);
|
||||||
|
|
||||||
|
GWEN_MsgEndpoint_SetHandleReadableFn(ep, _handleReadable);
|
||||||
|
GWEN_MsgEndpoint_SetHandleWritableFn(ep, _handleWritable);
|
||||||
|
GWEN_MsgEndpoint_SetGetReadFdFn(ep, _getReadFd);
|
||||||
|
GWEN_MsgEndpoint_SetGetWriteFdFn(ep, _getWriteFd);
|
||||||
|
|
||||||
|
xep->deviceName=strdup(devicePath);
|
||||||
|
|
||||||
|
fd=_openDevice(ep);
|
||||||
|
if (fd<0) {
|
||||||
|
DBG_INFO(NULL, "here (%d)", fd);
|
||||||
|
GWEN_MsgEndpoint_free(ep);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
GWEN_MsgEndpoint_SetFd(ep, fd);
|
||||||
|
_attnHigh(ep);
|
||||||
|
|
||||||
|
return ep;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void _freeData(void *bp, void *p)
|
||||||
|
{
|
||||||
|
AQH_MSG_ENDPOINT_NODE *xep;
|
||||||
|
|
||||||
|
xep=(AQH_MSG_ENDPOINT_NODE*) p;
|
||||||
|
GWEN_FREE_OBJECT(xep);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t AQH_NodeEndpoint_GetAcceptedMsgGroups(const GWEN_MSG_ENDPOINT *ep)
|
||||||
|
{
|
||||||
|
const AQH_MSG_ENDPOINT_NODE *xep;
|
||||||
|
|
||||||
|
xep=GWEN_INHERIT_GETDATA(GWEN_MSG_ENDPOINT, AQH_MSG_ENDPOINT_NODE, ep);
|
||||||
|
if (xep)
|
||||||
|
return xep->acceptedMsgGroups;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void AQH_NodeEndpoint_SetAcceptedMsgGroups(GWEN_MSG_ENDPOINT *ep, uint32_t f)
|
||||||
|
{
|
||||||
|
AQH_MSG_ENDPOINT_NODE *xep;
|
||||||
|
|
||||||
|
xep=GWEN_INHERIT_GETDATA(GWEN_MSG_ENDPOINT, AQH_MSG_ENDPOINT_NODE, ep);
|
||||||
|
if (xep)
|
||||||
|
xep->acceptedMsgGroups=f;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void AQH_NodeEndpoint_AddAcceptedMsgGroups(GWEN_MSG_ENDPOINT *ep, uint32_t f)
|
||||||
|
{
|
||||||
|
AQH_MSG_ENDPOINT_NODE *xep;
|
||||||
|
|
||||||
|
xep=GWEN_INHERIT_GETDATA(GWEN_MSG_ENDPOINT, AQH_MSG_ENDPOINT_NODE, ep);
|
||||||
|
if (xep)
|
||||||
|
xep->acceptedMsgGroups|=f;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void AQH_NodeEndpoint_DelAcceptedMsgGroups(GWEN_MSG_ENDPOINT *ep, uint32_t f)
|
||||||
|
{
|
||||||
|
AQH_MSG_ENDPOINT_NODE *xep;
|
||||||
|
|
||||||
|
xep=GWEN_INHERIT_GETDATA(GWEN_MSG_ENDPOINT, AQH_MSG_ENDPOINT_NODE, ep);
|
||||||
|
if (xep)
|
||||||
|
xep->acceptedMsgGroups&=~f;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int _getReadFd(GWEN_MSG_ENDPOINT *ep)
|
||||||
|
{
|
||||||
|
return GWEN_MsgEndpoint_GetFd(ep);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int _getWriteFd(GWEN_MSG_ENDPOINT *ep)
|
||||||
|
{
|
||||||
|
return GWEN_MsgEndpoint_HaveMessageToSend(ep)?GWEN_MsgEndpoint_GetFd(ep):GWEN_ERROR_NO_DATA;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int _handleReadable(GWEN_MSG_ENDPOINT *ep, GWEN_UNUSED GWEN_MSG_ENDPOINT_MGR *emgr)
|
||||||
|
{
|
||||||
|
int rv;
|
||||||
|
uint8_t buffer[AQH_MSG_ENDPOINT_NODE_BUFFERSIZE];
|
||||||
|
int len;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
DBG_DEBUG(GWEN_LOGDOMAIN, "Reading from endpoint %s", GWEN_MsgEndpoint_GetName(ep));
|
||||||
|
do {
|
||||||
|
rv=read(GWEN_MsgEndpoint_GetFd(ep), buffer, sizeof(buffer));
|
||||||
|
} while( (rv<0) && errno==EINTR);
|
||||||
|
if (rv<0) {
|
||||||
|
if (errno==EAGAIN || errno==EWOULDBLOCK)
|
||||||
|
return GWEN_ERROR_TRY_AGAIN;
|
||||||
|
DBG_ERROR(GWEN_LOGDOMAIN, "Error on read(): %s (%d)", strerror(errno), errno);
|
||||||
|
return GWEN_ERROR_IO;
|
||||||
|
}
|
||||||
|
else if (rv==0) {
|
||||||
|
DBG_ERROR(GWEN_LOGDOMAIN, "EOF met on read()");
|
||||||
|
return GWEN_ERROR_IO;
|
||||||
|
}
|
||||||
|
len=rv;
|
||||||
|
|
||||||
|
for (i=0; i<len; i++) {
|
||||||
|
GWEN_MSG *msg;
|
||||||
|
|
||||||
|
msg=GWEN_MsgEndpoint_GetCurrentlyReceivedMsg(ep);
|
||||||
|
if (msg==NULL) {
|
||||||
|
msg=GWEN_Msg_new(AQH_MSG_ENDPOINT_NODE_BUFFERSIZE);
|
||||||
|
GWEN_Msg_SetGroupId(msg, GWEN_MsgEndpoint_GetGroupId(ep));
|
||||||
|
GWEN_MsgEndpoint_SetCurrentlyReceivedMsg(ep, msg);
|
||||||
|
}
|
||||||
|
rv=GWEN_Msg_AddByte(msg, buffer[i]);
|
||||||
|
if (rv<0) {
|
||||||
|
DBG_ERROR(GWEN_LOGDOMAIN, "here (%d)", rv);
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
rv=AQH_NodeMsg_IsMsgComplete(msg);
|
||||||
|
if (rv<0) {
|
||||||
|
/* invalid message */
|
||||||
|
DBG_ERROR(GWEN_LOGDOMAIN, "Invalid message, discarding");
|
||||||
|
GWEN_MsgEndpoint_SetCurrentlyReceivedMsg(ep, NULL);
|
||||||
|
rv=GWEN_MsgEndpoint_DiscardInput(ep);
|
||||||
|
if (rv<0) {
|
||||||
|
DBG_ERROR(GWEN_LOGDOMAIN, "here (%d)", rv);
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (rv>0) {
|
||||||
|
/* complete msg received, add to list */
|
||||||
|
if (!AQH_NodeMsg_IsChecksumValid(msg)) {
|
||||||
|
DBG_ERROR(AQH_LOGDOMAIN, "Invalid checksum, discarding message");
|
||||||
|
GWEN_Text_DumpString(GWEN_Msg_GetBuffer(msg), GWEN_Msg_GetBytesInBuffer(msg), 6);
|
||||||
|
GWEN_MsgEndpoint_SetCurrentlyReceivedMsg(ep, NULL);
|
||||||
|
rv=GWEN_MsgEndpoint_DiscardInput(ep);
|
||||||
|
if (rv<0) {
|
||||||
|
DBG_ERROR(GWEN_LOGDOMAIN, "here (%d)", rv);
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
GWEN_Msg_Attach(msg);
|
||||||
|
GWEN_MsgEndpoint_SetCurrentlyReceivedMsg(ep, NULL);
|
||||||
|
GWEN_MsgEndpoint_AddReceivedMessage(ep, msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} /* for */
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int _handleWritable(GWEN_MSG_ENDPOINT *ep, GWEN_UNUSED GWEN_MSG_ENDPOINT_MGR *emgr)
|
||||||
|
{
|
||||||
|
GWEN_MSG *msg;
|
||||||
|
|
||||||
|
DBG_DEBUG(GWEN_LOGDOMAIN, "Writing to endpoint %s", GWEN_MsgEndpoint_GetName(ep));
|
||||||
|
msg=GWEN_MsgEndpoint_GetFirstSendMessage(ep);
|
||||||
|
if (msg) {
|
||||||
|
uint8_t pos;
|
||||||
|
int remaining;
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
pos=GWEN_Msg_GetCurrentPos(msg);
|
||||||
|
remaining=GWEN_Msg_GetRemainingBytes(msg);
|
||||||
|
if (remaining>0) {
|
||||||
|
const uint8_t *buf;
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
if (pos==0) {
|
||||||
|
/* start new message */
|
||||||
|
rv=_isLineBusy(ep);
|
||||||
|
if (rv<0 || rv==1) {
|
||||||
|
DBG_ERROR(AQH_LOGDOMAIN, "Line busy, not sending");
|
||||||
|
usleep(100);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
rv=_startMsg(ep);
|
||||||
|
if (rv<0) {
|
||||||
|
DBG_ERROR(AQH_LOGDOMAIN, "here (%d)", rv);
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fd=GWEN_MsgEndpoint_GetFd(ep);
|
||||||
|
/* start new message */
|
||||||
|
buf=GWEN_Msg_GetBuffer(msg)+pos;
|
||||||
|
do {
|
||||||
|
rv=write(fd, buf, remaining);
|
||||||
|
} while(rv<0 && errno==EINTR);
|
||||||
|
if (rv<0) {
|
||||||
|
if (errno==EAGAIN || errno==EWOULDBLOCK)
|
||||||
|
return GWEN_ERROR_TRY_AGAIN;
|
||||||
|
DBG_ERROR(GWEN_LOGDOMAIN, "Error on write(): %s (%d)", strerror(errno), errno);
|
||||||
|
return GWEN_ERROR_IO;
|
||||||
|
}
|
||||||
|
GWEN_Msg_IncCurrentPos(msg, rv);
|
||||||
|
if (rv==remaining) {
|
||||||
|
/* end current message */
|
||||||
|
rv=_endMsg(ep);
|
||||||
|
GWEN_Msg_List_Del(msg);
|
||||||
|
GWEN_Msg_free(msg);
|
||||||
|
if (rv<0) {
|
||||||
|
DBG_ERROR(AQH_LOGDOMAIN, "here (%d)", rv);
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int _openDevice(GWEN_MSG_ENDPOINT *ep)
|
||||||
|
{
|
||||||
|
AQH_MSG_ENDPOINT_NODE *xep;
|
||||||
|
int fd;
|
||||||
|
int status;
|
||||||
|
int i;
|
||||||
|
struct termios options;
|
||||||
|
int rv;
|
||||||
|
int m;
|
||||||
|
|
||||||
|
xep=GWEN_INHERIT_GETDATA(GWEN_MSG_ENDPOINT, AQH_MSG_ENDPOINT_NODE, ep);
|
||||||
|
fd=open(xep->deviceName, O_NOCTTY | O_NDELAY | O_RDWR);
|
||||||
|
if (fd<0) {
|
||||||
|
DBG_ERROR(AQH_LOGDOMAIN, "Error on open(%s): %s (%d)", xep->deviceName, strerror(errno), errno);
|
||||||
|
return GWEN_ERROR_IO;
|
||||||
|
}
|
||||||
|
rv=tcgetattr(fd, &(xep->previousOptions));
|
||||||
|
if (rv<0) {
|
||||||
|
DBG_ERROR(AQH_LOGDOMAIN, "Error on tcgetattr(%s): %s (%d)", xep->deviceName, strerror(errno), errno);
|
||||||
|
return GWEN_ERROR_IO;
|
||||||
|
}
|
||||||
|
memset(&options, 0, sizeof(options)); /* preset */
|
||||||
|
|
||||||
|
options.c_cflag=CLOCAL | CREAD | CS8;
|
||||||
|
options.c_iflag=IGNPAR | IGNBRK;
|
||||||
|
options.c_oflag=0;
|
||||||
|
options.c_lflag=0;
|
||||||
|
cfmakeraw(&options);
|
||||||
|
options.c_cc[VTIME]=0; /* read timeout in deciseconds */
|
||||||
|
options.c_cc[VMIN]=0; /* no minimum number of receive bytes */
|
||||||
|
|
||||||
|
rv=cfsetispeed(&options, AQH_MSG_ENDPOINT_NODE_BAUDRATE);
|
||||||
|
if (rv<0) {
|
||||||
|
DBG_ERROR(AQH_LOGDOMAIN, "Error on cfsetispeed(%s): %s (%d)", xep->deviceName, strerror(errno), errno);
|
||||||
|
return GWEN_ERROR_IO;
|
||||||
|
}
|
||||||
|
rv=cfsetospeed(&options, AQH_MSG_ENDPOINT_NODE_BAUDRATE);
|
||||||
|
if (rv<0) {
|
||||||
|
DBG_ERROR(AQH_LOGDOMAIN, "Error on cfsetospeed(%s): %s (%d)", xep->deviceName, strerror(errno), errno);
|
||||||
|
return GWEN_ERROR_IO;
|
||||||
|
}
|
||||||
|
|
||||||
|
rv=tcflush(fd, TCIOFLUSH);
|
||||||
|
if (rv<0) {
|
||||||
|
DBG_ERROR(AQH_LOGDOMAIN, "Error on tcflush(%s): %s (%d)", xep->deviceName, strerror(errno), errno);
|
||||||
|
return GWEN_ERROR_IO;
|
||||||
|
}
|
||||||
|
|
||||||
|
rv=tcsetattr(fd, TCSANOW, &options);
|
||||||
|
if (rv<0) {
|
||||||
|
DBG_ERROR(AQH_LOGDOMAIN, "Error on tcsetattr(%s): %s (%d)", xep->deviceName, strerror(errno), errno);
|
||||||
|
return GWEN_ERROR_IO;
|
||||||
|
}
|
||||||
|
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int _startMsg(GWEN_MSG_ENDPOINT *ep)
|
||||||
|
{
|
||||||
|
AQH_MSG_ENDPOINT_NODE *xep;
|
||||||
|
|
||||||
|
xep=GWEN_INHERIT_GETDATA(GWEN_MSG_ENDPOINT, AQH_MSG_ENDPOINT_NODE, ep);
|
||||||
|
if (xep->intendedAttnState==1) {
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
rv=_attnLow(ep);
|
||||||
|
if (rv<0) {
|
||||||
|
DBG_ERROR(AQH_LOGDOMAIN, "here (%d)", rv);
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
usleep(AQH_MSG_ENDPOINT_NODE_BYTE_MICROSECS/5);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int _endMsg(GWEN_MSG_ENDPOINT *ep)
|
||||||
|
{
|
||||||
|
/* TODO: flush before releasing ATTN */
|
||||||
|
_attnHigh(ep);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int _isLineBusy(GWEN_MSG_ENDPOINT *ep)
|
||||||
|
{
|
||||||
|
AQH_MSG_ENDPOINT_NODE *xep;
|
||||||
|
|
||||||
|
xep=GWEN_INHERIT_GETDATA(GWEN_MSG_ENDPOINT, AQH_MSG_ENDPOINT_NODE, ep);
|
||||||
|
if (xep->intendedAttnState==0) {
|
||||||
|
/* we pulled the line low ourselves, and because of the circuitry nobody can pull it high */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return _isAttnLow(ep);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int _attnLow(GWEN_MSG_ENDPOINT *ep)
|
||||||
|
{
|
||||||
|
AQH_MSG_ENDPOINT_NODE *xep;
|
||||||
|
int status;
|
||||||
|
int rv;
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
xep=GWEN_INHERIT_GETDATA(GWEN_MSG_ENDPOINT, AQH_MSG_ENDPOINT_NODE, ep);
|
||||||
|
fd=GWEN_MsgEndpoint_GetFd(ep);
|
||||||
|
rv=ioctl(fd, TIOCMGET, &status); /* GET the State of MODEM bits in Status */
|
||||||
|
if (rv<0) {
|
||||||
|
DBG_ERROR(AQH_LOGDOMAIN, "Error on ioctl(%s): %s (%d)", xep->deviceName, strerror(errno), errno);
|
||||||
|
return GWEN_ERROR_IO;
|
||||||
|
}
|
||||||
|
status |= TIOCM_DTR | TIOCM_RTS; /* clear the DTR pin (cave: signals inverted!) */
|
||||||
|
rv=ioctl(fd, TIOCMSET, &status);
|
||||||
|
if (rv<0) {
|
||||||
|
DBG_ERROR(AQH_LOGDOMAIN, "Error on ioctl(%s): %s (%d)", xep->deviceName, strerror(errno), errno);
|
||||||
|
return GWEN_ERROR_IO;
|
||||||
|
}
|
||||||
|
xep->intendedAttnState=0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int _attnHigh(GWEN_MSG_ENDPOINT *ep)
|
||||||
|
{
|
||||||
|
AQH_MSG_ENDPOINT_NODE *xep;
|
||||||
|
int status;
|
||||||
|
int rv;
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
xep=GWEN_INHERIT_GETDATA(GWEN_MSG_ENDPOINT, AQH_MSG_ENDPOINT_NODE, ep);
|
||||||
|
fd=GWEN_MsgEndpoint_GetFd(ep);
|
||||||
|
rv=ioctl(fd, TIOCMGET, &status);
|
||||||
|
if (rv<0) {
|
||||||
|
DBG_ERROR(AQH_LOGDOMAIN, "Error on ioctl(%s): %s (%d)", xep->deviceName, strerror(errno), errno);
|
||||||
|
return GWEN_ERROR_IO;
|
||||||
|
}
|
||||||
|
status |= TIOCM_DTR; /* Set the DTR pin */
|
||||||
|
status &= ~ (TIOCM_DTR | TIOCM_RTS); /* clear the DTR pin (cave: signals inverted!) */
|
||||||
|
rv=ioctl(fd, TIOCMSET, &status);
|
||||||
|
if (rv<0) {
|
||||||
|
DBG_ERROR(AQH_LOGDOMAIN, "Error on ioctl(%s): %s (%d)", xep->deviceName, strerror(errno), errno);
|
||||||
|
return GWEN_ERROR_IO;
|
||||||
|
}
|
||||||
|
|
||||||
|
xep->intendedAttnState=1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int _isAttnLow(GWEN_MSG_ENDPOINT *ep)
|
||||||
|
{
|
||||||
|
AQH_MSG_ENDPOINT_NODE *xep;
|
||||||
|
int status;
|
||||||
|
int rv;
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
xep=GWEN_INHERIT_GETDATA(GWEN_MSG_ENDPOINT, AQH_MSG_ENDPOINT_NODE, ep);
|
||||||
|
fd=GWEN_MsgEndpoint_GetFd(ep);
|
||||||
|
rv=ioctl(fd, TIOCMGET, &status);
|
||||||
|
if (rv<0) {
|
||||||
|
DBG_ERROR(AQH_LOGDOMAIN, "Error on ioctl(%s): %s (%d)", xep->deviceName, strerror(errno), errno);
|
||||||
|
return GWEN_ERROR_IO;
|
||||||
|
}
|
||||||
|
return (status & TIOCM_CTS)?1:0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
32
aqhome/msg/endpoint_node.h
Normal file
32
aqhome/msg/endpoint_node.h
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* This file is part of the project AqHome.
|
||||||
|
* AqHome (c) by 2023 Martin Preuss, all rights reserved.
|
||||||
|
*
|
||||||
|
* The license for this file can be found in the file COPYING which you
|
||||||
|
* should have received along with this file.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef AQH_MSGENDPOINT_NODE_H
|
||||||
|
#define AQH_MSGENDPOINT_NODE_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <aqhome/api.h>
|
||||||
|
|
||||||
|
#include <gwenhywfar/endpoint.h>
|
||||||
|
|
||||||
|
|
||||||
|
#define AQH_MSGEP_NODE_FLAGS_NOMESSAGES 0x0001
|
||||||
|
#define AQH_MSGEP_NODE_FLAGS_NOIO 0x0002
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
AQHOME_API GWEN_MSG_ENDPOINT *AQH_NodeEndpointNode_new(const char *devicePath, int groupId);
|
||||||
|
|
||||||
|
AQHOME_API uint32_t AQH_NodeEndpoint_GetAcceptedMsgGroups(const GWEN_MSG_ENDPOINT *ep);
|
||||||
|
AQHOME_API void AQH_NodeEndpoint_SetAcceptedMsgGroups(GWEN_MSG_ENDPOINT *ep, uint32_t f);
|
||||||
|
AQHOME_API void AQH_NodeEndpoint_AddAcceptedMsgGroups(GWEN_MSG_ENDPOINT *ep, uint32_t f);
|
||||||
|
AQHOME_API void AQH_NodeEndpoint_DelAcceptedMsgGroups(GWEN_MSG_ENDPOINT *ep, uint32_t f);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
34
aqhome/msg/endpoint_node_p.h
Normal file
34
aqhome/msg/endpoint_node_p.h
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* This file is part of the project AqHome.
|
||||||
|
* AqHome (c) by 2023 Martin Preuss, all rights reserved.
|
||||||
|
*
|
||||||
|
* The license for this file can be found in the file COPYING which you
|
||||||
|
* should have received along with this file.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef AQH_MSGENDPOINT_NODE_P_H
|
||||||
|
#define AQH_MSGENDPOINT_NODE_P_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <aqhome/api.h>
|
||||||
|
|
||||||
|
#include "aqhome/msg/endpoint_node.h"
|
||||||
|
|
||||||
|
#include <termios.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct AQH_MSG_ENDPOINT_NODE AQH_MSG_ENDPOINT_NODE;
|
||||||
|
struct AQH_MSG_ENDPOINT_NODE {
|
||||||
|
uint32_t acceptedMsgGroups;
|
||||||
|
|
||||||
|
char *deviceName;
|
||||||
|
struct termios previousOptions;
|
||||||
|
int intendedAttnState;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
165
aqhome/msg/endpointmgr.c
Normal file
165
aqhome/msg/endpointmgr.c
Normal file
@@ -0,0 +1,165 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* 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 <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#include "aqhome/msg/endpointmgr_p.h"
|
||||||
|
#include "aqhome/msg/msg_node.h"
|
||||||
|
#include "aqhome/msg/endpoint_node.h"
|
||||||
|
|
||||||
|
#include <gwenhywfar/misc.h>
|
||||||
|
#include <gwenhywfar/debug.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
GWEN_INHERIT(GWEN_MSG_ENDPOINT_MGR, AQH_MSG_ENDPOINT_MGR);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void GWENHYWFAR_CB _freeData(void *bp, void *p);
|
||||||
|
static void _handleEndpoint(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ENDPOINT *ep);
|
||||||
|
static void _handleNodeEndpoint(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ENDPOINT *ep);
|
||||||
|
static void _handleIpcEndpoint(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ENDPOINT *ep);
|
||||||
|
static void _distributeMsgFromNodeEndpoint(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ENDPOINT *srcEp, const GWEN_MSG *msg);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
GWEN_MSG_ENDPOINT_MGR *AQH_MsgEndpointMgr_new(uint8_t busAddr)
|
||||||
|
{
|
||||||
|
GWEN_MSG_ENDPOINT_MGR *mgr;
|
||||||
|
AQH_MSG_ENDPOINT_MGR *xmgr;
|
||||||
|
|
||||||
|
mgr=GWEN_MsgEndpointMgr_new();
|
||||||
|
GWEN_NEW_OBJECT(AQH_MSG_ENDPOINT_MGR, xmgr);
|
||||||
|
GWEN_INHERIT_SETDATA(GWEN_MSG_ENDPOINT_MGR, AQH_MSG_ENDPOINT_MGR, mgr, xmgr, _freeData);
|
||||||
|
|
||||||
|
xmgr->busAddr=busAddr;
|
||||||
|
|
||||||
|
return mgr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void _freeData(void *bp, void *p)
|
||||||
|
{
|
||||||
|
AQH_MSG_ENDPOINT_MGR *xmgr;
|
||||||
|
|
||||||
|
xmgr=(AQH_MSG_ENDPOINT_MGR*) p;
|
||||||
|
GWEN_FREE_OBJECT(xmgr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void _msgLoopOnce(GWEN_MSG_ENDPOINT_MGR *emgr)
|
||||||
|
{
|
||||||
|
GWEN_MSG_ENDPOINT_LIST *endpointList;
|
||||||
|
|
||||||
|
DBG_DEBUG(AQH_LOGDOMAIN, "Handle endpoint messages");
|
||||||
|
endpointList=GWEN_MsgEndpointMgr_GetEndpointList(emgr);
|
||||||
|
if (endpointList) {
|
||||||
|
GWEN_MSG_ENDPOINT *ep;
|
||||||
|
|
||||||
|
ep=GWEN_MsgEndpoint_List_First(endpointList);
|
||||||
|
while(ep) {
|
||||||
|
DBG_DEBUG(AQH_LOGDOMAIN, "- endpoint(%s)", GWEN_MsgEndpoint_GetName(ep));
|
||||||
|
_handleEndpoint(emgr, ep);
|
||||||
|
ep=GWEN_MsgEndpoint_List_Next(ep);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void _handleEndpoint(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ENDPOINT *ep)
|
||||||
|
{
|
||||||
|
switch(GWEN_MsgEndpoint_GetGroupId(ep)) {
|
||||||
|
case AQH_MSG_ENDPOINTGROUP_NODE: _handleNodeEndpoint(emgr, ep); break;
|
||||||
|
case AQH_MSG_ENDPOINTGROUP_IPC: _handleIpcEndpoint(emgr, ep); break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void _handleNodeEndpoint(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ENDPOINT *ep)
|
||||||
|
{
|
||||||
|
GWEN_MSG *msg;
|
||||||
|
|
||||||
|
while( (msg=GWEN_MsgEndpoint_TakeFirstReceivedMessage(ep)) ) {
|
||||||
|
DBG_INFO(AQH_LOGDOMAIN,
|
||||||
|
" - msg %d from %d to %d",
|
||||||
|
AQH_NodeMsg_GetMsgType(msg), AQH_NodeMsg_GetSourceAddress(msg), AQH_NodeMsg_GetDestAddress(msg));
|
||||||
|
_distributeMsgFromNodeEndpoint(emgr, ep, msg);
|
||||||
|
GWEN_Msg_free(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void _handleIpcEndpoint(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ENDPOINT *ep)
|
||||||
|
{
|
||||||
|
/* TODO: handle IPC messages */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void _distributeMsgFromNodeEndpoint(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ENDPOINT *srcEp, const GWEN_MSG *msg)
|
||||||
|
{
|
||||||
|
GWEN_MSG_ENDPOINT_LIST *endpointList;
|
||||||
|
|
||||||
|
endpointList=GWEN_MsgEndpointMgr_GetEndpointList(emgr);
|
||||||
|
if (endpointList) {
|
||||||
|
GWEN_MSG_ENDPOINT *ep;
|
||||||
|
int srcGroupId;
|
||||||
|
uint32_t msgGroup;
|
||||||
|
|
||||||
|
msgGroup=AQH_NodeMsg_GetMsgGroup(AQH_NodeMsg_GetMsgType(msg));
|
||||||
|
srcGroupId=GWEN_MsgEndpoint_GetGroupId(srcEp);
|
||||||
|
|
||||||
|
ep=GWEN_MsgEndpoint_List_First(endpointList);
|
||||||
|
while(ep) {
|
||||||
|
if (ep!=srcEp) {
|
||||||
|
uint32_t acceptedGroupIds;
|
||||||
|
uint32_t acceptedMsgGroups;
|
||||||
|
|
||||||
|
DBG_DEBUG(AQH_LOGDOMAIN, "- checking endpoint %s", GWEN_MsgEndpoint_GetName(ep));
|
||||||
|
acceptedGroupIds=AQH_NodeEndpoint_GetAcceptedMsgGroups(ep);
|
||||||
|
acceptedMsgGroups=AQH_NodeEndpoint_GetAcceptedMsgGroups(ep);
|
||||||
|
|
||||||
|
if (
|
||||||
|
!(GWEN_MsgEndpoint_GetFlags(ep) & AQH_MSGEP_NODE_FLAGS_NOMESSAGES) &&
|
||||||
|
(acceptedMsgGroups & msgGroup) &&
|
||||||
|
(acceptedGroupIds & srcGroupId)
|
||||||
|
) {
|
||||||
|
/* endpoint accepts this message */
|
||||||
|
DBG_DEBUG(AQH_LOGDOMAIN, " - endpoint %s accepts message", GWEN_MsgEndpoint_GetName(ep));
|
||||||
|
GWEN_MsgEndpoint_AddSendMessage(ep, GWEN_Msg_dup(msg));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
DBG_DEBUG(AQH_LOGDOMAIN, " - endpoint %s does not accept message", GWEN_MsgEndpoint_GetName(ep));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ep=GWEN_MsgEndpoint_List_Next(ep);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
31
aqhome/msg/endpointmgr.h
Normal file
31
aqhome/msg/endpointmgr.h
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* This file is part of the project AqHome.
|
||||||
|
* AqHome (c) by 2023 Martin Preuss, all rights reserved.
|
||||||
|
*
|
||||||
|
* The license for this file can be found in the file COPYING which you
|
||||||
|
* should have received along with this file.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef AQH_MSG_ENDPOINT_MGR_H
|
||||||
|
#define AQH_MSG_ENDPOINT_MGR_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <aqhome/api.h>
|
||||||
|
|
||||||
|
#include <gwenhywfar/endpointmgr.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#define AQH_MSG_ENDPOINTGROUP_NODE 1
|
||||||
|
#define AQH_MSG_ENDPOINTGROUP_IPC 2
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
AQHOME_API GWEN_MSG_ENDPOINT_MGR *AQH_MsgEndpointMgr_new(uint8_t busAddr);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
29
aqhome/msg/endpointmgr_p.h
Normal file
29
aqhome/msg/endpointmgr_p.h
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* This file is part of the project AqHome.
|
||||||
|
* AqHome (c) by 2023 Martin Preuss, all rights reserved.
|
||||||
|
*
|
||||||
|
* The license for this file can be found in the file COPYING which you
|
||||||
|
* should have received along with this file.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef AQH_MSG_ENDPOINT_MGR_P_H
|
||||||
|
#define AQH_MSG_ENDPOINT_MGR_P_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <aqhome/api.h>
|
||||||
|
|
||||||
|
#include "aqhome/msg/endpointmgr.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct AQH_MSG_ENDPOINT_MGR AQH_MSG_ENDPOINT_MGR;
|
||||||
|
struct AQH_MSG_ENDPOINT_MGR {
|
||||||
|
uint8_t busAddr;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
68
aqhome/msg/msg_claimaddr.c
Normal file
68
aqhome/msg/msg_claimaddr.c
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* 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 <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "aqhome/msg/msg_claimaddr.h"
|
||||||
|
|
||||||
|
#include <gwenhywfar/misc.h>
|
||||||
|
#include <gwenhywfar/list.h>
|
||||||
|
#include <gwenhywfar/error.h>
|
||||||
|
#include <gwenhywfar/debug.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t AQH_ClaimAddrMsg_GetUid(const GWEN_MSG *msg)
|
||||||
|
{
|
||||||
|
if ((AQH_NodeMsg_GetMsgType(msg)==AQH_MSG_TYPE_CLAIM_ADDRESS) &&
|
||||||
|
(GWEN_Msg_GetBytesInBuffer(msg)>=AQH_MSG_CLAIMADDR_MINSIZE)) {
|
||||||
|
const uint8_t *ptr;
|
||||||
|
|
||||||
|
ptr=GWEN_Msg_GetConstBuffer(msg)+AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_CLAIMADDR_UID;
|
||||||
|
return (uint32_t)(ptr[0])+(ptr[1]<<8)+(ptr[2]<<16)+(ptr[3]<<24);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t AQH_ClaimAddrMsg_GetAddress(const GWEN_MSG *msg)
|
||||||
|
{
|
||||||
|
if ((AQH_NodeMsg_GetMsgType(msg)==AQH_MSG_TYPE_CLAIM_ADDRESS) &&
|
||||||
|
(GWEN_Msg_GetBytesInBuffer(msg)>=AQH_MSG_CLAIMADDR_MINSIZE)) {
|
||||||
|
const uint8_t *ptr;
|
||||||
|
|
||||||
|
ptr=GWEN_Msg_GetConstBuffer(msg)+AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_CLAIMADDR_ADDR;
|
||||||
|
return ptr[0];
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void AQH_ClaimAddrMsg_DumpToBuffer(const GWEN_MSG *msg, GWEN_BUFFER *dbuf, const char *sText)
|
||||||
|
{
|
||||||
|
if ((AQH_NodeMsg_GetMsgType(msg)==AQH_MSG_TYPE_CLAIM_ADDRESS) &&
|
||||||
|
(GWEN_Msg_GetBytesInBuffer(msg)>=AQH_MSG_CLAIMADDR_MINSIZE)) {
|
||||||
|
GWEN_Buffer_AppendArgs(dbuf,
|
||||||
|
"0x%02x->0x%02x: CLAIM_ADDRESS %s (uid=0x%08x, address=0x%02x)\n",
|
||||||
|
AQH_NodeMsg_GetSourceAddress(msg),
|
||||||
|
AQH_NodeMsg_GetDestAddress(msg),
|
||||||
|
sText,
|
||||||
|
(unsigned int) AQH_ClaimAddrMsg_GetUid(msg),
|
||||||
|
AQH_ClaimAddrMsg_GetAddress(msg));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
37
aqhome/msg/msg_claimaddr.h
Normal file
37
aqhome/msg/msg_claimaddr.h
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* This file is part of the project AqHome.
|
||||||
|
* AqHome (c) by 2023 Martin Preuss, all rights reserved.
|
||||||
|
*
|
||||||
|
* The license for this file can be found in the file COPYING which you
|
||||||
|
* should have received along with this file.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef AQH_MSG_CLAIMADDR_H
|
||||||
|
#define AQH_MSG_CLAIMADDR_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <aqhome/api.h>
|
||||||
|
#include <aqhome/msg/msg_node.h>
|
||||||
|
|
||||||
|
#include <gwenhywfar/msg.h>
|
||||||
|
#include <gwenhywfar/buffer.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#define AQH_MSG_OFFS_CLAIMADDR_UID 0
|
||||||
|
#define AQH_MSG_OFFS_CLAIMADDR_ADDR 4
|
||||||
|
|
||||||
|
#define AQH_MSG_CLAIMADDR_MINSIZE (AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_CLAIMADDR_ADDR+1)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
AQHOME_API uint32_t AQH_ClaimAddrMsg_GetUid(const GWEN_MSG *msg);
|
||||||
|
AQHOME_API uint8_t AQH_ClaimAddrMsg_GetAddress(const GWEN_MSG *msg);
|
||||||
|
AQHOME_API void AQH_ClaimAddrMsg_DumpToBuffer(const GWEN_MSG *msg, GWEN_BUFFER *dbuf, const char *sText);
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
68
aqhome/msg/msg_denyaddr.c
Normal file
68
aqhome/msg/msg_denyaddr.c
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* 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 <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "aqhome/msg/msg_denyaddr.h"
|
||||||
|
|
||||||
|
#include <gwenhywfar/misc.h>
|
||||||
|
#include <gwenhywfar/list.h>
|
||||||
|
#include <gwenhywfar/error.h>
|
||||||
|
#include <gwenhywfar/debug.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t AQH_DenyAddrMsg_GetUid(const GWEN_MSG *msg)
|
||||||
|
{
|
||||||
|
if ((AQH_NodeMsg_GetMsgType(msg)==AQH_MSG_TYPE_DENY_ADDRESS) &&
|
||||||
|
(GWEN_Msg_GetBytesInBuffer(msg)>=AQH_MSG_DENYADDR_MINSIZE)) {
|
||||||
|
const uint8_t *ptr;
|
||||||
|
|
||||||
|
ptr=GWEN_Msg_GetConstBuffer(msg)+AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_DENYADDR_UID;
|
||||||
|
return (uint32_t)(ptr[0])+(ptr[1]<<8)+(ptr[2]<<16)+(ptr[3]<<24);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t AQH_DenyAddrMsg_GetAddress(const GWEN_MSG *msg)
|
||||||
|
{
|
||||||
|
if ((AQH_NodeMsg_GetMsgType(msg)==AQH_MSG_TYPE_DENY_ADDRESS) &&
|
||||||
|
(GWEN_Msg_GetBytesInBuffer(msg)>=AQH_MSG_DENYADDR_MINSIZE)) {
|
||||||
|
const uint8_t *ptr;
|
||||||
|
|
||||||
|
ptr=GWEN_Msg_GetConstBuffer(msg)+AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_DENYADDR_ADDR;
|
||||||
|
return ptr[0];
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void AQH_DenyAddrMsg_DumpToBuffer(const GWEN_MSG *msg, GWEN_BUFFER *dbuf, const char *sText)
|
||||||
|
{
|
||||||
|
if ((AQH_NodeMsg_GetMsgType(msg)==AQH_MSG_TYPE_DENY_ADDRESS) &&
|
||||||
|
(GWEN_Msg_GetBytesInBuffer(msg)>=AQH_MSG_DENYADDR_MINSIZE)) {
|
||||||
|
GWEN_Buffer_AppendArgs(dbuf,
|
||||||
|
"0x%02x->0x%02x: DENY_ADDRESS %s (uid=0x%08x, address=0x%02x)\n",
|
||||||
|
AQH_NodeMsg_GetSourceAddress(msg),
|
||||||
|
AQH_NodeMsg_GetDestAddress(msg),
|
||||||
|
sText,
|
||||||
|
(unsigned int) AQH_DenyAddrMsg_GetUid(msg),
|
||||||
|
AQH_DenyAddrMsg_GetAddress(msg));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
37
aqhome/msg/msg_denyaddr.h
Normal file
37
aqhome/msg/msg_denyaddr.h
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* This file is part of the project AqHome.
|
||||||
|
* AqHome (c) by 2023 Martin Preuss, all rights reserved.
|
||||||
|
*
|
||||||
|
* The license for this file can be found in the file COPYING which you
|
||||||
|
* should have received along with this file.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef AQH_MSG_DENYADDR_H
|
||||||
|
#define AQH_MSG_DENYADDR_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <aqhome/api.h>
|
||||||
|
#include <aqhome/msg/msg_node.h>
|
||||||
|
|
||||||
|
#include <gwenhywfar/msg.h>
|
||||||
|
#include <gwenhywfar/buffer.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#define AQH_MSG_OFFS_DENYADDR_UID 0
|
||||||
|
#define AQH_MSG_OFFS_DENYADDR_ADDR 4
|
||||||
|
|
||||||
|
#define AQH_MSG_DENYADDR_MINSIZE (AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_DENYADDR_ADDR+1)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
AQHOME_API uint32_t AQH_DenyAddrMsg_GetUid(const GWEN_MSG *msg);
|
||||||
|
AQHOME_API uint8_t AQH_DenyAddrMsg_GetAddress(const GWEN_MSG *msg);
|
||||||
|
AQHOME_API void AQH_DenyAddrMsg_DumpToBuffer(const GWEN_MSG *msg, GWEN_BUFFER *dbuf, const char *sText);
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
68
aqhome/msg/msg_haveaddr.c
Normal file
68
aqhome/msg/msg_haveaddr.c
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* 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 <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "aqhome/msg/msg_haveaddr.h"
|
||||||
|
|
||||||
|
#include <gwenhywfar/misc.h>
|
||||||
|
#include <gwenhywfar/list.h>
|
||||||
|
#include <gwenhywfar/error.h>
|
||||||
|
#include <gwenhywfar/debug.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t AQH_HaveAddrMsg_GetUid(const GWEN_MSG *msg)
|
||||||
|
{
|
||||||
|
if ((AQH_NodeMsg_GetMsgType(msg)==AQH_MSG_TYPE_HAVE_ADDRESS) &&
|
||||||
|
(GWEN_Msg_GetBytesInBuffer(msg)>=AQH_MSG_HAVEADDR_MINSIZE)) {
|
||||||
|
const uint8_t *ptr;
|
||||||
|
|
||||||
|
ptr=GWEN_Msg_GetConstBuffer(msg)+AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_HAVEADDR_UID;
|
||||||
|
return (uint32_t)(ptr[0])+(ptr[1]<<8)+(ptr[2]<<16)+(ptr[3]<<24);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t AQH_HaveAddrMsg_GetAddress(const GWEN_MSG *msg)
|
||||||
|
{
|
||||||
|
if ((AQH_NodeMsg_GetMsgType(msg)==AQH_MSG_TYPE_HAVE_ADDRESS) &&
|
||||||
|
(GWEN_Msg_GetBytesInBuffer(msg)>=AQH_MSG_HAVEADDR_MINSIZE)) {
|
||||||
|
const uint8_t *ptr;
|
||||||
|
|
||||||
|
ptr=GWEN_Msg_GetConstBuffer(msg)+AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_HAVEADDR_ADDR;
|
||||||
|
return ptr[0];
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void AQH_HaveAddrMsg_DumpToBuffer(const GWEN_MSG *msg, GWEN_BUFFER *dbuf, const char *sText)
|
||||||
|
{
|
||||||
|
if ((AQH_NodeMsg_GetMsgType(msg)==AQH_MSG_TYPE_HAVE_ADDRESS) &&
|
||||||
|
(GWEN_Msg_GetBytesInBuffer(msg)>=AQH_MSG_HAVEADDR_MINSIZE)) {
|
||||||
|
GWEN_Buffer_AppendArgs(dbuf,
|
||||||
|
"0x%02x->0x%02x: HAVE_ADDRESS %s (uid=0x%08x, address=0x%02x)\n",
|
||||||
|
AQH_NodeMsg_GetSourceAddress(msg),
|
||||||
|
AQH_NodeMsg_GetDestAddress(msg),
|
||||||
|
sText,
|
||||||
|
(unsigned int) AQH_HaveAddrMsg_GetUid(msg),
|
||||||
|
AQH_HaveAddrMsg_GetAddress(msg));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
37
aqhome/msg/msg_haveaddr.h
Normal file
37
aqhome/msg/msg_haveaddr.h
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* This file is part of the project AqHome.
|
||||||
|
* AqHome (c) by 2023 Martin Preuss, all rights reserved.
|
||||||
|
*
|
||||||
|
* The license for this file can be found in the file COPYING which you
|
||||||
|
* should have received along with this file.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef AQH_MSG_HAVEADDR_H
|
||||||
|
#define AQH_MSG_HAVEADDR_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <aqhome/api.h>
|
||||||
|
#include <aqhome/msg/msg_node.h>
|
||||||
|
|
||||||
|
#include <gwenhywfar/msg.h>
|
||||||
|
#include <gwenhywfar/buffer.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#define AQH_MSG_OFFS_HAVEADDR_UID 0
|
||||||
|
#define AQH_MSG_OFFS_HAVEADDR_ADDR 4
|
||||||
|
|
||||||
|
#define AQH_MSG_HAVEADDR_MINSIZE (AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_HAVEADDR_ADDR+1)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
AQHOME_API uint32_t AQH_HaveAddrMsg_GetUid(const GWEN_MSG *msg);
|
||||||
|
AQHOME_API uint8_t AQH_HaveAddrMsg_GetAddress(const GWEN_MSG *msg);
|
||||||
|
AQHOME_API void AQH_HaveAddrMsg_DumpToBuffer(const GWEN_MSG *msg, GWEN_BUFFER *dbuf, const char *sText);
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
53
aqhome/msg/msg_needaddr.c
Normal file
53
aqhome/msg/msg_needaddr.c
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* 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 <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "aqhome/msg/msg_needaddr.h"
|
||||||
|
|
||||||
|
#include <gwenhywfar/misc.h>
|
||||||
|
#include <gwenhywfar/list.h>
|
||||||
|
#include <gwenhywfar/error.h>
|
||||||
|
#include <gwenhywfar/debug.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t AQH_NeedAddrMsg_GetUid(const GWEN_MSG *msg)
|
||||||
|
{
|
||||||
|
if ((AQH_NodeMsg_GetMsgType(msg)==AQH_MSG_TYPE_NEED_ADDRESS) &&
|
||||||
|
(GWEN_Msg_GetBytesInBuffer(msg)>=AQH_MSG_NEEDADDR_MINSIZE)) {
|
||||||
|
const uint8_t *ptr;
|
||||||
|
|
||||||
|
ptr=GWEN_Msg_GetConstBuffer(msg)+AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_NEEDADDR_UID;
|
||||||
|
return (uint32_t)(ptr[0])+(ptr[1]<<8)+(ptr[2]<<16)+(ptr[3]<<24);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void AQH_NeedAddrMsg_DumpToBuffer(const GWEN_MSG *msg, GWEN_BUFFER *dbuf, const char *sText)
|
||||||
|
{
|
||||||
|
if ((AQH_NodeMsg_GetMsgType(msg)==AQH_MSG_TYPE_NEED_ADDRESS) &&
|
||||||
|
(GWEN_Msg_GetBytesInBuffer(msg)>=AQH_MSG_NEEDADDR_MINSIZE)) {
|
||||||
|
GWEN_Buffer_AppendArgs(dbuf,
|
||||||
|
"0x%02x->0x%02x: NEED_ADDRESS %s (uid=0x%08x)\n",
|
||||||
|
AQH_NodeMsg_GetSourceAddress(msg),
|
||||||
|
AQH_NodeMsg_GetDestAddress(msg),
|
||||||
|
sText,
|
||||||
|
(unsigned int) AQH_NeedAddrMsg_GetUid(msg));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
35
aqhome/msg/msg_needaddr.h
Normal file
35
aqhome/msg/msg_needaddr.h
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* This file is part of the project AqHome.
|
||||||
|
* AqHome (c) by 2023 Martin Preuss, all rights reserved.
|
||||||
|
*
|
||||||
|
* The license for this file can be found in the file COPYING which you
|
||||||
|
* should have received along with this file.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef AQH_MSG_NEEDADDR_H
|
||||||
|
#define AQH_MSG_NEEDADDR_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <aqhome/api.h>
|
||||||
|
#include <aqhome/msg/msg_node.h>
|
||||||
|
|
||||||
|
#include <gwenhywfar/msg.h>
|
||||||
|
#include <gwenhywfar/buffer.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#define AQH_MSG_OFFS_NEEDADDR_UID 0
|
||||||
|
|
||||||
|
#define AQH_MSG_NEEDADDR_MINSIZE (AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_NEEDADDR_UID+4)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
AQHOME_API uint32_t AQH_NeedAddrMsg_GetUid(const GWEN_MSG *msg);
|
||||||
|
AQHOME_API void AQH_NeedAddrMsg_DumpToBuffer(const GWEN_MSG *msg, GWEN_BUFFER *dbuf, const char *sText);
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
186
aqhome/msg/msg_node.c
Normal file
186
aqhome/msg/msg_node.c
Normal file
@@ -0,0 +1,186 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* 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 <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#include "aqhome/msg/msg_node.h"
|
||||||
|
|
||||||
|
#include <gwenhywfar/debug.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static uint8_t _calcChecksum(const uint8_t *ptr, uint8_t len);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t AQH_NodeMsg_GetDestAddress(const GWEN_MSG *msg)
|
||||||
|
{
|
||||||
|
if (msg && GWEN_Msg_GetBytesInBuffer(msg)>=AQH_MSG_OFFS_ALL_DATA_BEGIN) {
|
||||||
|
const uint8_t *ptr;
|
||||||
|
|
||||||
|
ptr=GWEN_Msg_GetConstBuffer(msg);
|
||||||
|
return ptr[AQH_MSG_OFFS_ALL_DEST_ADDRESS];
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t AQH_NodeMsg_GetMsgType(const GWEN_MSG *msg)
|
||||||
|
{
|
||||||
|
if (msg && GWEN_Msg_GetBytesInBuffer(msg)>=AQH_MSG_OFFS_ALL_DATA_BEGIN) {
|
||||||
|
const uint8_t *ptr;
|
||||||
|
|
||||||
|
ptr=GWEN_Msg_GetConstBuffer(msg);
|
||||||
|
return ptr[AQH_MSG_OFFS_ALL_MSG_TYPE];
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t AQH_NodeMsg_GetSourceAddress(const GWEN_MSG *msg)
|
||||||
|
{
|
||||||
|
if (msg && GWEN_Msg_GetBytesInBuffer(msg)>=AQH_MSG_OFFS_ALL_DATA_BEGIN) {
|
||||||
|
const uint8_t *ptr;
|
||||||
|
|
||||||
|
ptr=GWEN_Msg_GetConstBuffer(msg);
|
||||||
|
return ptr[AQH_MSG_OFFS_ALL_SRC_ADDRESS];
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t AQH_NodeMsg_GetMsgPayloadLen(const GWEN_MSG *msg)
|
||||||
|
{
|
||||||
|
if (msg && GWEN_Msg_GetBytesInBuffer(msg)>=AQH_MSG_OFFS_ALL_DATA_BEGIN) {
|
||||||
|
const uint8_t *ptr;
|
||||||
|
|
||||||
|
ptr=GWEN_Msg_GetConstBuffer(msg);
|
||||||
|
return ptr[AQH_MSG_OFFS_ALL_PAYLOAD_LEN];
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int AQH_NodeMsg_IsMsgComplete(const GWEN_MSG *msg)
|
||||||
|
{
|
||||||
|
if (msg) {
|
||||||
|
uint8_t msgLen;
|
||||||
|
|
||||||
|
msgLen=GWEN_Msg_GetBytesInBuffer(msg);
|
||||||
|
if (msgLen>=AQH_MSG_OFFS_ALL_DATA_BEGIN) {
|
||||||
|
const uint8_t *ptr;
|
||||||
|
uint8_t len;
|
||||||
|
|
||||||
|
ptr=GWEN_Msg_GetConstBuffer(msg);
|
||||||
|
len=ptr[AQH_MSG_OFFS_ALL_PAYLOAD_LEN]+AQH_MSG_OFFS_ALL_PAYLOAD_BEGIN+1;
|
||||||
|
if (len>AQH_MAXMSGSIZE)
|
||||||
|
return -1;
|
||||||
|
else if (msgLen>=len)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int AQH_NodeMsg_IsChecksumValid(const GWEN_MSG *msg)
|
||||||
|
{
|
||||||
|
if (msg && AQH_NodeMsg_IsMsgComplete(msg))
|
||||||
|
return (_calcChecksum(GWEN_Msg_GetConstBuffer(msg), GWEN_Msg_GetBytesInBuffer(msg))==0)?1:0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int AQH_NodeMsg_AddChecksum(GWEN_MSG *msg)
|
||||||
|
{
|
||||||
|
if (msg) {
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
rv=GWEN_Msg_AddByte(msg, _calcChecksum(GWEN_Msg_GetConstBuffer(msg), GWEN_Msg_GetBytesInBuffer(msg)));
|
||||||
|
if (rv<0) {
|
||||||
|
DBG_INFO(NULL, "here (%d)", rv);
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return GWEN_ERROR_GENERIC;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void AQH_NodeMsg_DumpToBuffer(const GWEN_MSG *msg, GWEN_BUFFER *dbuf, const char *sText)
|
||||||
|
{
|
||||||
|
GWEN_Buffer_AppendArgs(dbuf,
|
||||||
|
"0x%02x->0x%02x: %d %s\n",
|
||||||
|
AQH_NodeMsg_GetSourceAddress(msg),
|
||||||
|
AQH_NodeMsg_GetDestAddress(msg),
|
||||||
|
AQH_NodeMsg_GetMsgType(msg),
|
||||||
|
sText);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t AQH_NodeMsg_GetMsgGroup(uint8_t msgType)
|
||||||
|
{
|
||||||
|
switch(msgType) {
|
||||||
|
case AQH_MSG_TYPE_PING:
|
||||||
|
case AQH_MSG_TYPE_PONG:
|
||||||
|
case AQH_MSG_TYPE_COMSENDSTATS:
|
||||||
|
case AQH_MSG_TYPE_COMRECVSTATS:
|
||||||
|
case AQH_MSG_TYPE_TWIBUSMEMBER:
|
||||||
|
case AQH_MSG_TYPE_DEBUG:
|
||||||
|
return AQH_MSG_TYPEGROUP_INFO;
|
||||||
|
case AQH_MSG_TYPE_VALUE:
|
||||||
|
return AQH_MSG_TYPEGROUP_VALUES;
|
||||||
|
case AQH_MSG_TYPE_NEED_ADDRESS:
|
||||||
|
case AQH_MSG_TYPE_HAVE_ADDRESS:
|
||||||
|
case AQH_MSG_TYPE_CLAIM_ADDRESS:
|
||||||
|
case AQH_MSG_TYPE_DENY_ADDRESS:
|
||||||
|
case AQH_MSG_TYPE_ADDRESS_RANGE:
|
||||||
|
return AQH_MSG_TYPEGROUP_ADDRESS;
|
||||||
|
case AQH_MSG_TYPE_NET_SET_ACCEPTED_MSGGROUPS:
|
||||||
|
return AQH_MSG_TYPEGROUP_ADMIN;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t _calcChecksum(const uint8_t *ptr, uint8_t len)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
uint8_t x=0;
|
||||||
|
|
||||||
|
for (i=0; i<len; i++, ptr++) {
|
||||||
|
x^=*ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
75
aqhome/msg/msg_node.h
Normal file
75
aqhome/msg/msg_node.h
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* This file is part of the project AqHome.
|
||||||
|
* AqHome (c) by 2023 Martin Preuss, all rights reserved.
|
||||||
|
*
|
||||||
|
* The license for this file can be found in the file COPYING which you
|
||||||
|
* should have received along with this file.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef AQH_MSG_NODE_H
|
||||||
|
#define AQH_MSG_NODE_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <aqhome/api.h>
|
||||||
|
|
||||||
|
#include <gwenhywfar/msg.h>
|
||||||
|
#include <gwenhywfar/buffer.h>
|
||||||
|
|
||||||
|
|
||||||
|
#define AQH_MAXMSGSIZE 16
|
||||||
|
|
||||||
|
|
||||||
|
#define AQH_MSG_OFFS_ALL_DEST_ADDRESS 0
|
||||||
|
#define AQH_MSG_OFFS_ALL_PAYLOAD_LEN 1
|
||||||
|
#define AQH_MSG_OFFS_ALL_PAYLOAD_BEGIN 2
|
||||||
|
#define AQH_MSG_OFFS_ALL_MSG_TYPE 2
|
||||||
|
#define AQH_MSG_OFFS_ALL_SRC_ADDRESS 3
|
||||||
|
#define AQH_MSG_OFFS_ALL_DATA_BEGIN 4
|
||||||
|
|
||||||
|
|
||||||
|
#define AQH_MSG_TYPE_PING 10
|
||||||
|
#define AQH_MSG_TYPE_PONG 11
|
||||||
|
#define AQH_MSG_TYPE_COMSENDSTATS 20
|
||||||
|
#define AQH_MSG_TYPE_COMRECVSTATS 21
|
||||||
|
#define AQH_MSG_TYPE_TWIBUSMEMBER 30
|
||||||
|
#define AQH_MSG_TYPE_DEBUG 40
|
||||||
|
#define AQH_MSG_TYPE_VALUE 50
|
||||||
|
#define AQH_MSG_TYPE_NEED_ADDRESS 60
|
||||||
|
#define AQH_MSG_TYPE_HAVE_ADDRESS 61
|
||||||
|
#define AQH_MSG_TYPE_CLAIM_ADDRESS 62
|
||||||
|
#define AQH_MSG_TYPE_DENY_ADDRESS 63
|
||||||
|
#define AQH_MSG_TYPE_ADDRESS_RANGE 64
|
||||||
|
|
||||||
|
/* internal msg types via NET interface */
|
||||||
|
#define AQH_MSG_TYPE_NET_SET_ACCEPTED_MSGGROUPS 200
|
||||||
|
|
||||||
|
|
||||||
|
#define AQH_MSG_TYPEGROUP_INFO 0x00000001
|
||||||
|
#define AQH_MSG_TYPEGROUP_VALUES 0x00000002
|
||||||
|
#define AQH_MSG_TYPEGROUP_ADDRESS 0x00000004
|
||||||
|
#define AQH_MSG_TYPEGROUP_FLASH 0x00000008
|
||||||
|
#define AQH_MSG_TYPEGROUP_ADMIN 0x00000010
|
||||||
|
#define AQH_MSG_TYPEGROUP_ALL 0xffffffff
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
AQHOME_API uint8_t AQH_NodeMsg_GetDestAddress(const GWEN_MSG *msg);
|
||||||
|
AQHOME_API uint8_t AQH_NodeMsg_GetMsgType(const GWEN_MSG *msg);
|
||||||
|
AQHOME_API uint8_t AQH_NodeMsg_GetSourceAddress(const GWEN_MSG *msg);
|
||||||
|
AQHOME_API uint8_t AQH_NodeMsg_GetMsgPayloadLen(const GWEN_MSG *msg);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
AQHOME_API int AQH_NodeMsg_IsMsgComplete(const GWEN_MSG *msg);
|
||||||
|
AQHOME_API int AQH_NodeMsg_IsChecksumValid(const GWEN_MSG *msg);
|
||||||
|
AQHOME_API int AQH_NodeMsg_AddChecksum(GWEN_MSG *msg);
|
||||||
|
|
||||||
|
AQHOME_API void AQH_NodeMsg_DumpToBuffer(const GWEN_MSG *msg, GWEN_BUFFER *dbuf, const char *sText);
|
||||||
|
|
||||||
|
AQHOME_API uint32_t AQH_NodeMsg_GetMsgGroup(uint8_t msgType);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
53
aqhome/msg/msg_ping.c
Normal file
53
aqhome/msg/msg_ping.c
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* 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 <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "aqhome/msg/msg_ping.h"
|
||||||
|
|
||||||
|
#include <gwenhywfar/misc.h>
|
||||||
|
#include <gwenhywfar/list.h>
|
||||||
|
#include <gwenhywfar/error.h>
|
||||||
|
#include <gwenhywfar/debug.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t AQH_PingMsg_GetTimestamp(const GWEN_MSG *msg)
|
||||||
|
{
|
||||||
|
if ((AQH_NodeMsg_GetMsgType(msg)==AQH_MSG_TYPE_PING) &&
|
||||||
|
(GWEN_Msg_GetBytesInBuffer(msg)>=AQH_MSG_PING_MINSIZE)) {
|
||||||
|
const uint8_t *ptr;
|
||||||
|
|
||||||
|
ptr=GWEN_Msg_GetConstBuffer(msg)+AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_PING_TIMESTAMP;
|
||||||
|
return (uint32_t)(ptr[0])+(ptr[1]<<8)+(ptr[2]<<16)+(ptr[3]<<24);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void AQH_PingMsg_DumpToBuffer(const GWEN_MSG *msg, GWEN_BUFFER *dbuf, const char *sText)
|
||||||
|
{
|
||||||
|
if ((AQH_NodeMsg_GetMsgType(msg)==AQH_MSG_TYPE_PING) &&
|
||||||
|
(GWEN_Msg_GetBytesInBuffer(msg)>=AQH_MSG_PING_MINSIZE)) {
|
||||||
|
GWEN_Buffer_AppendArgs(dbuf,
|
||||||
|
"0x%02x->0x%02x: PING %s (timestamp=0x%08x)\n",
|
||||||
|
AQH_NodeMsg_GetSourceAddress(msg),
|
||||||
|
AQH_NodeMsg_GetDestAddress(msg),
|
||||||
|
sText,
|
||||||
|
(unsigned int) AQH_PingMsg_GetTimestamp(msg));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
36
aqhome/msg/msg_ping.h
Normal file
36
aqhome/msg/msg_ping.h
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* This file is part of the project AqHome.
|
||||||
|
* AqHome (c) by 2023 Martin Preuss, all rights reserved.
|
||||||
|
*
|
||||||
|
* The license for this file can be found in the file COPYING which you
|
||||||
|
* should have received along with this file.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef AQH_MSG_NODE_PING_H
|
||||||
|
#define AQH_MSG_NODE_PING_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <aqhome/api.h>
|
||||||
|
#include <aqhome/msg/msg_node.h>
|
||||||
|
|
||||||
|
#include <gwenhywfar/msg.h>
|
||||||
|
#include <gwenhywfar/buffer.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#define AQH_MSG_OFFS_PING_TIMESTAMP 0
|
||||||
|
|
||||||
|
#define AQH_MSG_PING_MINSIZE (AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_PING_TIMESTAMP+4)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
AQHOME_API uint32_t AQH_PingMsg_GetTimestamp(const GWEN_MSG *msg);
|
||||||
|
AQHOME_API void AQH_PingMsg_DumpToBuffer(const GWEN_MSG *msg, GWEN_BUFFER *dbuf, const char *sText);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
53
aqhome/msg/msg_pong.c
Normal file
53
aqhome/msg/msg_pong.c
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* 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 <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "aqhome/msg/msg_pong.h"
|
||||||
|
|
||||||
|
#include <gwenhywfar/misc.h>
|
||||||
|
#include <gwenhywfar/list.h>
|
||||||
|
#include <gwenhywfar/error.h>
|
||||||
|
#include <gwenhywfar/debug.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t AQH_PongMsg_GetTimestamp(const GWEN_MSG *msg)
|
||||||
|
{
|
||||||
|
if ((AQH_NodeMsg_GetMsgType(msg)==AQH_MSG_TYPE_PONG) &&
|
||||||
|
(GWEN_Msg_GetBytesInBuffer(msg)>=AQH_MSG_PONG_MINSIZE)) {
|
||||||
|
const uint8_t *ptr;
|
||||||
|
|
||||||
|
ptr=GWEN_Msg_GetConstBuffer(msg)+AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_PONG_TIMESTAMP;
|
||||||
|
return (uint32_t)(ptr[0])+(ptr[1]<<8)+(ptr[2]<<16)+(ptr[3]<<24);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void AQH_PongMsg_DumpToBuffer(const GWEN_MSG *msg, GWEN_BUFFER *dbuf, const char *sText)
|
||||||
|
{
|
||||||
|
if ((AQH_NodeMsg_GetMsgType(msg)==AQH_MSG_TYPE_PONG) &&
|
||||||
|
(GWEN_Msg_GetBytesInBuffer(msg)>=AQH_MSG_PONG_MINSIZE)) {
|
||||||
|
GWEN_Buffer_AppendArgs(dbuf,
|
||||||
|
"0x%02x->0x%02x: PONG %s (timestamp=0x%08x)\n",
|
||||||
|
AQH_NodeMsg_GetSourceAddress(msg),
|
||||||
|
AQH_NodeMsg_GetDestAddress(msg),
|
||||||
|
sText,
|
||||||
|
(unsigned int) AQH_PongMsg_GetTimestamp(msg));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
36
aqhome/msg/msg_pong.h
Normal file
36
aqhome/msg/msg_pong.h
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* This file is part of the project AqHome.
|
||||||
|
* AqHome (c) by 2023 Martin Preuss, all rights reserved.
|
||||||
|
*
|
||||||
|
* The license for this file can be found in the file COPYING which you
|
||||||
|
* should have received along with this file.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef AQH_MSG_NODE_PONG_H
|
||||||
|
#define AQH_MSG_NODE_PONG_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <aqhome/api.h>
|
||||||
|
#include <aqhome/msg/msg_node.h>
|
||||||
|
|
||||||
|
#include <gwenhywfar/msg.h>
|
||||||
|
#include <gwenhywfar/buffer.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#define AQH_MSG_OFFS_PONG_TIMESTAMP 0
|
||||||
|
|
||||||
|
#define AQH_MSG_PONG_MINSIZE (AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_PONG_TIMESTAMP+4)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
AQHOME_API uint32_t AQH_PongMsg_GetTimestamp(const GWEN_MSG *msg);
|
||||||
|
AQHOME_API void AQH_PongMsg_DumpToBuffer(const GWEN_MSG *msg, GWEN_BUFFER *dbuf, const char *sText);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
99
aqhome/msg/msg_sendstats.c
Normal file
99
aqhome/msg/msg_sendstats.c
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* 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 <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "aqhome/msg/msg_sendstats.h"
|
||||||
|
|
||||||
|
#include <gwenhywfar/misc.h>
|
||||||
|
#include <gwenhywfar/list.h>
|
||||||
|
#include <gwenhywfar/error.h>
|
||||||
|
#include <gwenhywfar/debug.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t AQH_SendStatsMsg_GetTimestamp(const GWEN_MSG *msg)
|
||||||
|
{
|
||||||
|
if ((AQH_NodeMsg_GetMsgType(msg)==AQH_MSG_TYPE_COMSENDSTATS) &&
|
||||||
|
(GWEN_Msg_GetBytesInBuffer(msg)>=AQH_MSG_SENDSTATS_MINSIZE)) {
|
||||||
|
const uint8_t *ptr;
|
||||||
|
|
||||||
|
ptr=GWEN_Msg_GetConstBuffer(msg)+AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_SENDSTATS_TIMESTAMP;
|
||||||
|
return (uint32_t)(ptr[0])+(ptr[1]<<8)+(ptr[2]<<16)+(ptr[3]<<24);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
uint16_t AQH_SendStatsMsg_GetPacketsOut(const GWEN_MSG *msg)
|
||||||
|
{
|
||||||
|
if ((AQH_NodeMsg_GetMsgType(msg)==AQH_MSG_TYPE_COMSENDSTATS) &&
|
||||||
|
(GWEN_Msg_GetBytesInBuffer(msg)>=AQH_MSG_SENDSTATS_MINSIZE)) {
|
||||||
|
const uint8_t *ptr;
|
||||||
|
|
||||||
|
ptr=GWEN_Msg_GetConstBuffer(msg)+AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_SENDSTATS_PACKETSOUT;
|
||||||
|
return (uint16_t)(ptr[0])+(ptr[1]<<8);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
uint16_t AQH_SendStatsMsg_GetCollisions(const GWEN_MSG *msg)
|
||||||
|
{
|
||||||
|
if ((AQH_NodeMsg_GetMsgType(msg)==AQH_MSG_TYPE_COMSENDSTATS) &&
|
||||||
|
(GWEN_Msg_GetBytesInBuffer(msg)>=AQH_MSG_SENDSTATS_MINSIZE)) {
|
||||||
|
const uint8_t *ptr;
|
||||||
|
|
||||||
|
ptr=GWEN_Msg_GetConstBuffer(msg)+AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_SENDSTATS_COLLISIONS;
|
||||||
|
return (uint16_t)(ptr[0])+(ptr[1]<<8);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
uint16_t AQH_SendStatsMsg_GetAborted(const GWEN_MSG *msg)
|
||||||
|
{
|
||||||
|
if ((AQH_NodeMsg_GetMsgType(msg)==AQH_MSG_TYPE_COMSENDSTATS) &&
|
||||||
|
(GWEN_Msg_GetBytesInBuffer(msg)>=AQH_MSG_SENDSTATS_MINSIZE)) {
|
||||||
|
const uint8_t *ptr;
|
||||||
|
|
||||||
|
ptr=GWEN_Msg_GetConstBuffer(msg)+AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_SENDSTATS_ABORTED;
|
||||||
|
return (uint16_t)(ptr[0])+(ptr[1]<<8);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void AQH_SendStatsMsg_DumpToBuffer(const GWEN_MSG *msg, GWEN_BUFFER *dbuf, const char *sText)
|
||||||
|
{
|
||||||
|
if ((AQH_NodeMsg_GetMsgType(msg)==AQH_MSG_TYPE_COMSENDSTATS) &&
|
||||||
|
(GWEN_Msg_GetBytesInBuffer(msg)>=AQH_MSG_SENDSTATS_MINSIZE)) {
|
||||||
|
GWEN_Buffer_AppendArgs(dbuf,
|
||||||
|
"0x%02x->0x%02x: SENDSTATS %s (timestamp=0x%08x, out=%d, collisions=%d, aborted=%d)\n",
|
||||||
|
AQH_NodeMsg_GetSourceAddress(msg),
|
||||||
|
AQH_NodeMsg_GetDestAddress(msg),
|
||||||
|
sText,
|
||||||
|
(unsigned int) AQH_SendStatsMsg_GetTimestamp(msg),
|
||||||
|
AQH_SendStatsMsg_GetPacketsOut(msg),
|
||||||
|
AQH_SendStatsMsg_GetCollisions(msg),
|
||||||
|
AQH_SendStatsMsg_GetAborted(msg));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
44
aqhome/msg/msg_sendstats.h
Normal file
44
aqhome/msg/msg_sendstats.h
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* This file is part of the project AqHome.
|
||||||
|
* AqHome (c) by 2023 Martin Preuss, all rights reserved.
|
||||||
|
*
|
||||||
|
* The license for this file can be found in the file COPYING which you
|
||||||
|
* should have received along with this file.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef AQH_MSG_SENDSTATS_H
|
||||||
|
#define AQH_MSG_SENDSTATS_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <aqhome/api.h>
|
||||||
|
#include <aqhome/msg/msg_node.h>
|
||||||
|
|
||||||
|
#include <gwenhywfar/msg.h>
|
||||||
|
#include <gwenhywfar/buffer.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#define AQH_MSG_OFFS_SENDSTATS_TIMESTAMP 0
|
||||||
|
#define AQH_MSG_OFFS_SENDSTATS_PACKETSOUT 4
|
||||||
|
#define AQH_MSG_OFFS_SENDSTATS_COLLISIONS 6
|
||||||
|
#define AQH_MSG_OFFS_SENDSTATS_ABORTED 8
|
||||||
|
|
||||||
|
#define AQH_MSG_SENDSTATS_MINSIZE (AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_SENDSTATS_ABORTED+2)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
AQHOME_API uint32_t AQH_SendStatsMsg_GetTimestamp(const GWEN_MSG *msg);
|
||||||
|
AQHOME_API uint16_t AQH_SendStatsMsg_GetPacketsOut(const GWEN_MSG *msg);
|
||||||
|
AQHOME_API uint16_t AQH_SendStatsMsg_GetCollisions(const GWEN_MSG *msg);
|
||||||
|
AQHOME_API uint16_t AQH_SendStatsMsg_GetAborted(const GWEN_MSG *msg);
|
||||||
|
|
||||||
|
|
||||||
|
AQHOME_API void AQH_SendStatsMsg_DumpToBuffer(const GWEN_MSG *msg, GWEN_BUFFER *dbuf, const char *sText);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
121
aqhome/msg/msg_value.c
Normal file
121
aqhome/msg/msg_value.c
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* 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 <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "aqhome/msg/msg_value.h"
|
||||||
|
|
||||||
|
#include <gwenhywfar/misc.h>
|
||||||
|
#include <gwenhywfar/list.h>
|
||||||
|
#include <gwenhywfar/error.h>
|
||||||
|
#include <gwenhywfar/debug.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t AQH_ValueMsg_GetTimestamp(const GWEN_MSG *msg)
|
||||||
|
{
|
||||||
|
if ((AQH_NodeMsg_GetMsgType(msg)==AQH_MSG_TYPE_VALUE) &&
|
||||||
|
(GWEN_Msg_GetBytesInBuffer(msg)>=AQH_MSG_VALUE_MINSIZE)) {
|
||||||
|
const uint8_t *ptr;
|
||||||
|
|
||||||
|
ptr=GWEN_Msg_GetConstBuffer(msg)+AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_VALUE_TIMESTAMP;
|
||||||
|
return (uint32_t)(ptr[0])+(ptr[1]<<8)+(ptr[2]<<16)+(ptr[3]<<24);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t AQH_ValueMsg_GetValueId(const GWEN_MSG *msg)
|
||||||
|
{
|
||||||
|
if ((AQH_NodeMsg_GetMsgType(msg)==AQH_MSG_TYPE_VALUE) &&
|
||||||
|
(GWEN_Msg_GetBytesInBuffer(msg)>=AQH_MSG_VALUE_MINSIZE)) {
|
||||||
|
const uint8_t *ptr;
|
||||||
|
|
||||||
|
ptr=GWEN_Msg_GetConstBuffer(msg)+AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_VALUE_VALUEID;
|
||||||
|
return ptr[0];
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t AQH_ValueMsg_GetValueType(const GWEN_MSG *msg)
|
||||||
|
{
|
||||||
|
if ((AQH_NodeMsg_GetMsgType(msg)==AQH_MSG_TYPE_VALUE) &&
|
||||||
|
(GWEN_Msg_GetBytesInBuffer(msg)>=AQH_MSG_VALUE_MINSIZE)) {
|
||||||
|
const uint8_t *ptr;
|
||||||
|
|
||||||
|
ptr=GWEN_Msg_GetConstBuffer(msg)+AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_VALUE_VALUETYPE;
|
||||||
|
return ptr[0];
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const char *AQH_ValueMsg_GetValueTypeName(const GWEN_MSG *msg)
|
||||||
|
{
|
||||||
|
uint8_t t;
|
||||||
|
|
||||||
|
t=AQH_ValueMsg_GetValueType(msg);
|
||||||
|
switch(t) {
|
||||||
|
case AQH_MSG_VALUE_TYPE_TEMP: return "temperature";
|
||||||
|
case AQH_MSG_VALUE_TYPE_HUMIDITY: return "humidity";
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
return "unknown";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
double AQH_ValueMsg_GetValue(const GWEN_MSG *msg)
|
||||||
|
{
|
||||||
|
if ((AQH_NodeMsg_GetMsgType(msg)==AQH_MSG_TYPE_VALUE) &&
|
||||||
|
(GWEN_Msg_GetBytesInBuffer(msg)>=AQH_MSG_VALUE_MINSIZE)) {
|
||||||
|
const uint8_t *ptr;
|
||||||
|
double value;
|
||||||
|
double denom;
|
||||||
|
uint16_t intDenom;
|
||||||
|
|
||||||
|
ptr=GWEN_Msg_GetConstBuffer(msg)+AQH_MSG_OFFS_ALL_DATA_BEGIN;
|
||||||
|
value=(double)((ptr[AQH_MSG_OFFS_VALUE_VALUE])+(ptr[AQH_MSG_OFFS_VALUE_VALUE+1]<<8));
|
||||||
|
intDenom=(ptr[AQH_MSG_OFFS_VALUE_DENOM])+(ptr[AQH_MSG_OFFS_VALUE_DENOM+1]<<8);
|
||||||
|
denom=(double)(intDenom);
|
||||||
|
if (intDenom==0)
|
||||||
|
denom=1.0;
|
||||||
|
return (double)(value/denom);
|
||||||
|
|
||||||
|
}
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void AQH_ValueMsg_DumpToBuffer(const GWEN_MSG *msg, GWEN_BUFFER *dbuf, const char *sText)
|
||||||
|
{
|
||||||
|
if ((AQH_NodeMsg_GetMsgType(msg)==AQH_MSG_TYPE_VALUE) &&
|
||||||
|
(GWEN_Msg_GetBytesInBuffer(msg)>=AQH_MSG_VALUE_MINSIZE)) {
|
||||||
|
GWEN_Buffer_AppendArgs(dbuf, "0x%02x->0x%02x: VALUE %s (timestamp=0x%08x, value_id=0x%02x type=%s value=%f)\n",
|
||||||
|
AQH_NodeMsg_GetSourceAddress(msg),
|
||||||
|
AQH_NodeMsg_GetDestAddress(msg),
|
||||||
|
sText,
|
||||||
|
(unsigned int) AQH_ValueMsg_GetTimestamp(msg),
|
||||||
|
AQH_ValueMsg_GetValueId(msg),
|
||||||
|
AQH_ValueMsg_GetValueTypeName(msg),
|
||||||
|
AQH_ValueMsg_GetValue(msg));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
47
aqhome/msg/msg_value.h
Normal file
47
aqhome/msg/msg_value.h
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* This file is part of the project AqHome.
|
||||||
|
* AqHome (c) by 2023 Martin Preuss, all rights reserved.
|
||||||
|
*
|
||||||
|
* The license for this file can be found in the file COPYING which you
|
||||||
|
* should have received along with this file.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef AQH_MSG_VALUE_H
|
||||||
|
#define AQH_MSG_VALUE_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <aqhome/api.h>
|
||||||
|
#include <aqhome/msg/msg_node.h>
|
||||||
|
|
||||||
|
#include <gwenhywfar/msg.h>
|
||||||
|
#include <gwenhywfar/buffer.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#define AQH_MSG_OFFS_VALUE_TIMESTAMP 0
|
||||||
|
#define AQH_MSG_OFFS_VALUE_VALUEID 4
|
||||||
|
#define AQH_MSG_OFFS_VALUE_VALUETYPE 5
|
||||||
|
#define AQH_MSG_OFFS_VALUE_VALUE 6
|
||||||
|
#define AQH_MSG_OFFS_VALUE_DENOM 8
|
||||||
|
|
||||||
|
#define AQH_MSG_VALUE_MINSIZE (AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_VALUE_DENOM+2)
|
||||||
|
|
||||||
|
#define AQH_MSG_VALUE_TYPE_TEMP 1
|
||||||
|
#define AQH_MSG_VALUE_TYPE_HUMIDITY 2
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
AQHOME_API uint32_t AQH_ValueMsg_GetTimestamp(const GWEN_MSG *msg);
|
||||||
|
AQHOME_API uint8_t AQH_ValueMsg_GetValueId(const GWEN_MSG *msg);
|
||||||
|
AQHOME_API uint8_t AQH_ValueMsg_GetValueType(const GWEN_MSG *msg);
|
||||||
|
AQHOME_API double AQH_ValueMsg_GetValue(const GWEN_MSG *msg);
|
||||||
|
|
||||||
|
|
||||||
|
AQHOME_API void AQH_ValueMsg_DumpToBuffer(const GWEN_MSG *msg, GWEN_BUFFER *dbuf, const char *sText);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
GWEN_INHERIT(AQH_MSG_ENDPOINT, AQH_MSG_ENDPOINT_LOG)
|
GWEN_INHERIT(AQH_MSG_ENDPOINT, AQH_MSG_ENDPOINT_LOG_OLD)
|
||||||
|
|
||||||
|
|
||||||
static void GWENHYWFAR_CB _freeData(void *bp, void *p);
|
static void GWENHYWFAR_CB _freeData(void *bp, void *p);
|
||||||
@@ -45,12 +45,12 @@ AQH_MSG_ENDPOINT *AQH_MsgEndpointLog_new(const char *filename)
|
|||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
AQH_MSG_ENDPOINT *ep;
|
AQH_MSG_ENDPOINT *ep;
|
||||||
AQH_MSG_ENDPOINT_LOG *xep;
|
AQH_MSG_ENDPOINT_LOG_OLD *xep;
|
||||||
|
|
||||||
ep=AQH_MsgEndpoint_new(-1, AQH_MSG_ENDPOINT_ENDPOINTGROUP_NET, "LOG");
|
ep=AQH_MsgEndpoint_new(-1, AQH_MSG_ENDPOINT_ENDPOINTGROUP_NET, "LOG");
|
||||||
GWEN_NEW_OBJECT(AQH_MSG_ENDPOINT_LOG, xep);
|
GWEN_NEW_OBJECT(AQH_MSG_ENDPOINT_LOG_OLD, xep);
|
||||||
xep->filename=strdup(filename);
|
xep->filename=strdup(filename);
|
||||||
GWEN_INHERIT_SETDATA(AQH_MSG_ENDPOINT, AQH_MSG_ENDPOINT_LOG, ep, xep, _freeData);
|
GWEN_INHERIT_SETDATA(AQH_MSG_ENDPOINT, AQH_MSG_ENDPOINT_LOG_OLD, ep, xep, _freeData);
|
||||||
AQH_MsgEndpoint_SetAcceptedEndpointGroups(ep, AQH_MSG_ENDPOINT_ENDPOINTGROUP_BUS);
|
AQH_MsgEndpoint_SetAcceptedEndpointGroups(ep, AQH_MSG_ENDPOINT_ENDPOINTGROUP_BUS);
|
||||||
AQH_MsgEndpoint_SetAcceptedMsgGroups(ep, AQH_MSG_ENDPOINT_MSGGROUP_ALL);
|
AQH_MsgEndpoint_SetAcceptedMsgGroups(ep, AQH_MSG_ENDPOINT_MSGGROUP_ALL);
|
||||||
AQH_MsgEndpoint_AddFlags(ep, AQH_MSG_ENDPOINT_FLAGS_NOIO);
|
AQH_MsgEndpoint_AddFlags(ep, AQH_MSG_ENDPOINT_FLAGS_NOIO);
|
||||||
@@ -63,9 +63,9 @@ AQH_MSG_ENDPOINT *AQH_MsgEndpointLog_new(const char *filename)
|
|||||||
|
|
||||||
void _freeData(void *bp, void *p)
|
void _freeData(void *bp, void *p)
|
||||||
{
|
{
|
||||||
AQH_MSG_ENDPOINT_LOG *xep;
|
AQH_MSG_ENDPOINT_LOG_OLD *xep;
|
||||||
|
|
||||||
xep=(AQH_MSG_ENDPOINT_LOG*) p;
|
xep=(AQH_MSG_ENDPOINT_LOG_OLD*) p;
|
||||||
free(xep->filename);
|
free(xep->filename);
|
||||||
GWEN_FREE_OBJECT(xep);
|
GWEN_FREE_OBJECT(xep);
|
||||||
}
|
}
|
||||||
@@ -96,7 +96,7 @@ void _run(AQH_MSG_ENDPOINT *ep)
|
|||||||
|
|
||||||
void _logMessage(AQH_MSG_ENDPOINT *ep, const AQH_MSG *msg)
|
void _logMessage(AQH_MSG_ENDPOINT *ep, const AQH_MSG *msg)
|
||||||
{
|
{
|
||||||
AQH_MSG_ENDPOINT_LOG *xep;
|
AQH_MSG_ENDPOINT_LOG_OLD *xep;
|
||||||
const uint8_t *ptr;
|
const uint8_t *ptr;
|
||||||
uint8_t len;
|
uint8_t len;
|
||||||
uint8_t msgType;
|
uint8_t msgType;
|
||||||
@@ -104,7 +104,7 @@ void _logMessage(AQH_MSG_ENDPOINT *ep, const AQH_MSG *msg)
|
|||||||
GWEN_BUFFER *dbuf;
|
GWEN_BUFFER *dbuf;
|
||||||
GWEN_TIME *ti;
|
GWEN_TIME *ti;
|
||||||
|
|
||||||
xep=GWEN_INHERIT_GETDATA(AQH_MSG_ENDPOINT, AQH_MSG_ENDPOINT_LOG, ep);
|
xep=GWEN_INHERIT_GETDATA(AQH_MSG_ENDPOINT, AQH_MSG_ENDPOINT_LOG_OLD, ep);
|
||||||
dbuf=GWEN_Buffer_new(0, 256, 0, 1);
|
dbuf=GWEN_Buffer_new(0, 256, 0, 1);
|
||||||
ti=GWEN_CurrentTime();
|
ti=GWEN_CurrentTime();
|
||||||
GWEN_Time_toString(ti, "YYYY-MM-DD hh:mm:ss ", dbuf);
|
GWEN_Time_toString(ti, "YYYY-MM-DD hh:mm:ss ", dbuf);
|
||||||
|
|||||||
@@ -13,8 +13,8 @@
|
|||||||
#include "aqhome/msgendpointlog.h"
|
#include "aqhome/msgendpointlog.h"
|
||||||
|
|
||||||
|
|
||||||
typedef struct AQH_MSG_ENDPOINT_LOG AQH_MSG_ENDPOINT_LOG;
|
typedef struct AQH_MSG_ENDPOINT_LOG_OLD AQH_MSG_ENDPOINT_LOG_OLD;
|
||||||
struct AQH_MSG_ENDPOINT_LOG {
|
struct AQH_MSG_ENDPOINT_LOG_OLD {
|
||||||
char *filename;
|
char *filename;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ static uint32_t _getMsgGroup(uint8_t msgType);
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
AQH_MSG_ENDPOINT_MGR *AQH_MsgEndpointMgr_new(uint8_t busAddr)
|
AQH_MSG_ENDPOINT_MGR *AQH_MsgEndpointManager_new(uint8_t busAddr)
|
||||||
{
|
{
|
||||||
AQH_MSG_ENDPOINT_MGR *emgr;
|
AQH_MSG_ENDPOINT_MGR *emgr;
|
||||||
|
|
||||||
@@ -45,7 +45,7 @@ AQH_MSG_ENDPOINT_MGR *AQH_MsgEndpointMgr_new(uint8_t busAddr)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_MsgEndpointMgr_free(AQH_MSG_ENDPOINT_MGR *emgr)
|
void AQH_MsgEndpointManager_free(AQH_MSG_ENDPOINT_MGR *emgr)
|
||||||
{
|
{
|
||||||
if (emgr) {
|
if (emgr) {
|
||||||
AQH_MsgEndpoint_List_free(emgr->endpointList);
|
AQH_MsgEndpoint_List_free(emgr->endpointList);
|
||||||
@@ -55,35 +55,35 @@ void AQH_MsgEndpointMgr_free(AQH_MSG_ENDPOINT_MGR *emgr)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint8_t AQH_MsgEndpointMgr_GetBusAddr(const AQH_MSG_ENDPOINT_MGR *emgr)
|
uint8_t AQH_MsgEndpointManager_GetBusAddr(const AQH_MSG_ENDPOINT_MGR *emgr)
|
||||||
{
|
{
|
||||||
return emgr->busAddr;
|
return emgr->busAddr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
AQH_MSG_ENDPOINT_LIST *AQH_MsgEndpointMgr_GetEndpointList(const AQH_MSG_ENDPOINT_MGR *emgr)
|
AQH_MSG_ENDPOINT_LIST *AQH_MsgEndpointManager_GetEndpointList(const AQH_MSG_ENDPOINT_MGR *emgr)
|
||||||
{
|
{
|
||||||
return emgr->endpointList;
|
return emgr->endpointList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_MsgEndpointMgr_AddEndpoint(AQH_MSG_ENDPOINT_MGR *emgr, AQH_MSG_ENDPOINT *ep)
|
void AQH_MsgEndpointManager_AddEndpoint(AQH_MSG_ENDPOINT_MGR *emgr, AQH_MSG_ENDPOINT *ep)
|
||||||
{
|
{
|
||||||
AQH_MsgEndpoint_List_Add(ep, emgr->endpointList);
|
AQH_MsgEndpoint_List_Add(ep, emgr->endpointList);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_MsgEndpointMgr_DelEndpoint(AQH_MSG_ENDPOINT_MGR *emgr, AQH_MSG_ENDPOINT *ep)
|
void AQH_MsgEndpointManager_DelEndpoint(AQH_MSG_ENDPOINT_MGR *emgr, AQH_MSG_ENDPOINT *ep)
|
||||||
{
|
{
|
||||||
AQH_MsgEndpoint_List_Del(ep);
|
AQH_MsgEndpoint_List_Del(ep);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int AQH_MsgEndpointMgr_LoopOnce(AQH_MSG_ENDPOINT_MGR *emgr)
|
int AQH_MsgEndpointManager_LoopOnce(AQH_MSG_ENDPOINT_MGR *emgr)
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
@@ -175,7 +175,7 @@ int _ioLoopOnce(AQH_MSG_ENDPOINT_MGR *emgr)
|
|||||||
if (rv<0 && rv!=GWEN_ERROR_TRY_AGAIN) {
|
if (rv<0 && rv!=GWEN_ERROR_TRY_AGAIN) {
|
||||||
DBG_DEBUG(AQH_LOGDOMAIN, "error, removing endpoint %s", AQH_MsgEndpoint_GetName(ep));
|
DBG_DEBUG(AQH_LOGDOMAIN, "error, removing endpoint %s", AQH_MsgEndpoint_GetName(ep));
|
||||||
fd=-1;
|
fd=-1;
|
||||||
AQH_MsgEndpointMgr_DelEndpoint(emgr, ep);
|
AQH_MsgEndpointManager_DelEndpoint(emgr, ep);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (fd!=-1 && FD_ISSET(fd, &writeSet)) {
|
if (fd!=-1 && FD_ISSET(fd, &writeSet)) {
|
||||||
@@ -184,7 +184,7 @@ int _ioLoopOnce(AQH_MSG_ENDPOINT_MGR *emgr)
|
|||||||
if (rv<0 && rv!=GWEN_ERROR_TRY_AGAIN) {
|
if (rv<0 && rv!=GWEN_ERROR_TRY_AGAIN) {
|
||||||
DBG_DEBUG(AQH_LOGDOMAIN, "error, removing endpoint %s", AQH_MsgEndpoint_GetName(ep));
|
DBG_DEBUG(AQH_LOGDOMAIN, "error, removing endpoint %s", AQH_MsgEndpoint_GetName(ep));
|
||||||
fd=-1;
|
fd=-1;
|
||||||
AQH_MsgEndpointMgr_DelEndpoint(emgr, ep);
|
AQH_MsgEndpointManager_DelEndpoint(emgr, ep);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ep=epNext;
|
ep=epNext;
|
||||||
|
|||||||
@@ -22,17 +22,17 @@ typedef struct AQH_MSG_ENDPOINT_MGR AQH_MSG_ENDPOINT_MGR;
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
AQHOME_API AQH_MSG_ENDPOINT_MGR *AQH_MsgEndpointMgr_new(uint8_t busAddr);
|
AQHOME_API AQH_MSG_ENDPOINT_MGR *AQH_MsgEndpointManager_new(uint8_t busAddr);
|
||||||
AQHOME_API void AQH_MsgEndpointMgr_free(AQH_MSG_ENDPOINT_MGR *emgr);
|
AQHOME_API void AQH_MsgEndpointManager_free(AQH_MSG_ENDPOINT_MGR *emgr);
|
||||||
|
|
||||||
AQHOME_API uint8_t AQH_MsgEndpointMgr_GetBusAddr(const AQH_MSG_ENDPOINT_MGR *emgr);
|
AQHOME_API uint8_t AQH_MsgEndpointManager_GetBusAddr(const AQH_MSG_ENDPOINT_MGR *emgr);
|
||||||
|
|
||||||
AQHOME_API AQH_MSG_ENDPOINT_LIST *AQH_MsgEndpointMgr_GetEndpointList(const AQH_MSG_ENDPOINT_MGR *emgr);
|
AQHOME_API AQH_MSG_ENDPOINT_LIST *AQH_MsgEndpointManager_GetEndpointList(const AQH_MSG_ENDPOINT_MGR *emgr);
|
||||||
|
|
||||||
AQHOME_API void AQH_MsgEndpointMgr_AddEndpoint(AQH_MSG_ENDPOINT_MGR *emgr, AQH_MSG_ENDPOINT *ep);
|
AQHOME_API void AQH_MsgEndpointManager_AddEndpoint(AQH_MSG_ENDPOINT_MGR *emgr, AQH_MSG_ENDPOINT *ep);
|
||||||
AQHOME_API void AQH_MsgEndpointMgr_DelEndpoint(AQH_MSG_ENDPOINT_MGR *emgr, AQH_MSG_ENDPOINT *ep);
|
AQHOME_API void AQH_MsgEndpointManager_DelEndpoint(AQH_MSG_ENDPOINT_MGR *emgr, AQH_MSG_ENDPOINT *ep);
|
||||||
|
|
||||||
AQHOME_API int AQH_MsgEndpointMgr_LoopOnce(AQH_MSG_ENDPOINT_MGR *emgr);
|
AQHOME_API int AQH_MsgEndpointManager_LoopOnce(AQH_MSG_ENDPOINT_MGR *emgr);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -202,7 +202,7 @@ int _handleReadable(AQH_MSG_ENDPOINT *ep, AQH_MSG_ENDPOINT_MGR *emgr)
|
|||||||
AQH_MsgEndpoint_SetAcceptedMsgGroups(newEp, AQH_MsgEndpoint_GetAcceptedMsgGroups(ep));
|
AQH_MsgEndpoint_SetAcceptedMsgGroups(newEp, AQH_MsgEndpoint_GetAcceptedMsgGroups(ep));
|
||||||
AQH_MsgEndpoint_SetAcceptedEndpointGroups(newEp, AQH_MsgEndpoint_GetAcceptedEndpointGroups(ep));
|
AQH_MsgEndpoint_SetAcceptedEndpointGroups(newEp, AQH_MsgEndpoint_GetAcceptedEndpointGroups(ep));
|
||||||
|
|
||||||
AQH_MsgEndpointMgr_AddEndpoint(emgr, newEp);
|
AQH_MsgEndpointManager_AddEndpoint(emgr, newEp);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user