int keepalive(MQTTClient *c) { int rc = SUCCESS; if (c->keepAliveInterval == 0) { goto exit; } if (TimerIsExpired(&c->last_sent) || TimerIsExpired(&c->last_received)) { if (c->ping_outstanding && TimerIsExpired(&c->ping_wait)) { rc = FAILURE; /* PINGRESP not received in keepalive interval */ } else { Timer timer; TimerInit(&timer); TimerCountdownMS(&timer, 1000); int len = MQTTSerialize_pingreq(c->buf, c->buf_size); if (len > 0 && (rc = sendPacket(c, len, &timer)) == SUCCESS) { // send the ping packet c->ping_outstanding = 1; TimerCountdownMS(&c->ping_wait, CONFIG_MQTT_PING_TIMEOUT); } } } exit: return rc; }
int MQTTDisconnect(MQTTClient *c) { int rc = FAILURE; Timer timer; // we might wait for incomplete incoming publishes to complete int len = 0; #if defined(MQTT_TASK) MutexLock(&c->mutex); #endif TimerInit(&timer); TimerCountdownMS(&timer, c->command_timeout_ms); len = MQTTSerialize_disconnect(c->buf, c->buf_size); if (len > 0) { rc = sendPacket(c, len, &timer); // send the disconnect packet } MQTTCloseSession(c); #if defined(MQTT_TASK) MutexUnlock(&c->mutex); #endif return rc; }
void MQTTRun(void *parm) { Timer timer; MQTTClient *c = (MQTTClient *)parm; TimerInit(&timer); while (1) { TimerCountdownMS(&timer, CONFIG_MQTT_RECV_CYCLE); /* Don't wait too long if no traffic is incoming */ #if CONFIG_MQTT_RECV_CYCLE == 0 /* The smaller cycle, the greater throughput */ esp_task_wdt_reset(); #endif #if defined(MQTT_TASK) MutexLock(&c->mutex); #endif int rc = cycle(c, &timer); if (rc == FAILURE) { ESP_LOGE(TAG, "MQTTRun cycle failed"); #if defined(MQTT_TASK) MutexUnlock(&c->mutex); #endif vTaskDelete(NULL); } #if defined(MQTT_TASK) MutexUnlock(&c->mutex); #endif } }
int MQTTUnsubscribe(MQTTClient* c, const char* topicFilter) { int rc = FAILURE; Timer timer; MQTTString topic = MQTTString_initializer; topic.cstring = (char *)topicFilter; 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 ((len = MQTTSerialize_unsubscribe(c->buf, c->buf_size, 0, getNextPacketId(c), 1, &topic)) <= 0) goto exit; if ((rc = sendPacket(c, len, &timer)) != SUCCESS) // send the subscribe packet goto exit; // there was a problem if (waitfor(c, UNSUBACK, &timer) == UNSUBACK) { unsigned short mypacketid; // should be the same as the packetid above if (MQTTDeserialize_unsuback(&mypacketid, c->readbuf, c->readbuf_size) == 1) rc = 0; } else rc = FAILURE; exit: #if defined(MQTT_TASK) FreeRTOS_MutexUnlock(&c->mutex); #endif return rc; }
int MQTTSubscribeWithResults(MQTTClient *c, const char *topicFilter, enum QoS qos, messageHandler messageHandler, MQTTSubackData *data) { int rc = FAILURE; Timer timer; int len = 0; MQTTString topic = MQTTString_initializer; topic.cstring = (char *)topicFilter; #if defined(MQTT_TASK) MutexLock(&c->mutex); #endif if (!c->isconnected) { goto exit; } TimerInit(&timer); TimerCountdownMS(&timer, c->command_timeout_ms); len = MQTTSerialize_subscribe(c->buf, c->buf_size, 0, getNextPacketId(c), 1, &topic, (int *)&qos); if (len <= 0) { goto exit; } if ((rc = sendPacket(c, len, &timer)) != SUCCESS) { // send the subscribe packet goto exit; // there was a problem } if (waitfor(c, SUBACK, &timer) == SUBACK) { // wait for suback int count = 0; unsigned short mypacketid; data->grantedQoS = QOS0; if (MQTTDeserialize_suback(&mypacketid, 1, &count, (int *)&data->grantedQoS, c->readbuf, c->readbuf_size) == 1) { if (data->grantedQoS != 0x80) { rc = MQTTSetMessageHandler(c, topicFilter, messageHandler); } } } else { rc = FAILURE; } exit: if (rc == FAILURE) { MQTTCloseSession(c); } #if defined(MQTT_TASK) MutexUnlock(&c->mutex); #endif 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 MQTTUnsubscribe(MQTTClient *c, const char *topicFilter) { int rc = FAILURE; Timer timer; MQTTString topic = MQTTString_initializer; topic.cstring = (char *)topicFilter; int len = 0; #if defined(MQTT_TASK) MutexLock(&c->mutex); #endif if (!c->isconnected) { goto exit; } TimerInit(&timer); TimerCountdownMS(&timer, c->command_timeout_ms); if ((len = MQTTSerialize_unsubscribe(c->buf, c->buf_size, 0, getNextPacketId(c), 1, &topic)) <= 0) { goto exit; } if ((rc = sendPacket(c, len, &timer)) != SUCCESS) { // send the subscribe packet goto exit; // there was a problem } if (waitfor(c, UNSUBACK, &timer) == UNSUBACK) { unsigned short mypacketid; // should be the same as the packetid above if (MQTTDeserialize_unsuback(&mypacketid, c->readbuf, c->readbuf_size) == 1) { /* remove the subscription message handler associated with this topic, if there is one */ MQTTSetMessageHandler(c, topicFilter, NULL); } } else { rc = FAILURE; } exit: if (rc == FAILURE) { MQTTCloseSession(c); } #if defined(MQTT_TASK) MutexUnlock(&c->mutex); #endif return rc; }
int MQTTSubscribe(MQTTClient* c, const char* topicFilter, enum QoS qos, messageHandler messageHandler) { int rc = FAILURE; Timer timer; int len = 0; MQTTString topic = MQTTString_initializer; topic.cstring = (char *)topicFilter; #if defined(MQTT_TASK) FreeRTOS_MutexLock(&c->mutex); #endif if (!c->isconnected) goto exit; TimerInit(&timer); TimerCountdownMS(&timer, c->command_timeout_ms); len = MQTTSerialize_subscribe(c->buf, c->buf_size, 0, getNextPacketId(c), 1, &topic, (int*)&qos); if (len <= 0) goto exit; if ((rc = sendPacket(c, len, &timer)) != SUCCESS) // send the subscribe packet goto exit; // there was a problem if (waitfor(c, SUBACK, &timer) == SUBACK) { // wait for 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) { int i; for (i = 0; i < MAX_MESSAGE_HANDLERS; ++i) { if (c->messageHandlers[i].topicFilter == 0) { c->messageHandlers[i].topicFilter = topicFilter; c->messageHandlers[i].fp = messageHandler; rc = 0; break; } } } } else rc = FAILURE; exit: #if defined(MQTT_TASK) FreeRTOS_MutexUnlock(&c->mutex); #endif return rc; }
int MQTTYield(MQTTClient *c, int timeout_ms) { int rc = SUCCESS; Timer timer; TimerInit(&timer); TimerCountdownMS(&timer, timeout_ms); do { if (cycle(c, &timer) < 0) { rc = FAILURE; break; } } while (!TimerIsExpired(&timer)); return rc; }
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; }
void MQTTRun(void* parm) { Timer timer; MQTTClient* c = (MQTTClient*)parm; TimerInit(&timer); while (1) { #if defined(MQTT_TASK) FreeRTOS_MutexLock(&c->mutex); #endif TimerCountdownMS(&timer, 500); /* Don't wait too long if no traffic is incoming */ cycle(c, &timer); #if defined(MQTT_TASK) FreeRTOS_MutexUnlock(&c->mutex); #endif } }
int MQTTYield(MQTTClient* c, int timeout_ms) { int rc = SUCCESS; Timer timer; TimerInit(&timer); #if defined(MQTT_TASK) FreeRTOS_MutexLock(&c->mutex); #endif TimerCountdownMS(&timer, timeout_ms); //printf("."); rc = cycle(c, &timer); #if defined(MQTT_TASK) FreeRTOS_MutexUnlock(&c->mutex); #endif sys_msleep(1); 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; }
void TimerCountdown(Timer* timer, uint32_t timeout) { TimerCountdownMS(timer, timeout * 1000); }
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; }