aqhome: removed uneeded files.

This commit is contained in:
Martin Preuss
2023-03-18 01:58:57 +01:00
parent 12d197dae2
commit c26119d34c
36 changed files with 0 additions and 4061 deletions

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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));
}
}

View File

@@ -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

View File

@@ -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));
}
}

View File

@@ -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

View File

@@ -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));
}
}

View File

@@ -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

View File

@@ -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));
}
}

View File

@@ -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

View File

@@ -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

View File

@@ -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));
}
}

View File

@@ -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

View File

@@ -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));
}
}

View File

@@ -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

View File

@@ -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));
}
}

View File

@@ -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

View File

@@ -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));
}
}

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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

View File

@@ -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);
}
}
}

View File

@@ -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

View File

@@ -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

View File

@@ -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;
}
}

View File

@@ -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

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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