mirror of
https://github.com/eclipse/paho.mqtt-sn.embedded-c.git
synced 2025-12-15 16:36:52 +01:00
Merge pull request #143 from eclipse/develop
Add functions of Aggregating Gateway, QoS-1 and forwarder encapsulation.
This commit is contained in:
@@ -1,4 +1,7 @@
|
||||
**MQTT-SN** requires a MQTT-SN Gateway which acts as a protocol converter to convert **MQTT-SN messages to MQTT messages**. MQTT-SN client (UDP) can not communicate directly with MQTT broker(TCP/IP).
|
||||
# MQTT-SN Transparent / Aggrigating Gateway
|
||||
|
||||
**MQTT-SN** requires a MQTT-SN Gateway which acts as a protocol converter to convert **MQTT-SN messages to MQTT messages**. MQTT-SN client over SensorNetwork can not communicate directly with MQTT broker(TCP/IP).
|
||||
This Gateway can run as a transparent or aggrigating Gateway by specifying the gateway.conf.
|
||||
|
||||
### **step1. Build the gateway**
|
||||
````
|
||||
@@ -36,12 +39,12 @@ BrokerPortNo=1883
|
||||
BrokerSecurePortNo=8883
|
||||
|
||||
#
|
||||
# When AggregateGateway=YES or ClientAuthentication=YES,
|
||||
# When AggregatingGateway=YES or ClientAuthentication=YES,
|
||||
# All clients must be specified by the ClientList File
|
||||
#
|
||||
|
||||
ClientAuthentication=NO
|
||||
AggregateGateway=NO
|
||||
AggregatingGateway=NO
|
||||
QoS-1=NO
|
||||
Forwarder=NO
|
||||
|
||||
@@ -82,7 +85,7 @@ ShearedMemory=NO;
|
||||
Client should know the MulticastIP and MulticastPortNo to send a SEARCHGW message.
|
||||
**GatewayId** is used by GWINFO message.
|
||||
**KeepAlive** is a duration of ADVERTISE message in seconds.
|
||||
when **AggregateGateway** or **ClientAuthentication** is **YES**, All clients which connect to the gateway must be declared by a **ClientsList** file.
|
||||
when **AggregatingGateway** or **ClientAuthentication** is **YES**, All clients which connect to the gateway must be declared by a **ClientsList** file.
|
||||
Format of the file is ClientId and SensorNetwork Address. e.g. IP address and Port No etc, in CSV. more detail see clients.conf.
|
||||
When **QoS-1** is **YES**, QoS-1 PUBLISH is available. All clients which send QoS-1 PUBLISH must be specified by Client.conf file.
|
||||
When **PredefinedTopic** is **YES**, **Pre-definedTopicId**s specified by **PredefinedTopicList** are effective. This file defines Pre-definedTopics of the clients. In this file, ClientID,TopicName and TopicID are declared in CSV format.
|
||||
|
||||
@@ -19,12 +19,12 @@ BrokerPortNo=1883
|
||||
BrokerSecurePortNo=8883
|
||||
|
||||
#
|
||||
# When AggregateGateway=YES or ClientAuthentication=YES,
|
||||
# When AggregatingGateway=YES or ClientAuthentication=YES,
|
||||
# All clients must be specified by the ClientList File
|
||||
#
|
||||
|
||||
ClientAuthentication=NO
|
||||
AggregateGateway=NO
|
||||
AggregatingGateway=NO
|
||||
QoS-1=NO
|
||||
Forwarder=NO
|
||||
|
||||
|
||||
@@ -16,14 +16,13 @@
|
||||
#
|
||||
# ClientID, TopicName, TopicID
|
||||
#
|
||||
# This file is consist from two sections.
|
||||
# One for QoS-1 PUBLISH Clients, the other for another clients.
|
||||
# Topics is common to all clients, ClientID should be *.
|
||||
|
||||
#
|
||||
# pre-defined-topics for Clients
|
||||
#
|
||||
|
||||
GatewayTestClient,ty4tw/predefinedTopic1, 1
|
||||
*,ty4tw/predefinedTopic1, 1
|
||||
GatewayTestClient,ty4tw/predefinedTopic2, 2
|
||||
GatewayTestClient,ty4tw/predefinedTopic3, 3
|
||||
|
||||
@@ -31,16 +30,7 @@ GatewayTestClient,ty4tw/predefinedTopic3, 3
|
||||
# pre-defined-topics for QoS-1 clients.
|
||||
#
|
||||
|
||||
QoS-1_Client01,ty4tw/proxy/predefTopic1, 1
|
||||
QoS-1_Client01,ty4tw/proxy/predefTopic2, 2
|
||||
QoS-1_Client01,ty4tw/proxy/predefTopic3, 3
|
||||
|
||||
QoS-1_Client02,ty4tw/proxy/predefTopic1, 1
|
||||
QoS-1_Client02,ty4tw/proxy/predefTopic3, 2
|
||||
QoS-1_Client02,ty4tw/proxy/predefTopic3, 3
|
||||
|
||||
QoS-1_Client03,ty4tw/proxy/predefTopic1, 1
|
||||
QoS-1_Client03,ty4tw/proxy/predefTopic2, 2
|
||||
QoS-1_Client03,ty4tw/proxy/predefTopic3, 3
|
||||
|
||||
|
||||
QoS-1_Client03,ty4tw/proxy/predefTopic4, 1
|
||||
QoS-1_Client03,ty4tw/proxy/predefTopic5, 2
|
||||
QoS-1_Client03,ty4tw/proxy/predefTopic6, 3
|
||||
|
||||
@@ -90,10 +90,10 @@ void MQTTGWConnectionHandler::handlePingresp(Client* client, MQTTGWPacket* packe
|
||||
|
||||
void MQTTGWConnectionHandler::handleDisconnect(Client* client, MQTTGWPacket* packet)
|
||||
{
|
||||
MQTTSNPacket* snPacket = new MQTTSNPacket();
|
||||
snPacket->setDISCONNECT(0);
|
||||
client->disconnected();
|
||||
client->getNetwork()->close();
|
||||
Event* ev1 = new Event();
|
||||
ev1->setClientSendEvent(client, snPacket);
|
||||
MQTTSNPacket* snPacket = new MQTTSNPacket();
|
||||
snPacket->setDISCONNECT(0);
|
||||
client->disconnected();
|
||||
client->getNetwork()->close();
|
||||
Event* ev1 = new Event();
|
||||
ev1->setClientSendEvent(client, snPacket);
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ void Aggregater::initialize(void)
|
||||
{
|
||||
char param[MQTTSNGW_PARAM_MAX];
|
||||
|
||||
if (_gateway->getParam("AggregateGateway", param) == 0 )
|
||||
if (_gateway->getParam("AggregatingGateway", param) == 0 )
|
||||
{
|
||||
if (!strcasecmp(param, "YES") )
|
||||
{
|
||||
|
||||
@@ -24,6 +24,8 @@ extern Gateway* theGateway;
|
||||
/*=====================================
|
||||
Class ClientList
|
||||
=====================================*/
|
||||
const char* common_topic = "*";
|
||||
|
||||
ClientList::ClientList()
|
||||
{
|
||||
_clientCnt = 0;
|
||||
@@ -414,50 +416,58 @@ Client* ClientList::createClient(SensorNetAddress* addr, MQTTSNString* clientId,
|
||||
|
||||
Client* ClientList::createPredefinedTopic( MQTTSNString* clientId, string topicName, uint16_t topicId, bool aggregate)
|
||||
{
|
||||
Client* client = getClient(clientId);
|
||||
if ( clientId->cstring == common_topic )
|
||||
{
|
||||
_gateway->getTopics()->add((const char*)topicName.c_str(), topicId);
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
Client* client = getClient(clientId);
|
||||
|
||||
if ( _authorize && client == nullptr)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if ( _authorize && client == nullptr )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* anonimous clients */
|
||||
if ( _clientCnt > MAX_CLIENTS )
|
||||
{
|
||||
return nullptr; // full of clients
|
||||
}
|
||||
/* anonimous clients */
|
||||
if ( _clientCnt > MAX_CLIENTS )
|
||||
{
|
||||
return nullptr; // full of clients
|
||||
}
|
||||
|
||||
if ( client == nullptr )
|
||||
{
|
||||
/* creat a new client */
|
||||
client = new Client();
|
||||
client->setClientId(*clientId);
|
||||
if ( aggregate )
|
||||
{
|
||||
client->setAggregated();
|
||||
}
|
||||
_mutex.lock();
|
||||
if ( client == nullptr )
|
||||
{
|
||||
/* creat a new client */
|
||||
client = new Client();
|
||||
client->setClientId(*clientId);
|
||||
if ( aggregate )
|
||||
{
|
||||
client->setAggregated();
|
||||
}
|
||||
_mutex.lock();
|
||||
|
||||
/* add the list */
|
||||
if ( _firstClient == nullptr )
|
||||
{
|
||||
_firstClient = client;
|
||||
_endClient = client;
|
||||
}
|
||||
else
|
||||
{
|
||||
_endClient->_nextClient = client;
|
||||
client->_prevClient = _endClient;
|
||||
_endClient = client;
|
||||
}
|
||||
_clientCnt++;
|
||||
_mutex.unlock();
|
||||
}
|
||||
/* add the list */
|
||||
if ( _firstClient == nullptr )
|
||||
{
|
||||
_firstClient = client;
|
||||
_endClient = client;
|
||||
}
|
||||
else
|
||||
{
|
||||
_endClient->_nextClient = client;
|
||||
client->_prevClient = _endClient;
|
||||
_endClient = client;
|
||||
}
|
||||
_clientCnt++;
|
||||
_mutex.unlock();
|
||||
}
|
||||
|
||||
// create Topic & Add it
|
||||
client->getTopics()->add((const char*)topicName.c_str(), topicId);
|
||||
client->_hasPredefTopic = true;
|
||||
return client;
|
||||
// create Topic & Add it
|
||||
client->getTopics()->add((const char*)topicName.c_str(), topicId);
|
||||
client->_hasPredefTopic = true;
|
||||
return client;
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t ClientList::getClientCount()
|
||||
|
||||
@@ -262,7 +262,7 @@ void ClientRecvTask::log(Client* client, MQTTSNPacket* packet, MQTTSNString* id)
|
||||
|
||||
void ClientRecvTask::log(const char* clientId, MQTTSNPacket* packet)
|
||||
{
|
||||
char pbuf[SIZE_OF_LOG_PACKET * 3];
|
||||
char pbuf[ SIZE_OF_LOG_PACKET * 3 + 1];
|
||||
char msgId[6];
|
||||
|
||||
switch (packet->getType())
|
||||
|
||||
@@ -84,7 +84,7 @@ void ClientSendTask::run()
|
||||
|
||||
void ClientSendTask::log(Client* client, MQTTSNPacket* packet)
|
||||
{
|
||||
char pbuf[SIZE_OF_LOG_PACKET * 3];
|
||||
char pbuf[SIZE_OF_LOG_PACKET * 3 + 1];
|
||||
char msgId[6];
|
||||
const char* clientId = client ? (const char*)client->getClientId() : UNKNOWNCL ;
|
||||
|
||||
|
||||
@@ -423,12 +423,9 @@ char* MQTTSNPacket::print(char* pbuf)
|
||||
{
|
||||
char* ptr = pbuf;
|
||||
char** pptr = &pbuf;
|
||||
int value = 0;
|
||||
|
||||
int i = MQTTSNPacket_decode(_buf, _bufLen, &value);
|
||||
int size = _bufLen > SIZE_OF_LOG_PACKET ? SIZE_OF_LOG_PACKET : _bufLen;
|
||||
|
||||
for (; i < size; i++)
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
sprintf(*pptr, " %02X", *(_buf + i));
|
||||
*pptr += 3;
|
||||
|
||||
@@ -79,10 +79,18 @@ MQTTGWPacket* MQTTSNPublishHandler::handlePublish(Client* client, MQTTSNPacket*
|
||||
else
|
||||
{
|
||||
topic = client->getTopics()->getTopicById(&topicid);
|
||||
if ( !topic )
|
||||
{
|
||||
topic = _gateway->getTopics()->getTopicById(&topicid);
|
||||
if ( topic )
|
||||
{
|
||||
topic = client->getTopics()->add(topic->getTopicName()->c_str(), topic->getTopicId());
|
||||
}
|
||||
}
|
||||
|
||||
if( !topic && qos == 3 )
|
||||
{
|
||||
WRITELOG("%s Invali TopicId.%s %s\n", ERRMSG_HEADER, client->getClientId(), ERRMSG_FOOTER);
|
||||
WRITELOG("%s Invalid TopicId.%s %s\n", ERRMSG_HEADER, client->getClientId(), ERRMSG_FOOTER);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
@@ -59,6 +59,8 @@ MQTTGWPacket* MQTTSNSubscribeHandler::handleSubscribe(Client* client, MQTTSNPack
|
||||
if ( topicFilter.type == MQTTSN_TOPIC_TYPE_PREDEFINED )
|
||||
{
|
||||
topic = client->getTopics()->getTopicById(&topicFilter);
|
||||
|
||||
|
||||
if ( topic )
|
||||
{
|
||||
topicId = topic->getTopicId();
|
||||
@@ -67,7 +69,15 @@ MQTTGWPacket* MQTTSNSubscribeHandler::handleSubscribe(Client* client, MQTTSNPack
|
||||
}
|
||||
else
|
||||
{
|
||||
goto RespExit;
|
||||
topic = _gateway->getTopics()->getTopicById(&topicFilter);
|
||||
if ( !topic )
|
||||
{
|
||||
topic = client->getTopics()->add(topic->getTopicName()->c_str(), topic->getTopicId());
|
||||
}
|
||||
else
|
||||
{
|
||||
goto RespExit;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (topicFilter.type == MQTTSN_TOPIC_TYPE_NORMAL)
|
||||
|
||||
@@ -17,6 +17,6 @@
|
||||
#ifndef MQTTSNGWVERSION_H_IN_
|
||||
#define MQTTSNGWVERSION_H_IN_
|
||||
|
||||
#define PAHO_GATEWAY_VERSION "1.3.0"
|
||||
#define PAHO_GATEWAY_VERSION "1.3.1"
|
||||
|
||||
#endif /* MQTTSNGWVERSION_H_IN_ */
|
||||
|
||||
@@ -37,6 +37,7 @@ Gateway::Gateway(void)
|
||||
_packetEventQue.setMaxSize(MAX_INFLIGHTMESSAGES * MAX_CLIENTS);
|
||||
_clientList = new ClientList();
|
||||
_adapterManager = new AdapterManager(this);
|
||||
_topics = new Topics();
|
||||
}
|
||||
|
||||
Gateway::~Gateway()
|
||||
@@ -103,6 +104,11 @@ Gateway::~Gateway()
|
||||
{
|
||||
delete _clientList;
|
||||
}
|
||||
|
||||
if ( _topics )
|
||||
{
|
||||
delete _topics;
|
||||
}
|
||||
}
|
||||
|
||||
int Gateway::getParam(const char* parameter, char* value)
|
||||
@@ -312,6 +318,11 @@ AdapterManager* Gateway::getAdapterManager(void)
|
||||
return _adapterManager;
|
||||
}
|
||||
|
||||
Topics* Gateway::getTopics(void)
|
||||
{
|
||||
return _topics;
|
||||
}
|
||||
|
||||
bool Gateway::hasSecureConnection(void)
|
||||
{
|
||||
return ( _params.certKey
|
||||
|
||||
@@ -191,6 +191,7 @@ public:
|
||||
AdapterManager* getAdapterManager(void);
|
||||
int getParam(const char* parameter, char* value);
|
||||
bool hasSecureConnection(void);
|
||||
Topics* getTopics(void);
|
||||
|
||||
private:
|
||||
GatewayParams _params;
|
||||
@@ -201,6 +202,7 @@ private:
|
||||
LightIndicator _lightIndicator;
|
||||
SensorNetwork _sensorNetwork;
|
||||
AdapterManager* _adapterManager {nullptr};
|
||||
Topics* _topics;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user