adapted to latest changes in gwen, more work on data and nodes servers.

This commit is contained in:
Martin Preuss
2024-09-26 10:45:22 +02:00
parent be053b035f
commit b0b6efb1c3
88 changed files with 1745 additions and 445 deletions

View File

@@ -8,6 +8,8 @@
$(gwenhywfar_cflags)
-I$(topsrcdir)
-I$(topbuilddir)
-I$(topsrcdir)/apps
-I$(topbuilddir)/apps
</includes>
<includes type="tm2" >
@@ -45,6 +47,8 @@
loop_ipc.h
db.h
tty_log.h
devicesread.h
devicesdump.h
</headers>
<sources>
@@ -61,9 +65,12 @@
loop_ipc.c
db.c
tty_log.c
devicesread.c
devicesdump.c
</sources>
<useTargets>
aqhnodes_types
aqhome
</useTargets>
@@ -72,6 +79,7 @@
</libraries>
<subdirs>
types
</subdirs>

View File

@@ -51,6 +51,7 @@ AQHOMED *AqHomed_new(void)
GWEN_NEW_OBJECT(AQHOMED, aqh);
aqh->rootEndpoint=GWEN_MsgEndpoint_new("root", 0);
aqh->nodeDb=AQH_NodeDb_new();
aqh->requestTree=GWEN_MsgRequest_new();
return aqh;
}
@@ -60,6 +61,7 @@ AQHOMED *AqHomed_new(void)
void AqHomed_free(AQHOMED *aqh)
{
if (aqh) {
GWEN_MsgRequest_free(aqh->requestTree);
GWEN_MsgEndpoint_free(aqh->rootEndpoint);
aqh->rootEndpoint=NULL;
aqh->ttyEndpoint=NULL;
@@ -164,5 +166,56 @@ int AqHomed_GetTimeout(const AQHOMED *aqh)
GWEN_MSG_REQUEST *AqHomed_GetRequestTree(const AQHOMED *aqh)
{
return aqh?aqh->requestTree:NULL;
}
void AqHomed_AddRequestToTree(AQHOMED *aqh, GWEN_MSG_REQUEST *rq)
{
if (aqh && rq)
GWEN_MsgRequest_Tree2_AddChild(aqh->requestTree, rq);
}
const AQHNODE_DEVICE_LIST *AqHomed_GetDeviceDefList(const AQHOMED *aqh)
{
return aqh?aqh->deviceDefList:NULL;
}
const AQHNODE_DEVICE *AqHomed_FindDeviceDef(const AQHOMED *aqh, uint32_t manufacturer, uint16_t deviceType, uint16_t deviceVersion)
{
if (aqh && aqh->deviceDefList) {
const AQHNODE_DEVICE *device;
device=AQHNODE_Device_List_First(aqh->deviceDefList);
while(device) {
if (AQHNODE_Device_GetManufacturer(device)==manufacturer &&
AQHNODE_Device_GetDeviceType(device)==deviceType &&
AQHNODE_Device_GetDeviceVersion(device)==(deviceVersion & 0xff00))
return device;
device=AQHNODE_Device_List_Next(device);
}
}
return NULL;
}
const AQHNODE_DEVICE *AqHomed_GetDeviceDefByName(const AQHOMED *aqh, const char *name)
{
if (aqh && aqh->deviceDefList && name)
return AQHNODE_Device_List_GetByName(aqh->deviceDefList, name);
return NULL;
}

View File

@@ -12,6 +12,7 @@
#include <gwenhywfar/endpoint.h>
#include <gwenhywfar/db.h>
#include <gwenhywfar/request.h>
#define AQHOME_ENDPOINTGROUP_NODE 1
@@ -21,6 +22,10 @@
typedef struct AQHOMED AQHOMED;
#include "aqhome-nodes/types/device.h"
AQHOMED *AqHomed_new(void);
void AqHomed_free(AQHOMED *aqh);
@@ -41,6 +46,14 @@ void AqHomed_SetDbFile(AQHOMED *aqh, const char *s);
int AqHomed_GetTimeout(const AQHOMED *aqh);
GWEN_MSG_REQUEST *AqHomed_GetRequestTree(const AQHOMED *aqh);
void AqHomed_AddRequestToTree(AQHOMED *aqh, GWEN_MSG_REQUEST *rq);
const AQHNODE_DEVICE_LIST *AqHomed_GetDeviceDefList(const AQHOMED *aqh);
const AQHNODE_DEVICE *AqHomed_FindDeviceDef(const AQHOMED *aqh, uint32_t manufacturer, uint16_t deviceType, uint16_t deviceVersion);
const AQHNODE_DEVICE *AqHomed_GetDeviceDefByName(const AQHOMED *aqh, const char *name);
#endif

View File

@@ -34,6 +34,7 @@ struct AQHOMED {
GWEN_MSG_ENDPOINT *brokerEndpoint;
AQH_NODE_DB *nodeDb;
AQHNODE_DEVICE_LIST *deviceDefList;
GWEN_DB_NODE *dbArgs;
@@ -44,6 +45,8 @@ struct AQHOMED {
int timeout; /* timeout for run e.g. inside valgrind */
int nodeAddress;
GWEN_MSG_REQUEST *requestTree;
};
#endif

View File

@@ -18,6 +18,7 @@
#include "aqhome/msg/msg_sendstats.h"
#include "aqhome/msg/msg_recvstats.h"
#include "aqhome/msg/msg_value2.h"
#include "aqhome/msg/msg_value3.h"
#include "aqhome/msg/msg_needaddr.h"
#include "aqhome/msg/msg_claimaddr.h"
#include "aqhome/msg/msg_haveaddr.h"
@@ -39,6 +40,7 @@
*/
static void _handleMsgValue2(AQHOMED *aqh, const GWEN_MSG *msg);
static void _handleMsgValue3(AQHOMED *aqh, const GWEN_MSG *msg);
static void _handleMsgNeedAddress(AQHOMED *aqh, const GWEN_MSG *msg);
static void _handleMsgClaimAddress(AQHOMED *aqh, const GWEN_MSG *msg);
static void _handleMsgHaveAddress(AQHOMED *aqh, const GWEN_MSG *msg);
@@ -49,6 +51,7 @@ static void _handleMsgFlashReady(AQHOMED *aqh, const GWEN_MSG *msg);
static AQH_NODE_INFO *_getOrCreateNodeAndUpdateUidAddr(AQHOMED *aqh, const GWEN_MSG *msg, uint32_t uid);
static void _updateTimestampLastChange(AQH_NODE_INFO *ni);
static void _assignDeviceId(AQHOMED *aqh, AQH_NODE_INFO *ni, uint32_t uid);
@@ -78,6 +81,7 @@ void AqHomed_NodeMsgToDb(AQHOMED *aqh, const GWEN_MSG *msg)
case AQH_MSG_TYPE_COMSENDSTATS: _handleMsgComSendStat(aqh, msg); break;
case AQH_MSG_TYPE_COMRECVSTATS: _handleMsgComRecvStat(aqh, msg); break;
case AQH_MSG_TYPE_VALUE2: _handleMsgValue2(aqh, msg); break;
case AQH_MSG_TYPE_VALUE_REPORT: _handleMsgValue3(aqh, msg); break;
case AQH_MSG_TYPE_NEED_ADDRESS: _handleMsgNeedAddress(aqh, msg); break;
case AQH_MSG_TYPE_CLAIM_ADDRESS: _handleMsgClaimAddress(aqh, msg); break;
case AQH_MSG_TYPE_HAVE_ADDRESS: _handleMsgHaveAddress(aqh, msg); break;
@@ -119,6 +123,20 @@ void _handleMsgValue2(AQHOMED *aqh, const GWEN_MSG *msg)
void _handleMsgValue3(AQHOMED *aqh, const GWEN_MSG *msg)
{
AQH_NODE_INFO *ni;
uint32_t uid;
uid=AQH_Value3Msg_GetUid(msg);
ni=_getOrCreateNodeAndUpdateUidAddr(aqh, msg, uid);
if (ni==NULL) {
DBG_INFO(AQH_LOGDOMAIN, "Error handling message");
}
}
void _handleMsgNeedAddress(AQHOMED *aqh, const GWEN_MSG *msg)
{
AQH_NODE_INFO *ni;
@@ -207,6 +225,8 @@ void _handleMsgDevice(AQHOMED *aqh, const GWEN_MSG *msg)
uid=AQH_DeviceMsg_GetUid(msg);
ni=_getOrCreateNodeAndUpdateUidAddr(aqh, msg, uid);
if (ni) {
const char *s;
AQH_NodeInfo_SetManufacturer(ni, AQH_DeviceMsg_GetManufacturer(msg));
AQH_NodeInfo_SetDeviceType(ni, AQH_DeviceMsg_GetDeviceType(msg));
AQH_NodeInfo_SetDeviceVersion(ni, (AQH_DeviceMsg_GetDeviceVersion(msg)<<8)+AQH_DeviceMsg_GetDeviceRevision(msg));
@@ -215,6 +235,9 @@ void _handleMsgDevice(AQHOMED *aqh, const GWEN_MSG *msg)
(AQH_DeviceMsg_GetFirmwareVersionMajor(msg)<<16) |
(AQH_DeviceMsg_GetFirmwareVersionMinor(msg)<<8) |
AQH_DeviceMsg_GetFirmwareVersionPatchlevel(msg));
s=AQH_NodeInfo_GetDeviceId(ni);
if (!(s && *s))
_assignDeviceId(aqh, ni, uid);
_updateTimestampLastChange(ni);
AQH_NodeDb_SetModified(aqh->nodeDb);
}
@@ -233,6 +256,8 @@ void _handleMsgFlashReady(AQHOMED *aqh, const GWEN_MSG *msg)
uid=AQH_FlashReadyMsg_GetUid(msg);
ni=_getOrCreateNodeAndUpdateUidAddr(aqh, msg, uid);
if (ni) {
const char *s;
AQH_NodeInfo_SetManufacturer(ni, AQH_FlashReadyMsg_GetManufacturer(msg));
AQH_NodeInfo_SetDeviceType(ni, AQH_FlashReadyMsg_GetDeviceType(msg));
AQH_NodeInfo_SetDeviceVersion(ni, (AQH_FlashReadyMsg_GetDeviceVersion(msg)<<8)+AQH_FlashReadyMsg_GetDeviceRevision(msg));
@@ -241,6 +266,9 @@ void _handleMsgFlashReady(AQHOMED *aqh, const GWEN_MSG *msg)
(AQH_FlashReadyMsg_GetFirmwareVersionMajor(msg)<<16) |
(AQH_FlashReadyMsg_GetFirmwareVersionMinor(msg)<<8) |
AQH_FlashReadyMsg_GetFirmwareVersionPatchlevel(msg));
s=AQH_NodeInfo_GetDeviceId(ni);
if (!(s && *s))
_assignDeviceId(aqh, ni, uid);
_updateTimestampLastChange(ni);
AQH_NodeDb_SetModified(aqh->nodeDb);
}
@@ -291,6 +319,32 @@ AQH_NODE_INFO *_getOrCreateNodeAndUpdateUidAddr(AQHOMED *aqh, const GWEN_MSG *ms
void _assignDeviceId(AQHOMED *aqh, AQH_NODE_INFO *ni, uint32_t uid)
{
const AQHNODE_DEVICE *dev;
dev=AqHomed_FindDeviceDef(aqh,
AQH_NodeInfo_GetManufacturer(ni),
AQH_NodeInfo_GetDeviceType(ni),
AQH_NodeInfo_GetDeviceVersion(ni));
if (dev==NULL) {
DBG_ERROR(NULL,
"Unknown NODE device encountered (%08x, %04x, %04x)",
AQH_NodeInfo_GetManufacturer(ni),
AQH_NodeInfo_GetDeviceType(ni),
AQH_NodeInfo_GetDeviceVersion(ni));
}
else {
const char *s;
s=AQHNODE_Device_GetName(dev);
DBG_ERROR(NULL, "Found device \"%s\" (%08x)", s?s:"<no name>", uid);
AQH_NodeInfo_SetDeviceId(ni, s);
}
}
void _updateTimestampLastChange(AQH_NODE_INFO *ni)
{
GWEN_TIMESTAMP *t;

View File

@@ -0,0 +1,125 @@
/****************************************************************************
* This file is part of the project AqHome.
* AqHome (c) by 2024 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 "./devicesdump.h"
#include "./aqhomed_p.h"
#include "aqhome/aqhome.h"
#include <gwenhywfar/debug.h>
/* ------------------------------------------------------------------------------------------------
* forward declarations
* ------------------------------------------------------------------------------------------------
*/
static void _dumpDevice(const AQHNODE_DEVICE *dev, GWEN_BUFFER *dbuf, int indent);
static void _dumpValue(const AQHNODE_VALUE *value, GWEN_BUFFER *dbuf, int indent);
/* ------------------------------------------------------------------------------------------------
* implementations
* ------------------------------------------------------------------------------------------------
*/
void AqHomeNodes_DumpDevices(const AQHNODE_DEVICE_LIST *devList, GWEN_BUFFER *dbuf)
{
if (devList && AQHNODE_Device_List_GetCount(devList)) {
const AQHNODE_DEVICE *dev;
GWEN_Buffer_AppendString(dbuf, "Devices:\n");
dev=AQHNODE_Device_List_First(devList);
while(dev) {
_dumpDevice(dev, dbuf, 2);
dev=AQHNODE_Device_List_Next(dev);
}
}
}
void _dumpDevice(const AQHNODE_DEVICE *dev, GWEN_BUFFER *dbuf, int indent)
{
const char *name;
const char *driver;
uint32_t manufacturer;
uint16_t deviceType;
uint16_t deviceVersion;
const AQHNODE_VALUE_LIST *valueList;
name=AQHNODE_Device_GetName(dev);
driver=AQHNODE_Device_GetDriver(dev);
manufacturer=AQHNODE_Device_GetManufacturer(dev);
deviceType=AQHNODE_Device_GetDeviceType(dev);
deviceVersion=AQHNODE_Device_GetDeviceVersion(dev);
GWEN_Buffer_FillWithBytes(dbuf, ' ', indent);
GWEN_Buffer_AppendArgs(dbuf, "Device: %s (%s, %08x, %04x, %04x)\n",
name?name:"<empty name>",
driver?driver:"<empty driver>",
manufacturer,
deviceType,
deviceVersion);
valueList=AQHNODE_Device_GetValueList(dev);
if (valueList && AQHNODE_Value_List_GetCount(valueList)) {
const AQHNODE_VALUE *value;
value=AQHNODE_Value_List_First(valueList);
while(value) {
_dumpValue(value, dbuf, indent+2);
value=AQHNODE_Value_List_Next(value);
}
}
}
void _dumpValue(const AQHNODE_VALUE *value, GWEN_BUFFER *dbuf, int indent)
{
int id;
const char *name;
const char *descr;
int valueType;
int dataType;
int modality;
const char *units;
id=AQHNODE_Value_GetId(value);
name=AQHNODE_Value_GetName(value);
descr=AQHNODE_Value_GetDescription(value);
valueType=AQHNODE_Value_GetValueType(value);
dataType=AQHNODE_Value_GetDataType(value);
modality=AQHNODE_Value_GetModality(value);
units=AQHNODE_Value_GetValueUnits(value);
GWEN_Buffer_FillWithBytes(dbuf, ' ', indent);
GWEN_Buffer_AppendArgs(dbuf, "Value: %d[%02x] (%s, %s, %s, %s, %s, %s)\n",
id, id,
name?name:"<empty name>",
AQH_ValueType_toString(valueType),
AQH_ValueDataType_toString(dataType),
AQH_ValueModality_toString(modality),
units?units:"<empty units>",
descr?descr:"<empty descr>");
}

View File

@@ -0,0 +1,24 @@
/****************************************************************************
* This file is part of the project AqHome.
* AqHome (c) by 2024 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 AQHOME_NODES_DEVICESDUMP_H
#define AQHOME_NODES_DEVICESDUMP_H
#include "./aqhomed.h"
#include "aqhome-nodes/types/device.h"
void AqHomeNodes_DumpDevices(const AQHNODE_DEVICE_LIST *devList, GWEN_BUFFER *dbuf);
#endif

View File

@@ -0,0 +1,396 @@
/****************************************************************************
* This file is part of the project AqHome.
* AqHome (c) by 2024 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 "./devicesread.h"
#include "./aqhomed_p.h"
#include "aqhome/aqhome.h"
#include <gwenhywfar/directory.h>
#include <gwenhywfar/debug.h>
#include <gwenhywfar/stringlist.h>
/* ------------------------------------------------------------------------------------------------
* defines
* ------------------------------------------------------------------------------------------------
*/
/* ------------------------------------------------------------------------------------------------
* forward declarations
* ------------------------------------------------------------------------------------------------
*/
static int _readDeviceFileToList(const char *sFilename, AQHNODE_DEVICE_LIST *deviceList);
static AQHNODE_DEVICE_LIST *_readDeviceFiles(const GWEN_STRINGLIST *sl);
static int _readXmlDevices(GWEN_XMLNODE *deviceListNode, AQHNODE_DEVICE_LIST *deviceList);
static AQHNODE_DEVICE *_readXmlDevice(GWEN_XMLNODE *deviceNode);
static AQHNODE_VALUE_LIST *_readXmlValueList(GWEN_XMLNODE *valuesNode);
static AQHNODE_VALUE *_readXmlValue(GWEN_XMLNODE *valueNode);
static int _readManufacturer(AQHNODE_DEVICE *device, GWEN_XMLNODE *deviceNode);
static int _readDeviceType(AQHNODE_DEVICE *device, GWEN_XMLNODE *deviceNode);
static int _readDeviceVersion(AQHNODE_DEVICE *device, GWEN_XMLNODE *deviceNode);
/* ------------------------------------------------------------------------------------------------
* implementations
* ------------------------------------------------------------------------------------------------
*/
AQHNODE_DEVICE_LIST *AqHomeNodes_ReadDeviceFile(const char *sFilename)
{
int rv;
rv=GWEN_Directory_GetPath(sFilename, GWEN_PATH_FLAGS_CHECKROOT | GWEN_PATH_FLAGS_PATHMUSTEXIST | GWEN_PATH_FLAGS_VARIABLE);
if (rv<0) {
DBG_ERROR(NULL, "File \"%s\" does not exists, writing later", sFilename);
return NULL;
}
else {
AQHNODE_DEVICE_LIST *deviceList;
deviceList=AQHNODE_Device_List_new();
rv=_readDeviceFileToList(sFilename, deviceList);
if (rv<0) {
DBG_ERROR(NULL, "File \"%s\" not found", sFilename);
AQHNODE_Device_List_free(deviceList);
return NULL;
}
if (AQHNODE_Device_List_GetCount(deviceList)<1) {
AQHNODE_Device_List_free(deviceList);
return NULL;
}
return deviceList;
}
}
AQHNODE_DEVICE_LIST *AqHomeNodes_ReadDataDeviceFiles()
{
GWEN_STRINGLIST *sl;
sl=AQH_GetListOfMatchingDataFiles("aqhome/devices/nodes", "*.xml");
if (sl) {
AQHNODE_DEVICE_LIST *deviceList;
deviceList=_readDeviceFiles(sl);
GWEN_StringList_free(sl);
if (deviceList==NULL) {
DBG_INFO(NULL, "Error reading data device files");
return NULL;
}
return deviceList;
}
else {
DBG_ERROR(NULL, "No data device files");
return NULL;
}
}
AQHNODE_DEVICE_LIST *_readDeviceFiles(const GWEN_STRINGLIST *sl)
{
GWEN_STRINGLISTENTRY *se;
AQHNODE_DEVICE_LIST *deviceList;
deviceList=AQHNODE_Device_List_new();
se=GWEN_StringList_FirstEntry(sl);
while(se) {
const char *s;
s=GWEN_StringListEntry_Data(se);
if (s && *s) {
int rv;
DBG_INFO(NULL, "Reading device file \"%s\"", s);
rv=_readDeviceFileToList(s, deviceList);
if (rv<0 && rv!=GWEN_ERROR_NO_DATA) {
DBG_WARN(NULL, "Error reading device file \"%s\" (%d), ignoring", s, rv);
}
}
se=GWEN_StringListEntry_Next(se);
}
if (AQHNODE_Device_List_GetCount(deviceList)<1) {
AQHNODE_Device_List_free(deviceList);
return NULL;
}
return deviceList;
}
int _readDeviceFileToList(const char *sFilename, AQHNODE_DEVICE_LIST *deviceList)
{
GWEN_XMLNODE *rootNode;
GWEN_XMLNODE *deviceListNode;
int rv;
rootNode=GWEN_XMLNode_new(GWEN_XMLNodeTypeTag, NULL);
rv=GWEN_XML_ReadFile(rootNode, sFilename, GWEN_XML_FLAGS_DEFAULT);
if (rv<0) {
DBG_ERROR(NULL, "Error reading XML file \"%s\": %d", sFilename, rv);
GWEN_XMLNode_free(rootNode);
return rv;
}
deviceListNode=GWEN_XMLNode_FindFirstTag(rootNode, "devices", NULL, NULL);
if (deviceListNode==NULL)
deviceListNode=rootNode;
rv=_readXmlDevices(deviceListNode, deviceList);
if (rv<0 && rv!=GWEN_ERROR_NO_DATA) {
DBG_ERROR(AQH_LOGDOMAIN, "Error reading devices from file \"%s\" (%d)", sFilename, rv);
GWEN_XMLNode_free(rootNode);
return rv;
}
GWEN_XMLNode_free(rootNode);
return 0;
}
int _readXmlDevices(GWEN_XMLNODE *deviceListNode, AQHNODE_DEVICE_LIST *deviceList)
{
GWEN_XMLNODE *deviceNode;
deviceNode=GWEN_XMLNode_FindFirstTag(deviceListNode, "device", NULL, NULL);
if (deviceNode) {
while(deviceNode) {
const char *driverName;
driverName=GWEN_XMLNode_GetProperty(deviceNode, "driver", NULL);
if (driverName && *driverName && strcasecmp(driverName, "nodes")==0) {
AQHNODE_DEVICE *device;
device=_readXmlDevice(deviceNode);
if (device==NULL) {
DBG_INFO(NULL, "Error reading device from XML");
return GWEN_ERROR_BAD_DATA;
}
else {
const char *sDeviceName;
sDeviceName=AQHNODE_Device_GetName(device);
if (sDeviceName && *sDeviceName) {
DBG_ERROR(NULL, "Adding device type \"%s\" to list", sDeviceName?sDeviceName:"<no type name>");
AQHNODE_Device_List_Add(device, deviceList);
}
else {
DBG_ERROR(NULL, "Device with no name, not adding");
AQHNODE_Device_free(device);
}
}
}
else {
DBG_INFO(NULL, "Device is not an NODES device, ignoring");
}
deviceNode=GWEN_XMLNode_FindNextTag(deviceNode, "device", NULL, NULL);
} /* while */
return 0;
}
else {
DBG_INFO(NULL, "No <device> element found");
return GWEN_ERROR_NO_DATA;
}
}
AQHNODE_DEVICE *_readXmlDevice(GWEN_XMLNODE *deviceNode)
{
AQHNODE_DEVICE *device;
GWEN_XMLNODE *valuesNode;
int rv;
device=AQHNODE_Device_new();
AQHNODE_Device_SetName(device, GWEN_XMLNode_GetProperty(deviceNode, "name", NULL));
AQHNODE_Device_SetDriver(device, GWEN_XMLNode_GetProperty(deviceNode, "driver", NULL));
rv=_readManufacturer(device, deviceNode);
if (rv<0) {
DBG_INFO(NULL, "here (%d)", rv);
AQHNODE_Device_free(device);
return NULL;
}
rv=_readDeviceType(device, deviceNode);
if (rv<0) {
DBG_INFO(NULL, "here (%d)", rv);
AQHNODE_Device_free(device);
return NULL;
}
rv=_readDeviceVersion(device, deviceNode);
if (rv<0) {
DBG_INFO(NULL, "here (%d)", rv);
AQHNODE_Device_free(device);
return NULL;
}
/* read values */
valuesNode=GWEN_XMLNode_FindFirstTag(deviceNode, "values", NULL, NULL);
if (valuesNode) {
AQHNODE_VALUE_LIST *valueList;
valueList=_readXmlValueList(valuesNode);
if (valueList==NULL) {
DBG_INFO(NULL, "here");
AQHNODE_Device_free(device);
return NULL;
}
AQHNODE_Device_SetValueList(device, valueList);
}
else {
DBG_INFO(NULL, "No <values> element");
AQHNODE_Device_free(device);
return NULL;
}
return device;
}
AQHNODE_VALUE_LIST *_readXmlValueList(GWEN_XMLNODE *valuesNode)
{
AQHNODE_VALUE_LIST *valueList;
GWEN_XMLNODE *node;
valueList=AQHNODE_Value_List_new();
node=GWEN_XMLNode_FindFirstTag(valuesNode, "value", NULL, NULL);
while(node) {
AQHNODE_VALUE *value;
value=_readXmlValue(node);
if (value)
AQHNODE_Value_List_Add(value, valueList);
else {
DBG_INFO(NULL, "Error reading <value> element");
AQHNODE_Value_List_free(valueList);
return NULL;
}
node=GWEN_XMLNode_FindNextTag(node, "value", NULL, NULL);
}
if (AQHNODE_Value_List_GetCount(valueList)<1) {
DBG_INFO(NULL, "No <value> element in <values> element");
AQHNODE_Value_List_free(valueList);
return NULL;
}
return valueList;
}
AQHNODE_VALUE *_readXmlValue(GWEN_XMLNODE *valueNode)
{
AQHNODE_VALUE *value;
value=AQHNODE_Value_new();
AQHNODE_Value_SetName(value, GWEN_XMLNode_GetProperty(valueNode, "name", NULL));
AQHNODE_Value_SetId(value, GWEN_XMLNode_GetIntProperty(valueNode, "id", 0));
AQHNODE_Value_SetValueUnits(value, GWEN_XMLNode_GetProperty(valueNode, "units", NULL));
AQHNODE_Value_SetValueType(value, AQH_ValueType_fromString(GWEN_XMLNode_GetProperty(valueNode, "type", NULL)));
AQHNODE_Value_SetDataType(value, AQH_ValueDataType_fromString(GWEN_XMLNode_GetProperty(valueNode, "dataType", NULL)));
AQHNODE_Value_SetModality(value, AQH_ValueModality_fromString(GWEN_XMLNode_GetProperty(valueNode, "modality", NULL)));
return value;
}
int _readManufacturer(AQHNODE_DEVICE *device, GWEN_XMLNODE *deviceNode)
{
const char *s;
uint32_t v;
s=GWEN_XMLNode_GetCharValue(deviceNode, "manufacturer", NULL);
if (!(s && *s)) {
DBG_ERROR(NULL, "Missing manufacturer");
return GWEN_ERROR_BAD_DATA;
}
if (strlen(s)>4) {
DBG_ERROR(NULL, "Bad manufacturer string (too long): \"%s\"", s);
return GWEN_ERROR_BAD_DATA;
}
v=0;
while(*s) {
v<<=8;
v|=*s & 0xff;
s++;
}
v=((v>>24) & 0x000000ffL) |
((v>>8) & 0x0000ff00L) |
((v<<8) & 0x00ff0000L) |
((v<<24) & 0xff000000L);
AQHNODE_Device_SetManufacturer(device, v);
return 0;
}
int _readDeviceType(AQHNODE_DEVICE *device, GWEN_XMLNODE *deviceNode)
{
const char *s;
uint16_t v;
s=GWEN_XMLNode_GetCharValue(deviceNode, "devicetype", NULL);
if (!(s && *s)) {
DBG_ERROR(NULL, "Missing device type");
return GWEN_ERROR_BAD_DATA;
}
if (strlen(s)>2) {
DBG_ERROR(NULL, "Bad devicetype string (too long): \"%s\"", s);
return GWEN_ERROR_BAD_DATA;
}
v=0;
while(*s) {
v<<=8;
v|=*s & 0xff;
s++;
}
AQHNODE_Device_SetDeviceType(device, v);
return 0;
}
int _readDeviceVersion(AQHNODE_DEVICE *device, GWEN_XMLNODE *deviceNode)
{
int v;
v=GWEN_XMLNode_GetIntValue(deviceNode, "deviceversion", -1);
if (v<0) {
DBG_ERROR(NULL, "Missing device version");
return GWEN_ERROR_BAD_DATA;
}
AQHNODE_Device_SetDeviceVersion(device, v<<8);
return 0;
}

View File

@@ -0,0 +1,25 @@
/****************************************************************************
* This file is part of the project AqHome.
* AqHome (c) by 2024 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 AQHOME_NODES_DEVICESREAD_H
#define AQHOME_NODES_DEVICESREAD_H
#include "./aqhomed.h"
#include "aqhome-nodes/types/device.h"
AQHNODE_DEVICE_LIST *AqHomeNodes_ReadDeviceFile(const char *sFilename);
AQHNODE_DEVICE_LIST *AqHomeNodes_ReadDataDeviceFiles(void);
#endif

View File

@@ -14,6 +14,8 @@
#include "./init.h"
#include "./aqhomed_p.h"
#include "./tty_log.h"
#include "./devicesread.h"
#include "./devicesdump.h"
#include "aqhome/aqhome.h"
#include "aqhome/msg/endpoint_tty.h"
@@ -65,6 +67,7 @@ static void _setupBroker(AQHOMED *aqh, GWEN_DB_NODE *dbArgs);
static GWEN_MSG_ENDPOINT *_acceptIpcFn(GWEN_MSG_ENDPOINT *ep, GWEN_SOCKET *sk, const GWEN_INETADDRESS *addr, void *data);
static void _setupLog(AQHOMED *aqh, GWEN_DB_NODE *dbArgs);
static void _setupDb(AQHOMED *aqh, GWEN_DB_NODE *dbArgs);
static int _loadDeviceList(AQHOMED *aqh);
static int _readArgs(int argc, char **argv, GWEN_DB_NODE *dbArgs);
static int _createPidFile(const char *pidFilename);
@@ -113,6 +116,20 @@ int AqHomed_Init(AQHOMED *aqh, int argc, char **argv)
aqh->nodeAddress=GWEN_DB_GetIntValue(dbArgs, "nodeAddress", 0, AQHOMED_DEFAULT_NODEADDR);
rv=_loadDeviceList(aqh);
if (rv<0) {
DBG_ERROR(NULL, "Error loading device list(%d)", rv);
return rv;
}
else {
GWEN_BUFFER *dbuf;
dbuf=GWEN_Buffer_new(0, 256, 0, 1);
AqHomeNodes_DumpDevices(aqh->deviceDefList, dbuf);
fprintf(stdout, "%s\n", GWEN_Buffer_GetStart(dbuf));
GWEN_Buffer_free(dbuf);
}
_setupDb(aqh, dbArgs);
rv=_setupTty(aqh, dbArgs);
@@ -220,9 +237,9 @@ void _setupBroker(AQHOMED *aqh, GWEN_DB_NODE *dbArgs)
GWEN_MSG_ENDPOINT *_acceptIpcFn(GWEN_MSG_ENDPOINT *ep,
GWEN_MSG_ENDPOINT *_acceptIpcFn(GWEN_UNUSED GWEN_MSG_ENDPOINT *ep,
GWEN_SOCKET *sk,
const GWEN_INETADDRESS *addr,
GWEN_UNUSED const GWEN_INETADDRESS *addr,
GWEN_UNUSED void *data)
{
/* AQHOMED *aqh;
@@ -258,7 +275,7 @@ void _setupDb(AQHOMED *aqh, GWEN_DB_NODE *dbArgs)
AqHomed_SetDbFile(aqh, s);
dbNodeDb=GWEN_DB_Group_new("dbNodes");
rv=GWEN_DB_ReadFile(dbNodeDb, s, GWEN_DB_FLAGS_DEFAULT);
rv=GWEN_DB_ReadFile(dbNodeDb, s, GWEN_DB_FLAGS_DEFAULT|GWEN_PATH_FLAGS_CREATE_GROUP);
if (rv==0) {
AQH_NodeDb_fromDb(aqh->nodeDb, dbNodeDb);
}
@@ -268,6 +285,21 @@ void _setupDb(AQHOMED *aqh, GWEN_DB_NODE *dbArgs)
int _loadDeviceList(AQHOMED *aqh)
{
AQHNODE_DEVICE_LIST *deviceList;
deviceList=AqHomeNodes_ReadDataDeviceFiles();
if (deviceList==NULL) {
DBG_ERROR(NULL, "Error reading device list");
return GWEN_ERROR_GENERIC;
}
aqh->deviceDefList=deviceList;
return 0;
}
int _createPidFile(const char *pidFilename)
{
FILE *f;

View File

@@ -13,6 +13,7 @@
#include "./loop_broker.h"
#include "./aqhomed_p.h"
#include "./b_setdata.h"
#include "./tty_log.h"
#include "./db.h"
@@ -22,6 +23,7 @@
#include "aqhome/msg/msg_ping.h"
#include "aqhome/ipc/endpoint_ipc.h"
#include "aqhome/ipc/msg_ipc_result.h"
#include "aqhome/ipc/data/ipc_data.h"
#include <gwenhywfar/gwenhywfar.h>
#include <gwenhywfar/args.h>
@@ -43,6 +45,9 @@
*/
static void _handleIpcMsg(AQHOMED *aqh, GWEN_MSG_ENDPOINT *ep, GWEN_MSG *msg);
/* ------------------------------------------------------------------------------------------------
* implementations
@@ -62,7 +67,7 @@ void AqHomed_ReadAndHandleBrokerMessages(AQHOMED *aqh)
code=GWEN_IpcMsg_GetCode(msg);
DBG_DEBUG(AQH_LOGDOMAIN, "Received IPC packet %d (%x)", (int) code, code);
_handleIpcMsg(aqh, epTcp, msg);
GWEN_Msg_free(msg);
}
}
@@ -70,6 +75,24 @@ void AqHomed_ReadAndHandleBrokerMessages(AQHOMED *aqh)
void _handleIpcMsg(AQHOMED *aqh, GWEN_MSG_ENDPOINT *ep, GWEN_MSG *msg)
{
uint16_t code;
/* exec IPC message */
code=GWEN_IpcMsg_GetCode(msg);
DBG_DEBUG(AQH_LOGDOMAIN, "Received IPC packet");
switch(code) {
// case AQH_MSGTYPE_IPC_DATA_SETDATA: AqHomeNodes_HandleBrokerSetData(aqh, ep, msg); break;
default: break;
}
}

View File

@@ -13,7 +13,9 @@
#include "./aqhomed.h"
/**
* Handle messageexchange with the broker (aqhome-data).
*/
void AqHomed_ReadAndHandleBrokerMessages(AQHOMED *aqh);

View File

@@ -19,6 +19,7 @@
#include "aqhome/msg/endpoint_tty.h"
#include "aqhome/msg/msg_node.h"
#include "aqhome/msg/msg_value2.h"
#include "aqhome/msg/msg_value3.h"
#include "aqhome/msg/msg_ping.h"
#include "aqhome/ipc/endpoint_ipc.h"
#include "aqhome/ipc/nodes/ipc_nodes.h"
@@ -27,6 +28,8 @@
#include "aqhome/ipc/nodes/msg_ipc_ping.h"
#include "aqhome/ipc/nodes/msg_ipc_setaccmsggrps.h"
#include "aqhome/ipc/nodes/msg_ipc_getdevices_rsp.h"
#include "aqhome/ipc/data/ipc_data.h"
#include "aqhome/ipc/data/msg_data_set.h"
#include "aqhome/ipc/msg_ipc_result.h"
#include <gwenhywfar/gwenhywfar.h>
@@ -34,6 +37,8 @@
#include <gwenhywfar/debug.h>
#include <gwenhywfar/endpoint_tcpd.h>
#include <stdio.h>
/* ------------------------------------------------------------------------------------------------
@@ -52,11 +57,14 @@
*/
static void _handleIpcEndpoint(AQHOMED *aqh, GWEN_MSG_ENDPOINT *ep);
static void _handleIpcMsg(AQHOMED *aqh, GWEN_MSG_ENDPOINT *ep, const GWEN_MSG *msg);
static void _handleIpcMsg(AQHOMED *aqh, GWEN_MSG_ENDPOINT *ep, GWEN_MSG *msg);
void _handleIpcMsgPing(AQHOMED *aqh, GWEN_MSG_ENDPOINT *ep, const GWEN_MSG *msg);
void _handleIpcMsgSetAccMsgGrps(AQHOMED *aqh, GWEN_MSG_ENDPOINT *ep, const GWEN_MSG *msg);
void _handleIpcMsgForward(AQHOMED *aqh, GWEN_MSG_ENDPOINT *ep, const GWEN_MSG *msg);
void _handleIpcMsgGetDevicesReq(AQHOMED *aqh, GWEN_MSG_ENDPOINT *ep, const GWEN_MSG *msg);
void _handleIpcMsgSetData(AQHOMED *aqh, GWEN_MSG_ENDPOINT *ep, GWEN_MSG *msg);
static int _readDataFromString(const char *s, uint16_t *pDataVal, uint16_t *pValDenom);
static AQH_NODE_INFO *_getNodeInfoFromValue(AQHOMED *aqh, const AQH_VALUE *value);
@@ -93,18 +101,19 @@ void _handleIpcEndpoint(AQHOMED *aqh, GWEN_MSG_ENDPOINT *ep)
void _handleIpcMsg(AQHOMED *aqh, GWEN_MSG_ENDPOINT *ep, const GWEN_MSG *msg)
void _handleIpcMsg(AQHOMED *aqh, GWEN_MSG_ENDPOINT *ep, GWEN_MSG *msg)
{
uint16_t code;
/* exec IPC message */
code=GWEN_IpcMsg_GetCode(msg);
DBG_DEBUG(AQH_LOGDOMAIN, "Received IPC packet");
DBG_INFO(AQH_LOGDOMAIN, "Received IPC packet (%d, %04x)", code, code);
switch(code) {
case AQH_MSGTYPE_IPC_NODES_PING: _handleIpcMsgPing(aqh, ep, msg); break;
case AQH_MSGTYPE_IPC_NODES_SETACCMSGGRPS: _handleIpcMsgSetAccMsgGrps(aqh, ep, msg); break;
case AQH_MSGTYPE_IPC_NODES_FORWARD: _handleIpcMsgForward(aqh, ep, msg); break;
case AQH_MSGTYPE_IPC_NODES_GETDEVICES_REQ: _handleIpcMsgGetDevicesReq(aqh, ep, msg); break;
case AQH_MSGTYPE_IPC_DATA_SETDATA: _handleIpcMsgSetData(aqh, ep, msg); break;
default: break;
}
}
@@ -128,7 +137,7 @@ void _handleIpcMsgSetAccMsgGrps(AQHOMED *aqh, GWEN_MSG_ENDPOINT *ep, const GWEN_
{
uint32_t groups;
DBG_DEBUG(AQH_LOGDOMAIN, "Received IPC SET_ACCEPTED_MSG_GROUPS message");
DBG_INFO(AQH_LOGDOMAIN, "Received IPC SET_ACCEPTED_MSG_GROUPS message");
groups=AQH_SetAcceptedMsgGroupsIpcMsg_GetMsgGroups(msg);
AQH_IpcEndpoint_SetAcceptedMsgGroups(ep, groups);
// TODO: send response?
@@ -154,7 +163,7 @@ void _handleIpcMsgGetDevicesReq(AQHOMED *aqh, GWEN_MSG_ENDPOINT *ep, const GWEN_
{
AQH_NODE_INFO_LIST *nodeInfoList;
DBG_DEBUG(AQH_LOGDOMAIN, "Received IPC GetDevicesRequest message");
DBG_INFO(AQH_LOGDOMAIN, "Received IPC GetDevicesRequest message");
nodeInfoList=AQH_NodeDb_GetAllNodeInfos(aqh->nodeDb);
if (nodeInfoList && AQH_NodeInfo_List_GetCount(nodeInfoList)) {
const AQH_NODE_INFO *ni;
@@ -166,7 +175,9 @@ void _handleIpcMsgGetDevicesReq(AQHOMED *aqh, GWEN_MSG_ENDPOINT *ep, const GWEN_
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_NODES_GETDEVICES_RSP, niNext?0:AQH_MSGIPC_GETDEVICES_RSP_FLAGS_LAST, ni);
msgOut=AQH_GetDevicesResponseIpcMsg_new(AQH_MSGTYPE_IPC_NODES_GETDEVICES_RSP,
GWEN_MsgEndpoint_GetNextMessageId(ep), GWEN_IpcMsg_GetMsgId(msg),
niNext?0:AQH_MSGIPC_GETDEVICES_RSP_FLAGS_LAST, ni);
GWEN_MsgEndpoint_AddSendMessage(ep, msgOut);
ni=niNext;
}
@@ -175,13 +186,112 @@ void _handleIpcMsgGetDevicesReq(AQHOMED *aqh, GWEN_MSG_ENDPOINT *ep, const GWEN_
GWEN_MSG *msgOut;
DBG_INFO(AQH_LOGDOMAIN, "No nodes");
msgOut=AQH_ResultIpcMsg_new(AQH_MSGTYPE_IPC_NODES_RESULT, AQH_MSG_IPC_ERROR_NODATA);
msgOut=AQH_ResultIpcMsg_new(AQH_MSGTYPE_IPC_NODES_RESULT,
GWEN_MsgEndpoint_GetNextMessageId(ep), GWEN_IpcMsg_GetMsgId(msg),
AQH_MSG_IPC_ERROR_NODATA);
GWEN_MsgEndpoint_AddSendMessage(ep, msgOut);
}
}
void _handleIpcMsgSetData(AQHOMED *aqh, GWEN_MSG_ENDPOINT *ep, GWEN_MSG *msg)
{
if (aqh->ttyEndpoint && GWEN_MsgEndpoint_GetState(aqh->ttyEndpoint)==GWEN_MSG_ENDPOINT_STATE_CONNECTED) {
AQH_VALUE *value;
DBG_DEBUG(AQH_LOGDOMAIN, "Received IPC SetDataRequest message");
AQH_SetDataIpcMsg_Parse(msg, 0);
value=AQH_SetDataIpcMsg_ReadValue(msg);
if (value) {
char *data;
data=AQH_SetDataIpcMsg_ReadData(msg);
if (data) {
uint16_t dataVal=0;
uint16_t dataDenom=0;
if (_readDataFromString(data, &dataVal, &dataDenom)==0) {
AQH_NODE_INFO *nodeInfo;
nodeInfo=_getNodeInfoFromValue(aqh, value);
if (nodeInfo) {
int valueId=0;
const char *s;
s=AQH_Value_GetName(value);
if (s && *s && 1==sscanf(s, "%d", &valueId)) {
GWEN_MSG *msgOut;
int destAddr;
destAddr=AQH_NodeInfo_GetBusAddress(nodeInfo);
msgOut=AQH_Value3Msg_new(aqh->nodeAddress, destAddr, AQH_MSG_TYPE_VALUE_SET, 0 /* msgid*/, valueId, dataVal, dataDenom);
GWEN_MsgEndpoint_AddSendMessage(aqh->ttyEndpoint, msgOut);
}
else {
DBG_ERROR(AQH_LOGDOMAIN, "Invalid value id \"%s\"", s);
}
}
else {
DBG_ERROR(AQH_LOGDOMAIN, "No matching node found");
}
}
free(data);
}
AQH_Value_free(value);
}
else {
DBG_ERROR(AQH_LOGDOMAIN, "Could not read value from message");
}
}
}
int _readDataFromString(const char *s, uint16_t *pDataVal, uint16_t *pDataDenom)
{
if (s && *s) {
if (*s=='&') {
unsigned long int v=0;
s++;
if (1==sscanf(s, "%lx", &v)) {
*pDataVal=(v>>16) & 0xffff;
*pDataDenom=v & 0xffff;
return 0;
}
else {
DBG_ERROR(AQH_LOGDOMAIN, "Bad hex value \"%s\"", s);
}
}
}
return GWEN_ERROR_GENERIC;
}
AQH_NODE_INFO *_getNodeInfoFromValue(AQHOMED *aqh, const AQH_VALUE *value)
{
const char *s;
unsigned long int uid;
s=AQH_Value_GetDeviceName(value);
if (s && *s && 1==sscanf(s, "%lx", &uid)) {
AQH_NODE_INFO *ni;
ni=AQH_NodeDb_GetNodeInfoByUid(aqh->nodeDb, uid);
if (ni==NULL) {
DBG_INFO(AQH_LOGDOMAIN, "Node \"%08lx\" not found", uid);
return NULL;
}
return ni;
}
return NULL;
}

View File

@@ -48,13 +48,11 @@
* ------------------------------------------------------------------------------------------------
*/
static void _processValue2Message(AQHOMED *aqh, const GWEN_MSG *nodeMsg);
static void _processValue3Message(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 _publishInt(AQHOMED *aqh, uint32_t uid, int valueId, const char *valueUnits, const char *valuePath, int v);
static void _publishDouble(AQHOMED *aqh, uint32_t uid, int valueId, const char *valueUnits, const char *valuePath, double v);
static void _setValueNameForDriver(AQH_VALUE *value, int valueId, const char *valuePath);
static void _publishInt(AQHOMED *aqh, uint32_t uid, const char *vPath, int vModality, const char *vUnits, int v);
static void _publishDouble(AQHOMED *aqh, uint32_t uid, const char *vPath, int vType, const char *vUnits, double v);
static void _setDeviceName(AQH_VALUE *value, uint32_t uid);
@@ -69,9 +67,6 @@ void AqHomed_ForwardTtyMsgToBroker(AQHOMED *aqh, const GWEN_MSG *nodeMsg)
if (GWEN_MsgEndpoint_GetState(aqh->brokerEndpoint)==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_VALUE_REPORT:
_processValue3Message(aqh, nodeMsg);
break;
@@ -89,26 +84,39 @@ void AqHomed_ForwardTtyMsgToBroker(AQHOMED *aqh, const GWEN_MSG *nodeMsg)
void _processValue2Message(AQHOMED *aqh, const GWEN_MSG *nodeMsg)
{
_publishDouble(aqh,
AQH_Value2Msg_GetUid(nodeMsg),
AQH_Value2Msg_GetValueId(nodeMsg),
AQH_Value2Msg_GetValueTypeUnits(nodeMsg),
AQH_Value2Msg_GetValueTypeName(nodeMsg),
AQH_Value2Msg_GetValue(nodeMsg));
}
void _processValue3Message(AQHOMED *aqh, const GWEN_MSG *nodeMsg)
{
_publishDouble(aqh,
AQH_Value3Msg_GetUid(nodeMsg),
AQH_Value3Msg_GetValueId(nodeMsg),
AQH_Value3Msg_GetValueTypeUnits(nodeMsg),
AQH_Value3Msg_GetValueTypeName(nodeMsg),
AQH_Value3Msg_GetValue(nodeMsg));
uint32_t uid;
uint8_t valueId;
AQH_NODE_INFO *ni;
double v;
uid=AQH_Value3Msg_GetUid(nodeMsg);
valueId=AQH_Value3Msg_GetValueId(nodeMsg);
v=AQH_Value3Msg_GetValue(nodeMsg);
ni=AQH_NodeDb_GetNodeInfoByUid(aqh->nodeDb, uid);
if (ni) {
const char *devName;
devName=AQH_NodeInfo_GetDeviceId(ni);
if (devName) {
const AQHNODE_DEVICE *devInfo;
devInfo=AqHomed_GetDeviceDefByName(aqh, devName);
if (devInfo) {
const AQHNODE_VALUE *value;
value=AQHNODE_Value_List_GetById(AQHNODE_Device_GetValueList(devInfo), valueId);
if (value) {
const char *vname;
vname=AQHNODE_Value_GetName(value);
if (vname && *vname)
_publishDouble(aqh, uid, vname, AQHNODE_Value_GetModality(value), AQHNODE_Value_GetValueUnits(value), v);
}
}
}
}
}
@@ -119,12 +127,14 @@ void _processSendStatsMessage(AQHOMED *aqh, const GWEN_MSG *nodeMsg)
packetsOutInt=AQH_SendStatsMsg_GetPacketsOut(nodeMsg);
if (packetsOutInt) {
uint32_t uid;
double packetsOut;
double collisions;
double busy;
double collisionsPercentage=0.0;
double busyPercentage=0.0;
uid=AQH_SendStatsMsg_GetUid(nodeMsg);
packetsOut=/*(double)*/ packetsOutInt;
collisions=/*(double)*/ AQH_SendStatsMsg_GetCollisions(nodeMsg);
busy=/*(double)*/ AQH_SendStatsMsg_GetBusyErrors(nodeMsg);
@@ -132,10 +142,10 @@ void _processSendStatsMessage(AQHOMED *aqh, const GWEN_MSG *nodeMsg)
collisionsPercentage=collisions*100.0/packetsOut;
busyPercentage=busy*100.0/packetsOut;
_publishInt(aqh, AQH_SendStatsMsg_GetUid(nodeMsg), 0, NULL, "net/packetsOut", packetsOutInt);
_publishInt(aqh, AQH_SendStatsMsg_GetUid(nodeMsg), 0, NULL, "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);
_publishInt( aqh, uid, "net/packetsOut", 0, NULL, packetsOutInt);
_publishInt( aqh, uid, "net/collisions", 0, NULL, (int) AQH_SendStatsMsg_GetCollisions(nodeMsg));
_publishDouble(aqh, uid, "net/collisionsPercent", 0, "%", collisionsPercentage);
_publishDouble(aqh, uid, "net/busyPercent", 0, "%", busyPercentage);
}
}
@@ -147,12 +157,14 @@ void _processRecvStatsMessage(AQHOMED *aqh, const GWEN_MSG *nodeMsg)
packetsInInt=AQH_RecvStatsMsg_GetPacketsIn(nodeMsg);
if (packetsInInt) {
uint32_t uid;
double packetsIn;
double crcErrors;
double ioErrors;
double crcErrorsPercentage=0.0;
double ioErrorsPercentage=0.0;
uid=AQH_SendStatsMsg_GetUid(nodeMsg);
packetsIn=/*(double)*/ packetsInInt;
crcErrors=/*(double)*/AQH_RecvStatsMsg_GetCrcErrors(nodeMsg);
ioErrors=/*(double)*/AQH_RecvStatsMsg_GetIoErrors(nodeMsg);
@@ -160,24 +172,24 @@ void _processRecvStatsMessage(AQHOMED *aqh, const GWEN_MSG *nodeMsg)
crcErrorsPercentage=crcErrors*100.0/packetsIn;
ioErrorsPercentage=ioErrors*100.0/packetsIn;
_publishInt(aqh, AQH_RecvStatsMsg_GetUid(nodeMsg), 0, NULL, "net/packetsIn", packetsInInt);
_publishInt(aqh, AQH_RecvStatsMsg_GetUid(nodeMsg), 0, NULL, "net/crcerrors", (int) AQH_RecvStatsMsg_GetCrcErrors(nodeMsg));
_publishInt(aqh, AQH_RecvStatsMsg_GetUid(nodeMsg), 0, NULL, "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);
_publishInt( aqh, uid, "net/packetsIn", 0, NULL, packetsInInt);
_publishInt( aqh, uid, "net/crcerrors", 0, NULL, (int) AQH_RecvStatsMsg_GetCrcErrors(nodeMsg));
_publishInt( aqh, uid, "net/ioerrors", 0, NULL, (int) AQH_RecvStatsMsg_GetIoErrors(nodeMsg));
_publishDouble(aqh, uid, "net/crcerrorsPercent", 0, "%", crcErrorsPercentage);
_publishDouble(aqh, uid, "net/ioerrorsPercent", 0, "%", ioErrorsPercentage);
}
}
void _publishInt(AQHOMED *aqh, uint32_t uid, int valueId, const char *valueUnits, const char *valuePath, int v)
void _publishInt(AQHOMED *aqh, uint32_t uid, const char *vPath, int vModality, const char *vUnits, int v)
{
_publishDouble(aqh, uid, valueId, valueUnits, valuePath, /*(double)*/ v);
_publishDouble(aqh, uid, vPath, vModality, vUnits, /*(double)*/ v);
}
void _publishDouble(AQHOMED *aqh, uint32_t uid, int valueId, const char *valueUnits, const char *valuePath, double v)
void _publishDouble(AQHOMED *aqh, uint32_t uid, const char *vPath, int vModality, const char *vUnits, double v)
{
GWEN_MSG *pubMsg;
union {double f; uint64_t i;} u;
@@ -189,12 +201,14 @@ void _publishDouble(AQHOMED *aqh, uint32_t uid, int valueId, const char *valueUn
arrayToSend[1]=u.i;
value=AQH_Value_new();
_setValueNameForDriver(value, valueId, valuePath);
AQH_Value_SetValueUnits(value, valueUnits);
AQH_Value_SetValueType(value, 0);
_setDeviceName(value, uid);
AQH_Value_SetName(value, vPath);
AQH_Value_SetValueUnits(value, vUnits);
AQH_Value_SetValueType(value, vModality);
pubMsg=AQH_MultiDataDataIpcMsg_new(AQH_MSGTYPE_IPC_DATA_UPDATEDATA, value, arrayToSend, 1);
pubMsg=AQH_MultiDataDataIpcMsg_new(AQH_MSGTYPE_IPC_DATA_UPDATEDATA,
GWEN_MsgEndpoint_GetNextMessageId(aqh->brokerEndpoint), 0,
value, arrayToSend, 1);
if (pubMsg) {
DBG_INFO(AQH_LOGDOMAIN, "BROKER PUBLISH %s: %f", AQH_Value_GetName(value), v);
GWEN_MsgEndpoint_AddSendMessage(aqh->brokerEndpoint, pubMsg);
@@ -204,21 +218,6 @@ void _publishDouble(AQHOMED *aqh, uint32_t uid, int valueId, const char *valueUn
void _setValueNameForDriver(AQH_VALUE *value, int valueId, const char *valuePath)
{
GWEN_BUFFER *buf;
buf=GWEN_Buffer_new(0, 64, 0, 1);
if (valueId>0)
GWEN_Buffer_AppendArgs(buf, "%d/%s", valueId, valuePath);
else
GWEN_Buffer_AppendArgs(buf, "%s", valuePath);
AQH_Value_SetName(value, GWEN_Buffer_GetStart(buf));
GWEN_Buffer_free(buf);
}
void _setDeviceName(AQH_VALUE *value, uint32_t uid)
{
GWEN_BUFFER *buf;

View File

@@ -93,6 +93,7 @@ void _forwardValue2MsgToIpc(GWEN_MSG_ENDPOINT *ep, const GWEN_MSG *nodeMsg)
GWEN_MSG *ipcMsg;
ipcMsg=AQH_ValueIpcMsg_new(AQH_MSGTYPE_IPC_NODES_VALUE,
GWEN_MsgEndpoint_GetNextMessageId(ep), 0,
AQH_Value2Msg_GetUid(nodeMsg),
AQH_Value2Msg_GetValueId(nodeMsg),
AQH_Value2Msg_GetValueType(nodeMsg),
@@ -107,7 +108,9 @@ void _forwardAnyMsgToIpc(GWEN_MSG_ENDPOINT *ep, const GWEN_MSG *nodeMsg)
{
GWEN_MSG *ipcMsg;
ipcMsg=AQH_ForwardIpcMsg_new(AQH_MSGTYPE_IPC_NODES_FORWARD, GWEN_Msg_GetConstBuffer(nodeMsg), GWEN_Msg_GetBytesInBuffer(nodeMsg));
ipcMsg=AQH_ForwardIpcMsg_new(AQH_MSGTYPE_IPC_NODES_FORWARD,
GWEN_MsgEndpoint_GetNextMessageId(ep), 0,
GWEN_Msg_GetConstBuffer(nodeMsg), GWEN_Msg_GetBytesInBuffer(nodeMsg));
GWEN_MsgEndpoint_AddSendMessage(ep, ipcMsg);
}

View File

@@ -0,0 +1,73 @@
<?xml?>
<gwbuild>
<target type="ConvenienceLibrary" name="aqhnodes_types" >
<includes type="c" >
$(gwenhywfar_cflags)
-I$(topsrcdir)
-I$(topbuilddir)
-I$(topsrcdir)/apps
-I$(topbuilddir)/apps
-I$(builddir)
-I$(srcdir)
</includes>
<includes type="tm2" >
--include=$(builddir)
--include=$(srcdir)
</includes>
<setVar name="local/cflags">$(visibility_cflags)</setVar>
<setVar name="tm2flags" >
</setVar>
<setVar name="local/typefiles" >
device.t2d
value.t2d
</setVar>
<setVar name="local/built_sources" >
device.c
value.c
</setVar>
<setVar name="local/built_headers_pub">
</setVar>
<setVar name="local/built_headers_priv" >
device.h
device_p.h
value.h
value_p.h
</setVar>
<headers dist="true" >
</headers>
<sources>
$(local/typefiles)
</sources>
<useTargets>
</useTargets>
<libraries>
</libraries>
<subdirs>
</subdirs>
<extradist>
</extradist>
</target>
</gwbuild>

View File

@@ -0,0 +1,87 @@
<?xml?>
<tm2>
<type id="AQHNODE_DEVICE" type="pointer">
<descr>
This object and its objects are used to store registered devices and definitions for possible new devices.
</descr>
<lang id="c">
<identifier>AQHNODE_DEVICE</identifier>
<prefix>AQHNODE_Device</prefix>
<baseFileName>device</baseFileName>
<flags>
with_list1
with_list2
</flags>
<headers>
<header type="sys" loc="pre">aqhome/api.h</header>
<header type="sys" loc="pre">aqhome-nodes/types/value.h</header>
</headers>
<inlines>
</inlines>
</lang>
<enums>
</enums>
<members>
<member name="name" type="char_ptr" maxlen="128">
<default>NULL</default>
<preset>NULL</preset>
<access>public</access>
<flags>own with_getbymember</flags>
</member>
<member name="driver" type="char_ptr" maxlen="64">
<default>NULL</default>
<preset>NULL</preset>
<access>public</access>
<flags>own</flags>
</member>
<member name="manufacturer" type="uint32_t" maxlen="8">
<default>0</default>
<preset>0</preset>
<access>public</access>
<flags></flags>
</member>
<member name="deviceType" type="uint16_t" maxlen="8">
<default>0</default>
<preset>0</preset>
<access>public</access>
<flags></flags>
</member>
<member name="deviceVersion" type="uint16_t" maxlen="8">
<default>0</default>
<preset>0</preset>
<access>public</access>
<flags></flags>
</member>
<member name="valueList" type="AQHNODE_VALUE_LIST" >
<default>NULL</default>
<preset>NULL</preset>
<access>public</access>
<flags>own</flags>
<getflags>none</getflags>
<setflags>none</setflags>
</member>
</members>
</type>
</tm2>

View File

@@ -0,0 +1,87 @@
<?xml?>
<tm2>
<type id="AQHNODE_VALUE" type="pointer">
<descr>
</descr>
<lang id="c">
<identifier>AQHNODE_VALUE</identifier>
<prefix>AQHNODE_Value</prefix>
<baseFileName>value</baseFileName>
<flags>
with_xml
with_db
with_list1
with_list2
</flags>
<headers>
<header type="sys" loc="pre">aqhome/api.h</header>
</headers>
<inlines>
</inlines>
</lang>
<members>
<member name="id" type="int" maxlen="8">
<default>0</default>
<preset>0</preset>
<access>public</access>
<flags>with_getbymember</flags>
</member>
<member name="name" type="char_ptr" maxlen="32">
<default>0</default>
<preset>0</preset>
<access>public</access>
<flags>own with_getbymember</flags>
</member>
<member name="description" type="char_ptr" maxlen="256">
<default>0</default>
<preset>0</preset>
<access>public</access>
<flags>own</flags>
</member>
<member name="valueType" type="int" maxlen="8">
<default>0</default>
<preset>0</preset>
<access>public</access>
<flags></flags>
</member>
<member name="dataType" type="int" maxlen="8">
<default>0</default>
<preset>0</preset>
<access>public</access>
<flags></flags>
</member>
<member name="modality" type="int" maxlen="8">
<default>0</default>
<preset>0</preset>
<access>public</access>
<flags></flags>
</member>
<member name="valueUnits" type="char_ptr" maxlen="32">
<default>0</default>
<preset>0</preset>
<access>public</access>
<flags>own</flags>
</member>
</members>
</type>
</tm2>