/** * Send an MQTT unsubscribe packet down a socket. * @param topics list of topics * @param msgid the MQTT message id to use * @param dup boolean - whether to set the MQTT DUP flag * @param socket the open socket to send the data to * @param clientID the string client identifier, only used for tracing * @return the completion code (e.g. TCPSOCKET_COMPLETE) */ int MQTTPacket_send_unsubscribe(List* topics, int msgid, int dup, int socket, char* clientID) { Header header; char *data, *ptr; int rc = -1; ListElement *elem = NULL; int datalen; FUNC_ENTRY; header.bits.type = UNSUBSCRIBE; header.bits.dup = dup; header.bits.qos = 1; header.bits.retain = 0; datalen = 2 + topics->count * 2; // utf length == 2 while (ListNextElement(topics, &elem)) datalen += strlen((char*)(elem->content)); ptr = data = malloc(datalen); writeInt(&ptr, msgid); elem = NULL; while (ListNextElement(topics, &elem)) writeUTF(&ptr, (char*)(elem->content)); rc = MQTTPacket_send(socket, header, data, datalen); Log(LOG_PROTOCOL, 25, NULL, socket, clientID, msgid, rc); free(data); FUNC_EXIT_RC(rc); return rc; }
/** * Send an MQTT unsubscribe packet down a socket. * @param topics list of topics * @param msgid the MQTT message id to use * @param dup boolean - whether to set the MQTT DUP flag * @param socket the open socket to send the data to * @param clientID the string client identifier, only used for tracing * @return the completion code (e.g. TCPSOCKET_COMPLETE) */ int MQTTPacket_send_unsubscribe(List* topics, int msgid, int dup, networkHandles* net, const char* clientID) { Header header; char *data, *ptr; int rc = -1; ListElement *elem = NULL; int datalen; FUNC_ENTRY; header.bits.type = UNSUBSCRIBE; header.bits.dup = dup; header.bits.qos = 1; header.bits.retain = 0; datalen = 2 + topics->count * 2; /* utf length == 2 */ while (ListNextElement(topics, &elem)) datalen += (int)strlen((char*)(elem->content)); ptr = data = malloc(datalen); writeInt(&ptr, msgid); elem = NULL; while (ListNextElement(topics, &elem)) writeUTF(&ptr, (char*)(elem->content)); rc = MQTTPacket_send(net, header, data, datalen, 1); Log(LOG_PROTOCOL, 25, NULL, net->socket, clientID, msgid, rc); if (rc != TCPSOCKET_INTERRUPTED) free(data); FUNC_EXIT_RC(rc); return rc; }
/** * Send an MQTT PINGREQ packet down a socket. * @param socket the open socket to send the data to * @param clientID the string client identifier, only used for tracing * @return the completion code (e.g. TCPSOCKET_COMPLETE) */ int MQTTPacket_send_pingreq(int socket, char* clientID) { Header header; int rc = 0; FUNC_ENTRY; header.byte = 0; header.bits.type = PINGREQ; rc = MQTTPacket_send(socket, header, NULL, 0); Log(LOG_PROTOCOL, 20, NULL, socket, clientID, rc); FUNC_EXIT_RC(rc); return rc; }
/** * Send an MQTT disconnect packet down a socket. * @param socket the open socket to send the data to * @return the completion code (e.g. TCPSOCKET_COMPLETE) */ int MQTTPacket_send_disconnect(networkHandles *net, const char* clientID) { Header header; int rc = 0; FUNC_ENTRY; header.byte = 0; header.bits.type = DISCONNECT; rc = MQTTPacket_send(net, header, NULL, 0, 0); Log(LOG_PROTOCOL, 28, NULL, net->socket, clientID, rc); FUNC_EXIT_RC(rc); return rc; }
/** * Send an MQTT PINGREQ packet down a socket. * @param socket the open socket to send the data to * @param clientID the string client identifier, only used for tracing * @return the completion code (e.g. TCPSOCKET_COMPLETE) */ int MQTTPacket_send_pingreq(networkHandles* net, const char* clientID) { Header header; int rc = 0; size_t buflen = 0; FUNC_ENTRY; header.byte = 0; header.bits.type = PINGREQ; rc = MQTTPacket_send(net, header, NULL, buflen,0); Log(LOG_PROTOCOL, 20, NULL, net->socket, clientID, rc); FUNC_EXIT_RC(rc); return rc; }
/** * Send an MQTT acknowledgement packet down a socket. * @param type the MQTT packet type e.g. SUBACK * @param msgid the MQTT message id to use * @param dup boolean - whether to set the MQTT DUP flag * @param socket the open socket to send the data to * @return the completion code (e.g. TCPSOCKET_COMPLETE) */ int MQTTPacket_send_ack(int type, int msgid, int dup, int socket) { Header header; int rc; char *buf = malloc(2); char *ptr = buf; FUNC_ENTRY; header.byte = 0; header.bits.type = type; header.bits.dup = dup; writeInt(&ptr, msgid); if ((rc = MQTTPacket_send(socket, header, buf, 2)) != TCPSOCKET_INTERRUPTED) free(buf); FUNC_EXIT_RC(rc); return rc; }
/** * Send an MQTT subscribe packet down a socket. * @param topics list of topics * @param qoss list of corresponding QoSs * @param msgid the MQTT message id to use * @param dup boolean - whether to set the MQTT DUP flag * @param socket the open socket to send the data to * @param clientID the string client identifier, only used for tracing * @return the completion code (e.g. TCPSOCKET_COMPLETE) */ int MQTTPacket_send_subscribe(List* topics, List* qoss, uint64_t msgid, int dup, networkHandles* net, const char* clientID) { Header header; char *data, *ptr; int rc = -1; ListElement *elem = NULL, *qosElem = NULL; int datalen; int mqtt_version = get_client_mqtt_version_from_network_handler(net); FUNC_ENTRY; header.bits.type = SUBSCRIBE; header.bits.dup = dup; header.bits.qos = 1; header.bits.retain = 0; //8 -> 64 bit msg id. if the msgid is 2 Byte, datalen will be decresed datalen = 8 + topics->count * 3; // utf length + char qos == 3 while (ListNextElement(topics, &elem)) datalen += strlen((char*)(elem->content)); ptr = data = malloc(datalen); if(mqtt_version == MQTTVERSION_YUNBA_3_1) { writeInt64(&ptr, msgid); }else{ msgid = (int)msgid; writeInt(&ptr, msgid); //make sure the datalen is adjusted datalen -= 6; } elem = NULL; while (ListNextElement(topics, &elem)) { ListNextElement(qoss, &qosElem); writeUTF(&ptr, (char*)(elem->content)); writeChar(&ptr, *(int*)(qosElem->content)); } rc = MQTTPacket_send(net, header, data, datalen, 1); Log(LOG_PROTOCOL, 22, NULL, net->socket, clientID, msgid, rc); if (rc != TCPSOCKET_INTERRUPTED) free(data); FUNC_EXIT_RC(rc); return rc; }
/** * Send an MQTT acknowledgement packet down a socket. * @param type the MQTT packet type e.g. SUBACK * @param msgid the MQTT message id to use * @param dup boolean - whether to set the MQTT DUP flag * @param net the network handle to send the data to * @return the completion code (e.g. TCPSOCKET_COMPLETE) */ static int MQTTPacket_send_ack(int type, int msgid, int dup, networkHandles *net) { Header header; int rc; char *buf = malloc(2); char *ptr = buf; FUNC_ENTRY; header.byte = 0; header.bits.type = type; header.bits.dup = dup; if (type == PUBREL) header.bits.qos = 1; writeInt(&ptr, msgid); if ((rc = MQTTPacket_send(net, header, buf, 2, 1)) != TCPSOCKET_INTERRUPTED) free(buf); FUNC_EXIT_RC(rc); return rc; }
/** * Send an MQTT unsubscribe packet down a socket. * @param topics list of topics * @param msgid the MQTT message id to use * @param dup boolean - whether to set the MQTT DUP flag * @param socket the open socket to send the data to * @param clientID the string client identifier, only used for tracing * @return the completion code (e.g. TCPSOCKET_COMPLETE) */ int MQTTPacket_send_unsubscribe(List* topics, uint64_t msgid, int dup, networkHandles* net, const char* clientID) { Header header; char *data, *ptr; int rc = -1; ListElement *elem = NULL; int datalen; int mqtt_version = get_client_mqtt_version_from_network_handler(net); FUNC_ENTRY; header.bits.type = UNSUBSCRIBE; header.bits.dup = dup; header.bits.qos = 1; header.bits.retain = 0; datalen = 8 + topics->count * 2; // utf length == 2 while (ListNextElement(topics, &elem)) datalen += strlen((char*)(elem->content)); ptr = data = malloc(datalen); if(MQTTVERSION_YUNBA_3_1 == mqtt_version) { writeInt64(&ptr, msgid); }else{ writeInt(&ptr, msgid); datalen -= 6; } elem = NULL; while (ListNextElement(topics, &elem)) writeUTF(&ptr, (char*)(elem->content)); rc = MQTTPacket_send(net, header, data, datalen, 1); Log(LOG_PROTOCOL, 25, NULL, net->socket, clientID, msgid, rc); if (rc != TCPSOCKET_INTERRUPTED) free(data); FUNC_EXIT_RC(rc); return rc; }
/** * Send an MQTT CONNECT packet down a socket. * @param client a structure from which to get all the required values * @return the completion code (e.g. TCPSOCKET_COMPLETE) */ int MQTTPacket_send_connect(Clients* client) { char *buf, *ptr; Connect packet; int rc, len; FUNC_ENTRY; packet.header.byte = 0; packet.header.bits.type = CONNECT; packet.header.bits.qos = 1; len = 12 + strlen(client->clientID)+2; if (client->will) len += strlen(client->will->topic)+2 + strlen(client->will->msg)+2; if (client->username) len += strlen(client->username)+2; if (client->password) len += strlen(client->password)+2; ptr = buf = malloc(len); writeUTF(&ptr, "MQIsdp"); if (client->noLocal) writeChar(&ptr, (char)-125); else writeChar(&ptr, (char)3); packet.flags.all = 0; packet.flags.bits.cleanstart = client->cleansession; packet.flags.bits.will = (client->will) ? 1 : 0; if (packet.flags.bits.will) { packet.flags.bits.willQoS = client->will->qos; packet.flags.bits.willRetain = client->will->retained; } if (client->username) packet.flags.bits.username = 1; if (client->password) packet.flags.bits.password = 1; writeChar(&ptr, packet.flags.all); writeInt(&ptr, client->keepAliveInterval); writeUTF(&ptr, client->clientID); if (client->will) { writeUTF(&ptr, client->will->topic); writeUTF(&ptr, client->will->msg); } if (client->username) writeUTF(&ptr, client->username); if (client->password) writeUTF(&ptr, client->password); rc = MQTTPacket_send(client->socket, packet.header, buf, len); Log(LOG_PROTOCOL, 0, NULL, client->socket, client->clientID, client->cleansession, client->noLocal, rc); free(buf); if (rc == TCPSOCKET_COMPLETE) time(&(client->lastContact)); FUNC_EXIT_RC(rc); return rc; }
/** * Send an MQTT CONNECT packet down a socket. * @param client a structure from which to get all the required values * @param MQTTVersion the MQTT version to connect with * @return the completion code (e.g. TCPSOCKET_COMPLETE) */ int MQTTPacket_send_connect(Clients* client, int MQTTVersion) { char *buf, *ptr; Connect packet; int rc = -1, len; FUNC_ENTRY; packet.header.byte = 0; packet.header.bits.type = CONNECT; packet.header.bits.qos = 1; len = ((MQTTVersion == 3 || MQTTVersion == MQTTVERSION_YUNBA_3_1) ? 12 : 10) + strlen(client->clientID)+2; if (client->will) len += strlen(client->will->topic)+2 + strlen(client->will->msg)+2; if (client->username) len += strlen(client->username)+2; if (client->password) len += strlen(client->password)+2; ptr = buf = malloc(len); if(MQTTVersion == 3 || MQTTVersion == MQTTVERSION_YUNBA_3_1) { writeUTF(&ptr, "MQIsdp"); }else { writeUTF(&ptr, "MQTT"); } writeChar(&ptr, (char)MQTTVersion); packet.flags.all = 0; packet.flags.bits.cleanstart = client->cleansession; packet.flags.bits.will = (client->will) ? 1 : 0; if (packet.flags.bits.will) { packet.flags.bits.willQoS = client->will->qos; packet.flags.bits.willRetain = client->will->retained; } if (client->username) packet.flags.bits.username = 1; if (client->password) packet.flags.bits.password = 1; writeChar(&ptr, packet.flags.all); writeInt(&ptr, client->keepAliveInterval); writeUTF(&ptr, client->clientID); if (client->will) { writeUTF(&ptr, client->will->topic); writeUTF(&ptr, client->will->msg); } if (client->username) writeUTF(&ptr, client->username); if (client->password) writeUTF(&ptr, client->password); rc = MQTTPacket_send(&client->net, packet.header, buf, len, 1); Log(LOG_PROTOCOL, 0, NULL, client->net.socket, client->clientID, client->cleansession, rc); exit: if (rc != TCPSOCKET_INTERRUPTED) free(buf); FUNC_EXIT_RC(rc); return rc; }