Example #1
0
/*-------------------------------------------------------
                Downstream MQTTPublish
 -------------------------------------------------------*/
void GatewayControlTask::handlePublish(Event* ev, ClientNode* clnode, MQTTMessage* msg){

	MQTTPublish* mqMsg = static_cast<MQTTPublish*>(msg);
	MQTTSnPublish* snMsg = new MQTTSnPublish();

	string* tp = mqMsg->getTopic();
	uint16_t tpId;

	if(tp->size() == 2){
		tpId = getUint16((uint8_t*)tp);
		snMsg->setFlags(MQTTSN_TOPIC_TYPE_SHORT);
	}else{
		tpId = clnode->getTopics()->getTopicId(tp);
		snMsg->setFlags(MQTTSN_TOPIC_TYPE_NORMAL);
	}
	if(tpId == 0){
		/* ----- may be a publish message response of subscribed with '#' or '+' -----*/
		tpId = clnode->getTopics()->createTopic(tp);

		if(tpId > 0){
			MQTTSnRegister* regMsg = new MQTTSnRegister();
			regMsg->setTopicId(tpId);
			regMsg->setTopicName(tp);
			printf(FORMAT2, currentDateTime(), "REGISTER", RIGHTARROW, clnode->getNodeId()->c_str(), msgPrint(regMsg));

			clnode->setClientSendMessage(regMsg);
			Event* evrg = new Event();
			evrg->setClientSendEvent(clnode);
			_res->getClientSendQue()->post(evrg);   // Send Register first.
		}else{
			printf("GatewayControlTask Can't create Topic   %s\n", tp->c_str());
			return;
		}
	}

	snMsg->setTopicId(tpId);
	snMsg->setMsgId(mqMsg->getMessageId());
	snMsg->setData(mqMsg->getPayload(),mqMsg->getPayloadLength());
	snMsg->setQos(mqMsg->getQos());

	if(mqMsg->isDup()){
		snMsg->setDup();
	}

	if(mqMsg->isRetain()){
		snMsg->setDup();
	}
	clnode->setClientSendMessage(snMsg);
	printf(GREEN_FORMAT1, currentDateTime(), "PUBLISH", RIGHTARROW, clnode->getNodeId()->c_str(), msgPrint(snMsg));

	Event* ev1 = new Event();
	ev1->setClientSendEvent(clnode);
	_res->getClientSendQue()->post(ev1);

}
Example #2
0
void GatewayControlTask::run(){
	Timer advertiseTimer;
	Timer sendUnixTimer;
	Event* ev = 0;

	_gatewayId = atoi(_res->getArgv('i'));
	if (_gatewayId == 0 || _gatewayId > 255){
		THROW_EXCEPTION(ExFatal, ERRNO_SYS_05, "Invalid Gateway Id");  // ABORT
	}

	int keepAlive = KEEP_ALIVE_TIME;
	if(_res->getArgv('k') != 0){
		keepAlive =atoi( _res->getArgv('k'));
		if (keepAlive > 65536){
				THROW_EXCEPTION(ExFatal, ERRNO_SYS_06, "KeepAliveTime is grater than 65536 Secs");  // ABORT
		}
	}

	if(_res->getArgv('l') != 0){
		_loginId = _res->getArgv('l');
	}
	if(_res->getArgv('w') != 0){
		_password = _res->getArgv('w');
	}

	_eventQue = _res->getGatewayEventQue();

	advertiseTimer.start(keepAlive * 1000UL);

	printf("%s TomyGateway start\n", currentDateTime());


	while(true){

		ev = _eventQue->timedwait(TIMEOUT_PERIOD);

		/*------     Check Client is Lost    ---------*/
		if(ev->getEventType() == EtTimeout){
			ClientList* clist = _res->getClientList();

			for( int i = 0; i < clist->getClientCount(); i++){
				if((*clist)[i]){
					(*clist)[i]->checkTimeover();
				}else{
					break;
				}
			}

			/*------ Check Keep Alive Timer & send Advertise ------*/
			if(advertiseTimer.isTimeup()){
				MQTTSnAdvertise* adv = new MQTTSnAdvertise();
				adv->setGwId(_gatewayId);
				adv->setDuration(keepAlive);
				Event* ev1 = new Event();
				ev1->setEvent(adv);  //broadcast
				printf(YELLOW_FORMAT2, currentDateTime(), "ADVERTISE", LEFTARROW, GATEWAY, msgPrint(adv));

				_res->getClientSendQue()->post(ev1);
				advertiseTimer.start(keepAlive * 1000UL);
				sendUnixTimer.start(SEND_UNIXTIME_TIME * 1000UL);
			}

			/*------ Check Timer & send UixTime ------*/
			if(sendUnixTimer.isTimeup()){
				uint8_t buf[4];
				uint32_t tm = time(0);
				setUint32(buf,tm);

				MQTTSnPublish* msg = new MQTTSnPublish();

				msg->setTopicId(MQTTSN_TOPICID_PREDEFINED_TIME);
				msg->setTopicIdType(MQTTSN_TOPIC_TYPE_PREDEFINED);
				msg->setData(buf, 4);
				msg->setQos(0);

				Event* ev1 = new Event();
				ev1->setEvent(msg);
				printf(YELLOW_FORMAT2, currentDateTime(), "PUBLISH", LEFTARROW, GATEWAY, msgPrint(msg));

				_res->getClientSendQue()->post(ev1);
				sendUnixTimer.stop();
			}
		}

		/*------   Check  SEARCHGW & send GWINFO      ---------*/
		else if(ev->getEventType() == EtBroadcast){
			MQTTSnMessage* msg = ev->getMqttSnMessage();
			printf(YELLOW_FORMAT2, currentDateTime(), "SERCHGW", LEFTARROW, CLIENT, msgPrint(msg));

			if(msg->getType() == MQTTSN_TYPE_SEARCHGW){
				if(_res->getClientList()->getClientCount() <  MAX_CLIENT_NODES ){
					MQTTSnGwInfo* gwinfo = new MQTTSnGwInfo();
					gwinfo->setGwId(_gatewayId);
					Event* ev1 = new Event();
					ev1->setEvent(gwinfo);
					printf(YELLOW_FORMAT1, currentDateTime(), "GWINFO", RIGHTARROW, CLIENT, msgPrint(gwinfo));

					_res->getClientSendQue()->post(ev1);
				}
			}

		}
		
		/*------   Message form Clients      ---------*/
		else if(ev->getEventType() == EtClientRecv){

			ClientNode* clnode = ev->getClientNode();
			MQTTSnMessage* msg = clnode->getClientRecvMessage();
			clnode->updateStatus(msg);
			
			if(msg->getType() == MQTTSN_TYPE_PUBLISH){
				handleSnPublish(ev, clnode, msg);
			}else if(msg->getType() == MQTTSN_TYPE_SUBSCRIBE){
				handleSnSubscribe(ev, clnode, msg);
			}else if(msg->getType() == MQTTSN_TYPE_UNSUBSCRIBE){
				handleSnUnsubscribe(ev, clnode, msg);
			}else if(msg->getType() == MQTTSN_TYPE_PINGREQ){
				handleSnPingReq(ev, clnode, msg);
			}else if(msg->getType() == MQTTSN_TYPE_PUBACK){
				handleSnPubAck(ev, clnode, msg);
			}else if(msg->getType() == MQTTSN_TYPE_CONNECT){
				handleSnConnect(ev, clnode, msg);
			}else if(msg->getType() == MQTTSN_TYPE_WILLTOPIC){
				handleSnWillTopic(ev, clnode, msg);
			}else if(msg->getType() == MQTTSN_TYPE_WILLMSG){
				handleSnWillMsg(ev, clnode, msg);
			}else if(msg->getType() == MQTTSN_TYPE_DISCONNECT){
				handleSnDisconnect(ev, clnode, msg);
			}else if(msg->getType() == MQTTSN_TYPE_REGISTER){
				handleSnRegister(ev, clnode, msg);
			}else if(msg->getType() == MQTTSN_TYPE_PUBREC){
				handleSnPubRec(ev, clnode, msg);
			}else if(msg->getType() == MQTTSN_TYPE_PUBREL){
				handleSnPubRel(ev, clnode, msg);
			}else if(msg->getType() == MQTTSN_TYPE_PUBCOMP){
				handleSnPubComp(ev, clnode, msg);
			}else{
				printf("%s   Irregular ClientRecvMessage\n", currentDateTime());
			}

		}
		/*------   Message form Broker      ---------*/
		else if(ev->getEventType() == EtBrokerRecv){

			ClientNode* clnode = ev->getClientNode();
			MQTTMessage* msg = clnode->getBrokerRecvMessage();
			
			if(msg->getType() == MQTT_TYPE_PUBACK){
				handlePuback(ev, clnode, msg);
			}else if(msg->getType() == MQTT_TYPE_PINGRESP){
				handlePingresp(ev, clnode, msg);
			}else if(msg->getType() == MQTT_TYPE_SUBACK){
				handleSuback(ev, clnode, msg);
			}else if(msg->getType() == MQTT_TYPE_UNSUBACK){
				handleUnsuback(ev, clnode, msg);
			}else if(msg->getType() == MQTT_TYPE_CONNACK){
				handleConnack(ev, clnode, msg);
			}else if(msg->getType() == MQTT_TYPE_PUBLISH){
				handlePublish(ev, clnode, msg);
			}else if(msg->getType() == MQTT_TYPE_DISCONNECT){
				handleDisconnect(ev, clnode, msg);
			}else if(msg->getType() == MQTT_TYPE_PUBREC){
				handlePubRec(ev, clnode, msg);
			}else if(msg->getType() == MQTT_TYPE_PUBREL){
				handlePubRel(ev, clnode, msg);
			}else if(msg->getType() == MQTT_TYPE_PUBCOMP){
				handlePubComp(ev, clnode, msg);
			}else{
				printf("%s   Irregular BrokerRecvMessage\n", currentDateTime());
			}
		}

		delete ev;
	}
}
Example #3
0
/*-------------------------------------------------------
                Upstream MQTTSnSubscribe
 -------------------------------------------------------*/
void GatewayControlTask::handleSnSubscribe(Event* ev, ClientNode* clnode, MQTTSnMessage* msg){
	printf(FORMAT2, currentDateTime(), "SUBSCRIBE", LEFTARROW, clnode->getNodeId()->c_str(), msgPrint(msg));

	MQTTSnSubscribe* sSubscribe = new MQTTSnSubscribe();
	MQTTSubscribe* subscribe = new MQTTSubscribe();
	sSubscribe->absorb(msg);

	uint8_t topicIdType = sSubscribe->getFlags() & 0x03;

	subscribe->setMessageId(sSubscribe->getMsgId());

	if(sSubscribe->getFlags() & MQTTSN_FLAG_DUP ){
		subscribe->setDup();
	}
	if(sSubscribe->getFlags() & MQTTSN_FLAG_RETAIN){
		subscribe->setRetain();
	}
	subscribe->setQos(sSubscribe->getQos());

	if(topicIdType != MQTTSN_FLAG_TOPICID_TYPE_RESV){
		if(topicIdType == MQTTSN_FLAG_TOPICID_TYPE_PREDEFINED){
			/*----- Predefined TopicId ------*/
			MQTTSnSubAck* sSuback = new MQTTSnSubAck();

			if(sSubscribe->getMsgId()){       // MessageID
				sSuback->setQos(sSubscribe->getQos());
				sSuback->setTopicId(sSubscribe->getTopicId());
				sSuback->setMsgId(sSubscribe->getMsgId());

				if(sSubscribe->getTopicId() == MQTTSN_TOPICID_PREDEFINED_TIME){
					sSuback->setReturnCode(MQTT_RC_ACCEPTED);
				}else{
					sSuback->setReturnCode(MQTT_RC_REFUSED_IDENTIFIER_REJECTED);
				}

				clnode->setClientSendMessage(sSuback);

				Event* evsuback = new Event();
				evsuback->setClientSendEvent(clnode);
				printf(FORMAT1, currentDateTime(), "SUBACK", RIGHTARROW, clnode->getNodeId()->c_str(), msgPrint(sSuback));

				_res->getClientSendQue()->post(evsuback);
			}

			if(sSubscribe->getTopicId() == MQTTSN_TOPICID_PREDEFINED_TIME){

				MQTTSnPublish* pub = new MQTTSnPublish();
				pub->setTopicIdType(1);  // pre-defined
				pub->setTopicId(MQTTSN_TOPICID_PREDEFINED_TIME);
				pub->setMsgId(clnode->getNextSnMsgId());

				uint8_t buf[4];
				uint32_t tm = time(0);
				setUint32(buf,tm);

				pub->setData(buf, 4);
				printf(GREEN_FORMAT1, currentDateTime(), "PUBLISH", RIGHTARROW, clnode->getNodeId()->c_str(), msgPrint(pub));

				clnode->setClientSendMessage(pub);

				Event *evpub = new Event();
				evpub->setClientSendEvent(clnode);
				_res->getClientSendQue()->post(evpub);
			}
			delete subscribe;
		}else{
			uint16_t tpId;

			Topic* tp = clnode->getTopics()->getTopic(sSubscribe->getTopicName());
			if (tp){
				tpId = tp->getTopicId();
			}else{
				tpId = clnode->getTopics()->createTopic(sSubscribe->getTopicName());
			}

			subscribe->setTopic(sSubscribe->getTopicName(), sSubscribe->getQos());
			if(sSubscribe->getMsgId()){
				MQTTSnSubAck* sSuback = new MQTTSnSubAck();
				sSuback->setMsgId(sSubscribe->getMsgId());
				sSuback->setTopicId(tpId);
				clnode->setWaitedSubAck(sSuback);
			}

			clnode->setBrokerSendMessage(subscribe);
			Event* ev1 = new Event();
			ev1->setBrokerSendEvent(clnode);
			_res->getBrokerSendQue()->post(ev1);
			delete sSubscribe;
			return;
		}

	}else{
		/*-- Irregular TopicIdType --*/
		if(sSubscribe->getMsgId()){
			MQTTSnSubAck* sSuback = new MQTTSnSubAck();
			sSuback->setMsgId(sSubscribe->getMsgId());
			sSuback->setTopicId(sSubscribe->getTopicId());
			sSuback->setReturnCode(MQTT_RC_REFUSED_IDENTIFIER_REJECTED);

			clnode->setClientSendMessage(sSuback);

			Event* evun = new Event();
			evun->setClientSendEvent(clnode);
			printf(FORMAT1, currentDateTime(), "SUBACK", RIGHTARROW, clnode->getNodeId()->c_str(), msgPrint(sSuback));

			_res->getClientSendQue()->post(evun);  // Send SUBACK to Client
		}
		delete subscribe;
	}
	delete sSubscribe;
}