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);