int MQTTPublish(Client* c, const char* topicName, MQTTMessage* message) { int rc = FAILURE; Timer timer; MQTTString topic = MQTTString_initializer; topic.cstring = (char *)topicName; int len = 0; InitTimer(&timer); countdown_ms(&timer, c->command_timeout_ms); if (!c->isconnected) goto exit; if (message->qos == QOS1 || message->qos == QOS2) message->id = getNextPacketId(c); len = MQTTSerialize_publish(c->buf, c->buf_size, 0, message->qos, message->retained, message->id, topic, (unsigned char*)message->payload, message->payloadlen); if (len <= 0) goto exit; if ((rc = sendPacket(c, len, &timer)) != SUCCESS) // send the publish packet goto exit; // there was a problem if (message->qos == QOS1) { if (waitfor(c, PUBACK, &timer) == PUBACK) { unsigned short mypacketid; unsigned char dup, type; if (MQTTDeserialize_ack(&type, &dup, &mypacketid, c->readbuf, c->readbuf_size) != 1) rc = FAILURE; } else rc = FAILURE; } else if (message->qos == QOS2) { if (waitfor(c, PUBCOMP, &timer) == PUBCOMP) { unsigned short mypacketid; unsigned char dup, type; if (MQTTDeserialize_ack(&type, &dup, &mypacketid, c->readbuf, c->readbuf_size) != 1) rc = FAILURE; } else rc = FAILURE; } exit: DeInitTimer(&timer); //STM: added this line return rc; }
int MQTTPublish(MQTTClient* c, const char* topicName, MQTTMessage* message) { int rc = FAILURE; Timer timer; MQTTString topic = MQTTString_initializer; topic.cstring = (char *)topicName; int len = 0; #if defined(MQTT_TASK) FreeRTOS_MutexLock(&c->mutex); #endif if (!c->isconnected) goto exit; TimerInit(&timer); TimerCountdownMS(&timer, c->command_timeout_ms); if (message->qos == QOS1 || message->qos == QOS2) message->id = getNextPacketId(c); len = MQTTSerialize_publish(c->buf, c->buf_size, 0, message->qos, message->retained, message->id, topic, (unsigned char*)message->payload, message->payloadlen); if (len <= 0) goto exit; if ((rc = sendPacket(c, len, &timer)) != SUCCESS) // send the subscribe packet goto exit; // there was a problem if (message->qos == QOS1) { if (waitfor(c, PUBACK, &timer) == PUBACK) { unsigned short mypacketid; unsigned char dup, type; if (MQTTDeserialize_ack(&type, &dup, &mypacketid, c->readbuf, c->readbuf_size) != 1) rc = FAILURE; } else rc = FAILURE; } else if (message->qos == QOS2) { if (waitfor(c, PUBCOMP, &timer) == PUBCOMP) { unsigned short mypacketid; unsigned char dup, type; if (MQTTDeserialize_ack(&type, &dup, &mypacketid, c->readbuf, c->readbuf_size) != 1) rc = FAILURE; } else rc = FAILURE; } exit: #if defined(MQTT_TASK) FreeRTOS_MutexUnlock(&c->mutex); #endif return rc; }
int mqtt_publish(mqtt_client_t *c, char* topicstr, mqtt_msg_t *msg) { int rc = -1; MQTTString topic = MQTTString_initializer; int len; int pktype; topic.cstring = topicstr; len = MQTTSerialize_publish(c->wbuf, c->wbuflen, msg->dup, msg->qos, msg->retained, msg->id, topic, msg->payload, msg->payloadlen); if (len <= 0) goto exit; if ((rc = mqtt_write(c->sockfd, c->wbuf, len)) <= 0) goto exit; pktype = MQTTPacket_read(c->rbuf, c->rbuflen, c->getfn); if (msg->qos == 1) { if (pktype == PUBACK) { unsigned short mypacketid; unsigned char dup, type; if (MQTTDeserialize_ack(&type, &dup, &mypacketid, c->rbuf, c->rbuflen) != 1) rc = -1; } else rc = -1; } else if (msg->qos == 2) { if (pktype == PUBCOMP) { unsigned short mypacketid; unsigned char dup, type; if (MQTTDeserialize_ack(&type, &dup, &mypacketid, c->rbuf, c->rbuflen) != 1) rc = -1; } else rc = -1; } exit: return rc; }
static int mqttClient_processPubAck(mqttClient_t* clientData) { int32_t rc = LE_OK; uint16_t packetId; uint8_t dup; uint8_t type; LE_DEBUG("---> UNSUBACK"); LE_ASSERT(clientData); rc = le_timer_Stop(clientData->session.cmdTimer); if (rc) { LE_ERROR("le_timer_Stop() failed(%d)", rc); goto cleanup; } rc = MQTTDeserialize_ack(&type, &dup, &packetId, clientData->session.rx.buf, sizeof(clientData->session.rx.buf)); if (rc != 1) { LE_ERROR("MQTTDeserialize_ack() failed"); rc = LE_BAD_PARAMETER; goto cleanup; } else if (clientData->session.nextPacketId != packetId) { LE_ERROR("invalid packet ID(%u != %u)", clientData->session.nextPacketId, packetId); rc = LE_BAD_PARAMETER; goto cleanup; } cleanup: return rc; }
/** * Deserializes the supplied (wire) buffer into unsuback data * @param packetid returned integer - the MQTT packet identifier * @param buf the raw buffer data, of the correct length determined by the remaining length field * @param buflen the length in bytes of the data in the supplied buffer * @return error code. 1 is success, 0 is failure */ int ICACHE_FLASH_ATTR MQTTDeserialize_unsuback(unsigned short* packetid, unsigned char* buf, int buflen) { unsigned char type = 0; unsigned char dup = 0; int rc = 0; FUNC_ENTRY; rc = MQTTDeserialize_ack(&type, &dup, packetid, buf, buflen); if (type == UNSUBACK) rc = 1; FUNC_EXIT_RC(rc); return rc; }
static int mqttClient_processPubRec(mqttClient_t* clientData) { int32_t rc = LE_OK; uint16_t packetId; uint8_t dup; uint8_t type; LE_DEBUG("---> PUBREC"); LE_ASSERT(clientData); if (MQTTDeserialize_ack(&type, &dup, &packetId, clientData->session.rx.buf, sizeof(clientData->session.rx.buf)) != 1) { LE_ERROR("MQTTDeserialize_ack() failed"); rc = LE_BAD_PARAMETER; goto cleanup; } else if (clientData->session.nextPacketId != packetId) { LE_ERROR("invalid packet ID(%u != %u)", clientData->session.nextPacketId, packetId); rc = LE_BAD_PARAMETER; goto cleanup; } int len = MQTTSerialize_ack(clientData->session.tx.buf, sizeof(clientData->session.tx.buf), PUBREL, 0, packetId); if (len <= 0) { LE_ERROR("MQTTSerialize_ack() failed(%d)", len); rc = LE_BAD_PARAMETER; goto cleanup; } LE_DEBUG("<--- PUBREL"); rc = mqttClient_write(clientData, len); if (rc) { LE_ERROR("mqttClient_write() failed(%d)", rc); goto cleanup; } cleanup: return rc; }
char* MQTTFormat_toServerString(char* strbuf, int strbuflen, unsigned char* buf, int buflen) { int index = 0; int rem_length = 0; MQTTHeader header = {0}; int strindex = 0; header.byte = buf[index++]; index += MQTTPacket_decodeBuf(&buf[index], &rem_length); switch (header.bits.type) { case CONNECT: { MQTTPacket_connectData data; int rc; if ((rc = MQTTDeserialize_connect(&data, buf, buflen)) == 1) strindex = MQTTStringFormat_connect(strbuf, strbuflen, &data); } break; case PUBLISH: { unsigned char dup, retained, *payload; uint64_t packetid; int qos, payloadlen; MQTTString topicName = MQTTString_initializer; if (MQTTDeserialize_publish(&dup, &qos, &retained, &packetid, &topicName, &payload, &payloadlen, buf, buflen) == 1) strindex = MQTTStringFormat_publish(strbuf, strbuflen, dup, qos, retained, packetid, topicName, payload, payloadlen); } break; case PUBACK: case PUBREC: case PUBREL: case PUBCOMP: { unsigned char packettype, dup; uint64_t packetid; if (MQTTDeserialize_ack(&packettype, &dup, &packetid, buf, buflen) == 1) strindex = MQTTStringFormat_ack(strbuf, strbuflen, packettype, dup, packetid); } break; case SUBSCRIBE: { unsigned char dup; uint64_t packetid; int maxcount = 1, count = 0; MQTTString topicFilters[1]; int requestedQoSs[1]; if (MQTTDeserialize_subscribe(&dup, &packetid, maxcount, &count, topicFilters, requestedQoSs, buf, buflen) == 1) strindex = MQTTStringFormat_subscribe(strbuf, strbuflen, dup, packetid, count, topicFilters, requestedQoSs);; } break; case UNSUBSCRIBE: { unsigned char dup; uint64_t packetid; int maxcount = 1, count = 0; MQTTString topicFilters[1]; if (MQTTDeserialize_unsubscribe(&dup, &packetid, maxcount, &count, topicFilters, buf, buflen) == 1) strindex = MQTTStringFormat_unsubscribe(strbuf, strbuflen, dup, packetid, count, topicFilters); } break; case PINGREQ: case PINGRESP: case DISCONNECT: strindex = snprintf(strbuf, strbuflen, "%s", MQTTPacket_names[header.bits.type]); break; } strbuf[strbuflen] = '\0'; return strbuf; }
char* MQTTFormat_toClientString(char* strbuf, int strbuflen, unsigned char* buf, int buflen) { int index = 0; int rem_length = 0; MQTTHeader header = {0}; int strindex = 0; header.byte = buf[index++]; index += MQTTPacket_decodeBuf(&buf[index], &rem_length); switch (header.bits.type) { case CONNACK: { unsigned char sessionPresent, connack_rc; if (MQTTDeserialize_connack(&sessionPresent, &connack_rc, buf, buflen) == 1) strindex = MQTTStringFormat_connack(strbuf, strbuflen, connack_rc, sessionPresent); } break; case PUBLISH: { unsigned char dup, retained, *payload; uint64_t packetid; int qos, payloadlen; MQTTString topicName = MQTTString_initializer; if (MQTTDeserialize_publish(&dup, &qos, &retained, &packetid, &topicName, &payload, &payloadlen, buf, buflen) == 1) strindex = MQTTStringFormat_publish(strbuf, strbuflen, dup, qos, retained, packetid, topicName, payload, payloadlen); } break; case PUBACK: case PUBREC: case PUBREL: case PUBCOMP: { unsigned char packettype, dup; uint64_t packetid; if (MQTTDeserialize_ack(&packettype, &dup, &packetid, buf, buflen) == 1) strindex = MQTTStringFormat_ack(strbuf, strbuflen, packettype, dup, packetid); } break; case SUBACK: { uint64_t packetid; int maxcount = 1, count = 0; int grantedQoSs[1]; if (MQTTDeserialize_suback(&packetid, maxcount, &count, grantedQoSs, buf, buflen) == 1) strindex = MQTTStringFormat_suback(strbuf, strbuflen, packetid, count, grantedQoSs); } break; case UNSUBACK: { uint64_t packetid; if (MQTTDeserialize_unsuback(&packetid, buf, buflen) == 1) strindex = MQTTStringFormat_ack(strbuf, strbuflen, UNSUBACK, 0, packetid); } break; case PINGREQ: case PINGRESP: case DISCONNECT: strindex = snprintf(strbuf, strbuflen, "%s", MQTTPacket_names[header.bits.type]); break; } return strbuf; }
int cycle(Client* c, Timer* timer) { // read the socket, see what work is due unsigned short packet_type = readPacket(c, timer); int len = 0, rc = SUCCESS; switch (packet_type) { case CONNACK: case PUBACK: case SUBACK: break; case PUBLISH: { MQTTString topicName; MQTTMessage msg; if (MQTTDeserialize_publish((unsigned char*)&msg.dup, (int*)&msg.qos, (unsigned char*)&msg.retained, (unsigned short*)&msg.id, &topicName, (unsigned char**)&msg.payload, (int*)&msg.payloadlen, c->readbuf, c->readbuf_size) != 1) goto exit; deliverMessage(c, &topicName, &msg); if (msg.qos != QOS0) { if (msg.qos == QOS1) len = MQTTSerialize_ack(c->buf, c->buf_size, PUBACK, 0, msg.id); else if (msg.qos == QOS2) len = MQTTSerialize_ack(c->buf, c->buf_size, PUBREC, 0, msg.id); if (len <= 0) rc = FAILURE; else rc = sendPacket(c, len, timer); if (rc == FAILURE) goto exit; // there was a problem } break; } case PUBREC: { unsigned short mypacketid; unsigned char dup, type; if (MQTTDeserialize_ack(&type, &dup, &mypacketid, c->readbuf, c->readbuf_size) != 1) rc = FAILURE; else if ((len = MQTTSerialize_ack(c->buf, c->buf_size, PUBREL, 0, mypacketid)) <= 0) rc = FAILURE; else if ((rc = sendPacket(c, len, timer)) != SUCCESS) // send the PUBREL packet rc = FAILURE; // there was a problem if (rc == FAILURE) goto exit; // there was a problem break; } case PUBCOMP: break; case PINGRESP: { INFO("<--PINGRESP"); c->ping_outstanding = 0; countdown(&c->ping_timer, c->keepAliveInterval); break; } } rc = keepalive(c); exit: if (rc == SUCCESS) rc = packet_type; return rc; }
int cycle(MQTTClient *c, Timer *timer) { int len = 0, rc = SUCCESS; int packet_type = readPacket(c, timer); /* read the socket, see what work is due */ switch (packet_type) { default: /* no more data to read, unrecoverable. Or read packet fails due to unexpected network error */ rc = packet_type; goto exit; case 0: /* timed out reading packet */ break; case CONNACK: case PUBACK: case SUBACK: case UNSUBACK: break; case PUBLISH: { MQTTString topicName; MQTTMessage msg; int intQoS; msg.payloadlen = 0; /* this is a size_t, but deserialize publish sets this as int */ if (MQTTDeserialize_publish(&msg.dup, &intQoS, &msg.retained, &msg.id, &topicName, (unsigned char **)&msg.payload, (int *)&msg.payloadlen, c->readbuf, c->readbuf_size) != 1) { goto exit; } msg.qos = (enum QoS)intQoS; deliverMessage(c, &topicName, &msg); if (msg.qos != QOS0) { if (msg.qos == QOS1) { len = MQTTSerialize_ack(c->buf, c->buf_size, PUBACK, 0, msg.id); } else if (msg.qos == QOS2) { len = MQTTSerialize_ack(c->buf, c->buf_size, PUBREC, 0, msg.id); } if (len <= 0) { rc = FAILURE; } else { rc = sendPacket(c, len, timer); } if (rc == FAILURE) { goto exit; // there was a problem } } break; } case PUBREC: case PUBREL: { unsigned short mypacketid; unsigned char dup, type; if (MQTTDeserialize_ack(&type, &dup, &mypacketid, c->readbuf, c->readbuf_size) != 1) { rc = FAILURE; } else if ((len = MQTTSerialize_ack(c->buf, c->buf_size, (packet_type == PUBREC) ? PUBREL : PUBCOMP, 0, mypacketid)) <= 0) { rc = FAILURE; } else if ((rc = sendPacket(c, len, timer)) != SUCCESS) { // send the PUBREL packet rc = FAILURE; // there was a problem } if (rc == FAILURE) { goto exit; // there was a problem } break; } case PUBCOMP: break; case PINGRESP: c->ping_outstanding = 0; break; } if (keepalive(c) != SUCCESS) { //check only keepalive FAILURE status so that previous FAILURE status can be considered as FAULT rc = FAILURE; } exit: if (rc == SUCCESS) { rc = packet_type; } else if (c->isconnected) { MQTTCloseSession(c); } return rc; }
int cycle( Client* c, Timer* timer ) { // read the socket, see what work is due unsigned short packet_type = readPacket( c, timer ); int len = 0; int rc = MQTT_SUCCESS; WPRINT_APP_INFO( ("Packet Type %d\n", packet_type) ); switch ( packet_type ) { case CONNACK: case PUBACK: case SUBACK: break; case PUBLISH: { MQTTString topicName; MQTTMessage msg; if ( MQTTDeserialize_publish( (unsigned char*) &msg.dup, (int*) &msg.qos, (unsigned char*) &msg.retained, (unsigned short*) &msg.id, &topicName, (unsigned char**) &msg.payload, (int*) &msg.payloadlen, c->readbuf, c->readbuf_size ) != 1 ) { goto exit; } deliverMessage( c, &topicName, &msg ); if ( msg.qos != QOS0 ) { if ( msg.qos == QOS1 ) { len = MQTTSerialize_ack( c->buf, c->buf_size, PUBACK, 0, msg.id ); } else if ( msg.qos == QOS2 ) { len = MQTTSerialize_ack( c->buf, c->buf_size, PUBREC, 0, msg.id ); } if ( len <= 0 ) { rc = MQTT_FAILURE; } else { rc = sendPacket( c, len, timer ); } if ( rc == MQTT_FAILURE ) { goto exit; // there was a problem } } break; } case PUBREC: { unsigned short mypacketid; unsigned char dup, type; if ( MQTTDeserialize_ack( &type, &dup, &mypacketid, c->readbuf, c->readbuf_size ) != 1 ) { rc = MQTT_FAILURE; } else if ( ( len = MQTTSerialize_ack( c->buf, c->buf_size, PUBREL, 0, mypacketid ) ) <= 0 ) { rc = MQTT_FAILURE; } else if ( ( rc = sendPacket( c, len, timer ) ) != MQTT_SUCCESS ) // send the PUBREL packet { rc = MQTT_FAILURE; // there was a problem } if ( rc == MQTT_FAILURE ) { goto exit; // there was a problem } break; } case PUBCOMP: break; case PINGRESP: c->ping_outstanding = 0; break; } keepalive( c ); exit: if ( rc == MQTT_SUCCESS ) { rc = packet_type; } return rc; }
int cycle(Client* c, Timer* timer) { // read the socket, see what work is due int read_status; unsigned short packet_type; read_status = readPacket(c, timer); packet_type = (unsigned short )read_status; if(read_status == SOCKET_CLOSED) { MQTTReConnect(c); goto exit; } int len = 0, rc = SUCCESS; switch (packet_type) { case CONNACK: { { unsigned char connack_rc = 255; char sessionPresent = 0; if (MQTTDeserialize_connack((unsigned char*)&sessionPresent, &connack_rc, c->readbuf, c->readbuf_size) == 1) { c->isconnected = 1; //开cloud灯 system(SET_LIGHT_CLOUD); log_printf(LOG_NOTICE, "[MqttConnected]: recv connack\n"); //subtopics and pubtopics init sprintf(&subtopics[0][0], "%s%s", SUBTOPIC_PRE1, gateway_info.did); sprintf(&subtopics[1][0], "%s%s", SUBTOPIC_PRE2, gateway_info.productkey); sprintf(&subtopics[2][0], "%s%s/#", SUBTOPIC_PRE3, gateway_info.did); sprintf(&pubtopics[0][0], "%s%s", PUBTOPIC_PRE1, gateway_info.did); sprintf(&pubtopics[1][0], "%s%s", PUBTOPIC_PRE2, gateway_info.did); sprintf(&pubtopics[2][0], "%s%s/#", PUBTOPIC_PRE3, gateway_info.did); rc = MQTTSubscribe(c, subtopics[c->suborder], 0, mh[c->suborder]); //for test log_printf(LOG_NOTICE, "Subscribing to %s\n", subtopics[c->suborder]); c->suborder++; } } } break; case PUBACK: break; case SUBACK: { int count = 0, grantedQoS = -1; unsigned short mypacketid; if (MQTTDeserialize_suback(&mypacketid, 1, &count, &grantedQoS, c->readbuf, c->readbuf_size) == 1) rc = grantedQoS; // 0, 1, 2 or 0x80 if (rc != 0x80) { if(c->suborder <subscribe_over) { rc = MQTTSubscribe(c, subtopics[c->suborder], 0, mh[c->suborder]); log_printf(LOG_NOTICE, "Subscribing to %s\n",subtopics[c->suborder]); c->suborder++; } // int i; // for (i = 0; i < MAX_MESSAGE_HANDLERS; ++i) // { // if (c->messageHandlers[i].topicFilter == 0) // { // c->messageHandlers[i].topicFilter = mytopics[i]; // c->messageHandlers[i].fp = mh[i]; // rc = 0; // break; // } // } } else { log_printf(LOG_ERROR, "SUCACK FAILED\n"); //TODO: error handle } } break; case PUBLISH: { if(c->suborder != subscribe_over) { log_printf(LOG_ERROR, "[REC_MSG] rece publish msg but subcribe not over\n"); //TODO: error } MQTTString topicName = MQTTString_initializer; MQTTMessage msg; if (MQTTDeserialize_publish((unsigned char*)&msg.dup, (int*)&msg.qos, (unsigned char*)&msg.retained, (unsigned short*)&msg.id, &topicName, (unsigned char**)&msg.payload, (int*)&msg.payloadlen, c->readbuf, c->readbuf_size) != 1) goto exit; deliverMessage(c, &topicName, &msg); // MQTTPublish(c, "applerespond", &msg); //add by yaly for test if (msg.qos != QOS0) { if (msg.qos == QOS1) len = MQTTSerialize_ack(c->buf, c->buf_size, PUBACK, 0, msg.id); else if (msg.qos == QOS2) len = MQTTSerialize_ack(c->buf, c->buf_size, PUBREC, 0, msg.id); if (len <= 0) rc = FAILURE; else rc = sendPacket_ev(c, len); if (rc == FAILURE) goto exit; } } break; case PUBREC: { unsigned short mypacketid; unsigned char dup, type; if (MQTTDeserialize_ack(&type, &dup, &mypacketid, c->readbuf, c->readbuf_size) != 1) rc = FAILURE; else if ((len = MQTTSerialize_ack(c->buf, c->buf_size, PUBREL, 0, mypacketid)) <= 0) rc = FAILURE; else if ((rc = sendPacket_ev(c, len)) != SUCCESS) // send the PUBREL packet rc = FAILURE; if (rc == FAILURE) goto exit; break; } break; case PUBCOMP: break; case PINGRESP: log_printf(LOG_NOTICE, "[MqttPingResp]\n"); c->ping_outstanding = 0; break; } // keepalive(c); //modify by yanly exit: if (rc == SUCCESS) rc = packet_type; return rc; }
/* success -> return packet type fail-> return FAIL */ int cycle(MQTTClient* c, Timer* timer) { int packet_type = readPacket(c, timer); int len = 0; int rc = SUCCESS; if (FAILURE == packet_type) { packet_type = NOPACKET; goto exit; } printf("received %s\n", MQTTPacket_names[packet_type]); switch (packet_type) { case CONNACK: case PUBACK: case SUBACK: break; case PUBLISH: { MQTTString topicName; MQTTMessage msg; int intQoS; if (MQTTDeserialize_publish(&msg.dup, &intQoS, &msg.retained, &msg.id, &topicName, (unsigned char**)&msg.payload, (int*)&msg.payloadlen, c->readbuf, c->readbuf_size) != 1) goto exit; msg.qos = (enum QoS)intQoS; //deliverMessage(c, &topicName, &msg); if (msg.qos != QOS0) { if (msg.qos == QOS1) len = MQTTSerialize_ack(c->buf, c->buf_size, PUBACK, 0, msg.id); else if (msg.qos == QOS2) len = MQTTSerialize_ack(c->buf, c->buf_size, PUBREC, 0, msg.id); if (len <= 0) rc = FAILURE; else rc = sendPacket(c, len, timer); if (rc == FAILURE) goto exit; // there was a problem } deliverMessage(c, &topicName, &msg); break; } case PUBREC: { unsigned short mypacketid; unsigned char dup, type; if (MQTTDeserialize_ack(&type, &dup, &mypacketid, c->readbuf, c->readbuf_size) != 1) rc = FAILURE; else if ((len = MQTTSerialize_ack(c->buf, c->buf_size, PUBREL, 0, mypacketid)) <= 0) rc = FAILURE; else if ((rc = sendPacket(c, len, timer)) != SUCCESS) // send the PUBREL packet rc = FAILURE; // there was a problem if (rc == FAILURE) goto exit; // there was a problem break; } case PUBCOMP: break; case PINGRESP: c->ping_outstanding = 0; //c->keepAliveFailCount = 0; break; case PUBREL: { unsigned short mypacketid; unsigned char dup, type; if (MQTTDeserialize_ack(&type, &dup, &mypacketid, c->readbuf, c->readbuf_size) != 1) rc = FAILURE; else if ((len = MQTTSerialize_ack(c->buf, c->buf_size, PUBCOMP, 0, mypacketid)) <= 0) rc = FAILURE; else if ((rc = sendPacket(c, len, timer)) != SUCCESS) // send the PUBCOMP packet rc = FAILURE; // there was a problem if (rc == FAILURE) goto exit; // there was a problem break; } } exit: if (FAILURE == keepalive(c)) { rc = FAILURE; } if (rc == SUCCESS) rc = packet_type; return rc; }
int MQTTPublish(MQTTClient* c, const char* topicName, MQTTMessage* message) { int rc = MQTT_FAILURE; Timer timer; MQTTString topic = MQTTString_initializer; topic.cstring = (char *)topicName; int len = 0; platform_mutex_lock(&c->mutex); if (!c->isconnected) goto exit; platform_timer_init(&timer); platform_timer_countdown(&timer, c->command_timeout_ms); if (message->qos == QOS1 || message->qos == QOS2) message->id = getNextPacketId(c); len = MQTTSerialize_publish(c->buf, c->buf_size, 0, message->qos, message->retained, message->id, topic, (unsigned char*)message->payload, message->payloadlen); if (len <= 0) goto exit; if ((rc = sendPacket(c, len, &timer)) != MQTT_SUCCESS) // send the subscribe packet { goto exit; // there was a problem } if (message->qos == QOS1) { if (waitfor(c, PUBACK, &timer) == PUBACK) { unsigned short mypacketid; unsigned char dup, type; if (MQTTDeserialize_ack(&type, &dup, &mypacketid, c->readbuf, c->readbuf_size) != 1) { platform_printf("failed to deserialize ACK\n"); rc = MQTT_FAILURE; } } else { rc = MQTT_CONNECTION_LOST; } } else if (message->qos == QOS2) { if (waitfor(c, PUBCOMP, &timer) == PUBCOMP) { unsigned short mypacketid; unsigned char dup, type; if (MQTTDeserialize_ack(&type, &dup, &mypacketid, c->readbuf, c->readbuf_size) != 1) rc = MQTT_FAILURE; } else { rc = MQTT_CONNECTION_LOST; } } exit: platform_mutex_unlock(&c->mutex); return rc; }
int cycle(MQTTClient* c, Timer* timer) { Timer t; platform_timer_init(&t); int len = 0, packet_type, rc = MQTT_SUCCESS; // read the socket, see what work is due if ((packet_type = readPacket(c, timer)) == MQTT_CONNECTION_LOST) { rc = MQTT_CONNECTION_LOST; goto exit; } switch (packet_type) { case CONNACK: case PUBACK: case SUBACK: break; case PUBLISH: { MQTTString topicName; MQTTMessage msg = {0}; int intQoS; if (MQTTDeserialize_publish(&msg.dup, &intQoS, &msg.retained, &msg.id, &topicName, (unsigned char**)&msg.payload, &msg.payloadlen, c->readbuf, c->readbuf_size) != 1) goto exit; msg.qos = (enum QoS)intQoS; deliverMessage(c, &topicName, &msg); if (msg.qos != QOS0) { if (msg.qos == QOS1) len = MQTTSerialize_ack(c->buf, c->buf_size, PUBACK, 0, msg.id); else if (msg.qos == QOS2) len = MQTTSerialize_ack(c->buf, c->buf_size, PUBREC, 0, msg.id); if (len <= 0) rc = MQTT_FAILURE; else { platform_timer_countdown(&t, c->command_timeout_ms); rc = sendPacket(c, len, &t); } if (rc == MQTT_FAILURE) goto exit; // there was a problem } break; } case PUBREC: { unsigned short mypacketid; unsigned char dup, type; platform_timer_countdown(&t, c->command_timeout_ms); if (MQTTDeserialize_ack(&type, &dup, &mypacketid, c->readbuf, c->readbuf_size) != 1) rc = MQTT_FAILURE; else if ((len = MQTTSerialize_ack(c->buf, c->buf_size, PUBREL, 0, mypacketid)) <= 0) rc = MQTT_FAILURE; else if ((rc = sendPacket(c, len, &t)) != MQTT_SUCCESS) // send the PUBREL packet rc = MQTT_FAILURE; // there was a problem if (rc == MQTT_FAILURE) goto exit; // there was a problem break; } case PUBCOMP: break; case PINGRESP: c->ping_outstanding = 0; platform_printf("received ping response\n"); break; } keepalive(c); if (c->ping_outstanding && platform_timer_isexpired(&c->pingresp_timer)) { c->ping_outstanding = 0; platform_printf("ping response was not received within keepalive timeout of %d\n", c->keepAliveInterval); rc = MQTT_CONNECTION_LOST; } exit: if (rc == MQTT_SUCCESS) rc = packet_type; return rc; }