MQTT client keep alive fixes

- Move keep alive management up to the Mongoose library
 - Only outgoing control messgaes should reset keepalive timer
 - Add unit test

https://forum.mongoose-os.com/discussion/1155/mqtt-keep-alive-compliance-issue

PUBLISHED_FROM=f86e30744ded53a6f7f96afec066b4ff3b4372c0
This commit is contained in:
Deomid Ryabkov 2017-06-04 15:10:52 +01:00 committed by Cesanta Bot
parent e4309d472b
commit 023b55f2e5
3 changed files with 17 additions and 2 deletions

View File

@ -5,6 +5,7 @@ symbol_kind: "struct"
signature: | signature: |
struct mg_mqtt_proto_data { struct mg_mqtt_proto_data {
uint16_t keep_alive; uint16_t keep_alive;
double last_control_time;
}; };
--- ---

View File

@ -2079,7 +2079,7 @@ void mg_if_poll(struct mg_connection *nc, time_t now) {
} }
} }
static void mg_destroy_conn(struct mg_connection *conn, int destroy_if) { void mg_destroy_conn(struct mg_connection *conn, int destroy_if) {
if (destroy_if) conn->iface->vtable->destroy_conn(conn); if (destroy_if) conn->iface->vtable->destroy_conn(conn);
if (conn->proto_data != NULL && conn->proto_data_destructor != NULL) { if (conn->proto_data != NULL && conn->proto_data_destructor != NULL) {
conn->proto_data_destructor(conn->proto_data); conn->proto_data_destructor(conn->proto_data);
@ -9957,7 +9957,7 @@ static void mqtt_handler(struct mg_connection *nc, int ev,
nc->handler(nc, ev, ev_data MG_UD_ARG(user_data)); nc->handler(nc, ev, ev_data MG_UD_ARG(user_data));
switch (ev) { switch (ev) {
case MG_EV_RECV: case MG_EV_RECV: {
/* There can be multiple messages in the buffer, process them all. */ /* There can be multiple messages in the buffer, process them all. */
while (1) { while (1) {
int len = parse_mqtt(io, &mm); int len = parse_mqtt(io, &mm);
@ -9966,6 +9966,17 @@ static void mqtt_handler(struct mg_connection *nc, int ev,
mbuf_remove(io, len); mbuf_remove(io, len);
} }
break; break;
}
case MG_EV_POLL: {
struct mg_mqtt_proto_data *pd =
(struct mg_mqtt_proto_data *) nc->proto_data;
double now = mg_time();
if (pd->keep_alive > 0 && pd->last_control_time > 0 &&
(now - pd->last_control_time) > pd->keep_alive) {
LOG(LL_DEBUG, ("Send PINGREQ"));
mg_mqtt_ping(nc);
}
}
} }
} }
@ -10007,6 +10018,7 @@ void mg_set_protocol_mqtt(struct mg_connection *nc) {
static void mg_mqtt_prepend_header(struct mg_connection *nc, uint8_t cmd, static void mg_mqtt_prepend_header(struct mg_connection *nc, uint8_t cmd,
uint8_t flags, size_t len) { uint8_t flags, size_t len) {
struct mg_mqtt_proto_data *pd = (struct mg_mqtt_proto_data *) nc->proto_data;
size_t off = nc->send_mbuf.len - len; size_t off = nc->send_mbuf.len - len;
uint8_t header = cmd << 4 | (uint8_t) flags; uint8_t header = cmd << 4 | (uint8_t) flags;
@ -10026,6 +10038,7 @@ static void mg_mqtt_prepend_header(struct mg_connection *nc, uint8_t cmd,
} while (len > 0); } while (len > 0);
mbuf_insert(&nc->send_mbuf, off, buf, vlen - buf); mbuf_insert(&nc->send_mbuf, off, buf, vlen - buf);
pd->last_control_time = mg_time();
} }
void mg_send_mqtt_handshake(struct mg_connection *nc, const char *client_id) { void mg_send_mqtt_handshake(struct mg_connection *nc, const char *client_id) {

View File

@ -5105,6 +5105,7 @@ struct mg_send_mqtt_handshake_opts {
/* mg_mqtt_proto_data should be in header to allow external access to it */ /* mg_mqtt_proto_data should be in header to allow external access to it */
struct mg_mqtt_proto_data { struct mg_mqtt_proto_data {
uint16_t keep_alive; uint16_t keep_alive;
double last_control_time;
}; };
/* Message types */ /* Message types */