Ejemplo n.º 1
0
int MQTTSProtocol_handleSubscribes(void* pack, int sock, char* clientAddr, Clients* client)
{
	int rc = 0;
	MQTTS_Subscribe* sub = (MQTTS_Subscribe*)pack;
	int isnew;
	int topicId = 0;
	char* topicName = NULL , *preDefinedTopicName = NULL;

	FUNC_ENTRY;
	Log(LOG_PROTOCOL, 67, NULL, sock, clientAddr, client ? client->clientID : "",
		sub->msgId,
		(sub->flags.QoS == 3) ? -1: sub->flags.QoS,
		sub->flags.topicIdType);

	// NORMAL (topic name is in subscribe packet) or SHORT topic name
	if (sub->flags.topicIdType == MQTTS_TOPIC_TYPE_NORMAL || sub->flags.topicIdType == MQTTS_TOPIC_TYPE_SHORT)
	{
		topicName = sub->topicName;
		sub->topicName = NULL;
	}
	// Pre-defined topic
	else if (sub->flags.topicIdType == MQTTS_TOPIC_TYPE_PREDEFINED && client != NULL && sub->topicId != 0)
	{
		char *name = MQTTSProtocol_getPreRegisteredTopicName(client, sub->topicId) ;
		if (name) {
			preDefinedTopicName = MQTTSProtocol_replaceTopicNamePlaceholders(client , name ) ;
		}
		topicName = preDefinedTopicName ;
		topicId = sub->topicId;
	}

	// If topic name not found send SubAck with Rejected - Invalid topic ID
	if (topicName == NULL)
		rc = MQTTSPacket_send_subAck(client, sub, 0, sub->flags.QoS, MQTTS_RC_REJECTED_INVALID_TOPIC_ID);
	else
	{
		if (sub->flags.topicIdType == MQTTS_TOPIC_TYPE_NORMAL && !Topics_hasWildcards(topicName))
		{
			char* regTopicName = malloc(strlen(topicName)+1);
			strcpy(regTopicName, topicName);
			topicId = (MQTTSProtocol_registerTopic(client, regTopicName))->id;
		}

		isnew = SubscriptionEngines_subscribe(bstate->se, client->clientID,
				topicName, sub->flags.QoS, client->noLocal, (client->cleansession == 0), PRIORITY_NORMAL);

		if ( (rc = MQTTSPacket_send_subAck(client, sub, topicId, sub->flags.QoS, MQTTS_RC_ACCEPTED)) == 0)
			if ((client->noLocal == 0) || isnew)
				MQTTProtocol_processRetaineds(client, topicName,sub->flags.QoS, PRIORITY_NORMAL);
	}
	time( &(client->lastContact) );
	MQTTSPacket_free_packet(pack);
	if (preDefinedTopicName)
		free (preDefinedTopicName);
	FUNC_EXIT_RC(rc);
	return rc;
}
Ejemplo n.º 2
0
int MQTTSProtocol_handlePublishes(void* pack, int sock, char* clientAddr, Clients* client)
{
	int rc = 0;
	char* topicName = NULL, *expandedPreDefinedTopicName = NULL;
	MQTTS_Publish* pub = NULL;

	FUNC_ENTRY;
	pub = (MQTTS_Publish*)pack;
	Log(LOG_PROTOCOL, 55, NULL, sock, clientAddr, client ? client->clientID : "",
			pub->msgId, pub->flags.QoS, pub->flags.retain);

	// Normal - registered topic
	if (pub->flags.topicIdType == MQTTS_TOPIC_TYPE_NORMAL && client != NULL && pub->topicId != 0)
	{
		/* copy the topic name as it will be freed later */
		char* name = MQTTSProtocol_getRegisteredTopicName(client, pub->topicId);
		if (name)
		{
			topicName = malloc(strlen(name) + 1);
			strcpy(topicName, name);
		}
	}
	// Pre-defined topics
	else if (pub->flags.topicIdType == MQTTS_TOPIC_TYPE_PREDEFINED && client != NULL && pub->topicId != 0)
	{
		/* copy the topic name as it will be freed later */
		char *origPreDefinedTopicName = MQTTSProtocol_getPreDefinedTopicName(client, pub->topicId) ;
		if (origPreDefinedTopicName)
		{
			expandedPreDefinedTopicName = MQTTSProtocol_replaceTopicNamePlaceholders(client, origPreDefinedTopicName) ;
		}

		// If original and expanded predef topic names are same, use expanded
		// while it is already a copy of orig name
		if (strcmp(origPreDefinedTopicName, expandedPreDefinedTopicName) == 0)
		{
			topicName = expandedPreDefinedTopicName ;
		} else {
			topicName = malloc(strlen(origPreDefinedTopicName)+1);
			strcpy(topicName, origPreDefinedTopicName);
		}
	}
	// Short topic names
	else if (pub->flags.topicIdType == MQTTS_TOPIC_TYPE_SHORT && pub->shortTopic != NULL)
	{
		topicName = pub->shortTopic;
		pub->shortTopic = NULL; /* will be freed in Protocol_handlePublishes */
	}

	// If topic name not found send PubAck with Rejected - Invalid topic ID
	if (topicName == NULL)
	{
		rc = MQTTSPacket_send_puback(client, pub->topicId , pub->msgId, MQTTS_RC_REJECTED_INVALID_TOPIC_ID);
	}
	else
	{
		Publish* publish = malloc(sizeof(Publish));
		publish->header.bits.type = PUBLISH;
		publish->header.bits.qos = pub->flags.QoS;
		publish->header.bits.retain = pub->flags.retain;
		publish->header.bits.dup = pub->flags.dup;
		publish->msgId = pub->msgId;
		publish->payload = pub->data;
		publish->payloadlen = pub->dataLen;
		publish->topic = topicName;
		rc = Protocol_handlePublishes(publish, sock, client, client ? client->clientID : clientAddr, pub->topicId);

		// If predefined topic Id and predefined topic name contains [ClientId]
		// publish message to expanded topic name too.
		if ( pub->flags.topicIdType == MQTTS_TOPIC_TYPE_PREDEFINED && topicName != expandedPreDefinedTopicName)
		{
			publish = malloc(sizeof(Publish));
			publish->header.bits.type = PUBLISH;
			publish->header.bits.qos = pub->flags.QoS;
			publish->header.bits.retain = pub->flags.retain;
			publish->header.bits.dup = pub->flags.dup;
			publish->msgId = pub->msgId;
			publish->payload = pub->data;
			publish->payloadlen = pub->dataLen;
			publish->topic = expandedPreDefinedTopicName;
			rc = Protocol_handlePublishes(publish, sock, client, client ? client->clientID : clientAddr, pub->topicId);
		}
	}

	if (client != NULL)
		time( &(client->lastContact) );

	MQTTSPacket_free_packet(pack);

	FUNC_EXIT_RC(rc);
	return rc;
}