22
33void lwmqtt_init (lwmqtt_client_t * client , uint8_t * write_buf , size_t write_buf_size , uint8_t * read_buf ,
44 size_t read_buf_size ) {
5- client -> last_packet_id = 1 ;
5+ client -> last_packet_id = 0 ;
66 client -> keep_alive_interval = 0 ;
77 client -> pong_pending = false;
88
@@ -404,6 +404,8 @@ lwmqtt_err_t lwmqtt_connect(lwmqtt_client_t *client, lwmqtt_connect_options_t *o
404404 options = & def_options ;
405405 }
406406
407+ // TODO: Reject password-only credentials (MQTT 3.1.1 compliance).
408+
407409 // set command timer
408410 client -> timer_set (client -> command_timer , timeout );
409411
@@ -483,6 +485,8 @@ lwmqtt_err_t lwmqtt_publish(lwmqtt_client_t *client, lwmqtt_publish_options_t *o
483485 }
484486 }
485487
488+ uint16_t expected_packet_id = packet_id ;
489+
486490 // encode publish packet
487491 size_t len = 0 ;
488492 lwmqtt_err_t err = lwmqtt_encode_publish (client -> write_buf , client -> write_buf_size , & len , dup , packet_id , topic , msg );
@@ -502,6 +506,9 @@ lwmqtt_err_t lwmqtt_publish(lwmqtt_client_t *client, lwmqtt_publish_options_t *o
502506 if (err != LWMQTT_SUCCESS ) {
503507 return err ;
504508 }
509+
510+ // Refresh keep-alive after the payload has been fully transmitted.
511+ client -> timer_set (client -> keep_alive_timer , client -> keep_alive_interval );
505512 }
506513
507514 // immediately return on qos zero
@@ -536,6 +543,9 @@ lwmqtt_err_t lwmqtt_publish(lwmqtt_client_t *client, lwmqtt_publish_options_t *o
536543 if (err != LWMQTT_SUCCESS ) {
537544 return err ;
538545 }
546+ if (packet_id != expected_packet_id ) {
547+ return LWMQTT_MISSING_OR_WRONG_PACKET ;
548+ }
539549
540550 return LWMQTT_SUCCESS ;
541551}
@@ -546,9 +556,11 @@ lwmqtt_err_t lwmqtt_subscribe(lwmqtt_client_t *client, int count, lwmqtt_string_
546556 client -> timer_set (client -> command_timer , timeout );
547557
548558 // encode subscribe packet
559+ uint16_t expected_packet_id = lwmqtt_get_next_packet_id (client );
560+
549561 size_t len ;
550- lwmqtt_err_t err = lwmqtt_encode_subscribe (client -> write_buf , client -> write_buf_size , & len ,
551- lwmqtt_get_next_packet_id ( client ), count , topic_filter , qos );
562+ lwmqtt_err_t err = lwmqtt_encode_subscribe (client -> write_buf , client -> write_buf_size , & len , expected_packet_id , count ,
563+ topic_filter , qos );
552564 if (err != LWMQTT_SUCCESS ) {
553565 return err ;
554566 }
@@ -576,6 +588,9 @@ lwmqtt_err_t lwmqtt_subscribe(lwmqtt_client_t *client, int count, lwmqtt_string_
576588 if (err != LWMQTT_SUCCESS ) {
577589 return err ;
578590 }
591+ if (packet_id != expected_packet_id ) {
592+ return LWMQTT_MISSING_OR_WRONG_PACKET ;
593+ }
579594
580595 // check suback codes
581596 for (int i = 0 ; i < suback_count ; i ++ ) {
@@ -597,9 +612,11 @@ lwmqtt_err_t lwmqtt_unsubscribe(lwmqtt_client_t *client, int count, lwmqtt_strin
597612 client -> timer_set (client -> command_timer , timeout );
598613
599614 // encode unsubscribe packet
615+ uint16_t expected_packet_id = lwmqtt_get_next_packet_id (client );
616+
600617 size_t len ;
601- lwmqtt_err_t err = lwmqtt_encode_unsubscribe (client -> write_buf , client -> write_buf_size , & len ,
602- lwmqtt_get_next_packet_id ( client ), count , topic_filter );
618+ lwmqtt_err_t err = lwmqtt_encode_unsubscribe (client -> write_buf , client -> write_buf_size , & len , expected_packet_id ,
619+ count , topic_filter );
603620 if (err != LWMQTT_SUCCESS ) {
604621 return err ;
605622 }
@@ -625,6 +642,9 @@ lwmqtt_err_t lwmqtt_unsubscribe(lwmqtt_client_t *client, int count, lwmqtt_strin
625642 if (err != LWMQTT_SUCCESS ) {
626643 return err ;
627644 }
645+ if (packet_id != expected_packet_id ) {
646+ return LWMQTT_MISSING_OR_WRONG_PACKET ;
647+ }
628648
629649 return LWMQTT_SUCCESS ;
630650}
0 commit comments