示例#1
0
/**
 * Internal publication to a system topic.
 * @param topic the topic to publish on
 * @param string the data to publish
 */
void MQTTProtocol_sys_publish(char* topic, char* string)
{
	List* rpl = NULL;
	int doPublish = 1;

	FUNC_ENTRY;
	rpl = SubscriptionEngines_getRetained(bstate->se, topic);
	if (rpl->count > 0)  /* this should be at most 1, as we must use a non-wildcard topic (for publishing) */
	{
		RetainedPublications* rp = (RetainedPublications*)(rpl->first->content);
		if (strlen(string) == rp->payloadlen && memcmp(rp->payload, string, rp->payloadlen) == 0)
			doPublish = 0;
	}
	ListFreeNoContent(rpl);
	if (doPublish)
	{
		Publish publish;
		publish.header.byte = 0;
		publish.header.bits.retain = 1;
		publish.payload = string;
		publish.payloadlen = strlen(string);
		publish.topic = topic;
		MQTTProtocol_handlePublishes(&publish, 0, NULL);
	}
	FUNC_EXIT;
}
示例#2
0
/**
 * Process retained messages (when a client subscribes)
 * @param client the client to send the messages to
 * @param topic the topic to match
 * @param qos the QoS of the subscription
 */
void MQTTProtocol_processRetaineds(Clients* client, char* topic, int qos, int priority)
{
	List* rpl = NULL;
	ListElement* currp = NULL;
#if defined(QOS0_SEND_LIMIT)
	int qos0count = 0;
#endif

	FUNC_ENTRY;
	rpl = SubscriptionEngines_getRetained(bstate->se, topic);
	while (ListNextElement(rpl, &currp))
	{
		int curqos;
		Publish publish;
		Messages* p = NULL;
		RetainedPublications* rp = (RetainedPublications*)(currp->content);

		publish.payload = rp->payload;
		publish.payloadlen = rp->payloadlen;
		publish.topic = rp->topicName;
		curqos = (rp->qos < qos) ? rp->qos : qos;
#if defined(QOS0_SEND_LIMIT)
		if (curqos == 0)
			++qos0count;
		if (qos0count > bstate->max_inflight_messages) /* a somewhat arbitrary criterion */
		{
			if (MQTTProtocol_queuePublish(client, &publish, curqos, 1, priority, &p) == SOCKET_ERROR)
				break;
		}
		else
		{
#endif
			if (Protocol_startOrQueuePublish(client, &publish, curqos, 1, priority, &p) == SOCKET_ERROR)
				break;
#if defined(QOS0_SEND_LIMIT)
		}
#endif
	}
	ListFreeNoContent(rpl);
	FUNC_EXIT;
}
示例#3
0
int MQTTClient_unsubscribeMany(MQTTClient handle, int count, char* const* topic)
{
	MQTTClients* m = handle;
	List* topics = ListInitialize();
	int i = 0;
	int rc = SOCKET_ERROR;
	int msgid = 0;

	FUNC_ENTRY;
	Thread_lock_mutex(mqttclient_mutex);

	if (m == NULL || m->c == NULL)
	{
		rc = MQTTCLIENT_FAILURE;
		goto exit;
	}
	if (m->c->connected == 0)
	{
		rc = MQTTCLIENT_DISCONNECTED;
		goto exit;
	}
	for (i = 0; i < count; i++)
	{
		if (!UTF8_validateString(topic[i]))
		{
			rc = MQTTCLIENT_BAD_UTF8_STRING;
			goto exit;
		}
	}
	if ((msgid = MQTTProtocol_assignMsgId(m->c)) == 0)
	{
		rc = MQTTCLIENT_MAX_MESSAGES_INFLIGHT;
		goto exit;
	}

	for (i = 0; i < count; i++)
		ListAppend(topics, topic[i], strlen(topic[i]));
	rc = MQTTProtocol_unsubscribe(m->c, topics, msgid);
	ListFreeNoContent(topics);

	if (rc == TCPSOCKET_COMPLETE)
	{
		MQTTPacket* pack = NULL;

		Thread_unlock_mutex(mqttclient_mutex);
		pack = MQTTClient_waitfor(handle, UNSUBACK, &rc, 10000L);
		Thread_lock_mutex(mqttclient_mutex);
		if (pack != NULL)
		{
			rc = MQTTProtocol_handleUnsubacks(pack, m->c->net.socket);
			m->pack = NULL;
		}
		else
			rc = SOCKET_ERROR;
	}

	if (rc == SOCKET_ERROR)
	{
		Thread_unlock_mutex(mqttclient_mutex);
		MQTTClient_disconnect_internal(handle, 0);
		Thread_lock_mutex(mqttclient_mutex);
	}

exit:
	Thread_unlock_mutex(mqttclient_mutex);
	FUNC_EXIT_RC(rc);
	return rc;
}
示例#4
0
int MQTTClient_subscribeMany(MQTTClient handle, int count, char* const* topic, int* qos)
{
	MQTTClients* m = handle;
	List* topics = ListInitialize();
	List* qoss = ListInitialize();
	int i = 0;
	int rc = MQTTCLIENT_FAILURE;
	int msgid = 0;

	FUNC_ENTRY;
	Thread_lock_mutex(mqttclient_mutex);

	if (m == NULL || m->c == NULL)
	{
		rc = MQTTCLIENT_FAILURE;
		goto exit;
	}
	if (m->c->connected == 0)
	{
		rc = MQTTCLIENT_DISCONNECTED;
		goto exit;
	}
	for (i = 0; i < count; i++)
	{
		if (!UTF8_validateString(topic[i]))
		{
			rc = MQTTCLIENT_BAD_UTF8_STRING;
			goto exit;
		}
		
		if(qos[i] < 0 || qos[i] > 2)
		{
			rc = MQTTCLIENT_BAD_QOS;
			goto exit;
		}
	}
	if ((msgid = MQTTProtocol_assignMsgId(m->c)) == 0)
	{
		rc = MQTTCLIENT_MAX_MESSAGES_INFLIGHT;
		goto exit;
	}

	for (i = 0; i < count; i++)
	{
		ListAppend(topics, topic[i], strlen(topic[i]));
		ListAppend(qoss, &qos[i], sizeof(int));
	}

	rc = MQTTProtocol_subscribe(m->c, topics, qoss, msgid);
	ListFreeNoContent(topics);
	ListFreeNoContent(qoss);

	if (rc == TCPSOCKET_COMPLETE)
	{
		MQTTPacket* pack = NULL;

		Thread_unlock_mutex(mqttclient_mutex);
		pack = MQTTClient_waitfor(handle, SUBACK, &rc, 10000L);
		Thread_lock_mutex(mqttclient_mutex);
		if (pack != NULL)
		{
			Suback* sub = (Suback*)pack;	
			ListElement* current = NULL;
			i = 0;
			while (ListNextElement(sub->qoss, &current))
			{
				int* reqqos = (int*)(current->content);
				qos[i++] = *reqqos;
			}	
			rc = MQTTProtocol_handleSubacks(pack, m->c->net.socket);
			m->pack = NULL;
		}
		else
			rc = SOCKET_ERROR;
	}

	if (rc == SOCKET_ERROR)
	{
		Thread_unlock_mutex(mqttclient_mutex);
		MQTTClient_disconnect_internal(handle, 0);
		Thread_lock_mutex(mqttclient_mutex);
	}
	else if (rc == TCPSOCKET_COMPLETE)
		rc = MQTTCLIENT_SUCCESS;

exit:
	Thread_unlock_mutex(mqttclient_mutex);
	FUNC_EXIT_RC(rc);
	return rc;
}
示例#5
0
int MQTTClient_subscribeMany(MQTTClient handle, int count, char** topic, int* qos)
{
	MQTTClients* m = handle;
	List* topics = ListInitialize();
	List* qoss = ListInitialize();
	int i = 0;
	int rc = MQTTCLIENT_FAILURE;

	FUNC_ENTRY;
	Thread_lock_mutex(mqttclient_mutex);

	if (m == NULL || m->c == NULL)
	{
		rc = MQTTCLIENT_FAILURE;
		goto exit;
	}
	if (m->c->connected == 0)
	{
		rc = MQTTCLIENT_DISCONNECTED;
		goto exit;
	}
	for (i = 0; i < count; i++)
	{
		if (!UTF8_validateString(topic[i]))
		{
			rc = MQTTCLIENT_BAD_UTF8_STRING;
			goto exit;
		}
	}

	for (i = 0; i < count; i++)
	{
		ListAppend(topics, topic[i], strlen(topic[i]));
		ListAppend(qoss, &qos[i], sizeof(int));
	}
	rc = MQTTProtocol_subscribe(m->c, topics, qoss);
	ListFreeNoContent(topics);
	ListFreeNoContent(qoss);

	if (rc == TCPSOCKET_COMPLETE)
	{
		MQTTPacket* pack = NULL;

		Thread_unlock_mutex(mqttclient_mutex);
		pack = MQTTClient_waitfor(handle, SUBACK, &rc, 10000L);
		Thread_lock_mutex(mqttclient_mutex);
		if (pack != NULL)
		{
			rc = MQTTProtocol_handleSubacks(pack, m->c->socket);
			m->pack = NULL;
		}
		else
			rc = SOCKET_ERROR;
	}

	if (rc == SOCKET_ERROR)
	{
		Thread_unlock_mutex(mqttclient_mutex);
		MQTTClient_disconnect_internal(handle, 0);
		Thread_lock_mutex(mqttclient_mutex);
	}
	else if (rc == TCPSOCKET_COMPLETE)
		rc = MQTTCLIENT_SUCCESS;

exit:
	Thread_unlock_mutex(mqttclient_mutex);
	FUNC_EXIT_RC(rc);
	return rc;
}