/** * 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
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; }