コード例 #1
0
ファイル: Protocol.c プロジェクト: TeamElevate/edison
int Protocol_handlePublishes(Publish* publish, int sock, Clients* client, char* clientid)
{
	int rc = TCPSOCKET_COMPLETE;
#if !defined(SINGLE_LISTENER)
	Listener* listener = NULL;
#endif

	FUNC_ENTRY;
	if (Protocol_isClientQuiescing(client))
		goto exit; /* don't accept new work */
#if !defined(SINGLE_LISTENER)
	listener = Socket_getParentListener(sock);
	if (listener && listener->mount_point)
	{
		char* temp = malloc(strlen(publish->topic) + strlen(listener->mount_point) + 1);
		strcpy(temp, listener->mount_point);
		strcat(temp, publish->topic);
		free(publish->topic);
		publish->topic = temp;
	}
#endif

#if !defined(NO_BRIDGE)
	if (client && client->outbound)
		Bridge_handleInbound(client, publish);
#endif

	if (publish->header.bits.qos == 0)
	{
		if (strlen(publish->topic) < 5 || strncmp(publish->topic, sysprefix, strlen(sysprefix)) != 0)
		{
			++(bstate->msgs_received);
			bstate->bytes_received += publish->payloadlen;
		}
		Protocol_processPublication(publish, clientid);
	}
	else if (publish->header.bits.qos == 1)
	{
		/* send puback before processing the publications because a lot of return publications could fill up the socket buffer */
#if defined(MQTTS)
		if (client->protocol == PROTOCOL_MQTTS)
			rc = MQTTSPacket_send_puback(client, publish->msgId, MQTTS_RC_ACCEPTED);
		else
#endif
			rc = MQTTPacket_send_puback(publish->msgId, sock, clientid);
		/* if we get a socket error from sending the puback, should we ignore the publication? */
		Protocol_processPublication(publish, clientid);
		++(bstate->msgs_received);
		bstate->bytes_received += publish->payloadlen;
	}
	else if (publish->header.bits.qos == 2 && client->inboundMsgs->count < bstate->max_inflight_messages)
	{
		/* store publication in inbound list - if list is full, ignore and rely on client retry */
		int len;
		ListElement* listElem = NULL;
		Messages* m = NULL;
		Publications* p = MQTTProtocol_storePublication(publish, &len);

		if ((listElem = ListFindItem(client->inboundMsgs, &publish->msgId, messageIDCompare)) != NULL)
		{
			m = (Messages*)(listElem->content);
			MQTTProtocol_removePublication(m->publish); /* remove old publication data - could be different */
		}
		else
			m = malloc(sizeof(Messages));

		m->publish = p;
		m->msgid = publish->msgId;
		m->qos = publish->header.bits.qos;
		m->retain = publish->header.bits.retain;
		m->nextMessageType = PUBREL;

		if (listElem == NULL)
			ListAppend(client->inboundMsgs, m, sizeof(Messages) + len);
#if defined(MQTTS)
		if (client->protocol == PROTOCOL_MQTTS)
			rc = MQTTSPacket_send_pubrec(client, publish->msgId);
		else
#endif
			rc = MQTTPacket_send_pubrec(publish->msgId, sock, clientid);
	}
	else if (publish->header.bits.qos == 3) /* only applies to MQTT-S */
	{
		publish->header.bits.qos = 0;
		Protocol_processPublication(publish, clientid);
	}
exit:
	if (sock > 0)
		MQTTPacket_freePublish(publish);
	FUNC_EXIT_RC(rc);
	return rc;
}
コード例 #2
0
ファイル: MQTTSProtocol.c プロジェクト: Frank-KunLi/rsmb
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;
}