diff --git a/aqhome/ipc/0BUILD b/aqhome/ipc/0BUILD
index 9ad0683..0ee4359 100644
--- a/aqhome/ipc/0BUILD
+++ b/aqhome/ipc/0BUILD
@@ -47,9 +47,12 @@
endpoint_node_ipc.h
endpoint_node_ipc_tcpd.h
+ endpoint_ipc_tcpc.h
+ endpoint_ipc_tcpc_p.h
msg_ipc.h
msg_ipc_forward.h
msg_ipc_value.h
+ msg_ipc_ping.h
@@ -62,9 +65,11 @@
endpoint_node_ipc.c
endpoint_node_ipc_tcpd.c
+ endpoint_ipc_tcpc.c
msg_ipc.c
msg_ipc_forward.c
msg_ipc_value.c
+ msg_ipc_ping.c
diff --git a/aqhome/ipc/endpoint_ipc_tcpc.c b/aqhome/ipc/endpoint_ipc_tcpc.c
new file mode 100644
index 0000000..7f9fd40
--- /dev/null
+++ b/aqhome/ipc/endpoint_ipc_tcpc.c
@@ -0,0 +1,84 @@
+/****************************************************************************
+ * This file is part of the project AqHome.
+ * AqHome (c) by 2023 Martin Preuss, all rights reserved.
+ *
+ * The license for this file can be found in the file COPYING which you
+ * should have received along with this file.
+ ****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include
+#endif
+
+
+#include "aqhome/ipc/endpoint_ipc_tcpc_p.h"
+
+#include
+#include
+#include
+
+
+
+
+#define AQH_MSG_ENDPOINT_IPCC_NAME "ipc_tcpc"
+
+
+GWEN_INHERIT(GWEN_MSG_ENDPOINT, AQH_ENDPOINT_IPCC)
+
+
+static void GWENHYWFAR_CB _freeData(void *bp, void *p);
+static void _run(GWEN_MSG_ENDPOINT *ep);
+
+
+
+
+
+
+GWEN_MSG_ENDPOINT *AQH_IpcTcpClientEndpoint_new(const char *host, int port, const char *name, int groupId)
+{
+ GWEN_MSG_ENDPOINT *ep;
+ AQH_ENDPOINT_IPCC *xep;
+
+ ep=GWEN_TcpcEndpoint_new(host, port, name?name:AQH_MSG_ENDPOINT_IPCC_NAME, groupId);
+ if (ep==NULL) {
+ DBG_INFO(AQH_LOGDOMAIN, "here");
+ return NULL;
+ }
+ GWEN_IpcEndpoint_Extend(ep);
+
+ GWEN_NEW_OBJECT(AQH_ENDPOINT_IPCC, xep);
+ GWEN_INHERIT_SETDATA(GWEN_MSG_ENDPOINT, AQH_ENDPOINT_IPCC, ep, xep, _freeData);
+
+ xep->previousRunFn=GWEN_MsgEndpoint_SetRunFn(ep, _run);
+
+ return ep;
+}
+
+
+
+void _freeData(void *bp, void *p)
+{
+ AQH_ENDPOINT_IPCC *xep;
+
+ xep=(AQH_ENDPOINT_IPCC*) p;
+ GWEN_FREE_OBJECT(xep);
+}
+
+
+
+void _run(GWEN_MSG_ENDPOINT *ep)
+{
+ AQH_ENDPOINT_IPCC *xep;
+
+ xep=GWEN_INHERIT_GETDATA(GWEN_MSG_ENDPOINT, AQH_ENDPOINT_IPCC, ep);
+ if (xep) {
+ if (xep->previousRunFn)
+ xep->previousRunFn(ep);
+ /* TODO: send CONNECT_REQ message, check for CONNECT_RSP */
+ }
+}
+
+
+
+
+
diff --git a/aqhome/ipc/endpoint_ipc_tcpc.h b/aqhome/ipc/endpoint_ipc_tcpc.h
new file mode 100644
index 0000000..1a7c095
--- /dev/null
+++ b/aqhome/ipc/endpoint_ipc_tcpc.h
@@ -0,0 +1,27 @@
+/****************************************************************************
+ * 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_IPCC_TCPC_H
+#define AQH_ENDPOINT_IPCC_TCPC_H
+
+
+#include
+
+#include
+
+
+
+
+
+
+AQHOME_API GWEN_MSG_ENDPOINT *AQH_IpcTcpClientEndpoint_new(const char *host, int port, const char *name, int groupId);
+
+
+#endif
+
diff --git a/aqhome/ipc/endpoint_ipc_tcpc_p.h b/aqhome/ipc/endpoint_ipc_tcpc_p.h
new file mode 100644
index 0000000..638d662
--- /dev/null
+++ b/aqhome/ipc/endpoint_ipc_tcpc_p.h
@@ -0,0 +1,39 @@
+/****************************************************************************
+ * 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_IPCC_TCPC_P_H
+#define AQH_ENDPOINT_IPCC_TCPC_P_H
+
+
+#include
+
+#include
+
+#include "aqhome/ipc/endpoint_ipc_tcpc.h"
+
+
+typedef struct AQH_ENDPOINT_IPCC AQH_ENDPOINT_IPCC;
+struct AQH_ENDPOINT_IPCC {
+
+ GWEN_MSG_ENDPOINT_RUN_FN previousRunFn;
+};
+
+
+
+
+
+#endif
+
+
+
+
+
+
+
+
+
diff --git a/aqhome/ipc/endpoint_node_ipc_tcpd.c b/aqhome/ipc/endpoint_node_ipc_tcpd.c
index 0357b8c..0afbbe2 100644
--- a/aqhome/ipc/endpoint_node_ipc_tcpd.c
+++ b/aqhome/ipc/endpoint_node_ipc_tcpd.c
@@ -15,6 +15,7 @@
#include "aqhome/ipc/endpoint_node_ipc.h"
#include "aqhome/msg/endpoint_node.h"
#include "aqhome/msg/msg_node.h"
+#include "aqhome/msgmanager.h"
#include
#include
@@ -38,6 +39,7 @@ GWEN_MSG_ENDPOINT *AQH_TcpdIpcNodeEndpoint_new(const char *host, int port, const
GWEN_MSG_ENDPOINT *ep;
ep=GWEN_IpcTcpdEndpoint_new(host, port, name?name:AQH_MSG_ENDPOINT_NODEIPCTCP_NAME, groupId);
+ AQH_NodeEndpoint_Extend(ep);
GWEN_MsgEndpoint_AddFlags(ep, AQH_MSGEP_NODE_FLAGS_NOMESSAGES);
GWEN_MsgEndpoint_SetCreateChildFn(ep, _createChild);
@@ -48,8 +50,13 @@ GWEN_MSG_ENDPOINT *AQH_TcpdIpcNodeEndpoint_new(const char *host, int port, const
GWEN_MSG_ENDPOINT *_createChild(GWEN_MSG_ENDPOINT *ep)
{
+ GWEN_MSG_ENDPOINT *epNew;
+
DBG_INFO(AQH_LOGDOMAIN, "Creating child endpoint for %s", GWEN_MsgEndpoint_GetName(ep));
- return AQH_IpcNodeEndpoint_new(NULL, GWEN_MsgEndpoint_GetGroupId(ep));
+ epNew=AQH_IpcNodeEndpoint_new(NULL, AQH_MSGMGR_ENDPOINTGROUP_IPC);
+ GWEN_MsgEndpoint_AddFlags(epNew, GWEN_MSG_ENDPOINT_FLAGS_DELONDISCONNECT);
+ GWEN_MsgEndpoint_SetAcceptedGroupIds(epNew, GWEN_MsgEndpoint_GetAcceptedGroupIds(ep));
+ return epNew;
}
diff --git a/aqhome/ipc/msg_ipc.h b/aqhome/ipc/msg_ipc.h
index f908564..81091d7 100644
--- a/aqhome/ipc/msg_ipc.h
+++ b/aqhome/ipc/msg_ipc.h
@@ -22,6 +22,7 @@
#define AQH_MSGTYPE_IPC_FORWARD 0x100
#define AQH_MSGTYPE_IPC_VALUE 0x200
+#define AQH_MSGTYPE_IPC_PING 0x300
diff --git a/aqhome/ipc/msg_ipc_forward.c b/aqhome/ipc/msg_ipc_forward.c
index b67e88c..e8d9328 100644
--- a/aqhome/ipc/msg_ipc_forward.c
+++ b/aqhome/ipc/msg_ipc_forward.c
@@ -58,6 +58,12 @@ uint32_t AQH_ForwardIpcMsg_GetMsgLen(const GWEN_MSG *msg)
}
+GWEN_MSG *AQH_ForwardIpcMsg_GetCopyOfNodeMsg(const GWEN_MSG *msg)
+{
+ return GWEN_Msg_fromBytes(AQH_ForwardIpcMsg_GetMsgPtr(msg), AQH_ForwardIpcMsg_GetMsgLen(msg));
+}
+
+
void AQH_ForwardIpcMsg_DumpToBuffer(const GWEN_MSG *msg, GWEN_BUFFER *dbuf, const char *sText)
{
diff --git a/aqhome/ipc/msg_ipc_forward.h b/aqhome/ipc/msg_ipc_forward.h
index c9103b7..64500a5 100644
--- a/aqhome/ipc/msg_ipc_forward.h
+++ b/aqhome/ipc/msg_ipc_forward.h
@@ -22,6 +22,7 @@
AQHOME_API GWEN_MSG *AQH_ForwardIpcMsg_new(uint16_t code, const uint8_t *ptr, uint32_t len);
AQHOME_API const uint8_t *AQH_ForwardIpcMsg_GetMsgPtr(const GWEN_MSG *msg);
AQHOME_API uint32_t AQH_ForwardIpcMsg_GetMsgLen(const GWEN_MSG *msg);
+AQHOME_API GWEN_MSG *AQH_ForwardIpcMsg_GetCopyOfNodeMsg(const GWEN_MSG *msg);
AQHOME_API void AQH_ForwardIpcMsg_DumpToBuffer(const GWEN_MSG *msg, GWEN_BUFFER *dbuf, const char *sText);
diff --git a/aqhome/ipc/msg_ipc_ping.c b/aqhome/ipc/msg_ipc_ping.c
new file mode 100644
index 0000000..50bb250
--- /dev/null
+++ b/aqhome/ipc/msg_ipc_ping.c
@@ -0,0 +1,69 @@
+/****************************************************************************
+ * This file is part of the project AqHome.
+ * AqHome (c) by 2023 Martin Preuss, all rights reserved.
+ *
+ * The license for this file can be found in the file COPYING which you
+ * should have received along with this file.
+ ****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include
+#endif
+
+#include
+
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+
+#define AQH_MSGIPC_PING_OFFS_DESTADDR 0 /* 1 bytes */
+
+#define AQH_MSGIPC_PING_MINSIZE (GWEN_MSGIPC_OFFS_PAYLOAD+1)
+
+
+
+
+GWEN_MSG *AQH_PingIpcMsg_new(uint16_t code, uint8_t destAddr)
+{
+ GWEN_MSG *msg;
+ uint8_t *ptr;
+
+ msg=GWEN_IpcMsg_new(AQH_IPC_PROTOCOL_ID, AQH_IPC_PROTOCOL_VERSION, code, AQH_MSGIPC_PING_MINSIZE, NULL);
+ ptr=GWEN_Msg_GetBuffer(msg);
+ ptr[GWEN_MSGIPC_OFFS_PAYLOAD+AQH_MSGIPC_PING_OFFS_DESTADDR]=destAddr & 0xff;
+
+ return msg;
+}
+
+
+
+uint8_t AQH_PingIpcMsg_GetDestAddr(const GWEN_MSG *msg)
+{
+ return GWEN_Msg_GetUint8At(msg, GWEN_MSGIPC_OFFS_PAYLOAD+AQH_MSGIPC_PING_OFFS_DESTADDR, 0);
+}
+
+
+
+void AQH_PingIpcMsg_DumpToBuffer(const GWEN_MSG *msg, GWEN_BUFFER *dbuf, const char *sText)
+{
+ if (GWEN_Msg_GetBytesInBuffer(msg)>=AQH_MSGIPC_PING_MINSIZE) {
+ GWEN_Buffer_AppendArgs(dbuf,
+ "PING (code=%d, proto=%d, proto version=%d, dest addr=%02x)\n",
+ GWEN_IpcMsg_GetCode(msg),
+ GWEN_IpcMsg_GetProtoId(msg),
+ GWEN_IpcMsg_GetProtoVersion(msg),
+ AQH_PingIpcMsg_GetDestAddr(msg));
+ }
+}
+
+
+
+
+
diff --git a/aqhome/ipc/msg_ipc_ping.h b/aqhome/ipc/msg_ipc_ping.h
new file mode 100644
index 0000000..2b1665e
--- /dev/null
+++ b/aqhome/ipc/msg_ipc_ping.h
@@ -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_IPC_PING_H
+#define AQH_MSG_IPC_PING_H
+
+
+#include
+#include
+
+#include
+#include
+
+
+AQHOME_API GWEN_MSG *AQH_PingIpcMsg_new(uint16_t code, uint8_t destAddr);
+
+AQHOME_API uint8_t AQH_PingIpcMsg_GetDestAddr(const GWEN_MSG *msg);
+
+AQHOME_API void AQH_PingIpcMsg_DumpToBuffer(const GWEN_MSG *msg, GWEN_BUFFER *dbuf, const char *sText);
+
+
+
+#endif
+
+
+
diff --git a/aqhome/ipc/msg_ipc_value.c b/aqhome/ipc/msg_ipc_value.c
index 9b08a88..f4241d9 100644
--- a/aqhome/ipc/msg_ipc_value.c
+++ b/aqhome/ipc/msg_ipc_value.c
@@ -67,65 +67,35 @@ GWEN_MSG *AQH_ValueIpcMsg_new(uint16_t code,
uint32_t AQH_ValueIpcMsg_GetUid(const GWEN_MSG *msg)
{
- if (GWEN_Msg_GetBytesInBuffer(msg)>=AQH_MSGIPC_VALUE_MINSIZE) {
- const uint8_t *ptr;
-
- ptr=GWEN_Msg_GetConstBuffer(msg)+GWEN_MSGIPC_OFFS_PAYLOAD+AQH_MSGIPC_VALUE_OFFS_UID;
- return (uint32_t)(ptr[0])+(ptr[1]<<8)+(ptr[2]<<16)+(ptr[3]<<24);
- }
- return 0;
+ return GWEN_Msg_GetUint32At(msg, GWEN_MSGIPC_OFFS_PAYLOAD+AQH_MSGIPC_VALUE_OFFS_UID, 0);
}
uint8_t AQH_ValueIpcMsg_GetValueId(const GWEN_MSG *msg)
{
- if (GWEN_Msg_GetBytesInBuffer(msg)>=AQH_MSGIPC_VALUE_MINSIZE) {
- const uint8_t *ptr;
-
- ptr=GWEN_Msg_GetConstBuffer(msg)+GWEN_MSGIPC_OFFS_PAYLOAD+AQH_MSGIPC_VALUE_OFFS_VALUEID;
- return (uint8_t)(ptr[0]);
- }
- return 0;
+ return GWEN_Msg_GetUint8At(msg, GWEN_MSGIPC_OFFS_PAYLOAD+AQH_MSGIPC_VALUE_OFFS_VALUEID, 0);
}
uint8_t AQH_ValueIpcMsg_GetValueType(const GWEN_MSG *msg)
{
- if (GWEN_Msg_GetBytesInBuffer(msg)>=AQH_MSGIPC_VALUE_MINSIZE) {
- const uint8_t *ptr;
-
- ptr=GWEN_Msg_GetConstBuffer(msg)+GWEN_MSGIPC_OFFS_PAYLOAD+AQH_MSGIPC_VALUE_OFFS_VALUETYPE;
- return (uint8_t)(ptr[0]);
- }
- return 0;
+ return GWEN_Msg_GetUint8At(msg, GWEN_MSGIPC_OFFS_PAYLOAD+AQH_MSGIPC_VALUE_OFFS_VALUETYPE, 0);
}
int16_t AQH_ValueIpcMsg_GetValueNom(const GWEN_MSG *msg)
{
- if (GWEN_Msg_GetBytesInBuffer(msg)>=AQH_MSGIPC_VALUE_MINSIZE) {
- const uint8_t *ptr;
-
- ptr=GWEN_Msg_GetConstBuffer(msg)+GWEN_MSGIPC_OFFS_PAYLOAD+AQH_MSGIPC_VALUE_OFFS_VALUE_NOM;
- return (int16_t)((uint16_t)((ptr[0])+(ptr[1]<<8)));
- }
- return 0;
+ return GWEN_Msg_GetUint16At(msg, GWEN_MSGIPC_OFFS_PAYLOAD+AQH_MSGIPC_VALUE_OFFS_VALUE_NOM, 0);
}
int16_t AQH_ValueIpcMsg_GetValueDenom(const GWEN_MSG *msg)
{
- if (GWEN_Msg_GetBytesInBuffer(msg)>=AQH_MSGIPC_VALUE_MINSIZE) {
- const uint8_t *ptr;
-
- ptr=GWEN_Msg_GetConstBuffer(msg)+GWEN_MSGIPC_OFFS_PAYLOAD+AQH_MSGIPC_VALUE_OFFS_VALUE_DENOM;
- return (int16_t)((uint16_t)((ptr[0])+(ptr[1]<<8)));
- }
- return 0;
+ return GWEN_Msg_GetUint16At(msg, GWEN_MSGIPC_OFFS_PAYLOAD+AQH_MSGIPC_VALUE_OFFS_VALUE_DENOM, 1);
}
diff --git a/aqhome/libtest.c b/aqhome/libtest.c
index ed74ceb..77a429d 100644
--- a/aqhome/libtest.c
+++ b/aqhome/libtest.c
@@ -9,6 +9,9 @@
#include "aqhome/msg/endpoint_log.h"
#include "aqhome/msg/endpoint_tty.h"
#include "aqhome/ipc/endpoint_node_ipc_tcpd.h"
+#include "aqhome/ipc/endpoint_ipc_tcpc.h"
+#include "aqhome/ipc/msg_ipc_ping.h"
+#include "aqhome/ipc/msg_ipc_forward.h"
#include "aqhome/mqtt/endpoint_mqttc.h"
#include "aqhome/mqtt/msg_mqtt_connect.h"
#include "aqhome/mqtt/msg_mqtt_connack.h"
@@ -265,13 +268,78 @@ int testMqttConnection()
+int testIpcConnection()
+{
+ int rv;
+ GWEN_MSG_ENDPOINT_MGR *emgr;
+ GWEN_MSG_ENDPOINT *epTcp;
+ GWEN_MSG *msgOut;
+
+ rv=AQH_Init();
+ if (rv<0) {
+ }
+
+ //emgr=AQH_MsgManager_new(0xc0);
+ emgr=GWEN_MsgEndpointMgr_new();
+
+ epTcp=AQH_IpcTcpClientEndpoint_new("127.0.0.1", 45454, "IPCClient", 0);
+ if (epTcp==NULL) {
+ DBG_ERROR(NULL, "Error creating endpoint TCPc");
+ return 2;
+ }
+ GWEN_MsgEndpointMgr_AddEndpoint(emgr, epTcp);
+
+ fprintf(stdout, "Sending PING\n");
+ msgOut=AQH_PingIpcMsg_new(AQH_MSGTYPE_IPC_PING, 1);
+ if (msgOut==NULL) {
+ DBG_ERROR(NULL, "Error creating message");
+ return 2;
+ }
+ GWEN_MsgEndpoint_AddSendMessage(epTcp, msgOut);
+
+ fprintf(stdout, "Waiting for response\n");
+ for (;;) {
+ GWEN_MSG *msg;
+
+ DBG_DEBUG(AQH_LOGDOMAIN, "Next loop");
+ //GWEN_MsgManager_LoopOnce(emgr);
+ GWEN_MsgEndpointMgr_RunAllEndpoints(emgr);
+ GWEN_MsgEndpointMgr_IoLoopOnce(emgr);
+ msg=GWEN_MsgEndpoint_TakeFirstReceivedMessage(epTcp);
+ if (msg) {
+ DBG_ERROR(NULL, "Received this message:");
+ GWEN_Text_DumpString((const char*) GWEN_Msg_GetConstBuffer(msg), GWEN_Msg_GetBytesInBuffer(msg), 2);
+ if (GWEN_IpcMsg_GetCode(msg)==AQH_MSGTYPE_IPC_FORWARD) {
+ GWEN_MSG *nodeMsg;
+
+ DBG_ERROR(AQH_LOGDOMAIN, "Received FORWARD msg");
+ nodeMsg=AQH_ForwardIpcMsg_GetCopyOfNodeMsg(msg);
+ if (nodeMsg) {
+ DBG_ERROR(AQH_LOGDOMAIN, "Received node msg (%d)", AQH_NodeMsg_GetMsgType(nodeMsg));
+ if (AQH_NodeMsg_GetMsgType(nodeMsg)==AQH_MSG_TYPE_PONG) {
+ DBG_ERROR(AQH_LOGDOMAIN, "Received PONG");
+ GWEN_Msg_free(msg);
+ break;
+ }
+ }
+ }
+ GWEN_Msg_free(msg);
+ }
+ }
+
+ return 0;
+}
+
+
+
int main(int argc, char **argv)
{
//return testEndpoints();
//return testMsgMqttConnect();
- return testMqttConnection();
+ //return testMqttConnection();
+ return testIpcConnection();
}
diff --git a/aqhome/msg/endpoint_tty.c b/aqhome/msg/endpoint_tty.c
index 61e6f2b..eb96329 100644
--- a/aqhome/msg/endpoint_tty.c
+++ b/aqhome/msg/endpoint_tty.c
@@ -27,8 +27,6 @@
#include
-#define AQH_MSG_ENDPOINT_TTY_NAME "tty"
-
#define AQH_MSG_ENDPOINT_TTY_BAUDRATE B19200
#define AQH_MSG_ENDPOINT_TTY_BYTE_MICROSECS 520
@@ -73,6 +71,8 @@ GWEN_MSG_ENDPOINT *AQH_TtyNodeEndpoint_new(const char *devicePath, int groupId)
GWEN_NEW_OBJECT(AQH_MSG_ENDPOINT_TTY, xep);
GWEN_INHERIT_SETDATA(GWEN_MSG_ENDPOINT, AQH_MSG_ENDPOINT_TTY, ep, xep, _freeData);
+ AQH_NodeEndpoint_SetAcceptedMsgGroups(ep, AQH_MSG_TYPEGROUP_ALL);
+
GWEN_MsgEndpoint_SetHandleReadableFn(ep, _handleReadable);
GWEN_MsgEndpoint_SetHandleWritableFn(ep, _handleWritable);
GWEN_ConnectableMsgEndpoint_SetConnectFn(ep, _connect);
@@ -113,6 +113,7 @@ int _connect(GWEN_MSG_ENDPOINT *ep)
return fd;
}
GWEN_MsgEndpoint_SetFd(ep, fd);
+ GWEN_ConnectableMsgEndpoint_SetState(ep, GWEN_MSG_ENDPOINT_CONN_STATE_CONNECTED);
_attnHigh(ep);
}
return 0;
@@ -137,11 +138,11 @@ int _handleReadable(GWEN_MSG_ENDPOINT *ep, GWEN_UNUSED GWEN_MSG_ENDPOINT_MGR *em
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);
+ DBG_INFO(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()");
+ DBG_INFO(GWEN_LOGDOMAIN, "EOF met on read()");
return GWEN_ERROR_IO;
}
len=rv;
@@ -157,7 +158,7 @@ int _handleReadable(GWEN_MSG_ENDPOINT *ep, GWEN_UNUSED GWEN_MSG_ENDPOINT_MGR *em
}
rv=GWEN_Msg_AddByte(msg, buffer[i]);
if (rv<0) {
- DBG_ERROR(GWEN_LOGDOMAIN, "here (%d)", rv);
+ DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
return rv;
}
rv=AQH_NodeMsg_IsMsgComplete(msg);
@@ -167,7 +168,7 @@ int _handleReadable(GWEN_MSG_ENDPOINT *ep, GWEN_UNUSED GWEN_MSG_ENDPOINT_MGR *em
GWEN_MsgEndpoint_SetCurrentlyReceivedMsg(ep, NULL);
rv=GWEN_MsgEndpoint_DiscardInput(ep);
if (rv<0) {
- DBG_ERROR(GWEN_LOGDOMAIN, "here (%d)", rv);
+ DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
return rv;
}
}
@@ -179,7 +180,7 @@ int _handleReadable(GWEN_MSG_ENDPOINT *ep, GWEN_UNUSED GWEN_MSG_ENDPOINT_MGR *em
GWEN_MsgEndpoint_SetCurrentlyReceivedMsg(ep, NULL);
rv=GWEN_MsgEndpoint_DiscardInput(ep);
if (rv<0) {
- DBG_ERROR(GWEN_LOGDOMAIN, "here (%d)", rv);
+ DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
return rv;
}
}
@@ -200,7 +201,7 @@ int _handleWritable(GWEN_MSG_ENDPOINT *ep, GWEN_UNUSED GWEN_MSG_ENDPOINT_MGR *em
{
GWEN_MSG *msg;
- DBG_DEBUG(GWEN_LOGDOMAIN, "Writing to endpoint %s", GWEN_MsgEndpoint_GetName(ep));
+ DBG_DEBUG(AQH_LOGDOMAIN, "Writing to endpoint %s", GWEN_MsgEndpoint_GetName(ep));
msg=GWEN_MsgEndpoint_GetFirstSendMessage(ep);
if (msg) {
uint8_t pos;
@@ -217,13 +218,13 @@ int _handleWritable(GWEN_MSG_ENDPOINT *ep, GWEN_UNUSED GWEN_MSG_ENDPOINT_MGR *em
/* start new message */
rv=_isLineBusy(ep);
if (rv<0 || rv==1) {
- DBG_ERROR(AQH_LOGDOMAIN, "Line busy, not sending");
+ DBG_INFO(AQH_LOGDOMAIN, "Line busy, not sending");
usleep(100);
return 0;
}
rv=_startMsg(ep);
if (rv<0) {
- DBG_ERROR(AQH_LOGDOMAIN, "here (%d)", rv);
+ DBG_INFO(AQH_LOGDOMAIN, "here (%d)", rv);
return rv;
}
}
@@ -237,7 +238,7 @@ int _handleWritable(GWEN_MSG_ENDPOINT *ep, GWEN_UNUSED GWEN_MSG_ENDPOINT_MGR *em
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);
+ DBG_INFO(GWEN_LOGDOMAIN, "Error on write(): %s (%d)", strerror(errno), errno);
return GWEN_ERROR_IO;
}
GWEN_Msg_IncCurrentPos(msg, rv);
@@ -247,11 +248,14 @@ int _handleWritable(GWEN_MSG_ENDPOINT *ep, GWEN_UNUSED GWEN_MSG_ENDPOINT_MGR *em
GWEN_Msg_List_Del(msg);
GWEN_Msg_free(msg);
if (rv<0) {
- DBG_ERROR(AQH_LOGDOMAIN, "here (%d)", rv);
+ DBG_INFO(AQH_LOGDOMAIN, "here (%d)", rv);
return rv;
}
}
}
+ else {
+ DBG_INFO(AQH_LOGDOMAIN, "No remaining bytes in msg");
+ }
}
return 0;
}
diff --git a/aqhome/msg/endpoint_tty.h b/aqhome/msg/endpoint_tty.h
index 91600b3..a7a47db 100644
--- a/aqhome/msg/endpoint_tty.h
+++ b/aqhome/msg/endpoint_tty.h
@@ -15,6 +15,9 @@
#include
+#define AQH_MSG_ENDPOINT_TTY_NAME "tty"
+
+
AQHOME_API GWEN_MSG_ENDPOINT *AQH_TtyNodeEndpoint_new(const char *devicePath, int groupId);
diff --git a/aqhome/msg/endpointmgr.c b/aqhome/msg/endpointmgr.c
index 5d59a9f..5df57cd 100644
--- a/aqhome/msg/endpointmgr.c
+++ b/aqhome/msg/endpointmgr.c
@@ -56,46 +56,72 @@ void _freeData(void *bp, void *p)
+uint8_t AQH_MsgEndpointMgr_GetBusAddr(GWEN_MSG_ENDPOINT_MGR *emgr)
+{
+ AQH_MSG_ENDPOINT_MGR *xmgr;
+
+ xmgr=GWEN_INHERIT_GETDATA(GWEN_MSG_ENDPOINT_MGR, AQH_MSG_ENDPOINT_MGR, emgr);
+ if (xmgr)
+ return xmgr->busAddr;
+ return 0;
+}
+
+
+
void AQH_MsgEndpointMgr_DistributeMsgFromNodeEndpoint(GWEN_MSG_ENDPOINT_MGR *emgr,
GWEN_MSG_ENDPOINT *srcEp,
const GWEN_MSG *msg,
- int groupId)
+ int groupId,
+ const char *wantedTypeName)
{
GWEN_MSG_ENDPOINT_LIST *endpointList;
endpointList=GWEN_MsgEndpointMgr_GetEndpointList(emgr);
if (endpointList) {
GWEN_MSG_ENDPOINT *ep;
- int acceptedGroupIds;
uint32_t msgGroup;
msgGroup=AQH_NodeMsg_GetMsgGroup(AQH_NodeMsg_GetMsgType(msg));
- acceptedGroupIds=GWEN_MsgEndpoint_GetAcceptedGroupIds(srcEp);
ep=GWEN_MsgEndpoint_List_First(endpointList);
while(ep) {
if (ep!=srcEp) {
- if (acceptedGroupIds & groupId) {
- uint32_t acceptedMsgGroups;
+ const char *epTypeName;
- acceptedMsgGroups=AQH_NodeEndpoint_GetAcceptedMsgGroups(ep);
- DBG_DEBUG(AQH_LOGDOMAIN, "- checking endpoint %s (msgGroup=%08x, accept: %08x, flags: %08x)",
- GWEN_MsgEndpoint_GetName(ep),
- msgGroup, acceptedMsgGroups,
- GWEN_MsgEndpoint_GetFlags(ep));
+ epTypeName=GWEN_MsgEndpoint_GetName(ep);
+ if (wantedTypeName==NULL || (wantedTypeName && epTypeName && strcasecmp(epTypeName, wantedTypeName)==0)) {
+ if (!(GWEN_MsgEndpoint_GetFlags(ep) & AQH_MSGEP_NODE_FLAGS_NOMESSAGES)) {
+ int acceptedGroupIds;
+ uint32_t acceptedMsgGroups;
- if (!(GWEN_MsgEndpoint_GetFlags(ep) & AQH_MSGEP_NODE_FLAGS_NOMESSAGES) &&
- (msgGroup & acceptedMsgGroups)) {
- /* endpoint accepts this message */
- DBG_DEBUG(AQH_LOGDOMAIN, " - endpoint %s accepts message", GWEN_MsgEndpoint_GetName(ep));
- GWEN_MsgEndpoint_ProcessOutMessage(ep, GWEN_Msg_dup(msg));
- }
+ acceptedGroupIds=GWEN_MsgEndpoint_GetAcceptedGroupIds(ep);
+ acceptedMsgGroups=AQH_NodeEndpoint_GetAcceptedMsgGroups(ep);
+
+ DBG_DEBUG(AQH_LOGDOMAIN, "- checking endpoint %s (msgGroup=%08x, accept: %08x, flags: %08x)",
+ GWEN_MsgEndpoint_GetName(ep),
+ msgGroup, acceptedMsgGroups,
+ GWEN_MsgEndpoint_GetFlags(ep));
+ if (acceptedGroupIds & groupId) {
+ if ((msgGroup & acceptedMsgGroups)) {
+ /* endpoint accepts this message */
+ DBG_DEBUG(AQH_LOGDOMAIN, " - endpoint %s accepts message", GWEN_MsgEndpoint_GetName(ep));
+ GWEN_MsgEndpoint_ProcessOutMessage(ep, GWEN_Msg_dup(msg));
+ }
+ else {
+ DBG_DEBUG(AQH_LOGDOMAIN, " - endpoint %s does not accept message", GWEN_MsgEndpoint_GetName(ep));
+ }
+ } /* if (acceptedGroupIds & groupId) */
+ else {
+ DBG_DEBUG(AQH_LOGDOMAIN, "Endpoint %s does not contain groupId %d (%d)",
+ GWEN_MsgEndpoint_GetName(ep), groupId, acceptedGroupIds);
+ }
+ } /* !(GWEN_MsgEndpoint_GetFlags(ep) & AQH_MSGEP_NODE_FLAGS_NOMESSAGES) */
else {
- DBG_DEBUG(AQH_LOGDOMAIN, " - endpoint %s does not accept message", GWEN_MsgEndpoint_GetName(ep));
+ DBG_DEBUG(AQH_LOGDOMAIN, "Not checking endpoint %s (NOMSG set)", epTypeName);
}
- } /* if (srcGroupId & groupId) */
+ } /* if wantedTypeName matches */
else {
- DBG_DEBUG(AQH_LOGDOMAIN, "Endpoint does not contain groupId %d (%02x)", groupId, groupId);
+ DBG_DEBUG(AQH_LOGDOMAIN, "Endpoint %s doesn't match", epTypeName);
}
} /* if (ep!=srcEp) */
ep=GWEN_MsgEndpoint_List_Next(ep);
diff --git a/aqhome/msg/endpointmgr.h b/aqhome/msg/endpointmgr.h
index 7f0b97d..0461d4f 100644
--- a/aqhome/msg/endpointmgr.h
+++ b/aqhome/msg/endpointmgr.h
@@ -18,10 +18,13 @@
AQHOME_API GWEN_MSG_ENDPOINT_MGR *AQH_MsgEndpointMgr_new(uint8_t busAddr);
+AQHOME_API uint8_t AQH_MsgEndpointMgr_GetBusAddr(GWEN_MSG_ENDPOINT_MGR *emgr);
+
AQHOME_API void AQH_MsgEndpointMgr_DistributeMsgFromNodeEndpoint(GWEN_MSG_ENDPOINT_MGR *emgr,
GWEN_MSG_ENDPOINT *srcEp,
const GWEN_MSG *msg,
- int groupId);
+ int groupId,
+ const char *wantedTypeName);
diff --git a/aqhome/msg/msg_claimaddr.c b/aqhome/msg/msg_claimaddr.c
index fb990b3..25085b7 100644
--- a/aqhome/msg/msg_claimaddr.c
+++ b/aqhome/msg/msg_claimaddr.c
@@ -27,14 +27,14 @@
uint32_t AQH_ClaimAddrMsg_GetUid(const GWEN_MSG *msg)
{
- return AQH_NodeMsg_GetUint32At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_CLAIMADDR_UID, 0);
+ return GWEN_Msg_GetUint32At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_CLAIMADDR_UID, 0);
}
uint8_t AQH_ClaimAddrMsg_GetAddress(const GWEN_MSG *msg)
{
- return AQH_NodeMsg_GetUint8At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_CLAIMADDR_ADDR, 0);
+ return GWEN_Msg_GetUint8At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_CLAIMADDR_ADDR, 0);
}
diff --git a/aqhome/msg/msg_denyaddr.c b/aqhome/msg/msg_denyaddr.c
index 2f2ce93..8894a98 100644
--- a/aqhome/msg/msg_denyaddr.c
+++ b/aqhome/msg/msg_denyaddr.c
@@ -28,14 +28,14 @@
uint32_t AQH_DenyAddrMsg_GetUid(const GWEN_MSG *msg)
{
- return AQH_NodeMsg_GetUint32At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_DENYADDR_UID, 0);
+ return GWEN_Msg_GetUint32At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_DENYADDR_UID, 0);
}
uint8_t AQH_DenyAddrMsg_GetAddress(const GWEN_MSG *msg)
{
- return AQH_NodeMsg_GetUint8At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_DENYADDR_ADDR, 0);
+ return GWEN_Msg_GetUint8At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_DENYADDR_ADDR, 0);
}
diff --git a/aqhome/msg/msg_device.c b/aqhome/msg/msg_device.c
index 45f66a0..78ccf1a 100644
--- a/aqhome/msg/msg_device.c
+++ b/aqhome/msg/msg_device.c
@@ -30,35 +30,35 @@
uint32_t AQH_DeviceMsg_GetUid(const GWEN_MSG *msg)
{
- return AQH_NodeMsg_GetUint32At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_DEVICE_UID, 0);
+ return GWEN_Msg_GetUint32At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_DEVICE_UID, 0);
}
uint16_t AQH_DeviceMsg_GetFirmwareType(const GWEN_MSG *msg)
{
- return AQH_NodeMsg_GetUint16At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_DEVICE_FWTYPE, 0);
+ return GWEN_Msg_GetUint16At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_DEVICE_FWTYPE, 0);
}
uint8_t AQH_DeviceMsg_GetFirmwareLow(const GWEN_MSG *msg)
{
- return AQH_NodeMsg_GetUint8At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_DEVICE_FWLOW, 0);
+ return GWEN_Msg_GetUint8At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_DEVICE_FWLOW, 0);
}
uint8_t AQH_DeviceMsg_GetFirmwareHigh(const GWEN_MSG *msg)
{
- return AQH_NodeMsg_GetUint8At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_DEVICE_FWHIGH, 0);
+ return GWEN_Msg_GetUint8At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_DEVICE_FWHIGH, 0);
}
uint16_t AQH_DeviceMsg_GetModuleMask(const GWEN_MSG *msg)
{
- return AQH_NodeMsg_GetUint16At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_DEVICE_MODULES, 0);
+ return GWEN_Msg_GetUint16At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_DEVICE_MODULES, 0);
}
diff --git a/aqhome/msg/msg_haveaddr.c b/aqhome/msg/msg_haveaddr.c
index 13c4467..1ae44b5 100644
--- a/aqhome/msg/msg_haveaddr.c
+++ b/aqhome/msg/msg_haveaddr.c
@@ -27,14 +27,14 @@
uint32_t AQH_HaveAddrMsg_GetUid(const GWEN_MSG *msg)
{
- return AQH_NodeMsg_GetUint32At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_HAVEADDR_UID, 0);
+ return GWEN_Msg_GetUint32At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_HAVEADDR_UID, 0);
}
uint8_t AQH_HaveAddrMsg_GetAddress(const GWEN_MSG *msg)
{
- return AQH_NodeMsg_GetUint8At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_HAVEADDR_ADDR, 0);
+ return GWEN_Msg_GetUint8At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_HAVEADDR_ADDR, 0);
}
diff --git a/aqhome/msg/msg_memstats.c b/aqhome/msg/msg_memstats.c
index 5b594af..3a761be 100644
--- a/aqhome/msg/msg_memstats.c
+++ b/aqhome/msg/msg_memstats.c
@@ -32,41 +32,41 @@
uint32_t AQH_MemStatsMsg_GetUid(const GWEN_MSG *msg)
{
- return AQH_NodeMsg_GetUint32At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_MEMSTATS_UID, 0);
+ return GWEN_Msg_GetUint32At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_MEMSTATS_UID, 0);
}
uint32_t AQH_MemStatsMsg_GetSeconds(const GWEN_MSG *msg)
{
- return AQH_NodeMsg_GetUint32At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_MEMSTATS_SECONDS, 0);
+ return GWEN_Msg_GetUint32At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_MEMSTATS_SECONDS, 0);
}
uint16_t AQH_MemStatsMsg_GetStackUsage(const GWEN_MSG *msg)
{
- return AQH_NodeMsg_GetUint16At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_MEMSTATS_STACKUSAGE, 0);
+ return GWEN_Msg_GetUint16At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_MEMSTATS_STACKUSAGE, 0);
}
uint8_t AQH_MemStatsMsg_GetBuffersUsed(const GWEN_MSG *msg)
{
- return AQH_NodeMsg_GetUint8At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_MEMSTATS_BUFFERSUSED, 0);
+ return GWEN_Msg_GetUint8At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_MEMSTATS_BUFFERSUSED, 0);
}
uint8_t AQH_MemStatsMsg_GetMaxBuffersUsed(const GWEN_MSG *msg)
{
- return AQH_NodeMsg_GetUint8At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_MEMSTATS_MAXBUFFERSUSED, 0);
+ return GWEN_Msg_GetUint8At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_MEMSTATS_MAXBUFFERSUSED, 0);
}
uint16_t AQH_MemStatsMsg_GetRecvNoBufferErrors(const GWEN_MSG *msg)
{
- return AQH_NodeMsg_GetUint16At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_MEMSTATS_RECVNOBUFFER, 0);
+ return GWEN_Msg_GetUint16At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_MEMSTATS_RECVNOBUFFER, 0);
}
diff --git a/aqhome/msg/msg_needaddr.c b/aqhome/msg/msg_needaddr.c
index b5a6827..7bf1e99 100644
--- a/aqhome/msg/msg_needaddr.c
+++ b/aqhome/msg/msg_needaddr.c
@@ -27,7 +27,7 @@
uint32_t AQH_NeedAddrMsg_GetUid(const GWEN_MSG *msg)
{
- return AQH_NodeMsg_GetUint32At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_NEEDADDR_UID, 0);
+ return GWEN_Msg_GetUint32At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_NEEDADDR_UID, 0);
}
diff --git a/aqhome/msg/msg_node.c b/aqhome/msg/msg_node.c
index 5673c70..6d4c1e8 100644
--- a/aqhome/msg/msg_node.c
+++ b/aqhome/msg/msg_node.c
@@ -27,6 +27,33 @@ static uint8_t _calcXorChecksum(const uint8_t *ptr, uint8_t len);
#endif
+
+GWEN_MSG *AQH_NodeMsg_new(uint8_t destAddr, uint8_t srcAddr, uint8_t code, uint8_t payloadLen, const uint8_t *payload)
+{
+ GWEN_MSG *msg;
+ uint32_t len;
+ uint8_t *ptr;
+
+ len=AQH_MSG_OFFS_ALL_DATA_BEGIN+payloadLen+1; /* dest, len, code, src, payload, crc8 */
+ msg=GWEN_Msg_new(len);
+ if (msg==NULL)
+ return NULL;
+ ptr=GWEN_Msg_GetBuffer(msg);
+
+ ptr[AQH_MSG_OFFS_ALL_DEST_ADDRESS]=destAddr & 0xff;
+ ptr[AQH_MSG_OFFS_ALL_PAYLOAD_LEN]=6;
+ ptr[AQH_MSG_OFFS_ALL_MSG_TYPE]=code;
+ ptr[AQH_MSG_OFFS_ALL_SRC_ADDRESS]=srcAddr;
+
+ if (payloadLen && payload)
+ memmove(ptr+AQH_MSG_OFFS_ALL_DATA_BEGIN, payload, payloadLen);
+ GWEN_Msg_SetBytesInBuffer(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+payloadLen);
+ GWEN_Msg_IncCurrentPos(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+payloadLen);
+ return msg;
+}
+
+
+
uint8_t AQH_NodeMsg_GetDestAddress(const GWEN_MSG *msg)
{
if (msg && GWEN_Msg_GetBytesInBuffer(msg)>=AQH_MSG_OFFS_ALL_DATA_BEGIN) {
@@ -142,45 +169,6 @@ int AQH_NodeMsg_AddChecksum(GWEN_MSG *msg)
-uint32_t AQH_NodeMsg_GetUint32At(const GWEN_MSG *msg, int offs, int defaultValue)
-{
- if ((GWEN_Msg_GetBytesInBuffer(msg)>=offs+4)) {
- const uint8_t *ptr;
-
- ptr=GWEN_Msg_GetConstBuffer(msg)+offs;
- return (uint32_t)(ptr[0])+(ptr[1]<<8)+(ptr[2]<<16)+(ptr[3]<<24);
- }
- return defaultValue;
-}
-
-
-
-uint16_t AQH_NodeMsg_GetUint16At(const GWEN_MSG *msg, int offs, int defaultValue)
-{
- if ((GWEN_Msg_GetBytesInBuffer(msg)>=offs+2)) {
- const uint8_t *ptr;
-
- ptr=GWEN_Msg_GetConstBuffer(msg)+offs;
- return (uint16_t)(ptr[0])+(ptr[1]<<8);
- }
- return defaultValue;
-}
-
-
-
-uint8_t AQH_NodeMsg_GetUint8At(const GWEN_MSG *msg, int offs, int defaultValue)
-{
- if ((GWEN_Msg_GetBytesInBuffer(msg)>=offs+1)) {
- const uint8_t *ptr;
-
- ptr=GWEN_Msg_GetConstBuffer(msg)+offs;
- return ptr[0];
- }
- return defaultValue;
-}
-
-
-
void AQH_NodeMsg_DumpToBuffer(const GWEN_MSG *msg, GWEN_BUFFER *dbuf, const char *sText)
{
GWEN_Buffer_AppendArgs(dbuf,
diff --git a/aqhome/msg/msg_node.h b/aqhome/msg/msg_node.h
index ce57bad..c44e267 100644
--- a/aqhome/msg/msg_node.h
+++ b/aqhome/msg/msg_node.h
@@ -58,6 +58,7 @@
#define AQH_MSG_TYPEGROUP_ALL 0xffffffff
+AQHOME_API GWEN_MSG *AQH_NodeMsg_new(uint8_t destAddr, uint8_t srcAddr, uint8_t code, uint8_t payloadLen, const uint8_t *payload);
AQHOME_API uint8_t AQH_NodeMsg_GetDestAddress(const GWEN_MSG *msg);
@@ -71,10 +72,6 @@ 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 uint32_t AQH_NodeMsg_GetUint32At(const GWEN_MSG *msg, int offs, int defaultValue);
-AQHOME_API uint16_t AQH_NodeMsg_GetUint16At(const GWEN_MSG *msg, int offs, int defaultValue);
-AQHOME_API uint8_t AQH_NodeMsg_GetUint8At(const GWEN_MSG *msg, int offs, int defaultValue);
-
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);
diff --git a/aqhome/msg/msg_ping.c b/aqhome/msg/msg_ping.c
index 976c284..b7a5c02 100644
--- a/aqhome/msg/msg_ping.c
+++ b/aqhome/msg/msg_ping.c
@@ -11,22 +11,53 @@
#endif
#include "aqhome/msg/msg_ping.h"
+#include "aqhome/msg/msg_node.h"
#include
#include
#include
#include
+#include
+
#define AQH_MSG_OFFS_PING_TIMESTAMP 0
-#define AQH_MSG_PING_MINSIZE (AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_PING_TIMESTAMP+4)
+#define AQH_MSG_PING_MINSIZE (AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_PING_TIMESTAMP+4+1)
+
+
+
+
+GWEN_MSG *AQH_PingMsg_new(uint8_t srcAddr, uint8_t destAddr, uint8_t code)
+{
+ GWEN_MSG *msg;
+ uint8_t *ptr;
+ int rv;
+
+ msg=AQH_NodeMsg_new(destAddr, srcAddr, code, 4, NULL);
+ ptr=GWEN_Msg_GetBuffer(msg)+AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_PING_TIMESTAMP;
+ *(ptr++)=0; /* timestamp */
+ *(ptr++)=0;
+ *(ptr++)=0;
+ *ptr=0;
+
+ GWEN_Msg_IncCurrentPos(msg, 4);
+
+ rv=AQH_NodeMsg_AddChecksum(msg);
+ if (rv<0) {
+ DBG_INFO(AQH_LOGDOMAIN, "here (%d)", rv);
+ GWEN_Msg_free(msg);
+ return NULL;
+ }
+
+ return msg;
+}
uint32_t AQH_PingMsg_GetTimestamp(const GWEN_MSG *msg)
{
- return AQH_NodeMsg_GetUint32At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_PING_TIMESTAMP, 0);
+ return GWEN_Msg_GetUint32At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_PING_TIMESTAMP, 0);
}
diff --git a/aqhome/msg/msg_ping.h b/aqhome/msg/msg_ping.h
index c4b9dde..218ca59 100644
--- a/aqhome/msg/msg_ping.h
+++ b/aqhome/msg/msg_ping.h
@@ -17,6 +17,7 @@
#include
+AQHOME_API GWEN_MSG *AQH_PingMsg_new(uint8_t code, uint8_t srcAddr, uint8_t destAddr);
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);
diff --git a/aqhome/msg/msg_pong.c b/aqhome/msg/msg_pong.c
index 2ff9289..a8e898b 100644
--- a/aqhome/msg/msg_pong.c
+++ b/aqhome/msg/msg_pong.c
@@ -26,7 +26,7 @@
uint32_t AQH_PongMsg_GetTimestamp(const GWEN_MSG *msg)
{
- return AQH_NodeMsg_GetUint32At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_PONG_TIMESTAMP, 0);
+ return GWEN_Msg_GetUint32At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_PONG_TIMESTAMP, 0);
}
diff --git a/aqhome/msg/msg_recvstats.c b/aqhome/msg/msg_recvstats.c
index 297d63a..3395a18 100644
--- a/aqhome/msg/msg_recvstats.c
+++ b/aqhome/msg/msg_recvstats.c
@@ -33,49 +33,49 @@
uint32_t AQH_RecvStatsMsg_GetUid(const GWEN_MSG *msg)
{
- return AQH_NodeMsg_GetUint32At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_RECVSTATS_UID, 0);
+ return GWEN_Msg_GetUint32At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_RECVSTATS_UID, 0);
}
uint16_t AQH_RecvStatsMsg_GetPacketsIn(const GWEN_MSG *msg)
{
- return AQH_NodeMsg_GetUint16At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_RECVSTATS_PACKETSIN, 0);
+ return GWEN_Msg_GetUint16At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_RECVSTATS_PACKETSIN, 0);
}
uint16_t AQH_RecvStatsMsg_GetCrcErrors(const GWEN_MSG *msg)
{
- return AQH_NodeMsg_GetUint16At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_RECVSTATS_CRCERRORS, 0);
+ return GWEN_Msg_GetUint16At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_RECVSTATS_CRCERRORS, 0);
}
uint16_t AQH_RecvStatsMsg_GetIoErrors(const GWEN_MSG *msg)
{
- return AQH_NodeMsg_GetUint16At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_RECVSTATS_IOERRORS, 0);
+ return GWEN_Msg_GetUint16At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_RECVSTATS_IOERRORS, 0);
}
uint16_t AQH_RecvStatsMsg_GetNoBufferErrors(const GWEN_MSG *msg)
{
- return AQH_NodeMsg_GetUint16At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_RECVSTATS_NOBUFFER, 0);
+ return GWEN_Msg_GetUint16At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_RECVSTATS_NOBUFFER, 0);
}
uint16_t AQH_RecvStatsMsg_GetHandled(const GWEN_MSG *msg)
{
- return AQH_NodeMsg_GetUint16At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_RECVSTATS_HANDLED, 0);
+ return GWEN_Msg_GetUint16At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_RECVSTATS_HANDLED, 0);
}
uint16_t AQH_RecvStatsMsg_GetMissed(const GWEN_MSG *msg)
{
- return AQH_NodeMsg_GetUint16At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_RECVSTATS_MISSED, 0);
+ return GWEN_Msg_GetUint16At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_RECVSTATS_MISSED, 0);
}
diff --git a/aqhome/msg/msg_sendstats.c b/aqhome/msg/msg_sendstats.c
index 7cc184d..33c9765 100644
--- a/aqhome/msg/msg_sendstats.c
+++ b/aqhome/msg/msg_sendstats.c
@@ -29,28 +29,28 @@
uint32_t AQH_SendStatsMsg_GetUid(const GWEN_MSG *msg)
{
- return AQH_NodeMsg_GetUint32At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_SENDSTATS_UID, 0);
+ return GWEN_Msg_GetUint32At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_SENDSTATS_UID, 0);
}
uint16_t AQH_SendStatsMsg_GetPacketsOut(const GWEN_MSG *msg)
{
- return AQH_NodeMsg_GetUint16At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_SENDSTATS_PACKETSOUT, 0);
+ return GWEN_Msg_GetUint16At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_SENDSTATS_PACKETSOUT, 0);
}
uint16_t AQH_SendStatsMsg_GetCollisions(const GWEN_MSG *msg)
{
- return AQH_NodeMsg_GetUint16At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_SENDSTATS_COLLISIONS, 0);
+ return GWEN_Msg_GetUint16At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_SENDSTATS_COLLISIONS, 0);
}
uint16_t AQH_SendStatsMsg_GetBusyErrors(const GWEN_MSG *msg)
{
- return AQH_NodeMsg_GetUint16At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_SENDSTATS_BUSY, 0);
+ return GWEN_Msg_GetUint16At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_SENDSTATS_BUSY, 0);
}
diff --git a/aqhome/msg/msg_sysstats.c b/aqhome/msg/msg_sysstats.c
index 203aea9..b5e15fc 100644
--- a/aqhome/msg/msg_sysstats.c
+++ b/aqhome/msg/msg_sysstats.c
@@ -30,27 +30,27 @@
uint32_t AQH_SysStatsMsg_GetUid(const GWEN_MSG *msg)
{
- return AQH_NodeMsg_GetUint32At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_SYSSTATS_UID, 0);
+ return GWEN_Msg_GetUint32At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_SYSSTATS_UID, 0);
}
uint32_t AQH_SysStatsMsg_GetSeconds(const GWEN_MSG *msg)
{
- return AQH_NodeMsg_GetUint32At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_SYSSTATS_SECONDS, 0);
+ return GWEN_Msg_GetUint32At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_SYSSTATS_SECONDS, 0);
}
uint16_t AQH_SysStatsMsg_GetComInterrupts(const GWEN_MSG *msg)
{
- return AQH_NodeMsg_GetUint16At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_SYSSTATS_COMIRQS, 0);
+ return GWEN_Msg_GetUint16At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_SYSSTATS_COMIRQS, 0);
}
uint16_t AQH_SysStatsMsg_GetTimerInterrupts(const GWEN_MSG *msg)
{
- return AQH_NodeMsg_GetUint16At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_SYSSTATS_TIMERIRQS, 0);
+ return GWEN_Msg_GetUint16At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_SYSSTATS_TIMERIRQS, 0);
}
diff --git a/aqhome/msg/msg_value.c b/aqhome/msg/msg_value.c
index bb2a0fa..12306cc 100644
--- a/aqhome/msg/msg_value.c
+++ b/aqhome/msg/msg_value.c
@@ -22,21 +22,21 @@
uint32_t AQH_ValueMsg_GetTimestamp(const GWEN_MSG *msg)
{
- return AQH_NodeMsg_GetUint32At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_VALUE_TIMESTAMP, 0);
+ return GWEN_Msg_GetUint32At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_VALUE_TIMESTAMP, 0);
}
uint8_t AQH_ValueMsg_GetValueId(const GWEN_MSG *msg)
{
- return AQH_NodeMsg_GetUint8At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_VALUE_VALUEID, 0);
+ return GWEN_Msg_GetUint8At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_VALUE_VALUEID, 0);
}
uint8_t AQH_ValueMsg_GetValueType(const GWEN_MSG *msg)
{
- return AQH_NodeMsg_GetUint8At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_VALUE_VALUETYPE, 0);
+ return GWEN_Msg_GetUint8At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_VALUE_VALUETYPE, 0);
}
diff --git a/aqhome/msg/msg_value2.c b/aqhome/msg/msg_value2.c
index d7b01c6..d6c9274 100644
--- a/aqhome/msg/msg_value2.c
+++ b/aqhome/msg/msg_value2.c
@@ -31,35 +31,35 @@
uint32_t AQH_Value2Msg_GetUid(const GWEN_MSG *msg)
{
- return AQH_NodeMsg_GetUint32At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_VALUE2_UID, 0);
+ return GWEN_Msg_GetUint32At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_VALUE2_UID, 0);
}
uint8_t AQH_Value2Msg_GetValueId(const GWEN_MSG *msg)
{
- return AQH_NodeMsg_GetUint8At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_VALUE2_VALUEID, 0);
+ return GWEN_Msg_GetUint8At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_VALUE2_VALUEID, 0);
}
uint8_t AQH_Value2Msg_GetValueType(const GWEN_MSG *msg)
{
- return AQH_NodeMsg_GetUint8At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_VALUE2_VALUETYPE, 0);
+ return GWEN_Msg_GetUint8At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_VALUE2_VALUETYPE, 0);
}
int16_t AQH_Value2Msg_GetValueNom(const GWEN_MSG *msg)
{
- return (int16_t) AQH_NodeMsg_GetUint16At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_VALUE2_VALUE, 0);
+ return (int16_t) GWEN_Msg_GetUint16At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_VALUE2_VALUE, 0);
}
int16_t AQH_Value2Msg_GetValueDenom(const GWEN_MSG *msg)
{
- return (int16_t) AQH_NodeMsg_GetUint16At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_VALUE2_DENOM, 0);
+ return (int16_t) GWEN_Msg_GetUint16At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_VALUE2_DENOM, 0);
}
diff --git a/aqhome/msgmanager.c b/aqhome/msgmanager.c
index 3c1d0fb..e561133 100644
--- a/aqhome/msgmanager.c
+++ b/aqhome/msgmanager.c
@@ -21,10 +21,15 @@
#include "aqhome/msg/msg_claimaddr.h"
#include "aqhome/msg/msg_haveaddr.h"
#include "aqhome/msg/msg_device.h"
+#include "aqhome/msg/msg_ping.h"
+#include "aqhome/msg/endpoint_tty.h"
#include "aqhome/mqtt/endpoint_mqttc.h"
+#include "aqhome/ipc/msg_ipc.h"
+#include "aqhome/ipc/msg_ipc_ping.h"
#include
#include
+#include
#include
#include
@@ -46,6 +51,9 @@ static void _handleMsgHaveAddress(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ENDPOINT
static void _handleMsgComSendStat(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ENDPOINT *ep, const GWEN_MSG *msg);
static void _handleMsgComRecvStat(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ENDPOINT *ep, const GWEN_MSG *msg);
static void _handleMsgDevice(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ENDPOINT *ep, const GWEN_MSG *msg);
+
+static void _handleIpcMsgPing(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ENDPOINT *ep, const GWEN_MSG *msg);
+
static AQH_NODE_INFO *_getOrCreateNodeAndUpdateUidAddr(GWEN_MSG_ENDPOINT_MGR *emgr, const GWEN_MSG *msg, uint32_t uid);
@@ -200,7 +208,7 @@ void _handleNodeMsg(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ENDPOINT *ep, const GW
AQH_NodeMsg_GetMsgType(msg), AQH_NodeMsg_GetSourceAddress(msg), AQH_NodeMsg_GetDestAddress(msg));
- AQH_MsgEndpointMgr_DistributeMsgFromNodeEndpoint(emgr, ep, msg, AQH_MSGMGR_ENDPOINTGROUP_NODE);
+ AQH_MsgEndpointMgr_DistributeMsgFromNodeEndpoint(emgr, ep, msg, AQH_MSGMGR_ENDPOINTGROUP_NODE, NULL);
msgIsValid=(AQH_NodeMsg_IsChecksumValid(msg) && AQH_NodeMsg_IsMsgComplete(msg));
msgType=AQH_NodeMsg_GetMsgType(msg);
@@ -223,7 +231,15 @@ void _handleNodeMsg(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ENDPOINT *ep, const GW
void _handleIpcMsg(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ENDPOINT *ep, const GWEN_MSG *msg)
{
+ uint16_t code;
+
/* exec IPC message */
+ code=GWEN_IpcMsg_GetCode(msg);
+ DBG_ERROR(AQH_LOGDOMAIN, "Received IPC packet");
+ switch(code) {
+ case AQH_MSGTYPE_IPC_PING: _handleIpcMsgPing(emgr, ep, msg); break;
+ default: break;
+ }
}
@@ -235,6 +251,20 @@ void _handleMqttMsg(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ENDPOINT *ep, const GW
+void _handleIpcMsgPing(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ENDPOINT *ep, const GWEN_MSG *msg)
+{
+ GWEN_MSG *msgOut;
+
+ DBG_ERROR(AQH_LOGDOMAIN, "Received IPC PING message");
+ msgOut=AQH_PingMsg_new(AQH_MsgEndpointMgr_GetBusAddr(emgr),
+ AQH_PingIpcMsg_GetDestAddr(msg),
+ AQH_MSG_TYPE_PING);
+ AQH_MsgEndpointMgr_DistributeMsgFromNodeEndpoint(emgr, ep, msgOut, AQH_MSGMGR_ENDPOINTGROUP_NODE, AQH_MSG_ENDPOINT_TTY_NAME);
+ GWEN_Msg_free(msgOut);
+}
+
+
+
void _handleMsgValue2(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ENDPOINT *ep, const GWEN_MSG *msg)
{
AQH_MSG_MANAGER *xmgr;
diff --git a/aqhomed.sh b/aqhomed.sh
index b11f266..6b0f0b6 100644
--- a/aqhomed.sh
+++ b/aqhomed.sh
@@ -1,4 +1,4 @@
# AQHOME_LOGLEVEL=info LD_LIBRARY_PATH="../../aqhome/:$LD_LIBRARY_PATH" ./aqhomed -l aqhome.log -db aqhome.db -ma 127.0.0.1
-AQHOME_LOGLEVEL=info LD_LIBRARY_PATH="../../aqhome/:$LD_LIBRARY_PATH" ./aqhomed -l aqhome.log -db aqhome.db -ma 192.168.117.192 -mp 1883
+AQHOME_LOGLEVEL=info LD_LIBRARY_PATH="../../aqhome/:$LD_LIBRARY_PATH" ./aqhomed -l aqhome.log -db aqhome.db -ma 192.168.117.192 -mp 1883 -t 127.0.0.1