Add Bluetooth classic as a sensor network #69, #195, #90

I think the architecture of the ble sensor network, which does not use
threads per socket, can be applied to DTLS.

Known bug:
Occasionally a timeout error occurs when connecting to RFCOMM.
BLE is not supported yet. I need help to do it.


Signed-off-by: tomoaki <tomoaki@tomy-tech.com>
This commit is contained in:
tomoaki
2021-06-02 20:15:52 +09:00
parent 982e6d4884
commit 55128f0f0e
54 changed files with 1764 additions and 934 deletions

View File

@@ -97,11 +97,13 @@
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.cpp.link.option.libs.1848275182" name="Libraries (-l)" superClass="gnu.cpp.link.option.libs" useByScannerDiscovery="false" valueType="libs"> <option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.cpp.link.option.libs.1848275182" name="Libraries (-l)" superClass="gnu.cpp.link.option.libs" useByScannerDiscovery="false" valueType="libs">
<listOptionValue builtIn="false" srcPrefixMapping="" srcRootPath="" value="pthread"/> <listOptionValue builtIn="false" value="pthread"/>
<listOptionValue builtIn="false" srcPrefixMapping="" srcRootPath="" value="ssl"/> <listOptionValue builtIn="false" value="ssl"/>
<listOptionValue builtIn="false" srcPrefixMapping="" srcRootPath="" value="crypto"/> <listOptionValue builtIn="false" value="crypto"/>
<listOptionValue builtIn="false" value="bluetooth"/>
</option> </option>
@@ -133,7 +135,11 @@
<sourceEntries> <sourceEntries>
<entry excluding="MQTTSNGateway/GatewayTester|MQTTSNGateway/GatewayTester/samples/ClientPubQoS-1|MQTTSNGateway/GatewayTester/samples/ClientSub|MQTTSNGateway/GatewayTester/samples/ClientPub|MQTTSNGateway/src/linux/udp6|MQTTSNGateway/src/linux/loralink|MQTTSNClient|MQTTSNGateway/src/MQTTSNGWProxy.cpp|MQTTSNPacket/test|MQTTSNPacket/samples|MQTTSNGateway/src/mainLogmonitor.cpp|MQTTSNGateway/src/linux/xbee|MQTTSNGateway/GatewayTester/samples/mainTemplate.cpp|MQTTSNGateway/src/tests|MQTTSNGateway/src/tests/mainTestProcessFramework.cpp|ClientPubQoS-1|MQTTSNGateway/GatewayTester/samples/mainOTA.cpp" flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name=""/> <entry excluding="src/linux/ble|src/mainLogmonitor.cpp|src/linux/xbee|src/linux/udp6|src/linux/loralink|src/tests|GatewayTester|GatewayTester/samples|GatewayTester/src" flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name="MQTTSNGateway"/>
<entry excluding="samples|src" flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name="MQTTSNGateway/GatewayTester"/>
<entry excluding="samples|test" flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name="MQTTSNPacket"/>
</sourceEntries> </sourceEntries>
@@ -273,9 +279,9 @@
<sourceEntries> <sourceEntries>
<entry excluding="MQTTSNGateway/GatewayTester|MQTTSNGateway/GatewayTester/samples/ClientPubQoS-1|MQTTSNGateway/GatewayTester/samples/ClientSub|MQTTSNGateway/GatewayTester/samples/ClientPub|MQTTSNGateway/src/tests/mainTestProcess.cpp|MQTTSNGateway/src/linux|MQTTSNPacket/src|MQTTSNClient|MQTTSNPacket/test|MQTTSNPacket/samples|MQTTSNGateway/GatewayTester/samples/mainOTA.cpp|MQTTSNGateway/src/mainLogmonitor.cpp|MQTTSNGateway/GatewayTester/samples/mainTemplate.cpp|ClientPubQoS-1" flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name=""/> <entry excluding="MQTTSNGateway|MQTTSNGateway/GatewayTester|MQTTSNGateway/src|MQTTSNGateway/GatewayTester/samples/ClientPubQoS-1|MQTTSNGateway/GatewayTester/samples/ClientSub|MQTTSNGateway/GatewayTester/samples/ClientPub|MQTTSNGateway/src/tests/mainTestProcess.cpp|MQTTSNGateway/src/linux|MQTTSNPacket/src|MQTTSNClient|MQTTSNPacket/test|MQTTSNPacket/samples|MQTTSNGateway/GatewayTester/samples/mainOTA.cpp|MQTTSNGateway/src/mainLogmonitor.cpp|MQTTSNGateway/GatewayTester/samples/mainTemplate.cpp|ClientPubQoS-1" flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name=""/>
<entry excluding="udp6|xbee|loralink" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="MQTTSNGateway/src/linux"/> <entry excluding="linux/ble" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="MQTTSNGateway/src"/>
<entry flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name="MQTTSNPacket/src"/> <entry flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name="MQTTSNPacket/src"/>

View File

@@ -11,7 +11,7 @@
<provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/> <provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
<provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector" console="false" env-hash="-152861151764916298" id="org.eclipse.cdt.managedbuilder.core.GCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true"> <provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector" console="false" env-hash="-152611677936340298" id="org.eclipse.cdt.managedbuilder.core.GCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
<language-scope id="org.eclipse.cdt.core.gcc"/> <language-scope id="org.eclipse.cdt.core.gcc"/>
@@ -33,7 +33,7 @@
<provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/> <provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
<provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector" console="false" env-hash="-152861151764916298" id="org.eclipse.cdt.managedbuilder.core.GCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true"> <provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector" console="false" env-hash="-152611677936340298" id="org.eclipse.cdt.managedbuilder.core.GCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
<language-scope id="org.eclipse.cdt.core.gcc"/> <language-scope id="org.eclipse.cdt.core.gcc"/>

View File

@@ -20,6 +20,7 @@ CPPSRCS := \
$(SUBDIR)/LGwProxy.cpp \ $(SUBDIR)/LGwProxy.cpp \
$(SUBDIR)/LMqttsnClient.cpp \ $(SUBDIR)/LMqttsnClient.cpp \
$(SUBDIR)/LNetworkUdp.cpp \ $(SUBDIR)/LNetworkUdp.cpp \
$(SUBDIR)/LNetworkBle.cpp \
$(SUBDIR)/LPublishManager.cpp \ $(SUBDIR)/LPublishManager.cpp \
$(SUBDIR)/LRegisterManager.cpp \ $(SUBDIR)/LRegisterManager.cpp \
$(SUBDIR)/LSubscribeManager.cpp \ $(SUBDIR)/LSubscribeManager.cpp \
@@ -41,7 +42,7 @@ DEFS :=
LIBS += LIBS +=
LDFLAGS := LDFLAGS :=
CXXFLAGS := -Wall -O3 -std=c++11 CXXFLAGS := -Wall -O3 -std=c++11
LDADD := LDADD := -lbluetooth
OUTDIR := Build OUTDIR := Build
PROG := $(OUTDIR)/$(PROGTEST) PROG := $(OUTDIR)/$(PROGTEST)

View File

@@ -1,7 +1,7 @@
###Gateway Test Program. # Gateway Test Program.
**sample/mainTest.cpp** is a Test sample coading. **sample/mainTest.cpp** is a Test sample coading.
Each test is described as one function. test1(), test2()... Each test is described as one function. test1(), test2()...
```` ```
/*------------------------------------------------------ /*------------------------------------------------------
* Test functions * Test functions
* *
@@ -25,37 +25,51 @@ Each test is described as one function. test1(), test2()...
void test1(void) void test1(void)
{ {
char payload[300]; char payload[300];
sprintf(payload, "ESP8266-08b133 "); sprintf(payload, "ESP8266-08b133 ");
uint8_t qos = 0; uint8_t qos = 0;
PUBLISH(topic1,(uint8_t*)payload, strlen(payload), qos); PUBLISH(topic1,(uint8_t*)payload, strlen(payload), qos);
} }
void test2(void) void test2(void)
{ {
uint8_t qos = 1; uint8_t qos = 1;
SUBSCRIBE(topic2, on_publish02, qos); SUBSCRIBE(topic2, on_publish02, qos);
} }
```` ```
**TEST_LIST** is a test senario. Test functions are executed one by one. **TEST_LIST** is a test senario. Test functions are executed one by one.
```` ```
/*------------------------------------------------------ /*------------------------------------------------------
* A List of Test Tasks * A List of Test Tasks
*------------------------------------------------------*/ *------------------------------------------------------*/
TEST_LIST = {// e.g. TEST( Label, Test), TEST_LIST = {// e.g. TEST( Label, Test),
TEST("Publish topic1", test1), TEST("Publish topic1", test1),
TEST("Subscribe topic2", test2), TEST("Subscribe topic2", test2),
TEST("Publish topic2", test3), TEST("Publish topic2", test3),
TEST("Unsubscribe topic2", test4), TEST("Unsubscribe topic2", test4),
TEST("Publish topic2", test3), TEST("Publish topic2", test3),
TEST("Disconnect", test5), TEST("Disconnect", test5),
END_OF_TEST_LIST END_OF_TEST_LIST
}; };
````
```
## step1. Define a sensor network
### **step1. Build ** **UDP** or **Bluetooth** is available as a sensor network.
```` Uncomment a line \#define UDP or BLE in LMqttsnClientApp.h file.
```
/*======================================
* Program mode Flag
======================================*/
//#define CLIENT_MODE
#define UDP
//#define BLE
```
## step2. Build
```
$ git clone https://github.com/eclipse/paho.mqtt-sn.embedded-c $ git clone https://github.com/eclipse/paho.mqtt-sn.embedded-c
$ cd paho.mqtt-sn.embedded-c/MQTTSNGateway/GatewayTester $ cd paho.mqtt-sn.embedded-c/MQTTSNGateway/GatewayTester
$ make $ make
@@ -65,9 +79,9 @@ $ make clean
MQTT-SNGatewayTester program is copied into ../../../ directory. MQTT-SNGatewayTester program is copied into ../../../ directory.
### **step2. Execute Gateway Tester.** ## **step3. Execute Gateway Tester.**
```` ```
$ cd ../../.. $ cd ../../..
$ ./MQTT-SNGatewayTester $ ./MQTT-SNGatewayTester
@@ -116,4 +130,4 @@ recved 192.168.11.17 :10000 08 13 20 00 01 00 01 00
Execute Publish topic1 Test ? ( Y/N ) : Execute Publish topic1 Test ? ( Y/N ) :
```` ```

View File

@@ -58,6 +58,14 @@ UDPCONF = {
20010, // Local PortNo 20010, // Local PortNo
}; };
/*------------------------------------------------------
* BLE Configuration (theNetcon)
*------------------------------------------------------*/
BLECONF = { "GatewayTestClient", // ClientId
{ 0x60, 0x57, 0x18, 0x06, 0x8b, 0x72 }, // GW Address
1, // Rfcomm channel
};
/*------------------------------------------------------ /*------------------------------------------------------
* Client Configuration (theMqcon) * Client Configuration (theMqcon)
*------------------------------------------------------*/ *------------------------------------------------------*/

View File

@@ -58,6 +58,14 @@ UDPCONF = {
20001, // Local PortNo 20001, // Local PortNo
}; };
/*------------------------------------------------------
* BLE Configuration (theNetcon)
*------------------------------------------------------*/
BLECONF = { "GatewayTestClient", // ClientId
{ 0x60, 0x57, 0x18, 0x06, 0x8b, 0x72 }, // GW Address
1, // Rfcomm channel
};
/*------------------------------------------------------ /*------------------------------------------------------
* Client Configuration (theMqcon) * Client Configuration (theMqcon)
*------------------------------------------------------*/ *------------------------------------------------------*/

View File

@@ -58,6 +58,14 @@ UDPCONF = {
20011, // Local PortNo 20011, // Local PortNo
}; };
/*------------------------------------------------------
* BLE Configuration (theNetcon)
*------------------------------------------------------*/
BLECONF = { "GatewayTestClient", // ClientId
{ 0x44, 0x1C, 0xA8, 0x16, 0x94, 0x94 }, // GW Address
1, // Rfcomm channel
};
/*------------------------------------------------------ /*------------------------------------------------------
* Client Configuration (theMqcon) * Client Configuration (theMqcon)
*------------------------------------------------------*/ *------------------------------------------------------*/

View File

@@ -51,25 +51,31 @@ extern LScreen* theScreen;
/*------------------------------------------------------ /*------------------------------------------------------
* UDP Configuration (theNetcon) * UDP Configuration (theNetcon)
*------------------------------------------------------*/ *------------------------------------------------------*/
UDPCONF = UDPCONF = { "GatewayTestClient", // ClientId
{ "GatewayTestClient", // ClientId
{ 225, 1, 1, 1 }, // Multicast group IP { 225, 1, 1, 1 }, // Multicast group IP
1883, // Multicast group Port 1883, // Multicast group Port
20020, // Local PortNo 20020, // Local PortNo
}; };
/*------------------------------------------------------
* BLE Configuration (theNetcon)
*------------------------------------------------------*/
BLECONF = { "GatewayTestClient", // ClientId
{ 0x60, 0x57, 0x18, 0x06, 0x8b, 0x72 }, // GW Address
1, // Rfcomm channel
};
/*------------------------------------------------------ /*------------------------------------------------------
* Client Configuration (theMqcon) * Client Configuration (theMqcon)
*------------------------------------------------------*/ *------------------------------------------------------*/
MQTTSNCONF = MQTTSNCONF = { 60, //KeepAlive [seconds]
{ 60, //KeepAlive [seconds] true, //Clean session
true, //Clean session 300, //Sleep duration [seconds]
300, //Sleep duration [seconds] "", //WillTopic
"", //WillTopic "", //WillMessage
"", //WillMessage 0, //WillQos
0, //WillQos false //WillRetain
false //WillRetain };
};
/*------------------------------------------------------ /*------------------------------------------------------
* Define Topics * Define Topics

View File

@@ -66,7 +66,7 @@ LGwProxy::~LGwProxy()
_topicTbl.clearTopic(); _topicTbl.clearTopic();
} }
void LGwProxy::initialize(LUdpConfig netconf, LMqttsnConfig mqconf) void LGwProxy::initialize(SENSORNET_CONFIG_t netconf, LMqttsnConfig mqconf)
{ {
_network.initialize(netconf); _network.initialize(netconf);
_clientId = netconf.clientId; _clientId = netconf.clientId;
@@ -87,6 +87,12 @@ void LGwProxy::connect()
{ {
pos = _msg; pos = _msg;
if (!_network.isBroadcastable() && _status == GW_LOST)
{
_status = GW_CONNECTING;
continue;
}
if (_status == GW_LOST) if (_status == GW_LOST)
{ {

View File

@@ -23,6 +23,7 @@
#include "LMqttsnClientApp.h" #include "LMqttsnClientApp.h"
#include "LNetworkUdp.h" #include "LNetworkUdp.h"
#include "LNetworkBle.h"
#include "LRegisterManager.h" #include "LRegisterManager.h"
#include "LTimer.h" #include "LTimer.h"
#include "LTopicTable.h" #include "LTopicTable.h"
@@ -54,7 +55,7 @@ public:
LGwProxy(); LGwProxy();
~LGwProxy(); ~LGwProxy();
void initialize(LUdpConfig netconf, LMqttsnConfig mqconf); void initialize(SENSORNET_CONFIG_t netconf, LMqttsnConfig mqconf);
void connect(void); void connect(void);
void disconnect(uint16_t sec = 0); void disconnect(uint16_t sec = 0);
int getMessage(void); int getMessage(void);

View File

@@ -29,7 +29,7 @@ extern TaskList theTaskList[];
extern TestList theTestList[]; extern TestList theTestList[];
extern OnPublishList theOnPublishList[]; extern OnPublishList theOnPublishList[];
extern MQTTSNCONF; extern MQTTSNCONF;
extern UDPCONF; extern SENSORNET_CONFIG_t theNetcon;
extern void setup(void); extern void setup(void);
/*===================================== /*=====================================
@@ -50,7 +50,14 @@ int main(int argc, char** argv)
#ifndef CLIENT_MODE #ifndef CLIENT_MODE
char c = 0; char c = 0;
printf("\n%s", PAHO_COPYRIGHT4); printf("\n%s", PAHO_COPYRIGHT4);
printf("\n%s\n", PAHO_COPYRIGHT0); printf("\n%s", PAHO_COPYRIGHT0);
#if defined(UDP)
printf(" UDP\n");
#elif defined(BLE)
printf(" BLE\n");
#else
printf("\n");
#endif
printf("%s\n", PAHO_COPYRIGHT1); printf("%s\n", PAHO_COPYRIGHT1);
printf("%s\n", PAHO_COPYRIGHT2); printf("%s\n", PAHO_COPYRIGHT2);
printf(" *\n%s\n", PAHO_COPYRIGHT3); printf(" *\n%s\n", PAHO_COPYRIGHT3);
@@ -108,7 +115,7 @@ LMqttsnClient::~LMqttsnClient()
} }
void LMqttsnClient::initialize(LUdpConfig netconf, LMqttsnConfig mqconf) void LMqttsnClient::initialize(SENSORNET_CONFIG_t netconf, LMqttsnConfig mqconf)
{ {
_gwProxy.initialize(netconf, mqconf); _gwProxy.initialize(netconf, mqconf);
setSleepDuration(mqconf.sleepDuration); setSleepDuration(mqconf.sleepDuration);

View File

@@ -58,7 +58,7 @@ public:
void unsubscribe(const char* topicName); void unsubscribe(const char* topicName);
void unsubscribe(const uint16_t topicId); void unsubscribe(const uint16_t topicId);
void disconnect(uint16_t sleepInSecs); void disconnect(uint16_t sleepInSecs);
void initialize(LUdpConfig netconf, LMqttsnConfig mqconf); void initialize(SENSORNET_CONFIG_t netconf, LMqttsnConfig mqconf);
void run(void); void run(void);
void addTask(bool test); void addTask(bool test);
void setSleepDuration(uint32_t duration); void setSleepDuration(uint32_t duration);

View File

@@ -21,11 +21,12 @@
* Program mode Flag * Program mode Flag
======================================*/ ======================================*/
//#define CLIENT_MODE //#define CLIENT_MODE
#define UDP
//#define BLE
/*====================================== /*======================================
* Debug Flag * Debug Flag
======================================*/ ======================================*/
//#define DEBUG_NW #define DEBUG_NW
//#define DEBUG_MQTTSN //#define DEBUG_MQTTSN
/**************************************** /****************************************
@@ -55,7 +56,8 @@ typedef signed int int32_t;
Application config structures Application config structures
*****************************************/ *****************************************/
struct LMqttsnConfig{ struct LMqttsnConfig
{
uint16_t keepAlive; uint16_t keepAlive;
bool cleanSession; bool cleanSession;
uint32_t sleepDuration; uint32_t sleepDuration;
@@ -65,13 +67,21 @@ struct LMqttsnConfig{
bool willRetain; bool willRetain;
}; };
struct LUdpConfig{ struct LUdpConfig
{
const char* clientId; const char* clientId;
uint8_t ipAddress[4]; uint8_t ipAddress[4];
uint16_t gPortNo; uint16_t gPortNo;
uint16_t uPortNo; uint16_t uPortNo;
}; };
struct LBleConfig
{
const char* clientId;
uint8_t gwAddress[6];
uint8_t channel;
};
typedef enum typedef enum
{ {
@@ -85,7 +95,19 @@ typedef enum
MACROs for Application MACROs for Application
=======================================*/ =======================================*/
#define MQTTSN_CONFIG MqttsnConfig theMqttsnConfig #define MQTTSN_CONFIG MqttsnConfig theMqttsnConfig
#define MQTTSNCONF LMqttsnConfig theMqcon
#ifdef UDP
#define NETWORK_CONFIG UdpConfig theNetworkConfig #define NETWORK_CONFIG UdpConfig theNetworkConfig
#define UDPCONF LUdpConfig theNetcon
#define BLECONF LBleConfig theConf
#define SENSORNET_CONFIG_t LUdpConfig
#else
#define NETWORK_CONFIG BleConfig theNetworkConfig
#define BLECONF LBleConfig theNetcon
#define UDPCONF LUdpConfig theConf
#define SENSORNET_CONFIG_t LBleConfig
#endif
#define CONNECT(...) theClient->getGwProxy()->connect(__VA_ARGS__) #define CONNECT(...) theClient->getGwProxy()->connect(__VA_ARGS__)
#define PUBLISH(...) theClient->publish(__VA_ARGS__) #define PUBLISH(...) theClient->publish(__VA_ARGS__)
@@ -104,8 +126,7 @@ typedef enum
#define SUBSCRIBE_LIST OnPublishList theOnPublishList[] #define SUBSCRIBE_LIST OnPublishList theOnPublishList[]
#define SUB(...) {__VA_ARGS__} #define SUB(...) {__VA_ARGS__}
#define END_OF_SUBSCRIBE_LIST {MQTTSN_TOPIC_TYPE_NORMAL,0,0,0, 0} #define END_OF_SUBSCRIBE_LIST {MQTTSN_TOPIC_TYPE_NORMAL,0,0,0, 0}
#define UDPCONF LUdpConfig theNetcon
#define MQTTSNCONF LMqttsnConfig theMqcon
#define SetForwarderMode(...) theClient->getGwProxy()->setForwarderMode(__VA_ARGS__) #define SetForwarderMode(...) theClient->getGwProxy()->setForwarderMode(__VA_ARGS__)
#define SetQoSMinus1Mode(...) theClient->getGwProxy()->setQoSMinus1Mode(__VA_ARGS__) #define SetQoSMinus1Mode(...) theClient->getGwProxy()->setQoSMinus1Mode(__VA_ARGS__)

View File

@@ -0,0 +1,295 @@
/**************************************************************************************
* Copyright (c) 2021, Tomoaki Yamaguchi
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Tomoaki Yamaguchi - initial API and implementation and/or initial documentation
**************************************************************************************/
#include "LMqttsnClientApp.h"
#ifdef BLE
#include <stdio.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <termios.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/rfcomm.h>
#include "LNetworkBle.h"
#include "LTimer.h"
#include "LScreen.h"
using namespace std;
using namespace linuxAsyncClient;
extern uint16_t getUint16(const uint8_t* pos);
extern uint32_t getUint32(const uint8_t* pos);
extern LScreen* theScreen;
extern bool theClientMode;
extern LBleConfig theNetcon;
/*=========================================
Class LNetwork
=========================================*/
LNetwork::LNetwork()
{
_sleepflg = false;
_returnCode = 0;
}
LNetwork::~LNetwork()
{
}
int LNetwork::broadcast(const uint8_t* xmitData, uint16_t dataLen)
{
return LBlePort::unicast(xmitData, dataLen);
}
int LNetwork::unicast(const uint8_t* xmitData, uint16_t dataLen)
{
return LBlePort::unicast(xmitData, dataLen);
}
uint8_t* LNetwork::getMessage(int* len)
{
*len = 0;
if (checkRecvBuf())
{
uint16_t recvLen = LBlePort::recv(_rxDataBuf, MQTTSN_MAX_PACKET_SIZE, false);
if (recvLen < 0)
{
*len = recvLen;
return 0;
}
else
{
if (_rxDataBuf[0] == 0x01)
{
*len = getUint16(_rxDataBuf + 1);
}
else
{
*len = _rxDataBuf[0];
}
//if(recvLen != *len){
// *len = 0;
// return 0;
//}else{
return _rxDataBuf;
//}
}
}
return 0;
}
void LNetwork::setGwAddress(void)
{
}
void LNetwork::setFixedGwAddress(void)
{
_channel = LBlePort::_channel;
memcpy(_gwAddress, theNetcon.gwAddress, 6);
}
bool LNetwork::initialize(LBleConfig config)
{
return LBlePort::open(config);
}
void LNetwork::setSleep()
{
_sleepflg = true;
}
bool LNetwork::isBroadcastable()
{
return false;
}
/*=========================================
Class BleStack
=========================================*/
LBlePort::LBlePort()
{
_disconReq = false;
_sockBle = 0;
_channel = 0;
}
LBlePort::~LBlePort()
{
close();
}
void LBlePort::close()
{
if (_sockBle > 0)
{
::close(_sockBle);
_sockBle = 0;
}
}
bool LBlePort::open(LBleConfig config)
{
const int reuse = 1;
uint8_t* gw = config.gwAddress + 5;
for (int i = 0; i < 6; i++)
{
*(_gwAddress + i) = *gw--;
}
_channel = config.channel;
if (_channel == 0 || _gwAddress == 0 || _devAddress == 0)
{
D_NWLOG("\033[0m\033[0;31merror BLE Address in BlePort::open\033[0m\033[0;37m\n");
DISPLAY("\033[0m\033[0;31m\nerror BLE Address in BlePort::open\033[0m\033[0;37m\n");
return false;
}
_sockBle = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
if (_sockBle < 0)
{
D_NWLOG("\033[0m\033[0;31merror Can't create socket in BlePort::open\033[0m\033[0;37m\n");
DISPLAY("\033[0m\033[0;31m\nerror Can't create socket in BlePort::open\033[0m\033[0;37m\n");
return false;
}
setsockopt(_sockBle, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));
struct sockaddr_rc addru = { 0 };
addru.rc_family = AF_BLUETOOTH;
addru.rc_channel = _channel;
memcpy(&addru.rc_bdaddr, _gwAddress, 6);
char bufgw[30];
ba2str(&addru.rc_bdaddr, bufgw);
DISPLAY("GW MAC = %s RFCOMM CH = %d\n", bufgw, addru.rc_channel);
// connect to server
errno = 0;
int status = connect(_sockBle, (struct sockaddr *) &addru, sizeof(addru));
if (status < 0)
{
D_NWLOG("\033[0m\033[0;31merror = %d Can't connect to GW in BlePort::open\033[0m\033[0;37m\n", errno);
DISPLAY("\033[0m\033[0;31mCan't connect to GW Ble socket in BlePort::open\033[0m\033[0;37m\n");
close();
return false;
}
return true;
}
int LBlePort::unicast(const uint8_t* buf, uint32_t length)
{
int status = ::write(_sockBle, buf, length);
if (status < 0)
{
D_NWLOG("errno == %d in LBlePort::unicast\n", errno);
DISPLAY("errno == %d in LBlePort::unicast\n", errno);
}
else
{
D_NWLOG("sendto %-2d", _channel);
for (uint16_t i = 0; i < length; i++)
{
D_NWLOG(" %02x", *(buf + i));
}
D_NWLOG("\n");
if (!theClientMode)
{
char sbuf[SCREEN_BUFF_SIZE];
int pos = 0;
sprintf(sbuf, "\033[0;34msendto %-2dch", _channel);
pos = strlen(sbuf);
for (uint16_t i = 0; i < length; i++)
{
sprintf(sbuf + pos, " %02x", *(buf + i));
if (strlen(sbuf) > SCREEN_BUFF_SIZE - 20) // -20 for Escape sequence
{
break;
}
pos += 3;
}
sprintf(sbuf + strlen(sbuf), "\033[0;37m\n");
theScreen->display(sbuf);
}
}
return status;
}
bool LBlePort::checkRecvBuf()
{
uint8_t buf[2];
if (::recv(_sockBle, buf, 1, MSG_DONTWAIT | MSG_PEEK) > 0)
{
return true;
}
return false;
}
int LBlePort::recv(uint8_t* buf, uint16_t length, bool flg)
{
int flags = flg ? MSG_DONTWAIT : 0;
int status = ::recv(_sockBle, buf, length, flags);
if (status < 0 && errno != EAGAIN)
{
D_NWLOG("\033[0m\033[0;31merrno == %d in BlePort::recv \033[0m\033[0;37m\n", errno);
DISPLAY("\033[0m\033[0;31merrno == %d in BlePort::recv \033[0m\033[0;37m\n", errno);
}
else if (status > 0)
{
D_NWLOG("\nrecved ");
for (uint16_t i = 0; i < status; i++)
{
D_NWLOG(" %02x", *(buf + i));
}
D_NWLOG("\n");
if (!theClientMode)
{
char sbuf[SCREEN_BUFF_SIZE];
int pos = 0;
sprintf(sbuf, "\033[0;34mrecved ");
pos = strlen(sbuf);
for (uint16_t i = 0; i < status; i++)
{
sprintf(sbuf + pos, " %02x", *(buf + i));
if (strlen(sbuf) > SCREEN_BUFF_SIZE - 20)
{
break;
}
pos += 3;
}
sprintf(sbuf + strlen(sbuf), "\033[0;37m\n");
theScreen->display(sbuf);
}
return status;
}
else
{
return 0;
}
return status;
}
#endif

View File

@@ -0,0 +1,106 @@
/**************************************************************************************
* Copyright (c) 2021, Tomoaki Yamaguchi
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Tomoaki Yamaguchi - initial API and implementation and/or initial documentation
**************************************************************************************/
#ifndef NETWORKBLE_H_
#define NETWORKBLE_H_
#include "LMqttsnClientApp.h"
#ifdef BLE
#include <sys/time.h>
#include <iostream>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <unistd.h>
#include <string>
#include <bluetooth/bluetooth.h>
#define SOCKET_MAXHOSTNAME 200
#define SOCKET_MAXCONNECTIONS 5
#define SOCKET_MAXRECV 500
#define SOCKET_MAXBUFFER_LENGTH 500 // buffer size
#define STAT_UNICAST 1
#define STAT_MULTICAST 2
using namespace std;
namespace linuxAsyncClient
{
/*========================================
Class LBlePort
=======================================*/
class LBlePort
{
friend class LNetwork;
public:
LBlePort();
virtual ~LBlePort();
bool open(LBleConfig config);
int unicast(const uint8_t* buf, uint32_t length);
int recv(uint8_t* buf, uint16_t len, bool nonblock);
bool checkRecvBuf();
bool isUnicast();
private:
void close();
int _sockBle;
uint8_t _devAddress[6];
uint8_t _gwAddress[6];
uint8_t _channel;
bool _disconReq;
};
#define NO_ERROR 0
#define PACKET_EXCEEDS_LENGTH 1
/*===========================================
Class Network
============================================*/
class LNetwork: public LBlePort
{
public:
LNetwork();
~LNetwork();
int broadcast(const uint8_t* payload, uint16_t payloadLen);
int unicast(const uint8_t* payload, uint16_t payloadLen);
void setGwAddress(void);
void resetGwAddress(void);
void setFixedGwAddress(void);
bool initialize(LBleConfig config);
uint8_t* getMessage(int* len);
bool isBroadcastable();
private:
void setSleep();
int readApiFrame(void);
int _returnCode;
bool _sleepflg;
uint8_t _rxDataBuf[MQTTSN_MAX_PACKET_SIZE + 1]; // defined in MqttsnClientApp.h
};
} /* end of namespace */
#endif /* BLE */
#endif /* NETWORKBLE_H_ */

View File

@@ -13,6 +13,8 @@
* Contributors: * Contributors:
* Tomoaki Yamaguchi - initial API and implementation and/or initial documentation * Tomoaki Yamaguchi - initial API and implementation and/or initial documentation
**************************************************************************************/ **************************************************************************************/
#include "LMqttsnClientApp.h"
#ifdef UDP
#include <stdio.h> #include <stdio.h>
#include <sys/time.h> #include <sys/time.h>
@@ -29,7 +31,6 @@
#include "LTimer.h" #include "LTimer.h"
#include "LScreen.h" #include "LScreen.h"
#include "LMqttsnClientApp.h"
using namespace std; using namespace std;
using namespace linuxAsyncClient; using namespace linuxAsyncClient;
@@ -111,6 +112,10 @@ void LNetwork::setSleep(){
_sleepflg = true; _sleepflg = true;
} }
bool LNetwork::isBroadcastable()
{
return true;
}
/*========================================= /*=========================================
Class udpStack Class udpStack
=========================================*/ =========================================*/
@@ -385,5 +390,5 @@ int LUdpPort::recvfrom (uint8_t* buf, uint16_t length, int flags, uint32_t* ipAd
return status; return status;
} }
#endif

View File

@@ -17,6 +17,9 @@
#ifndef NETWORKUDP_H_ #ifndef NETWORKUDP_H_
#define NETWORKUDP_H_ #define NETWORKUDP_H_
#include "LMqttsnClientApp.h"
#ifdef UDP
#include <sys/time.h> #include <sys/time.h>
#include <iostream> #include <iostream>
#include <sys/types.h> #include <sys/types.h>
@@ -27,7 +30,6 @@
#include <string> #include <string>
#include <arpa/inet.h> #include <arpa/inet.h>
#include "LMqttsnClientApp.h"
#define SOCKET_MAXHOSTNAME 200 #define SOCKET_MAXHOSTNAME 200
#define SOCKET_MAXCONNECTIONS 5 #define SOCKET_MAXCONNECTIONS 5
@@ -89,6 +91,7 @@ public:
void setFixedGwAddress(void); void setFixedGwAddress(void);
bool initialize(LUdpConfig config); bool initialize(LUdpConfig config);
uint8_t* getMessage(int* len); uint8_t* getMessage(int* len);
bool isBroadcastable();
private: private:
void setSleep(); void setSleep();
int readApiFrame(void); int readApiFrame(void);
@@ -103,6 +106,6 @@ private:
}; };
} /* end of namespace */ } /* end of namespace */
#endif /* UDP */
#endif /* NETWORKUDP_H_ */ #endif /* NETWORKUDP_H_ */

View File

@@ -7,7 +7,7 @@ This Gateway can run as a transparent or aggregating Gateway by specifying the g
```` ````
$ git clone -b develop https://github.com/eclipse/paho.mqtt-sn.embedded-c $ git clone -b develop https://github.com/eclipse/paho.mqtt-sn.embedded-c
$ cd paho.mqtt-sn.embedded-c/MQTTSNGateway $ cd paho.mqtt-sn.embedded-c/MQTTSNGateway
$ ./build.sh {udp|udp6|xbee|loralink} $ ./build.sh [udp|udp6|xbee|loralink | ble]
```` ````
In order to build a gateway, an argument is required. In order to build a gateway, an argument is required.
@@ -50,6 +50,7 @@ ClientAuthentication=NO
AggregatingGateway=NO AggregatingGateway=NO
QoS-1=NO QoS-1=NO
Forwarder=NO Forwarder=NO
MaxNumberOfClients=30;
#ClientsList=/path/to/your_clients.conf #ClientsList=/path/to/your_clients.conf
@@ -91,6 +92,9 @@ BaudrateLoRaLink=115200
DeviceRxLoRaLink=/dev/ttyLoRaLinkRx DeviceRxLoRaLink=/dev/ttyLoRaLinkRx
DeviceTxLoRaLink=/dev/ttyLoRaLinkTx DeviceTxLoRaLink=/dev/ttyLoRaLinkTx
# BLE RFCOMM
BleAddress=60:57:18:06:8B:72.*
# LOG # LOG
ShearedMemory=NO; ShearedMemory=NO;
@@ -106,6 +110,7 @@ Format of the file is ClientId and SensorNetwork Address. e.g. IP address and Po
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 **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. 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.
When **Forwarder** is **YES**, Forwarder Encapsulation Message is available. Connectable Forwarders must be declared by a **ClientsList** file. When **Forwarder** is **YES**, Forwarder Encapsulation Message is available. Connectable Forwarders must be declared by a **ClientsList** file.
**MaxNumberOfClients** Maximum number of clients allocated.
### ** How to monitor the gateway from remote. ** ### ** How to monitor the gateway from remote. **
Change gateway.conf as follows: Change gateway.conf as follows:

View File

@@ -27,6 +27,7 @@ ClientAuthentication=NO
AggregatingGateway=NO AggregatingGateway=NO
QoS-1=NO QoS-1=NO
Forwarder=NO Forwarder=NO
MaxNumberOfClients=30;
#ClientsList=/path/to/your_clients.conf #ClientsList=/path/to/your_clients.conf
@@ -68,6 +69,9 @@ BaudrateLoRaLink=115200
DeviceRxLoRaLink=/dev/loralinkRx DeviceRxLoRaLink=/dev/loralinkRx
DeviceTxLoRaLink=/dev/loralinkTx DeviceTxLoRaLink=/dev/loralinkTx
# BLE RFCOMM
BleAddress=60:57:18:06:8B:72.*
# LOG # LOG
ShearedMemory=NO; ShearedMemory=NO;

View File

@@ -87,12 +87,27 @@ TARGET_INCLUDE_DIRECTORIES(mqtt-sngateway_common
/usr/local/opt/openssl/include /usr/local/opt/openssl/include
) )
IF(SENSORNET MATCHES "ble")
TARGET_LINK_LIBRARIES(mqtt-sngateway_common TARGET_LINK_LIBRARIES(mqtt-sngateway_common
PRIVATE PRIVATE
MQTTSNPacket MQTTSNPacket
pthread pthread
ssl ssl
crypto) crypto
bluetooth
)
ELSE()
TARGET_LINK_LIBRARIES(mqtt-sngateway_common
PRIVATE
MQTTSNPacket
pthread
ssl
crypto
)
ENDIF()
ADD_EXECUTABLE(MQTT-SNGateway ADD_EXECUTABLE(MQTT-SNGateway
mainGateway.cpp mainGateway.cpp

View File

@@ -30,8 +30,7 @@ MQTTGWConnectionHandler::~MQTTGWConnectionHandler()
} }
void MQTTGWConnectionHandler::handleConnack(Client* client, void MQTTGWConnectionHandler::handleConnack(Client* client, MQTTGWPacket* packet)
MQTTGWPacket* packet)
{ {
uint8_t rc = MQTT_SERVER_UNAVAILABLE; uint8_t rc = MQTT_SERVER_UNAVAILABLE;
Connack resp; Connack resp;
@@ -45,35 +44,28 @@ void MQTTGWConnectionHandler::handleConnack(Client* client,
else if (resp.rc == MQTT_UNACCEPTABLE_PROTOCOL_VERSION) else if (resp.rc == MQTT_UNACCEPTABLE_PROTOCOL_VERSION)
{ {
rc = MQTTSN_RC_NOT_SUPPORTED; rc = MQTTSN_RC_NOT_SUPPORTED;
WRITELOG( WRITELOG(" ClientID : %s Requested Protocol version is not supported.\n", client->getClientId());
" ClientID : %s Requested Protocol version is not supported.\n",
client->getClientId());
} }
else if (resp.rc == MQTT_IDENTIFIER_REJECTED) else if (resp.rc == MQTT_IDENTIFIER_REJECTED)
{ {
rc = MQTTSN_RC_NOT_SUPPORTED; rc = MQTTSN_RC_NOT_SUPPORTED;
WRITELOG( WRITELOG(" ClientID : %s ClientID is collect UTF-8 but not allowed by the Server.\n", client->getClientId());
" ClientID : %s ClientID is collect UTF-8 but not allowed by the Server.\n",
client->getClientId());
} }
else if (resp.rc == MQTT_SERVER_UNAVAILABLE) else if (resp.rc == MQTT_SERVER_UNAVAILABLE)
{ {
rc = MQTTSN_RC_REJECTED_CONGESTED; rc = MQTTSN_RC_REJECTED_CONGESTED;
WRITELOG( WRITELOG(" ClientID : %s The Network Connection has been made but the MQTT service is unavailable.\n",
" ClientID : %s The Network Connection has been made but the MQTT service is unavailable.\n",
client->getClientId()); client->getClientId());
} }
else if (resp.rc == MQTT_BAD_USERNAME_OR_PASSWORD) else if (resp.rc == MQTT_BAD_USERNAME_OR_PASSWORD)
{ {
rc = MQTTSN_RC_NOT_SUPPORTED; rc = MQTTSN_RC_NOT_SUPPORTED;
WRITELOG( WRITELOG(" Gateway Configuration Error: The data in the user name or password is malformed.\n");
" Gateway Configuration Error: The data in the user name or password is malformed.\n");
} }
else if (resp.rc == MQTT_NOT_AUTHORIZED) else if (resp.rc == MQTT_NOT_AUTHORIZED)
{ {
rc = MQTTSN_RC_NOT_SUPPORTED; rc = MQTTSN_RC_NOT_SUPPORTED;
WRITELOG( WRITELOG(" Gateway Configuration Error: The Client is not authorized to connect.\n");
" Gateway Configuration Error: The Client is not authorized to connect.\n");
} }
MQTTSNPacket* snPacket = new MQTTSNPacket(); MQTTSNPacket* snPacket = new MQTTSNPacket();
@@ -85,8 +77,7 @@ void MQTTGWConnectionHandler::handleConnack(Client* client,
_gateway->getClientSendQue()->post(ev1); _gateway->getClientSendQue()->post(ev1);
} }
void MQTTGWConnectionHandler::handlePingresp(Client* client, void MQTTGWConnectionHandler::handlePingresp(Client* client, MQTTGWPacket* packet)
MQTTGWPacket* packet)
{ {
MQTTSNPacket* snPacket = new MQTTSNPacket(); MQTTSNPacket* snPacket = new MQTTSNPacket();
snPacket->setPINGRESP(); snPacket->setPINGRESP();
@@ -96,8 +87,7 @@ void MQTTGWConnectionHandler::handlePingresp(Client* client,
_gateway->getClientSendQue()->post(ev1); _gateway->getClientSendQue()->post(ev1);
} }
void MQTTGWConnectionHandler::handleDisconnect(Client* client, void MQTTGWConnectionHandler::handleDisconnect(Client* client, MQTTGWPacket* packet)
MQTTGWPacket* packet)
{ {
MQTTSNPacket* snPacket = new MQTTSNPacket(); MQTTSNPacket* snPacket = new MQTTSNPacket();
snPacket->setDISCONNECT(0); snPacket->setDISCONNECT(0);

View File

@@ -28,10 +28,8 @@ void writeInt(unsigned char** pptr, int msgId);
/** /**
* List of the predefined MQTT v3 packet names. * List of the predefined MQTT v3 packet names.
*/ */
static const char* mqtt_packet_names[] = static const char* mqtt_packet_names[] = { "RESERVED", "CONNECT", "CONNACK", "PUBLISH", "PUBACK", "PUBREC", "PUBREL", "PUBCOMP",
{ "RESERVED", "CONNECT", "CONNACK", "PUBLISH", "PUBACK", "PUBREC", "PUBREL", "SUBSCRIBE", "SUBACK", "UNSUBSCRIBE", "UNSUBACK", "PINGREQ", "PINGRESP", "DISCONNECT" };
"PUBCOMP", "SUBSCRIBE", "SUBACK", "UNSUBSCRIBE", "UNSUBACK", "PINGREQ",
"PINGRESP", "DISCONNECT" };
/** /**
* Encodes the message length according to the MQTT algorithm * Encodes the message length according to the MQTT algorithm
@@ -50,7 +48,8 @@ int MQTTPacket_encode(char* buf, int length)
if (length > 0) if (length > 0)
d |= 0x80; d |= 0x80;
buf[rc++] = d; buf[rc++] = d;
} while (length > 0); }
while (length > 0);
return rc; return rc;
} }
@@ -206,7 +205,8 @@ int MQTTGWPacket::recv(Network* network)
} }
_remainingLength += (c & 127) * multiplier; _remainingLength += (c & 127) * multiplier;
multiplier *= 128; multiplier *= 128;
} while ((c & 128) != 0); }
while ((c & 128) != 0);
if (_remainingLength > 0) if (_remainingLength > 0)
{ {
@@ -243,9 +243,8 @@ int MQTTGWPacket::send(Network* network)
int MQTTGWPacket::getAck(Ack* ack) int MQTTGWPacket::getAck(Ack* ack)
{ {
if (PUBACK != _header.bits.type && PUBREC != _header.bits.type if (PUBACK != _header.bits.type && PUBREC != _header.bits.type && PUBREL != _header.bits.type
&& PUBREL != _header.bits.type && PUBCOMP != _header.bits.type && PUBCOMP != _header.bits.type && UNSUBACK != _header.bits.type)
&& UNSUBACK != _header.bits.type)
{ {
return 0; return 0;
} }
@@ -305,18 +304,15 @@ int MQTTGWPacket::getPUBLISH(Publish* pub)
return 1; return 1;
} }
int MQTTGWPacket::setCONNECT(Connect* connect, unsigned char* username, int MQTTGWPacket::setCONNECT(Connect* connect, unsigned char* username, unsigned char* password)
unsigned char* password)
{ {
clearData(); clearData();
_header = connect->header; _header = connect->header;
_remainingLength = ((connect->version == 3) ? 12 : 10) _remainingLength = ((connect->version == 3) ? 12 : 10) + (int) strlen(connect->clientID) + 2;
+ (int) strlen(connect->clientID) + 2;
if (connect->flags.bits.will) if (connect->flags.bits.will)
{ {
_remainingLength += (int) strlen(connect->willTopic) + 2 _remainingLength += (int) strlen(connect->willTopic) + 2 + (int) strlen(connect->willMsg) + 2;
+ (int) strlen(connect->willMsg) + 2;
} }
if (connect->flags.bits.username) if (connect->flags.bits.username)
{ {
@@ -365,8 +361,7 @@ int MQTTGWPacket::setCONNECT(Connect* connect, unsigned char* username,
return 1; return 1;
} }
int MQTTGWPacket::setSUBSCRIBE(const char* topic, unsigned char qos, int MQTTGWPacket::setSUBSCRIBE(const char* topic, unsigned char qos, unsigned short msgId)
unsigned short msgId)
{ {
clearData(); clearData();
_header.byte = 0; _header.byte = 0;
@@ -640,8 +635,7 @@ MQTTGWPacket& MQTTGWPacket::operator =(MQTTGWPacket& packet)
UTF8String MQTTGWPacket::getTopic(void) UTF8String MQTTGWPacket::getTopic(void)
{ {
UTF8String str = UTF8String str = { 0, nullptr };
{ 0, nullptr };
if (_header.bits.type == SUBSCRIBE || _header.bits.type == UNSUBSCRIBE) if (_header.bits.type == SUBSCRIBE || _header.bits.type == UNSUBSCRIBE)
{ {
char* ptr = (char*) (_data + 2); char* ptr = (char*) (_data + 2);

View File

@@ -40,7 +40,7 @@ void MQTTGWPublishHandler::handlePublish(Client* client, MQTTGWPacket* packet)
if (!client->isActive() && !client->isSleep() && !client->isAwake()) if (!client->isActive() && !client->isSleep() && !client->isAwake())
{ {
WRITELOG("%s The client is neither active nor sleep %s%s\n", WRITELOG("%s The client is neither active nor sleep %s%s\n",
ERRMSG_HEADER, client->getStatus(), ERRMSG_FOOTER); ERRMSG_HEADER, client->getStatus(), ERRMSG_FOOTER);
return; return;
} }
@@ -66,9 +66,8 @@ void MQTTGWPublishHandler::handlePublish(Client* client, MQTTGWPacket* packet)
*msg = *packet; *msg = *packet;
if (msg->getType() == 0) if (msg->getType() == 0)
{ {
WRITELOG( WRITELOG("%s MQTTGWPublishHandler::handlePublish can't allocate memories for Packet.%s\n",
"%s MQTTGWPublishHandler::handlePublish can't allocate memories for Packet.%s\n", ERRMSG_HEADER, ERRMSG_FOOTER);
ERRMSG_HEADER, ERRMSG_FOOTER);
delete msg; delete msg;
return; return;
} }
@@ -105,15 +104,14 @@ void MQTTGWPublishHandler::handlePublish(Client* client, MQTTGWPacket* packet)
} }
else else
{ {
/* This message might be subscribed with wild card or not cleanSession*/ /* This message might be subscribed with wild card or not cleanSession*/
topicId.type = MQTTSN_TOPIC_TYPE_NORMAL; topicId.type = MQTTSN_TOPIC_TYPE_NORMAL;
Topic* topic = client->getTopics()->match(&topicId); Topic* topic = client->getTopics()->match(&topicId);
if (topic == nullptr && client->isCleanSession()) if (topic == nullptr && client->isCleanSession())
{ {
WRITELOG( WRITELOG("%sMQTTGWPublishHandler Invalid Topic. PUBLISH message is discarded.%s\n",
"%sMQTTGWPublishHandler Invalid Topic. PUBLISH message is discarded.%s\n", ERRMSG_HEADER, ERRMSG_FOOTER);
ERRMSG_HEADER, ERRMSG_FOOTER);
if (pub.header.bits.qos == 1) if (pub.header.bits.qos == 1)
{ {
replyACK(client, &pub, PUBACK); replyACK(client, &pub, PUBACK);
@@ -127,20 +125,20 @@ void MQTTGWPublishHandler::handlePublish(Client* client, MQTTGWPacket* packet)
return; return;
} }
if (topic == nullptr) if (topic == nullptr)
{ {
topicId.type = MQTTSN_TOPIC_TYPE_NORMAL; topicId.type = MQTTSN_TOPIC_TYPE_NORMAL;
topicId.data.long_.len = pub.topiclen; topicId.data.long_.len = pub.topiclen;
topicId.data.long_.name = pub.topic; topicId.data.long_.name = pub.topic;
topicId.data.id = 0; topicId.data.id = 0;
} }
/* add the Topic and get a TopicId */ /* add the Topic and get a TopicId */
topic = client->getTopics()->add(&topicId); topic = client->getTopics()->add(&topicId);
if (topic == nullptr) if (topic == nullptr)
{ {
WRITELOG( WRITELOG(
"%sMQTTGWPublishHandler Can't Add a Topic. MAX_TOPIC_PAR_CLIENT is exceeded. PUBLISH message is discarded.%s\n", "%sMQTTGWPublishHandler Can't Add a Topic. MAX_TOPIC_PAR_CLIENT is exceeded. PUBLISH message is discarded.%s\n",
ERRMSG_HEADER, ERRMSG_FOOTER); ERRMSG_HEADER, ERRMSG_FOOTER);
delete snPacket; delete snPacket;
return; return;
@@ -165,29 +163,23 @@ void MQTTGWPublishHandler::handlePublish(Client* client, MQTTGWPacket* packet)
/* send PUBLISH */ /* send PUBLISH */
topicId.data.id = id; topicId.data.id = id;
snPacket->setPUBLISH((uint8_t) pub.header.bits.dup, snPacket->setPUBLISH((uint8_t) pub.header.bits.dup, (int) pub.header.bits.qos, (uint8_t) pub.header.bits.retain,
(int) pub.header.bits.qos, (uint16_t) pub.msgId, topicId, (uint8_t*) pub.payload, pub.payloadlen);
(uint8_t) pub.header.bits.retain, (uint16_t) pub.msgId, client->getWaitREGACKPacketList()->setPacket(snPacket, regackMsgId);
topicId, (uint8_t*) pub.payload, pub.payloadlen);
client->getWaitREGACKPacketList()->setPacket(snPacket,
regackMsgId);
return; return;
} }
else else
{ {
WRITELOG( WRITELOG("%sMQTTGWPublishHandler Can't create a Topic. PUBLISH message is discarded.%s\n",
"%sMQTTGWPublishHandler Can't create a Topic. PUBLISH message is discarded.%s\n", ERRMSG_HEADER, ERRMSG_FOOTER);
ERRMSG_HEADER, ERRMSG_FOOTER);
delete snPacket; delete snPacket;
return; return;
} }
} }
} }
snPacket->setPUBLISH((uint8_t) pub.header.bits.dup, snPacket->setPUBLISH((uint8_t) pub.header.bits.dup, (int) pub.header.bits.qos, (uint8_t) pub.header.bits.retain,
(int) pub.header.bits.qos, (uint8_t) pub.header.bits.retain, (uint16_t) pub.msgId, topicId, (uint8_t*) pub.payload, pub.payloadlen);
(uint16_t) pub.msgId, topicId, (uint8_t*) pub.payload,
pub.payloadlen);
Event* ev1 = new Event(); Event* ev1 = new Event();
ev1->setClientSendEvent(client, snPacket); ev1->setClientSendEvent(client, snPacket);
_gateway->getClientSendQue()->post(ev1); _gateway->getClientSendQue()->post(ev1);
@@ -207,8 +199,7 @@ void MQTTGWPublishHandler::handlePuback(Client* client, MQTTGWPacket* packet)
{ {
Ack ack; Ack ack;
packet->getAck(&ack); packet->getAck(&ack);
TopicIdMapElement* topicId = client->getWaitedPubTopicId( TopicIdMapElement* topicId = client->getWaitedPubTopicId((uint16_t) ack.msgId);
(uint16_t) ack.msgId);
if (topicId) if (topicId)
{ {
MQTTSNPacket* mqttsnPacket = new MQTTSNPacket(); MQTTSNPacket* mqttsnPacket = new MQTTSNPacket();
@@ -220,13 +211,11 @@ void MQTTGWPublishHandler::handlePuback(Client* client, MQTTGWPacket* packet)
_gateway->getClientSendQue()->post(ev1); _gateway->getClientSendQue()->post(ev1);
return; return;
} }
WRITELOG( WRITELOG(" PUBACK from the Broker is invalid. PacketID : %04X ClientID : %s \n", (uint16_t) ack.msgId,
" PUBACK from the Broker is invalid. PacketID : %04X ClientID : %s \n", client->getClientId());
(uint16_t) ack.msgId, client->getClientId());
} }
void MQTTGWPublishHandler::handleAck(Client* client, MQTTGWPacket* packet, void MQTTGWPublishHandler::handleAck(Client* client, MQTTGWPacket* packet, int type)
int type)
{ {
Ack ack; Ack ack;
packet->getAck(&ack); packet->getAck(&ack);
@@ -264,13 +253,11 @@ void MQTTGWPublishHandler::handleAck(Client* client, MQTTGWPacket* packet,
} }
} }
void MQTTGWPublishHandler::handleAggregatePuback(Client* client, void MQTTGWPublishHandler::handleAggregatePuback(Client* client, MQTTGWPacket* packet)
MQTTGWPacket* packet)
{ {
uint16_t msgId = packet->getMsgId(); uint16_t msgId = packet->getMsgId();
uint16_t clientMsgId = 0; uint16_t clientMsgId = 0;
Client* newClient = _gateway->getAdapterManager()->convertClient(msgId, Client* newClient = _gateway->getAdapterManager()->convertClient(msgId, &clientMsgId);
&clientMsgId);
if (newClient != nullptr) if (newClient != nullptr)
{ {
packet->setMsgId((int) clientMsgId); packet->setMsgId((int) clientMsgId);
@@ -278,13 +265,11 @@ void MQTTGWPublishHandler::handleAggregatePuback(Client* client,
} }
} }
void MQTTGWPublishHandler::handleAggregateAck(Client* client, void MQTTGWPublishHandler::handleAggregateAck(Client* client, MQTTGWPacket* packet, int type)
MQTTGWPacket* packet, int type)
{ {
uint16_t msgId = packet->getMsgId(); uint16_t msgId = packet->getMsgId();
uint16_t clientMsgId = 0; uint16_t clientMsgId = 0;
Client* newClient = _gateway->getAdapterManager()->convertClient(msgId, Client* newClient = _gateway->getAdapterManager()->convertClient(msgId, &clientMsgId);
&clientMsgId);
if (newClient != nullptr) if (newClient != nullptr)
{ {
packet->setMsgId((int) clientMsgId); packet->setMsgId((int) clientMsgId);
@@ -292,16 +277,14 @@ void MQTTGWPublishHandler::handleAggregateAck(Client* client,
} }
} }
void MQTTGWPublishHandler::handleAggregatePubrel(Client* client, void MQTTGWPublishHandler::handleAggregatePubrel(Client* client, MQTTGWPacket* packet)
MQTTGWPacket* packet)
{ {
Publish pub; Publish pub;
packet->getPUBLISH(&pub); packet->getPUBLISH(&pub);
replyACK(client, &pub, PUBCOMP); replyACK(client, &pub, PUBCOMP);
} }
void MQTTGWPublishHandler::handleAggregatePublish(Client* client, void MQTTGWPublishHandler::handleAggregatePublish(Client* client, MQTTGWPacket* packet)
MQTTGWPacket* packet)
{ {
Publish pub; Publish pub;
packet->getPUBLISH(&pub); packet->getPUBLISH(&pub);
@@ -310,9 +293,7 @@ void MQTTGWPublishHandler::handleAggregatePublish(Client* client,
Topic topic = Topic(topicName, MQTTSN_TOPIC_TYPE_NORMAL); Topic topic = Topic(topicName, MQTTSN_TOPIC_TYPE_NORMAL);
// ToDo: need to refactor // ToDo: need to refactor
ClientTopicElement* elm = ClientTopicElement* elm = _gateway->getAdapterManager()->getAggregater()->getClientElement(&topic);
_gateway->getAdapterManager()->getAggregater()->getClientElement(
&topic);
while (elm != nullptr) while (elm != nullptr)
{ {
@@ -322,9 +303,8 @@ void MQTTGWPublishHandler::handleAggregatePublish(Client* client,
if (msg->getType() == 0) if (msg->getType() == 0)
{ {
WRITELOG( WRITELOG("%s MQTTGWPublishHandler::handleAggregatePublish can't allocate memories for Packet.%s\n",
"%s MQTTGWPublishHandler::handleAggregatePublish can't allocate memories for Packet.%s\n", ERRMSG_HEADER, ERRMSG_FOOTER);
ERRMSG_HEADER, ERRMSG_FOOTER);
delete msg; delete msg;
break; break;
} }

View File

@@ -61,8 +61,7 @@ void MQTTGWSubscribeHandler::handleSuback(Client* client, MQTTGWPacket* packet)
} }
} }
void MQTTGWSubscribeHandler::handleUnsuback(Client* client, void MQTTGWSubscribeHandler::handleUnsuback(Client* client, MQTTGWPacket* packet)
MQTTGWPacket* packet)
{ {
Ack ack; Ack ack;
packet->getAck(&ack); packet->getAck(&ack);
@@ -73,14 +72,11 @@ void MQTTGWSubscribeHandler::handleUnsuback(Client* client,
_gateway->getClientSendQue()->post(evt); _gateway->getClientSendQue()->post(evt);
} }
void MQTTGWSubscribeHandler::handleAggregateSuback(Client* client, void MQTTGWSubscribeHandler::handleAggregateSuback(Client* client, MQTTGWPacket* packet)
MQTTGWPacket* packet)
{ {
uint16_t msgId = packet->getMsgId(); uint16_t msgId = packet->getMsgId();
uint16_t clientMsgId = 0; uint16_t clientMsgId = 0;
Client* newClient = Client* newClient = _gateway->getAdapterManager()->getAggregater()->convertClient(msgId, &clientMsgId);
_gateway->getAdapterManager()->getAggregater()->convertClient(msgId,
&clientMsgId);
if (newClient != nullptr) if (newClient != nullptr)
{ {
packet->setMsgId((int) clientMsgId); packet->setMsgId((int) clientMsgId);
@@ -88,14 +84,11 @@ void MQTTGWSubscribeHandler::handleAggregateSuback(Client* client,
} }
} }
void MQTTGWSubscribeHandler::handleAggregateUnsuback(Client* client, void MQTTGWSubscribeHandler::handleAggregateUnsuback(Client* client, MQTTGWPacket* packet)
MQTTGWPacket* packet)
{ {
uint16_t msgId = packet->getMsgId(); uint16_t msgId = packet->getMsgId();
uint16_t clientMsgId = 0; uint16_t clientMsgId = 0;
Client* newClient = Client* newClient = _gateway->getAdapterManager()->getAggregater()->convertClient(msgId, &clientMsgId);
_gateway->getAdapterManager()->getAggregater()->convertClient(msgId,
&clientMsgId);
if (newClient != nullptr) if (newClient != nullptr)
{ {
packet->setMsgId((int) clientMsgId); packet->setMsgId((int) clientMsgId);

View File

@@ -26,8 +26,7 @@ using namespace MQTTSNGW;
/*===================================== /*=====================================
Class MQTTSNAggregateConnectionHandler Class MQTTSNAggregateConnectionHandler
=====================================*/ =====================================*/
MQTTSNAggregateConnectionHandler::MQTTSNAggregateConnectionHandler( MQTTSNAggregateConnectionHandler::MQTTSNAggregateConnectionHandler(Gateway* gateway)
Gateway* gateway)
{ {
_gateway = gateway; _gateway = gateway;
} }
@@ -40,8 +39,7 @@ MQTTSNAggregateConnectionHandler::~MQTTSNAggregateConnectionHandler()
/* /*
* CONNECT * CONNECT
*/ */
void MQTTSNAggregateConnectionHandler::handleConnect(Client* client, void MQTTSNAggregateConnectionHandler::handleConnect(Client* client, MQTTSNPacket* packet)
MQTTSNPacket* packet)
{ {
MQTTSNPacket_connectData data; MQTTSNPacket_connectData data;
if (packet->getCONNECT(&data) == 0) if (packet->getCONNECT(&data) == 0)
@@ -86,8 +84,7 @@ void MQTTSNAggregateConnectionHandler::handleConnect(Client* client,
{ {
if (tp->getType() == MQTTSN_TOPIC_TYPE_NORMAL) if (tp->getType() == MQTTSN_TOPIC_TYPE_NORMAL)
{ {
_gateway->getAdapterManager()->getAggregater()->removeAggregateTopic( _gateway->getAdapterManager()->getAggregater()->removeAggregateTopic(tp, client);
tp, client);
} }
tp = topics->getNextTopic(tp); tp = topics->getNextTopic(tp);
} }
@@ -124,8 +121,7 @@ void MQTTSNAggregateConnectionHandler::handleConnect(Client* client,
/* /*
* WILLMSG * WILLMSG
*/ */
void MQTTSNAggregateConnectionHandler::handleWillmsg(Client* client, void MQTTSNAggregateConnectionHandler::handleWillmsg(Client* client, MQTTSNPacket* packet)
MQTTSNPacket* packet)
{ {
if (!client->isWaitWillMsg()) if (!client->isWaitWillMsg())
{ {
@@ -160,8 +156,7 @@ void MQTTSNAggregateConnectionHandler::handleWillmsg(Client* client,
/* /*
* DISCONNECT * DISCONNECT
*/ */
void MQTTSNAggregateConnectionHandler::handleDisconnect(Client* client, void MQTTSNAggregateConnectionHandler::handleDisconnect(Client* client, MQTTSNPacket* packet)
MQTTSNPacket* packet)
{ {
MQTTSNPacket* snMsg = new MQTTSNPacket(); MQTTSNPacket* snMsg = new MQTTSNPacket();
snMsg->setDISCONNECT(0); snMsg->setDISCONNECT(0);
@@ -173,11 +168,9 @@ void MQTTSNAggregateConnectionHandler::handleDisconnect(Client* client,
/* /*
* PINGREQ * PINGREQ
*/ */
void MQTTSNAggregateConnectionHandler::handlePingreq(Client* client, void MQTTSNAggregateConnectionHandler::handlePingreq(Client* client, MQTTSNPacket* packet)
MQTTSNPacket* packet)
{ {
if ((client->isSleep() || client->isAwake()) if ((client->isSleep() || client->isAwake()) && client->getClientSleepPacket())
&& client->getClientSleepPacket())
{ {
sendStoredPublish(client); sendStoredPublish(client);
client->holdPingRequest(); client->holdPingRequest();

View File

@@ -63,13 +63,12 @@ void Adapter::setup(const char* adpterName, AdapterType adapterType)
string nameSecure = string(adpterName) + "-S"; string nameSecure = string(adpterName) + "-S";
idSecure.cstring = const_cast<char*>(nameSecure.c_str()); idSecure.cstring = const_cast<char*>(nameSecure.c_str());
Client* client = _gateway->getClientList()->createClient(0, &id, true, Client* client = _gateway->getClientList()->createClient(0, &id, true, false, TRANSPEARENT_TYPE);
false, TRANSPEARENT_TYPE);
setClient(client, false); setClient(client, false);
client->setAdapterType(adapterType); client->setAdapterType(adapterType);
client = _gateway->getClientList()->createClient(0, &idSecure, true, true, client = _gateway->getClientList()->createClient(0, &idSecure, true, true,
TRANSPEARENT_TYPE); TRANSPEARENT_TYPE);
setClient(client, true); setClient(client, true);
client->setAdapterType(adapterType); client->setAdapterType(adapterType);
} }
@@ -173,9 +172,8 @@ void Adapter::send(MQTTSNPacket* packet, Client* client)
} }
else else
{ {
WRITELOG( WRITELOG("%s %s No Secure connections %s 's packet is discarded.%s\n",
"%s %s No Secure connections %s 's packet is discarded.%s\n", ERRMSG_HEADER, client->getClientId(), ERRMSG_FOOTER);
ERRMSG_HEADER, client->getClientId(), ERRMSG_FOOTER);
return; return;
} }
} }
@@ -243,8 +241,7 @@ Proxy::~Proxy(void)
void Proxy::checkConnection(Client* client) void Proxy::checkConnection(Client* client)
{ {
if (client->isDisconnect() if (client->isDisconnect() || (client->isConnecting() && _responseTimer.isTimeup()))
|| (client->isConnecting() && _responseTimer.isTimeup()))
{ {
client->connectSended(); client->connectSended();
_responseTimer.start(PROXY_RESPONSE_DURATION * 1000UL); _responseTimer.start(PROXY_RESPONSE_DURATION * 1000UL);
@@ -258,8 +255,7 @@ void Proxy::checkConnection(Client* client)
ev->setClientRecvEvent(client, packet); ev->setClientRecvEvent(client, packet);
_gateway->getPacketEventQue()->post(ev); _gateway->getPacketEventQue()->post(ev);
} }
else if ((client->isActive() && _keepAliveTimer.isTimeup()) else if ((client->isActive() && _keepAliveTimer.isTimeup()) || (_isWaitingResp && _responseTimer.isTimeup()))
|| (_isWaitingResp && _responseTimer.isTimeup()))
{ {
MQTTSNPacket* packet = new MQTTSNPacket(); MQTTSNPacket* packet = new MQTTSNPacket();
MQTTSNString clientId = MQTTSNString_initializer; MQTTSNString clientId = MQTTSNString_initializer;

View File

@@ -39,8 +39,7 @@ AdapterManager::AdapterManager(Gateway* gw)
_aggregater = new Aggregater(gw); _aggregater = new Aggregater(gw);
} }
void AdapterManager::initialize(char* gwName, bool aggregate, bool forwarder, void AdapterManager::initialize(char* gwName, bool aggregate, bool forwarder, bool qosM1)
bool qosM1)
{ {
if (aggregate) if (aggregate)
{ {
@@ -91,8 +90,7 @@ Aggregater* AdapterManager::getAggregater(void)
bool AdapterManager::isAggregatedClient(Client* client) bool AdapterManager::isAggregatedClient(Client* client)
{ {
if (!_aggregater->isActive() || client->isQoSm1() || client->isAggregater() if (!_aggregater->isActive() || client->isQoSm1() || client->isAggregater() || client->isQoSm1Proxy())
|| client->isQoSm1Proxy())
{ {
return false; return false;
} }
@@ -128,8 +126,7 @@ Client* AdapterManager::getClient(Client* client)
return newClient; return newClient;
} }
int AdapterManager::unicastToClient(Client* client, MQTTSNPacket* packet, int AdapterManager::unicastToClient(Client* client, MQTTSNPacket* packet, ClientSendTask* task)
ClientSendTask* task)
{ {
char pbuf[SIZE_OF_LOG_PACKET * 3]; char pbuf[SIZE_OF_LOG_PACKET * 3];
Forwarder* fwd = client->getForwarder(); Forwarder* fwd = client->getForwarder();
@@ -141,10 +138,8 @@ int AdapterManager::unicastToClient(Client* client, MQTTSNPacket* packet,
WirelessNodeId* wnId = fwd->getWirelessNodeId(client); WirelessNodeId* wnId = fwd->getWirelessNodeId(client);
encap.setWirelessNodeId(wnId); encap.setWirelessNodeId(wnId);
task->log(client, packet); task->log(client, packet);
WRITELOG(FORMAT_Y_W_G, currentDateTime(), encap.getName(), RIGHTARROW, WRITELOG(FORMAT_Y_W_G, currentDateTime(), encap.getName(), RIGHTARROW, fwd->getId(), encap.print(pbuf));
fwd->getId(), encap.print(pbuf)); rc = encap.unicast(_gateway->getSensorNetwork(), fwd->getSensorNetAddr());
rc = encap.unicast(_gateway->getSensorNetwork(),
fwd->getSensorNetAddr());
} }
else else
{ {
@@ -159,8 +154,7 @@ int AdapterManager::unicastToClient(Client* client, MQTTSNPacket* packet,
} }
else else
{ {
rc = packet->unicast(_gateway->getSensorNetwork(), rc = packet->unicast(_gateway->getSensorNetwork(), client->getSensorNetAddress());
client->getSensorNetAddress());
} }
} }
return rc; return rc;

View File

@@ -129,8 +129,7 @@ ClientTopicElement* AggregateTopicElement::getFirstClientTopicElement(void)
return _head; return _head;
} }
ClientTopicElement* AggregateTopicElement::getNextClientTopicElement( ClientTopicElement* AggregateTopicElement::getNextClientTopicElement(ClientTopicElement* elmClient)
ClientTopicElement* elmClient)
{ {
return elmClient->_next; return elmClient->_next;
} }
@@ -262,8 +261,7 @@ void AggregateTopicTable::erase(AggregateTopicElement* elmTopic)
} }
} }
AggregateTopicElement* AggregateTopicTable::getAggregateTopicElement( AggregateTopicElement* AggregateTopicTable::getAggregateTopicElement(Topic* topic)
Topic* topic)
{ {
AggregateTopicElement* elm = _head; AggregateTopicElement* elm = _head;

View File

@@ -84,8 +84,7 @@ uint16_t Aggregater::getMsgId(Client* client, uint16_t clientMsgId)
return _msgIdTable.getMsgId(client, clientMsgId); return _msgIdTable.getMsgId(client, clientMsgId);
} }
AggregateTopicElement* Aggregater::addAggregateTopic(Topic* topic, AggregateTopicElement* Aggregater::addAggregateTopic(Topic* topic, Client* client)
Client* client)
{ {
return _topicTable.add(topic, client); return _topicTable.add(topic, client);
} }

View File

@@ -54,7 +54,7 @@ void BrokerRecvTask::run(void)
{ {
struct timeval timeout; struct timeval timeout;
MQTTGWPacket* packet = nullptr; MQTTGWPacket* packet = nullptr;
int rc; int rc;
Event* ev = nullptr; Event* ev = nullptr;
fd_set rset; fd_set rset;
fd_set wset; fd_set wset;
@@ -135,53 +135,43 @@ void BrokerRecvTask::run(void)
{ {
if (rc == 0) // Disconnected if (rc == 0) // Disconnected
{ {
WRITELOG( WRITELOG("%s BrokerRecvTask %s is disconnected by the broker.%s\n",
"%s BrokerRecvTask %s is disconnected by the broker.%s\n", ERRMSG_HEADER, client->getClientId(),
ERRMSG_HEADER, ERRMSG_FOOTER);
client->getClientId(), client->getNetwork()->close();
ERRMSG_FOOTER); client->disconnected();
client->getNetwork()->close();
client->disconnected();
} }
else if (rc == -1) else if (rc == -1)
{ {
WRITELOG( WRITELOG("%s BrokerRecvTask can't receive a packet from the broker errno=%d %s%s\n",
"%s BrokerRecvTask can't receive a packet from the broker errno=%d %s%s\n", ERRMSG_HEADER, errno, client->getClientId(),
ERRMSG_HEADER, errno, ERRMSG_FOOTER);
client->getClientId(),
ERRMSG_FOOTER);
} }
else if (rc == -2) else if (rc == -2)
{ {
WRITELOG( WRITELOG(
"%s BrokerRecvTask receive invalid length of packet from the broker. DISCONNECT %s %s\n", "%s BrokerRecvTask receive invalid length of packet from the broker. DISCONNECT %s %s\n",
ERRMSG_HEADER, ERRMSG_HEADER, client->getClientId(),
client->getClientId(),
ERRMSG_FOOTER); ERRMSG_FOOTER);
} }
else if (rc == -3) else if (rc == -3)
{ {
WRITELOG( WRITELOG("%s BrokerRecvTask can't allocate memories for the packet %s%s\n",
"%s BrokerRecvTask can't allocate memories for the packet %s%s\n", ERRMSG_HEADER, client->getClientId(),
ERRMSG_HEADER, ERRMSG_FOOTER);
client->getClientId(),
ERRMSG_FOOTER);
} }
delete packet; delete packet;
if ((rc == -1 || rc == -2) if ((rc == -1 || rc == -2) && (client->isActive() || client->isSleep() || client->isAwake()))
&& (client->isActive()
|| client->isSleep()
|| client->isAwake()))
{ {
client->getNetwork()->close(); client->getNetwork()->close();
client->disconnected(); client->disconnected();
} }
} }
} }
} }
nextClient: client = client->getNextClient(); nextClient: client = client->getNextClient();
} }
} }
} }
@@ -200,31 +190,26 @@ int BrokerRecvTask::log(Client* client, MQTTGWPacket* packet)
switch (packet->getType()) switch (packet->getType())
{ {
case CONNACK: case CONNACK:
WRITELOG(FORMAT_Y_Y_W, currentDateTime(), packet->getName(), LEFTARROWB, WRITELOG(FORMAT_Y_Y_W, currentDateTime(), packet->getName(), LEFTARROWB, client->getClientId(), packet->print(pbuf));
client->getClientId(), packet->print(pbuf));
break; break;
case PUBLISH: case PUBLISH:
WRITELOG(FORMAT_W_MSGID_Y_W_NL, currentDateTime(), packet->getName(), WRITELOG(FORMAT_W_MSGID_Y_W_NL, currentDateTime(), packet->getName(), packet->getMsgId(msgId), LEFTARROWB,
packet->getMsgId(msgId), LEFTARROWB, client->getClientId(), client->getClientId(), packet->print(pbuf));
packet->print(pbuf));
break; break;
case PUBACK: case PUBACK:
case PUBREC: case PUBREC:
case PUBREL: case PUBREL:
case PUBCOMP: case PUBCOMP:
WRITELOG(FORMAT_W_MSGID_Y_W, currentDateTime(), packet->getName(), WRITELOG(FORMAT_W_MSGID_Y_W, currentDateTime(), packet->getName(), packet->getMsgId(msgId), LEFTARROWB,
packet->getMsgId(msgId), LEFTARROWB, client->getClientId(), client->getClientId(), packet->print(pbuf));
packet->print(pbuf));
break; break;
case SUBACK: case SUBACK:
case UNSUBACK: case UNSUBACK:
WRITELOG(FORMAT_W_MSGID_Y_W, currentDateTime(), packet->getName(), WRITELOG(FORMAT_W_MSGID_Y_W, currentDateTime(), packet->getName(), packet->getMsgId(msgId), LEFTARROWB,
packet->getMsgId(msgId), LEFTARROWB, client->getClientId(), client->getClientId(), packet->print(pbuf));
packet->print(pbuf));
break; break;
case PINGRESP: case PINGRESP:
WRITELOG(FORMAT_Y_Y_W, currentDateTime(), packet->getName(), LEFTARROWB, WRITELOG(FORMAT_Y_Y_W, currentDateTime(), packet->getName(), LEFTARROWB, client->getClientId(), packet->print(pbuf));
client->getClientId(), packet->print(pbuf));
break; break;
default: default:
WRITELOG("Type=%x\n", packet->getType()); WRITELOG("Type=%x\n", packet->getType());

View File

@@ -94,28 +94,20 @@ void BrokerSendTask::run()
if (client->isSecureNetwork()) if (client->isSecureNetwork())
{ {
rc = client->getNetwork()->connect( rc = client->getNetwork()->connect((const char*) _gwparams->brokerName, (const char*) _gwparams->portSecure,
(const char*) _gwparams->brokerName, (const char*) _gwparams->rootCApath, (const char*) _gwparams->rootCAfile,
(const char*) _gwparams->portSecure, (const char*) _gwparams->certKey, (const char*) _gwparams->privateKey);
(const char*) _gwparams->rootCApath,
(const char*) _gwparams->rootCAfile,
(const char*) _gwparams->certKey,
(const char*) _gwparams->privateKey);
} }
else else
{ {
rc = client->getNetwork()->connect( rc = client->getNetwork()->connect((const char*) _gwparams->brokerName, (const char*) _gwparams->port);
(const char*) _gwparams->brokerName,
(const char*) _gwparams->port);
} }
if (!rc) if (!rc)
{ {
/* disconnect the broker and the client */ /* disconnect the broker and the client */
WRITELOG( WRITELOG("%s BrokerSendTask: %s can't connect to the broker. errno=%d %s %s\n",
"%s BrokerSendTask: %s can't connect to the broker. errno=%d %s %s\n", ERRMSG_HEADER, client->getClientId(), errno, strerror(errno), ERRMSG_FOOTER);
ERRMSG_HEADER, client->getClientId(), errno,
strerror(errno), ERRMSG_FOOTER);
delete ev; delete ev;
client->getNetwork()->close(); client->getNetwork()->close();
continue; continue;
@@ -139,10 +131,8 @@ void BrokerSendTask::run()
} }
else else
{ {
WRITELOG( WRITELOG("%s BrokerSendTask: %s can't send a packet to the broker. errno=%d %s %s\n",
"%s BrokerSendTask: %s can't send a packet to the broker. errno=%d %s %s\n", ERRMSG_HEADER, client->getClientId(), rc == -1 ? errno : 0, strerror(errno), ERRMSG_FOOTER);
ERRMSG_HEADER, client->getClientId(),
rc == -1 ? errno : 0, strerror(errno), ERRMSG_FOOTER);
if ( errno != EBADF) if ( errno != EBADF)
{ {
client->getNetwork()->close(); client->getNetwork()->close();
@@ -174,12 +164,11 @@ void BrokerSendTask::log(Client* client, MQTTGWPacket* packet)
{ {
case CONNECT: case CONNECT:
WRITELOG(FORMAT_Y_Y_W, currentDateTime(), packet->getName(), WRITELOG(FORMAT_Y_Y_W, currentDateTime(), packet->getName(),
RIGHTARROWB, client->getClientId(), packet->print(pbuf)); RIGHTARROWB, client->getClientId(), packet->print(pbuf));
break; break;
case PUBLISH: case PUBLISH:
WRITELOG(FORMAT_W_MSGID_Y_W, currentDateTime(), packet->getName(), WRITELOG(FORMAT_W_MSGID_Y_W, currentDateTime(), packet->getName(), packet->getMsgId(msgId), RIGHTARROWB,
packet->getMsgId(msgId), RIGHTARROWB, client->getClientId(), client->getClientId(), packet->print(pbuf));
packet->print(pbuf));
break; break;
case SUBSCRIBE: case SUBSCRIBE:
case UNSUBSCRIBE: case UNSUBSCRIBE:
@@ -187,17 +176,16 @@ void BrokerSendTask::log(Client* client, MQTTGWPacket* packet)
case PUBREC: case PUBREC:
case PUBREL: case PUBREL:
case PUBCOMP: case PUBCOMP:
WRITELOG(FORMAT_W_MSGID_Y_W, currentDateTime(), packet->getName(), WRITELOG(FORMAT_W_MSGID_Y_W, currentDateTime(), packet->getName(), packet->getMsgId(msgId), RIGHTARROWB,
packet->getMsgId(msgId), RIGHTARROWB, client->getClientId(), client->getClientId(), packet->print(pbuf));
packet->print(pbuf));
break; break;
case PINGREQ: case PINGREQ:
WRITELOG(FORMAT_Y_Y_W, currentDateTime(), packet->getName(), WRITELOG(FORMAT_Y_Y_W, currentDateTime(), packet->getName(),
RIGHTARROWB, client->getClientId(), packet->print(pbuf)); RIGHTARROWB, client->getClientId(), packet->print(pbuf));
break; break;
case DISCONNECT: case DISCONNECT:
WRITELOG(FORMAT_Y_Y_W, currentDateTime(), packet->getName(), WRITELOG(FORMAT_Y_Y_W, currentDateTime(), packet->getName(),
RIGHTARROWB, client->getClientId(), packet->print(pbuf)); RIGHTARROWB, client->getClientId(), packet->print(pbuf));
break; break;
default: default:
break; break;

View File

@@ -31,16 +31,14 @@ char* currentDateTime(void);
/*===================================== /*=====================================
Class Client Class Client
=====================================*/ =====================================*/
static const char* theClientStatus[] = static const char* theClientStatus[] = { "InPool", "Disconnected", "TryConnecting", "Connecting", "Active", "Asleep", "Awake",
{ "InPool", "Disconnected", "TryConnecting", "Connecting", "Active", "Asleep",
"Awake",
"Lost" }; "Lost" };
Client::Client(bool secure) Client::Client(bool secure)
{ {
_packetId = 0; _packetId = 0;
_snMsgId = 0; _snMsgId = 0;
_status = Cstat_Free; _status = Cstat_Free;
_keepAliveMsec = 0; _keepAliveMsec = 0;
_topics = new Topics(); _topics = new Topics();
_clientId = nullptr; _clientId = nullptr;
@@ -121,13 +119,11 @@ int Client::setClientSleepPacket(MQTTGWPacket* packet)
int rc = _clientSleepPacketQue.post(packet); int rc = _clientSleepPacketQue.post(packet);
if (rc) if (rc)
{ {
WRITELOG("%s %s is sleeping. the packet was saved.\n", WRITELOG("%s %s is sleeping. the packet was saved.\n", currentDateTime(), _clientId);
currentDateTime(), _clientId);
} }
else else
{ {
WRITELOG("%s %s is sleeping but discard the packet.\n", WRITELOG("%s %s is sleeping but discard the packet.\n", currentDateTime(), _clientId);
currentDateTime(), _clientId);
} }
return rc; return rc;
} }
@@ -147,13 +143,11 @@ int Client::setProxyPacket(MQTTSNPacket* packet)
int rc = _proxyPacketQue.post(packet); int rc = _proxyPacketQue.post(packet);
if (rc) if (rc)
{ {
WRITELOG("%s %s is Disconnected. the packet was saved.\n", WRITELOG("%s %s is Disconnected. the packet was saved.\n", currentDateTime(), _clientId);
currentDateTime(), _clientId);
} }
else else
{ {
WRITELOG("%s %s is Disconnected and discard the packet.\n", WRITELOG("%s %s is Disconnected and discard the packet.\n", currentDateTime(), _clientId);
currentDateTime(), _clientId);
} }
return rc; return rc;
} }
@@ -231,8 +225,7 @@ bool Client::erasable(void)
void Client::updateStatus(MQTTSNPacket* packet) void Client::updateStatus(MQTTSNPacket* packet)
{ {
if (((_status == Cstat_Disconnected) || (_status == Cstat_Lost)) if (((_status == Cstat_Disconnected) || (_status == Cstat_Lost)) && packet->getType() == MQTTSN_CONNECT)
&& packet->getType() == MQTTSN_CONNECT)
{ {
setKeepAlive(packet); setKeepAlive(packet);
} }
@@ -288,7 +281,7 @@ void Client::updateStatus(MQTTSNPacket* packet)
default: default:
break; break;
} }
} DEBUGLOG("Client Status = %s\n", theClientStatus[_status]); }DEBUGLOG("Client Status = %s\n", theClientStatus[_status]);
} }
void Client::updateStatus(ClientStatus stat) void Client::updateStatus(ClientStatus stat)
@@ -326,7 +319,7 @@ void Client::tryConnect(void)
bool Client::isCleanSession(void) bool Client::isCleanSession(void)
{ {
return _sessionStatus; return _sessionStatus;
} }
bool Client::isConnectSendable(void) bool Client::isConnectSendable(void)

View File

@@ -32,8 +32,8 @@ ClientList::ClientList(Gateway* gw)
_authorize = false; _authorize = false;
_firstClient = nullptr; _firstClient = nullptr;
_endClient = nullptr; _endClient = nullptr;
_clientsPool = new ClientsPool(); _clientsPool = new ClientsPool();
_gateway = gw; _gateway = gw;
} }
ClientList::~ClientList() ClientList::~ClientList()
@@ -49,18 +49,18 @@ ClientList::~ClientList()
cl = ncl; cl = ncl;
}; };
if (_clientsPool) if (_clientsPool)
{ {
delete _clientsPool; delete _clientsPool;
} }
_mutex.unlock(); _mutex.unlock();
} }
void ClientList::initialize(bool aggregate) void ClientList::initialize(bool aggregate)
{ {
_clientsPool->allocate(_gateway->getGWParams()->maxClients); _clientsPool->allocate(_gateway->getGWParams()->maxClients);
if (_gateway->getGWParams()->clientAuthentication) if (_gateway->getGWParams()->clientAuthentication)
{ {
int type = TRANSPEARENT_TYPE; int type = TRANSPEARENT_TYPE;
if (aggregate) if (aggregate)
@@ -71,7 +71,7 @@ void ClientList::initialize(bool aggregate)
_authorize = true; _authorize = true;
} }
if (_gateway->getGWParams()->predefinedTopic) if (_gateway->getGWParams()->predefinedTopic)
{ {
setPredefinedTopics(aggregate); setPredefinedTopics(aggregate);
} }
@@ -79,21 +79,17 @@ void ClientList::initialize(bool aggregate)
void ClientList::setClientList(int type) void ClientList::setClientList(int type)
{ {
if (!createList(_gateway->getGWParams()->clientListName, type)) if (!createList(_gateway->getGWParams()->clientListName, type))
{ {
throw EXCEPTION( throw EXCEPTION("ClientList::setClientList Client list not found!", 0);
"ClientList::setClientList Client list not found!", 0);
} }
} }
void ClientList::setPredefinedTopics(bool aggrecate) void ClientList::setPredefinedTopics(bool aggrecate)
{ {
if (!readPredefinedList(_gateway->getGWParams()->predefinedTopicFileName, if (!readPredefinedList(_gateway->getGWParams()->predefinedTopicFileName, aggrecate))
aggrecate))
{ {
throw EXCEPTION( throw EXCEPTION("ClientList::setPredefinedTopics PredefindTopic list not found!", 0);
"ClientList::setPredefinedTopics PredefindTopic list not found!",
0);
} }
} }
@@ -161,15 +157,13 @@ bool ClientList::createList(const char* fileName, int type)
forwarder = (data.find("forwarder") != string::npos); forwarder = (data.find("forwarder") != string::npos);
secure = (data.find("secureConnection") != string::npos); secure = (data.find("secureConnection") != string::npos);
stable = !(data.find("unstableLine") != string::npos); stable = !(data.find("unstableLine") != string::npos);
if ((qos_1 && type == QOSM1PROXY_TYPE) if ((qos_1 && type == QOSM1PROXY_TYPE) || (!qos_1 && type == AGGREGATER_TYPE))
|| (!qos_1 && type == AGGREGATER_TYPE))
{ {
createClient(&netAddr, &clientId, stable, secure, type); createClient(&netAddr, &clientId, stable, secure, type);
} }
else if (forwarder && type == FORWARDER_TYPE) else if (forwarder && type == FORWARDER_TYPE)
{ {
_gateway->getAdapterManager()->getForwarderList()->addForwarder( _gateway->getAdapterManager()->getForwarderList()->addForwarder(&netAddr, &clientId);
&netAddr, &clientId);
} }
else if (type == TRANSPEARENT_TYPE) else if (type == TRANSPEARENT_TYPE)
{ {
@@ -230,8 +224,7 @@ bool ClientList::readPredefinedList(const char* fileName, bool aggregate)
} }
else else
{ {
WRITELOG("ClientList can not open the Predefined Topic List. %s\n", WRITELOG("ClientList can not open the Predefined Topic List. %s\n", fileName);
fileName);
return false; return false;
} }
return rc; return rc;
@@ -327,8 +320,7 @@ Client* ClientList::getClient(MQTTSNString* clientId)
while (client != nullptr) while (client != nullptr)
{ {
if (strncmp((const char*) client->getClientId(), clID, if (strncmp((const char*) client->getClientId(), clID, MQTTSNstrlen(*clientId)) == 0)
MQTTSNstrlen(*clientId)) == 0)
{ {
_mutex.unlock(); _mutex.unlock();
return client; return client;
@@ -339,14 +331,12 @@ Client* ClientList::getClient(MQTTSNString* clientId)
return 0; return 0;
} }
Client* ClientList::createClient(SensorNetAddress* addr, MQTTSNString* clientId, Client* ClientList::createClient(SensorNetAddress* addr, MQTTSNString* clientId, int type)
int type)
{ {
return createClient(addr, clientId, false, false, type); return createClient(addr, clientId, false, false, type);
} }
Client* ClientList::createClient(SensorNetAddress* addr, MQTTSNString* clientId, Client* ClientList::createClient(SensorNetAddress* addr, MQTTSNString* clientId, bool unstableLine, bool secure, int type)
bool unstableLine, bool secure, int type)
{ {
Client* client = getClient(addr); Client* client = getClient(addr);
if (client) if (client)
@@ -355,16 +345,16 @@ Client* ClientList::createClient(SensorNetAddress* addr, MQTTSNString* clientId,
} }
/* acquire a free client */ /* acquire a free client */
client = _clientsPool->getClient(); client = _clientsPool->getClient();
if (!client) if (!client)
{ {
WRITELOG("%s%sMax number of Clients%s\n", currentDateTime(), WRITELOG("%s%sMax number of Clients%s\n", currentDateTime(),
ERRMSG_HEADER, ERRMSG_FOOTER); ERRMSG_HEADER, ERRMSG_FOOTER);
return nullptr; return nullptr;
} }
client->disconnected(); client->disconnected();
if (addr) if (addr)
{ {
client->setClientAddress(addr); client->setClientAddress(addr);
@@ -410,19 +400,17 @@ Client* ClientList::createClient(SensorNetAddress* addr, MQTTSNString* clientId,
return client; return client;
} }
Client* ClientList::createPredefinedTopic(MQTTSNString* clientId, Client* ClientList::createPredefinedTopic(MQTTSNString* clientId, string topicName, uint16_t topicId, bool aggregate)
string topicName, uint16_t topicId, bool aggregate)
{ {
if (topicId == 0) if (topicId == 0)
{ {
WRITELOG("Invalid TopicId. Predefined Topic %s, TopicId is 0. \n", WRITELOG("Invalid TopicId. Predefined Topic %s, TopicId is 0. \n", topicName.c_str());
topicName.c_str());
return nullptr; return nullptr;
} }
if (strcmp(clientId->cstring, common_topic) == 0) if (strcmp(clientId->cstring, common_topic) == 0)
{ {
_gateway->getTopics()->add((const char*) topicName.c_str(), topicId); _gateway->getTopics()->add((const char*) topicName.c_str(), topicId);
return nullptr; return nullptr;
} }
else else
@@ -490,63 +478,62 @@ bool ClientList::isAuthorized()
ClientsPool::ClientsPool() ClientsPool::ClientsPool()
{ {
_clientCnt = 0; _clientCnt = 0;
_firstClient = nullptr; _firstClient = nullptr;
_endClient = nullptr; _endClient = nullptr;
} }
ClientsPool::~ClientsPool() ClientsPool::~ClientsPool()
{ {
Client* cl = _firstClient; Client* cl = _firstClient;
Client* ncl; Client* ncl;
while (cl != nullptr) while (cl != nullptr)
{ {
ncl = cl->_nextClient; ncl = cl->_nextClient;
delete cl; delete cl;
cl = ncl; cl = ncl;
}; };
} }
void ClientsPool::allocate(int maxClients) void ClientsPool::allocate(int maxClients)
{ {
Client* cl = nullptr; Client* cl = nullptr;
_firstClient = new Client(); _firstClient = new Client();
for (int i = 0; i < maxClients; i++) for (int i = 0; i < maxClients; i++)
{ {
if ((cl = new Client()) == nullptr) if ((cl = new Client()) == nullptr)
{ {
throw Exception( throw Exception("ClientsPool::Can't allocate max number of clients\n", 0);
"ClientsPool::Can't allocate max number of clients\n", 0); }
} cl->_nextClient = _firstClient;
cl->_nextClient = _firstClient; _firstClient = cl;
_firstClient = cl; _clientCnt++;
_clientCnt++; }
}
} }
Client* ClientsPool::getClient(void) Client* ClientsPool::getClient(void)
{ {
while (_firstClient != nullptr) while (_firstClient != nullptr)
{ {
Client* cl = _firstClient; Client* cl = _firstClient;
_firstClient = cl->_nextClient; _firstClient = cl->_nextClient;
cl->_nextClient = nullptr; cl->_nextClient = nullptr;
_clientCnt--; _clientCnt--;
return cl; return cl;
} }
return nullptr; return nullptr;
} }
void ClientsPool::setClient(Client* client) void ClientsPool::setClient(Client* client)
{ {
if (client) if (client)
{ {
client->_nextClient = _firstClient; client->_nextClient = _firstClient;
_firstClient = client; _firstClient = client;
_clientCnt++; _clientCnt++;
} }
} }

View File

@@ -29,23 +29,18 @@ char* currentDateTime(void);
=====================================*/ =====================================*/
ClientRecvTask::ClientRecvTask(Gateway* gateway) ClientRecvTask::ClientRecvTask(Gateway* gateway)
{ {
_gateway = gateway; _gateway = gateway;
_gateway->attach((Thread*) this); _gateway->attach((Thread*) this);
_sensorNetwork = _gateway->getSensorNetwork(); _sensorNetwork = _gateway->getSensorNetwork();
setTaskName("ClientRecvTask"); setTaskName("ClientRecvTask");
} }
ClientRecvTask::~ClientRecvTask() ClientRecvTask::~ClientRecvTask()
{ {
} }
/**
* Initialize SensorNetwork
*/
void ClientRecvTask::initialize(int argc, char** argv) void ClientRecvTask::initialize(int argc, char** argv)
{ {
_sensorNetwork->initialize();
} }
/* /*
@@ -55,305 +50,286 @@ void ClientRecvTask::initialize(int argc, char** argv)
*/ */
void ClientRecvTask::run() void ClientRecvTask::run()
{ {
Event* ev = nullptr; Event* ev = nullptr;
AdapterManager* adpMgr = _gateway->getAdapterManager(); AdapterManager* adpMgr = _gateway->getAdapterManager();
QoSm1Proxy* qosm1Proxy = adpMgr->getQoSm1Proxy(); QoSm1Proxy* qosm1Proxy = adpMgr->getQoSm1Proxy();
int clientType = int clientType = adpMgr->isAggregaterActive() ? AGGREGATER_TYPE : TRANSPEARENT_TYPE;
adpMgr->isAggregaterActive() ? AGGREGATER_TYPE : TRANSPEARENT_TYPE; ClientList* clientList = _gateway->getClientList();
ClientList* clientList = _gateway->getClientList(); EventQue* packetEventQue = _gateway->getPacketEventQue();
EventQue* packetEventQue = _gateway->getPacketEventQue(); EventQue* clientsendQue = _gateway->getClientSendQue();
EventQue* clientsendQue = _gateway->getClientSendQue();
char buf[128]; char buf[128];
while (true) while (true)
{ {
Client* client = nullptr; Client* client = nullptr;
Forwarder* fwd = nullptr; Forwarder* fwd = nullptr;
WirelessNodeId nodeId; WirelessNodeId nodeId;
MQTTSNPacket* packet = new MQTTSNPacket(); MQTTSNPacket* packet = new MQTTSNPacket();
int packetLen = packet->recv(_sensorNetwork); int packetLen = packet->recv(_sensorNetwork);
if (CHK_SIGINT) if (CHK_SIGINT)
{ {
WRITELOG("%s %s stopped.\n", currentDateTime(), getTaskName()); WRITELOG("%s %s stopped.\n", currentDateTime(), getTaskName());
delete packet; delete packet;
return; return;
} }
if (packetLen < 2) if (packetLen < 2)
{ {
delete packet; delete packet;
continue; continue;
} }
if (packet->getType() <= MQTTSN_ADVERTISE if (packet->getType() <= MQTTSN_ADVERTISE || packet->getType() == MQTTSN_GWINFO)
|| packet->getType() == MQTTSN_GWINFO) {
{ delete packet;
delete packet; continue;
continue; }
}
if (packet->getType() == MQTTSN_SEARCHGW) if (packet->getType() == MQTTSN_SEARCHGW)
{ {
/* write log and post Event */ /* write log and post Event */
log(0, packet, 0); log(0, packet, 0);
ev = new Event(); ev = new Event();
ev->setBrodcastEvent(packet); ev->setBrodcastEvent(packet);
packetEventQue->post(ev); packetEventQue->post(ev);
continue; continue;
} }
SensorNetAddress* senderAddr = SensorNetAddress* senderAddr = _gateway->getSensorNetwork()->getSenderAddress();
_gateway->getSensorNetwork()->getSenderAddress();
if (packet->getType() == MQTTSN_ENCAPSULATED) if (packet->getType() == MQTTSN_ENCAPSULATED)
{ {
fwd = fwd = _gateway->getAdapterManager()->getForwarderList()->getForwarder(senderAddr);
_gateway->getAdapterManager()->getForwarderList()->getForwarder(
senderAddr);
if (fwd != nullptr) if (fwd != nullptr)
{ {
MQTTSNString fwdName = MQTTSNString_initializer; MQTTSNString fwdName = MQTTSNString_initializer;
fwdName.cstring = const_cast<char *>(fwd->getName()); fwdName.cstring = const_cast<char *>(fwd->getName());
log(0, packet, &fwdName); log(0, packet, &fwdName);
/* get the packet from the encapsulation message */ /* get the packet from the encapsulation message */
MQTTSNGWEncapsulatedPacket encap; MQTTSNGWEncapsulatedPacket encap;
encap.desirialize(packet->getPacketData(), encap.desirialize(packet->getPacketData(), packet->getPacketLength());
packet->getPacketLength()); nodeId.setId(encap.getWirelessNodeId());
nodeId.setId(encap.getWirelessNodeId()); client = fwd->getClient(&nodeId);
client = fwd->getClient(&nodeId); packet = encap.getMQTTSNPacket();
packet = encap.getMQTTSNPacket(); }
} }
} else
else {
{ /* Check the client belonging to QoS-1Proxy ? */
/* Check the client belonging to QoS-1Proxy ? */
if (qosm1Proxy->isActive()) if (qosm1Proxy->isActive())
{ {
const char* clientName = qosm1Proxy->getClientId(senderAddr); const char* clientName = qosm1Proxy->getClientId(senderAddr);
if (clientName != nullptr) if (clientName != nullptr)
{ {
client = qosm1Proxy->getClient(); client = qosm1Proxy->getClient();
if (!packet->isQoSMinusPUBLISH()) if (!packet->isQoSMinusPUBLISH())
{ {
log(clientName, packet); log(clientName, packet);
WRITELOG( WRITELOG("%s %s %s can send only PUBLISH with QoS-1.%s\n",
"%s %s %s can send only PUBLISH with QoS-1.%s\n", ERRMSG_HEADER, clientName, senderAddr->sprint(buf), ERRMSG_FOOTER);
ERRMSG_HEADER, clientName, delete packet;
senderAddr->sprint(buf), ERRMSG_FOOTER); continue;
delete packet; }
continue; }
} }
}
}
if (client == nullptr) if (client == nullptr)
{ {
client = _gateway->getClientList()->getClient(senderAddr); client = _gateway->getClientList()->getClient(senderAddr);
} }
} }
if (client != nullptr) if (client != nullptr)
{ {
log(client, packet, 0); log(client, packet, 0);
if (client->isDisconnect() && packet->getType() != MQTTSN_CONNECT) if (client->isDisconnect() && packet->getType() != MQTTSN_CONNECT)
{ {
WRITELOG("%s MQTTSNGWClientRecvTask %s is not connecting.%s\n", WRITELOG("%s MQTTSNGWClientRecvTask %s is not connecting.%s\n",
ERRMSG_HEADER, client->getClientId(), ERRMSG_FOOTER); ERRMSG_HEADER, client->getClientId(), ERRMSG_FOOTER);
/* send DISCONNECT to the client, if it is not connected */ /* send DISCONNECT to the client, if it is not connected */
MQTTSNPacket* snPacket = new MQTTSNPacket(); MQTTSNPacket* snPacket = new MQTTSNPacket();
snPacket->setDISCONNECT(0); snPacket->setDISCONNECT(0);
ev = new Event(); ev = new Event();
ev->setClientSendEvent(client, snPacket); ev->setClientSendEvent(client, snPacket);
clientsendQue->post(ev); clientsendQue->post(ev);
delete packet; delete packet;
continue; continue;
} }
else else
{ {
ev = new Event(); ev = new Event();
ev->setClientRecvEvent(client, packet); ev->setClientRecvEvent(client, packet);
packetEventQue->post(ev); packetEventQue->post(ev);
} }
} }
else else
{ {
/* new client */ /* new client */
if (packet->getType() == MQTTSN_CONNECT) if (packet->getType() == MQTTSN_CONNECT)
{ {
MQTTSNPacket_connectData data; MQTTSNPacket_connectData data;
memset(&data, 0, sizeof(MQTTSNPacket_connectData)); memset(&data, 0, sizeof(MQTTSNPacket_connectData));
if (!packet->getCONNECT(&data)) if (!packet->getCONNECT(&data))
{ {
log(0, packet, &data.clientID); log(0, packet, &data.clientID);
WRITELOG("%s CONNECT message form %s is incorrect.%s\n", WRITELOG("%s CONNECT message form %s is incorrect.%s\n",
ERRMSG_HEADER, senderAddr->sprint(buf), ERRMSG_HEADER, senderAddr->sprint(buf),
ERRMSG_FOOTER); ERRMSG_FOOTER);
delete packet; delete packet;
continue; continue;
} }
client = clientList->getClient(&data.clientID); client = clientList->getClient(&data.clientID);
if (fwd != nullptr) if (fwd != nullptr)
{ {
if (client == nullptr) if (client == nullptr)
{ {
/* create a new client */ /* create a new client */
client = clientList->createClient(0, &data.clientID, client = clientList->createClient(0, &data.clientID, clientType);
clientType); }
} /* Add to a forwarded client list of forwarder. */
/* Add to a forwarded client list of forwarder. */ fwd->addClient(client, &nodeId);
fwd->addClient(client, &nodeId); }
} else
else {
{ if (client)
if (client) {
{ /* Authentication is not required */
/* Authentication is not required */ if (_gateway->getGWParams()->clientAuthentication == false)
if (_gateway->getGWParams()->clientAuthentication {
== false) client->setClientAddress(senderAddr);
{ }
client->setClientAddress(senderAddr); }
} else
} {
else /* create a new client */
{ client = clientList->createClient(senderAddr, &data.clientID, clientType);
/* create a new client */ }
client = clientList->createClient(senderAddr, }
&data.clientID, clientType);
}
}
log(client, packet, &data.clientID); log(client, packet, &data.clientID);
if (client == nullptr) if (client == nullptr)
{ {
WRITELOG( WRITELOG("%s Client(%s) was rejected. CONNECT message has been discarded.%s\n",
"%s Client(%s) was rejected. CONNECT message has been discarded.%s\n", ERRMSG_HEADER, senderAddr->sprint(buf),
ERRMSG_HEADER, senderAddr->sprint(buf), ERRMSG_FOOTER);
ERRMSG_FOOTER); delete packet;
delete packet; continue;
continue; }
}
/* post Client RecvEvent */ /* post Client RecvEvent */
ev = new Event(); ev = new Event();
ev->setClientRecvEvent(client, packet); ev->setClientRecvEvent(client, packet);
packetEventQue->post(ev); packetEventQue->post(ev);
} }
else else
{ {
log(client, packet, 0); log(client, packet, 0);
if (packet->getType() == MQTTSN_ENCAPSULATED) if (packet->getType() == MQTTSN_ENCAPSULATED)
{ {
WRITELOG( WRITELOG(
"%s MQTTSNGWClientRecvTask Forwarder(%s) is not declared by ClientList file. message has been discarded.%s\n", "%s MQTTSNGWClientRecvTask Forwarder(%s) is not declared by ClientList file. message has been discarded.%s\n",
ERRMSG_HEADER, ERRMSG_HEADER, _sensorNetwork->getSenderAddress()->sprint(buf),
_sensorNetwork->getSenderAddress()->sprint(buf), ERRMSG_FOOTER);
ERRMSG_FOOTER); }
} else
else {
{ WRITELOG("%s MQTTSNGWClientRecvTask Client(%s) is not connecting. message has been discarded.%s\n",
WRITELOG( ERRMSG_HEADER, senderAddr->sprint(buf),
"%s MQTTSNGWClientRecvTask Client(%s) is not connecting. message has been discarded.%s\n", ERRMSG_FOOTER);
ERRMSG_HEADER, senderAddr->sprint(buf), }
ERRMSG_FOOTER); delete packet;
} }
delete packet; }
} }
}
}
} }
void ClientRecvTask::log(Client* client, MQTTSNPacket* packet, MQTTSNString* id) void ClientRecvTask::log(Client* client, MQTTSNPacket* packet, MQTTSNString* id)
{ {
const char* clientId; const char* clientId;
char cstr[MAX_CLIENTID_LENGTH + 1]; char cstr[MAX_CLIENTID_LENGTH + 1];
if (id) if (id)
{ {
if (id->cstring) if (id->cstring)
{ {
strncpy(cstr, id->cstring, strlen(id->cstring)); strncpy(cstr, id->cstring, strlen(id->cstring));
clientId = cstr; clientId = cstr;
} }
else else
{ {
memset((void*) cstr, 0, id->lenstring.len + 1); memset((void*) cstr, 0, id->lenstring.len + 1);
strncpy(cstr, id->lenstring.data, id->lenstring.len); strncpy(cstr, id->lenstring.data, id->lenstring.len);
clientId = cstr; clientId = cstr;
} }
} }
else if (client) else if (client)
{ {
clientId = client->getClientId(); clientId = client->getClientId();
} }
else else
{ {
clientId = UNKNOWNCL; clientId = UNKNOWNCL;
} }
log(clientId, packet); log(clientId, packet);
} }
void ClientRecvTask::log(const char* clientId, MQTTSNPacket* packet) void ClientRecvTask::log(const char* clientId, MQTTSNPacket* packet)
{ {
char pbuf[ SIZE_OF_LOG_PACKET * 3 + 1]; char pbuf[ SIZE_OF_LOG_PACKET * 3 + 1];
char msgId[6]; char msgId[6];
switch (packet->getType()) switch (packet->getType())
{ {
case MQTTSN_SEARCHGW: case MQTTSN_SEARCHGW:
WRITELOG(FORMAT_Y_G_G_NL, currentDateTime(), packet->getName(), WRITELOG(FORMAT_Y_G_G_NL, currentDateTime(), packet->getName(),
LEFTARROW, CLIENT, packet->print(pbuf)); LEFTARROW, CLIENT, packet->print(pbuf));
break; break;
case MQTTSN_CONNECT: case MQTTSN_CONNECT:
case MQTTSN_PINGREQ: case MQTTSN_PINGREQ:
WRITELOG(FORMAT_Y_G_G_NL, currentDateTime(), packet->getName(), WRITELOG(FORMAT_Y_G_G_NL, currentDateTime(), packet->getName(),
LEFTARROW, clientId, packet->print(pbuf)); LEFTARROW, clientId, packet->print(pbuf));
break; break;
case MQTTSN_DISCONNECT: case MQTTSN_DISCONNECT:
case MQTTSN_WILLTOPICUPD: case MQTTSN_WILLTOPICUPD:
case MQTTSN_WILLMSGUPD: case MQTTSN_WILLMSGUPD:
case MQTTSN_WILLTOPIC: case MQTTSN_WILLTOPIC:
case MQTTSN_WILLMSG: case MQTTSN_WILLMSG:
WRITELOG(FORMAT_Y_G_G, currentDateTime(), packet->getName(), LEFTARROW, WRITELOG(FORMAT_Y_G_G, currentDateTime(), packet->getName(), LEFTARROW, clientId, packet->print(pbuf));
clientId, packet->print(pbuf)); break;
break; case MQTTSN_PUBLISH:
case MQTTSN_PUBLISH: case MQTTSN_REGISTER:
case MQTTSN_REGISTER: case MQTTSN_SUBSCRIBE:
case MQTTSN_SUBSCRIBE: case MQTTSN_UNSUBSCRIBE:
case MQTTSN_UNSUBSCRIBE: WRITELOG(FORMAT_G_MSGID_G_G_NL, currentDateTime(), packet->getName(), packet->getMsgId(msgId), LEFTARROW, clientId,
WRITELOG(FORMAT_G_MSGID_G_G_NL, currentDateTime(), packet->getName(), packet->print(pbuf));
packet->getMsgId(msgId), LEFTARROW, clientId, break;
packet->print(pbuf)); case MQTTSN_REGACK:
break; case MQTTSN_PUBACK:
case MQTTSN_REGACK: case MQTTSN_PUBREC:
case MQTTSN_PUBACK: case MQTTSN_PUBREL:
case MQTTSN_PUBREC: case MQTTSN_PUBCOMP:
case MQTTSN_PUBREL: WRITELOG(FORMAT_G_MSGID_G_G, currentDateTime(), packet->getName(), packet->getMsgId(msgId), LEFTARROW, clientId,
case MQTTSN_PUBCOMP: packet->print(pbuf));
WRITELOG(FORMAT_G_MSGID_G_G, currentDateTime(), packet->getName(), break;
packet->getMsgId(msgId), LEFTARROW, clientId, case MQTTSN_ENCAPSULATED:
packet->print(pbuf)); WRITELOG(FORMAT_Y_G_G, currentDateTime(), packet->getName(), LEFTARROW, clientId, packet->print(pbuf));
break; break;
case MQTTSN_ENCAPSULATED: default:
WRITELOG(FORMAT_Y_G_G, currentDateTime(), packet->getName(), LEFTARROW, WRITELOG(FORMAT_W_NL, currentDateTime(), packet->getName(), LEFTARROW, clientId, packet->print(pbuf));
clientId, packet->print(pbuf)); break;
break; }
default:
WRITELOG(FORMAT_W_NL, currentDateTime(), packet->getName(), LEFTARROW,
clientId, packet->print(pbuf));
break;
}
} }

View File

@@ -63,9 +63,8 @@ void ClientSendTask::run()
if (packet->broadcast(_sensorNetwork) < 0) if (packet->broadcast(_sensorNetwork) < 0)
{ {
WRITELOG( WRITELOG("%s ClientSendTask can't multicast a packet Error=%d%s\n",
"%s ClientSendTask can't multicast a packet Error=%d%s\n", ERRMSG_HEADER, errno, ERRMSG_FOOTER);
ERRMSG_HEADER, errno, ERRMSG_FOOTER);
} }
} }
else else
@@ -85,12 +84,9 @@ void ClientSendTask::run()
if (rc < 0) if (rc < 0)
{ {
WRITELOG( WRITELOG("%s ClientSendTask can't send a packet to the client %s. Error=%d%s\n",
"%s ClientSendTask can't send a packet to the client %s. Error=%d%s\n", ERRMSG_HEADER, (client ? (const char*) client->getClientId() : UNKNOWNCL),
ERRMSG_HEADER, errno, ERRMSG_FOOTER);
(client ?
(const char*) client->getClientId() : UNKNOWNCL),
errno, ERRMSG_FOOTER);
} }
} }
delete ev; delete ev;
@@ -101,15 +97,14 @@ void ClientSendTask::log(Client* client, MQTTSNPacket* packet)
{ {
char pbuf[SIZE_OF_LOG_PACKET * 3 + 1]; char pbuf[SIZE_OF_LOG_PACKET * 3 + 1];
char msgId[6]; char msgId[6];
const char* clientId = const char* clientId = client ? (const char*) client->getClientId() : UNKNOWNCL;
client ? (const char*) client->getClientId() : UNKNOWNCL;
switch (packet->getType()) switch (packet->getType())
{ {
case MQTTSN_ADVERTISE: case MQTTSN_ADVERTISE:
case MQTTSN_GWINFO: case MQTTSN_GWINFO:
WRITELOG(FORMAT_Y_W_G, currentDateTime(), packet->getName(), RIGHTARROW, WRITELOG(FORMAT_Y_W_G, currentDateTime(), packet->getName(), RIGHTARROW,
CLIENTS, packet->print(pbuf)); CLIENTS, packet->print(pbuf));
break; break;
case MQTTSN_CONNACK: case MQTTSN_CONNACK:
case MQTTSN_DISCONNECT: case MQTTSN_DISCONNECT:
@@ -118,13 +113,11 @@ void ClientSendTask::log(Client* client, MQTTSNPacket* packet)
case MQTTSN_WILLTOPICRESP: case MQTTSN_WILLTOPICRESP:
case MQTTSN_WILLMSGRESP: case MQTTSN_WILLMSGRESP:
case MQTTSN_PINGRESP: case MQTTSN_PINGRESP:
WRITELOG(FORMAT_Y_W_G, currentDateTime(), packet->getName(), RIGHTARROW, WRITELOG(FORMAT_Y_W_G, currentDateTime(), packet->getName(), RIGHTARROW, clientId, packet->print(pbuf));
clientId, packet->print(pbuf));
break; break;
case MQTTSN_REGISTER: case MQTTSN_REGISTER:
case MQTTSN_PUBLISH: case MQTTSN_PUBLISH:
WRITELOG(FORMAT_W_MSGID_W_G, currentDateTime(), packet->getName(), WRITELOG(FORMAT_W_MSGID_W_G, currentDateTime(), packet->getName(), packet->getMsgId(msgId), RIGHTARROW, clientId,
packet->getMsgId(msgId), RIGHTARROW, clientId,
packet->print(pbuf)); packet->print(pbuf));
break; break;
case MQTTSN_REGACK: case MQTTSN_REGACK:
@@ -134,8 +127,7 @@ void ClientSendTask::log(Client* client, MQTTSNPacket* packet)
case MQTTSN_PUBCOMP: case MQTTSN_PUBCOMP:
case MQTTSN_SUBACK: case MQTTSN_SUBACK:
case MQTTSN_UNSUBACK: case MQTTSN_UNSUBACK:
WRITELOG(FORMAT_W_MSGID_W_G, currentDateTime(), packet->getName(), WRITELOG(FORMAT_W_MSGID_W_G, currentDateTime(), packet->getName(), packet->getMsgId(msgId), RIGHTARROW, clientId,
packet->getMsgId(msgId), RIGHTARROW, clientId,
packet->print(pbuf)); packet->print(pbuf));
break; break;
default: default:

View File

@@ -42,8 +42,7 @@ MQTTSNConnectionHandler::~MQTTSNConnectionHandler()
void MQTTSNConnectionHandler::sendADVERTISE() void MQTTSNConnectionHandler::sendADVERTISE()
{ {
MQTTSNPacket* adv = new MQTTSNPacket(); MQTTSNPacket* adv = new MQTTSNPacket();
adv->setADVERTISE(_gateway->getGWParams()->gatewayId, adv->setADVERTISE(_gateway->getGWParams()->gatewayId, _gateway->getGWParams()->keepAlive);
_gateway->getGWParams()->keepAlive);
Event* ev1 = new Event(); Event* ev1 = new Event();
ev1->setBrodcastEvent(adv); //broadcast ev1->setBrodcastEvent(adv); //broadcast
_gateway->getClientSendQue()->post(ev1); _gateway->getClientSendQue()->post(ev1);
@@ -67,8 +66,7 @@ void MQTTSNConnectionHandler::handleSearchgw(MQTTSNPacket* packet)
/* /*
* CONNECT * CONNECT
*/ */
void MQTTSNConnectionHandler::handleConnect(Client* client, void MQTTSNConnectionHandler::handleConnect(Client* client, MQTTSNPacket* packet)
MQTTSNPacket* packet)
{ {
MQTTSNPacket_connectData data; MQTTSNPacket_connectData data;
if (packet->getCONNECT(&data) == 0) if (packet->getCONNECT(&data) == 0)
@@ -149,8 +147,7 @@ void MQTTSNConnectionHandler::handleConnect(Client* client,
/* CONNECT message was not qued in. /* CONNECT message was not qued in.
* create CONNECT message & send it to the broker */ * create CONNECT message & send it to the broker */
MQTTGWPacket* mqMsg = new MQTTGWPacket(); MQTTGWPacket* mqMsg = new MQTTGWPacket();
mqMsg->setCONNECT(client->getConnectData(), mqMsg->setCONNECT(client->getConnectData(), (unsigned char*) _gateway->getGWParams()->loginId,
(unsigned char*) _gateway->getGWParams()->loginId,
(unsigned char*) _gateway->getGWParams()->password); (unsigned char*) _gateway->getGWParams()->password);
Event* ev1 = new Event(); Event* ev1 = new Event();
ev1->setBrokerSendEvent(client, mqMsg); ev1->setBrokerSendEvent(client, mqMsg);
@@ -161,8 +158,7 @@ void MQTTSNConnectionHandler::handleConnect(Client* client,
/* /*
* WILLTOPIC * WILLTOPIC
*/ */
void MQTTSNConnectionHandler::handleWilltopic(Client* client, void MQTTSNConnectionHandler::handleWilltopic(Client* client, MQTTSNPacket* packet)
MQTTSNPacket* packet)
{ {
int willQos; int willQos;
uint8_t willRetain; uint8_t willRetain;
@@ -192,8 +188,7 @@ void MQTTSNConnectionHandler::handleWilltopic(Client* client,
/* /*
* WILLMSG * WILLMSG
*/ */
void MQTTSNConnectionHandler::handleWillmsg(Client* client, void MQTTSNConnectionHandler::handleWillmsg(Client* client, MQTTSNPacket* packet)
MQTTSNPacket* packet)
{ {
if (!client->isWaitWillMsg()) if (!client->isWaitWillMsg())
{ {
@@ -216,8 +211,7 @@ void MQTTSNConnectionHandler::handleWillmsg(Client* client,
/* create CONNECT message */ /* create CONNECT message */
MQTTGWPacket* mqttPacket = new MQTTGWPacket(); MQTTGWPacket* mqttPacket = new MQTTGWPacket();
connectData->willMsg = client->getWillMsg(); connectData->willMsg = client->getWillMsg();
mqttPacket->setCONNECT(connectData, mqttPacket->setCONNECT(connectData, (unsigned char*) _gateway->getGWParams()->loginId,
(unsigned char*) _gateway->getGWParams()->loginId,
(unsigned char*) _gateway->getGWParams()->password); (unsigned char*) _gateway->getGWParams()->password);
/* Send CONNECT to the broker */ /* Send CONNECT to the broker */
@@ -231,8 +225,7 @@ void MQTTSNConnectionHandler::handleWillmsg(Client* client,
/* /*
* DISCONNECT * DISCONNECT
*/ */
void MQTTSNConnectionHandler::handleDisconnect(Client* client, void MQTTSNConnectionHandler::handleDisconnect(Client* client, MQTTSNPacket* packet)
MQTTSNPacket* packet)
{ {
uint16_t duration = 0; uint16_t duration = 0;
@@ -258,8 +251,7 @@ void MQTTSNConnectionHandler::handleDisconnect(Client* client,
/* /*
* WILLTOPICUPD * WILLTOPICUPD
*/ */
void MQTTSNConnectionHandler::handleWilltopicupd(Client* client, void MQTTSNConnectionHandler::handleWilltopicupd(Client* client, MQTTSNPacket* packet)
MQTTSNPacket* packet)
{ {
/* send NOT_SUPPORTED responce to the client */ /* send NOT_SUPPORTED responce to the client */
MQTTSNPacket* respMsg = new MQTTSNPacket(); MQTTSNPacket* respMsg = new MQTTSNPacket();
@@ -272,8 +264,7 @@ void MQTTSNConnectionHandler::handleWilltopicupd(Client* client,
/* /*
* WILLMSGUPD * WILLMSGUPD
*/ */
void MQTTSNConnectionHandler::handleWillmsgupd(Client* client, void MQTTSNConnectionHandler::handleWillmsgupd(Client* client, MQTTSNPacket* packet)
MQTTSNPacket* packet)
{ {
/* send NOT_SUPPORTED responce to the client */ /* send NOT_SUPPORTED responce to the client */
MQTTSNPacket* respMsg = new MQTTSNPacket(); MQTTSNPacket* respMsg = new MQTTSNPacket();
@@ -286,11 +277,9 @@ void MQTTSNConnectionHandler::handleWillmsgupd(Client* client,
/* /*
* PINGREQ * PINGREQ
*/ */
void MQTTSNConnectionHandler::handlePingreq(Client* client, void MQTTSNConnectionHandler::handlePingreq(Client* client, MQTTSNPacket* packet)
MQTTSNPacket* packet)
{ {
if ((client->isSleep() || client->isAwake()) if ((client->isSleep() || client->isAwake()) && client->getClientSleepPacket())
&& client->getClientSleepPacket())
{ {
sendStoredPublish(client); sendStoredPublish(client);
client->holdPingRequest(); client->holdPingRequest();

View File

@@ -22,9 +22,7 @@ using namespace MQTTSNGW;
using namespace std; using namespace std;
WirelessNodeId::WirelessNodeId() : WirelessNodeId::WirelessNodeId() :
_len _len { 0 }, _nodeId { 0 }
{ 0 }, _nodeId
{ 0 }
{ {
} }
@@ -78,17 +76,13 @@ bool WirelessNodeId::operator ==(WirelessNodeId& id)
* Class MQTTSNGWEncapsulatedPacket * Class MQTTSNGWEncapsulatedPacket
*/ */
MQTTSNGWEncapsulatedPacket::MQTTSNGWEncapsulatedPacket() : MQTTSNGWEncapsulatedPacket::MQTTSNGWEncapsulatedPacket() :
_mqttsn _mqttsn { 0 }, _ctrl { 0 }
{ 0 }, _ctrl
{ 0 }
{ {
} }
MQTTSNGWEncapsulatedPacket::MQTTSNGWEncapsulatedPacket(MQTTSNPacket* packet) : MQTTSNGWEncapsulatedPacket::MQTTSNGWEncapsulatedPacket(MQTTSNPacket* packet) :
_mqttsn _mqttsn { packet }, _ctrl { 0 }
{ packet }, _ctrl
{ 0 }
{ {
} }
@@ -98,8 +92,7 @@ MQTTSNGWEncapsulatedPacket::~MQTTSNGWEncapsulatedPacket()
/* Do not delete the MQTTSNPacket. MQTTSNPacket is deleted by delete Event */ /* Do not delete the MQTTSNPacket. MQTTSNPacket is deleted by delete Event */
} }
int MQTTSNGWEncapsulatedPacket::unicast(SensorNetwork* network, int MQTTSNGWEncapsulatedPacket::unicast(SensorNetwork* network, SensorNetAddress* sendTo)
SensorNetAddress* sendTo)
{ {
uint8_t buf[MQTTSNGW_MAX_PACKET_SIZE]; uint8_t buf[MQTTSNGW_MAX_PACKET_SIZE];
int len = serialize(buf); int len = serialize(buf);
@@ -121,8 +114,7 @@ int MQTTSNGWEncapsulatedPacket::serialize(uint8_t* buf)
return buf[0] + len; return buf[0] + len;
} }
int MQTTSNGWEncapsulatedPacket::desirialize(unsigned char* buf, int MQTTSNGWEncapsulatedPacket::desirialize(unsigned char* buf, unsigned short len)
unsigned short len)
{ {
if (_mqttsn) if (_mqttsn)
{ {

View File

@@ -64,8 +64,7 @@ Forwarder* ForwarderList::getForwarder(SensorNetAddress* addr)
return p; return p;
} }
Forwarder* ForwarderList::addForwarder(SensorNetAddress* addr, Forwarder* ForwarderList::addForwarder(SensorNetAddress* addr, MQTTSNString* forwarderId)
MQTTSNString* forwarderId)
{ {
Forwarder* fdr = new Forwarder(addr, forwarderId); Forwarder* fdr = new Forwarder(addr, forwarderId);
if (_head == nullptr) if (_head == nullptr)
@@ -251,10 +250,7 @@ SensorNetAddress* Forwarder::getSensorNetAddr(void)
*/ */
ForwarderElement::ForwarderElement() : ForwarderElement::ForwarderElement() :
_client _client { 0 }, _wirelessNodeId { 0 }, _next { 0 }
{ 0 }, _wirelessNodeId
{ 0 }, _next
{ 0 }
{ {
} }

View File

@@ -45,8 +45,7 @@ MessageIdTable::~MessageIdTable()
_mutex.unlock(); _mutex.unlock();
} }
MessageIdElement* MessageIdTable::add(Aggregater* aggregater, Client* client, MessageIdElement* MessageIdTable::add(Aggregater* aggregater, Client* client, uint16_t clientMsgId)
uint16_t clientMsgId)
{ {
if (_cnt > _maxSize) if (_cnt > _maxSize)
{ {
@@ -194,18 +193,12 @@ uint16_t MessageIdTable::getMsgId(Client* client, uint16_t clientMsgId)
* Class MessageIdElement * Class MessageIdElement
===============================*/ ===============================*/
MessageIdElement::MessageIdElement(void) : MessageIdElement::MessageIdElement(void) :
_msgId _msgId { 0 }, _clientMsgId { 0 }, _client { nullptr }, _next { nullptr }, _prev { nullptr }
{ 0 }, _clientMsgId
{ 0 }, _client
{ nullptr }, _next
{ nullptr }, _prev
{ nullptr }
{ {
} }
MessageIdElement::MessageIdElement(uint16_t msgId, Client* client, MessageIdElement::MessageIdElement(uint16_t msgId, Client* client, uint16_t clientMsgId) :
uint16_t clientMsgId) :
MessageIdElement() MessageIdElement()
{ {
_msgId = msgId; _msgId = msgId;

View File

@@ -149,8 +149,7 @@ int MQTTSNPacket::setADVERTISE(uint8_t gatewayid, uint16_t duration)
{ {
unsigned char buf[5]; unsigned char buf[5];
int buflen = sizeof(buf); int buflen = sizeof(buf);
int len = MQTTSNSerialize_advertise(buf, buflen, (unsigned char) gatewayid, int len = MQTTSNSerialize_advertise(buf, buflen, (unsigned char) gatewayid, (unsigned short) duration);
(unsigned short) duration);
return desirialize(buf, len); return desirialize(buf, len);
} }
@@ -158,8 +157,7 @@ int MQTTSNPacket::setGWINFO(uint8_t gatewayId)
{ {
unsigned char buf[3]; unsigned char buf[3];
int buflen = sizeof(buf); int buflen = sizeof(buf);
int len = MQTTSNSerialize_gwinfo(buf, buflen, (unsigned char) gatewayId, 0, int len = MQTTSNSerialize_gwinfo(buf, buflen, (unsigned char) gatewayId, 0, 0);
0);
return desirialize(buf, len); return desirialize(buf, len);
} }
@@ -202,45 +200,37 @@ int MQTTSNPacket::setWILLMSGREQ(void)
return desirialize(buf, len); return desirialize(buf, len);
} }
int MQTTSNPacket::setREGISTER(uint16_t topicId, uint16_t msgId, int MQTTSNPacket::setREGISTER(uint16_t topicId, uint16_t msgId, MQTTSNString* topicName)
MQTTSNString* topicName)
{ {
unsigned char buf[MQTTSNGW_MAX_PACKET_SIZE]; unsigned char buf[MQTTSNGW_MAX_PACKET_SIZE];
int buflen = sizeof(buf); int buflen = sizeof(buf);
int len = MQTTSNSerialize_register(buf, buflen, (unsigned short) topicId, int len = MQTTSNSerialize_register(buf, buflen, (unsigned short) topicId, (unsigned short) msgId, topicName);
(unsigned short) msgId, topicName);
return desirialize(buf, len); return desirialize(buf, len);
} }
int MQTTSNPacket::setREGACK(uint16_t topicId, uint16_t msgId, int MQTTSNPacket::setREGACK(uint16_t topicId, uint16_t msgId, uint8_t returnCode)
uint8_t returnCode)
{ {
unsigned char buf[7]; unsigned char buf[7];
int buflen = sizeof(buf); int buflen = sizeof(buf);
int len = MQTTSNSerialize_regack(buf, buflen, (unsigned short) topicId, int len = MQTTSNSerialize_regack(buf, buflen, (unsigned short) topicId, (unsigned short) msgId, (unsigned char) returnCode);
(unsigned short) msgId, (unsigned char) returnCode);
return desirialize(buf, len); return desirialize(buf, len);
} }
int MQTTSNPacket::setPUBLISH(uint8_t dup, int qos, uint8_t retained, int MQTTSNPacket::setPUBLISH(uint8_t dup, int qos, uint8_t retained, uint16_t msgId, MQTTSN_topicid topic, uint8_t* payload,
uint16_t msgId, MQTTSN_topicid topic, uint8_t* payload,
uint16_t payloadlen) uint16_t payloadlen)
{ {
unsigned char buf[MQTTSNGW_MAX_PACKET_SIZE]; unsigned char buf[MQTTSNGW_MAX_PACKET_SIZE];
int buflen = sizeof(buf); int buflen = sizeof(buf);
int len = MQTTSNSerialize_publish(buf, buflen, (unsigned char) dup, qos, int len = MQTTSNSerialize_publish(buf, buflen, (unsigned char) dup, qos, (unsigned char) retained, (unsigned short) msgId,
(unsigned char) retained, (unsigned short) msgId, topic, topic, (unsigned char*) payload, (int) payloadlen);
(unsigned char*) payload, (int) payloadlen);
return desirialize(buf, len); return desirialize(buf, len);
} }
int MQTTSNPacket::setPUBACK(uint16_t topicId, uint16_t msgId, int MQTTSNPacket::setPUBACK(uint16_t topicId, uint16_t msgId, uint8_t returnCode)
uint8_t returnCode)
{ {
unsigned char buf[7]; unsigned char buf[7];
int buflen = sizeof(buf); int buflen = sizeof(buf);
int len = MQTTSNSerialize_puback(buf, buflen, (unsigned short) topicId, int len = MQTTSNSerialize_puback(buf, buflen, (unsigned short) topicId, (unsigned short) msgId, (unsigned char) returnCode);
(unsigned short) msgId, (unsigned char) returnCode);
return desirialize(buf, len); return desirialize(buf, len);
} }
@@ -268,13 +258,12 @@ int MQTTSNPacket::setPUBCOMP(uint16_t msgId)
return desirialize(buf, len); return desirialize(buf, len);
} }
int MQTTSNPacket::setSUBACK(int qos, uint16_t topicId, uint16_t msgId, int MQTTSNPacket::setSUBACK(int qos, uint16_t topicId, uint16_t msgId, uint8_t returnCode)
uint8_t returnCode)
{ {
unsigned char buf[8]; unsigned char buf[8];
int buflen = sizeof(buf); int buflen = sizeof(buf);
int len = MQTTSNSerialize_suback(buf, buflen, qos, (unsigned short) topicId, int len = MQTTSNSerialize_suback(buf, buflen, qos, (unsigned short) topicId, (unsigned short) msgId,
(unsigned short) msgId, (unsigned char) returnCode); (unsigned char) returnCode);
return desirialize(buf, len); return desirialize(buf, len);
} }
@@ -336,8 +325,7 @@ int MQTTSNPacket::setPINGREQ(MQTTSNString* clientId)
int MQTTSNPacket::getSERCHGW(uint8_t* radius) int MQTTSNPacket::getSERCHGW(uint8_t* radius)
{ {
return MQTTSNDeserialize_searchgw((unsigned char*) radius, return MQTTSNDeserialize_searchgw((unsigned char*) radius, (unsigned char*) _buf, _bufLen);
(unsigned char*) _buf, _bufLen);
} }
int MQTTSNPacket::getCONNECT(MQTTSNPacket_connectData* data) int MQTTSNPacket::getCONNECT(MQTTSNPacket_connectData* data)
@@ -350,11 +338,9 @@ int MQTTSNPacket::getCONNACK(uint8_t* returnCode)
return MQTTSNSerialize_connack(_buf, _bufLen, (int) *returnCode); return MQTTSNSerialize_connack(_buf, _bufLen, (int) *returnCode);
} }
int MQTTSNPacket::getWILLTOPIC(int* willQoS, uint8_t* willRetain, int MQTTSNPacket::getWILLTOPIC(int* willQoS, uint8_t* willRetain, MQTTSNString* willTopic)
MQTTSNString* willTopic)
{ {
return MQTTSNDeserialize_willtopic((int*) willQoS, return MQTTSNDeserialize_willtopic((int*) willQoS, (unsigned char*) willRetain, willTopic, _buf, _bufLen);
(unsigned char*) willRetain, willTopic, _buf, _bufLen);
} }
int MQTTSNPacket::getWILLMSG(MQTTSNString* willmsg) int MQTTSNPacket::getWILLMSG(MQTTSNString* willmsg)
@@ -362,34 +348,28 @@ int MQTTSNPacket::getWILLMSG(MQTTSNString* willmsg)
return MQTTSNDeserialize_willmsg(willmsg, _buf, _bufLen); return MQTTSNDeserialize_willmsg(willmsg, _buf, _bufLen);
} }
int MQTTSNPacket::getREGISTER(uint16_t* topicId, uint16_t* msgId, int MQTTSNPacket::getREGISTER(uint16_t* topicId, uint16_t* msgId, MQTTSNString* topicName)
MQTTSNString* topicName)
{ {
return MQTTSNDeserialize_register((unsigned short*) topicId, return MQTTSNDeserialize_register((unsigned short*) topicId, (unsigned short*) msgId, topicName, _buf, _bufLen);
(unsigned short*) msgId, topicName, _buf, _bufLen);
} }
int MQTTSNPacket::getREGACK(uint16_t* topicId, uint16_t* msgId, int MQTTSNPacket::getREGACK(uint16_t* topicId, uint16_t* msgId, uint8_t* returnCode)
uint8_t* returnCode)
{ {
return MQTTSNDeserialize_regack((unsigned short*) topicId, return MQTTSNDeserialize_regack((unsigned short*) topicId, (unsigned short*) msgId, (unsigned char*) returnCode, _buf,
(unsigned short*) msgId, (unsigned char*) returnCode, _buf, _bufLen); _bufLen);
} }
int MQTTSNPacket::getPUBLISH(uint8_t* dup, int* qos, uint8_t* retained, int MQTTSNPacket::getPUBLISH(uint8_t* dup, int* qos, uint8_t* retained, uint16_t* msgId, MQTTSN_topicid* topic,
uint16_t* msgId, MQTTSN_topicid* topic, uint8_t** payload, uint8_t** payload, int* payloadlen)
int* payloadlen)
{ {
return MQTTSNDeserialize_publish((unsigned char*) dup, qos, return MQTTSNDeserialize_publish((unsigned char*) dup, qos, (unsigned char*) retained, (unsigned short*) msgId, topic,
(unsigned char*) retained, (unsigned short*) msgId, topic,
(unsigned char**) payload, (int*) payloadlen, _buf, _bufLen); (unsigned char**) payload, (int*) payloadlen, _buf, _bufLen);
} }
int MQTTSNPacket::getPUBACK(uint16_t* topicId, uint16_t* msgId, int MQTTSNPacket::getPUBACK(uint16_t* topicId, uint16_t* msgId, uint8_t* returnCode)
uint8_t* returnCode)
{ {
return MQTTSNDeserialize_puback((unsigned short*) topicId, return MQTTSNDeserialize_puback((unsigned short*) topicId, (unsigned short*) msgId, (unsigned char*) returnCode, _buf,
(unsigned short*) msgId, (unsigned char*) returnCode, _buf, _bufLen); _bufLen);
} }
int MQTTSNPacket::getACK(uint16_t* msgId) int MQTTSNPacket::getACK(uint16_t* msgId)
@@ -398,17 +378,14 @@ int MQTTSNPacket::getACK(uint16_t* msgId)
return MQTTSNDeserialize_ack(&type, (unsigned short*) msgId, _buf, _bufLen); return MQTTSNDeserialize_ack(&type, (unsigned short*) msgId, _buf, _bufLen);
} }
int MQTTSNPacket::getSUBSCRIBE(uint8_t* dup, int* qos, uint16_t* msgId, int MQTTSNPacket::getSUBSCRIBE(uint8_t* dup, int* qos, uint16_t* msgId, MQTTSN_topicid* topicFilter)
MQTTSN_topicid* topicFilter)
{ {
return MQTTSNDeserialize_subscribe((unsigned char*) dup, qos, return MQTTSNDeserialize_subscribe((unsigned char*) dup, qos, (unsigned short*) msgId, topicFilter, _buf, _bufLen);
(unsigned short*) msgId, topicFilter, _buf, _bufLen);
} }
int MQTTSNPacket::getUNSUBSCRIBE(uint16_t* msgId, MQTTSN_topicid* topicFilter) int MQTTSNPacket::getUNSUBSCRIBE(uint16_t* msgId, MQTTSN_topicid* topicFilter)
{ {
return MQTTSNDeserialize_unsubscribe((unsigned short*) msgId, topicFilter, return MQTTSNDeserialize_unsubscribe((unsigned short*) msgId, topicFilter, _buf, _bufLen);
_buf, _bufLen);
} }
int MQTTSNPacket::getPINGREQ(void) int MQTTSNPacket::getPINGREQ(void)
@@ -428,11 +405,9 @@ int MQTTSNPacket::getDISCONNECT(uint16_t* duration)
return rc; return rc;
} }
int MQTTSNPacket::getWILLTOPICUPD(uint8_t* willQoS, uint8_t* willRetain, int MQTTSNPacket::getWILLTOPICUPD(uint8_t* willQoS, uint8_t* willRetain, MQTTSNString* willTopic)
MQTTSNString* willTopic)
{ {
return MQTTSNDeserialize_willtopicupd((int*) willQoS, return MQTTSNDeserialize_willtopicupd((int*) willQoS, (unsigned char*) willRetain, willTopic, _buf, _bufLen);
(unsigned char*) willRetain, willTopic, _buf, _bufLen);
} }
int MQTTSNPacket::getWILLMSGUPD(MQTTSNString* willMsg) int MQTTSNPacket::getWILLMSGUPD(MQTTSNString* willMsg)

View File

@@ -125,8 +125,7 @@ void PacketHandleTask::run()
if (_advertiseTimer.isTimeup()) if (_advertiseTimer.isTimeup())
{ {
_mqttsnConnection->sendADVERTISE(); _mqttsnConnection->sendADVERTISE();
_advertiseTimer.start( _advertiseTimer.start(_gateway->getGWParams()->keepAlive * 1000UL);
_gateway->getGWParams()->keepAlive * 1000UL);
} }
/*------ Check Adapters Connect or PINGREQ ------*/ /*------ Check Adapters Connect or PINGREQ ------*/
@@ -180,8 +179,7 @@ void PacketHandleTask::run()
} }
} }
void PacketHandleTask::aggregatePacketHandler(Client*client, void PacketHandleTask::aggregatePacketHandler(Client*client, MQTTSNPacket* packet)
MQTTSNPacket* packet)
{ {
switch (packet->getType()) switch (packet->getType())
{ {
@@ -238,8 +236,7 @@ void PacketHandleTask::aggregatePacketHandler(Client*client,
} }
} }
void PacketHandleTask::aggregatePacketHandler(Client*client, void PacketHandleTask::aggregatePacketHandler(Client*client, MQTTGWPacket* packet)
MQTTGWPacket* packet)
{ {
switch (packet->getType()) switch (packet->getType())
{ {
@@ -275,8 +272,7 @@ void PacketHandleTask::aggregatePacketHandler(Client*client,
} }
} }
void PacketHandleTask::transparentPacketHandler(Client*client, void PacketHandleTask::transparentPacketHandler(Client*client, MQTTSNPacket* packet)
MQTTSNPacket* packet)
{ {
switch (packet->getType()) switch (packet->getType())
{ {
@@ -333,8 +329,7 @@ void PacketHandleTask::transparentPacketHandler(Client*client,
} }
} }
void PacketHandleTask::transparentPacketHandler(Client*client, void PacketHandleTask::transparentPacketHandler(Client*client, MQTTGWPacket* packet)
MQTTGWPacket* packet)
{ {
switch (packet->getType()) switch (packet->getType())
{ {

View File

@@ -163,7 +163,7 @@ int Process::getParam(const char* parameter, char* value)
if ((fp = fopen(configPath.c_str(), "r")) == NULL) if ((fp = fopen(configPath.c_str(), "r")) == NULL)
{ {
throw Exception("No config file:\n\nUsage: Command -f path/config_file_name\n", 0); throw Exception("Config file not found:\n\nUsage: Command -f path/config_file_name\n", 0);
} }
while (true) while (true)
@@ -257,7 +257,7 @@ MultiTaskProcess::~MultiTaskProcess()
{ {
for (int i = 0; i < _threadCount; i++) for (int i = 0; i < _threadCount; i++)
{ {
_threadList[i]->stop(); _threadList[i]->stop();
} }
} }
@@ -338,18 +338,18 @@ int MultiTaskProcess::getParam(const char* parameter, char* value)
======================================*/ ======================================*/
Exception::Exception(const char* message, const int errNo) Exception::Exception(const char* message, const int errNo)
{ {
_message = message; _message = message;
_errNo = errNo; _errNo = errNo;
_fileName = nullptr; _fileName = nullptr;
_functionName = nullptr; _functionName = nullptr;
_line = 0; _line = 0;
} }
Exception::Exception(const char* message, const int errNo, const char* file, Exception::Exception(const char* message, const int errNo, const char* file, const char* function, const int line)
const char* function, const int line)
{ {
_message = message; _message = message;
_errNo = errNo; _errNo = errNo;
_fileName = getFileName(file);; _fileName = getFileName(file);
;
_functionName = function; _functionName = function;
_line = line; _line = line;
} }
@@ -388,39 +388,40 @@ void Exception::writeMessage()
{ {
if (_fileName == nullptr) if (_fileName == nullptr)
{ {
if (_errNo == 0) if (_errNo == 0)
{ {
WRITELOG("%s%s %s%s\n", currentDateTime(), RED_HDR, _message, CLR_HDR); WRITELOG("%s%s %s%s\n", currentDateTime(), RED_HDR, _message, CLR_HDR);
} }
else else
{ {
WRITELOG("%s%s %s.\n errno=%d : %s%s\n", currentDateTime(), RED_HDR,_message, _errNo, strerror(_errNo), CLR_HDR); WRITELOG("%s%s %s.\n errno=%d : %s%s\n", currentDateTime(), RED_HDR, _message, _errNo,
} strerror(_errNo), CLR_HDR);
}
} }
else else
{ {
if (_errNo == 0) if (_errNo == 0)
{ {
WRITELOG("%s%s %s. %s line %-4d %s()%s\n", WRITELOG("%s%s %s. %s line %-4d %s()%s\n", currentDateTime(), RED_HDR, _message, _fileName, _line, _functionName,
currentDateTime(), RED_HDR, _message, _fileName, _line, _functionName, CLR_HDR); CLR_HDR);
} }
else else
{ {
WRITELOG("%s%s %s. %s line %-4d %s()\n errno=%d : %s%s\n", WRITELOG("%s%s %s. %s line %-4d %s()\n errno=%d : %s%s\n", currentDateTime(), RED_HDR, _message,
currentDateTime(), RED_HDR, _message, _fileName, _line, _functionName, _errNo, strerror(_errNo), CLR_HDR); _fileName, _line, _functionName, _errNo, strerror(_errNo), CLR_HDR);
} }
} }
} }
const char* Exception::getFileName(const char* file) const char* Exception::getFileName(const char* file)
{ {
for ( int len = strlen(file); len > 0; len-- ) for (int len = strlen(file); len > 0; len--)
{ {
if (*(file + len) == '/') if (*(file + len) == '/')
{ {
return file + len + 1; return file + len + 1;
} }
} }
return file; return file;
} }

View File

@@ -35,14 +35,13 @@ MQTTSNPublishHandler::~MQTTSNPublishHandler()
} }
MQTTGWPacket* MQTTSNPublishHandler::handlePublish(Client* client, MQTTGWPacket* MQTTSNPublishHandler::handlePublish(Client* client, MQTTSNPacket* packet)
MQTTSNPacket* packet)
{ {
uint8_t dup; uint8_t dup;
int qos; int qos;
uint8_t retained; uint8_t retained;
uint16_t msgId; uint16_t msgId;
uint16_t tid; uint16_t tid;
uint8_t* payload; uint8_t* payload;
MQTTSN_topicid topicid; MQTTSN_topicid topicid;
int payloadlen; int payloadlen;
@@ -54,15 +53,13 @@ MQTTGWPacket* MQTTSNPublishHandler::handlePublish(Client* client,
{ {
if (client->isQoSm1()) if (client->isQoSm1())
{ {
_gateway->getAdapterManager()->getQoSm1Proxy()->savePacket(client, _gateway->getAdapterManager()->getQoSm1Proxy()->savePacket(client, packet);
packet);
return nullptr; return nullptr;
} }
} }
if (packet->getPUBLISH(&dup, &qos, &retained, &msgId, &topicid, &payload, if (packet->getPUBLISH(&dup, &qos, &retained, &msgId, &topicid, &payload, &payloadlen) == 0)
&payloadlen) == 0)
{ {
return nullptr; return nullptr;
} }
@@ -70,7 +67,7 @@ MQTTGWPacket* MQTTSNPublishHandler::handlePublish(Client* client,
pub.header.bits.dup = dup; pub.header.bits.dup = dup;
pub.header.bits.qos = (qos == 3 ? 0 : qos); pub.header.bits.qos = (qos == 3 ? 0 : qos);
pub.header.bits.retain = retained; pub.header.bits.retain = retained;
tid = topicid.data.id; tid = topicid.data.id;
Topic* topic = nullptr; Topic* topic = nullptr;
@@ -89,22 +86,19 @@ MQTTGWPacket* MQTTSNPublishHandler::handlePublish(Client* client,
topic = _gateway->getTopics()->getTopicById(&topicid); topic = _gateway->getTopics()->getTopicById(&topicid);
if (topic) if (topic)
{ {
topic = client->getTopics()->add(topic->getTopicName()->c_str(), topic = client->getTopics()->add(topic->getTopicName()->c_str(), topic->getTopicId());
topic->getTopicId());
} }
} }
if (!topic && qos == 3) if (!topic && qos == 3)
{ {
WRITELOG("%s Invalid TopicId.%s %s\n", ERRMSG_HEADER, WRITELOG("%s Invalid TopicId.%s %s\n", ERRMSG_HEADER, client->getClientId(), ERRMSG_FOOTER);
client->getClientId(), ERRMSG_FOOTER);
return nullptr; return nullptr;
} }
if ((qos == 0 || qos == 3) && msgId > 0) if ((qos == 0 || qos == 3) && msgId > 0)
{ {
WRITELOG("%s Invalid MsgId.%s %s\n", ERRMSG_HEADER, WRITELOG("%s Invalid MsgId.%s %s\n", ERRMSG_HEADER, client->getClientId(), ERRMSG_FOOTER);
client->getClientId(), ERRMSG_FOOTER);
return nullptr; return nullptr;
} }
@@ -112,8 +106,7 @@ MQTTGWPacket* MQTTSNPublishHandler::handlePublish(Client* client,
{ {
/* Reply PubAck with INVALID_TOPIC_ID to the client */ /* Reply PubAck with INVALID_TOPIC_ID to the client */
MQTTSNPacket* pubAck = new MQTTSNPacket(); MQTTSNPacket* pubAck = new MQTTSNPacket();
pubAck->setPUBACK(topicid.data.id, msgId, pubAck->setPUBACK(topicid.data.id, msgId, MQTTSN_RC_REJECTED_INVALID_TOPIC_ID);
MQTTSN_RC_REJECTED_INVALID_TOPIC_ID);
Event* ev1 = new Event(); Event* ev1 = new Event();
ev1->setClientSendEvent(client, pubAck); ev1->setClientSendEvent(client, pubAck);
_gateway->getClientSendQue()->post(ev1); _gateway->getClientSendQue()->post(ev1);
@@ -123,14 +116,14 @@ MQTTGWPacket* MQTTSNPublishHandler::handlePublish(Client* client,
{ {
pub.topic = (char*) topic->getTopicName()->data(); pub.topic = (char*) topic->getTopicName()->data();
pub.topiclen = topic->getTopicName()->length(); pub.topiclen = topic->getTopicName()->length();
topicid.data.long_.name = pub.topic; topicid.data.long_.name = pub.topic;
topicid.data.long_.len = pub.topiclen; topicid.data.long_.len = pub.topiclen;
} }
} }
/* Save a msgId & a TopicId pare for PUBACK */ /* Save a msgId & a TopicId pare for PUBACK */
if (msgId && qos > 0 && qos < 3) if (msgId && qos > 0 && qos < 3)
{ {
client->setWaitedPubTopicId(msgId, tid, &topicid); client->setWaitedPubTopicId(msgId, tid, &topicid);
} }
pub.payload = (char*) payload; pub.payload = (char*) payload;
@@ -139,8 +132,7 @@ MQTTGWPacket* MQTTSNPublishHandler::handlePublish(Client* client,
MQTTGWPacket* publish = new MQTTGWPacket(); MQTTGWPacket* publish = new MQTTGWPacket();
publish->setPUBLISH(&pub); publish->setPUBLISH(&pub);
if (_gateway->getAdapterManager()->isAggregaterActive() if (_gateway->getAdapterManager()->isAggregaterActive() && client->isAggregated())
&& client->isAggregated())
{ {
return publish; return publish;
} }
@@ -184,8 +176,7 @@ void MQTTSNPublishHandler::handlePuback(Client* client, MQTTSNPacket* packet)
} }
} }
void MQTTSNPublishHandler::handleAck(Client* client, MQTTSNPacket* packet, void MQTTSNPublishHandler::handleAck(Client* client, MQTTSNPacket* packet, uint8_t packetType)
uint8_t packetType)
{ {
uint16_t msgId; uint16_t msgId;
@@ -245,19 +236,17 @@ void MQTTSNPublishHandler::handleRegAck(Client* client, MQTTSNPacket* packet)
} }
/* get PUBLISH message */ /* get PUBLISH message */
MQTTSNPacket* regAck = client->getWaitREGACKPacketList()->getPacket( MQTTSNPacket* regAck = client->getWaitREGACKPacketList()->getPacket(msgId);
msgId);
if (regAck != nullptr) if (regAck != nullptr)
{ {
client->getWaitREGACKPacketList()->erase(msgId); client->getWaitREGACKPacketList()->erase(msgId);
Event* ev = new Event(); Event* ev = new Event();
ev->setClientSendEvent(client, regAck); ev->setClientSendEvent(client, regAck);
_gateway->getClientSendQue()->post(ev); _gateway->getClientSendQue()->post(ev);
} }
if (client->isHoldPingReqest() if (client->isHoldPingReqest() && client->getWaitREGACKPacketList()->getCount() == 0)
&& client->getWaitREGACKPacketList()->getCount() == 0)
{ {
/* send PINGREQ to the broker */ /* send PINGREQ to the broker */
client->resetPingRequest(); client->resetPingRequest();
@@ -271,8 +260,7 @@ void MQTTSNPublishHandler::handleRegAck(Client* client, MQTTSNPacket* packet)
} }
void MQTTSNPublishHandler::handleAggregatePublish(Client* client, void MQTTSNPublishHandler::handleAggregatePublish(Client* client, MQTTSNPacket* packet)
MQTTSNPacket* packet)
{ {
int msgId = 0; int msgId = 0;
MQTTGWPacket* publish = handlePublish(client, packet); MQTTGWPacket* publish = handlePublish(client, packet);
@@ -282,15 +270,11 @@ void MQTTSNPublishHandler::handleAggregatePublish(Client* client,
{ {
if (packet->isDuplicate()) if (packet->isDuplicate())
{ {
msgId = msgId = _gateway->getAdapterManager()->getAggregater()->getMsgId(client, packet->getMsgId());
_gateway->getAdapterManager()->getAggregater()->getMsgId(
client, packet->getMsgId());
} }
else else
{ {
msgId = msgId = _gateway->getAdapterManager()->getAggregater()->addMessageIdTable(client, packet->getMsgId());
_gateway->getAdapterManager()->getAggregater()->addMessageIdTable(
client, packet->getMsgId());
} }
publish->setMsgId(msgId); publish->setMsgId(msgId);
} }
@@ -300,8 +284,7 @@ void MQTTSNPublishHandler::handleAggregatePublish(Client* client,
} }
} }
void MQTTSNPublishHandler::handleAggregateAck(Client* client, void MQTTSNPublishHandler::handleAggregateAck(Client* client, MQTTSNPacket* packet, int type)
MQTTSNPacket* packet, int type)
{ {
if (type == MQTTSN_PUBREC) if (type == MQTTSN_PUBREC)
{ {

View File

@@ -34,8 +34,7 @@ MQTTSNSubscribeHandler::~MQTTSNSubscribeHandler()
} }
MQTTGWPacket* MQTTSNSubscribeHandler::handleSubscribe(Client* client, MQTTGWPacket* MQTTSNSubscribeHandler::handleSubscribe(Client* client, MQTTSNPacket* packet)
MQTTSNPacket* packet)
{ {
uint8_t dup; uint8_t dup;
int qos; int qos;
@@ -63,16 +62,15 @@ MQTTGWPacket* MQTTSNSubscribeHandler::handleSubscribe(Client* client,
if (!topic) if (!topic)
{ {
/* Search the topic in Client common topic table */ /* Search the topic in Client common topic table */
topic = _gateway->getTopics()->getTopicById(&topicFilter); topic = _gateway->getTopics()->getTopicById(&topicFilter);
if (topic) if (topic)
{ {
topic = client->getTopics()->add(topic->getTopicName()->c_str(), topic = client->getTopics()->add(topic->getTopicName()->c_str(), topic->getTopicId());
topic->getTopicId());
if (topic == nullptr) if (topic == nullptr)
{ {
WRITELOG("%s Client(%s) can't add the Topic.%s\n", WRITELOG("%s Client(%s) can't add the Topic.%s\n",
ERRMSG_HEADER, client->getClientId(), ERRMSG_FOOTER); ERRMSG_HEADER, client->getClientId(), ERRMSG_FOOTER);
goto RespExit; goto RespExit;
} }
} }
@@ -83,8 +81,7 @@ MQTTGWPacket* MQTTSNSubscribeHandler::handleSubscribe(Client* client,
} }
topicId = topic->getTopicId(); topicId = topic->getTopicId();
subscribe = new MQTTGWPacket(); subscribe = new MQTTGWPacket();
subscribe->setSUBSCRIBE((char*) topic->getTopicName()->c_str(), subscribe->setSUBSCRIBE((char*) topic->getTopicName()->c_str(), (uint8_t) qos, (uint16_t) msgId);
(uint8_t) qos, (uint16_t) msgId);
} }
else if (topicFilter.type == MQTTSN_TOPIC_TYPE_NORMAL) else if (topicFilter.type == MQTTSN_TOPIC_TYPE_NORMAL)
@@ -96,15 +93,14 @@ MQTTGWPacket* MQTTSNSubscribeHandler::handleSubscribe(Client* client,
if (topic == nullptr) if (topic == nullptr)
{ {
WRITELOG("%s Client(%s) can't add the Topic.%s\n", WRITELOG("%s Client(%s) can't add the Topic.%s\n",
ERRMSG_HEADER, client->getClientId(), ERRMSG_FOOTER); ERRMSG_HEADER, client->getClientId(), ERRMSG_FOOTER);
goto RespExit; goto RespExit;
} }
} }
topicId = topic->getTopicId(); topicId = topic->getTopicId();
subscribe = new MQTTGWPacket(); subscribe = new MQTTGWPacket();
subscribe->setSUBSCRIBE((char*) topic->getTopicName()->c_str(), subscribe->setSUBSCRIBE((char*) topic->getTopicName()->c_str(), (uint8_t) qos, (uint16_t) msgId);
(uint8_t) qos, (uint16_t) msgId);
} }
else //MQTTSN_TOPIC_TYPE_SHORT else //MQTTSN_TOPIC_TYPE_SHORT
{ {
@@ -133,16 +129,14 @@ MQTTGWPacket* MQTTSNSubscribeHandler::handleSubscribe(Client* client,
} }
RespExit: MQTTSNPacket* sSuback = new MQTTSNPacket(); RespExit: MQTTSNPacket* sSuback = new MQTTSNPacket();
sSuback->setSUBACK(qos, topicFilter.data.id, msgId, sSuback->setSUBACK(qos, topicFilter.data.id, msgId, MQTTSN_RC_REJECTED_INVALID_TOPIC_ID);
MQTTSN_RC_REJECTED_INVALID_TOPIC_ID);
evsuback = new Event(); evsuback = new Event();
evsuback->setClientSendEvent(client, sSuback); evsuback->setClientSendEvent(client, sSuback);
_gateway->getClientSendQue()->post(evsuback); _gateway->getClientSendQue()->post(evsuback);
return nullptr; return nullptr;
} }
MQTTGWPacket* MQTTSNSubscribeHandler::handleUnsubscribe(Client* client, MQTTGWPacket* MQTTSNSubscribeHandler::handleUnsubscribe(Client* client, MQTTSNPacket* packet)
MQTTSNPacket* packet)
{ {
uint16_t msgId; uint16_t msgId;
MQTTSN_topicid topicFilter; MQTTSN_topicid topicFilter;
@@ -209,8 +203,7 @@ MQTTGWPacket* MQTTSNSubscribeHandler::handleUnsubscribe(Client* client,
} }
} }
void MQTTSNSubscribeHandler::handleAggregateSubscribe(Client* client, void MQTTSNSubscribeHandler::handleAggregateSubscribe(Client* client, MQTTSNPacket* packet)
MQTTSNPacket* packet)
{ {
MQTTGWPacket* subscribe = handleSubscribe(client, packet); MQTTGWPacket* subscribe = handleSubscribe(client, packet);
@@ -219,21 +212,17 @@ void MQTTSNSubscribeHandler::handleAggregateSubscribe(Client* client,
int msgId = 0; int msgId = 0;
if (packet->isDuplicate()) if (packet->isDuplicate())
{ {
msgId = _gateway->getAdapterManager()->getAggregater()->getMsgId( msgId = _gateway->getAdapterManager()->getAggregater()->getMsgId(client, packet->getMsgId());
client, packet->getMsgId());
} }
else else
{ {
msgId = msgId = _gateway->getAdapterManager()->getAggregater()->addMessageIdTable(client, packet->getMsgId());
_gateway->getAdapterManager()->getAggregater()->addMessageIdTable(
client, packet->getMsgId());
} }
if (msgId == 0) if (msgId == 0)
{ {
WRITELOG( WRITELOG("%s MQTTSNSubscribeHandler can't create MessageIdTableElement %s%s\n",
"%s MQTTSNSubscribeHandler can't create MessageIdTableElement %s%s\n", ERRMSG_HEADER, client->getClientId(), ERRMSG_FOOTER);
ERRMSG_HEADER, client->getClientId(), ERRMSG_FOOTER);
return; return;
} }
@@ -241,8 +230,7 @@ void MQTTSNSubscribeHandler::handleAggregateSubscribe(Client* client,
string* topicName = new string(str.data, str.len); // topicName is delete by topic string* topicName = new string(str.data, str.len); // topicName is delete by topic
Topic topic = Topic(topicName, MQTTSN_TOPIC_TYPE_NORMAL); Topic topic = Topic(topicName, MQTTSN_TOPIC_TYPE_NORMAL);
_gateway->getAdapterManager()->getAggregater()->addAggregateTopic( _gateway->getAdapterManager()->getAggregater()->addAggregateTopic(&topic, client);
&topic, client);
subscribe->setMsgId(msgId); subscribe->setMsgId(msgId);
Event* ev = new Event(); Event* ev = new Event();
@@ -251,8 +239,7 @@ void MQTTSNSubscribeHandler::handleAggregateSubscribe(Client* client,
} }
} }
void MQTTSNSubscribeHandler::handleAggregateUnsubscribe(Client* client, void MQTTSNSubscribeHandler::handleAggregateUnsubscribe(Client* client, MQTTSNPacket* packet)
MQTTSNPacket* packet)
{ {
MQTTGWPacket* unsubscribe = handleUnsubscribe(client, packet); MQTTGWPacket* unsubscribe = handleUnsubscribe(client, packet);
if (unsubscribe != nullptr) if (unsubscribe != nullptr)
@@ -260,29 +247,24 @@ void MQTTSNSubscribeHandler::handleAggregateUnsubscribe(Client* client,
int msgId = 0; int msgId = 0;
if (packet->isDuplicate()) if (packet->isDuplicate())
{ {
msgId = _gateway->getAdapterManager()->getAggregater()->getMsgId( msgId = _gateway->getAdapterManager()->getAggregater()->getMsgId(client, packet->getMsgId());
client, packet->getMsgId());
} }
else else
{ {
msgId = msgId = _gateway->getAdapterManager()->getAggregater()->addMessageIdTable(client, packet->getMsgId());
_gateway->getAdapterManager()->getAggregater()->addMessageIdTable(
client, packet->getMsgId());
} }
if (msgId == 0) if (msgId == 0)
{ {
WRITELOG( WRITELOG("%s MQTTSNUnsubscribeHandler can't create MessageIdTableElement %s%s\n",
"%s MQTTSNUnsubscribeHandler can't create MessageIdTableElement %s%s\n", ERRMSG_HEADER, client->getClientId(), ERRMSG_FOOTER);
ERRMSG_HEADER, client->getClientId(), ERRMSG_FOOTER);
return; return;
} }
UTF8String str = unsubscribe->getTopic(); UTF8String str = unsubscribe->getTopic();
string* topicName = new string(str.data, str.len); // topicName is delete by topic string* topicName = new string(str.data, str.len); // topicName is delete by topic
Topic topic = Topic(topicName, MQTTSN_TOPIC_TYPE_NORMAL); Topic topic = Topic(topicName, MQTTSN_TOPIC_TYPE_NORMAL);
_gateway->getAdapterManager()->getAggregater()->removeAggregateTopic( _gateway->getAdapterManager()->getAggregater()->removeAggregateTopic(&topic, client);
&topic, client);
unsubscribe->setMsgId(msgId); unsubscribe->setMsgId(msgId);
Event* ev = new Event(); Event* ev = new Event();

View File

@@ -166,8 +166,7 @@ bool Topic::isMatch(string* topicName)
void Topic::print(void) void Topic::print(void)
{ {
WRITELOG("TopicName=%s ID=%d Type=%d\n", _topicName->c_str(), _topicId, WRITELOG("TopicName=%s ID=%d Type=%d\n", _topicName->c_str(), _topicId, _type);
_type);
} }
/*===================================== /*=====================================
@@ -402,16 +401,16 @@ TopicIdMapElement::TopicIdMapElement(uint16_t msgId, uint16_t topicId, MQTTSN_to
_msgId = msgId; _msgId = msgId;
_topicId = topicId; _topicId = topicId;
_type = topic->type; _type = topic->type;
_wildcard = 0; _wildcard = 0;
_next = nullptr; _next = nullptr;
_prev = nullptr; _prev = nullptr;
if (_type == MQTTSN_TOPIC_TYPE_NORMAL) if (_type == MQTTSN_TOPIC_TYPE_NORMAL)
{ {
if ( strchr(topic->data.long_.name, '#') != 0 || strchr(topic->data.long_.name, '+') != 0 ) if (strchr(topic->data.long_.name, '#') != 0 || strchr(topic->data.long_.name, '+') != 0)
{ {
_wildcard = 1; _wildcard = 1;
} }
} }
} }
@@ -427,14 +426,14 @@ MQTTSN_topicTypes TopicIdMapElement::getTopicType(void)
uint16_t TopicIdMapElement::getTopicId(void) uint16_t TopicIdMapElement::getTopicId(void)
{ {
if (_wildcard > 0) if (_wildcard > 0)
{ {
return 0; return 0;
} }
else else
{ {
return _topicId; return _topicId;
} }
} }
TopicIdMap::TopicIdMap() TopicIdMap::TopicIdMap()
@@ -473,8 +472,7 @@ TopicIdMapElement* TopicIdMap::getElement(uint16_t msgId)
TopicIdMapElement* TopicIdMap::add(uint16_t msgId, uint16_t topicId, MQTTSN_topicid* topic) TopicIdMapElement* TopicIdMap::add(uint16_t msgId, uint16_t topicId, MQTTSN_topicid* topic)
{ {
if (_cnt > _maxInflight * 2 if (_cnt > _maxInflight * 2 || (topicId == 0 && topic->type != MQTTSN_TOPIC_TYPE_SHORT))
|| (topicId == 0 && topic->type != MQTTSN_TOPIC_TYPE_SHORT))
{ {
return 0; return 0;
} }

View File

@@ -101,7 +101,7 @@ public:
TopicIdMap(); TopicIdMap();
~TopicIdMap(); ~TopicIdMap();
TopicIdMapElement* getElement(uint16_t msgId); TopicIdMapElement* getElement(uint16_t msgId);
TopicIdMapElement* add(uint16_t msgId, uint16_t topicId, MQTTSN_topicid* topic); TopicIdMapElement* add(uint16_t msgId, uint16_t topicId, MQTTSN_topicid* topic);
void erase(uint16_t msgId); void erase(uint16_t msgId);
void clear(void); void clear(void);
private: private:

View File

@@ -35,7 +35,7 @@ Gateway::Gateway(void)
theMultiTaskProcess = this; theMultiTaskProcess = this;
theProcess = this; theProcess = this;
_packetEventQue.setMaxSize(MAX_INFLIGHTMESSAGES * MAX_CLIENTS); _packetEventQue.setMaxSize(MAX_INFLIGHTMESSAGES * MAX_CLIENTS);
_clientList = new ClientList(); _clientList = new ClientList(this);
_adapterManager = new AdapterManager(this); _adapterManager = new AdapterManager(this);
_topics = new Topics(); _topics = new Topics();
_stopFlg = false; _stopFlg = false;
@@ -101,6 +101,11 @@ Gateway::~Gateway()
free(_params.qosMinusClientListName); free(_params.qosMinusClientListName);
} }
if (_params.bleAddress)
{
free(_params.bleAddress);
}
if (_adapterManager) if (_adapterManager)
{ {
delete _adapterManager; delete _adapterManager;
@@ -114,7 +119,6 @@ Gateway::~Gateway()
{ {
delete _topics; delete _topics;
} }
// WRITELOG("Gateway is deleted normally.\r\n");
} }
int Gateway::getParam(const char* parameter, char* value) int Gateway::getParam(const char* parameter, char* value)
@@ -201,7 +205,7 @@ void Gateway::initialize(int argc, char** argv)
_params.mqttVersion = atoi(param); _params.mqttVersion = atoi(param);
} }
_params.maxInflightMsgs = DEFAULT_MQTT_VERSION; _params.maxInflightMsgs = MAX_INFLIGHTMESSAGES;
if (getParam("MaxInflightMsgs", param) == 0) if (getParam("MaxInflightMsgs", param) == 0)
{ {
_params.maxInflightMsgs = atoi(param); _params.maxInflightMsgs = atoi(param);
@@ -272,12 +276,25 @@ void Gateway::initialize(int argc, char** argv)
} }
} }
_params.maxClients = MAX_CLIENTS;
if (getParam("MaxNumberOfClients", param) == 0)
{
_params.maxClients = atoi(param);
}
if (getParam("BleAddress", param) == 0)
{
_params.bleAddress = strdup(param);
}
/* Initialize adapters */ /* Initialize adapters */
_adapterManager->initialize(_params.gatewayName, _params.aggregatingGw, _adapterManager->initialize(_params.gatewayName, _params.aggregatingGw, _params.forwarder, _params.qosMinus1);
_params.forwarder, _params.qosMinus1);
/* Setup ClientList and Predefined topics */ /* Setup ClientList and Predefined topics */
_clientList->initialize(_params.aggregatingGw); _clientList->initialize(_params.aggregatingGw);
/* SensorNetwork initialize */
_sensorNetwork.initialize();
} }
void Gateway::run(void) void Gateway::run(void)
@@ -291,8 +308,7 @@ void Gateway::run(void)
WRITELOG(" *\n%s\n", PAHO_COPYRIGHT3); WRITELOG(" *\n%s\n", PAHO_COPYRIGHT3);
WRITELOG(" * Version: %s\n", PAHO_GATEWAY_VERSION); WRITELOG(" * Version: %s\n", PAHO_GATEWAY_VERSION);
WRITELOG("%s\n", PAHO_COPYRIGHT4); WRITELOG("%s\n", PAHO_COPYRIGHT4);
WRITELOG("\n%s %s has been started.\n\n", currentDateTime(), WRITELOG("\n%s %s has been started.\n\n", currentDateTime(), _params.gatewayName);
_params.gatewayName);
WRITELOG(" ConfigFile: %s\n", _params.configName); WRITELOG(" ConfigFile: %s\n", _params.configName);
if (_params.clientListName) if (_params.clientListName)
@@ -306,8 +322,8 @@ void Gateway::run(void)
} }
WRITELOG(" SensorN/W: %s\n", _sensorNetwork.getDescription()); WRITELOG(" SensorN/W: %s\n", _sensorNetwork.getDescription());
WRITELOG(" Broker: %s : %s, %s\n", _params.brokerName, _params.port, WRITELOG(" Broker: %s : %s, %s\n", _params.brokerName, _params.port, _params.portSecure);
_params.portSecure); WRITELOG(" Max number of Clients: %d\n", _params.maxClients);
WRITELOG(" RootCApath: %s\n", _params.rootCApath); WRITELOG(" RootCApath: %s\n", _params.rootCApath);
WRITELOG(" RootCAfile: %s\n", _params.rootCAfile); WRITELOG(" RootCAfile: %s\n", _params.rootCAfile);
WRITELOG(" CertKey: %s\n", _params.certKey); WRITELOG(" CertKey: %s\n", _params.certKey);
@@ -390,8 +406,7 @@ Topics* Gateway::getTopics(void)
bool Gateway::hasSecureConnection(void) bool Gateway::hasSecureConnection(void)
{ {
return (_params.certKey && _params.privateKey && _params.rootCApath return (_params.certKey && _params.privateKey && _params.rootCApath && _params.rootCAfile);
&& _params.rootCAfile);
} }
/*===================================== /*=====================================
Class EventQue Class EventQue

View File

@@ -167,6 +167,8 @@ public:
bool aggregatingGw { false }; bool aggregatingGw { false };
bool qosMinus1 { false }; bool qosMinus1 { false };
bool forwarder { false }; bool forwarder { false };
int maxClients {0};
char* bleAddress { nullptr };
}; };
/*===================================== /*=====================================
@@ -174,6 +176,7 @@ public:
=====================================*/ =====================================*/
class AdapterManager; class AdapterManager;
class ClientList; class ClientList;
class ClientsPool;
class Gateway: public MultiTaskProcess class Gateway: public MultiTaskProcess
{ {
@@ -201,13 +204,13 @@ public:
private: private:
GatewayParams _params; GatewayParams _params;
ClientList* _clientList { nullptr }; ClientList* _clientList;
EventQue _packetEventQue; EventQue _packetEventQue;
EventQue _brokerSendQue; EventQue _brokerSendQue;
EventQue _clientSendQue; EventQue _clientSendQue;
LightIndicator _lightIndicator; LightIndicator _lightIndicator;
SensorNetwork _sensorNetwork; SensorNetwork _sensorNetwork;
AdapterManager* _adapterManager { nullptr }; AdapterManager* _adapterManager;
Topics* _topics; Topics* _topics;
bool _stopFlg; bool _stopFlg;
}; };

View File

@@ -524,7 +524,7 @@ bool Thread::equals(pthread_t *t1, pthread_t *t2)
int Thread::start(void) int Thread::start(void)
{ {
Runnable* runnable = this; Runnable* runnable = this;
return pthread_create(&_threadID, 0, _run, runnable); return pthread_create(&_threadID, 0, _run, runnable);
} }

View File

@@ -95,7 +95,7 @@ private:
class RingBuffer class RingBuffer
{ {
public: public:
RingBuffer(const char* keyDirctory = MQTTSNGW_KEY_DIRECTORY); RingBuffer(const char* keyDirctory = MQTTSNGW_KEY_DIRECTORY);
~RingBuffer(); ~RingBuffer();
void put(char* buffer); void put(char* buffer);
int get(char* buffer, int bufferLength); int get(char* buffer, int bufferLength);

View File

@@ -0,0 +1,425 @@
/**************************************************************************************
* Copyright (c) 2016, Tomoaki Yamaguchi
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Tomoaki Yamaguchi - initial API and implementation and/or initial documentation
**************************************************************************************/
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/rfcomm.h>
#include <string.h>
#include <regex>
#include <string>
#include <stdlib.h>
#include "SensorNetwork.h"
#include "MQTTSNGWProcess.h"
using namespace std;
using namespace MQTTSNGW;
/*===========================================
* Class SensorNetAddreess
* These 4 methods are minimum requirements for the SensorNetAddress class.
* isMatch(SensorNetAddress* )
* operator =(SensorNetAddress& )
* setAddress(string* )
* sprint(char* )
* BlePort class requires these 3 methods.
* getIpAddress(void)
* getPortNo(void)
* setAddress(uint32_t BtAddr, uint16_t channel)
============================================*/
bdaddr_t NullAddr = { 0, 0, 0, 0, 0, 0 };
SensorNetAddress::SensorNetAddress()
{
_channel = 0;
bacpy(&_bdAddr, &NullAddr);
}
SensorNetAddress::~SensorNetAddress()
{
}
bdaddr_t* SensorNetAddress::getAddress(void)
{
return &_bdAddr;
}
uint16_t SensorNetAddress::getPortNo(void)
{
return _channel;
}
void SensorNetAddress::setAddress(bdaddr_t BdAddr, uint16_t channel)
{
bacpy(&_bdAddr, &BdAddr);
_channel = channel;
}
/**
* Set Address data to SensorNetAddress
*
* @param *dev_channel is "Device_Address.Channel" format string
* @return success = 0, Invalid format = -1
*
* Valid channels are 1 to 30.
*
* Client01,XX:XX:XX:XX:XX:XX.1
*
*/
int SensorNetAddress::setAddress(string* dev_channel)
{
int rc = -1;
size_t pos = dev_channel->find_first_of(".");
if (pos == string::npos)
{
_channel = 0;
memset(&_bdAddr, 0, sizeof(bdaddr_t));
return rc;
}
string dvAddr = dev_channel->substr(0, pos);
string strchannel = dev_channel->substr(pos + 1);
if (strchannel == "*")
{
_channel = 0;
}
else
{
_channel = atoi(strchannel.c_str());
}
str2ba(dvAddr.c_str(), &_bdAddr);
if ((_channel < 0 && _channel > 30) || bacmp(&_bdAddr, &NullAddr) == 0)
{
return rc;
}
return 0;
}
bool SensorNetAddress::isMatch(SensorNetAddress* addr)
{
return ((this->_channel == addr->_channel) && bacmp(&this->_bdAddr, &addr->_bdAddr) == 0);
}
SensorNetAddress& SensorNetAddress::operator =(SensorNetAddress& addr)
{
this->_channel = addr._channel;
this->_bdAddr = addr._bdAddr;
return *this;
}
char* SensorNetAddress::sprint(char* buf)
{
ba2str(const_cast<bdaddr_t*>(&_bdAddr), buf);
sprintf(buf + strlen(buf), ".%d", _channel);
return buf;
}
/*================================================================
Class SensorNetwork
getDescpription( ) is used by Gateway::initialize( )
initialize( ) is used by Gateway::initialize( )
getSenderAddress( ) is used by ClientRecvTask::run( )
broadcast( ) is used by MQTTSNPacket::broadcast( )
unicast( ) is used by MQTTSNPacket::unicast( )
read( ) is used by MQTTSNPacket::recv( )
================================================================*/
SensorNetwork::SensorNetwork()
{
}
SensorNetwork::~SensorNetwork()
{
}
int SensorNetwork::unicast(const uint8_t* payload, uint16_t payloadLength, SensorNetAddress* sendToAddr)
{
uint16_t ch = sendToAddr->getPortNo();
BlePort* blep = &_rfPorts[ch - 1];
int rc = 0;
errno = 0;
if ((rc = blep->send(payload, (uint32_t) payloadLength)) < 0)
{
D_NWSTACK("errno == %d in BlePort::sendto %d\n", errno, ch);
} D_NWSTACK("sendto %u length = %d\n", ch, rc);
return rc;
}
int SensorNetwork::broadcast(const uint8_t* payload, uint16_t payloadLength)
{
int rc = 0;
for (int i = 0; i < MAX_RFCOMM_CH; i++)
{
errno = 0;
if (_rfPorts[i].getSock() > 0)
{
if ((rc = _rfPorts[i].send(payload, (uint32_t) payloadLength)) < 0)
{
D_NWSTACK("errno == %d in BlePort::sendto %d\n", errno, i + 1);
}D_NWSTACK("sendto %u length = %d\n", i + 1, rc);
}
}
return rc;
}
int SensorNetwork::read(uint8_t* buf, uint16_t bufLen)
{
struct timeval timeout;
fd_set recvfds;
int maxSock = 0;
timeout.tv_sec = 1;
timeout.tv_usec = 0; // 1 sec
FD_ZERO(&recvfds);
for (int i = 0; i < MAX_RFCOMM_CH; i++)
{
if (_rfPorts[i]._rfCommSock > 0)
{
if (maxSock < _rfPorts[i]._rfCommSock)
{
maxSock = _rfPorts[i]._rfCommSock;
}
FD_SET(_rfPorts[i]._rfCommSock, &recvfds);
}
else if (_rfPorts[i]._listenSock > 0)
{
if (maxSock < _rfPorts[i]._listenSock)
{
maxSock = _rfPorts[i]._listenSock;
}
FD_SET(_rfPorts[i]._listenSock, &recvfds);
}
}
int rc = 0;
if (select(maxSock + 1, &recvfds, 0, 0, &timeout) > 0)
{
WRITELOG("RECV\n");
for (int i = 0; i < MAX_RFCOMM_CH; i++)
{
if (_rfPorts[i]._rfCommSock > 0)
{
if (FD_ISSET(_rfPorts[i]._rfCommSock, &recvfds))
{
rc = _rfPorts[i].recv(buf, bufLen);
if (rc == -1)
{
_rfPorts[i].close();
}
}
}
else if (_rfPorts[i]._listenSock > 0)
{
if (FD_ISSET(_rfPorts[i]._listenSock, &recvfds))
{
int sock = _rfPorts[i].accept(&_senderAddr);
if (sock > 0)
{
_rfPorts[i]._rfCommSock = sock;
}
WRITELOG("accept sock= %d CH = %d\n", sock, i + 1);
}
}
}
}
return rc;
}
/**
* Prepare UDP sockets and description of SensorNetwork like
* "UDP Multicast 225.1.1.1:1883 Gateway Port 10000".
* The description is for a start up prompt.
*/
void SensorNetwork::initialize(void)
{
char param[MQTTSNGW_PARAM_MAX];
string devAddr;
SensorNetAddress sa;
/*
* theProcess->getParam( ) copies
* a text specified by "Key" into param[] from the Gateway.conf
*
* in Gateway.conf e.g.
*
* # BLE
* BleAddress=XX:XX:XX:XX:XX:XX.0
*
*/
if (theProcess->getParam("BleAddress", param) == 0)
{
devAddr = param;
_description = "BLE RFCOMM ";
_description += param;
}
errno = 0;
if (sa.setAddress(&devAddr) == -1)
{
throw EXCEPTION("Invalid BLE Address", errno);
}
/* Prepare BLE sockets */
WRITELOG("Initialize ble\n");
int rc = MAX_RFCOMM_CH;
for (uint16_t i = 0; i < MAX_RFCOMM_CH; i++)
{
rc += _rfPorts[i].open(sa.getAddress(), i + 1);
}
if (rc == 0)
{
throw EXCEPTION("Can't open BLE RFComms", errno);
}
}
const char* SensorNetwork::getDescription(void)
{
return _description.c_str();
}
SensorNetAddress* SensorNetwork::getSenderAddress(void)
{
return &_senderAddr;
}
/*=========================================
Class BleStack
=========================================*/
BlePort::BlePort()
{
_disconReq = false;
_rfCommSock = 0;
_listenSock = 0;
_channel = 0;
}
BlePort::~BlePort()
{
close();
if (_listenSock > 0)
{
::close(_listenSock);
}
}
void BlePort::close(void)
{
if (_rfCommSock > 0)
{
::close(_rfCommSock);
_rfCommSock = 0;
}
}
int BlePort::open(bdaddr_t* devAddr, uint16_t channel)
{
const int reuse = 1;
if (channel < 1 || channel > 30)
{
D_NWSTACK("error Channel undefined in BlePort::open\n");
return 0;
}
/*------ Create unicast socket --------*/
_listenSock = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
if (_listenSock < 0)
{
D_NWSTACK("error can't create Rfcomm socket in BlePort::open\n");
return 0;
}
sockaddr_rc addru;
addru.rc_family = AF_BLUETOOTH;
addru.rc_channel = channel;
bacpy(&addru.rc_bdaddr, devAddr);
uint8_t buf[20];
ba2str(devAddr, (char*) buf);
setsockopt(_listenSock, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));
errno = 0;
if (::bind(_listenSock, (sockaddr*) &addru, sizeof(addru)) < 0)
{
WRITELOG("\033[0m\033[0;31mCan't bind RFCOMM CH = %d %s\033[0m\033[0;37m\n", channel, strerror(errno));
::close(_listenSock);
return 0;
}
_channel = channel;
::listen(_listenSock, 1);
WRITELOG("Listen RFCOMM CH = %d\n", channel);
return 1;
}
int BlePort::send(const uint8_t* buf, uint32_t length)
{
WRITELOG("sock = %d\n", _rfCommSock);
return ::send(_rfCommSock, buf, length, 0);
}
int BlePort::recv(uint8_t* buf, uint16_t len)
{
int rc = 0;
errno = 0;
rc = ::read(_rfCommSock, buf, len);
if (rc < 0 && errno != EAGAIN)
{
D_NWSTACK("errno = %d in BlePort::recv\n", errno);
return -1;
}
return rc;
}
int BlePort::accept(SensorNetAddress* addr)
{
struct sockaddr_rc devAddr = { 0 };
socklen_t opt = sizeof(devAddr);
int sock = 0;
errno = 0;
sock = ::accept(_listenSock, (sockaddr *) &devAddr, &opt);
if (sock < 0 && errno != EAGAIN)
{
D_NWSTACK("errno == %d in BlePort::recv\n", errno);
return -1;
}
bdaddr_t bdAddr = devAddr.rc_bdaddr;
addr->setAddress(bdAddr, _channel);
return sock;
}
int BlePort::getSock(void)
{
return _rfCommSock;
}

View File

@@ -0,0 +1,104 @@
/**************************************************************************************
* Copyright (c) 2016, Tomoaki Yamaguchi
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Tomoaki Yamaguchi - initial API and implementation and/or initial documentation
**************************************************************************************/
#ifndef SENSORNETWORK_H_
#define SENSORNETWORK_H_
#include "MQTTSNGWDefines.h"
#include <string>
#include <bluetooth/bluetooth.h>
using namespace std;
namespace MQTTSNGW
{
#ifdef DEBUG_NWSTACK
#define D_NWSTACK(...) printf(__VA_ARGS__)
#else
#define D_NWSTACK(...)
#endif
#define MAX_RFCOMM_CH 30
/*===========================================
Class SensorNetAddreess
============================================*/
class SensorNetAddress
{
public:
SensorNetAddress();
~SensorNetAddress();
void setAddress(bdaddr_t bdAddr, uint16_t channel);
int setAddress(string* data);
uint16_t getPortNo(void);
bdaddr_t* getAddress(void);
bool isMatch(SensorNetAddress* addr);
SensorNetAddress& operator =(SensorNetAddress& addr);
char* sprint(char* buf);
private:
uint16_t _channel;
bdaddr_t _bdAddr;
};
/*========================================
Class BlePort
=======================================*/
class BlePort
{
friend class SensorNetwork;
public:
BlePort();
virtual ~BlePort();
int open(bdaddr_t* devAddress, uint16_t channel);
void close(void);
int send(const uint8_t* buf, uint32_t length);
int recv(uint8_t* buf, uint16_t len);
int getSock(void);
int accept(SensorNetAddress* addr);
private:
int _rfCommSock;
int _listenSock;
uint16_t _channel;
bool _disconReq;
};
/*===========================================
Class SensorNetwork
============================================*/
class SensorNetwork
{
public:
SensorNetwork();
~SensorNetwork();
int unicast(const uint8_t* payload, uint16_t payloadLength, SensorNetAddress* sendto);
int broadcast(const uint8_t* payload, uint16_t payloadLength);
int read(uint8_t* buf, uint16_t bufLen);
void initialize(void);
const char* getDescription(void);
SensorNetAddress* getSenderAddress(void);
private:
// sockets for RFCOMM
BlePort _rfPorts[MAX_RFCOMM_CH];
SensorNetAddress _senderAddr;
string _description;
};
}
#endif /* SENSORNETWORK_H_ */

View File

@@ -142,7 +142,7 @@ char* SensorNetAddress::sprint(char* buf)
In Gateway version 1.0 In Gateway version 1.0
getDescpription( ) is used by Gateway::initialize( ) getDescpription( ) is used by Gateway::initialize( )
initialize( ) is used by ClientSendTask::initialize( ) initialize( ) is used by Gateway::initialize( )
getSenderAddress( ) is used by ClientRecvTask::run( ) getSenderAddress( ) is used by ClientRecvTask::run( )
broadcast( ) is used by MQTTSNPacket::broadcast( ) broadcast( ) is used by MQTTSNPacket::broadcast( )
unicast( ) is used by MQTTSNPacket::unicast( ) unicast( ) is used by MQTTSNPacket::unicast( )

View File

@@ -9,6 +9,8 @@ echo "travis build dir $TRAVIS_BUILD_DIR pwd $PWD"
cmake .. -DSENSORNET=loralink cmake .. -DSENSORNET=loralink
make make
ctest -VV --timeout 600 ctest -VV --timeout 600
cmake .. -DSENSORNET=ble
make MQTT-SNGateway
cmake .. -DSENSORNET=xbee cmake .. -DSENSORNET=xbee
make MQTT-SNGateway make MQTT-SNGateway
cmake .. -DSENSORNET=udp6 cmake .. -DSENSORNET=udp6