diff --git a/apps/aqhome-nodes/0BUILD b/apps/aqhome-nodes/0BUILD
index b1deec1..5c0eca9 100644
--- a/apps/aqhome-nodes/0BUILD
+++ b/apps/aqhome-nodes/0BUILD
@@ -49,6 +49,9 @@
tty_log.h
devicesread.h
devicesdump.h
+ requests.h
+ n_setdata.h
+ r_setdata.h
@@ -67,6 +70,9 @@
tty_log.c
devicesread.c
devicesdump.c
+ requests.c
+ n_setdata.c
+ r_setdata.c
diff --git a/apps/aqhome-nodes/n_setdata.c b/apps/aqhome-nodes/n_setdata.c
new file mode 100644
index 0000000..01e5286
--- /dev/null
+++ b/apps/aqhome-nodes/n_setdata.c
@@ -0,0 +1,166 @@
+/****************************************************************************
+ * This file is part of the project AqHome.
+ * AqHome (c) by 2024 Martin Preuss, all rights reserved.
+ *
+ * The license for this file can be found in the file COPYING which you
+ * should have received along with this file.
+ ****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include
+#endif
+
+
+#include "./n_setdata.h"
+#include "./aqhomed_p.h"
+#include "./r_setdata.h"
+
+#include "aqhome/data/value.h"
+#include "aqhome/ipc/data/msg_data_set.h"
+#include "aqhome/ipc/data/ipc_data.h"
+#include "aqhome/ipc/msg_ipc_result.h"
+#include "aqhome/ipc/endpoint_ipc.h"
+
+#include
+
+
+
+/* ------------------------------------------------------------------------------------------------
+ * defines
+ * ------------------------------------------------------------------------------------------------
+ */
+
+
+
+
+/* ------------------------------------------------------------------------------------------------
+ * forward declarations
+ * ------------------------------------------------------------------------------------------------
+ */
+
+static int _readDataFromString(const char *s, uint16_t *pDataVal, uint16_t *pDataDenom);
+static AQH_NODE_INFO *_getNodeInfoFromValue(AQHOMED *aqh, const AQH_VALUE *value);
+
+
+
+/* ------------------------------------------------------------------------------------------------
+ * implementations
+ * ------------------------------------------------------------------------------------------------
+ */
+
+void AqHomeNodes_HandleNodeSetData(AQHOMED *aqh, GWEN_MSG_ENDPOINT *ep, GWEN_MSG *recvdMsg)
+{
+ uint32_t msgId;
+
+ DBG_DEBUG(AQH_LOGDOMAIN, "Received IPC SetDataRequest message");
+ msgId=GWEN_IpcMsg_GetMsgId(recvdMsg);
+
+ if (aqh->ttyEndpoint && GWEN_MsgEndpoint_GetState(aqh->ttyEndpoint)==GWEN_MSG_ENDPOINT_STATE_CONNECTED) {
+ AQH_VALUE *value;
+
+ AQH_SetDataIpcMsg_Parse(recvdMsg, 0);
+ value=AQH_SetDataIpcMsg_ReadValue(recvdMsg);
+ if (value) {
+ char *data;
+
+ data=AQH_SetDataIpcMsg_ReadData(recvdMsg);
+ if (data) {
+ uint16_t dataVal=0;
+ uint16_t dataDenom=0;
+
+ if (_readDataFromString(data, &dataVal, &dataDenom)==0) {
+ AQH_NODE_INFO *nodeInfo;
+
+ nodeInfo=_getNodeInfoFromValue(aqh, value);
+ if (nodeInfo) {
+ int valueId=0;
+ const char *s;
+
+ s=AQH_Value_GetName(value);
+ if (s && *s && 1==sscanf(s, "%d", &valueId)) {
+ GWEN_MSG_REQUEST *rq;
+ int destAddr;
+
+ destAddr=AQH_NodeInfo_GetBusAddress(nodeInfo);
+
+ rq=AqHomeNodes_MkRequest_SetData(aqh, ep, msgId, destAddr, valueId, dataVal, dataDenom);
+ AqHomed_AddRequestToTree(aqh, rq);
+ /* done */
+ }
+ else {
+ DBG_ERROR(AQH_LOGDOMAIN, "Invalid value id \"%s\"", s);
+ AQH_IpcEndpoint_SendResponseResult(ep, msgId, AQH_MSGTYPE_IPC_DATA_RESULT, AQH_MSG_IPC_ERROR_INVALID);
+ }
+ }
+ else {
+ DBG_ERROR(AQH_LOGDOMAIN, "No matching node found");
+ AQH_IpcEndpoint_SendResponseResult(ep, msgId, AQH_MSGTYPE_IPC_DATA_RESULT, AQH_MSG_IPC_ERROR_NOTFOUND);
+ }
+ }
+ else {
+ DBG_ERROR(AQH_LOGDOMAIN, "Bad data \"%s\"", data);
+ AQH_IpcEndpoint_SendResponseResult(ep, msgId, AQH_MSGTYPE_IPC_DATA_RESULT, AQH_MSG_IPC_ERROR_BADDATA);
+ }
+ free(data);
+ }
+ else {
+ DBG_ERROR(AQH_LOGDOMAIN, "No data");
+ AQH_IpcEndpoint_SendResponseResult(ep, msgId, AQH_MSGTYPE_IPC_DATA_RESULT, AQH_MSG_IPC_ERROR_NODATA);
+ }
+ AQH_Value_free(value);
+ }
+ else {
+ DBG_ERROR(AQH_LOGDOMAIN, "Could not read value from message");
+ }
+ }
+ else {
+ DBG_ERROR(AQH_LOGDOMAIN, "TTY endpoint not connected");
+ AQH_IpcEndpoint_SendResponseResult(ep, msgId, AQH_MSGTYPE_IPC_DATA_RESULT, AQH_MSG_IPC_ERROR_IO);
+ }
+}
+
+
+
+int _readDataFromString(const char *s, uint16_t *pDataVal, uint16_t *pDataDenom)
+{
+ if (s && *s) {
+ if (*s=='&') {
+ unsigned long int v=0;
+
+ s++;
+ if (1==sscanf(s, "%lx", &v)) {
+ *pDataVal=(v>>16) & 0xffff;
+ *pDataDenom=v & 0xffff;
+ return 0;
+ }
+ else {
+ DBG_ERROR(AQH_LOGDOMAIN, "Bad hex value \"%s\"", s);
+ }
+ }
+ }
+
+ return GWEN_ERROR_GENERIC;
+}
+
+
+
+AQH_NODE_INFO *_getNodeInfoFromValue(AQHOMED *aqh, const AQH_VALUE *value)
+{
+ const char *s;
+ unsigned long int uid;
+
+ s=AQH_Value_GetDeviceName(value);
+ if (s && *s && 1==sscanf(s, "%lx", &uid)) {
+ AQH_NODE_INFO *ni;
+
+ ni=AQH_NodeDb_GetNodeInfoByUid(aqh->nodeDb, uid);
+ if (ni==NULL) {
+ DBG_INFO(AQH_LOGDOMAIN, "Node \"%08lx\" not found", uid);
+ return NULL;
+ }
+ return ni;
+ }
+ return NULL;
+}
+
+
diff --git a/apps/aqhome-nodes/n_setdata.h b/apps/aqhome-nodes/n_setdata.h
new file mode 100644
index 0000000..e705750
--- /dev/null
+++ b/apps/aqhome-nodes/n_setdata.h
@@ -0,0 +1,26 @@
+/****************************************************************************
+ * This file is part of the project AqHome.
+ * AqHome (c) by 2024 Martin Preuss, all rights reserved.
+ *
+ * The license for this file can be found in the file COPYING which you
+ * should have received along with this file.
+ ****************************************************************************/
+
+#ifndef AQHOMED_N_SETDATA_H
+#define AQHOMED_N_SETDATA_H
+
+
+#include "./aqhomed.h"
+
+#include
+
+
+
+void AqHomeNodes_HandleNodeSetData(AQHOMED *aqh, GWEN_MSG_ENDPOINT *ep, GWEN_MSG *recvdMsg);
+
+
+
+
+#endif
+
+
diff --git a/apps/aqhome-nodes/r_setdata.c b/apps/aqhome-nodes/r_setdata.c
new file mode 100644
index 0000000..a721ae7
--- /dev/null
+++ b/apps/aqhome-nodes/r_setdata.c
@@ -0,0 +1,209 @@
+/****************************************************************************
+ * 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 "./r_setdata.h"
+#include "./aqhomed_p.h"
+
+#include "aqhome/ipc/endpoint_ipc.h"
+#include "aqhome/ipc/msg_ipc_result.h"
+#include "aqhome/ipc/data/msg_data_set.h"
+#include "aqhome/ipc/data/ipc_data.h"
+#include "aqhome/msg/msg_value3.h"
+
+#include
+
+
+/* ------------------------------------------------------------------------------------------------
+ * definitions
+ * ------------------------------------------------------------------------------------------------
+ */
+
+
+#define R_SETDATA_REQUEST_EXPIRE_SECS 20
+#define R_SETDATA_SUBREQUEST_EXPIRE_SECS 10
+
+
+
+/* ------------------------------------------------------------------------------------------------
+ * forward declarations
+ * ------------------------------------------------------------------------------------------------
+ */
+
+static void _rqSubRequestFinished(GWEN_MSG_REQUEST *rq, GWEN_MSG_REQUEST *subRq, int reason);
+static void _rqAbort(GWEN_MSG_REQUEST *rq);
+
+static GWEN_MSG_REQUEST *_mkSubRequest_SetData(AQHOMED *aqh, int destAddr, int valueId, uint16_t dataVal, uint16_t dataDenom);
+static int _subRqHandleResponse(GWEN_MSG_REQUEST *rq, GWEN_MSG *msg);
+static void _subRqAbort(GWEN_MSG_REQUEST *rq);
+
+
+
+/* ------------------------------------------------------------------------------------------------
+ * implementations
+ * ------------------------------------------------------------------------------------------------
+ */
+
+GWEN_MSG_REQUEST *AqHomeNodes_MkRequest_SetData(AQHOMED *aqh,
+ GWEN_MSG_ENDPOINT *ep, uint32_t requestMsgId,
+ int destAddr, int valueId, uint16_t dataVal, uint16_t dataDenom)
+{
+ GWEN_MSG_REQUEST *rq;
+ GWEN_MSG_REQUEST *subRq;
+
+ rq=GWEN_MsgRequest_new();
+ GWEN_MsgRequest_SetPrivateData(rq, aqh);
+ GWEN_MsgRequest_SetEndpoint(rq, ep);
+ GWEN_MsgRequest_SetRequestMsgId(rq, requestMsgId);
+ GWEN_MsgRequest_SetSubRequestFinishedFn(rq, _rqSubRequestFinished);
+ GWEN_MsgRequest_SetAbortFn(rq, _rqAbort);
+ GWEN_MsgRequest_SetTimestamps(rq, R_SETDATA_REQUEST_EXPIRE_SECS);
+
+ subRq=_mkSubRequest_SetData(aqh, destAddr, valueId, dataVal, dataDenom);
+ GWEN_MsgRequest_Tree2_AddChild(rq, subRq);
+
+ return rq;
+}
+
+
+
+void _rqSubRequestFinished(GWEN_MSG_REQUEST *rq, GWEN_MSG_REQUEST *subRq, int reason)
+{
+ GWEN_MSG_ENDPOINT *ep;
+ uint32_t refMsgId;
+ int result;
+
+ DBG_INFO(NULL, "SubRequest finished");
+ refMsgId=GWEN_MsgRequest_GetRequestMsgId(rq);
+ ep=GWEN_MsgRequest_GetEndpoint(rq);
+ result=GWEN_MsgRequest_GetResult(subRq);
+
+ if (reason==GWEN_MSG_REQUEST_REASON_ABORTED)
+ AQH_IpcEndpoint_SendResponseResult(ep, refMsgId, AQH_MSGTYPE_IPC_DATA_RESULT, AQH_MSG_IPC_ERROR_GENERIC);
+ else
+ AQH_IpcEndpoint_SendResponseResult(ep, refMsgId, AQH_MSGTYPE_IPC_DATA_RESULT, result);
+
+ GWEN_MsgRequest_SetResult(rq, result);
+ GWEN_MsgRequest_SetState(rq, GWEN_MSG_REQUEST_STATE_DONE);
+}
+
+
+
+void _rqAbort(GWEN_MSG_REQUEST *rq)
+{
+ GWEN_MSG_ENDPOINT *ep;
+ uint32_t refMsgId;
+ GWEN_MSG_REQUEST *rqParent;
+
+ DBG_INFO(NULL, "Aborting request");
+ refMsgId=GWEN_MsgRequest_GetRequestMsgId(rq);
+ ep=GWEN_MsgRequest_GetEndpoint(rq);
+ AQH_IpcEndpoint_SendResponseResult(ep, refMsgId, AQH_MSGTYPE_IPC_DATA_RESULT, AQH_MSG_IPC_ERROR_GENERIC);
+ GWEN_MsgRequest_SetState(rq, GWEN_MSG_REQUEST_STATE_DONE);
+
+ rqParent=GWEN_MsgRequest_Tree2_GetParent(rq);
+ if (rqParent)
+ GWEN_MsgRequest_SubRequestFinished(rqParent, rq, GWEN_MSG_REQUEST_REASON_ABORTED);
+}
+
+
+
+
+
+
+
+
+GWEN_MSG_REQUEST *_mkSubRequest_SetData(AQHOMED *aqh, int destAddr, int valueId, uint16_t dataVal, uint16_t dataDenom)
+{
+ GWEN_MSG_REQUEST *rq;
+ uint16_t msgId;
+ GWEN_MSG *msgOut;
+
+ rq=GWEN_MsgRequest_new();
+ GWEN_MsgRequest_SetPrivateData(rq, aqh);
+ GWEN_MsgRequest_SetEndpoint(rq, aqh->ttyEndpoint);
+
+ GWEN_MsgRequest_SetHandleResponseFn(rq, _subRqHandleResponse);
+ GWEN_MsgRequest_SetAbortFn(rq, _subRqAbort);
+
+ msgId=GWEN_MsgEndpoint_GetNextMessageId(aqh->ttyEndpoint) & 0xffff;
+ GWEN_MsgRequest_SetRequestMsgId(rq, msgId);
+ GWEN_MsgRequest_SetTimestamps(rq, R_SETDATA_SUBREQUEST_EXPIRE_SECS);
+
+ msgOut=AQH_Value3Msg_new(aqh->nodeAddress, destAddr, AQH_MSG_TYPE_VALUE_SET, msgId, valueId, dataVal, dataDenom);
+ GWEN_MsgEndpoint_AddSendMessage(aqh->ttyEndpoint, msgOut);
+
+ return rq;
+}
+
+
+
+int _subRqHandleResponse(GWEN_MSG_REQUEST *rq, GWEN_MSG *msg)
+{
+ AQHOMED *aqh;
+ uint8_t destAddr;
+
+ DBG_DEBUG(NULL, "Checking message from %02x", AQH_NodeMsg_GetSourceAddress(msg));
+ aqh=(AQHOMED*)GWEN_MsgRequest_GetPrivateData(rq);
+
+ destAddr=AQH_NodeMsg_GetDestAddress(msg);
+ if (destAddr==0xff || destAddr==aqh->nodeAddress) {
+ uint8_t msgCode;
+
+ msgCode=AQH_NodeMsg_GetMsgType(msg);
+ if (msgCode==AQH_MSG_TYPE_VALUE_SET_ACK || msgCode==AQH_MSG_TYPE_VALUE_SET_NACK) {
+ uint16_t msgId;
+
+ msgId=AQH_Value3Msg_GetMsgId(msg);
+ if (msgId==GWEN_MsgRequest_GetRequestMsgId(rq)) {
+ GWEN_MSG_REQUEST *rqParent;
+
+ DBG_INFO(NULL,
+ "Received response (%02x) for msg id %04x from %02x",
+ msgCode, msgId, AQH_NodeMsg_GetSourceAddress(msg));
+ GWEN_MsgRequest_SetResult(rq, (msgCode==AQH_MSG_TYPE_VALUE_SET_ACK)?AQH_MSG_IPC_SUCCESS:AQH_MSG_IPC_ERROR_GENERIC);
+ GWEN_MsgRequest_SetState(rq, GWEN_MSG_REQUEST_STATE_DONE);
+ rqParent=GWEN_MsgRequest_Tree2_GetParent(rq);
+ if (rqParent)
+ GWEN_MsgRequest_SubRequestFinished(rqParent, rq, GWEN_MSG_REQUEST_REASON_DONE);
+ return GWEN_MSG_REQUEST_RESULT_HANDLED;
+ }
+ else {
+ DBG_DEBUG(NULL, " Non-matching message id");
+ }
+ }
+ else {
+ DBG_DEBUG(NULL, " Non-matching message code");
+ }
+ }
+ return GWEN_MSG_REQUEST_RESULT_NOT_HANDLED;
+}
+
+
+
+void _subRqAbort(GWEN_MSG_REQUEST *rq)
+{
+ GWEN_MSG_REQUEST *rqParent;
+
+ DBG_INFO(NULL, "Aborting request");
+
+ GWEN_MsgRequest_SetResult(rq, AQH_MSG_IPC_ERROR_GENERIC);
+ GWEN_MsgRequest_SetState(rq, GWEN_MSG_REQUEST_STATE_DONE);
+
+ rqParent=GWEN_MsgRequest_Tree2_GetParent(rq);
+ if (rqParent)
+ GWEN_MsgRequest_SubRequestFinished(rqParent, rq, GWEN_MSG_REQUEST_REASON_ABORTED);
+}
+
+
+
+
diff --git a/apps/aqhome-nodes/r_setdata.h b/apps/aqhome-nodes/r_setdata.h
new file mode 100644
index 0000000..e829f9c
--- /dev/null
+++ b/apps/aqhome-nodes/r_setdata.h
@@ -0,0 +1,28 @@
+/****************************************************************************
+ * This file is part of the project AqHome.
+ * AqHome (c) by 2024 Martin Preuss, all rights reserved.
+ *
+ * The license for this file can be found in the file COPYING which you
+ * should have received along with this file.
+ ****************************************************************************/
+
+#ifndef AQHOMED_R_SETDATA_H
+#define AQHOMED_R_SETDATA_H
+
+
+#include "./aqhomed.h"
+
+#include
+
+
+
+GWEN_MSG_REQUEST *AqHomeNodes_MkRequest_SetData(AQHOMED *aqh,
+ GWEN_MSG_ENDPOINT *ep, uint32_t requestMsgId,
+ int destAddr, int valueId, uint16_t dataVal, uint16_t dataDenom);
+
+
+
+
+#endif
+
+
diff --git a/apps/aqhome-nodes/requests.c b/apps/aqhome-nodes/requests.c
new file mode 100644
index 0000000..6cf6d4b
--- /dev/null
+++ b/apps/aqhome-nodes/requests.c
@@ -0,0 +1,138 @@
+/****************************************************************************
+ * This file is part of the project AqHome.
+ * AqHome (c) by 2024 Martin Preuss, all rights reserved.
+ *
+ * The license for this file can be found in the file COPYING which you
+ * should have received along with this file.
+ ****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include
+#endif
+
+
+#include "./requests.h"
+#include "./aqhomed_p.h"
+
+#include "aqhome/ipc/endpoint_ipc.h"
+#include "aqhome/ipc/data/ipc_data.h"
+
+#include
+#include
+
+
+
+static void _freeFinishedRequests(GWEN_MSG_REQUEST *rq);
+
+
+
+
+void AqHomeNodes_Requests_CheckTimeouts(AQHOMED *aqh)
+{
+ if (aqh && aqh->requestTree) {
+ GWEN_MSG_REQUEST *rq;
+ GWEN_TIMESTAMP *now;
+
+ now=GWEN_Timestamp_NowInLocalTime();
+ rq=GWEN_MsgRequest_Tree2_GetFirstChild(aqh->requestTree);
+ while(rq) {
+ const GWEN_TIMESTAMP *ts;
+
+ ts=GWEN_MsgRequest_GetExpiresAt(rq);
+ if (GWEN_Timestamp_Compare(now, ts)>=0) {
+ /* timeout */
+ DBG_INFO(NULL, "Request timed out, aborting");
+ GWEN_MsgRequest_Abort(rq);
+ }
+ rq=GWEN_MsgRequest_Tree2_GetBelow(rq);
+ }
+ GWEN_Timestamp_free(now);
+ }
+}
+
+
+
+void AqHomeNodes_Requests_Cleanup(AQHOMED *aqh)
+{
+ if (aqh && aqh->requestTree) {
+ GWEN_MSG_REQUEST *rq;
+
+ rq=GWEN_MsgRequest_Tree2_GetFirstChild(aqh->requestTree);
+ while(rq) {
+ GWEN_MSG_REQUEST *nextSubRq;
+
+ nextSubRq=GWEN_MsgRequest_Tree2_GetNext(rq);
+ _freeFinishedRequests(rq);
+ rq=nextSubRq;
+ }
+ }
+}
+
+
+
+int AqHomeNodes_Requests_HandleIpcMsg(AQHOMED *aqh, GWEN_MSG_ENDPOINT *srcEp, GWEN_MSG *recvdMsg)
+{
+ if (aqh && aqh->requestTree) {
+ uint32_t refMsgId;
+
+ refMsgId=GWEN_IpcMsg_GetRefMsgId(recvdMsg);
+ if (refMsgId) {
+ GWEN_MSG_REQUEST *rq;
+
+ rq=GWEN_MsgRequest_Tree2_GetFirstChild(aqh->requestTree);
+ while(rq) {
+ if (srcEp==GWEN_MsgRequest_GetEndpoint(rq) && refMsgId==GWEN_MsgRequest_GetRequestMsgId(rq)) {
+ if (GWEN_MsgRequest_HandleResponse(rq, recvdMsg)==GWEN_MSG_REQUEST_RESULT_HANDLED)
+ return GWEN_MSG_REQUEST_RESULT_HANDLED;
+ }
+
+ rq=GWEN_MsgRequest_Tree2_GetBelow(rq);
+ }
+ }
+ else {
+ DBG_INFO(NULL, "Message has no reference msg id, not a response");
+ }
+ }
+ return GWEN_MSG_REQUEST_RESULT_NOT_HANDLED;
+}
+
+
+
+int AqHomeNodes_Requests_HandleTtyMsg(AQHOMED *aqh, GWEN_MSG_ENDPOINT *srcEp, GWEN_MSG *recvdMsg)
+{
+ if (aqh && aqh->requestTree) {
+ GWEN_MSG_REQUEST *rq;
+
+ rq=GWEN_MsgRequest_Tree2_GetFirstChild(aqh->requestTree);
+ while(rq) {
+ if (srcEp==GWEN_MsgRequest_GetEndpoint(rq)) {
+ if (GWEN_MsgRequest_HandleResponse(rq, recvdMsg)==GWEN_MSG_REQUEST_RESULT_HANDLED)
+ return GWEN_MSG_REQUEST_RESULT_HANDLED;
+ }
+
+ rq=GWEN_MsgRequest_Tree2_GetBelow(rq);
+ }
+ }
+ return GWEN_MSG_REQUEST_RESULT_NOT_HANDLED;
+}
+
+
+
+void _freeFinishedRequests(GWEN_MSG_REQUEST *rq)
+{
+ GWEN_MSG_REQUEST *subRq;
+
+ subRq=GWEN_MsgRequest_Tree2_GetFirstChild(rq);
+ while(subRq) {
+ GWEN_MSG_REQUEST *nextSubRq;
+
+ nextSubRq=GWEN_MsgRequest_Tree2_GetNext(subRq);
+ _freeFinishedRequests(subRq);
+ subRq=nextSubRq;
+ }
+
+ if (GWEN_MsgRequest_GetState(rq)==GWEN_MSG_REQUEST_STATE_DONE)
+ GWEN_MsgRequest_free(rq);
+}
+
+
diff --git a/apps/aqhome-nodes/requests.h b/apps/aqhome-nodes/requests.h
new file mode 100644
index 0000000..c2827eb
--- /dev/null
+++ b/apps/aqhome-nodes/requests.h
@@ -0,0 +1,30 @@
+/****************************************************************************
+ * This file is part of the project AqHome.
+ * AqHome (c) by 2024 Martin Preuss, all rights reserved.
+ *
+ * The license for this file can be found in the file COPYING which you
+ * should have received along with this file.
+ ****************************************************************************/
+
+#ifndef AQHOMED_REQUESTS_H
+#define AQHOMED_REQUESTS_H
+
+
+#include "./aqhomed.h"
+
+#include
+
+
+
+void AqHomeNodes_Requests_CheckTimeouts(AQHOMED *aqh);
+void AqHomeNodes_Requests_Cleanup(AQHOMED *aqh);
+
+int AqHomeNodes_Requests_HandleIpcMsg(AQHOMED *aqh, GWEN_MSG_ENDPOINT *srcEp, GWEN_MSG *recvdMsg);
+int AqHomeNodes_Requests_HandleTtyMsg(AQHOMED *aqh, GWEN_MSG_ENDPOINT *srcEp, GWEN_MSG *recvdMsg);
+
+
+
+
+#endif
+
+