static int mqttClient_processPublish(mqttClient_t* clientData) { MQTTString topicName; mqttClient_msg_t msg; int len = 0; int32_t rc = LE_OK; LE_DEBUG("---> PUBLISH"); LE_ASSERT(clientData); 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, clientData->session.rx.buf, sizeof(clientData->session.rx.buf)) != 1) { LE_ERROR("MQTTDeserialize_publish() failed"); rc = LE_BAD_PARAMETER; goto cleanup; } if (msg.qos != MQTT_CLIENT_QOS0) { if (msg.qos == MQTT_CLIENT_QOS1) len = MQTTSerialize_ack(clientData->session.tx.buf, sizeof(clientData->session.tx.buf), PUBACK, 0, msg.id); else if (msg.qos == MQTT_CLIENT_QOS2) len = MQTTSerialize_ack(clientData->session.tx.buf, sizeof(clientData->session.tx.buf), PUBREC, 0, msg.id); if (len <= 0) { LE_ERROR("MQTTSerialize_ack() failed(%d)", len); rc = LE_BAD_PARAMETER; goto cleanup; } LE_DEBUG("<--- PUBACK"); rc = mqttClient_write(clientData, len); if (rc) { LE_ERROR("mqttClient_write() failed(%d)", rc); goto cleanup; } } rc = mqttClient_deliverMsg(clientData, &topicName, &msg); if (rc) { LE_ERROR("mqttClient_deliverMsg() failed(%d)", rc); goto cleanup; } cleanup: 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; }
/** * Serializes a pubrel packet into the supplied buffer. * @param buf the buffer into which the packet will be serialized * @param buflen the length in bytes of the supplied buffer * @param packetid integer - the MQTT packet identifier * @return serialized length, or error if 0 */ int MQTTSerialize_pubcomp(unsigned char* buf, int buflen, uint64_t packetid) { return MQTTSerialize_ack(buf, buflen, PUBCOMP, 0, packetid); }
/** * Serializes a pubrel packet into the supplied buffer. * @param buf the buffer into which the packet will be serialized * @param buflen the length in bytes of the supplied buffer * @param dup integer - the MQTT dup flag * @param packetid integer - the MQTT packet identifier * @return serialized length, or error if 0 */ int MQTTSerialize_pubrel(unsigned char* buf, int buflen, unsigned char dup, uint64_t packetid) { return MQTTSerialize_ack(buf, buflen, PUBREL, dup, packetid); }
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; }
/** * Serializes a puback packet into the supplied buffer. * @param buf the buffer into which the packet will be serialized * @param buflen the length in bytes of the supplied buffer * @param packetid integer - the MQTT packet identifier * @return serialized length, or error if 0 */ int MQTTSerialize_puback(unsigned char* buf, int buflen, unsigned short packetid) { return MQTTSerialize_ack(buf, buflen, PUBACK, 0, packetid); }
/** * Serializes a pubrel packet into the supplied buffer. * @param buf the buffer into which the packet will be serialized * @param buflen the length in bytes of the supplied buffer * @param packetid integer - the MQTT packet identifier * @return serialized length, or error if 0 */ int MQTTSerialize_pubcomp(unsigned char* buf, int buflen, unsigned short packetid) { return MQTTSerialize_ack(buf, buflen, PUBCOMP, packetid, 0); }
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; }
static void *mqtt_sub_thread(void *param) { MQTTPacket_connectData condata = MQTTPacket_connectData_initializer; int pktype, rc, len; int failcnt = 0; unsigned char wbuf[64]; unsigned char rbuf[64]; DEBUG("sub thread start\n"); _csub.wbuf = wbuf; _csub.wbuflen = sizeof(wbuf); _csub.rbuf = rbuf; _csub.rbuflen = sizeof(rbuf); _csub.getfn = sub_read; if ((_csub.sockfd = mqtt_netconnect(HOSTNAME, HOSTPORT)) < 0) { DEBUG("sub netconnect fail\n"); return 0; } DEBUG("sub connect to: %s %d\n", HOSTNAME, HOSTPORT); condata.clientID.cstring = "mqttsub"; condata.keepAliveInterval = KEEPALIVE_INTERVAL; condata.cleansession = 1; condata.username.cstring = USERNAME; condata.password.cstring = PASSWORD; rc = mqtt_connect(&_csub, &condata); if (rc < 0) goto exit; DEBUG("sub connect ok\n"); rc = mqtt_subscribe(&_csub, TOPIC, 0); if (rc < 0) goto exit; DEBUG("sub topic: %s\n", TOPIC); mqtt_ping_start(&_csub.sockfd); while (1) { pktype = MQTTPacket_read(_csub.rbuf, _csub.rbuflen, sub_read); switch (pktype) { case CONNACK: case PUBACK: case SUBACK: break; case PUBLISH: { MQTTString topic; mqtt_msg_t msg; if (MQTTDeserialize_publish(&msg.dup, &msg.qos, &msg.retained, &msg.id, &topic, &msg.payload, &msg.payloadlen, _csub.rbuf, _csub.rbuflen) != 1) goto exit; msgprocess(&topic, &msg); if (msg.qos != 0) { if (msg.qos == 1) len = MQTTSerialize_ack(_csub.wbuf, _csub.wbuflen, PUBACK, 0, msg.id); else if (msg.qos == 2) len = MQTTSerialize_ack(_csub.wbuf, _csub.wbuflen, PUBREC, 0, msg.id); if (len <= 0) rc = -1; else rc = mqtt_write(_csub.sockfd, _csub.wbuf, len); if (rc == -1) goto exit; } } break; case PUBCOMP: break; case PINGRESP: failcnt = 0; break; case -1: if (++failcnt > KEEPALIVE_INTERVAL) { /* */ goto exit; } break; } } /* */ mqtt_disconnect(&_csub); exit: mqtt_netdisconnect(&_csub.sockfd); DEBUG("sub thread exit\n"); return 0; }
/* 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 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; }