diff --git a/aqhome/ipc/0BUILD b/aqhome/ipc/0BUILD index fb59b24..5f7fbe3 100644 --- a/aqhome/ipc/0BUILD +++ b/aqhome/ipc/0BUILD @@ -50,6 +50,7 @@ msg_ipc_qwords.h msg_ipc_result.h msg_ipc_tag16.h + requests.h @@ -67,6 +68,7 @@ msg_ipc_qwords.c msg_ipc_result.c msg_ipc_tag16.c + requests.c diff --git a/aqhome/ipc/requests.c b/aqhome/ipc/requests.c new file mode 100644 index 0000000..c715138 --- /dev/null +++ b/aqhome/ipc/requests.c @@ -0,0 +1,141 @@ +/**************************************************************************** + * 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 + + + +/* ------------------------------------------------------------------------------------------------ + * forward declarations + * ------------------------------------------------------------------------------------------------ + */ + +static void _freeFinishedRequests(GWEN_MSG_REQUEST *rq); + + + + +void AQH_Requests_CheckTimeouts(GWEN_MSG_REQUEST *requestTreeRoot) +{ + if (requestTreeRoot) { + GWEN_MSG_REQUEST *rq; + GWEN_TIMESTAMP *now; + + now=GWEN_Timestamp_NowInLocalTime(); + rq=GWEN_MsgRequest_Tree2_GetFirstChild(requestTreeRoot); + 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 AQH_Requests_Cleanup(GWEN_MSG_REQUEST *requestTreeRoot) +{ + if (requestTreeRoot) { + GWEN_MSG_REQUEST *rq; + + rq=GWEN_MsgRequest_Tree2_GetFirstChild(requestTreeRoot); + while(rq) { + GWEN_MSG_REQUEST *nextSubRq; + + nextSubRq=GWEN_MsgRequest_Tree2_GetNext(rq); + _freeFinishedRequests(rq); + rq=nextSubRq; + } + } +} + + + +int AQH_Requests_HandleIpcMsg(GWEN_MSG_REQUEST *requestTreeRoot, GWEN_MSG_ENDPOINT *srcEp, GWEN_MSG *recvdMsg) +{ + if (requestTreeRoot) { + uint32_t refMsgId; + + refMsgId=GWEN_IpcMsg_GetRefMsgId(recvdMsg); + if (refMsgId) { + GWEN_MSG_REQUEST *rq; + + rq=GWEN_MsgRequest_Tree2_GetFirstChild(requestTreeRoot); + 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 AQH_Requests_HandleTtyMsg(GWEN_MSG_REQUEST *requestTreeRoot, GWEN_MSG_ENDPOINT *srcEp, GWEN_MSG *recvdMsg) +{ + if (requestTreeRoot) { + GWEN_MSG_REQUEST *rq; + + rq=GWEN_MsgRequest_Tree2_GetFirstChild(requestTreeRoot); + 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) { + DBG_ERROR(NULL, "Deleting request"); + GWEN_MsgRequest_free(rq); + } +} + + + diff --git a/aqhome/ipc/requests.h b/aqhome/ipc/requests.h new file mode 100644 index 0000000..44e36be --- /dev/null +++ b/aqhome/ipc/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 AQHOME_REQUESTS_H +#define AQHOME_REQUESTS_H + + +#include + +#include + + + +AQHOME_API void AQH_Requests_CheckTimeouts(GWEN_MSG_REQUEST *requestTreeRoot); +AQHOME_API void AQH_Requests_Cleanup(GWEN_MSG_REQUEST *requestTreeRoot); + +AQHOME_API int AQH_Requests_HandleIpcMsg(GWEN_MSG_REQUEST *requestTreeRoot, GWEN_MSG_ENDPOINT *srcEp, GWEN_MSG *recvdMsg); +AQHOME_API int AQH_Requests_HandleTtyMsg(GWEN_MSG_REQUEST *requestTreeRoot, GWEN_MSG_ENDPOINT *srcEp, GWEN_MSG *recvdMsg); + + + + +#endif + +