Files
aqhomecontrol/apps/aqhome-data/s_getvalues.c
2025-06-25 00:01:52 +02:00

184 lines
5.2 KiB
C

/****************************************************************************
* This file is part of the project AqHome.
* AqHome (c) by 2025 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 "./s_getvalues.h"
#include "./server_p.h"
#include "aqhome/aqhome.h"
#include "aqhome/ipc2/endpoint.h"
#include "aqhome/msg/ipc/m_ipc.h"
#include "aqhome/msg/ipc/data/m_ipcd.h"
#include "aqhome/msg/ipc/data/m_ipcd_getvalues.h"
#include "aqhome/msg/ipc/data/m_ipcd_values.h"
#include "aqhome/msg/ipc/m_ipc_result.h"
#include "aqhome/msg/ipc/m_ipc_tag16.h"
#include <gwenhywfar/text.h>
#include <gwenhywfar/debug.h>
/* ------------------------------------------------------------------------------------------------
* defines
* ------------------------------------------------------------------------------------------------
*/
#define AQHOMEDATA_VALUESPERMSG 10
/* ------------------------------------------------------------------------------------------------
* forward declarations
* ------------------------------------------------------------------------------------------------
*/
static AQH_VALUE_LIST *_getMatchingValueList(AQHOME_SERVER *xo, const GWEN_TAG16_LIST *tagList);
static void _sendValueList(AQH_OBJECT *ep, const AQH_VALUE_LIST *vl, uint32_t refMsgId);
static void _sendValueListMsg(AQH_OBJECT *ep, const AQH_VALUE_LIST *vl, uint32_t flags, uint32_t refMsgId);
static int _valueMatches(const AQH_VALUE *v, const char *deviceName, int modality);
/* ------------------------------------------------------------------------------------------------
* implementations
* ------------------------------------------------------------------------------------------------
*/
void AqHomeDataServer_HandleGetValues(AQH_OBJECT *o, AQH_OBJECT *ep, const AQH_MESSAGE *msg, const GWEN_TAG16_LIST *tagList)
{
AQHOME_SERVER *xo;
xo=AqHomeDataServer_GetServerData(o);
if (xo) {
AQH_VALUE_LIST *valueList;
uint32_t refMsgId;
refMsgId=AQH_IpcMessage_GetMsgId(msg);
DBG_INFO(NULL, "HandleGetValues");
valueList=_getMatchingValueList(xo, tagList);
if (valueList) {
_sendValueList(ep, valueList, refMsgId);
AQH_Value_List_free(valueList);
}
else {
/* empty list */
_sendValueListMsg(ep, NULL, AQH_MSGDATA_VALUES_FLAGS_LASTMSG, refMsgId);
}
}
}
AQH_VALUE_LIST *_getMatchingValueList(AQHOME_SERVER *xo, const GWEN_TAG16_LIST *tagList)
{
const AQH_VALUE_LIST *origValueList;
AQH_VALUE_LIST *tmpValueList=NULL;
char *deviceName;
int modality;
deviceName=tagList?AQH_Tag16_GetTagDataAsNewString(tagList, AQH_MSGDATA_GETVALUES_TAGS_DEVICENAME, NULL):NULL;
modality=tagList?AQH_Tag16_GetTagDataAsUint64(tagList, AQH_MSGDATA_GETVALUES_TAGS_MODALITY, 0):0;
origValueList=AQH_Storage_GetValueList(xo->storage);
if (origValueList) {
const AQH_VALUE *v;
tmpValueList=AQH_Value_List_new();
v=AQH_Value_List_First(origValueList);
while(v) {
if (_valueMatches(v, deviceName, modality)) {
AQH_VALUE *copyOfValue;
copyOfValue=AQH_Value_dup(v);
AQH_Value_List_Add(copyOfValue, tmpValueList);
}
v=AQH_Value_List_Next(v);
}
if (AQH_Value_List_GetCount(tmpValueList)<1) {
AQH_Value_List_free(tmpValueList);
tmpValueList=NULL;
}
}
free(deviceName);
return tmpValueList;
}
void _sendValueList(AQH_OBJECT *ep, const AQH_VALUE_LIST *vl, uint32_t refMsgId)
{
AQH_VALUE_LIST *tmpValueList;
const AQH_VALUE *v;
tmpValueList=AQH_Value_List_new();
v=AQH_Value_List_First(vl);
while(v) {
const AQH_VALUE *next;
AQH_VALUE *copyOfValue;
next=AQH_Value_List_Next(v);
copyOfValue=AQH_Value_dup(v);
AQH_Value_List_Add(copyOfValue, tmpValueList);
if (AQH_Value_List_GetCount(tmpValueList)>=AQHOMEDATA_VALUESPERMSG) {
DBG_INFO(NULL, "Sending %d values", AQH_Value_List_GetCount(tmpValueList));
_sendValueListMsg(ep, tmpValueList, next?0:AQH_MSGDATA_VALUES_FLAGS_LASTMSG, refMsgId);
AQH_Value_List_Clear(tmpValueList);
}
v=next;
}
if (AQH_Value_List_GetCount(tmpValueList)) {
DBG_INFO(NULL, "Sending %d values", AQH_Value_List_GetCount(tmpValueList));
_sendValueListMsg(ep, tmpValueList, AQH_MSGDATA_VALUES_FLAGS_LASTMSG, refMsgId); /* send remaining */
}
AQH_Value_List_free(tmpValueList);
}
void _sendValueListMsg(AQH_OBJECT *ep, const AQH_VALUE_LIST *vl, uint32_t flags, uint32_t refMsgId)
{
AQH_MESSAGE *msg;
DBG_INFO(NULL, "Sending msg (refMsgId=%d)", refMsgId);
msg=AQH_IpcdMessageValues_new(AQH_MSGTYPE_IPC_DATA_GETVALUES_RSP, AQH_Endpoint_GetNextMessageId(ep), refMsgId, flags, vl);
AQH_Endpoint_AddMsgOut(ep, msg);
}
int _valueMatches(const AQH_VALUE *v, const char *deviceName, int modality)
{
if (modality!=AQH_ValueModality_Unknown) {
int valModality;
valModality=AQH_Value_GetModality(v);
if (valModality!=modality)
return 0;
}
if (deviceName && *deviceName) {
const char *s;
s=AQH_Value_GetDeviceNameForSystem(v);
if (s && *s && GWEN_Text_ComparePattern(s, deviceName, 0)==-1)
return 0;
}
return 1;
}