diff --git a/apps/0BUILD b/apps/0BUILD index 9aeb2dc..a418765 100644 --- a/apps/0BUILD +++ b/apps/0BUILD @@ -6,7 +6,6 @@ aqhomed aqhome-tool aqhome-mqttlog - aqhome-storage aqhome-data diff --git a/apps/aqhome-data/0BUILD b/apps/aqhome-data/0BUILD index 26f2031..c98fe2f 100644 --- a/apps/aqhome-data/0BUILD +++ b/apps/aqhome-data/0BUILD @@ -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 @@ -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 diff --git a/apps/aqhome-data/aqhome_data.c b/apps/aqhome-data/aqhome_data.c index 75afd47..950cce0 100644 --- a/apps/aqhome-data/aqhome_data.c +++ b/apps/aqhome-data/aqhome_data.c @@ -12,6 +12,7 @@ #include "./aqhome_data_p.h" +#include "aqhome/ipc/endpoint_ipc.h" #include #include @@ -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; +} + diff --git a/apps/aqhome-data/aqhome_data.h b/apps/aqhome-data/aqhome_data.h index 3c89906..60e0227 100644 --- a/apps/aqhome-data/aqhome_data.h +++ b/apps/aqhome-data/aqhome_data.h @@ -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); diff --git a/apps/aqhome-data/c_connect.c b/apps/aqhome-data/c_connect.c new file mode 100644 index 0000000..5284306 --- /dev/null +++ b/apps/aqhome-data/c_connect.c @@ -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 +#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 + + + +/* ------------------------------------------------------------------------------------------------ + * 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); +} + + + diff --git a/aqhome/ipc/data/msg_data_getvalues_req.h b/apps/aqhome-data/c_connect.h similarity index 65% rename from aqhome/ipc/data/msg_data_getvalues_req.h rename to apps/aqhome-data/c_connect.h index 7395bcd..bfc8550 100644 --- a/aqhome/ipc/data/msg_data_getvalues_req.h +++ b/apps/aqhome-data/c_connect.h @@ -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 - -#include - - - -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); + + diff --git a/apps/aqhome-data/c_getdatapoints.c b/apps/aqhome-data/c_getdatapoints.c new file mode 100644 index 0000000..5e38b4a --- /dev/null +++ b/apps/aqhome-data/c_getdatapoints.c @@ -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 +#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 + + + +/* ------------------------------------------------------------------------------------------------ + * 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); +} + + diff --git a/apps/aqhome-data/c_getdatapoints.h b/apps/aqhome-data/c_getdatapoints.h new file mode 100644 index 0000000..b89fa5b --- /dev/null +++ b/apps/aqhome-data/c_getdatapoints.h @@ -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 + + + + + diff --git a/apps/aqhome-data/c_getlastdatapoint.c b/apps/aqhome-data/c_getlastdatapoint.c new file mode 100644 index 0000000..3844e52 --- /dev/null +++ b/apps/aqhome-data/c_getlastdatapoint.c @@ -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 +#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 + + + +/* ------------------------------------------------------------------------------------------------ + * defines + * ------------------------------------------------------------------------------------------------ + */ + + + +/* ------------------------------------------------------------------------------------------------ + * forward declarations + * ------------------------------------------------------------------------------------------------ + */ + + + +/* ------------------------------------------------------------------------------------------------ + * implementations + * ------------------------------------------------------------------------------------------------ + */ + + +void AqHomeData_HandleGetLastDataPoint(AQHOME_DATA *aqh, GWEN_MSG_ENDPOINT *ep, const GWEN_MSG *msg) +{ +} + + diff --git a/apps/aqhome-data/c_getlastdatapoint.h b/apps/aqhome-data/c_getlastdatapoint.h new file mode 100644 index 0000000..972c905 --- /dev/null +++ b/apps/aqhome-data/c_getlastdatapoint.h @@ -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 + + + + + diff --git a/apps/aqhome-data/c_getvalues.c b/apps/aqhome-data/c_getvalues.c new file mode 100644 index 0000000..2d604d1 --- /dev/null +++ b/apps/aqhome-data/c_getvalues.c @@ -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 +#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 + + + +/* ------------------------------------------------------------------------------------------------ + * 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, 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); +} + + + diff --git a/apps/aqhome-data/c_getvalues.h b/apps/aqhome-data/c_getvalues.h new file mode 100644 index 0000000..5cdfde6 --- /dev/null +++ b/apps/aqhome-data/c_getvalues.h @@ -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 + + + + + diff --git a/apps/aqhome-data/c_updatedata.c b/apps/aqhome-data/c_updatedata.c new file mode 100644 index 0000000..eb526d2 --- /dev/null +++ b/apps/aqhome-data/c_updatedata.c @@ -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 +#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 + + + +/* ------------------------------------------------------------------------------------------------ + * 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; istorage, 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; +} + + + diff --git a/apps/aqhome-data/c_updatedata.h b/apps/aqhome-data/c_updatedata.h new file mode 100644 index 0000000..34ba363 --- /dev/null +++ b/apps/aqhome-data/c_updatedata.h @@ -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 + + + + + diff --git a/apps/aqhome-data/loop.c b/apps/aqhome-data/loop.c index 3500010..27cc0ca 100644 --- a/apps/aqhome-data/loop.c +++ b/apps/aqhome-data/loop.c @@ -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, 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; istorage, 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) -{ -} - - - - - - - diff --git a/apps/aqhome-storage/u_values.c b/apps/aqhome-storage/u_values.c index 4b8ee43..622fe6e 100644 --- a/apps/aqhome-storage/u_values.c +++ b/apps/aqhome-storage/u_values.c @@ -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); diff --git a/apps/aqhome-tool/data/0BUILD b/apps/aqhome-tool/data/0BUILD index 2185d69..21385ed 100644 --- a/apps/aqhome-tool/data/0BUILD +++ b/apps/aqhome-tool/data/0BUILD @@ -34,16 +34,16 @@ getvalues.h - addvalue.h adddata.h + getdatapoints.h $(local/typefiles) getvalues.c - addvalue.c adddata.c + getdatapoints.c diff --git a/apps/aqhome-tool/data/adddata.c b/apps/aqhome-tool/data/adddata.c index 9c9fd48..542b53b 100644 --- a/apps/aqhome-tool/data/adddata.c +++ b/apps/aqhome-tool/data/adddata.c @@ -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); } diff --git a/apps/aqhome-tool/data/addvalue.c b/apps/aqhome-tool/data/getdatapoints.c similarity index 52% rename from apps/aqhome-tool/data/addvalue.c rename to apps/aqhome-tool/data/getdatapoints.c index 7821f51..29e4727 100644 --- a/apps/aqhome-tool/data/addvalue.c +++ b/apps/aqhome-tool/data/getdatapoints.c @@ -10,12 +10,12 @@ # include #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 @@ -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 -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 diff --git a/apps/aqhome-tool/data/getvalues.c b/apps/aqhome-tool/data/getvalues.c index 8a76bf7..65f3d2c 100644 --- a/apps/aqhome-tool/data/getvalues.c +++ b/apps/aqhome-tool/data/getvalues.c @@ -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); diff --git a/apps/aqhome-tool/main.c b/apps/aqhome-tool/main.c index 664b190..b02006d 100644 --- a/apps/aqhome-tool/main.c +++ b/apps/aqhome-tool/main.c @@ -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 #include @@ -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; diff --git a/apps/aqhome-tool/utils.c b/apps/aqhome-tool/utils.c index 6072dcc..9977113 100644 --- a/apps/aqhome-tool/utils.c +++ b/apps/aqhome-tool/utils.c @@ -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 #include @@ -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; +} + + + diff --git a/apps/aqhome-tool/utils.h b/apps/aqhome-tool/utils.h index e06f032..ed88c49 100644 --- a/apps/aqhome-tool/utils.h +++ b/apps/aqhome-tool/utils.h @@ -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 diff --git a/aqhome/data/storage.c b/aqhome/data/storage.c index 8eac62a..a508515 100644 --- a/aqhome/data/storage.c +++ b/aqhome/data/storage.c @@ -21,6 +21,9 @@ #include +#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=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)); } } diff --git a/aqhome/data/storage.h b/aqhome/data/storage.h index c1a1675..45aceee 100644 --- a/aqhome/data/storage.h +++ b/aqhome/data/storage.h @@ -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); diff --git a/aqhome/data/value.t2d b/aqhome/data/value.t2d index 23473cb..26ab7a7 100644 --- a/aqhome/data/value.t2d +++ b/aqhome/data/value.t2d @@ -49,7 +49,21 @@ with_getbymember - + + 0 + 0 + public + own + + + + 0 + 0 + public + own + + + 0 0 public diff --git a/aqhome/ipc/0BUILD b/aqhome/ipc/0BUILD index 0395db3..d4f24a6 100644 --- a/aqhome/ipc/0BUILD +++ b/aqhome/ipc/0BUILD @@ -48,6 +48,7 @@ endpoint_ipc.h msg_ipc_result.h msg_ipc_qwords.h + msg_ipc_tag16.h @@ -62,6 +63,7 @@ endpoint_ipc.c msg_ipc_result.c msg_ipc_qwords.c + msg_ipc_tag16.c diff --git a/aqhome/ipc/data/0BUILD b/aqhome/ipc/data/0BUILD index b3baaad..456f52e 100644 --- a/aqhome/ipc/data/0BUILD +++ b/aqhome/ipc/data/0BUILD @@ -46,10 +46,9 @@ 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 @@ -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 diff --git a/aqhome/ipc/data/ipc_data.h b/aqhome/ipc/data/ipc_data.h index c789fbc..df32b78 100644 --- a/aqhome/ipc/data/ipc_data.h +++ b/aqhome/ipc/data/ipc_data.h @@ -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 */ diff --git a/aqhome/ipc/data/msg_data_connect.c b/aqhome/ipc/data/msg_data_connect.c new file mode 100644 index 0000000..4703f91 --- /dev/null +++ b/aqhome/ipc/data/msg_data_connect.c @@ -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 +#endif + +#include +#include +#include + +#include +#include + +#include +#include + + + +#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:"", + userId?userId:"", + flags); + free(userId); + free(clientId); + GWEN_Tag16_List_free(tagList); + } +} + + + + + + + diff --git a/aqhome/ipc/data/msg_data_connect.h b/aqhome/ipc/data/msg_data_connect.h new file mode 100644 index 0000000..9985214 --- /dev/null +++ b/aqhome/ipc/data/msg_data_connect.h @@ -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 + +#include + +#include + + +/** + * 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 + + + diff --git a/aqhome/ipc/data/msg_data_getvalues_req.c b/aqhome/ipc/data/msg_data_getvalues_req.c deleted file mode 100644 index fdc59a9..0000000 --- a/aqhome/ipc/data/msg_data_getvalues_req.c +++ /dev/null @@ -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 -#endif - -#include -#include - -#include -#include - -#include -#include -#include -#include -#include -#include - - - - -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)); - } -} - - - - - - - diff --git a/aqhome/ipc/data/msg_data_getvalues_rsp.c b/aqhome/ipc/data/msg_data_getvalues_rsp.c deleted file mode 100644 index a31273d..0000000 --- a/aqhome/ipc/data/msg_data_getvalues_rsp.c +++ /dev/null @@ -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 -#endif - -#include -#include - -#include -#include - -#include -#include - -#include - - -#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) { - 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)); - } -} - - - - - - - diff --git a/aqhome/ipc/data/msg_data_getvalues_rsp.h b/aqhome/ipc/data/msg_data_getvalues_rsp.h deleted file mode 100644 index 5c4c587..0000000 --- a/aqhome/ipc/data/msg_data_getvalues_rsp.h +++ /dev/null @@ -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 - -#include - -#include - - -#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 - - - diff --git a/aqhome/ipc/data/msg_data_values.c b/aqhome/ipc/data/msg_data_values.c index fc5fa2a..9906405 100644 --- a/aqhome/ipc/data/msg_data_values.c +++ b/aqhome/ipc/data/msg_data_values.c @@ -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; diff --git a/aqhome/ipc/data/msg_data_values.h b/aqhome/ipc/data/msg_data_values.h index cba0c5a..0a85769 100644 --- a/aqhome/ipc/data/msg_data_values.h +++ b/aqhome/ipc/data/msg_data_values.h @@ -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); diff --git a/aqhome/ipc/endpoint_ipc.c b/aqhome/ipc/endpoint_ipc.c index 947d09b..db547eb 100644 --- a/aqhome/ipc/endpoint_ipc.c +++ b/aqhome/ipc/endpoint_ipc.c @@ -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; diff --git a/aqhome/ipc/endpoint_ipc.h b/aqhome/ipc/endpoint_ipc.h index bd60c8b..5f02504 100644 --- a/aqhome/ipc/endpoint_ipc.h +++ b/aqhome/ipc/endpoint_ipc.h @@ -15,6 +15,17 @@ #include +#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 diff --git a/aqhome/ipc/endpoint_ipc_p.h b/aqhome/ipc/endpoint_ipc_p.h index 6fce069..4d6d740 100644 --- a/aqhome/ipc/endpoint_ipc_p.h +++ b/aqhome/ipc/endpoint_ipc_p.h @@ -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; }; diff --git a/aqhome/ipc/msg_ipc_result.h b/aqhome/ipc/msg_ipc_result.h index 91a417d..91788e5 100644 --- a/aqhome/ipc/msg_ipc_result.h +++ b/aqhome/ipc/msg_ipc_result.h @@ -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); diff --git a/aqhome/ipc/msg_ipc_tag16.c b/aqhome/ipc/msg_ipc_tag16.c index 796343d..2aa9f5e 100644 --- a/aqhome/ipc/msg_ipc_tag16.c +++ b/aqhome/ipc/msg_ipc_tag16.c @@ -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; diff --git a/aqhome/ipc/msg_ipc_tag16.h b/aqhome/ipc/msg_ipc_tag16.h index f1a3e87..510a262 100644 --- a/aqhome/ipc/msg_ipc_tag16.h +++ b/aqhome/ipc/msg_ipc_tag16.h @@ -17,7 +17,7 @@ #include -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);