Files
paho.mqtt-sn.embedded-c/MQTTSNGateway/src/MQTTSNGWPacketHandleTask.cpp
tomoaki 5fb4312aad This branch for debugging DTLS #90, #150, #195, #227
The purpose of this branch is to share work in process.
Change sellect() of UDP to poll()
Rewrite UDP6 for DTLS6

Known bug: can't reconnect DTLS

Signed-off-by: tomoaki <tomoaki@tomy-tech.com>
2021-08-01 19:45:58 +09:00

372 lines
11 KiB
C++

/**************************************************************************************
* 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
* Tieto Poland Sp. z o.o. - Gateway improvements
**************************************************************************************/
#include "MQTTSNGWDefines.h"
#include "MQTTSNGWPacketHandleTask.h"
#include "MQTTSNGWProcess.h"
#include "MQTTGWPacket.h"
#include "MQTTSNGWClient.h"
#include "MQTTSNGWProcess.h"
#include "MQTTSNGWAdapterManager.h"
#include "MQTTGWConnectionHandler.h"
#include "MQTTGWPublishHandler.h"
#include "MQTTGWSubscribeHandler.h"
#include "MQTTSNGWConnectionHandler.h"
#include "MQTTSNGWPublishHandler.h"
#include "MQTTSNGWSubscribeHandler.h"
#include "Timer.h"
#include "MQTTSNAggregateConnectionHandler.h"
#include <string.h>
using namespace std;
using namespace MQTTSNGW;
#define EVENT_QUE_TIME_OUT 2000 // 2000 msecs
char* currentDateTime(void);
/*=====================================
Class PacketHandleTask
=====================================*/
PacketHandleTask::PacketHandleTask(Gateway* gateway)
{
_gateway = gateway;
_gateway->attach((Thread*) this);
_mqttConnection = new MQTTGWConnectionHandler(_gateway);
_mqttPublish = new MQTTGWPublishHandler(_gateway);
_mqttSubscribe = new MQTTGWSubscribeHandler(_gateway);
_mqttsnConnection = new MQTTSNConnectionHandler(_gateway);
_mqttsnPublish = new MQTTSNPublishHandler(_gateway);
_mqttsnSubscribe = new MQTTSNSubscribeHandler(_gateway);
_mqttsnAggrConnection = new MQTTSNAggregateConnectionHandler(_gateway);
setTaskName("PacketHandleTask");
}
/**
* Destructor is called by Gateway's destructor indirectly.
*/
PacketHandleTask::~PacketHandleTask()
{
if (_mqttConnection)
{
delete _mqttConnection;
}
if (_mqttPublish)
{
delete _mqttPublish;
}
if (_mqttSubscribe)
{
delete _mqttSubscribe;
}
if (_mqttsnConnection)
{
delete _mqttsnConnection;
}
if (_mqttsnPublish)
{
delete _mqttsnPublish;
}
if (_mqttsnSubscribe)
{
delete _mqttsnSubscribe;
}
if (_mqttsnAggrConnection)
{
delete _mqttsnAggrConnection;
}
}
void PacketHandleTask::run()
{
Event* ev = nullptr;
EventQue* eventQue = _gateway->getPacketEventQue();
AdapterManager* adpMgr = _gateway->getAdapterManager();
Client* client = nullptr;
MQTTSNPacket* snPacket = nullptr;
MQTTGWPacket* brPacket = nullptr;
char msgId[6];
memset(msgId, 0, 6);
_advertiseTimer.start(_gateway->getGWParams()->keepAlive * 1000UL);
while (true)
{
/* wait Event */
ev = eventQue->timedwait(EVENT_QUE_TIME_OUT);
if (ev->getEventType() == EtStop)
{
WRITELOG("%s %s stopped.\n", currentDateTime(), getTaskName());
delete ev;
return;
}
if (ev->getEventType() == EtTimeout)
{
/*------ Check Keep Alive Timer & send Advertise ------*/
if (_advertiseTimer.isTimeup())
{
_mqttsnConnection->sendADVERTISE();
_advertiseTimer.start(_gateway->getGWParams()->keepAlive * 1000UL);
}
/*------ Check Adapters Connect or PINGREQ ------*/
adpMgr->checkConnection();
}
/*------ Handle SEARCHGW Message ---------*/
else if (ev->getEventType() == EtBroadcast)
{
snPacket = ev->getMQTTSNPacket();
_mqttsnConnection->handleSearchgw(snPacket);
}
/*------ Handle Messages form Clients ---------*/
else if (ev->getEventType() == EtClientRecv)
{
client = ev->getClient();
snPacket = ev->getMQTTSNPacket();
DEBUGLOG(" PacketHandleTask gets %s %s from the client.\n", snPacket->getName(), snPacket->getMsgId(msgId));
if (adpMgr->isAggregatedClient(client))
{
aggregatePacketHandler(client, snPacket); // client is converted to Aggregater by BrokerSendTask
}
else
{
transparentPacketHandler(client, snPacket);
}
/* Reset the Timer for PINGREQ. */
client->updateStatus(snPacket);
}
/*------ Handle Messages form Broker ---------*/
else if (ev->getEventType() == EtBrokerRecv)
{
client = ev->getClient();
brPacket = ev->getMQTTGWPacket();
DEBUGLOG(" PacketHandleTask gets %s %s from the broker.\n", brPacket->getName(), brPacket->getMsgId(msgId));
if (client->isAggregater())
{
aggregatePacketHandler(client, brPacket);
}
else
{
transparentPacketHandler(client, brPacket);
}
}
delete ev;
}
}
void PacketHandleTask::aggregatePacketHandler(Client*client, MQTTSNPacket* packet)
{
switch (packet->getType())
{
case MQTTSN_CONNECT:
_mqttsnAggrConnection->handleConnect(client, packet);
break;
case MQTTSN_WILLTOPIC:
_mqttsnConnection->handleWilltopic(client, packet);
break;
case MQTTSN_WILLMSG:
_mqttsnAggrConnection->handleWillmsg(client, packet);
break;
case MQTTSN_DISCONNECT:
_mqttsnAggrConnection->handleDisconnect(client, packet);
break;
case MQTTSN_WILLTOPICUPD:
_mqttsnConnection->handleWilltopicupd(client, packet);
break;
case MQTTSN_WILLMSGUPD:
_mqttsnConnection->handleWillmsgupd(client, packet);
break;
case MQTTSN_PINGREQ:
_mqttsnAggrConnection->handlePingreq(client, packet);
break;
case MQTTSN_PUBLISH:
_mqttsnPublish->handleAggregatePublish(client, packet);
break;
case MQTTSN_PUBACK:
_mqttsnPublish->handleAggregateAck(client, packet, MQTTSN_PUBACK);
break;
case MQTTSN_PUBREC:
_mqttsnPublish->handleAggregateAck(client, packet, MQTTSN_PUBREC);
break;
case MQTTSN_PUBREL:
_mqttsnPublish->handleAggregateAck(client, packet, MQTTSN_PUBREL);
break;
case MQTTSN_PUBCOMP:
_mqttsnPublish->handleAggregateAck(client, packet, MQTTSN_PUBCOMP);
break;
case MQTTSN_REGISTER:
_mqttsnPublish->handleRegister(client, packet);
break;
case MQTTSN_REGACK:
_mqttsnPublish->handleRegAck(client, packet);
break;
case MQTTSN_SUBSCRIBE:
_mqttsnSubscribe->handleAggregateSubscribe(client, packet);
break;
case MQTTSN_UNSUBSCRIBE:
_mqttsnSubscribe->handleAggregateUnsubscribe(client, packet);
break;
default:
break;
}
}
void PacketHandleTask::aggregatePacketHandler(Client*client, MQTTGWPacket* packet)
{
switch (packet->getType())
{
case CONNACK:
_mqttConnection->handleConnack(client, packet);
break;
case PINGRESP:
_mqttConnection->handlePingresp(client, packet);
break;
case PUBLISH:
_mqttPublish->handleAggregatePublish(client, packet);
break;
case PUBACK:
_mqttPublish->handleAggregatePuback(client, packet);
break;
case PUBREC:
_mqttPublish->handleAggregateAck(client, packet, PUBREC);
break;
case PUBREL:
_mqttPublish->handleAggregatePubrel(client, packet);
break;
case PUBCOMP:
_mqttPublish->handleAggregateAck(client, packet, PUBCOMP);
break;
case SUBACK:
_mqttSubscribe->handleAggregateSuback(client, packet);
break;
case UNSUBACK:
_mqttSubscribe->handleAggregateUnsuback(client, packet);
break;
default:
break;
}
}
void PacketHandleTask::transparentPacketHandler(Client*client, MQTTSNPacket* packet)
{
switch (packet->getType())
{
case MQTTSN_CONNECT:
_mqttsnConnection->handleConnect(client, packet);
break;
case MQTTSN_WILLTOPIC:
_mqttsnConnection->handleWilltopic(client, packet);
break;
case MQTTSN_WILLMSG:
_mqttsnConnection->handleWillmsg(client, packet);
break;
case MQTTSN_DISCONNECT:
_mqttsnConnection->handleDisconnect(client, packet);
break;
case MQTTSN_WILLTOPICUPD:
_mqttsnConnection->handleWilltopicupd(client, packet);
break;
case MQTTSN_WILLMSGUPD:
_mqttsnConnection->handleWillmsgupd(client, packet);
break;
case MQTTSN_PINGREQ:
_mqttsnConnection->handlePingreq(client, packet);
break;
case MQTTSN_PUBLISH:
_mqttsnPublish->handlePublish(client, packet);
break;
case MQTTSN_PUBACK:
_mqttsnPublish->handlePuback(client, packet);
break;
case MQTTSN_PUBREC:
_mqttsnPublish->handleAck(client, packet, PUBREC);
break;
case MQTTSN_PUBREL:
_mqttsnPublish->handleAck(client, packet, PUBREL);
break;
case MQTTSN_PUBCOMP:
_mqttsnPublish->handleAck(client, packet, PUBCOMP);
break;
case MQTTSN_REGISTER:
_mqttsnPublish->handleRegister(client, packet);
break;
case MQTTSN_REGACK:
_mqttsnPublish->handleRegAck(client, packet);
break;
case MQTTSN_SUBSCRIBE:
_mqttsnSubscribe->handleSubscribe(client, packet);
break;
case MQTTSN_UNSUBSCRIBE:
_mqttsnSubscribe->handleUnsubscribe(client, packet);
break;
default:
break;
}
}
void PacketHandleTask::transparentPacketHandler(Client*client, MQTTGWPacket* packet)
{
switch (packet->getType())
{
case CONNACK:
_mqttConnection->handleConnack(client, packet);
break;
case PINGRESP:
_mqttConnection->handlePingresp(client, packet);
break;
case PUBLISH:
_mqttPublish->handlePublish(client, packet);
break;
case PUBACK:
_mqttPublish->handlePuback(client, packet);
break;
case PUBREC:
_mqttPublish->handleAck(client, packet, PUBREC);
break;
case PUBREL:
_mqttPublish->handleAck(client, packet, PUBREL);
break;
case PUBCOMP:
_mqttPublish->handleAck(client, packet, PUBCOMP);
break;
case SUBACK:
_mqttSubscribe->handleSuback(client, packet);
break;
case UNSUBACK:
_mqttSubscribe->handleUnsuback(client, packet);
break;
case DISCONNECT:
client->disconnected(); // Just change Client's status to "Disconnected"
break;
default:
break;
}
}