int MQTTConnect(MQTTClient* c, MQTTPacket_connectData* options) { Timer connect_timer; int rc = FAILURE; MQTTPacket_connectData default_options = MQTTPacket_connectData_initializer; int len = 0; #if defined(MQTT_TASK) FreeRTOS_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; TimerCountdown(&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)) != SUCCESS) goto exit; // this will be a blocking call, wait for the connack if (waitfor(c, CONNACK, &connect_timer) == CONNACK) { unsigned char connack_rc = 255; unsigned char sessionPresent = 0; if (MQTTDeserialize_connack(&sessionPresent, &connack_rc, c->readbuf, c->readbuf_size) == 1) rc = connack_rc; else rc = FAILURE; } else rc = FAILURE; exit: if (rc == SUCCESS) c->isconnected = 1; #if defined(MQTT_TASK) FreeRTOS_MutexUnlock(&c->mutex); #endif return rc; }
static int readPacket(MQTTClient *c, Timer *timer) { MQTTHeader header = {0}; int len = 0; int rem_len = 0; /* 1. read the header byte. This has the packet type in it */ int rc = c->ipstack->mqttread(c->ipstack, c->readbuf, 1, TimerLeftMS(timer)); if (rc != 1) { goto exit; } len = 1; /* 2. read the remaining length. This is variable in itself */ decodePacket(c, &rem_len, TimerLeftMS(timer)); len += MQTTPacket_encode(c->readbuf + 1, rem_len); /* put the original remaining length back into the buffer */ if (rem_len > (c->readbuf_size - len)) { rc = BUFFER_OVERFLOW; goto exit; } /* 3. read the rest of the buffer using a callback to supply the rest of the data */ if (rem_len > 0 && (rc = c->ipstack->mqttread(c->ipstack, c->readbuf + len, rem_len, TimerLeftMS(timer)) != rem_len)) { rc = 0; goto exit; } header.byte = c->readbuf[0]; rc = header.bits.type; if (c->keepAliveInterval > 0) { TimerCountdown(&c->last_received, c->keepAliveInterval); // record the fact that we have successfully received a packet } exit: return rc; }
static int sendPacket(MQTTClient *c, int length, Timer *timer) { int rc = FAILURE, sent = 0; while (sent < length && !TimerIsExpired(timer)) { rc = c->ipstack->mqttwrite(c->ipstack, &c->buf[sent], length, TimerLeftMS(timer)); if (rc < 0) { // there was an error writing the data break; } sent += rc; } if (sent == length) { TimerCountdown(&c->last_sent, c->keepAliveInterval); // record the fact that we have successfully sent the packet rc = SUCCESS; } else { rc = FAILURE; } return rc; }
int keepalive(MQTTClient* c) { int rc = SUCCESS; if (c->keepAliveInterval == 0) { rc = SUCCESS; goto exit; } if (TimerIsExpired(&c->ping_timer)) { printf("keep alive counter expired\n"); if (!c->ping_outstanding) { printf("keep alive counter reset\n"); //Set the pingreq send timeout Timer timer; TimerInit(&timer); TimerCountdownMS(&timer, 1000); int len = MQTTSerialize_pingreq(c->buf, c->buf_size); /* If the sendPacket success, the keep alive works with keepAliveInterval */ if (len > 0 && (rc = sendPacket(c, len, &timer)) == SUCCESS) {// send the ping packet c->ping_outstanding = 1; TimerCountdown(&c->ping_timer, c->keepAliveInterval); // record the fact that we have successfully sent the packet } else { rc = FAILURE; } } else { printf("keep alive counter failure\n"); rc = FAILURE; } } exit: return rc; }
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; }