Exemple #1
0
/**
 * Timeslice function to run protocol exchanges
 */
void Protocol_timeslice()
{
	int sock;
	int bridge_connection = 0;
	static int more_work = 0;

	FUNC_ENTRY;
	if ((sock = Socket_getReadySocket(more_work, NULL)) == SOCKET_ERROR)
	{
#if defined(WIN32)
		int errno;
		errno = WSAGetLastError();
#endif
		if (errno != EINTR && errno != EAGAIN && errno != EINPROGRESS && errno != EWOULDBLOCK)
		{
			Log(LOG_SEVERE, 0, "Restarting MQTT protocol to resolve socket problems");
			MQTTProtocol_shutdown(0);
			SubscriptionEngines_save(bstate->se);
			MQTTProtocol_reinitialize();
			goto exit;
		}
	}

	MQTTProtocol_checkPendingWrites();
	if (sock > 0)
	{
		Clients* client = NULL;
		Node* curnode = TreeFind(bstate->clients, &sock);

		if (curnode)
		{
			client = (Clients*)(curnode->content);
#if !defined(NO_BRIDGE)
			if (client->outbound && client->connect_state == 1)
			{
				Bridge_handleConnection(client);
				bridge_connection = 1;
			}
#endif
		}
		
		if (bridge_connection == 0)
#if defined(MQTTS)
		{
			int protocol = PROTOCOL_MQTT;
			if (client == NULL)
				protocol = Socket_getParentListener(sock)->protocol;
			else
				protocol = client->protocol;

			if (protocol == PROTOCOL_MQTT)
#endif
				MQTTProtocol_timeslice(sock, client);
#if defined(MQTTS)
			else if (protocol == PROTOCOL_MQTTS)
			    MQTTSProtocol_timeslice(sock);
		}
#endif
	}
	if (bstate->state != BROKER_STOPPING)
#if !defined(NO_ADMIN_COMMANDS)
		Persistence_read_command(bstate);
#else
		;
#endif
	else
Exemple #2
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;
}