/**************************************************************************** * 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 "./loop.h" #include "aqhome/ipc/data/ipc_data.h" #include "aqhome/ipc/data/msg_data_multidata.h" #include "aqhome/ipc/endpoint_ipc.h" #include "aqhome/ipc/msg_ipc_result.h" #include "aqhome/ipc/msg_ipc_tag16.h" #include /* ------------------------------------------------------------------------------------------------ * defines * ------------------------------------------------------------------------------------------------ */ #define DISABLE_DEBUGLOG /* ------------------------------------------------------------------------------------------------ * forward declarations * ------------------------------------------------------------------------------------------------ */ static int _storeDataPoints(AQHOME_DATA *aqh, const AQH_VALUE *v, const uint64_t *dataPoints, unsigned int numValues); static void _sendDataChangedMsgToAllClients(AQHOME_DATA *aqh, GWEN_MSG_ENDPOINT *epSrc, const AQH_VALUE *v, const uint64_t *dataPoints, uint32_t numValues); /* ------------------------------------------------------------------------------------------------ * implementations * ------------------------------------------------------------------------------------------------ */ void AqHomeData_HandleUpdateData(AQHOME_DATA *aqh, GWEN_MSG_ENDPOINT *ep, GWEN_MSG *recvdMsg) { GWEN_MSG *outMsg; int resultCode=AQH_MSG_IPC_SUCCESS; const GWEN_TAG16 *tag; AQH_VALUE *recvdValue; const char *valueName; const uint64_t *dataPoints=NULL; unsigned int numberOfPoints=0; AQH_MultiDataDataIpcMsg_Parse(recvdMsg, 0); recvdValue=AQH_MultiDataDataIpcMsg_ReadValue(recvdMsg); valueName=recvdValue?AQH_Value_GetName(recvdValue):NULL; tag=AQH_Tag16IpcMsg_FindFirstTagByType(recvdMsg, AQH_MSGDATA_MULTIDATA_TAGS_DATA); dataPoints=tag?((const uint64_t*)GWEN_Tag16_GetTagData(tag)):NULL; numberOfPoints=(tag?GWEN_Tag16_GetTagLength(tag):0)/(2*sizeof(uint64_t)); if (numberOfPoints>0) { AQH_VALUE *value; value=AqHomeData_GetOrCreateValueForDriverWithTemplate(aqh, ep, recvdValue); if (value) { resultCode=_storeDataPoints(aqh, value, dataPoints, numberOfPoints); if (resultCode==AQH_MSG_IPC_SUCCESS) _sendDataChangedMsgToAllClients(aqh, ep, value, dataPoints, numberOfPoints); } else { DBG_INFO(NULL, "No permissions to add datapoint for value \"%s\"", valueName); resultCode=AQH_MSG_IPC_ERROR_PERMS; } } else { DBG_INFO(NULL, "No datapoints"); resultCode=AQH_MSG_IPC_ERROR_INVALID; } AQH_Value_free(recvdValue); outMsg=AQH_ResultIpcMsg_new(AQH_MSGTYPE_IPC_DATA_RESULT, resultCode); GWEN_MsgEndpoint_AddSendMessage(ep, outMsg); } int _storeDataPoints(AQHOME_DATA *aqh, const AQH_VALUE *v, const uint64_t *dataPoints, unsigned int 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_DEBUG(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_DEBUG(AQH_LOGDOMAIN, "Sending update msg to endpoint %s", GWEN_MsgEndpoint_GetName(ep)); msg=AQH_MultiDataDataIpcMsg_new(AQH_MSGTYPE_IPC_DATA_DATACHANGED, v, dataPoints, numValues); GWEN_MsgEndpoint_AddSendMessage(ep, msg); } else { DBG_DEBUG(AQH_LOGDOMAIN, "Endpoint %s doesn't want updates", GWEN_MsgEndpoint_GetName(ep)); } } else { DBG_DEBUG(AQH_LOGDOMAIN, "Not sending update msg to source of updates"); } ep=GWEN_MsgEndpoint_Tree2_GetNext(ep); } }