/**************************************************************************** * 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; }