Example #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;
}
Example #2
0
/**
 * Publish a message to the system log topic
 * @param topic topic to publish on
 * @param string the message to publish
 */
void Log_Publish(char* topic, char* string)
{
	Publish publish;
	publish.header.byte = 0; /* Qos 0, not retained */
	publish.payload = string;
	publish.payloadlen = strlen(string);
	publish.topic = topic;
	MQTTProtocol_handlePublishes(&publish, 0, NULL);
}
Example #3
0
MQTTPacket* MQTTClient_cycle(int* sock, unsigned long timeout, int* rc)
{
	struct timeval tp = {0L, 0L};
	static Ack ack;
	MQTTPacket* pack = NULL;

	FUNC_ENTRY;
	if (timeout > 0L)
	{
		tp.tv_sec = timeout / 1000;
		tp.tv_usec = (timeout % 1000) * 1000; /* this field is microseconds! */
	}

#if defined(OPENSSL)
	if ((*sock = SSLSocket_getPendingRead()) == -1)
	{
		/* 0 from getReadySocket indicates no work to do, -1 == error, but can happen normally */
#endif
		Thread_lock_mutex(socket_mutex);
		*sock = Socket_getReadySocket(0, &tp);
		Thread_unlock_mutex(socket_mutex);
#if defined(OPENSSL)
	}
#endif
	Thread_lock_mutex(mqttclient_mutex);
	if (*sock > 0)
	{
		MQTTClients* m = NULL;
		if (ListFindItem(handles, sock, clientSockCompare) != NULL)
			m = (MQTTClient)(handles->current->content);
		if (m != NULL)
		{
			if (m->c->connect_state == 1 || m->c->connect_state == 2)
				*rc = 0;  /* waiting for connect state to clear */
			else
			{
				pack = MQTTPacket_Factory(&m->c->net, rc);
				if (*rc == TCPSOCKET_INTERRUPTED)
					*rc = 0;
			}
		}
		if (pack)
		{
			int freed = 1;

			/* Note that these handle... functions free the packet structure that they are dealing with */
			if (pack->header.bits.type == PUBLISH)
				*rc = MQTTProtocol_handlePublishes(pack, *sock);
			else if (pack->header.bits.type == PUBACK || pack->header.bits.type == PUBCOMP)
			{
				int msgid;

				ack = (pack->header.bits.type == PUBCOMP) ? *(Pubcomp*)pack : *(Puback*)pack;
				msgid = ack.msgId;
				*rc = (pack->header.bits.type == PUBCOMP) ?
						MQTTProtocol_handlePubcomps(pack, *sock) : MQTTProtocol_handlePubacks(pack, *sock);
				if (m && m->dc)
				{
					Log(TRACE_MIN, -1, "Calling deliveryComplete for client %s, msgid %d", m->c->clientID, msgid);
					(*(m->dc))(m->context, msgid);
				}
			}
			else if (pack->header.bits.type == PUBREC)
				*rc = MQTTProtocol_handlePubrecs(pack, *sock);
			else if (pack->header.bits.type == PUBREL)
				*rc = MQTTProtocol_handlePubrels(pack, *sock);
			else if (pack->header.bits.type == PINGRESP)
				*rc = MQTTProtocol_handlePingresps(pack, *sock);
			else
				freed = 0;
			if (freed)
				pack = NULL;
		}
	}
	MQTTClient_retry();
	Thread_unlock_mutex(mqttclient_mutex);
	FUNC_EXIT_RC(*rc);
	return pack;
}