aqhome: removed uneeded files.
This commit is contained in:
273
aqhome/msg.c
273
aqhome/msg.c
@@ -1,273 +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/msg_p.h"
|
|
||||||
|
|
||||||
#include <gwenhywfar/misc.h>
|
|
||||||
#include <gwenhywfar/list.h>
|
|
||||||
#include <gwenhywfar/error.h>
|
|
||||||
#include <gwenhywfar/debug.h>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
GWEN_LIST_FUNCTIONS(AQH_MSG, AQH_Msg)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static uint8_t _calcChecksum(const uint8_t *ptr, uint8_t len);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
AQH_MSG *AQH_Msg_new()
|
|
||||||
{
|
|
||||||
AQH_MSG *msg;
|
|
||||||
|
|
||||||
GWEN_NEW_OBJECT(AQH_MSG, msg);
|
|
||||||
GWEN_LIST_INIT(AQH_MSG, msg);
|
|
||||||
return msg;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_Msg_free(AQH_MSG *msg)
|
|
||||||
{
|
|
||||||
if (msg) {
|
|
||||||
GWEN_LIST_FINI(AQH_MSG, msg);
|
|
||||||
GWEN_FREE_OBJECT(msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
AQH_MSG *AQH_Msg_dup(const AQH_MSG *srcMsg)
|
|
||||||
{
|
|
||||||
AQH_MSG *msg;
|
|
||||||
|
|
||||||
msg=AQH_Msg_new();
|
|
||||||
memmove(msg->buffer, srcMsg->buffer, AQH_MAXMSGSIZE);
|
|
||||||
msg->bytesInBuffer=srcMsg->bytesInBuffer;
|
|
||||||
msg->currentPos=srcMsg->currentPos;
|
|
||||||
|
|
||||||
return msg;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint8_t *AQH_Msg_GetBuffer(AQH_MSG *msg)
|
|
||||||
{
|
|
||||||
if (msg)
|
|
||||||
return msg->buffer;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const uint8_t *AQH_Msg_GetConstBuffer(const AQH_MSG *msg)
|
|
||||||
{
|
|
||||||
if (msg)
|
|
||||||
return msg->buffer;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint8_t AQH_Msg_GetBytesInBuffer(const AQH_MSG *msg)
|
|
||||||
{
|
|
||||||
if (msg)
|
|
||||||
return msg->bytesInBuffer;
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint8_t AQH_Msg_GetCurrentPos(const AQH_MSG *msg)
|
|
||||||
{
|
|
||||||
if (msg)
|
|
||||||
return msg->currentPos;
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int AQH_Msg_AddByte(AQH_MSG *msg, uint8_t b)
|
|
||||||
{
|
|
||||||
if (msg) {
|
|
||||||
if ((msg->bytesInBuffer<AQH_MAXMSGSIZE) &&
|
|
||||||
(msg->currentPos<AQH_MAXMSGSIZE)) {
|
|
||||||
msg->buffer[(msg->currentPos)++]=b;
|
|
||||||
msg->bytesInBuffer++;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return GWEN_ERROR_MEMORY_FULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int AQH_Msg_ReadNextByte(AQH_MSG *msg)
|
|
||||||
{
|
|
||||||
if (msg) {
|
|
||||||
if ((msg->currentPos<AQH_MAXMSGSIZE) &&
|
|
||||||
(msg->currentPos<msg->bytesInBuffer)) {
|
|
||||||
return ((int)(msg->buffer[(msg->currentPos)++])) & 0xff;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return GWEN_ERROR_EOF;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int AQH_Msg_IncCurrentPos(AQH_MSG *msg, uint8_t i)
|
|
||||||
{
|
|
||||||
if (msg) {
|
|
||||||
if (((msg->currentPos+i)<AQH_MAXMSGSIZE) &&
|
|
||||||
((msg->currentPos+i)<msg->bytesInBuffer)) {
|
|
||||||
msg->currentPos+=i;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return GWEN_ERROR_EOF;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int AQH_Msg_RewindCurrentPos(AQH_MSG *msg)
|
|
||||||
{
|
|
||||||
if (msg) {
|
|
||||||
msg->currentPos=0;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return GWEN_ERROR_EOF;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int AQH_Msg_GetRemainingBytes(const AQH_MSG *msg)
|
|
||||||
{
|
|
||||||
if (msg)
|
|
||||||
return msg->bytesInBuffer-msg->currentPos;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint8_t AQH_Msg_GetDestAddress(const AQH_MSG *msg)
|
|
||||||
{
|
|
||||||
if (msg && msg->bytesInBuffer>AQH_MSG_OFFS_ALL_DEST_ADDRESS)
|
|
||||||
return msg->buffer[AQH_MSG_OFFS_ALL_DEST_ADDRESS];
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint8_t AQH_Msg_GetMsgType(const AQH_MSG *msg)
|
|
||||||
{
|
|
||||||
if (msg && msg->bytesInBuffer>AQH_MSG_OFFS_ALL_MSG_TYPE)
|
|
||||||
return msg->buffer[AQH_MSG_OFFS_ALL_MSG_TYPE];
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint8_t AQH_Msg_GetSourceAddress(const AQH_MSG *msg)
|
|
||||||
{
|
|
||||||
if (msg && msg->bytesInBuffer>AQH_MSG_OFFS_ALL_SRC_ADDRESS)
|
|
||||||
return msg->buffer[AQH_MSG_OFFS_ALL_SRC_ADDRESS];
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint8_t AQH_Msg_GetMsgPayloadLen(const AQH_MSG *msg)
|
|
||||||
{
|
|
||||||
if (msg && msg->bytesInBuffer>AQH_MSG_OFFS_ALL_PAYLOAD_LEN)
|
|
||||||
return msg->buffer[AQH_MSG_OFFS_ALL_PAYLOAD_LEN];
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int AQH_Msg_IsMsgComplete(const AQH_MSG *msg)
|
|
||||||
{
|
|
||||||
if (msg && msg->bytesInBuffer>AQH_MSG_OFFS_ALL_PAYLOAD_LEN) {
|
|
||||||
uint8_t len;
|
|
||||||
|
|
||||||
len=msg->buffer[AQH_MSG_OFFS_ALL_PAYLOAD_LEN]+AQH_MSG_OFFS_ALL_PAYLOAD_BEGIN+1;
|
|
||||||
if (len>AQH_MAXMSGSIZE)
|
|
||||||
return -1;
|
|
||||||
else if (msg->bytesInBuffer>=len)
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int AQH_Msg_IsChecksumValid(const AQH_MSG *msg)
|
|
||||||
{
|
|
||||||
if (msg && AQH_Msg_IsMsgComplete(msg))
|
|
||||||
return (_calcChecksum(msg->buffer, msg->bytesInBuffer)==0)?1:0;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int AQH_Msg_AddChecksum(AQH_MSG *msg)
|
|
||||||
{
|
|
||||||
if (msg) {
|
|
||||||
int rv;
|
|
||||||
|
|
||||||
rv=AQH_Msg_AddByte(msg, _calcChecksum(msg->buffer, msg->bytesInBuffer));
|
|
||||||
if (rv<0) {
|
|
||||||
DBG_INFO(NULL, "here (%d)", rv);
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return GWEN_ERROR_GENERIC;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_Msg_DumpToBuffer(const AQH_MSG *msg, GWEN_BUFFER *dbuf, const char *sText)
|
|
||||||
{
|
|
||||||
GWEN_Buffer_AppendArgs(dbuf,
|
|
||||||
"0x%02x->0x%02x: %d %s\n",
|
|
||||||
AQH_Msg_GetSourceAddress(msg),
|
|
||||||
AQH_Msg_GetDestAddress(msg),
|
|
||||||
AQH_Msg_GetMsgType(msg),
|
|
||||||
sText);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint8_t _calcChecksum(const uint8_t *ptr, uint8_t len)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
uint8_t x=0;
|
|
||||||
|
|
||||||
for (i=0; i<len; i++, ptr++) {
|
|
||||||
x^=*ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
83
aqhome/msg.h
83
aqhome/msg.h
@@ -1,83 +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_H
|
|
||||||
#define AQH_MSG_H
|
|
||||||
|
|
||||||
|
|
||||||
#define AQH_MAXMSGSIZE 16
|
|
||||||
|
|
||||||
#include <aqhome/api.h>
|
|
||||||
|
|
||||||
#include <gwenhywfar/list.h>
|
|
||||||
#include <gwenhywfar/buffer.h>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define AQH_MSG_OFFS_ALL_DEST_ADDRESS 0
|
|
||||||
#define AQH_MSG_OFFS_ALL_PAYLOAD_LEN 1
|
|
||||||
#define AQH_MSG_OFFS_ALL_PAYLOAD_BEGIN 2
|
|
||||||
#define AQH_MSG_OFFS_ALL_MSG_TYPE 2
|
|
||||||
#define AQH_MSG_OFFS_ALL_SRC_ADDRESS 3
|
|
||||||
#define AQH_MSG_OFFS_ALL_DATA_BEGIN 4
|
|
||||||
|
|
||||||
|
|
||||||
#define AQH_MSG_TYPE_PING 10
|
|
||||||
#define AQH_MSG_TYPE_PONG 11
|
|
||||||
#define AQH_MSG_TYPE_COMSENDSTATS 20
|
|
||||||
#define AQH_MSG_TYPE_COMRECVSTATS 21
|
|
||||||
#define AQH_MSG_TYPE_TWIBUSMEMBER 30
|
|
||||||
#define AQH_MSG_TYPE_DEBUG 40
|
|
||||||
#define AQH_MSG_TYPE_VALUE 50
|
|
||||||
#define AQH_MSG_TYPE_NEED_ADDRESS 60
|
|
||||||
#define AQH_MSG_TYPE_HAVE_ADDRESS 61
|
|
||||||
#define AQH_MSG_TYPE_CLAIM_ADDRESS 62
|
|
||||||
#define AQH_MSG_TYPE_DENY_ADDRESS 63
|
|
||||||
#define AQH_MSG_TYPE_ADDRESS_RANGE 64
|
|
||||||
|
|
||||||
/* internal msg types via NET interface */
|
|
||||||
#define AQH_MSG_TYPE_NET_SET_ACCEPTED_MSGGROUPS 200
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct AQH_MSG AQH_MSG;
|
|
||||||
GWEN_LIST_FUNCTION_LIB_DEFS(AQH_MSG, AQH_Msg, AQHOME_API)
|
|
||||||
|
|
||||||
|
|
||||||
AQHOME_API AQH_MSG *AQH_Msg_new();
|
|
||||||
AQHOME_API void AQH_Msg_free(AQH_MSG *msg);
|
|
||||||
AQHOME_API AQH_MSG *AQH_Msg_dup(const AQH_MSG *srcMsg);
|
|
||||||
|
|
||||||
AQHOME_API uint8_t *AQH_Msg_GetBuffer(AQH_MSG *msg);
|
|
||||||
AQHOME_API const uint8_t *AQH_Msg_GetConstBuffer(const AQH_MSG *msg);
|
|
||||||
AQHOME_API uint8_t AQH_Msg_GetBytesInBuffer(const AQH_MSG *msg);
|
|
||||||
AQHOME_API uint8_t AQH_Msg_GetCurrentPos(const AQH_MSG *msg);
|
|
||||||
AQHOME_API int AQH_Msg_AddByte(AQH_MSG *msg, uint8_t b);
|
|
||||||
AQHOME_API int AQH_Msg_ReadNextByte(AQH_MSG *msg);
|
|
||||||
AQHOME_API int AQH_Msg_IncCurrentPos(AQH_MSG *msg, uint8_t i);
|
|
||||||
AQHOME_API int AQH_Msg_GetRemainingBytes(const AQH_MSG *msg);
|
|
||||||
AQHOME_API int AQH_Msg_RewindCurrentPos(AQH_MSG *msg);
|
|
||||||
|
|
||||||
AQHOME_API uint8_t AQH_Msg_GetDestAddress(const AQH_MSG *msg);
|
|
||||||
AQHOME_API uint8_t AQH_Msg_GetMsgType(const AQH_MSG *msg);
|
|
||||||
AQHOME_API uint8_t AQH_Msg_GetSourceAddress(const AQH_MSG *msg);
|
|
||||||
AQHOME_API uint8_t AQH_Msg_GetMsgPayloadLen(const AQH_MSG *msg);
|
|
||||||
|
|
||||||
AQHOME_API int AQH_Msg_IsMsgComplete(const AQH_MSG *msg);
|
|
||||||
AQHOME_API int AQH_Msg_IsChecksumValid(const AQH_MSG *msg);
|
|
||||||
AQHOME_API int AQH_Msg_AddChecksum(AQH_MSG *msg);
|
|
||||||
|
|
||||||
AQHOME_API void AQH_Msg_DumpToBuffer(const AQH_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/msg_claimaddr.h"
|
|
||||||
|
|
||||||
#include <gwenhywfar/misc.h>
|
|
||||||
#include <gwenhywfar/list.h>
|
|
||||||
#include <gwenhywfar/error.h>
|
|
||||||
#include <gwenhywfar/debug.h>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint32_t AQH_MsgClaimAddr_GetUid(const AQH_MSG *msg)
|
|
||||||
{
|
|
||||||
if ((AQH_Msg_GetMsgType(msg)==AQH_MSG_TYPE_CLAIM_ADDRESS) &&
|
|
||||||
(AQH_Msg_GetBytesInBuffer(msg)>=AQH_MSG_CLAIMADDR_MINSIZE)) {
|
|
||||||
const uint8_t *ptr;
|
|
||||||
|
|
||||||
ptr=AQH_Msg_GetConstBuffer(msg)+AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_CLAIMADDR_UID;
|
|
||||||
return (uint32_t)(ptr[0])+(ptr[1]<<8)+(ptr[2]<<16)+(ptr[3]<<24);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint8_t AQH_MsgClaimAddr_GetAddress(const AQH_MSG *msg)
|
|
||||||
{
|
|
||||||
if ((AQH_Msg_GetMsgType(msg)==AQH_MSG_TYPE_CLAIM_ADDRESS) &&
|
|
||||||
(AQH_Msg_GetBytesInBuffer(msg)>=AQH_MSG_CLAIMADDR_MINSIZE)) {
|
|
||||||
const uint8_t *ptr;
|
|
||||||
|
|
||||||
ptr=AQH_Msg_GetConstBuffer(msg)+AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_CLAIMADDR_ADDR;
|
|
||||||
return ptr[0];
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_MsgClaimAddr_DumpToBuffer(const AQH_MSG *msg, GWEN_BUFFER *dbuf, const char *sText)
|
|
||||||
{
|
|
||||||
if ((AQH_Msg_GetMsgType(msg)==AQH_MSG_TYPE_CLAIM_ADDRESS) &&
|
|
||||||
(AQH_Msg_GetBytesInBuffer(msg)>=AQH_MSG_CLAIMADDR_MINSIZE)) {
|
|
||||||
GWEN_Buffer_AppendArgs(dbuf,
|
|
||||||
"0x%02x->0x%02x: CLAIM_ADDRESS %s (uid=0x%08x, address=0x%02x)\n",
|
|
||||||
AQH_Msg_GetSourceAddress(msg),
|
|
||||||
AQH_Msg_GetDestAddress(msg),
|
|
||||||
sText,
|
|
||||||
(unsigned int) AQH_MsgClaimAddr_GetUid(msg),
|
|
||||||
AQH_MsgClaimAddr_GetAddress(msg));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -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_CLAIMADDR_H
|
|
||||||
#define AQH_MSG_CLAIMADDR_H
|
|
||||||
|
|
||||||
|
|
||||||
#include <aqhome/api.h>
|
|
||||||
|
|
||||||
#include "aqhome/msg.h"
|
|
||||||
|
|
||||||
#include <gwenhywfar/list.h>
|
|
||||||
#include <gwenhywfar/buffer.h>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define AQH_MSG_OFFS_CLAIMADDR_UID 0
|
|
||||||
#define AQH_MSG_OFFS_CLAIMADDR_ADDR 4
|
|
||||||
|
|
||||||
#define AQH_MSG_CLAIMADDR_MINSIZE (AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_CLAIMADDR_ADDR+1)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
AQHOME_API uint32_t AQH_MsgClaimAddr_GetUid(const AQH_MSG *msg);
|
|
||||||
AQHOME_API uint8_t AQH_MsgClaimAddr_GetAddress(const AQH_MSG *msg);
|
|
||||||
AQHOME_API void AQH_MsgClaimAddr_DumpToBuffer(const AQH_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/msg_denyaddr.h"
|
|
||||||
|
|
||||||
#include <gwenhywfar/misc.h>
|
|
||||||
#include <gwenhywfar/list.h>
|
|
||||||
#include <gwenhywfar/error.h>
|
|
||||||
#include <gwenhywfar/debug.h>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint32_t AQH_MsgDenyAddr_GetUid(const AQH_MSG *msg)
|
|
||||||
{
|
|
||||||
if ((AQH_Msg_GetMsgType(msg)==AQH_MSG_TYPE_DENY_ADDRESS) &&
|
|
||||||
(AQH_Msg_GetBytesInBuffer(msg)>=AQH_MSG_DENYADDR_MINSIZE)) {
|
|
||||||
const uint8_t *ptr;
|
|
||||||
|
|
||||||
ptr=AQH_Msg_GetConstBuffer(msg)+AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_DENYADDR_UID;
|
|
||||||
return (uint32_t)(ptr[0])+(ptr[1]<<8)+(ptr[2]<<16)+(ptr[3]<<24);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint8_t AQH_MsgDenyAddr_GetAddress(const AQH_MSG *msg)
|
|
||||||
{
|
|
||||||
if ((AQH_Msg_GetMsgType(msg)==AQH_MSG_TYPE_DENY_ADDRESS) &&
|
|
||||||
(AQH_Msg_GetBytesInBuffer(msg)>=AQH_MSG_DENYADDR_MINSIZE)) {
|
|
||||||
const uint8_t *ptr;
|
|
||||||
|
|
||||||
ptr=AQH_Msg_GetConstBuffer(msg)+AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_DENYADDR_ADDR;
|
|
||||||
return ptr[0];
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_MsgDenyAddr_DumpToBuffer(const AQH_MSG *msg, GWEN_BUFFER *dbuf, const char *sText)
|
|
||||||
{
|
|
||||||
if ((AQH_Msg_GetMsgType(msg)==AQH_MSG_TYPE_DENY_ADDRESS) &&
|
|
||||||
(AQH_Msg_GetBytesInBuffer(msg)>=AQH_MSG_DENYADDR_MINSIZE)) {
|
|
||||||
GWEN_Buffer_AppendArgs(dbuf,
|
|
||||||
"0x%02x->0x%02x: DENY_ADDRESS %s (uid=0x%08x, address=0x%02x)\n",
|
|
||||||
AQH_Msg_GetSourceAddress(msg),
|
|
||||||
AQH_Msg_GetDestAddress(msg),
|
|
||||||
sText,
|
|
||||||
(unsigned int) AQH_MsgDenyAddr_GetUid(msg),
|
|
||||||
AQH_MsgDenyAddr_GetAddress(msg));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -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_DENYADDR_H
|
|
||||||
#define AQH_MSG_DENYADDR_H
|
|
||||||
|
|
||||||
|
|
||||||
#include <aqhome/api.h>
|
|
||||||
|
|
||||||
#include "aqhome/msg.h"
|
|
||||||
|
|
||||||
#include <gwenhywfar/list.h>
|
|
||||||
#include <gwenhywfar/buffer.h>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define AQH_MSG_OFFS_DENYADDR_UID 0
|
|
||||||
#define AQH_MSG_OFFS_DENYADDR_ADDR 4
|
|
||||||
|
|
||||||
#define AQH_MSG_DENYADDR_MINSIZE (AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_DENYADDR_ADDR+1)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
AQHOME_API uint32_t AQH_MsgDenyAddr_GetUid(const AQH_MSG *msg);
|
|
||||||
AQHOME_API uint8_t AQH_MsgDenyAddr_GetAddress(const AQH_MSG *msg);
|
|
||||||
AQHOME_API void AQH_MsgDenyAddr_DumpToBuffer(const AQH_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/msg_haveaddr.h"
|
|
||||||
|
|
||||||
#include <gwenhywfar/misc.h>
|
|
||||||
#include <gwenhywfar/list.h>
|
|
||||||
#include <gwenhywfar/error.h>
|
|
||||||
#include <gwenhywfar/debug.h>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint32_t AQH_MsgHaveAddr_GetUid(const AQH_MSG *msg)
|
|
||||||
{
|
|
||||||
if ((AQH_Msg_GetMsgType(msg)==AQH_MSG_TYPE_HAVE_ADDRESS) &&
|
|
||||||
(AQH_Msg_GetBytesInBuffer(msg)>=AQH_MSG_HAVEADDR_MINSIZE)) {
|
|
||||||
const uint8_t *ptr;
|
|
||||||
|
|
||||||
ptr=AQH_Msg_GetConstBuffer(msg)+AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_HAVEADDR_UID;
|
|
||||||
return (uint32_t)(ptr[0])+(ptr[1]<<8)+(ptr[2]<<16)+(ptr[3]<<24);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint8_t AQH_MsgHaveAddr_GetAddress(const AQH_MSG *msg)
|
|
||||||
{
|
|
||||||
if ((AQH_Msg_GetMsgType(msg)==AQH_MSG_TYPE_HAVE_ADDRESS) &&
|
|
||||||
(AQH_Msg_GetBytesInBuffer(msg)>=AQH_MSG_HAVEADDR_MINSIZE)) {
|
|
||||||
const uint8_t *ptr;
|
|
||||||
|
|
||||||
ptr=AQH_Msg_GetConstBuffer(msg)+AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_HAVEADDR_ADDR;
|
|
||||||
return ptr[0];
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_MsgHaveAddr_DumpToBuffer(const AQH_MSG *msg, GWEN_BUFFER *dbuf, const char *sText)
|
|
||||||
{
|
|
||||||
if ((AQH_Msg_GetMsgType(msg)==AQH_MSG_TYPE_HAVE_ADDRESS) &&
|
|
||||||
(AQH_Msg_GetBytesInBuffer(msg)>=AQH_MSG_HAVEADDR_MINSIZE)) {
|
|
||||||
GWEN_Buffer_AppendArgs(dbuf,
|
|
||||||
"0x%02x->0x%02x: HAVE_ADDRESS %s (uid=0x%08x, address=0x%02x)\n",
|
|
||||||
AQH_Msg_GetSourceAddress(msg),
|
|
||||||
AQH_Msg_GetDestAddress(msg),
|
|
||||||
sText,
|
|
||||||
(unsigned int) AQH_MsgHaveAddr_GetUid(msg),
|
|
||||||
AQH_MsgHaveAddr_GetAddress(msg));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -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_HAVEADDR_H
|
|
||||||
#define AQH_MSG_HAVEADDR_H
|
|
||||||
|
|
||||||
|
|
||||||
#include <aqhome/api.h>
|
|
||||||
|
|
||||||
#include "aqhome/msg.h"
|
|
||||||
|
|
||||||
#include <gwenhywfar/list.h>
|
|
||||||
#include <gwenhywfar/buffer.h>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define AQH_MSG_OFFS_HAVEADDR_UID 0
|
|
||||||
#define AQH_MSG_OFFS_HAVEADDR_ADDR 4
|
|
||||||
|
|
||||||
#define AQH_MSG_HAVEADDR_MINSIZE (AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_HAVEADDR_ADDR+1)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
AQHOME_API uint32_t AQH_MsgHaveAddr_GetUid(const AQH_MSG *msg);
|
|
||||||
AQHOME_API uint8_t AQH_MsgHaveAddr_GetAddress(const AQH_MSG *msg);
|
|
||||||
AQHOME_API void AQH_MsgHaveAddr_DumpToBuffer(const AQH_MSG *msg, GWEN_BUFFER *dbuf, const char *sText);
|
|
||||||
|
|
||||||
|
|
||||||
#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.
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
# include <config.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "aqhome/msg_needaddr.h"
|
|
||||||
|
|
||||||
#include <gwenhywfar/misc.h>
|
|
||||||
#include <gwenhywfar/list.h>
|
|
||||||
#include <gwenhywfar/error.h>
|
|
||||||
#include <gwenhywfar/debug.h>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint32_t AQH_MsgNeedAddr_GetUid(const AQH_MSG *msg)
|
|
||||||
{
|
|
||||||
if ((AQH_Msg_GetMsgType(msg)==AQH_MSG_TYPE_NEED_ADDRESS) &&
|
|
||||||
(AQH_Msg_GetBytesInBuffer(msg)>=AQH_MSG_NEEDADDR_MINSIZE)) {
|
|
||||||
const uint8_t *ptr;
|
|
||||||
|
|
||||||
ptr=AQH_Msg_GetConstBuffer(msg)+AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_NEEDADDR_UID;
|
|
||||||
return (uint32_t)(ptr[0])+(ptr[1]<<8)+(ptr[2]<<16)+(ptr[3]<<24);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_MsgNeedAddr_DumpToBuffer(const AQH_MSG *msg, GWEN_BUFFER *dbuf, const char *sText)
|
|
||||||
{
|
|
||||||
if ((AQH_Msg_GetMsgType(msg)==AQH_MSG_TYPE_NEED_ADDRESS) &&
|
|
||||||
(AQH_Msg_GetBytesInBuffer(msg)>=AQH_MSG_NEEDADDR_MINSIZE)) {
|
|
||||||
GWEN_Buffer_AppendArgs(dbuf,
|
|
||||||
"0x%02x->0x%02x: NEED_ADDRESS %s (uid=0x%08x)\n",
|
|
||||||
AQH_Msg_GetSourceAddress(msg),
|
|
||||||
AQH_Msg_GetDestAddress(msg),
|
|
||||||
sText,
|
|
||||||
(unsigned int) AQH_MsgNeedAddr_GetUid(msg));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,36 +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_NEEDADDR_H
|
|
||||||
#define AQH_MSG_NEEDADDR_H
|
|
||||||
|
|
||||||
|
|
||||||
#include <aqhome/api.h>
|
|
||||||
|
|
||||||
#include "aqhome/msg.h"
|
|
||||||
|
|
||||||
#include <gwenhywfar/list.h>
|
|
||||||
#include <gwenhywfar/buffer.h>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define AQH_MSG_OFFS_NEEDADDR_UID 0
|
|
||||||
|
|
||||||
#define AQH_MSG_NEEDADDR_MINSIZE (AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_NEEDADDR_UID+4)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
AQHOME_API uint32_t AQH_MsgNeedAddr_GetUid(const AQH_MSG *msg);
|
|
||||||
AQHOME_API void AQH_MsgNeedAddr_DumpToBuffer(const AQH_MSG *msg, GWEN_BUFFER *dbuf, const char *sText);
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -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_P_H
|
|
||||||
#define AQH_MSG_P_H
|
|
||||||
|
|
||||||
|
|
||||||
#include "aqhome/msg.h"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct AQH_MSG {
|
|
||||||
GWEN_LIST_ELEMENT(AQH_MSG)
|
|
||||||
|
|
||||||
uint8_t buffer[AQH_MAXMSGSIZE];
|
|
||||||
uint8_t bytesInBuffer;
|
|
||||||
uint8_t currentPos;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#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.
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
# include <config.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "aqhome/msg_ping.h"
|
|
||||||
|
|
||||||
#include <gwenhywfar/misc.h>
|
|
||||||
#include <gwenhywfar/list.h>
|
|
||||||
#include <gwenhywfar/error.h>
|
|
||||||
#include <gwenhywfar/debug.h>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint32_t AQH_MsgPing_GetTimestamp(const AQH_MSG *msg)
|
|
||||||
{
|
|
||||||
if ((AQH_Msg_GetMsgType(msg)==AQH_MSG_TYPE_PING) &&
|
|
||||||
(AQH_Msg_GetBytesInBuffer(msg)>=AQH_MSG_PING_MINSIZE)) {
|
|
||||||
const uint8_t *ptr;
|
|
||||||
|
|
||||||
ptr=AQH_Msg_GetConstBuffer(msg)+AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_PING_TIMESTAMP;
|
|
||||||
return (uint32_t)(ptr[0])+(ptr[1]<<8)+(ptr[2]<<16)+(ptr[3]<<24);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_MsgPing_DumpToBuffer(const AQH_MSG *msg, GWEN_BUFFER *dbuf, const char *sText)
|
|
||||||
{
|
|
||||||
if ((AQH_Msg_GetMsgType(msg)==AQH_MSG_TYPE_PING) &&
|
|
||||||
(AQH_Msg_GetBytesInBuffer(msg)>=AQH_MSG_PING_MINSIZE)) {
|
|
||||||
GWEN_Buffer_AppendArgs(dbuf,
|
|
||||||
"0x%02x->0x%02x: PING %s (timestamp=0x%08x)\n",
|
|
||||||
AQH_Msg_GetSourceAddress(msg),
|
|
||||||
AQH_Msg_GetDestAddress(msg),
|
|
||||||
sText,
|
|
||||||
(unsigned int) AQH_MsgPing_GetTimestamp(msg));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,37 +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_PING_H
|
|
||||||
#define AQH_MSG_PING_H
|
|
||||||
|
|
||||||
|
|
||||||
#include <aqhome/api.h>
|
|
||||||
|
|
||||||
#include "aqhome/msg.h"
|
|
||||||
|
|
||||||
#include <gwenhywfar/list.h>
|
|
||||||
#include <gwenhywfar/buffer.h>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define AQH_MSG_OFFS_PING_TIMESTAMP 0
|
|
||||||
|
|
||||||
#define AQH_MSG_PING_MINSIZE (AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_PING_TIMESTAMP+4)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
AQHOME_API uint32_t AQH_MsgPing_GetTimestamp(const AQH_MSG *msg);
|
|
||||||
AQHOME_API void AQH_MsgPing_DumpToBuffer(const AQH_MSG *msg, GWEN_BUFFER *dbuf, const char *sText);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#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.
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
# include <config.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "aqhome/msg_pong.h"
|
|
||||||
|
|
||||||
#include <gwenhywfar/misc.h>
|
|
||||||
#include <gwenhywfar/list.h>
|
|
||||||
#include <gwenhywfar/error.h>
|
|
||||||
#include <gwenhywfar/debug.h>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint32_t AQH_MsgPong_GetTimestamp(const AQH_MSG *msg)
|
|
||||||
{
|
|
||||||
if ((AQH_Msg_GetMsgType(msg)==AQH_MSG_TYPE_PONG) &&
|
|
||||||
(AQH_Msg_GetBytesInBuffer(msg)>=AQH_MSG_PONG_MINSIZE)) {
|
|
||||||
const uint8_t *ptr;
|
|
||||||
|
|
||||||
ptr=AQH_Msg_GetConstBuffer(msg)+AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_PONG_TIMESTAMP;
|
|
||||||
return (uint32_t)(ptr[0])+(ptr[1]<<8)+(ptr[2]<<16)+(ptr[3]<<24);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_MsgPong_DumpToBuffer(const AQH_MSG *msg, GWEN_BUFFER *dbuf, const char *sText)
|
|
||||||
{
|
|
||||||
if ((AQH_Msg_GetMsgType(msg)==AQH_MSG_TYPE_PONG) &&
|
|
||||||
(AQH_Msg_GetBytesInBuffer(msg)>=AQH_MSG_PONG_MINSIZE)) {
|
|
||||||
GWEN_Buffer_AppendArgs(dbuf,
|
|
||||||
"0x%02x->0x%02x: PONG %s (timestamp=0x%08x)\n",
|
|
||||||
AQH_Msg_GetSourceAddress(msg),
|
|
||||||
AQH_Msg_GetDestAddress(msg),
|
|
||||||
sText,
|
|
||||||
(unsigned int) AQH_MsgPong_GetTimestamp(msg));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,37 +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_PONG_H
|
|
||||||
#define AQH_MSG_PONG_H
|
|
||||||
|
|
||||||
|
|
||||||
#include <aqhome/api.h>
|
|
||||||
|
|
||||||
#include "aqhome/msg.h"
|
|
||||||
|
|
||||||
#include <gwenhywfar/list.h>
|
|
||||||
#include <gwenhywfar/buffer.h>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define AQH_MSG_OFFS_PONG_TIMESTAMP 0
|
|
||||||
|
|
||||||
#define AQH_MSG_PONG_MINSIZE (AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_PONG_TIMESTAMP+4)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
AQHOME_API uint32_t AQH_MsgPong_GetTimestamp(const AQH_MSG *msg);
|
|
||||||
AQHOME_API void AQH_MsgPong_DumpToBuffer(const AQH_MSG *msg, GWEN_BUFFER *dbuf, const char *sText);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,99 +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/msg_sendstats.h"
|
|
||||||
|
|
||||||
#include <gwenhywfar/misc.h>
|
|
||||||
#include <gwenhywfar/list.h>
|
|
||||||
#include <gwenhywfar/error.h>
|
|
||||||
#include <gwenhywfar/debug.h>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint32_t AQH_MsgSendStats_GetTimestamp(const AQH_MSG *msg)
|
|
||||||
{
|
|
||||||
if ((AQH_Msg_GetMsgType(msg)==AQH_MSG_TYPE_COMSENDSTATS) &&
|
|
||||||
(AQH_Msg_GetBytesInBuffer(msg)>=AQH_MSG_SENDSTATS_MINSIZE)) {
|
|
||||||
const uint8_t *ptr;
|
|
||||||
|
|
||||||
ptr=AQH_Msg_GetConstBuffer(msg)+AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_SENDSTATS_TIMESTAMP;
|
|
||||||
return (uint32_t)(ptr[0])+(ptr[1]<<8)+(ptr[2]<<16)+(ptr[3]<<24);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint16_t AQH_MsgSendStats_GetPacketsOut(const AQH_MSG *msg)
|
|
||||||
{
|
|
||||||
if ((AQH_Msg_GetMsgType(msg)==AQH_MSG_TYPE_COMSENDSTATS) &&
|
|
||||||
(AQH_Msg_GetBytesInBuffer(msg)>=AQH_MSG_SENDSTATS_MINSIZE)) {
|
|
||||||
const uint8_t *ptr;
|
|
||||||
|
|
||||||
ptr=AQH_Msg_GetConstBuffer(msg)+AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_SENDSTATS_PACKETSOUT;
|
|
||||||
return (uint16_t)(ptr[0])+(ptr[1]<<8);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint16_t AQH_MsgSendStats_GetCollisions(const AQH_MSG *msg)
|
|
||||||
{
|
|
||||||
if ((AQH_Msg_GetMsgType(msg)==AQH_MSG_TYPE_COMSENDSTATS) &&
|
|
||||||
(AQH_Msg_GetBytesInBuffer(msg)>=AQH_MSG_SENDSTATS_MINSIZE)) {
|
|
||||||
const uint8_t *ptr;
|
|
||||||
|
|
||||||
ptr=AQH_Msg_GetConstBuffer(msg)+AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_SENDSTATS_COLLISIONS;
|
|
||||||
return (uint16_t)(ptr[0])+(ptr[1]<<8);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint16_t AQH_MsgSendStats_GetAborted(const AQH_MSG *msg)
|
|
||||||
{
|
|
||||||
if ((AQH_Msg_GetMsgType(msg)==AQH_MSG_TYPE_COMSENDSTATS) &&
|
|
||||||
(AQH_Msg_GetBytesInBuffer(msg)>=AQH_MSG_SENDSTATS_MINSIZE)) {
|
|
||||||
const uint8_t *ptr;
|
|
||||||
|
|
||||||
ptr=AQH_Msg_GetConstBuffer(msg)+AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_SENDSTATS_ABORTED;
|
|
||||||
return (uint16_t)(ptr[0])+(ptr[1]<<8);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_MsgSendStats_DumpToBuffer(const AQH_MSG *msg, GWEN_BUFFER *dbuf, const char *sText)
|
|
||||||
{
|
|
||||||
if ((AQH_Msg_GetMsgType(msg)==AQH_MSG_TYPE_COMSENDSTATS) &&
|
|
||||||
(AQH_Msg_GetBytesInBuffer(msg)>=AQH_MSG_SENDSTATS_MINSIZE)) {
|
|
||||||
GWEN_Buffer_AppendArgs(dbuf,
|
|
||||||
"0x%02x->0x%02x: SENDSTATS %s (timestamp=0x%08x, out=%d, collisions=%d, aborted=%d)\n",
|
|
||||||
AQH_Msg_GetSourceAddress(msg),
|
|
||||||
AQH_Msg_GetDestAddress(msg),
|
|
||||||
sText,
|
|
||||||
(unsigned int) AQH_MsgSendStats_GetTimestamp(msg),
|
|
||||||
AQH_MsgSendStats_GetPacketsOut(msg),
|
|
||||||
AQH_MsgSendStats_GetCollisions(msg),
|
|
||||||
AQH_MsgSendStats_GetAborted(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_SENDSTATS_H
|
|
||||||
#define AQH_MSG_SENDSTATS_H
|
|
||||||
|
|
||||||
|
|
||||||
#include <aqhome/api.h>
|
|
||||||
|
|
||||||
#include "aqhome/msg.h"
|
|
||||||
|
|
||||||
#include <gwenhywfar/list.h>
|
|
||||||
#include <gwenhywfar/buffer.h>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define AQH_MSG_OFFS_SENDSTATS_TIMESTAMP 0
|
|
||||||
#define AQH_MSG_OFFS_SENDSTATS_PACKETSOUT 4
|
|
||||||
#define AQH_MSG_OFFS_SENDSTATS_COLLISIONS 6
|
|
||||||
#define AQH_MSG_OFFS_SENDSTATS_ABORTED 8
|
|
||||||
|
|
||||||
#define AQH_MSG_SENDSTATS_MINSIZE (AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_SENDSTATS_ABORTED+2)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
AQHOME_API uint32_t AQH_MsgSendStats_GetTimestamp(const AQH_MSG *msg);
|
|
||||||
AQHOME_API uint16_t AQH_MsgSendStats_GetPacketsOut(const AQH_MSG *msg);
|
|
||||||
AQHOME_API uint16_t AQH_MsgSendStats_GetCollisions(const AQH_MSG *msg);
|
|
||||||
AQHOME_API uint16_t AQH_MsgSendStats_GetAborted(const AQH_MSG *msg);
|
|
||||||
|
|
||||||
|
|
||||||
AQHOME_API void AQH_MsgSendStats_DumpToBuffer(const AQH_MSG *msg, GWEN_BUFFER *dbuf, const char *sText);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#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/msg_value.h"
|
|
||||||
|
|
||||||
#include <gwenhywfar/misc.h>
|
|
||||||
#include <gwenhywfar/list.h>
|
|
||||||
#include <gwenhywfar/error.h>
|
|
||||||
#include <gwenhywfar/debug.h>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint32_t AQH_MsgValue_GetTimestamp(const AQH_MSG *msg)
|
|
||||||
{
|
|
||||||
if ((AQH_Msg_GetMsgType(msg)==AQH_MSG_TYPE_VALUE) &&
|
|
||||||
(AQH_Msg_GetBytesInBuffer(msg)>=AQH_MSG_VALUE_MINSIZE)) {
|
|
||||||
const uint8_t *ptr;
|
|
||||||
|
|
||||||
ptr=AQH_Msg_GetConstBuffer(msg)+AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_VALUE_TIMESTAMP;
|
|
||||||
return (uint32_t)(ptr[0])+(ptr[1]<<8)+(ptr[2]<<16)+(ptr[3]<<24);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint8_t AQH_MsgValue_GetValueId(const AQH_MSG *msg)
|
|
||||||
{
|
|
||||||
if ((AQH_Msg_GetMsgType(msg)==AQH_MSG_TYPE_VALUE) &&
|
|
||||||
(AQH_Msg_GetBytesInBuffer(msg)>=AQH_MSG_VALUE_MINSIZE)) {
|
|
||||||
const uint8_t *ptr;
|
|
||||||
|
|
||||||
ptr=AQH_Msg_GetConstBuffer(msg)+AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_VALUE_VALUEID;
|
|
||||||
return ptr[0];
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint8_t AQH_MsgValue_GetValueType(const AQH_MSG *msg)
|
|
||||||
{
|
|
||||||
if ((AQH_Msg_GetMsgType(msg)==AQH_MSG_TYPE_VALUE) &&
|
|
||||||
(AQH_Msg_GetBytesInBuffer(msg)>=AQH_MSG_VALUE_MINSIZE)) {
|
|
||||||
const uint8_t *ptr;
|
|
||||||
|
|
||||||
ptr=AQH_Msg_GetConstBuffer(msg)+AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_VALUE_VALUETYPE;
|
|
||||||
return ptr[0];
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const char *AQH_MsgValue_GetValueTypeName(const AQH_MSG *msg)
|
|
||||||
{
|
|
||||||
uint8_t t;
|
|
||||||
|
|
||||||
t=AQH_MsgValue_GetValueType(msg);
|
|
||||||
switch(t) {
|
|
||||||
case AQH_MSG_VALUE_TYPE_TEMP: return "temperature";
|
|
||||||
case AQH_MSG_VALUE_TYPE_HUMIDITY: return "humidity";
|
|
||||||
default: break;
|
|
||||||
}
|
|
||||||
return "unknown";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
double AQH_MsgValue_GetValue(const AQH_MSG *msg)
|
|
||||||
{
|
|
||||||
if ((AQH_Msg_GetMsgType(msg)==AQH_MSG_TYPE_VALUE) &&
|
|
||||||
(AQH_Msg_GetBytesInBuffer(msg)>=AQH_MSG_VALUE_MINSIZE)) {
|
|
||||||
const uint8_t *ptr;
|
|
||||||
double value;
|
|
||||||
double denom;
|
|
||||||
uint16_t intDenom;
|
|
||||||
|
|
||||||
ptr=AQH_Msg_GetConstBuffer(msg)+AQH_MSG_OFFS_ALL_DATA_BEGIN;
|
|
||||||
value=(double)((ptr[AQH_MSG_OFFS_VALUE_VALUE])+(ptr[AQH_MSG_OFFS_VALUE_VALUE+1]<<8));
|
|
||||||
intDenom=(ptr[AQH_MSG_OFFS_VALUE_DENOM])+(ptr[AQH_MSG_OFFS_VALUE_DENOM+1]<<8);
|
|
||||||
denom=(double)(intDenom);
|
|
||||||
if (intDenom==0)
|
|
||||||
denom=1.0;
|
|
||||||
return (double)(value/denom);
|
|
||||||
|
|
||||||
}
|
|
||||||
return 0.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_MsgValue_DumpToBuffer(const AQH_MSG *msg, GWEN_BUFFER *dbuf, const char *sText)
|
|
||||||
{
|
|
||||||
if ((AQH_Msg_GetMsgType(msg)==AQH_MSG_TYPE_VALUE) &&
|
|
||||||
(AQH_Msg_GetBytesInBuffer(msg)>=AQH_MSG_VALUE_MINSIZE)) {
|
|
||||||
GWEN_Buffer_AppendArgs(dbuf, "0x%02x->0x%02x: VALUE %s (timestamp=0x%08x, value_id=0x%02x type=%s value=%f)\n",
|
|
||||||
AQH_Msg_GetSourceAddress(msg),
|
|
||||||
AQH_Msg_GetDestAddress(msg),
|
|
||||||
sText,
|
|
||||||
(unsigned int) AQH_MsgValue_GetTimestamp(msg),
|
|
||||||
AQH_MsgValue_GetValueId(msg),
|
|
||||||
AQH_MsgValue_GetValueTypeName(msg),
|
|
||||||
AQH_MsgValue_GetValue(msg));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -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_VALUE_H
|
|
||||||
#define AQH_MSG_VALUE_H
|
|
||||||
|
|
||||||
|
|
||||||
#include <aqhome/api.h>
|
|
||||||
|
|
||||||
#include "aqhome/msg.h"
|
|
||||||
|
|
||||||
#include <gwenhywfar/list.h>
|
|
||||||
#include <gwenhywfar/buffer.h>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define AQH_MSG_OFFS_VALUE_TIMESTAMP 0
|
|
||||||
#define AQH_MSG_OFFS_VALUE_VALUEID 4
|
|
||||||
#define AQH_MSG_OFFS_VALUE_VALUETYPE 5
|
|
||||||
#define AQH_MSG_OFFS_VALUE_VALUE 6
|
|
||||||
#define AQH_MSG_OFFS_VALUE_DENOM 8
|
|
||||||
|
|
||||||
#define AQH_MSG_VALUE_MINSIZE (AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_VALUE_DENOM+2)
|
|
||||||
|
|
||||||
#define AQH_MSG_VALUE_TYPE_TEMP 1
|
|
||||||
#define AQH_MSG_VALUE_TYPE_HUMIDITY 2
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
AQHOME_API uint32_t AQH_MsgValue_GetTimestamp(const AQH_MSG *msg);
|
|
||||||
AQHOME_API uint8_t AQH_MsgValue_GetValueId(const AQH_MSG *msg);
|
|
||||||
AQHOME_API uint8_t AQH_MsgValue_GetValueType(const AQH_MSG *msg);
|
|
||||||
AQHOME_API double AQH_MsgValue_GetValue(const AQH_MSG *msg);
|
|
||||||
|
|
||||||
|
|
||||||
AQHOME_API void AQH_MsgValue_DumpToBuffer(const AQH_MSG *msg, GWEN_BUFFER *dbuf, const char *sText);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,574 +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/msgendpoint_p.h"
|
|
||||||
|
|
||||||
|
|
||||||
#include <gwenhywfar/misc.h>
|
|
||||||
#include <gwenhywfar/list.h>
|
|
||||||
#include <gwenhywfar/error.h>
|
|
||||||
#include <gwenhywfar/debug.h>
|
|
||||||
#include <gwenhywfar/text.h>
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <termios.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <sys/ioctl.h>
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <sys/time.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <netinet/in.h>
|
|
||||||
#ifdef HAVE_ARPA_INET_H
|
|
||||||
# include <arpa/inet.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#define AQH_MSG_ENDPOINT_BUFFERSIZE 32
|
|
||||||
|
|
||||||
|
|
||||||
GWEN_LIST_FUNCTIONS(AQH_MSG_ENDPOINT, AQH_MsgEndpoint)
|
|
||||||
GWEN_INHERIT_FUNCTIONS(AQH_MSG_ENDPOINT)
|
|
||||||
|
|
||||||
|
|
||||||
static int _internalHandleReadable(AQH_MSG_ENDPOINT *ep);
|
|
||||||
static int _internalHandleWritable(AQH_MSG_ENDPOINT *ep, AQH_MSG_ENDPOINT_MGR *emgr);
|
|
||||||
static int _setSocketNonBlocking(int fd);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
AQH_MSG_ENDPOINT *AQH_MsgEndpoint_new(int fd, int groupId, const char *name)
|
|
||||||
{
|
|
||||||
AQH_MSG_ENDPOINT *ep;
|
|
||||||
|
|
||||||
GWEN_NEW_OBJECT(AQH_MSG_ENDPOINT, ep);
|
|
||||||
GWEN_INHERIT_INIT(AQH_MSG_ENDPOINT, ep);
|
|
||||||
GWEN_LIST_INIT(AQH_MSG_ENDPOINT, ep);
|
|
||||||
ep->fd=fd;
|
|
||||||
ep->groupId=groupId;
|
|
||||||
ep->receivedMessageList=AQH_Msg_List_new();
|
|
||||||
ep->sendMessageList=AQH_Msg_List_new();
|
|
||||||
ep->name=name?strdup(name):"<unnamed>";
|
|
||||||
|
|
||||||
return ep;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_MsgEndpoint_free(AQH_MSG_ENDPOINT *ep)
|
|
||||||
{
|
|
||||||
if (ep) {
|
|
||||||
GWEN_LIST_FINI(AQH_MSG_ENDPOINT, ep);
|
|
||||||
GWEN_INHERIT_FINI(AQH_MSG_ENDPOINT, ep);
|
|
||||||
if (ep->fd>=0)
|
|
||||||
close(ep->fd);
|
|
||||||
AQH_Msg_free(ep->currentlyReceivedMsg);
|
|
||||||
AQH_Msg_List_free(ep->receivedMessageList);
|
|
||||||
AQH_Msg_List_free(ep->sendMessageList);
|
|
||||||
GWEN_FREE_OBJECT(ep);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int AQH_MsgEndpoint_GetFd(const AQH_MSG_ENDPOINT *ep)
|
|
||||||
{
|
|
||||||
return ep->fd;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_MsgEndpoint_SetFd(AQH_MSG_ENDPOINT *ep, int fd)
|
|
||||||
{
|
|
||||||
ep->fd=fd;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const char *AQH_MsgEndpoint_GetName(const AQH_MSG_ENDPOINT *ep)
|
|
||||||
{
|
|
||||||
return ep->name;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint32_t AQH_MsgEndpoint_GetGroupId(const AQH_MSG_ENDPOINT *ep)
|
|
||||||
{
|
|
||||||
return ep->groupId;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint32_t AQH_MsgEndpoint_GetAcceptedMsgGroups(const AQH_MSG_ENDPOINT *ep)
|
|
||||||
{
|
|
||||||
return ep->acceptedMsgGroups;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_MsgEndpoint_SetAcceptedMsgGroups(AQH_MSG_ENDPOINT *ep, uint32_t f)
|
|
||||||
{
|
|
||||||
ep->acceptedMsgGroups=f;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_MsgEndpoint_AddAcceptedMsgGroups(AQH_MSG_ENDPOINT *ep, uint32_t f)
|
|
||||||
{
|
|
||||||
ep->acceptedMsgGroups|=f;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_MsgEndpoint_DelAcceptedMsgGroups(AQH_MSG_ENDPOINT *ep, uint32_t f)
|
|
||||||
{
|
|
||||||
ep->acceptedMsgGroups&=~f;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint32_t AQH_MsgEndpoint_GetAcceptedEndpointGroups(const AQH_MSG_ENDPOINT *ep)
|
|
||||||
{
|
|
||||||
return ep->acceptedEndpointGroups;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_MsgEndpoint_SetAcceptedEndpointGroups(AQH_MSG_ENDPOINT *ep, uint32_t f)
|
|
||||||
{
|
|
||||||
ep->acceptedEndpointGroups=f;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_MsgEndpoint_AddAcceptedEndpointGroups(AQH_MSG_ENDPOINT *ep, uint32_t f)
|
|
||||||
{
|
|
||||||
ep->acceptedEndpointGroups|=f;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_MsgEndpoint_DelAcceptedEndpointGroups(AQH_MSG_ENDPOINT *ep, uint32_t f)
|
|
||||||
{
|
|
||||||
ep->acceptedEndpointGroups&=~f;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint32_t AQH_MsgEndpoint_GetFlags(const AQH_MSG_ENDPOINT *ep)
|
|
||||||
{
|
|
||||||
return ep->flags;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_MsgEndpoint_SetFlags(AQH_MSG_ENDPOINT *ep, uint32_t f)
|
|
||||||
{
|
|
||||||
ep->flags=f;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_MsgEndpoint_AddFlags(AQH_MSG_ENDPOINT *ep, uint32_t f)
|
|
||||||
{
|
|
||||||
ep->flags|=f;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_MsgEndpoint_SubFlags(AQH_MSG_ENDPOINT *ep, uint32_t f)
|
|
||||||
{
|
|
||||||
ep->flags&=~f;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
AQH_MSG_LIST *AQH_MsgEndpoint_GetReceivedMessageList(const AQH_MSG_ENDPOINT *ep)
|
|
||||||
{
|
|
||||||
return ep->receivedMessageList;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
AQH_MSG *AQH_MsgEndpoint_TakeFirstReceivedMessage(AQH_MSG_ENDPOINT *ep)
|
|
||||||
{
|
|
||||||
AQH_MSG *msg;
|
|
||||||
|
|
||||||
msg=AQH_Msg_List_First(ep->receivedMessageList);
|
|
||||||
if (msg)
|
|
||||||
AQH_Msg_List_Del(msg);
|
|
||||||
return msg;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
AQH_MSG_LIST *AQH_MsgEndpoint_GetSendMessageList(const AQH_MSG_ENDPOINT *ep)
|
|
||||||
{
|
|
||||||
return ep->sendMessageList;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_MsgEndpoint_AddReceivedMessage(AQH_MSG_ENDPOINT *ep, AQH_MSG *m)
|
|
||||||
{
|
|
||||||
AQH_Msg_List_Add(m, ep->receivedMessageList);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_MsgEndpoint_AddSendMessage(AQH_MSG_ENDPOINT *ep, AQH_MSG *m)
|
|
||||||
{
|
|
||||||
AQH_Msg_List_Add(m, ep->sendMessageList);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
AQH_MSG *AQH_MsgEndpoint_GetCurrentlyReceivedMsg(const AQH_MSG_ENDPOINT *ep)
|
|
||||||
{
|
|
||||||
return ep->currentlyReceivedMsg;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_MsgEndpoint_SetCurrentlyReceivedMsg(AQH_MSG_ENDPOINT *ep, AQH_MSG *m)
|
|
||||||
{
|
|
||||||
AQH_Msg_free(ep->currentlyReceivedMsg);
|
|
||||||
ep->currentlyReceivedMsg=m;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int AQH_MsgEndpoint_HandleReadable(AQH_MSG_ENDPOINT *ep, AQH_MSG_ENDPOINT_MGR *emgr)
|
|
||||||
{
|
|
||||||
return (ep->handleReadableFn)?(ep->handleReadableFn(ep, emgr)):_internalHandleReadable(ep);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int AQH_MsgEndpoint_HandleWritable(AQH_MSG_ENDPOINT *ep, AQH_MSG_ENDPOINT_MGR *emgr)
|
|
||||||
{
|
|
||||||
return (ep->handleWritableFn)?(ep->handleWritableFn(ep, emgr)):_internalHandleWritable(ep, emgr);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_MsgEndpoint_Run(AQH_MSG_ENDPOINT *ep)
|
|
||||||
{
|
|
||||||
if (ep->runFn)
|
|
||||||
ep->runFn(ep);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int AQH_MsgEndpoint_StartMsg(AQH_MSG_ENDPOINT *ep)
|
|
||||||
{
|
|
||||||
int rv;
|
|
||||||
|
|
||||||
rv=(ep->startMsgFn)?(ep->startMsgFn(ep)):0;
|
|
||||||
if (rv==0)
|
|
||||||
ep->sendingMessage=1;
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int AQH_MsgEndpoint_EndMsg(AQH_MSG_ENDPOINT *ep)
|
|
||||||
{
|
|
||||||
int rv;
|
|
||||||
|
|
||||||
rv=(ep->endMsgFn)?(ep->endMsgFn(ep)):0;
|
|
||||||
if (rv==0)
|
|
||||||
ep->sendingMessage=0;
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int AQH_MsgEndpoint_CheckMsg(AQH_MSG_ENDPOINT *ep)
|
|
||||||
{
|
|
||||||
return (ep->checkMsgFn)?(ep->checkMsgFn(ep)):1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
AQH_MSG_ENDPOINT_HANDLEREADABLE_FN AQH_MsgEndpoint_SetHandleReadableFn(AQH_MSG_ENDPOINT *ep,
|
|
||||||
AQH_MSG_ENDPOINT_HANDLEREADABLE_FN f)
|
|
||||||
{
|
|
||||||
AQH_MSG_ENDPOINT_HANDLEREADABLE_FN oldFn;
|
|
||||||
|
|
||||||
oldFn=ep->handleReadableFn;
|
|
||||||
ep->handleReadableFn=f;
|
|
||||||
return oldFn;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
AQH_MSG_ENDPOINT_HANDLEWRITABLE_FN AQH_MsgEndpoint_SetHandleWritableFn(AQH_MSG_ENDPOINT *ep,
|
|
||||||
AQH_MSG_ENDPOINT_HANDLEWRITABLE_FN f)
|
|
||||||
{
|
|
||||||
AQH_MSG_ENDPOINT_HANDLEWRITABLE_FN oldFn;
|
|
||||||
|
|
||||||
oldFn=ep->handleWritableFn;
|
|
||||||
ep->handleWritableFn=f;
|
|
||||||
return oldFn;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
AQH_MSG_ENDPOINT_GET_READFD_FN AQH_MsgEndpoint_SetGetReadFdFn(AQH_MSG_ENDPOINT *ep,
|
|
||||||
AQH_MSG_ENDPOINT_GET_READFD_FN f)
|
|
||||||
{
|
|
||||||
AQH_MSG_ENDPOINT_GET_READFD_FN oldFn;
|
|
||||||
|
|
||||||
oldFn=ep->getReadFdFn;
|
|
||||||
ep->getReadFdFn=f;
|
|
||||||
return oldFn;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
AQH_MSG_ENDPOINT_GET_WRITEFD_FN AQH_MsgEndpoint_SetGetWriteFdFn(AQH_MSG_ENDPOINT *ep,
|
|
||||||
AQH_MSG_ENDPOINT_GET_WRITEFD_FN f)
|
|
||||||
{
|
|
||||||
AQH_MSG_ENDPOINT_GET_WRITEFD_FN oldFn;
|
|
||||||
|
|
||||||
oldFn=ep->getWriteFdFn;
|
|
||||||
ep->getWriteFdFn=f;
|
|
||||||
return oldFn;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
AQH_MSG_ENDPOINT_RUN_FN AQH_MsgEndpoint_SetRunFn(AQH_MSG_ENDPOINT *ep, AQH_MSG_ENDPOINT_RUN_FN f)
|
|
||||||
{
|
|
||||||
AQH_MSG_ENDPOINT_RUN_FN oldFn;
|
|
||||||
|
|
||||||
oldFn=ep->runFn;
|
|
||||||
ep->runFn=f;
|
|
||||||
return oldFn;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
AQH_MSG_ENDPOINT_STARTMSG_FN AQH_MsgEndpoint_SetStartMsgFn(AQH_MSG_ENDPOINT *ep, AQH_MSG_ENDPOINT_STARTMSG_FN f)
|
|
||||||
{
|
|
||||||
AQH_MSG_ENDPOINT_STARTMSG_FN oldFn;
|
|
||||||
|
|
||||||
oldFn=ep->startMsgFn;
|
|
||||||
ep->startMsgFn=f;
|
|
||||||
return oldFn;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
AQH_MSG_ENDPOINT_ENDMSG_FN AQH_MsgEndpoint_SetEndMsgFn(AQH_MSG_ENDPOINT *ep, AQH_MSG_ENDPOINT_ENDMSG_FN f)
|
|
||||||
{
|
|
||||||
AQH_MSG_ENDPOINT_ENDMSG_FN oldFn;
|
|
||||||
|
|
||||||
oldFn=ep->endMsgFn;
|
|
||||||
ep->endMsgFn=f;
|
|
||||||
return oldFn;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
AQH_MSG_ENDPOINT_CHECKMSG_FN AQH_MsgEndpoint_SetCheckMsgFn(AQH_MSG_ENDPOINT *ep, AQH_MSG_ENDPOINT_CHECKMSG_FN f)
|
|
||||||
{
|
|
||||||
AQH_MSG_ENDPOINT_CHECKMSG_FN oldFn;
|
|
||||||
|
|
||||||
oldFn=ep->checkMsgFn;
|
|
||||||
ep->checkMsgFn=f;
|
|
||||||
return oldFn;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int AQH_MsgEndpoint_GetReadFd(AQH_MSG_ENDPOINT *ep)
|
|
||||||
{
|
|
||||||
return (ep->getReadFdFn)?(ep->getReadFdFn(ep)):(ep->fd);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int AQH_MsgEndpoint_GetWriteFd(AQH_MSG_ENDPOINT *ep)
|
|
||||||
{
|
|
||||||
if (ep->getWriteFdFn)
|
|
||||||
return ep->getWriteFdFn(ep);
|
|
||||||
else {
|
|
||||||
int somethingToWrite;
|
|
||||||
|
|
||||||
somethingToWrite=(AQH_Msg_List_First(ep->sendMessageList)!=NULL)?1:0;
|
|
||||||
if (somethingToWrite)
|
|
||||||
return ep->fd;
|
|
||||||
}
|
|
||||||
return GWEN_ERROR_NO_DATA;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int AQH_MsgEndpoint_DiscardInput(AQH_MSG_ENDPOINT *ep)
|
|
||||||
{
|
|
||||||
int rv;
|
|
||||||
uint8_t buffer[AQH_MSG_ENDPOINT_BUFFERSIZE];
|
|
||||||
|
|
||||||
do {
|
|
||||||
rv=read(ep->fd, buffer, sizeof(buffer));
|
|
||||||
} while(rv>0 || (rv<0 && errno==EINTR));
|
|
||||||
if (rv<0 && errno!=EAGAIN && errno!=EWOULDBLOCK) {
|
|
||||||
DBG_ERROR(AQH_LOGDOMAIN, "Error on read(): %s (%d)", strerror(errno), errno);
|
|
||||||
return GWEN_ERROR_IO;
|
|
||||||
}
|
|
||||||
else if (rv==0) {
|
|
||||||
DBG_ERROR(AQH_LOGDOMAIN, "EOF met on read()");
|
|
||||||
#if 0
|
|
||||||
return GWEN_ERROR_IO;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int _internalHandleReadable(AQH_MSG_ENDPOINT *ep)
|
|
||||||
{
|
|
||||||
int rv;
|
|
||||||
uint8_t buffer[AQH_MSG_ENDPOINT_BUFFERSIZE*2];
|
|
||||||
int len;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
DBG_DEBUG(AQH_LOGDOMAIN, "Reading from endpoint %s", AQH_MsgEndpoint_GetName(ep));
|
|
||||||
do {
|
|
||||||
rv=read(ep->fd, buffer, sizeof(buffer));
|
|
||||||
} while( (rv<0) && errno==EINTR);
|
|
||||||
if (rv<0) {
|
|
||||||
if (errno==EAGAIN || errno==EWOULDBLOCK)
|
|
||||||
return GWEN_ERROR_TRY_AGAIN;
|
|
||||||
DBG_ERROR(AQH_LOGDOMAIN, "Error on read(): %s (%d)", strerror(errno), errno);
|
|
||||||
return GWEN_ERROR_IO;
|
|
||||||
}
|
|
||||||
else if (rv==0) {
|
|
||||||
DBG_ERROR(AQH_LOGDOMAIN, "EOF met on read()");
|
|
||||||
return GWEN_ERROR_IO;
|
|
||||||
}
|
|
||||||
len=rv;
|
|
||||||
|
|
||||||
for (i=0; i<len; i++) {
|
|
||||||
if (ep->currentlyReceivedMsg==NULL)
|
|
||||||
ep->currentlyReceivedMsg=AQH_Msg_new();
|
|
||||||
rv=AQH_Msg_AddByte(ep->currentlyReceivedMsg, buffer[i]);
|
|
||||||
if (rv<0) {
|
|
||||||
DBG_ERROR(AQH_LOGDOMAIN, "here (%d)", rv);
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
rv=AQH_Msg_IsMsgComplete(ep->currentlyReceivedMsg);
|
|
||||||
if (rv<0) {
|
|
||||||
/* invalid message */
|
|
||||||
DBG_ERROR(AQH_LOGDOMAIN, "Invalid message, discarding");
|
|
||||||
AQH_Msg_free(ep->currentlyReceivedMsg);
|
|
||||||
ep->currentlyReceivedMsg=NULL;
|
|
||||||
rv=AQH_MsgEndpoint_DiscardInput(ep);
|
|
||||||
if (rv<0) {
|
|
||||||
DBG_ERROR(AQH_LOGDOMAIN, "here (%d)", rv);
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (rv>0) {
|
|
||||||
if (!AQH_Msg_IsChecksumValid(ep->currentlyReceivedMsg)) {
|
|
||||||
DBG_ERROR(AQH_LOGDOMAIN, "Invalid checksum, discarding message");
|
|
||||||
GWEN_Text_DumpString(AQH_Msg_GetBuffer(ep->currentlyReceivedMsg), AQH_Msg_GetBytesInBuffer(ep->currentlyReceivedMsg), 6);
|
|
||||||
AQH_Msg_free(ep->currentlyReceivedMsg);
|
|
||||||
ep->currentlyReceivedMsg=NULL;
|
|
||||||
rv=AQH_MsgEndpoint_DiscardInput(ep);
|
|
||||||
if (rv<0) {
|
|
||||||
DBG_ERROR(AQH_LOGDOMAIN, "here (%d)", rv);
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
/* valid msg received, add to list */
|
|
||||||
AQH_Msg_List_Add(ep->currentlyReceivedMsg, ep->receivedMessageList);
|
|
||||||
ep->currentlyReceivedMsg=NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int _internalHandleWritable(AQH_MSG_ENDPOINT *ep, AQH_MSG_ENDPOINT_MGR *emgr)
|
|
||||||
{
|
|
||||||
AQH_MSG *msg;
|
|
||||||
|
|
||||||
DBG_DEBUG(AQH_LOGDOMAIN, "Writing to endpoint %s", AQH_MsgEndpoint_GetName(ep));
|
|
||||||
msg=AQH_Msg_List_First(ep->sendMessageList);
|
|
||||||
if (msg) {
|
|
||||||
uint8_t pos;
|
|
||||||
int len;
|
|
||||||
int remaining;
|
|
||||||
int rv;
|
|
||||||
|
|
||||||
rv=AQH_MsgEndpoint_CheckMsg(ep);
|
|
||||||
if (rv<0 || rv==1) {
|
|
||||||
DBG_ERROR(AQH_LOGDOMAIN, "Line busy, not sending");
|
|
||||||
usleep(100);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
pos=AQH_Msg_GetCurrentPos(msg);
|
|
||||||
remaining=AQH_Msg_GetRemainingBytes(msg);
|
|
||||||
if (remaining>0) {
|
|
||||||
const uint8_t *buf;
|
|
||||||
|
|
||||||
rv=AQH_MsgEndpoint_StartMsg(ep);
|
|
||||||
if (rv<0) {
|
|
||||||
DBG_ERROR(AQH_LOGDOMAIN, "here (%d)", rv);
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
buf=AQH_Msg_GetBuffer(msg)+pos;
|
|
||||||
do {
|
|
||||||
rv=write(ep->fd, buf, remaining);
|
|
||||||
} while(rv<0 && errno==EINTR);
|
|
||||||
if (rv<0) {
|
|
||||||
if (errno==EAGAIN || errno==EWOULDBLOCK)
|
|
||||||
return GWEN_ERROR_TRY_AGAIN;
|
|
||||||
DBG_ERROR(AQH_LOGDOMAIN, "Error on write(): %s (%d)", strerror(errno), errno);
|
|
||||||
return GWEN_ERROR_IO;
|
|
||||||
}
|
|
||||||
AQH_Msg_IncCurrentPos(msg, rv);
|
|
||||||
if (rv==remaining) {
|
|
||||||
rv=AQH_MsgEndpoint_EndMsg(ep);
|
|
||||||
// TODO: callback msg sent
|
|
||||||
AQH_Msg_List_Del(msg);
|
|
||||||
AQH_Msg_free(msg);
|
|
||||||
if (rv<0) {
|
|
||||||
DBG_ERROR(AQH_LOGDOMAIN, "here (%d)", rv);
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,128 +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_MSGENDPOINT_H
|
|
||||||
#define AQH_MSGENDPOINT_H
|
|
||||||
|
|
||||||
|
|
||||||
#include <aqhome/api.h>
|
|
||||||
|
|
||||||
#include "aqhome/msg.h"
|
|
||||||
|
|
||||||
#include <gwenhywfar/list.h>
|
|
||||||
#include <gwenhywfar/inherit.h>
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct AQH_MSG_ENDPOINT AQH_MSG_ENDPOINT;
|
|
||||||
GWEN_LIST_FUNCTION_LIB_DEFS(AQH_MSG_ENDPOINT, AQH_MsgEndpoint, AQHOME_API)
|
|
||||||
GWEN_INHERIT_FUNCTION_LIB_DEFS(AQH_MSG_ENDPOINT, AQHOME_API)
|
|
||||||
|
|
||||||
|
|
||||||
#include "aqhome/msgendpointmanager.h"
|
|
||||||
|
|
||||||
#include <gwenhywfar/buffer.h>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define AQH_MSG_ENDPOINT_ENDPOINTGROUP_BUS 0x0001
|
|
||||||
#define AQH_MSG_ENDPOINT_ENDPOINTGROUP_NET 0x0002
|
|
||||||
|
|
||||||
|
|
||||||
#define AQH_MSG_ENDPOINT_MSGGROUP_INFO 0x00000001
|
|
||||||
#define AQH_MSG_ENDPOINT_MSGGROUP_VALUES 0x00000002
|
|
||||||
#define AQH_MSG_ENDPOINT_MSGGROUP_ADDRESS 0x00000004
|
|
||||||
#define AQH_MSG_ENDPOINT_MSGGROUP_FLASH 0x00000008
|
|
||||||
#define AQH_MSG_ENDPOINT_MSGGROUP_ADMIN 0x00000010
|
|
||||||
#define AQH_MSG_ENDPOINT_MSGGROUP_ALL 0xffffffff
|
|
||||||
|
|
||||||
#define AQH_MSG_ENDPOINT_FLAGS_NOMESSAGES 0x0001
|
|
||||||
#define AQH_MSG_ENDPOINT_FLAGS_NOIO 0x0002
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
typedef int (*AQH_MSG_ENDPOINT_HANDLEREADABLE_FN)(AQH_MSG_ENDPOINT *ep, AQH_MSG_ENDPOINT_MGR *emgr);
|
|
||||||
typedef int (*AQH_MSG_ENDPOINT_HANDLEWRITABLE_FN)(AQH_MSG_ENDPOINT *ep, AQH_MSG_ENDPOINT_MGR *emgr);
|
|
||||||
typedef void (*AQH_MSG_ENDPOINT_RUN_FN)(AQH_MSG_ENDPOINT *ep);
|
|
||||||
typedef int (*AQH_MSG_ENDPOINT_GET_READFD_FN)(AQH_MSG_ENDPOINT *ep);
|
|
||||||
typedef int (*AQH_MSG_ENDPOINT_GET_WRITEFD_FN)(AQH_MSG_ENDPOINT *ep);
|
|
||||||
|
|
||||||
typedef int (*AQH_MSG_ENDPOINT_STARTMSG_FN)(AQH_MSG_ENDPOINT *ep);
|
|
||||||
typedef int (*AQH_MSG_ENDPOINT_ENDMSG_FN)(AQH_MSG_ENDPOINT *ep);
|
|
||||||
typedef int (*AQH_MSG_ENDPOINT_CHECKMSG_FN)(AQH_MSG_ENDPOINT *ep);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
AQHOME_API AQH_MSG_ENDPOINT *AQH_MsgEndpoint_new(int fd, int groupId, const char *name);
|
|
||||||
AQHOME_API void AQH_MsgEndpoint_free(AQH_MSG_ENDPOINT *ep);
|
|
||||||
|
|
||||||
AQHOME_API int AQH_MsgEndpoint_GetFd(const AQH_MSG_ENDPOINT *ep);
|
|
||||||
AQHOME_API void AQH_MsgEndpoint_SetFd(AQH_MSG_ENDPOINT *ep, int fd);
|
|
||||||
|
|
||||||
AQHOME_API const char *AQH_MsgEndpoint_GetName(const AQH_MSG_ENDPOINT *ep);
|
|
||||||
|
|
||||||
AQHOME_API uint32_t AQH_MsgEndpoint_GetGroupId(const AQH_MSG_ENDPOINT *ep);
|
|
||||||
|
|
||||||
AQHOME_API uint32_t AQH_MsgEndpoint_GetAcceptedMsgGroups(const AQH_MSG_ENDPOINT *ep);
|
|
||||||
AQHOME_API void AQH_MsgEndpoint_SetAcceptedMsgGroups(AQH_MSG_ENDPOINT *ep, uint32_t f);
|
|
||||||
AQHOME_API void AQH_MsgEndpoint_AddAcceptedMsgGroups(AQH_MSG_ENDPOINT *ep, uint32_t f);
|
|
||||||
AQHOME_API void AQH_MsgEndpoint_DelAcceptedMsgGroups(AQH_MSG_ENDPOINT *ep, uint32_t f);
|
|
||||||
|
|
||||||
AQHOME_API uint32_t AQH_MsgEndpoint_GetAcceptedEndpointGroups(const AQH_MSG_ENDPOINT *ep);
|
|
||||||
AQHOME_API void AQH_MsgEndpoint_SetAcceptedEndpointGroups(AQH_MSG_ENDPOINT *ep, uint32_t f);
|
|
||||||
AQHOME_API void AQH_MsgEndpoint_AddAcceptedEndpointGroups(AQH_MSG_ENDPOINT *ep, uint32_t f);
|
|
||||||
AQHOME_API void AQH_MsgEndpoint_DelAcceptedEndpointGroups(AQH_MSG_ENDPOINT *ep, uint32_t f);
|
|
||||||
|
|
||||||
AQHOME_API uint32_t AQH_MsgEndpoint_GetFlags(const AQH_MSG_ENDPOINT *ep);
|
|
||||||
AQHOME_API void AQH_MsgEndpoint_SetFlags(AQH_MSG_ENDPOINT *ep, uint32_t f);
|
|
||||||
AQHOME_API void AQH_MsgEndpoint_AddFlags(AQH_MSG_ENDPOINT *ep, uint32_t f);
|
|
||||||
AQHOME_API void AQH_MsgEndpoint_SubFlags(AQH_MSG_ENDPOINT *ep, uint32_t f);
|
|
||||||
|
|
||||||
AQHOME_API AQH_MSG_LIST *AQH_MsgEndpoint_GetReceivedMessageList(const AQH_MSG_ENDPOINT *ep);
|
|
||||||
AQHOME_API AQH_MSG_LIST *AQH_MsgEndpoint_GetSendMessageList(const AQH_MSG_ENDPOINT *ep);
|
|
||||||
|
|
||||||
AQHOME_API void AQH_MsgEndpoint_AddReceivedMessage(AQH_MSG_ENDPOINT *ep, AQH_MSG *m);
|
|
||||||
AQHOME_API AQH_MSG *AQH_MsgEndpoint_TakeFirstReceivedMessage(AQH_MSG_ENDPOINT *ep);
|
|
||||||
AQHOME_API void AQH_MsgEndpoint_AddSendMessage(AQH_MSG_ENDPOINT *ep, AQH_MSG *m);
|
|
||||||
|
|
||||||
AQHOME_API AQH_MSG *AQH_MsgEndpoint_GetCurrentlyReceivedMsg(const AQH_MSG_ENDPOINT *ep);
|
|
||||||
AQHOME_API void AQH_MsgEndpoint_SetCurrentlyReceivedMsg(AQH_MSG_ENDPOINT *ep, AQH_MSG *m);
|
|
||||||
|
|
||||||
|
|
||||||
AQHOME_API int AQH_MsgEndpoint_GetReadFd(AQH_MSG_ENDPOINT *ep);
|
|
||||||
AQHOME_API int AQH_MsgEndpoint_GetWriteFd(AQH_MSG_ENDPOINT *ep);
|
|
||||||
|
|
||||||
AQHOME_API int AQH_MsgEndpoint_HandleReadable(AQH_MSG_ENDPOINT *ep, AQH_MSG_ENDPOINT_MGR *emgr);
|
|
||||||
AQHOME_API int AQH_MsgEndpoint_HandleWritable(AQH_MSG_ENDPOINT *ep, AQH_MSG_ENDPOINT_MGR *emgr);
|
|
||||||
AQHOME_API void AQH_MsgEndpoint_Run(AQH_MSG_ENDPOINT *ep);
|
|
||||||
|
|
||||||
AQHOME_API int AQH_MsgEndpoint_DiscardInput(AQH_MSG_ENDPOINT *ep);
|
|
||||||
|
|
||||||
AQHOME_API int AQH_MsgEndpoint_StartMsg(AQH_MSG_ENDPOINT *ep);
|
|
||||||
AQHOME_API int AQH_MsgEndpoint_EndMsg(AQH_MSG_ENDPOINT *ep);
|
|
||||||
AQHOME_API int AQH_MsgEndpoint_CheckMsg(AQH_MSG_ENDPOINT *ep);
|
|
||||||
|
|
||||||
|
|
||||||
AQHOME_API AQH_MSG_ENDPOINT_HANDLEREADABLE_FN AQH_MsgEndpoint_SetHandleReadableFn(AQH_MSG_ENDPOINT *ep,
|
|
||||||
AQH_MSG_ENDPOINT_HANDLEREADABLE_FN f);
|
|
||||||
AQHOME_API AQH_MSG_ENDPOINT_HANDLEWRITABLE_FN AQH_MsgEndpoint_SetHandleWritableFn(AQH_MSG_ENDPOINT *ep,
|
|
||||||
AQH_MSG_ENDPOINT_HANDLEWRITABLE_FN f);
|
|
||||||
AQHOME_API AQH_MSG_ENDPOINT_GET_READFD_FN AQH_MsgEndpoint_SetGetReadFdFn(AQH_MSG_ENDPOINT *ep,
|
|
||||||
AQH_MSG_ENDPOINT_GET_READFD_FN f);
|
|
||||||
AQHOME_API AQH_MSG_ENDPOINT_GET_WRITEFD_FN AQH_MsgEndpoint_SetGetWriteFdFn(AQH_MSG_ENDPOINT *ep,
|
|
||||||
AQH_MSG_ENDPOINT_GET_WRITEFD_FN f);
|
|
||||||
|
|
||||||
AQHOME_API AQH_MSG_ENDPOINT_RUN_FN AQH_MsgEndpoint_SetRunFn(AQH_MSG_ENDPOINT *ep, AQH_MSG_ENDPOINT_RUN_FN f);
|
|
||||||
AQHOME_API AQH_MSG_ENDPOINT_STARTMSG_FN AQH_MsgEndpoint_SetStartMsgFn(AQH_MSG_ENDPOINT *ep, AQH_MSG_ENDPOINT_STARTMSG_FN f);
|
|
||||||
AQHOME_API AQH_MSG_ENDPOINT_ENDMSG_FN AQH_MsgEndpoint_SetEndMsgFn(AQH_MSG_ENDPOINT *ep, AQH_MSG_ENDPOINT_ENDMSG_FN f);
|
|
||||||
AQHOME_API AQH_MSG_ENDPOINT_CHECKMSG_FN AQH_MsgEndpoint_SetCheckMsgFn(AQH_MSG_ENDPOINT *ep, AQH_MSG_ENDPOINT_CHECKMSG_FN f);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#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_MSGENDPOINT_P_H
|
|
||||||
#define AQH_MSGENDPOINT_P_H
|
|
||||||
|
|
||||||
|
|
||||||
#include <aqhome/api.h>
|
|
||||||
|
|
||||||
#include "aqhome/msgendpoint.h"
|
|
||||||
|
|
||||||
#include <gwenhywfar/list.h>
|
|
||||||
#include <gwenhywfar/buffer.h>
|
|
||||||
|
|
||||||
|
|
||||||
struct AQH_MSG_ENDPOINT {
|
|
||||||
GWEN_INHERIT_ELEMENT(AQH_MSG_ENDPOINT)
|
|
||||||
GWEN_LIST_ELEMENT(AQH_MSG_ENDPOINT)
|
|
||||||
|
|
||||||
int fd;
|
|
||||||
char *name;
|
|
||||||
|
|
||||||
AQH_MSG_LIST *receivedMessageList;
|
|
||||||
AQH_MSG_LIST *sendMessageList;
|
|
||||||
AQH_MSG *currentlyReceivedMsg;
|
|
||||||
|
|
||||||
AQH_MSG_ENDPOINT_HANDLEREADABLE_FN handleReadableFn;
|
|
||||||
AQH_MSG_ENDPOINT_HANDLEWRITABLE_FN handleWritableFn;
|
|
||||||
AQH_MSG_ENDPOINT_GET_READFD_FN getReadFdFn;
|
|
||||||
AQH_MSG_ENDPOINT_GET_WRITEFD_FN getWriteFdFn;
|
|
||||||
AQH_MSG_ENDPOINT_RUN_FN runFn;
|
|
||||||
AQH_MSG_ENDPOINT_STARTMSG_FN startMsgFn;
|
|
||||||
AQH_MSG_ENDPOINT_ENDMSG_FN endMsgFn;
|
|
||||||
AQH_MSG_ENDPOINT_CHECKMSG_FN checkMsgFn;
|
|
||||||
|
|
||||||
uint32_t flags;
|
|
||||||
uint32_t groupId;
|
|
||||||
uint32_t acceptedEndpointGroups;
|
|
||||||
uint32_t acceptedMsgGroups;
|
|
||||||
|
|
||||||
int sendingMessage;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#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/msgendpointlog_p.h"
|
|
||||||
|
|
||||||
#include "aqhome/msg_value.h"
|
|
||||||
#include "aqhome/msg_sendstats.h"
|
|
||||||
#include "aqhome/msg_ping.h"
|
|
||||||
#include "aqhome/msg_pong.h"
|
|
||||||
#include "aqhome/msg_needaddr.h"
|
|
||||||
#include "aqhome/msg_claimaddr.h"
|
|
||||||
#include "aqhome/msg_haveaddr.h"
|
|
||||||
#include "aqhome/msg_denyaddr.h"
|
|
||||||
|
|
||||||
#include <gwenhywfar/list.h>
|
|
||||||
#include <gwenhywfar/inherit.h>
|
|
||||||
#include <gwenhywfar/debug.h>
|
|
||||||
#include <gwenhywfar/gwentime.h>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
GWEN_INHERIT(AQH_MSG_ENDPOINT, AQH_MSG_ENDPOINT_LOG_OLD)
|
|
||||||
|
|
||||||
|
|
||||||
static void GWENHYWFAR_CB _freeData(void *bp, void *p);
|
|
||||||
static void _run(AQH_MSG_ENDPOINT *ep);
|
|
||||||
static void _logMessage(AQH_MSG_ENDPOINT *ep, const AQH_MSG *msg);
|
|
||||||
static void _writeToLogFile(const char *filename, const char *txt);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
AQH_MSG_ENDPOINT *AQH_MsgEndpointLog_new(const char *filename)
|
|
||||||
{
|
|
||||||
int fd;
|
|
||||||
AQH_MSG_ENDPOINT *ep;
|
|
||||||
AQH_MSG_ENDPOINT_LOG_OLD *xep;
|
|
||||||
|
|
||||||
ep=AQH_MsgEndpoint_new(-1, AQH_MSG_ENDPOINT_ENDPOINTGROUP_NET, "LOG");
|
|
||||||
GWEN_NEW_OBJECT(AQH_MSG_ENDPOINT_LOG_OLD, xep);
|
|
||||||
xep->filename=strdup(filename);
|
|
||||||
GWEN_INHERIT_SETDATA(AQH_MSG_ENDPOINT, AQH_MSG_ENDPOINT_LOG_OLD, ep, xep, _freeData);
|
|
||||||
AQH_MsgEndpoint_SetAcceptedEndpointGroups(ep, AQH_MSG_ENDPOINT_ENDPOINTGROUP_BUS);
|
|
||||||
AQH_MsgEndpoint_SetAcceptedMsgGroups(ep, AQH_MSG_ENDPOINT_MSGGROUP_ALL);
|
|
||||||
AQH_MsgEndpoint_AddFlags(ep, AQH_MSG_ENDPOINT_FLAGS_NOIO);
|
|
||||||
AQH_MsgEndpoint_SetRunFn(ep, _run);
|
|
||||||
|
|
||||||
return ep;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void _freeData(void *bp, void *p)
|
|
||||||
{
|
|
||||||
AQH_MSG_ENDPOINT_LOG_OLD *xep;
|
|
||||||
|
|
||||||
xep=(AQH_MSG_ENDPOINT_LOG_OLD*) p;
|
|
||||||
free(xep->filename);
|
|
||||||
GWEN_FREE_OBJECT(xep);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void _run(AQH_MSG_ENDPOINT *ep)
|
|
||||||
{
|
|
||||||
AQH_MSG_LIST *msgList;
|
|
||||||
|
|
||||||
msgList=AQH_MsgEndpoint_GetSendMessageList(ep);
|
|
||||||
if (msgList && AQH_Msg_List_GetCount(msgList)) {
|
|
||||||
AQH_MSG *msg;
|
|
||||||
|
|
||||||
msg=AQH_Msg_List_First(msgList);
|
|
||||||
while(msg) {
|
|
||||||
AQH_MSG *next;
|
|
||||||
|
|
||||||
next=AQH_Msg_List_Next(msg);
|
|
||||||
_logMessage(ep, msg);
|
|
||||||
AQH_Msg_free(msg);
|
|
||||||
msg=next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void _logMessage(AQH_MSG_ENDPOINT *ep, const AQH_MSG *msg)
|
|
||||||
{
|
|
||||||
AQH_MSG_ENDPOINT_LOG_OLD *xep;
|
|
||||||
const uint8_t *ptr;
|
|
||||||
uint8_t len;
|
|
||||||
uint8_t msgType;
|
|
||||||
int msgIsValid;
|
|
||||||
GWEN_BUFFER *dbuf;
|
|
||||||
GWEN_TIME *ti;
|
|
||||||
|
|
||||||
xep=GWEN_INHERIT_GETDATA(AQH_MSG_ENDPOINT, AQH_MSG_ENDPOINT_LOG_OLD, ep);
|
|
||||||
dbuf=GWEN_Buffer_new(0, 256, 0, 1);
|
|
||||||
ti=GWEN_CurrentTime();
|
|
||||||
GWEN_Time_toString(ti, "YYYY-MM-DD hh:mm:ss ", dbuf);
|
|
||||||
GWEN_Time_free(ti);
|
|
||||||
ti=NULL;
|
|
||||||
|
|
||||||
msgIsValid=(AQH_Msg_IsChecksumValid(msg) && AQH_Msg_IsMsgComplete(msg));
|
|
||||||
ptr=AQH_Msg_GetConstBuffer(msg);
|
|
||||||
len=AQH_Msg_GetBytesInBuffer(msg);
|
|
||||||
msgType=AQH_Msg_GetMsgType(msg);
|
|
||||||
|
|
||||||
switch(msgType) {
|
|
||||||
case AQH_MSG_TYPE_PING: AQH_MsgPing_DumpToBuffer(msg, dbuf, "received"); break;
|
|
||||||
case AQH_MSG_TYPE_PONG: AQH_MsgPong_DumpToBuffer(msg, dbuf, "received"); break;
|
|
||||||
case AQH_MSG_TYPE_COMSENDSTATS: AQH_MsgSendStats_DumpToBuffer(msg, dbuf, "received"); break;
|
|
||||||
case AQH_MSG_TYPE_TWIBUSMEMBER: AQH_Msg_DumpToBuffer(msg, dbuf, "received"); break;
|
|
||||||
case AQH_MSG_TYPE_DEBUG: AQH_Msg_DumpToBuffer(msg, dbuf, "received"); break;
|
|
||||||
case AQH_MSG_TYPE_VALUE: AQH_MsgValue_DumpToBuffer(msg, dbuf, "received"); break;
|
|
||||||
case AQH_MSG_TYPE_NEED_ADDRESS: AQH_MsgNeedAddr_DumpToBuffer(msg, dbuf, "received"); break;
|
|
||||||
case AQH_MSG_TYPE_CLAIM_ADDRESS: AQH_MsgClaimAddr_DumpToBuffer(msg, dbuf, "received"); break;
|
|
||||||
case AQH_MSG_TYPE_HAVE_ADDRESS: AQH_MsgHaveAddr_DumpToBuffer(msg, dbuf, "received"); break;
|
|
||||||
case AQH_MSG_TYPE_DENY_ADDRESS: AQH_MsgDenyAddr_DumpToBuffer(msg, dbuf, "received"); break;
|
|
||||||
default: AQH_MsgValue_DumpToBuffer(msg, dbuf, "received"); break;
|
|
||||||
}
|
|
||||||
_writeToLogFile(xep->filename, GWEN_Buffer_GetStart(dbuf));
|
|
||||||
GWEN_Buffer_free(dbuf);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void _writeToLogFile(const char *filename, const char *txt)
|
|
||||||
{
|
|
||||||
if (txt && *txt) {
|
|
||||||
FILE *f;
|
|
||||||
|
|
||||||
f=fopen(filename, "a+");
|
|
||||||
if (f) {
|
|
||||||
if (1!=fwrite(txt, strlen(txt), 1, f)) {
|
|
||||||
DBG_ERROR(AQH_LOGDOMAIN, "Error logging.");
|
|
||||||
}
|
|
||||||
fclose(f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -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_MSGENDPOINT_LOG_H
|
|
||||||
#define AQH_MSGENDPOINT_LOG_H
|
|
||||||
|
|
||||||
|
|
||||||
#include <aqhome/api.h>
|
|
||||||
|
|
||||||
#include "aqhome/msgendpoint.h"
|
|
||||||
|
|
||||||
#include <gwenhywfar/list.h>
|
|
||||||
#include <gwenhywfar/inherit.h>
|
|
||||||
|
|
||||||
|
|
||||||
AQHOME_API AQH_MSG_ENDPOINT *AQH_MsgEndpointLog_new(const char *filename);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#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_MSGENDPOINT_LOG_P_H
|
|
||||||
#define AQH_MSGENDPOINT_LOG_P_H
|
|
||||||
|
|
||||||
|
|
||||||
#include "aqhome/msgendpointlog.h"
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct AQH_MSG_ENDPOINT_LOG_OLD AQH_MSG_ENDPOINT_LOG_OLD;
|
|
||||||
struct AQH_MSG_ENDPOINT_LOG_OLD {
|
|
||||||
char *filename;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
@@ -1,344 +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/msgendpointmanager_p.h"
|
|
||||||
#include "aqhome/msg_setaccmsggrps.h"
|
|
||||||
|
|
||||||
#include <gwenhywfar/misc.h>
|
|
||||||
#include <gwenhywfar/list.h>
|
|
||||||
#include <gwenhywfar/error.h>
|
|
||||||
#include <gwenhywfar/debug.h>
|
|
||||||
|
|
||||||
#include <errno.h>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static int _ioLoopOnce(AQH_MSG_ENDPOINT_MGR *emgr);
|
|
||||||
static void _msgLoopOnce(AQH_MSG_ENDPOINT_MGR *emgr);
|
|
||||||
static void _runAllEndpoints(AQH_MSG_ENDPOINT_MGR *emgr);
|
|
||||||
static void _distributeMsg(AQH_MSG_ENDPOINT_MGR *emgr, AQH_MSG_ENDPOINT *ep, const AQH_MSG *msg);
|
|
||||||
static void _handleAdminMsg(AQH_MSG_ENDPOINT_MGR *emgr, AQH_MSG_ENDPOINT *ep, const AQH_MSG *msg);
|
|
||||||
static void _handleMsgSetAcceptedMsgGroups(AQH_MSG_ENDPOINT_MGR *emgr, AQH_MSG_ENDPOINT *ep, const AQH_MSG *msg);
|
|
||||||
static uint32_t _getMsgGroup(uint8_t msgType);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
AQH_MSG_ENDPOINT_MGR *AQH_MsgEndpointManager_new(uint8_t busAddr)
|
|
||||||
{
|
|
||||||
AQH_MSG_ENDPOINT_MGR *emgr;
|
|
||||||
|
|
||||||
GWEN_NEW_OBJECT(AQH_MSG_ENDPOINT_MGR, emgr);
|
|
||||||
emgr->endpointList=AQH_MsgEndpoint_List_new();
|
|
||||||
emgr->busAddr=busAddr;
|
|
||||||
return emgr;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_MsgEndpointManager_free(AQH_MSG_ENDPOINT_MGR *emgr)
|
|
||||||
{
|
|
||||||
if (emgr) {
|
|
||||||
AQH_MsgEndpoint_List_free(emgr->endpointList);
|
|
||||||
GWEN_FREE_OBJECT(emgr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint8_t AQH_MsgEndpointManager_GetBusAddr(const AQH_MSG_ENDPOINT_MGR *emgr)
|
|
||||||
{
|
|
||||||
return emgr->busAddr;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
AQH_MSG_ENDPOINT_LIST *AQH_MsgEndpointManager_GetEndpointList(const AQH_MSG_ENDPOINT_MGR *emgr)
|
|
||||||
{
|
|
||||||
return emgr->endpointList;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_MsgEndpointManager_AddEndpoint(AQH_MSG_ENDPOINT_MGR *emgr, AQH_MSG_ENDPOINT *ep)
|
|
||||||
{
|
|
||||||
AQH_MsgEndpoint_List_Add(ep, emgr->endpointList);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_MsgEndpointManager_DelEndpoint(AQH_MSG_ENDPOINT_MGR *emgr, AQH_MSG_ENDPOINT *ep)
|
|
||||||
{
|
|
||||||
AQH_MsgEndpoint_List_Del(ep);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int AQH_MsgEndpointManager_LoopOnce(AQH_MSG_ENDPOINT_MGR *emgr)
|
|
||||||
{
|
|
||||||
int rv;
|
|
||||||
|
|
||||||
rv=_ioLoopOnce(emgr);
|
|
||||||
_msgLoopOnce(emgr);
|
|
||||||
_runAllEndpoints(emgr);
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int _ioLoopOnce(AQH_MSG_ENDPOINT_MGR *emgr)
|
|
||||||
{
|
|
||||||
AQH_MSG_ENDPOINT *ep;
|
|
||||||
fd_set readSet;
|
|
||||||
fd_set writeSet;
|
|
||||||
int highestRdFd=-1;
|
|
||||||
int highestWrFd=-1;
|
|
||||||
struct timeval tv;
|
|
||||||
int rv;
|
|
||||||
|
|
||||||
FD_ZERO(&readSet);
|
|
||||||
FD_ZERO(&writeSet);
|
|
||||||
tv.tv_sec=2;
|
|
||||||
tv.tv_usec=0;
|
|
||||||
|
|
||||||
DBG_DEBUG(AQH_LOGDOMAIN, "Sampling sockets");
|
|
||||||
ep=AQH_MsgEndpoint_List_First(emgr->endpointList);
|
|
||||||
if (ep==NULL) {
|
|
||||||
DBG_ERROR(AQH_LOGDOMAIN, "No endpoints.");
|
|
||||||
return GWEN_ERROR_GENERIC;
|
|
||||||
}
|
|
||||||
while(ep) {
|
|
||||||
DBG_DEBUG(AQH_LOGDOMAIN, "- checking endpoint %s", AQH_MsgEndpoint_GetName(ep));
|
|
||||||
if (!(AQH_MsgEndpoint_GetFlags(ep) & AQH_MSG_ENDPOINT_FLAGS_NOIO)) {
|
|
||||||
int fd;
|
|
||||||
|
|
||||||
fd=AQH_MsgEndpoint_GetReadFd(ep);
|
|
||||||
if (fd>=0) {
|
|
||||||
DBG_DEBUG(AQH_LOGDOMAIN, " - adding socket %d for read", fd);
|
|
||||||
FD_SET(fd, &readSet);
|
|
||||||
highestRdFd=(fd>highestRdFd)?fd:highestRdFd;
|
|
||||||
}
|
|
||||||
|
|
||||||
fd=AQH_MsgEndpoint_GetWriteFd(ep);
|
|
||||||
if (fd>=0) {
|
|
||||||
DBG_DEBUG(AQH_LOGDOMAIN, " - adding socket %d for write", fd);
|
|
||||||
FD_SET(fd, &writeSet);
|
|
||||||
highestWrFd=(fd>highestWrFd)?fd:highestWrFd;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
DBG_DEBUG(AQH_LOGDOMAIN, " - endpoint %s does not support IO", AQH_MsgEndpoint_GetName(ep));
|
|
||||||
}
|
|
||||||
ep=AQH_MsgEndpoint_List_Next(ep);
|
|
||||||
}
|
|
||||||
|
|
||||||
DBG_DEBUG(AQH_LOGDOMAIN, "Calling select (highest read socket: %d, highest write socket: %d)", highestRdFd, highestWrFd);
|
|
||||||
rv=select(((highestRdFd>highestWrFd)?highestRdFd:highestWrFd)+1,
|
|
||||||
(highestRdFd<0)?NULL:&readSet,
|
|
||||||
(highestWrFd<0)?NULL:&writeSet,
|
|
||||||
NULL,
|
|
||||||
&tv);
|
|
||||||
DBG_DEBUG(AQH_LOGDOMAIN, "Return from select (%d, %d=%s)", rv, (rv<0)?errno:0, (rv<0)?strerror(errno):"no error");
|
|
||||||
if (rv<0) {
|
|
||||||
if (errno!=EINTR) {
|
|
||||||
DBG_ERROR(AQH_LOGDOMAIN, "Error on select");
|
|
||||||
return GWEN_ERROR_IO;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (rv==0) {
|
|
||||||
/* timeout */
|
|
||||||
DBG_DEBUG(AQH_LOGDOMAIN, "timeout");
|
|
||||||
return GWEN_ERROR_TRY_AGAIN;
|
|
||||||
}
|
|
||||||
else if (rv) {
|
|
||||||
DBG_DEBUG(AQH_LOGDOMAIN, "Letting all endpoints handle IO");
|
|
||||||
ep=AQH_MsgEndpoint_List_First(emgr->endpointList);
|
|
||||||
while(ep) {
|
|
||||||
AQH_MSG_ENDPOINT *epNext;
|
|
||||||
int fd;
|
|
||||||
int rv;
|
|
||||||
|
|
||||||
epNext=AQH_MsgEndpoint_List_Next(ep);
|
|
||||||
fd=AQH_MsgEndpoint_GetFd(ep);
|
|
||||||
if (fd!=-1 && FD_ISSET(fd, &readSet)) {
|
|
||||||
DBG_DEBUG(AQH_LOGDOMAIN, "- endpoint(%s): read", AQH_MsgEndpoint_GetName(ep));
|
|
||||||
rv=AQH_MsgEndpoint_HandleReadable(ep, emgr);
|
|
||||||
if (rv<0 && rv!=GWEN_ERROR_TRY_AGAIN) {
|
|
||||||
DBG_DEBUG(AQH_LOGDOMAIN, "error, removing endpoint %s", AQH_MsgEndpoint_GetName(ep));
|
|
||||||
fd=-1;
|
|
||||||
AQH_MsgEndpointManager_DelEndpoint(emgr, ep);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (fd!=-1 && FD_ISSET(fd, &writeSet)) {
|
|
||||||
DBG_DEBUG(AQH_LOGDOMAIN, "- endpoint(%s): write", AQH_MsgEndpoint_GetName(ep));
|
|
||||||
rv=AQH_MsgEndpoint_HandleWritable(ep, emgr);
|
|
||||||
if (rv<0 && rv!=GWEN_ERROR_TRY_AGAIN) {
|
|
||||||
DBG_DEBUG(AQH_LOGDOMAIN, "error, removing endpoint %s", AQH_MsgEndpoint_GetName(ep));
|
|
||||||
fd=-1;
|
|
||||||
AQH_MsgEndpointManager_DelEndpoint(emgr, ep);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ep=epNext;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void _msgLoopOnce(AQH_MSG_ENDPOINT_MGR *emgr)
|
|
||||||
{
|
|
||||||
AQH_MSG_ENDPOINT *ep;
|
|
||||||
|
|
||||||
DBG_DEBUG(AQH_LOGDOMAIN, "Handle endpoint messages");
|
|
||||||
ep=AQH_MsgEndpoint_List_First(emgr->endpointList);
|
|
||||||
while(ep) {
|
|
||||||
AQH_MSG *msg;
|
|
||||||
|
|
||||||
DBG_DEBUG(AQH_LOGDOMAIN, "- endpoint(%s)", AQH_MsgEndpoint_GetName(ep));
|
|
||||||
while( (msg=AQH_MsgEndpoint_TakeFirstReceivedMessage(ep)) ) {
|
|
||||||
uint32_t msgGroup;
|
|
||||||
|
|
||||||
DBG_INFO(AQH_LOGDOMAIN,
|
|
||||||
" - msg %d from %d to %d",
|
|
||||||
AQH_Msg_GetMsgType(msg), AQH_Msg_GetSourceAddress(msg), AQH_Msg_GetDestAddress(msg));
|
|
||||||
msgGroup=_getMsgGroup(AQH_Msg_GetMsgType(msg));
|
|
||||||
if (msgGroup & AQH_MSG_ENDPOINT_MSGGROUP_ADMIN) {
|
|
||||||
if (!(AQH_MsgEndpoint_GetGroupId(ep) & AQH_MSG_ENDPOINT_ENDPOINTGROUP_BUS)) {
|
|
||||||
/* only handle admin messages not from nodes */
|
|
||||||
DBG_DEBUG(AQH_LOGDOMAIN, " - handling admin message");
|
|
||||||
_handleAdminMsg(emgr, ep, msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
DBG_DEBUG(AQH_LOGDOMAIN, " - distributing message");
|
|
||||||
_distributeMsg(emgr, ep, msg);
|
|
||||||
}
|
|
||||||
AQH_Msg_free(msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
ep=AQH_MsgEndpoint_List_Next(ep);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void _runAllEndpoints(AQH_MSG_ENDPOINT_MGR *emgr)
|
|
||||||
{
|
|
||||||
AQH_MSG_ENDPOINT *ep;
|
|
||||||
|
|
||||||
DBG_DEBUG(AQH_LOGDOMAIN, "Running all endpoints");
|
|
||||||
ep=AQH_MsgEndpoint_List_First(emgr->endpointList);
|
|
||||||
while(ep) {
|
|
||||||
AQH_MSG_ENDPOINT *next;
|
|
||||||
|
|
||||||
next=AQH_MsgEndpoint_List_Next(ep);
|
|
||||||
DBG_DEBUG(AQH_LOGDOMAIN, "- running endpoint %s", AQH_MsgEndpoint_GetName(ep));
|
|
||||||
AQH_MsgEndpoint_Run(ep);
|
|
||||||
ep=next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void _distributeMsg(AQH_MSG_ENDPOINT_MGR *emgr, AQH_MSG_ENDPOINT *srcEp, const AQH_MSG *msg)
|
|
||||||
{
|
|
||||||
AQH_MSG_ENDPOINT *ep;
|
|
||||||
int srcGroupId;
|
|
||||||
uint32_t msgGroup;
|
|
||||||
|
|
||||||
msgGroup=_getMsgGroup(AQH_Msg_GetMsgType(msg));
|
|
||||||
srcGroupId=AQH_MsgEndpoint_GetGroupId(srcEp);
|
|
||||||
|
|
||||||
ep=AQH_MsgEndpoint_List_First(emgr->endpointList);
|
|
||||||
while(ep) {
|
|
||||||
if (ep!=srcEp) {
|
|
||||||
uint32_t acceptedGroupIds;
|
|
||||||
uint32_t acceptedMsgGroups;
|
|
||||||
|
|
||||||
DBG_DEBUG(AQH_LOGDOMAIN, "- checking endpoint %s", AQH_MsgEndpoint_GetName(ep));
|
|
||||||
acceptedGroupIds=AQH_MsgEndpoint_GetAcceptedMsgGroups(ep);
|
|
||||||
acceptedMsgGroups=AQH_MsgEndpoint_GetAcceptedMsgGroups(ep);
|
|
||||||
|
|
||||||
if (
|
|
||||||
!(AQH_MsgEndpoint_GetFlags(ep) & AQH_MSG_ENDPOINT_FLAGS_NOMESSAGES) &&
|
|
||||||
(acceptedMsgGroups & msgGroup) &&
|
|
||||||
(acceptedGroupIds & srcGroupId)
|
|
||||||
) {
|
|
||||||
/* endpoint accepts this message */
|
|
||||||
DBG_DEBUG(AQH_LOGDOMAIN, " - endpoint %s accepts message", AQH_MsgEndpoint_GetName(ep));
|
|
||||||
AQH_MsgEndpoint_AddSendMessage(ep, AQH_Msg_dup(msg));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
DBG_DEBUG(AQH_LOGDOMAIN, " - endpoint %s does not accept message", AQH_MsgEndpoint_GetName(ep));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ep=AQH_MsgEndpoint_List_Next(ep);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void _handleAdminMsg(AQH_MSG_ENDPOINT_MGR *emgr, AQH_MSG_ENDPOINT *ep, const AQH_MSG *msg)
|
|
||||||
{
|
|
||||||
uint8_t mt;
|
|
||||||
|
|
||||||
mt=AQH_Msg_GetMsgType(msg);
|
|
||||||
switch(mt) {
|
|
||||||
case AQH_MSG_TYPE_NET_SET_ACCEPTED_MSGGROUPS:
|
|
||||||
_handleMsgSetAcceptedMsgGroups(emgr, ep, msg);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void _handleMsgSetAcceptedMsgGroups(AQH_MSG_ENDPOINT_MGR *emgr, AQH_MSG_ENDPOINT *ep, const AQH_MSG *msg)
|
|
||||||
{
|
|
||||||
AQH_MsgEndpoint_SetAcceptedMsgGroups(ep, AQH_MsgSetAcceptedMsgGroups_GetMsgGroups(msg));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint32_t _getMsgGroup(uint8_t msgType)
|
|
||||||
{
|
|
||||||
switch(msgType) {
|
|
||||||
case AQH_MSG_TYPE_PING:
|
|
||||||
case AQH_MSG_TYPE_PONG:
|
|
||||||
case AQH_MSG_TYPE_COMSENDSTATS:
|
|
||||||
case AQH_MSG_TYPE_COMRECVSTATS:
|
|
||||||
case AQH_MSG_TYPE_TWIBUSMEMBER:
|
|
||||||
case AQH_MSG_TYPE_DEBUG:
|
|
||||||
return AQH_MSG_ENDPOINT_MSGGROUP_INFO;
|
|
||||||
case AQH_MSG_TYPE_VALUE:
|
|
||||||
return AQH_MSG_ENDPOINT_MSGGROUP_VALUES;
|
|
||||||
case AQH_MSG_TYPE_NEED_ADDRESS:
|
|
||||||
case AQH_MSG_TYPE_HAVE_ADDRESS:
|
|
||||||
case AQH_MSG_TYPE_CLAIM_ADDRESS:
|
|
||||||
case AQH_MSG_TYPE_DENY_ADDRESS:
|
|
||||||
case AQH_MSG_TYPE_ADDRESS_RANGE:
|
|
||||||
return AQH_MSG_ENDPOINT_MSGGROUP_ADDRESS;
|
|
||||||
case AQH_MSG_TYPE_NET_SET_ACCEPTED_MSGGROUPS:
|
|
||||||
return AQH_MSG_ENDPOINT_MSGGROUP_ADMIN;
|
|
||||||
default:
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -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_MSGENDPOINT_MGR_H
|
|
||||||
#define AQH_MSGENDPOINT_MGR_H
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct AQH_MSG_ENDPOINT_MGR AQH_MSG_ENDPOINT_MGR;
|
|
||||||
|
|
||||||
|
|
||||||
#include <aqhome/api.h>
|
|
||||||
|
|
||||||
#include "aqhome/msg.h"
|
|
||||||
#include "aqhome/msgendpoint.h"
|
|
||||||
|
|
||||||
#include <gwenhywfar/list.h>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
AQHOME_API AQH_MSG_ENDPOINT_MGR *AQH_MsgEndpointManager_new(uint8_t busAddr);
|
|
||||||
AQHOME_API void AQH_MsgEndpointManager_free(AQH_MSG_ENDPOINT_MGR *emgr);
|
|
||||||
|
|
||||||
AQHOME_API uint8_t AQH_MsgEndpointManager_GetBusAddr(const AQH_MSG_ENDPOINT_MGR *emgr);
|
|
||||||
|
|
||||||
AQHOME_API AQH_MSG_ENDPOINT_LIST *AQH_MsgEndpointManager_GetEndpointList(const AQH_MSG_ENDPOINT_MGR *emgr);
|
|
||||||
|
|
||||||
AQHOME_API void AQH_MsgEndpointManager_AddEndpoint(AQH_MSG_ENDPOINT_MGR *emgr, AQH_MSG_ENDPOINT *ep);
|
|
||||||
AQHOME_API void AQH_MsgEndpointManager_DelEndpoint(AQH_MSG_ENDPOINT_MGR *emgr, AQH_MSG_ENDPOINT *ep);
|
|
||||||
|
|
||||||
AQHOME_API int AQH_MsgEndpointManager_LoopOnce(AQH_MSG_ENDPOINT_MGR *emgr);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
@@ -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_MSGENDPOINT_MGR_P_H
|
|
||||||
#define AQH_MSGENDPOINT_MGR_P_H
|
|
||||||
|
|
||||||
|
|
||||||
#include "aqhome/msgendpointmanager.h"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct AQH_MSG_ENDPOINT_MGR {
|
|
||||||
uint8_t busAddr;
|
|
||||||
AQH_MSG_ENDPOINT_LIST *endpointList;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
@@ -1,222 +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/msgendpointtcp.h"
|
|
||||||
|
|
||||||
#include <gwenhywfar/list.h>
|
|
||||||
#include <gwenhywfar/inherit.h>
|
|
||||||
#include <gwenhywfar/debug.h>
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <netinet/in.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <arpa/inet.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define AQH_MSG_ENDPOINTTCP_BACKLOG 10
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static int _setupListeningSocket(const char *host, int port);
|
|
||||||
static int _setSocketNonBlocking(int fd);
|
|
||||||
static int _getReadFd(AQH_MSG_ENDPOINT *ep);
|
|
||||||
static int _getWriteFd(AQH_MSG_ENDPOINT *ep);
|
|
||||||
static int _handleReadable(AQH_MSG_ENDPOINT *ep, AQH_MSG_ENDPOINT_MGR *emgr);
|
|
||||||
static int _handleWritable(AQH_MSG_ENDPOINT *ep, AQH_MSG_ENDPOINT_MGR *emgr);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
AQH_MSG_ENDPOINT *AQH_MsgEndpointTcp_new(const char *host, int port)
|
|
||||||
{
|
|
||||||
int fd;
|
|
||||||
AQH_MSG_ENDPOINT *ep;
|
|
||||||
|
|
||||||
fd=_setupListeningSocket(host, port);
|
|
||||||
if (fd<0) {
|
|
||||||
DBG_INFO(NULL, "here");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
ep=AQH_MsgEndpoint_new(fd, AQH_MSG_ENDPOINT_ENDPOINTGROUP_NET, "TCP Server");
|
|
||||||
AQH_MsgEndpoint_SetAcceptedEndpointGroups(ep, AQH_MSG_ENDPOINT_ENDPOINTGROUP_BUS);
|
|
||||||
AQH_MsgEndpoint_AddFlags(ep, AQH_MSG_ENDPOINT_FLAGS_NOMESSAGES);
|
|
||||||
|
|
||||||
AQH_MsgEndpoint_SetHandleReadableFn(ep, _handleReadable);
|
|
||||||
AQH_MsgEndpoint_SetHandleWritableFn(ep, _handleWritable);
|
|
||||||
AQH_MsgEndpoint_SetGetReadFdFn(ep, _getReadFd);
|
|
||||||
AQH_MsgEndpoint_SetGetWriteFdFn(ep, _getWriteFd);
|
|
||||||
|
|
||||||
return ep;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int _setupListeningSocket(const char *host, int port)
|
|
||||||
{
|
|
||||||
struct sockaddr_in addr;
|
|
||||||
int rv;
|
|
||||||
int sk;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
memset(&addr, 0, sizeof(addr));
|
|
||||||
addr.sin_port=htons(port);
|
|
||||||
addr.sin_family=AF_INET;
|
|
||||||
|
|
||||||
if (inet_aton(host, &(addr.sin_addr))==0) {
|
|
||||||
/* bad address */
|
|
||||||
}
|
|
||||||
|
|
||||||
sk=socket(AF_INET, SOCK_STREAM, 0);
|
|
||||||
if (sk<0) {
|
|
||||||
/* socket error */
|
|
||||||
DBG_ERROR(AQH_LOGDOMAIN, "socket(): %s", strerror(errno));
|
|
||||||
}
|
|
||||||
|
|
||||||
i=1;
|
|
||||||
rv=setsockopt(sk, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i));
|
|
||||||
if (rv<0) {
|
|
||||||
DBG_ERROR(AQH_LOGDOMAIN, "setsockopt(): %s", strerror(errno));
|
|
||||||
close(sk);
|
|
||||||
return GWEN_ERROR_IO;
|
|
||||||
}
|
|
||||||
|
|
||||||
rv=_setSocketNonBlocking(sk);
|
|
||||||
if (rv<0) {
|
|
||||||
DBG_INFO(NULL, "here (%d)", rv);
|
|
||||||
close(sk);
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
rv=bind(sk, (struct sockaddr*) &addr, sizeof(addr));
|
|
||||||
if (rv<0) {
|
|
||||||
DBG_ERROR(AQH_LOGDOMAIN, "bind(): %s", strerror(errno));
|
|
||||||
close(sk);
|
|
||||||
return GWEN_ERROR_IO;
|
|
||||||
}
|
|
||||||
|
|
||||||
rv=listen(sk, AQH_MSG_ENDPOINTTCP_BACKLOG);
|
|
||||||
if (rv<0) {
|
|
||||||
DBG_ERROR(AQH_LOGDOMAIN, "listen(): %s", strerror(errno));
|
|
||||||
close(sk);
|
|
||||||
return GWEN_ERROR_IO;
|
|
||||||
}
|
|
||||||
|
|
||||||
return sk;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int _setSocketNonBlocking(int fd)
|
|
||||||
{
|
|
||||||
int prevFlags;
|
|
||||||
int newFlags;
|
|
||||||
|
|
||||||
/* get current socket flags */
|
|
||||||
prevFlags=fcntl(fd, F_GETFL);
|
|
||||||
if (prevFlags==-1) {
|
|
||||||
DBG_ERROR(AQH_LOGDOMAIN, "fcntl(): %s", strerror(errno));
|
|
||||||
return GWEN_ERROR_IO;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* set nonblocking/blocking */
|
|
||||||
newFlags=prevFlags|O_NONBLOCK;
|
|
||||||
|
|
||||||
if (-1==fcntl(fd, F_SETFL, newFlags)) {
|
|
||||||
DBG_ERROR(AQH_LOGDOMAIN, "fcntl(): %s", strerror(errno));
|
|
||||||
return GWEN_ERROR_IO;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int _getReadFd(AQH_MSG_ENDPOINT *ep)
|
|
||||||
{
|
|
||||||
return AQH_MsgEndpoint_GetFd(ep);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int _getWriteFd(AQH_MSG_ENDPOINT *ep)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int _handleReadable(AQH_MSG_ENDPOINT *ep, AQH_MSG_ENDPOINT_MGR *emgr)
|
|
||||||
{
|
|
||||||
int fd;
|
|
||||||
int newSock;
|
|
||||||
int rv;
|
|
||||||
struct sockaddr_in clientAddr;
|
|
||||||
socklen_t len;
|
|
||||||
AQH_MSG_ENDPOINT *newEp;
|
|
||||||
|
|
||||||
fd=AQH_MsgEndpoint_GetFd(ep);
|
|
||||||
memset(&clientAddr, 0, sizeof(clientAddr));
|
|
||||||
do {
|
|
||||||
len=sizeof(clientAddr);
|
|
||||||
rv=accept(fd, (struct sockaddr*) &clientAddr, &len);
|
|
||||||
} while(rv<0 && errno==EINTR);
|
|
||||||
if (rv<0) {
|
|
||||||
if (errno==EAGAIN || errno==EWOULDBLOCK)
|
|
||||||
return GWEN_ERROR_TRY_AGAIN;
|
|
||||||
DBG_ERROR(AQH_LOGDOMAIN, "Error on accept(): %s (%d)", strerror(errno), errno);
|
|
||||||
return GWEN_ERROR_IO;
|
|
||||||
}
|
|
||||||
newSock=rv;
|
|
||||||
|
|
||||||
rv=_setSocketNonBlocking(newSock);
|
|
||||||
if (rv<0) {
|
|
||||||
DBG_INFO(NULL, "here (%d)", rv);
|
|
||||||
close(newSock);
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
newEp=AQH_MsgEndpoint_new(newSock, AQH_MsgEndpoint_GetGroupId(ep), "TCP Client");
|
|
||||||
AQH_MsgEndpoint_SetFlags(newEp, AQH_MsgEndpoint_GetFlags(ep));
|
|
||||||
AQH_MsgEndpoint_SubFlags(newEp, AQH_MSG_ENDPOINT_FLAGS_NOMESSAGES);
|
|
||||||
AQH_MsgEndpoint_SetAcceptedMsgGroups(newEp, AQH_MsgEndpoint_GetAcceptedMsgGroups(ep));
|
|
||||||
AQH_MsgEndpoint_SetAcceptedEndpointGroups(newEp, AQH_MsgEndpoint_GetAcceptedEndpointGroups(ep));
|
|
||||||
|
|
||||||
AQH_MsgEndpointManager_AddEndpoint(emgr, newEp);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int _handleWritable(AQH_MSG_ENDPOINT *ep, AQH_MSG_ENDPOINT_MGR *emgr)
|
|
||||||
{
|
|
||||||
/* should not get called */
|
|
||||||
return GWEN_ERROR_INVALID;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -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_MSGENDPOINT_TCP_H
|
|
||||||
#define AQH_MSGENDPOINT_TCP_H
|
|
||||||
|
|
||||||
|
|
||||||
#include <aqhome/api.h>
|
|
||||||
|
|
||||||
#include "aqhome/msgendpoint.h"
|
|
||||||
|
|
||||||
#include <gwenhywfar/list.h>
|
|
||||||
#include <gwenhywfar/inherit.h>
|
|
||||||
|
|
||||||
|
|
||||||
AQHOME_API AQH_MSG_ENDPOINT *AQH_MsgEndpointTcp_new(const char *host, int port);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
@@ -1,267 +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/msgendpointtty_p.h"
|
|
||||||
|
|
||||||
#include <gwenhywfar/list.h>
|
|
||||||
#include <gwenhywfar/inherit.h>
|
|
||||||
#include <gwenhywfar/debug.h>
|
|
||||||
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <termios.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <sys/ioctl.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
|
|
||||||
#define AQH_MSG_ENDPOINT_TTY_BAUDRATE B19200
|
|
||||||
#define AQH_MSG_ENDPOINT_TTY_BYTE_MICROSECS 520
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
GWEN_INHERIT(AQH_MSG_ENDPOINT, AQH_MSG_ENDPOINT_TTY)
|
|
||||||
|
|
||||||
|
|
||||||
static void GWENHYWFAR_CB _freeData(void *bp, void *p);
|
|
||||||
|
|
||||||
static int _startMsg(AQH_MSG_ENDPOINT *ep);
|
|
||||||
static int _endMsg(AQH_MSG_ENDPOINT *ep);
|
|
||||||
static int _checkMsg(AQH_MSG_ENDPOINT *ep);
|
|
||||||
|
|
||||||
static int _openDevice(AQH_MSG_ENDPOINT *ep);
|
|
||||||
static int _attnLow(AQH_MSG_ENDPOINT *ep);
|
|
||||||
static int _attnHigh(AQH_MSG_ENDPOINT *ep);
|
|
||||||
static int _isAttnLow(AQH_MSG_ENDPOINT *ep);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
AQH_MSG_ENDPOINT *AQH_MsgEndpointTty_new(const char *deviceName)
|
|
||||||
{
|
|
||||||
AQH_MSG_ENDPOINT *ep;
|
|
||||||
AQH_MSG_ENDPOINT_TTY *xep;
|
|
||||||
int fd;
|
|
||||||
|
|
||||||
ep=AQH_MsgEndpoint_new(-1, AQH_MSG_ENDPOINT_ENDPOINTGROUP_BUS, "TTY");
|
|
||||||
AQH_MsgEndpoint_SetAcceptedEndpointGroups(ep, AQH_MSG_ENDPOINT_ENDPOINTGROUP_NET);
|
|
||||||
AQH_MsgEndpoint_SetAcceptedMsgGroups(ep, AQH_MSG_ENDPOINT_MSGGROUP_ALL);
|
|
||||||
|
|
||||||
GWEN_NEW_OBJECT(AQH_MSG_ENDPOINT_TTY, xep);
|
|
||||||
GWEN_INHERIT_SETDATA(AQH_MSG_ENDPOINT, AQH_MSG_ENDPOINT_TTY, ep, xep, _freeData);
|
|
||||||
xep->deviceName=strdup(deviceName);
|
|
||||||
|
|
||||||
AQH_MsgEndpoint_SetStartMsgFn(ep, _startMsg);
|
|
||||||
AQH_MsgEndpoint_SetEndMsgFn(ep, _endMsg);
|
|
||||||
AQH_MsgEndpoint_SetCheckMsgFn(ep, _checkMsg);
|
|
||||||
|
|
||||||
fd=_openDevice(ep);
|
|
||||||
if (fd<0) {
|
|
||||||
DBG_INFO(NULL, "here (%d)", fd);
|
|
||||||
AQH_MsgEndpoint_free(ep);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
AQH_MsgEndpoint_SetFd(ep, fd);
|
|
||||||
_attnHigh(ep);
|
|
||||||
|
|
||||||
return ep;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void _freeData(void *bp, void *p)
|
|
||||||
{
|
|
||||||
AQH_MSG_ENDPOINT *ep;
|
|
||||||
AQH_MSG_ENDPOINT_TTY *xep;
|
|
||||||
int fd;
|
|
||||||
|
|
||||||
ep=(AQH_MSG_ENDPOINT*) bp;
|
|
||||||
xep=(AQH_MSG_ENDPOINT_TTY*) p;
|
|
||||||
fd=AQH_MsgEndpoint_GetFd(ep);
|
|
||||||
if (fd>=0)
|
|
||||||
tcsetattr(fd, TCSANOW, &xep->previousOptions);
|
|
||||||
free(xep->deviceName);
|
|
||||||
GWEN_FREE_OBJECT(xep);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int _startMsg(AQH_MSG_ENDPOINT *ep)
|
|
||||||
{
|
|
||||||
AQH_MSG_ENDPOINT_TTY *xep;
|
|
||||||
|
|
||||||
xep=GWEN_INHERIT_GETDATA(AQH_MSG_ENDPOINT, AQH_MSG_ENDPOINT_TTY, ep);
|
|
||||||
if (xep->intendedAttnState==1) {
|
|
||||||
int rv;
|
|
||||||
|
|
||||||
rv=_attnLow(ep);
|
|
||||||
if (rv<0) {
|
|
||||||
DBG_ERROR(AQH_LOGDOMAIN, "here (%d)", rv);
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
usleep(AQH_MSG_ENDPOINT_TTY_BYTE_MICROSECS/5);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int _endMsg(AQH_MSG_ENDPOINT *ep)
|
|
||||||
{
|
|
||||||
_attnHigh(ep);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int _checkMsg(AQH_MSG_ENDPOINT *ep)
|
|
||||||
{
|
|
||||||
return _isAttnLow(ep);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int _openDevice(AQH_MSG_ENDPOINT *ep)
|
|
||||||
{
|
|
||||||
AQH_MSG_ENDPOINT_TTY *xep;
|
|
||||||
int fd;
|
|
||||||
int status;
|
|
||||||
int i;
|
|
||||||
struct termios options;
|
|
||||||
int rv;
|
|
||||||
int m;
|
|
||||||
|
|
||||||
xep=GWEN_INHERIT_GETDATA(AQH_MSG_ENDPOINT, AQH_MSG_ENDPOINT_TTY, ep);
|
|
||||||
fd=open(xep->deviceName, O_NOCTTY | O_NDELAY | O_RDWR);
|
|
||||||
if (fd<0) {
|
|
||||||
DBG_ERROR(AQH_LOGDOMAIN, "Error on open(%s): %s (%d)", xep->deviceName, strerror(errno), errno);
|
|
||||||
return GWEN_ERROR_IO;
|
|
||||||
}
|
|
||||||
rv=tcgetattr(fd, &(xep->previousOptions));
|
|
||||||
if (rv<0) {
|
|
||||||
DBG_ERROR(AQH_LOGDOMAIN, "Error on tcgetattr(%s): %s (%d)", xep->deviceName, strerror(errno), errno);
|
|
||||||
return GWEN_ERROR_IO;
|
|
||||||
}
|
|
||||||
memset(&options, 0, sizeof(options)); /* preset */
|
|
||||||
|
|
||||||
options.c_cflag=CLOCAL | CREAD | CS8;
|
|
||||||
options.c_iflag=IGNPAR | IGNBRK;
|
|
||||||
options.c_oflag=0;
|
|
||||||
options.c_lflag=0;
|
|
||||||
cfmakeraw(&options);
|
|
||||||
options.c_cc[VTIME]=0; /* read timeout in deciseconds */
|
|
||||||
options.c_cc[VMIN]=0; /* no minimum number of receive bytes */
|
|
||||||
|
|
||||||
rv=cfsetispeed(&options, AQH_MSG_ENDPOINT_TTY_BAUDRATE);
|
|
||||||
if (rv<0) {
|
|
||||||
DBG_ERROR(AQH_LOGDOMAIN, "Error on cfsetispeed(%s): %s (%d)", xep->deviceName, strerror(errno), errno);
|
|
||||||
return GWEN_ERROR_IO;
|
|
||||||
}
|
|
||||||
rv=cfsetospeed(&options, AQH_MSG_ENDPOINT_TTY_BAUDRATE);
|
|
||||||
if (rv<0) {
|
|
||||||
DBG_ERROR(AQH_LOGDOMAIN, "Error on cfsetospeed(%s): %s (%d)", xep->deviceName, strerror(errno), errno);
|
|
||||||
return GWEN_ERROR_IO;
|
|
||||||
}
|
|
||||||
|
|
||||||
rv=tcflush(fd, TCIOFLUSH);
|
|
||||||
if (rv<0) {
|
|
||||||
DBG_ERROR(AQH_LOGDOMAIN, "Error on tcflush(%s): %s (%d)", xep->deviceName, strerror(errno), errno);
|
|
||||||
return GWEN_ERROR_IO;
|
|
||||||
}
|
|
||||||
|
|
||||||
rv=tcsetattr(fd, TCSANOW, &options);
|
|
||||||
if (rv<0) {
|
|
||||||
DBG_ERROR(AQH_LOGDOMAIN, "Error on tcsetattr(%s): %s (%d)", xep->deviceName, strerror(errno), errno);
|
|
||||||
return GWEN_ERROR_IO;
|
|
||||||
}
|
|
||||||
|
|
||||||
return fd;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int _attnLow(AQH_MSG_ENDPOINT *ep)
|
|
||||||
{
|
|
||||||
AQH_MSG_ENDPOINT_TTY *xep;
|
|
||||||
int status;
|
|
||||||
int rv;
|
|
||||||
int fd;
|
|
||||||
|
|
||||||
xep=GWEN_INHERIT_GETDATA(AQH_MSG_ENDPOINT, AQH_MSG_ENDPOINT_TTY, ep);
|
|
||||||
fd=AQH_MsgEndpoint_GetFd(ep);
|
|
||||||
rv=ioctl(fd, TIOCMGET, &status); /* GET the State of MODEM bits in Status */
|
|
||||||
if (rv<0) {
|
|
||||||
DBG_ERROR(AQH_LOGDOMAIN, "Error on ioctl(%s): %s (%d)", xep->deviceName, strerror(errno), errno);
|
|
||||||
return GWEN_ERROR_IO;
|
|
||||||
}
|
|
||||||
status |= TIOCM_DTR | TIOCM_RTS; /* clear the DTR pin (cave: signals inverted!) */
|
|
||||||
rv=ioctl(fd, TIOCMSET, &status);
|
|
||||||
if (rv<0) {
|
|
||||||
DBG_ERROR(AQH_LOGDOMAIN, "Error on ioctl(%s): %s (%d)", xep->deviceName, strerror(errno), errno);
|
|
||||||
return GWEN_ERROR_IO;
|
|
||||||
}
|
|
||||||
xep->intendedAttnState=0;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int _attnHigh(AQH_MSG_ENDPOINT *ep)
|
|
||||||
{
|
|
||||||
AQH_MSG_ENDPOINT_TTY *xep;
|
|
||||||
int status;
|
|
||||||
int rv;
|
|
||||||
int fd;
|
|
||||||
|
|
||||||
xep=GWEN_INHERIT_GETDATA(AQH_MSG_ENDPOINT, AQH_MSG_ENDPOINT_TTY, ep);
|
|
||||||
fd=AQH_MsgEndpoint_GetFd(ep);
|
|
||||||
rv=ioctl(fd, TIOCMGET, &status);
|
|
||||||
if (rv<0) {
|
|
||||||
DBG_ERROR(AQH_LOGDOMAIN, "Error on ioctl(%s): %s (%d)", xep->deviceName, strerror(errno), errno);
|
|
||||||
return GWEN_ERROR_IO;
|
|
||||||
}
|
|
||||||
status |= TIOCM_DTR; /* Set the DTR pin */
|
|
||||||
status &= ~ (TIOCM_DTR | TIOCM_RTS); /* clear the DTR pin (cave: signals inverted!) */
|
|
||||||
rv=ioctl(fd, TIOCMSET, &status);
|
|
||||||
if (rv<0) {
|
|
||||||
DBG_ERROR(AQH_LOGDOMAIN, "Error on ioctl(%s): %s (%d)", xep->deviceName, strerror(errno), errno);
|
|
||||||
return GWEN_ERROR_IO;
|
|
||||||
}
|
|
||||||
|
|
||||||
xep->intendedAttnState=1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int _isAttnLow(AQH_MSG_ENDPOINT *ep)
|
|
||||||
{
|
|
||||||
AQH_MSG_ENDPOINT_TTY *xep;
|
|
||||||
int status;
|
|
||||||
int rv;
|
|
||||||
int fd;
|
|
||||||
|
|
||||||
xep=GWEN_INHERIT_GETDATA(AQH_MSG_ENDPOINT, AQH_MSG_ENDPOINT_TTY, ep);
|
|
||||||
fd=AQH_MsgEndpoint_GetFd(ep);
|
|
||||||
rv=ioctl(fd, TIOCMGET, &status);
|
|
||||||
if (rv<0) {
|
|
||||||
DBG_ERROR(AQH_LOGDOMAIN, "Error on ioctl(%s): %s (%d)", xep->deviceName, strerror(errno), errno);
|
|
||||||
return GWEN_ERROR_IO;
|
|
||||||
}
|
|
||||||
//return (status & TIOCM_CTS)?1:0;
|
|
||||||
return (status & TIOCM_CTS)?1:0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -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_MSGENDPOINT_TTY_H
|
|
||||||
#define AQH_MSGENDPOINT_TTY_H
|
|
||||||
|
|
||||||
|
|
||||||
#include <aqhome/api.h>
|
|
||||||
|
|
||||||
#include "aqhome/msgendpoint.h"
|
|
||||||
|
|
||||||
#include <gwenhywfar/list.h>
|
|
||||||
#include <gwenhywfar/inherit.h>
|
|
||||||
|
|
||||||
|
|
||||||
AQHOME_API AQH_MSG_ENDPOINT *AQH_MsgEndpointTty_new(const char *devName);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
@@ -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_MSGENDPOINT_TTY_P_H
|
|
||||||
#define AQH_MSGENDPOINT_TTY_P_H
|
|
||||||
|
|
||||||
|
|
||||||
#include "aqhome/msgendpointtty.h"
|
|
||||||
|
|
||||||
#include <termios.h>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct AQH_MSG_ENDPOINT_TTY AQH_MSG_ENDPOINT_TTY;
|
|
||||||
struct AQH_MSG_ENDPOINT_TTY {
|
|
||||||
char *deviceName;
|
|
||||||
struct termios previousOptions;
|
|
||||||
int intendedAttnState;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
716
aqhome/serial.c
716
aqhome/serial.c
@@ -1,716 +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/serial_p.h"
|
|
||||||
|
|
||||||
#include <gwenhywfar/misc.h>
|
|
||||||
#include <gwenhywfar/debug.h>
|
|
||||||
#include <gwenhywfar/text.h>
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <termios.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <sys/ioctl.h>
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <sys/time.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int _attnLow(AQH_SERIAL *sr);
|
|
||||||
int _attnHigh(AQH_SERIAL *sr);
|
|
||||||
int _readForced(AQH_SERIAL *sr, uint8_t *buf, int len);
|
|
||||||
int _writeForced(AQH_SERIAL *sr, const uint8_t *buf, uint8_t len);
|
|
||||||
int _discardInput(AQH_SERIAL *sr);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define AQH_SERIAL_BAUDRATE B19200
|
|
||||||
#define AQH_SERIAL_BYTE_MICROSECS 520
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
AQH_SERIAL *AQH_Serial_new(const char *deviceName, uint8_t addr)
|
|
||||||
{
|
|
||||||
AQH_SERIAL *sr;
|
|
||||||
|
|
||||||
GWEN_NEW_OBJECT(AQH_SERIAL, sr);
|
|
||||||
sr->deviceName=deviceName?strdup(deviceName):NULL;
|
|
||||||
sr->address=addr;
|
|
||||||
sr->fd=-1;
|
|
||||||
sr->intendedAttnState=1;
|
|
||||||
|
|
||||||
sr->receivedMessageList=AQH_Msg_List_new();
|
|
||||||
sr->sendMessageList=AQH_Msg_List_new();
|
|
||||||
return sr;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_Serial_free(AQH_SERIAL *sr)
|
|
||||||
{
|
|
||||||
if (sr) {
|
|
||||||
AQH_Msg_List_free(sr->receivedMessageList);
|
|
||||||
AQH_Msg_List_free(sr->sendMessageList);
|
|
||||||
free(sr->deviceName);
|
|
||||||
GWEN_FREE_OBJECT(sr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint8_t AQH_Serial_GetAddress(const AQH_SERIAL *sr)
|
|
||||||
{
|
|
||||||
return sr->address;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int AQH_Serial_Open(AQH_SERIAL *sr, int rwMode)
|
|
||||||
{
|
|
||||||
int fd;
|
|
||||||
int status;
|
|
||||||
int i;
|
|
||||||
struct termios options;
|
|
||||||
int rv;
|
|
||||||
int m;
|
|
||||||
|
|
||||||
m=O_NOCTTY | O_NDELAY;
|
|
||||||
switch(rwMode) {
|
|
||||||
case AQH_SerialReadWriteMode_ReadOnly: m|=O_RDONLY; break;
|
|
||||||
case AQH_SerialReadWriteMode_WriteOnly: m|=O_WRONLY; break;
|
|
||||||
case AQH_SerialReadWriteMode_ReadWrite: m|=O_RDWR; break;
|
|
||||||
default: m|=O_RDONLY; break;
|
|
||||||
}
|
|
||||||
|
|
||||||
fd=open(sr->deviceName, m);
|
|
||||||
if (fd<0) {
|
|
||||||
DBG_ERROR(NULL, "Error on open(%s): %s (%d)", sr->deviceName, strerror(errno), errno);
|
|
||||||
return GWEN_ERROR_IO;
|
|
||||||
}
|
|
||||||
rv=tcgetattr(fd, &(sr->previousOptions));
|
|
||||||
if (rv<0) {
|
|
||||||
DBG_ERROR(NULL, "Error on tcgetattr(%s): %s (%d)", sr->deviceName, strerror(errno), errno);
|
|
||||||
return GWEN_ERROR_IO;
|
|
||||||
}
|
|
||||||
memset(&options, 0, sizeof(options)); /* preset */
|
|
||||||
|
|
||||||
options.c_cflag=CLOCAL | CREAD | CS8;
|
|
||||||
options.c_iflag=IGNPAR | IGNBRK;
|
|
||||||
options.c_oflag=0;
|
|
||||||
options.c_lflag=0;
|
|
||||||
cfmakeraw(&options);
|
|
||||||
options.c_cc[VTIME]=0; /* read timeout in deciseconds */
|
|
||||||
options.c_cc[VMIN]=0; /* no minimum number of receive bytes */
|
|
||||||
|
|
||||||
rv=cfsetispeed(&options, AQH_SERIAL_BAUDRATE);
|
|
||||||
if (rv<0) {
|
|
||||||
DBG_ERROR(NULL, "Error on cfsetispeed(%s): %s (%d)", sr->deviceName, strerror(errno), errno);
|
|
||||||
return GWEN_ERROR_IO;
|
|
||||||
}
|
|
||||||
rv=cfsetospeed(&options, AQH_SERIAL_BAUDRATE);
|
|
||||||
if (rv<0) {
|
|
||||||
DBG_ERROR(NULL, "Error on cfsetospeed(%s): %s (%d)", sr->deviceName, strerror(errno), errno);
|
|
||||||
return GWEN_ERROR_IO;
|
|
||||||
}
|
|
||||||
|
|
||||||
rv=tcflush(fd, TCIOFLUSH);
|
|
||||||
if (rv<0) {
|
|
||||||
DBG_ERROR(NULL, "Error on tcflush(%s): %s (%d)", sr->deviceName, strerror(errno), errno);
|
|
||||||
return GWEN_ERROR_IO;
|
|
||||||
}
|
|
||||||
|
|
||||||
rv=tcsetattr(fd, TCSANOW, &options);
|
|
||||||
if (rv<0) {
|
|
||||||
DBG_ERROR(NULL, "Error on tcsetattr(%s): %s (%d)", sr->deviceName, strerror(errno), errno);
|
|
||||||
return GWEN_ERROR_IO;
|
|
||||||
}
|
|
||||||
|
|
||||||
sr->fd=fd;
|
|
||||||
|
|
||||||
_attnHigh(sr);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_Serial_Close(AQH_SERIAL *sr)
|
|
||||||
{
|
|
||||||
if (sr->fd>=0) {
|
|
||||||
close (sr->fd);
|
|
||||||
sr->fd=-1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int AQH_Serial_IsOpen(AQH_SERIAL *sr)
|
|
||||||
{
|
|
||||||
if (sr->fd<0) {
|
|
||||||
DBG_ERROR(NULL, "Device not open");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
struct termios options;
|
|
||||||
int rv;
|
|
||||||
|
|
||||||
rv=tcgetattr(sr->fd, &options);
|
|
||||||
if (rv<0) {
|
|
||||||
DBG_ERROR(NULL, "Error on tcgetattr(%s): %s (%d)", sr->deviceName, strerror(errno), errno);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int AQH_Serial_Recv(AQH_SERIAL *sr, uint8_t *buf, int len)
|
|
||||||
{
|
|
||||||
#if 0
|
|
||||||
int rv;
|
|
||||||
uint8_t *bufSaved;
|
|
||||||
int bytesReceived=0;
|
|
||||||
int msgLen;
|
|
||||||
|
|
||||||
bufSaved=buf;
|
|
||||||
|
|
||||||
/* destination, msg length */
|
|
||||||
rv=_readForced(sr, buf, 2);
|
|
||||||
if (rv<0) {
|
|
||||||
DBG_ERROR(NULL, "here (%d)", rv);
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
msgLen=buf[1];
|
|
||||||
buf+=2; /* two bytes already read */
|
|
||||||
|
|
||||||
/* read message and XOR byte */
|
|
||||||
rv=_readForced(sr, buf, msgLen+1); /* add one byte for XOR checksum */
|
|
||||||
if (rv<0) {
|
|
||||||
DBG_ERROR(NULL, "here (%d)", rv);
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
buf+=msgLen;
|
|
||||||
|
|
||||||
bytesReceived=msgLen+3;
|
|
||||||
rv=_check(bufSaved, bytesReceived);
|
|
||||||
if (rv<0) {
|
|
||||||
DBG_ERROR(NULL, "here (%d)", rv);
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
return bytesReceived;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int AQH_Serial_Send(AQH_SERIAL *sr, const uint8_t *ptr, uint8_t len)
|
|
||||||
{
|
|
||||||
#if 0
|
|
||||||
int rv;
|
|
||||||
|
|
||||||
rv=_check(ptr, len);
|
|
||||||
if (rv<0) {
|
|
||||||
DBG_ERROR(NULL, "here (%d)", rv);
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
rv=_attnLow(sr);
|
|
||||||
if (rv<0) {
|
|
||||||
DBG_ERROR(NULL, "here (%d)", rv);
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
usleep(50);
|
|
||||||
|
|
||||||
rv=_writeForced(sr, ptr, len);
|
|
||||||
if (rv<0) {
|
|
||||||
DBG_ERROR(NULL, "here (%d)", rv);
|
|
||||||
_attnHigh(sr);
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
_attnHigh(sr);
|
|
||||||
return 0;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int AQH_Serial_SendPacket(AQH_SERIAL *sr, uint8_t destAddr, const uint8_t *ptr, uint8_t len)
|
|
||||||
{
|
|
||||||
int rv;
|
|
||||||
uint8_t x=0;
|
|
||||||
|
|
||||||
rv=_attnLow(sr);
|
|
||||||
if (rv<0) {
|
|
||||||
DBG_ERROR(NULL, "here (%d)", rv);
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
usleep(10);
|
|
||||||
|
|
||||||
/* send dest address */
|
|
||||||
rv=_writeForced(sr, &destAddr, 1);
|
|
||||||
if (rv<0) {
|
|
||||||
DBG_ERROR(NULL, "here (%d)", rv);
|
|
||||||
_attnHigh(sr);
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
x^=destAddr;
|
|
||||||
|
|
||||||
/* send msg len */
|
|
||||||
rv=_writeForced(sr, &len, 1);
|
|
||||||
if (rv<0) {
|
|
||||||
DBG_ERROR(NULL, "here (%d)", rv);
|
|
||||||
_attnHigh(sr);
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
x^=len;
|
|
||||||
|
|
||||||
if (len>0) {
|
|
||||||
uint8_t i;
|
|
||||||
|
|
||||||
/* send message */
|
|
||||||
rv=_writeForced(sr, ptr, len);
|
|
||||||
if (rv<0) {
|
|
||||||
DBG_ERROR(NULL, "here (%d)", rv);
|
|
||||||
_attnHigh(sr);
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i=0; i<len; i++)
|
|
||||||
x^=ptr[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
/* send XOR checksum */
|
|
||||||
rv=_writeForced(sr, &x, 1);
|
|
||||||
if (rv<0) {
|
|
||||||
DBG_ERROR(NULL, "here (%d)", rv);
|
|
||||||
_attnHigh(sr);
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
_attnHigh(sr);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_Serial_SetPacketReceivedFn(AQH_SERIAL *sr, AQH_SERIAL_PACKETRECEIVED_FN fn)
|
|
||||||
{
|
|
||||||
sr->packetReceivedFn=fn;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int _attnLow(AQH_SERIAL *sr)
|
|
||||||
{
|
|
||||||
int status;
|
|
||||||
int rv;
|
|
||||||
|
|
||||||
rv=ioctl(sr->fd, TIOCMGET, &status); /* GET the State of MODEM bits in Status */
|
|
||||||
if (rv<0) {
|
|
||||||
DBG_ERROR(NULL, "Error on ioctl(%s): %s (%d)", sr->deviceName, strerror(errno), errno);
|
|
||||||
return GWEN_ERROR_IO;
|
|
||||||
}
|
|
||||||
status |= TIOCM_DTR | TIOCM_RTS; /* clear the DTR pin (cave: signals inverted!) */
|
|
||||||
rv=ioctl(sr->fd, TIOCMSET, &status);
|
|
||||||
if (rv<0) {
|
|
||||||
DBG_ERROR(NULL, "Error on ioctl(%s): %s (%d)", sr->deviceName, strerror(errno), errno);
|
|
||||||
return GWEN_ERROR_IO;
|
|
||||||
}
|
|
||||||
sr->intendedAttnState=0;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int _attnHigh(AQH_SERIAL *sr)
|
|
||||||
{
|
|
||||||
int status;
|
|
||||||
int rv;
|
|
||||||
|
|
||||||
rv=ioctl(sr->fd, TIOCMGET, &status);
|
|
||||||
if (rv<0) {
|
|
||||||
DBG_ERROR(NULL, "Error on ioctl(%s): %s (%d)", sr->deviceName, strerror(errno), errno);
|
|
||||||
return GWEN_ERROR_IO;
|
|
||||||
}
|
|
||||||
status |= TIOCM_DTR; /* Set the DTR pin */
|
|
||||||
status &= ~ (TIOCM_DTR | TIOCM_RTS); /* clear the DTR pin (cave: signals inverted!) */
|
|
||||||
rv=ioctl(sr->fd, TIOCMSET, &status);
|
|
||||||
if (rv<0) {
|
|
||||||
DBG_ERROR(NULL, "Error on ioctl(%s): %s (%d)", sr->deviceName, strerror(errno), errno);
|
|
||||||
return GWEN_ERROR_IO;
|
|
||||||
}
|
|
||||||
|
|
||||||
sr->intendedAttnState=1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int _isAttnLow(AQH_SERIAL *sr)
|
|
||||||
{
|
|
||||||
int status;
|
|
||||||
int rv;
|
|
||||||
|
|
||||||
rv=ioctl(sr->fd, TIOCMGET, &status);
|
|
||||||
if (rv<0) {
|
|
||||||
DBG_ERROR(NULL, "Error on ioctl(%s): %s (%d)", sr->deviceName, strerror(errno), errno);
|
|
||||||
return GWEN_ERROR_IO;
|
|
||||||
}
|
|
||||||
//return (status & TIOCM_CTS)?1:0;
|
|
||||||
return (status & TIOCM_CTS)?1:0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int _readForced(AQH_SERIAL *sr, uint8_t *buf, int len)
|
|
||||||
{
|
|
||||||
while(len>0) {
|
|
||||||
int rv;
|
|
||||||
|
|
||||||
rv=(int) read(sr->fd, buf, len);
|
|
||||||
if (rv==0) {
|
|
||||||
DBG_ERROR(NULL, "EOF met on read(%s)", sr->deviceName);
|
|
||||||
return GWEN_ERROR_IO;
|
|
||||||
}
|
|
||||||
else if (rv<0) {
|
|
||||||
if (errno!=EINTR) {
|
|
||||||
DBG_ERROR(NULL, "Error on read(%s): %s (%d)", sr->deviceName, strerror(errno), errno);
|
|
||||||
return GWEN_ERROR_IO;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
len-=rv;
|
|
||||||
buf+=rv;
|
|
||||||
}
|
|
||||||
} /* while */
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int _writeForced(AQH_SERIAL *sr, const uint8_t *buf, uint8_t len)
|
|
||||||
{
|
|
||||||
while(len>0) {
|
|
||||||
int rv;
|
|
||||||
|
|
||||||
rv=(int) write(sr->fd, buf, len);
|
|
||||||
if (rv<0) {
|
|
||||||
if (errno!=EINTR) {
|
|
||||||
DBG_ERROR(NULL, "Error on write(%s): %s (%d)", sr->deviceName, strerror(errno), errno);
|
|
||||||
return GWEN_ERROR_IO;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
len-=rv;
|
|
||||||
buf+=rv;
|
|
||||||
}
|
|
||||||
} /* while */
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_Serial_PacketReceived(AQH_SERIAL *sr, AQH_MSG *msg)
|
|
||||||
{
|
|
||||||
if (sr->packetReceivedFn)
|
|
||||||
sr->packetReceivedFn(sr, msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int _readFromFd(AQH_SERIAL *sr)
|
|
||||||
{
|
|
||||||
int rv;
|
|
||||||
uint8_t buffer[AQH_SERIAL_BUFFERSIZE*2];
|
|
||||||
int len;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
do {
|
|
||||||
if (!AQH_Serial_IsOpen(sr)) {
|
|
||||||
DBG_ERROR(NULL, "Disconnected");
|
|
||||||
return GWEN_ERROR_IO;
|
|
||||||
}
|
|
||||||
rv=read(sr->fd, buffer, sizeof(buffer));
|
|
||||||
} while( (rv<0) && errno==EINTR);
|
|
||||||
if (rv<0) {
|
|
||||||
DBG_ERROR(NULL, "Error on read(%s): %s (%d)", sr->deviceName, strerror(errno), errno);
|
|
||||||
return GWEN_ERROR_IO;
|
|
||||||
}
|
|
||||||
len=rv;
|
|
||||||
|
|
||||||
for (i=0; i<len; i++) {
|
|
||||||
if (sr->currentlyReceivedMsg==NULL)
|
|
||||||
sr->currentlyReceivedMsg=AQH_Msg_new();
|
|
||||||
rv=AQH_Msg_AddByte(sr->currentlyReceivedMsg, buffer[i]);
|
|
||||||
if (rv<0) {
|
|
||||||
DBG_ERROR(NULL, "here (%d)", rv);
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
rv=AQH_Msg_IsMsgComplete(sr->currentlyReceivedMsg);
|
|
||||||
if (rv<0) {
|
|
||||||
/* invalid message */
|
|
||||||
DBG_ERROR(NULL, "Invalid message, discarding");
|
|
||||||
AQH_Msg_free(sr->currentlyReceivedMsg);
|
|
||||||
sr->currentlyReceivedMsg=NULL;
|
|
||||||
rv=_discardInput(sr);
|
|
||||||
if (rv<0) {
|
|
||||||
DBG_ERROR(NULL, "here (%d)", rv);
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (rv>0) {
|
|
||||||
if (!AQH_Msg_IsChecksumValid(sr->currentlyReceivedMsg)) {
|
|
||||||
DBG_ERROR(NULL, "Invalid checksum, discarding message");
|
|
||||||
GWEN_Text_DumpString(AQH_Msg_GetBuffer(sr->currentlyReceivedMsg), AQH_Msg_GetBytesInBuffer(sr->currentlyReceivedMsg), 6);
|
|
||||||
AQH_Msg_free(sr->currentlyReceivedMsg);
|
|
||||||
sr->currentlyReceivedMsg=NULL;
|
|
||||||
rv=_discardInput(sr);
|
|
||||||
if (rv<0) {
|
|
||||||
DBG_ERROR(NULL, "here (%d)", rv);
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
/* valid msg received, handle */
|
|
||||||
AQH_Serial_PacketReceived(sr, sr->currentlyReceivedMsg);
|
|
||||||
//AQH_Msg_List_Add(sr->currentlyReceivedMsg, sr->receivedMessageList);
|
|
||||||
sr->currentlyReceivedMsg=NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int _writeToFd(AQH_SERIAL *sr)
|
|
||||||
{
|
|
||||||
AQH_MSG *msg;
|
|
||||||
|
|
||||||
msg=AQH_Msg_List_First(sr->sendMessageList);
|
|
||||||
if (msg) {
|
|
||||||
uint8_t pos;
|
|
||||||
int len;
|
|
||||||
int remaining;
|
|
||||||
int rv;
|
|
||||||
|
|
||||||
if (_isAttnLow(sr)) {
|
|
||||||
DBG_ERROR(NULL, "ATTN is low, not sending");
|
|
||||||
usleep(100);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
pos=AQH_Msg_GetCurrentPos(msg);
|
|
||||||
remaining=AQH_Msg_GetRemainingBytes(msg);
|
|
||||||
if (remaining>0) {
|
|
||||||
const uint8_t *buf;
|
|
||||||
|
|
||||||
if (sr->intendedAttnState==1) {
|
|
||||||
rv=_attnLow(sr);
|
|
||||||
if (rv<0) {
|
|
||||||
DBG_ERROR(NULL, "here (%d)", rv);
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
usleep(AQH_SERIAL_BYTE_MICROSECS/5);
|
|
||||||
}
|
|
||||||
|
|
||||||
buf=AQH_Msg_GetBuffer(msg)+pos;
|
|
||||||
do {
|
|
||||||
if (!AQH_Serial_IsOpen(sr)) {
|
|
||||||
DBG_ERROR(NULL, "Disconnected");
|
|
||||||
return GWEN_ERROR_IO;
|
|
||||||
}
|
|
||||||
rv=write(sr->fd, buf, remaining);
|
|
||||||
} while(rv<0 && errno==EINTR);
|
|
||||||
if (rv<0) {
|
|
||||||
DBG_ERROR(NULL, "Error on write(%s): %s (%d)", sr->deviceName, strerror(errno), errno);
|
|
||||||
return GWEN_ERROR_IO;
|
|
||||||
}
|
|
||||||
AQH_Msg_IncCurrentPos(msg, rv);
|
|
||||||
if (rv==remaining) {
|
|
||||||
rv=_attnHigh(sr);
|
|
||||||
// TODO: callback msg sent
|
|
||||||
AQH_Msg_List_Del(msg);
|
|
||||||
AQH_Msg_free(msg);
|
|
||||||
if (rv<0) {
|
|
||||||
DBG_ERROR(NULL, "here (%d)", rv);
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int _discardInput(AQH_SERIAL *sr)
|
|
||||||
{
|
|
||||||
int rv;
|
|
||||||
uint8_t buffer[AQH_SERIAL_BUFFERSIZE];
|
|
||||||
|
|
||||||
do {
|
|
||||||
if (!AQH_Serial_IsOpen(sr)) {
|
|
||||||
DBG_ERROR(NULL, "Disconnected");
|
|
||||||
return GWEN_ERROR_IO;
|
|
||||||
}
|
|
||||||
rv=read(sr->fd, buffer, sizeof(buffer));
|
|
||||||
} while( (rv>0 || (rv<0) && errno==EINTR));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int AQH_Serial_AddMessageToSend(AQH_SERIAL *sr, AQH_MSG *msg)
|
|
||||||
{
|
|
||||||
int rv;
|
|
||||||
|
|
||||||
rv=AQH_Msg_IsMsgComplete(msg);
|
|
||||||
if (rv!=1) {
|
|
||||||
DBG_ERROR(NULL, "Message not complete");
|
|
||||||
return GWEN_ERROR_BAD_DATA;
|
|
||||||
}
|
|
||||||
if (!AQH_Msg_IsChecksumValid(msg)) {
|
|
||||||
DBG_ERROR(NULL, "Checksum is invalid");
|
|
||||||
return GWEN_ERROR_BAD_DATA;
|
|
||||||
}
|
|
||||||
AQH_Msg_RewindCurrentPos(msg);
|
|
||||||
AQH_Msg_List_Add(msg, sr->sendMessageList);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int AQH_Serial_Loop(AQH_SERIAL *sr)
|
|
||||||
{
|
|
||||||
fd_set readSet;
|
|
||||||
fd_set writeSet;
|
|
||||||
int somethingToWrite;
|
|
||||||
struct timeval tv;
|
|
||||||
int rv;
|
|
||||||
|
|
||||||
tv.tv_sec=2;
|
|
||||||
tv.tv_usec=0;
|
|
||||||
|
|
||||||
somethingToWrite=(AQH_Msg_List_First(sr->sendMessageList)!=NULL)?1:0;
|
|
||||||
if (somethingToWrite) {
|
|
||||||
FD_ZERO(&writeSet);
|
|
||||||
FD_SET(sr->fd, &writeSet);
|
|
||||||
}
|
|
||||||
FD_ZERO(&readSet);
|
|
||||||
FD_SET(sr->fd, &readSet);
|
|
||||||
|
|
||||||
rv=select(sr->fd+1, &readSet, somethingToWrite?(&writeSet):NULL, NULL, &tv);
|
|
||||||
if (rv<0) {
|
|
||||||
if (errno!=EINTR) {
|
|
||||||
DBG_ERROR(NULL, "Error on select");
|
|
||||||
return GWEN_ERROR_IO;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (rv) {
|
|
||||||
if (FD_ISSET(sr->fd, &readSet)) {
|
|
||||||
rv=_readFromFd(sr);
|
|
||||||
if (rv<0) {
|
|
||||||
DBG_ERROR(NULL, "here (%d)", rv);
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (somethingToWrite && FD_ISSET(sr->fd, &writeSet)) {
|
|
||||||
rv=_writeToFd(sr);
|
|
||||||
if (rv<0) {
|
|
||||||
DBG_ERROR(NULL, "here (%d)", rv);
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (rv==0) {
|
|
||||||
/* timeout */
|
|
||||||
if (sr->currentlyReceivedMsg) {
|
|
||||||
AQH_Msg_free(sr->currentlyReceivedMsg);
|
|
||||||
sr->currentlyReceivedMsg=NULL;
|
|
||||||
rv=_discardInput(sr);
|
|
||||||
if (rv<0) {
|
|
||||||
DBG_ERROR(NULL, "here (%d)", rv);
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int AQH_Serial_ReadOnlyLoop(AQH_SERIAL *sr)
|
|
||||||
{
|
|
||||||
fd_set readSet;
|
|
||||||
struct timeval tv;
|
|
||||||
int rv;
|
|
||||||
|
|
||||||
tv.tv_sec=2;
|
|
||||||
tv.tv_usec=0;
|
|
||||||
|
|
||||||
FD_ZERO(&readSet);
|
|
||||||
FD_SET(sr->fd, &readSet);
|
|
||||||
|
|
||||||
rv=select(sr->fd+1, &readSet, NULL, NULL, &tv);
|
|
||||||
if (rv<0) {
|
|
||||||
if (errno!=EINTR) {
|
|
||||||
DBG_ERROR(NULL, "Error on select");
|
|
||||||
return GWEN_ERROR_IO;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (rv) {
|
|
||||||
if (FD_ISSET(sr->fd, &readSet)) {
|
|
||||||
rv=_readFromFd(sr);
|
|
||||||
if (rv<0) {
|
|
||||||
DBG_ERROR(NULL, "here (%d)", rv);
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (rv==0) {
|
|
||||||
/* timeout */
|
|
||||||
if (sr->currentlyReceivedMsg) {
|
|
||||||
AQH_Msg_free(sr->currentlyReceivedMsg);
|
|
||||||
sr->currentlyReceivedMsg=NULL;
|
|
||||||
rv=_discardInput(sr);
|
|
||||||
if (rv<0) {
|
|
||||||
DBG_ERROR(NULL, "here (%d)", rv);
|
|
||||||
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_SERIAL_H
|
|
||||||
#define AQH_SERIAL_H
|
|
||||||
|
|
||||||
#include <aqhome/api.h>
|
|
||||||
#include "aqhome/msg.h"
|
|
||||||
|
|
||||||
#include <gwenhywfar/buffer.h>
|
|
||||||
|
|
||||||
#include <inttypes.h>
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct AQH_SERIAL AQH_SERIAL;
|
|
||||||
|
|
||||||
|
|
||||||
typedef void (*AQH_SERIAL_PACKETRECEIVED_FN)(AQH_SERIAL *sr, AQH_MSG *msg);
|
|
||||||
|
|
||||||
|
|
||||||
enum {
|
|
||||||
AQH_SerialReadWriteMode_ReadOnly=1,
|
|
||||||
AQH_SerialReadWriteMode_WriteOnly=2,
|
|
||||||
AQH_SerialReadWriteMode_ReadWrite=3
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
AQHOME_API AQH_SERIAL *AQH_Serial_new(const char *deviceName, uint8_t addr);
|
|
||||||
AQHOME_API void AQH_Serial_free(AQH_SERIAL *sr);
|
|
||||||
|
|
||||||
AQHOME_API uint8_t AQH_Serial_GetAddress(const AQH_SERIAL *sr);
|
|
||||||
|
|
||||||
|
|
||||||
AQHOME_API int AQH_Serial_Open(AQH_SERIAL *sr, int rwMode);
|
|
||||||
AQHOME_API void AQH_Serial_Close(AQH_SERIAL *sr);
|
|
||||||
|
|
||||||
AQHOME_API int AQH_Serial_Recv(AQH_SERIAL *sr, uint8_t *buf, int len);
|
|
||||||
AQHOME_API int AQH_Serial_Send(AQH_SERIAL *sr, const uint8_t *ptr, uint8_t len);
|
|
||||||
|
|
||||||
AQHOME_API int AQH_Serial_SendPacket(AQH_SERIAL *sr, uint8_t destAddr, const uint8_t *ptr, uint8_t len);
|
|
||||||
|
|
||||||
|
|
||||||
AQHOME_API int AQH_Serial_Loop(AQH_SERIAL *sr);
|
|
||||||
AQHOME_API int AQH_Serial_ReadOnlyLoop(AQH_SERIAL *sr);
|
|
||||||
AQHOME_API int AQH_Serial_AddMessageToSend(AQH_SERIAL *sr, AQH_MSG *msg);
|
|
||||||
|
|
||||||
AQHOME_API int AQH_Serial_StartWriting(AQH_SERIAL *sr, const uint8_t *ptr, uint8_t len);
|
|
||||||
|
|
||||||
|
|
||||||
AQHOME_API void AQH_Serial_SetPacketReceivedFn(AQH_SERIAL *sr, AQH_SERIAL_PACKETRECEIVED_FN fn);
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
@@ -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_SERIAL_P_H
|
|
||||||
#define AQH_SERIAL_P_H
|
|
||||||
|
|
||||||
#include "aqhome/serial.h"
|
|
||||||
|
|
||||||
#include <termios.h>
|
|
||||||
#include <inttypes.h>
|
|
||||||
|
|
||||||
|
|
||||||
#define AQH_SERIAL_BUFFERSIZE 32
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct AQH_SERIAL {
|
|
||||||
char *deviceName;
|
|
||||||
int fd;
|
|
||||||
uint8_t address;
|
|
||||||
int intendedAttnState;
|
|
||||||
|
|
||||||
AQH_MSG *currentlyReceivedMsg;
|
|
||||||
|
|
||||||
AQH_MSG_LIST *receivedMessageList;
|
|
||||||
AQH_MSG_LIST *sendMessageList;
|
|
||||||
|
|
||||||
struct termios previousOptions;
|
|
||||||
|
|
||||||
AQH_SERIAL_PACKETRECEIVED_FN packetReceivedFn;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user