Heavy work on IPC.

We will now have a broker (aqhome-data) which stores data and distributes
value change messages among connected clients.
aqhomed will connect to that broker and send its values there.
aqhome-mqtt will also connect to the broker and send its values there.
Other clients can later connect to check for changes and react according
to rules.
This commit is contained in:
Martin Preuss
2023-09-10 23:13:03 +02:00
parent 2b733a52ca
commit 518a3a53f9
43 changed files with 1412 additions and 707 deletions

View File

@@ -6,7 +6,6 @@
aqhomed
aqhome-tool
aqhome-mqttlog
aqhome-storage
aqhome-data
</subdirs>

View File

@@ -40,6 +40,11 @@
fini.h
init.h
loop.h
c_connect.h
c_updatedata.h
c_getvalues.h
c_getdatapoints.h
c_getlastdatapoint.h
</headers>
<sources>
@@ -49,6 +54,11 @@
fini.c
init.c
loop.c
c_connect.c
c_updatedata.c
c_getvalues.c
c_getdatapoints.c
c_getlastdatapoint.c
main.c
</sources>

View File

@@ -12,6 +12,7 @@
#include "./aqhome_data_p.h"
#include "aqhome/ipc/endpoint_ipc.h"
#include <gwenhywfar/misc.h>
#include <gwenhywfar/debug.h>
@@ -111,6 +112,23 @@ int AqHomeData_UnlockStorage(AQHOME_DATA *aqh)
GWEN_MSG_ENDPOINT *AqHomeData_GetIpcEndpointByServiceName(const AQHOME_DATA *aqh, const char *serviceName)
{
GWEN_MSG_ENDPOINT *ep;
ep=GWEN_MsgEndpoint_Tree2_GetFirstChild(aqh->ipcdEndpoint);
while(ep) {
const char *s;
s=AQH_IpcEndpoint_GetServiceName(ep);
if (s && *s && strcasecmp(s, serviceName)==0)
return ep;
ep=GWEN_MsgEndpoint_Tree2_GetNext(ep);
}
return NULL;
}

View File

@@ -24,6 +24,8 @@ void AqHomeData_free(AQHOME_DATA *aqh);
GWEN_MSG_ENDPOINT *AqHomeData_GetIpcdEndpoint(const AQHOME_DATA *aqh);
GWEN_MSG_ENDPOINT *AqHomeData_GetIpcEndpointByServiceName(const AQHOME_DATA *aqh, const char *serviceName);
GWEN_DB_NODE *AqHomeData_GetDbArgs(const AQHOME_DATA *aqh);
AQH_STORAGE *AqHomeData_GetStorage(const AQHOME_DATA *aqh);

View File

@@ -0,0 +1,93 @@
/****************************************************************************
* 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 "./c_connect.h"
#include "./aqhome_data_p.h"
#include "aqhome/ipc/data/ipc_data.h"
#include "aqhome/ipc/endpoint_ipc.h"
#include "aqhome/ipc/msg_ipc_result.h"
#include "aqhome/ipc/data/msg_data_connect.h"
#include "aqhome/ipc/msg_ipc_tag16.h"
#include <gwenhywfar/debug.h>
/* ------------------------------------------------------------------------------------------------
* defines
* ------------------------------------------------------------------------------------------------
*/
/* ------------------------------------------------------------------------------------------------
* forward declarations
* ------------------------------------------------------------------------------------------------
*/
/* ------------------------------------------------------------------------------------------------
* implementations
* ------------------------------------------------------------------------------------------------
*/
void AqHomeData_HandleConnect(AQHOME_DATA *aqh, GWEN_MSG_ENDPOINT *ep, const GWEN_MSG *msg)
{
GWEN_MSG *outMsg;
int resultCode=AQH_MSG_IPC_SUCCESS;
GWEN_TAG16_LIST *tagList;
char *clientId=NULL;
char *userId=NULL;
char *passw=NULL;
tagList=AQH_Tag16IpcMsg_ParseTags(msg, 0);
if (tagList) {
const GWEN_TAG16 *tag;
tag=GWEN_Tag16_List_FindFirstByTagType(tagList, AQH_MSGDATA_CONNECT_TAGS_CLIENTID);
clientId=tag?GWEN_Tag16_GetTagDataAsNewString(tag, NULL):NULL;
tag=GWEN_Tag16_List_FindFirstByTagType(tagList, AQH_MSGDATA_CONNECT_TAGS_USERID);
userId=tag?GWEN_Tag16_GetTagDataAsNewString(tag, NULL):NULL;
tag=GWEN_Tag16_List_FindFirstByTagType(tagList, AQH_MSGDATA_CONNECT_TAGS_PASSWORD);
passw=tag?GWEN_Tag16_GetTagDataAsNewString(tag, NULL):NULL;
}
if (clientId)
AQH_IpcEndpoint_SetServiceName(ep, clientId);
if (userId)
AQH_IpcEndpoint_SetUserName(ep, userId);
/* TODO: add user management, for now we allow all */
AQH_IpcEndpoint_SetPermissions(ep,
AQH_IPCENDPOINT_PERMS_LISTVALUES |
AQH_IPCENDPOINT_PERMS_READVALUE |
AQH_IPCENDPOINT_PERMS_ADDVALUE |
AQH_IPCENDPOINT_PERMS_LISTDATA |
AQH_IPCENDPOINT_PERMS_READDATA |
AQH_IPCENDPOINT_PERMS_ADDDATA);
free(passw);
free(userId);
free(clientId);
GWEN_Tag16_List_free(tagList);
outMsg=AQH_ResultIpcMsg_new(AQH_MSGTYPE_IPC_DATA_RESULT, resultCode);
GWEN_MsgEndpoint_AddSendMessage(ep, outMsg);
}

View File

@@ -6,19 +6,14 @@
* should have received along with this file.
****************************************************************************/
#ifndef AQH_MSG_IPC_DATA_GETVALUES_REQ_H
#define AQH_MSG_IPC_DATA_GETVALUES_REQ_H
#ifndef AQHOME_DATA_C_CONNECT_H
#define AQHOME_DATA_C_CONNECT_H
#include <aqhome/api.h>
#include <gwenhywfar/msg_ipc.h>
AQHOME_API GWEN_MSG *AQH_GetValuesReqDataIpcMsg_new(uint16_t code);
#include "./aqhome_data.h"
void AqHomeData_HandleConnect(AQHOME_DATA *aqh, GWEN_MSG_ENDPOINT *ep, const GWEN_MSG *msg);
@@ -26,3 +21,5 @@ AQHOME_API GWEN_MSG *AQH_GetValuesReqDataIpcMsg_new(uint16_t code);

View File

@@ -0,0 +1,117 @@
/****************************************************************************
* 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 "./c_getdatapoints.h"
#include "./aqhome_data_p.h"
#include "aqhome/ipc/data/ipc_data.h"
#include "aqhome/ipc/data/msg_data_datapoints.h"
#include "aqhome/ipc/msg_ipc_result.h"
#include <gwenhywfar/debug.h>
/* ------------------------------------------------------------------------------------------------
* defines
* ------------------------------------------------------------------------------------------------
*/
#define AQHOMEDATA_HANDLEGETDATAPOINTS_MAXTABLEENTRIES 2048
/* ------------------------------------------------------------------------------------------------
* forward declarations
* ------------------------------------------------------------------------------------------------
*/
/* ------------------------------------------------------------------------------------------------
* implementations
* ------------------------------------------------------------------------------------------------
*/
void AqHomeData_HandleGetDataPoints(AQHOME_DATA *aqh, GWEN_MSG_ENDPOINT *ep, const GWEN_MSG *recvdMsg)
{
GWEN_MSG *outMsg;
int resultCode=0;
if (AQH_DataPointsDataIpcMsg_IsValid(recvdMsg)) {
const char *valueName;
valueName=AQH_DataPointsDataIpcMsg_GetValueName(recvdMsg);
if (valueName) {
const AQH_VALUE *value;
value=AQH_Storage_GetValueByNameForSystem(aqh->storage, valueName);
if (value) {
uint64_t valueId;
uint32_t numValues;
uint64_t tsBegin=0;
uint64_t tsEnd=0;
uint64_t *tablePtr;
valueId=AQH_Value_GetId(value);
numValues=AQH_DataPointsDataIpcMsg_GetNumValues(recvdMsg);
if (numValues==1) {
const uint64_t *dataPoints;
dataPoints=AQH_DataPointsDataIpcMsg_GetDataPoints(recvdMsg);
tsBegin=dataPoints[0];
tsEnd=dataPoints[1];
}
tablePtr=AQH_Storage_GetDataPoints(aqh->storage, valueId, tsBegin, tsEnd, AQHOMEDATA_HANDLEGETDATAPOINTS_MAXTABLEENTRIES);
if (tablePtr) {
int numTableEntries;
int numDataPoints;
numTableEntries=(int)(tablePtr[0]);
numDataPoints=numTableEntries/2;
outMsg=AQH_DataPointsDataIpcMsg_new(AQH_MSGTYPE_IPC_DATA_GETDATA_RSP, AQH_MSGDATA_DATAPOINTS_FLAGS_LASTMSG,
valueId,
AQH_Value_GetNameForSystem(value),
AQH_Value_GetValueUnits(value),
&(tablePtr[1]), numDataPoints);
GWEN_MsgEndpoint_AddSendMessage(ep, outMsg);
free(tablePtr);
return;
}
else {
DBG_INFO(NULL, "No matching datapoints for value \"%s\"", valueName);
resultCode=AQH_MSG_IPC_ERROR_NODATA;
}
}
else {
DBG_INFO(NULL, "Value \"%s\" not found", valueName);
resultCode=AQH_MSG_IPC_ERROR_NOTFOUND;
}
}
else {
DBG_INFO(NULL, "No value name in request");
resultCode=AQH_MSG_IPC_ERROR_INVALID;
}
}
else {
DBG_INFO(NULL, "Invalid request message");
resultCode=AQH_MSG_IPC_ERROR_INVALID;
}
outMsg=AQH_ResultIpcMsg_new(AQH_MSGTYPE_IPC_DATA_RESULT, resultCode);
GWEN_MsgEndpoint_AddSendMessage(ep, outMsg);
}

View File

@@ -0,0 +1,25 @@
/****************************************************************************
* 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 AQHOME_DATA_C_GETDATAPOINTS_H
#define AQHOME_DATA_C_GETDATAPOINTS_H
#include "./aqhome_data.h"
void AqHomeData_HandleGetDataPoints(AQHOME_DATA *aqh, GWEN_MSG_ENDPOINT *ep, const GWEN_MSG *msg);
#endif

View File

@@ -0,0 +1,48 @@
/****************************************************************************
* 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 "./c_getlastdatapoint.h"
#include "./aqhome_data_p.h"
#include "aqhome/ipc/data/ipc_data.h"
#include "aqhome/ipc/data/msg_data_values.h"
#include "aqhome/ipc/msg_ipc_result.h"
#include <gwenhywfar/debug.h>
/* ------------------------------------------------------------------------------------------------
* defines
* ------------------------------------------------------------------------------------------------
*/
/* ------------------------------------------------------------------------------------------------
* forward declarations
* ------------------------------------------------------------------------------------------------
*/
/* ------------------------------------------------------------------------------------------------
* implementations
* ------------------------------------------------------------------------------------------------
*/
void AqHomeData_HandleGetLastDataPoint(AQHOME_DATA *aqh, GWEN_MSG_ENDPOINT *ep, const GWEN_MSG *msg)
{
}

View File

@@ -0,0 +1,25 @@
/****************************************************************************
* 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 AQHOME_DATA_C_GETLASTDATAPOINT_H
#define AQHOME_DATA_C_GETLASTDATAPOINT_H
#include "./aqhome_data.h"
void AqHomeData_HandleGetLastDataPoint(AQHOME_DATA *aqh, GWEN_MSG_ENDPOINT *ep, const GWEN_MSG *msg);
#endif

View File

@@ -0,0 +1,96 @@
/****************************************************************************
* 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 "./c_getvalues.h"
#include "./aqhome_data_p.h"
#include "aqhome/ipc/data/ipc_data.h"
#include "aqhome/ipc/data/msg_data_values.h"
#include "aqhome/ipc/msg_ipc_result.h"
#include <gwenhywfar/debug.h>
/* ------------------------------------------------------------------------------------------------
* defines
* ------------------------------------------------------------------------------------------------
*/
#define AQHOMEDATA_VALUESPERMSG 10
/* ------------------------------------------------------------------------------------------------
* forward declarations
* ------------------------------------------------------------------------------------------------
*/
static void _sendValueList(AQHOME_DATA *aqh, GWEN_MSG_ENDPOINT *ep, const AQH_VALUE_LIST *vl, uint32_t flags);
/* ------------------------------------------------------------------------------------------------
* implementations
* ------------------------------------------------------------------------------------------------
*/
void AqHomeData_HandleGetValues(AQHOME_DATA *aqh, GWEN_MSG_ENDPOINT *ep, const GWEN_MSG *msg)
{
const AQH_VALUE_LIST *origValueList;
origValueList=AQH_Storage_GetValueList(aqh->storage);
if (origValueList) {
if (AQH_Value_List_GetCount(origValueList)<AQHOMEDATA_VALUESPERMSG)
_sendValueList(aqh, ep, origValueList, AQH_MSGDATA_VALUES_FLAGS_LASTMSG);
else {
AQH_VALUE_LIST *tmpValueList;
const AQH_VALUE *v;
tmpValueList=AQH_Value_List_new();
v=AQH_Value_List_First(origValueList);
while(v) {
const AQH_VALUE *next;
AQH_VALUE *copyOfValue;
next=AQH_Value_List_Next(v);
copyOfValue=AQH_Value_dup(v);
AQH_Value_List_Add(copyOfValue, tmpValueList);
if (AQH_Value_List_GetCount(tmpValueList)>=AQHOMEDATA_VALUESPERMSG) {
_sendValueList(aqh, ep, tmpValueList, next?0:AQH_MSGDATA_VALUES_FLAGS_LASTMSG);
AQH_Value_List_Clear(tmpValueList);
}
v=next;
}
if (AQH_Value_List_GetCount(tmpValueList))
_sendValueList(aqh, ep, tmpValueList, AQH_MSGDATA_VALUES_FLAGS_LASTMSG); /* send remaining */
AQH_Value_List_free(tmpValueList);
}
}
else {
/* empty list */
_sendValueList(aqh, ep, NULL, AQH_MSGDATA_VALUES_FLAGS_LASTMSG);
}
}
void _sendValueList(AQHOME_DATA *aqh, GWEN_MSG_ENDPOINT *ep, const AQH_VALUE_LIST *vl, uint32_t flags)
{
GWEN_MSG *msg;
msg=AQH_ValuesDataIpcMsg_new(AQH_MSGTYPE_IPC_DATA_GETVALUES_RSP, flags, vl, 1);
GWEN_MsgEndpoint_AddSendMessage(ep, msg);
}

View File

@@ -0,0 +1,25 @@
/****************************************************************************
* 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 AQHOME_DATA_C_GETVALUES_H
#define AQHOME_DATA_C_GETVALUES_H
#include "./aqhome_data.h"
void AqHomeData_HandleGetValues(AQHOME_DATA *aqh, GWEN_MSG_ENDPOINT *ep, const GWEN_MSG *msg);
#endif

View File

@@ -0,0 +1,210 @@
/****************************************************************************
* 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 "./c_updatedata.h"
#include "./aqhome_data_p.h"
#include "aqhome/ipc/data/ipc_data.h"
#include "aqhome/ipc/data/msg_data_datapoints.h"
#include "aqhome/ipc/endpoint_ipc.h"
#include "aqhome/ipc/msg_ipc_result.h"
#include <gwenhywfar/debug.h>
/* ------------------------------------------------------------------------------------------------
* defines
* ------------------------------------------------------------------------------------------------
*/
/* ------------------------------------------------------------------------------------------------
* forward declarations
* ------------------------------------------------------------------------------------------------
*/
static int _readDataPoints(AQHOME_DATA *aqh, const AQH_VALUE *v, const uint64_t *dataPoints, uint32_t numValues);
static void _sendDataChangedMsgToAllClients(AQHOME_DATA *aqh, GWEN_MSG_ENDPOINT *epSrc, const AQH_VALUE *v,
const uint64_t *dataPoints, uint32_t numValues);
static AQH_VALUE *_getOrCreateValue(AQHOME_DATA *aqh, GWEN_MSG_ENDPOINT *ep, const char *nameForDriver, const char *units);
/* ------------------------------------------------------------------------------------------------
* implementations
* ------------------------------------------------------------------------------------------------
*/
void AqHomeData_HandleUpdateData(AQHOME_DATA *aqh, GWEN_MSG_ENDPOINT *ep, const GWEN_MSG *recvdMsg)
{
GWEN_MSG *outMsg;
int resultCode=AQH_MSG_IPC_SUCCESS;
if (AQH_IpcEndpoint_GetPermissions(ep) & AQH_IPCENDPOINT_PERMS_ADDDATA) {
if (AQH_DataPointsDataIpcMsg_IsValid(recvdMsg)) {
uint32_t numValues;
numValues=AQH_DataPointsDataIpcMsg_GetNumValues(recvdMsg);
if (numValues) {
const char *s;
s=AQH_DataPointsDataIpcMsg_GetValueName(recvdMsg);
if (s && *s) {
AQH_VALUE *v;
v=_getOrCreateValue(aqh, ep, s, AQH_DataPointsDataIpcMsg_GetUnits(recvdMsg));
if (v==NULL) {
resultCode=AQH_MSG_IPC_ERROR_PERMS;
}
else {
const uint64_t *dataPoints;
dataPoints=AQH_DataPointsDataIpcMsg_GetDataPoints(recvdMsg);
if (dataPoints)
resultCode=_readDataPoints(aqh, v, dataPoints, numValues);
else {
DBG_INFO(NULL, "No datapoints");
resultCode=AQH_MSG_IPC_ERROR_BADDATA;
}
if (resultCode==AQH_MSG_IPC_SUCCESS)
_sendDataChangedMsgToAllClients(aqh, ep, v, dataPoints, numValues);
}
}
else {
DBG_INFO(NULL, "Value without name ");
resultCode=AQH_MSG_IPC_ERROR_INVALID;
}
}
else {
DBG_INFO(NULL, "No datapoints");
resultCode=AQH_MSG_IPC_ERROR_BADDATA;
}
}
else {
DBG_INFO(NULL, "Invalid message received");
resultCode=AQH_MSG_IPC_ERROR_BADDATA;
}
}
else {
DBG_ERROR(AQH_LOGDOMAIN, "No permissions to add data");
resultCode=AQH_MSG_IPC_ERROR_PERMS;
}
outMsg=AQH_ResultIpcMsg_new(AQH_MSGTYPE_IPC_DATA_RESULT, resultCode);
GWEN_MsgEndpoint_AddSendMessage(ep, outMsg);
}
int _readDataPoints(AQHOME_DATA *aqh, const AQH_VALUE *v, const uint64_t *dataPoints, uint32_t numValues)
{
uint32_t i;
for(i=0; i<numValues; i++) {
uint64_t timestamp;
union {double f; uint64_t i;} u;
int rv;
timestamp=*(dataPoints++);
u.i=*(dataPoints++);
rv=AQH_Storage_AddDatapoint(aqh->storage, AQH_Value_GetId(v), timestamp, u.f);
if (rv<0) {
DBG_INFO(NULL, "here (%d)", rv);
return AQH_MSG_IPC_ERROR_GENERIC;
}
else {
DBG_INFO(NULL, "Datapoint added for value \"%s\"", AQH_Value_GetNameForSystem(v));
}
} /* for */
return AQH_MSG_IPC_SUCCESS;
}
void _sendDataChangedMsgToAllClients(AQHOME_DATA *aqh, GWEN_MSG_ENDPOINT *epSrc, const AQH_VALUE *v,
const uint64_t *dataPoints, uint32_t numValues)
{
GWEN_MSG_ENDPOINT *ep;
ep=GWEN_MsgEndpoint_Tree2_GetFirstChild(aqh->ipcdEndpoint);
while(ep) {
if (ep!=epSrc) {
if (GWEN_MsgEndpoint_GetFlags(ep) & AQH_IPCENDPOINT_FLAGS_WANTUPDATES) {
GWEN_MSG *msg;
DBG_INFO(AQH_LOGDOMAIN, "Sending update msg to endpoint %s", GWEN_MsgEndpoint_GetName(ep));
msg=AQH_DataPointsDataIpcMsg_new(AQH_MSGTYPE_IPC_DATA_DATACHANGED,
0, /* flags */
AQH_Value_GetId(v),
AQH_Value_GetNameForSystem(v),
AQH_Value_GetValueUnits(v),
dataPoints, numValues);
GWEN_MsgEndpoint_AddSendMessage(ep, msg);
}
else {
DBG_INFO(AQH_LOGDOMAIN, "Endpoint %s doesn't want updates", GWEN_MsgEndpoint_GetName(ep));
}
}
else {
DBG_INFO(AQH_LOGDOMAIN, "Not sending update msg to source of updates");
}
ep=GWEN_MsgEndpoint_Tree2_GetNext(ep);
}
}
AQH_VALUE *_getOrCreateValue(AQHOME_DATA *aqh, GWEN_MSG_ENDPOINT *ep, const char *nameForDriver, const char *units)
{
const char *serviceName;
AQH_VALUE *v;
GWEN_BUFFER *buf;
serviceName=AQH_IpcEndpoint_GetServiceName(ep);
buf=GWEN_Buffer_new(0, 256, 0, 1);
if (serviceName && *serviceName) {
GWEN_Buffer_AppendString(buf, serviceName);
GWEN_Buffer_AppendString(buf, "/");
}
else {
GWEN_Buffer_AppendString(buf, "unknown/");
}
GWEN_Buffer_AppendString(buf, nameForDriver);
v=AQH_Storage_GetValueByNameForSystem(aqh->storage, GWEN_Buffer_GetStart(buf));
if (v==NULL) {
if (AQH_IpcEndpoint_GetPermissions(ep) & AQH_IPCENDPOINT_PERMS_ADDVALUE) {
DBG_INFO(AQH_LOGDOMAIN, "Creating value \"%s\"", GWEN_Buffer_GetStart(buf));
v=AQH_Value_new();
AQH_Value_SetDriver(v, serviceName);
AQH_Value_SetNameForDriver(v, nameForDriver);
AQH_Value_SetNameForSystem(v, GWEN_Buffer_GetStart(buf));
AQH_Value_SetValueUnits(v, units);
AQH_Storage_AddValue(aqh->storage, v);
}
else {
DBG_ERROR(AQH_LOGDOMAIN, "No permissions to create value \"%s\"", GWEN_Buffer_GetStart(buf));
GWEN_Buffer_free(buf);
return NULL;
}
}
GWEN_Buffer_free(buf);
return v;
}

View File

@@ -0,0 +1,25 @@
/****************************************************************************
* 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 AQHOME_DATA_C_UPDATEDATA_H
#define AQHOME_DATA_C_UPDATEDATA_H
#include "./aqhome_data.h"
void AqHomeData_HandleUpdateData(AQHOME_DATA *aqh, GWEN_MSG_ENDPOINT *ep, const GWEN_MSG *recvdMsg);
#endif

View File

@@ -12,6 +12,11 @@
#include "./loop.h"
#include "./c_connect.h"
#include "./c_updatedata.h"
#include "./c_getdatapoints.h"
#include "./c_getlastdatapoint.h"
#include "./c_getvalues.h"
#include "./aqhome_data_p.h"
#include "aqhome/ipc/data/ipc_data.h"
#include "aqhome/ipc/data/msg_data_values.h"
@@ -31,8 +36,6 @@
* ------------------------------------------------------------------------------------------------
*/
#define AQHOMEDATA_VALUESPERMSG 10
/* ------------------------------------------------------------------------------------------------
@@ -44,14 +47,6 @@ static void _readAndHandleIpcMessages(AQHOME_DATA *aqh);
static void _handleIpcEndpoint(AQHOME_DATA *aqh, GWEN_MSG_ENDPOINT *ep);
static void _handleIpcMsg(AQHOME_DATA *aqh, GWEN_MSG_ENDPOINT *ep, const GWEN_MSG *msg);
static void _handleGetValues(AQHOME_DATA *aqh, GWEN_MSG_ENDPOINT *ep, const GWEN_MSG *msg);
static void _sendValueList(AQHOME_DATA *aqh, GWEN_MSG_ENDPOINT *ep, const AQH_VALUE_LIST *vl, uint32_t flags);
static void _handleAddValue(AQHOME_DATA *aqh, GWEN_MSG_ENDPOINT *ep, const GWEN_MSG *msg);
static void _handleEditValues(AQHOME_DATA *aqh, GWEN_MSG_ENDPOINT *ep, const GWEN_MSG *msg);
static void _handleAddDataPoints(AQHOME_DATA *aqh, GWEN_MSG_ENDPOINT *ep, const GWEN_MSG *msg);
static void _handleGetDataPoints(AQHOME_DATA *aqh, GWEN_MSG_ENDPOINT *ep, const GWEN_MSG *msg);
static void _handleGetLastDataPoint(AQHOME_DATA *aqh, GWEN_MSG_ENDPOINT *ep, const GWEN_MSG *msg);
/* ------------------------------------------------------------------------------------------------
@@ -134,260 +129,14 @@ void _handleIpcMsg(AQHOME_DATA *aqh, GWEN_MSG_ENDPOINT *ep, const GWEN_MSG *msg)
code=GWEN_IpcMsg_GetCode(msg);
DBG_ERROR(AQH_LOGDOMAIN, "Received IPC packet %d", (int) code);
switch(code) {
case AQH_MSGTYPE_IPC_DATA_GETVALUES_REQ: _handleGetValues(aqh, ep, msg); break;
case AQH_MSGTYPE_IPC_DATA_ADDVALUES_REQ: _handleAddValue(aqh, ep, msg); break;
case AQH_MSGTYPE_IPC_DATA_EDITVALUE_REQ: _handleEditValues(aqh, ep, msg); break;
case AQH_MSGTYPE_IPC_DATA_ADDDATAPOINTS_REQ: _handleAddDataPoints(aqh, ep, msg); break;
case AQH_MSGTYPE_IPC_DATA_GETDATAPOINTS_REQ: _handleGetDataPoints(aqh, ep, msg); break;
case AQH_MSGTYPE_IPC_DATA_GETLASTDATAPOINT_REQ: _handleGetLastDataPoint(aqh, ep, msg); break;
case AQH_MSGTYPE_IPC_DATA_CONNECT_REQ: AqHomeData_HandleConnect(aqh, ep, msg); break;
case AQH_MSGTYPE_IPC_DATA_UPDATEDATA: AqHomeData_HandleUpdateData(aqh, ep, msg); break;
case AQH_MSGTYPE_IPC_DATA_GETVALUES_REQ: AqHomeData_HandleGetValues(aqh, ep, msg); break;
case AQH_MSGTYPE_IPC_DATA_GETDATA_REQ: AqHomeData_HandleGetDataPoints(aqh, ep, msg); break;
case AQH_MSGTYPE_IPC_DATA_GETLASTDATAPOINT_REQ: AqHomeData_HandleGetLastDataPoint(aqh, ep, msg); break;
default: break;
}
}
void _handleGetValues(AQHOME_DATA *aqh, GWEN_MSG_ENDPOINT *ep, const GWEN_MSG *msg)
{
const AQH_VALUE_LIST *origValueList;
origValueList=AQH_Storage_GetValueList(aqh->storage);
if (origValueList) {
if (AQH_Value_List_GetCount(origValueList)<AQHOMEDATA_VALUESPERMSG)
_sendValueList(aqh, ep, origValueList, AQH_MSGDATA_VALUES_FLAGS_LASTMSG);
else {
AQH_VALUE_LIST *tmpValueList;
const AQH_VALUE *v;
tmpValueList=AQH_Value_List_new();
v=AQH_Value_List_First(origValueList);
while(v) {
const AQH_VALUE *next;
AQH_VALUE *copyOfValue;
next=AQH_Value_List_Next(v);
copyOfValue=AQH_Value_dup(v);
AQH_Value_List_Add(copyOfValue, tmpValueList);
if (AQH_Value_List_GetCount(tmpValueList)>=AQHOMEDATA_VALUESPERMSG) {
_sendValueList(aqh, ep, tmpValueList, next?0:AQH_MSGDATA_VALUES_FLAGS_LASTMSG);
AQH_Value_List_Clear(tmpValueList);
}
v=next;
}
if (AQH_Value_List_GetCount(tmpValueList))
_sendValueList(aqh, ep, tmpValueList, AQH_MSGDATA_VALUES_FLAGS_LASTMSG); /* send remaining */
AQH_Value_List_free(tmpValueList);
}
}
else {
/* empty list */
_sendValueList(aqh, ep, NULL, AQH_MSGDATA_VALUES_FLAGS_LASTMSG);
}
}
void _sendValueList(AQHOME_DATA *aqh, GWEN_MSG_ENDPOINT *ep, const AQH_VALUE_LIST *vl, uint32_t flags)
{
GWEN_MSG *msg;
msg=AQH_ValuesDataIpcMsg_new(AQH_MSGTYPE_IPC_DATA_GETVALUES_RSP, flags, vl);
GWEN_MsgEndpoint_AddSendMessage(ep, msg);
}
void _handleAddValue(AQHOME_DATA *aqh, GWEN_MSG_ENDPOINT *ep, const GWEN_MSG *recvdMsg)
{
GWEN_MSG *outMsg;
int resultCode=0;
if (AQH_ValuesDataIpcMsg_IsValid(recvdMsg)) {
uint32_t numValues;
numValues=AQH_ValuesDataIpcMsg_GetNumValues(recvdMsg);
if (numValues==1) {
const char *s;
s=AQH_ValuesDataIpcMsg_GetValueName(recvdMsg, 0);
if (s && *s) {
if (AQH_Storage_GetValueByName(aqh->storage, s)==NULL) {
AQH_VALUE *v;
v=AQH_Value_new();
AQH_Value_SetName(v, s);
s=AQH_ValuesDataIpcMsg_GetValueUnits(recvdMsg, 0);
if (s && *s)
AQH_Value_SetValueUnits(v, s);
DBG_INFO(NULL, "Adding value \"%s\" (%s)", AQH_Value_GetName(v), AQH_Value_GetValueUnits(v));
AQH_Storage_AddValue(aqh->storage, v);
AQH_Storage_AddRuntimeFlags(aqh->storage, AQH_STORAGE_RTFLAGS_MODIFIED);
resultCode=AQH_MSG_IPC_SUCCESS;
}
else {
DBG_INFO(NULL, "Value \"%s\" already exists", s);
resultCode=AQH_MSG_IPC_ERROR_EXISTS;
}
}
else {
DBG_INFO(NULL, "Value without name ");
resultCode=AQH_MSG_IPC_ERROR_INVALID;
}
}
else {
DBG_INFO(NULL, "Invalid number of values in message (%d)", numValues);
resultCode=AQH_MSG_IPC_ERROR_INVALID;
}
}
else {
DBG_INFO(NULL, "Invalid message received");
resultCode=AQH_MSG_IPC_ERROR_BADDATA;
}
outMsg=AQH_ResultIpcMsg_new(AQH_MSGTYPE_IPC_DATA_RESULT, resultCode);
GWEN_MsgEndpoint_AddSendMessage(ep, outMsg);
}
void _handleEditValues(AQHOME_DATA *aqh, GWEN_MSG_ENDPOINT *ep, const GWEN_MSG *recvdMsg)
{
GWEN_MSG *outMsg;
int resultCode=0;
if (AQH_ValuesDataIpcMsg_IsValid(recvdMsg)) {
uint32_t numValues;
numValues=AQH_ValuesDataIpcMsg_GetNumValues(recvdMsg);
if (numValues==1) {
const char *s;
s=AQH_ValuesDataIpcMsg_GetValueName(recvdMsg, 0);
if (s && *s) {
AQH_VALUE *v;
v=AQH_Storage_GetValueByName(aqh->storage, s);
if (v==NULL) {
DBG_INFO(NULL, "Value \"%s\" doesn't not exist", s);
resultCode=AQH_MSG_IPC_ERROR_EXISTS;
}
else {
DBG_INFO(NULL, "Updating value \"%s\" (%s)", AQH_Value_GetName(v), AQH_Value_GetValueUnits(v));
s=AQH_ValuesDataIpcMsg_GetValueUnits(recvdMsg, 0);
if (s && *s)
AQH_Value_SetValueUnits(v, s);
AQH_Storage_AddRuntimeFlags(aqh->storage, AQH_STORAGE_RTFLAGS_MODIFIED);
resultCode=AQH_MSG_IPC_SUCCESS;
}
}
else {
DBG_INFO(NULL, "Value without name ");
resultCode=AQH_MSG_IPC_ERROR_INVALID;
}
}
else {
DBG_INFO(NULL, "Invalid number of values in message (%d)", numValues);
resultCode=AQH_MSG_IPC_ERROR_INVALID;
}
}
else {
DBG_INFO(NULL, "Invalid message received");
resultCode=AQH_MSG_IPC_ERROR_BADDATA;
}
outMsg=AQH_ResultIpcMsg_new(AQH_MSGTYPE_IPC_DATA_RESULT, resultCode);
GWEN_MsgEndpoint_AddSendMessage(ep, outMsg);
}
void _handleAddDataPoints(AQHOME_DATA *aqh, GWEN_MSG_ENDPOINT *ep, const GWEN_MSG *recvdMsg)
{
GWEN_MSG *outMsg;
int resultCode=0;
if (AQH_DataPointsDataIpcMsg_IsValid(recvdMsg)) {
uint32_t numValues;
numValues=AQH_DataPointsDataIpcMsg_GetNumValues(recvdMsg);
if (numValues) {
const char *s;
s=AQH_DataPointsDataIpcMsg_GetValueName(recvdMsg);
if (s && *s) {
AQH_VALUE *v;
v=AQH_Storage_GetValueByName(aqh->storage, s);
if (v==NULL) {
// TODO: maybe create the value on the fly
DBG_INFO(NULL, "Value \"%s\" doesn't not exist", s);
resultCode=AQH_MSG_IPC_ERROR_EXISTS;
}
else {
const uint64_t *dataPoints;
dataPoints=AQH_DataPointsDataIpcMsg_GetDataPoints(recvdMsg);
if (dataPoints) {
uint32_t i;
for(i=0; i<numValues; i++) {
uint64_t timestamp;
union {double f; uint64_t i;} u;
int rv;
timestamp=*(dataPoints++);
u.i=*(dataPoints++);
rv=AQH_Storage_AddDatapoint(aqh->storage, AQH_Value_GetId(v), timestamp, u.f);
if (rv<0) {
DBG_INFO(NULL, "here (%d)", rv);
resultCode=AQH_MSG_IPC_ERROR_GENERIC;
}
else {
DBG_INFO(NULL, "Datapoint added for value \"%s\"", s);
resultCode=0;
}
} /* for */
} /* if datapoints */
else {
DBG_INFO(NULL, "No datapoints");
resultCode=AQH_MSG_IPC_ERROR_BADDATA;
}
}
}
else {
DBG_INFO(NULL, "Value without name ");
resultCode=AQH_MSG_IPC_ERROR_INVALID;
}
}
else {
DBG_INFO(NULL, "No datapoints");
resultCode=AQH_MSG_IPC_ERROR_BADDATA;
}
}
else {
DBG_INFO(NULL, "Invalid message received");
resultCode=AQH_MSG_IPC_ERROR_BADDATA;
}
outMsg=AQH_ResultIpcMsg_new(AQH_MSGTYPE_IPC_DATA_RESULT, resultCode);
GWEN_MsgEndpoint_AddSendMessage(ep, outMsg);
}
void _handleGetDataPoints(AQHOME_DATA *aqh, GWEN_MSG_ENDPOINT *ep, const GWEN_MSG *msg)
{
}
void _handleGetLastDataPoint(AQHOME_DATA *aqh, GWEN_MSG_ENDPOINT *ep, const GWEN_MSG *msg)
{
}

View File

@@ -83,7 +83,7 @@ int _addOrEditObject(AQH_HTTP_URLHANDLER *uh, GWEN_DB_NODE *db, int id)
newValue=AQH_Value_fromDb(db);
valueName=AQH_Value_GetName(newValue);
valueName=AQH_Value_GetNameForSystem(newValue);
if (!(valueName && *valueName)) {
DBG_INFO(NULL, "Missing value name");
AQH_Value_free(newValue);

View File

@@ -34,16 +34,16 @@
<headers dist="true" >
getvalues.h
addvalue.h
adddata.h
getdatapoints.h
</headers>
<sources>
$(local/typefiles)
getvalues.c
addvalue.c
adddata.c
getdatapoints.c
</sources>
<useTargets>

View File

@@ -101,11 +101,11 @@ int AQH_Tool_AddDataPoint(GWEN_DB_NODE *dbGlobalArgs, int argc, char **argv)
{
GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */
GWEN_ArgsType_Char, /* type */
"timestamp", /* name */
"timestamp", /* name */
0, /* minnum */
1, /* maxnum */
"t", /* short option */
"timestamp", /* long option */
"timestamp", /* long option */
I18S("Timestamp of the data (now if omitted)"),
I18S("Timestamp of the data (now if omitted)")
},
@@ -120,6 +120,39 @@ int AQH_Tool_AddDataPoint(GWEN_DB_NODE *dbGlobalArgs, int argc, char **argv)
I18S("Value to write"),
I18S("Value to write")
},
{
GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */
GWEN_ArgsType_Char, /* type */
"clientId", /* name */
0, /* minnum */
1, /* maxnum */
"c", /* short option */
"clientid", /* long option */
I18S("Specify CLIENTID"),
I18S("Specify CLIENTID")
},
{
GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */
GWEN_ArgsType_Char, /* type */
"userId", /* name */
0, /* minnum */
1, /* maxnum */
"u", /* short option */
"userid", /* long option */
I18S("Specify user id"),
I18S("Specify user id")
},
{
GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */
GWEN_ArgsType_Char, /* type */
"password", /* name */
0, /* minnum */
1, /* maxnum */
"p", /* short option */
"password", /* long option */
I18S("Specify service password"),
I18S("Specify service password")
},
{
GWEN_ARGS_FLAGS_HELP | GWEN_ARGS_FLAGS_LAST, /* flags */
GWEN_ArgsType_Int, /* type */
@@ -209,7 +242,7 @@ int _doAddData(GWEN_DB_NODE *dbArgs)
fprintf(stdout, "Sending AddData request\n");
epTcp=Utils_SetupIpcEndpoint(dbArgs);
epTcp=Utils_OpenConnection(dbArgs, 0, timeoutInSeconds);
if (epTcp==NULL) {
DBG_ERROR(NULL, "ERROR creating TCP connection");
return 2;
@@ -264,7 +297,7 @@ void _sendCommand(GWEN_MSG_ENDPOINT *epTcp, const char *valueName, const char *v
arrayToSend[0]=timestampToSend;
arrayToSend[1]=u.i;
msgOut=AQH_DataPointsDataIpcMsg_new(AQH_MSGTYPE_IPC_DATA_ADDDATAPOINTS_REQ, 0, 0, valueName, valueUnits, arrayToSend, 1);
msgOut=AQH_DataPointsDataIpcMsg_new(AQH_MSGTYPE_IPC_DATA_UPDATEDATA, 0, 0, valueName, valueUnits, arrayToSend, 1);
GWEN_MsgEndpoint_AddSendMessage(epTcp, msgOut);
}

View File

@@ -10,12 +10,12 @@
# include <config.h>
#endif
#include "./addvalue.h"
#include "./getdatapoints.h"
#include "../utils.h"
#include "aqhome/msg/msg_node.h"
#include "aqhome/ipc/msg_ipc_result.h"
#include "aqhome/ipc/data/msg_data_values.h"
#include "aqhome/ipc/data/msg_data_datapoints.h"
#include "aqhome/ipc/data/ipc_data.h"
#include <gwenhywfar/args.h>
@@ -31,13 +31,14 @@
#define I18N(msg) GWEN_I18N_Translate(PACKAGE, msg)
static int _doAddValue(GWEN_DB_NODE *dbArgs);
static void _sendCommand(GWEN_MSG_ENDPOINT *epTcp, const char *valueName, const char *valueUnits);
static int _doGetDataPoints(GWEN_DB_NODE *dbArgs);
static void _sendCommand(GWEN_MSG_ENDPOINT *epTcp, const char *valueName, uint64_t tsBegin, uint64_t tsEnd);
static uint64_t _getTimeStampFromString(const char *s);
int AQH_Tool_AddValue(GWEN_DB_NODE *dbGlobalArgs, int argc, char **argv)
int AQH_Tool_GetDataPoints(GWEN_DB_NODE *dbGlobalArgs, int argc, char **argv)
{
GWEN_DB_NODE *dbLocalArgs;
int rv;
@@ -89,13 +90,57 @@ int AQH_Tool_AddValue(GWEN_DB_NODE *dbGlobalArgs, int argc, char **argv)
{
GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */
GWEN_ArgsType_Char, /* type */
"valueUnits", /* name */
"tsBegin", /* name */
0, /* minnum */
1, /* maxnum */
"U", /* short option */
"valueunits", /* long option */
I18S("Units of the value to add (e.g. \"Grad Celsius\")"),
I18S("Units of the value to add (e.g. \"Grad Celsius\")")
"tb", /* short option */
"tsbegin", /* long option */
I18S("Get data from this timestamp on (earliest timestamp if omitted)"),
I18S("Get data from this timestamp on (earliest timestamp if omitted)")
},
{
GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */
GWEN_ArgsType_Char, /* type */
"tsEnd", /* name */
0, /* minnum */
1, /* maxnum */
"te", /* short option */
"tsend", /* long option */
I18S("Get data up until this timestamp (latest timestamp if omitted)"),
I18S("Get data up until this timestamp (latest timestamp if omitted)")
},
{
GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */
GWEN_ArgsType_Char, /* type */
"clientId", /* name */
0, /* minnum */
1, /* maxnum */
"c", /* short option */
"clientid", /* long option */
I18S("Specify CLIENTID"),
I18S("Specify CLIENTID")
},
{
GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */
GWEN_ArgsType_Char, /* type */
"userId", /* name */
0, /* minnum */
1, /* maxnum */
"u", /* short option */
"userid", /* long option */
I18S("Specify user id"),
I18S("Specify user id")
},
{
GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */
GWEN_ArgsType_Char, /* type */
"password", /* name */
0, /* minnum */
1, /* maxnum */
"p", /* short option */
"password", /* long option */
I18S("Specify service password"),
I18S("Specify service password")
},
{
GWEN_ARGS_FLAGS_HELP | GWEN_ARGS_FLAGS_LAST, /* flags */
@@ -132,59 +177,93 @@ int AQH_Tool_AddValue(GWEN_DB_NODE *dbGlobalArgs, int argc, char **argv)
return 0;
}
return _doAddValue(dbLocalArgs);
return _doGetDataPoints(dbLocalArgs);
}
int _doAddValue(GWEN_DB_NODE *dbArgs)
int _doGetDataPoints(GWEN_DB_NODE *dbArgs)
{
GWEN_MSG_ENDPOINT *epTcp;
int timeoutInSeconds;
const char *valueName;
const char *valueUnits;
GWEN_MSG *msg;
const char *valueName;
uint64_t tsBegin;
uint64_t tsEnd;
timeoutInSeconds=GWEN_DB_GetIntValue(dbArgs, "timeout", 0, 5);
valueName=GWEN_DB_GetCharValue(dbArgs, "valueName", 0, NULL);
valueUnits=GWEN_DB_GetCharValue(dbArgs, "valueUnits", 0, NULL);
if (!(valueName && *valueName)) {
DBG_ERROR(NULL, "ERROR: Missing value name");
return 1;
tsBegin=_getTimeStampFromString(GWEN_DB_GetCharValue(dbArgs, "tsBegin", 0, NULL));
if (tsBegin==(uint64_t) (-1)) {
DBG_ERROR(NULL, "Bad begin timestamp");
return 2;
}
tsEnd=_getTimeStampFromString(GWEN_DB_GetCharValue(dbArgs, "tsEnd", 0, NULL));
if (tsEnd==(uint64_t) (-1)) {
DBG_ERROR(NULL, "Bad end timestamp");
return 2;
}
fprintf(stdout, "Sending AddValue request\n");
epTcp=Utils_SetupIpcEndpoint(dbArgs);
epTcp=Utils_OpenConnection(dbArgs, 0, timeoutInSeconds);
if (epTcp==NULL) {
DBG_ERROR(NULL, "ERROR creating TCP connection");
return 2;
}
_sendCommand(epTcp, valueName, valueUnits);
fprintf(stdout, "Sending GetDataPoints request\n");
_sendCommand(epTcp, valueName, tsBegin, tsEnd);
for (;;) {
uint16_t code;
msg=Utils_WaitForSpecificIpcMessage(epTcp, AQH_MSGTYPE_IPC_DATA_ADDVALUES_RSP, timeoutInSeconds);
msg=Utils_WaitForSpecificIpcMessage(epTcp, AQH_MSGTYPE_IPC_DATA_GETDATA_RSP, timeoutInSeconds);
if (msg==NULL) {
DBG_ERROR(NULL, "No response received");
return 2;
}
code=GWEN_IpcMsg_GetCode(msg);
if (code==AQH_MSGTYPE_IPC_DATA_ADDVALUES_RSP ||
code==AQH_MSGTYPE_IPC_DATA_RESULT) {
if (code==AQH_MSGTYPE_IPC_DATA_GETDATA_RSP) {
if (AQH_DataPointsDataIpcMsg_IsValid(msg)) {
const uint64_t *dataPoints;
const char *valueUnits;
uint32_t numValues;
uint32_t i;
dataPoints=AQH_DataPointsDataIpcMsg_GetDataPoints(msg);
valueUnits=AQH_DataPointsDataIpcMsg_GetUnits(msg);
numValues=AQH_DataPointsDataIpcMsg_GetNumValues(msg);
for(i=0; i<numValues; i++) {
uint64_t timestamp;
union {double f; uint64_t i;} u;
timestamp=*(dataPoints++);
u.i=*(dataPoints++);
fprintf(stdout, "%lu\t%lf\t%s\n",
(unsigned long int) timestamp,
u.f,
valueUnits?valueUnits:"");
}
if (AQH_DataPointsDataIpcMsg_GetFlags(msg) & AQH_MSGDATA_DATAPOINTS_FLAGS_LASTMSG) {
DBG_INFO(NULL, "Last message received");
break;
}
}
else {
DBG_ERROR(NULL, "Invalid message received");
GWEN_MsgEndpoint_free(epTcp);
return 3;
}
}
else if (code==AQH_MSGTYPE_IPC_DATA_RESULT) {
uint32_t resultCode;
resultCode=AQH_ResultIpcMsg_GetResultCode(msg);
if (resultCode!=AQH_MSG_IPC_SUCCESS) {
fprintf(stderr, "ERROR: %d\n", resultCode);
GWEN_MsgEndpoint_free(epTcp);
return 3;
}
else {
fprintf(stdout, "Value added.\n");
break;
}
fprintf(stderr, "ERROR: %d\n", resultCode);
GWEN_MsgEndpoint_free(epTcp);
return 3;
}
else {
DBG_INFO(NULL, "Unexpected message \"%d\"", code);
@@ -199,22 +278,34 @@ int _doAddValue(GWEN_DB_NODE *dbArgs)
void _sendCommand(GWEN_MSG_ENDPOINT *epTcp, const char *valueName, const char *valueUnits)
void _sendCommand(GWEN_MSG_ENDPOINT *epTcp, const char *valueName, uint64_t tsBegin, uint64_t tsEnd)
{
GWEN_MSG *msgOut;
AQH_VALUE *v;
uint64_t array[2];
v=AQH_Value_new();
AQH_Value_SetName(v, valueName);
AQH_Value_SetValueUnits(v, valueUnits);
array[0]=tsBegin;
array[1]=tsEnd;
msgOut=AQH_ValuesDataIpcMsg_newForOneValue(AQH_MSGTYPE_IPC_DATA_ADDVALUES_REQ, AQH_MSGDATA_VALUES_FLAGS_LASTMSG, v);
msgOut=AQH_DataPointsDataIpcMsg_new(AQH_MSGTYPE_IPC_DATA_GETDATA_REQ, 0, 0, valueName, NULL, array, 2);
GWEN_MsgEndpoint_AddSendMessage(epTcp, msgOut);
AQH_Value_free(v);
}
uint64_t _getTimeStampFromString(const char *s)
{
if (s && *s) {
unsigned long int x;
if (1!=sscanf("%lu", s, &x)) {
DBG_ERROR(NULL, "ERROR: Invalid timestamp");
return (uint64_t) (-1);
}
return (uint64_t) x;
}
return 0;
}

View File

@@ -6,15 +6,15 @@
* should have received along with this file.
****************************************************************************/
#ifndef AQHOME_TOOL_ADDVALUE_H
#define AQHOME_TOOL_ADDVALUE_H
#ifndef AQHOME_TOOL_GETDATAPOINTS_H
#define AQHOME_TOOL_GETDATAPOINTS_H
#include <gwenhywfar/db.h>
int AQH_Tool_AddValue(GWEN_DB_NODE *dbGlobalArgs, int argc, char **argv);
int AQH_Tool_GetDataPoints(GWEN_DB_NODE *dbGlobalArgs, int argc, char **argv);
#endif

View File

@@ -75,6 +75,39 @@ int AQH_Tool_GetValues(GWEN_DB_NODE *dbGlobalArgs, int argc, char **argv)
I18S("Specify timeout in seconds for response"),
I18S("Specify timeout in seconds for response")
},
{
GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */
GWEN_ArgsType_Char, /* type */
"clientId", /* name */
0, /* minnum */
1, /* maxnum */
"c", /* short option */
"clientid", /* long option */
I18S("Specify CLIENTID"),
I18S("Specify CLIENTID")
},
{
GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */
GWEN_ArgsType_Char, /* type */
"userId", /* name */
0, /* minnum */
1, /* maxnum */
"u", /* short option */
"userid", /* long option */
I18S("Specify user id"),
I18S("Specify user id")
},
{
GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */
GWEN_ArgsType_Char, /* type */
"password", /* name */
0, /* minnum */
1, /* maxnum */
"p", /* short option */
"password", /* long option */
I18S("Specify service password"),
I18S("Specify service password")
},
{
GWEN_ARGS_FLAGS_HELP | GWEN_ARGS_FLAGS_LAST, /* flags */
GWEN_ArgsType_Int, /* type */
@@ -121,14 +154,14 @@ int _doGetValues(GWEN_DB_NODE *dbArgs)
int timeoutInSeconds;
GWEN_MSG *msg;
epTcp=Utils_SetupIpcEndpoint(dbArgs);
timeoutInSeconds=GWEN_DB_GetIntValue(dbArgs, "timeout", 0, 5);
epTcp=Utils_OpenConnection(dbArgs, 0, timeoutInSeconds);
if (epTcp==NULL) {
DBG_ERROR(NULL, "ERROR creating TCP connection");
return 2;
}
timeoutInSeconds=GWEN_DB_GetIntValue(dbArgs, "timeout", 0, 5);
fprintf(stdout, "Sending GetValues request\n");
_sendCommand(epTcp);

View File

@@ -14,8 +14,8 @@
#include "./nodes/flash.h"
#include "./nodes/getdevices.h"
#include "./data/getvalues.h"
#include "./data/addvalue.h"
#include "./data/adddata.h"
#include "./data/getdatapoints.h"
#include <aqhome/api.h>
#include <aqhome/aqhome.h>
@@ -73,8 +73,8 @@ int main(int argc, char **argv)
GWEN_FE_DAH("flash", AQH_Tool_Flash, I18N("Flash a given node on the network")),
GWEN_FE_DAH("getdevices", AQH_Tool_GetDevices, I18N("Request list of known devices on the network")),
GWEN_FE_DAH("getvalues", AQH_Tool_GetValues, I18N("Request list of known values on the data server")),
GWEN_FE_DAH("addvalue", AQH_Tool_AddValue, I18N("Add a value to the data server")),
GWEN_FE_DAH("adddata", AQH_Tool_AddDataPoint, I18N("Send a datapoint to the data server")),
GWEN_FE_DAH("getdata", AQH_Tool_GetDataPoints, I18N("Request list of datapoints for a value on the data server")),
GWEN_FE_END(),
};
const GWEN_FUNCS *func;

View File

@@ -17,6 +17,8 @@
#include "aqhome/ipc/nodes/msg_ipc_setaccmsggrps.h"
#include "aqhome/ipc/nodes/msg_ipc_forward.h"
#include "aqhome/ipc/data/ipc_data.h"
#include "aqhome/ipc/data/msg_data_connect.h"
#include "aqhome/ipc/msg_ipc_result.h"
#include <gwenhywfar/endpoint_tcpc.h>
#include <gwenhywfar/debug.h>
@@ -181,5 +183,54 @@ int Utils_SendAcceptedMsgGroups(GWEN_MSG_ENDPOINT *epTcp, uint32_t groups)
GWEN_MSG_ENDPOINT *Utils_OpenConnection(GWEN_DB_NODE *dbArgs, uint32_t flags, int timeoutInSeconds)
{
GWEN_MSG_ENDPOINT *epTcp;
GWEN_MSG *msgOut;
GWEN_MSG *msgIn;
uint32_t result;
const char *clientId;
const char *userId;
const char *password;
clientId=GWEN_DB_GetCharValue(dbArgs, "clientId", 0, NULL);
userId=GWEN_DB_GetCharValue(dbArgs, "userId", 0, NULL);
password=GWEN_DB_GetCharValue(dbArgs, "password", 0, NULL);
epTcp=Utils_SetupIpcEndpoint(dbArgs);
if (epTcp==NULL) {
DBG_ERROR(NULL, "ERROR creating TCP connection");
return NULL;
}
msgOut=AQH_ConnectDataIpcMsg_new(AQH_MSGTYPE_IPC_DATA_CONNECT_REQ, clientId, userId, password, flags);
if (msgOut==NULL) {
DBG_ERROR(NULL, "Error creating message");
GWEN_MsgEndpoint_free(epTcp);
return NULL;
}
GWEN_MsgEndpoint_AddSendMessage(epTcp, msgOut);
msgIn=Utils_WaitForSpecificIpcMessage(epTcp, AQH_MSGTYPE_IPC_DATA_RESULT, timeoutInSeconds);
if (msgIn==NULL) {
DBG_ERROR(NULL, "No response received");
GWEN_MsgEndpoint_free(epTcp);
return NULL;
}
result=AQH_ResultIpcMsg_GetResultCode(msgIn);
GWEN_Msg_free(msgIn);
if (result!=AQH_MSG_IPC_SUCCESS) {
DBG_ERROR(NULL, "Response: %d", result);
GWEN_MsgEndpoint_free(epTcp);
return NULL;
}
return epTcp;
}

View File

@@ -25,6 +25,8 @@ int Utils_FlushOutMessageQueue(GWEN_MSG_ENDPOINT *epTcp, int timeoutInSeconds);
int Utils_SendAcceptedMsgGroups(GWEN_MSG_ENDPOINT *epTcp, uint32_t groups);
GWEN_MSG_ENDPOINT *Utils_OpenConnection(GWEN_DB_NODE *dbArgs, uint32_t flags, int timeoutInSeconds);
#endif

View File

@@ -21,6 +21,9 @@
#include <gwenhywfar/json_read.h>
#define AQH_STORAGE_DATAPOINTS_STEPS 128
/* ------------------------------------------------------------------------------------------------
* forward declarations
@@ -219,6 +222,7 @@ void AQH_Storage_AddValue(AQH_STORAGE *sto, AQH_VALUE *value)
id=++(sto->lastValueId);
AQH_Value_SetId(value, id);
AQH_Value_List_Add(value, sto->valueList);
AQH_Storage_AddRuntimeFlags(sto, AQH_STORAGE_RTFLAGS_MODIFIED);
}
}
@@ -238,9 +242,9 @@ AQH_VALUE *AQH_Storage_GetValueById(const AQH_STORAGE *sto, uint64_t id)
AQH_VALUE *AQH_Storage_GetValueByName(const AQH_STORAGE *sto, const char *s)
AQH_VALUE *AQH_Storage_GetValueByNameForSystem(const AQH_STORAGE *sto, const char *s)
{
return sto?AQH_Value_List_GetByName(sto->valueList, s):NULL;
return sto?AQH_Value_List_GetByNameForSystem(sto->valueList, s):NULL;
}
@@ -377,6 +381,96 @@ int AQH_Storage_AddDatapoint(AQH_STORAGE *sto, uint64_t valueId, uint64_t timest
uint64_t *AQH_Storage_GetDataPoints(AQH_STORAGE *sto, uint64_t valueId, uint64_t fromTime, uint64_t toTime, uint64_t maxArrayLen)
{
AQH_DATAFILE *df;
uint64_t numEntries;
uint64_t arrayLen;
uint64_t arrayPos;
uint64_t *arrayPtr;
uint64_t i;
df=_getDataFileByValueId(sto, valueId);
if (df==NULL) {
DBG_ERROR(AQH_LOGDOMAIN, "No file for value id %lu", (unsigned long int) valueId);
return NULL;
}
numEntries=AQH_DataFile_GetNumberOfEntries(df);
if (fromTime==0 && toTime==0)
arrayLen=numEntries+1;
else
arrayLen=AQH_STORAGE_DATAPOINTS_STEPS+1;
if (arrayLen>maxArrayLen+1)
arrayLen=maxArrayLen+1;
arrayPtr=(uint64_t*) malloc(arrayLen*sizeof(uint64_t));
if (arrayPtr==NULL) {
DBG_ERROR(AQH_LOGDOMAIN, "Not enough memory for %lu entries", (unsigned long int) arrayLen);
free(arrayPtr);
return NULL;
}
arrayPos=1;
for (i=1; i<numEntries; i++) { /* first entry in datafile is reserved */
union {double f; uint64_t i;} u;
uint64_t ts;
int rv;
DBG_INFO(NULL, "Reading record %lu", (unsigned long int) i);
rv=AQH_DataFile_ReadRecord(df, i, &ts, &(u.f));
if (rv<0) {
DBG_ERROR(AQH_LOGDOMAIN, "here (%d)", rv);
free(arrayPtr);
return NULL;
}
DBG_INFO(NULL, "Read record %lu (%lu - %lf)", (unsigned long int) i, (unsigned long int) ts, u.f);
if ((fromTime==0 || ts>=fromTime) && (toTime==0 || ts<=toTime)) {
DBG_INFO(NULL, "Will add record %lu", (unsigned long int) i);
if (arrayPos>maxArrayLen) {
DBG_INFO(AQH_LOGDOMAIN, "Limit for number of returned entries reached");
break;
}
if (arrayPos+1>=arrayLen) {
uint64_t newArrayLen;
void *p;
newArrayLen=arrayLen+AQH_STORAGE_DATAPOINTS_STEPS;
if (newArrayLen>maxArrayLen+1)
newArrayLen=maxArrayLen+1;
if (newArrayLen==arrayLen) {
DBG_INFO(AQH_LOGDOMAIN, "Limit for number of returned entries reached");
break;
}
p=realloc((void*) arrayPtr, newArrayLen*sizeof(uint64_t));
if (p==NULL) {
DBG_ERROR(AQH_LOGDOMAIN, "Not enough memory for %lu entries", (unsigned long int) arrayLen+AQH_STORAGE_DATAPOINTS_STEPS);
free(arrayPtr);
return NULL;
}
arrayPtr=(uint64_t*) p;
arrayLen=newArrayLen;
}
arrayPtr[arrayPos++]=ts;
arrayPtr[arrayPos++]=u.i;
}
else {
DBG_INFO(NULL, "Entry %lu does not match", (unsigned long int) i);
}
} /* for */
if (arrayPos<=1) {
DBG_INFO(AQH_LOGDOMAIN, "No matching records");
free(arrayPtr);
return NULL;
}
arrayPtr[0]=arrayPos-1;
return arrayPtr;
}
void AQH_Storage_HandleMqttPublish(AQH_STORAGE *sto, const char *sTopic, const char *sValue)
{
if (sto) {
@@ -470,7 +564,7 @@ void _handleValueForJsonElement(AQH_STORAGE *sto,
}
}
else {
DBG_INFO(AQH_LOGDOMAIN, "No datapath in value \"%s\"", AQH_Value_GetName(value));
DBG_INFO(AQH_LOGDOMAIN, "No datapath in value \"%s\"", AQH_Value_GetNameForSystem(value));
}
}

View File

@@ -67,7 +67,7 @@ AQHOME_API AQH_MQTT_TOPIC *AQH_Storage_GetMqttTopicByTopic(const AQH_STORAGE *st
AQHOME_API void AQH_Storage_AddValue(AQH_STORAGE *sto, AQH_VALUE *value);
AQHOME_API AQH_VALUE_LIST *AQH_Storage_GetValueList(const AQH_STORAGE *sto);
AQHOME_API AQH_VALUE *AQH_Storage_GetValueById(const AQH_STORAGE *sto, uint64_t id);
AQHOME_API AQH_VALUE *AQH_Storage_GetValueByName(const AQH_STORAGE *sto, const char *s);
AQHOME_API AQH_VALUE *AQH_Storage_GetValueByNameForSystem(const AQH_STORAGE *sto, const char *s);
AQHOME_API const char *AQH_Storage_GetStateFile(const AQH_STORAGE *sto);
AQHOME_API void AQH_Storage_SetStateFile(AQH_STORAGE *sto, const char *s);
@@ -87,6 +87,9 @@ AQHOME_API int AQH_Storage_Fini(AQH_STORAGE *sto);
AQHOME_API int AQH_Storage_WriteState(AQH_STORAGE *sto);
AQHOME_API int AQH_Storage_AddDatapoint(AQH_STORAGE *sto, uint64_t valueId, uint64_t timestamp, double dataPoint);
AQHOME_API uint64_t *AQH_Storage_GetDataPoints(AQH_STORAGE *sto, uint64_t valueId,
uint64_t fromTime, uint64_t toTime,
uint64_t maxArrayLen);
AQHOME_API void AQH_Storage_HandleMqttPublish(AQH_STORAGE *sto, const char *topic, const char *value);

View File

@@ -49,7 +49,21 @@
<flags>with_getbymember</flags>
</member>
<member name="name" type="char_ptr" maxlen="32">
<member name="driver" type="char_ptr" maxlen="32">
<default>0</default>
<preset>0</preset>
<access>public</access>
<flags>own</flags>
</member>
<member name="nameForDriver" type="char_ptr" maxlen="128">
<default>0</default>
<preset>0</preset>
<access>public</access>
<flags>own</flags>
</member>
<member name="nameForSystem" type="char_ptr" maxlen="128">
<default>0</default>
<preset>0</preset>
<access>public</access>

View File

@@ -48,6 +48,7 @@
endpoint_ipc.h
msg_ipc_result.h
msg_ipc_qwords.h
msg_ipc_tag16.h
</headers>
@@ -62,6 +63,7 @@
endpoint_ipc.c
msg_ipc_result.c
msg_ipc_qwords.c
msg_ipc_tag16.c
</sources>

View File

@@ -46,10 +46,9 @@
<headers dist="true" install="$(pkgincludedir)/ipc" >
ipc_data.h
msg_data_getvalues_rsp.c
msg_data_getvalues_rsp.h
msg_data_values.h
msg_data_datapoints.h
msg_data_connect.h
</headers>
@@ -61,10 +60,9 @@
$(local/typefiles)
ipc_data.c
msg_data_getvalues_req.c
msg_data_getvalues_rsp.c
msg_data_values.c
msg_data_datapoints.c
msg_data_connect.c
</sources>

View File

@@ -21,23 +21,40 @@
#define AQH_MSGTYPE_IPC_DATA_RESULT 0x001 /* AQH_ResultIpcMsg */
#define AQH_MSGTYPE_IPC_DATA_GETVALUES_REQ 0x100 /* AQH_QwordsIpcMsg */
#define AQH_MSGTYPE_IPC_DATA_GETVALUES_RSP 0x200 /* AQH_ValuesDataIpcMsg */
#define AQH_MSGTYPE_IPC_DATA_CONNECT_REQ 0x010 /* serviceName, userName, password */
#define AQH_MSGTYPE_IPC_DATA_ADDVALUES_REQ 0x300 /* AQH_ValuesDataIpcMsg */
#define AQH_MSGTYPE_IPC_DATA_ADDVALUES_RSP 0x400 /* AQH_ResultIpcMsg */
#define AQH_MSGTYPE_IPC_DATA_UPDATEDATA 0x100 /* AQH_DataPointsDataIpcMsg */
#define AQH_MSGTYPE_IPC_DATA_DATACHANGED 0x200 /* AQH_DataPointsDataIpcMsg */
#define AQH_MSGTYPE_IPC_DATA_EDITVALUE_REQ 0x500 /* AQH_ValuesDataIpcMsg */
#define AQH_MSGTYPE_IPC_DATA_EDITVALUE_RSP 0x600 /* AQH_ResultIpcMsg */
#define AQH_MSGTYPE_IPC_DATA_SETDATA_REQ 0x300 /* AQH_DataPointsDataIpcMsg */
#define AQH_MSGTYPE_IPC_DATA_SETDATA_RSP 0x400 /* AQH_ResultIpcMsg */
#define AQH_MSGTYPE_IPC_DATA_ADDDATAPOINTS_REQ 0x700 /* AQH_DataPointsDataIpcMsg */
#define AQH_MSGTYPE_IPC_DATA_ADDDATAPOINTS_RSP 0x800 /* AQH_ResultIpcMsg */
#define AQH_MSGTYPE_IPC_DATA_GETDATA_REQ 0x500 /* AQH_DataPointsDataIpcMsg (1 pair: fromTime, toTime) */
#define AQH_MSGTYPE_IPC_DATA_GETDATA_RSP 0x600 /* AQH_DataPointsDataIpcMsg */
#define AQH_MSGTYPE_IPC_DATA_GETDATAPOINTS_REQ 0x900 /* AQH_DataPointsDataIpcMsg (1 pair: fromTime, toTime) */
#define AQH_MSGTYPE_IPC_DATA_GETDATAPOINTS_RSP 0xa00 /* AQH_DataPointsDataIpcMsg */
#define AQH_MSGTYPE_IPC_DATA_GETLASTDATA_REQ 0x700 /* AQH_DataPointsDataIpcMsg (0 datapoints) */
#define AQH_MSGTYPE_IPC_DATA_GETLASTDATA_RSP 0x800 /* AQH_DataPointsDataIpcMsg */
#define AQH_MSGTYPE_IPC_DATA_GETLASTDATAPOINT_REQ 0xb00 /* AQH_DataPointsDataIpcMsg (0 datapoints) */
#define AQH_MSGTYPE_IPC_DATA_GETLASTDATAPOINT_RSP 0xc00 /* AQH_DataPointsDataIpcMsg */
#define AQH_MSGTYPE_IPC_DATA_GETVALUES_REQ 0x900 /* AQH_QwordsIpcMsg */
#define AQH_MSGTYPE_IPC_DATA_GETVALUES_RSP 0xa00 /* AQH_ValuesDataIpcMsg */
/* remove */
#define AQH_MSGTYPE_IPC_DATA_ADDVALUES_REQ 0xf01 /* AQH_ValuesDataIpcMsg -> remove */
#define AQH_MSGTYPE_IPC_DATA_ADDVALUES_RSP 0xf02 /* AQH_ResultIpcMsg -> remove */
#define AQH_MSGTYPE_IPC_DATA_EDITVALUE_REQ 0xf03 /* AQH_ValuesDataIpcMsg -> remove */
#define AQH_MSGTYPE_IPC_DATA_EDITVALUE_RSP 0xf04 /* AQH_ResultIpcMsg -> remove */
#define AQH_MSGTYPE_IPC_DATA_ADDDATAPOINTS_REQ 0xf05 /* AQH_DataPointsDataIpcMsg */
#define AQH_MSGTYPE_IPC_DATA_ADDDATAPOINTS_RSP 0xf06 /* AQH_ResultIpcMsg */
#define AQH_MSGTYPE_IPC_DATA_GETDATAPOINTS_REQ 0xf07 /* AQH_DataPointsDataIpcMsg (1 pair: fromTime, toTime) */
#define AQH_MSGTYPE_IPC_DATA_GETDATAPOINTS_RSP 0xf08 /* AQH_DataPointsDataIpcMsg */
#define AQH_MSGTYPE_IPC_DATA_GETLASTDATAPOINT_REQ 0xf09 /* AQH_DataPointsDataIpcMsg (0 datapoints) */
#define AQH_MSGTYPE_IPC_DATA_GETLASTDATAPOINT_RSP 0xf0a /* AQH_DataPointsDataIpcMsg */

View File

@@ -0,0 +1,94 @@
/****************************************************************************
* This file is part of the project AqHome.
* AqHome (c) by 2023 Martin Preuss, all rights reserved.
*
* The license for this file can be found in the file COPYING which you
* should have received along with this file.
****************************************************************************/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <aqhome/ipc/data/msg_data_connect.h>
#include <aqhome/ipc/data/ipc_data.h>
#include <aqhome/ipc/msg_ipc_tag16.h>
#include <gwenhywfar/msg.h>
#include <gwenhywfar/buffer.h>
#include <gwenhywfar/debug.h>
#include <gwenhywfar/msg_ipc.h>
#define AQH_MSGDATA_CONNECT_MINSIZE GWEN_MSGIPC_OFFS_PAYLOAD
GWEN_MSG *AQH_ConnectDataIpcMsg_new(uint16_t code, const char *clientId, const char *userId, const char *password, uint32_t flags)
{
GWEN_MSG *msg;
GWEN_BUFFER *buf;
buf=GWEN_Buffer_new(0, 256, 0, 1);
if (clientId && *clientId)
GWEN_Tag16_WriteStringTagToBuffer(AQH_MSGDATA_CONNECT_TAGS_CLIENTID, clientId, buf);
if (userId && *userId)
GWEN_Tag16_WriteStringTagToBuffer(AQH_MSGDATA_CONNECT_TAGS_USERID, userId, buf);
if (password && *password)
GWEN_Tag16_WriteStringTagToBuffer(AQH_MSGDATA_CONNECT_TAGS_PASSWORD, password, buf);
GWEN_Tag16_WriteUint32TagToBuffer(AQH_MSGDATA_CONNECT_TAGS_FLAGS, flags, buf);
msg=AQH_Tag16IpcMsg_new(AQH_IPC_PROTOCOL_DATA_ID, AQH_IPC_PROTOCOL_DATA_VERSION, code,
GWEN_Buffer_GetUsedBytes(buf), (const uint8_t*) GWEN_Buffer_GetStart(buf));
GWEN_Buffer_free(buf);
return msg;
}
void AQH_ConnectDataIpcMsg_DumpToBuffer(const GWEN_MSG *msg, GWEN_BUFFER *dbuf, const char *sText)
{
if (GWEN_Msg_GetBytesInBuffer(msg)>=AQH_MSGDATA_CONNECT_MINSIZE) {
GWEN_TAG16_LIST *tagList;
char *clientId=NULL;
char *userId=NULL;
uint32_t flags=0;
tagList=AQH_Tag16IpcMsg_ParseTags(msg, 0);
if (tagList) {
const GWEN_TAG16 *tag;
tag=GWEN_Tag16_List_FindFirstByTagType(tagList, AQH_MSGDATA_CONNECT_TAGS_CLIENTID);
clientId=tag?GWEN_Tag16_GetTagDataAsNewString(tag, NULL):NULL;
tag=GWEN_Tag16_List_FindFirstByTagType(tagList, AQH_MSGDATA_CONNECT_TAGS_USERID);
userId=tag?GWEN_Tag16_GetTagDataAsNewString(tag, NULL):NULL;
tag=GWEN_Tag16_List_FindFirstByTagType(tagList, AQH_MSGDATA_CONNECT_TAGS_FLAGS);
flags=tag?GWEN_Tag16_GetTagDataAsUint32(tag, 0):0;
}
GWEN_Buffer_AppendArgs(dbuf,
"CONNECT (code=%d, proto=%d, proto version=%d, clientId=%s, userId=%s, flags=%08x)\n",
GWEN_IpcMsg_GetCode(msg),
GWEN_IpcMsg_GetProtoId(msg),
GWEN_IpcMsg_GetProtoVersion(msg),
clientId?clientId:"<empty>",
userId?userId:"<empty>",
flags);
free(userId);
free(clientId);
GWEN_Tag16_List_free(tagList);
}
}

View File

@@ -0,0 +1,50 @@
/****************************************************************************
* 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_DATA_CONNECT_H
#define AQH_MSG_IPC_DATA_CONNECT_H
#include <aqhome/api.h>
#include <aqhome/data/value.h>
#include <gwenhywfar/msg_ipc.h>
/**
* This message is used in request AQH_MSGTYPE_IPC_DATA_ADDVALUES_REQ and in response AQH_MSGTYPE_IPC_DATA_GETVALUES_RSP.
*/
#define AQH_MSGDATA_CONNECT_TAGS_CLIENTID 0x0001
#define AQH_MSGDATA_CONNECT_TAGS_USERID 0x0002
#define AQH_MSGDATA_CONNECT_TAGS_PASSWORD 0x0003
#define AQH_MSGDATA_CONNECT_TAGS_FLAGS 0x0004
#define AQH_MSGDATA_CONNECT_FLAGS_WANTUPDATES 0x0001
AQHOME_API GWEN_MSG *AQH_ConnectDataIpcMsg_new(uint16_t code,
const char *clientId,
const char *userId, const char *password,
uint32_t flags);
AQHOME_API int AQH_ConnectDataIpcMsg_IsValid(const GWEN_MSG *msg);
AQHOME_API void AQH_ConnectDataIpcMsg_DumpToBuffer(const GWEN_MSG *msg, GWEN_BUFFER *dbuf, const char *sText);
#endif

View File

@@ -1,52 +0,0 @@
/****************************************************************************
* This file is part of the project AqHome.
* AqHome (c) by 2023 Martin Preuss, all rights reserved.
*
* The license for this file can be found in the file COPYING which you
* should have received along with this file.
****************************************************************************/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <aqhome/ipc/data/msg_data_getvalues_req.h>
#include <aqhome/ipc/data/ipc_data.h>
#include <gwenhywfar/msg.h>
#include <gwenhywfar/buffer.h>
#include <gwenhywfar/misc.h>
#include <gwenhywfar/list.h>
#include <gwenhywfar/error.h>
#include <gwenhywfar/debug.h>
#include <gwenhywfar/text.h>
#include <gwenhywfar/msg_ipc.h>
GWEN_MSG *AQH_GetValuesReqDataIpcMsg_new(uint16_t code)
{
return GWEN_IpcMsg_new(AQH_IPC_PROTOCOL_DATA_ID, AQH_IPC_PROTOCOL_DATA_VERSION, code, 0, NULL);
}
void AQH_GetValuesReqDataIpcMsg_DumpToBuffer(const GWEN_MSG *msg, GWEN_BUFFER *dbuf, const char *sText)
{
if (GWEN_Msg_GetBytesInBuffer(msg)>=GWEN_MSGIPC_OFFS_PAYLOAD) {
GWEN_Buffer_AppendArgs(dbuf,
"GETVALUESREQ (code=%d, proto=%d, proto version=%d)\n",
GWEN_IpcMsg_GetCode(msg),
GWEN_IpcMsg_GetProtoId(msg),
GWEN_IpcMsg_GetProtoVersion(msg));
}
}

View File

@@ -1,210 +0,0 @@
/****************************************************************************
* This file is part of the project AqHome.
* AqHome (c) by 2023 Martin Preuss, all rights reserved.
*
* The license for this file can be found in the file COPYING which you
* should have received along with this file.
****************************************************************************/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <aqhome/ipc/data/msg_data_getvalues_rsp.h>
#include <aqhome/ipc/data/ipc_data.h>
#include <gwenhywfar/msg.h>
#include <gwenhywfar/buffer.h>
#include <gwenhywfar/debug.h>
#include <gwenhywfar/msg_ipc.h>
#include <string.h>
#define AQH_MSGDATA_GETVALUES_RSP_OFFS_FLAGS 0 /* 4 bytes */
#define AQH_MSGDATA_GETVALUES_RSP_OFFS_NUMVALUES 4 /* 4 bytes */
#define AQH_MSGDATA_GETVALUES_RSP_OFFS_VALUES 8 /* 8 byte */
#define AQH_MSGDATA_GETVALUES_RSP_VALUES_OFFS_ID 0 /* 8 byte */
#define AQH_MSGDATA_GETVALUES_RSP_VALUES_OFFS_NAME 8 /* 104 byte */
# define AQH_MSGDATA_GETVALUES_RSP_VALUES_SIZE_NAME 104 /* 104 byte */
#define AQH_MSGDATA_GETVALUES_RSP_VALUES_OFFS_UNITS 112 /* 16 bytes */
# define AQH_MSGDATA_GETVALUES_RSP_VALUES_SIZE_UNITS 16
#define AQH_MSGDATA_GETVALUES_RSP_VALUES_SIZE 128
#define AQH_MSGDATA_GETVALUES_RSP_MINSIZE (GWEN_MSGIPC_OFFS_PAYLOAD+AQH_MSGDATA_GETVALUES_RSP_OFFS_VALUES)
GWEN_MSG *AQH_GetValuesRspDataIpcMsg_new(uint16_t code, uint32_t flags, const AQH_VALUE_LIST *valueList)
{
GWEN_MSG *msg;
uint8_t *ptr;
int count;
int payloadSize;
count=AQH_Value_List_GetCount(valueList);
payloadSize=AQH_MSGDATA_GETVALUES_RSP_OFFS_VALUES+(count*AQH_MSGDATA_GETVALUES_RSP_VALUES_SIZE);
msg=GWEN_IpcMsg_new(AQH_IPC_PROTOCOL_DATA_ID, AQH_IPC_PROTOCOL_DATA_VERSION, code, payloadSize, NULL);
ptr=GWEN_Msg_GetBuffer(msg)+GWEN_MSGIPC_OFFS_PAYLOAD;
*(ptr++)=flags & 0xff;
*(ptr++)=(flags>>8) & 0xff;
*(ptr++)=(flags>>16) & 0xff;
*(ptr++)=(flags>>24) & 0xff;
*(ptr++)=count & 0xff;
*(ptr++)=(count>>8) & 0xff;
*(ptr++)=(count>>16) & 0xff;
*(ptr++)=(count>>24) & 0xff;
if (count>0) {
const AQH_VALUE *value;
value=AQH_Value_List_First(valueList);
while(value) {
uint64_t i64;
const char *name;
const char *units;
i64=AQH_Value_GetId(value);
name=AQH_Value_GetName(value);
units=AQH_Value_GetValueUnits(value);
*(ptr++)=i64 & 0xff;
*(ptr++)=(i64>>8) & 0xff;
*(ptr++)=(i64>>16) & 0xff;
*(ptr++)=(i64>>24) & 0xff;
*(ptr++)=(i64>>32) & 0xff;
*(ptr++)=(i64>>40) & 0xff;
*(ptr++)=(i64>>48) & 0xff;
*(ptr++)=(i64>>56) & 0xff;
if (name) {
strncpy((char*) ptr, name, AQH_MSGDATA_GETVALUES_RSP_VALUES_SIZE_NAME-1);
ptr[AQH_MSGDATA_GETVALUES_RSP_VALUES_SIZE_NAME-1]=0;
}
else
memset(ptr, 0, AQH_MSGDATA_GETVALUES_RSP_VALUES_SIZE_NAME);
ptr+=AQH_MSGDATA_GETVALUES_RSP_VALUES_SIZE_NAME;
if (units) {
strncpy((char*) ptr, units, AQH_MSGDATA_GETVALUES_RSP_VALUES_SIZE_UNITS-1);
ptr[AQH_MSGDATA_GETVALUES_RSP_VALUES_SIZE_UNITS-1]=0;
}
else
memset(ptr, 0, AQH_MSGDATA_GETVALUES_RSP_VALUES_SIZE_UNITS);
ptr+=AQH_MSGDATA_GETVALUES_RSP_VALUES_SIZE_UNITS;
value=AQH_Value_List_Next(value);
}
}
return msg;
}
uint32_t AQH_GetValuesRspDataIpcMsg_GetFlags(const GWEN_MSG *msg)
{
return GWEN_Msg_GetUint32At(msg, GWEN_MSGIPC_OFFS_PAYLOAD+AQH_MSGDATA_GETVALUES_RSP_OFFS_FLAGS, 0);
}
uint32_t AQH_GetValuesRspDataIpcMsg_GetNumValues(const GWEN_MSG *msg)
{
return GWEN_Msg_GetUint32At(msg, GWEN_MSGIPC_OFFS_PAYLOAD+AQH_MSGDATA_GETVALUES_RSP_OFFS_NUMVALUES, 0);
}
uint8_t AQH_GetValuesRspDataIpcMsg_GetValueId(const GWEN_MSG *msg, int idx)
{
uint32_t pos;
pos=
AQH_MSGDATA_GETVALUES_RSP_OFFS_VALUES+
(idx*AQH_MSGDATA_GETVALUES_RSP_VALUES_SIZE)+
AQH_MSGDATA_GETVALUES_RSP_VALUES_OFFS_ID;
return GWEN_Msg_GetUint64At(msg, GWEN_MSGIPC_OFFS_PAYLOAD+pos, 0);
}
const char *AQH_GetValuesRspDataIpcMsg_GetValueName(const GWEN_MSG *msg, int idx)
{
uint32_t pos;
pos=
AQH_MSGDATA_GETVALUES_RSP_OFFS_VALUES+
(idx*AQH_MSGDATA_GETVALUES_RSP_VALUES_SIZE)+
AQH_MSGDATA_GETVALUES_RSP_VALUES_OFFS_NAME;
if (GWEN_Msg_GetBytesInBuffer(msg)>=pos+GWEN_MSGIPC_OFFS_PAYLOAD)
return (const char*) (GWEN_Msg_GetConstBuffer(msg)+GWEN_MSGIPC_OFFS_PAYLOAD+pos);
return NULL;
}
int AQH_GetValuesRspDataIpcMsg_IsValid(const GWEN_MSG *msg)
{
int msgLen;
int numValues;
const uint8_t *ptr;
int i;
msgLen=GWEN_Msg_GetBytesInBuffer(msg);
if (msgLen<AQH_MSGDATA_GETVALUES_RSP_MINSIZE) {
DBG_ERROR(AQH_LOGDOMAIN, "Message too small (%d<%d)", GWEN_Msg_GetBytesInBuffer(msg), AQH_MSGDATA_GETVALUES_RSP_MINSIZE);
return 0;
}
numValues=(int)AQH_GetValuesRspDataIpcMsg_GetNumValues(msg);
if (msgLen<(numValues*AQH_MSGDATA_GETVALUES_RSP_VALUES_SIZE)+AQH_MSGDATA_GETVALUES_RSP_OFFS_VALUES+GWEN_MSGIPC_OFFS_PAYLOAD) {
DBG_ERROR(AQH_LOGDOMAIN, "Message too small to contain %d values", numValues);
return 0;
}
ptr=GWEN_Msg_GetConstBuffer(msg)+GWEN_MSGIPC_OFFS_PAYLOAD+AQH_MSGDATA_GETVALUES_RSP_OFFS_VALUES;
for (i=0; i<numValues; i++) {
if (ptr[AQH_MSGDATA_GETVALUES_RSP_VALUES_OFFS_NAME+AQH_MSGDATA_GETVALUES_RSP_VALUES_SIZE_NAME-1]!=0) {
DBG_ERROR(AQH_LOGDOMAIN, "Name string for value %d is not null-terminated", i);
return 0;
}
if (ptr[AQH_MSGDATA_GETVALUES_RSP_VALUES_OFFS_UNITS+AQH_MSGDATA_GETVALUES_RSP_VALUES_SIZE_UNITS-1]!=0) {
DBG_ERROR(AQH_LOGDOMAIN, "Units string for value %d is not null-terminated", i);
return 0;
}
ptr+=AQH_MSGDATA_GETVALUES_RSP_VALUES_SIZE;
}
return 1;
}
void AQH_GetValuesRspDataIpcMsg_DumpToBuffer(const GWEN_MSG *msg, GWEN_BUFFER *dbuf, const char *sText)
{
if (GWEN_Msg_GetBytesInBuffer(msg)>=AQH_MSGDATA_GETVALUES_RSP_MINSIZE) {
GWEN_Buffer_AppendArgs(dbuf,
"GETVALUESRSP (code=%d, proto=%d, proto version=%d, flags=0x%08x, values=%d)\n",
GWEN_IpcMsg_GetCode(msg),
GWEN_IpcMsg_GetProtoId(msg),
GWEN_IpcMsg_GetProtoVersion(msg),
(unsigned int)AQH_GetValuesRspDataIpcMsg_GetFlags(msg),
AQH_GetValuesRspDataIpcMsg_GetNumValues(msg));
}
}

View File

@@ -1,42 +0,0 @@
/****************************************************************************
* 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_DATA_GETVALUES_RSP_H
#define AQH_MSG_IPC_DATA_GETVALUES_RSP_H
#include <aqhome/api.h>
#include <aqhome/data/value.h>
#include <gwenhywfar/msg_ipc.h>
#define AQH_MSGDATA_GETVALUES_RSP_FLAGS_LASTMSG 0x0001
AQHOME_API GWEN_MSG *AQH_GetValuesRspDataIpcMsg_new(uint16_t code, uint32_t flags, const AQH_VALUE_LIST *valueList);
AQHOME_API uint32_t AQH_GetValuesRspDataIpcMsg_GetFlags(const GWEN_MSG *msg);
AQHOME_API uint32_t AQH_GetValuesRspDataIpcMsg_GetNumValues(const GWEN_MSG *msg);
AQHOME_API uint8_t AQH_GetValuesRspDataIpcMsg_GetValueId(const GWEN_MSG *msg, int idx);
AQHOME_API const char *AQH_GetValuesRspDataIpcMsg_GetValueName(const GWEN_MSG *msg, int idx);
AQHOME_API int AQH_GetValuesRspDataIpcMsg_IsValid(const GWEN_MSG *msg);
AQHOME_API void AQH_GetValuesRspDataIpcMsg_DumpToBuffer(const GWEN_MSG *msg, GWEN_BUFFER *dbuf, const char *sText);
#endif

View File

@@ -42,12 +42,12 @@
static void _writeValue(const AQH_VALUE *value, uint8_t *ptr);
static void _writeValue(const AQH_VALUE *value, uint8_t *ptr, int useSystemName);
GWEN_MSG *AQH_ValuesDataIpcMsg_new(uint16_t code, uint32_t flags, const AQH_VALUE_LIST *valueList)
GWEN_MSG *AQH_ValuesDataIpcMsg_new(uint16_t code, uint32_t flags, const AQH_VALUE_LIST *valueList, int useSystemName)
{
GWEN_MSG *msg;
uint8_t *ptr;
@@ -74,7 +74,7 @@ GWEN_MSG *AQH_ValuesDataIpcMsg_new(uint16_t code, uint32_t flags, const AQH_VALU
value=AQH_Value_List_First(valueList);
while(value) {
_writeValue(value, ptr);
_writeValue(value, ptr, useSystemName);
ptr+=AQH_MSGDATA_VALUES_VALUES_SIZE;
value=AQH_Value_List_Next(value);
}
@@ -84,7 +84,7 @@ GWEN_MSG *AQH_ValuesDataIpcMsg_new(uint16_t code, uint32_t flags, const AQH_VALU
GWEN_MSG *AQH_ValuesDataIpcMsg_newForOneValue(uint16_t code, uint32_t flags, const AQH_VALUE *value)
GWEN_MSG *AQH_ValuesDataIpcMsg_newForOneValue(uint16_t code, uint32_t flags, const AQH_VALUE *value, int useSystemName)
{
GWEN_MSG *msg;
uint8_t *ptr;
@@ -106,21 +106,21 @@ GWEN_MSG *AQH_ValuesDataIpcMsg_newForOneValue(uint16_t code, uint32_t flags, con
*(ptr++)=(count>>16) & 0xff;
*(ptr++)=(count>>24) & 0xff;
_writeValue(value, ptr);
_writeValue(value, ptr, useSystemName);
return msg;
}
void _writeValue(const AQH_VALUE *value, uint8_t *ptr)
void _writeValue(const AQH_VALUE *value, uint8_t *ptr, int useSystemName)
{
uint64_t i64;
const char *name;
const char *units;
i64=AQH_Value_GetId(value);
name=AQH_Value_GetName(value);
name=useSystemName?AQH_Value_GetNameForSystem(value):AQH_Value_GetNameForDriver(value);
units=AQH_Value_GetValueUnits(value);
*(ptr++)=i64 & 0xff;

View File

@@ -24,8 +24,8 @@
#define AQH_MSGDATA_VALUES_FLAGS_LASTMSG 0x0001
AQHOME_API GWEN_MSG *AQH_ValuesDataIpcMsg_new(uint16_t code, uint32_t flags, const AQH_VALUE_LIST *valueList);
AQHOME_API GWEN_MSG *AQH_ValuesDataIpcMsg_newForOneValue(uint16_t code, uint32_t flags, const AQH_VALUE *value);
AQHOME_API GWEN_MSG *AQH_ValuesDataIpcMsg_new(uint16_t code, uint32_t flags, const AQH_VALUE_LIST *valueList, int useSystemName);
AQHOME_API GWEN_MSG *AQH_ValuesDataIpcMsg_newForOneValue(uint16_t code, uint32_t flags, const AQH_VALUE *value, int useSystemName);
AQHOME_API uint32_t AQH_ValuesDataIpcMsg_GetFlags(const GWEN_MSG *msg);

View File

@@ -55,6 +55,10 @@ void _freeData(void *bp, void *p)
AQH_ENDPOINT_IPC *xep;
xep=(AQH_ENDPOINT_IPC*) p;
free(xep->serviceName);
free(xep->userName);
GWEN_FREE_OBJECT(xep);
}
@@ -115,6 +119,94 @@ void AQH_IpcEndpoint_SubAcceptedMsgGroups(GWEN_MSG_ENDPOINT *ep, uint32_t i)
const char *AQH_IpcEndpoint_GetServiceName(const GWEN_MSG_ENDPOINT *ep)
{
if (ep) {
AQH_ENDPOINT_IPC *xep;
xep=GWEN_INHERIT_GETDATA(GWEN_MSG_ENDPOINT, AQH_ENDPOINT_IPC, ep);
if (xep)
return xep->serviceName;
}
return NULL;
}
void AQH_IpcEndpoint_SetServiceName(GWEN_MSG_ENDPOINT *ep, const char *s)
{
if (ep) {
AQH_ENDPOINT_IPC *xep;
xep=GWEN_INHERIT_GETDATA(GWEN_MSG_ENDPOINT, AQH_ENDPOINT_IPC, ep);
if (xep) {
free(xep->serviceName);
xep->serviceName=s?strdup(s):NULL;
}
}
}
const char *AQH_IpcEndpoint_GetUserName(const GWEN_MSG_ENDPOINT *ep)
{
if (ep) {
AQH_ENDPOINT_IPC *xep;
xep=GWEN_INHERIT_GETDATA(GWEN_MSG_ENDPOINT, AQH_ENDPOINT_IPC, ep);
if (xep)
return xep->userName;
}
return NULL;
}
void AQH_IpcEndpoint_SetUserName(GWEN_MSG_ENDPOINT *ep, const char *s)
{
if (ep) {
AQH_ENDPOINT_IPC *xep;
xep=GWEN_INHERIT_GETDATA(GWEN_MSG_ENDPOINT, AQH_ENDPOINT_IPC, ep);
if (xep) {
free(xep->userName);
xep->userName=s?strdup(s):NULL;
}
}
}
uint32_t AQH_IpcEndpoint_GetPermissions(const GWEN_MSG_ENDPOINT *ep)
{
if (ep) {
AQH_ENDPOINT_IPC *xep;
xep=GWEN_INHERIT_GETDATA(GWEN_MSG_ENDPOINT, AQH_ENDPOINT_IPC, ep);
if (xep)
return xep->permissions;
}
return 0;
}
void AQH_IpcEndpoint_SetPermissions(GWEN_MSG_ENDPOINT *ep, uint32_t i)
{
if (ep) {
AQH_ENDPOINT_IPC *xep;
xep=GWEN_INHERIT_GETDATA(GWEN_MSG_ENDPOINT, AQH_ENDPOINT_IPC, ep);
if (xep)
xep->permissions=i;
}
}
GWEN_MSG_ENDPOINT *AQH_IpcEndpoint_CreateIpcTcpClient(const char *host, int port, const char *name, int groupId)
{
GWEN_MSG_ENDPOINT *ep;

View File

@@ -15,6 +15,17 @@
#include <gwenhywfar/endpoint.h>
#define AQH_IPCENDPOINT_FLAGS_WANTUPDATES 0x0001
#define AQH_IPCENDPOINT_PERMS_LISTVALUES 0x0001
#define AQH_IPCENDPOINT_PERMS_READVALUE 0x0002
#define AQH_IPCENDPOINT_PERMS_ADDVALUE 0x0004
#define AQH_IPCENDPOINT_PERMS_LISTDATA 0x0010
#define AQH_IPCENDPOINT_PERMS_READDATA 0x0020
#define AQH_IPCENDPOINT_PERMS_ADDDATA 0x0040
AQHOME_API void AQH_IpcEndpoint_Extend(GWEN_MSG_ENDPOINT *ep);
@@ -26,6 +37,15 @@ AQHOME_API void AQH_IpcEndpoint_SetAcceptedMsgGroups(GWEN_MSG_ENDPOINT *ep, uint
AQHOME_API void AQH_IpcEndpoint_AddAcceptedMsgGroups(GWEN_MSG_ENDPOINT *ep, uint32_t i);
AQHOME_API void AQH_IpcEndpoint_SubAcceptedMsgGroups(GWEN_MSG_ENDPOINT *ep, uint32_t i);
AQHOME_API const char *AQH_IpcEndpoint_GetServiceName(const GWEN_MSG_ENDPOINT *ep);
AQHOME_API void AQH_IpcEndpoint_SetServiceName(GWEN_MSG_ENDPOINT *ep, const char *s);
AQHOME_API const char *AQH_IpcEndpoint_GetUserName(const GWEN_MSG_ENDPOINT *ep);
AQHOME_API void AQH_IpcEndpoint_SetUserName(GWEN_MSG_ENDPOINT *ep, const char *s);
AQHOME_API uint32_t AQH_IpcEndpoint_GetPermissions(const GWEN_MSG_ENDPOINT *ep);
AQHOME_API void AQH_IpcEndpoint_SetPermissions(GWEN_MSG_ENDPOINT *ep, uint32_t i);
#endif

View File

@@ -20,6 +20,9 @@
typedef struct AQH_ENDPOINT_IPC AQH_ENDPOINT_IPC;
struct AQH_ENDPOINT_IPC {
uint32_t acceptedMsgGroups;
char *serviceName;
char *userName;
uint32_t permissions;
};

View File

@@ -22,12 +22,14 @@
#define AQH_IPC_PROTOCOL_RESULT_VERSION 1
#define AQH_MSG_IPC_SUCCESS 0
#define AQH_MSG_IPC_ERROR_GENERIC 1
#define AQH_MSG_IPC_ERROR_INVALID 2
#define AQH_MSG_IPC_ERROR_EXISTS 3
#define AQH_MSG_IPC_ERROR_NODATA 4
#define AQH_MSG_IPC_ERROR_BADDATA 5
#define AQH_MSG_IPC_SUCCESS 0
#define AQH_MSG_IPC_ERROR_GENERIC 1
#define AQH_MSG_IPC_ERROR_INVALID 2
#define AQH_MSG_IPC_ERROR_EXISTS 3
#define AQH_MSG_IPC_ERROR_NODATA 4
#define AQH_MSG_IPC_ERROR_BADDATA 5
#define AQH_MSG_IPC_ERROR_PERMS 6
#define AQH_MSG_IPC_ERROR_NOTFOUND 7
AQHOME_API GWEN_MSG *AQH_ResultIpcMsg_new(uint16_t code, uint32_t resultCode);

View File

@@ -18,25 +18,9 @@
GWEN_MSG *AQH_Tag16IpcMsg_new(uint8_t protoId, uint8_t protoVer, uint16_t code, const GWEN_TAG16_LIST *tagList)
GWEN_MSG *AQH_Tag16IpcMsg_new(uint8_t protoId, uint8_t protoVer, uint16_t code, uint32_t payloadLen, const uint8_t *payload)
{
GWEN_MSG *msg;
const GWEN_TAG16 *tag;
GWEN_BUFFER *buf;
buf=GWEN_Buffer_new(0, 256, 0, 1);
tag=GWEN_Tag16_List_First(tagList);
while(tag) {
GWEN_Tag16_DirectlyToBuffer(GWEN_Tag16_GetTagType(tag),
GWEN_Tag16_GetTagData(tag),
GWEN_Tag16_GetTagLength(tag),
buf);
tag=GWEN_Tag16_List_Next(tag);
}
msg=GWEN_IpcMsg_new(protoId, protoVer, code, GWEN_Buffer_GetUsedBytes(buf), (const uint8_t*) GWEN_Buffer_GetStart(buf));
GWEN_Buffer_free(buf);
return msg;
return GWEN_IpcMsg_new(protoId, protoVer, code, payloadLen, payload);
}
@@ -49,33 +33,20 @@ GWEN_TAG16_LIST *AQH_Tag16IpcMsg_ParseTags(const GWEN_MSG *msg, int doCopy)
if (msgSize>GWEN_MSGIPC_OFFS_PAYLOAD) {
const uint8_t *ptr;
uint32_t payloadSize;
GWEN_TAG16_LIST *tagList;
ptr=GWEN_Msg_GetConstBuffer(msg)+GWEN_MSGIPC_OFFS_PAYLOAD;
payloadSize=msgSize-GWEN_MSGIPC_OFFS_PAYLOAD;
tagList=GWEN_Tag16_List_new();
while(payloadSize) {
GWEN_TAG16 *tag;
unsigned int tagSize;
tag=GWEN_Tag16_fromBuffer2(ptr, payloadSize, doCopy);
if (tag==NULL)
break;
tagSize=GWEN_Tag16_GetTagSize(tag);
if (payloadSize>tagSize) {
DBG_ERROR(AQH_LOGDOMAIN, "Error in tag size");
GWEN_Tag16_List_free(tagList);
if (payloadSize) {
GWEN_TAG16_LIST *tagList;
tagList=GWEN_Tag16_List_fromBuffer(ptr, payloadSize, doCopy);
if (tagList==NULL) {
DBG_INFO(AQH_LOGDOMAIN, "Error reading tags from message");
return NULL;
}
GWEN_Tag16_List_Add(tag, tagList);
ptr+=tagSize;
payloadSize-=tagSize;
} /* while */
if (GWEN_Tag16_List_GetCount(tagList)<1) {
GWEN_Tag16_List_free(tagList);
return NULL;
return tagList;
}
return tagList;
}
return NULL;

View File

@@ -17,7 +17,7 @@
#include <gwenhywfar/tag16.h>
AQHOME_API GWEN_MSG *AQH_Tag16IpcMsg_new(uint8_t protoId, uint8_t protoVer, uint16_t code, const GWEN_TAG16_LIST *tagList);
AQHOME_API GWEN_MSG *AQH_Tag16IpcMsg_new(uint8_t protoId, uint8_t protoVer, uint16_t code, uint32_t payloadLen, const uint8_t *payload);
AQHOME_API GWEN_TAG16_LIST *AQH_Tag16IpcMsg_ParseTags(const GWEN_MSG *msg, int doCopy);
AQHOME_API void AQH_Tag16IpcMsg_DumpToBuffer(const GWEN_MSG *msg, GWEN_BUFFER *dbuf, const char *sText);