aqhome: completed adapting to msgio2 interface.
This commit is contained in:
@@ -38,6 +38,10 @@
|
||||
init.h
|
||||
fini.h
|
||||
loop.h
|
||||
loop_tty.h
|
||||
loop_tty_ipc.h
|
||||
loop_tty_mqtt.h
|
||||
loop_ipc.h
|
||||
db.h
|
||||
tty_log.h
|
||||
tty_write.h
|
||||
@@ -50,6 +54,10 @@
|
||||
init.c
|
||||
fini.c
|
||||
loop.c
|
||||
loop_tty.c
|
||||
loop_tty_ipc.c
|
||||
loop_tty_mqtt.c
|
||||
loop_ipc.c
|
||||
db.c
|
||||
tty_log.c
|
||||
tty_write.c
|
||||
|
||||
@@ -74,6 +74,7 @@ void AqHomed_free(AQHOMED *aqh)
|
||||
free(aqh->writeFolder);
|
||||
free(aqh->pidFile);
|
||||
free(aqh->dbFile);
|
||||
free(aqh->mqttTopicPrefix);
|
||||
|
||||
GWEN_FREE_OBJECT(aqh);
|
||||
}
|
||||
@@ -177,7 +178,20 @@ void AqHomed_SetDbFile(AQHOMED *aqh, const char *s)
|
||||
|
||||
|
||||
|
||||
|
||||
const char *AqHomed_GetMqttTopicPrefix(const AQHOMED *aqh)
|
||||
{
|
||||
return aqh?aqh->mqttTopicPrefix:NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void AqHomed_SetMqttTopicPrefix(AQHOMED *aqh, const char *s)
|
||||
{
|
||||
if (aqh) {
|
||||
free(aqh->mqttTopicPrefix);
|
||||
aqh->mqttTopicPrefix=s?strdup(s):NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -42,6 +42,8 @@ void AqHomed_SetPidFile(AQHOMED *aqh, const char *s);
|
||||
const char *AqHomed_GetDbFile(const AQHOMED *aqh);
|
||||
void AqHomed_SetDbFile(AQHOMED *aqh, const char *s);
|
||||
|
||||
const char *AqHomed_GetMqttTopicPrefix(const AQHOMED *aqh);
|
||||
void AqHomed_SetMqttTopicPrefix(AQHOMED *aqh, const char *s);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -44,6 +44,7 @@ struct AQHOMED {
|
||||
char *pidFile;
|
||||
|
||||
int nodeAddress;
|
||||
char *mqttTopicPrefix;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -185,6 +185,7 @@ void _setupMqtt(AQHOMED *aqh, GWEN_DB_NODE *dbArgs)
|
||||
int rv;
|
||||
|
||||
ep=AQH_MqttClientEndpoint2_new(mqttClientId, mqttAddress, mqttPort, NULL, AQHOME_ENDPOINTGROUP_MQTT);
|
||||
AqHomed_SetMqttTopicPrefix(aqh, mqttTopicPrefix);
|
||||
AQH_MqttClientEndpoint2_SetTopicPrefix(ep, mqttTopicPrefix);
|
||||
AQH_MqttClientEndpoint2_SetKeepAliveTime(ep, mqttKeepAlive);
|
||||
|
||||
|
||||
23
apps/aqhomed/ipc.h
Normal file
23
apps/aqhomed/ipc.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 AQHOMED_LOOP_IPC_H
|
||||
#define AQHOMED_LOOP_IPC_H
|
||||
|
||||
|
||||
#include "./aqhomed.h"
|
||||
|
||||
|
||||
|
||||
void AqHomed_ForwardTtyMsgToIpcClients(AQHOMED *aqh, const GWEN_MSG *msg);
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
|
||||
|
||||
#include "./loop.h"
|
||||
#include "./loop_tty.h"
|
||||
#include "./loop_ipc.h"
|
||||
#include "./aqhomed_p.h"
|
||||
#include "./tty_log.h"
|
||||
#include "./tty_write.h"
|
||||
@@ -47,11 +49,6 @@
|
||||
* ------------------------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static void _readTtyMessages(AQHOMED *aqh);
|
||||
static void _handleTtyMsg(AQHOMED *aqh, const GWEN_MSG *msg);
|
||||
static void _forwardTtyMsgToIpcClients(AQHOMED *aqh, const GWEN_MSG *msg);
|
||||
static void _forwardValue2MsgToIpc(GWEN_MSG_ENDPOINT2 *ep, const GWEN_MSG *nodeMsg);
|
||||
static void _forwardAnyMsgToIpc(GWEN_MSG_ENDPOINT2 *ep, const GWEN_MSG *nodeMsg);
|
||||
|
||||
|
||||
|
||||
@@ -64,7 +61,8 @@ void AqHomed_Loop(AQHOMED *aqh, int timeoutInMsecs)
|
||||
{
|
||||
if (aqh) {
|
||||
GWEN_MsgEndpoint2_ChildrenIoLoop(aqh->rootEndpoint, timeoutInMsecs);
|
||||
_readTtyMessages(aqh);
|
||||
AqHomed_ReadAndHandleTtyMessages(aqh);
|
||||
AqHomed_ReadAndHandleIpcMessages(aqh);
|
||||
|
||||
if (AQH_NodeDb_IsModified(aqh->nodeDb)) {
|
||||
if (aqh->dbFile) {
|
||||
@@ -81,88 +79,3 @@ void AqHomed_Loop(AQHOMED *aqh, int timeoutInMsecs)
|
||||
|
||||
|
||||
|
||||
void _readTtyMessages(AQHOMED *aqh)
|
||||
{
|
||||
GWEN_MSG *msg;
|
||||
|
||||
while( (msg=GWEN_MsgEndpoint2_TakeFirstReceivedMessage(aqh->ttyEndpoint)) ) {
|
||||
_handleTtyMsg(aqh, msg);
|
||||
GWEN_Msg_free(msg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void _handleTtyMsg(AQHOMED *aqh, const GWEN_MSG *msg)
|
||||
{
|
||||
if (aqh->logFile)
|
||||
AqHomed_LogTtyMsg(aqh, msg);
|
||||
if (aqh->writeFolder)
|
||||
AqHomed_WriteTtyMsg(aqh, msg);
|
||||
if (aqh->nodeDb)
|
||||
AqHomed_NodeMsgToDb(aqh, msg);
|
||||
if (aqh->ipcdEndpoint)
|
||||
_forwardTtyMsgToIpcClients(aqh, msg);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void _forwardTtyMsgToIpcClients(AQHOMED *aqh, const GWEN_MSG *msg)
|
||||
{
|
||||
uint32_t msgGroup;
|
||||
|
||||
msgGroup=AQH_NodeMsg_GetMsgGroup(AQH_NodeMsg_GetMsgType(msg));
|
||||
if (msgGroup) {
|
||||
GWEN_MSG_ENDPOINT2 *ep;
|
||||
|
||||
ep=GWEN_MsgEndpoint2_Tree2_GetFirstChild(aqh->ipcdEndpoint);
|
||||
while(ep) {
|
||||
if (msgGroup & AQH_IpcEndpoint2_GetAcceptedMsgGroups(ep)) {
|
||||
DBG_INFO(NULL, "Endpoint accepts msg group %d", msgGroup);
|
||||
switch(AQH_NodeMsg_GetMsgType(msg)) {
|
||||
case AQH_MSG_TYPE_VALUE2:
|
||||
_forwardValue2MsgToIpc(ep, msg);
|
||||
break;
|
||||
default:
|
||||
_forwardAnyMsgToIpc(ep, msg);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
ep=GWEN_MsgEndpoint2_Tree2_GetNext(ep);
|
||||
}
|
||||
}
|
||||
else {
|
||||
DBG_ERROR(NULL, "Message type %d not in any message group, ignoring message", AQH_NodeMsg_GetMsgType(msg));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void _forwardValue2MsgToIpc(GWEN_MSG_ENDPOINT2 *ep, const GWEN_MSG *nodeMsg)
|
||||
{
|
||||
GWEN_MSG *ipcMsg;
|
||||
|
||||
ipcMsg=AQH_ValueIpcMsg_new(AQH_MSGTYPE_IPC_VALUE,
|
||||
AQH_Value2Msg_GetUid(nodeMsg),
|
||||
AQH_Value2Msg_GetValueId(nodeMsg),
|
||||
AQH_Value2Msg_GetValueType(nodeMsg),
|
||||
AQH_Value2Msg_GetValueNom(nodeMsg),
|
||||
AQH_Value2Msg_GetValueDenom(nodeMsg));
|
||||
GWEN_MsgEndpoint2_AddSendMessage(ep, ipcMsg);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void _forwardAnyMsgToIpc(GWEN_MSG_ENDPOINT2 *ep, const GWEN_MSG *nodeMsg)
|
||||
{
|
||||
GWEN_MSG *ipcMsg;
|
||||
|
||||
ipcMsg=AQH_ForwardIpcMsg_new(AQH_MSGTYPE_IPC_FORWARD, GWEN_Msg_GetConstBuffer(nodeMsg), GWEN_Msg_GetBytesInBuffer(nodeMsg));
|
||||
GWEN_MsgEndpoint2_AddSendMessage(ep, ipcMsg);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
188
apps/aqhomed/loop_ipc.c
Normal file
188
apps/aqhomed/loop_ipc.c
Normal file
@@ -0,0 +1,188 @@
|
||||
/****************************************************************************
|
||||
* This file is part of the project AqHome.
|
||||
* AqHome (c) by 2023 Martin Preuss, all rights reserved.
|
||||
*
|
||||
* The license for this file can be found in the file COPYING which you
|
||||
* should have received along with this file.
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
|
||||
#include "./loop_ipc.h"
|
||||
#include "./aqhomed_p.h"
|
||||
#include "./tty_log.h"
|
||||
#include "./tty_write.h"
|
||||
#include "./db.h"
|
||||
|
||||
#include "aqhome/msg/endpoint2_tty.h"
|
||||
#include "aqhome/msg/msg_node.h"
|
||||
#include "aqhome/msg/msg_value2.h"
|
||||
#include "aqhome/msg/msg_ping.h"
|
||||
#include "aqhome/ipc/endpoint2_ipc.h"
|
||||
#include "aqhome/ipc/msg_ipc.h"
|
||||
#include "aqhome/ipc/msg_ipc_forward.h"
|
||||
#include "aqhome/ipc/msg_ipc_value.h"
|
||||
#include "aqhome/ipc/msg_ipc_ping.h"
|
||||
#include "aqhome/ipc/msg_ipc_setaccmsggrps.h"
|
||||
#include "aqhome/ipc/msg_ipc_getdevices_rsp.h"
|
||||
#include "aqhome/ipc/msg_ipc_error.h"
|
||||
|
||||
#include <gwenhywfar/gwenhywfar.h>
|
||||
#include <gwenhywfar/args.h>
|
||||
#include <gwenhywfar/debug.h>
|
||||
#include <gwenhywfar/endpoint2_tcpd.h>
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* defines
|
||||
* ------------------------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#define I18N(msg) msg
|
||||
#define I18S(msg) msg
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* forward declarations
|
||||
* ------------------------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static void _handleIpcEndpoint(AQHOMED *aqh, GWEN_MSG_ENDPOINT2 *ep);
|
||||
static void _handleIpcMsg(AQHOMED *aqh, GWEN_MSG_ENDPOINT2 *ep, const GWEN_MSG *msg);
|
||||
void _handleIpcMsgPing(AQHOMED *aqh, GWEN_MSG_ENDPOINT2 *ep, const GWEN_MSG *msg);
|
||||
void _handleIpcMsgSetAccMsgGrps(AQHOMED *aqh, GWEN_MSG_ENDPOINT2 *ep, const GWEN_MSG *msg);
|
||||
void _handleIpcMsgForward(AQHOMED *aqh, GWEN_MSG_ENDPOINT2 *ep, const GWEN_MSG *msg);
|
||||
void _handleIpcMsgGetDevicesReq(AQHOMED *aqh, GWEN_MSG_ENDPOINT2 *ep, const GWEN_MSG *msg);
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* implementations
|
||||
* ------------------------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
void AqHomed_ReadAndHandleIpcMessages(AQHOMED *aqh)
|
||||
{
|
||||
if (aqh->ipcdEndpoint) {
|
||||
GWEN_MSG_ENDPOINT2 *ep;
|
||||
|
||||
ep=GWEN_MsgEndpoint2_Tree2_GetFirstChild(aqh->ipcdEndpoint);
|
||||
while(ep) {
|
||||
_handleIpcEndpoint(aqh, ep);
|
||||
ep=GWEN_MsgEndpoint2_Tree2_GetNext(ep);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void _handleIpcEndpoint(AQHOMED *aqh, GWEN_MSG_ENDPOINT2 *ep)
|
||||
{
|
||||
GWEN_MSG *msg;
|
||||
|
||||
while( (msg=GWEN_MsgEndpoint2_TakeFirstReceivedMessage(ep)) ) {
|
||||
_handleIpcMsg(aqh, ep, msg);
|
||||
GWEN_Msg_free(msg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void _handleIpcMsg(AQHOMED *aqh, GWEN_MSG_ENDPOINT2 *ep, const GWEN_MSG *msg)
|
||||
{
|
||||
uint16_t code;
|
||||
|
||||
/* exec IPC message */
|
||||
code=GWEN_IpcMsg_GetCode(msg);
|
||||
DBG_ERROR(AQH_LOGDOMAIN, "Received IPC packet");
|
||||
switch(code) {
|
||||
case AQH_MSGTYPE_IPC_PING: _handleIpcMsgPing(aqh, ep, msg); break;
|
||||
case AQH_MSGTYPE_IPC_SETACCMSGGRPS: _handleIpcMsgSetAccMsgGrps(aqh, ep, msg); break;
|
||||
case AQH_MSGTYPE_IPC_FORWARD: _handleIpcMsgForward(aqh, ep, msg); break;
|
||||
case AQH_MSGTYPE_IPC_GETDEVICES_REQ: _handleIpcMsgGetDevicesReq(aqh, ep, msg); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void _handleIpcMsgPing(AQHOMED *aqh, GWEN_MSG_ENDPOINT2 *ep, const GWEN_MSG *msg)
|
||||
{
|
||||
if (aqh->ttyEndpoint && GWEN_MsgEndpoint2_GetState(aqh->ttyEndpoint)==GWEN_MSG_ENDPOINT_STATE_CONNECTED) {
|
||||
GWEN_MSG *msgOut;
|
||||
|
||||
DBG_ERROR(AQH_LOGDOMAIN, "Received IPC PING message");
|
||||
msgOut=AQH_PingMsg_new(aqh->nodeAddress, AQH_PingIpcMsg_GetDestAddr(msg), AQH_MSG_TYPE_PING);
|
||||
GWEN_MsgEndpoint2_AddSendMessage(aqh->ttyEndpoint, msgOut);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void _handleIpcMsgSetAccMsgGrps(AQHOMED *aqh, GWEN_MSG_ENDPOINT2 *ep, const GWEN_MSG *msg)
|
||||
{
|
||||
uint32_t groups;
|
||||
|
||||
DBG_ERROR(AQH_LOGDOMAIN, "Received IPC SET_ACCEPTED_MSG_GROUPS message");
|
||||
groups=AQH_SetAcceptedMsgGroupsIpcMsg_GetMsgGroups(msg);
|
||||
AQH_IpcEndpoint2_SetAcceptedMsgGroups(ep, groups);
|
||||
// TODO: send response?
|
||||
}
|
||||
|
||||
|
||||
|
||||
void _handleIpcMsgForward(AQHOMED *aqh, GWEN_MSG_ENDPOINT2 *ep, const GWEN_MSG *msg)
|
||||
{
|
||||
if (aqh->ttyEndpoint && GWEN_MsgEndpoint2_GetState(aqh->ttyEndpoint)==GWEN_MSG_ENDPOINT_STATE_CONNECTED) {
|
||||
GWEN_MSG *msgOut;
|
||||
|
||||
DBG_ERROR(AQH_LOGDOMAIN, "Received IPC FORWARD message");
|
||||
msgOut=AQH_ForwardIpcMsg_GetCopyOfNodeMsg(msg);
|
||||
if (msgOut)
|
||||
GWEN_MsgEndpoint2_AddSendMessage(aqh->ttyEndpoint, msgOut);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void _handleIpcMsgGetDevicesReq(AQHOMED *aqh, GWEN_MSG_ENDPOINT2 *ep, const GWEN_MSG *msg)
|
||||
{
|
||||
AQH_NODE_INFO_LIST *nodeInfoList;
|
||||
|
||||
DBG_ERROR(AQH_LOGDOMAIN, "Received IPC GetDevicesRequest message");
|
||||
nodeInfoList=AQH_NodeDb_GetAllNodeInfos(aqh->nodeDb);
|
||||
if (nodeInfoList && AQH_NodeInfo_List_GetCount(nodeInfoList)) {
|
||||
const AQH_NODE_INFO *ni;
|
||||
|
||||
ni=AQH_NodeInfo_List_First(nodeInfoList);
|
||||
while(ni) {
|
||||
const AQH_NODE_INFO *niNext;
|
||||
GWEN_MSG *msgOut;
|
||||
|
||||
niNext=AQH_NodeInfo_List_Next(ni);
|
||||
DBG_INFO(AQH_LOGDOMAIN, "Sending response for node %02x (%08x)", AQH_NodeInfo_GetBusAddress(ni), AQH_NodeInfo_GetUid(ni));
|
||||
msgOut=AQH_GetDevicesResponseIpcMsg_new(AQH_MSGTYPE_IPC_GETDEVICES_RSP, niNext?0:AQH_MSGIPC_GETDEVICES_RSP_FLAGS_LAST, ni);
|
||||
GWEN_MsgEndpoint2_AddSendMessage(ep, msgOut);
|
||||
ni=niNext;
|
||||
}
|
||||
}
|
||||
else {
|
||||
GWEN_MSG *msgOut;
|
||||
|
||||
DBG_INFO(AQH_LOGDOMAIN, "No nodes");
|
||||
msgOut=AQH_ErrorIpcMsg_new(AQH_MSGTYPE_IPC_ERROR, AQH_MSG_IPC_ERROR_NODATA);
|
||||
GWEN_MsgEndpoint2_AddSendMessage(ep, msgOut);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
23
apps/aqhomed/loop_ipc.h
Normal file
23
apps/aqhomed/loop_ipc.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 AQHOMED_LOOP_IPC_H
|
||||
#define AQHOMED_LOOP_IPC_H
|
||||
|
||||
|
||||
#include "./aqhomed.h"
|
||||
|
||||
|
||||
|
||||
void AqHomed_ReadAndHandleIpcMessages(AQHOMED *aqh);
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
89
apps/aqhomed/loop_tty.c
Normal file
89
apps/aqhomed/loop_tty.c
Normal file
@@ -0,0 +1,89 @@
|
||||
/****************************************************************************
|
||||
* This file is part of the project AqHome.
|
||||
* AqHome (c) by 2023 Martin Preuss, all rights reserved.
|
||||
*
|
||||
* The license for this file can be found in the file COPYING which you
|
||||
* should have received along with this file.
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
|
||||
#include "./loop_tty.h"
|
||||
#include "./loop_tty_ipc.h"
|
||||
#include "./loop_tty_mqtt.h"
|
||||
#include "./aqhomed_p.h"
|
||||
#include "./tty_log.h"
|
||||
#include "./tty_write.h"
|
||||
#include "./db.h"
|
||||
|
||||
#include "aqhome/msg/endpoint2_tty.h"
|
||||
#include "aqhome/msg/msg_node.h"
|
||||
#include "aqhome/msg/msg_value2.h"
|
||||
#include "aqhome/ipc/endpoint2_ipc.h"
|
||||
#include "aqhome/ipc/msg_ipc_forward.h"
|
||||
#include "aqhome/ipc/msg_ipc_value.h"
|
||||
#include "aqhome/mqtt/endpoint2_mqttc.h"
|
||||
|
||||
#include <gwenhywfar/gwenhywfar.h>
|
||||
#include <gwenhywfar/args.h>
|
||||
#include <gwenhywfar/debug.h>
|
||||
#include <gwenhywfar/endpoint2_tcpd.h>
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* defines
|
||||
* ------------------------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#define I18N(msg) msg
|
||||
#define I18S(msg) msg
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* forward declarations
|
||||
* ------------------------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static void _handleTtyMsg(AQHOMED *aqh, const GWEN_MSG *msg);
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* implementations
|
||||
* ------------------------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
void AqHomed_ReadAndHandleTtyMessages(AQHOMED *aqh)
|
||||
{
|
||||
GWEN_MSG *msg;
|
||||
|
||||
while( (msg=GWEN_MsgEndpoint2_TakeFirstReceivedMessage(aqh->ttyEndpoint)) ) {
|
||||
_handleTtyMsg(aqh, msg);
|
||||
GWEN_Msg_free(msg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void _handleTtyMsg(AQHOMED *aqh, const GWEN_MSG *msg)
|
||||
{
|
||||
if (aqh->logFile)
|
||||
AqHomed_LogTtyMsg(aqh, msg);
|
||||
if (aqh->writeFolder)
|
||||
AqHomed_WriteTtyMsg(aqh, msg);
|
||||
if (aqh->nodeDb)
|
||||
AqHomed_NodeMsgToDb(aqh, msg);
|
||||
if (aqh->ipcdEndpoint)
|
||||
AqHomed_ForwardTtyMsgToIpcClients(aqh, msg);
|
||||
if (aqh->mqttEndpoint)
|
||||
AqHomed_ForwardTtyMsgToMqttServer(aqh, msg);
|
||||
}
|
||||
|
||||
|
||||
|
||||
23
apps/aqhomed/loop_tty.h
Normal file
23
apps/aqhomed/loop_tty.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 AQHOMED_LOOP_TTY_H
|
||||
#define AQHOMED_LOOP_TTY_H
|
||||
|
||||
|
||||
#include "./aqhomed.h"
|
||||
|
||||
|
||||
|
||||
void AqHomed_ReadAndHandleTtyMessages(AQHOMED *aqh);
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
118
apps/aqhomed/loop_tty_ipc.c
Normal file
118
apps/aqhomed/loop_tty_ipc.c
Normal file
@@ -0,0 +1,118 @@
|
||||
/****************************************************************************
|
||||
* This file is part of the project AqHome.
|
||||
* AqHome (c) by 2023 Martin Preuss, all rights reserved.
|
||||
*
|
||||
* The license for this file can be found in the file COPYING which you
|
||||
* should have received along with this file.
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
|
||||
#include "./loop_tty_ipc.h"
|
||||
#include "./aqhomed_p.h"
|
||||
#include "./tty_log.h"
|
||||
#include "./tty_write.h"
|
||||
#include "./db.h"
|
||||
|
||||
#include "aqhome/msg/endpoint2_tty.h"
|
||||
#include "aqhome/msg/msg_node.h"
|
||||
#include "aqhome/msg/msg_value2.h"
|
||||
#include "aqhome/ipc/endpoint2_ipc.h"
|
||||
#include "aqhome/ipc/msg_ipc_forward.h"
|
||||
#include "aqhome/ipc/msg_ipc_value.h"
|
||||
#include "aqhome/mqtt/endpoint2_mqttc.h"
|
||||
|
||||
#include <gwenhywfar/gwenhywfar.h>
|
||||
#include <gwenhywfar/args.h>
|
||||
#include <gwenhywfar/debug.h>
|
||||
#include <gwenhywfar/endpoint2_tcpd.h>
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* defines
|
||||
* ------------------------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#define I18N(msg) msg
|
||||
#define I18S(msg) msg
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* forward declarations
|
||||
* ------------------------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static void _forwardValue2MsgToIpc(GWEN_MSG_ENDPOINT2 *ep, const GWEN_MSG *nodeMsg);
|
||||
static void _forwardAnyMsgToIpc(GWEN_MSG_ENDPOINT2 *ep, const GWEN_MSG *nodeMsg);
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* implementations
|
||||
* ------------------------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void AqHomed_ForwardTtyMsgToIpcClients(AQHOMED *aqh, const GWEN_MSG *msg)
|
||||
{
|
||||
uint32_t msgGroup;
|
||||
|
||||
msgGroup=AQH_NodeMsg_GetMsgGroup(AQH_NodeMsg_GetMsgType(msg));
|
||||
if (msgGroup) {
|
||||
GWEN_MSG_ENDPOINT2 *ep;
|
||||
|
||||
ep=GWEN_MsgEndpoint2_Tree2_GetFirstChild(aqh->ipcdEndpoint);
|
||||
while(ep) {
|
||||
if (msgGroup & AQH_IpcEndpoint2_GetAcceptedMsgGroups(ep)) {
|
||||
DBG_INFO(NULL, "Endpoint accepts msg group %d", msgGroup);
|
||||
switch(AQH_NodeMsg_GetMsgType(msg)) {
|
||||
case AQH_MSG_TYPE_VALUE2:
|
||||
_forwardValue2MsgToIpc(ep, msg);
|
||||
break;
|
||||
default:
|
||||
_forwardAnyMsgToIpc(ep, msg);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
ep=GWEN_MsgEndpoint2_Tree2_GetNext(ep);
|
||||
}
|
||||
}
|
||||
else {
|
||||
DBG_ERROR(NULL, "Message type %d not in any message group, ignoring message", AQH_NodeMsg_GetMsgType(msg));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void _forwardValue2MsgToIpc(GWEN_MSG_ENDPOINT2 *ep, const GWEN_MSG *nodeMsg)
|
||||
{
|
||||
GWEN_MSG *ipcMsg;
|
||||
|
||||
ipcMsg=AQH_ValueIpcMsg_new(AQH_MSGTYPE_IPC_VALUE,
|
||||
AQH_Value2Msg_GetUid(nodeMsg),
|
||||
AQH_Value2Msg_GetValueId(nodeMsg),
|
||||
AQH_Value2Msg_GetValueType(nodeMsg),
|
||||
AQH_Value2Msg_GetValueNom(nodeMsg),
|
||||
AQH_Value2Msg_GetValueDenom(nodeMsg));
|
||||
GWEN_MsgEndpoint2_AddSendMessage(ep, ipcMsg);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void _forwardAnyMsgToIpc(GWEN_MSG_ENDPOINT2 *ep, const GWEN_MSG *nodeMsg)
|
||||
{
|
||||
GWEN_MSG *ipcMsg;
|
||||
|
||||
ipcMsg=AQH_ForwardIpcMsg_new(AQH_MSGTYPE_IPC_FORWARD, GWEN_Msg_GetConstBuffer(nodeMsg), GWEN_Msg_GetBytesInBuffer(nodeMsg));
|
||||
GWEN_MsgEndpoint2_AddSendMessage(ep, ipcMsg);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
23
apps/aqhomed/loop_tty_ipc.h
Normal file
23
apps/aqhomed/loop_tty_ipc.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 AQHOMED_LOOP_TTY_IPC_H
|
||||
#define AQHOMED_LOOP_TTY_IPC_H
|
||||
|
||||
|
||||
#include "./aqhomed.h"
|
||||
|
||||
|
||||
|
||||
void AqHomed_ForwardTtyMsgToIpcClients(AQHOMED *aqh, const GWEN_MSG *msg);
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
215
apps/aqhomed/loop_tty_mqtt.c
Normal file
215
apps/aqhomed/loop_tty_mqtt.c
Normal file
@@ -0,0 +1,215 @@
|
||||
/****************************************************************************
|
||||
* This file is part of the project AqHome.
|
||||
* AqHome (c) by 2023 Martin Preuss, all rights reserved.
|
||||
*
|
||||
* The license for this file can be found in the file COPYING which you
|
||||
* should have received along with this file.
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
|
||||
#include "./loop_tty_mqtt.h"
|
||||
#include "./aqhomed_p.h"
|
||||
#include "./tty_log.h"
|
||||
#include "./tty_write.h"
|
||||
#include "./db.h"
|
||||
|
||||
#include "aqhome/msg/endpoint2_tty.h"
|
||||
#include "aqhome/msg/msg_node.h"
|
||||
#include "aqhome/msg/msg_value2.h"
|
||||
#include "aqhome/msg/msg_sendstats.h"
|
||||
#include "aqhome/msg/msg_recvstats.h"
|
||||
#include "aqhome/ipc/endpoint2_ipc.h"
|
||||
#include "aqhome/ipc/msg_ipc_forward.h"
|
||||
#include "aqhome/ipc/msg_ipc_value.h"
|
||||
#include "aqhome/mqtt/endpoint2_mqttc.h"
|
||||
#include "aqhome/mqtt/msg_mqtt_publish.h"
|
||||
|
||||
#include <gwenhywfar/gwenhywfar.h>
|
||||
#include <gwenhywfar/args.h>
|
||||
#include <gwenhywfar/debug.h>
|
||||
#include <gwenhywfar/endpoint2_tcpd.h>
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* defines
|
||||
* ------------------------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#define I18N(msg) msg
|
||||
#define I18S(msg) msg
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* forward declarations
|
||||
* ------------------------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static void _processValue2Message(AQHOMED *aqh, const GWEN_MSG *nodeMsg);
|
||||
static void _processSendStatsMessage(AQHOMED *aqh, const GWEN_MSG *nodeMsg);
|
||||
static void _processRecvStatsMessage(AQHOMED *aqh, const GWEN_MSG *nodeMsg);
|
||||
static void _publishDouble(AQHOMED *aqh, uint32_t uid, int valueId, const char *valuePath, double v);
|
||||
static void _publishInt(AQHOMED *aqh, uint32_t uid, int valueId, const char *valuePath, int v);
|
||||
static void _publishString(AQHOMED *aqh, uint32_t uid, int valueId, const char *valuePath, const char *v);
|
||||
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* implementations
|
||||
* ------------------------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
|
||||
void AqHomed_ForwardTtyMsgToMqttServer(AQHOMED *aqh, const GWEN_MSG *nodeMsg)
|
||||
{
|
||||
if (GWEN_MsgEndpoint2_GetState(aqh->mqttEndpoint)==GWEN_MSG_ENDPOINT_STATE_CONNECTED) {
|
||||
DBG_DEBUG(AQH_LOGDOMAIN, "Processing output message");
|
||||
switch(AQH_NodeMsg_GetMsgType(nodeMsg)) {
|
||||
case AQH_MSG_TYPE_VALUE2:
|
||||
_processValue2Message(aqh, nodeMsg);
|
||||
break;
|
||||
case AQH_MSG_TYPE_COMSENDSTATS:
|
||||
_processSendStatsMessage(aqh, nodeMsg);
|
||||
break;
|
||||
case AQH_MSG_TYPE_COMRECVSTATS:
|
||||
_processRecvStatsMessage(aqh, nodeMsg);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void _processValue2Message(AQHOMED *aqh, const GWEN_MSG *nodeMsg)
|
||||
{
|
||||
if (AQH_Value2Msg_GetValueType(nodeMsg)==AQH_MSG_VALUE2_TYPE_DOOR)
|
||||
_publishString(aqh,
|
||||
AQH_Value2Msg_GetUid(nodeMsg),
|
||||
AQH_Value2Msg_GetValueId(nodeMsg),
|
||||
AQH_Value2Msg_GetValueTypeName(nodeMsg),
|
||||
AQH_Value2Msg_GetValueAsWindowStateString(nodeMsg));
|
||||
else
|
||||
_publishDouble(aqh,
|
||||
AQH_Value2Msg_GetUid(nodeMsg),
|
||||
AQH_Value2Msg_GetValueId(nodeMsg),
|
||||
AQH_Value2Msg_GetValueTypeName(nodeMsg),
|
||||
AQH_Value2Msg_GetValue(nodeMsg));
|
||||
}
|
||||
|
||||
|
||||
|
||||
void _processSendStatsMessage(AQHOMED *aqh, const GWEN_MSG *nodeMsg)
|
||||
{
|
||||
uint16_t packetsOutInt;
|
||||
|
||||
packetsOutInt=AQH_SendStatsMsg_GetPacketsOut(nodeMsg);
|
||||
if (packetsOutInt) {
|
||||
double packetsOut;
|
||||
double collisions;
|
||||
double busy;
|
||||
double collisionsPercentage=0.0;
|
||||
double busyPercentage=0.0;
|
||||
|
||||
packetsOut=(double) packetsOutInt;
|
||||
collisions=(double)AQH_SendStatsMsg_GetCollisions(nodeMsg);
|
||||
busy=(double)AQH_SendStatsMsg_GetBusyErrors(nodeMsg);
|
||||
|
||||
collisionsPercentage=collisions*100.0/packetsOut;
|
||||
busyPercentage=busy*100.0/packetsOut;
|
||||
|
||||
_publishInt(aqh, AQH_SendStatsMsg_GetUid(nodeMsg), 0, "net/packetsOut", packetsOutInt);
|
||||
_publishInt(aqh, AQH_SendStatsMsg_GetUid(nodeMsg), 0, "net/collisions", (int) AQH_SendStatsMsg_GetCollisions(nodeMsg));
|
||||
_publishDouble(aqh, AQH_SendStatsMsg_GetUid(nodeMsg), 0, "net/collisionsPercent", collisionsPercentage);
|
||||
_publishDouble(aqh, AQH_SendStatsMsg_GetUid(nodeMsg), 0, "net/busyPercent", busyPercentage);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void _processRecvStatsMessage(AQHOMED *aqh, const GWEN_MSG *nodeMsg)
|
||||
{
|
||||
uint16_t packetsInInt;
|
||||
|
||||
packetsInInt=AQH_RecvStatsMsg_GetPacketsIn(nodeMsg);
|
||||
if (packetsInInt) {
|
||||
double packetsIn;
|
||||
double crcErrors;
|
||||
double ioErrors;
|
||||
double crcErrorsPercentage=0.0;
|
||||
double ioErrorsPercentage=0.0;
|
||||
|
||||
packetsIn=(double) packetsInInt;
|
||||
crcErrors=(double)AQH_RecvStatsMsg_GetCrcErrors(nodeMsg);
|
||||
ioErrors=(double)AQH_RecvStatsMsg_GetIoErrors(nodeMsg);
|
||||
|
||||
crcErrorsPercentage=crcErrors*100.0/packetsIn;
|
||||
ioErrorsPercentage=ioErrors*100.0/packetsIn;
|
||||
|
||||
_publishInt(aqh, AQH_RecvStatsMsg_GetUid(nodeMsg), 0, "net/packetsIn", packetsInInt);
|
||||
_publishInt(aqh, AQH_RecvStatsMsg_GetUid(nodeMsg), 0, "net/crcerrors", (int) AQH_RecvStatsMsg_GetCrcErrors(nodeMsg));
|
||||
_publishInt(aqh, AQH_RecvStatsMsg_GetUid(nodeMsg), 0, "net/ioerrors", (int) AQH_RecvStatsMsg_GetIoErrors(nodeMsg));
|
||||
_publishDouble(aqh, AQH_RecvStatsMsg_GetUid(nodeMsg), 0, "net/crcerrorsPercent", crcErrorsPercentage);
|
||||
_publishDouble(aqh, AQH_RecvStatsMsg_GetUid(nodeMsg), 0, "net/ioerrorsPercent", ioErrorsPercentage);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void _publishDouble(AQHOMED *aqh, uint32_t uid, int valueId, const char *valuePath, double v)
|
||||
{
|
||||
char numBuf[16];
|
||||
|
||||
snprintf(numBuf, sizeof(numBuf)-1, "%f", v);
|
||||
numBuf[sizeof(numBuf)-1]=0;
|
||||
_publishString(aqh, uid, valueId, valuePath, numBuf);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void _publishInt(AQHOMED *aqh, uint32_t uid, int valueId, const char *valuePath, int v)
|
||||
{
|
||||
char numBuf[16];
|
||||
|
||||
snprintf(numBuf, sizeof(numBuf)-1, "%d", v);
|
||||
numBuf[sizeof(numBuf)-1]=0;
|
||||
_publishString(aqh, uid, valueId, valuePath, numBuf);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void _publishString(AQHOMED *aqh, uint32_t uid, int valueId, const char *valuePath, const char *v)
|
||||
{
|
||||
GWEN_BUFFER *bufTopic;
|
||||
GWEN_MSG *pubMsg;
|
||||
|
||||
bufTopic=GWEN_Buffer_new(0, 64, 0, 1);
|
||||
if (valueId>0)
|
||||
GWEN_Buffer_AppendArgs(bufTopic, "%s/%08x/%d/%s",
|
||||
aqh->mqttTopicPrefix,
|
||||
uid,
|
||||
valueId,
|
||||
valuePath);
|
||||
else
|
||||
GWEN_Buffer_AppendArgs(bufTopic, "%s/%08x/%s",
|
||||
aqh->mqttTopicPrefix,
|
||||
uid,
|
||||
valuePath);
|
||||
|
||||
pubMsg=AQH_PublishMqttMsg_new(0, 0, GWEN_Buffer_GetStart(bufTopic), (const uint8_t*) v, strlen(v));
|
||||
if (pubMsg) {
|
||||
DBG_INFO(AQH_LOGDOMAIN, "MQTT PUBLISH %s: %s", GWEN_Buffer_GetStart(bufTopic), v);
|
||||
GWEN_MsgEndpoint2_AddSendMessage(aqh->mqttEndpoint, pubMsg);
|
||||
}
|
||||
GWEN_Buffer_free(bufTopic);
|
||||
}
|
||||
|
||||
|
||||
23
apps/aqhomed/loop_tty_mqtt.h
Normal file
23
apps/aqhomed/loop_tty_mqtt.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 AQHOMED_LOOP_TTY_MQTT_H
|
||||
#define AQHOMED_LOOP_TTY_MQTT_H
|
||||
|
||||
|
||||
#include "./aqhomed.h"
|
||||
|
||||
|
||||
|
||||
void AqHomed_ForwardTtyMsgToMqttServer(AQHOMED *aqh, const GWEN_MSG *msg);
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
Reference in New Issue
Block a user