aqhome-data, aqhome-tool: more work on new protocol.

This commit is contained in:
Martin Preuss
2025-02-27 23:50:18 +01:00
parent d887747b3c
commit f2d527cd2f
35 changed files with 2070 additions and 2353 deletions

View File

@@ -15,11 +15,18 @@
#include "./s_connect.h"
#include "./s_getdevices.h"
#include "./s_getvalues.h"
#include "./s_addvalue.h"
#include "./s_annvalue.h"
#include "./s_updatedata.h"
#include "./s_setdata.h"
#include "./s_getdatapoints.h"
#include "./s_moddevice.h"
#include <aqhome/aqhome.h>
#include <aqhome/ipc2/ipc_server.h>
#include <aqhome/ipc2/tcpd_object.h>
#include <aqhome/msg/ipc/m_ipc.h>
#include <aqhome/msg/ipc/m_ipc_result.h>
#include <aqhome/msg/ipc/data/m_ipcd.h>
#include <gwenhywfar/args.h>
@@ -71,6 +78,7 @@ static int _handleNewClient(AQH_OBJECT *o, AQH_OBJECT *clientEndpoint);
static int _handleClientDown(AQH_OBJECT *o, AQH_OBJECT *clientEndpoint);
static void _handleMsgsFromClient(AQH_OBJECT *o, AQHOME_SERVER *xo, AQH_OBJECT *ep);
static void _handleMsgFromClient(AQH_OBJECT *o, AQH_OBJECT *ep, AQH_MESSAGE *msg);
static AQH_DEVICE *_getOrCreateDeviceForDriver(AQHOME_SERVER *xo, AQH_OBJECT *epDriver, const char *deviceName);
static int _createPidFile(const char *pidFilename);
static int _readArgs(int argc, char **argv, GWEN_DB_NODE *dbArgs);
@@ -421,22 +429,55 @@ void _handleMsgFromClient(AQH_OBJECT *o, AQH_OBJECT *ep, AQH_MESSAGE *msg)
if (protoId==AQH_IPC_PROTOCOL_DATA_ID) {
DBG_ERROR(NULL, "Received IPC packet %d (%x)", (int) code, code);
switch(code) {
case AQH_MSGTYPE_IPC_DATA_CONNECT_REQ: AqHomeDataServer_HandleConnect(o, ep, msg); break;
case AQH_MSGTYPE_IPC_DATA_UPDATEDATA: break;
case AQH_MSGTYPE_IPC_DATA_GETVALUES_REQ: AqHomeDataServer_HandleGetValues(o, ep, msg); break;
case AQH_MSGTYPE_IPC_DATA_GETDATA_REQ: break;
case AQH_MSGTYPE_IPC_DATA_SETDATA: break;
case AQH_MSGTYPE_IPC_DATA_ADDVALUE: break;
case AQH_MSGTYPE_IPC_DATA_ANNOUNCEVALUE: break;
case AQH_MSGTYPE_IPC_DATA_GETDEVICES_REQ: AqHomeDataServer_HandleGetDevices(o, ep, msg); break;
case AQH_MSGTYPE_IPC_DATA_MODDEVICE_REQ: break;
case AQH_MSGTYPE_IPC_DATA_CONNECT_REQ: AqHomeDataServer_HandleConnect(o, ep, msg); break;
case AQH_MSGTYPE_IPC_DATA_UPDATEDATA: AqHomeDataServer_HandleUpdateData(o, ep, msg); break;
case AQH_MSGTYPE_IPC_DATA_GETVALUES_REQ: AqHomeDataServer_HandleGetValues(o, ep, msg); break;
case AQH_MSGTYPE_IPC_DATA_GETDATA_REQ: AqHomeDataServer_HandleGetDataPoints(o, ep, msg); break;
case AQH_MSGTYPE_IPC_DATA_SETDATA: AqHomeDataServer_HandleSetData(o, ep, msg); break;
case AQH_MSGTYPE_IPC_DATA_ADDVALUE: AqHomeDataServer_HandleAddValue(o, ep, msg); break;
case AQH_MSGTYPE_IPC_DATA_ANNOUNCEVALUE: AqHomeDataServer_HandleAnnounceValue(o, ep, msg); break;
case AQH_MSGTYPE_IPC_DATA_GETDEVICES_REQ: AqHomeDataServer_HandleGetDevices(o, ep, msg); break;
case AQH_MSGTYPE_IPC_DATA_MODDEVICE_REQ: AqHomeDataServer_HandleModDevice(o, ep, msg); break;
default: break;
}
}
else {
DBG_ERROR(NULL, "Invalid IPC protocol %d (%02x)", protoId, protoId);
}
}
AQH_OBJECT *AqHomeDataServer_GetIpcEndpointByServiceName(const AQH_OBJECT *o, const char *serviceName)
{
AQHOME_SERVER *xo;
xo=GWEN_INHERIT_GETDATA(AQH_OBJECT, AQHOME_SERVER, o);
if (xo) {
AQH_OBJECT *ep;
ep=AQH_Object_List_First(xo->tcpClientList);
while(ep) {
const char *s;
s=AQH_Endpoint_GetServiceName(ep);
if (s && *s && strcasecmp(s, serviceName)==0)
return ep;
ep=AQH_Object_List_Next(ep);
}
}
return NULL;
}
void AqHomeDataServer_SendResponseResultToEndpoint(AQH_OBJECT *ep, uint32_t refMsgId, int result)
{
AQH_MESSAGE *msg;
msg=AQH_IpcMessageResult_new(AQH_IPC_PROTOCOL_DATA_ID, AQH_IPC_PROTOCOL_DATA_VERSION, AQH_MSGTYPE_IPC_DATA_RESULT,
AQH_Endpoint_GetNextMessageId(ep), refMsgId, result, NULL);
AQH_Endpoint_AddMsgOut(ep, msg);
}
@@ -563,6 +604,98 @@ int AqHomeDataServer_WriteStorageIfChanged(AQH_OBJECT *o)
AQH_VALUE *AqHomeDataServer_GetOrCreateValueForDriverWithTemplate(AQH_OBJECT *o, AQH_OBJECT *epDriver, const AQH_VALUE *valueTemplate)
{
AQHOME_SERVER *xo;
xo=GWEN_INHERIT_GETDATA(AQH_OBJECT, AQHOME_SERVER, o);
if (xo) {
const char *serviceName;
AQH_VALUE *v;
GWEN_BUFFER *buf;
const char *valueName;
const char *deviceName;
serviceName=AQH_Endpoint_GetServiceName(epDriver);
valueName=AQH_Value_GetName(valueTemplate);
deviceName=AQH_Value_GetDeviceName(valueTemplate);
buf=GWEN_Buffer_new(0, 256, 0, 1);
if (deviceName && *deviceName)
GWEN_Buffer_AppendArgs(buf, "%s/%s/%s", (serviceName && *serviceName)?serviceName:"unknown", deviceName, valueName);
else
GWEN_Buffer_AppendArgs(buf, "%s/%s", (serviceName && *serviceName)?serviceName:"unknown", valueName);
v=AQH_Storage_GetValueByNameForSystem(xo->storage, GWEN_Buffer_GetStart(buf));
if (v==NULL) {
if (AQH_Endpoint_GetPermissions(epDriver) & AQH_ENDPOINT_PERMS_ADDVALUE) {
AQH_DEVICE *device;
DBG_INFO(AQH_LOGDOMAIN, "Creating value \"%s\"", GWEN_Buffer_GetStart(buf));
device=(deviceName && *deviceName)?_getOrCreateDeviceForDriver(xo, epDriver, deviceName):NULL;
v=AQH_Value_new();
AQH_Value_SetDriver(v, serviceName);
AQH_Value_SetName(v, AQH_Value_GetName(valueTemplate));
AQH_Value_SetNameForSystem(v, GWEN_Buffer_GetStart(buf));
AQH_Value_SetValueUnits(v, AQH_Value_GetValueUnits(valueTemplate));
AQH_Value_SetValueType(v, AQH_Value_GetValueType(valueTemplate));
AQH_Value_SetModality(v, AQH_Value_GetModality(valueTemplate));
AQH_Value_SetTimestampCreation(v, (uint64_t) time(NULL));
if (device) {
AQH_Value_SetDeviceNameForSystem(v, AQH_Device_GetNameForSystem(device));
AQH_Value_SetDeviceName(v, AQH_Device_GetName(device));
}
AQH_Storage_AddValue(xo->storage, v);
}
else {
DBG_ERROR(AQH_LOGDOMAIN, "No permissions to create value \"%s\"", GWEN_Buffer_GetStart(buf));
GWEN_Buffer_free(buf);
return NULL;
}
}
GWEN_Buffer_free(buf);
return v;
}
return NULL;
}
AQH_DEVICE *_getOrCreateDeviceForDriver(AQHOME_SERVER *xo, AQH_OBJECT *epDriver, const char *deviceName)
{
const char *serviceName;
AQH_DEVICE *device;
GWEN_BUFFER *buf;
serviceName=AQH_Endpoint_GetServiceName(epDriver);
buf=GWEN_Buffer_new(0, 256, 0, 1);
GWEN_Buffer_AppendArgs(buf, "%s/%s", (serviceName && *serviceName)?serviceName:"unknown", deviceName);
device=AQH_Storage_GetDeviceByNameForSystem(xo->storage, GWEN_Buffer_GetStart(buf));
if (device==NULL) {
if (AQH_Endpoint_GetPermissions(epDriver) & AQH_ENDPOINT_PERMS_ADDDEVICE) {
DBG_INFO(AQH_LOGDOMAIN, "Creating device \"%s\"", GWEN_Buffer_GetStart(buf));
device=AQH_Device_new();
AQH_Device_SetDriver(device, serviceName);
AQH_Device_SetName(device, deviceName);
AQH_Device_SetNameForSystem(device, GWEN_Buffer_GetStart(buf));
AQH_Device_SetTimestampCreation(device, (uint64_t) time(NULL));
AQH_Storage_AddDevice(xo->storage, device);
}
else {
DBG_ERROR(AQH_LOGDOMAIN, "No permissions to create device \"%s\"", GWEN_Buffer_GetStart(buf));
GWEN_Buffer_free(buf);
return NULL;
}
}
GWEN_Buffer_free(buf);
return device;
}
/* xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
* helper functions