/** * Start up the broker. * @return completion code, success == 0 */ int Broker_startup() { int rc; FUNC_ENTRY; signal(SIGINT, finish); signal(SIGTERM, finish); signal(SIGHUP, HUPHandler); #if !defined(_DEBUG) set_sigsegv(); #endif BrokerState.clients = ListInitialize(); #if !defined(SINGLE_LISTENER) BrokerState.listeners = ListInitialize(); #endif Users_initialize(&BrokerState); if ((rc = Persistence_read_config(config, &BrokerState, config_set)) == 0) { BrokerState.se = SubscriptionEngines_initialize(); rc = Protocol_initialize(&BrokerState); #if !defined(SINGLE_LISTENER) rc = Socket_initialize(BrokerState.listeners); #else rc = Socket_initialize(BrokerState.bind_address, BrokerState.port, BrokerState.ipv6); #endif #if !defined(NO_BRIDGE) Bridge_initialize(&(BrokerState.bridge), BrokerState.se); #endif Log_setPublish(true); } FUNC_EXIT_RC(rc); return rc; }
/** * Initialize the socket module for outbound communications */ void Socket_outInitialize() { #if defined(WIN32) WORD winsockVer = 0x0202; WSADATA wsd; FUNC_ENTRY; WSAStartup(winsockVer, &wsd); #else FUNC_ENTRY; signal(SIGPIPE, SIG_IGN); #endif SocketBuffer_initialize(); #if !defined(USE_POLL) s.clientsds = ListInitialize(); s.connect_pending = ListInitialize(); s.write_pending = ListInitialize(); s.cur_clientsds = NULL; FD_ZERO(&(s.rset)); /* Initialize the descriptor set */ FD_ZERO(&(s.pending_wset)); s.maxfdp1 = 0; memcpy((void*)&(s.rset_saved), (void*)&(s.rset), sizeof(s.rset_saved)); FD_ZERO(&(s.pending_wset)); #else s.fds_tree = TreeInitialize(TreeSockCompare); s.epoll_fds = epoll_create(1024); s.cur_sds = 0; s.no_ready = 0; #endif s.newSockets = ListInitialize(); FUNC_EXIT; }
DLLExport int MQTTSClient_create(MQTTClient* handle, char* serverURI, char* clientId, int persistence_type, void* persistence_context) { int i; newc = malloc(sizeof(Clients)); memset(newc, '\0', sizeof(Clients)); newc->outboundMsgs = ListInitialize(); newc->inboundMsgs = ListInitialize(); newc->clientID = clientID; }
/** * Function used in the new packets table to create suback packets. * @param aHeader the MQTT header byte * @param data the rest of the packet * @param datalen the length of the rest of the packet * @return pointer to the packet structure */ void* MQTTPacket_suback(unsigned char aHeader, char* data, size_t datalen, networkHandles* handler) { Suback* pack = malloc(sizeof(Suback)); char* curdata = data; int mqtt_version = get_client_mqtt_version_from_network_handler(handler); FUNC_ENTRY; pack->header.byte = aHeader; if(mqtt_version == MQTTVERSION_YUNBA_3_1) { pack->msgId = readInt64(&curdata); }else{ pack->msgId = readInt(&curdata); } pack->qoss = ListInitialize(); while ((size_t)(curdata - data) < datalen) { int* newint; newint = malloc(sizeof(int)); *newint = (int)readChar(&curdata); ListAppend(pack->qoss, newint, sizeof(int)); } FUNC_EXIT; return pack; }
List * randomTwentyDeadline(){ int i; int nRandomTCnt; int nRandomTCBDeadline; listobj * nodes[20]; listobj * node; TCB * tcb; List * ls; srand(time(NULL)); for (i = 0; i < 20; i++){ node = (listobj *)calloc(1, sizeof(listobj)); tcb = (TCB *)calloc(1, sizeof(TCB)); nRandomTCnt = (rand() % 20) + 1; nRandomTCBDeadline = (rand() % 20) + 1; node->pTask = tcb; node->nTCnt = nRandomTCnt; tcb->DeadLine = nRandomTCBDeadline; nodes[i] = node; } ls = ListInitialize(); for (i = 0; i < 20; i++){ insertOnTCBDeadLine(nodes[i], ls); } return ls; };
PyMODINIT_FUNC initpaho_mqtt3c(void) { PyObject *m; PyEval_InitThreads(); callbacks = ListInitialize(); m = Py_InitModule("paho_mqtt3c", MqttV3Methods); if (m == NULL) return; MqttV3Error = PyErr_NewException("paho_mqtt3c.error", NULL, NULL); Py_INCREF(MqttV3Error); PyModule_AddObject(m, "error", MqttV3Error); PyModule_AddIntConstant(m, "SUCCESS", MQTTCLIENT_SUCCESS); PyModule_AddIntConstant(m, "FAILURE", MQTTCLIENT_FAILURE); PyModule_AddIntConstant(m, "DISCONNECTED", MQTTCLIENT_DISCONNECTED); PyModule_AddIntConstant(m, "MAX_MESSAGES_INFLIGHT", MQTTCLIENT_MAX_MESSAGES_INFLIGHT); PyModule_AddIntConstant(m, "BAD_UTF8_STRING", MQTTCLIENT_BAD_UTF8_STRING); PyModule_AddIntConstant(m, "BAD_NULL_PARAMETER", MQTTCLIENT_NULL_PARAMETER); PyModule_AddIntConstant(m, "BAD_TOPICNAME_TRUNCATED", MQTTCLIENT_TOPICNAME_TRUNCATED); PyModule_AddIntConstant(m, "PERSISTENCE_DEFAULT", MQTTCLIENT_PERSISTENCE_DEFAULT); PyModule_AddIntConstant(m, "PERSISTENCE_NONE", MQTTCLIENT_PERSISTENCE_NONE); PyModule_AddIntConstant(m, "PERSISTENCE_USER", MQTTCLIENT_PERSISTENCE_USER); PyModule_AddIntConstant(m, "PERSISTENCE_ERROR", MQTTCLIENT_PERSISTENCE_ERROR); }
Clients* MQTTSProtocol_connect(char* ip_address, char* clientID, int cleansession, int try_private, int keepalive, willMessages* willMessage) { /* outgoing connection */ int rc, port; char* addr; Clients* newc = malloc(sizeof(Clients)); FUNC_ENTRY; newc->clientID = clientID; newc->cleansession = cleansession; newc->outbound = 1; newc->connected = 0; newc->ping_outstanding = 0; newc->keepAliveInterval = keepalive; newc->msgID = 0; newc->outboundMsgs = ListInitialize(); newc->inboundMsgs = ListInitialize(); newc->queuedMsgs = ListInitialize(); newc->registrations = ListInitialize(); newc->will = willMessage; newc->good = 1; newc->connect_state = 0; newc->noLocal = try_private; /* try private connection first */ time(&(newc->lastContact)); newc->discardedMsgs = 0; newc->pendingRegistration = NULL; newc->protocol = PROTOCOL_MQTTS; addr = MQTTProtocol_addressPort(ip_address, &port); newc->addr = malloc(strlen(ip_address)); strcpy(newc->addr,ip_address); rc = Socket_new_type(addr, port, &(newc->socket), SOCK_DGRAM); if (rc == EINPROGRESS || rc == EWOULDBLOCK) newc->connect_state = 1; // UDP connect called - improbable, but possible on obscure platforms else if (rc == 0) { Log(LOG_PROTOCOL, 69, NULL, newc->clientID, newc->socket, newc->noLocal); newc->connect_state = 2; rc = MQTTSPacket_send_connect(newc); } ListAppend(bstate->clients, newc, sizeof(Clients) + strlen(newc->clientID)+1 + 3*sizeof(List)); FUNC_EXIT; return newc; }
/** * Initialize the socketBuffer module */ void SocketBuffer_initialize(void) { FUNC_ENTRY; SocketBuffer_newDefQ(); queues = ListInitialize(); ListZero(&writes); FUNC_EXIT; }
list_p ListCopy(list_p list, void*(*data_copy_callback)(const void* data)) { list_p newList = ListInitialize(); listNode_p node; for(node = list->listhead; node!=NULL; node = node->next) { ListAppend(newList, data_copy_callback(node->node_data)); } return newList; }
/** * Initialize the log module. * @return completion code, success == 0 */ int Log_initialize() { int rc = -1; trace_queue = malloc(sizeof(traceEntry) * trace_settings.max_trace_entries); trace_queue_size = trace_settings.max_trace_entries; if ((log_buffer = ListInitialize()) != NULL) rc = 0; return rc; }
HRESULT TaskMallocInitialize( void ) { initCount++; if( initCount == 1 ) { ListInitialize( &allocList ); return S_OK; } return S_FALSE; }
/** * Initialize the socket module */ void Socket_outInitialize() { #if defined(WIN32) || defined(WIN64) WORD winsockVer = 0x0202; WSADATA wsd; FUNC_ENTRY; WSAStartup(winsockVer, &wsd); #else FUNC_ENTRY; signal(SIGPIPE, SIG_IGN); #endif SocketBuffer_initialize(); s.clientsds = ListInitialize(); s.connect_pending = ListInitialize(); s.write_pending = ListInitialize(); s.cur_clientsds = NULL; FD_ZERO(&(s.rset)); /* Initialize the descriptor set */ FD_ZERO(&(s.pending_wset)); s.maxfdp1 = 0; memcpy((void*)&(s.rset_saved), (void*)&(s.rset), sizeof(s.rset_saved)); FUNC_EXIT; }
int main(int argc, char *argv[]) { int i, *ip, *todelete; ListElement* current = NULL; List* l = ListInitialize(); printf("List initialized\n"); for (i = 0; i < 10; i++) { ip = malloc(sizeof(int)); *ip = i; ListAppend(l, (void*)ip, sizeof(int)); if (i==5) todelete = ip; printf("List element appended %d\n", *((int*)(l->last->content))); } printf("List contents:\n"); current = NULL; while (ListNextElement(l, ¤t) != NULL) printf("List element: %d\n", *((int*)(current->content))); printf("List contents in reverse order:\n"); current = NULL; while (ListPrevElement(l, ¤t) != NULL) printf("List element: %d\n", *((int*)(current->content))); //if ListFindItem(l, *ip, intcompare)->content printf("List contents having deleted element %d:\n", *todelete); ListRemove(l, todelete); current = NULL; while (ListNextElement(l, ¤t) != NULL) printf("List element: %d\n", *((int*)(current->content))); i = 9; ListRemoveItem(l, &i, intcompare); printf("List contents having deleted another element, %d, size now %d:\n", i, l->size); current = NULL; while (ListNextElement(l, ¤t) != NULL) printf("List element: %d\n", *((int*)(current->content))); ListFree(l); printf("List freed\n"); }
/** * Function used in the new packets table to create suback packets. * @param aHeader the MQTT header byte * @param data the rest of the packet * @param datalen the length of the rest of the packet * @return pointer to the packet structure */ void* MQTTPacket_suback(unsigned char aHeader, char* data, int datalen) { Suback* pack = malloc(sizeof(Suback)); char* curdata = data; FUNC_ENTRY; pack->header.byte = aHeader; pack->msgId = readInt(&curdata); pack->qoss = ListInitialize(); while (curdata - data < datalen) { int* newint; newint = malloc(sizeof(int)); *newint = (int)readChar(&curdata); ListAppend(pack->qoss, newint, sizeof(int)); } FUNC_EXIT; return pack; }
int testIndexFetch(){ List * test = ListInitialize(); listobj * nodeToInsert = (listobj*)calloc(1, sizeof(listobj)); listobj * compareNode; int i; for (i = 0; i < 10; i++){ nodeToInsert = (listobj*)calloc(1, sizeof(listobj)); nodeToInsert->nTCnt = i; insertonTCnt(nodeToInsert, test); } for (i = 0; i < 10; i++){ compareNode = nodeAtindex(test, i); if (compareNode->nTCnt != i){ return 0; } } return 1; }
Clients* MQTTSProtocol_create_multicast(char* ip_address, char* clientID, int loopback) { /* outgoing connection */ int i, port, rc; char* addr; Clients* newc = NULL; char* intface = NULL; int ipv6 = 0; FUNC_ENTRY; newc = malloc(sizeof(Clients)); memset(newc, '\0', sizeof(Clients)); newc->clientID = clientID; newc->outbound = 1; newc->good = 1; newc->connected = 1; newc->outboundMsgs = ListInitialize(); newc->inboundMsgs = ListInitialize(); for (i = 0; i < PRIORITY_MAX; ++i) newc->queuedMsgs[i] = ListInitialize(); newc->registrations = ListInitialize(); newc->protocol = PROTOCOL_MQTTS_MULTICAST; /* if there is a space in the ip_address string, it means we have address plus interface specified */ if ((intface = strchr(ip_address, ' ')) != NULL) { *intface = '\0'; ++intface; } addr = MQTTProtocol_addressPort(ip_address, &port); newc->addr = malloc(strlen(ip_address) + 1); strcpy(newc->addr, ip_address); ipv6 = (newc->addr[0] == '['); rc = Socket_new_udp(&(newc->socket), ipv6); if (setsockopt(newc->socket, IPPROTO_IP, IP_MULTICAST_LOOP, (const char*)&loopback, sizeof(loopback)) == SOCKET_ERROR) Socket_error("set bridge IP_MULTICAST_LOOP", newc->socket); if (intface) { if (ipv6) { int index = 0; if ((index = if_nametoindex(intface)) == 0) Socket_error("get interface index", newc->socket); else if (setsockopt(newc->socket, IPPROTO_IPV6, IPV6_MULTICAST_IF, (const char*)&index, sizeof(index)) == SOCKET_ERROR) Socket_error("set bridge IP_MULTICAST_IF", newc->socket); } else { struct in_addr interface_addr; #if defined(WIN32) if ((rc = win_inet_pton(AF_INET, intface, &interface_addr)) == SOCKET_ERROR) Socket_error("WSAStringToAddress interface", newc->socket); else { #else /* get address of the interface */ struct ifreq ifreq; strncpy(ifreq.ifr_name, intface, IFNAMSIZ); if (ioctl(newc->socket, SIOCGIFADDR, &ifreq) == SOCKET_ERROR) Socket_error("get interface address", newc->socket); else { memcpy(&interface_addr, &((struct sockaddr_in *)&ifreq.ifr_addr)->sin_addr, sizeof(struct in_addr)); #endif if (setsockopt(newc->socket, IPPROTO_IP, IP_MULTICAST_IF, &interface_addr, sizeof(interface_addr)) == SOCKET_ERROR) Socket_error("set bridge IP_MULTICAST_IF", newc->socket); } } } TreeAdd(bstate->disconnected_mqtts_clients, newc, sizeof(Clients) + strlen(newc->clientID)+1 + 3*sizeof(List)); FUNC_EXIT; return newc; } Clients* MQTTSProtocol_connect(char* ip_address, char* clientID, int cleansession, int try_private, int keepalive, willMessages* willMessage) { /* outgoing connection */ int rc, port; char* addr; Clients* newc = NULL; FUNC_ENTRY; newc = TreeRemoveKeyIndex(bstate->disconnected_clients, clientID, 1); /* must be a dummy client */ if (newc == NULL) newc = TreeRemoveKeyIndex(bstate->clients, clientID, 1); if (newc) { free(clientID); newc->connected = newc->ping_outstanding = newc->connect_state = newc->msgID = newc->discardedMsgs = 0; } else { int i; newc = malloc(sizeof(Clients)); memset(newc, '\0', sizeof(Clients)); newc->outboundMsgs = ListInitialize(); newc->inboundMsgs = ListInitialize(); for (i = 0; i < PRIORITY_MAX; ++i) newc->queuedMsgs[i] = ListInitialize(); newc->clientID = clientID; } newc->cleansession = cleansession; newc->outbound = newc->good = 1; newc->keepAliveInterval = keepalive; newc->registrations = ListInitialize(); newc->will = willMessage; newc->noLocal = try_private; /* try private connection first */ time(&(newc->lastContact)); newc->pendingRegistration = NULL; newc->protocol = PROTOCOL_MQTTS; addr = MQTTProtocol_addressPort(ip_address, &port); newc->addr = malloc(strlen(ip_address)); strcpy(newc->addr, ip_address); rc = Socket_new_type(addr, port, &(newc->socket), SOCK_DGRAM); if (rc == EINPROGRESS || rc == EWOULDBLOCK) newc->connect_state = 1; /* UDP connect called - improbable, but possible on obscure platforms */ else if (rc == 0) { newc->connect_state = 2; rc = MQTTSPacket_send_connect(newc); } TreeAdd(bstate->clients, newc, sizeof(Clients) + strlen(newc->clientID)+1 + 3*sizeof(List)); FUNC_EXIT; return newc; }
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, ¤t)) { 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; }
int MQTTSProtocol_handleConnects(void* pack, int sock, char* clientAddr, Clients* client, uint8_t* wirelessNodeId , uint8_t wirelessNodeIdLen) { MQTTS_Connect* connect = (MQTTS_Connect*)pack; Listener* list = NULL; int terminate = 0; Node* elem = NULL; int rc = 0; int existingClient = 0; FUNC_ENTRY; Log(LOG_PROTOCOL, 39, NULL, sock, clientAddr, client ? client->clientID : "", connect->flags.cleanSession); if (bstate->clientid_prefixes->count > 0 && !ListFindItem(bstate->clientid_prefixes, connect->clientID, clientPrefixCompare)) { Log(LOG_WARNING, 31, NULL, connect->clientID); terminate = 1; } else { list = Socket_getParentListener(sock); if (list->max_connections > -1 && list->connections->count > list->max_connections) { /* TODO: why is this commented out? delete if not needed //MQTTPacket_send_connack(3, sock); */ Log(LOG_WARNING, 141, NULL, connect->clientID, list->max_connections, list->port); terminate = 1; } else if (connect->protocolID != 1) { Log(LOG_WARNING, 32, NULL, "MQTT-S", connect->protocolID); /* TODO: why is this commented out? delete if not needed //MQTTPacket_send_connack(1, sock); */ terminate = 1; } } if (terminate) { /*TODO: process the terminate*/ MQTTSPacket_free_packet(pack); goto exit; } if (client != NULL && !strcmp(client->clientID, connect->clientID)) { /* Connect for a new client id on a used addr * TODO: clean out 'old' Client (that may be 'connected') */ } elem = TreeFindIndex(bstate->mqtts_clients, connect->clientID, 1); if (elem == NULL) { client = TreeRemoveKey(bstate->disconnected_mqtts_clients, connect->clientID); if (client == NULL) /* this is a totally new connection */ { /* Brand new client connection */ int i; client = malloc(sizeof(Clients)); memset(client, '\0', sizeof(Clients)); client->protocol = PROTOCOL_MQTTS; client->outboundMsgs = ListInitialize(); client->inboundMsgs = ListInitialize(); for (i = 0; i < PRIORITY_MAX; ++i) client->queuedMsgs[i] = ListInitialize(); client->registrations = ListInitialize(); client->noLocal = 0; /* (connect->version == PRIVATE_PROTOCOL_VERSION) ? 1 : 0; */ client->clientID = connect->clientID; connect->clientID = NULL; /* don't want to free this space as it is being used in the clients tree below */ // Set Wireless Node ID if exists if ( wirelessNodeId == NULL) { client->wirelessNodeId = NULL ; client->wirelessNodeIdLen = 0 ; } else { client->wirelessNodeId = malloc((sizeof(uint8_t) * wirelessNodeIdLen)) ; memcpy( client->wirelessNodeId , wirelessNodeId , sizeof(uint8_t) * wirelessNodeIdLen) ; client->wirelessNodeIdLen = wirelessNodeIdLen ; } } // // client == NULL else /* there is an existing disconnected client */ { /* Reconnect of a disconnected client */ free(client->addr); client->connect_state = 0; client->connected = 0; /* Do not connect until we know the connack has been sent */ // Delete Wireless Node ID if exists in existing client if ( wirelessNodeId == NULL) { if ( client->wirelessNodeId != NULL) free( client->wirelessNodeId ) ; client->wirelessNodeId = NULL ; client->wirelessNodeIdLen = 0 ; } else // Replace existing Wireless Node ID with value from current connect packet { if ( client->wirelessNodeId != NULL) free ( client->wirelessNodeId ) ; client->wirelessNodeId = malloc((sizeof(uint8_t) * wirelessNodeIdLen)) ; memcpy( client->wirelessNodeId , wirelessNodeId , sizeof(uint8_t) * wirelessNodeIdLen) ; client->wirelessNodeIdLen = wirelessNodeIdLen ; } } // client != NULL client->good = 1; /* good is set to 0 in disconnect, so we need to reset it here */ client->keepAliveInterval = connect->keepAlive; client->cleansession = connect->flags.cleanSession; client->socket = sock; client->addr = malloc(strlen(clientAddr)+1); strcpy(client->addr, clientAddr); TreeAdd(bstate->mqtts_clients, client, sizeof(Clients) + strlen(client->clientID)+1 + 3*sizeof(List)); if (client->cleansession) MQTTProtocol_removeAllSubscriptions(client->clientID); /* clear any persistent subscriptions */ if (connect->flags.will) { client->connect_state = 1; rc = MQTTSPacket_send_willTopicReq(client); } else { client->connected = 1; rc = MQTTSPacket_send_connack(client, 0); /* send response */ } } else { /* Reconnect of a connected client */ client = (Clients*)(elem->content); if (client->connected) { Log(LOG_INFO, 34, NULL, connect->clientID, clientAddr); if (client->socket != sock) Socket_close(client->socket); } client->socket = sock; client->connected = 0; /* Do not connect until we know the connack has been sent */ client->connect_state = 0; // Delete Wireless Node ID if exists in existing client if ( wirelessNodeId == NULL) { if ( client->wirelessNodeId != NULL) free( client->wirelessNodeId ) ; client->wirelessNodeId = NULL ; client->wirelessNodeIdLen = 0 ; } else // Replace existing Wireless Node ID with value from current connect packet { if ( client->wirelessNodeId != NULL) free ( client->wirelessNodeId ) ; client->wirelessNodeId = malloc((sizeof(uint8_t) * wirelessNodeIdLen)) ; memcpy( client->wirelessNodeId , wirelessNodeId , sizeof(uint8_t) * wirelessNodeIdLen) ; client->wirelessNodeIdLen = wirelessNodeIdLen ; } client->good = 1; if (client->addr != NULL) free(client->addr); client->addr = malloc(strlen(clientAddr)+1); strcpy(client->addr, clientAddr); client->cleansession = connect->flags.cleanSession; if (client->cleansession) { int i; MQTTProtocol_removeAllSubscriptions(client->clientID); /* empty pending message lists */ MQTTProtocol_emptyMessageList(client->outboundMsgs); MQTTProtocol_emptyMessageList(client->inboundMsgs); for (i = 0; i < PRIORITY_MAX; ++i) MQTTProtocol_emptyMessageList(client->queuedMsgs[i]); MQTTProtocol_clearWill(client); } /* registrations are always cleared */ MQTTSProtocol_emptyRegistrationList(client->registrations); /* have to remove and re-add client so it is in the right order for new socket */ if (client->socket != sock) { TreeRemoveNodeIndex(bstate->mqtts_clients, elem, 1); TreeRemoveKeyIndex(bstate->mqtts_clients, &client->socket, 0); client->socket = sock; TreeAdd(bstate->mqtts_clients, client, sizeof(Clients) + strlen(client->clientID)+1 + 3*sizeof(List)); } client->keepAliveInterval = connect->keepAlive; client->pendingRegistration = NULL; #if !defined(NO_BRIDGE) client->pendingSubscription = NULL; #endif if (connect->flags.will) { client->connect_state = 1; rc = MQTTSPacket_send_willTopicReq(client); } else { client->connected = 1; rc = MQTTSPacket_send_connack(client,0); /* send response */ } } if (existingClient) MQTTProtocol_processQueued(client); Log(LOG_INFO, 0, "Client connected to udp port %d from %s (%s)", list->port, client->clientID, clientAddr); MQTTSPacket_free_packet(pack); time( &(client->lastContact) ); exit: FUNC_EXIT_RC(rc); return rc; }
static void initialize_mock_api() { ListInitialize(&lg_mocked_functions_list); lg_initialized=1; }
/** * Process an incoming connect packet for a socket * @param pack pointer to the connect packet * @param sock the socket on which the packet was received * @return completion code */ int MQTTProtocol_handleConnects(void* pack, int sock, Clients* client) { Connect* connect = (Connect*)pack; Node* elem = NULL; int terminate = 0; int rc = TCPSOCKET_COMPLETE; #if !defined(SINGLE_LISTENER) Listener* listener = Socket_getParentListener(sock); #endif FUNC_ENTRY; Log(LOG_PROTOCOL, 26, NULL, sock, connect->clientID);/* connect->Protocol, connect->flags.bits.cleanstart, connect->keepAliveTimer, connect->version, connect->username, connect->password);*/ Socket_removeNew(sock); if (bstate->state != BROKER_RUNNING) terminate = 1; /* don't accept new connection requests when we are shutting down */ /* Now check the version. If we don't recognize it we will not have parsed the packet, * so nothing else in the packet structure will have been filled in. */ else if (!MQTTPacket_checkVersion(pack)) { Log(LOG_WARNING, 32, NULL, connect->Protocol, connect->version); rc = MQTTPacket_send_connack(CONNACK_UNACCEPTABLE_PROTOCOL_VERSION, sock, Socket_getpeer(sock)); /* send response */ terminate = 1; } else if (connect->clientID[0] == '\0' || (connect->version == 3 && strlen(connect->clientID) > 23)) { rc = MQTTPacket_send_connack(CONNACK_IDENTIFIER_REJECTED, sock, Socket_getpeer(sock)); /* send response */ terminate = 1; } else if (bstate->password_file != NULL) { if (connect->flags.bits.username && connect->flags.bits.password && (Users_authenticate(connect->username, connect->password) == false)) { Log(LOG_WARNING, 31, NULL, connect->clientID); rc = MQTTPacket_send_connack(CONNACK_BAD_USERNAME_OR_PASSWORD, sock, connect->clientID); /* send bad user/pass response */ terminate = 1; } else if ((!connect->flags.bits.username || !connect->flags.bits.password) && !bstate->allow_anonymous) { Log(LOG_WARNING, 31, NULL, connect->clientID); rc = MQTTPacket_send_connack(CONNACK_BROKER_UNAVAILABLE, sock, connect->clientID); /* send broker unavailable response */ terminate = 1; } } if (terminate) ; else if (bstate->clientid_prefixes->count > 0 && !ListFindItem(bstate->clientid_prefixes, connect->clientID, clientPrefixCompare)) { Log(LOG_WARNING, 31, NULL, connect->clientID); terminate = 1; } else { #if !defined(SINGLE_LISTENER) if (listener->max_connections > -1 && listener->connections->count > listener->max_connections) { Log(LOG_WARNING, 141, NULL, connect->clientID, listener->max_connections, listener->port); #else if (bstate->max_connections > -1 && MQTTProtocol_getNoConnectedClients() >= bstate->max_connections) { Log(LOG_WARNING, 141, NULL, connect->clientID, bstate->max_connections, bstate->port); #endif rc = MQTTPacket_send_connack(CONNACK_BROKER_UNAVAILABLE, sock, connect->clientID); /* send response */ terminate = 1; } } if (terminate) { MQTTPacket_freeConnect(connect); Socket_close(sock); rc = TCPSOCKET_COMPLETE; goto exit; } if (bstate->connection_messages) Log(LOG_INFO, #if !defined(SINGLE_LISTENER) 33, NULL, listener->port, connect->clientID, Socket_getpeer(sock)); #else 33, NULL, bstate->port, connect->clientID, Socket_getpeer(sock)); #endif elem = TreeFindIndex(bstate->clients, connect->clientID, 1); if (elem == NULL) { client = TreeRemoveKey(bstate->disconnected_clients, connect->clientID); if (client == NULL) { int i; char* tmpAddr = NULL; client = malloc(sizeof(Clients)); memset(client, '\0', sizeof(Clients)); tmpAddr = Socket_getpeer(sock); client->addr = malloc(strlen(tmpAddr)+1); strcpy(client->addr, tmpAddr); #if defined(MQTTS) client->protocol = PROTOCOL_MQTT; #endif client->clientID = connect->clientID; client->outboundMsgs = ListInitialize(); client->inboundMsgs = ListInitialize(); for (i = 0; i < PRIORITY_MAX; ++i) client->queuedMsgs[i] = ListInitialize(); connect->clientID = NULL; /* don't want to free this space as it is being used in the client structure */ } client->socket = sock; TreeAdd(bstate->clients, client, sizeof(Clients) + strlen(client->clientID)+1 + 3*sizeof(List)); } else { client = (Clients*)(elem->content); if (client->connected) { Log(LOG_INFO, 34, NULL, connect->clientID, Socket_getpeer(sock)); if (client->socket != sock) Socket_close(client->socket); } if (connect->flags.bits.cleanstart) { int i; /* empty pending message lists */ MQTTProtocol_emptyMessageList(client->outboundMsgs); MQTTProtocol_emptyMessageList(client->inboundMsgs); for (i = 0; i < PRIORITY_MAX; ++i) MQTTProtocol_emptyMessageList(client->queuedMsgs[i]); client->msgID = client->outbound = client->ping_outstanding = 0; } /* have to remove and re-add client so it is in the right order for new socket */ if (client->socket != sock) { TreeRemoveNodeIndex(bstate->clients, elem, 1); TreeRemoveKeyIndex(bstate->clients, &client->socket, 0); client->socket = sock; TreeAdd(bstate->clients, client, sizeof(Clients) + strlen(client->clientID)+1 + 3*sizeof(List)); } } client->good = client->connected = 1; client->cleansession = connect->flags.bits.cleanstart; client->keepAliveInterval = connect->keepAliveTimer; client->noLocal = (connect->version == PRIVATE_PROTOCOL_VERSION) ? 1 : 0; if (client->cleansession) MQTTProtocol_removeAllSubscriptions(client->clientID); /* clear any persistent subscriptions */ #if !defined(SINGLE_LISTENER) if (listener && listener->mount_point && connect->flags.bits.will) { char* temp = malloc(strlen(connect->willTopic) + strlen(listener->mount_point) + 1); strcpy(temp, listener->mount_point); strcat(temp, connect->willTopic); free(connect->willTopic); connect->willTopic = temp; } #endif #if defined(MQTTS) if (connect->flags.bits.will) { MQTTProtocol_setWillTopic(client, connect->willTopic, connect->flags.bits.willRetain, connect->flags.bits.willQoS); MQTTProtocol_setWillMsg(client, connect->willMsg); connect->willTopic = NULL; connect->willMsg = NULL; } #else MQTTProtocol_setWill(connect, client); #endif if (connect->flags.bits.username) { client->user = Users_get_user(connect->username); } rc = MQTTPacket_send_connack(CONNACK_CONNECTION_ACCEPTED, sock, client->clientID); /* send response */ if (client->cleansession == 0) { ListElement* outcurrent = NULL; time_t now = 0; /* ensure that inflight messages are retried now by setting the last touched time * to very old (0) before calling the retry function */ time(&(now)); while (ListNextElement(client->outboundMsgs, &outcurrent)) { Messages* m = (Messages*)(outcurrent->content); m->lastTouch = 0; } MQTTProtocol_retries(now, client); MQTTProtocol_processQueued(client); } time(&(client->lastContact)); MQTTPacket_freeConnect(connect); exit: FUNC_EXIT_RC(rc); return rc; } /** * Process an incoming ping request 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_handlePingreqs(void* pack, int sock, Clients* client) { int rc = TCPSOCKET_COMPLETE; FUNC_ENTRY; Log(LOG_PROTOCOL, 3, NULL, sock, client->clientID); rc = MQTTPacket_send_pingresp(sock, client->clientID); FUNC_EXIT_RC(rc); return rc; }
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; }
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; }
int MQTTClient_create(MQTTClient* handle, const char* serverURI, const char* clientId, int persistence_type, void* persistence_context) { int rc = 0; MQTTClients *m = NULL; FUNC_ENTRY; rc = Thread_lock_mutex(mqttclient_mutex); if (serverURI == NULL || clientId == NULL) { rc = MQTTCLIENT_NULL_PARAMETER; goto exit; } if (!UTF8_validateString(clientId)) { rc = MQTTCLIENT_BAD_UTF8_STRING; goto exit; } if (!initialized) { #if defined(HEAP_H) Heap_initialize(); #endif Log_initialize((Log_nameValue*)MQTTClient_getVersionInfo()); bstate->clients = ListInitialize(); Socket_outInitialize(); Socket_setWriteCompleteCallback(MQTTClient_writeComplete); handles = ListInitialize(); #if defined(OPENSSL) SSLSocket_initialize(); #endif initialized = 1; } m = malloc(sizeof(MQTTClients)); *handle = m; memset(m, '\0', sizeof(MQTTClients)); if (strncmp(URI_TCP, serverURI, strlen(URI_TCP)) == 0) serverURI += strlen(URI_TCP); #if defined(OPENSSL) else if (strncmp(URI_SSL, serverURI, strlen(URI_SSL)) == 0) { serverURI += strlen(URI_SSL); m->ssl = 1; } #endif m->serverURI = MQTTStrdup(serverURI); ListAppend(handles, m, sizeof(MQTTClients)); m->c = malloc(sizeof(Clients)); memset(m->c, '\0', sizeof(Clients)); m->c->context = m; m->c->outboundMsgs = ListInitialize(); m->c->inboundMsgs = ListInitialize(); m->c->messageQueue = ListInitialize(); m->c->clientID = MQTTStrdup(clientId); m->connect_sem = Thread_create_sem(); m->connack_sem = Thread_create_sem(); m->suback_sem = Thread_create_sem(); m->unsuback_sem = Thread_create_sem(); #if !defined(NO_PERSISTENCE) rc = MQTTPersistence_create(&(m->c->persistence), persistence_type, persistence_context); if (rc == 0) { rc = MQTTPersistence_initialize(m->c, m->serverURI); if (rc == 0) MQTTPersistence_restoreMessageQueue(m->c); } #endif ListAppend(bstate->clients, m->c, sizeof(Clients) + 3*sizeof(List)); exit: Thread_unlock_mutex(mqttclient_mutex); FUNC_EXIT_RC(rc); return rc; }
int MQTTClient_create(MQTTClient* handle, char* serverURI, char* clientId, int persistence_type, void* persistence_context) { int rc = 0; MQTTClients *m = NULL; FUNC_ENTRY; rc = Thread_lock_mutex(mqttclient_mutex); if (serverURI == NULL || clientId == NULL) { rc = MQTTCLIENT_NULL_PARAMETER; goto exit; } if (!UTF8_validateString(clientId)) { rc = MQTTCLIENT_BAD_UTF8_STRING; goto exit; } if (!initialized) { #if defined(HEAP_H) Heap_initialize(); #endif Log_initialize(); bstate->clients = ListInitialize(); Socket_outInitialize(); handles = ListInitialize(); initialized = 1; } m = malloc(sizeof(MQTTClients)); *handle = m; memset(m, '\0', sizeof(MQTTClients)); if (strncmp(URI_TCP, serverURI, strlen(URI_TCP)) == 0) serverURI += strlen(URI_TCP); m->serverURI = malloc(strlen(serverURI)+1); strcpy(m->serverURI, serverURI); ListAppend(handles, m, sizeof(MQTTClients)); m->c = malloc(sizeof(Clients)); memset(m->c, '\0', sizeof(Clients)); m->c->outboundMsgs = ListInitialize(); m->c->inboundMsgs = ListInitialize(); m->c->messageQueue = ListInitialize(); m->c->clientID = malloc(strlen(clientId)+1); strcpy(m->c->clientID, clientId); m->connect_sem = Thread_create_sem(); m->connack_sem = Thread_create_sem(); m->suback_sem = Thread_create_sem(); m->unsuback_sem = Thread_create_sem(); #if !defined(NO_PERSISTENCE) rc = MQTTPersistence_create(&(m->c->persistence), persistence_type, persistence_context); if (rc == 0) rc = MQTTPersistence_initialize(m->c, m->serverURI); #endif ListAppend(bstate->clients, m->c, sizeof(Clients) + 3*sizeof(List)); exit: if (Thread_unlock_mutex(mqttclient_mutex) != 0) /* FFDC? */; FUNC_EXIT_RC(rc); return rc; }