int MQTTConnectWithResults(MQTTClient *c, MQTTPacket_connectData *options, MQTTConnackData *data) { Timer connect_timer; int rc = FAILURE; MQTTPacket_connectData default_options = MQTTPacket_connectData_initializer; int len = 0; #if defined(MQTT_TASK) MutexLock(&c->mutex); #endif if (c->isconnected) { /* don't send connect packet again if we are already connected */ goto exit; } TimerInit(&connect_timer); TimerCountdownMS(&connect_timer, c->command_timeout_ms); if (options == 0) { options = &default_options; /* set default options if none were supplied */ } c->keepAliveInterval = options->keepAliveInterval; c->cleansession = options->cleansession; TimerCountdown(&c->last_received, c->keepAliveInterval); if ((len = MQTTSerialize_connect(c->buf, c->buf_size, options)) <= 0) { goto exit; } if ((rc = sendPacket(c, len, &connect_timer)) != SUCCESS) { // send the connect packet goto exit; // there was a problem } // this will be a blocking call, wait for the connack if (waitfor(c, CONNACK, &connect_timer) == CONNACK) { data->rc = 0; data->sessionPresent = 0; if (MQTTDeserialize_connack(&data->sessionPresent, &data->rc, c->readbuf, c->readbuf_size) == 1) { rc = data->rc; } else { rc = FAILURE; } } else { rc = FAILURE; } exit: if (rc == SUCCESS) { c->isconnected = 1; c->ping_outstanding = 0; } #if defined(MQTT_TASK) MutexUnlock(&c->mutex); #endif return rc; }
int main(int argc, char *argv[]) { MQTTPacket_connectData data = MQTTPacket_connectData_initializer; int rc = 0; int mysock = 0; unsigned char buf[200]; int buflen = sizeof(buf); int msgid = 1; MQTTString topicString = MQTTString_initializer; int req_qos = 0; char* payload = "mypayload"; int payloadlen = strlen(payload); int len = 0; char *host = "m2m.eclipse.org"; int port = 1883; stop_init(); if (argc > 1) host = argv[1]; if (argc > 2) port = atoi(argv[2]); mysock = transport_open(host, port); if(mysock < 0) return mysock; printf("Sending to hostname %s port %d\n", host, port); data.clientID.cstring = "me"; data.keepAliveInterval = 20; data.cleansession = 1; data.username.cstring = "testuser"; data.password.cstring = "testpassword"; len = MQTTSerialize_connect(buf, buflen, &data); rc = transport_sendPacketBuffer(mysock, buf, len); /* wait for connack */ if (MQTTPacket_read(buf, buflen, transport_getdata) == CONNACK) { unsigned char sessionPresent, connack_rc; if (MQTTDeserialize_connack(&sessionPresent, &connack_rc, buf, buflen) != 1 || connack_rc != 0) { printf("Unable to connect, return code %d\n", connack_rc); goto exit; } } else goto exit; /* subscribe */ topicString.cstring = "substopic"; len = MQTTSerialize_subscribe(buf, buflen, 0, msgid, 1, &topicString, &req_qos); rc = transport_sendPacketBuffer(mysock, buf, len); if (MQTTPacket_read(buf, buflen, transport_getdata) == SUBACK) /* wait for suback */ { unsigned short submsgid; int subcount; int granted_qos; rc = MQTTDeserialize_suback(&submsgid, 1, &subcount, &granted_qos, buf, buflen); if (granted_qos != 0) { printf("granted qos != 0, %d\n", granted_qos); goto exit; } } else goto exit; /* loop getting msgs on subscribed topic */ topicString.cstring = "pubtopic"; while (!toStop) { /* transport_getdata() has a built-in 1 second timeout, your mileage will vary */ if (MQTTPacket_read(buf, buflen, transport_getdata) == PUBLISH) { unsigned char dup; int qos; unsigned char retained; unsigned short msgid; int payloadlen_in; unsigned char* payload_in; int rc; MQTTString receivedTopic; rc = MQTTDeserialize_publish(&dup, &qos, &retained, &msgid, &receivedTopic, &payload_in, &payloadlen_in, buf, buflen); printf("message arrived %.*s\n", payloadlen_in, payload_in); } printf("publishing reading\n"); len = MQTTSerialize_publish(buf, buflen, 0, 0, 0, 0, topicString, (unsigned char*)payload, payloadlen); rc = transport_sendPacketBuffer(mysock, buf, len); } printf("disconnecting\n"); len = MQTTSerialize_disconnect(buf, buflen); rc = transport_sendPacketBuffer(mysock, buf, len); exit: transport_close(mysock); return 0; }
int MQTTConnect( Client* c, MQTTPacket_connectData* options ) { Timer connect_timer; int rc = MQTT_FAILURE; MQTTPacket_connectData default_options = MQTTPacket_connectData_initializer; int len = 0; wiced_init_timer( &connect_timer ); wiced_countdown_ms( &connect_timer, c->command_timeout_ms ); if ( c->isconnected ) // don't send connect packet again if we are already connected { goto exit; } if ( options == 0 ) { options = &default_options; // set default options if none were supplied } c->keepAliveInterval = options->keepAliveInterval; wiced_countdown( &c->ping_timer, c->keepAliveInterval ); if ( ( len = MQTTSerialize_connect( c->buf, c->buf_size, options ) ) <= 0 ) { goto exit; } if ( ( rc = sendPacket( c, len, &connect_timer ) ) != MQTT_SUCCESS ) // send the connect packet { goto exit; // there was a problem } // this will be a blocking call, wait for the connack if ( waitfor( c, CONNACK, &connect_timer ) == CONNACK ) { unsigned char connack_rc = 255; char sessionPresent = 0; if ( MQTTDeserialize_connack( (unsigned char*) &sessionPresent, &connack_rc, c->readbuf, c->readbuf_size ) == 1 ) { rc = connack_rc; } else { rc = MQTT_FAILURE; } } else { rc = MQTT_FAILURE; } exit: if ( rc != MQTT_FAILURE ) { c->isconnected = 1; } 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; }