/************************************************************************************** * 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 "MQTTSNGWConnectionHandler.h" #include "MQTTSNGateway.h" #include "MQTTSNGWPacket.h" #include "MQTTGWPacket.h" #include using namespace std; using namespace MQTTSNGW; /*===================================== Class MQTTSNConnectionHandler =====================================*/ MQTTSNConnectionHandler::MQTTSNConnectionHandler(Gateway* gateway) { _gateway = gateway; } MQTTSNConnectionHandler::~MQTTSNConnectionHandler() { } /* * ADVERTISE */ void MQTTSNConnectionHandler::sendADVERTISE() { MQTTSNPacket* adv = new MQTTSNPacket(); adv->setADVERTISE(_gateway->getGWParams()->gatewayId, _gateway->getGWParams()->keepAlive); Event* ev1 = new Event(); ev1->setBrodcastEvent(adv); //broadcast _gateway->getClientSendQue()->post(ev1); } /* * SEARCHGW */ void MQTTSNConnectionHandler::handleSearchgw(MQTTSNPacket* packet) { if (packet->getType() == MQTTSN_SEARCHGW) { MQTTSNPacket* gwinfo = new MQTTSNPacket(); gwinfo->setGWINFO(_gateway->getGWParams()->gatewayId); Event* ev1 = new Event(); ev1->setBrodcastEvent(gwinfo); _gateway->getClientSendQue()->post(ev1); } } /* * CONNECT */ void MQTTSNConnectionHandler::handleConnect(Client* client, MQTTSNPacket* packet) { MQTTSNPacket_connectData data; if ( packet->getCONNECT(&data) == 0 ) { return; } /* clear ConnectData of Client */ Connect* connectData = client->getConnectData(); memset(connectData, 0, sizeof(Connect)); client->disconnected(); Topics* topics = client->getTopics(); /* CONNECT was not sent yet. prepare Connect data */ connectData->header.bits.type = CONNECT; connectData->clientID = client->getClientId(); connectData->version = _gateway->getGWParams()->mqttVersion; connectData->keepAliveTimer = data.duration; connectData->flags.bits.will = data.willFlag; if ((const char*) _gateway->getGWParams()->loginId != 0 && (const char*) _gateway->getGWParams()->password != 0) { connectData->flags.bits.password = 1; connectData->flags.bits.username = 1; } client->setSessionStatus(false); if (data.cleansession) { connectData->flags.bits.cleanstart = 1; /* reset the table of msgNo and TopicId pare */ client->clearWaitedPubTopicId(); client->clearWaitedSubTopicId(); /* renew the TopicList */ if (topics) { delete topics; } topics = new Topics(); client->setTopics(topics); client->setSessionStatus(true); } if (data.willFlag) { /* create & send WILLTOPICREQ message to the client */ MQTTSNPacket* reqTopic = new MQTTSNPacket(); reqTopic->setWILLTOPICREQ(); Event* evwr = new Event(); evwr->setClientSendEvent(client, reqTopic); /* Send WILLTOPICREQ to the client */ _gateway->getClientSendQue()->post(evwr); } else { /* CONNECT message was not qued in. * create CONNECT message & send it to the broker */ MQTTGWPacket* mqMsg = new MQTTGWPacket(); mqMsg->setCONNECT(client->getConnectData(), (unsigned char*)_gateway->getGWParams()->loginId, (unsigned char*)_gateway->getGWParams()->password); Event* ev1 = new Event(); ev1->setBrokerSendEvent(client, mqMsg); _gateway->getBrokerSendQue()->post(ev1); } } /* * WILLTOPIC */ void MQTTSNConnectionHandler::handleWilltopic(Client* client, MQTTSNPacket* packet) { int willQos; uint8_t willRetain; MQTTSNString willTopic; if ( packet->getWILLTOPIC(&willQos, &willRetain, &willTopic) == 0 ) { return; } client->setWillTopic(willTopic); Connect* connectData = client->getConnectData(); /* add the connectData for MQTT CONNECT message */ connectData->willTopic = client->getWillTopic(); connectData->flags.bits.willQoS = willQos; connectData->flags.bits.willRetain = willRetain; /* Send WILLMSGREQ to the client */ client->setWaitWillMsgFlg(true); MQTTSNPacket* reqMsg = new MQTTSNPacket(); reqMsg->setWILLMSGREQ(); Event* evt = new Event(); evt->setClientSendEvent(client, reqMsg); _gateway->getClientSendQue()->post(evt); } /* * WILLMSG */ void MQTTSNConnectionHandler::handleWillmsg(Client* client, MQTTSNPacket* packet) { if ( !client->isWaitWillMsg() ) { DEBUGLOG(" MQTTSNConnectionHandler::handleWillmsg WaitWillMsgFlg is off.\n"); return; } MQTTSNString willmsg; Connect* connectData = client->getConnectData(); if( client->isConnectSendable() ) { /* save WillMsg in the client */ if ( packet->getWILLMSG(&willmsg) == 0 ) { return; } client->setWillMsg(willmsg); /* create CONNECT message */ MQTTGWPacket* mqttPacket = new MQTTGWPacket(); connectData->willMsg = client->getWillMsg(); mqttPacket->setCONNECT(connectData, (unsigned char*)_gateway->getGWParams()->loginId, (unsigned char*)_gateway->getGWParams()->password); /* Send CONNECT to the broker */ Event* evt = new Event(); evt->setBrokerSendEvent(client, mqttPacket); client->setWaitWillMsgFlg(false); _gateway->getBrokerSendQue()->post(evt); } } /* * DISCONNECT */ void MQTTSNConnectionHandler::handleDisconnect(Client* client, MQTTSNPacket* packet) { Event* ev = new Event(); MQTTSNPacket* snMsg = new MQTTSNPacket(); snMsg->setDISCONNECT(0); ev->setClientSendEvent(client, snMsg); _gateway->getClientSendQue()->post(ev); uint16_t duration = 0; if ( packet->getDISCONNECT(&duration) == 0 ) { return; } if ( duration == 0 ) { MQTTGWPacket* mqMsg = new MQTTGWPacket(); mqMsg->setHeader(DISCONNECT); ev = new Event(); ev->setBrokerSendEvent(client, mqMsg); _gateway->getBrokerSendQue()->post(ev); } } /* * WILLTOPICUPD */ void MQTTSNConnectionHandler::handleWilltopicupd(Client* client, MQTTSNPacket* packet) { /* send NOT_SUPPORTED responce to the client */ MQTTSNPacket* respMsg = new MQTTSNPacket(); respMsg->setWILLTOPICRESP(MQTTSN_RC_NOT_SUPPORTED); Event* evt = new Event(); evt->setClientSendEvent(client, respMsg); _gateway->getClientSendQue()->post(evt); } /* * WILLMSGUPD */ void MQTTSNConnectionHandler::handleWillmsgupd(Client* client, MQTTSNPacket* packet) { /* send NOT_SUPPORTED responce to the client */ MQTTSNPacket* respMsg = new MQTTSNPacket(); respMsg->setWILLMSGRESP(MQTTSN_RC_NOT_SUPPORTED); Event* evt = new Event(); evt->setClientSendEvent(client, respMsg); _gateway->getClientSendQue()->post(evt); } /* * PINGREQ */ void MQTTSNConnectionHandler::handlePingreq(Client* client, MQTTSNPacket* packet) { /* send PINGREQ to the broker */ MQTTGWPacket* pingreq = new MQTTGWPacket(); pingreq->setHeader(PINGREQ); Event* evt = new Event(); evt->setBrokerSendEvent(client, pingreq); _gateway->getBrokerSendQue()->post(evt); }