Previously this field contained the device name, too. This would make it necessary for drivers to remove the device part of the name when SetValue is called. Instead the device name is now always provided by the driver in the appropriate field DeviceNameForDriver.
130 lines
3.9 KiB
C
130 lines
3.9 KiB
C
/****************************************************************************
|
|
* 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 <config.h>
|
|
#endif
|
|
|
|
|
|
#include "./c_setdata.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 <gwenhywfar/debug.h>
|
|
|
|
|
|
|
|
/* ------------------------------------------------------------------------------------------------
|
|
* defines
|
|
* ------------------------------------------------------------------------------------------------
|
|
*/
|
|
|
|
|
|
|
|
|
|
/* ------------------------------------------------------------------------------------------------
|
|
* forward declarations
|
|
* ------------------------------------------------------------------------------------------------
|
|
*/
|
|
|
|
static int _forwardDataToDriver(AQHOME_DATA *aqh, const AQH_VALUE *v, uint64_t timestamp, double datapoint);
|
|
|
|
|
|
|
|
/* ------------------------------------------------------------------------------------------------
|
|
* implementations
|
|
* ------------------------------------------------------------------------------------------------
|
|
*/
|
|
|
|
void AqHomeData_HandleSetData(AQHOME_DATA *aqh, GWEN_MSG_ENDPOINT *epSrc, GWEN_MSG *recvdMsg)
|
|
{
|
|
GWEN_MSG *outMsg;
|
|
int resultCode=AQH_MSG_IPC_SUCCESS;
|
|
AQH_VALUE *recvdValue;
|
|
const char *valueName;
|
|
const GWEN_TAG16 *tag;
|
|
const uint64_t *dataPoints;
|
|
unsigned int numberOfPoints;
|
|
|
|
AQH_MultiDataDataIpcMsg_Parse(recvdMsg, 0);
|
|
recvdValue=AQH_MultiDataDataIpcMsg_ReadValue(recvdMsg);
|
|
valueName=recvdValue?AQH_Value_GetNameForSystem(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=AQH_Storage_GetValueByNameForSystem(aqh->storage, valueName);
|
|
if (value) {
|
|
if (AQH_Value_GetValueType(value)==AQH_ValueType_Actor) {
|
|
union {double f; uint64_t i;} u;
|
|
|
|
u.i=dataPoints[1];
|
|
resultCode=_forwardDataToDriver(aqh, value, dataPoints[0], u.f);
|
|
}
|
|
else {
|
|
DBG_INFO(NULL, "Value \"%s\" is not an actor", valueName);
|
|
resultCode=AQH_MSG_IPC_ERROR_INVALID;
|
|
}
|
|
}
|
|
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(epSrc, outMsg);
|
|
}
|
|
|
|
|
|
|
|
int _forwardDataToDriver(AQHOME_DATA *aqh, const AQH_VALUE *v, uint64_t timestamp, double datapoint)
|
|
{
|
|
const char *driverName;
|
|
|
|
driverName=AQH_Value_GetDriver(v);
|
|
if (driverName && *driverName) {
|
|
GWEN_MSG_ENDPOINT *ep;
|
|
|
|
ep=AqHomeData_GetIpcEndpointByServiceName(aqh, driverName);
|
|
if (ep) {
|
|
GWEN_MSG *driverMsg;
|
|
|
|
DBG_INFO(AQH_LOGDOMAIN, "Sending SETDATA msg to driver endpoint (%s)", GWEN_MsgEndpoint_GetName(ep));
|
|
driverMsg=AQH_MultiDataDataIpcMsg_newForOne(AQH_MSGTYPE_IPC_DATA_SETDATA, v, timestamp, datapoint);
|
|
GWEN_MsgEndpoint_AddSendMessage(ep, driverMsg);
|
|
return AQH_MSG_IPC_SUCCESS;
|
|
}
|
|
else {
|
|
DBG_INFO(NULL, "Driver \"%s\" not available", driverName);
|
|
return AQH_MSG_IPC_ERROR_GENERIC;
|
|
}
|
|
}
|
|
else {
|
|
DBG_INFO(NULL, "No driver name");
|
|
return AQH_MSG_IPC_ERROR_GENERIC;
|
|
}
|
|
}
|
|
|
|
|
|
|