aqhome, aqhome-apps: cleanup, removed unneeded files.
This commit is contained in:
@@ -31,7 +31,7 @@
|
|||||||
* ------------------------------------------------------------------------------------------------
|
* ------------------------------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int _handlePublish(AQH_OBJECT *o, const char *rcvdTopic, const char *rcvdValue);
|
static int _handlePublish(AQH_OBJECT *o, AQH_MQTTLOG_SERVER *xo, const char *rcvdTopic, const char *rcvdValue);
|
||||||
static void _handleNumTopic(AQH_MQTTLOG_SERVER *xo, AQHMQTT_DEVICE *device,
|
static void _handleNumTopic(AQH_MQTTLOG_SERVER *xo, AQHMQTT_DEVICE *device,
|
||||||
AQHMQTT_TOPIC *topic, const char *rcvdValue);
|
AQHMQTT_TOPIC *topic, const char *rcvdValue);
|
||||||
static void _handleJsonTopic(AQH_MQTTLOG_SERVER *xo, AQHMQTT_DEVICE *device,
|
static void _handleJsonTopic(AQH_MQTTLOG_SERVER *xo, AQHMQTT_DEVICE *device,
|
||||||
@@ -69,12 +69,12 @@ void AQH_MqttLogServer_HandlePublishMsg(AQH_OBJECT *o, GWEN_UNUSED AQH_OBJECT *e
|
|||||||
if (topic && value) {
|
if (topic && value) {
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
rv=_handlePublish(o, topic, value);
|
rv=_handlePublish(o, xo, topic, value);
|
||||||
if (rv!=1) {
|
if (rv!=1) {
|
||||||
DBG_INFO(NULL, "New topic \"%s\", trying to register", topic);
|
DBG_INFO(NULL, "New topic \"%s\", trying to register", topic);
|
||||||
rv=_registerNewDeviceForTopic(xo, topic);
|
rv=_registerNewDeviceForTopic(xo, topic);
|
||||||
if (rv==1) {
|
if (rv==1) {
|
||||||
rv=_handlePublish(o, topic, value);
|
rv=_handlePublish(o, xo, topic, value);
|
||||||
if (rv!=1) {
|
if (rv!=1) {
|
||||||
DBG_ERROR(NULL, "Topic \"%s\" still not handled, SNH!", topic);
|
DBG_ERROR(NULL, "Topic \"%s\" still not handled, SNH!", topic);
|
||||||
}
|
}
|
||||||
@@ -92,53 +92,48 @@ void AQH_MqttLogServer_HandlePublishMsg(AQH_OBJECT *o, GWEN_UNUSED AQH_OBJECT *e
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
int _handlePublish(AQH_OBJECT *o, const char *rcvdTopic, const char *rcvdValue)
|
int _handlePublish(AQH_OBJECT *o, AQH_MQTTLOG_SERVER *xo, const char *rcvdTopic, const char *rcvdValue)
|
||||||
{
|
{
|
||||||
if (o && rcvdTopic && *rcvdTopic) {
|
if (o && rcvdTopic && *rcvdTopic && xo && xo->registeredDeviceList) {
|
||||||
AQH_MQTTLOG_SERVER *xo;
|
AQHMQTT_DEVICE *device;
|
||||||
|
|
||||||
xo=AQH_MqttLogServer_GetServerData(o);
|
device=AQHMQTT_Device_List_First(xo->registeredDeviceList);
|
||||||
if (xo && xo->registeredDeviceList) {
|
while(device) {
|
||||||
AQHMQTT_DEVICE *device;
|
AQHMQTT_TOPIC_LIST *topicList;
|
||||||
|
const char *sDeviceName;
|
||||||
|
const char *sDeviceId;
|
||||||
|
|
||||||
device=AQHMQTT_Device_List_First(xo->registeredDeviceList);
|
sDeviceName=AQHMQTT_Device_GetName(device);
|
||||||
while(device) {
|
sDeviceId=AQHMQTT_Device_GetId(device);
|
||||||
AQHMQTT_TOPIC_LIST *topicList;
|
|
||||||
const char *sDeviceName;
|
|
||||||
const char *sDeviceId;
|
|
||||||
|
|
||||||
sDeviceName=AQHMQTT_Device_GetName(device);
|
topicList=AQHMQTT_Device_GetTopicList(device);
|
||||||
sDeviceId=AQHMQTT_Device_GetId(device);
|
if (topicList) {
|
||||||
|
AQHMQTT_TOPIC *topic;
|
||||||
|
|
||||||
topicList=AQHMQTT_Device_GetTopicList(device);
|
topic=_findTopicMatchingTopic(topicList, rcvdTopic, AQHMQTT_TopicDir_In);
|
||||||
if (topicList) {
|
|
||||||
AQHMQTT_TOPIC *topic;
|
|
||||||
|
|
||||||
topic=_findTopicMatchingTopic(topicList, rcvdTopic, AQHMQTT_TopicDir_In);
|
|
||||||
#if 0
|
#if 0
|
||||||
if (topic==NULL) {
|
if (topic==NULL) {
|
||||||
topic=_findMaskMatchingTopic(topicList, rcvdTopic, AQHMQTT_TopicDir_In);
|
topic=_findMaskMatchingTopic(topicList, rcvdTopic, AQHMQTT_TopicDir_In);
|
||||||
if (topic)
|
if (topic)
|
||||||
AQHMQTT_Topic_SetTopic(topic, rcvdTopic);
|
AQHMQTT_Topic_SetTopic(topic, rcvdTopic);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (topic) {
|
if (topic) {
|
||||||
DBG_INFO(AQH_LOGDOMAIN,
|
DBG_INFO(AQH_LOGDOMAIN,
|
||||||
"Handling topic \"%s\" for device type %s (id: %s)",
|
"Handling topic \"%s\" for device type %s (id: %s)",
|
||||||
rcvdTopic,
|
rcvdTopic,
|
||||||
sDeviceName, sDeviceId?sDeviceId:"<no id>");
|
sDeviceName, sDeviceId?sDeviceId:"<no id>");
|
||||||
if (AQHMQTT_Topic_GetTopicType(topic)==AQHMQTT_TopicType_Json)
|
if (AQHMQTT_Topic_GetTopicType(topic)==AQHMQTT_TopicType_Json)
|
||||||
_handleJsonTopic(xo, device, topic, rcvdValue);
|
_handleJsonTopic(xo, device, topic, rcvdValue);
|
||||||
else
|
else
|
||||||
_handleNumTopic(xo, device, topic, rcvdValue);
|
_handleNumTopic(xo, device, topic, rcvdValue);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
device=AQHMQTT_Device_List_Next(device);
|
|
||||||
}
|
}
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "ignoring topic \"%s\"", rcvdTopic);
|
|
||||||
|
device=AQHMQTT_Device_List_Next(device);
|
||||||
}
|
}
|
||||||
|
DBG_INFO(AQH_LOGDOMAIN, "ignoring topic \"%s\"", rcvdTopic);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -282,7 +277,7 @@ void _sendAnnounceValueMessage(AQH_MQTTLOG_SERVER *xo, const AQHMQTT_DEVICE *dev
|
|||||||
AQH_Endpoint_GetNextMessageId(xo->brokerEndpoint), 0,
|
AQH_Endpoint_GetNextMessageId(xo->brokerEndpoint), 0,
|
||||||
0, msgValue);
|
0, msgValue);
|
||||||
if (pubMsg) {
|
if (pubMsg) {
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "BROKER ANNOUNCE_VALUE %s", AQH_Value_GetName(msgValue));
|
DBG_ERROR(AQH_LOGDOMAIN, "BROKER ANNOUNCE_VALUE %s/%s", AQH_Value_GetDeviceName(msgValue), AQH_Value_GetName(msgValue));
|
||||||
AQH_Endpoint_AddMsgOut(xo->brokerEndpoint, pubMsg);
|
AQH_Endpoint_AddMsgOut(xo->brokerEndpoint, pubMsg);
|
||||||
}
|
}
|
||||||
AQH_Value_free(msgValue);
|
AQH_Value_free(msgValue);
|
||||||
|
|||||||
@@ -31,8 +31,7 @@
|
|||||||
|
|
||||||
static void _sendDataForDevice(AQH_MQTTLOG_SERVER *xo, const AQHMQTT_DEVICE *device,
|
static void _sendDataForDevice(AQH_MQTTLOG_SERVER *xo, const AQHMQTT_DEVICE *device,
|
||||||
const char *valueName, const char *valueData);
|
const char *valueName, const char *valueData);
|
||||||
static void _sendValueToMqtt(AQH_MQTTLOG_SERVER *xo, const char *deviceId,
|
static void _sendValueToMqtt(AQH_MQTTLOG_SERVER *xo, const char *deviceId, const AQHMQTT_TOPIC *topic, const char *valueData);
|
||||||
const AQHMQTT_TOPIC *topic, const char *valueData);
|
|
||||||
static GWEN_BUFFER *_createBufferForTopic(const char *deviceId, const AQHMQTT_TOPIC *topic);
|
static GWEN_BUFFER *_createBufferForTopic(const char *deviceId, const AQHMQTT_TOPIC *topic);
|
||||||
|
|
||||||
|
|
||||||
@@ -131,7 +130,7 @@ void _sendDataForDevice(AQH_MQTTLOG_SERVER *xo,
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void _sendValueToMqtt(AQH_MQTTLOG_SERVER *xo, const char *deviceId, const AQHMQTT_TOPIC *topic, const char *valueData)
|
void _sendValueToMqtt(AQH_MQTTLOG_SERVER *xo, const char *deviceId, const AQHMQTT_TOPIC *topic, const char *valueData)
|
||||||
{
|
{
|
||||||
GWEN_BUFFER *buf;
|
GWEN_BUFFER *buf;
|
||||||
#if !DEBUG_DRY_RUN
|
#if !DEBUG_DRY_RUN
|
||||||
|
|||||||
@@ -109,10 +109,10 @@ static int _handleSignal(AQH_OBJECT *o, uint32_t slotId, AQH_OBJECT *senderObjec
|
|||||||
static int _handleBrokerDown(AQH_MQTTLOG_SERVER *xo);
|
static int _handleBrokerDown(AQH_MQTTLOG_SERVER *xo);
|
||||||
static int _handleMqttDown(AQH_MQTTLOG_SERVER *xo);
|
static int _handleMqttDown(AQH_MQTTLOG_SERVER *xo);
|
||||||
|
|
||||||
static void _handleMsgFromBroker(AQH_OBJECT *o, AQH_OBJECT *ep, const AQH_MESSAGE *msg);
|
static void _handleMsgFromBroker(AQH_OBJECT *o, const AQH_MESSAGE *msg);
|
||||||
|
|
||||||
static void _handleMsgFromMqtt(AQH_OBJECT *o, AQH_OBJECT *ep, const AQH_MESSAGE *msg);
|
static void _handleMsgFromMqtt(AQH_OBJECT *o, AQH_OBJECT *ep, const AQH_MESSAGE *msg);
|
||||||
static void _handleMqttMsgPingRsp(AQH_OBJECT *o, AQH_OBJECT *ep, const AQH_MESSAGE *msg);
|
static void _handleMqttMsgPingRsp(void);
|
||||||
|
|
||||||
static int _createPidFile(const char *pidFilename);
|
static int _createPidFile(const char *pidFilename);
|
||||||
static int _diffInSeconds(time_t t1, time_t t0);
|
static int _diffInSeconds(time_t t1, time_t t0);
|
||||||
@@ -474,7 +474,7 @@ int _startBroker(AQH_OBJECT *o, AQH_MQTTLOG_SERVER *xo)
|
|||||||
DBG_ERROR(NULL, "Error connecting to broker: %d", rv);
|
DBG_ERROR(NULL, "Error connecting to broker: %d", rv);
|
||||||
return (rv<0)?rv:GWEN_ERROR_PERMISSIONS;
|
return (rv<0)?rv:GWEN_ERROR_PERMISSIONS;
|
||||||
}
|
}
|
||||||
DBG_NOTICE(NULL, "Connected to broker at %s:%d", xo->brokerAddress, xo->brokerPort);
|
DBG_NOTICE(NULL, "Fully connected to broker at %s:%d", xo->brokerAddress, xo->brokerPort);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -658,7 +658,7 @@ void AQH_MqttLogServer_HandleBrokerMsgs(AQH_OBJECT *o)
|
|||||||
|
|
||||||
while( (msg=AQH_Endpoint_GetNextMsgIn(xo->brokerEndpoint)) ) {
|
while( (msg=AQH_Endpoint_GetNextMsgIn(xo->brokerEndpoint)) ) {
|
||||||
AQH_Message_SetObject(msg, xo->brokerEndpoint);
|
AQH_Message_SetObject(msg, xo->brokerEndpoint);
|
||||||
_handleMsgFromBroker(o, xo->brokerEndpoint, msg);
|
_handleMsgFromBroker(o, msg);
|
||||||
AQH_Message_free(msg);
|
AQH_Message_free(msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -666,7 +666,7 @@ void AQH_MqttLogServer_HandleBrokerMsgs(AQH_OBJECT *o)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void _handleMsgFromBroker(AQH_OBJECT *o, AQH_OBJECT *ep, const AQH_MESSAGE *msg)
|
void _handleMsgFromBroker(AQH_OBJECT *o, const AQH_MESSAGE *msg)
|
||||||
{
|
{
|
||||||
GWEN_TAG16_LIST *tagList;
|
GWEN_TAG16_LIST *tagList;
|
||||||
|
|
||||||
@@ -762,14 +762,14 @@ void _handleMsgFromMqtt(AQH_OBJECT *o, AQH_OBJECT *ep, const AQH_MESSAGE *msg)
|
|||||||
code=AQH_MqttMessage_GetTypeAndFlags(msg);
|
code=AQH_MqttMessage_GetTypeAndFlags(msg);
|
||||||
switch(code & 0xf0) {
|
switch(code & 0xf0) {
|
||||||
case (AQH_MQTTMSG_MSGTYPE_PUBLISH & 0xf0): AQH_MqttLogServer_HandlePublishMsg(o, ep, msg); break;
|
case (AQH_MQTTMSG_MSGTYPE_PUBLISH & 0xf0): AQH_MqttLogServer_HandlePublishMsg(o, ep, msg); break;
|
||||||
case (AQH_MQTTMSG_MSGTYPE_PINGRESP & 0xf0): _handleMqttMsgPingRsp(o, ep, msg); break;
|
case (AQH_MQTTMSG_MSGTYPE_PINGRESP & 0xf0): _handleMqttMsgPingRsp(); break;
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void _handleMqttMsgPingRsp(AQH_OBJECT *o, AQH_OBJECT *ep, const AQH_MESSAGE *msg)
|
void _handleMqttMsgPingRsp(void)
|
||||||
{
|
{
|
||||||
DBG_INFO(NULL, "PING response received");
|
DBG_INFO(NULL, "PING response received");
|
||||||
}
|
}
|
||||||
@@ -962,8 +962,9 @@ void AQH_MqttLogServer_LoadRuntimeDeviceFiles(AQH_OBJECT *o)
|
|||||||
|
|
||||||
DBG_INFO(NULL, "Loading registered devices from file \"%s\"", xo->deviceFile);
|
DBG_INFO(NULL, "Loading registered devices from file \"%s\"", xo->deviceFile);
|
||||||
deviceList=AQH_MqttLogServer_ReadDeviceFile(o, xo->deviceFile);
|
deviceList=AQH_MqttLogServer_ReadDeviceFile(o, xo->deviceFile);
|
||||||
if (deviceList)
|
if (deviceList==NULL)
|
||||||
AQH_MqttLogServer_SetRegisteredDeviceList(o, deviceList);
|
deviceList=AQHMQTT_Device_List_new();
|
||||||
|
AQH_MqttLogServer_SetRegisteredDeviceList(o, deviceList);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -999,7 +1000,7 @@ int AQH_MqttLogServer_SaveRuntimeDeviceFiles(AQH_OBJECT *o)
|
|||||||
* xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
* xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int _handleSignal(AQH_OBJECT *o, uint32_t slotId, AQH_OBJECT *senderObject, GWEN_UNUSED int param1, void *param2)
|
int _handleSignal(AQH_OBJECT *o, uint32_t slotId, GWEN_UNUSED AQH_OBJECT *senderObject, GWEN_UNUSED int param1, GWEN_UNUSED void *param2)
|
||||||
{
|
{
|
||||||
AQH_MQTTLOG_SERVER *xo;
|
AQH_MQTTLOG_SERVER *xo;
|
||||||
|
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ AQHMQTT_DEVICE_LIST *AQH_MqttLogServer_ReadDeviceFile(AQH_OBJECT *o, const char
|
|||||||
deviceList=AQHMQTT_Device_List_new();
|
deviceList=AQHMQTT_Device_List_new();
|
||||||
rv=_readDeviceFileToList(sFilename, deviceList);
|
rv=_readDeviceFileToList(sFilename, deviceList);
|
||||||
if (rv<0) {
|
if (rv<0) {
|
||||||
DBG_ERROR(NULL, "File \"%s\" not found", sFilename);
|
DBG_ERROR(NULL, "Could not read file \"%s\" (empty?)", sFilename);
|
||||||
AQHMQTT_Device_List_free(deviceList);
|
AQHMQTT_Device_List_free(deviceList);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -258,22 +258,24 @@ void _setDeviceName(AQH_VALUE *value, uint32_t uid)
|
|||||||
|
|
||||||
void _announceValue(AQH_NODE_SERVER *xo, uint32_t uid, const AQHNODE_VALUE *v)
|
void _announceValue(AQH_NODE_SERVER *xo, uint32_t uid, const AQHNODE_VALUE *v)
|
||||||
{
|
{
|
||||||
AQH_VALUE *value;
|
if (xo && xo->brokerEndpoint) {
|
||||||
AQH_MESSAGE *msg;
|
AQH_VALUE *value;
|
||||||
|
AQH_MESSAGE *msg;
|
||||||
|
|
||||||
value=AQH_Value_new();
|
value=AQH_Value_new();
|
||||||
_setDeviceName(value, uid);
|
_setDeviceName(value, uid);
|
||||||
AQH_Value_SetDriver(value, "nodes");
|
AQH_Value_SetDriver(value, "nodes");
|
||||||
AQH_Value_SetName(value, AQHNODE_Value_GetName(v));
|
AQH_Value_SetName(value, AQHNODE_Value_GetName(v));
|
||||||
AQH_Value_SetValueUnits(value, AQHNODE_Value_GetValueUnits(v));
|
AQH_Value_SetValueUnits(value, AQHNODE_Value_GetValueUnits(v));
|
||||||
AQH_Value_SetValueType(value, AQHNODE_Value_GetValueType(v));
|
AQH_Value_SetValueType(value, AQHNODE_Value_GetValueType(v));
|
||||||
AQH_Value_SetModality(value, AQHNODE_Value_GetModality(v));
|
AQH_Value_SetModality(value, AQHNODE_Value_GetModality(v));
|
||||||
|
|
||||||
msg=AQH_IpcdMessageValues_newForOne(AQH_MSGTYPE_IPC_DATA_ANNOUNCEVALUE,
|
msg=AQH_IpcdMessageValues_newForOne(AQH_MSGTYPE_IPC_DATA_ANNOUNCEVALUE,
|
||||||
AQH_Endpoint_GetNextMessageId(xo->brokerEndpoint), 0,
|
AQH_Endpoint_GetNextMessageId(xo->brokerEndpoint), 0,
|
||||||
0, value);
|
0, value);
|
||||||
AQH_Endpoint_AddMsgOut(xo->brokerEndpoint, msg);
|
AQH_Endpoint_AddMsgOut(xo->brokerEndpoint, msg);
|
||||||
AQH_Value_free(value);
|
AQH_Value_free(value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -149,13 +149,13 @@ void _runService(AQH_OBJECT *aqh, AQH_EVENT_LOOP *eventLoop)
|
|||||||
now=time(NULL);
|
now=time(NULL);
|
||||||
|
|
||||||
if (_diffInSeconds(now, timeLastConnectionCleanup)>CONNCLEAN_INTERVAL_IN_SECS) {
|
if (_diffInSeconds(now, timeLastConnectionCleanup)>CONNCLEAN_INTERVAL_IN_SECS) {
|
||||||
DBG_ERROR(NULL, "Cleanup connections");
|
DBG_INFO(NULL, "Cleanup connections");
|
||||||
AQH_NodeServer_CleanupClients(aqh);
|
AQH_NodeServer_CleanupClients(aqh);
|
||||||
timeLastConnectionCleanup=now;
|
timeLastConnectionCleanup=now;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_diffInSeconds(now, timeLastConnCheck)>CONNCHECK_INTERVAL_IN_SECS) {
|
if (_diffInSeconds(now, timeLastConnCheck)>CONNCHECK_INTERVAL_IN_SECS) {
|
||||||
DBG_ERROR(NULL, "Check connections");
|
DBG_INFO(NULL, "Check connections");
|
||||||
AQH_NodeServer_CheckBrokerConnection(aqh);
|
AQH_NodeServer_CheckBrokerConnection(aqh);
|
||||||
AQH_NodeServer_CheckTtyConnection(aqh);
|
AQH_NodeServer_CheckTtyConnection(aqh);
|
||||||
timeLastConnCheck=now;
|
timeLastConnCheck=now;
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
#include <aqhome/ipc2/ipc_server.h>
|
#include <aqhome/ipc2/ipc_server.h>
|
||||||
#include <aqhome/ipc2/tcpd_object.h>
|
#include <aqhome/ipc2/tcpd_object.h>
|
||||||
#include <aqhome/ipc2/tty_endpoint.h>
|
#include <aqhome/ipc2/tty_endpoint.h>
|
||||||
#include <aqhome/ipc2/ttyobject.h>
|
#include <aqhome/ipc2/tty_object.h>
|
||||||
#include <aqhome/ipc2/tcp_object.h>
|
#include <aqhome/ipc2/tcp_object.h>
|
||||||
#include <aqhome/ipc2/tcpd_object.h>
|
#include <aqhome/ipc2/tcpd_object.h>
|
||||||
#include <aqhome/ipc2/ipc_client.h>
|
#include <aqhome/ipc2/ipc_client.h>
|
||||||
@@ -580,7 +580,7 @@ int _startBroker(AQH_OBJECT *o, AQH_NODE_SERVER *xo)
|
|||||||
DBG_ERROR(NULL, "Error connecting to broker: %d", rv);
|
DBG_ERROR(NULL, "Error connecting to broker: %d", rv);
|
||||||
return (rv<0)?rv:GWEN_ERROR_PERMISSIONS;
|
return (rv<0)?rv:GWEN_ERROR_PERMISSIONS;
|
||||||
}
|
}
|
||||||
DBG_ERROR(NULL, "Connected to broker at %s:%d", xo->brokerAddress, xo->brokerPort);
|
DBG_ERROR(NULL, "Fully connected to broker at %s:%d", xo->brokerAddress, xo->brokerPort);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -808,7 +808,7 @@ void _handleMsgFromTty(AQH_OBJECT *o, AQH_NODE_SERVER *xo, const AQH_MESSAGE *ms
|
|||||||
uint8_t code;
|
uint8_t code;
|
||||||
|
|
||||||
code=AQH_NodeMessage_GetMsgType(msg);
|
code=AQH_NodeMessage_GetMsgType(msg);
|
||||||
DBG_ERROR(NULL, "Received Node packet %d (%x)", (int) code, code);
|
DBG_INFO(NULL, "Received Node packet %d (%x)", (int) code, code);
|
||||||
AQH_NodeServer_NodeMsgToDb(o, msg);
|
AQH_NodeServer_NodeMsgToDb(o, msg);
|
||||||
_writeTtyMsgToLogFile(xo, msg);
|
_writeTtyMsgToLogFile(xo, msg);
|
||||||
_forwardTtyMsgToBroker(o, xo, msg);
|
_forwardTtyMsgToBroker(o, xo, msg);
|
||||||
@@ -1117,7 +1117,7 @@ void _handleMsgFromBroker(AQH_OBJECT *o, AQH_OBJECT *ep, const AQH_MESSAGE *msg)
|
|||||||
code=AQH_IpcMessage_GetCode(msg);
|
code=AQH_IpcMessage_GetCode(msg);
|
||||||
protoId=AQH_IpcMessage_GetProtoId(msg);
|
protoId=AQH_IpcMessage_GetProtoId(msg);
|
||||||
if (protoId==AQH_IPC_PROTOCOL_DATA_ID) {
|
if (protoId==AQH_IPC_PROTOCOL_DATA_ID) {
|
||||||
DBG_ERROR(NULL, "Received IPC packet %d (%x)", (int) code, code);
|
DBG_INFO(NULL, "Received IPC packet %d (%x)", (int) code, code);
|
||||||
switch(code) {
|
switch(code) {
|
||||||
case AQH_MSGTYPE_IPC_DATA_SETDATA: AQH_NodeServer_HandleSetData(o, ep, msg); break;
|
case AQH_MSGTYPE_IPC_DATA_SETDATA: AQH_NodeServer_HandleSetData(o, ep, msg); break;
|
||||||
default: break;
|
default: break;
|
||||||
|
|||||||
@@ -198,7 +198,7 @@ void _runService(AQH_OBJECT *aqh, AQH_EVENT_LOOP *eventLoop)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (_diffInSeconds(now, lastSaveTime)>AQHOME_REACT_SAVE_INTERVAL) {
|
if (_diffInSeconds(now, lastSaveTime)>AQHOME_REACT_SAVE_INTERVAL) {
|
||||||
DBG_ERROR(NULL, "Writing var file");
|
DBG_INFO(NULL, "Writing var file");
|
||||||
rv=AQH_ReactServer_WriteVarsFile(aqh);
|
rv=AQH_ReactServer_WriteVarsFile(aqh);
|
||||||
if (rv<0) {
|
if (rv<0) {
|
||||||
DBG_INFO(NULL, "Error writing runtime data");
|
DBG_INFO(NULL, "Error writing runtime data");
|
||||||
|
|||||||
@@ -496,7 +496,7 @@ int _startBroker(AQH_OBJECT *o, AQH_REACT_SERVER *xo)
|
|||||||
DBG_ERROR(NULL, "Error connecting to broker: %d", rv);
|
DBG_ERROR(NULL, "Error connecting to broker: %d", rv);
|
||||||
return (rv<0)?rv:GWEN_ERROR_PERMISSIONS;
|
return (rv<0)?rv:GWEN_ERROR_PERMISSIONS;
|
||||||
}
|
}
|
||||||
DBG_INFO(NULL, "Connected to broker at %s:%d", xo->brokerAddress, xo->brokerPort);
|
DBG_ERROR(NULL, "Fully connected to broker at %s:%d", xo->brokerAddress, xo->brokerPort);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|||||||
184
aqhome-mqtt.devices.old
Normal file
184
aqhome-mqtt.devices.old
Normal file
@@ -0,0 +1,184 @@
|
|||||||
|
<devices>
|
||||||
|
<device id="plug01" name="tasmotaplug" driver="mqtt">
|
||||||
|
<mqtttopics>
|
||||||
|
<mqtttopic type="json" direction="in" name="sensor">
|
||||||
|
<topic>tele/tasmota/plug01/SENSOR</topic>
|
||||||
|
<mask>tele/tasmota/*/SENSOR</mask>
|
||||||
|
<beforeId>tele/tasmota/</beforeId>
|
||||||
|
<afterId>/SENSOR</afterId>
|
||||||
|
<values>
|
||||||
|
<value name="powerusage" units="W" path="ENERGY/POWER" type="sensor"></value>
|
||||||
|
<value name="totalenergy" units="kWh" path="ENERGY/TOTAL" type="sensor"></value>
|
||||||
|
<value name="apparentpower" units="VA" path="ENERGY/ApparentPower" type="sensor"></value>
|
||||||
|
<value name="reactivepower" units="VAr" path="ENERGY/ReactivePower" type="sensor"></value>
|
||||||
|
<value name="powerfactor" path="ENERGY/Factor" type="sensor"></value>
|
||||||
|
<value name="voltage" units="V" path="ENERGY/Voltage" type="sensor"></value>
|
||||||
|
<value name="current" units="A" path="ENERGY/Current" type="sensor"></value>
|
||||||
|
</values>
|
||||||
|
</mqtttopic>
|
||||||
|
<mqtttopic type="num" direction="out" name="power">
|
||||||
|
<beforeId>cmnd/tasmota/</beforeId>
|
||||||
|
<afterId>/Power</afterId>
|
||||||
|
<values>
|
||||||
|
<value name="power" type="actor"></value>
|
||||||
|
</values>
|
||||||
|
</mqtttopic>
|
||||||
|
</mqtttopics>
|
||||||
|
</device>
|
||||||
|
<device id="plug02" name="tasmotaplug" driver="mqtt">
|
||||||
|
<mqtttopics>
|
||||||
|
<mqtttopic type="json" direction="in" name="sensor">
|
||||||
|
<topic>tele/tasmota/plug02/SENSOR</topic>
|
||||||
|
<mask>tele/tasmota/*/SENSOR</mask>
|
||||||
|
<beforeId>tele/tasmota/</beforeId>
|
||||||
|
<afterId>/SENSOR</afterId>
|
||||||
|
<values>
|
||||||
|
<value name="powerusage" units="W" path="ENERGY/POWER" type="sensor"></value>
|
||||||
|
<value name="totalenergy" units="kWh" path="ENERGY/TOTAL" type="sensor"></value>
|
||||||
|
<value name="apparentpower" units="VA" path="ENERGY/ApparentPower" type="sensor"></value>
|
||||||
|
<value name="reactivepower" units="VAr" path="ENERGY/ReactivePower" type="sensor"></value>
|
||||||
|
<value name="powerfactor" path="ENERGY/Factor" type="sensor"></value>
|
||||||
|
<value name="voltage" units="V" path="ENERGY/Voltage" type="sensor"></value>
|
||||||
|
<value name="current" units="A" path="ENERGY/Current" type="sensor"></value>
|
||||||
|
</values>
|
||||||
|
</mqtttopic>
|
||||||
|
<mqtttopic type="num" direction="out" name="power">
|
||||||
|
<beforeId>cmnd/tasmota/</beforeId>
|
||||||
|
<afterId>/Power</afterId>
|
||||||
|
<values>
|
||||||
|
<value name="power" type="actor"></value>
|
||||||
|
</values>
|
||||||
|
</mqtttopic>
|
||||||
|
</mqtttopics>
|
||||||
|
</device>
|
||||||
|
<device id="plug03" name="tasmotaplug" driver="mqtt">
|
||||||
|
<mqtttopics>
|
||||||
|
<mqtttopic type="json" direction="in" name="sensor">
|
||||||
|
<topic>tele/tasmota/plug03/SENSOR</topic>
|
||||||
|
<mask>tele/tasmota/*/SENSOR</mask>
|
||||||
|
<beforeId>tele/tasmota/</beforeId>
|
||||||
|
<afterId>/SENSOR</afterId>
|
||||||
|
<values>
|
||||||
|
<value name="powerusage" units="W" path="ENERGY/POWER" type="sensor"></value>
|
||||||
|
<value name="totalenergy" units="kWh" path="ENERGY/TOTAL" type="sensor"></value>
|
||||||
|
<value name="apparentpower" units="VA" path="ENERGY/ApparentPower" type="sensor"></value>
|
||||||
|
<value name="reactivepower" units="VAr" path="ENERGY/ReactivePower" type="sensor"></value>
|
||||||
|
<value name="powerfactor" path="ENERGY/Factor" type="sensor"></value>
|
||||||
|
<value name="voltage" units="V" path="ENERGY/Voltage" type="sensor"></value>
|
||||||
|
<value name="current" units="A" path="ENERGY/Current" type="sensor"></value>
|
||||||
|
</values>
|
||||||
|
</mqtttopic>
|
||||||
|
<mqtttopic type="num" direction="out" name="power">
|
||||||
|
<beforeId>cmnd/tasmota/</beforeId>
|
||||||
|
<afterId>/Power</afterId>
|
||||||
|
<values>
|
||||||
|
<value name="power" type="actor"></value>
|
||||||
|
</values>
|
||||||
|
</mqtttopic>
|
||||||
|
</mqtttopics>
|
||||||
|
</device>
|
||||||
|
<device id="109C2F" name="tasmotaplug" driver="mqtt">
|
||||||
|
<mqtttopics>
|
||||||
|
<mqtttopic type="json" direction="in" name="sensor">
|
||||||
|
<topic>tele/tasmota_109C2F/SENSOR</topic>
|
||||||
|
<mask>tele/tasmota_*/SENSOR</mask>
|
||||||
|
<beforeId>tele/tasmota_</beforeId>
|
||||||
|
<afterId>/SENSOR</afterId>
|
||||||
|
<values>
|
||||||
|
<value name="powerusage" units="W" path="ENERGY/POWER" type="sensor"></value>
|
||||||
|
<value name="totalenergy" units="kWh" path="ENERGY/TOTAL" type="sensor"></value>
|
||||||
|
<value name="apparentpower" units="VA" path="ENERGY/ApparentPower" type="sensor"></value>
|
||||||
|
<value name="reactivepower" units="VAr" path="ENERGY/ReactivePower" type="sensor"></value>
|
||||||
|
<value name="powerfactor" path="ENERGY/Factor" type="sensor"></value>
|
||||||
|
<value name="voltage" units="V" path="ENERGY/Voltage" type="sensor"></value>
|
||||||
|
<value name="current" units="A" path="ENERGY/Current" type="sensor"></value>
|
||||||
|
</values>
|
||||||
|
</mqtttopic>
|
||||||
|
<mqtttopic type="num" direction="out" name="power">
|
||||||
|
<beforeId>cmnd/tasmota/</beforeId>
|
||||||
|
<afterId>/Power</afterId>
|
||||||
|
<values>
|
||||||
|
<value name="power" type="actor"></value>
|
||||||
|
</values>
|
||||||
|
</mqtttopic>
|
||||||
|
</mqtttopics>
|
||||||
|
</device>
|
||||||
|
<device id="10359B" name="tasmotaplug" driver="mqtt">
|
||||||
|
<mqtttopics>
|
||||||
|
<mqtttopic type="json" direction="in" name="sensor">
|
||||||
|
<topic>tele/tasmota_10359B/SENSOR</topic>
|
||||||
|
<mask>tele/tasmota_*/SENSOR</mask>
|
||||||
|
<beforeId>tele/tasmota_</beforeId>
|
||||||
|
<afterId>/SENSOR</afterId>
|
||||||
|
<values>
|
||||||
|
<value name="powerusage" units="W" path="ENERGY/POWER" type="sensor"></value>
|
||||||
|
<value name="totalenergy" units="kWh" path="ENERGY/TOTAL" type="sensor"></value>
|
||||||
|
<value name="apparentpower" units="VA" path="ENERGY/ApparentPower" type="sensor"></value>
|
||||||
|
<value name="reactivepower" units="VAr" path="ENERGY/ReactivePower" type="sensor"></value>
|
||||||
|
<value name="powerfactor" path="ENERGY/Factor" type="sensor"></value>
|
||||||
|
<value name="voltage" units="V" path="ENERGY/Voltage" type="sensor"></value>
|
||||||
|
<value name="current" units="A" path="ENERGY/Current" type="sensor"></value>
|
||||||
|
</values>
|
||||||
|
</mqtttopic>
|
||||||
|
<mqtttopic type="num" direction="out" name="power">
|
||||||
|
<beforeId>cmnd/tasmota_</beforeId>
|
||||||
|
<afterId>/Power</afterId>
|
||||||
|
<values>
|
||||||
|
<value name="power" type="actor"></value>
|
||||||
|
</values>
|
||||||
|
</mqtttopic>
|
||||||
|
</mqtttopics>
|
||||||
|
</device>
|
||||||
|
<device id="0F25C2" name="tasmotaplug" driver="mqtt">
|
||||||
|
<mqtttopics>
|
||||||
|
<mqtttopic type="json" direction="in" name="sensor">
|
||||||
|
<topic>tele/tasmota_0F25C2/SENSOR</topic>
|
||||||
|
<mask>tele/tasmota_*/SENSOR</mask>
|
||||||
|
<beforeId>tele/tasmota_</beforeId>
|
||||||
|
<afterId>/SENSOR</afterId>
|
||||||
|
<values>
|
||||||
|
<value name="powerusage" units="W" path="ENERGY/POWER" type="sensor"></value>
|
||||||
|
<value name="totalenergy" units="kWh" path="ENERGY/TOTAL" type="sensor"></value>
|
||||||
|
<value name="apparentpower" units="VA" path="ENERGY/ApparentPower" type="sensor"></value>
|
||||||
|
<value name="reactivepower" units="VAr" path="ENERGY/ReactivePower" type="sensor"></value>
|
||||||
|
<value name="powerfactor" path="ENERGY/Factor" type="sensor"></value>
|
||||||
|
<value name="voltage" units="V" path="ENERGY/Voltage" type="sensor"></value>
|
||||||
|
<value name="current" units="A" path="ENERGY/Current" type="sensor"></value>
|
||||||
|
</values>
|
||||||
|
</mqtttopic>
|
||||||
|
<mqtttopic type="num" direction="out" name="power">
|
||||||
|
<beforeId>cmnd/tasmota_</beforeId>
|
||||||
|
<afterId>/Power</afterId>
|
||||||
|
<values>
|
||||||
|
<value name="power" type="actor"></value>
|
||||||
|
</values>
|
||||||
|
</mqtttopic>
|
||||||
|
</mqtttopics>
|
||||||
|
</device>
|
||||||
|
<device id="10A4B7" name="tasmotaplug" driver="mqtt">
|
||||||
|
<mqtttopics>
|
||||||
|
<mqtttopic type="json" direction="in" name="sensor">
|
||||||
|
<topic>tele/tasmota_10A4B7/SENSOR</topic>
|
||||||
|
<mask>tele/tasmota_*/SENSOR</mask>
|
||||||
|
<beforeId>tele/tasmota_</beforeId>
|
||||||
|
<afterId>/SENSOR</afterId>
|
||||||
|
<values>
|
||||||
|
<value name="powerusage" units="W" path="ENERGY/POWER" type="sensor"></value>
|
||||||
|
<value name="totalenergy" units="kWh" path="ENERGY/TOTAL" type="sensor"></value>
|
||||||
|
<value name="apparentpower" units="VA" path="ENERGY/ApparentPower" type="sensor"></value>
|
||||||
|
<value name="reactivepower" units="VAr" path="ENERGY/ReactivePower" type="sensor"></value>
|
||||||
|
<value name="powerfactor" path="ENERGY/Factor" type="sensor"></value>
|
||||||
|
<value name="voltage" units="V" path="ENERGY/Voltage" type="sensor"></value>
|
||||||
|
<value name="current" units="A" path="ENERGY/Current" type="sensor"></value>
|
||||||
|
</values>
|
||||||
|
</mqtttopic>
|
||||||
|
<mqtttopic type="num" direction="out" name="power">
|
||||||
|
<beforeId>cmnd/tasmota_</beforeId>
|
||||||
|
<afterId>/Power</afterId>
|
||||||
|
<values>
|
||||||
|
<value name="power" type="actor"></value>
|
||||||
|
</values>
|
||||||
|
</mqtttopic>
|
||||||
|
</mqtttopics>
|
||||||
|
</device>
|
||||||
|
</devices>
|
||||||
@@ -3,5 +3,4 @@
|
|||||||
# export AQHOME_LOGLEVEL=info
|
# export AQHOME_LOGLEVEL=info
|
||||||
export LD_LIBRARY_PATH="0-build/aqhome/:$LD_LIBRARY_PATH"
|
export LD_LIBRARY_PATH="0-build/aqhome/:$LD_LIBRARY_PATH"
|
||||||
|
|
||||||
0-build/apps/aqhome-react/aqhome-react -p ./aqhome-react.pid "$@"
|
0-build/apps/aqhome-react/aqhome-react -p ./aqhome-react.pid -V ./aqhome-react.vars "$@"
|
||||||
|
|
||||||
|
|||||||
0
aqhome-react.vars
Normal file
0
aqhome-react.vars
Normal file
@@ -64,29 +64,21 @@
|
|||||||
|
|
||||||
<subdirs>
|
<subdirs>
|
||||||
msg
|
msg
|
||||||
ipc
|
|
||||||
ipc2
|
ipc2
|
||||||
nodes
|
nodes
|
||||||
mqtt
|
|
||||||
hexfile
|
hexfile
|
||||||
data
|
data
|
||||||
events
|
|
||||||
events2
|
events2
|
||||||
client
|
|
||||||
</subdirs>
|
</subdirs>
|
||||||
|
|
||||||
|
|
||||||
<useTargets>
|
<useTargets>
|
||||||
aqhmsg
|
aqhmsg
|
||||||
aqhipc
|
|
||||||
aqhipc2
|
aqhipc2
|
||||||
aqhnodes
|
aqhnodes
|
||||||
aqhmqtt
|
|
||||||
aqhhexfile
|
aqhhexfile
|
||||||
aqhdata
|
aqhdata
|
||||||
aqhevents
|
|
||||||
aqhevents2
|
aqhevents2
|
||||||
aqhclient
|
|
||||||
</useTargets>
|
</useTargets>
|
||||||
|
|
||||||
<libraries>
|
<libraries>
|
||||||
|
|||||||
@@ -1,78 +0,0 @@
|
|||||||
<?xml?>
|
|
||||||
|
|
||||||
<gwbuild>
|
|
||||||
|
|
||||||
<target type="ConvenienceLibrary" name="aqhclient" >
|
|
||||||
|
|
||||||
<includes type="c" >
|
|
||||||
$(gwenhywfar_cflags)
|
|
||||||
-I$(topsrcdir)
|
|
||||||
-I$(topbuilddir)
|
|
||||||
</includes>
|
|
||||||
|
|
||||||
<includes type="tm2" >
|
|
||||||
--include=$(builddir)
|
|
||||||
--include=$(srcdir)
|
|
||||||
</includes>
|
|
||||||
|
|
||||||
|
|
||||||
<define name="BUILDING_AQHOME" />
|
|
||||||
|
|
||||||
<setVar name="local/cflags">$(visibility_cflags)</setVar>
|
|
||||||
|
|
||||||
|
|
||||||
<setVar name="tm2flags" >
|
|
||||||
--api=AQHOME_API
|
|
||||||
</setVar>
|
|
||||||
|
|
||||||
<setVar name="local/typefiles" >
|
|
||||||
</setVar>
|
|
||||||
|
|
||||||
<setVar name="local/built_sources" >
|
|
||||||
</setVar>
|
|
||||||
|
|
||||||
<setVar name="local/built_headers_pub">
|
|
||||||
</setVar>
|
|
||||||
|
|
||||||
|
|
||||||
<setVar name="local/built_headers_priv" >
|
|
||||||
</setVar>
|
|
||||||
|
|
||||||
|
|
||||||
<headers dist="false" install="$(pkgincludedir)/client" >
|
|
||||||
$(local/built_headers_pub)
|
|
||||||
</headers>
|
|
||||||
|
|
||||||
|
|
||||||
<headers dist="true" install="$(pkgincludedir)/client" >
|
|
||||||
connection.h
|
|
||||||
</headers>
|
|
||||||
|
|
||||||
|
|
||||||
<headers dist="true" >
|
|
||||||
</headers>
|
|
||||||
|
|
||||||
|
|
||||||
<sources>
|
|
||||||
$(local/typefiles)
|
|
||||||
|
|
||||||
connection.c
|
|
||||||
</sources>
|
|
||||||
|
|
||||||
|
|
||||||
<extradist>
|
|
||||||
</extradist>
|
|
||||||
|
|
||||||
|
|
||||||
<useTargets>
|
|
||||||
</useTargets>
|
|
||||||
|
|
||||||
<subdirs>
|
|
||||||
</subdirs>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</target>
|
|
||||||
|
|
||||||
</gwbuild>
|
|
||||||
@@ -1,175 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
* 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 <config.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "./connection.h"
|
|
||||||
|
|
||||||
#include "aqhome/ipc/endpoint_ipc.h"
|
|
||||||
#include "aqhome/ipc/endpoint_ipcclient.h"
|
|
||||||
#include "aqhome/ipc/data/ipc_data.h"
|
|
||||||
#include "aqhome/ipc/data/msg_data_connect.h"
|
|
||||||
#include "aqhome/ipc/msg_ipc_result.h"
|
|
||||||
|
|
||||||
#include <gwenhywfar/endpoint_tcpc.h>
|
|
||||||
#include <gwenhywfar/endpoint_multilayer.h>
|
|
||||||
#include <gwenhywfar/msg_ipc.h>
|
|
||||||
#include <gwenhywfar/debug.h>
|
|
||||||
#include <gwenhywfar/timestamp.h>
|
|
||||||
#include <gwenhywfar/db.h>
|
|
||||||
|
|
||||||
#include <time.h>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
GWEN_MSG_ENDPOINT *_physConnectToBroker(const char *addr, int port, const char *clientId, uint32_t flags);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int AQH_BrokerConnection_FlushOutMessageQueue(GWEN_MSG_ENDPOINT *epTcp, int timeoutInSeconds)
|
|
||||||
{
|
|
||||||
time_t startTime;
|
|
||||||
|
|
||||||
startTime=time(NULL);
|
|
||||||
|
|
||||||
while(GWEN_MsgEndpoint_HaveMessageToSend(epTcp)) {
|
|
||||||
time_t now;
|
|
||||||
|
|
||||||
GWEN_MsgEndpoint_IoLoop(epTcp, 1000); /* 1000 ms */
|
|
||||||
now=time(NULL);
|
|
||||||
if (now-startTime>timeoutInSeconds) {
|
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "Timeout");
|
|
||||||
return GWEN_ERROR_TIMEOUT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
GWEN_MSG *AQH_BrokerConnection_WaitForSpecificMessage(GWEN_MSG_ENDPOINT *epTcp, int msgCode, int timeoutInSeconds)
|
|
||||||
{
|
|
||||||
time_t startTime;
|
|
||||||
|
|
||||||
startTime=time(NULL);
|
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
GWEN_MSG *msg;
|
|
||||||
time_t now;
|
|
||||||
|
|
||||||
GWEN_MsgEndpoint_IoLoop(epTcp, 1000); /* 1000 ms */
|
|
||||||
msg=GWEN_MsgEndpoint_TakeFirstReceivedMessage(epTcp);
|
|
||||||
if (msg) {
|
|
||||||
uint16_t code;
|
|
||||||
|
|
||||||
code=GWEN_IpcMsg_GetCode(msg);
|
|
||||||
if (code==msgCode) {
|
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "Received expected IPC message");
|
|
||||||
return msg;
|
|
||||||
}
|
|
||||||
else if (code==AQH_MSGTYPE_IPC_DATA_RESULT) {
|
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "Received IPC result message");
|
|
||||||
return msg;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "Received unexpected message %d (%x)", code, code);
|
|
||||||
}
|
|
||||||
GWEN_Msg_free(msg);
|
|
||||||
}
|
|
||||||
now=time(NULL);
|
|
||||||
if (now-startTime>timeoutInSeconds) {
|
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "Timeout");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
GWEN_MSG_ENDPOINT *AQH_BrokerConnection_OpenConnection(const char *addr, int port,
|
|
||||||
const char *clientId,
|
|
||||||
const char *userId, const char *passwd,
|
|
||||||
uint32_t flags,
|
|
||||||
int timeoutInSeconds)
|
|
||||||
{
|
|
||||||
GWEN_MSG_ENDPOINT *epTcp;
|
|
||||||
GWEN_MSG *msgOut;
|
|
||||||
GWEN_MSG *msgIn;
|
|
||||||
uint32_t result;
|
|
||||||
|
|
||||||
epTcp=_physConnectToBroker(addr, port, clientId, 0);
|
|
||||||
if (epTcp==NULL) {
|
|
||||||
DBG_ERROR(AQH_LOGDOMAIN, "ERROR creating TCP connection");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
msgOut=AQH_ConnectDataIpcMsg_new(AQH_MSGTYPE_IPC_DATA_CONNECT_REQ,
|
|
||||||
GWEN_MsgEndpoint_GetNextMessageId(epTcp), 0,
|
|
||||||
clientId, userId, passwd, flags);
|
|
||||||
if (msgOut==NULL) {
|
|
||||||
DBG_ERROR(AQH_LOGDOMAIN, "Error creating message");
|
|
||||||
GWEN_MsgEndpoint_free(epTcp);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
GWEN_MsgEndpoint_AddSendMessage(epTcp, msgOut);
|
|
||||||
|
|
||||||
msgIn=AQH_BrokerConnection_WaitForSpecificMessage(epTcp, AQH_MSGTYPE_IPC_DATA_RESULT, timeoutInSeconds);
|
|
||||||
if (msgIn==NULL) {
|
|
||||||
DBG_ERROR(AQH_LOGDOMAIN, "No response received");
|
|
||||||
GWEN_MsgEndpoint_free(epTcp);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
result=AQH_ResultIpcMsg_GetResultCode(msgIn);
|
|
||||||
GWEN_Msg_free(msgIn);
|
|
||||||
|
|
||||||
if (result!=AQH_MSG_IPC_SUCCESS) {
|
|
||||||
DBG_ERROR(AQH_LOGDOMAIN, "Response: %d", result);
|
|
||||||
GWEN_MsgEndpoint_free(epTcp);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return epTcp;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
GWEN_MSG_ENDPOINT *_physConnectToBroker(const char *addr, int port, const char *clientId, uint32_t flags)
|
|
||||||
{
|
|
||||||
GWEN_MSG_ENDPOINT *ep;
|
|
||||||
GWEN_MSG_ENDPOINT *ipcBaseEndpoint;
|
|
||||||
int rv;
|
|
||||||
|
|
||||||
ep=AQH_ClientIpcEndpoint_new("brokerIpcClient", 0);
|
|
||||||
GWEN_MsgEndpoint_AddFlags(ep, flags);
|
|
||||||
|
|
||||||
ipcBaseEndpoint=AQH_IpcEndpoint_CreateIpcTcpClient(addr, port, "brokerPhysEndpoint", 0);
|
|
||||||
AQH_IpcEndpoint_SetServiceName(ipcBaseEndpoint, clientId);
|
|
||||||
GWEN_MsgEndpoint_Tree2_AddChild(ep, ipcBaseEndpoint);
|
|
||||||
|
|
||||||
rv=GWEN_MultilayerEndpoint_StartConnect(ep);
|
|
||||||
if (rv<0 && rv!=GWEN_ERROR_IN_PROGRESS) {
|
|
||||||
DBG_ERROR(AQH_LOGDOMAIN, "Error connecting to broker server %s:%d (%d)", addr, port, rv);
|
|
||||||
GWEN_MsgEndpoint_free(ep);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ep;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
* 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.
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
#ifndef AQHOME_CLIENT_CONNECTION_H
|
|
||||||
#define AQHOME_CLIENT_CONNECTION_H
|
|
||||||
|
|
||||||
|
|
||||||
#include <aqhome/api.h>
|
|
||||||
|
|
||||||
#include <gwenhywfar/endpoint.h>
|
|
||||||
|
|
||||||
|
|
||||||
GWEN_MSG_ENDPOINT *AQH_BrokerConnection_OpenConnection(const char *addr, int port,
|
|
||||||
const char *clientId,
|
|
||||||
const char *userId, const char *passwd,
|
|
||||||
uint32_t flags,
|
|
||||||
int timeoutInSeconds);
|
|
||||||
int AQH_BrokerConnection_FlushOutMessageQueue(GWEN_MSG_ENDPOINT *epTcp, int timeoutInSeconds);
|
|
||||||
GWEN_MSG *AQH_BrokerConnection_WaitForSpecificMessage(GWEN_MSG_ENDPOINT *epTcp, int msgCode, int timeoutInSeconds);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -97,7 +97,6 @@ AQH_VARS *AQH_Vars_ReadDbFormat(const char *src)
|
|||||||
|
|
||||||
const char *_readLine(AQH_VARS **pVars, const char *src, GWEN_BUFFER *wbuf)
|
const char *_readLine(AQH_VARS **pVars, const char *src, GWEN_BUFFER *wbuf)
|
||||||
{
|
{
|
||||||
int rv;
|
|
||||||
const char *s;
|
const char *s;
|
||||||
|
|
||||||
s=src;
|
s=src;
|
||||||
@@ -143,7 +142,6 @@ const char *_readLine(AQH_VARS **pVars, const char *src, GWEN_BUFFER *wbuf)
|
|||||||
const char *_readGroupOrVar(AQH_VARS **pVars, const char *src, GWEN_BUFFER *wbuf)
|
const char *_readGroupOrVar(AQH_VARS **pVars, const char *src, GWEN_BUFFER *wbuf)
|
||||||
{
|
{
|
||||||
const char *s;
|
const char *s;
|
||||||
int rv;
|
|
||||||
|
|
||||||
GWEN_Buffer_Reset(wbuf);
|
GWEN_Buffer_Reset(wbuf);
|
||||||
s=_getWordToBuffer(src, " ={#\t\r\n", wbuf, _textFlags);
|
s=_getWordToBuffer(src, " ={#\t\r\n", wbuf, _textFlags);
|
||||||
|
|||||||
@@ -1,87 +0,0 @@
|
|||||||
<?xml?>
|
|
||||||
|
|
||||||
<gwbuild>
|
|
||||||
|
|
||||||
<target type="ConvenienceLibrary" name="aqhevents" >
|
|
||||||
|
|
||||||
<includes type="c" >
|
|
||||||
$(gwenhywfar_cflags)
|
|
||||||
$(aqdatabase_cflags)
|
|
||||||
-I$(topsrcdir)
|
|
||||||
-I$(topbuilddir)
|
|
||||||
</includes>
|
|
||||||
|
|
||||||
<includes type="tm2" >
|
|
||||||
--include=$(builddir)
|
|
||||||
--include=$(srcdir)
|
|
||||||
--include=$(aqdatabase_AQDATABASE_TYPEMAKERDIR)/c
|
|
||||||
</includes>
|
|
||||||
|
|
||||||
|
|
||||||
<define name="BUILDING_AQHOME" />
|
|
||||||
|
|
||||||
<setVar name="local/cflags">$(visibility_cflags)</setVar>
|
|
||||||
|
|
||||||
|
|
||||||
<setVar name="tm2flags" >
|
|
||||||
--api=AQHOME_API
|
|
||||||
</setVar>
|
|
||||||
|
|
||||||
<setVar name="local/typefiles" >
|
|
||||||
</setVar>
|
|
||||||
|
|
||||||
<setVar name="local/built_sources" >
|
|
||||||
</setVar>
|
|
||||||
|
|
||||||
<setVar name="local/built_headers_pub">
|
|
||||||
</setVar>
|
|
||||||
|
|
||||||
|
|
||||||
<setVar name="local/built_headers_priv" >
|
|
||||||
</setVar>
|
|
||||||
|
|
||||||
|
|
||||||
<headers dist="false" install="$(pkgincludedir)/data" >
|
|
||||||
$(local/built_headers_pub)
|
|
||||||
</headers>
|
|
||||||
|
|
||||||
|
|
||||||
<headers dist="true" install="$(pkgincludedir)/data" >
|
|
||||||
eventsubscription.h
|
|
||||||
eventtimer.h
|
|
||||||
eventhandler.h
|
|
||||||
</headers>
|
|
||||||
|
|
||||||
|
|
||||||
<headers dist="true" >
|
|
||||||
eventsubscription_p.h
|
|
||||||
eventtimer_p.h
|
|
||||||
eventhandler_p.h
|
|
||||||
</headers>
|
|
||||||
|
|
||||||
|
|
||||||
<sources>
|
|
||||||
$(local/typefiles)
|
|
||||||
|
|
||||||
eventsubscription.c
|
|
||||||
eventtimer.c
|
|
||||||
eventhandler.c
|
|
||||||
</sources>
|
|
||||||
|
|
||||||
|
|
||||||
<extradist>
|
|
||||||
</extradist>
|
|
||||||
|
|
||||||
|
|
||||||
<useTargets>
|
|
||||||
</useTargets>
|
|
||||||
|
|
||||||
<subdirs>
|
|
||||||
</subdirs>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</target>
|
|
||||||
|
|
||||||
</gwbuild>
|
|
||||||
@@ -1,138 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
* This file is part of the project Gwenhywfar.
|
|
||||||
* Gwenhywfar (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 "./eventhandler_p.h"
|
|
||||||
|
|
||||||
#include <gwenhywfar/debug.h>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
GWEN_INHERIT_FUNCTIONS(AQH_EVENT_HANDLER)
|
|
||||||
GWEN_LIST_FUNCTIONS(AQH_EVENT_HANDLER, AQH_EventHandler)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
AQH_EVENT_HANDLER *AQH_EventHandler_new()
|
|
||||||
{
|
|
||||||
AQH_EVENT_HANDLER *evh;
|
|
||||||
|
|
||||||
GWEN_NEW_OBJECT(AQH_EVENT_HANDLER, evh);
|
|
||||||
GWEN_INHERIT_INIT(AQH_EVENT_HANDLER, evh);
|
|
||||||
GWEN_LIST_INIT(AQH_EVENT_HANDLER, evh);
|
|
||||||
|
|
||||||
evh->timerList=AQH_EventTimer_List_new();
|
|
||||||
evh->subscriptionList=AQH_EventSubscription_List_new();
|
|
||||||
|
|
||||||
return evh;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_EventHandler_free(AQH_EVENT_HANDLER *evh)
|
|
||||||
{
|
|
||||||
if (evh) {
|
|
||||||
GWEN_LIST_FINI(AQH_EVENT_HANDLER, evh);
|
|
||||||
GWEN_INHERIT_FINI(AQH_EVENT_HANDLER, evh);
|
|
||||||
|
|
||||||
AQH_EventSubscription_List_free(evh->subscriptionList);
|
|
||||||
AQH_EventTimer_List_free(evh->timerList);
|
|
||||||
GWEN_FREE_OBJECT(evh);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
AQH_EVENT_TIMER_LIST *AQH_EventHandler_GetTimerList(const AQH_EVENT_HANDLER *evh)
|
|
||||||
{
|
|
||||||
return evh?evh->timerList:NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_EventHandler_AddTimer(AQH_EVENT_HANDLER *evh, AQH_EVENT_TIMER *evt)
|
|
||||||
{
|
|
||||||
if (evh && evt) {
|
|
||||||
AQH_EventTimer_SetId(evt, ++(evh->lastTimerId));
|
|
||||||
AQH_EventTimer_List_Add(evt, evh->timerList);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
AQH_EVENT_SUBSCRIPTION_LIST *AQH_EventHandler_GetSubscriptionList(const AQH_EVENT_HANDLER *evh)
|
|
||||||
{
|
|
||||||
return evh?evh->subscriptionList:NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_EventHandler_AddSubscription(AQH_EVENT_HANDLER *evh, AQH_EVENT_SUBSCRIPTION *evs)
|
|
||||||
{
|
|
||||||
if (evh && evs)
|
|
||||||
AQH_EventSubscription_List_Add(evs, evh->subscriptionList);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_EventHandler_HandleTimeTick(AQH_EVENT_HANDLER *evh, uint64_t t)
|
|
||||||
{
|
|
||||||
if (evh) {
|
|
||||||
AQH_EVENT_TIMER *evt;
|
|
||||||
|
|
||||||
evt=AQH_EventTimer_List_First(evh->timerList);
|
|
||||||
while(evt) {
|
|
||||||
AQH_EVENT_TIMER *evtNext;
|
|
||||||
|
|
||||||
evtNext=AQH_EventTimer_List_Next(evt);
|
|
||||||
if (AQH_EventTimer_CheckWhetherTickTriggers(evt, t)) {
|
|
||||||
AQH_EventHandler_HandleEvent(evh, AQH_EventTimer_GetEventType(evt), AQH_EventTimer_GetId(evt), 0.0);
|
|
||||||
if (AQH_EventTimer_GetFlags(evt) & AQH_EVENT_TIMER_FLAGS_DELETE_IF_TRIGGERED) {
|
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "Deleting timer after trigger");
|
|
||||||
AQH_EventTimer_List_Del(evt);
|
|
||||||
AQH_EventTimer_free(evt);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
evt=evtNext;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_EventHandler_HandleEvent(AQH_EVENT_HANDLER *evh, int eventType, uint64_t objectId, double data)
|
|
||||||
{
|
|
||||||
if (evh) {
|
|
||||||
AQH_EVENT_SUBSCRIPTION *evs;
|
|
||||||
|
|
||||||
evs=AQH_EventSubscription_List_First(evh->subscriptionList);
|
|
||||||
while(evs) {
|
|
||||||
if (AQH_EventSubscription_GetEventType(evs)==eventType) {
|
|
||||||
int objectIdFromSubscription;
|
|
||||||
|
|
||||||
objectIdFromSubscription=AQH_EventSubscription_GetObjectId(evs);
|
|
||||||
if (objectIdFromSubscription==0 || objectIdFromSubscription==objectId)
|
|
||||||
AQH_EventSubscription_CallHandler(evs, eventType, objectId, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
evs=AQH_EventSubscription_List_Next(evs);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
* This file is part of the project Gwenhywfar.
|
|
||||||
* Gwenhywfar (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 AQH_EVENT_HANDLER_H
|
|
||||||
#define AQH_EVENT_HANDLER_H
|
|
||||||
|
|
||||||
|
|
||||||
#include "aqhome/api.h"
|
|
||||||
|
|
||||||
#include <gwenhywfar/inherit.h>
|
|
||||||
#include <gwenhywfar/list.h>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct AQH_EVENT_HANDLER AQH_EVENT_HANDLER;
|
|
||||||
GWEN_INHERIT_FUNCTION_LIB_DEFS(AQH_EVENT_HANDLER, AQHOME_API)
|
|
||||||
GWEN_LIST_FUNCTION_LIB_DEFS(AQH_EVENT_HANDLER, AQH_EventHandler, AQHOME_API)
|
|
||||||
|
|
||||||
#include "aqhome/events/eventtimer.h"
|
|
||||||
#include "aqhome/events/eventsubscription.h"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
AQHOME_API AQH_EVENT_HANDLER *AQH_EventHandler_new();
|
|
||||||
AQHOME_API void AQH_EventHandler_free(AQH_EVENT_HANDLER *evh);
|
|
||||||
|
|
||||||
AQHOME_API AQH_EVENT_TIMER_LIST *AQH_EventHandler_GetTimerList(const AQH_EVENT_HANDLER *evh);
|
|
||||||
AQHOME_API void AQH_EventHandler_AddTimer(AQH_EVENT_HANDLER *evh, AQH_EVENT_TIMER *evt);
|
|
||||||
|
|
||||||
AQHOME_API AQH_EVENT_SUBSCRIPTION_LIST *AQH_EventHandler_GetSubscriptionList(const AQH_EVENT_HANDLER *evh);
|
|
||||||
AQHOME_API void AQH_EventHandler_AddSubscription(AQH_EVENT_HANDLER *evh, AQH_EVENT_SUBSCRIPTION *evs);
|
|
||||||
|
|
||||||
|
|
||||||
AQHOME_API void AQH_EventHandler_HandleTimeTick(AQH_EVENT_HANDLER *evh, uint64_t t);
|
|
||||||
AQHOME_API void AQH_EventHandler_HandleEvent(AQH_EVENT_HANDLER *evh, int eventType, uint64_t objectId, double data);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
* This file is part of the project Gwenhywfar.
|
|
||||||
* Gwenhywfar (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 AQH_EVENT_HANDLER_P_H
|
|
||||||
#define AQH_EVENT_HANDLER_P_H
|
|
||||||
|
|
||||||
|
|
||||||
#include "aqhome/events/eventhandler.h"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct AQH_EVENT_HANDLER {
|
|
||||||
GWEN_INHERIT_ELEMENT(AQH_EVENT_HANDLER)
|
|
||||||
GWEN_LIST_ELEMENT(AQH_EVENT_HANDLER)
|
|
||||||
|
|
||||||
uint64_t lastTimerId;
|
|
||||||
AQH_EVENT_TIMER_LIST *timerList;
|
|
||||||
AQH_EVENT_SUBSCRIPTION_LIST *subscriptionList;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,93 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
* This file is part of the project Gwenhywfar.
|
|
||||||
* Gwenhywfar (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 "./eventsubscription_p.h"
|
|
||||||
|
|
||||||
#include <gwenhywfar/debug.h>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
GWEN_INHERIT_FUNCTIONS(AQH_EVENT_SUBSCRIPTION)
|
|
||||||
GWEN_LIST_FUNCTIONS(AQH_EVENT_SUBSCRIPTION, AQH_EventSubscription)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
AQH_EVENT_SUBSCRIPTION *AQH_EventSubscription_new()
|
|
||||||
{
|
|
||||||
AQH_EVENT_SUBSCRIPTION *evs;
|
|
||||||
|
|
||||||
GWEN_NEW_OBJECT(AQH_EVENT_SUBSCRIPTION, evs);
|
|
||||||
GWEN_INHERIT_INIT(AQH_EVENT_SUBSCRIPTION, evs);
|
|
||||||
GWEN_LIST_INIT(AQH_EVENT_SUBSCRIPTION, evs);
|
|
||||||
|
|
||||||
return evs;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_EventSubscription_free(AQH_EVENT_SUBSCRIPTION *evs)
|
|
||||||
{
|
|
||||||
if (evs) {
|
|
||||||
GWEN_LIST_FINI(AQH_EVENT_SUBSCRIPTION, evs);
|
|
||||||
GWEN_INHERIT_FINI(AQH_EVENT_SUBSCRIPTION, evs);
|
|
||||||
GWEN_FREE_OBJECT(evs);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int AQH_EventSubscription_GetEventType(const AQH_EVENT_SUBSCRIPTION *evs)
|
|
||||||
{
|
|
||||||
return evs?evs->eventType:0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_EventSubscription_SetEventType(AQH_EVENT_SUBSCRIPTION *evs, int i)
|
|
||||||
{
|
|
||||||
if (evs)
|
|
||||||
evs->eventType=i;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint64_t AQH_EventSubscription_GetObjectId(const AQH_EVENT_SUBSCRIPTION *evs)
|
|
||||||
{
|
|
||||||
return evs?evs->objectId:0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_EventSubscription_SetObjectId(AQH_EVENT_SUBSCRIPTION *evs, uint64_t i)
|
|
||||||
{
|
|
||||||
if (evs)
|
|
||||||
evs->objectId=i;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int AQH_EventSubscription_CallHandler(AQH_EVENT_SUBSCRIPTION *evs, int eventType, uint64_t objectId, double data)
|
|
||||||
{
|
|
||||||
if (evs && evs->handlerFn)
|
|
||||||
return evs->handlerFn(evs, eventType, objectId, data);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
* This file is part of the project Gwenhywfar.
|
|
||||||
* Gwenhywfar (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 AQH_EVENTSUBSCRIPTION_H
|
|
||||||
#define AQH_EVENTSUBSCRIPTION_H
|
|
||||||
|
|
||||||
|
|
||||||
#include "aqhome/api.h"
|
|
||||||
|
|
||||||
#include <gwenhywfar/inherit.h>
|
|
||||||
#include <gwenhywfar/list.h>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct AQH_EVENT_SUBSCRIPTION AQH_EVENT_SUBSCRIPTION;
|
|
||||||
GWEN_INHERIT_FUNCTION_LIB_DEFS(AQH_EVENT_SUBSCRIPTION, AQHOME_API)
|
|
||||||
GWEN_LIST_FUNCTION_LIB_DEFS(AQH_EVENT_SUBSCRIPTION, AQH_EventSubscription, AQHOME_API)
|
|
||||||
|
|
||||||
typedef int (*AQH_EVENT_SUBSCRIPTION_HANDLER_FN)(AQH_EVENT_SUBSCRIPTION *evs, int eventType, uint64_t objectId, double data);
|
|
||||||
|
|
||||||
|
|
||||||
AQHOME_API AQH_EVENT_SUBSCRIPTION *AQH_EventSubscription_new();
|
|
||||||
AQHOME_API void AQH_EventSubscription_free(AQH_EVENT_SUBSCRIPTION *evs);
|
|
||||||
|
|
||||||
AQHOME_API int AQH_EventSubscription_GetEventType(const AQH_EVENT_SUBSCRIPTION *evs);
|
|
||||||
AQHOME_API void AQH_EventSubscription_SetEventType(AQH_EVENT_SUBSCRIPTION *evs, int i);
|
|
||||||
|
|
||||||
AQHOME_API uint64_t AQH_EventSubscription_GetObjectId(const AQH_EVENT_SUBSCRIPTION *evs);
|
|
||||||
AQHOME_API void AQH_EventSubscription_SetObjectId(AQH_EVENT_SUBSCRIPTION *evs, uint64_t i);
|
|
||||||
|
|
||||||
AQHOME_API int AQH_EventSubscription_CallHandler(AQH_EVENT_SUBSCRIPTION *evs, int eventType, uint64_t objectId, double data);
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
* This file is part of the project Gwenhywfar.
|
|
||||||
* Gwenhywfar (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 AQH_EVENTSUBSCRIPTION_P_H
|
|
||||||
#define AQH_EVENTSUBSCRIPTION_P_H
|
|
||||||
|
|
||||||
|
|
||||||
#include "aqhome/events/eventsubscription.h"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct AQH_EVENT_SUBSCRIPTION {
|
|
||||||
GWEN_INHERIT_ELEMENT(AQH_EVENT_SUBSCRIPTION)
|
|
||||||
GWEN_LIST_ELEMENT(AQH_EVENT_SUBSCRIPTION)
|
|
||||||
|
|
||||||
int eventType;
|
|
||||||
uint64_t objectId;
|
|
||||||
|
|
||||||
AQH_EVENT_SUBSCRIPTION_HANDLER_FN handlerFn;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,194 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
* This file is part of the project Gwenhywfar.
|
|
||||||
* Gwenhywfar (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 "./eventtimer_p.h"
|
|
||||||
|
|
||||||
#include <gwenhywfar/debug.h>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
GWEN_INHERIT_FUNCTIONS(AQH_EVENT_TIMER)
|
|
||||||
GWEN_LIST_FUNCTIONS(AQH_EVENT_TIMER, AQH_EventTimer)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
AQH_EVENT_TIMER *AQH_EventTimer_new()
|
|
||||||
{
|
|
||||||
AQH_EVENT_TIMER *evt;
|
|
||||||
|
|
||||||
GWEN_NEW_OBJECT(AQH_EVENT_TIMER, evt);
|
|
||||||
GWEN_INHERIT_INIT(AQH_EVENT_TIMER, evt);
|
|
||||||
GWEN_LIST_INIT(AQH_EVENT_TIMER, evt);
|
|
||||||
|
|
||||||
return evt;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_EventTimer_free(AQH_EVENT_TIMER *evt)
|
|
||||||
{
|
|
||||||
if (evt) {
|
|
||||||
GWEN_LIST_FINI(AQH_EVENT_TIMER, evt);
|
|
||||||
GWEN_INHERIT_FINI(AQH_EVENT_TIMER, evt);
|
|
||||||
|
|
||||||
GWEN_FREE_OBJECT(evt);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint32_t AQH_EventTimer_GetFlags(const AQH_EVENT_TIMER *evt)
|
|
||||||
{
|
|
||||||
return evt?evt->flags:0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_EventTimer_SetFlags(AQH_EVENT_TIMER *evt, uint32_t f)
|
|
||||||
{
|
|
||||||
if (evt)
|
|
||||||
evt->flags=f;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_EventTimer_AddFlags(AQH_EVENT_TIMER *evt, uint32_t f)
|
|
||||||
{
|
|
||||||
if (evt)
|
|
||||||
evt->flags|=f;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_EventTimer_SubFlags(AQH_EVENT_TIMER *evt, uint32_t f)
|
|
||||||
{
|
|
||||||
if (evt)
|
|
||||||
evt->flags&=~f;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int AQH_EventTimer_GetTimerType(const AQH_EVENT_TIMER *evt)
|
|
||||||
{
|
|
||||||
return evt?evt->timerType:0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_EventTimer_SetTimerType(AQH_EVENT_TIMER *evt, int i)
|
|
||||||
{
|
|
||||||
if (evt)
|
|
||||||
evt->timerType=i;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint64_t AQH_EventTimer_GetId(const AQH_EVENT_TIMER *evt)
|
|
||||||
{
|
|
||||||
return evt?evt->id:0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_EventTimer_SetId(AQH_EVENT_TIMER *evt, uint64_t i)
|
|
||||||
{
|
|
||||||
if (evt)
|
|
||||||
evt->id=i;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint64_t AQH_EventTimer_GetCurrentValue(const AQH_EVENT_TIMER *evt)
|
|
||||||
{
|
|
||||||
return evt?evt->currentValue:0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_EventTimer_SetCurrentValue(AQH_EVENT_TIMER *evt, uint64_t i)
|
|
||||||
{
|
|
||||||
if (evt)
|
|
||||||
evt->currentValue=i;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint64_t AQH_EventTimer_GetReloadOrAlarmValue(const AQH_EVENT_TIMER *evt)
|
|
||||||
{
|
|
||||||
return evt?evt->reloadOrAlarmValue:0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_EventTimer_SetReloadOrAlarmValue(AQH_EVENT_TIMER *evt, uint64_t i)
|
|
||||||
{
|
|
||||||
if (evt)
|
|
||||||
evt->reloadOrAlarmValue=i;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int AQH_EventTimer_GetEventType(const AQH_EVENT_TIMER *evt)
|
|
||||||
{
|
|
||||||
return evt?evt->eventType:0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_EventTimer_SetEventType(AQH_EVENT_TIMER *evt, int i)
|
|
||||||
{
|
|
||||||
if (evt)
|
|
||||||
evt->eventType=i;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int AQH_EventTimer_CheckWhetherTickTriggers(AQH_EVENT_TIMER *evt, uint64_t t)
|
|
||||||
{
|
|
||||||
if (evt && evt->flags & AQH_EVENT_TIMER_FLAGS_RUNNING) {
|
|
||||||
if (evt->timerType==AQH_EventTimerType_CountDown) {
|
|
||||||
if (evt->currentValue>0) {
|
|
||||||
evt->currentValue--;
|
|
||||||
if (evt->currentValue==0) {
|
|
||||||
if (evt->flags & AQH_EVENT_TIMER_FLAGS_RESTART) {
|
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "Timer %lu expired, restarting", (unsigned long int) (evt->id));
|
|
||||||
evt->currentValue=evt->reloadOrAlarmValue;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "Timer %lu expired", (unsigned long int) (evt->id));
|
|
||||||
evt->flags&=~AQH_EVENT_TIMER_FLAGS_RUNNING;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (evt->timerType==AQH_EventTimerType_Alarm) {
|
|
||||||
if (t>=evt->reloadOrAlarmValue) {
|
|
||||||
evt->flags&=~AQH_EVENT_TIMER_FLAGS_RUNNING;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "Unknown timer type %d", evt->timerType);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
* This file is part of the project Gwenhywfar.
|
|
||||||
* Gwenhywfar (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 AQH_EVENT_TIMER_H
|
|
||||||
#define AQH_EVENT_TIMER_H
|
|
||||||
|
|
||||||
|
|
||||||
#include "aqhome/api.h"
|
|
||||||
|
|
||||||
#include <gwenhywfar/inherit.h>
|
|
||||||
#include <gwenhywfar/list.h>
|
|
||||||
|
|
||||||
|
|
||||||
enum {
|
|
||||||
AQH_EventTimerType_CountDown=0,
|
|
||||||
AQH_EventTimerType_Alarm
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#define AQH_EVENT_TIMER_FLAGS_RUNNING 0x0001
|
|
||||||
#define AQH_EVENT_TIMER_FLAGS_RESTART 0x0002
|
|
||||||
#define AQH_EVENT_TIMER_FLAGS_DELETE_IF_TRIGGERED 0x0004
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct AQH_EVENT_TIMER AQH_EVENT_TIMER;
|
|
||||||
GWEN_INHERIT_FUNCTION_LIB_DEFS(AQH_EVENT_TIMER, AQHOME_API)
|
|
||||||
GWEN_LIST_FUNCTION_LIB_DEFS(AQH_EVENT_TIMER, AQH_EventTimer, AQHOME_API)
|
|
||||||
|
|
||||||
|
|
||||||
AQHOME_API AQH_EVENT_TIMER *AQH_EventTimer_new();
|
|
||||||
AQHOME_API void AQH_EventTimer_free(AQH_EVENT_TIMER *evt);
|
|
||||||
|
|
||||||
AQHOME_API uint32_t AQH_EventTimer_GetFlags(const AQH_EVENT_TIMER *evt);
|
|
||||||
AQHOME_API void AQH_EventTimer_SetFlags(AQH_EVENT_TIMER *evt, uint32_t f);
|
|
||||||
AQHOME_API void AQH_EventTimer_AddFlags(AQH_EVENT_TIMER *evt, uint32_t f);
|
|
||||||
AQHOME_API void AQH_EventTimer_SubFlags(AQH_EVENT_TIMER *evt, uint32_t f);
|
|
||||||
|
|
||||||
AQHOME_API int AQH_EventTimer_GetTimerType(const AQH_EVENT_TIMER *evt);
|
|
||||||
AQHOME_API void AQH_EventTimer_SetTimerType(AQH_EVENT_TIMER *evt, int i);
|
|
||||||
|
|
||||||
AQHOME_API uint64_t AQH_EventTimer_GetId(const AQH_EVENT_TIMER *evt);
|
|
||||||
AQHOME_API void AQH_EventTimer_SetId(AQH_EVENT_TIMER *evt, uint64_t i);
|
|
||||||
|
|
||||||
AQHOME_API uint64_t AQH_EventTimer_GetCurrentValue(const AQH_EVENT_TIMER *evt);
|
|
||||||
AQHOME_API void AQH_EventTimer_SetCurrentValue(AQH_EVENT_TIMER *evt, uint64_t i);
|
|
||||||
|
|
||||||
AQHOME_API uint64_t AQH_EventTimer_GetReloadOrAlarmValue(const AQH_EVENT_TIMER *evt);
|
|
||||||
AQHOME_API void AQH_EventTimer_SetReloadOrAlarmValue(AQH_EVENT_TIMER *evt, uint64_t i);
|
|
||||||
|
|
||||||
AQHOME_API int AQH_EventTimer_GetEventType(const AQH_EVENT_TIMER *evt);
|
|
||||||
AQHOME_API void AQH_EventTimer_SetEventType(AQH_EVENT_TIMER *evt, int i);
|
|
||||||
|
|
||||||
|
|
||||||
AQHOME_API int AQH_EventTimer_CheckWhetherTickTriggers(AQH_EVENT_TIMER *evt, uint64_t t);
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
* This file is part of the project Gwenhywfar.
|
|
||||||
* Gwenhywfar (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 AQH_EVENT_TIMER_P_H
|
|
||||||
#define AQH_EVENT_TIMER_P_H
|
|
||||||
|
|
||||||
|
|
||||||
#include "aqhome/events/eventtimer.h"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct AQH_EVENT_TIMER {
|
|
||||||
GWEN_INHERIT_ELEMENT(AQH_EVENT_TIMER)
|
|
||||||
GWEN_LIST_ELEMENT(AQH_EVENT_TIMER)
|
|
||||||
|
|
||||||
uint32_t flags;
|
|
||||||
int timerType;
|
|
||||||
uint64_t id;
|
|
||||||
uint64_t currentValue;
|
|
||||||
uint64_t reloadOrAlarmValue;
|
|
||||||
|
|
||||||
int eventType;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,95 +0,0 @@
|
|||||||
<?xml?>
|
|
||||||
|
|
||||||
<gwbuild>
|
|
||||||
|
|
||||||
<target type="ConvenienceLibrary" name="aqhhttp" >
|
|
||||||
|
|
||||||
<includes type="c" >
|
|
||||||
$(gwenhywfar_cflags)
|
|
||||||
-I$(topsrcdir)
|
|
||||||
-I$(topbuilddir)
|
|
||||||
</includes>
|
|
||||||
|
|
||||||
<includes type="tm2" >
|
|
||||||
--include=$(builddir)
|
|
||||||
--include=$(srcdir)
|
|
||||||
</includes>
|
|
||||||
|
|
||||||
|
|
||||||
<define name="BUILDING_AQHOME" />
|
|
||||||
|
|
||||||
<setVar name="local/cflags">$(visibility_cflags)</setVar>
|
|
||||||
|
|
||||||
|
|
||||||
<setVar name="tm2flags" >
|
|
||||||
--api=AQHOME_API
|
|
||||||
</setVar>
|
|
||||||
|
|
||||||
<setVar name="local/typefiles" >
|
|
||||||
</setVar>
|
|
||||||
|
|
||||||
<setVar name="local/built_sources" >
|
|
||||||
</setVar>
|
|
||||||
|
|
||||||
<setVar name="local/built_headers_pub">
|
|
||||||
</setVar>
|
|
||||||
|
|
||||||
|
|
||||||
<setVar name="local/built_headers_priv" >
|
|
||||||
</setVar>
|
|
||||||
|
|
||||||
|
|
||||||
<headers dist="false" install="$(pkgincludedir)/ipc" >
|
|
||||||
$(local/built_headers_pub)
|
|
||||||
</headers>
|
|
||||||
|
|
||||||
|
|
||||||
<headers dist="true" install="$(pkgincludedir)/http" >
|
|
||||||
endpoint_http.h
|
|
||||||
httpservice.h
|
|
||||||
httpservice_conf.h
|
|
||||||
httpservice_http.h
|
|
||||||
httprequest.h
|
|
||||||
urlhandler.h
|
|
||||||
content.h
|
|
||||||
content_files.h
|
|
||||||
</headers>
|
|
||||||
|
|
||||||
|
|
||||||
<headers dist="true" >
|
|
||||||
endpoint_http_p.h
|
|
||||||
httpservice_p.h
|
|
||||||
httprequest_p.h
|
|
||||||
urlhandler_p.h
|
|
||||||
content_p.h
|
|
||||||
content_files_p.h
|
|
||||||
</headers>
|
|
||||||
|
|
||||||
|
|
||||||
<sources>
|
|
||||||
$(local/typefiles)
|
|
||||||
|
|
||||||
endpoint_http.c
|
|
||||||
httpservice.c
|
|
||||||
httpservice_conf.c
|
|
||||||
httpservice_http.c
|
|
||||||
httprequest.c
|
|
||||||
urlhandler.c
|
|
||||||
content.c
|
|
||||||
content_files.c
|
|
||||||
</sources>
|
|
||||||
|
|
||||||
|
|
||||||
<extradist>
|
|
||||||
</extradist>
|
|
||||||
|
|
||||||
|
|
||||||
<useTargets>
|
|
||||||
</useTargets>
|
|
||||||
|
|
||||||
<subdirs>
|
|
||||||
</subdirs>
|
|
||||||
|
|
||||||
</target>
|
|
||||||
|
|
||||||
</gwbuild>
|
|
||||||
@@ -1,117 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
* 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
|
|
||||||
|
|
||||||
//#define DISABLE_DEBUGLOG
|
|
||||||
|
|
||||||
|
|
||||||
#include "aqhome/http/content_p.h"
|
|
||||||
|
|
||||||
#include <gwenhywfar/debug.h>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
GWEN_INHERIT_FUNCTIONS(AQH_HTTP_CONTENT)
|
|
||||||
GWEN_TREE2_FUNCTIONS(AQH_HTTP_CONTENT, AQH_HttpContent)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
AQH_HTTP_CONTENT *AQH_HttpContent_new(const char *name)
|
|
||||||
{
|
|
||||||
AQH_HTTP_CONTENT *cp;
|
|
||||||
|
|
||||||
GWEN_NEW_OBJECT(AQH_HTTP_CONTENT, cp);
|
|
||||||
GWEN_INHERIT_INIT(AQH_HTTP_CONTENT, cp);
|
|
||||||
GWEN_TREE2_INIT(AQH_HTTP_CONTENT, cp, AQH_HttpContent);
|
|
||||||
|
|
||||||
cp->name=name?strdup(name):NULL;
|
|
||||||
|
|
||||||
return cp;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_HttpContent_free(AQH_HTTP_CONTENT *cp)
|
|
||||||
{
|
|
||||||
if (cp) {
|
|
||||||
GWEN_TREE2_FINI(AQH_HTTP_CONTENT, cp, AQH_HttpContent);
|
|
||||||
GWEN_INHERIT_FINI(AQH_HTTP_CONTENT, cp);
|
|
||||||
|
|
||||||
free(cp->name);
|
|
||||||
|
|
||||||
GWEN_FREE_OBJECT(cp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const char *AQH_HttpContent_GetName(const AQH_HTTP_CONTENT *cp)
|
|
||||||
{
|
|
||||||
return cp?cp->name:NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int AQH_HttpContent_AddOpeningContent(AQH_HTTP_CONTENT *cp, int mode, GWEN_BUFFER *buffer)
|
|
||||||
{
|
|
||||||
return (cp && cp->addOpeningContentFn)?(cp->addOpeningContentFn(cp, mode, buffer)):0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int AQH_HttpContent_AddClosingContent(AQH_HTTP_CONTENT *cp, int mode, GWEN_BUFFER *buffer)
|
|
||||||
{
|
|
||||||
return (cp && cp->addClosingContentFn)?(cp->addClosingContentFn(cp, mode, buffer)):0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_HttpContent_SetAddOpeningContentFn(AQH_HTTP_CONTENT *cp, AQH_HTTP_CONTENT_ADD_OPENING_CONTENT_FN f)
|
|
||||||
{
|
|
||||||
if (cp)
|
|
||||||
cp->addOpeningContentFn=f;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_HttpContent_SetAddClosingContentFn(AQH_HTTP_CONTENT *cp, AQH_HTTP_CONTENT_ADD_CLOSING_CONTENT_FN f)
|
|
||||||
{
|
|
||||||
if (cp)
|
|
||||||
cp->addClosingContentFn=f;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
AQH_HTTP_CONTENT *AQH_HttpContent_Tree2_FindChildByName(AQH_HTTP_CONTENT *parent, const char *name)
|
|
||||||
{
|
|
||||||
if (parent) {
|
|
||||||
AQH_HTTP_CONTENT *c;
|
|
||||||
|
|
||||||
c=AQH_HttpContent_Tree2_GetFirstChild(parent);
|
|
||||||
while(c) {
|
|
||||||
const char *s;
|
|
||||||
|
|
||||||
s=AQH_HttpContent_GetName(c);
|
|
||||||
if (s && *s && strcasecmp(s, name)==0)
|
|
||||||
return c;
|
|
||||||
c=AQH_HttpContent_Tree2_GetNext(c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,63 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
* 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_HTTP_CONTENT_H
|
|
||||||
#define AQHOME_HTTP_CONTENT_H
|
|
||||||
|
|
||||||
|
|
||||||
#include <aqhome/api.h>
|
|
||||||
|
|
||||||
#include <gwenhywfar/buffer.h>
|
|
||||||
#include <gwenhywfar/inherit.h>
|
|
||||||
#include <gwenhywfar/tree2.h>
|
|
||||||
|
|
||||||
|
|
||||||
#define AQH_HTTP_CONTENT_MODE_DESKTOP 0
|
|
||||||
#define AQH_HTTP_CONTENT_MODE_MOBILE 1
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct AQH_HTTP_CONTENT AQH_HTTP_CONTENT;
|
|
||||||
GWEN_INHERIT_FUNCTION_LIB_DEFS(AQH_HTTP_CONTENT, AQHOME_API)
|
|
||||||
GWEN_TREE2_FUNCTION_LIB_DEFS(AQH_HTTP_CONTENT, AQH_HttpContent, AQHOME_API)
|
|
||||||
|
|
||||||
|
|
||||||
typedef int (*AQH_HTTP_CONTENT_ADD_OPENING_CONTENT_FN)(AQH_HTTP_CONTENT *cp, int mode, GWEN_BUFFER *buffer);
|
|
||||||
typedef int (*AQH_HTTP_CONTENT_ADD_CLOSING_CONTENT_FN)(AQH_HTTP_CONTENT *cp, int mode, GWEN_BUFFER *buffer);
|
|
||||||
|
|
||||||
|
|
||||||
AQHOME_API AQH_HTTP_CONTENT *AQH_HttpContent_new(const char *name);
|
|
||||||
AQHOME_API void AQH_HttpContent_free(AQH_HTTP_CONTENT *cp);
|
|
||||||
|
|
||||||
AQHOME_API const char *AQH_HttpContent_GetName(const AQH_HTTP_CONTENT *cp);
|
|
||||||
|
|
||||||
|
|
||||||
AQHOME_API int AQH_HttpContent_AddOpeningContent(AQH_HTTP_CONTENT *cp, int mode, GWEN_BUFFER *buffer);
|
|
||||||
AQHOME_API int AQH_HttpContent_AddClosingContent(AQH_HTTP_CONTENT *cp, int mode, GWEN_BUFFER *buffer);
|
|
||||||
|
|
||||||
|
|
||||||
AQHOME_API void AQH_HttpContent_SetAddOpeningContentFn(AQH_HTTP_CONTENT *cp, AQH_HTTP_CONTENT_ADD_OPENING_CONTENT_FN f);
|
|
||||||
AQHOME_API void AQH_HttpContent_SetAddClosingContentFn(AQH_HTTP_CONTENT *cp, AQH_HTTP_CONTENT_ADD_CLOSING_CONTENT_FN f);
|
|
||||||
|
|
||||||
AQHOME_API AQH_HTTP_CONTENT *AQH_HttpContent_Tree2_FindChildByName(AQH_HTTP_CONTENT *parent, const char *name);
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
@@ -1,143 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
* 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
|
|
||||||
|
|
||||||
//#define DISABLE_DEBUGLOG
|
|
||||||
|
|
||||||
|
|
||||||
#include "aqhome/http/content_files_p.h"
|
|
||||||
|
|
||||||
#include <gwenhywfar/debug.h>
|
|
||||||
#include <gwenhywfar/syncio.h>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
GWEN_INHERIT(AQH_HTTP_CONTENT, AQH_HTTP_CONTENT_FILES)
|
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------------------------------
|
|
||||||
* forward declarations
|
|
||||||
* ------------------------------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
static void _freeData(void *bp, void *p);
|
|
||||||
static int _addOpeningContent(AQH_HTTP_CONTENT *cp, int mode, GWEN_BUFFER *buffer);
|
|
||||||
static int _addClosingContent(AQH_HTTP_CONTENT *cp, int mode, GWEN_BUFFER *buffer);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------------------------------
|
|
||||||
* implementations
|
|
||||||
* ------------------------------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
AQH_HTTP_CONTENT *AQH_HttpContentFiles_new(const char *name, const char *headerFilename, const char *footerFilename)
|
|
||||||
{
|
|
||||||
AQH_HTTP_CONTENT *cp;
|
|
||||||
AQH_HTTP_CONTENT_FILES *xcp;
|
|
||||||
|
|
||||||
cp=AQH_HttpContent_new(name);
|
|
||||||
GWEN_NEW_OBJECT(AQH_HTTP_CONTENT_FILES, xcp);
|
|
||||||
GWEN_INHERIT_SETDATA(AQH_HTTP_CONTENT, AQH_HTTP_CONTENT_FILES, cp, xcp, _freeData);
|
|
||||||
|
|
||||||
xcp->headerFilename=(headerFilename && *headerFilename)?strdup(headerFilename):NULL;
|
|
||||||
xcp->footerFilename=(footerFilename && *footerFilename)?strdup(footerFilename):NULL;
|
|
||||||
|
|
||||||
AQH_HttpContent_SetAddOpeningContentFn(cp, _addOpeningContent);
|
|
||||||
AQH_HttpContent_SetAddClosingContentFn(cp, _addClosingContent);
|
|
||||||
|
|
||||||
return cp;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void _freeData(void *bp, void *p)
|
|
||||||
{
|
|
||||||
AQH_HTTP_CONTENT_FILES *xcp;
|
|
||||||
|
|
||||||
xcp=(AQH_HTTP_CONTENT_FILES*) p;
|
|
||||||
|
|
||||||
free(xcp->footerData);
|
|
||||||
free(xcp->headerData);
|
|
||||||
|
|
||||||
free(xcp->footerFilename);
|
|
||||||
free(xcp->headerFilename);
|
|
||||||
GWEN_FREE_OBJECT(xcp);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int _addOpeningContent(AQH_HTTP_CONTENT *cp, int mode, GWEN_BUFFER *buffer)
|
|
||||||
{
|
|
||||||
if (cp) {
|
|
||||||
AQH_HTTP_CONTENT_FILES *xcp;
|
|
||||||
|
|
||||||
xcp=GWEN_INHERIT_GETDATA(AQH_HTTP_CONTENT, AQH_HTTP_CONTENT_FILES, cp);
|
|
||||||
if (xcp) {
|
|
||||||
if (xcp->headerData==NULL) {
|
|
||||||
if (xcp->headerFilename) {
|
|
||||||
int rv;
|
|
||||||
GWEN_BUFFER *fileBuffer;
|
|
||||||
|
|
||||||
fileBuffer=GWEN_Buffer_new(0, 256, 0, 1);
|
|
||||||
rv=GWEN_SyncIo_Helper_ReadFile(xcp->headerFilename, fileBuffer);
|
|
||||||
if (rv<0) {
|
|
||||||
DBG_ERROR(AQH_LOGDOMAIN, "Error reading header file \"%s\": %d", xcp->headerFilename, rv);
|
|
||||||
GWEN_Buffer_free(fileBuffer);
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
xcp->headerData=strdup(GWEN_Buffer_GetStart(fileBuffer));
|
|
||||||
GWEN_Buffer_free(fileBuffer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (xcp->headerData)
|
|
||||||
GWEN_Buffer_AppendString(buffer, xcp->headerData);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int _addClosingContent(AQH_HTTP_CONTENT *cp, int mode, GWEN_BUFFER *buffer)
|
|
||||||
{
|
|
||||||
if (cp) {
|
|
||||||
AQH_HTTP_CONTENT_FILES *xcp;
|
|
||||||
|
|
||||||
xcp=GWEN_INHERIT_GETDATA(AQH_HTTP_CONTENT, AQH_HTTP_CONTENT_FILES, cp);
|
|
||||||
if (xcp) {
|
|
||||||
if (xcp->footerData==NULL) {
|
|
||||||
if (xcp->footerFilename) {
|
|
||||||
int rv;
|
|
||||||
GWEN_BUFFER *fileBuffer;
|
|
||||||
|
|
||||||
fileBuffer=GWEN_Buffer_new(0, 256, 0, 1);
|
|
||||||
rv=GWEN_SyncIo_Helper_ReadFile(xcp->footerFilename, fileBuffer);
|
|
||||||
if (rv<0) {
|
|
||||||
DBG_ERROR(AQH_LOGDOMAIN, "Error reading footer file \"%s\": %d", xcp->footerFilename, rv);
|
|
||||||
GWEN_Buffer_free(fileBuffer);
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
xcp->footerData=strdup(GWEN_Buffer_GetStart(fileBuffer));
|
|
||||||
GWEN_Buffer_free(fileBuffer);
|
|
||||||
}
|
|
||||||
if (xcp->footerData)
|
|
||||||
GWEN_Buffer_AppendString(buffer, xcp->footerData);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
* 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_HTTP_CONTENT_FILES_H
|
|
||||||
#define AQHOME_HTTP_CONTENT_FILES_H
|
|
||||||
|
|
||||||
|
|
||||||
#include <aqhome/api.h>
|
|
||||||
#include <aqhome/http/content.h>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
AQHOME_API AQH_HTTP_CONTENT *AQH_HttpContentFiles_new(const char *name, const char *headerFilename, const char *footerFilename);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
* 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_HTTP_CONTENT_FILES_P_H
|
|
||||||
#define AQHOME_HTTP_CONTENT_FILES_P_H
|
|
||||||
|
|
||||||
|
|
||||||
#include "aqhome/http/content_files.h"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct AQH_HTTP_CONTENT_FILES AQH_HTTP_CONTENT_FILES;
|
|
||||||
struct AQH_HTTP_CONTENT_FILES {
|
|
||||||
char *headerFilename;
|
|
||||||
char *footerFilename;
|
|
||||||
|
|
||||||
char *headerData;
|
|
||||||
char *footerData;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
* 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_HTTP_CONTENT_P_H
|
|
||||||
#define AQHOME_HTTP_CONTENT_P_H
|
|
||||||
|
|
||||||
|
|
||||||
#include "aqhome/http/content.h"
|
|
||||||
|
|
||||||
|
|
||||||
struct AQH_HTTP_CONTENT {
|
|
||||||
GWEN_INHERIT_ELEMENT(AQH_HTTP_CONTENT);
|
|
||||||
GWEN_TREE2_ELEMENT(AQH_HTTP_CONTENT);
|
|
||||||
|
|
||||||
char *name;
|
|
||||||
AQH_HTTP_CONTENT_ADD_OPENING_CONTENT_FN addOpeningContentFn;
|
|
||||||
AQH_HTTP_CONTENT_ADD_CLOSING_CONTENT_FN addClosingContentFn;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
@@ -1,661 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
* 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
|
|
||||||
|
|
||||||
//#define DISABLE_DEBUGLOG
|
|
||||||
|
|
||||||
|
|
||||||
#include "aqhome/http/endpoint_http_p.h"
|
|
||||||
|
|
||||||
|
|
||||||
#include <gwenhywfar/endpoint_tcpc.h>
|
|
||||||
#include <gwenhywfar/debug.h>
|
|
||||||
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <errno.h>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define AQH_ENDPOINT_HTTP_NAME "http"
|
|
||||||
#define AQH_ENDPOINT_HTTP_BUFFERSIZE 1024
|
|
||||||
|
|
||||||
#define AQH_ENDPOINT_HTTP_BOOKMARK_HEADER 0
|
|
||||||
#define AQH_ENDPOINT_HTTP_BOOKMARK_BODY 1
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
GWEN_INHERIT(GWEN_MSG_ENDPOINT, AQH_ENDPOINT_HTTP)
|
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------------------------------
|
|
||||||
* forward declarations
|
|
||||||
* ------------------------------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
static void GWENHYWFAR_CB _freeData(void *bp, void *p);
|
|
||||||
static void _addSockets(GWEN_MSG_ENDPOINT *ep, GWEN_SOCKETSET *readSet, GWEN_SOCKETSET *writeSet, GWEN_UNUSED GWEN_SOCKETSET *xSet);
|
|
||||||
static void _checkSockets(GWEN_MSG_ENDPOINT *ep, GWEN_SOCKETSET *readSet, GWEN_SOCKETSET *writeSet, GWEN_SOCKETSET *xSet);
|
|
||||||
static int _writeCurrentMessage(GWEN_MSG_ENDPOINT *ep);
|
|
||||||
static int _readCurrentMessage(GWEN_MSG_ENDPOINT *ep);
|
|
||||||
static int _distributeBufferContent(GWEN_MSG_ENDPOINT *ep, const uint8_t *bufferPtr, int bufferLen);
|
|
||||||
static int _distributeBufferInCommandMode(GWEN_MSG_ENDPOINT *ep, const uint8_t *bufferPtr, int bufferLen);
|
|
||||||
static int _distributeBufferInStatusMode(GWEN_MSG_ENDPOINT *ep, const uint8_t *bufferPtr, int bufferLen);
|
|
||||||
static int _distributeBufferInHeaderMode(GWEN_MSG_ENDPOINT *ep, const uint8_t *bufferPtr, int bufferLen);
|
|
||||||
static int _distributeBufferInBodyMode(GWEN_MSG_ENDPOINT *ep, const uint8_t *bufferPtr, int bufferLen);
|
|
||||||
static int _distributeBufferAsLine(GWEN_MSG_ENDPOINT *ep, const uint8_t *bufferPtr, int bufferLen);
|
|
||||||
static void _finishMessageAndStartNext(GWEN_MSG_ENDPOINT *ep);
|
|
||||||
static void _abortMessage(GWEN_MSG_ENDPOINT *ep);
|
|
||||||
static int _parseHeader(char *bufferPtr, GWEN_DB_NODE *db);
|
|
||||||
static int _parseCommand(const char *buffer, GWEN_DB_NODE *db);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------------------------------
|
|
||||||
* implementations
|
|
||||||
* ------------------------------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
void AQH_HttpEndpoint_Extend(GWEN_MSG_ENDPOINT *ep, uint32_t flags)
|
|
||||||
{
|
|
||||||
if (ep) {
|
|
||||||
AQH_ENDPOINT_HTTP *xep;
|
|
||||||
|
|
||||||
GWEN_NEW_OBJECT(AQH_ENDPOINT_HTTP, xep);
|
|
||||||
GWEN_INHERIT_SETDATA(GWEN_MSG_ENDPOINT, AQH_ENDPOINT_HTTP, ep, xep, _freeData);
|
|
||||||
xep->readMode=AQH_EndpointHttpd_ReadMode_Command;
|
|
||||||
xep->flags=flags;
|
|
||||||
|
|
||||||
xep->addSocketsFn=GWEN_MsgEndpoint_SetAddSocketsFn(ep, _addSockets);
|
|
||||||
xep->checkSocketsFn=GWEN_MsgEndpoint_SetCheckSocketsFn(ep, _checkSockets);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void _freeData(void *bp, void *p)
|
|
||||||
{
|
|
||||||
AQH_ENDPOINT_HTTP *xep;
|
|
||||||
|
|
||||||
xep=(AQH_ENDPOINT_HTTP*) p;
|
|
||||||
|
|
||||||
GWEN_DB_Group_free(xep->dbCurrentReadHeader);
|
|
||||||
GWEN_DB_Group_free(xep->dbCurrentReadCommand);
|
|
||||||
GWEN_Buffer_free(xep->currentReadBuffer);
|
|
||||||
|
|
||||||
GWEN_FREE_OBJECT(xep);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void _addSockets(GWEN_MSG_ENDPOINT *ep, GWEN_SOCKETSET *readSet, GWEN_SOCKETSET *writeSet, GWEN_UNUSED GWEN_SOCKETSET *xSet)
|
|
||||||
{
|
|
||||||
if (ep) {
|
|
||||||
AQH_ENDPOINT_HTTP *xep;
|
|
||||||
|
|
||||||
xep=GWEN_INHERIT_GETDATA(GWEN_MSG_ENDPOINT, AQH_ENDPOINT_HTTP, ep);
|
|
||||||
if (xep) {
|
|
||||||
if (GWEN_MsgEndpoint_GetState(ep)==GWEN_MSG_ENDPOINT_STATE_CONNECTED) {
|
|
||||||
GWEN_SOCKET *sk;
|
|
||||||
|
|
||||||
sk=GWEN_MsgEndpoint_GetSocket(ep);
|
|
||||||
if (sk) {
|
|
||||||
DBG_DEBUG(AQH_LOGDOMAIN, "Endpoint %s: Adding socket %d to read set",
|
|
||||||
GWEN_MsgEndpoint_GetName(ep),
|
|
||||||
GWEN_Socket_GetSocketInt(sk));
|
|
||||||
GWEN_SocketSet_AddSocket(readSet, sk);
|
|
||||||
if (GWEN_MsgEndpoint_HaveMessageToSend(ep)) {
|
|
||||||
DBG_DEBUG(AQH_LOGDOMAIN, "Endpoint %s: Adding socket %d to write set",
|
|
||||||
GWEN_MsgEndpoint_GetName(ep),
|
|
||||||
GWEN_Socket_GetSocketInt(sk));
|
|
||||||
GWEN_SocketSet_AddSocket(writeSet, sk);
|
|
||||||
}
|
|
||||||
} /* if socket */
|
|
||||||
}
|
|
||||||
else if (xep->addSocketsFn) {
|
|
||||||
DBG_DEBUG(AQH_LOGDOMAIN, "Endpoint %s: Not connected, calling base function", GWEN_MsgEndpoint_GetName(ep));
|
|
||||||
xep->addSocketsFn(ep, readSet, writeSet, xSet);
|
|
||||||
}
|
|
||||||
} /* if (xep) */
|
|
||||||
} /* if (ep) */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void _checkSockets(GWEN_MSG_ENDPOINT *ep, GWEN_SOCKETSET *readSet, GWEN_SOCKETSET *writeSet, GWEN_SOCKETSET *xSet)
|
|
||||||
{
|
|
||||||
if (ep) {
|
|
||||||
AQH_ENDPOINT_HTTP *xep;
|
|
||||||
|
|
||||||
xep=GWEN_INHERIT_GETDATA(GWEN_MSG_ENDPOINT, AQH_ENDPOINT_HTTP, ep);
|
|
||||||
if (xep) {
|
|
||||||
int rv;
|
|
||||||
|
|
||||||
if (GWEN_MsgEndpoint_GetState(ep)==GWEN_MSG_ENDPOINT_STATE_CONNECTED) {
|
|
||||||
GWEN_SOCKET *sk;
|
|
||||||
|
|
||||||
sk=GWEN_MsgEndpoint_GetSocket(ep);
|
|
||||||
if (sk) {
|
|
||||||
if (GWEN_SocketSet_HasSocket(writeSet, sk)) {
|
|
||||||
DBG_DEBUG(AQH_LOGDOMAIN, "Endpoint %s: Has socket in write set", GWEN_MsgEndpoint_GetName(ep));
|
|
||||||
rv=_writeCurrentMessage(ep);
|
|
||||||
if (rv<0 && rv!=GWEN_ERROR_TIMEOUT) {
|
|
||||||
DBG_INFO(AQH_LOGDOMAIN,
|
|
||||||
"Endpoint %s: Error writing current message (%d), disconnecting",
|
|
||||||
GWEN_MsgEndpoint_GetName(ep),
|
|
||||||
rv);
|
|
||||||
_abortMessage(ep);
|
|
||||||
GWEN_MsgEndpoint_Disconnect(ep);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GWEN_SocketSet_HasSocket(readSet, sk)) {
|
|
||||||
DBG_DEBUG(AQH_LOGDOMAIN, "Endpoint %s: Has socket in read set", GWEN_MsgEndpoint_GetName(ep));
|
|
||||||
rv=_readCurrentMessage(ep);
|
|
||||||
if (rv<0 && rv!=GWEN_ERROR_TIMEOUT) {
|
|
||||||
DBG_INFO(AQH_LOGDOMAIN,
|
|
||||||
"Endpoint %s: Error reading current message (%d), disconnecting",
|
|
||||||
GWEN_MsgEndpoint_GetName(ep),
|
|
||||||
rv);
|
|
||||||
_abortMessage(ep);
|
|
||||||
GWEN_MsgEndpoint_Disconnect(ep);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} /* if connected */
|
|
||||||
else if (xep->checkSocketsFn) {
|
|
||||||
DBG_DEBUG(AQH_LOGDOMAIN, "Endpoint %s: Not connected, calling base function", GWEN_MsgEndpoint_GetName(ep));
|
|
||||||
xep->checkSocketsFn(ep, readSet, writeSet, xSet);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int _writeCurrentMessage(GWEN_MSG_ENDPOINT *ep)
|
|
||||||
{
|
|
||||||
GWEN_MSG *msg;
|
|
||||||
|
|
||||||
DBG_DEBUG(AQH_LOGDOMAIN, "Writing to endpoint %s", GWEN_MsgEndpoint_GetName(ep));
|
|
||||||
msg=GWEN_MsgEndpoint_GetFirstSendMessage(ep);
|
|
||||||
if (msg) {
|
|
||||||
uint8_t pos;
|
|
||||||
int remaining;
|
|
||||||
int rv;
|
|
||||||
|
|
||||||
pos=GWEN_Msg_GetCurrentPos(msg);
|
|
||||||
remaining=GWEN_Msg_GetRemainingBytes(msg);
|
|
||||||
if (remaining>0) {
|
|
||||||
const uint8_t *buf;
|
|
||||||
|
|
||||||
/* start new message */
|
|
||||||
buf=GWEN_Msg_GetBuffer(msg)+pos;
|
|
||||||
rv=GWEN_MsgEndpoint_WriteToSocket(ep, buf, remaining);
|
|
||||||
if (rv<0) {
|
|
||||||
if (rv==GWEN_ERROR_TIMEOUT)
|
|
||||||
return rv;
|
|
||||||
DBG_ERROR(AQH_LOGDOMAIN, "Error on write() (%d)", rv);
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
GWEN_Msg_IncCurrentPos(msg, rv);
|
|
||||||
if (rv==remaining) {
|
|
||||||
DBG_DEBUG(AQH_LOGDOMAIN, "Message completely sent");
|
|
||||||
/* end current message */
|
|
||||||
GWEN_Msg_List_Del(msg);
|
|
||||||
GWEN_Msg_free(msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
DBG_DEBUG(AQH_LOGDOMAIN, "Nothing to send");
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int _readCurrentMessage(GWEN_MSG_ENDPOINT *ep)
|
|
||||||
{
|
|
||||||
int rv;
|
|
||||||
uint8_t buffer[AQH_ENDPOINT_HTTP_BUFFERSIZE];
|
|
||||||
|
|
||||||
DBG_DEBUG(AQH_LOGDOMAIN, "Reading from endpoint %s", GWEN_MsgEndpoint_GetName(ep));
|
|
||||||
rv=GWEN_MsgEndpoint_ReadFromSocket(ep, buffer, sizeof(buffer));
|
|
||||||
if (rv<0 && rv!=GWEN_ERROR_TIMEOUT) {
|
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "here (%d)", rv);
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
else if (rv==0) {
|
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "EOF met on read()");
|
|
||||||
return GWEN_ERROR_IO;
|
|
||||||
}
|
|
||||||
|
|
||||||
rv=_distributeBufferContent(ep, buffer, rv);
|
|
||||||
if (rv<0) {
|
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "here (%d)", rv);
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int _distributeBufferContent(GWEN_MSG_ENDPOINT *ep, const uint8_t *bufferPtr, int bufferLen)
|
|
||||||
{
|
|
||||||
if (ep) {
|
|
||||||
AQH_ENDPOINT_HTTP *xep;
|
|
||||||
|
|
||||||
xep=GWEN_INHERIT_GETDATA(GWEN_MSG_ENDPOINT, AQH_ENDPOINT_HTTP, ep);
|
|
||||||
if (xep) {
|
|
||||||
int rv;
|
|
||||||
if (xep->currentReadBuffer==NULL)
|
|
||||||
xep->currentReadBuffer=GWEN_Buffer_new(0, 256, 0, 1);
|
|
||||||
|
|
||||||
while(bufferLen) {
|
|
||||||
switch(xep->readMode) {
|
|
||||||
case AQH_EndpointHttpd_ReadMode_Command:
|
|
||||||
rv=_distributeBufferInCommandMode(ep, bufferPtr, bufferLen);
|
|
||||||
break;
|
|
||||||
case AQH_EndpointHttpd_ReadMode_Status:
|
|
||||||
rv=_distributeBufferInStatusMode(ep, bufferPtr, bufferLen);
|
|
||||||
break;
|
|
||||||
case AQH_EndpointHttpd_ReadMode_Headers:
|
|
||||||
rv=_distributeBufferInHeaderMode(ep, bufferPtr, bufferLen);
|
|
||||||
break;
|
|
||||||
case AQH_EndpointHttpd_ReadMode_Body:
|
|
||||||
rv=_distributeBufferInBodyMode(ep, bufferPtr, bufferLen);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
DBG_ERROR(AQH_LOGDOMAIN, "Invalid read mode %d", xep->readMode);
|
|
||||||
return GWEN_ERROR_GENERIC;
|
|
||||||
}
|
|
||||||
if (rv<0) {
|
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "here (%d)", rv);
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
else if (rv==0) {
|
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "No bytes used? SNH!");
|
|
||||||
return GWEN_ERROR_INTERNAL;
|
|
||||||
}
|
|
||||||
bufferPtr+=rv;
|
|
||||||
bufferLen-=rv;
|
|
||||||
} /* while */
|
|
||||||
return 0;
|
|
||||||
} /* if (xep) */
|
|
||||||
} /* if (ep) */
|
|
||||||
return GWEN_ERROR_GENERIC;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int _distributeBufferInCommandMode(GWEN_MSG_ENDPOINT *ep, const uint8_t *bufferPtr, int bufferLen)
|
|
||||||
{
|
|
||||||
int rv;
|
|
||||||
|
|
||||||
rv=_distributeBufferAsLine(ep, bufferPtr, bufferLen);
|
|
||||||
if (rv<0) {
|
|
||||||
AQH_ENDPOINT_HTTP *xep;
|
|
||||||
const char *s;
|
|
||||||
|
|
||||||
/* line complete */
|
|
||||||
DBG_DEBUG(AQH_LOGDOMAIN, "Command line complete");
|
|
||||||
rv=-rv;
|
|
||||||
xep=GWEN_INHERIT_GETDATA(GWEN_MSG_ENDPOINT, AQH_ENDPOINT_HTTP, ep);
|
|
||||||
|
|
||||||
xep->dbCurrentReadCommand=GWEN_DB_Group_new("command");
|
|
||||||
|
|
||||||
if (_parseCommand(GWEN_Buffer_GetStart(xep->currentReadBuffer), xep->dbCurrentReadCommand)<0) {
|
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "Error parsing command line [%s]", GWEN_Buffer_GetStart(xep->currentReadBuffer));
|
|
||||||
return GWEN_ERROR_BAD_DATA;
|
|
||||||
}
|
|
||||||
DBG_DEBUG(AQH_LOGDOMAIN, "Command line received: %s", GWEN_Buffer_GetStart(xep->currentReadBuffer));
|
|
||||||
s=GWEN_DB_GetCharValue(xep->dbCurrentReadCommand, "protocol", 0, "HTTP/0.9");
|
|
||||||
if (s && *s && strcasecmp(s, "HTTP/0.9")==0) {
|
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "HTTP 0.9, no header, message finished");
|
|
||||||
_finishMessageAndStartNext(ep);
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
DBG_DEBUG(AQH_LOGDOMAIN,
|
|
||||||
"Command line complete, advancing to header read mode (start: %d)",
|
|
||||||
GWEN_Buffer_GetPos(xep->currentReadBuffer));
|
|
||||||
xep->readMode=AQH_EndpointHttpd_ReadMode_Headers;
|
|
||||||
xep->currentHeaderPos=GWEN_Buffer_GetPos(xep->currentReadBuffer);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
DBG_DEBUG(AQH_LOGDOMAIN, "Line not yet finished (%d)", rv);
|
|
||||||
}
|
|
||||||
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int _distributeBufferInStatusMode(GWEN_MSG_ENDPOINT *ep, const uint8_t *bufferPtr, int bufferLen)
|
|
||||||
{
|
|
||||||
int rv;
|
|
||||||
|
|
||||||
rv=_distributeBufferAsLine(ep, bufferPtr, bufferLen);
|
|
||||||
if (rv<0) {
|
|
||||||
AQH_ENDPOINT_HTTP *xep;
|
|
||||||
|
|
||||||
/* line complete, TODO: parse status/command line */
|
|
||||||
rv=-rv;
|
|
||||||
xep=GWEN_INHERIT_GETDATA(GWEN_MSG_ENDPOINT, AQH_ENDPOINT_HTTP, ep);
|
|
||||||
DBG_DEBUG(AQH_LOGDOMAIN, "Line complete, advancing to header read mode");
|
|
||||||
xep->readMode=AQH_EndpointHttpd_ReadMode_Headers;
|
|
||||||
xep->currentBodyPos=GWEN_Buffer_GetPos(xep->currentReadBuffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int _distributeBufferInHeaderMode(GWEN_MSG_ENDPOINT *ep, const uint8_t *bufferPtr, int bufferLen)
|
|
||||||
{
|
|
||||||
int rv;
|
|
||||||
|
|
||||||
rv=_distributeBufferAsLine(ep, bufferPtr, bufferLen);
|
|
||||||
if (rv<0) {
|
|
||||||
AQH_ENDPOINT_HTTP *xep;
|
|
||||||
int lineLength;
|
|
||||||
|
|
||||||
/* line complete, parse status/command line */
|
|
||||||
rv=-rv;
|
|
||||||
xep=GWEN_INHERIT_GETDATA(GWEN_MSG_ENDPOINT, AQH_ENDPOINT_HTTP, ep);
|
|
||||||
|
|
||||||
lineLength=GWEN_Buffer_GetPos(xep->currentReadBuffer)-xep->lastLineStartPos;
|
|
||||||
xep->lastLineStartPos=GWEN_Buffer_GetPos(xep->currentReadBuffer);
|
|
||||||
if (lineLength==2) {
|
|
||||||
char *copyOfHeader;
|
|
||||||
int contentLength;
|
|
||||||
|
|
||||||
/* Empty line received, TODO: parse header */
|
|
||||||
DBG_DEBUG(AQH_LOGDOMAIN, "Empty header line received, end of header reached (header pos: %d).", xep->currentHeaderPos);
|
|
||||||
copyOfHeader=strdup(GWEN_Buffer_GetStart(xep->currentReadBuffer)+xep->currentHeaderPos);
|
|
||||||
xep->dbCurrentReadHeader=GWEN_DB_Group_new("header");
|
|
||||||
if (_parseHeader(copyOfHeader, xep->dbCurrentReadHeader)<0) {
|
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "Error parsing HTTP header");
|
|
||||||
free(copyOfHeader);
|
|
||||||
return GWEN_ERROR_BAD_DATA;
|
|
||||||
}
|
|
||||||
free(copyOfHeader);
|
|
||||||
contentLength=GWEN_DB_GetIntValue(xep->dbCurrentReadHeader, "Content-Length", 0, -1);
|
|
||||||
if (contentLength==0 || contentLength==-1) {
|
|
||||||
DBG_DEBUG(AQH_LOGDOMAIN, "Message has no body, done");
|
|
||||||
_finishMessageAndStartNext(ep);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
xep->currentBodyPos=GWEN_Buffer_GetPos(xep->currentReadBuffer);
|
|
||||||
xep->currentBodySize=contentLength;
|
|
||||||
xep->remainingBodySize=contentLength;
|
|
||||||
xep->readMode=AQH_EndpointHttpd_ReadMode_Body;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int _distributeBufferInBodyMode(GWEN_MSG_ENDPOINT *ep, const uint8_t *bufferPtr, int bufferLen)
|
|
||||||
{
|
|
||||||
AQH_ENDPOINT_HTTP *xep;
|
|
||||||
|
|
||||||
xep=GWEN_INHERIT_GETDATA(GWEN_MSG_ENDPOINT, AQH_ENDPOINT_HTTP, ep);
|
|
||||||
if (xep->remainingBodySize>0) {
|
|
||||||
int len;
|
|
||||||
|
|
||||||
len=bufferLen;
|
|
||||||
if (len>xep->remainingBodySize)
|
|
||||||
len=xep->remainingBodySize;
|
|
||||||
if (len) {
|
|
||||||
GWEN_Buffer_AppendBytes(xep->currentReadBuffer, (const char*) bufferPtr, len);
|
|
||||||
xep->remainingBodySize-=len;
|
|
||||||
if (xep->remainingBodySize==0) {
|
|
||||||
DBG_DEBUG(AQH_LOGDOMAIN, "Body completely received");
|
|
||||||
_finishMessageAndStartNext(ep);
|
|
||||||
}
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
DBG_ERROR(AQH_LOGDOMAIN, "No bytes left to read, SNH!");
|
|
||||||
return GWEN_ERROR_INTERNAL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
DBG_ERROR(AQH_LOGDOMAIN, "No body size, aborting");
|
|
||||||
return GWEN_ERROR_GENERIC;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* return negative number of bytes handled when LF encountered (i.e. line done), positive value otherwise */
|
|
||||||
int _distributeBufferAsLine(GWEN_MSG_ENDPOINT *ep, const uint8_t *bufferPtr, int bufferLen)
|
|
||||||
{
|
|
||||||
AQH_ENDPOINT_HTTP *xep;
|
|
||||||
const char *s;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
xep=GWEN_INHERIT_GETDATA(GWEN_MSG_ENDPOINT, AQH_ENDPOINT_HTTP, ep);
|
|
||||||
|
|
||||||
s=(const char*) bufferPtr;
|
|
||||||
i=0;
|
|
||||||
while(i<bufferLen && *s!=10) { /* scan until LF is encountered */
|
|
||||||
s++;
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
i++;
|
|
||||||
GWEN_Buffer_AppendBytes(xep->currentReadBuffer, (const char*) bufferPtr, i);
|
|
||||||
if (*s==10) {
|
|
||||||
DBG_DEBUG(AQH_LOGDOMAIN, "Received full line (added %d bytes from %d)", i, bufferLen);
|
|
||||||
i=-i;
|
|
||||||
}
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void _finishMessageAndStartNext(GWEN_MSG_ENDPOINT *ep)
|
|
||||||
{
|
|
||||||
AQH_ENDPOINT_HTTP *xep;
|
|
||||||
GWEN_MSG *msg;
|
|
||||||
GWEN_DB_NODE *dbParsedData;
|
|
||||||
|
|
||||||
DBG_DEBUG(AQH_LOGDOMAIN, "Message completely received.");
|
|
||||||
xep=GWEN_INHERIT_GETDATA(GWEN_MSG_ENDPOINT, AQH_ENDPOINT_HTTP, ep);
|
|
||||||
|
|
||||||
msg=GWEN_Msg_fromBytes((const uint8_t*)GWEN_Buffer_GetStart(xep->currentReadBuffer), GWEN_Buffer_GetUsedBytes(xep->currentReadBuffer));
|
|
||||||
if (xep->currentBodySize) {
|
|
||||||
GWEN_Msg_SetParsedPayloadOffset(msg, xep->currentBodyPos);
|
|
||||||
GWEN_Msg_SetParsedPayloadSize(msg, xep->currentBodySize);
|
|
||||||
}
|
|
||||||
dbParsedData=GWEN_DB_Group_new("parsedData");
|
|
||||||
if (xep->dbCurrentReadCommand)
|
|
||||||
GWEN_DB_AddGroup(dbParsedData, xep->dbCurrentReadCommand);
|
|
||||||
if (xep->dbCurrentReadHeader)
|
|
||||||
GWEN_DB_AddGroup(dbParsedData, xep->dbCurrentReadHeader);
|
|
||||||
GWEN_Msg_SetDbParsedInfo(msg, dbParsedData);
|
|
||||||
|
|
||||||
GWEN_MsgEndpoint_AddReceivedMessage(ep, msg);
|
|
||||||
|
|
||||||
GWEN_Buffer_Reset(xep->currentReadBuffer);
|
|
||||||
xep->currentHeaderPos=0;
|
|
||||||
xep->currentBodyPos=0;
|
|
||||||
xep->currentBodySize=0;
|
|
||||||
xep->remainingBodySize=0;
|
|
||||||
xep->lastLineStartPos=0;
|
|
||||||
xep->dbCurrentReadCommand=NULL;
|
|
||||||
xep->dbCurrentReadHeader=NULL;
|
|
||||||
|
|
||||||
if (xep->flags & AQH_ENDPOINT_HTTP_FLAGS_PASSIVE) {
|
|
||||||
DBG_DEBUG(AQH_LOGDOMAIN, "Passive connection");
|
|
||||||
xep->readMode=AQH_EndpointHttpd_ReadMode_Command;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
DBG_DEBUG(AQH_LOGDOMAIN, "Active connection");
|
|
||||||
xep->readMode=AQH_EndpointHttpd_ReadMode_Status;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void _abortMessage(GWEN_MSG_ENDPOINT *ep)
|
|
||||||
{
|
|
||||||
AQH_ENDPOINT_HTTP *xep;
|
|
||||||
|
|
||||||
DBG_DEBUG(AQH_LOGDOMAIN, "Aborting message (if any).");
|
|
||||||
xep=GWEN_INHERIT_GETDATA(GWEN_MSG_ENDPOINT, AQH_ENDPOINT_HTTP, ep);
|
|
||||||
|
|
||||||
if (xep->currentReadBuffer)
|
|
||||||
GWEN_Buffer_Reset(xep->currentReadBuffer);
|
|
||||||
xep->currentHeaderPos=0;
|
|
||||||
xep->currentBodyPos=0;
|
|
||||||
xep->currentBodySize=0;
|
|
||||||
xep->remainingBodySize=0;
|
|
||||||
xep->lastLineStartPos=0;
|
|
||||||
if (xep->dbCurrentReadCommand)
|
|
||||||
GWEN_DB_Group_free(xep->dbCurrentReadCommand);
|
|
||||||
xep->dbCurrentReadCommand=NULL;
|
|
||||||
if (xep->dbCurrentReadHeader)
|
|
||||||
GWEN_DB_Group_free(xep->dbCurrentReadHeader);
|
|
||||||
xep->dbCurrentReadHeader=NULL;
|
|
||||||
|
|
||||||
xep->readMode=AQH_EndpointHttpd_ReadMode_Aborted;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int _parseHeader(char *bufferPtr, GWEN_DB_NODE *db)
|
|
||||||
{
|
|
||||||
char *p;
|
|
||||||
|
|
||||||
/* resolve line continuations */
|
|
||||||
p=bufferPtr;
|
|
||||||
while (*p) {
|
|
||||||
p=strchr(p, 10);
|
|
||||||
if (p) {
|
|
||||||
if (p[1]==32 || p[1]==9)
|
|
||||||
/* found a continuation */
|
|
||||||
*p=32;
|
|
||||||
p++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* parse every line */
|
|
||||||
p=bufferPtr;
|
|
||||||
while (p && *p) {
|
|
||||||
char *pNext;
|
|
||||||
char *pVarBegin;
|
|
||||||
char *pVarEnd;
|
|
||||||
|
|
||||||
/* find end of line */
|
|
||||||
pNext=strchr(p, 13);
|
|
||||||
if (pNext) {
|
|
||||||
*pNext=0;
|
|
||||||
pNext++;
|
|
||||||
}
|
|
||||||
/* skip LF */
|
|
||||||
if (*p==10)
|
|
||||||
p++;
|
|
||||||
while (*p && (*p==32 || *p==9))
|
|
||||||
p++;
|
|
||||||
if (*p) {
|
|
||||||
pVarBegin=p;
|
|
||||||
while (*p && *p!=':' && *p>32 && *p<127)
|
|
||||||
p++;
|
|
||||||
pVarEnd=p;
|
|
||||||
if (*p!=':') {
|
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "No separator after variable name in received header (var: [%s])", pVarBegin);
|
|
||||||
return GWEN_ERROR_BAD_DATA;
|
|
||||||
}
|
|
||||||
*pVarEnd=0;
|
|
||||||
p++;
|
|
||||||
|
|
||||||
while (*p && (*p==32 || *p==9))
|
|
||||||
p++;
|
|
||||||
if (*p) {
|
|
||||||
DBG_DEBUG(AQH_LOGDOMAIN, "Setting header variable: [%s] = [%s]", pVarBegin, p);
|
|
||||||
GWEN_DB_SetCharValue(db, GWEN_PATH_FLAGS_CREATE_VAR, pVarBegin, p);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
p=pNext;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int _parseCommand(const char *buffer, GWEN_DB_NODE *db)
|
|
||||||
{
|
|
||||||
char *tmp;
|
|
||||||
char *p;
|
|
||||||
char *s;
|
|
||||||
|
|
||||||
tmp=strdup(buffer);
|
|
||||||
/* get end of line (marked by CR/LF) */
|
|
||||||
s=strchr(tmp, 13);
|
|
||||||
if (s)
|
|
||||||
*s=0;
|
|
||||||
s=tmp;
|
|
||||||
|
|
||||||
/* read command */
|
|
||||||
p=strchr(s, ' ');
|
|
||||||
if (!p) {
|
|
||||||
DBG_ERROR(AQH_LOGDOMAIN, "Bad format of HTTP request (%s)", buffer);
|
|
||||||
free(tmp);
|
|
||||||
return GWEN_ERROR_BAD_DATA;
|
|
||||||
}
|
|
||||||
*p=0;
|
|
||||||
p++;
|
|
||||||
|
|
||||||
GWEN_DB_SetCharValue(db, GWEN_DB_FLAGS_OVERWRITE_VARS, "command", s);
|
|
||||||
s=p;
|
|
||||||
|
|
||||||
/* read URL */
|
|
||||||
p=strchr(s, ' ');
|
|
||||||
if (!p) {
|
|
||||||
DBG_ERROR(AQH_LOGDOMAIN, "Bad format of HTTP request (%s)", buffer);
|
|
||||||
free(tmp);
|
|
||||||
return GWEN_ERROR_BAD_DATA;
|
|
||||||
}
|
|
||||||
*p=0;
|
|
||||||
p++;
|
|
||||||
|
|
||||||
GWEN_DB_SetCharValue(db, GWEN_DB_FLAGS_OVERWRITE_VARS, "url", s);
|
|
||||||
s=p;
|
|
||||||
|
|
||||||
if (*s==0) {
|
|
||||||
/* no protocol information follows, so we assume HTTP/0.9 */
|
|
||||||
DBG_ERROR(AQH_LOGDOMAIN, "Bad request (not in HTTP>=1.0)");
|
|
||||||
free(tmp);
|
|
||||||
return GWEN_ERROR_BAD_DATA;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
GWEN_DB_SetCharValue(db, GWEN_DB_FLAGS_OVERWRITE_VARS, "protocol", s);
|
|
||||||
}
|
|
||||||
|
|
||||||
free(tmp);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
* 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 AQH_ENDPOINT_HTTP_H
|
|
||||||
#define AQH_ENDPOINT_HTTP_H
|
|
||||||
|
|
||||||
|
|
||||||
#include <aqhome/api.h>
|
|
||||||
|
|
||||||
#include <gwenhywfar/endpoint.h>
|
|
||||||
|
|
||||||
|
|
||||||
#define AQH_ENDPOINT_HTTP_FLAGS_PASSIVE 0x0001
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
AQHOME_API void AQH_HttpEndpoint_Extend(GWEN_MSG_ENDPOINT *ep, uint32_t flags);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
* 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 AQH_ENDPOINT_HTTP_P_H
|
|
||||||
#define AQH_ENDPOINT_HTTP_P_H
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include "aqhome/http/endpoint_http.h"
|
|
||||||
|
|
||||||
#include <gwenhywfar/db.h>
|
|
||||||
#include <gwenhywfar/buffer.h>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
enum {
|
|
||||||
AQH_EndpointHttpd_ReadMode_Aborted=-1,
|
|
||||||
AQH_EndpointHttpd_ReadMode_Command=0,
|
|
||||||
AQH_EndpointHttpd_ReadMode_Status,
|
|
||||||
AQH_EndpointHttpd_ReadMode_Headers,
|
|
||||||
AQH_EndpointHttpd_ReadMode_Body
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct AQH_ENDPOINT_HTTP AQH_ENDPOINT_HTTP;
|
|
||||||
struct AQH_ENDPOINT_HTTP {
|
|
||||||
int readMode;
|
|
||||||
|
|
||||||
uint32_t flags;
|
|
||||||
|
|
||||||
GWEN_MSG_ENDPOINT_ADDSOCKETS_FN addSocketsFn;
|
|
||||||
GWEN_MSG_ENDPOINT_CHECKSOCKETS_FN checkSocketsFn;
|
|
||||||
|
|
||||||
GWEN_BUFFER *currentReadBuffer;
|
|
||||||
GWEN_DB_NODE *dbCurrentReadCommand;
|
|
||||||
GWEN_DB_NODE *dbCurrentReadHeader;
|
|
||||||
int currentHeaderPos;
|
|
||||||
int currentBodyPos;
|
|
||||||
int currentBodySize;
|
|
||||||
int remainingBodySize;
|
|
||||||
int lastLineStartPos;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
@@ -1,730 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
* 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
|
|
||||||
|
|
||||||
//#define DISABLE_DEBUGLOG
|
|
||||||
|
|
||||||
|
|
||||||
#include "./httprequest_p.h"
|
|
||||||
|
|
||||||
#include <gwenhywfar/debug.h>
|
|
||||||
#include <gwenhywfar/text.h>
|
|
||||||
|
|
||||||
#include <ctype.h>
|
|
||||||
|
|
||||||
|
|
||||||
GWEN_TREE2_FUNCTIONS(AQH_HTTP_REQUEST, AQH_HttpRequest);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------------------------------
|
|
||||||
* forward declarations
|
|
||||||
* ------------------------------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
static int _getParsedDbInfo(AQH_HTTP_REQUEST *rq, const GWEN_MSG *msg);
|
|
||||||
static int _inspectReceivedMessage(AQH_HTTP_REQUEST *rq, const GWEN_MSG *msg);
|
|
||||||
static int _inspectMsgCommand(AQH_HTTP_REQUEST *rq, const GWEN_MSG *msg);
|
|
||||||
static void _inspectMsgHeader(AQH_HTTP_REQUEST *rq, const GWEN_MSG *msg);
|
|
||||||
static int _inspectMsgBody(AQH_HTTP_REQUEST *rq, const GWEN_MSG *msg);
|
|
||||||
static GWEN_DB_NODE *_extractCookies(GWEN_DB_NODE *dbHeader);
|
|
||||||
static void _setCookieValue(GWEN_DB_NODE *dbCookies,
|
|
||||||
const char *nameStart, int nameLen,
|
|
||||||
const char *valueStart, int valueLen,
|
|
||||||
uint32_t dbFlags);
|
|
||||||
static int _parsePostBody(const char *s, int contentLength, GWEN_DB_NODE *dbBody);
|
|
||||||
static int _unescapeUrlEncoded(const char *src, unsigned int srclen, char *buffer, unsigned int maxsize);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------------------------------
|
|
||||||
* implementations
|
|
||||||
* ------------------------------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
AQH_HTTP_REQUEST *AQH_HttpRequest_new(GWEN_MSG_ENDPOINT *endpoint, const GWEN_MSG *receivedMsg)
|
|
||||||
{
|
|
||||||
AQH_HTTP_REQUEST *rq;
|
|
||||||
int rv;
|
|
||||||
|
|
||||||
GWEN_NEW_OBJECT(AQH_HTTP_REQUEST, rq);
|
|
||||||
GWEN_TREE2_INIT(AQH_HTTP_REQUEST, rq, AQH_HttpRequest);
|
|
||||||
|
|
||||||
rq->endpoint=endpoint;
|
|
||||||
rq->receivedMsg=receivedMsg;
|
|
||||||
|
|
||||||
rv=_inspectReceivedMessage(rq, receivedMsg);
|
|
||||||
if (rv<0) {
|
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "here (%d)", rv);
|
|
||||||
AQH_HttpRequest_free(rq);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
return rq;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_HttpRequest_free(AQH_HTTP_REQUEST *rq)
|
|
||||||
{
|
|
||||||
if (rq) {
|
|
||||||
GWEN_TREE2_FINI(AQH_HTTP_REQUEST, rq, AQH_HttpRequest);
|
|
||||||
free(rq->sessionId);
|
|
||||||
free(rq->moduleName);
|
|
||||||
free(rq->responseText);
|
|
||||||
GWEN_Msg_free(rq->responseMsg);
|
|
||||||
GWEN_StringList_free(rq->urlPathMembers);
|
|
||||||
GWEN_Url_free(rq->url);
|
|
||||||
GWEN_DB_Group_free(rq->dbPostBody);
|
|
||||||
|
|
||||||
GWEN_FREE_OBJECT(rq);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
GWEN_MSG_ENDPOINT *AQH_HttpRequest_GetEndpoint(const AQH_HTTP_REQUEST *rq)
|
|
||||||
{
|
|
||||||
return rq?(rq->endpoint):NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const GWEN_MSG *AQH_HttpRequest_GetReceivedMsg(const AQH_HTTP_REQUEST *rq)
|
|
||||||
{
|
|
||||||
return rq?(rq->receivedMsg):NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const char *AQH_HttpRequest_GetCommand(const AQH_HTTP_REQUEST *rq)
|
|
||||||
{
|
|
||||||
return rq?(rq->command):NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const char *AQH_HttpRequest_GetProtocol(const AQH_HTTP_REQUEST *rq)
|
|
||||||
{
|
|
||||||
return rq?(rq->protocol):NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
GWEN_URL *AQH_HttpRequest_GetUrl(const AQH_HTTP_REQUEST *rq)
|
|
||||||
{
|
|
||||||
return rq?(rq->url):NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_HttpRequest_SetUrl(AQH_HTTP_REQUEST *rq, GWEN_URL *url)
|
|
||||||
{
|
|
||||||
if (rq) {
|
|
||||||
GWEN_Url_free(rq->url);
|
|
||||||
rq->url=url;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const char *AQH_HttpRequest_GetUrlPath(const AQH_HTTP_REQUEST *rq)
|
|
||||||
{
|
|
||||||
return rq?(rq->urlPath):NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
GWEN_STRINGLIST *AQH_HttpRequest_GetUrlPathMembers(const AQH_HTTP_REQUEST *rq)
|
|
||||||
{
|
|
||||||
return rq?(rq->urlPathMembers):NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_HttpRequest_SetUrlPathMembers(AQH_HTTP_REQUEST *rq, GWEN_STRINGLIST *sl)
|
|
||||||
{
|
|
||||||
if (rq) {
|
|
||||||
GWEN_StringList_free(rq->urlPathMembers);
|
|
||||||
rq->urlPathMembers=sl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
GWEN_DB_NODE *AQH_HttpRequest_GetDbCommand(const AQH_HTTP_REQUEST *rq)
|
|
||||||
{
|
|
||||||
return rq?(rq->dbCommand):NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
GWEN_DB_NODE *AQH_HttpRequest_GetDbHeader(const AQH_HTTP_REQUEST *rq)
|
|
||||||
{
|
|
||||||
return rq?(rq->dbHeader):NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
GWEN_DB_NODE *AQH_HttpRequest_GetDbCookies(const AQH_HTTP_REQUEST *rq)
|
|
||||||
{
|
|
||||||
return rq?(rq->dbCookies):NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
GWEN_DB_NODE *AQH_HttpRequest_GetDbPostBody(const AQH_HTTP_REQUEST *rq)
|
|
||||||
{
|
|
||||||
return rq?(rq->dbPostBody):NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const char *AQH_HttpRequest_GetSessionId(const AQH_HTTP_REQUEST *rq)
|
|
||||||
{
|
|
||||||
return rq?(rq->sessionId):NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_HttpRequest_SetSessionId(AQH_HTTP_REQUEST *rq, const char *s)
|
|
||||||
{
|
|
||||||
if (rq) {
|
|
||||||
free(rq->sessionId);
|
|
||||||
rq->sessionId=s?strdup(s):NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const char *AQH_HttpRequest_GetModuleName(const AQH_HTTP_REQUEST *rq)
|
|
||||||
{
|
|
||||||
return rq?(rq->moduleName):NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_HttpRequest_SetModuleName(AQH_HTTP_REQUEST *rq, const char *s)
|
|
||||||
{
|
|
||||||
if (rq) {
|
|
||||||
free(rq->moduleName);
|
|
||||||
rq->moduleName=s?strdup(s):NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
AQH_SESSION *AQH_HttpRequest_GetSession(const AQH_HTTP_REQUEST *rq)
|
|
||||||
{
|
|
||||||
return rq?(rq->session):NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_HttpRequest_SetSession(AQH_HTTP_REQUEST *rq, AQH_SESSION *session)
|
|
||||||
{
|
|
||||||
if (rq)
|
|
||||||
rq->session=session;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
AQH_MODULE *AQH_HttpRequest_GetModule(const AQH_HTTP_REQUEST *rq)
|
|
||||||
{
|
|
||||||
return rq?(rq->module):NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_HttpRequest_SetModule(AQH_HTTP_REQUEST *rq, AQH_MODULE *m)
|
|
||||||
{
|
|
||||||
if (rq)
|
|
||||||
rq->module=m;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint32_t AQH_HttpRequest_GetModulePerms(const AQH_HTTP_REQUEST *rq)
|
|
||||||
{
|
|
||||||
return rq?(rq->modulePerms):0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_HttpRequest_SetModulePerms(AQH_HTTP_REQUEST *rq, uint32_t i)
|
|
||||||
{
|
|
||||||
if (rq)
|
|
||||||
rq->modulePerms=i;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int AQH_HttpRequest_GetResponseCode(const AQH_HTTP_REQUEST *rq)
|
|
||||||
{
|
|
||||||
return rq?(rq->responseCode):0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_HttpRequest_SetResponseCode(AQH_HTTP_REQUEST *rq, int i)
|
|
||||||
{
|
|
||||||
if (rq)
|
|
||||||
rq->responseCode=i;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const char *AQH_HttpRequest_GetResponseText(const AQH_HTTP_REQUEST *rq)
|
|
||||||
{
|
|
||||||
return rq?(rq->responseText):NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_HttpRequest_SetResponseText(AQH_HTTP_REQUEST *rq, const char *s)
|
|
||||||
{
|
|
||||||
if (rq) {
|
|
||||||
free(rq->responseText);
|
|
||||||
rq->responseText=s?strdup(s):NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
GWEN_MSG *AQH_HttpRequest_GetResponseMsg(const AQH_HTTP_REQUEST *rq)
|
|
||||||
{
|
|
||||||
return rq?(rq->responseMsg):NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
GWEN_MSG *AQH_HttpRequest_TakeResponseMsg(AQH_HTTP_REQUEST *rq)
|
|
||||||
{
|
|
||||||
if (rq) {
|
|
||||||
GWEN_MSG *msg;
|
|
||||||
|
|
||||||
msg=rq->responseMsg;
|
|
||||||
rq->responseMsg=NULL;
|
|
||||||
return msg;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_HttpRequest_SetResponseMsg(AQH_HTTP_REQUEST *rq, GWEN_MSG *msg)
|
|
||||||
{
|
|
||||||
if (rq && msg) {
|
|
||||||
GWEN_Msg_free(rq->responseMsg);
|
|
||||||
rq->responseMsg=msg;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_HttpRequest_SetupUrlPathMembers(AQH_HTTP_REQUEST *rq)
|
|
||||||
{
|
|
||||||
const char *path;
|
|
||||||
|
|
||||||
path=AQH_HttpRequest_GetUrlPath(rq);
|
|
||||||
if (path && *path) {
|
|
||||||
GWEN_STRINGLIST *sl;
|
|
||||||
|
|
||||||
if (*path=='/') /* skip leading slash */
|
|
||||||
path++;
|
|
||||||
sl=GWEN_StringList_fromString(path, "/", 0);
|
|
||||||
if (sl==NULL) {
|
|
||||||
DBG_ERROR(NULL, "Empty url path member list");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
AQH_HttpRequest_SetUrlPathMembers(rq, sl);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int _inspectReceivedMessage(AQH_HTTP_REQUEST *rq, const GWEN_MSG *msg)
|
|
||||||
{
|
|
||||||
int rv;
|
|
||||||
|
|
||||||
rv=_getParsedDbInfo(rq, msg);
|
|
||||||
if (rv<0) {
|
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "here (%d)", rv);
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
rv=_inspectMsgCommand(rq, msg);
|
|
||||||
if (rv<0) {
|
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "here (%d)", rv);
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
_inspectMsgHeader(rq, msg);
|
|
||||||
|
|
||||||
rv=_inspectMsgBody(rq, msg);
|
|
||||||
if (rv<0) {
|
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "here (%d)", rv);
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int _getParsedDbInfo(AQH_HTTP_REQUEST *rq, const GWEN_MSG *msg)
|
|
||||||
{
|
|
||||||
GWEN_DB_NODE *dbParsedInfo;
|
|
||||||
GWEN_DB_NODE *db;
|
|
||||||
|
|
||||||
dbParsedInfo=GWEN_Msg_GetDbParsedInfo(msg);
|
|
||||||
if (dbParsedInfo==NULL) {
|
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "No parsed info db, msg probably not generated by HTTP endpoint module");
|
|
||||||
return GWEN_ERROR_GENERIC;
|
|
||||||
}
|
|
||||||
|
|
||||||
db=GWEN_DB_GetGroup(dbParsedInfo, GWEN_PATH_FLAGS_PATHMUSTEXIST, "command");
|
|
||||||
if (db==NULL) {
|
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "No parsed command db, msg probably not generated by HTTP endpoint module");
|
|
||||||
return GWEN_ERROR_GENERIC;
|
|
||||||
}
|
|
||||||
rq->dbCommand=db;
|
|
||||||
|
|
||||||
db=GWEN_DB_GetGroup(dbParsedInfo, GWEN_PATH_FLAGS_PATHMUSTEXIST, "header");
|
|
||||||
if (db==NULL) {
|
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "No parsed header db, msg probably not generated by HTTP endpoint module or no header recvd, ignoring");
|
|
||||||
}
|
|
||||||
rq->dbHeader=db;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int _inspectMsgCommand(AQH_HTTP_REQUEST *rq, const GWEN_MSG *msg)
|
|
||||||
{
|
|
||||||
const char *s;
|
|
||||||
|
|
||||||
s=GWEN_DB_GetCharValue(rq->dbCommand, "command", 0, NULL);
|
|
||||||
if (!(s && *s)) {
|
|
||||||
DBG_ERROR(AQH_LOGDOMAIN, "No command in request");
|
|
||||||
return GWEN_ERROR_GENERIC;
|
|
||||||
}
|
|
||||||
rq->command=s;
|
|
||||||
|
|
||||||
s=GWEN_DB_GetCharValue(rq->dbCommand, "protocol", 0, NULL);
|
|
||||||
if (!(s && *s)) {
|
|
||||||
DBG_ERROR(AQH_LOGDOMAIN, "No protocol in request");
|
|
||||||
return GWEN_ERROR_GENERIC;
|
|
||||||
}
|
|
||||||
rq->protocol=s;
|
|
||||||
|
|
||||||
s=GWEN_DB_GetCharValue(rq->dbCommand, "url", 0, NULL);
|
|
||||||
if (!(s && *s)) {
|
|
||||||
DBG_ERROR(AQH_LOGDOMAIN, "No url in request");
|
|
||||||
return GWEN_ERROR_GENERIC;
|
|
||||||
}
|
|
||||||
|
|
||||||
rq->url=GWEN_Url_fromCommandString(s);
|
|
||||||
if (rq->url==NULL) {
|
|
||||||
DBG_ERROR(AQH_LOGDOMAIN, "Invalid URL [%s]", s);
|
|
||||||
return GWEN_ERROR_GENERIC;
|
|
||||||
}
|
|
||||||
|
|
||||||
s=GWEN_Url_GetPath(rq->url);
|
|
||||||
if (!(s && *s)) {
|
|
||||||
DBG_ERROR(AQH_LOGDOMAIN, "Empty url in request, assuming \"/\"");
|
|
||||||
s="/";
|
|
||||||
}
|
|
||||||
rq->urlPath=s;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void _inspectMsgHeader(AQH_HTTP_REQUEST *rq, const GWEN_MSG *msg)
|
|
||||||
{
|
|
||||||
if (rq->dbHeader)
|
|
||||||
rq->dbCookies=_extractCookies(rq->dbHeader);
|
|
||||||
if (rq->dbCookies) {
|
|
||||||
const char *s;
|
|
||||||
|
|
||||||
s=GWEN_DB_GetCharValue(rq->dbCookies, AQH_HTTP_REQUEST_SESSIONCOOKIE, 0, NULL);
|
|
||||||
if (s && *s) {
|
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "Sessionid: %s", s);
|
|
||||||
AQH_HttpRequest_SetSessionId(rq, s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int _inspectMsgBody(AQH_HTTP_REQUEST *rq, const GWEN_MSG *msg)
|
|
||||||
{
|
|
||||||
int rv;
|
|
||||||
|
|
||||||
rq->recvdBodySize=GWEN_Msg_GetParsedPayloadSize(msg);
|
|
||||||
if (rq->recvdBodySize>0)
|
|
||||||
rq->recvdBodyPtr=GWEN_Msg_GetConstBuffer(msg)+GWEN_Msg_GetParsedPayloadOffset(msg);
|
|
||||||
|
|
||||||
if (rq->dbHeader && rq->recvdBodySize>0 && strcasecmp(rq->command, "POST")==0) {
|
|
||||||
const char *s;
|
|
||||||
|
|
||||||
/* check whether we need to parse POST body */
|
|
||||||
s=GWEN_DB_GetCharValue(rq->dbHeader, "content-type", 0, NULL);
|
|
||||||
if (s && strcasecmp(s, "application/x-www-form-urlencoded")==0) {
|
|
||||||
rq->dbPostBody=GWEN_DB_Group_new("post");
|
|
||||||
rv=_parsePostBody((const char*) (rq->recvdBodyPtr), rq->recvdBodySize, rq->dbPostBody);
|
|
||||||
if (rv<0) {
|
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "here (%d)", rv);
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
GWEN_DB_NODE *_extractCookies(GWEN_DB_NODE *dbHeader)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
GWEN_DB_NODE *dbCookies;
|
|
||||||
|
|
||||||
dbCookies=GWEN_DB_GetGroup(dbHeader, 0, "cookies");
|
|
||||||
for (i=0; ; i++) {
|
|
||||||
const char *sCookie;
|
|
||||||
|
|
||||||
sCookie=GWEN_DB_GetCharValue(dbHeader, "Cookie", i, NULL);
|
|
||||||
if (sCookie && *sCookie) {
|
|
||||||
const char *s;
|
|
||||||
|
|
||||||
s=sCookie;
|
|
||||||
while(*s) {
|
|
||||||
while(*s && *s<33)
|
|
||||||
s++;
|
|
||||||
|
|
||||||
if (*s) {
|
|
||||||
const char *nameStart;
|
|
||||||
int nameLen;
|
|
||||||
|
|
||||||
nameStart=s++;
|
|
||||||
while(*s && *s!='=')
|
|
||||||
s++;
|
|
||||||
if (*s=='=') {
|
|
||||||
nameLen=s-nameStart;
|
|
||||||
s++;
|
|
||||||
while(*s && *s<33)
|
|
||||||
s++;
|
|
||||||
if (*s) {
|
|
||||||
const char *valueStart;
|
|
||||||
int valueLen;
|
|
||||||
|
|
||||||
valueStart=s;
|
|
||||||
while(*s && *s!=';')
|
|
||||||
s++;
|
|
||||||
valueLen=s-valueStart;
|
|
||||||
|
|
||||||
_setCookieValue(dbCookies, nameStart, nameLen, valueStart, valueLen, 0);
|
|
||||||
|
|
||||||
if (*s)
|
|
||||||
s++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} /* while(*s) */
|
|
||||||
} /* if (sCookie && *sCookie) */
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
} /* for */
|
|
||||||
return dbCookies;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void _setCookieValue(GWEN_DB_NODE *dbCookies, const char *nameStart, int nameLen, const char *valueStart, int valueLen, uint32_t dbFlags)
|
|
||||||
{
|
|
||||||
if (nameLen && valueLen) {
|
|
||||||
int i;
|
|
||||||
char *sName;
|
|
||||||
char *sValue;
|
|
||||||
|
|
||||||
for (i=nameLen-1; i>0; i--) {
|
|
||||||
if (nameStart[i]>32)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
sName=GWEN_Text_strndup(nameStart, i+1);
|
|
||||||
|
|
||||||
for (i=valueLen-1; i>0; i--) {
|
|
||||||
if (valueStart[i]>32)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
sValue=GWEN_Text_strndup(valueStart, i+1);
|
|
||||||
|
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "Received Cookie: [%s]=[%s]", sName, sValue);
|
|
||||||
GWEN_DB_SetCharValue(dbCookies, dbFlags, sName, sValue);
|
|
||||||
free(sValue);
|
|
||||||
free(sName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int _parsePostBody(const char *s, int contentLength, GWEN_DB_NODE *dbBody)
|
|
||||||
{
|
|
||||||
while(contentLength>0) {
|
|
||||||
const char *sNameStart;
|
|
||||||
int nameLen;
|
|
||||||
|
|
||||||
while((contentLength>0) && (*s<33)) {
|
|
||||||
contentLength--;
|
|
||||||
s++;
|
|
||||||
}
|
|
||||||
sNameStart=s;
|
|
||||||
while((contentLength>0) && (*s!='=') && (*s!='&')) {
|
|
||||||
contentLength--;
|
|
||||||
s++;
|
|
||||||
}
|
|
||||||
nameLen=s-sNameStart;
|
|
||||||
|
|
||||||
if ((contentLength>0) && (*s=='=')) {
|
|
||||||
const char *sValueStart;
|
|
||||||
int valueLen;
|
|
||||||
|
|
||||||
s++;
|
|
||||||
contentLength--;
|
|
||||||
while((contentLength>0) && (*s<33)) {
|
|
||||||
s++;
|
|
||||||
contentLength--;
|
|
||||||
}
|
|
||||||
sValueStart=s;
|
|
||||||
while((contentLength>0) && (*s!='&')) {
|
|
||||||
contentLength--;
|
|
||||||
s++;
|
|
||||||
}
|
|
||||||
valueLen=s-sValueStart;
|
|
||||||
|
|
||||||
if (nameLen && valueLen) {
|
|
||||||
char sNameBuf[32];
|
|
||||||
char sValueBuf[64];
|
|
||||||
|
|
||||||
if (_unescapeUrlEncoded(sNameStart, nameLen, sNameBuf, sizeof(sNameBuf))>=0 &&
|
|
||||||
_unescapeUrlEncoded(sValueStart, valueLen, sValueBuf, sizeof(sValueBuf))>=0)
|
|
||||||
GWEN_DB_SetCharValue(dbBody, 0, sNameBuf, sValueBuf);
|
|
||||||
else {
|
|
||||||
DBG_ERROR(NULL, "Either name or value invalid in body, aborting");
|
|
||||||
return GWEN_ERROR_BAD_DATA;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ((contentLength>0) && (*s=='&')) {
|
|
||||||
contentLength--;
|
|
||||||
s++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} /* while */
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int _unescapeUrlEncoded(const char *src, unsigned int srclen, char *buffer, unsigned int maxsize)
|
|
||||||
{
|
|
||||||
unsigned int size;
|
|
||||||
|
|
||||||
size=0;
|
|
||||||
|
|
||||||
while (srclen>0 && *src) {
|
|
||||||
unsigned char x;
|
|
||||||
|
|
||||||
x=(unsigned char)*src;
|
|
||||||
if (
|
|
||||||
(x>='A' && x<='Z') ||
|
|
||||||
(x>='a' && x<='z') ||
|
|
||||||
(x>='0' && x<='9') ||
|
|
||||||
x==' ' ||
|
|
||||||
x=='.' ||
|
|
||||||
x==',' ||
|
|
||||||
x=='.' ||
|
|
||||||
x=='*' ||
|
|
||||||
x=='?' ||
|
|
||||||
x=='+' ||
|
|
||||||
x=='-' ||
|
|
||||||
x=='_'
|
|
||||||
) {
|
|
||||||
if (size<(maxsize-1)) {
|
|
||||||
buffer[size++]=(x=='+')?' ':x;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
DBG_ERROR(GWEN_LOGDOMAIN, "Buffer too small");
|
|
||||||
return GWEN_ERROR_BUFFER_OVERFLOW;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (*src=='%') {
|
|
||||||
unsigned char d1, d2;
|
|
||||||
unsigned char c;
|
|
||||||
|
|
||||||
if (srclen<3) {
|
|
||||||
DBG_ERROR(GWEN_LOGDOMAIN, "Incomplete escape sequence (EOLN met)");
|
|
||||||
return GWEN_ERROR_BAD_DATA;
|
|
||||||
}
|
|
||||||
/* skip '%' */
|
|
||||||
src++;
|
|
||||||
if (!(*src) || !isxdigit((int)*src)) {
|
|
||||||
DBG_ERROR(GWEN_LOGDOMAIN, "Incomplete escape sequence (no digits)");
|
|
||||||
return GWEN_ERROR_BAD_DATA;
|
|
||||||
}
|
|
||||||
/* read first digit */
|
|
||||||
d1=(unsigned char)(toupper(*src));
|
|
||||||
|
|
||||||
/* get second digit */
|
|
||||||
src++;
|
|
||||||
if (!(*src) || !isxdigit((int)*src)) {
|
|
||||||
DBG_ERROR(GWEN_LOGDOMAIN, "Incomplete escape sequence (only 1 digit)");
|
|
||||||
return GWEN_ERROR_BAD_DATA;
|
|
||||||
}
|
|
||||||
d2=(unsigned char)(toupper(*src));
|
|
||||||
/* compute character */
|
|
||||||
d1-='0';
|
|
||||||
if (d1>9)
|
|
||||||
d1-=7;
|
|
||||||
c=(d1<<4)&0xf0;
|
|
||||||
d2-='0';
|
|
||||||
if (d2>9)
|
|
||||||
d2-=7;
|
|
||||||
c+=(d2&0xf);
|
|
||||||
/* store character */
|
|
||||||
if (size<(maxsize-1))
|
|
||||||
buffer[size++]=(char)c;
|
|
||||||
else {
|
|
||||||
DBG_ERROR(GWEN_LOGDOMAIN, "Buffer too small");
|
|
||||||
return GWEN_ERROR_BUFFER_OVERFLOW;
|
|
||||||
}
|
|
||||||
srclen-=2;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
DBG_ERROR(GWEN_LOGDOMAIN, "Found non-alphanum characters in escaped string (\"%s\")", src);
|
|
||||||
return GWEN_ERROR_BAD_DATA;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
srclen--;
|
|
||||||
src++;
|
|
||||||
} /* while */
|
|
||||||
|
|
||||||
buffer[size]=0;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,85 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
* 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 AQH_HTTP_REQUEST_H
|
|
||||||
#define AQH_HTTP_REQUEST_H
|
|
||||||
|
|
||||||
|
|
||||||
#include "aqhome/service/session.h"
|
|
||||||
#include "aqhome/service/module.h"
|
|
||||||
|
|
||||||
#include <gwenhywfar/tree2.h>
|
|
||||||
#include <gwenhywfar/endpoint.h>
|
|
||||||
#include <gwenhywfar/msg.h>
|
|
||||||
#include <gwenhywfar/url.h>
|
|
||||||
|
|
||||||
|
|
||||||
#define AQH_HTTP_REQUEST_SESSIONCOOKIE "sessionid"
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct AQH_HTTP_REQUEST AQH_HTTP_REQUEST;
|
|
||||||
GWEN_TREE2_FUNCTION_LIB_DEFS(AQH_HTTP_REQUEST, AQH_HttpRequest, AQHOME_API);
|
|
||||||
|
|
||||||
AQHOME_API AQH_HTTP_REQUEST *AQH_HttpRequest_new(GWEN_MSG_ENDPOINT *endpoint, const GWEN_MSG *receivedMsg);
|
|
||||||
AQHOME_API void AQH_HttpRequest_free(AQH_HTTP_REQUEST *rq);
|
|
||||||
|
|
||||||
AQHOME_API GWEN_MSG_ENDPOINT *AQH_HttpRequest_GetEndpoint(const AQH_HTTP_REQUEST *rq);
|
|
||||||
|
|
||||||
AQHOME_API const GWEN_MSG *AQH_HttpRequest_GetReceivedMsg(const AQH_HTTP_REQUEST *rq);
|
|
||||||
|
|
||||||
AQHOME_API const char *AQH_HttpRequest_GetCommand(const AQH_HTTP_REQUEST *rq);
|
|
||||||
|
|
||||||
AQHOME_API const char *AQH_HttpRequest_GetProtocol(const AQH_HTTP_REQUEST *rq);
|
|
||||||
|
|
||||||
AQHOME_API GWEN_URL *AQH_HttpRequest_GetUrl(const AQH_HTTP_REQUEST *rq);
|
|
||||||
AQHOME_API void AQH_HttpRequest_SetUrl(AQH_HTTP_REQUEST *rq, GWEN_URL *url);
|
|
||||||
|
|
||||||
AQHOME_API const char *AQH_HttpRequest_GetUrlPath(const AQH_HTTP_REQUEST *rq);
|
|
||||||
|
|
||||||
AQHOME_API GWEN_STRINGLIST *AQH_HttpRequest_GetUrlPathMembers(const AQH_HTTP_REQUEST *rq);
|
|
||||||
AQHOME_API void AQH_HttpRequest_SetUrlPathMembers(AQH_HTTP_REQUEST *rq, GWEN_STRINGLIST *sl);
|
|
||||||
|
|
||||||
AQHOME_API GWEN_DB_NODE *AQH_HttpRequest_GetDbCommand(const AQH_HTTP_REQUEST *rq);
|
|
||||||
AQHOME_API GWEN_DB_NODE *AQH_HttpRequest_GetDbHeader(const AQH_HTTP_REQUEST *rq);
|
|
||||||
AQHOME_API GWEN_DB_NODE *AQH_HttpRequest_GetDbCookies(const AQH_HTTP_REQUEST *rq);
|
|
||||||
AQHOME_API GWEN_DB_NODE *AQH_HttpRequest_GetDbPostBody(const AQH_HTTP_REQUEST *rq);
|
|
||||||
|
|
||||||
|
|
||||||
AQHOME_API const char *AQH_HttpRequest_GetSessionId(const AQH_HTTP_REQUEST *rq);
|
|
||||||
AQHOME_API void AQH_HttpRequest_SetSessionId(AQH_HTTP_REQUEST *rq, const char *s);
|
|
||||||
|
|
||||||
AQHOME_API const char *AQH_HttpRequest_GetModuleName(const AQH_HTTP_REQUEST *rq);
|
|
||||||
AQHOME_API void AQH_HttpRequest_SetModuleName(AQH_HTTP_REQUEST *rq, const char *s);
|
|
||||||
|
|
||||||
AQHOME_API AQH_SESSION *AQH_HttpRequest_GetSession(const AQH_HTTP_REQUEST *rq);
|
|
||||||
AQHOME_API void AQH_HttpRequest_SetSession(AQH_HTTP_REQUEST *rq, AQH_SESSION *session);
|
|
||||||
|
|
||||||
AQHOME_API AQH_MODULE *AQH_HttpRequest_GetModule(const AQH_HTTP_REQUEST *rq);
|
|
||||||
AQHOME_API void AQH_HttpRequest_SetModule(AQH_HTTP_REQUEST *rq, AQH_MODULE *m);
|
|
||||||
|
|
||||||
AQHOME_API uint32_t AQH_HttpRequest_GetModulePerms(const AQH_HTTP_REQUEST *rq);
|
|
||||||
AQHOME_API void AQH_HttpRequest_SetModulePerms(AQH_HTTP_REQUEST *rq, uint32_t i);
|
|
||||||
|
|
||||||
|
|
||||||
AQHOME_API int AQH_HttpRequest_GetResponseCode(const AQH_HTTP_REQUEST *rq);
|
|
||||||
AQHOME_API void AQH_HttpRequest_SetResponseCode(AQH_HTTP_REQUEST *rq, int i);
|
|
||||||
|
|
||||||
AQHOME_API const char *AQH_HttpRequest_GetResponseText(const AQH_HTTP_REQUEST *rq);
|
|
||||||
AQHOME_API void AQH_HttpRequest_SetResponseText(AQH_HTTP_REQUEST *rq, const char *s);
|
|
||||||
|
|
||||||
AQHOME_API GWEN_MSG *AQH_HttpRequest_GetResponseMsg(const AQH_HTTP_REQUEST *rq);
|
|
||||||
AQHOME_API GWEN_MSG *AQH_HttpRequest_TakeResponseMsg(AQH_HTTP_REQUEST *rq);
|
|
||||||
AQHOME_API void AQH_HttpRequest_SetResponseMsg(AQH_HTTP_REQUEST *rq, GWEN_MSG *msg);
|
|
||||||
|
|
||||||
AQHOME_API void AQH_HttpRequest_SetupUrlPathMembers(AQH_HTTP_REQUEST *rq);
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,62 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
* 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 AQH_HTTP_REQUEST_P_H
|
|
||||||
#define AQH_HTTP_REQUEST_P_H
|
|
||||||
|
|
||||||
|
|
||||||
#include "aqhome/http/httprequest.h"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct AQH_HTTP_REQUEST AQH_HTTP_REQUEST;
|
|
||||||
struct AQH_HTTP_REQUEST {
|
|
||||||
GWEN_TREE2_ELEMENT(AQH_HTTP_REQUEST)
|
|
||||||
|
|
||||||
GWEN_MSG_ENDPOINT *endpoint;
|
|
||||||
|
|
||||||
/* received stuff */
|
|
||||||
const GWEN_MSG *receivedMsg; /* don't free */
|
|
||||||
|
|
||||||
const char *command; /* don't free */
|
|
||||||
const char *protocol; /* don't free */
|
|
||||||
const char *urlPath; /* don't free */
|
|
||||||
GWEN_URL *url;
|
|
||||||
|
|
||||||
GWEN_STRINGLIST *urlPathMembers;
|
|
||||||
|
|
||||||
GWEN_DB_NODE *dbCommand; /* don't free */
|
|
||||||
GWEN_DB_NODE *dbHeader; /* don't free */
|
|
||||||
GWEN_DB_NODE *dbCookies; /* don't free */
|
|
||||||
|
|
||||||
uint32_t recvdBodySize;
|
|
||||||
const uint8_t *recvdBodyPtr;
|
|
||||||
|
|
||||||
/* derived stuff */
|
|
||||||
char *sessionId;
|
|
||||||
char *moduleName;
|
|
||||||
|
|
||||||
AQH_SESSION *session; /* don't free */
|
|
||||||
AQH_MODULE *module; /* don't free */
|
|
||||||
uint32_t modulePerms;
|
|
||||||
|
|
||||||
GWEN_DB_NODE *dbPostBody;
|
|
||||||
|
|
||||||
|
|
||||||
/* response stuff */
|
|
||||||
int responseCode;
|
|
||||||
char *responseText;
|
|
||||||
GWEN_MSG *responseMsg;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,259 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
* 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
|
|
||||||
|
|
||||||
//#define DISABLE_DEBUGLOG
|
|
||||||
|
|
||||||
|
|
||||||
#include "aqhome/http/httpservice_p.h"
|
|
||||||
|
|
||||||
#include <gwenhywfar/db.h>
|
|
||||||
#include <gwenhywfar/buffer.h>
|
|
||||||
#include <gwenhywfar/text.h>
|
|
||||||
#include <gwenhywfar/debug.h>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
GWEN_INHERIT(AQH_SERVICE, AQH_HTTP_SERVICE)
|
|
||||||
|
|
||||||
|
|
||||||
static void GWENHYWFAR_CB _freeData(void *bp, void *p);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
AQH_SERVICE *AQH_HttpService_new(const char *configFolder, const char *sourceFolder)
|
|
||||||
{
|
|
||||||
AQH_SERVICE *sv;
|
|
||||||
|
|
||||||
sv=AQH_Service_new();
|
|
||||||
AQH_HttpService_Extend(sv, configFolder, sourceFolder);
|
|
||||||
|
|
||||||
return sv;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_HttpService_Extend(AQH_SERVICE *sv, const char *configFolder, const char *sourceFolder)
|
|
||||||
{
|
|
||||||
AQH_HTTP_SERVICE *xsv;
|
|
||||||
|
|
||||||
GWEN_NEW_OBJECT(AQH_HTTP_SERVICE, xsv);
|
|
||||||
GWEN_INHERIT_SETDATA(AQH_SERVICE, AQH_HTTP_SERVICE, sv, xsv, _freeData);
|
|
||||||
|
|
||||||
AQH_HttpService_SetConfigFolder(sv, configFolder);
|
|
||||||
AQH_HttpService_SetSourceFolder(sv, sourceFolder);
|
|
||||||
|
|
||||||
xsv->moduleMutex=GWEN_Mutex_new();
|
|
||||||
xsv->userMutex=GWEN_Mutex_new();
|
|
||||||
xsv->sessionMutex=GWEN_Mutex_new();
|
|
||||||
|
|
||||||
xsv->urlHandlerList=AQH_HttpUrlHandler_List_new(sv);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void _freeData(void *bp, void *p)
|
|
||||||
{
|
|
||||||
AQH_HTTP_SERVICE *xsv;
|
|
||||||
|
|
||||||
xsv=(AQH_HTTP_SERVICE*) p;
|
|
||||||
|
|
||||||
AQH_HttpUrlHandler_List_free(xsv->urlHandlerList);
|
|
||||||
|
|
||||||
GWEN_Mutex_free(xsv->moduleMutex);
|
|
||||||
GWEN_Mutex_free(xsv->userMutex);
|
|
||||||
GWEN_Mutex_free(xsv->sessionMutex);
|
|
||||||
|
|
||||||
free(xsv->configFolder);
|
|
||||||
free(xsv->sourceFolder);
|
|
||||||
free(xsv->siteHeader);
|
|
||||||
free(xsv->siteFooter);
|
|
||||||
GWEN_FREE_OBJECT(xsv);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const char *AQH_HttpService_GetConfigFolder(const AQH_SERVICE *sv)
|
|
||||||
{
|
|
||||||
if (sv) {
|
|
||||||
AQH_HTTP_SERVICE *xsv;
|
|
||||||
|
|
||||||
xsv=GWEN_INHERIT_GETDATA(AQH_SERVICE, AQH_HTTP_SERVICE, sv);
|
|
||||||
if (xsv)
|
|
||||||
return xsv->configFolder;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_HttpService_SetConfigFolder(AQH_SERVICE *sv, const char *s)
|
|
||||||
{
|
|
||||||
if (sv) {
|
|
||||||
AQH_HTTP_SERVICE *xsv;
|
|
||||||
|
|
||||||
xsv=GWEN_INHERIT_GETDATA(AQH_SERVICE, AQH_HTTP_SERVICE, sv);
|
|
||||||
if (xsv) {
|
|
||||||
free(xsv->configFolder);
|
|
||||||
xsv->configFolder=s?strdup(s):NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const char *AQH_HttpService_GetSourceFolder(const AQH_SERVICE *sv)
|
|
||||||
{
|
|
||||||
if (sv) {
|
|
||||||
AQH_HTTP_SERVICE *xsv;
|
|
||||||
|
|
||||||
xsv=GWEN_INHERIT_GETDATA(AQH_SERVICE, AQH_HTTP_SERVICE, sv);
|
|
||||||
if (xsv)
|
|
||||||
return xsv->sourceFolder;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_HttpService_SetSourceFolder(AQH_SERVICE *sv, const char *s)
|
|
||||||
{
|
|
||||||
if (sv) {
|
|
||||||
AQH_HTTP_SERVICE *xsv;
|
|
||||||
|
|
||||||
xsv=GWEN_INHERIT_GETDATA(AQH_SERVICE, AQH_HTTP_SERVICE, sv);
|
|
||||||
if (xsv) {
|
|
||||||
free(xsv->sourceFolder);
|
|
||||||
xsv->sourceFolder=s?strdup(s):NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint32_t AQH_HttpService_GetNextModuleId(AQH_SERVICE *sv)
|
|
||||||
{
|
|
||||||
if (sv) {
|
|
||||||
AQH_HTTP_SERVICE *xsv;
|
|
||||||
|
|
||||||
xsv=GWEN_INHERIT_GETDATA(AQH_SERVICE, AQH_HTTP_SERVICE, sv);
|
|
||||||
if (xsv) {
|
|
||||||
return ++(xsv->lastModuleId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint32_t AQH_HttpService_GetNextUserId(AQH_SERVICE *sv)
|
|
||||||
{
|
|
||||||
if (sv) {
|
|
||||||
AQH_HTTP_SERVICE *xsv;
|
|
||||||
|
|
||||||
xsv=GWEN_INHERIT_GETDATA(AQH_SERVICE, AQH_HTTP_SERVICE, sv);
|
|
||||||
if (xsv) {
|
|
||||||
return ++(xsv->lastUserId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int AQH_HttpService_GetMaxSessionAgeInSecs(const AQH_SERVICE *sv)
|
|
||||||
{
|
|
||||||
if (sv) {
|
|
||||||
AQH_HTTP_SERVICE *xsv;
|
|
||||||
|
|
||||||
xsv=GWEN_INHERIT_GETDATA(AQH_SERVICE, AQH_HTTP_SERVICE, sv);
|
|
||||||
if (xsv) {
|
|
||||||
return xsv->maxSessionAgeInSecs;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_HttpService_SetMaxSessionAgeInSecs(AQH_SERVICE *sv, int i)
|
|
||||||
{
|
|
||||||
if (sv) {
|
|
||||||
AQH_HTTP_SERVICE *xsv;
|
|
||||||
|
|
||||||
xsv=GWEN_INHERIT_GETDATA(AQH_SERVICE, AQH_HTTP_SERVICE, sv);
|
|
||||||
if (xsv)
|
|
||||||
xsv->maxSessionAgeInSecs=i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const char *AQH_HttpService_GetSiteHeader(const AQH_SERVICE *sv)
|
|
||||||
{
|
|
||||||
if (sv) {
|
|
||||||
AQH_HTTP_SERVICE *xsv;
|
|
||||||
|
|
||||||
xsv=GWEN_INHERIT_GETDATA(AQH_SERVICE, AQH_HTTP_SERVICE, sv);
|
|
||||||
if (xsv)
|
|
||||||
return xsv->siteHeader;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_HttpService_SetSiteHeader(AQH_SERVICE *sv, const char *s)
|
|
||||||
{
|
|
||||||
if (sv) {
|
|
||||||
AQH_HTTP_SERVICE *xsv;
|
|
||||||
|
|
||||||
xsv=GWEN_INHERIT_GETDATA(AQH_SERVICE, AQH_HTTP_SERVICE, sv);
|
|
||||||
if (xsv) {
|
|
||||||
free(xsv->siteHeader);
|
|
||||||
xsv->siteHeader=s?strdup(s):NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const char *AQH_HttpService_GetSiteFooter(const AQH_SERVICE *sv)
|
|
||||||
{
|
|
||||||
if (sv) {
|
|
||||||
AQH_HTTP_SERVICE *xsv;
|
|
||||||
|
|
||||||
xsv=GWEN_INHERIT_GETDATA(AQH_SERVICE, AQH_HTTP_SERVICE, sv);
|
|
||||||
if (xsv)
|
|
||||||
return xsv->siteFooter;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_HttpService_SetSiteFooter(AQH_SERVICE *sv, const char *s)
|
|
||||||
{
|
|
||||||
if (sv) {
|
|
||||||
AQH_HTTP_SERVICE *xsv;
|
|
||||||
|
|
||||||
xsv=GWEN_INHERIT_GETDATA(AQH_SERVICE, AQH_HTTP_SERVICE, sv);
|
|
||||||
if (xsv) {
|
|
||||||
free(xsv->siteFooter);
|
|
||||||
xsv->siteFooter=s?strdup(s):NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,57 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
* 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 AQH_HTTP_SERVICE_H
|
|
||||||
#define AQH_HTTP_SERVICE_H
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include "aqhome/service/service.h"
|
|
||||||
|
|
||||||
#include "aqhome/http/httprequest.h"
|
|
||||||
#include "aqhome/http/urlhandler.h"
|
|
||||||
|
|
||||||
#include <gwenhywfar/msg.h>
|
|
||||||
#include <gwenhywfar/db.h>
|
|
||||||
#include <gwenhywfar/buffer.h>
|
|
||||||
#include <gwenhywfar/url.h>
|
|
||||||
#include <gwenhywfar/mutex.h>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
AQHOME_API AQH_SERVICE *AQH_HttpService_new(const char *configFolder, const char *sourceFolder);
|
|
||||||
AQHOME_API void AQH_HttpService_Extend(AQH_SERVICE *sv, const char *configFolder, const char *sourceFolder);
|
|
||||||
|
|
||||||
|
|
||||||
AQHOME_API const char *AQH_HttpService_GetConfigFolder(const AQH_SERVICE *sv);
|
|
||||||
AQHOME_API void AQH_HttpService_SetConfigFolder(AQH_SERVICE *sv, const char *s);
|
|
||||||
|
|
||||||
|
|
||||||
AQHOME_API const char *AQH_HttpService_GetSourceFolder(const AQH_SERVICE *sv);
|
|
||||||
AQHOME_API void AQH_HttpService_SetSourceFolder(AQH_SERVICE *sv, const char *s);
|
|
||||||
|
|
||||||
AQHOME_API const char *AQH_HttpService_GetSiteHeader(const AQH_SERVICE *sv);
|
|
||||||
AQHOME_API void AQH_HttpService_SetSiteHeader(AQH_SERVICE *sv, const char *s);
|
|
||||||
|
|
||||||
|
|
||||||
AQHOME_API const char *AQH_HttpService_GetSiteFooter(const AQH_SERVICE *sv);
|
|
||||||
AQHOME_API void AQH_HttpService_SetSiteFooter(AQH_SERVICE *sv, const char *s);
|
|
||||||
|
|
||||||
|
|
||||||
AQHOME_API uint32_t AQH_HttpService_GetNextModuleId(AQH_SERVICE *sv);
|
|
||||||
AQHOME_API uint32_t AQH_HttpService_GetNextUserId(AQH_SERVICE *sv);
|
|
||||||
|
|
||||||
AQHOME_API int AQH_HttpService_GetMaxSessionAgeInSecs(const AQH_SERVICE *sv);
|
|
||||||
AQHOME_API void AQH_HttpService_SetMaxSessionAgeInSecs(AQH_SERVICE *sv, int i);
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,60 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
* 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 AQH_HTTP_SERVICE_CONF_H
|
|
||||||
#define AQH_HTTP_SERVICE_CONF_H
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include "aqhome/service/service.h"
|
|
||||||
|
|
||||||
#include <gwenhywfar/db.h>
|
|
||||||
#include <gwenhywfar/buffer.h>
|
|
||||||
#include <gwenhywfar/msg.h>
|
|
||||||
#include <gwenhywfar/url.h>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define AQH_HTTP_SERVICE_ADMINUSER "admin"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
AQHOME_API int AQH_HttpService_LoadConfig(AQH_SERVICE *sv);
|
|
||||||
AQHOME_API int AQH_HttpService_SaveConfig(const AQH_SERVICE *sv);
|
|
||||||
|
|
||||||
AQHOME_API AQH_MODULE *AQH_HttpService_GetModule(AQH_SERVICE *sv, const char *modName);
|
|
||||||
AQHOME_API AQH_USER *AQH_HttpService_GetUser(AQH_SERVICE *sv, const char *alias);
|
|
||||||
AQHOME_API int AQH_HttpService_WriteUser(const AQH_SERVICE *sv, const AQH_USER *user);
|
|
||||||
|
|
||||||
AQHOME_API AQH_SESSION *AQH_HttpService_GetSession(AQH_SERVICE *sv, const char *sessionUid);
|
|
||||||
AQHOME_API int AQH_HttpService_LockSessions(AQH_SERVICE *sv);
|
|
||||||
AQHOME_API int AQH_HttpService_UnlockSessions(AQH_SERVICE *sv);
|
|
||||||
AQHOME_API int AQH_HttpService_CleanupSessions(AQH_SERVICE *sv, int maxAgeInSecs);
|
|
||||||
|
|
||||||
AQHOME_API AQH_MODULE *AQH_HttpService_LoadModule(const AQH_SERVICE *sv, const char *modName);
|
|
||||||
AQHOME_API int AQH_HttpService_SaveModule(const AQH_SERVICE *sv, const AQH_MODULE *m);
|
|
||||||
AQHOME_API int AQH_HttpService_AddModule(AQH_SERVICE *sv, AQH_MODULE *m);
|
|
||||||
|
|
||||||
AQHOME_API AQH_USER *AQH_HttpService_LoadUser(const AQH_SERVICE *sv, const char *userAlias);
|
|
||||||
AQHOME_API int AQH_HttpService_SaveUser(const AQH_SERVICE *sv, const AQH_USER *user);
|
|
||||||
AQHOME_API int AQH_HttpService_AddUser(AQH_SERVICE *sv, AQH_USER *user);
|
|
||||||
AQHOME_API int AQH_HttpService_DelUser(AQH_SERVICE *sv, AQH_USER *user);
|
|
||||||
|
|
||||||
AQHOME_API AQH_SESSION *AQH_HttpService_LoadSession(const AQH_SERVICE *sv, const char *sessionUid);
|
|
||||||
AQHOME_API int AQH_HttpService_SaveSession(const AQH_SERVICE *sv, const AQH_SESSION *session);
|
|
||||||
AQHOME_API int AQH_HttpService_AddSession(AQH_SERVICE *sv, AQH_SESSION *session);
|
|
||||||
AQHOME_API int AQH_HttpService_DelSession(AQH_SERVICE *sv, AQH_SESSION *session);
|
|
||||||
AQHOME_API void AQH_HttpService_LoadAllSessions(AQH_SERVICE *sv);
|
|
||||||
|
|
||||||
|
|
||||||
AQHOME_API GWEN_STRINGLIST *AQH_HttpService_GetFolderFileList(const char *folder, const char *mask, int senseCase);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,412 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
* 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
|
|
||||||
|
|
||||||
//#define DISABLE_DEBUGLOG
|
|
||||||
|
|
||||||
|
|
||||||
#include "aqhome/http/httpservice_http.h"
|
|
||||||
#include "aqhome/http/httpservice_conf.h"
|
|
||||||
#include "aqhome/http/httpservice_p.h"
|
|
||||||
#include "aqhome/http/urlhandler.h"
|
|
||||||
|
|
||||||
#include <gwenhywfar/db.h>
|
|
||||||
#include <gwenhywfar/buffer.h>
|
|
||||||
#include <gwenhywfar/text.h>
|
|
||||||
#include <gwenhywfar/debug.h>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef GWEN_INHERIT_REF
|
|
||||||
GWEN_INHERIT_REF(AQH_SERVICE, AQH_HTTP_SERVICE)
|
|
||||||
#else
|
|
||||||
extern uint32_t AQH_HTTP_SERVICE_ID;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------------------------------
|
|
||||||
* forward declarations
|
|
||||||
* ------------------------------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
static void _writeDefaultResponseHeaderToBuffer(AQH_SERVICE *sv, int contentLength, GWEN_BUFFER *buf);
|
|
||||||
static GWEN_BUFFER *_getPageFilePath(const AQH_SERVICE *sv, const char *langFolder, const char *fileName);
|
|
||||||
static AQH_HTTP_URLHANDLER *_findMatchingUrlHandler(AQH_SERVICE *sv, const char *path);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------------------------------
|
|
||||||
* implementations
|
|
||||||
* ------------------------------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
GWEN_MSG *AQH_HttpService_HandleHttpRequest(AQH_SERVICE *sv, GWEN_MSG_ENDPOINT *endpoint, const GWEN_MSG *msgReceived)
|
|
||||||
{
|
|
||||||
AQH_HTTP_SERVICE *xsv;
|
|
||||||
AQH_HTTP_REQUEST *rq;
|
|
||||||
const char *s;
|
|
||||||
const char *cmd;
|
|
||||||
const char *protocol;
|
|
||||||
AQH_SESSION *session=NULL;
|
|
||||||
GWEN_MSG *msgResponse;
|
|
||||||
int rv;
|
|
||||||
AQH_HTTP_URLHANDLER *uh;
|
|
||||||
|
|
||||||
xsv=GWEN_INHERIT_GETDATA(AQH_SERVICE, AQH_HTTP_SERVICE, sv);
|
|
||||||
if (xsv==NULL) {
|
|
||||||
DBG_ERROR(AQH_LOGDOMAIN, "Not a AQH_HttpService object");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
rq=AQH_HttpRequest_new(endpoint, msgReceived);
|
|
||||||
if (rq==NULL) {
|
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "Could not create valie request from incoming message");
|
|
||||||
return AQH_HttpService_CreateResponseMsg(sv, 500, "Internal server error", "HTTP/1.1", NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd=AQH_HttpRequest_GetCommand(rq);
|
|
||||||
protocol=AQH_HttpRequest_GetProtocol(rq);
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
s=AQH_HttpRequest_GetModuleName(rq);
|
|
||||||
if (s && *s) {
|
|
||||||
m=AQH_HttpService_GetModule(sv, s);
|
|
||||||
if (m==NULL) {
|
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "Module \"%s\" not found", s);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
AQH_HttpRequest_SetModule(rq, m);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
s=AQH_HttpRequest_GetSessionId(rq);
|
|
||||||
if (s && *s) {
|
|
||||||
session=AQH_HttpService_GetSession(sv, s);
|
|
||||||
if (session==NULL) {
|
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "Session \"%s\" not found", s);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
GWEN_TIMESTAMP *ts;
|
|
||||||
|
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "Found session \"%s\"", s);
|
|
||||||
ts=GWEN_Timestamp_NowInLocalTime();
|
|
||||||
AQH_Session_SetTimestampLastAccess(session, ts);
|
|
||||||
GWEN_Timestamp_free(ts);
|
|
||||||
AQH_Session_AddRuntimeFlags(session, AQH_SESSION_RTFLAGS_MODIFIED);
|
|
||||||
AQH_HttpRequest_SetSession(rq, session);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
s=AQH_HttpRequest_GetUrlPath(rq);
|
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "Received \"%s\" request for url \"%s\"", cmd?cmd:"<no cmd>", s);
|
|
||||||
uh=_findMatchingUrlHandler(sv, s);
|
|
||||||
if (uh==NULL) {
|
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "No matching handler found for url \"%s\"", s);
|
|
||||||
AQH_HttpRequest_free(rq);
|
|
||||||
return AQH_HttpService_CreateResponseMsg(sv, 404, "Not found", protocol?protocol:"http/1.1", NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
rv=AQH_HttpUrlHandler_HandleMessage(uh, rq);
|
|
||||||
if (rv<0) {
|
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "Error handling request");
|
|
||||||
AQH_HttpRequest_free(rq);
|
|
||||||
return AQH_HttpService_CreateResponseMsg(sv, 500, "Internal server error", protocol?protocol:"http/1.1", NULL);
|
|
||||||
}
|
|
||||||
msgResponse=AQH_HttpRequest_TakeResponseMsg(rq);
|
|
||||||
AQH_HttpRequest_free(rq);
|
|
||||||
return msgResponse;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_HttpService_AddUrlHandler(AQH_SERVICE *sv, AQH_HTTP_URLHANDLER *urlHandler)
|
|
||||||
{
|
|
||||||
AQH_HTTP_SERVICE *xsv;
|
|
||||||
|
|
||||||
xsv=GWEN_INHERIT_GETDATA(AQH_SERVICE, AQH_HTTP_SERVICE, sv);
|
|
||||||
if (xsv==NULL) {
|
|
||||||
DBG_ERROR(AQH_LOGDOMAIN, "Not a AQH_HttpService object");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
AQH_HttpUrlHandler_List_Add(urlHandler, xsv->urlHandlerList);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_HttpService_SetRequestPerms(AQH_SERVICE *sv, AQH_HTTP_REQUEST *rq)
|
|
||||||
{
|
|
||||||
AQH_MODULE *m;
|
|
||||||
AQH_SESSION *session;
|
|
||||||
|
|
||||||
AQH_HttpRequest_SetModulePerms(rq, 0);
|
|
||||||
m=AQH_HttpRequest_GetModule(rq);
|
|
||||||
session=AQH_HttpRequest_GetSession(rq);
|
|
||||||
if (m) {
|
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "Presetting module's guest perms");
|
|
||||||
AQH_HttpRequest_SetModulePerms(rq, AQH_Module_GetGuestPerms(m));
|
|
||||||
if (session) {
|
|
||||||
AQH_USER * user;
|
|
||||||
|
|
||||||
user=AQH_Session_GetUser(session);
|
|
||||||
if (user) {
|
|
||||||
AQH_MODULE_PERMS_LIST *permsList;
|
|
||||||
|
|
||||||
permsList=AQH_User_GetModulePermList(user);
|
|
||||||
if (permsList) {
|
|
||||||
AQH_MODULE_PERMS *userPerms;
|
|
||||||
|
|
||||||
userPerms=AQH_ModulePerms_List_GetByModuleId(AQH_User_GetModulePermList(user), AQH_Module_GetId(m));
|
|
||||||
if (userPerms) {
|
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "Using user perms for module");
|
|
||||||
AQH_HttpRequest_SetModulePerms(rq, AQH_ModulePerms_GetPerms(userPerms));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "No module perms list in user, using module's guest perms");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "Session but no user, SNH!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "No session, using module's guest perms");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "No module, no perms");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_HttpService_AddStatusLine(AQH_SERVICE *sv, int code, const char *msg, const char *proto, GWEN_BUFFER *buf)
|
|
||||||
{
|
|
||||||
GWEN_Buffer_AppendArgs(buf, "%s %03d %s \r\n", proto?proto:"HTTP/1.1", code, msg?msg:"");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_HttpService_AddHeader(AQH_SERVICE *sv, GWEN_DB_NODE *dbHeader, GWEN_BUFFER *buf)
|
|
||||||
{
|
|
||||||
GWEN_DB_NODE *dbVar;
|
|
||||||
|
|
||||||
dbVar=GWEN_DB_GetFirstVar(dbHeader);
|
|
||||||
while (dbVar) {
|
|
||||||
GWEN_DB_NODE *dbVal;
|
|
||||||
|
|
||||||
/* only handle first value */
|
|
||||||
dbVal=GWEN_DB_GetFirstValue(dbVar);
|
|
||||||
if (dbVal) {
|
|
||||||
const char *sVar;
|
|
||||||
|
|
||||||
sVar=GWEN_DB_VariableName(dbVar);
|
|
||||||
if (sVar && *sVar) {
|
|
||||||
GWEN_DB_NODE_TYPE vtype;
|
|
||||||
|
|
||||||
vtype=GWEN_DB_GetValueType(dbVal);
|
|
||||||
if (vtype==GWEN_DB_NodeType_ValueChar) {
|
|
||||||
const char *sValue;
|
|
||||||
|
|
||||||
sValue=GWEN_DB_GetCharValueFromNode(dbVal);
|
|
||||||
if (sValue)
|
|
||||||
GWEN_Buffer_AppendArgs(buf, "%s: %s\r\n", sVar, sValue);
|
|
||||||
} /* if char */
|
|
||||||
else if (vtype==GWEN_DB_NodeType_ValueInt) {
|
|
||||||
int i;
|
|
||||||
|
|
||||||
i=GWEN_DB_GetIntValueFromNode(dbVal);
|
|
||||||
if (i!=-1 || strcasecmp(sVar, "Content-Length")==0)
|
|
||||||
GWEN_Buffer_AppendArgs(buf, "%s: %d\r\n", sVar, i);
|
|
||||||
} /* if int */
|
|
||||||
else {
|
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "Variable type %d of var [%s] not supported, ignoring", vtype, sVar);
|
|
||||||
}
|
|
||||||
} /* if sVar */
|
|
||||||
}
|
|
||||||
dbVar=GWEN_DB_GetNextVar(dbVar);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* finalize header */
|
|
||||||
GWEN_Buffer_AppendString(buf, "\r\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
GWEN_MSG *AQH_HttpService_CreateResponseMsg(AQH_SERVICE *sv, int code, const char *text, const char *protocol, const char *page)
|
|
||||||
{
|
|
||||||
GWEN_BUFFER *buf;
|
|
||||||
GWEN_MSG *msg;
|
|
||||||
|
|
||||||
buf=GWEN_Buffer_new(0, 256, 0, 1);
|
|
||||||
AQH_HttpService_AddStatusLine(sv, code, text, protocol, buf);
|
|
||||||
_writeDefaultResponseHeaderToBuffer(sv, (page && *page)?strlen(page):0, buf);
|
|
||||||
|
|
||||||
if (page && *page)
|
|
||||||
GWEN_Buffer_AppendString(buf, page);
|
|
||||||
|
|
||||||
msg=GWEN_Msg_fromBytes((const uint8_t*)GWEN_Buffer_GetStart(buf), GWEN_Buffer_GetUsedBytes(buf));
|
|
||||||
GWEN_Buffer_free(buf);
|
|
||||||
return msg;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
GWEN_MSG *AQH_HttpService_CreateRedirectingResponseMsg(AQH_SERVICE *sv, const char *protocol, const char *newPage)
|
|
||||||
{
|
|
||||||
GWEN_BUFFER *buf;
|
|
||||||
GWEN_MSG *msg;
|
|
||||||
GWEN_DB_NODE *db;
|
|
||||||
|
|
||||||
buf=GWEN_Buffer_new(0, 256, 0, 1);
|
|
||||||
AQH_HttpService_AddStatusLine(sv, 303, "OK, redirecting to content", protocol, buf);
|
|
||||||
db=GWEN_DB_Group_new("header");
|
|
||||||
GWEN_DB_SetCharValue(db, GWEN_DB_FLAGS_OVERWRITE_VARS, "Connection", "Keep-Alive");
|
|
||||||
GWEN_DB_SetCharValue(db, GWEN_DB_FLAGS_OVERWRITE_VARS, "Content-Type", "text/html; charset=utf-8");
|
|
||||||
GWEN_DB_SetCharValue(db, GWEN_DB_FLAGS_OVERWRITE_VARS, "Location", newPage);
|
|
||||||
GWEN_DB_SetIntValue(db, GWEN_DB_FLAGS_OVERWRITE_VARS, "Content-Length", 0);
|
|
||||||
AQH_HttpService_AddHeader(sv, db, buf);
|
|
||||||
GWEN_DB_Group_free(db);
|
|
||||||
|
|
||||||
msg=GWEN_Msg_fromBytes((const uint8_t*)GWEN_Buffer_GetStart(buf), GWEN_Buffer_GetUsedBytes(buf));
|
|
||||||
GWEN_Buffer_free(buf);
|
|
||||||
return msg;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int AQH_HttpService_AddFile(AQH_SERVICE *sv, GWEN_UNUSED AQH_SESSION *session, const char *fname, GWEN_BUFFER *buf)
|
|
||||||
{
|
|
||||||
if (fname && *fname) {
|
|
||||||
int rv;
|
|
||||||
GWEN_BUFFER *nameBuf;
|
|
||||||
|
|
||||||
nameBuf=_getPageFilePath(sv, NULL, fname);
|
|
||||||
|
|
||||||
rv=GWEN_SyncIo_Helper_ReadFile(GWEN_Buffer_GetStart(nameBuf), buf);
|
|
||||||
if (rv<0) {
|
|
||||||
DBG_ERROR(AQH_LOGDOMAIN, "Error reading file \"%s\": %d", fname, rv);
|
|
||||||
GWEN_Buffer_free(nameBuf);
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
GWEN_Buffer_free(nameBuf);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_HttpService_SetupModuleAndPerms(AQH_SERVICE *sv, AQH_HTTP_REQUEST *rq, const char *modulName)
|
|
||||||
{
|
|
||||||
AQH_SESSION *session;
|
|
||||||
AQH_MODULE *m;
|
|
||||||
|
|
||||||
AQH_HttpRequest_SetModuleName(rq, modulName);
|
|
||||||
m=AQH_HttpService_GetModule(sv, modulName);
|
|
||||||
if (m==NULL) {
|
|
||||||
DBG_ERROR(NULL, "Module \"%s\" not found", modulName);
|
|
||||||
AQH_HttpRequest_SetModulePerms(rq, 0);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
AQH_HttpRequest_SetModule(rq, m);
|
|
||||||
}
|
|
||||||
|
|
||||||
session=AQH_HttpRequest_GetSession(rq);
|
|
||||||
if (session) {
|
|
||||||
AQH_USER *u;
|
|
||||||
|
|
||||||
u=AQH_Session_GetUser(session);
|
|
||||||
if (u) {
|
|
||||||
if (strcasecmp(AQH_User_GetAlias(u), AQH_HTTP_SERVICE_ADMINUSER)==0) {
|
|
||||||
DBG_ERROR(NULL, "special admin user, full access granted");
|
|
||||||
AQH_HttpRequest_SetModulePerms(rq, 0xffffffff);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
AQH_HttpService_SetRequestPerms(sv, rq);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
GWEN_BUFFER *_getPageFilePath(const AQH_SERVICE *sv, const char *langFolder, const char *fileName)
|
|
||||||
{
|
|
||||||
const char *sourceFolder;
|
|
||||||
|
|
||||||
sourceFolder=AQH_HttpService_GetSourceFolder(sv);
|
|
||||||
if (!(sourceFolder && *sourceFolder)) {
|
|
||||||
DBG_ERROR(AQH_LOGDOMAIN, "No source folder given");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
GWEN_BUFFER *nameBuf;
|
|
||||||
|
|
||||||
nameBuf=GWEN_Buffer_new(0, 256, 0, 1);
|
|
||||||
GWEN_Buffer_AppendString(nameBuf, sourceFolder);
|
|
||||||
GWEN_Buffer_AppendString(nameBuf, GWEN_DIR_SEPARATOR_S);
|
|
||||||
if (langFolder && *langFolder) {
|
|
||||||
GWEN_Buffer_AppendString(nameBuf, langFolder);
|
|
||||||
GWEN_Buffer_AppendString(nameBuf, GWEN_DIR_SEPARATOR_S);
|
|
||||||
}
|
|
||||||
GWEN_Text_EscapeToBufferTolerant(fileName, nameBuf);
|
|
||||||
return nameBuf;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void _writeDefaultResponseHeaderToBuffer(AQH_SERVICE *sv, int contentLength, GWEN_BUFFER *buf)
|
|
||||||
{
|
|
||||||
GWEN_DB_NODE *db;
|
|
||||||
|
|
||||||
db=GWEN_DB_Group_new("header");
|
|
||||||
GWEN_DB_SetCharValue(db, GWEN_DB_FLAGS_OVERWRITE_VARS, "Connection", "Keep-Alive");
|
|
||||||
GWEN_DB_SetCharValue(db, GWEN_DB_FLAGS_OVERWRITE_VARS, "Content-Type", "text/html; charset=utf-8");
|
|
||||||
GWEN_DB_SetIntValue(db, GWEN_DB_FLAGS_OVERWRITE_VARS, "Content-Length", contentLength);
|
|
||||||
|
|
||||||
AQH_HttpService_AddHeader(sv, db, buf);
|
|
||||||
GWEN_DB_Group_free(db);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
AQH_HTTP_URLHANDLER *_findMatchingUrlHandler(AQH_SERVICE *sv, const char *path)
|
|
||||||
{
|
|
||||||
AQH_HTTP_SERVICE *xsv;
|
|
||||||
AQH_HTTP_URLHANDLER *uh;
|
|
||||||
|
|
||||||
xsv=GWEN_INHERIT_GETDATA(AQH_SERVICE, AQH_HTTP_SERVICE, sv);
|
|
||||||
if (xsv==NULL) {
|
|
||||||
DBG_ERROR(AQH_LOGDOMAIN, "Not a AQH_HttpService object");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
uh=AQH_HttpUrlHandler_List_First(xsv->urlHandlerList);
|
|
||||||
while(uh) {
|
|
||||||
if (AQH_HttpUrlHandler_UrlMatches(uh, path)) {
|
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "Found matching url handler for \"%s\"", path);
|
|
||||||
return uh;
|
|
||||||
}
|
|
||||||
uh=AQH_HttpUrlHandler_List_Next(uh);
|
|
||||||
}
|
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "No matching url handler for \"%s\"", path);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,64 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
* 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 AQH_HTTP_SERVICE_HTTP_H
|
|
||||||
#define AQH_HTTP_SERVICE_HTTP_H
|
|
||||||
|
|
||||||
|
|
||||||
#include "aqhome/service/service.h"
|
|
||||||
#include "aqhome/http/httprequest.h"
|
|
||||||
#include "aqhome/http/urlhandler.h"
|
|
||||||
|
|
||||||
#include <gwenhywfar/endpoint.h>
|
|
||||||
#include <gwenhywfar/msg.h>
|
|
||||||
#include <gwenhywfar/url.h>
|
|
||||||
|
|
||||||
|
|
||||||
#define AQH_HTTP_SERVICE_SESSIONCOOKIE "sessionid"
|
|
||||||
|
|
||||||
|
|
||||||
AQHOME_API GWEN_MSG *AQH_HttpService_HandleHttpRequest(AQH_SERVICE *sv, GWEN_MSG_ENDPOINT *endpoint, const GWEN_MSG *msgReceived);
|
|
||||||
|
|
||||||
AQHOME_API void AQH_HttpService_AddUrlHandler(AQH_SERVICE *sv, AQH_HTTP_URLHANDLER *urlHandler);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set modulname in request, get and set matching module and determine the calling users permissions in regard
|
|
||||||
* to the selected module.
|
|
||||||
*/
|
|
||||||
AQHOME_API void AQH_HttpService_SetupModuleAndPerms(AQH_SERVICE *sv, AQH_HTTP_REQUEST *rq, const char *modulName);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set permissions for this request according to session, user and module.
|
|
||||||
*
|
|
||||||
* The members session and module must have been set before calling this function.
|
|
||||||
*/
|
|
||||||
AQHOME_API void AQH_HttpService_SetRequestPerms(AQH_SERVICE *sv, AQH_HTTP_REQUEST *rq);
|
|
||||||
|
|
||||||
|
|
||||||
AQHOME_API void AQH_HttpService_AddStatusLine(AQH_SERVICE *sv, int code, const char *msg, const char *proto, GWEN_BUFFER *buf);
|
|
||||||
AQHOME_API void AQH_HttpService_AddHeader(AQH_SERVICE *sv, GWEN_DB_NODE *dbHeader, GWEN_BUFFER *buf);
|
|
||||||
|
|
||||||
AQHOME_API int AQH_HttpService_ParsePostBody(AQH_SERVICE *sv, const GWEN_MSG *msgReceived, GWEN_DB_NODE *dbBody);
|
|
||||||
|
|
||||||
|
|
||||||
AQHOME_API GWEN_MSG *AQH_HttpService_CreateResponseMsg(AQH_SERVICE *sv,
|
|
||||||
int code, const char *text, const char *protocol,
|
|
||||||
const char *page);
|
|
||||||
|
|
||||||
AQHOME_API GWEN_MSG *AQH_HttpService_CreateRedirectingResponseMsg(AQH_SERVICE *sv, const char *protocol, const char *newPage);
|
|
||||||
|
|
||||||
|
|
||||||
AQHOME_API int AQH_HttpService_AddFile(AQH_SERVICE *sv, AQH_SESSION *session, const char *fname, GWEN_BUFFER *buf);
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
* 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 "aqhome/http/httpservice_login.h"
|
|
||||||
#include "aqhome/http/httpservice_p.h"
|
|
||||||
|
|
||||||
#include <gwenhywfar/db.h>
|
|
||||||
#include <gwenhywfar/buffer.h>
|
|
||||||
#include <gwenhywfar/text.h>
|
|
||||||
#include <gwenhywfar/debug.h>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
Login process:
|
|
||||||
- GET: send a login page
|
|
||||||
- POST:
|
|
||||||
- get USER and PASS
|
|
||||||
- look for user (maybe add virtual function to load a user?)
|
|
||||||
- check password
|
|
||||||
- if all okay:
|
|
||||||
- create session
|
|
||||||
- add header "set-cookie"
|
|
||||||
- redirect to main page
|
|
||||||
*/
|
|
||||||
|
|
||||||
GWEN_MSG *AQH_HttpService_HandleLoginUrl(AQH_SERVICE *sv, const GWEN_MSG *msgReceived, const GWEN_URL *url)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
* 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 AQH_HTTP_SERVICE_LOGIN_H
|
|
||||||
#define AQH_HTTP_SERVICE_LOGIN_H
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include "aqhome/http/httpservice.h"
|
|
||||||
|
|
||||||
#include <gwenhywfar/db.h>
|
|
||||||
#include <gwenhywfar/buffer.h>
|
|
||||||
#include <gwenhywfar/msg.h>
|
|
||||||
#include <gwenhywfar/url.h>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
AQHOME_API GWEN_MSG *AQH_HttpService_HandleLoginUrl(AQH_SERVICE *sv, const GWEN_MSG *msgReceived, const GWEN_URL *url);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
* 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 AQH_HTTP_SERVICE_P_H
|
|
||||||
#define AQH_HTTP_SERVICE_P_H
|
|
||||||
|
|
||||||
|
|
||||||
#include "aqhome/http/httpservice.h"
|
|
||||||
|
|
||||||
|
|
||||||
#define AQH_HTTP_SERVICE_DEFAULT_MAXSESSIONAGE 600 /* 10m */
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct AQH_HTTP_SERVICE AQH_HTTP_SERVICE;
|
|
||||||
struct AQH_HTTP_SERVICE {
|
|
||||||
char *sourceFolder;
|
|
||||||
char *configFolder;
|
|
||||||
|
|
||||||
char *siteHeader;
|
|
||||||
char *siteFooter;
|
|
||||||
|
|
||||||
uint32_t lastModuleId;
|
|
||||||
uint32_t lastUserId;
|
|
||||||
|
|
||||||
int maxSessionAgeInSecs;
|
|
||||||
|
|
||||||
GWEN_MUTEX *moduleMutex;
|
|
||||||
GWEN_MUTEX *userMutex;
|
|
||||||
GWEN_MUTEX *sessionMutex;
|
|
||||||
|
|
||||||
AQH_HTTP_URLHANDLER_LIST *urlHandlerList;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,261 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
* 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
|
|
||||||
|
|
||||||
//#define DISABLE_DEBUGLOG
|
|
||||||
|
|
||||||
|
|
||||||
#include "./urlhandler_p.h"
|
|
||||||
#include "aqhome/http/httpservice_http.h"
|
|
||||||
|
|
||||||
#include <gwenhywfar/debug.h>
|
|
||||||
#include <gwenhywfar/misc.h>
|
|
||||||
#include <gwenhywfar/text.h>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
GWEN_INHERIT_FUNCTIONS(AQH_HTTP_URLHANDLER)
|
|
||||||
GWEN_LIST_FUNCTIONS(AQH_HTTP_URLHANDLER, AQH_HttpUrlHandler)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static int _addContentHeaders(AQH_HTTP_CONTENT *c, int m, GWEN_BUFFER *dbuf);
|
|
||||||
static int _addContentFooters(AQH_HTTP_CONTENT *c, int m, GWEN_BUFFER *dbuf);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
AQH_HTTP_URLHANDLER *AQH_HttpUrlHandler_new(AQH_SERVICE *sv)
|
|
||||||
{
|
|
||||||
AQH_HTTP_URLHANDLER *uh;
|
|
||||||
|
|
||||||
GWEN_NEW_OBJECT(AQH_HTTP_URLHANDLER, uh);
|
|
||||||
GWEN_INHERIT_INIT(AQH_HTTP_URLHANDLER, uh);
|
|
||||||
GWEN_LIST_INIT(AQH_HTTP_URLHANDLER, uh);
|
|
||||||
uh->urlPatternList=GWEN_StringList_new();
|
|
||||||
uh->httpService=sv;
|
|
||||||
|
|
||||||
return uh;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_HttpUrlHandler_free(AQH_HTTP_URLHANDLER *uh)
|
|
||||||
{
|
|
||||||
if (uh) {
|
|
||||||
GWEN_LIST_FINI(AQH_HTTP_URLHANDLER, uh);
|
|
||||||
GWEN_INHERIT_FINI(AQH_HTTP_URLHANDLER, uh);
|
|
||||||
|
|
||||||
free(uh->folder);
|
|
||||||
GWEN_StringList_free(uh->urlPatternList);
|
|
||||||
GWEN_FREE_OBJECT(uh);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
AQH_SERVICE *AQH_HttpUrlHandler_GetHttpService(const AQH_HTTP_URLHANDLER *uh)
|
|
||||||
{
|
|
||||||
return uh?uh->httpService:NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
AQH_HTTP_CONTENT *AQH_HttpUrlHandler_GetContentProvider(const AQH_HTTP_URLHANDLER *uh)
|
|
||||||
{
|
|
||||||
return uh?uh->httpContentProvider:NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_HttpUrlHandler_SetContentProvider(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_CONTENT *cp)
|
|
||||||
{
|
|
||||||
if (uh)
|
|
||||||
uh->httpContentProvider=cp;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_HttpUrlHandler_AddUrlPattern(AQH_HTTP_URLHANDLER *uh, const char *s)
|
|
||||||
{
|
|
||||||
if (uh && s && *s)
|
|
||||||
GWEN_StringList_AppendString(uh->urlPatternList, s, 0, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const char *AQH_HttpUrlHandler_GetFolder(const AQH_HTTP_URLHANDLER *uh)
|
|
||||||
{
|
|
||||||
return uh?uh->folder:NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_HttpUrlHandler_SetFolder(AQH_HTTP_URLHANDLER *uh, const char *s)
|
|
||||||
{
|
|
||||||
if (uh) {
|
|
||||||
free(uh->folder);
|
|
||||||
uh->folder=s?strdup(s):NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int AQH_HttpUrlHandler_UrlMatches(const AQH_HTTP_URLHANDLER *uh, const char *s)
|
|
||||||
{
|
|
||||||
if (uh && s && *s) {
|
|
||||||
GWEN_STRINGLISTENTRY *se;
|
|
||||||
|
|
||||||
se=GWEN_StringList_FirstEntry(uh->urlPatternList);
|
|
||||||
while(se) {
|
|
||||||
const char *pattern;
|
|
||||||
|
|
||||||
pattern=GWEN_StringListEntry_Data(se);
|
|
||||||
if (GWEN_Text_ComparePattern(s, pattern, 0)!=-1)
|
|
||||||
return 1;
|
|
||||||
se=GWEN_StringListEntry_Next(se);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_HttpUrlHandler_SetHandleFn(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_URLHANDLER_HANDLE_FN fn)
|
|
||||||
{
|
|
||||||
if (uh)
|
|
||||||
uh->handleFn=fn;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int AQH_HttpUrlHandler_HandleMessage(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_REQUEST *rq)
|
|
||||||
{
|
|
||||||
if (uh && uh->handleFn)
|
|
||||||
return uh->handleFn(uh, rq);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int AQH_HttpUrlHandler_AddContentHeaders(AQH_HTTP_URLHANDLER *uh, int m, GWEN_BUFFER *dbuf)
|
|
||||||
{
|
|
||||||
return _addContentHeaders(uh->httpContentProvider, m, dbuf);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int AQH_HttpUrlHandler_AddContentFooters(AQH_HTTP_URLHANDLER *uh, int m, GWEN_BUFFER *dbuf)
|
|
||||||
{
|
|
||||||
return _addContentFooters(uh->httpContentProvider, m, dbuf);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
GWEN_MSG *AQH_HttpUrlHandler_CreatePageMessage(AQH_HTTP_URLHANDLER *uh,
|
|
||||||
AQH_HTTP_REQUEST *rq,
|
|
||||||
const char *statusTextColor, const char *statusMsg,
|
|
||||||
int withHeadersAndFooters,
|
|
||||||
GWEN_DB_NODE *dbValues,
|
|
||||||
AQH_HTTP_URLHANDLER_WRITEPAGE_CB cb)
|
|
||||||
{
|
|
||||||
GWEN_BUFFER *pageBuf;
|
|
||||||
int rv;
|
|
||||||
GWEN_MSG *msgOut=NULL;
|
|
||||||
const char *protocol;
|
|
||||||
|
|
||||||
protocol=AQH_HttpRequest_GetProtocol(rq);
|
|
||||||
pageBuf=GWEN_Buffer_new(0, 256, 0, 1);
|
|
||||||
if (withHeadersAndFooters) {
|
|
||||||
rv=AQH_HttpUrlHandler_AddContentHeaders(uh, AQH_HTTP_CONTENT_MODE_DESKTOP, pageBuf);
|
|
||||||
if (rv<0) {
|
|
||||||
DBG_ERROR(AQH_LOGDOMAIN, "Error adding headers");
|
|
||||||
GWEN_Buffer_free(pageBuf);
|
|
||||||
return AQH_HttpService_CreateResponseMsg(uh->httpService, 500, "Internal Error", protocol, NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (statusMsg)
|
|
||||||
GWEN_Buffer_AppendArgs(pageBuf, "<p><font color=\"%s\">%s</font></p>", statusTextColor?statusTextColor:"black", statusMsg);
|
|
||||||
if (cb) {
|
|
||||||
rv=cb(uh, rq, dbValues, pageBuf);
|
|
||||||
if (rv<0) {
|
|
||||||
DBG_ERROR(AQH_LOGDOMAIN, "Error adding headers");
|
|
||||||
GWEN_Buffer_free(pageBuf);
|
|
||||||
return AQH_HttpService_CreateResponseMsg(uh->httpService, 500, "Internal Error", protocol, NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (withHeadersAndFooters) {
|
|
||||||
rv=AQH_HttpUrlHandler_AddContentFooters(uh, AQH_HTTP_CONTENT_MODE_DESKTOP, pageBuf);
|
|
||||||
if (rv<0) {
|
|
||||||
DBG_ERROR(AQH_LOGDOMAIN, "Error adding footers");
|
|
||||||
GWEN_Buffer_free(pageBuf);
|
|
||||||
return AQH_HttpService_CreateResponseMsg(uh->httpService, 500, "Internal Error", protocol, NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
msgOut=AQH_HttpService_CreateResponseMsg(uh->httpService, 200, "OK", protocol, GWEN_Buffer_GetStart(pageBuf));
|
|
||||||
GWEN_Buffer_free(pageBuf);
|
|
||||||
return msgOut;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int _addContentHeaders(AQH_HTTP_CONTENT *c, int m, GWEN_BUFFER *dbuf)
|
|
||||||
{
|
|
||||||
AQH_HTTP_CONTENT *parent;
|
|
||||||
int rv;
|
|
||||||
|
|
||||||
parent=AQH_HttpContent_Tree2_GetParent(c);
|
|
||||||
if (parent) {
|
|
||||||
rv=_addContentHeaders(parent, m, dbuf);
|
|
||||||
if (rv<0) {
|
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "Error adding content headers for \"%s\"", AQH_HttpContent_GetName(parent));
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
rv=AQH_HttpContent_AddOpeningContent(c, m, dbuf);
|
|
||||||
if (rv<0) {
|
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "Error adding content headers for \"%s\"", AQH_HttpContent_GetName(c));
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int _addContentFooters(AQH_HTTP_CONTENT *c, int m, GWEN_BUFFER *dbuf)
|
|
||||||
{
|
|
||||||
AQH_HTTP_CONTENT *parent;
|
|
||||||
int rv;
|
|
||||||
|
|
||||||
rv=AQH_HttpContent_AddClosingContent(c, m, dbuf);
|
|
||||||
if (rv<0) {
|
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "Error adding content footers for \"%s\"", AQH_HttpContent_GetName(c));
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
parent=AQH_HttpContent_Tree2_GetParent(c);
|
|
||||||
if (parent) {
|
|
||||||
rv=_addContentFooters(parent, m, dbuf);
|
|
||||||
if (rv<0) {
|
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "Error adding content footers for \"%s\"", AQH_HttpContent_GetName(parent));
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,70 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
* 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 AQH_HTTP_URLHANDLER_H
|
|
||||||
#define AQH_HTTP_URLHANDLER_H
|
|
||||||
|
|
||||||
|
|
||||||
#include <aqhome/api.h>
|
|
||||||
#include <aqhome/http/httprequest.h>
|
|
||||||
#include <aqhome/http/content.h>
|
|
||||||
#include <aqhome/service/service.h>
|
|
||||||
|
|
||||||
#include <gwenhywfar/inherit.h>
|
|
||||||
#include <gwenhywfar/stringlist.h>
|
|
||||||
#include <gwenhywfar/endpoint.h>
|
|
||||||
#include <gwenhywfar/msg.h>
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct AQH_HTTP_URLHANDLER AQH_HTTP_URLHANDLER;
|
|
||||||
GWEN_INHERIT_FUNCTION_LIB_DEFS(AQH_HTTP_URLHANDLER, AQHOME_API)
|
|
||||||
GWEN_LIST_FUNCTION_LIB_DEFS(AQH_HTTP_URLHANDLER, AQH_HttpUrlHandler, AQHOME_API)
|
|
||||||
|
|
||||||
|
|
||||||
typedef int (*AQH_HTTP_URLHANDLER_HANDLE_FN)(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_REQUEST *rq);
|
|
||||||
|
|
||||||
AQHOME_API AQH_HTTP_URLHANDLER *AQH_HttpUrlHandler_new(AQH_SERVICE *sv);
|
|
||||||
AQHOME_API void AQH_HttpUrlHandler_free(AQH_HTTP_URLHANDLER *uh);
|
|
||||||
|
|
||||||
AQHOME_API AQH_SERVICE *AQH_HttpUrlHandler_GetHttpService(const AQH_HTTP_URLHANDLER *uh);
|
|
||||||
|
|
||||||
AQHOME_API void AQH_HttpUrlHandler_AddUrlPattern(AQH_HTTP_URLHANDLER *uh, const char *s);
|
|
||||||
AQHOME_API int AQH_HttpUrlHandler_UrlMatches(const AQH_HTTP_URLHANDLER *uh, const char *s);
|
|
||||||
|
|
||||||
AQHOME_API AQH_HTTP_CONTENT *AQH_HttpUrlHandler_GetContentProvider(const AQH_HTTP_URLHANDLER *uh);
|
|
||||||
AQHOME_API void AQH_HttpUrlHandler_SetContentProvider(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_CONTENT *cp);
|
|
||||||
|
|
||||||
AQHOME_API const char *AQH_HttpUrlHandler_GetFolder(const AQH_HTTP_URLHANDLER *uh);
|
|
||||||
AQHOME_API void AQH_HttpUrlHandler_SetFolder(AQH_HTTP_URLHANDLER *uh, const char *s);
|
|
||||||
|
|
||||||
AQHOME_API void AQH_HttpUrlHandler_SetHandleFn(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_URLHANDLER_HANDLE_FN fn);
|
|
||||||
|
|
||||||
AQHOME_API int AQH_HttpUrlHandler_AddContentHeaders(AQH_HTTP_URLHANDLER *uh, int m, GWEN_BUFFER *dbuf);
|
|
||||||
AQHOME_API int AQH_HttpUrlHandler_AddContentFooters(AQH_HTTP_URLHANDLER *uh, int m, GWEN_BUFFER *dbuf);
|
|
||||||
|
|
||||||
|
|
||||||
AQHOME_API int AQH_HttpUrlHandler_HandleMessage(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_REQUEST *rq);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
typedef int (*AQH_HTTP_URLHANDLER_WRITEPAGE_CB)(AQH_HTTP_URLHANDLER *uh,
|
|
||||||
AQH_HTTP_REQUEST *rq,
|
|
||||||
GWEN_DB_NODE *dbValues,
|
|
||||||
GWEN_BUFFER *pageBuf);
|
|
||||||
AQHOME_API GWEN_MSG *AQH_HttpUrlHandler_CreatePageMessage(AQH_HTTP_URLHANDLER *uh,
|
|
||||||
AQH_HTTP_REQUEST *rq,
|
|
||||||
const char *statusTextColor, const char *statusMsg,
|
|
||||||
int withHeadersAndFooters,
|
|
||||||
GWEN_DB_NODE *dbValues,
|
|
||||||
AQH_HTTP_URLHANDLER_WRITEPAGE_CB cb);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
* 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 AQH_HTTP_URLHANDLER_P_H
|
|
||||||
#define AQH_HTTP_URLHANDLER_P_H
|
|
||||||
|
|
||||||
|
|
||||||
#include "aqhome/http/urlhandler.h"
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct AQH_HTTP_URLHANDLER AQH_HTTP_URLHANDLER;
|
|
||||||
struct AQH_HTTP_URLHANDLER {
|
|
||||||
GWEN_INHERIT_ELEMENT(AQH_HTTP_URLHANDLER);
|
|
||||||
GWEN_LIST_ELEMENT(AQH_HTTP_URLHANDLER);
|
|
||||||
|
|
||||||
AQH_SERVICE *httpService;
|
|
||||||
GWEN_STRINGLIST *urlPatternList;
|
|
||||||
AQH_HTTP_CONTENT *httpContentProvider;
|
|
||||||
char *folder;
|
|
||||||
|
|
||||||
AQH_HTTP_URLHANDLER_HANDLE_FN handleFn;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,94 +0,0 @@
|
|||||||
<?xml?>
|
|
||||||
|
|
||||||
<gwbuild>
|
|
||||||
|
|
||||||
<target type="ConvenienceLibrary" name="aqhipc" >
|
|
||||||
|
|
||||||
<includes type="c" >
|
|
||||||
$(gwenhywfar_cflags)
|
|
||||||
-I$(topsrcdir)
|
|
||||||
-I$(topbuilddir)
|
|
||||||
</includes>
|
|
||||||
|
|
||||||
<includes type="tm2" >
|
|
||||||
--include=$(builddir)
|
|
||||||
--include=$(srcdir)
|
|
||||||
</includes>
|
|
||||||
|
|
||||||
|
|
||||||
<define name="BUILDING_AQHOME" />
|
|
||||||
|
|
||||||
<setVar name="local/cflags">$(visibility_cflags)</setVar>
|
|
||||||
|
|
||||||
|
|
||||||
<setVar name="tm2flags" >
|
|
||||||
--api=AQHOME_API
|
|
||||||
</setVar>
|
|
||||||
|
|
||||||
<setVar name="local/typefiles" >
|
|
||||||
</setVar>
|
|
||||||
|
|
||||||
<setVar name="local/built_sources" >
|
|
||||||
</setVar>
|
|
||||||
|
|
||||||
<setVar name="local/built_headers_pub">
|
|
||||||
</setVar>
|
|
||||||
|
|
||||||
|
|
||||||
<setVar name="local/built_headers_priv" >
|
|
||||||
</setVar>
|
|
||||||
|
|
||||||
|
|
||||||
<headers dist="false" install="$(pkgincludedir)/ipc" >
|
|
||||||
$(local/built_headers_pub)
|
|
||||||
</headers>
|
|
||||||
|
|
||||||
|
|
||||||
<headers dist="true" install="$(pkgincludedir)/ipc" >
|
|
||||||
endpoint_ipc.h
|
|
||||||
endpoint_ipcclient.h
|
|
||||||
msg_ipc_qwords.h
|
|
||||||
msg_ipc_result.h
|
|
||||||
msg_ipc_tag16.h
|
|
||||||
requests.h
|
|
||||||
</headers>
|
|
||||||
|
|
||||||
|
|
||||||
<headers dist="true" >
|
|
||||||
endpoint_ipc_p.h
|
|
||||||
msg_ipc_tag16_p.h
|
|
||||||
</headers>
|
|
||||||
|
|
||||||
|
|
||||||
<sources>
|
|
||||||
$(local/typefiles)
|
|
||||||
|
|
||||||
endpoint_ipc.c
|
|
||||||
endpoint_ipcclient.c
|
|
||||||
msg_ipc_qwords.c
|
|
||||||
msg_ipc_result.c
|
|
||||||
msg_ipc_tag16.c
|
|
||||||
requests.c
|
|
||||||
</sources>
|
|
||||||
|
|
||||||
|
|
||||||
<extradist>
|
|
||||||
</extradist>
|
|
||||||
|
|
||||||
|
|
||||||
<useTargets>
|
|
||||||
aqhipcnodes
|
|
||||||
aqhipcdata
|
|
||||||
</useTargets>
|
|
||||||
|
|
||||||
<subdirs>
|
|
||||||
nodes
|
|
||||||
data
|
|
||||||
</subdirs>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</target>
|
|
||||||
|
|
||||||
</gwbuild>
|
|
||||||
@@ -1,90 +0,0 @@
|
|||||||
<?xml?>
|
|
||||||
|
|
||||||
<gwbuild>
|
|
||||||
|
|
||||||
<target type="ConvenienceLibrary" name="aqhipcdata" >
|
|
||||||
|
|
||||||
<includes type="c" >
|
|
||||||
$(gwenhywfar_cflags)
|
|
||||||
-I$(topsrcdir)
|
|
||||||
-I$(topbuilddir)
|
|
||||||
</includes>
|
|
||||||
|
|
||||||
<includes type="tm2" >
|
|
||||||
--include=$(builddir)
|
|
||||||
--include=$(srcdir)
|
|
||||||
</includes>
|
|
||||||
|
|
||||||
|
|
||||||
<define name="BUILDING_AQHOME" />
|
|
||||||
|
|
||||||
<setVar name="local/cflags">$(visibility_cflags)</setVar>
|
|
||||||
|
|
||||||
|
|
||||||
<setVar name="tm2flags" >
|
|
||||||
--api=AQHOME_API
|
|
||||||
</setVar>
|
|
||||||
|
|
||||||
<setVar name="local/typefiles" >
|
|
||||||
</setVar>
|
|
||||||
|
|
||||||
<setVar name="local/built_sources" >
|
|
||||||
</setVar>
|
|
||||||
|
|
||||||
<setVar name="local/built_headers_pub">
|
|
||||||
</setVar>
|
|
||||||
|
|
||||||
|
|
||||||
<setVar name="local/built_headers_priv" >
|
|
||||||
</setVar>
|
|
||||||
|
|
||||||
|
|
||||||
<headers dist="false" install="$(pkgincludedir)/ipc" >
|
|
||||||
$(local/built_headers_pub)
|
|
||||||
</headers>
|
|
||||||
|
|
||||||
|
|
||||||
<headers dist="true" install="$(pkgincludedir)/ipc" >
|
|
||||||
ipc_data.h
|
|
||||||
msg_data_connect.h
|
|
||||||
msg_data_datapoints.h
|
|
||||||
msg_data_devices.h
|
|
||||||
msg_data_getdata.h
|
|
||||||
msg_data_multidata.h
|
|
||||||
msg_data_values.h
|
|
||||||
msg_data_set.h
|
|
||||||
</headers>
|
|
||||||
|
|
||||||
|
|
||||||
<headers dist="true" >
|
|
||||||
</headers>
|
|
||||||
|
|
||||||
|
|
||||||
<sources>
|
|
||||||
$(local/typefiles)
|
|
||||||
|
|
||||||
ipc_data.c
|
|
||||||
msg_data_connect.c
|
|
||||||
msg_data_datapoints.c
|
|
||||||
msg_data_devices.c
|
|
||||||
msg_data_getdata.c
|
|
||||||
msg_data_multidata.c
|
|
||||||
msg_data_values.c
|
|
||||||
msg_data_set.c
|
|
||||||
</sources>
|
|
||||||
|
|
||||||
|
|
||||||
<extradist>
|
|
||||||
</extradist>
|
|
||||||
|
|
||||||
|
|
||||||
<useTargets>
|
|
||||||
</useTargets>
|
|
||||||
|
|
||||||
<subdirs>
|
|
||||||
</subdirs>
|
|
||||||
|
|
||||||
|
|
||||||
</target>
|
|
||||||
|
|
||||||
</gwbuild>
|
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
GWEN_MSG *AQH_CmdDataIpc_WaitForSpecificIpcMessage(GWEN_MSG_ENDPOINT *epTcp, int msgCode, int timeoutInSeconds)
|
|
||||||
{
|
|
||||||
time_t startTime;
|
|
||||||
|
|
||||||
startTime=time(NULL);
|
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
GWEN_MSG *msg;
|
|
||||||
time_t now;
|
|
||||||
|
|
||||||
while( (msg=GWEN_MsgEndpoint_TakeFirstReceivedMessage(epTcp)) ) {
|
|
||||||
uint16_t code;
|
|
||||||
|
|
||||||
code=GWEN_IpcMsg_GetCode(msg);
|
|
||||||
if (code==msgCode) {
|
|
||||||
DBG_INFO(NULL, "Received expected IPC message");
|
|
||||||
return msg;
|
|
||||||
}
|
|
||||||
else if (code==AQH_MSGTYPE_IPC_DATA_RESULT) {
|
|
||||||
DBG_INFO(NULL, "Received IPC result message");
|
|
||||||
return msg;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
DBG_INFO(NULL, "Received unexpected message %d (%x)", code, code);
|
|
||||||
}
|
|
||||||
GWEN_Msg_free(msg);
|
|
||||||
}
|
|
||||||
now=time(NULL);
|
|
||||||
if (now-startTime>timeoutInSeconds) {
|
|
||||||
DBG_INFO(NULL, "Timeout");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
GWEN_MsgEndpoint_IoLoop(epTcp, 2000); /* 2000 ms */
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,110 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
* 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 <aqhome/ipc/data/msg_data_datapoints.h>
|
|
||||||
#include <aqhome/ipc/data/ipc_data.h>
|
|
||||||
#include <aqhome/ipc/data/msg_data_multidata.h>
|
|
||||||
#include <aqhome/ipc/data/msg_data_getdata.h>
|
|
||||||
#include <aqhome/ipc/data/ipc_data.h>
|
|
||||||
#include <aqhome/ipc/msg_ipc_tag16.h>
|
|
||||||
|
|
||||||
#include <gwenhywfar/msg.h>
|
|
||||||
#include <gwenhywfar/buffer.h>
|
|
||||||
|
|
||||||
#include <gwenhywfar/debug.h>
|
|
||||||
#include <gwenhywfar/msg_ipc.h>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
GWEN_MSG *_waitForMatchingResponse(GWEN_MSG_ENDPOINT *epTcp, int msgCode, int timeoutInSeconds);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
GWEN_MSG *AQH_CmdDataIpc_RequestDatapointsMsg(GWEN_MSG_ENDPOINT *ep,
|
|
||||||
const char *valueName, uint64_t tsBegin, uint64_t tsEnd, uint64_t num,
|
|
||||||
int timeoutInSeconds)
|
|
||||||
{
|
|
||||||
GWEN_MSG *msg;
|
|
||||||
time_t startTime;
|
|
||||||
|
|
||||||
msg=AQH_GetDataDataIpcMsg_new(AQH_MSGTYPE_IPC_DATA_GETDATA_REQ, valueName, tsBegin, tsEnd, num);
|
|
||||||
GWEN_MsgEndpoint_AddSendMessage(ep, msg);
|
|
||||||
|
|
||||||
msg=_waitForMatchingResponse(ep, AQH_MSGTYPE_IPC_DATA_GETDATA_RSP, timeoutInSeconds);
|
|
||||||
if (msg) {
|
|
||||||
uint16_t code;
|
|
||||||
|
|
||||||
code=GWEN_IpcMsg_GetCode(msg);
|
|
||||||
if (code==AQH_MSGTYPE_IPC_DATA_RESULT) {
|
|
||||||
uint32_t resultCode;
|
|
||||||
|
|
||||||
resultCode=AQH_ResultIpcMsg_GetResultCode(msg);
|
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "IPC error: %d", resultCode);
|
|
||||||
GWEN_Msg_free(msg);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
else if (code==AQH_MSGTYPE_IPC_DATA_GETDATA_RSP) {
|
|
||||||
int rv;
|
|
||||||
|
|
||||||
AQH_MultiDataDataIpcMsg_Parse(msg, 0);
|
|
||||||
return msg;
|
|
||||||
}
|
|
||||||
GWEN_Msg_free(msg);
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
GWEN_MSG *_waitForMatchingResponse(GWEN_MSG_ENDPOINT *epTcp, int msgCode, int timeoutInSeconds)
|
|
||||||
{
|
|
||||||
time_t startTime;
|
|
||||||
|
|
||||||
startTime=time(NULL);
|
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
GWEN_MSG *msg;
|
|
||||||
time_t now;
|
|
||||||
|
|
||||||
while( (msg=GWEN_MsgEndpoint_TakeFirstReceivedMessage(epTcp)) ) {
|
|
||||||
uint16_t code;
|
|
||||||
|
|
||||||
code=GWEN_IpcMsg_GetCode(msg);
|
|
||||||
if (code==msgCode) {
|
|
||||||
DBG_INFO(NULL, "Received expected IPC message");
|
|
||||||
return msg;
|
|
||||||
}
|
|
||||||
else if (code==AQH_MSGTYPE_IPC_DATA_RESULT) {
|
|
||||||
DBG_INFO(NULL, "Received IPC result message");
|
|
||||||
return msg;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
DBG_INFO(NULL, "Received unexpected message %d (%x), ignoring", code, code);
|
|
||||||
}
|
|
||||||
GWEN_Msg_free(msg);
|
|
||||||
} /* while */
|
|
||||||
|
|
||||||
now=time(NULL);
|
|
||||||
if (now-startTime>timeoutInSeconds) {
|
|
||||||
DBG_INFO(NULL, "Timeout");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
GWEN_MsgEndpoint_IoLoop(epTcp, 2000); /* 2000 ms */
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,502 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
* 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 <aqhome/ipc/data/ipc_data.h>
|
|
||||||
#include <aqhome/ipc/msg_ipc_tag16.h>
|
|
||||||
|
|
||||||
#include <gwenhywfar/debug.h>
|
|
||||||
#include <gwenhywfar/tag16.h>
|
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------------------------------
|
|
||||||
* defines
|
|
||||||
* ------------------------------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define AQH_IPCDATA_VALUE_TAGS_ID 0x01
|
|
||||||
#define AQH_IPCDATA_VALUE_TAGS_DRIVER 0x02
|
|
||||||
#define AQH_IPCDATA_VALUE_TAGS_NAMEFORDRIVER 0x03
|
|
||||||
#define AQH_IPCDATA_VALUE_TAGS_NAMEFORSYSTEM 0x04
|
|
||||||
#define AQH_IPCDATA_VALUE_TAGS_TYPE 0x05
|
|
||||||
#define AQH_IPCDATA_VALUE_TAGS_UNITS 0x06
|
|
||||||
#define AQH_IPCDATA_VALUE_TAGS_TIMEOFCREATION 0x07
|
|
||||||
#define AQH_IPCDATA_VALUE_TAGS_DEVFORDRIVER 0x08
|
|
||||||
#define AQH_IPCDATA_VALUE_TAGS_DEVFORSYSTEM 0x09
|
|
||||||
#define AQH_IPCDATA_VALUE_TAGS_MODALITY 0x0a
|
|
||||||
|
|
||||||
#define AQH_IPCDATA_DEVICE_TAGS_ID 0x01
|
|
||||||
#define AQH_IPCDATA_DEVICE_TAGS_DRIVER 0x02
|
|
||||||
#define AQH_IPCDATA_DEVICE_TAGS_ROOMNAME 0x03
|
|
||||||
#define AQH_IPCDATA_DEVICE_TAGS_NAMEFORDRIVER 0x04
|
|
||||||
#define AQH_IPCDATA_DEVICE_TAGS_NAMEFORSYSTEM 0x05
|
|
||||||
#define AQH_IPCDATA_DEVICE_TAGS_NAMEFORGUI 0x06
|
|
||||||
#define AQH_IPCDATA_DEVICE_TAGS_LOCATION 0x07
|
|
||||||
#define AQH_IPCDATA_DEVICE_TAGS_DESCRIPTION 0x08
|
|
||||||
#define AQH_IPCDATA_DEVICE_TAGS_DEVTYPE 0x09
|
|
||||||
#define AQH_IPCDATA_DEVICE_TAGS_MANUFACTURER 0x0a
|
|
||||||
#define AQH_IPCDATA_DEVICE_TAGS_TIMEOFCREATION 0x0b
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------------------------------
|
|
||||||
* forward declarations
|
|
||||||
* ------------------------------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
static void _writeValueFieldsAsTagsToBuffer(const AQH_VALUE *value, GWEN_BUFFER *buf);
|
|
||||||
static AQH_VALUE *_readValueFromTag(const uint8_t *ptr, uint32_t len);
|
|
||||||
static void _writeDeviceFieldsAsTagsToBuffer(const AQH_DEVICE *device, GWEN_BUFFER *buf);
|
|
||||||
static AQH_DEVICE *_readDeviceFromTag(const uint8_t *ptr, uint32_t len);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------------------------------
|
|
||||||
* code
|
|
||||||
* ------------------------------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int AQH_DataIpc_WriteValueListAsTagsToBuffer(unsigned int tagType, const AQH_VALUE_LIST *valueList, GWEN_BUFFER *buf)
|
|
||||||
{
|
|
||||||
if (valueList) {
|
|
||||||
const AQH_VALUE *value;
|
|
||||||
|
|
||||||
value=AQH_Value_List_First(valueList);
|
|
||||||
while(value) {
|
|
||||||
int rv;
|
|
||||||
|
|
||||||
rv=AQH_DataIpc_WriteValueAsTagToBuffer(tagType, value, buf);
|
|
||||||
if (rv<0) {
|
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "here (%d)", rv);
|
|
||||||
GWEN_Buffer_free(buf);
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
value=AQH_Value_List_Next(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int AQH_DataIpc_WriteValueAsTagToBuffer(unsigned int tagType, const AQH_VALUE *value, GWEN_BUFFER *buf)
|
|
||||||
{
|
|
||||||
int startPos;
|
|
||||||
int rv;
|
|
||||||
|
|
||||||
startPos=GWEN_Tag16_StartTagInBuffer(tagType, buf);
|
|
||||||
if (startPos<0) {
|
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "here (%d)", startPos);
|
|
||||||
return startPos;
|
|
||||||
}
|
|
||||||
|
|
||||||
_writeValueFieldsAsTagsToBuffer(value, buf);
|
|
||||||
|
|
||||||
rv=GWEN_Tag16_EndTagInBuffer(startPos, buf);
|
|
||||||
if (rv<0) {
|
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "here (%d)", rv);
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int AQH_DataIpc_WriteDeviceListAsTagsToBuffer(unsigned int tagType, const AQH_DEVICE_LIST *deviceList, GWEN_BUFFER *buf)
|
|
||||||
{
|
|
||||||
if (deviceList) {
|
|
||||||
const AQH_DEVICE *device;
|
|
||||||
|
|
||||||
device=AQH_Device_List_First(deviceList);
|
|
||||||
while(device) {
|
|
||||||
int rv;
|
|
||||||
|
|
||||||
rv=AQH_DataIpc_WriteDeviceAsTagToBuffer(tagType, device, buf);
|
|
||||||
if (rv<0) {
|
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "here (%d)", rv);
|
|
||||||
GWEN_Buffer_free(buf);
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
device=AQH_Device_List_Next(device);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int AQH_DataIpc_WriteDeviceAsTagToBuffer(unsigned int tagType, const AQH_DEVICE *device, GWEN_BUFFER *buf)
|
|
||||||
{
|
|
||||||
int startPos;
|
|
||||||
int rv;
|
|
||||||
|
|
||||||
startPos=GWEN_Tag16_StartTagInBuffer(tagType, buf);
|
|
||||||
if (startPos<0) {
|
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "here (%d)", startPos);
|
|
||||||
return startPos;
|
|
||||||
}
|
|
||||||
|
|
||||||
_writeDeviceFieldsAsTagsToBuffer(device, buf);
|
|
||||||
|
|
||||||
rv=GWEN_Tag16_EndTagInBuffer(startPos, buf);
|
|
||||||
if (rv<0) {
|
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "here (%d)", rv);
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void _writeValueFieldsAsTagsToBuffer(const AQH_VALUE *value, GWEN_BUFFER *buf)
|
|
||||||
{
|
|
||||||
const char *s;
|
|
||||||
|
|
||||||
GWEN_Tag16_WriteUint64TagToBuffer(AQH_IPCDATA_VALUE_TAGS_ID, AQH_Value_GetId(value), buf);
|
|
||||||
|
|
||||||
s=AQH_Value_GetDriver(value);
|
|
||||||
if (s && *s)
|
|
||||||
GWEN_Tag16_WriteStringTagToBuffer(AQH_IPCDATA_VALUE_TAGS_DRIVER, s, buf);
|
|
||||||
|
|
||||||
s=AQH_Value_GetName(value);
|
|
||||||
if (s && *s)
|
|
||||||
GWEN_Tag16_WriteStringTagToBuffer(AQH_IPCDATA_VALUE_TAGS_NAMEFORDRIVER, s, buf);
|
|
||||||
|
|
||||||
s=AQH_Value_GetNameForSystem(value);
|
|
||||||
if (s && *s)
|
|
||||||
GWEN_Tag16_WriteStringTagToBuffer(AQH_IPCDATA_VALUE_TAGS_NAMEFORSYSTEM, s, buf);
|
|
||||||
|
|
||||||
GWEN_Tag16_WriteUint32TagToBuffer(AQH_IPCDATA_VALUE_TAGS_TYPE, AQH_Value_GetValueType(value), buf);
|
|
||||||
|
|
||||||
s=AQH_Value_GetValueUnits(value);
|
|
||||||
if (s && *s)
|
|
||||||
GWEN_Tag16_WriteStringTagToBuffer(AQH_IPCDATA_VALUE_TAGS_UNITS, s, buf);
|
|
||||||
|
|
||||||
GWEN_Tag16_WriteUint64TagToBuffer(AQH_IPCDATA_VALUE_TAGS_TIMEOFCREATION, AQH_Value_GetTimestampCreation(value), buf);
|
|
||||||
|
|
||||||
s=AQH_Value_GetDeviceName(value);
|
|
||||||
if (s && *s)
|
|
||||||
GWEN_Tag16_WriteStringTagToBuffer(AQH_IPCDATA_VALUE_TAGS_DEVFORDRIVER, s, buf);
|
|
||||||
|
|
||||||
s=AQH_Value_GetDeviceNameForSystem(value);
|
|
||||||
if (s && *s)
|
|
||||||
GWEN_Tag16_WriteStringTagToBuffer(AQH_IPCDATA_VALUE_TAGS_DEVFORSYSTEM, s, buf);
|
|
||||||
|
|
||||||
GWEN_Tag16_WriteUint32TagToBuffer(AQH_IPCDATA_VALUE_TAGS_MODALITY, AQH_Value_GetModality(value), buf);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
AQH_VALUE_LIST *AQH_DataIpc_ReadValuesFromTagList(const GWEN_TAG16_LIST *tagList, unsigned int wantedTagType)
|
|
||||||
{
|
|
||||||
AQH_VALUE_LIST *valueList;
|
|
||||||
const GWEN_TAG16 *tag;
|
|
||||||
|
|
||||||
valueList=AQH_Value_List_new();
|
|
||||||
tag=GWEN_Tag16_List_First(tagList);
|
|
||||||
while(tag) {
|
|
||||||
unsigned int tagType;
|
|
||||||
AQH_VALUE *value;
|
|
||||||
|
|
||||||
tagType=GWEN_Tag16_GetTagType(tag);
|
|
||||||
if (tagType==wantedTagType) {
|
|
||||||
value=_readValueFromTag((const uint8_t*) GWEN_Tag16_GetTagData(tag), (uint32_t) GWEN_Tag16_GetTagLength(tag));
|
|
||||||
if (value)
|
|
||||||
AQH_Value_List_Add(value, valueList);
|
|
||||||
}
|
|
||||||
|
|
||||||
tag=GWEN_Tag16_List_Next(tag);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (AQH_Value_List_GetCount(valueList)<1) {
|
|
||||||
AQH_Value_List_free(valueList);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return valueList;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
AQH_VALUE *AQH_DataIpc_ReadValueFromTagList(const GWEN_TAG16_LIST *tagList, unsigned int wantedTagType)
|
|
||||||
{
|
|
||||||
if (tagList) {
|
|
||||||
const GWEN_TAG16 *tag;
|
|
||||||
|
|
||||||
tag=GWEN_Tag16_List_FindFirstByTagType(tagList, wantedTagType);
|
|
||||||
return tag?_readValueFromTag((const uint8_t*) GWEN_Tag16_GetTagData(tag), (uint32_t) GWEN_Tag16_GetTagLength(tag)):NULL;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
AQH_DEVICE_LIST *AQH_DataIpc_ReadDevicesFromTagList(const GWEN_TAG16_LIST *tagList, unsigned int wantedTagType)
|
|
||||||
{
|
|
||||||
AQH_DEVICE_LIST *deviceList;
|
|
||||||
const GWEN_TAG16 *tag;
|
|
||||||
|
|
||||||
deviceList=AQH_Device_List_new();
|
|
||||||
tag=GWEN_Tag16_List_First(tagList);
|
|
||||||
while(tag) {
|
|
||||||
unsigned int tagType;
|
|
||||||
AQH_DEVICE *device;
|
|
||||||
|
|
||||||
tagType=GWEN_Tag16_GetTagType(tag);
|
|
||||||
if (tagType==wantedTagType) {
|
|
||||||
device=_readDeviceFromTag((const uint8_t*) GWEN_Tag16_GetTagData(tag), (uint32_t) GWEN_Tag16_GetTagLength(tag));
|
|
||||||
if (device)
|
|
||||||
AQH_Device_List_Add(device, deviceList);
|
|
||||||
}
|
|
||||||
|
|
||||||
tag=GWEN_Tag16_List_Next(tag);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (AQH_Device_List_GetCount(deviceList)<1) {
|
|
||||||
AQH_Device_List_free(deviceList);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return deviceList;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
AQH_DEVICE *AQH_DataIpc_ReadDeviceFromTagList(const GWEN_TAG16_LIST *tagList, unsigned int wantedTagType)
|
|
||||||
{
|
|
||||||
if (tagList) {
|
|
||||||
const GWEN_TAG16 *tag;
|
|
||||||
|
|
||||||
tag=GWEN_Tag16_List_FindFirstByTagType(tagList, wantedTagType);
|
|
||||||
return tag?_readDeviceFromTag((const uint8_t*) GWEN_Tag16_GetTagData(tag), (uint32_t) GWEN_Tag16_GetTagLength(tag)):NULL;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
AQH_VALUE *_readValueFromTag(const uint8_t *ptr, uint32_t len)
|
|
||||||
{
|
|
||||||
GWEN_TAG16_LIST *tagList;
|
|
||||||
|
|
||||||
tagList=GWEN_Tag16_List_fromBuffer(ptr, len, 0);
|
|
||||||
if (tagList) {
|
|
||||||
GWEN_TAG16 *tag;
|
|
||||||
AQH_VALUE *value;
|
|
||||||
|
|
||||||
value=AQH_Value_new();
|
|
||||||
tag=GWEN_Tag16_List_First(tagList);
|
|
||||||
while(tag) {
|
|
||||||
unsigned int tagType;
|
|
||||||
char *s;
|
|
||||||
|
|
||||||
tagType=GWEN_Tag16_GetTagType(tag);
|
|
||||||
switch(tagType) {
|
|
||||||
case AQH_IPCDATA_VALUE_TAGS_ID:
|
|
||||||
AQH_Value_SetId(value, GWEN_Tag16_GetTagDataAsUint64(tag, 0));
|
|
||||||
break;
|
|
||||||
case AQH_IPCDATA_VALUE_TAGS_DRIVER:
|
|
||||||
s=GWEN_Tag16_GetTagDataAsNewString(tag, NULL);
|
|
||||||
AQH_Value_SetDriver(value, s);
|
|
||||||
free(s);
|
|
||||||
break;
|
|
||||||
case AQH_IPCDATA_VALUE_TAGS_NAMEFORDRIVER:
|
|
||||||
s=GWEN_Tag16_GetTagDataAsNewString(tag, NULL);
|
|
||||||
AQH_Value_SetName(value, s);
|
|
||||||
free(s);
|
|
||||||
break;
|
|
||||||
case AQH_IPCDATA_VALUE_TAGS_NAMEFORSYSTEM:
|
|
||||||
s=GWEN_Tag16_GetTagDataAsNewString(tag, NULL);
|
|
||||||
AQH_Value_SetNameForSystem(value, s);
|
|
||||||
free(s);
|
|
||||||
break;
|
|
||||||
case AQH_IPCDATA_VALUE_TAGS_TYPE:
|
|
||||||
AQH_Value_SetValueType(value, GWEN_Tag16_GetTagDataAsUint32(tag, 0));
|
|
||||||
break;
|
|
||||||
case AQH_IPCDATA_VALUE_TAGS_UNITS:
|
|
||||||
s=GWEN_Tag16_GetTagDataAsNewString(tag, NULL);
|
|
||||||
AQH_Value_SetValueUnits(value, s);
|
|
||||||
free(s);
|
|
||||||
break;
|
|
||||||
case AQH_IPCDATA_VALUE_TAGS_TIMEOFCREATION:
|
|
||||||
AQH_Value_SetTimestampCreation(value, GWEN_Tag16_GetTagDataAsUint64(tag, 0));
|
|
||||||
break;
|
|
||||||
case AQH_IPCDATA_VALUE_TAGS_DEVFORDRIVER:
|
|
||||||
s=GWEN_Tag16_GetTagDataAsNewString(tag, NULL);
|
|
||||||
AQH_Value_SetDeviceName(value, s);
|
|
||||||
free(s);
|
|
||||||
break;
|
|
||||||
case AQH_IPCDATA_VALUE_TAGS_DEVFORSYSTEM:
|
|
||||||
s=GWEN_Tag16_GetTagDataAsNewString(tag, NULL);
|
|
||||||
AQH_Value_SetDeviceNameForSystem(value, s);
|
|
||||||
free(s);
|
|
||||||
break;
|
|
||||||
case AQH_IPCDATA_VALUE_TAGS_MODALITY:
|
|
||||||
AQH_Value_SetModality(value, GWEN_Tag16_GetTagDataAsUint32(tag, 0));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "Unhandled tag typ %d (%02x)", tagType, tagType);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
tag=GWEN_Tag16_List_Next(tag);
|
|
||||||
}
|
|
||||||
GWEN_Tag16_List_free(tagList);
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void _writeDeviceFieldsAsTagsToBuffer(const AQH_DEVICE *device, GWEN_BUFFER *buf)
|
|
||||||
{
|
|
||||||
const char *s;
|
|
||||||
|
|
||||||
GWEN_Tag16_WriteUint64TagToBuffer(AQH_IPCDATA_DEVICE_TAGS_ID, AQH_Device_GetId(device), buf);
|
|
||||||
|
|
||||||
s=AQH_Device_GetDriver(device);
|
|
||||||
if (s && *s)
|
|
||||||
GWEN_Tag16_WriteStringTagToBuffer(AQH_IPCDATA_DEVICE_TAGS_DRIVER, s, buf);
|
|
||||||
|
|
||||||
s=AQH_Device_GetRoomName(device);
|
|
||||||
if (s && *s)
|
|
||||||
GWEN_Tag16_WriteStringTagToBuffer(AQH_IPCDATA_DEVICE_TAGS_ROOMNAME, s, buf);
|
|
||||||
|
|
||||||
s=AQH_Device_GetName(device);
|
|
||||||
if (s && *s)
|
|
||||||
GWEN_Tag16_WriteStringTagToBuffer(AQH_IPCDATA_DEVICE_TAGS_NAMEFORDRIVER, s, buf);
|
|
||||||
|
|
||||||
s=AQH_Device_GetNameForSystem(device);
|
|
||||||
if (s && *s)
|
|
||||||
GWEN_Tag16_WriteStringTagToBuffer(AQH_IPCDATA_DEVICE_TAGS_NAMEFORSYSTEM, s, buf);
|
|
||||||
|
|
||||||
s=AQH_Device_GetNameForGui(device);
|
|
||||||
if (s && *s)
|
|
||||||
GWEN_Tag16_WriteStringTagToBuffer(AQH_IPCDATA_DEVICE_TAGS_NAMEFORGUI, s, buf);
|
|
||||||
|
|
||||||
s=AQH_Device_GetLocation(device);
|
|
||||||
if (s && *s)
|
|
||||||
GWEN_Tag16_WriteStringTagToBuffer(AQH_IPCDATA_DEVICE_TAGS_LOCATION, s, buf);
|
|
||||||
|
|
||||||
s=AQH_Device_GetDescription(device);
|
|
||||||
if (s && *s)
|
|
||||||
GWEN_Tag16_WriteStringTagToBuffer(AQH_IPCDATA_DEVICE_TAGS_DESCRIPTION, s, buf);
|
|
||||||
|
|
||||||
s=AQH_Device_GetDeviceType(device);
|
|
||||||
if (s && *s)
|
|
||||||
GWEN_Tag16_WriteStringTagToBuffer(AQH_IPCDATA_DEVICE_TAGS_DEVTYPE, s, buf);
|
|
||||||
|
|
||||||
s=AQH_Device_GetManufacturer(device);
|
|
||||||
if (s && *s)
|
|
||||||
GWEN_Tag16_WriteStringTagToBuffer(AQH_IPCDATA_DEVICE_TAGS_MANUFACTURER, s, buf);
|
|
||||||
|
|
||||||
GWEN_Tag16_WriteUint64TagToBuffer(AQH_IPCDATA_DEVICE_TAGS_TIMEOFCREATION, AQH_Device_GetTimestampCreation(device), buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
AQH_DEVICE *_readDeviceFromTag(const uint8_t *ptr, uint32_t len)
|
|
||||||
{
|
|
||||||
GWEN_TAG16_LIST *tagList;
|
|
||||||
|
|
||||||
tagList=GWEN_Tag16_List_fromBuffer(ptr, len, 0);
|
|
||||||
if (tagList) {
|
|
||||||
GWEN_TAG16 *tag;
|
|
||||||
AQH_DEVICE *device;
|
|
||||||
|
|
||||||
device=AQH_Device_new();
|
|
||||||
tag=GWEN_Tag16_List_First(tagList);
|
|
||||||
while(tag) {
|
|
||||||
unsigned int tagType;
|
|
||||||
char *s;
|
|
||||||
|
|
||||||
tagType=GWEN_Tag16_GetTagType(tag);
|
|
||||||
switch(tagType) {
|
|
||||||
case AQH_IPCDATA_DEVICE_TAGS_ID:
|
|
||||||
AQH_Device_SetId(device, GWEN_Tag16_GetTagDataAsUint64(tag, 0));
|
|
||||||
break;
|
|
||||||
case AQH_IPCDATA_DEVICE_TAGS_DRIVER:
|
|
||||||
s=GWEN_Tag16_GetTagDataAsNewString(tag, NULL);
|
|
||||||
AQH_Device_SetDriver(device, s);
|
|
||||||
free(s);
|
|
||||||
break;
|
|
||||||
case AQH_IPCDATA_DEVICE_TAGS_ROOMNAME:
|
|
||||||
s=GWEN_Tag16_GetTagDataAsNewString(tag, NULL);
|
|
||||||
AQH_Device_SetRoomName(device, s);
|
|
||||||
free(s);
|
|
||||||
break;
|
|
||||||
case AQH_IPCDATA_DEVICE_TAGS_NAMEFORDRIVER:
|
|
||||||
s=GWEN_Tag16_GetTagDataAsNewString(tag, NULL);
|
|
||||||
AQH_Device_SetName(device, s);
|
|
||||||
free(s);
|
|
||||||
break;
|
|
||||||
case AQH_IPCDATA_DEVICE_TAGS_NAMEFORSYSTEM:
|
|
||||||
s=GWEN_Tag16_GetTagDataAsNewString(tag, NULL);
|
|
||||||
AQH_Device_SetNameForSystem(device, s);
|
|
||||||
free(s);
|
|
||||||
break;
|
|
||||||
case AQH_IPCDATA_DEVICE_TAGS_NAMEFORGUI:
|
|
||||||
s=GWEN_Tag16_GetTagDataAsNewString(tag, NULL);
|
|
||||||
AQH_Device_SetNameForGui(device, s);
|
|
||||||
free(s);
|
|
||||||
break;
|
|
||||||
case AQH_IPCDATA_DEVICE_TAGS_LOCATION:
|
|
||||||
s=GWEN_Tag16_GetTagDataAsNewString(tag, NULL);
|
|
||||||
AQH_Device_SetLocation(device, s);
|
|
||||||
free(s);
|
|
||||||
break;
|
|
||||||
case AQH_IPCDATA_DEVICE_TAGS_DESCRIPTION:
|
|
||||||
s=GWEN_Tag16_GetTagDataAsNewString(tag, NULL);
|
|
||||||
AQH_Device_SetDescription(device, s);
|
|
||||||
free(s);
|
|
||||||
break;
|
|
||||||
case AQH_IPCDATA_DEVICE_TAGS_DEVTYPE:
|
|
||||||
s=GWEN_Tag16_GetTagDataAsNewString(tag, NULL);
|
|
||||||
AQH_Device_SetDeviceType(device, s);
|
|
||||||
free(s);
|
|
||||||
break;
|
|
||||||
case AQH_IPCDATA_DEVICE_TAGS_MANUFACTURER:
|
|
||||||
s=GWEN_Tag16_GetTagDataAsNewString(tag, NULL);
|
|
||||||
AQH_Device_SetManufacturer(device, s);
|
|
||||||
free(s);
|
|
||||||
break;
|
|
||||||
case AQH_IPCDATA_DEVICE_TAGS_TIMEOFCREATION:
|
|
||||||
AQH_Device_SetTimestampCreation(device, GWEN_Tag16_GetTagDataAsUint64(tag, 0));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "Unhandled tag typ %d (%02x)", tagType, tagType);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
tag=GWEN_Tag16_List_Next(tag);
|
|
||||||
}
|
|
||||||
GWEN_Tag16_List_free(tagList);
|
|
||||||
return device;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,72 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
* 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 AQH_MSG_IPC_DATA_H
|
|
||||||
#define AQH_MSG_IPC_DATA_H
|
|
||||||
|
|
||||||
|
|
||||||
#include <aqhome/api.h>
|
|
||||||
#include <aqhome/data/value.h>
|
|
||||||
#include <aqhome/data/device.h>
|
|
||||||
|
|
||||||
#include <gwenhywfar/msg_ipc.h>
|
|
||||||
#include <gwenhywfar/buffer.h>
|
|
||||||
#include <gwenhywfar/tag16.h>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define AQH_IPC_PROTOCOL_DATA_ID 2
|
|
||||||
#define AQH_IPC_PROTOCOL_DATA_VERSION 1
|
|
||||||
|
|
||||||
|
|
||||||
#define AQH_MSGTYPE_IPC_DATA_RESULT 0x0001 /* AQH_ResultIpcMsg */
|
|
||||||
|
|
||||||
#define AQH_MSGTYPE_IPC_DATA_CONNECT_REQ 0x0010 /* serviceName, userName, password */
|
|
||||||
|
|
||||||
#define AQH_MSGTYPE_IPC_DATA_UPDATEDATA 0x0100 /* AQH_MultiDataDataIpcMsg */
|
|
||||||
#define AQH_MSGTYPE_IPC_DATA_DATACHANGED 0x0200 /* AQH_MultiDataDataIpcMsg */
|
|
||||||
|
|
||||||
#define AQH_MSGTYPE_IPC_DATA_SETDATA 0x0300 /* AQH_SetDataIpcMsg */
|
|
||||||
|
|
||||||
#define AQH_MSGTYPE_IPC_DATA_ADDVALUE 0x0400 /* AQH_AddValueDataIpcMsg */
|
|
||||||
|
|
||||||
#define AQH_MSGTYPE_IPC_DATA_GETDATA_REQ 0x0500 /* AQH_GetDataDataIpcMsg */
|
|
||||||
#define AQH_MSGTYPE_IPC_DATA_GETDATA_RSP 0x0600 /* AQH_MultiDataDataIpcMsg */
|
|
||||||
|
|
||||||
#define AQH_MSGTYPE_IPC_DATA_GETLASTDATA_REQ 0x0700 /* AQH_GetDataDataIpcMsg */
|
|
||||||
#define AQH_MSGTYPE_IPC_DATA_GETLASTDATA_RSP 0x0800 /* AQH_MultiDataDataIpcMsg */
|
|
||||||
|
|
||||||
#define AQH_MSGTYPE_IPC_DATA_GETVALUES_REQ 0x0900 /* GWEN_IpcMsg */
|
|
||||||
#define AQH_MSGTYPE_IPC_DATA_GETVALUES_RSP 0x0a00 /* AQH_ValuesDataIpcMsg */
|
|
||||||
|
|
||||||
#define AQH_MSGTYPE_IPC_DATA_GETDEVICES_REQ 0x0b00 /* GWEN_IpcMsg */
|
|
||||||
#define AQH_MSGTYPE_IPC_DATA_GETDEVICES_RSP 0x0c00 /* AQH_DevicesDataIpcMsg */
|
|
||||||
|
|
||||||
#define AQH_MSGTYPE_IPC_DATA_MODDEVICE_REQ 0x0d00 /* AQH_DevicesDataIpcMsg */
|
|
||||||
|
|
||||||
#define AQH_MSGTYPE_IPC_DATA_ANNOUNCEVALUE 0x0e00 /* AQH_ValuesDataIpcMsg */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* utils */
|
|
||||||
AQHOME_API int AQH_DataIpc_WriteValueListAsTagsToBuffer(unsigned int tagType, const AQH_VALUE_LIST *valueList, GWEN_BUFFER *buf);
|
|
||||||
AQHOME_API int AQH_DataIpc_WriteValueAsTagToBuffer(unsigned int tagType, const AQH_VALUE *value, GWEN_BUFFER *buf);
|
|
||||||
AQHOME_API AQH_VALUE_LIST *AQH_DataIpc_ReadValuesFromTagList(const GWEN_TAG16_LIST *tagList, unsigned int wantedTagType);
|
|
||||||
AQHOME_API AQH_VALUE *AQH_DataIpc_ReadValueFromTagList(const GWEN_TAG16_LIST *tagList, unsigned int wantedTagType);
|
|
||||||
|
|
||||||
AQHOME_API int AQH_DataIpc_WriteDeviceListAsTagsToBuffer(unsigned int tagType, const AQH_DEVICE_LIST *deviceList, GWEN_BUFFER *buf);
|
|
||||||
AQHOME_API int AQH_DataIpc_WriteDeviceAsTagToBuffer(unsigned int tagType, const AQH_DEVICE *device, GWEN_BUFFER *buf);
|
|
||||||
AQHOME_API AQH_DEVICE_LIST *AQH_DataIpc_ReadDevicesFromTagList(const GWEN_TAG16_LIST *tagList, unsigned int wantedTagType);
|
|
||||||
AQHOME_API AQH_DEVICE *AQH_DataIpc_ReadDeviceFromTagList(const GWEN_TAG16_LIST *tagList, unsigned int wantedTagType);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,91 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
* 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 <aqhome/ipc/data/msg_data_connect.h>
|
|
||||||
#include <aqhome/ipc/data/ipc_data.h>
|
|
||||||
#include <aqhome/ipc/msg_ipc_tag16.h>
|
|
||||||
|
|
||||||
#include <gwenhywfar/msg.h>
|
|
||||||
#include <gwenhywfar/buffer.h>
|
|
||||||
|
|
||||||
#include <gwenhywfar/debug.h>
|
|
||||||
#include <gwenhywfar/msg_ipc.h>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define AQH_MSGDATA_CONNECT_MINSIZE GWEN_MSGIPC_OFFS_PAYLOAD
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
GWEN_MSG *AQH_ConnectDataIpcMsg_new(uint16_t code,
|
|
||||||
uint32_t msgId, uint32_t refMsgId,
|
|
||||||
const char *clientId, const char *userId, const char *password, uint32_t flags)
|
|
||||||
{
|
|
||||||
GWEN_MSG *msg;
|
|
||||||
GWEN_BUFFER *buf;
|
|
||||||
|
|
||||||
buf=GWEN_Buffer_new(0, 256, 0, 1);
|
|
||||||
if (clientId && *clientId)
|
|
||||||
GWEN_Tag16_WriteStringTagToBuffer(AQH_MSGDATA_CONNECT_TAGS_CLIENTID, clientId, buf);
|
|
||||||
if (userId && *userId)
|
|
||||||
GWEN_Tag16_WriteStringTagToBuffer(AQH_MSGDATA_CONNECT_TAGS_USERID, userId, buf);
|
|
||||||
if (password && *password)
|
|
||||||
GWEN_Tag16_WriteStringTagToBuffer(AQH_MSGDATA_CONNECT_TAGS_PASSWORD, password, buf);
|
|
||||||
GWEN_Tag16_WriteUint32TagToBuffer(AQH_MSGDATA_CONNECT_TAGS_FLAGS, flags, buf);
|
|
||||||
|
|
||||||
msg=AQH_Tag16IpcMsg_new(AQH_IPC_PROTOCOL_DATA_ID, AQH_IPC_PROTOCOL_DATA_VERSION, code, msgId, refMsgId,
|
|
||||||
GWEN_Buffer_GetUsedBytes(buf), (const uint8_t*) GWEN_Buffer_GetStart(buf));
|
|
||||||
GWEN_Buffer_free(buf);
|
|
||||||
return msg;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_ConnectDataIpcMsg_Parse(GWEN_MSG *msg, int doCopy)
|
|
||||||
{
|
|
||||||
AQH_Tag16IpcMsg_ExtendAndParse(msg, doCopy);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_ConnectDataIpcMsg_DumpToBuffer(const GWEN_MSG *msg, GWEN_BUFFER *dbuf, const char *sText)
|
|
||||||
{
|
|
||||||
if (GWEN_Msg_GetBytesInBuffer(msg)>=AQH_MSGDATA_CONNECT_MINSIZE) {
|
|
||||||
char *clientId;
|
|
||||||
char *userId;
|
|
||||||
uint32_t flags;
|
|
||||||
|
|
||||||
clientId=AQH_Tag16IpcMsg_GetTagDataAsNewString(msg, AQH_MSGDATA_CONNECT_TAGS_CLIENTID, NULL);
|
|
||||||
userId=AQH_Tag16IpcMsg_GetTagDataAsNewString(msg, AQH_MSGDATA_CONNECT_TAGS_USERID, NULL);
|
|
||||||
flags=AQH_Tag16IpcMsg_GetTagDataAsUint32(msg, AQH_MSGDATA_CONNECT_TAGS_FLAGS, 0);
|
|
||||||
|
|
||||||
GWEN_Buffer_AppendArgs(dbuf,
|
|
||||||
"CONNECT %s (code=%d, proto=%d, proto version=%d, clientId=%s, userId=%s, flags=%08x)\n",
|
|
||||||
sText?sText:"",
|
|
||||||
GWEN_IpcMsg_GetCode(msg),
|
|
||||||
GWEN_IpcMsg_GetProtoId(msg),
|
|
||||||
GWEN_IpcMsg_GetProtoVersion(msg),
|
|
||||||
clientId?clientId:"<empty>",
|
|
||||||
userId?userId:"<empty>",
|
|
||||||
flags);
|
|
||||||
free(userId);
|
|
||||||
free(clientId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
* 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 AQH_MSG_IPC_DATA_CONNECT_H
|
|
||||||
#define AQH_MSG_IPC_DATA_CONNECT_H
|
|
||||||
|
|
||||||
|
|
||||||
#include <aqhome/api.h>
|
|
||||||
|
|
||||||
#include <aqhome/data/value.h>
|
|
||||||
|
|
||||||
#include <gwenhywfar/msg_ipc.h>
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This message is used in request AQH_MSGTYPE_IPC_DATA_ADDVALUES_REQ and in response AQH_MSGTYPE_IPC_DATA_GETVALUES_RSP.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define AQH_MSGDATA_CONNECT_TAGS_CLIENTID 0x0001
|
|
||||||
#define AQH_MSGDATA_CONNECT_TAGS_USERID 0x0002
|
|
||||||
#define AQH_MSGDATA_CONNECT_TAGS_PASSWORD 0x0003
|
|
||||||
#define AQH_MSGDATA_CONNECT_TAGS_FLAGS 0x0004
|
|
||||||
|
|
||||||
#define AQH_MSGDATA_CONNECT_FLAGS_WANTUPDATES 0x0001
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
AQHOME_API GWEN_MSG *AQH_ConnectDataIpcMsg_new(uint16_t code,
|
|
||||||
uint32_t msgId, uint32_t refMsgId,
|
|
||||||
const char *clientId,
|
|
||||||
const char *userId, const char *password,
|
|
||||||
uint32_t flags);
|
|
||||||
|
|
||||||
AQHOME_API void AQH_ConnectDataIpcMsg_Parse(GWEN_MSG *msg, int doCopy);
|
|
||||||
|
|
||||||
AQHOME_API int AQH_ConnectDataIpcMsg_IsValid(const GWEN_MSG *msg);
|
|
||||||
AQHOME_API void AQH_ConnectDataIpcMsg_DumpToBuffer(const GWEN_MSG *msg, GWEN_BUFFER *dbuf, const char *sText);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,175 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
* 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 <aqhome/ipc/data/msg_data_datapoints.h>
|
|
||||||
#include <aqhome/ipc/data/ipc_data.h>
|
|
||||||
|
|
||||||
#include <gwenhywfar/msg.h>
|
|
||||||
#include <gwenhywfar/buffer.h>
|
|
||||||
|
|
||||||
#include <gwenhywfar/debug.h>
|
|
||||||
#include <gwenhywfar/msg_ipc.h>
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
|
|
||||||
#define AQH_MSGDATA_DATAPOINTS_OFFS_FLAGS 0 /* 4 bytes */
|
|
||||||
#define AQH_MSGDATA_DATAPOINTS_OFFS_NUMVALUES 4 /* 4 bytes */
|
|
||||||
|
|
||||||
#define AQH_MSGDATA_DATAPOINTS_OFFS_VALUEID 8 /* 8 byte */
|
|
||||||
#define AQH_MSGDATA_DATAPOINTS_OFFS_VALUENAME 16 /* 104 byte */
|
|
||||||
# define AQH_MSGDATA_DATAPOINTS_SIZE_VALUENAME 104
|
|
||||||
#define AQH_MSGDATA_DATAPOINTS_OFFS_VALUEUNITS 120 /* 16 byte */
|
|
||||||
# define AQH_MSGDATA_DATAPOINTS_SIZE_VALUEUNITS 16
|
|
||||||
#define AQH_MSGDATA_DATAPOINTS_OFFS_VALUES 136
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define AQH_MSGDATA_DATAPOINTS_PAYLOADSIZE (AQH_MSGDATA_DATAPOINTS_OFFS_VALUES)
|
|
||||||
#define AQH_MSGDATA_DATAPOINTS_MINSIZE (GWEN_MSGIPC_OFFS_PAYLOAD+AQH_MSGDATA_DATAPOINTS_PAYLOADSIZE)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
GWEN_MSG *AQH_DataPointsDataIpcMsg_new(uint16_t code, uint32_t msgId, uint32_t refMsgId, uint32_t flags,
|
|
||||||
uint64_t valueId, const char *valueName, const char *units,
|
|
||||||
const uint64_t *i64Ptr, int numOfDataPoints)
|
|
||||||
{
|
|
||||||
GWEN_MSG *msg;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
msg=GWEN_IpcMsg_new(AQH_IPC_PROTOCOL_DATA_ID, AQH_IPC_PROTOCOL_DATA_VERSION, code, msgId, refMsgId, 0, NULL);
|
|
||||||
GWEN_Msg_AddUint32(msg, flags);
|
|
||||||
GWEN_Msg_AddUint32(msg, numOfDataPoints);
|
|
||||||
GWEN_Msg_AddUint64(msg, valueId);
|
|
||||||
|
|
||||||
GWEN_Msg_AddStringWithTrailingNull(msg, valueName, AQH_MSGDATA_DATAPOINTS_SIZE_VALUENAME, 0);
|
|
||||||
GWEN_Msg_AddStringWithTrailingNull(msg, units, AQH_MSGDATA_DATAPOINTS_SIZE_VALUEUNITS, 0);
|
|
||||||
|
|
||||||
for (i=0; i<numOfDataPoints; i++) {
|
|
||||||
GWEN_Msg_AddUint64(msg, *(i64Ptr++)); /* timestamp */
|
|
||||||
GWEN_Msg_AddUint64(msg, *(i64Ptr++)); /* value */
|
|
||||||
}
|
|
||||||
GWEN_IpcMsg_AdjustMsgSize(msg);
|
|
||||||
|
|
||||||
return msg;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint32_t AQH_DataPointsDataIpcMsg_GetFlags(const GWEN_MSG *msg)
|
|
||||||
{
|
|
||||||
return GWEN_Msg_GetUint32At(msg, GWEN_MSGIPC_OFFS_PAYLOAD+AQH_MSGDATA_DATAPOINTS_OFFS_FLAGS, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint32_t AQH_DataPointsDataIpcMsg_GetNumValues(const GWEN_MSG *msg)
|
|
||||||
{
|
|
||||||
return GWEN_Msg_GetUint32At(msg, GWEN_MSGIPC_OFFS_PAYLOAD+AQH_MSGDATA_DATAPOINTS_OFFS_NUMVALUES, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint64_t AQH_DataPointsDataIpcMsg_GetValueId(const GWEN_MSG *msg)
|
|
||||||
{
|
|
||||||
return GWEN_Msg_GetUint64At(msg, GWEN_MSGIPC_OFFS_PAYLOAD+AQH_MSGDATA_DATAPOINTS_OFFS_VALUEID, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const char *AQH_DataPointsDataIpcMsg_GetValueName(const GWEN_MSG *msg)
|
|
||||||
{
|
|
||||||
if (GWEN_Msg_GetBytesInBuffer(msg)>=AQH_MSGDATA_DATAPOINTS_MINSIZE)
|
|
||||||
return (const char*) (GWEN_Msg_GetConstBuffer(msg)+GWEN_MSGIPC_OFFS_PAYLOAD+AQH_MSGDATA_DATAPOINTS_OFFS_VALUENAME);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const char *AQH_DataPointsDataIpcMsg_GetUnits(const GWEN_MSG *msg)
|
|
||||||
{
|
|
||||||
if (GWEN_Msg_GetBytesInBuffer(msg)>=AQH_MSGDATA_DATAPOINTS_MINSIZE)
|
|
||||||
return (const char*) (GWEN_Msg_GetConstBuffer(msg)+GWEN_MSGIPC_OFFS_PAYLOAD+AQH_MSGDATA_DATAPOINTS_OFFS_VALUEUNITS);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const uint64_t *AQH_DataPointsDataIpcMsg_GetDataPoints(const GWEN_MSG *msg)
|
|
||||||
{
|
|
||||||
if (GWEN_Msg_GetBytesInBuffer(msg)>=AQH_MSGDATA_DATAPOINTS_MINSIZE)
|
|
||||||
return (const uint64_t*) (GWEN_Msg_GetConstBuffer(msg)+GWEN_MSGIPC_OFFS_PAYLOAD+AQH_MSGDATA_DATAPOINTS_OFFS_VALUES);
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int AQH_DataPointsDataIpcMsg_IsValid(const GWEN_MSG *msg)
|
|
||||||
{
|
|
||||||
int msgLen;
|
|
||||||
int numValues;
|
|
||||||
const uint8_t *ptr;
|
|
||||||
|
|
||||||
msgLen=GWEN_Msg_GetBytesInBuffer(msg);
|
|
||||||
if (msgLen<AQH_MSGDATA_DATAPOINTS_MINSIZE) {
|
|
||||||
DBG_ERROR(AQH_LOGDOMAIN, "Message too small (%d<%d)", GWEN_Msg_GetBytesInBuffer(msg), AQH_MSGDATA_DATAPOINTS_MINSIZE);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
numValues=(int)AQH_DataPointsDataIpcMsg_GetNumValues(msg);
|
|
||||||
if (msgLen<(numValues*16)+AQH_MSGDATA_DATAPOINTS_OFFS_VALUES+GWEN_MSGIPC_OFFS_PAYLOAD) {
|
|
||||||
DBG_ERROR(AQH_LOGDOMAIN, "Message too small to contain %d values", numValues);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
ptr=GWEN_Msg_GetConstBuffer(msg);
|
|
||||||
if (ptr[GWEN_MSGIPC_OFFS_PAYLOAD+AQH_MSGDATA_DATAPOINTS_OFFS_VALUENAME+AQH_MSGDATA_DATAPOINTS_SIZE_VALUENAME-1]!=0) {
|
|
||||||
DBG_ERROR(AQH_LOGDOMAIN, "Name string for value is not null-terminated");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ptr[GWEN_MSGIPC_OFFS_PAYLOAD+AQH_MSGDATA_DATAPOINTS_OFFS_VALUEUNITS+AQH_MSGDATA_DATAPOINTS_SIZE_VALUEUNITS-1]!=0) {
|
|
||||||
DBG_ERROR(AQH_LOGDOMAIN, "Units string for value is not null-terminated");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_DataPointsDataIpcMsg_DumpToBuffer(const GWEN_MSG *msg, GWEN_BUFFER *dbuf, const char *sText)
|
|
||||||
{
|
|
||||||
if (GWEN_Msg_GetBytesInBuffer(msg)>=AQH_MSGDATA_DATAPOINTS_MINSIZE) {
|
|
||||||
const char *valueName;
|
|
||||||
|
|
||||||
valueName=AQH_DataPointsDataIpcMsg_GetValueName(msg);
|
|
||||||
GWEN_Buffer_AppendArgs(dbuf,
|
|
||||||
"DATAPOINTS %s (code=%d, proto=%d, proto version=%d, flags=0x%08x, valueName=%s, values=%d)\n",
|
|
||||||
sText?sText:"",
|
|
||||||
GWEN_IpcMsg_GetCode(msg),
|
|
||||||
GWEN_IpcMsg_GetProtoId(msg),
|
|
||||||
GWEN_IpcMsg_GetProtoVersion(msg),
|
|
||||||
(unsigned int)AQH_DataPointsDataIpcMsg_GetFlags(msg),
|
|
||||||
valueName?valueName:"<no name>",
|
|
||||||
AQH_DataPointsDataIpcMsg_GetNumValues(msg));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
* 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 AQH_MSG_IPC_DATA_DATAPOINTS_H
|
|
||||||
#define AQH_MSG_IPC_DATA_DATAPOINTS_H
|
|
||||||
|
|
||||||
|
|
||||||
#include <aqhome/api.h>
|
|
||||||
|
|
||||||
#include <aqhome/data/value.h>
|
|
||||||
|
|
||||||
#include <gwenhywfar/msg_ipc.h>
|
|
||||||
|
|
||||||
|
|
||||||
#define AQH_MSGDATA_DATAPOINTS_FLAGS_LASTMSG 0x0001
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
AQHOME_API GWEN_MSG *AQH_DataPointsDataIpcMsg_new(uint16_t code,
|
|
||||||
uint32_t msgId, uint32_t refMsgId,
|
|
||||||
uint32_t flags,
|
|
||||||
uint64_t valueId, const char *valueName, const char *units,
|
|
||||||
const uint64_t *i64Ptr, int numOfDataPoints);
|
|
||||||
|
|
||||||
AQHOME_API uint32_t AQH_DataPointsDataIpcMsg_GetFlags(const GWEN_MSG *msg);
|
|
||||||
AQHOME_API uint32_t AQH_DataPointsDataIpcMsg_GetNumValues(const GWEN_MSG *msg);
|
|
||||||
AQHOME_API uint64_t AQH_DataPointsDataIpcMsg_GetValueId(const GWEN_MSG *msg);
|
|
||||||
AQHOME_API const char *AQH_DataPointsDataIpcMsg_GetValueName(const GWEN_MSG *msg);
|
|
||||||
AQHOME_API const char *AQH_DataPointsDataIpcMsg_GetUnits(const GWEN_MSG *msg);
|
|
||||||
AQHOME_API const uint64_t *AQH_DataPointsDataIpcMsg_GetDataPoints(const GWEN_MSG *msg);
|
|
||||||
|
|
||||||
AQHOME_API int AQH_DataPointsDataIpcMsg_IsValid(const GWEN_MSG *msg);
|
|
||||||
AQHOME_API void AQH_DataPointsDataIpcMsg_DumpToBuffer(const GWEN_MSG *msg, GWEN_BUFFER *dbuf, const char *sText);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,153 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
* 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 <aqhome/ipc/data/msg_data_devices.h>
|
|
||||||
#include <aqhome/ipc/data/ipc_data.h>
|
|
||||||
#include <aqhome/ipc/msg_ipc_tag16.h>
|
|
||||||
|
|
||||||
#include <gwenhywfar/msg.h>
|
|
||||||
#include <gwenhywfar/buffer.h>
|
|
||||||
|
|
||||||
#include <gwenhywfar/debug.h>
|
|
||||||
#include <gwenhywfar/msg_ipc.h>
|
|
||||||
#include <gwenhywfar/text.h>
|
|
||||||
#include <gwenhywfar/tag16.h>
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
|
|
||||||
#define AQH_MSGDATA_DEVICES_MINSIZE GWEN_MSGIPC_OFFS_PAYLOAD
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------------------------------
|
|
||||||
* forward declarations
|
|
||||||
* ------------------------------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------------------------------
|
|
||||||
* code
|
|
||||||
* ------------------------------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
GWEN_MSG *AQH_DevicesDataIpcMsg_new(uint16_t code, uint32_t msgId, uint32_t refMsgId,
|
|
||||||
uint32_t flags, const AQH_DEVICE_LIST *deviceList)
|
|
||||||
{
|
|
||||||
GWEN_MSG *msg;
|
|
||||||
GWEN_BUFFER *buf;
|
|
||||||
int rv;
|
|
||||||
|
|
||||||
buf=GWEN_Buffer_new(0, 256, 0, 1);
|
|
||||||
GWEN_Tag16_WriteUint32TagToBuffer(AQH_MSGDATA_DEVICES_TAGS_FLAGS, flags, buf);
|
|
||||||
rv=AQH_DataIpc_WriteDeviceListAsTagsToBuffer(AQH_MSGDATA_DEVICES_TAGS_DEVICE, deviceList, buf);
|
|
||||||
if (rv<0) {
|
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "here (%d)", rv);
|
|
||||||
GWEN_Buffer_free(buf);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
msg=AQH_Tag16IpcMsg_new(AQH_IPC_PROTOCOL_DATA_ID, AQH_IPC_PROTOCOL_DATA_VERSION, code, msgId, refMsgId,
|
|
||||||
GWEN_Buffer_GetUsedBytes(buf), (const uint8_t*) GWEN_Buffer_GetStart(buf));
|
|
||||||
GWEN_Buffer_free(buf);
|
|
||||||
return msg;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
GWEN_MSG *AQH_DevicesDataIpcMsg_newForOneDevice(uint16_t code, uint32_t msgId, uint32_t refMsgId,
|
|
||||||
uint32_t flags, const AQH_DEVICE *device)
|
|
||||||
{
|
|
||||||
GWEN_MSG *msg;
|
|
||||||
GWEN_BUFFER *buf;
|
|
||||||
int rv;
|
|
||||||
|
|
||||||
buf=GWEN_Buffer_new(0, 256, 0, 1);
|
|
||||||
GWEN_Tag16_WriteUint32TagToBuffer(AQH_MSGDATA_DEVICES_TAGS_FLAGS, flags, buf);
|
|
||||||
rv=AQH_DataIpc_WriteDeviceAsTagToBuffer(AQH_MSGDATA_DEVICES_TAGS_DEVICE, device, buf);
|
|
||||||
if (rv<0) {
|
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "here (%d)", rv);
|
|
||||||
GWEN_Buffer_free(buf);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
msg=AQH_Tag16IpcMsg_new(AQH_IPC_PROTOCOL_DATA_ID, AQH_IPC_PROTOCOL_DATA_VERSION, code, msgId, refMsgId,
|
|
||||||
GWEN_Buffer_GetUsedBytes(buf), (const uint8_t*) GWEN_Buffer_GetStart(buf));
|
|
||||||
GWEN_Buffer_free(buf);
|
|
||||||
return msg;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_DevicesDataIpcMsg_Parse(GWEN_MSG *msg, int doCopy)
|
|
||||||
{
|
|
||||||
AQH_Tag16IpcMsg_ExtendAndParse(msg, doCopy);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
AQH_DEVICE_LIST *AQH_DevicesDataIpcMsg_ReadDeviceList(const GWEN_MSG *msg)
|
|
||||||
{
|
|
||||||
const GWEN_TAG16_LIST *tagList;
|
|
||||||
|
|
||||||
tagList=AQH_Tag16IpcMsg_GetTags(msg);
|
|
||||||
if (tagList) {
|
|
||||||
AQH_DEVICE_LIST *deviceList;
|
|
||||||
|
|
||||||
deviceList=AQH_DataIpc_ReadDevicesFromTagList(tagList, AQH_MSGDATA_DEVICES_TAGS_DEVICE);
|
|
||||||
if (deviceList==NULL) {
|
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "No device list received");
|
|
||||||
}
|
|
||||||
return deviceList;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "No tag16 list received");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
AQH_DEVICE *AQH_DevicesDataIpcMsg_ReadFirstDevice(const GWEN_MSG *msg)
|
|
||||||
{
|
|
||||||
return AQH_DataIpc_ReadDeviceFromTagList(AQH_Tag16IpcMsg_GetTags(msg), AQH_MSGDATA_DEVICES_TAGS_DEVICE);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint32_t AQH_DevicesDataIpcMsg_GetFlags(const GWEN_MSG *msg)
|
|
||||||
{
|
|
||||||
return AQH_Tag16IpcMsg_GetTagDataAsUint32(msg, AQH_MSGDATA_DEVICES_TAGS_FLAGS, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_DevicesDataIpcMsg_DumpToBuffer(const GWEN_MSG *msg, GWEN_BUFFER *dbuf, const char *sText)
|
|
||||||
{
|
|
||||||
if (GWEN_Msg_GetBytesInBuffer(msg)>=AQH_MSGDATA_DEVICES_MINSIZE) {
|
|
||||||
GWEN_Buffer_AppendArgs(dbuf,
|
|
||||||
"DEVICES %s (code=%d, proto=%d, proto version=%d, flags=0x%08x)\n",
|
|
||||||
sText?sText:"",
|
|
||||||
GWEN_IpcMsg_GetCode(msg),
|
|
||||||
GWEN_IpcMsg_GetProtoId(msg),
|
|
||||||
GWEN_IpcMsg_GetProtoVersion(msg),
|
|
||||||
(unsigned int)AQH_DevicesDataIpcMsg_GetFlags(msg));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
* 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 AQH_MSG_IPC_DATA_DEVICES_H
|
|
||||||
#define AQH_MSG_IPC_DATA_DEVICES_H
|
|
||||||
|
|
||||||
|
|
||||||
#include <aqhome/api.h>
|
|
||||||
|
|
||||||
#include <aqhome/data/device.h>
|
|
||||||
|
|
||||||
#include <gwenhywfar/msg_ipc.h>
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This message is used in request AQH_MSGTYPE_IPC_DATA_ADDDEVICES_REQ and in response AQH_MSGTYPE_IPC_DATA_GETDEVICES_RSP.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define AQH_MSGDATA_DEVICES_FLAGS_LASTMSG 0x0001
|
|
||||||
|
|
||||||
#define AQH_MSGDATA_DEVICES_TAGS_FLAGS 0x01
|
|
||||||
#define AQH_MSGDATA_DEVICES_TAGS_DEVICE 0xc2
|
|
||||||
|
|
||||||
|
|
||||||
AQHOME_API GWEN_MSG *AQH_DevicesDataIpcMsg_new(uint16_t code, uint32_t msgId, uint32_t refMsgId,
|
|
||||||
uint32_t flags, const AQH_DEVICE_LIST *deviceList);
|
|
||||||
AQHOME_API GWEN_MSG *AQH_DevicesDataIpcMsg_newForOneDevice(uint16_t code, uint32_t msgId, uint32_t refMsgId,
|
|
||||||
uint32_t flags, const AQH_DEVICE *device);
|
|
||||||
|
|
||||||
AQHOME_API void AQH_DevicesDataIpcMsg_Parse(GWEN_MSG *msg, int doCopy);
|
|
||||||
|
|
||||||
AQHOME_API AQH_DEVICE_LIST *AQH_DevicesDataIpcMsg_ReadDeviceList(const GWEN_MSG *msg);
|
|
||||||
AQHOME_API AQH_DEVICE *AQH_DevicesDataIpcMsg_ReadFirstDevice(const GWEN_MSG *msg);
|
|
||||||
|
|
||||||
|
|
||||||
AQHOME_API uint32_t AQH_DevicesDataIpcMsg_GetFlags(const GWEN_MSG *msg);
|
|
||||||
|
|
||||||
AQHOME_API void AQH_DevicesDataIpcMsg_DumpToBuffer(const GWEN_MSG *msg, GWEN_BUFFER *dbuf, const char *sText);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,88 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
* 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 <aqhome/ipc/data/msg_data_getdata.h>
|
|
||||||
#include <aqhome/ipc/data/ipc_data.h>
|
|
||||||
#include <aqhome/ipc/msg_ipc_tag16.h>
|
|
||||||
|
|
||||||
#include <gwenhywfar/msg.h>
|
|
||||||
#include <gwenhywfar/buffer.h>
|
|
||||||
|
|
||||||
#include <gwenhywfar/debug.h>
|
|
||||||
#include <gwenhywfar/msg_ipc.h>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define AQH_MSGDATA_GETDATA_MINSIZE GWEN_MSGIPC_OFFS_PAYLOAD
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
GWEN_MSG *AQH_GetDataDataIpcMsg_new(uint16_t code,
|
|
||||||
uint32_t msgId, uint32_t refMsgId,
|
|
||||||
const char *valueName, uint64_t tsBegin, uint64_t tsEnd, uint64_t num)
|
|
||||||
{
|
|
||||||
GWEN_MSG *msg;
|
|
||||||
GWEN_BUFFER *buf;
|
|
||||||
|
|
||||||
buf=GWEN_Buffer_new(0, 256, 0, 1);
|
|
||||||
if (valueName && *valueName)
|
|
||||||
GWEN_Tag16_WriteStringTagToBuffer(AQH_MSGDATA_GETDATA_TAGS_NAME, valueName, buf);
|
|
||||||
GWEN_Tag16_WriteUint64TagToBuffer(AQH_MSGDATA_GETDATA_TAGS_BEGIN, tsBegin, buf);
|
|
||||||
GWEN_Tag16_WriteUint64TagToBuffer(AQH_MSGDATA_GETDATA_TAGS_END, tsEnd, buf);
|
|
||||||
GWEN_Tag16_WriteUint64TagToBuffer(AQH_MSGDATA_GETDATA_TAGS_NUM, num, buf);
|
|
||||||
|
|
||||||
msg=AQH_Tag16IpcMsg_new(AQH_IPC_PROTOCOL_DATA_ID, AQH_IPC_PROTOCOL_DATA_VERSION, code, msgId, refMsgId,
|
|
||||||
GWEN_Buffer_GetUsedBytes(buf), (const uint8_t*) GWEN_Buffer_GetStart(buf));
|
|
||||||
GWEN_Buffer_free(buf);
|
|
||||||
return msg;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_GetDataDataIpcMsg_Parse(GWEN_MSG *msg, int doCopy)
|
|
||||||
{
|
|
||||||
AQH_Tag16IpcMsg_ExtendAndParse(msg, doCopy);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_GetDataDataIpcMsg_DumpToBuffer(const GWEN_MSG *msg, GWEN_BUFFER *dbuf, const char *sText)
|
|
||||||
{
|
|
||||||
if (GWEN_Msg_GetBytesInBuffer(msg)>=AQH_MSGDATA_GETDATA_MINSIZE) {
|
|
||||||
char *valueName=NULL;
|
|
||||||
uint64_t tsBegin=0;
|
|
||||||
uint64_t tsEnd=0;
|
|
||||||
|
|
||||||
valueName=AQH_Tag16IpcMsg_GetTagDataAsNewString(msg, AQH_MSGDATA_GETDATA_TAGS_NAME, NULL);
|
|
||||||
tsBegin=AQH_Tag16IpcMsg_GetTagDataAsUint64(msg, AQH_MSGDATA_GETDATA_TAGS_BEGIN, 0);
|
|
||||||
tsEnd=AQH_Tag16IpcMsg_GetTagDataAsUint64(msg, AQH_MSGDATA_GETDATA_TAGS_END, 0);
|
|
||||||
|
|
||||||
GWEN_Buffer_AppendArgs(dbuf,
|
|
||||||
"GETDATA %s (code=%d, proto=%d, proto version=%d, name=%s, tsBegin=%lu, tsEnd=%lu)\n",
|
|
||||||
sText?sText:"",
|
|
||||||
GWEN_IpcMsg_GetCode(msg),
|
|
||||||
GWEN_IpcMsg_GetProtoId(msg),
|
|
||||||
GWEN_IpcMsg_GetProtoVersion(msg),
|
|
||||||
valueName?valueName:"<empty>",
|
|
||||||
(unsigned long int) tsBegin,
|
|
||||||
(unsigned long int) tsEnd);
|
|
||||||
free(valueName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
* 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 AQH_MSG_IPC_DATA_GETDATA_H
|
|
||||||
#define AQH_MSG_IPC_DATA_GETDATA_H
|
|
||||||
|
|
||||||
|
|
||||||
#include <aqhome/api.h>
|
|
||||||
|
|
||||||
#include <aqhome/data/value.h>
|
|
||||||
|
|
||||||
#include <gwenhywfar/msg_ipc.h>
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This message is used in request AQH_MSGTYPE_IPC_DATA_ADDVALUE_REQ.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define AQH_MSGDATA_GETDATA_TAGS_NAME 0x0001
|
|
||||||
#define AQH_MSGDATA_GETDATA_TAGS_BEGIN 0x0020
|
|
||||||
#define AQH_MSGDATA_GETDATA_TAGS_END 0x0021
|
|
||||||
#define AQH_MSGDATA_GETDATA_TAGS_NUM 0x0022
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
AQHOME_API GWEN_MSG *AQH_GetDataDataIpcMsg_new(uint16_t code,
|
|
||||||
uint32_t msgId, uint32_t refMsgId,
|
|
||||||
const char *valueName, uint64_t tsBegin, uint64_t tsEnd, uint64_t num);
|
|
||||||
|
|
||||||
AQHOME_API void AQH_GetDataDataIpcMsg_Parse(GWEN_MSG *msg, int doCopy);
|
|
||||||
|
|
||||||
AQHOME_API void AQH_GetDataDataIpcMsg_DumpToBuffer(const GWEN_MSG *msg, GWEN_BUFFER *dbuf, const char *sText);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,160 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
* 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 <aqhome/ipc/data/msg_data_multidata.h>
|
|
||||||
#include <aqhome/ipc/data/ipc_data.h>
|
|
||||||
#include <aqhome/ipc/msg_ipc_tag16.h>
|
|
||||||
|
|
||||||
#include <gwenhywfar/msg.h>
|
|
||||||
#include <gwenhywfar/buffer.h>
|
|
||||||
|
|
||||||
#include <gwenhywfar/debug.h>
|
|
||||||
#include <gwenhywfar/msg_ipc.h>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define AQH_MSGDATA_MULTIDATA_MINSIZE GWEN_MSGIPC_OFFS_PAYLOAD
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
GWEN_MSG *AQH_MultiDataDataIpcMsg_new(uint16_t code,
|
|
||||||
uint32_t msgId, uint32_t refMsgId,
|
|
||||||
const AQH_VALUE *value, const uint64_t *i64Ptr, int numOfDataPoints)
|
|
||||||
{
|
|
||||||
GWEN_MSG *msg;
|
|
||||||
GWEN_BUFFER *buf;
|
|
||||||
int rv;
|
|
||||||
|
|
||||||
buf=GWEN_Buffer_new(0, 256, 0, 1);
|
|
||||||
|
|
||||||
rv=AQH_DataIpc_WriteValueAsTagToBuffer(AQH_MSGDATA_MULTIDATA_TAGS_VALUE, value, buf);
|
|
||||||
if (rv<0) {
|
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "here (%d)", rv);
|
|
||||||
GWEN_Buffer_free(buf);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (i64Ptr && numOfDataPoints)
|
|
||||||
GWEN_Tag16_WriteTagToBuffer(AQH_MSGDATA_MULTIDATA_TAGS_DATA, (const uint8_t*)i64Ptr, numOfDataPoints*2*sizeof(uint64_t), buf);
|
|
||||||
|
|
||||||
msg=AQH_Tag16IpcMsg_new(AQH_IPC_PROTOCOL_DATA_ID, AQH_IPC_PROTOCOL_DATA_VERSION, code, msgId, refMsgId,
|
|
||||||
GWEN_Buffer_GetUsedBytes(buf), (const uint8_t*) GWEN_Buffer_GetStart(buf));
|
|
||||||
GWEN_Buffer_free(buf);
|
|
||||||
return msg;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
GWEN_MSG *AQH_MultiDataDataIpcMsg_newForOne(uint16_t code,
|
|
||||||
uint32_t msgId, uint32_t refMsgId,
|
|
||||||
const AQH_VALUE *value, uint64_t timeStamp, double dataPoint)
|
|
||||||
{
|
|
||||||
GWEN_MSG *msg;
|
|
||||||
GWEN_BUFFER *buf;
|
|
||||||
int rv;
|
|
||||||
union {double f; uint64_t i;} u;
|
|
||||||
uint64_t arrayToSend[2];
|
|
||||||
|
|
||||||
buf=GWEN_Buffer_new(0, 256, 0, 1);
|
|
||||||
|
|
||||||
rv=AQH_DataIpc_WriteValueAsTagToBuffer(AQH_MSGDATA_MULTIDATA_TAGS_VALUE, value, buf);
|
|
||||||
if (rv<0) {
|
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "here (%d)", rv);
|
|
||||||
GWEN_Buffer_free(buf);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
arrayToSend[0]=timeStamp;
|
|
||||||
u.f=dataPoint;
|
|
||||||
arrayToSend[1]=u.i;
|
|
||||||
GWEN_Tag16_WriteTagToBuffer(AQH_MSGDATA_MULTIDATA_TAGS_DATA, (const uint8_t*) arrayToSend, 2*sizeof(uint64_t), buf);
|
|
||||||
|
|
||||||
msg=AQH_Tag16IpcMsg_new(AQH_IPC_PROTOCOL_DATA_ID, AQH_IPC_PROTOCOL_DATA_VERSION, code, msgId, refMsgId,
|
|
||||||
GWEN_Buffer_GetUsedBytes(buf), (const uint8_t*) GWEN_Buffer_GetStart(buf));
|
|
||||||
GWEN_Buffer_free(buf);
|
|
||||||
return msg;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_MultiDataDataIpcMsg_Parse(GWEN_MSG *msg, int doCopy)
|
|
||||||
{
|
|
||||||
AQH_Tag16IpcMsg_ExtendAndParse(msg, doCopy);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
AQH_VALUE *AQH_MultiDataDataIpcMsg_ReadValue(const GWEN_MSG *msg)
|
|
||||||
{
|
|
||||||
return AQH_DataIpc_ReadValueFromTagList(AQH_Tag16IpcMsg_GetTags(msg), AQH_MSGDATA_MULTIDATA_TAGS_VALUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_ValuesDataIpcMsg_GetDatapoints(const GWEN_MSG *msg, const uint64_t **pDataPtr, uint64_t *pNumberOfPoints)
|
|
||||||
{
|
|
||||||
if (msg) {
|
|
||||||
const GWEN_TAG16 *tag;
|
|
||||||
unsigned int numberOfPoints;
|
|
||||||
const uint64_t *dataPoints;
|
|
||||||
|
|
||||||
tag=AQH_Tag16IpcMsg_FindFirstTagByType(msg, AQH_MSGDATA_MULTIDATA_TAGS_DATA);
|
|
||||||
numberOfPoints=(tag?GWEN_Tag16_GetTagLength(tag):0)/(2*sizeof(uint64_t));
|
|
||||||
dataPoints=tag?((const uint64_t*) GWEN_Tag16_GetTagData(tag)):NULL;
|
|
||||||
if (numberOfPoints>0 && dataPoints) {
|
|
||||||
*pDataPtr=dataPoints;
|
|
||||||
*pNumberOfPoints=numberOfPoints;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_MultiDataDataIpcMsg_DumpToBuffer(const GWEN_MSG *msg, GWEN_BUFFER *dbuf, const char *sText)
|
|
||||||
{
|
|
||||||
if (GWEN_Msg_GetBytesInBuffer(msg)>=AQH_MSGDATA_MULTIDATA_MINSIZE) {
|
|
||||||
const GWEN_TAG16 *tag;
|
|
||||||
AQH_VALUE *value;
|
|
||||||
const char *valueName;
|
|
||||||
const char *valueUnits;
|
|
||||||
int valueType;
|
|
||||||
unsigned int numberOfPoints=0;
|
|
||||||
|
|
||||||
value=AQH_MultiDataDataIpcMsg_ReadValue(msg);
|
|
||||||
valueName=value?AQH_Value_GetNameForSystem(value):NULL;
|
|
||||||
valueUnits=value?AQH_Value_GetValueUnits(value):NULL;
|
|
||||||
valueType=value?AQH_Value_GetValueType(value):0;
|
|
||||||
|
|
||||||
tag=AQH_Tag16IpcMsg_FindFirstTagByType(msg, AQH_MSGDATA_MULTIDATA_TAGS_DATA);
|
|
||||||
numberOfPoints=(tag?GWEN_Tag16_GetTagLength(tag):0)/(2*sizeof(uint64_t));
|
|
||||||
|
|
||||||
GWEN_Buffer_AppendArgs(dbuf,
|
|
||||||
"MULTIDATA %s (code=%d, proto=%d, proto version=%d, name=%s, units=%s, type=%d, datapoints=%u)\n",
|
|
||||||
sText?sText:"",
|
|
||||||
GWEN_IpcMsg_GetCode(msg),
|
|
||||||
GWEN_IpcMsg_GetProtoId(msg),
|
|
||||||
GWEN_IpcMsg_GetProtoVersion(msg),
|
|
||||||
valueName?valueName:"<empty>",
|
|
||||||
valueUnits?valueUnits:"<empty>",
|
|
||||||
valueType,
|
|
||||||
numberOfPoints);
|
|
||||||
AQH_Value_free(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
* 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 AQH_MSG_IPC_DATA_MULTIDATA_H
|
|
||||||
#define AQH_MSG_IPC_DATA_MULTIDATA_H
|
|
||||||
|
|
||||||
|
|
||||||
#include <aqhome/api.h>
|
|
||||||
|
|
||||||
#include <aqhome/data/value.h>
|
|
||||||
|
|
||||||
#include <gwenhywfar/msg_ipc.h>
|
|
||||||
|
|
||||||
|
|
||||||
#define AQH_MSGDATA_MULTIDATA_TAGS_VALUE 0xc1
|
|
||||||
#define AQH_MSGDATA_MULTIDATA_TAGS_DATA 0xc2
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
AQHOME_API GWEN_MSG *AQH_MultiDataDataIpcMsg_new(uint16_t code,
|
|
||||||
uint32_t msgId, uint32_t refMsgId,
|
|
||||||
const AQH_VALUE *value, const uint64_t *i64Ptr, int numOfDataPoints);
|
|
||||||
AQHOME_API GWEN_MSG *AQH_MultiDataDataIpcMsg_newForOne(uint16_t code,
|
|
||||||
uint32_t msgId, uint32_t refMsgId,
|
|
||||||
const AQH_VALUE *value, uint64_t timeStamp, double dataPoint);
|
|
||||||
|
|
||||||
AQHOME_API void AQH_MultiDataDataIpcMsg_Parse(GWEN_MSG *msg, int doCopy);
|
|
||||||
AQHOME_API AQH_VALUE *AQH_MultiDataDataIpcMsg_ReadValue(const GWEN_MSG *msg);
|
|
||||||
AQHOME_API AQH_VALUE *AQH_ValuesDataIpcMsg_ReadFirstValue(const GWEN_MSG *msg);
|
|
||||||
AQHOME_API void AQH_ValuesDataIpcMsg_GetDatapoints(const GWEN_MSG *msg, const uint64_t **pDataPtr, uint64_t *pNumberOfPoints);
|
|
||||||
|
|
||||||
AQHOME_API void AQH_MultiDataDataIpcMsg_DumpToBuffer(const GWEN_MSG *msg, GWEN_BUFFER *dbuf, const char *sText);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,107 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
* 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 <config.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <aqhome/ipc/data/msg_data_set.h>
|
|
||||||
#include <aqhome/ipc/data/ipc_data.h>
|
|
||||||
#include <aqhome/ipc/msg_ipc_tag16.h>
|
|
||||||
|
|
||||||
#include <gwenhywfar/msg.h>
|
|
||||||
#include <gwenhywfar/buffer.h>
|
|
||||||
|
|
||||||
#include <gwenhywfar/debug.h>
|
|
||||||
#include <gwenhywfar/msg_ipc.h>
|
|
||||||
#include <gwenhywfar/text.h>
|
|
||||||
#include <gwenhywfar/tag16.h>
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
|
|
||||||
#define AQH_MSGDATA_SET_MINSIZE GWEN_MSGIPC_OFFS_PAYLOAD
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------------------------------
|
|
||||||
* forward declarations
|
|
||||||
* ------------------------------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------------------------------
|
|
||||||
* code
|
|
||||||
* ------------------------------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
GWEN_MSG *AQH_SetDataIpcMsg_new(uint16_t code,
|
|
||||||
uint32_t msgId, uint32_t refMsgId,
|
|
||||||
const AQH_VALUE *value, const char *data)
|
|
||||||
{
|
|
||||||
GWEN_MSG *msg;
|
|
||||||
GWEN_BUFFER *buf;
|
|
||||||
int rv;
|
|
||||||
|
|
||||||
buf=GWEN_Buffer_new(0, 256, 0, 1);
|
|
||||||
rv=AQH_DataIpc_WriteValueAsTagToBuffer(AQH_MSGDATA_SET_TAGS_VALUE, value, buf);
|
|
||||||
if (rv<0) {
|
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "here (%d)", rv);
|
|
||||||
GWEN_Buffer_free(buf);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if (data && *data)
|
|
||||||
GWEN_Tag16_WriteStringTagToBuffer(AQH_MSGDATA_SET_TAGS_DATA, data, buf);
|
|
||||||
|
|
||||||
|
|
||||||
msg=AQH_Tag16IpcMsg_new(AQH_IPC_PROTOCOL_DATA_ID, AQH_IPC_PROTOCOL_DATA_VERSION, code, msgId, refMsgId,
|
|
||||||
GWEN_Buffer_GetUsedBytes(buf), (const uint8_t*) GWEN_Buffer_GetStart(buf));
|
|
||||||
GWEN_Buffer_free(buf);
|
|
||||||
return msg;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_SetDataIpcMsg_Parse(GWEN_MSG *msg, int doCopy)
|
|
||||||
{
|
|
||||||
AQH_Tag16IpcMsg_ExtendAndParse(msg, doCopy);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
AQH_VALUE *AQH_SetDataIpcMsg_ReadValue(const GWEN_MSG *msg)
|
|
||||||
{
|
|
||||||
return AQH_DataIpc_ReadValueFromTagList(AQH_Tag16IpcMsg_GetTags(msg), AQH_MSGDATA_SET_TAGS_VALUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
char *AQH_SetDataIpcMsg_ReadData(const GWEN_MSG *msg)
|
|
||||||
{
|
|
||||||
return AQH_Tag16IpcMsg_GetTagDataAsNewString(msg, AQH_MSGDATA_SET_TAGS_DATA, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_SetDataIpcMsg_DumpToBuffer(const GWEN_MSG *msg, GWEN_BUFFER *dbuf, const char *sText)
|
|
||||||
{
|
|
||||||
if (GWEN_Msg_GetBytesInBuffer(msg)>=AQH_MSGDATA_SET_MINSIZE) {
|
|
||||||
GWEN_Buffer_AppendArgs(dbuf,
|
|
||||||
"SET %s (code=%d, proto=%d, proto version=%d)\n",
|
|
||||||
sText?sText:"",
|
|
||||||
GWEN_IpcMsg_GetCode(msg),
|
|
||||||
GWEN_IpcMsg_GetProtoId(msg),
|
|
||||||
GWEN_IpcMsg_GetProtoVersion(msg));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
* 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 AQH_MSG_IPC_DATA_SET_H
|
|
||||||
#define AQH_MSG_IPC_DATA_SET_H
|
|
||||||
|
|
||||||
|
|
||||||
#include <aqhome/api.h>
|
|
||||||
|
|
||||||
#include <aqhome/data/value.h>
|
|
||||||
|
|
||||||
#include <gwenhywfar/msg_ipc.h>
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define AQH_MSGDATA_SET_TAGS_VALUE 0xc1
|
|
||||||
#define AQH_MSGDATA_SET_TAGS_DATA 0x02
|
|
||||||
|
|
||||||
|
|
||||||
AQHOME_API GWEN_MSG *AQH_SetDataIpcMsg_new(uint16_t code,
|
|
||||||
uint32_t msgId, uint32_t refMsgId,
|
|
||||||
const AQH_VALUE *value, const char *data);
|
|
||||||
AQHOME_API void AQH_SetDataIpcMsg_Parse(GWEN_MSG *msg, int doCopy);
|
|
||||||
AQHOME_API AQH_VALUE *AQH_SetDataIpcMsg_ReadValue(const GWEN_MSG *msg);
|
|
||||||
AQHOME_API char *AQH_SetDataIpcMsg_ReadData(const GWEN_MSG *msg);
|
|
||||||
AQHOME_API void AQH_SetDataIpcMsg_DumpToBuffer(const GWEN_MSG *msg, GWEN_BUFFER *dbuf, const char *sText);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,155 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
* 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 <aqhome/ipc/data/msg_data_values.h>
|
|
||||||
#include <aqhome/ipc/data/ipc_data.h>
|
|
||||||
#include <aqhome/ipc/msg_ipc_tag16.h>
|
|
||||||
|
|
||||||
#include <gwenhywfar/msg.h>
|
|
||||||
#include <gwenhywfar/buffer.h>
|
|
||||||
|
|
||||||
#include <gwenhywfar/debug.h>
|
|
||||||
#include <gwenhywfar/msg_ipc.h>
|
|
||||||
#include <gwenhywfar/text.h>
|
|
||||||
#include <gwenhywfar/tag16.h>
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
|
|
||||||
#define AQH_MSGDATA_VALUES_MINSIZE GWEN_MSGIPC_OFFS_PAYLOAD
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------------------------------
|
|
||||||
* forward declarations
|
|
||||||
* ------------------------------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------------------------------
|
|
||||||
* code
|
|
||||||
* ------------------------------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
GWEN_MSG *AQH_ValuesDataIpcMsg_new(uint16_t code,
|
|
||||||
uint32_t msgId, uint32_t refMsgId,
|
|
||||||
uint32_t flags, const AQH_VALUE_LIST *valueList)
|
|
||||||
{
|
|
||||||
GWEN_MSG *msg;
|
|
||||||
GWEN_BUFFER *buf;
|
|
||||||
int rv;
|
|
||||||
|
|
||||||
buf=GWEN_Buffer_new(0, 256, 0, 1);
|
|
||||||
GWEN_Tag16_WriteUint32TagToBuffer(AQH_MSGDATA_VALUES_TAGS_FLAGS, flags, buf);
|
|
||||||
rv=AQH_DataIpc_WriteValueListAsTagsToBuffer(AQH_MSGDATA_VALUES_TAGS_VALUE, valueList, buf);
|
|
||||||
if (rv<0) {
|
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "here (%d)", rv);
|
|
||||||
GWEN_Buffer_free(buf);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
msg=AQH_Tag16IpcMsg_new(AQH_IPC_PROTOCOL_DATA_ID, AQH_IPC_PROTOCOL_DATA_VERSION, code, msgId, refMsgId,
|
|
||||||
GWEN_Buffer_GetUsedBytes(buf), (const uint8_t*) GWEN_Buffer_GetStart(buf));
|
|
||||||
GWEN_Buffer_free(buf);
|
|
||||||
return msg;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
GWEN_MSG *AQH_ValuesDataIpcMsg_newForOneValue(uint16_t code,
|
|
||||||
uint32_t msgId, uint32_t refMsgId,
|
|
||||||
uint32_t flags, const AQH_VALUE *value)
|
|
||||||
{
|
|
||||||
GWEN_MSG *msg;
|
|
||||||
GWEN_BUFFER *buf;
|
|
||||||
int rv;
|
|
||||||
|
|
||||||
buf=GWEN_Buffer_new(0, 256, 0, 1);
|
|
||||||
GWEN_Tag16_WriteUint32TagToBuffer(AQH_MSGDATA_VALUES_TAGS_FLAGS, flags, buf);
|
|
||||||
rv=AQH_DataIpc_WriteValueAsTagToBuffer(AQH_MSGDATA_VALUES_TAGS_VALUE, value, buf);
|
|
||||||
if (rv<0) {
|
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "here (%d)", rv);
|
|
||||||
GWEN_Buffer_free(buf);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
msg=AQH_Tag16IpcMsg_new(AQH_IPC_PROTOCOL_DATA_ID, AQH_IPC_PROTOCOL_DATA_VERSION, code, msgId, refMsgId,
|
|
||||||
GWEN_Buffer_GetUsedBytes(buf), (const uint8_t*) GWEN_Buffer_GetStart(buf));
|
|
||||||
GWEN_Buffer_free(buf);
|
|
||||||
return msg;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_ValuesDataIpcMsg_Parse(GWEN_MSG *msg, int doCopy)
|
|
||||||
{
|
|
||||||
AQH_Tag16IpcMsg_ExtendAndParse(msg, doCopy);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
AQH_VALUE_LIST *AQH_ValuesDataIpcMsg_ReadValueList(const GWEN_MSG *msg)
|
|
||||||
{
|
|
||||||
const GWEN_TAG16_LIST *tagList;
|
|
||||||
|
|
||||||
tagList=AQH_Tag16IpcMsg_GetTags(msg);
|
|
||||||
if (tagList) {
|
|
||||||
AQH_VALUE_LIST *valueList;
|
|
||||||
|
|
||||||
valueList=AQH_DataIpc_ReadValuesFromTagList(tagList, AQH_MSGDATA_VALUES_TAGS_VALUE);
|
|
||||||
if (valueList==NULL) {
|
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "No value list received");
|
|
||||||
}
|
|
||||||
return valueList;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "No tag16 list received");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
AQH_VALUE *AQH_ValuesDataIpcMsg_ReadFirstValue(const GWEN_MSG *msg)
|
|
||||||
{
|
|
||||||
return AQH_DataIpc_ReadValueFromTagList(AQH_Tag16IpcMsg_GetTags(msg), AQH_MSGDATA_VALUES_TAGS_VALUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint32_t AQH_ValuesDataIpcMsg_GetFlags(const GWEN_MSG *msg)
|
|
||||||
{
|
|
||||||
return AQH_Tag16IpcMsg_GetTagDataAsUint32(msg, AQH_MSGDATA_VALUES_TAGS_FLAGS, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_ValuesDataIpcMsg_DumpToBuffer(const GWEN_MSG *msg, GWEN_BUFFER *dbuf, const char *sText)
|
|
||||||
{
|
|
||||||
if (GWEN_Msg_GetBytesInBuffer(msg)>=AQH_MSGDATA_VALUES_MINSIZE) {
|
|
||||||
GWEN_Buffer_AppendArgs(dbuf,
|
|
||||||
"VALUES %s (code=%d, proto=%d, proto version=%d, flags=0x%08x)\n",
|
|
||||||
sText?sText:"",
|
|
||||||
GWEN_IpcMsg_GetCode(msg),
|
|
||||||
GWEN_IpcMsg_GetProtoId(msg),
|
|
||||||
GWEN_IpcMsg_GetProtoVersion(msg),
|
|
||||||
(unsigned int)AQH_ValuesDataIpcMsg_GetFlags(msg));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
* 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 AQH_MSG_IPC_DATA_VALUES_H
|
|
||||||
#define AQH_MSG_IPC_DATA_VALUES_H
|
|
||||||
|
|
||||||
|
|
||||||
#include <aqhome/api.h>
|
|
||||||
|
|
||||||
#include <aqhome/data/value.h>
|
|
||||||
|
|
||||||
#include <gwenhywfar/msg_ipc.h>
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This message is used in request AQH_MSGTYPE_IPC_DATA_ADDVALUES_REQ and in response AQH_MSGTYPE_IPC_DATA_GETVALUES_RSP.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define AQH_MSGDATA_VALUES_FLAGS_LASTMSG 0x0001
|
|
||||||
|
|
||||||
#define AQH_MSGDATA_VALUES_TAGS_FLAGS 0x01
|
|
||||||
#define AQH_MSGDATA_VALUES_TAGS_VALUE 0xc2
|
|
||||||
|
|
||||||
|
|
||||||
AQHOME_API GWEN_MSG *AQH_ValuesDataIpcMsg_new(uint16_t code,
|
|
||||||
uint32_t msgId, uint32_t refMsgId,
|
|
||||||
uint32_t flags, const AQH_VALUE_LIST *valueList);
|
|
||||||
AQHOME_API GWEN_MSG *AQH_ValuesDataIpcMsg_newForOneValue(uint16_t code,
|
|
||||||
uint32_t msgId, uint32_t refMsgId,
|
|
||||||
uint32_t flags, const AQH_VALUE *value);
|
|
||||||
|
|
||||||
AQHOME_API void AQH_ValuesDataIpcMsg_Parse(GWEN_MSG *msg, int doCopy);
|
|
||||||
|
|
||||||
AQHOME_API AQH_VALUE_LIST *AQH_ValuesDataIpcMsg_ReadValueList(const GWEN_MSG *msg);
|
|
||||||
AQHOME_API AQH_VALUE *AQH_ValuesDataIpcMsg_ReadFirstValue(const GWEN_MSG *msg);
|
|
||||||
|
|
||||||
|
|
||||||
AQHOME_API uint32_t AQH_ValuesDataIpcMsg_GetFlags(const GWEN_MSG *msg);
|
|
||||||
|
|
||||||
AQHOME_API void AQH_ValuesDataIpcMsg_DumpToBuffer(const GWEN_MSG *msg, GWEN_BUFFER *dbuf, const char *sText);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,277 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
* 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 "aqhome/ipc/endpoint_ipc_p.h"
|
|
||||||
|
|
||||||
#include "aqhome/ipc/msg_ipc_result.h"
|
|
||||||
|
|
||||||
#include <gwenhywfar/endpoint_ipc.h>
|
|
||||||
#include <gwenhywfar/msg_ipc.h>
|
|
||||||
#include <gwenhywfar/debug.h>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define AQH_MSG_ENDPOINT_IPC_NAME "ipc"
|
|
||||||
|
|
||||||
|
|
||||||
GWEN_INHERIT(GWEN_MSG_ENDPOINT, AQH_ENDPOINT_IPC)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------------------------------
|
|
||||||
* forward declarations
|
|
||||||
* ------------------------------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
static void GWENHYWFAR_CB _freeData(void *bp, void *p);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------------------------------
|
|
||||||
* implementations
|
|
||||||
* ------------------------------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
void AQH_IpcEndpoint_Extend(GWEN_MSG_ENDPOINT *ep)
|
|
||||||
{
|
|
||||||
AQH_ENDPOINT_IPC *xep;
|
|
||||||
|
|
||||||
GWEN_NEW_OBJECT(AQH_ENDPOINT_IPC, xep);
|
|
||||||
GWEN_INHERIT_SETDATA(GWEN_MSG_ENDPOINT, AQH_ENDPOINT_IPC, ep, xep, _freeData);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void _freeData(GWEN_UNUSED void *bp, void *p)
|
|
||||||
{
|
|
||||||
AQH_ENDPOINT_IPC *xep;
|
|
||||||
|
|
||||||
xep=(AQH_ENDPOINT_IPC*) p;
|
|
||||||
|
|
||||||
free(xep->serviceName);
|
|
||||||
free(xep->userName);
|
|
||||||
free(xep->password);
|
|
||||||
|
|
||||||
GWEN_FREE_OBJECT(xep);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint32_t AQH_IpcEndpoint_GetAcceptedMsgGroups(const GWEN_MSG_ENDPOINT *ep)
|
|
||||||
{
|
|
||||||
if (ep) {
|
|
||||||
AQH_ENDPOINT_IPC *xep;
|
|
||||||
|
|
||||||
xep=GWEN_INHERIT_GETDATA(GWEN_MSG_ENDPOINT, AQH_ENDPOINT_IPC, ep);
|
|
||||||
if (xep) {
|
|
||||||
return xep->acceptedMsgGroups;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_IpcEndpoint_SetAcceptedMsgGroups(GWEN_MSG_ENDPOINT *ep, uint32_t i)
|
|
||||||
{
|
|
||||||
if (ep) {
|
|
||||||
AQH_ENDPOINT_IPC *xep;
|
|
||||||
|
|
||||||
xep=GWEN_INHERIT_GETDATA(GWEN_MSG_ENDPOINT, AQH_ENDPOINT_IPC, ep);
|
|
||||||
if (xep)
|
|
||||||
xep->acceptedMsgGroups=i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_IpcEndpoint_AddAcceptedMsgGroups(GWEN_MSG_ENDPOINT *ep, uint32_t i)
|
|
||||||
{
|
|
||||||
if (ep) {
|
|
||||||
AQH_ENDPOINT_IPC *xep;
|
|
||||||
|
|
||||||
xep=GWEN_INHERIT_GETDATA(GWEN_MSG_ENDPOINT, AQH_ENDPOINT_IPC, ep);
|
|
||||||
if (xep)
|
|
||||||
xep->acceptedMsgGroups|=i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_IpcEndpoint_SubAcceptedMsgGroups(GWEN_MSG_ENDPOINT *ep, uint32_t i)
|
|
||||||
{
|
|
||||||
if (ep) {
|
|
||||||
AQH_ENDPOINT_IPC *xep;
|
|
||||||
|
|
||||||
xep=GWEN_INHERIT_GETDATA(GWEN_MSG_ENDPOINT, AQH_ENDPOINT_IPC, ep);
|
|
||||||
if (xep)
|
|
||||||
xep->acceptedMsgGroups&=~i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const char *AQH_IpcEndpoint_GetServiceName(const GWEN_MSG_ENDPOINT *ep)
|
|
||||||
{
|
|
||||||
if (ep) {
|
|
||||||
AQH_ENDPOINT_IPC *xep;
|
|
||||||
|
|
||||||
xep=GWEN_INHERIT_GETDATA(GWEN_MSG_ENDPOINT, AQH_ENDPOINT_IPC, ep);
|
|
||||||
if (xep)
|
|
||||||
return xep->serviceName;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_IpcEndpoint_SetServiceName(GWEN_MSG_ENDPOINT *ep, const char *s)
|
|
||||||
{
|
|
||||||
if (ep) {
|
|
||||||
AQH_ENDPOINT_IPC *xep;
|
|
||||||
|
|
||||||
xep=GWEN_INHERIT_GETDATA(GWEN_MSG_ENDPOINT, AQH_ENDPOINT_IPC, ep);
|
|
||||||
if (xep) {
|
|
||||||
free(xep->serviceName);
|
|
||||||
xep->serviceName=s?strdup(s):NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const char *AQH_IpcEndpoint_GetUserName(const GWEN_MSG_ENDPOINT *ep)
|
|
||||||
{
|
|
||||||
if (ep) {
|
|
||||||
AQH_ENDPOINT_IPC *xep;
|
|
||||||
|
|
||||||
xep=GWEN_INHERIT_GETDATA(GWEN_MSG_ENDPOINT, AQH_ENDPOINT_IPC, ep);
|
|
||||||
if (xep)
|
|
||||||
return xep->userName;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_IpcEndpoint_SetUserName(GWEN_MSG_ENDPOINT *ep, const char *s)
|
|
||||||
{
|
|
||||||
if (ep) {
|
|
||||||
AQH_ENDPOINT_IPC *xep;
|
|
||||||
|
|
||||||
xep=GWEN_INHERIT_GETDATA(GWEN_MSG_ENDPOINT, AQH_ENDPOINT_IPC, ep);
|
|
||||||
if (xep) {
|
|
||||||
free(xep->userName);
|
|
||||||
xep->userName=s?strdup(s):NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const char *AQH_IpcEndpoint_GetPassword(const GWEN_MSG_ENDPOINT *ep)
|
|
||||||
{
|
|
||||||
if (ep) {
|
|
||||||
AQH_ENDPOINT_IPC *xep;
|
|
||||||
|
|
||||||
xep=GWEN_INHERIT_GETDATA(GWEN_MSG_ENDPOINT, AQH_ENDPOINT_IPC, ep);
|
|
||||||
if (xep)
|
|
||||||
return xep->password;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_IpcEndpoint_SetPassword(GWEN_MSG_ENDPOINT *ep, const char *s)
|
|
||||||
{
|
|
||||||
if (ep) {
|
|
||||||
AQH_ENDPOINT_IPC *xep;
|
|
||||||
|
|
||||||
xep=GWEN_INHERIT_GETDATA(GWEN_MSG_ENDPOINT, AQH_ENDPOINT_IPC, ep);
|
|
||||||
if (xep) {
|
|
||||||
free(xep->password);
|
|
||||||
xep->password=s?strdup(s):NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint32_t AQH_IpcEndpoint_GetPermissions(const GWEN_MSG_ENDPOINT *ep)
|
|
||||||
{
|
|
||||||
if (ep) {
|
|
||||||
AQH_ENDPOINT_IPC *xep;
|
|
||||||
|
|
||||||
xep=GWEN_INHERIT_GETDATA(GWEN_MSG_ENDPOINT, AQH_ENDPOINT_IPC, ep);
|
|
||||||
if (xep)
|
|
||||||
return xep->permissions;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_IpcEndpoint_SetPermissions(GWEN_MSG_ENDPOINT *ep, uint32_t i)
|
|
||||||
{
|
|
||||||
if (ep) {
|
|
||||||
AQH_ENDPOINT_IPC *xep;
|
|
||||||
|
|
||||||
xep=GWEN_INHERIT_GETDATA(GWEN_MSG_ENDPOINT, AQH_ENDPOINT_IPC, ep);
|
|
||||||
if (xep)
|
|
||||||
xep->permissions=i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
GWEN_MSG_ENDPOINT *AQH_IpcEndpoint_CreateIpcTcpClient(const char *host, int port, const char *name, int groupId)
|
|
||||||
{
|
|
||||||
GWEN_MSG_ENDPOINT *ep;
|
|
||||||
|
|
||||||
ep=GWEN_IpcEndpoint_CreateIpcTcpClient(host, port, name?name:AQH_MSG_ENDPOINT_IPC_NAME, groupId);
|
|
||||||
AQH_IpcEndpoint_Extend(ep);
|
|
||||||
return ep;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
GWEN_MSG_ENDPOINT *AQH_IpcEndpoint_CreateIpcTcpServiceForSocket(GWEN_SOCKET *sk, const char *name, int groupId)
|
|
||||||
{
|
|
||||||
GWEN_MSG_ENDPOINT *ep;
|
|
||||||
|
|
||||||
ep=GWEN_IpcEndpoint_CreateIpcTcpServiceForSocket(sk, name?name:AQH_MSG_ENDPOINT_IPC_NAME, groupId);
|
|
||||||
AQH_IpcEndpoint_Extend(ep);
|
|
||||||
return ep;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_IpcEndpoint_SendResponseResult(GWEN_MSG_ENDPOINT *ep, uint32_t refMsgId, uint16_t code, uint32_t resultCode)
|
|
||||||
{
|
|
||||||
if (ep) {
|
|
||||||
GWEN_MSG *msgOut;
|
|
||||||
uint32_t msgId;
|
|
||||||
|
|
||||||
msgId=GWEN_MsgEndpoint_GetNextMessageId(ep);
|
|
||||||
msgOut=AQH_ResultIpcMsg_new(code, msgId, refMsgId, resultCode);
|
|
||||||
GWEN_MsgEndpoint_AddSendMessage(ep, msgOut);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,62 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
* 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 AQH_ENDPOINT_IPC_H
|
|
||||||
#define AQH_ENDPOINT_IPC_H
|
|
||||||
|
|
||||||
|
|
||||||
#include <aqhome/api.h>
|
|
||||||
|
|
||||||
#include <gwenhywfar/endpoint.h>
|
|
||||||
|
|
||||||
|
|
||||||
#define AQH_IPCENDPOINT_FLAGS_WANTUPDATES 0x0001
|
|
||||||
|
|
||||||
#define AQH_IPCENDPOINT_PERMS_LISTVALUES 0x0001
|
|
||||||
#define AQH_IPCENDPOINT_PERMS_READVALUE 0x0002
|
|
||||||
#define AQH_IPCENDPOINT_PERMS_ADDVALUE 0x0004
|
|
||||||
|
|
||||||
#define AQH_IPCENDPOINT_PERMS_LISTDATA 0x0010
|
|
||||||
#define AQH_IPCENDPOINT_PERMS_READDATA 0x0020
|
|
||||||
#define AQH_IPCENDPOINT_PERMS_ADDDATA 0x0040
|
|
||||||
#define AQH_IPCENDPOINT_PERMS_SETDATA 0x0080
|
|
||||||
|
|
||||||
#define AQH_IPCENDPOINT_PERMS_LISTDEVICES 0x0100
|
|
||||||
#define AQH_IPCENDPOINT_PERMS_READDEVICE 0x0200
|
|
||||||
#define AQH_IPCENDPOINT_PERMS_ADDDEVICE 0x0400
|
|
||||||
#define AQH_IPCENDPOINT_PERMS_MODDEVICE 0x0800
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
AQHOME_API void AQH_IpcEndpoint_Extend(GWEN_MSG_ENDPOINT *ep);
|
|
||||||
|
|
||||||
AQHOME_API GWEN_MSG_ENDPOINT *AQH_IpcEndpoint_CreateIpcTcpClient(const char *host, int port, const char *name, int groupId);
|
|
||||||
AQHOME_API GWEN_MSG_ENDPOINT *AQH_IpcEndpoint_CreateIpcTcpServiceForSocket(GWEN_SOCKET *sk, const char *name, int groupId);
|
|
||||||
|
|
||||||
AQHOME_API uint32_t AQH_IpcEndpoint_GetAcceptedMsgGroups(const GWEN_MSG_ENDPOINT *ep);
|
|
||||||
AQHOME_API void AQH_IpcEndpoint_SetAcceptedMsgGroups(GWEN_MSG_ENDPOINT *ep, uint32_t i);
|
|
||||||
AQHOME_API void AQH_IpcEndpoint_AddAcceptedMsgGroups(GWEN_MSG_ENDPOINT *ep, uint32_t i);
|
|
||||||
AQHOME_API void AQH_IpcEndpoint_SubAcceptedMsgGroups(GWEN_MSG_ENDPOINT *ep, uint32_t i);
|
|
||||||
|
|
||||||
AQHOME_API const char *AQH_IpcEndpoint_GetServiceName(const GWEN_MSG_ENDPOINT *ep);
|
|
||||||
AQHOME_API void AQH_IpcEndpoint_SetServiceName(GWEN_MSG_ENDPOINT *ep, const char *s);
|
|
||||||
|
|
||||||
AQHOME_API const char *AQH_IpcEndpoint_GetUserName(const GWEN_MSG_ENDPOINT *ep);
|
|
||||||
AQHOME_API void AQH_IpcEndpoint_SetUserName(GWEN_MSG_ENDPOINT *ep, const char *s);
|
|
||||||
|
|
||||||
AQHOME_API const char *AQH_IpcEndpoint_GetPassword(const GWEN_MSG_ENDPOINT *ep);
|
|
||||||
AQHOME_API void AQH_IpcEndpoint_SetPassword(GWEN_MSG_ENDPOINT *ep, const char *s);
|
|
||||||
|
|
||||||
AQHOME_API uint32_t AQH_IpcEndpoint_GetPermissions(const GWEN_MSG_ENDPOINT *ep);
|
|
||||||
AQHOME_API void AQH_IpcEndpoint_SetPermissions(GWEN_MSG_ENDPOINT *ep, uint32_t i);
|
|
||||||
|
|
||||||
AQHOME_API void AQH_IpcEndpoint_SendResponseResult(GWEN_MSG_ENDPOINT *ep, uint32_t refMsgId, uint16_t code, uint32_t resultCode);
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
* 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 AQH_ENDPOINT_IPC_P_H
|
|
||||||
#define AQH_ENDPOINT_IPC_P_H
|
|
||||||
|
|
||||||
|
|
||||||
#include <aqhome/api.h>
|
|
||||||
|
|
||||||
#include <gwenhywfar/endpoint.h>
|
|
||||||
|
|
||||||
#include "aqhome/ipc/endpoint_ipc.h"
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct AQH_ENDPOINT_IPC AQH_ENDPOINT_IPC;
|
|
||||||
struct AQH_ENDPOINT_IPC {
|
|
||||||
uint32_t acceptedMsgGroups;
|
|
||||||
char *serviceName;
|
|
||||||
char *userName;
|
|
||||||
char *password;
|
|
||||||
uint32_t permissions;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,136 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
* 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 "aqhome/ipc/endpoint_ipcclient.h"
|
|
||||||
#include "aqhome/ipc/data/ipc_data.h"
|
|
||||||
#include "aqhome/ipc/endpoint_ipc.h"
|
|
||||||
#include "aqhome/ipc/data/msg_data_connect.h"
|
|
||||||
#include "aqhome/ipc/msg_ipc_result.h"
|
|
||||||
|
|
||||||
#include <gwenhywfar/endpoint_ipc.h>
|
|
||||||
#include <gwenhywfar/endpoint_tcpc.h>
|
|
||||||
#include <gwenhywfar/endpoint_multilayer.h>
|
|
||||||
#include <gwenhywfar/debug.h>
|
|
||||||
|
|
||||||
|
|
||||||
#define AQH_MSG_ENDPOINT_IPCCLIENT_NAME "ipc-client"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------------------------------
|
|
||||||
* forward declarations
|
|
||||||
* ------------------------------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
static int _startConnect(GWEN_MSG_ENDPOINT *ep, GWEN_MSG_ENDPOINT *epChild);
|
|
||||||
static void _checkSockets(GWEN_MSG_ENDPOINT *ep,
|
|
||||||
GWEN_MSG_ENDPOINT *epChild,
|
|
||||||
GWEN_SOCKETSET *readSet,
|
|
||||||
GWEN_SOCKETSET *writeSet,
|
|
||||||
GWEN_SOCKETSET *xSet);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------------------------------
|
|
||||||
* implementations
|
|
||||||
* ------------------------------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
GWEN_MSG_ENDPOINT *AQH_ClientIpcEndpoint_new(const char *name, int groupId)
|
|
||||||
{
|
|
||||||
GWEN_MSG_ENDPOINT *ep;
|
|
||||||
|
|
||||||
ep=GWEN_MultilayerEndpoint_new(name?name:AQH_MSG_ENDPOINT_IPCCLIENT_NAME, groupId);
|
|
||||||
GWEN_MultilayerEndpoint_SetStartConnectFn(ep, _startConnect);
|
|
||||||
GWEN_MultilayerEndpoint_SetCheckSocketsFn(ep, _checkSockets);
|
|
||||||
|
|
||||||
return ep;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int _startConnect(GWEN_MSG_ENDPOINT *ep, GWEN_MSG_ENDPOINT *epChild)
|
|
||||||
{
|
|
||||||
if (epChild) {
|
|
||||||
int rv;
|
|
||||||
GWEN_MSG *msg;
|
|
||||||
uint32_t flagsForConnectMsg;
|
|
||||||
|
|
||||||
flagsForConnectMsg=(GWEN_MsgEndpoint_GetFlags(ep) & AQH_ENDPOINT_IPCCLIENT_FLAGS_WANTUPDATES)?AQH_IPCENDPOINT_FLAGS_WANTUPDATES:0;
|
|
||||||
|
|
||||||
rv=GWEN_TcpcEndpoint_StartConnect(epChild);
|
|
||||||
if (rv<0 && rv!=GWEN_ERROR_IN_PROGRESS) {
|
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "Error starting to connect child layer (%d)", rv);
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
msg=AQH_ConnectDataIpcMsg_new(AQH_MSGTYPE_IPC_DATA_CONNECT_REQ,
|
|
||||||
GWEN_MsgEndpoint_GetNextMessageId(epChild), 0,
|
|
||||||
AQH_IpcEndpoint_GetServiceName(epChild),
|
|
||||||
AQH_IpcEndpoint_GetUserName(epChild),
|
|
||||||
AQH_IpcEndpoint_GetPassword(epChild),
|
|
||||||
flagsForConnectMsg);
|
|
||||||
GWEN_MsgEndpoint_AddSendMessage(epChild, msg);
|
|
||||||
GWEN_MsgEndpoint_SetState(ep, GWEN_MSG_ENDPOINT_STATE_CONNECTING);
|
|
||||||
return rv; /* result from GWEN_TcpcEndpoint_StartConnect() above */
|
|
||||||
}
|
|
||||||
return GWEN_ERROR_GENERIC;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void _checkSockets(GWEN_MSG_ENDPOINT *ep,
|
|
||||||
GWEN_MSG_ENDPOINT *epChild,
|
|
||||||
GWEN_SOCKETSET *readSet,
|
|
||||||
GWEN_SOCKETSET *writeSet,
|
|
||||||
GWEN_SOCKETSET *xSet)
|
|
||||||
{
|
|
||||||
GWEN_MSG *msg;
|
|
||||||
|
|
||||||
GWEN_MsgEndpoint_CheckSockets(epChild, readSet, writeSet, xSet); /* let base layer work */
|
|
||||||
|
|
||||||
msg=GWEN_MsgEndpoint_GetFirstReceivedMessage(epChild);
|
|
||||||
while(msg) {
|
|
||||||
GWEN_MSG *msgNext;
|
|
||||||
uint16_t code;
|
|
||||||
|
|
||||||
msgNext=GWEN_Msg_List_Next(msg);
|
|
||||||
code=GWEN_IpcMsg_GetCode(msg);
|
|
||||||
if (code==AQH_MSGTYPE_IPC_DATA_RESULT) {
|
|
||||||
uint32_t resultCode;
|
|
||||||
|
|
||||||
GWEN_Msg_List_Del(msg); /* remove from list */
|
|
||||||
resultCode=AQH_ResultIpcMsg_GetResultCode(msg);
|
|
||||||
if (resultCode==AQH_MSG_IPC_SUCCESS) {
|
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "Positive CONNECT response, connected");
|
|
||||||
GWEN_MsgEndpoint_SetState(ep, GWEN_MSG_ENDPOINT_STATE_CONNECTED);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
DBG_ERROR(AQH_LOGDOMAIN, "Negative CONNECT response (%d)", code);
|
|
||||||
GWEN_MsgEndpoint_Disconnect(epChild);
|
|
||||||
GWEN_MsgEndpoint_Disconnect(ep);
|
|
||||||
}
|
|
||||||
GWEN_Msg_free(msg);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
DBG_ERROR(AQH_LOGDOMAIN, "Ignoring response (%u)", code);
|
|
||||||
GWEN_Msg_free(msg);
|
|
||||||
}
|
|
||||||
msg=msgNext;
|
|
||||||
} /* while */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
* 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 AQH_ENDPOINT_IPCCLIENT_H
|
|
||||||
#define AQH_ENDPOINT_IPCCLIENT_H
|
|
||||||
|
|
||||||
|
|
||||||
#include <aqhome/api.h>
|
|
||||||
|
|
||||||
#include <gwenhywfar/endpoint.h>
|
|
||||||
|
|
||||||
|
|
||||||
#define AQH_ENDPOINT_IPCCLIENT_FLAGS_WANTUPDATES 0x0001
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This class expects to later have a child endpoint derived in any form from GWEN_TcpcEndpoint and from
|
|
||||||
* AQH_IpcEndpoint. It allows for automatic connect/reconnect including automatic exchange of AQH_ConnectDataIpcMsg
|
|
||||||
* messages thereby combining physical and logical connection to a server in one class.
|
|
||||||
*
|
|
||||||
* Use this class like this:
|
|
||||||
* <code>
|
|
||||||
* GWEN_MSG_ENDPOINT *clientEndpoint;
|
|
||||||
* GWEN_MSG_ENDPOINT *ipcBaseEndpoint;
|
|
||||||
*
|
|
||||||
* clientEndpoint=AQH_ClientIpcEndpoint_new("testClient", 0);
|
|
||||||
* ipcBaseEndpoint=AQH_IpcEndpoint_CreateIpcTcpClient("127.0.0.1", 1234, "ipcBaseClient", 0);
|
|
||||||
* AQH_IpcEndpoint_SetServiceName(ipcBaseEndpoint, "testclient");
|
|
||||||
* AQH_IpcEndpoint_SetUserName(ipcBaseEndpoint, "testUser");
|
|
||||||
* ...
|
|
||||||
* GWEN_MsgEndpoint_Tree2_AddChild(clientEndpoint, ipcBaseEndpoint);
|
|
||||||
* </code>
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
AQHOME_API GWEN_MSG_ENDPOINT *AQH_ClientIpcEndpoint_new(const char *name, int groupId);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
@@ -1,121 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
* 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 <aqhome/ipc/msg_ipc_qwords.h>
|
|
||||||
|
|
||||||
#include <gwenhywfar/msg.h>
|
|
||||||
#include <gwenhywfar/buffer.h>
|
|
||||||
|
|
||||||
#include <gwenhywfar/misc.h>
|
|
||||||
#include <gwenhywfar/debug.h>
|
|
||||||
#include <gwenhywfar/msg_ipc.h>
|
|
||||||
|
|
||||||
|
|
||||||
#define AQH_MSGDATA_QWORDS_OFFS_FLAGS 0 /* 4 bytes */
|
|
||||||
#define AQH_MSGDATA_QWORDS_OFFS_NUMVALUES 4 /* 4 bytes */
|
|
||||||
|
|
||||||
#define AQH_MSGDATA_QWORDS_OFFS_VALUES 8 /* 8 byte */
|
|
||||||
|
|
||||||
|
|
||||||
#define AQH_MSGDATA_QWORDS_PAYLOADSIZE (AQH_MSGDATA_QWORDS_OFFS_VALUES)
|
|
||||||
#define AQH_MSGDATA_QWORDS_MINSIZE (GWEN_MSGIPC_OFFS_PAYLOAD+AQH_MSGDATA_QWORDS_PAYLOADSIZE)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
GWEN_MSG *AQH_QwordsIpcMsg_new(uint8_t protoId, uint8_t protoVer, uint16_t code,
|
|
||||||
uint32_t msgId, uint32_t refMsgId,
|
|
||||||
uint32_t flags, const uint64_t *i64Ptr, int count)
|
|
||||||
{
|
|
||||||
GWEN_MSG *msg;
|
|
||||||
int payloadSize;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
payloadSize=AQH_MSGDATA_QWORDS_PAYLOADSIZE+(count*8);
|
|
||||||
|
|
||||||
msg=GWEN_IpcMsg_new(protoId, protoVer, code, msgId, refMsgId, payloadSize, NULL);
|
|
||||||
GWEN_Msg_AddUint32(msg, flags);
|
|
||||||
GWEN_Msg_AddUint32(msg, count);
|
|
||||||
|
|
||||||
for(i=0; i<count; i++)
|
|
||||||
GWEN_Msg_AddUint64(msg, *(i64Ptr++));
|
|
||||||
|
|
||||||
return msg;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint32_t AQH_QwordsIpcMsg_GetFlags(const GWEN_MSG *msg)
|
|
||||||
{
|
|
||||||
return GWEN_Msg_GetUint32At(msg, GWEN_MSGIPC_OFFS_PAYLOAD+AQH_MSGDATA_QWORDS_OFFS_FLAGS, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint32_t AQH_QwordsIpcMsg_GetNumValues(const GWEN_MSG *msg)
|
|
||||||
{
|
|
||||||
return GWEN_Msg_GetUint32At(msg, GWEN_MSGIPC_OFFS_PAYLOAD+AQH_MSGDATA_QWORDS_OFFS_NUMVALUES, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint64_t AQH_QwordsIpcMsg_GetValue(const GWEN_MSG *msg, int idx)
|
|
||||||
{
|
|
||||||
uint32_t pos;
|
|
||||||
|
|
||||||
pos=AQH_MSGDATA_QWORDS_OFFS_VALUES+(idx*8);
|
|
||||||
return GWEN_Msg_GetUint64At(msg, GWEN_MSGIPC_OFFS_PAYLOAD+pos, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int AQH_QwordsIpcMsg_IsValid(const GWEN_MSG *msg)
|
|
||||||
{
|
|
||||||
int msgLen;
|
|
||||||
int numValues;
|
|
||||||
|
|
||||||
msgLen=GWEN_Msg_GetBytesInBuffer(msg);
|
|
||||||
if (msgLen<AQH_MSGDATA_QWORDS_MINSIZE) {
|
|
||||||
DBG_ERROR(AQH_LOGDOMAIN, "Message too small (%d<%d)", GWEN_Msg_GetBytesInBuffer(msg), AQH_MSGDATA_QWORDS_MINSIZE);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
numValues=(int)AQH_QwordsIpcMsg_GetNumValues(msg);
|
|
||||||
if (msgLen<(numValues*8)+AQH_MSGDATA_QWORDS_OFFS_VALUES+GWEN_MSGIPC_OFFS_PAYLOAD) {
|
|
||||||
DBG_ERROR(AQH_LOGDOMAIN, "Message too small to contain %d values", numValues);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_QwordsIpcMsg_DumpToBuffer(const GWEN_MSG *msg, GWEN_BUFFER *dbuf, const char *sText)
|
|
||||||
{
|
|
||||||
if (GWEN_Msg_GetBytesInBuffer(msg)>=AQH_MSGDATA_QWORDS_MINSIZE) {
|
|
||||||
GWEN_Buffer_AppendArgs(dbuf,
|
|
||||||
"QWORDS (code=%d, proto=%d, proto version=%d, flags=0x%08x, values=%d)\n",
|
|
||||||
GWEN_IpcMsg_GetCode(msg),
|
|
||||||
GWEN_IpcMsg_GetProtoId(msg),
|
|
||||||
GWEN_IpcMsg_GetProtoVersion(msg),
|
|
||||||
(unsigned int)AQH_QwordsIpcMsg_GetFlags(msg),
|
|
||||||
AQH_QwordsIpcMsg_GetNumValues(msg));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
* 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 AQH_MSG_IPC_QWORDS_H
|
|
||||||
#define AQH_MSG_IPC_QWORDS_H
|
|
||||||
|
|
||||||
|
|
||||||
#include <aqhome/api.h>
|
|
||||||
#include <aqhome/ipc/nodes/ipc_nodes.h>
|
|
||||||
#include <aqhome/msg/msg_node.h>
|
|
||||||
|
|
||||||
#include <gwenhywfar/msg.h>
|
|
||||||
#include <gwenhywfar/buffer.h>
|
|
||||||
|
|
||||||
|
|
||||||
AQHOME_API GWEN_MSG *AQH_QwordsIpcMsg_new(uint8_t protoId, uint8_t protoVer, uint16_t code,
|
|
||||||
uint32_t msgId, uint32_t refMsgId,
|
|
||||||
uint32_t flags, const uint64_t *i64Ptr, int count);
|
|
||||||
|
|
||||||
AQHOME_API uint32_t AQH_QwordsIpcMsg_GetFlags(const GWEN_MSG *msg);
|
|
||||||
AQHOME_API uint32_t AQH_QwordsIpcMsg_GetNumValues(const GWEN_MSG *msg);
|
|
||||||
AQHOME_API uint64_t AQH_QwordsIpcMsg_GetValue(const GWEN_MSG *msg, int idx);
|
|
||||||
AQHOME_API int AQH_QwordsIpcMsg_IsValid(const GWEN_MSG *msg);
|
|
||||||
AQHOME_API void AQH_QwordsIpcMsg_DumpToBuffer(const GWEN_MSG *msg, GWEN_BUFFER *dbuf, const char *sText);
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,78 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
* 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 <aqhome/ipc/msg_ipc_result.h>
|
|
||||||
#include <aqhome/ipc/data/ipc_data.h>
|
|
||||||
|
|
||||||
#include <gwenhywfar/msg.h>
|
|
||||||
#include <gwenhywfar/buffer.h>
|
|
||||||
|
|
||||||
#include <gwenhywfar/misc.h>
|
|
||||||
#include <gwenhywfar/list.h>
|
|
||||||
#include <gwenhywfar/error.h>
|
|
||||||
#include <gwenhywfar/debug.h>
|
|
||||||
#include <gwenhywfar/text.h>
|
|
||||||
#include <gwenhywfar/msg_ipc.h>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define AQH_MSGIPC_RESULT_OFFS_RESULTCODE 0 /* 4 bytes */
|
|
||||||
|
|
||||||
#define AQH_MSGIPC_RESULT_PAYLOADSIZE (AQH_MSGIPC_RESULT_OFFS_RESULTCODE+4)
|
|
||||||
#define AQH_MSGIPC_RESULT_MINSIZE (GWEN_MSGIPC_OFFS_PAYLOAD+AQH_MSGIPC_RESULT_PAYLOADSIZE)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
GWEN_MSG *AQH_ResultIpcMsg_new(uint16_t code, uint32_t msgId, uint32_t refMsgId, uint32_t resultCode)
|
|
||||||
{
|
|
||||||
GWEN_MSG *msg;
|
|
||||||
|
|
||||||
msg=GWEN_IpcMsg_new(AQH_IPC_PROTOCOL_DATA_ID, AQH_IPC_PROTOCOL_DATA_VERSION, code,
|
|
||||||
msgId, refMsgId,
|
|
||||||
AQH_MSGIPC_RESULT_PAYLOADSIZE, NULL);
|
|
||||||
GWEN_Msg_AddUint32(msg, resultCode);
|
|
||||||
return msg;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint32_t AQH_ResultIpcMsg_GetResultCode(const GWEN_MSG *msg)
|
|
||||||
{
|
|
||||||
return GWEN_Msg_GetUint32At(msg, GWEN_MSGIPC_OFFS_PAYLOAD+AQH_MSGIPC_RESULT_OFFS_RESULTCODE, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_ResultIpcMsg_DumpToBuffer(const GWEN_MSG *msg, GWEN_BUFFER *dbuf, const char *sText)
|
|
||||||
{
|
|
||||||
if (GWEN_Msg_GetBytesInBuffer(msg)>=AQH_MSGIPC_RESULT_MINSIZE) {
|
|
||||||
GWEN_Buffer_AppendArgs(dbuf,
|
|
||||||
"ERROR %s (code=%d, proto=%d, proto version=%d, error=%d, msgId=%d, refMsgId=%d)\n",
|
|
||||||
sText?sText:"",
|
|
||||||
GWEN_IpcMsg_GetCode(msg),
|
|
||||||
GWEN_IpcMsg_GetProtoId(msg),
|
|
||||||
GWEN_IpcMsg_GetProtoVersion(msg),
|
|
||||||
AQH_ResultIpcMsg_GetResultCode(msg),
|
|
||||||
GWEN_IpcMsg_GetMsgId(msg),
|
|
||||||
GWEN_IpcMsg_GetRefMsgId(msg));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
* 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 AQH_MSG_IPC_RESULT_H
|
|
||||||
#define AQH_MSG_IPC_RESULT_H
|
|
||||||
|
|
||||||
|
|
||||||
#include <aqhome/api.h>
|
|
||||||
#include <aqhome/ipc/nodes/ipc_nodes.h>
|
|
||||||
#include <aqhome/msg/msg_node.h>
|
|
||||||
|
|
||||||
#include <gwenhywfar/msg.h>
|
|
||||||
#include <gwenhywfar/buffer.h>
|
|
||||||
|
|
||||||
|
|
||||||
#define AQH_IPC_PROTOCOL_RESULT_ID 0
|
|
||||||
#define AQH_IPC_PROTOCOL_RESULT_VERSION 1
|
|
||||||
|
|
||||||
|
|
||||||
#define AQH_MSG_IPC_SUCCESS 0
|
|
||||||
#define AQH_MSG_IPC_ERROR_GENERIC 1
|
|
||||||
#define AQH_MSG_IPC_ERROR_INVALID 2
|
|
||||||
#define AQH_MSG_IPC_ERROR_EXISTS 3
|
|
||||||
#define AQH_MSG_IPC_ERROR_NODATA 4
|
|
||||||
#define AQH_MSG_IPC_ERROR_BADDATA 5
|
|
||||||
#define AQH_MSG_IPC_ERROR_PERMS 6
|
|
||||||
#define AQH_MSG_IPC_ERROR_NOTFOUND 7
|
|
||||||
#define AQH_MSG_IPC_ERROR_IO 8
|
|
||||||
#define AQH_MSG_IPC_ERROR_TRYAGAIN 9
|
|
||||||
|
|
||||||
|
|
||||||
AQHOME_API GWEN_MSG *AQH_ResultIpcMsg_new(uint16_t code, uint32_t msgId, uint32_t refMsgId, uint32_t resultCode);
|
|
||||||
AQHOME_API uint32_t AQH_ResultIpcMsg_GetResultCode(const GWEN_MSG *msg);
|
|
||||||
AQHOME_API void AQH_ResultIpcMsg_DumpToBuffer(const GWEN_MSG *msg, GWEN_BUFFER *dbuf, const char *sText);
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,255 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
* 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 "msg_ipc_tag16_p.h"
|
|
||||||
|
|
||||||
#include <gwenhywfar/msg_ipc.h>
|
|
||||||
#include <gwenhywfar/debug.h>
|
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------------------------------
|
|
||||||
* forward declarations
|
|
||||||
* ------------------------------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
static void GWENHYWFAR_CB _freeData(void *bp, void *p);
|
|
||||||
static GWEN_TAG16_LIST *_parseTags(const GWEN_MSG *msg, int doCopy);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------------------------------
|
|
||||||
* implementations
|
|
||||||
* ------------------------------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
GWEN_INHERIT(GWEN_MSG, AQH_MSG_IPC_TAG16);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
GWEN_MSG *AQH_Tag16IpcMsg_new(uint8_t protoId, uint8_t protoVer, uint16_t code,
|
|
||||||
uint32_t msgId, uint32_t refMsgId,
|
|
||||||
uint32_t payloadLen, const uint8_t *payload)
|
|
||||||
{
|
|
||||||
GWEN_MSG *msg;
|
|
||||||
|
|
||||||
msg=GWEN_IpcMsg_new(protoId, protoVer, code, msgId, refMsgId, payloadLen, payload);
|
|
||||||
AQH_Tag16IpcMsg_Extend(msg);
|
|
||||||
return msg;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_Tag16IpcMsg_Extend(GWEN_MSG *msg)
|
|
||||||
{
|
|
||||||
AQH_MSG_IPC_TAG16 *xmsg;
|
|
||||||
|
|
||||||
GWEN_NEW_OBJECT(AQH_MSG_IPC_TAG16, xmsg);
|
|
||||||
GWEN_INHERIT_SETDATA(GWEN_MSG, AQH_MSG_IPC_TAG16, msg, xmsg, _freeData);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void _freeData(GWEN_UNUSED void *bp, void *p)
|
|
||||||
{
|
|
||||||
AQH_MSG_IPC_TAG16 *xmsg;
|
|
||||||
|
|
||||||
xmsg=(AQH_MSG_IPC_TAG16*) p;
|
|
||||||
GWEN_Tag16_List_free(xmsg->tagList);
|
|
||||||
GWEN_FREE_OBJECT(xmsg);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
GWEN_TAG16_LIST *AQH_Tag16IpcMsg_GetTags(const GWEN_MSG *msg)
|
|
||||||
{
|
|
||||||
if (msg) {
|
|
||||||
AQH_MSG_IPC_TAG16 *xmsg;
|
|
||||||
|
|
||||||
xmsg=GWEN_INHERIT_GETDATA(GWEN_MSG, AQH_MSG_IPC_TAG16, msg);
|
|
||||||
if (xmsg) {
|
|
||||||
return xmsg->tagList;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "Not a Tag16IpcMsg message");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "NULLPOINTER");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_Tag16IpcMsg_ReadTags(GWEN_MSG *msg, int doCopy)
|
|
||||||
{
|
|
||||||
if (msg) {
|
|
||||||
AQH_MSG_IPC_TAG16 *xmsg;
|
|
||||||
|
|
||||||
xmsg=GWEN_INHERIT_GETDATA(GWEN_MSG, AQH_MSG_IPC_TAG16, msg);
|
|
||||||
if (xmsg) {
|
|
||||||
if (xmsg->tagList) {
|
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "Tags already parsed");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
xmsg->tagList=_parseTags(msg, doCopy);
|
|
||||||
if (xmsg->tagList==NULL) {
|
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "No tags received");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "Not a Tag16IpcMsg message");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "NULLPOINTER");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_Tag16IpcMsg_ExtendAndParse(GWEN_MSG *msg, int doCopy)
|
|
||||||
{
|
|
||||||
if (!(GWEN_INHERIT_ISOFTYPE(GWEN_MSG, AQH_MSG_IPC_TAG16, msg)))
|
|
||||||
AQH_Tag16IpcMsg_Extend(msg);
|
|
||||||
AQH_Tag16IpcMsg_ReadTags(msg, doCopy);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
char *AQH_Tag16IpcMsg_GetTagDataAsNewString(const GWEN_MSG *msg, unsigned int tagType, const char *defaultValue)
|
|
||||||
{
|
|
||||||
if (msg) {
|
|
||||||
AQH_MSG_IPC_TAG16 *xmsg;
|
|
||||||
|
|
||||||
xmsg=GWEN_INHERIT_GETDATA(GWEN_MSG, AQH_MSG_IPC_TAG16, msg);
|
|
||||||
if (xmsg && xmsg->tagList) {
|
|
||||||
const GWEN_TAG16 *tag;
|
|
||||||
|
|
||||||
tag=GWEN_Tag16_List_FindFirstByTagType(xmsg->tagList, tagType);
|
|
||||||
if (tag)
|
|
||||||
return GWEN_Tag16_GetTagDataAsNewString(tag, defaultValue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return defaultValue?strdup(defaultValue):NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint32_t AQH_Tag16IpcMsg_GetTagDataAsUint32(const GWEN_MSG *msg, unsigned int tagType, uint32_t defaultValue)
|
|
||||||
{
|
|
||||||
if (msg) {
|
|
||||||
AQH_MSG_IPC_TAG16 *xmsg;
|
|
||||||
|
|
||||||
xmsg=GWEN_INHERIT_GETDATA(GWEN_MSG, AQH_MSG_IPC_TAG16, msg);
|
|
||||||
if (xmsg && xmsg->tagList) {
|
|
||||||
const GWEN_TAG16 *tag;
|
|
||||||
|
|
||||||
tag=GWEN_Tag16_List_FindFirstByTagType(xmsg->tagList, tagType);
|
|
||||||
return tag?GWEN_Tag16_GetTagDataAsUint32(tag, defaultValue):defaultValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return defaultValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint64_t AQH_Tag16IpcMsg_GetTagDataAsUint64(const GWEN_MSG *msg, unsigned int tagType, uint64_t defaultValue)
|
|
||||||
{
|
|
||||||
if (msg) {
|
|
||||||
AQH_MSG_IPC_TAG16 *xmsg;
|
|
||||||
|
|
||||||
xmsg=GWEN_INHERIT_GETDATA(GWEN_MSG, AQH_MSG_IPC_TAG16, msg);
|
|
||||||
if (xmsg && xmsg->tagList) {
|
|
||||||
const GWEN_TAG16 *tag;
|
|
||||||
|
|
||||||
tag=GWEN_Tag16_List_FindFirstByTagType(xmsg->tagList, tagType);
|
|
||||||
return tag?GWEN_Tag16_GetTagDataAsUint64(tag, defaultValue):defaultValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return defaultValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const GWEN_TAG16 *AQH_Tag16IpcMsg_FindFirstTagByType(const GWEN_MSG *msg, unsigned int tagType)
|
|
||||||
{
|
|
||||||
if (msg) {
|
|
||||||
AQH_MSG_IPC_TAG16 *xmsg;
|
|
||||||
|
|
||||||
xmsg=GWEN_INHERIT_GETDATA(GWEN_MSG, AQH_MSG_IPC_TAG16, msg);
|
|
||||||
if (xmsg && xmsg->tagList)
|
|
||||||
return GWEN_Tag16_List_FindFirstByTagType(xmsg->tagList, tagType);
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
GWEN_TAG16_LIST *AQH_Tag16IpcMsg_ParseTags(const GWEN_MSG *msg, int doCopy)
|
|
||||||
{
|
|
||||||
return _parseTags(msg, doCopy);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
GWEN_TAG16_LIST *_parseTags(const GWEN_MSG *msg, int doCopy)
|
|
||||||
{
|
|
||||||
uint32_t msgSize;
|
|
||||||
|
|
||||||
msgSize=GWEN_Msg_GetBytesInBuffer(msg);
|
|
||||||
if (msgSize>GWEN_MSGIPC_OFFS_PAYLOAD) {
|
|
||||||
const uint8_t *ptr;
|
|
||||||
uint32_t payloadSize;
|
|
||||||
|
|
||||||
ptr=GWEN_Msg_GetConstBuffer(msg)+GWEN_MSGIPC_OFFS_PAYLOAD;
|
|
||||||
payloadSize=msgSize-GWEN_MSGIPC_OFFS_PAYLOAD;
|
|
||||||
|
|
||||||
if (payloadSize) {
|
|
||||||
GWEN_TAG16_LIST *tagList;
|
|
||||||
|
|
||||||
tagList=GWEN_Tag16_List_fromBuffer(ptr, payloadSize, doCopy);
|
|
||||||
if (tagList==NULL) {
|
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "Error reading tags from message");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
return tagList;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_Tag16IpcMsg_DumpToBuffer(const GWEN_MSG *msg, GWEN_BUFFER *dbuf, const char *sText)
|
|
||||||
{
|
|
||||||
if (GWEN_Msg_GetBytesInBuffer(msg)>=GWEN_MSGIPC_OFFS_PAYLOAD) {
|
|
||||||
GWEN_Buffer_AppendArgs(dbuf,
|
|
||||||
"Tag16 %s (code=%d, proto=%d, proto version=%d)\n",
|
|
||||||
sText?sText:"",
|
|
||||||
GWEN_IpcMsg_GetCode(msg),
|
|
||||||
GWEN_IpcMsg_GetProtoId(msg),
|
|
||||||
GWEN_IpcMsg_GetProtoVersion(msg));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
* 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 AQH_MSG_IPC_TAG16_H
|
|
||||||
#define AQH_MSG_IPC_TAG16_H
|
|
||||||
|
|
||||||
|
|
||||||
#include <aqhome/api.h>
|
|
||||||
|
|
||||||
#include <gwenhywfar/msg.h>
|
|
||||||
#include <gwenhywfar/buffer.h>
|
|
||||||
#include <gwenhywfar/tag16.h>
|
|
||||||
|
|
||||||
|
|
||||||
AQHOME_API GWEN_MSG *AQH_Tag16IpcMsg_new(uint8_t protoId, uint8_t protoVer, uint16_t code,
|
|
||||||
uint32_t msgId, uint32_t refMsgId,
|
|
||||||
uint32_t payloadLen, const uint8_t *payload);
|
|
||||||
AQHOME_API void AQH_Tag16IpcMsg_ExtendAndParse(GWEN_MSG *msg, int doCopy);
|
|
||||||
|
|
||||||
AQHOME_API void AQH_Tag16IpcMsg_Extend(GWEN_MSG *msg);
|
|
||||||
AQHOME_API void AQH_Tag16IpcMsg_ReadTags(GWEN_MSG *msg, int doCopy);
|
|
||||||
|
|
||||||
AQHOME_API GWEN_TAG16_LIST *AQH_Tag16IpcMsg_GetTags(const GWEN_MSG *msg);
|
|
||||||
|
|
||||||
AQHOME_API GWEN_DEPRECATED GWEN_TAG16_LIST *AQH_Tag16IpcMsg_ParseTags(const GWEN_MSG *msg, int doCopy);
|
|
||||||
AQHOME_API void AQH_Tag16IpcMsg_DumpToBuffer(const GWEN_MSG *msg, GWEN_BUFFER *dbuf, const char *sText);
|
|
||||||
|
|
||||||
AQHOME_API const GWEN_TAG16 *AQH_Tag16IpcMsg_FindFirstTagByType(const GWEN_MSG *msg, unsigned int tagType);
|
|
||||||
|
|
||||||
AQHOME_API char *AQH_Tag16IpcMsg_GetTagDataAsNewString(const GWEN_MSG *msg, unsigned int tagType, const char *defaultValue);
|
|
||||||
AQHOME_API uint32_t AQH_Tag16IpcMsg_GetTagDataAsUint32(const GWEN_MSG *msg, unsigned int tagType, uint32_t defaultValue);
|
|
||||||
AQHOME_API uint64_t AQH_Tag16IpcMsg_GetTagDataAsUint64(const GWEN_MSG *msg, unsigned int tagType, uint64_t defaultValue);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
* 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 AQH_MSG_IPC_TAG16_P_H
|
|
||||||
#define AQH_MSG_IPC_TAG16_P_H
|
|
||||||
|
|
||||||
|
|
||||||
#include <aqhome/ipc/msg_ipc_tag16.h>
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct AQH_MSG_IPC_TAG16 AQH_MSG_IPC_TAG16;
|
|
||||||
struct AQH_MSG_IPC_TAG16 {
|
|
||||||
GWEN_TAG16_LIST *tagList;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,90 +0,0 @@
|
|||||||
<?xml?>
|
|
||||||
|
|
||||||
<gwbuild>
|
|
||||||
|
|
||||||
<target type="ConvenienceLibrary" name="aqhipcnodes" >
|
|
||||||
|
|
||||||
<includes type="c" >
|
|
||||||
$(gwenhywfar_cflags)
|
|
||||||
-I$(topsrcdir)
|
|
||||||
-I$(topbuilddir)
|
|
||||||
</includes>
|
|
||||||
|
|
||||||
<includes type="tm2" >
|
|
||||||
--include=$(builddir)
|
|
||||||
--include=$(srcdir)
|
|
||||||
</includes>
|
|
||||||
|
|
||||||
|
|
||||||
<define name="BUILDING_AQHOME" />
|
|
||||||
|
|
||||||
<setVar name="local/cflags">$(visibility_cflags)</setVar>
|
|
||||||
|
|
||||||
|
|
||||||
<setVar name="tm2flags" >
|
|
||||||
--api=AQHOME_API
|
|
||||||
</setVar>
|
|
||||||
|
|
||||||
<setVar name="local/typefiles" >
|
|
||||||
</setVar>
|
|
||||||
|
|
||||||
<setVar name="local/built_sources" >
|
|
||||||
</setVar>
|
|
||||||
|
|
||||||
<setVar name="local/built_headers_pub">
|
|
||||||
</setVar>
|
|
||||||
|
|
||||||
|
|
||||||
<setVar name="local/built_headers_priv" >
|
|
||||||
</setVar>
|
|
||||||
|
|
||||||
|
|
||||||
<headers dist="false" install="$(pkgincludedir)/ipc" >
|
|
||||||
$(local/built_headers_pub)
|
|
||||||
</headers>
|
|
||||||
|
|
||||||
|
|
||||||
<headers dist="true" install="$(pkgincludedir)/ipc" >
|
|
||||||
ipc_nodes.h
|
|
||||||
msg_ipc_forward.h
|
|
||||||
msg_ipc_getdevices_req.h
|
|
||||||
msg_ipc_getdevices_rsp.h
|
|
||||||
msg_ipc_ping.h
|
|
||||||
msg_ipc_setaccmsggrps.h
|
|
||||||
msg_ipc_value.h
|
|
||||||
</headers>
|
|
||||||
|
|
||||||
|
|
||||||
<headers dist="true" >
|
|
||||||
</headers>
|
|
||||||
|
|
||||||
|
|
||||||
<sources>
|
|
||||||
$(local/typefiles)
|
|
||||||
|
|
||||||
ipc_nodes.c
|
|
||||||
msg_ipc_forward.c
|
|
||||||
msg_ipc_getdevices_req.c
|
|
||||||
msg_ipc_getdevices_rsp.c
|
|
||||||
msg_ipc_ping.c
|
|
||||||
msg_ipc_setaccmsggrps.c
|
|
||||||
msg_ipc_value.c
|
|
||||||
</sources>
|
|
||||||
|
|
||||||
|
|
||||||
<extradist>
|
|
||||||
</extradist>
|
|
||||||
|
|
||||||
|
|
||||||
<useTargets>
|
|
||||||
</useTargets>
|
|
||||||
|
|
||||||
<subdirs>
|
|
||||||
</subdirs>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</target>
|
|
||||||
|
|
||||||
</gwbuild>
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
* 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 <aqhome/ipc/nodes/ipc_nodes.h>
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
* 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 AQH_MSG_IPC_NODES_H
|
|
||||||
#define AQH_MSG_IPC_NODES_H
|
|
||||||
|
|
||||||
|
|
||||||
#include <aqhome/api.h>
|
|
||||||
|
|
||||||
#include <gwenhywfar/msg_ipc.h>
|
|
||||||
#include <gwenhywfar/buffer.h>
|
|
||||||
|
|
||||||
|
|
||||||
#define AQH_IPC_PROTOCOL_NODES_ID 1
|
|
||||||
#define AQH_IPC_PROTOCOL_NODES_VERSION 1
|
|
||||||
|
|
||||||
|
|
||||||
#define AQH_MSGTYPE_IPC_NODES_RESULT 0xf001
|
|
||||||
|
|
||||||
#define AQH_MSGTYPE_IPC_NODES_FORWARD 0xf100
|
|
||||||
#define AQH_MSGTYPE_IPC_NODES_VALUE 0xf200
|
|
||||||
#define AQH_MSGTYPE_IPC_NODES_PING 0xf300
|
|
||||||
#define AQH_MSGTYPE_IPC_NODES_SETACCMSGGRPS 0xf400
|
|
||||||
#define AQH_MSGTYPE_IPC_NODES_GETDEVICES_REQ 0xf500
|
|
||||||
#define AQH_MSGTYPE_IPC_NODES_GETDEVICES_RSP 0xf600
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,95 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
* 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 <aqhome/ipc/nodes/msg_ipc_forward.h>
|
|
||||||
|
|
||||||
#include <gwenhywfar/msg.h>
|
|
||||||
#include <gwenhywfar/buffer.h>
|
|
||||||
|
|
||||||
#include <gwenhywfar/misc.h>
|
|
||||||
#include <gwenhywfar/list.h>
|
|
||||||
#include <gwenhywfar/error.h>
|
|
||||||
#include <gwenhywfar/debug.h>
|
|
||||||
#include <gwenhywfar/text.h>
|
|
||||||
#include <gwenhywfar/msg_ipc.h>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define AQH_MSG_OFFS_FORWARD_MSG (GWEN_MSGIPC_OFFS_PAYLOAD+0)
|
|
||||||
|
|
||||||
#define AQH_MSG_FORWARD_MINSIZE (AQH_MSG_OFFS_FORWARD_MSG+AQH_MSG_OFFS_ALL_DATA_BEGIN)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
GWEN_MSG *AQH_ForwardIpcMsg_new(uint16_t code,
|
|
||||||
uint32_t msgId, uint32_t refMsgId,
|
|
||||||
const uint8_t *ptr, uint32_t len)
|
|
||||||
{
|
|
||||||
return GWEN_IpcMsg_new(AQH_IPC_PROTOCOL_NODES_ID, AQH_IPC_PROTOCOL_NODES_VERSION, code, msgId, refMsgId, len, ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const uint8_t *AQH_ForwardIpcMsg_GetMsgPtr(const GWEN_MSG *msg)
|
|
||||||
{
|
|
||||||
if (GWEN_Msg_GetBytesInBuffer(msg)>=AQH_MSG_FORWARD_MINSIZE)
|
|
||||||
return GWEN_Msg_GetConstBuffer(msg)+AQH_MSG_OFFS_FORWARD_MSG;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint32_t AQH_ForwardIpcMsg_GetMsgLen(const GWEN_MSG *msg)
|
|
||||||
{
|
|
||||||
uint32_t len;
|
|
||||||
|
|
||||||
len=GWEN_Msg_GetBytesInBuffer(msg);
|
|
||||||
if (len>AQH_MSG_FORWARD_MINSIZE) {
|
|
||||||
return len-AQH_MSG_OFFS_FORWARD_MSG;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
GWEN_MSG *AQH_ForwardIpcMsg_GetCopyOfNodeMsg(const GWEN_MSG *msg)
|
|
||||||
{
|
|
||||||
return GWEN_Msg_fromBytes(AQH_ForwardIpcMsg_GetMsgPtr(msg), AQH_ForwardIpcMsg_GetMsgLen(msg));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_ForwardIpcMsg_DumpToBuffer(const GWEN_MSG *msg, GWEN_BUFFER *dbuf, const char *sText)
|
|
||||||
{
|
|
||||||
if (GWEN_Msg_GetBytesInBuffer(msg)>=AQH_MSG_FORWARD_MINSIZE) {
|
|
||||||
const uint8_t *ptr;
|
|
||||||
uint32_t len;
|
|
||||||
|
|
||||||
ptr=AQH_ForwardIpcMsg_GetMsgPtr(msg);
|
|
||||||
len=AQH_ForwardIpcMsg_GetMsgLen(msg);
|
|
||||||
|
|
||||||
GWEN_Buffer_AppendArgs(dbuf, "FORWARD (code=%d, protocol=%d, protocol version=%d)\n",
|
|
||||||
GWEN_IpcMsg_GetCode(msg),
|
|
||||||
GWEN_IpcMsg_GetProtoId(msg),
|
|
||||||
GWEN_IpcMsg_GetProtoVersion(msg));
|
|
||||||
if (ptr && len) {
|
|
||||||
GWEN_Text_DumpString2Buffer((const char*)ptr, len, dbuf, 2);
|
|
||||||
GWEN_Buffer_AppendByte(dbuf, '\n');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
* 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 AQH_MSG_IPC_FORWARD_H
|
|
||||||
#define AQH_MSG_IPC_FORWARD_H
|
|
||||||
|
|
||||||
|
|
||||||
#include <aqhome/api.h>
|
|
||||||
#include <aqhome/ipc/nodes/ipc_nodes.h>
|
|
||||||
#include <aqhome/msg/msg_node.h>
|
|
||||||
|
|
||||||
#include <gwenhywfar/msg.h>
|
|
||||||
#include <gwenhywfar/buffer.h>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
AQHOME_API GWEN_MSG *AQH_ForwardIpcMsg_new(uint16_t code, uint32_t msgId, uint32_t refMsgId, const uint8_t *ptr, uint32_t len);
|
|
||||||
AQHOME_API const uint8_t *AQH_ForwardIpcMsg_GetMsgPtr(const GWEN_MSG *msg);
|
|
||||||
AQHOME_API uint32_t AQH_ForwardIpcMsg_GetMsgLen(const GWEN_MSG *msg);
|
|
||||||
AQHOME_API GWEN_MSG *AQH_ForwardIpcMsg_GetCopyOfNodeMsg(const GWEN_MSG *msg);
|
|
||||||
AQHOME_API void AQH_ForwardIpcMsg_DumpToBuffer(const GWEN_MSG *msg, GWEN_BUFFER *dbuf, const char *sText);
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,57 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
* 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 <aqhome/ipc/nodes/msg_ipc_getdevices_req.h>
|
|
||||||
|
|
||||||
#include <gwenhywfar/msg.h>
|
|
||||||
#include <gwenhywfar/buffer.h>
|
|
||||||
|
|
||||||
#include <gwenhywfar/misc.h>
|
|
||||||
#include <gwenhywfar/list.h>
|
|
||||||
#include <gwenhywfar/error.h>
|
|
||||||
#include <gwenhywfar/debug.h>
|
|
||||||
#include <gwenhywfar/text.h>
|
|
||||||
#include <gwenhywfar/msg_ipc.h>
|
|
||||||
|
|
||||||
|
|
||||||
#define AQH_MSGIPC_GETDEVICES_REQ_PAYLOADSIZE 0
|
|
||||||
#define AQH_MSGIPC_GETDEVICES_REQ_MINSIZE (GWEN_MSGIPC_OFFS_PAYLOAD+AQH_MSGIPC_GETDEVICES_REQ_PAYLOADSIZE)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
GWEN_MSG *AQH_GetDevicesRequestIpcMsg_new(uint16_t code, uint32_t msgId, uint32_t refMsgId)
|
|
||||||
{
|
|
||||||
return GWEN_IpcMsg_new(AQH_IPC_PROTOCOL_NODES_ID, AQH_IPC_PROTOCOL_NODES_VERSION, code,
|
|
||||||
msgId, refMsgId, AQH_MSGIPC_GETDEVICES_REQ_PAYLOADSIZE, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_GetDevicesRequestIpcMsg_DumpToBuffer(const GWEN_MSG *msg, GWEN_BUFFER *dbuf, const char *sText)
|
|
||||||
{
|
|
||||||
if (GWEN_Msg_GetBytesInBuffer(msg)>=AQH_MSGIPC_GETDEVICES_REQ_MINSIZE) {
|
|
||||||
GWEN_Buffer_AppendArgs(dbuf,
|
|
||||||
"GET_DEVICES REQ %s (code=%d, proto=%d, proto version=%d, msgId=%d, refMsgId=%d)\n",
|
|
||||||
sText?sText:"",
|
|
||||||
GWEN_IpcMsg_GetCode(msg),
|
|
||||||
GWEN_IpcMsg_GetProtoId(msg),
|
|
||||||
GWEN_IpcMsg_GetProtoVersion(msg),
|
|
||||||
GWEN_IpcMsg_GetMsgId(msg),
|
|
||||||
GWEN_IpcMsg_GetRefMsgId(msg));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
* 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 AQH_MSGIPC_GETDEVICES_REQ_H
|
|
||||||
#define AQH_MSGIPC_GETDEVICES_REQ_H
|
|
||||||
|
|
||||||
|
|
||||||
#include <aqhome/api.h>
|
|
||||||
#include <aqhome/ipc/nodes/ipc_nodes.h>
|
|
||||||
|
|
||||||
#include <gwenhywfar/msg.h>
|
|
||||||
#include <gwenhywfar/buffer.h>
|
|
||||||
|
|
||||||
|
|
||||||
AQHOME_API GWEN_MSG *AQH_GetDevicesRequestIpcMsg_new(uint16_t code, uint32_t msgId, uint32_t refMsgId);
|
|
||||||
|
|
||||||
AQHOME_API void AQH_GetDevicesRequestIpcMsg_DumpToBuffer(const GWEN_MSG *msg, GWEN_BUFFER *dbuf, const char *sText);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
@@ -1,189 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
* 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 <aqhome/ipc/nodes/msg_ipc_getdevices_rsp.h>
|
|
||||||
|
|
||||||
#include <gwenhywfar/msg.h>
|
|
||||||
#include <gwenhywfar/buffer.h>
|
|
||||||
|
|
||||||
#include <gwenhywfar/misc.h>
|
|
||||||
#include <gwenhywfar/list.h>
|
|
||||||
#include <gwenhywfar/error.h>
|
|
||||||
#include <gwenhywfar/debug.h>
|
|
||||||
#include <gwenhywfar/text.h>
|
|
||||||
#include <gwenhywfar/msg_ipc.h>
|
|
||||||
|
|
||||||
|
|
||||||
#define AQH_MSGIPC_GETDEVICES_RSP_OFFS_FLAGS 0 /* 1 bytes */
|
|
||||||
#define AQH_MSGIPC_GETDEVICES_RSP_OFFS_BUSADDR 1 /* 1 bytes */
|
|
||||||
#define AQH_MSGIPC_GETDEVICES_RSP_OFFS_UID 2 /* 4 bytes */
|
|
||||||
#define AQH_MSGIPC_GETDEVICES_RSP_OFFS_MANUF 6 /* 4 bytes */
|
|
||||||
#define AQH_MSGIPC_GETDEVICES_RSP_OFFS_DEVTYPE 10 /* 2 bytes */
|
|
||||||
#define AQH_MSGIPC_GETDEVICES_RSP_OFFS_DEVVER 12 /* 2 bytes */
|
|
||||||
#define AQH_MSGIPC_GETDEVICES_RSP_OFFS_FWVER 14 /* 4 bytes */
|
|
||||||
#define AQH_MSGIPC_GETDEVICES_RSP_OFFS_LASTCHG 18 /* 8 bytes */
|
|
||||||
#define AQH_MSGIPC_GETDEVICES_RSP_OFFS_PKGOUT 26 /* 2 bytes */
|
|
||||||
#define AQH_MSGIPC_GETDEVICES_RSP_OFFS_PKGIN 28 /* 2 bytes */
|
|
||||||
#define AQH_MSGIPC_GETDEVICES_RSP_OFFS_COLLISIONS 30 /* 2 bytes */
|
|
||||||
#define AQH_MSGIPC_GETDEVICES_RSP_OFFS_BUSY 32 /* 2 bytes */
|
|
||||||
#define AQH_MSGIPC_GETDEVICES_RSP_OFFS_CRC 34 /* 2 bytes */
|
|
||||||
#define AQH_MSGIPC_GETDEVICES_RSP_OFFS_IO 36 /* 2 bytes */
|
|
||||||
|
|
||||||
|
|
||||||
#define AQH_MSGIPC_GETDEVICES_RSP_MINSIZE (GWEN_MSGIPC_OFFS_PAYLOAD+AQH_MSGIPC_GETDEVICES_RSP_OFFS_IO+2)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
GWEN_MSG *AQH_GetDevicesResponseIpcMsg_new(uint16_t code, uint32_t msgId, uint32_t refMsgId, uint8_t flags, const AQH_NODE_INFO *ni)
|
|
||||||
{
|
|
||||||
GWEN_MSG *msg;
|
|
||||||
const GWEN_TIMESTAMP *t;
|
|
||||||
|
|
||||||
msg=GWEN_IpcMsg_new(AQH_IPC_PROTOCOL_NODES_ID, AQH_IPC_PROTOCOL_NODES_VERSION, code, msgId, refMsgId, 0, NULL);
|
|
||||||
GWEN_Msg_AddUint8(msg, flags & 0xff);
|
|
||||||
GWEN_Msg_AddUint8(msg, AQH_NodeInfo_GetBusAddress(ni));
|
|
||||||
GWEN_Msg_AddUint32(msg, AQH_NodeInfo_GetUid(ni));
|
|
||||||
|
|
||||||
GWEN_Msg_AddUint32(msg, AQH_NodeInfo_GetManufacturer(ni));
|
|
||||||
GWEN_Msg_AddUint16(msg, AQH_NodeInfo_GetDeviceType(ni));
|
|
||||||
GWEN_Msg_AddUint16(msg, AQH_NodeInfo_GetDeviceVersion(ni));
|
|
||||||
GWEN_Msg_AddUint32(msg, AQH_NodeInfo_GetFirmwareVersion(ni));
|
|
||||||
t=AQH_NodeInfo_GetTimestampLastChange(ni);
|
|
||||||
GWEN_Msg_AddUint64(msg, t?((uint64_t)GWEN_Timestamp_toInt64(t)):0L);
|
|
||||||
|
|
||||||
GWEN_Msg_AddUint16(msg, AQH_NodeInfo_GetStatsPacketsOut(ni));
|
|
||||||
GWEN_Msg_AddUint16(msg, AQH_NodeInfo_GetStatsPacketsIn(ni));
|
|
||||||
GWEN_Msg_AddUint16(msg, AQH_NodeInfo_GetStatsCollisions(ni));
|
|
||||||
GWEN_Msg_AddUint16(msg, AQH_NodeInfo_GetStatsBusy(ni));
|
|
||||||
GWEN_Msg_AddUint16(msg, AQH_NodeInfo_GetStatsCrcErrors(ni));
|
|
||||||
GWEN_Msg_AddUint16(msg, AQH_NodeInfo_GetStatsIoErrors(ni));
|
|
||||||
GWEN_IpcMsg_AdjustMsgSize(msg);
|
|
||||||
|
|
||||||
return msg;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint8_t AQH_GetDevicesResponseIpcMsg_GetFlags(const GWEN_MSG *msg)
|
|
||||||
{
|
|
||||||
return GWEN_Msg_GetUint8At(msg, GWEN_MSGIPC_OFFS_PAYLOAD+AQH_MSGIPC_GETDEVICES_RSP_OFFS_FLAGS, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint8_t AQH_GetDevicesResponseIpcMsg_GetBusAddress(const GWEN_MSG *msg)
|
|
||||||
{
|
|
||||||
return GWEN_Msg_GetUint16At(msg, GWEN_MSGIPC_OFFS_PAYLOAD+AQH_MSGIPC_GETDEVICES_RSP_OFFS_BUSADDR, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint32_t AQH_GetDevicesResponseIpcMsg_GetUid(const GWEN_MSG *msg)
|
|
||||||
{
|
|
||||||
return GWEN_Msg_GetUint32At(msg, GWEN_MSGIPC_OFFS_PAYLOAD+AQH_MSGIPC_GETDEVICES_RSP_OFFS_UID, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint32_t AQH_GetDevicesResponseIpcMsg_GetManufacturer(const GWEN_MSG *msg)
|
|
||||||
{
|
|
||||||
return GWEN_Msg_GetUint32At(msg, GWEN_MSGIPC_OFFS_PAYLOAD+AQH_MSGIPC_GETDEVICES_RSP_OFFS_MANUF, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint16_t AQH_GetDevicesResponseIpcMsg_GetDeviceType(const GWEN_MSG *msg)
|
|
||||||
{
|
|
||||||
return GWEN_Msg_GetUint16At(msg, GWEN_MSGIPC_OFFS_PAYLOAD+AQH_MSGIPC_GETDEVICES_RSP_OFFS_DEVTYPE, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint16_t AQH_GetDevicesResponseIpcMsg_GetDeviceVersion(const GWEN_MSG *msg)
|
|
||||||
{
|
|
||||||
return GWEN_Msg_GetUint16At(msg, GWEN_MSGIPC_OFFS_PAYLOAD+AQH_MSGIPC_GETDEVICES_RSP_OFFS_DEVVER, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint32_t AQH_GetDevicesResponseIpcMsg_GetFirmwareVersion(const GWEN_MSG *msg)
|
|
||||||
{
|
|
||||||
return GWEN_Msg_GetUint32At(msg, GWEN_MSGIPC_OFFS_PAYLOAD+AQH_MSGIPC_GETDEVICES_RSP_OFFS_FWVER, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int64_t AQH_GetDevicesResponseIpcMsg_GetTimestamp(const GWEN_MSG *msg)
|
|
||||||
{
|
|
||||||
return GWEN_Msg_GetUint64At(msg, GWEN_MSGIPC_OFFS_PAYLOAD+AQH_MSGIPC_GETDEVICES_RSP_OFFS_LASTCHG, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint16_t AQH_GetDevicesResponseIpcMsg_GetPkgOut(const GWEN_MSG *msg)
|
|
||||||
{
|
|
||||||
return GWEN_Msg_GetUint16At(msg, GWEN_MSGIPC_OFFS_PAYLOAD+AQH_MSGIPC_GETDEVICES_RSP_OFFS_PKGOUT, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint16_t AQH_GetDevicesResponseIpcMsg_GetPkgIn(const GWEN_MSG *msg)
|
|
||||||
{
|
|
||||||
return GWEN_Msg_GetUint16At(msg, GWEN_MSGIPC_OFFS_PAYLOAD+AQH_MSGIPC_GETDEVICES_RSP_OFFS_PKGIN, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint16_t AQH_GetDevicesResponseIpcMsg_GetCollisions(const GWEN_MSG *msg)
|
|
||||||
{
|
|
||||||
return GWEN_Msg_GetUint16At(msg, GWEN_MSGIPC_OFFS_PAYLOAD+AQH_MSGIPC_GETDEVICES_RSP_OFFS_COLLISIONS, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint16_t AQH_GetDevicesResponseIpcMsg_GetBusy(const GWEN_MSG *msg)
|
|
||||||
{
|
|
||||||
return GWEN_Msg_GetUint16At(msg, GWEN_MSGIPC_OFFS_PAYLOAD+AQH_MSGIPC_GETDEVICES_RSP_OFFS_BUSY, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint16_t AQH_GetDevicesResponseIpcMsg_GetCrcErrors(const GWEN_MSG *msg)
|
|
||||||
{
|
|
||||||
return GWEN_Msg_GetUint16At(msg, GWEN_MSGIPC_OFFS_PAYLOAD+AQH_MSGIPC_GETDEVICES_RSP_OFFS_CRC, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint16_t AQH_GetDevicesResponseIpcMsg_GetIoErrors(const GWEN_MSG *msg)
|
|
||||||
{
|
|
||||||
return GWEN_Msg_GetUint16At(msg, GWEN_MSGIPC_OFFS_PAYLOAD+AQH_MSGIPC_GETDEVICES_RSP_OFFS_IO, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_GetDevicesResponseIpcMsg_DumpToBuffer(const GWEN_MSG *msg, GWEN_BUFFER *dbuf, const char *sText)
|
|
||||||
{
|
|
||||||
if (GWEN_Msg_GetBytesInBuffer(msg)>=AQH_MSGIPC_GETDEVICES_RSP_MINSIZE) {
|
|
||||||
GWEN_Buffer_AppendArgs(dbuf,
|
|
||||||
"GET_DEVICES_RSP %s (code=%d, proto=%d, proto version=%d, uid=0x%08x, bus addr=0x%02x, flags=0x%02x)\n",
|
|
||||||
sText,
|
|
||||||
GWEN_IpcMsg_GetCode(msg),
|
|
||||||
GWEN_IpcMsg_GetProtoId(msg),
|
|
||||||
GWEN_IpcMsg_GetProtoVersion(msg),
|
|
||||||
(unsigned int) AQH_GetDevicesResponseIpcMsg_GetUid(msg),
|
|
||||||
AQH_GetDevicesResponseIpcMsg_GetBusAddress(msg),
|
|
||||||
AQH_GetDevicesResponseIpcMsg_GetFlags(msg));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
* 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 AQH_MSGIPC_GETDEVICES_RSP_H
|
|
||||||
#define AQH_MSGIPC_GETDEVICES_RSP_H
|
|
||||||
|
|
||||||
|
|
||||||
#include <aqhome/api.h>
|
|
||||||
#include <aqhome/ipc/nodes/ipc_nodes.h>
|
|
||||||
#include <aqhome/nodes/nodeinfo.h>
|
|
||||||
|
|
||||||
#include <gwenhywfar/msg.h>
|
|
||||||
#include <gwenhywfar/buffer.h>
|
|
||||||
|
|
||||||
|
|
||||||
#define AQH_MSGIPC_GETDEVICES_RSP_FLAGS_LAST 0x01
|
|
||||||
|
|
||||||
|
|
||||||
AQHOME_API GWEN_MSG *AQH_GetDevicesResponseIpcMsg_new(uint16_t code,
|
|
||||||
uint32_t msgId, uint32_t refMsgId,
|
|
||||||
uint8_t flags, const AQH_NODE_INFO *ni);
|
|
||||||
|
|
||||||
AQHOME_API uint8_t AQH_GetDevicesResponseIpcMsg_GetFlags(const GWEN_MSG *msg);
|
|
||||||
AQHOME_API uint8_t AQH_GetDevicesResponseIpcMsg_GetBusAddress(const GWEN_MSG *msg);
|
|
||||||
|
|
||||||
AQHOME_API uint32_t AQH_GetDevicesResponseIpcMsg_GetUid(const GWEN_MSG *msg);
|
|
||||||
|
|
||||||
AQHOME_API uint32_t AQH_GetDevicesResponseIpcMsg_GetManufacturer(const GWEN_MSG *msg);
|
|
||||||
AQHOME_API uint16_t AQH_GetDevicesResponseIpcMsg_GetDeviceType(const GWEN_MSG *msg);
|
|
||||||
AQHOME_API uint16_t AQH_GetDevicesResponseIpcMsg_GetDeviceVersion(const GWEN_MSG *msg);
|
|
||||||
AQHOME_API uint32_t AQH_GetDevicesResponseIpcMsg_GetFirmwareVersion(const GWEN_MSG *msg);
|
|
||||||
|
|
||||||
AQHOME_API int64_t AQH_GetDevicesResponseIpcMsg_GetTimestamp(const GWEN_MSG *msg);
|
|
||||||
|
|
||||||
AQHOME_API uint16_t AQH_GetDevicesResponseIpcMsg_GetPkgOut(const GWEN_MSG *msg);
|
|
||||||
AQHOME_API uint16_t AQH_GetDevicesResponseIpcMsg_GetPkgIn(const GWEN_MSG *msg);
|
|
||||||
AQHOME_API uint16_t AQH_GetDevicesResponseIpcMsg_GetCollisions(const GWEN_MSG *msg);
|
|
||||||
AQHOME_API uint16_t AQH_GetDevicesResponseIpcMsg_GetBusy(const GWEN_MSG *msg);
|
|
||||||
AQHOME_API uint16_t AQH_GetDevicesResponseIpcMsg_GetCrcErrors(const GWEN_MSG *msg);
|
|
||||||
AQHOME_API uint16_t AQH_GetDevicesResponseIpcMsg_GetIoErrors(const GWEN_MSG *msg);
|
|
||||||
|
|
||||||
|
|
||||||
AQHOME_API void AQH_GetDevicesResponseIpcMsg_DumpToBuffer(const GWEN_MSG *msg, GWEN_BUFFER *dbuf, const char *sText);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
@@ -1,71 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
* 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 <aqhome/ipc/nodes/msg_ipc_ping.h>
|
|
||||||
|
|
||||||
#include <gwenhywfar/msg.h>
|
|
||||||
#include <gwenhywfar/buffer.h>
|
|
||||||
|
|
||||||
#include <gwenhywfar/misc.h>
|
|
||||||
#include <gwenhywfar/list.h>
|
|
||||||
#include <gwenhywfar/error.h>
|
|
||||||
#include <gwenhywfar/debug.h>
|
|
||||||
#include <gwenhywfar/text.h>
|
|
||||||
#include <gwenhywfar/msg_ipc.h>
|
|
||||||
|
|
||||||
|
|
||||||
#define AQH_MSGIPC_PING_OFFS_DESTADDR 0 /* 1 bytes */
|
|
||||||
|
|
||||||
#define AQH_MSGIPC_PING_PAYLOADSIZE 1
|
|
||||||
#define AQH_MSGIPC_PING_MINSIZE (GWEN_MSGIPC_OFFS_PAYLOAD+AQH_MSGIPC_PING_PAYLOADSIZE)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
GWEN_MSG *AQH_PingIpcMsg_new(uint16_t code, uint32_t msgId, uint32_t refMsgId, uint8_t destAddr)
|
|
||||||
{
|
|
||||||
GWEN_MSG *msg;
|
|
||||||
|
|
||||||
msg=GWEN_IpcMsg_new(AQH_IPC_PROTOCOL_NODES_ID, AQH_IPC_PROTOCOL_NODES_VERSION, code,
|
|
||||||
msgId, refMsgId,
|
|
||||||
AQH_MSGIPC_PING_PAYLOADSIZE, NULL);
|
|
||||||
GWEN_Msg_AddUint8(msg, destAddr & 0xff);
|
|
||||||
|
|
||||||
return msg;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint8_t AQH_PingIpcMsg_GetDestAddr(const GWEN_MSG *msg)
|
|
||||||
{
|
|
||||||
return GWEN_Msg_GetUint8At(msg, GWEN_MSGIPC_OFFS_PAYLOAD+AQH_MSGIPC_PING_OFFS_DESTADDR, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_PingIpcMsg_DumpToBuffer(const GWEN_MSG *msg, GWEN_BUFFER *dbuf, const char *sText)
|
|
||||||
{
|
|
||||||
if (GWEN_Msg_GetBytesInBuffer(msg)>=AQH_MSGIPC_PING_MINSIZE) {
|
|
||||||
GWEN_Buffer_AppendArgs(dbuf,
|
|
||||||
"PING %s (code=%d, proto=%d, proto version=%d, dest addr=%02x)\n",
|
|
||||||
sText?sText:"",
|
|
||||||
GWEN_IpcMsg_GetCode(msg),
|
|
||||||
GWEN_IpcMsg_GetProtoId(msg),
|
|
||||||
GWEN_IpcMsg_GetProtoVersion(msg),
|
|
||||||
AQH_PingIpcMsg_GetDestAddr(msg));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
* 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 AQH_MSG_IPC_PING_H
|
|
||||||
#define AQH_MSG_IPC_PING_H
|
|
||||||
|
|
||||||
|
|
||||||
#include <aqhome/api.h>
|
|
||||||
#include <aqhome/ipc/nodes/ipc_nodes.h>
|
|
||||||
|
|
||||||
#include <gwenhywfar/msg.h>
|
|
||||||
#include <gwenhywfar/buffer.h>
|
|
||||||
|
|
||||||
|
|
||||||
AQHOME_API GWEN_MSG *AQH_PingIpcMsg_new(uint16_t code, uint32_t msgId, uint32_t refMsgId, uint8_t destAddr);
|
|
||||||
|
|
||||||
AQHOME_API uint8_t AQH_PingIpcMsg_GetDestAddr(const GWEN_MSG *msg);
|
|
||||||
|
|
||||||
AQHOME_API void AQH_PingIpcMsg_DumpToBuffer(const GWEN_MSG *msg, GWEN_BUFFER *dbuf, const char *sText);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
@@ -1,68 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
* 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 <aqhome/ipc/nodes/msg_ipc_setaccmsggrps.h>
|
|
||||||
|
|
||||||
#include <gwenhywfar/msg.h>
|
|
||||||
#include <gwenhywfar/buffer.h>
|
|
||||||
|
|
||||||
#include <gwenhywfar/misc.h>
|
|
||||||
#include <gwenhywfar/list.h>
|
|
||||||
#include <gwenhywfar/error.h>
|
|
||||||
#include <gwenhywfar/debug.h>
|
|
||||||
#include <gwenhywfar/text.h>
|
|
||||||
#include <gwenhywfar/msg_ipc.h>
|
|
||||||
|
|
||||||
|
|
||||||
#define AQH_MSGIPC_SETACCEPTEDMSGGRPS_OFFS_GROUPS 0 /* 4 bytes */
|
|
||||||
|
|
||||||
#define AQH_MSGIPC_SETACCEPTEDMSGGRPS_PAYLOADSIZE (AQH_MSGIPC_SETACCEPTEDMSGGRPS_OFFS_GROUPS+4)
|
|
||||||
#define AQH_MSGIPC_SETACCEPTEDMSGGRPS_MINSIZE (GWEN_MSGIPC_OFFS_PAYLOAD+AQH_MSGIPC_SETACCEPTEDMSGGRPS_PAYLOADSIZE)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
GWEN_MSG *AQH_SetAcceptedMsgGroupsIpcMsg_new(uint16_t code, uint32_t msgId, uint32_t refMsgId, uint32_t groups)
|
|
||||||
{
|
|
||||||
GWEN_MSG *msg;
|
|
||||||
uint8_t *ptr;
|
|
||||||
|
|
||||||
msg=GWEN_IpcMsg_new(AQH_IPC_PROTOCOL_NODES_ID, AQH_IPC_PROTOCOL_NODES_VERSION, code,
|
|
||||||
msgId, refMsgId,
|
|
||||||
AQH_MSGIPC_SETACCEPTEDMSGGRPS_PAYLOADSIZE, NULL);
|
|
||||||
GWEN_Msg_AddUint32(msg, groups);
|
|
||||||
return msg;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint32_t AQH_SetAcceptedMsgGroupsIpcMsg_GetMsgGroups(const GWEN_MSG *msg)
|
|
||||||
{
|
|
||||||
return GWEN_Msg_GetUint32At(msg, GWEN_MSGIPC_OFFS_PAYLOAD+AQH_MSGIPC_SETACCEPTEDMSGGRPS_OFFS_GROUPS, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_SetAcceptedMsgGroupsIpcMsg_DumpToBuffer(const GWEN_MSG *msg, GWEN_BUFFER *dbuf, const char *sText)
|
|
||||||
{
|
|
||||||
if (GWEN_Msg_GetBytesInBuffer(msg)>=AQH_MSGIPC_SETACCEPTEDMSGGRPS_MINSIZE) {
|
|
||||||
GWEN_Buffer_AppendArgs(dbuf,
|
|
||||||
"SET_ACCEPTED_MSG_GROUPS (code=%d, proto=%d, proto version=%d, groups=%08x)\n",
|
|
||||||
GWEN_IpcMsg_GetCode(msg),
|
|
||||||
GWEN_IpcMsg_GetProtoId(msg),
|
|
||||||
GWEN_IpcMsg_GetProtoVersion(msg),
|
|
||||||
AQH_SetAcceptedMsgGroupsIpcMsg_GetMsgGroups(msg));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
* 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 AQH_MSGIPC_SETACCEPTEDMSGGRPS_H
|
|
||||||
#define AQH_MSGIPC_SETACCEPTEDMSGGRPS_H
|
|
||||||
|
|
||||||
|
|
||||||
#include <aqhome/api.h>
|
|
||||||
#include <aqhome/ipc/nodes/ipc_nodes.h>
|
|
||||||
|
|
||||||
#include <gwenhywfar/msg.h>
|
|
||||||
#include <gwenhywfar/buffer.h>
|
|
||||||
|
|
||||||
|
|
||||||
AQHOME_API GWEN_MSG *AQH_SetAcceptedMsgGroupsIpcMsg_new(uint16_t code, uint32_t msgId, uint32_t refMsgId, uint32_t groups);
|
|
||||||
|
|
||||||
AQHOME_API uint32_t AQH_SetAcceptedMsgGroupsIpcMsg_GetMsgGroups(const GWEN_MSG *msg);
|
|
||||||
|
|
||||||
AQHOME_API void AQH_SetAcceptedMsgGroupsIpcMsg_DumpToBuffer(const GWEN_MSG *msg, GWEN_BUFFER *dbuf, const char *sText);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
@@ -1,136 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
* 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 <aqhome/ipc/nodes/msg_ipc_value.h>
|
|
||||||
|
|
||||||
#include <gwenhywfar/msg.h>
|
|
||||||
#include <gwenhywfar/buffer.h>
|
|
||||||
|
|
||||||
#include <gwenhywfar/misc.h>
|
|
||||||
#include <gwenhywfar/list.h>
|
|
||||||
#include <gwenhywfar/error.h>
|
|
||||||
#include <gwenhywfar/debug.h>
|
|
||||||
#include <gwenhywfar/text.h>
|
|
||||||
#include <gwenhywfar/msg_ipc.h>
|
|
||||||
|
|
||||||
|
|
||||||
#define AQH_MSGIPC_VALUE_OFFS_UID 0 /* 4 bytes */
|
|
||||||
#define AQH_MSGIPC_VALUE_OFFS_VALUEID 4 /* 1 byte */
|
|
||||||
#define AQH_MSGIPC_VALUE_OFFS_VALUETYPE 5 /* 1 byte */
|
|
||||||
#define AQH_MSGIPC_VALUE_OFFS_VALUE_NOM 6 /* 2 bytes */
|
|
||||||
#define AQH_MSGIPC_VALUE_OFFS_VALUE_DENOM 8 /* 2 bytes */
|
|
||||||
|
|
||||||
#define AQH_MSGIPC_VALUE_PAYLOADIZE (AQH_MSGIPC_VALUE_OFFS_UID+10)
|
|
||||||
#define AQH_MSGIPC_VALUE_MINSIZE (GWEN_MSGIPC_OFFS_PAYLOAD+AQH_MSGIPC_VALUE_PAYLOADIZE)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
GWEN_MSG *AQH_ValueIpcMsg_new(uint16_t code, uint32_t msgId, uint32_t refMsgId,
|
|
||||||
uint32_t uid,
|
|
||||||
uint8_t valueId,
|
|
||||||
uint8_t valueType,
|
|
||||||
int16_t valueNom,
|
|
||||||
int16_t valueDenom)
|
|
||||||
{
|
|
||||||
GWEN_MSG *msg;
|
|
||||||
uint8_t *ptr;
|
|
||||||
|
|
||||||
msg=GWEN_IpcMsg_new(AQH_IPC_PROTOCOL_NODES_ID, AQH_IPC_PROTOCOL_NODES_VERSION, code,
|
|
||||||
msgId, refMsgId, AQH_MSGIPC_VALUE_PAYLOADIZE, NULL);
|
|
||||||
GWEN_Msg_AddUint32(msg, uid);
|
|
||||||
GWEN_Msg_AddUint8(msg, valueId);
|
|
||||||
GWEN_Msg_AddUint8(msg, valueType);
|
|
||||||
GWEN_Msg_AddUint16(msg, valueNom);
|
|
||||||
GWEN_Msg_AddUint16(msg, valueDenom);
|
|
||||||
|
|
||||||
return msg;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint32_t AQH_ValueIpcMsg_GetUid(const GWEN_MSG *msg)
|
|
||||||
{
|
|
||||||
return GWEN_Msg_GetUint32At(msg, GWEN_MSGIPC_OFFS_PAYLOAD+AQH_MSGIPC_VALUE_OFFS_UID, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint8_t AQH_ValueIpcMsg_GetValueId(const GWEN_MSG *msg)
|
|
||||||
{
|
|
||||||
return GWEN_Msg_GetUint8At(msg, GWEN_MSGIPC_OFFS_PAYLOAD+AQH_MSGIPC_VALUE_OFFS_VALUEID, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint8_t AQH_ValueIpcMsg_GetValueType(const GWEN_MSG *msg)
|
|
||||||
{
|
|
||||||
return GWEN_Msg_GetUint8At(msg, GWEN_MSGIPC_OFFS_PAYLOAD+AQH_MSGIPC_VALUE_OFFS_VALUETYPE, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int16_t AQH_ValueIpcMsg_GetValueNom(const GWEN_MSG *msg)
|
|
||||||
{
|
|
||||||
return GWEN_Msg_GetUint16At(msg, GWEN_MSGIPC_OFFS_PAYLOAD+AQH_MSGIPC_VALUE_OFFS_VALUE_NOM, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int16_t AQH_ValueIpcMsg_GetValueDenom(const GWEN_MSG *msg)
|
|
||||||
{
|
|
||||||
return GWEN_Msg_GetUint16At(msg, GWEN_MSGIPC_OFFS_PAYLOAD+AQH_MSGIPC_VALUE_OFFS_VALUE_DENOM, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
double AQH_ValueIpcMsg_GetValueAsDouble(const GWEN_MSG *msg)
|
|
||||||
{
|
|
||||||
if (GWEN_Msg_GetBytesInBuffer(msg)>=AQH_MSGIPC_VALUE_MINSIZE) {
|
|
||||||
double nom;
|
|
||||||
int16_t rawDenom;
|
|
||||||
double denom;
|
|
||||||
|
|
||||||
nom=(double) AQH_ValueIpcMsg_GetValueNom(msg);
|
|
||||||
rawDenom=AQH_ValueIpcMsg_GetValueDenom(msg);
|
|
||||||
if (rawDenom==0)
|
|
||||||
denom=1.0;
|
|
||||||
else
|
|
||||||
denom=(double) rawDenom;
|
|
||||||
return (double)(nom/denom);
|
|
||||||
}
|
|
||||||
return 0.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_ValueIpcMsg_DumpToBuffer(const GWEN_MSG *msg, GWEN_BUFFER *dbuf, const char *sText)
|
|
||||||
{
|
|
||||||
if (GWEN_Msg_GetBytesInBuffer(msg)>=AQH_MSGIPC_VALUE_MINSIZE) {
|
|
||||||
GWEN_Buffer_AppendArgs(dbuf,
|
|
||||||
"VALUE (code=%d, proto=%d, proto version=%d, uid=0x%08x, value_id=0x%02x, type=0x%02x, value=%f)\n",
|
|
||||||
GWEN_IpcMsg_GetCode(msg),
|
|
||||||
GWEN_IpcMsg_GetProtoId(msg),
|
|
||||||
GWEN_IpcMsg_GetProtoVersion(msg),
|
|
||||||
(unsigned int) AQH_ValueIpcMsg_GetUid(msg),
|
|
||||||
AQH_ValueIpcMsg_GetValueId(msg),
|
|
||||||
AQH_ValueIpcMsg_GetValueType(msg),
|
|
||||||
AQH_ValueIpcMsg_GetValueAsDouble(msg));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
* 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 AQH_MSG_IPC_VALUE_H
|
|
||||||
#define AQH_MSG_IPC_VALUE_H
|
|
||||||
|
|
||||||
|
|
||||||
#include <aqhome/api.h>
|
|
||||||
#include <aqhome/ipc/nodes/ipc_nodes.h>
|
|
||||||
#include <aqhome/msg/msg_node.h>
|
|
||||||
|
|
||||||
#include <gwenhywfar/msg.h>
|
|
||||||
#include <gwenhywfar/buffer.h>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
AQHOME_API GWEN_MSG *AQH_ValueIpcMsg_new(uint16_t code, uint32_t msgId, uint32_t refMsgId,
|
|
||||||
uint32_t uid,
|
|
||||||
uint8_t valueId,
|
|
||||||
uint8_t valueType,
|
|
||||||
int16_t valueNom,
|
|
||||||
int16_t valueDenom);
|
|
||||||
AQHOME_API uint32_t AQH_ValueIpcMsg_GetUid(const GWEN_MSG *msg);
|
|
||||||
AQHOME_API uint8_t AQH_ValueIpcMsg_GetValueId(const GWEN_MSG *msg);
|
|
||||||
AQHOME_API uint8_t AQH_ValueIpcMsg_GetValueType(const GWEN_MSG *msg);
|
|
||||||
AQHOME_API int16_t AQH_ValueIpcMsg_GetValueNom(const GWEN_MSG *msg);
|
|
||||||
AQHOME_API int16_t AQH_ValueIpcMsg_GetValueDenom(const GWEN_MSG *msg);
|
|
||||||
AQHOME_API double AQH_ValueIpcMsg_GetValueAsDouble(const GWEN_MSG *msg);
|
|
||||||
|
|
||||||
AQHOME_API void AQH_ValueIpcMsg_DumpToBuffer(const GWEN_MSG *msg, GWEN_BUFFER *dbuf, const char *sText);
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,142 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
* 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 <config.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#include "./requests.h"
|
|
||||||
|
|
||||||
#include <gwenhywfar/debug.h>
|
|
||||||
#include <gwenhywfar/msg_ipc.h>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------------------------------
|
|
||||||
* forward declarations
|
|
||||||
* ------------------------------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
static void _freeFinishedRequests(GWEN_MSG_REQUEST *rq);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_Requests_CheckTimeouts(GWEN_MSG_REQUEST *requestTreeRoot)
|
|
||||||
{
|
|
||||||
if (requestTreeRoot) {
|
|
||||||
GWEN_MSG_REQUEST *rq;
|
|
||||||
GWEN_TIMESTAMP *now;
|
|
||||||
|
|
||||||
now=GWEN_Timestamp_NowInLocalTime();
|
|
||||||
rq=GWEN_MsgRequest_Tree2_GetFirstChild(requestTreeRoot);
|
|
||||||
while(rq) {
|
|
||||||
const GWEN_TIMESTAMP *ts;
|
|
||||||
|
|
||||||
ts=GWEN_MsgRequest_GetExpiresAt(rq);
|
|
||||||
if (GWEN_Timestamp_Compare(now, ts)>=0) {
|
|
||||||
/* timeout */
|
|
||||||
DBG_INFO(NULL, "Request timed out, aborting");
|
|
||||||
GWEN_MsgRequest_Abort(rq, GWEN_MSG_REQUEST_REASON_TIMEOUT);
|
|
||||||
}
|
|
||||||
rq=GWEN_MsgRequest_Tree2_GetBelow(rq);
|
|
||||||
}
|
|
||||||
GWEN_Timestamp_free(now);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_Requests_Cleanup(GWEN_MSG_REQUEST *requestTreeRoot)
|
|
||||||
{
|
|
||||||
if (requestTreeRoot) {
|
|
||||||
GWEN_MSG_REQUEST *rq;
|
|
||||||
|
|
||||||
rq=GWEN_MsgRequest_Tree2_GetFirstChild(requestTreeRoot);
|
|
||||||
while(rq) {
|
|
||||||
GWEN_MSG_REQUEST *nextSubRq;
|
|
||||||
|
|
||||||
nextSubRq=GWEN_MsgRequest_Tree2_GetNext(rq);
|
|
||||||
_freeFinishedRequests(rq);
|
|
||||||
rq=nextSubRq;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int AQH_Requests_HandleIpcMsg(GWEN_MSG_REQUEST *requestTreeRoot, GWEN_MSG_ENDPOINT *srcEp, GWEN_MSG *recvdMsg)
|
|
||||||
{
|
|
||||||
if (requestTreeRoot) {
|
|
||||||
uint32_t refMsgId;
|
|
||||||
|
|
||||||
refMsgId=GWEN_IpcMsg_GetRefMsgId(recvdMsg);
|
|
||||||
if (refMsgId) {
|
|
||||||
GWEN_MSG_REQUEST *rq;
|
|
||||||
|
|
||||||
rq=GWEN_MsgRequest_Tree2_GetFirstChild(requestTreeRoot);
|
|
||||||
while(rq) {
|
|
||||||
if (srcEp==GWEN_MsgRequest_GetEndpoint(rq) && refMsgId==GWEN_MsgRequest_GetRequestMsgId(rq)) {
|
|
||||||
if (GWEN_MsgRequest_HandleResponse(rq, recvdMsg)==GWEN_MSG_REQUEST_RESULT_HANDLED)
|
|
||||||
return GWEN_MSG_REQUEST_RESULT_HANDLED;
|
|
||||||
}
|
|
||||||
|
|
||||||
rq=GWEN_MsgRequest_Tree2_GetBelow(rq);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
DBG_INFO(NULL, "Message has no reference msg id, not a response");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return GWEN_MSG_REQUEST_RESULT_NOT_HANDLED;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int AQH_Requests_HandleTtyMsg(GWEN_MSG_REQUEST *requestTreeRoot, GWEN_MSG_ENDPOINT *srcEp, GWEN_MSG *recvdMsg)
|
|
||||||
{
|
|
||||||
if (requestTreeRoot) {
|
|
||||||
GWEN_MSG_REQUEST *rq;
|
|
||||||
|
|
||||||
rq=GWEN_MsgRequest_Tree2_GetFirstChild(requestTreeRoot);
|
|
||||||
while(rq) {
|
|
||||||
if (srcEp==GWEN_MsgRequest_GetEndpoint(rq)) {
|
|
||||||
if (GWEN_MsgRequest_HandleResponse(rq, recvdMsg)==GWEN_MSG_REQUEST_RESULT_HANDLED)
|
|
||||||
return GWEN_MSG_REQUEST_RESULT_HANDLED;
|
|
||||||
}
|
|
||||||
|
|
||||||
rq=GWEN_MsgRequest_Tree2_GetBelow(rq);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return GWEN_MSG_REQUEST_RESULT_NOT_HANDLED;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void _freeFinishedRequests(GWEN_MSG_REQUEST *rq)
|
|
||||||
{
|
|
||||||
GWEN_MSG_REQUEST *subRq;
|
|
||||||
|
|
||||||
subRq=GWEN_MsgRequest_Tree2_GetFirstChild(rq);
|
|
||||||
while(subRq) {
|
|
||||||
GWEN_MSG_REQUEST *nextSubRq;
|
|
||||||
|
|
||||||
nextSubRq=GWEN_MsgRequest_Tree2_GetNext(subRq);
|
|
||||||
_freeFinishedRequests(subRq);
|
|
||||||
subRq=nextSubRq;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GWEN_MsgRequest_GetState(rq)==GWEN_MSG_REQUEST_STATE_DONE) {
|
|
||||||
DBG_INFO(NULL, "Deleting request");
|
|
||||||
GWEN_MsgRequest_free(rq);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user