added devices, added command getdevices.

This commit is contained in:
Martin Preuss
2023-10-01 23:44:26 +02:00
parent c57472d86e
commit 45da38b64a
26 changed files with 1076 additions and 50 deletions

View File

@@ -43,6 +43,7 @@
c_connect.h
c_updatedata.h
c_getvalues.h
c_getdevices.h
c_getdatapoints.h
c_getlastdatapoint.h
c_setdata.h
@@ -59,6 +60,7 @@
c_connect.c
c_updatedata.c
c_getvalues.c
c_getdevices.c
c_getdatapoints.c
c_getlastdatapoint.c
c_setdata.c

View File

@@ -74,7 +74,11 @@ void AqHomeData_HandleConnect(AQHOME_DATA *aqh, GWEN_MSG_ENDPOINT *ep, GWEN_MSG
AQH_IPCENDPOINT_PERMS_ADDVALUE |
AQH_IPCENDPOINT_PERMS_LISTDATA |
AQH_IPCENDPOINT_PERMS_READDATA |
AQH_IPCENDPOINT_PERMS_ADDDATA);
AQH_IPCENDPOINT_PERMS_ADDDATA |
AQH_IPCENDPOINT_PERMS_LISTDEVICES |
AQH_IPCENDPOINT_PERMS_READDEVICE |
AQH_IPCENDPOINT_PERMS_ADDDEVICE |
AQH_IPCENDPOINT_PERMS_MODDEVICE);
free(passw);
free(userId);
free(clientId);

View File

@@ -0,0 +1,104 @@
/****************************************************************************
* 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_getdevices.h"
#include "./aqhome_data_p.h"
#include "aqhome/ipc/data/ipc_data.h"
#include "aqhome/ipc/data/msg_data_devices.h"
#include "aqhome/ipc/msg_ipc_result.h"
#include <gwenhywfar/debug.h>
/* ------------------------------------------------------------------------------------------------
* defines
* ------------------------------------------------------------------------------------------------
*/
#define AQHOMEDATA_DEVICESPERMSG 10
/* ------------------------------------------------------------------------------------------------
* forward declarations
* ------------------------------------------------------------------------------------------------
*/
static void _sendDeviceList(AQHOME_DATA *aqh, GWEN_MSG_ENDPOINT *ep, const AQH_DEVICE_LIST *vl, uint32_t flags);
/* ------------------------------------------------------------------------------------------------
* implementations
* ------------------------------------------------------------------------------------------------
*/
void AqHomeData_HandleGetDevices(AQHOME_DATA *aqh, GWEN_MSG_ENDPOINT *ep, const GWEN_MSG *msg)
{
const AQH_DEVICE_LIST *origDeviceList;
DBG_INFO(NULL, "HandleGetDevices");
origDeviceList=AQH_Storage_GetDeviceList(aqh->storage);
if (origDeviceList) {
DBG_INFO(NULL, "Have a list of %d devices", AQH_Device_List_GetCount(origDeviceList));
if (AQH_Device_List_GetCount(origDeviceList)<AQHOMEDATA_DEVICESPERMSG) {
DBG_INFO(NULL, "Sending all entries in one message");
_sendDeviceList(aqh, ep, origDeviceList, AQH_MSGDATA_DEVICES_FLAGS_LASTMSG);
}
else {
AQH_DEVICE_LIST *tmpDeviceList;
const AQH_DEVICE *v;
DBG_INFO(NULL, "Sending entries in multiple messages");
tmpDeviceList=AQH_Device_List_new();
v=AQH_Device_List_First(origDeviceList);
while(v) {
const AQH_DEVICE *next;
AQH_DEVICE *copyOfDevice;
next=AQH_Device_List_Next(v);
copyOfDevice=AQH_Device_dup(v);
AQH_Device_List_Add(copyOfDevice, tmpDeviceList);
if (AQH_Device_List_GetCount(tmpDeviceList)>=AQHOMEDATA_DEVICESPERMSG) {
DBG_INFO(NULL, "Sending %d devices", AQH_Device_List_GetCount(tmpDeviceList));
_sendDeviceList(aqh, ep, tmpDeviceList, next?0:AQH_MSGDATA_DEVICES_FLAGS_LASTMSG);
AQH_Device_List_Clear(tmpDeviceList);
}
v=next;
}
if (AQH_Device_List_GetCount(tmpDeviceList)) {
DBG_INFO(NULL, "Sending %d devices", AQH_Device_List_GetCount(tmpDeviceList));
_sendDeviceList(aqh, ep, tmpDeviceList, AQH_MSGDATA_DEVICES_FLAGS_LASTMSG); /* send remaining */
}
AQH_Device_List_free(tmpDeviceList);
}
}
else {
/* empty list */
_sendDeviceList(aqh, ep, NULL, AQH_MSGDATA_DEVICES_FLAGS_LASTMSG);
}
}
void _sendDeviceList(AQHOME_DATA *aqh, GWEN_MSG_ENDPOINT *ep, const AQH_DEVICE_LIST *vl, uint32_t flags)
{
GWEN_MSG *msg;
msg=AQH_DevicesDataIpcMsg_new(AQH_MSGTYPE_IPC_DATA_GETDEVICES_RSP, flags, vl);
GWEN_MsgEndpoint_AddSendMessage(ep, msg);
}

View File

@@ -0,0 +1,25 @@
/****************************************************************************
* 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.
****************************************************************************/
#ifndef AQHOME_DATA_C_GETDEVICES_H
#define AQHOME_DATA_C_GETDEVICES_H
#include "./aqhome_data.h"
void AqHomeData_HandleGetDevices(AQHOME_DATA *aqh, GWEN_MSG_ENDPOINT *ep, const GWEN_MSG *msg);
#endif

View File

@@ -45,7 +45,7 @@
* ------------------------------------------------------------------------------------------------
*/
//#define I18N(msg) msg
#define I18N(msg) msg
#define I18S(msg) msg

View File

@@ -17,6 +17,7 @@
#include "./c_getdatapoints.h"
#include "./c_getlastdatapoint.h"
#include "./c_getvalues.h"
#include "./c_getdevices.h"
#include "./c_setdata.h"
#include "./c_addvalue.h"
#include "./aqhome_data_p.h"
@@ -49,6 +50,7 @@
static void _readAndHandleIpcMessages(AQHOME_DATA *aqh);
static void _handleIpcEndpoint(AQHOME_DATA *aqh, GWEN_MSG_ENDPOINT *ep);
static void _handleIpcMsg(AQHOME_DATA *aqh, GWEN_MSG_ENDPOINT *ep, GWEN_MSG *msg);
static AQH_DEVICE *_getOrCreateDeviceForDriver(AQHOME_DATA *aqh, GWEN_MSG_ENDPOINT *epDriver, const char *nameForDriver);
@@ -144,9 +146,11 @@ AQH_VALUE *AqHomeData_GetOrCreateValueForDriverWithTemplate(AQHOME_DATA *aqh,
AQH_VALUE *v;
GWEN_BUFFER *buf;
const char *nameForDriver;
const char *deviceNameForDriver;
serviceName=AQH_IpcEndpoint_GetServiceName(epDriver);
nameForDriver=AQH_Value_GetNameForDriver(valueTemplate);
deviceNameForDriver=AQH_Value_GetDeviceNameForDriver(valueTemplate);
buf=GWEN_Buffer_new(0, 256, 0, 1);
GWEN_Buffer_AppendArgs(buf, "%s/%s", (serviceName && *serviceName)?serviceName:"unknown", nameForDriver);
@@ -154,8 +158,11 @@ AQH_VALUE *AqHomeData_GetOrCreateValueForDriverWithTemplate(AQHOME_DATA *aqh,
v=AQH_Storage_GetValueByNameForSystem(aqh->storage, GWEN_Buffer_GetStart(buf));
if (v==NULL) {
if (AQH_IpcEndpoint_GetPermissions(epDriver) & AQH_IPCENDPOINT_PERMS_ADDVALUE) {
/* TODO: get or create device */
AQH_DEVICE *device;
DBG_INFO(AQH_LOGDOMAIN, "Creating value \"%s\"", GWEN_Buffer_GetStart(buf));
device=(deviceNameForDriver && *deviceNameForDriver)?_getOrCreateDeviceForDriver(aqh, epDriver, deviceNameForDriver):NULL;
v=AQH_Value_new();
AQH_Value_SetDriver(v, serviceName);
AQH_Value_SetNameForDriver(v, AQH_Value_GetNameForDriver(valueTemplate));
@@ -163,6 +170,10 @@ AQH_VALUE *AqHomeData_GetOrCreateValueForDriverWithTemplate(AQHOME_DATA *aqh,
AQH_Value_SetValueUnits(v, AQH_Value_GetValueUnits(valueTemplate));
AQH_Value_SetValueType(v, AQH_Value_GetValueType(valueTemplate));
AQH_Value_SetTimestampCreation(v, (uint64_t) time(NULL));
if (device) {
AQH_Value_SetDeviceNameForSystem(v, AQH_Device_GetNameForSystem(device));
AQH_Value_SetDeviceNameForDriver(v, AQH_Device_GetNameForDriver(device));
}
AQH_Storage_AddValue(aqh->storage, v);
}
else {
@@ -177,6 +188,39 @@ AQH_VALUE *AqHomeData_GetOrCreateValueForDriverWithTemplate(AQHOME_DATA *aqh,
AQH_DEVICE *_getOrCreateDeviceForDriver(AQHOME_DATA *aqh, GWEN_MSG_ENDPOINT *epDriver, const char *nameForDriver)
{
const char *serviceName;
AQH_DEVICE *device;
GWEN_BUFFER *buf;
serviceName=AQH_IpcEndpoint_GetServiceName(epDriver);
buf=GWEN_Buffer_new(0, 256, 0, 1);
GWEN_Buffer_AppendArgs(buf, "%s/%s", (serviceName && *serviceName)?serviceName:"unknown", nameForDriver);
device=AQH_Storage_GetDeviceByNameForSystem(aqh->storage, GWEN_Buffer_GetStart(buf));
if (device==NULL) {
if (AQH_IpcEndpoint_GetPermissions(epDriver) & AQH_IPCENDPOINT_PERMS_ADDDEVICE) {
DBG_INFO(AQH_LOGDOMAIN, "Creating device \"%s\"", GWEN_Buffer_GetStart(buf));
device=AQH_Device_new();
AQH_Device_SetDriver(device, serviceName);
AQH_Device_SetNameForDriver(device, nameForDriver);
AQH_Device_SetNameForSystem(device, GWEN_Buffer_GetStart(buf));
AQH_Storage_AddDevice(aqh->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;
}
void _readAndHandleIpcMessages(AQHOME_DATA *aqh)
{
if (aqh->ipcdEndpoint) {
@@ -207,19 +251,27 @@ void _handleIpcEndpoint(AQHOME_DATA *aqh, GWEN_MSG_ENDPOINT *ep)
void _handleIpcMsg(AQHOME_DATA *aqh, GWEN_MSG_ENDPOINT *ep, GWEN_MSG *msg)
{
uint16_t code;
uint8_t protoId;
/* exec IPC message */
code=GWEN_IpcMsg_GetCode(msg);
DBG_DEBUG(AQH_LOGDOMAIN, "Received IPC packet %d (%x)", (int) code, code);
switch(code) {
case AQH_MSGTYPE_IPC_DATA_CONNECT_REQ: AqHomeData_HandleConnect(aqh, ep, msg); break;
case AQH_MSGTYPE_IPC_DATA_UPDATEDATA: AqHomeData_HandleUpdateData(aqh, ep, msg); break;
case AQH_MSGTYPE_IPC_DATA_GETVALUES_REQ: AqHomeData_HandleGetValues(aqh, ep, msg); break;
case AQH_MSGTYPE_IPC_DATA_GETDATA_REQ: AqHomeData_HandleGetDataPoints(aqh, ep, msg); break;
case AQH_MSGTYPE_IPC_DATA_GETLASTDATA_REQ: AqHomeData_HandleGetLastDataPoint(aqh, ep, msg); break;
case AQH_MSGTYPE_IPC_DATA_SETDATA: AqHomeData_HandleSetData(aqh, ep, msg); break;
case AQH_MSGTYPE_IPC_DATA_ADDVALUE: AqHomeData_HandleAddValue(aqh, ep, msg); break;
default: break;
protoId=GWEN_IpcMsg_GetProtoId(msg);
if (protoId==AQH_IPC_PROTOCOL_DATA_ID) {
DBG_DEBUG(AQH_LOGDOMAIN, "Received IPC packet %d (%x)", (int) code, code);
switch(code) {
case AQH_MSGTYPE_IPC_DATA_CONNECT_REQ: AqHomeData_HandleConnect(aqh, ep, msg); break;
case AQH_MSGTYPE_IPC_DATA_UPDATEDATA: AqHomeData_HandleUpdateData(aqh, ep, msg); break;
case AQH_MSGTYPE_IPC_DATA_GETVALUES_REQ: AqHomeData_HandleGetValues(aqh, ep, msg); break;
case AQH_MSGTYPE_IPC_DATA_GETDATA_REQ: AqHomeData_HandleGetDataPoints(aqh, ep, msg); break;
case AQH_MSGTYPE_IPC_DATA_GETLASTDATA_REQ: AqHomeData_HandleGetLastDataPoint(aqh, ep, msg); break;
case AQH_MSGTYPE_IPC_DATA_SETDATA: AqHomeData_HandleSetData(aqh, ep, msg); break;
case AQH_MSGTYPE_IPC_DATA_ADDVALUE: AqHomeData_HandleAddValue(aqh, ep, msg); break;
case AQH_MSGTYPE_IPC_DATA_GETDEVICES_REQ: AqHomeData_HandleGetDevices(aqh, ep, msg); break;
default: break;
}
}
else {
DBG_ERROR(NULL, "Invalid IPC protocol %d (%02x)", protoId, protoId);
}
}