/** * Process an incoming puback packet for a socket * @param pack pointer to the publish packet * @param sock the socket on which the packet was received * @return completion code */ int MQTTProtocol_handlePubacks(void* pack, int sock) { Puback* puback = (Puback*)pack; Clients* client = (Clients*)(ListFindItem(bstate->clients, &sock, clientSocketCompare)->content); int rc = TCPSOCKET_COMPLETE; FUNC_ENTRY; Log(LOG_PROTOCOL, 14, NULL, sock, client->clientID, puback->msgId); /* look for the message by message id in the records of outbound messages for this client */ if (ListFindItem(client->outboundMsgs, &(puback->msgId), messageIDCompare) == NULL) Log(LOG_WARNING, 50, NULL, "PUBACK", client->clientID, puback->msgId); else { Messages* m = (Messages*)(client->outboundMsgs->current->content); if (m->qos != 1) Log(LOG_WARNING, 51, NULL, "PUBACK", client->clientID, puback->msgId, m->qos); else { Log(TRACE_MIN, 4, NULL, client->clientID, puback->msgId); ++(bstate->msgs_sent); bstate->bytes_sent += m->publish->payloadlen; MQTTProtocol_removePublication(m->publish); ListRemove(client->outboundMsgs, m); } } free(pack); FUNC_EXIT_RC(rc); return rc; }
/** * Process an incoming puback packet for a socket * @param pack pointer to the publish packet * @param sock the socket on which the packet was received * @return completion code */ int MQTTProtocol_handlePubacks(void* pack, int sock) { Puback* puback = (Puback*)pack; Clients* client = NULL; int rc = TCPSOCKET_COMPLETE; FUNC_ENTRY; client = (Clients*)(ListFindItem(bstate->clients, &sock, clientSocketCompare)->content); Log(LOG_PROTOCOL, 14, NULL, sock, client->clientID, puback->msgId); /* look for the message by message id in the records of outbound messages for this client */ if (ListFindItem(client->outboundMsgs, &(puback->msgId), messageIDCompare) == NULL) Log(TRACE_MIN, 3, NULL, "PUBACK", client->clientID, puback->msgId); else { Messages* m = (Messages*)(client->outboundMsgs->current->content); if (m->qos != 1) Log(TRACE_MIN, 4, NULL, "PUBACK", client->clientID, puback->msgId, m->qos); else { Log(TRACE_MIN, 6, NULL, "PUBACK", client->clientID, puback->msgId); #if !defined(NO_PERSISTENCE) rc = MQTTPersistence_remove(client, PERSISTENCE_PUBLISH_SENT, m->qos, puback->msgId); #endif MQTTProtocol_removePublication(m->publish); ListRemove(client->outboundMsgs, m); } } free(pack); FUNC_EXIT_RC(rc); return rc; }
/** * Process an incoming pubrel packet for a socket * @param pack pointer to the publish packet * @param sock the socket on which the packet was received * @return completion code */ int MQTTProtocol_handlePubrels(void* pack, int sock) { Pubrel* pubrel = (Pubrel*)pack; Clients* client = (Clients*)(ListFindItem(bstate->clients, &sock, clientSocketCompare)->content); int rc = TCPSOCKET_COMPLETE; FUNC_ENTRY; Log(LOG_PROTOCOL, 17, NULL, sock, client->clientID, pubrel->msgId); /* look for the message by message id in the records of inbound messages for this client */ if (ListFindItem(client->inboundMsgs, &(pubrel->msgId), messageIDCompare) == NULL) { if (pubrel->header.bits.dup == 0) Log(LOG_WARNING, 50, NULL, "PUBREL", client->clientID, pubrel->msgId); /* Apparently this is "normal" behaviour, so we don't need to issue a warning */ rc = MQTTPacket_send_pubcomp(pubrel->msgId, sock, client->clientID); } else { Messages* m = (Messages*)(client->inboundMsgs->current->content); if (m->qos != 2) Log(LOG_WARNING, 51, NULL, "PUBREL", client->clientID, pubrel->msgId, m->qos); else if (m->nextMessageType != PUBREL) Log(LOG_WARNING, 52, NULL, "PUBREL", client->clientID, pubrel->msgId); else { Publish publish; char saved_clientid[MAX_CLIENTID_LEN + 1]; strcpy(saved_clientid, client->clientID); /* send pubcomp before processing the publications because a lot of return publications could fill up the socket buffer */ rc = MQTTPacket_send_pubcomp(pubrel->msgId, sock, client->clientID); publish.header.bits.qos = m->qos; publish.header.bits.retain = m->retain; publish.msgId = m->msgid; publish.topic = m->publish->topic; publish.payload = m->publish->payload; publish.payloadlen = m->publish->payloadlen; publish.priority = m->priority; ++(bstate->msgs_received); bstate->bytes_received += m->publish->payloadlen; Protocol_processPublication(&publish, client->clientID); /* The client structure might have been removed in processPublication, on error */ if (ListFindItem(bstate->clients, saved_clientid, clientIDCompare)) { ListRemove(client->inboundMsgs, m); MQTTProtocol_removePublication(m->publish); } } } free(pack); FUNC_EXIT_RC(rc); return rc; }
int MQTTProtocol_handleGets(void* pack, int sock) { Getack* getack = (Getack*)pack; Clients* client = NULL; char* clientid = NULL; int rc = TCPSOCKET_COMPLETE; FUNC_ENTRY; // printf("------>%s, %s, %d\n", __func__, getack->ack_payload.ret_string, getack->ack_payload.ext_cmd); client = (Clients*)(ListFindItem(bstate->clients, &sock, clientSocketCompare)->content); clientid = client->clientID; // Log(LOG_PROTOCOL, 11, NULL, sock, clientid, getack->msgId, get->header.bits.qos, // getack->header.bits.retain, min(20, getack->ext_payloadlen), get->ext_payload); /* here we needn't process some just like publish. only to parse ext ack, get one callback. */ #if 0 if (get->header.bits.qos == 0) Protocol_processPublication(get, client); else if (get->header.bits.qos == 1) { /* send puback before processing the publications because a lot of return publications could fill up the socket buffer */ rc = MQTTPacket_send_puback(publish->msgId, &client->net, client->clientID); /* if we get a socket error from sending the puback, should we ignore the publication? */ Protocol_processPublication(publish, client); } else if (publish->header.bits.qos == 2) { /* store publication in inbound list */ int len; ListElement* listElem = NULL; Messages* m = malloc(sizeof(Messages)); Publications* p = MQTTProtocol_storePublication(publish, &len); m->publish = p; m->msgid = publish->msgId; m->qos = publish->header.bits.qos; m->retain = publish->header.bits.retain; m->nextMessageType = PUBREL; if ( ( listElem = ListFindItem(client->inboundMsgs, &(m->msgid), messageIDCompare) ) != NULL ) { /* discard queued publication with same msgID that the current incoming message */ Messages* msg = (Messages*)(listElem->content); MQTTProtocol_removePublication(msg->publish); ListInsert(client->inboundMsgs, m, sizeof(Messages) + len, listElem); ListRemove(client->inboundMsgs, msg); } else ListAppend(client->inboundMsgs, m, sizeof(Messages) + len); rc = MQTTPacket_send_pubrec(publish->msgId, &client->net, client->clientID); publish->topic = NULL; } MQTTPacket_freePublish(publish); #endif MQTTPacket_freeGet(getack); FUNC_EXIT_RC(rc); return rc; }
/** * Process an incoming pubrel packet for a socket * @param pack pointer to the publish packet * @param sock the socket on which the packet was received * @return completion code */ int MQTTProtocol_handlePubrels(void* pack, int sock) { Pubrel* pubrel = (Pubrel*)pack; Clients* client = NULL; int rc = TCPSOCKET_COMPLETE; FUNC_ENTRY; client = (Clients*)(ListFindItem(bstate->clients, &sock, clientSocketCompare)->content); Log(LOG_PROTOCOL, 17, NULL, sock, client->clientID, pubrel->msgId); /* look for the message by message id in the records of inbound messages for this client */ if (ListFindItem(client->inboundMsgs, &(pubrel->msgId), messageIDCompare) == NULL) { if (pubrel->header.bits.dup == 0) Log(TRACE_MIN, 3, NULL, "PUBREL", client->clientID, pubrel->msgId); else /* Apparently this is "normal" behaviour, so we don't need to issue a warning */ rc = MQTTPacket_send_pubcomp(pubrel->msgId, &client->net, client->clientID); } else { Messages* m = (Messages*)(client->inboundMsgs->current->content); if (m->qos != 2) Log(TRACE_MIN, 4, NULL, "PUBREL", client->clientID, pubrel->msgId, m->qos); else if (m->nextMessageType != PUBREL) Log(TRACE_MIN, 5, NULL, "PUBREL", client->clientID, pubrel->msgId); else { Publish publish; /* send pubcomp before processing the publications because a lot of return publications could fill up the socket buffer */ rc = MQTTPacket_send_pubcomp(pubrel->msgId, &client->net, client->clientID); publish.header.bits.qos = m->qos; publish.header.bits.retain = m->retain; publish.msgId = m->msgid; publish.topic = m->publish->topic; publish.topiclen = m->publish->topiclen; publish.payload = m->publish->payload; publish.payloadlen = m->publish->payloadlen; Protocol_processPublication(&publish, client); #if !defined(NO_PERSISTENCE) rc += MQTTPersistence_remove(client, PERSISTENCE_PUBLISH_RECEIVED, m->qos, pubrel->msgId); #endif ListRemove(&(state.publications), m->publish); ListRemove(client->inboundMsgs, m); ++(state.msgs_received); } } free(pack); FUNC_EXIT_RC(rc); return rc; }
int MQTTSProtocol_handlePubacks(void* pack, int sock, char* clientAddr, Clients* client) { int rc = 0; MQTTS_PubAck* puback = (MQTTS_PubAck*)pack; FUNC_ENTRY; Log(LOG_PROTOCOL, 57, NULL, sock, clientAddr, client ? client->clientID : "", puback->msgId); /* look for the message by message id in the records of outbound messages for this client */ if (ListFindItem(client->outboundMsgs, &(puback->msgId), messageIDCompare) == NULL) Log(LOG_WARNING, 50, NULL, "PUBACK", client->clientID, puback->msgId); else { Messages* m = (Messages*)(client->outboundMsgs->current->content); if (m->qos != 1) Log(LOG_WARNING, 51, NULL, "PUBACK", client->clientID, puback->msgId, m->qos); else { Log(TRACE_MAX, 4, NULL, client->clientID, puback->msgId); MQTTProtocol_removePublication(m->publish); ListRemove(client->outboundMsgs, m); /* TODO: msgs counts */ /* (++state.msgs_sent);*/ } } MQTTSPacket_free_packet(pack); FUNC_EXIT_RC(rc); return rc; }
/** * Reallocates a block of memory. A direct replacement for realloc, but keeps track of items * allocated in a list, so that free can check that a item is being freed correctly and that * we can check that all memory is freed at shutdown. * @param file use the __FILE__ macro to indicate which file this item was reallocated in * @param line use the __LINE__ macro to indicate which line this item was reallocated at * @param p pointer to the item to be reallocated * @param size the new size of the item * @return pointer to the allocated item, or NULL if there was an error */ void *myrealloc(char* file, int line, void* p, size_t size) { void* rc = NULL; ListElement* e = ListFindItem(&heap, p, ptrCompare); if (e == NULL) Log(LOG_ERROR, -1, "Failed to reallocate heap item at file %s line %d", file, line); else { storageElement* s = (storageElement*)(heap.current->content); state.current_size += size - s->size; if (state.current_size > state.max_size) state.max_size = state.current_size; rc = s->ptr = realloc(s->ptr, size); s->size = size; s->file = realloc(s->file, strlen(file)+1); strcpy(s->file, file); s->line = line; if (s->stack) { free(s->stack); s->stack = StackTrace_get(Thread_getid()); } } return rc; }
/** * Removes and optionally frees an element in a list by comparing the content. * A callback function is used to define the method of comparison for each element. * @param aList the list in which the search is to be conducted * @param content pointer to the content to look for * @param callback pointer to a function which compares each element * @param freeContent boolean value to indicate whether the item found is to be freed * @return 1=item removed, 0=item not removed */ int ListUnlink(List* aList, void* content, int(*callback)(void*, void*), int freeContent) { ListElement* next = NULL; ListElement* saved = aList->current; int saveddeleted = 0; if (!ListFindItem(aList, content, callback)) return 0; /* false, did not remove item */ if (aList->current->prev == NULL) /* so this is the first element, and we have to update the "first" pointer */ aList->first = aList->current->next; else aList->current->prev->next = aList->current->next; if (aList->current->next == NULL) aList->last = aList->current->prev; else aList->current->next->prev = aList->current->prev; next = aList->current->next; if (freeContent) free(aList->current->content); if (saved == aList->current) saveddeleted = 1; free(aList->current); if (saveddeleted) aList->current = next; else aList->current = saved; --(aList->count); return 1; /* successfully removed item */ }
/** * Assign a new message id for a client. Make sure it isn't already being used and does * not exceed the maximum. * @param client a client structure * @return the next message id to use, or 0 if none available */ uint64_t MQTTProtocol_assignMsgId(Clients* client) { uint64_t msgid; FUNC_ENTRY; msgid = generate_uuid(); client->msgID = msgid; FUNC_EXIT_RC(msgid); return msgid; #if 0 int start_msgid = client->msgID; uint64_t msgid = start_msgid; FUNC_ENTRY; msgid = (msgid == MAX_MSG_ID) ? 1 : msgid + 1; while (ListFindItem(client->outboundMsgs, &msgid, messageIDCompare) != NULL) { msgid = (msgid == MAX_MSG_ID) ? 1 : msgid + 1; if (msgid == start_msgid) { /* we've tried them all - none free */ msgid = 0; break; } } if (msgid != 0) client->msgID = msgid; FUNC_EXIT_RC(msgid); return msgid; #endif }
void *ListDeleteItem(ListNode *Head, void *Item) { ListNode *Node; Node=ListFindItem(Head, Item); if (Node) ListDeleteNode(Node); }
void MQTTClient_yield(void) { START_TIME_TYPE start = MQTTClient_start_clock(); unsigned long elapsed = 0L; unsigned long timeout = 100L; int rc = 0; FUNC_ENTRY; if (running) { MQTTClient_sleep(timeout); goto exit; } elapsed = MQTTClient_elapsed(start); do { int sock = -1; MQTTClient_cycle(&sock, (timeout > elapsed) ? timeout - elapsed : 0L, &rc); if (rc == SOCKET_ERROR && ListFindItem(handles, &sock, clientSockCompare)) { MQTTClients* m = (MQTTClient)(handles->current->content); if (m->c->connect_state != -2) MQTTClient_disconnect_internal(m, 0); } elapsed = MQTTClient_elapsed(start); } while (elapsed < timeout); exit: FUNC_EXIT; }
/** * Get any queued data for a specific socket * @param socket the socket to get queued data for * @param bytes the number of bytes of data to retrieve * @param actual_len the actual length returned * @return the actual data */ char* SocketBuffer_getQueuedData(int socket, size_t bytes, size_t* actual_len) { socket_queue* queue = NULL; FUNC_ENTRY; if (ListFindItem(queues, &socket, socketcompare)) { /* if there is queued data for this socket, add any data read to it */ queue = (socket_queue*)(queues->current->content); *actual_len = queue->datalen; } else { *actual_len = 0; queue = def_queue; } if (bytes > queue->buflen) { if (queue->datalen > 0) { void* newmem = malloc(bytes); memcpy(newmem, queue->buf, queue->datalen); free(queue->buf); queue->buf = newmem; } else queue->buf = realloc(queue->buf, bytes); queue->buflen = bytes; } FUNC_EXIT; return queue->buf; }
/** * Get any queued character for a specific socket * @param socket the socket to get queued data for * @param c the character returned if any * @return completion code */ int SocketBuffer_getQueuedChar(int socket, char* c) { int rc = SOCKETBUFFER_INTERRUPTED; FUNC_ENTRY; if (ListFindItem(queues, &socket, socketcompare)) { /* if there is queued data for this socket, read that first */ socket_queue* queue = (socket_queue*)(queues->current->content); if (queue->index < queue->headerlen) { *c = queue->fixed_header[(queue->index)++]; Log(TRACE_MAX, -1, "index is now %d, headerlen %d", queue->index, queue->headerlen); rc = SOCKETBUFFER_COMPLETE; goto exit; } else if (queue->index > 4) { Log(LOG_FATAL, -1, "header is already at full length"); rc = SOCKET_ERROR; goto exit; } } exit: FUNC_EXIT_RC(rc); return rc; /* there was no queued char if rc is SOCKETBUFFER_INTERRUPTED*/ }
/** * A socket operation had now completed so we can get rid of the queue * @param socket the socket for which the operation is now complete * @param c the character to queue */ void SocketBuffer_queueChar(int socket, char c) { int error = 0; socket_queue* curq = def_queue; FUNC_ENTRY; if (ListFindItem(queues, &socket, socketcompare)) curq = (socket_queue*)(queues->current->content); else if (def_queue->socket == 0) { def_queue->socket = socket; def_queue->index = 0; def_queue->datalen = 0; } else if (def_queue->socket != socket) { Log(LOG_FATAL, -1, "attempt to reuse socket queue"); error = 1; } if (curq->index > 4) { Log(LOG_FATAL, -1, "socket queue fixed_header field full"); error = 1; } if (!error) { curq->fixed_header[(curq->index)++] = c; curq->headerlen = curq->index; } Log(TRACE_MAX, -1, "queueChar: index is now %d, headerlen %d", curq->index, curq->headerlen); FUNC_EXIT; }
int MQTTClient_waitForCompletion(MQTTClient handle, MQTTClient_deliveryToken mdt, unsigned long timeout) { int rc = MQTTCLIENT_FAILURE; START_TIME_TYPE start = MQTTClient_start_clock(); unsigned long elapsed = 0L; MQTTClients* m = handle; 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; } if (ListFindItem(m->c->outboundMsgs, &mdt, messageIDCompare) == NULL) { rc = MQTTCLIENT_SUCCESS; /* well we couldn't find it */ goto exit; } elapsed = MQTTClient_elapsed(start); while (elapsed < timeout) { Thread_unlock_mutex(mqttclient_mutex); MQTTClient_yield(); Thread_lock_mutex(mqttclient_mutex); if (ListFindItem(m->c->outboundMsgs, &mdt, messageIDCompare) == NULL) { rc = MQTTCLIENT_SUCCESS; /* well we couldn't find it */ goto exit; } elapsed = MQTTClient_elapsed(start); } exit: Thread_unlock_mutex(mqttclient_mutex); FUNC_EXIT_RC(rc); return rc; }
int MQTTClient_receive(MQTTClient handle, char** topicName, int* topicLen, MQTTClient_message** message, unsigned long timeout) { int rc = TCPSOCKET_COMPLETE; START_TIME_TYPE start = MQTTClient_start_clock(); unsigned long elapsed = 0L; MQTTClients* m = handle; FUNC_ENTRY; if (m == NULL || m->c == NULL) { rc = MQTTCLIENT_FAILURE; goto exit; } if (m->c->connected == 0) { rc = MQTTCLIENT_DISCONNECTED; goto exit; } *topicName = NULL; *message = NULL; /* if there is already a message waiting, don't hang around but still do some packet handling */ if (m->c->messageQueue->count > 0) timeout = 0L; elapsed = MQTTClient_elapsed(start); do { int sock = 0; MQTTClient_cycle(&sock, (timeout > elapsed) ? timeout - elapsed : 0L, &rc); if (rc == SOCKET_ERROR) { if (ListFindItem(handles, &sock, clientSockCompare) && /* find client corresponding to socket */ (MQTTClient)(handles->current->content) == handle) break; /* there was an error on the socket we are interested in */ } elapsed = MQTTClient_elapsed(start); } while (elapsed < timeout && m->c->messageQueue->count == 0); if (m->c->messageQueue->count > 0) rc = MQTTClient_deliverMessage(rc, m, topicName, topicLen, message); if (rc == SOCKET_ERROR) MQTTClient_disconnect_internal(handle, 0); exit: FUNC_EXIT_RC(rc); return rc; }
/** * Process an incoming pubrec packet for a socket * @param pack pointer to the publish packet * @param sock the socket on which the packet was received * @return completion code */ int MQTTProtocol_handlePubrecs(void* pack, int sock) { Pubrec* pubrec = (Pubrec*)pack; Clients* client = (Clients*)(ListFindItem(bstate->clients, &sock, clientSocketCompare)->content); int rc = TCPSOCKET_COMPLETE; FUNC_ENTRY; Log(LOG_PROTOCOL, 15, NULL, sock, client->clientID, pubrec->msgId); /* look for the message by message id in the records of outbound messages for this client */ client->outboundMsgs->current = NULL; if (ListFindItem(client->outboundMsgs, &(pubrec->msgId), messageIDCompare) == NULL) { if (pubrec->header.bits.dup == 0) Log(LOG_WARNING, 50, NULL, "PUBREC", client->clientID, pubrec->msgId); } else { Messages* m = (Messages*)(client->outboundMsgs->current->content); if (m->qos != 2) { if (pubrec->header.bits.dup == 0) Log(LOG_WARNING, 51, NULL, "PUBREC", client->clientID, pubrec->msgId, m->qos); } else if (m->nextMessageType != PUBREC) { if (pubrec->header.bits.dup == 0) Log(LOG_WARNING, 52, NULL, "PUBREC", client->clientID, pubrec->msgId); } else { rc = MQTTPacket_send_pubrel(pubrec->msgId, 0, sock, client->clientID); m->nextMessageType = PUBCOMP; time(&(m->lastTouch)); if (rc == TCPSOCKET_COMPLETE && client->outbound) client->lastContact = m->lastTouch; } } free(pack); FUNC_EXIT_RC(rc); return rc; }
/** * Assign a new message id for a client. Make sure it isn't already being used and does * not exceed the maximum. * @param client a client structure * @return the next message id to use */ int MQTTProtocol_assignMsgId(Clients* client) { FUNC_ENTRY; ++(client->msgID); while (ListFindItem(client->outboundMsgs, &(client->msgID), messageIDCompare) != NULL) ++(client->msgID); if (client->msgID == MAX_MSG_ID) client->msgID = 1; FUNC_EXIT_RC(client->msgID); return client->msgID; }
void SocketBuffer_cleanup(int socket) { FUNC_ENTRY; if (ListFindItem(queues, &socket, socketcompare)) { free(((socket_queue*)(queues->current->content))->buf); ListRemove(queues, queues->current->content); } if (def_queue->socket == socket) def_queue->socket = def_queue->index = def_queue->headerlen = def_queue->datalen = 0; FUNC_EXIT; }
/** * Don't accept work from a client unless it is accepting work back, i.e. its socket is writeable * this seems like a reasonable form of flow control, and practically, seems to work. * @param socket the socket to check * @param read_set the socket read set (see select doc) * @param write_set the socket write set (see select doc) * @return boolean - is the socket ready to go? */ int isReady(int socket, fd_set* read_set, fd_set* write_set) { int rc = 1; FUNC_ENTRY; if (ListFindItem(s.connect_pending, &socket, intcompare) && FD_ISSET(socket, write_set)) ListRemoveItem(s.connect_pending, &socket, intcompare); else rc = FD_ISSET(socket, read_set) && FD_ISSET(socket, write_set) && Socket_noPendingWrites(socket); FUNC_EXIT_RC(rc); return rc; }
/** * Process an incoming pingresp packet for a socket * @param pack pointer to the publish packet * @param sock the socket on which the packet was received * @return completion code */ int MQTTProtocol_handlePingresps(void* pack, int sock) { Clients* client = NULL; int rc = TCPSOCKET_COMPLETE; FUNC_ENTRY; client = (Clients*)(ListFindItem(bstate->clients, &sock, clientSocketCompare)->content); Log(LOG_PROTOCOL, 21, NULL, sock, client->clientID); client->ping_outstanding = 0; FUNC_EXIT_RC(rc); return rc; }
/** * Process an incoming unsuback packet for a socket * @param pack pointer to the publish packet * @param sock the socket on which the packet was received * @return completion code */ int MQTTProtocol_handleUnsubacks(void* pack, int sock) { Unsuback* unsuback = (Unsuback*)pack; Clients* client = NULL; int rc = TCPSOCKET_COMPLETE; FUNC_ENTRY; client = (Clients*)(ListFindItem(bstate->clients, &sock, clientSocketCompare)->content); Log(LOG_PROTOCOL, 24, NULL, sock, client->clientID, unsuback->msgId); free(unsuback); FUNC_EXIT_RC(rc); return rc; }
char* SocketBuffer_complete(int socket) { FUNC_ENTRY; if (ListFindItem(queues, &socket, socketcompare)) { socket_queue* queue = (socket_queue*)(queues->current->content); SocketBuffer_freeDefQ(); def_queue = queue; ListDetach(queues, queue); } def_queue->socket = def_queue->index = def_queue->headerlen = def_queue->datalen = 0; FUNC_EXIT; return def_queue->buf; }
void SSLSocket_addPendingRead(int sock) { FUNC_ENTRY; if (ListFindItem(&pending_reads, &sock, intcompare) == NULL) /* make sure we don't add the same socket twice */ { int* psock = (int*)malloc(sizeof(sock)); *psock = sock; ListAppend(&pending_reads, psock, sizeof(sock)); } else Log(TRACE_MIN, -1, "SSLSocket_addPendingRead: socket %d already in the list", sock); FUNC_EXIT; }
void myfree(char* file, int line, void* p) { ListElement* e = ListFindItem(&heap, p, ptrCompare); if (e == NULL) Log(LOG_ERROR, Messages_get(99), file, line); else { storageElement* s = (storageElement*)(heap.current->content); //Log(LOG_DEBUG, "Freeing %d bytes in heap at file %s line %d, heap use now %d bytes\n", s->size, file, line, state.current_size); free(s->file); state.current_size -= s->size; ListRemoveCurrentItem(&heap); } free(p); }
Registration* MQTTSProtocol_getRegisteredTopicId(Clients* client, char* topicName) { ListElement* elem; Registration* rc = NULL; FUNC_ENTRY; if ((elem = ListFindItem(client->registrations, topicName, registeredTopicNameCompare)) == NULL) goto exit; if ( client->pendingRegistration!= NULL && elem->content == client->pendingRegistration->registration ) goto exit; rc = (Registration*)(elem->content); exit: FUNC_EXIT_RC(rc); return rc; }
char* MQTTSProtocol_getRegisteredTopicName(Clients* client, int topicId) { ListElement* elem; char* rc = NULL; FUNC_ENTRY; if ((elem = ListFindItem(client->registrations, &topicId, registeredTopicIdCompare)) == NULL) goto exit; if (client->pendingRegistration != NULL && elem->content == client->pendingRegistration->registration) goto exit; rc = ((Registration*)(elem->content))->topicName; exit: FUNC_EXIT; return rc; }
/** * Adds a record to the persistent store. This function must not be called for QoS0 * messages. * @param socket the socket of the client. * @param buf0 fixed header. * @param buf0len length of the fixed header. * @param count number of buffers representing the variable header and/or the payload. * @param buffers the buffers representing the variable header and/or the payload. * @param buflens length of the buffers representing the variable header and/or the payload. * @param msgId the message ID. * @param scr 0 indicates message in the sending direction; 1 indicates message in the * receiving direction. * @return 0 if success, #MQTTCLIENT_PERSISTENCE_ERROR otherwise. */ int MQTTPersistence_put(int socket, char* buf0, size_t buf0len, int count, char** buffers, size_t* buflens, int htype, int msgId, int scr ) { int rc = 0; extern ClientStates* bstate; int nbufs, i; int* lens = NULL; char** bufs = NULL; char *key; Clients* client = NULL; FUNC_ENTRY; client = (Clients*)(ListFindItem(bstate->clients, &socket, clientSocketCompare)->content); if (client->persistence != NULL) { key = malloc(MESSAGE_FILENAME_LENGTH + 1); nbufs = 1 + count; lens = (int *)malloc(nbufs * sizeof(int)); bufs = (char **)malloc(nbufs * sizeof(char *)); lens[0] = (int)buf0len; bufs[0] = buf0; for (i = 0; i < count; i++) { lens[i+1] = (int)buflens[i]; bufs[i+1] = buffers[i]; } // key if ( scr == 0 ) { /* sending */ if (htype == PUBLISH) /* PUBLISH QoS1 and QoS2*/ sprintf(key, "%s%d", PERSISTENCE_PUBLISH_SENT, msgId); if (htype == PUBREL) /* PUBREL */ sprintf(key, "%s%d", PERSISTENCE_PUBREL, msgId); } if ( scr == 1 ) /* receiving PUBLISH QoS2 */ sprintf(key, "%s%d", PERSISTENCE_PUBLISH_RECEIVED, msgId); rc = client->persistence->pput(client->phandle, key, nbufs, bufs, lens); free(key); free(lens); free(bufs); } FUNC_EXIT_RC(rc); return rc; }
int MQTTSProtocol_handlePubrels(void* pack, int sock, char* clientAddr, Clients* client) { int rc = 0; MQTTS_PubRel* pubrel = (MQTTS_PubRel*)pack; FUNC_ENTRY; /* look for the message by message id in the records of inbound messages for this client */ if (ListFindItem(client->inboundMsgs, &(pubrel->msgId), messageIDCompare) == NULL) { /* TODO: no dup flag in mqtts... not sure this is right if (pubrel->header.dup == 0) Log(LOG_WARNING, 50, "PUBREL", client->clientID, pubrel->msgId); else */ /* Apparently this is "normal" behavior, so we don't need to issue a warning */ rc = MQTTSPacket_send_pubcomp(client,pubrel->msgId); } else { Messages* m = (Messages*)(client->inboundMsgs->current->content); if (m->qos != 2) Log(LOG_WARNING, 51, NULL, "PUBREL", client->clientID, pubrel->msgId, m->qos); else if (m->nextMessageType != PUBREL) Log(LOG_WARNING, 52, NULL, "PUBREL", client->clientID, pubrel->msgId); else { Publish publish; /* send pubcomp before processing the publications because a lot of return publications could fill up the socket buffer */ rc = MQTTSPacket_send_pubcomp(client, pubrel->msgId); publish.header.bits.qos = m->qos; publish.header.bits.retain = m->retain; publish.msgId = m->msgid; publish.topic = m->publish->topic; publish.payload = m->publish->payload; publish.payloadlen = m->publish->payloadlen; Protocol_processPublication(&publish, client->clientID); MQTTProtocol_removePublication(m->publish); ListRemove(client->inboundMsgs, m); /* TODO: msgs counts */ /* ++(state.msgs_received); */ } } time( &(client->lastContact) ); MQTTSPacket_free_packet(pack); FUNC_EXIT_RC(rc); return rc; }
/** * A socket read was interrupted so we need to queue data * @param socket the socket to get queued data for * @param actual_len the actual length of data that was read */ void SocketBuffer_interrupted(int socket, size_t actual_len) { socket_queue* queue = NULL; FUNC_ENTRY; if (ListFindItem(queues, &socket, socketcompare)) queue = (socket_queue*)(queues->current->content); else /* new saved queue */ { queue = def_queue; ListAppend(queues, def_queue, sizeof(socket_queue)+def_queue->buflen); SocketBuffer_newDefQ(); } queue->index = 0; queue->datalen = actual_len; FUNC_EXIT; }