Bugfix: Expose config to error handler to be able to change and reconnect
Re #16
This commit is contained in:
parent
745485dde3
commit
315e45803f
6 changed files with 21 additions and 14 deletions
14
Readme.md
14
Readme.md
|
@ -19,7 +19,6 @@ MQTT library for multiple platforms including embedded targets.
|
|||
|
||||
- [ ] QoS testing, client -> server QoS partly works, server -> client does not
|
||||
- [ ] Running in MQTT Broker mode
|
||||
- [ ] Last will is implemented but not exposed in API
|
||||
- [ ] Implement Protocol level 3 (low prio)
|
||||
- [ ] Implement Draft Protocol level 5 (somewhat low prio as it's a draft spec)
|
||||
- [ ] Support ESP8266 (RTOS)
|
||||
|
@ -79,10 +78,15 @@ typedef struct {
|
|||
char *hostname; /**< Hostname to connect to, will do DNS resolution */
|
||||
uint16_t port; /**< Port the broker listens on, set to 0 for 1883 default */
|
||||
|
||||
char *client_id; /**< Client identification */
|
||||
char *client_id; /**< Client identification max 23 chars */
|
||||
bool clean_session; /**< Set to true to reset the session on reconnect */
|
||||
|
||||
char *username; /**< User name, set to NULL to connect anonymously */
|
||||
char *password; /**< Password, set to NULL to connect without password */
|
||||
|
||||
char *last_will_topic; /**< last will topic that is automatically published on connection loss */
|
||||
char *last_will_message; /**< last will message */
|
||||
bool last_will_retain; /**< tell server to retain last will message */
|
||||
} MQTTConfig;
|
||||
```
|
||||
|
||||
|
@ -104,7 +108,7 @@ or re-trying by changing settings and calling mqtt_reconnect() and returning fal
|
|||
The error handler should be defined like this:
|
||||
|
||||
```c
|
||||
bool error_handler(MQTTHandle *handle, MQTTErrorCode code) {
|
||||
bool error_handler(MQTTHandle *handle, MQTTConfig *config, MQTTErrorCode code) {
|
||||
|
||||
return true; // kill the handle, return false to keep it
|
||||
}
|
||||
|
@ -138,10 +142,11 @@ a successful reconnect.
|
|||
#### Subscribe to a topic
|
||||
|
||||
```c
|
||||
MQTTStatus mqtt_subscribe(MQTTHandle *handle, char *topic, MQTTPublishEventHandler callback);
|
||||
MQTTStatus mqtt_subscribe(MQTTHandle *handle, char *topic, MQTTQosLevel qos_level, MQTTPublishEventHandler callback);
|
||||
```
|
||||
- `handle`: MQTT Handle from `mqtt_connect`
|
||||
- `topic`: Topic to subscribe
|
||||
- `qos_level`: Maximum QoS level to subscribe for
|
||||
- `callback`: Callback function to call when receiving something for that topic
|
||||
- Returns status code
|
||||
|
||||
|
@ -174,6 +179,7 @@ MQTTStatus mqtt_publish(MQTTHandle *handle, char *topic, char *payload, MQTTQosL
|
|||
- `handle`: MQTT Handle from `mqtt_connect`
|
||||
- `topic`: Topic to publish to
|
||||
- `payload`: Message payload to publish
|
||||
- `qos_level`: QoS Level for the publish (0 = Fire and forget, 1 = At least once, 2 = One time for sure)
|
||||
- Returns status code
|
||||
|
||||
This uses a c-string as the payload, theoretically the protocol would allow for binary payloads, but this is currently
|
||||
|
|
14
src/mqtt.c
14
src/mqtt.c
|
@ -137,7 +137,7 @@ static void _mqtt_connect(MQTTHandle *handle, MQTTEventHandler callback, void *c
|
|||
|
||||
char ip[40];
|
||||
if (!hostname_to_ip(handle->config->hostname, ip)) {
|
||||
bool free_handle = handle->error_handler(handle, MQTT_Error_Host_Not_Found);
|
||||
bool free_handle = handle->error_handler(handle, handle->config, MQTT_Error_Host_Not_Found);
|
||||
if (free_handle) {
|
||||
mqtt_free(handle);
|
||||
}
|
||||
|
@ -147,7 +147,7 @@ static void _mqtt_connect(MQTTHandle *handle, MQTTEventHandler callback, void *c
|
|||
}
|
||||
ret = inet_pton(AF_INET, ip, &(servaddr.sin_addr));
|
||||
if (ret == 0) {
|
||||
bool free_handle = handle->error_handler(handle, MQTT_Error_Host_Not_Found);
|
||||
bool free_handle = handle->error_handler(handle, handle->config, MQTT_Error_Host_Not_Found);
|
||||
if (free_handle) {
|
||||
mqtt_free(handle);
|
||||
}
|
||||
|
@ -158,7 +158,7 @@ static void _mqtt_connect(MQTTHandle *handle, MQTTEventHandler callback, void *c
|
|||
|
||||
ret = connect(handle->sock, (struct sockaddr *)&servaddr, sizeof(servaddr));
|
||||
if (ret != 0) {
|
||||
bool free_handle = handle->error_handler(handle, MQTT_Error_Connection_Refused);
|
||||
bool free_handle = handle->error_handler(handle, handle->config, MQTT_Error_Connection_Refused);
|
||||
if (free_handle) {
|
||||
mqtt_free(handle);
|
||||
}
|
||||
|
@ -174,7 +174,7 @@ static void _mqtt_connect(MQTTHandle *handle, MQTTEventHandler callback, void *c
|
|||
bool result = send_connect_packet(handle);
|
||||
if (result == false) {
|
||||
DEBUG_LOG("Sending connect packet failed, running error handler");
|
||||
bool free_handle = handle->error_handler(handle, MQTT_Error_Broker_Disconnected);
|
||||
bool free_handle = handle->error_handler(handle, handle->config, MQTT_Error_Broker_Disconnected);
|
||||
if (free_handle) {
|
||||
mqtt_free(handle);
|
||||
}
|
||||
|
@ -223,7 +223,7 @@ MQTTStatus mqtt_reconnect(MQTTHandle *handle, MQTTEventHandler callback, void *c
|
|||
|
||||
MQTTStatus mqtt_subscribe(MQTTHandle *handle, char *topic, MQTTQosLevel qos_level, MQTTPublishEventHandler callback) {
|
||||
if (!handle->reader_alive) {
|
||||
handle->error_handler(handle, MQTT_Error_Connection_Reset);
|
||||
handle->error_handler(handle, handle->config, MQTT_Error_Connection_Reset);
|
||||
return MQTT_STATUS_ERROR;
|
||||
}
|
||||
add_subscription(handle, topic, qos_level, callback);
|
||||
|
@ -232,7 +232,7 @@ MQTTStatus mqtt_subscribe(MQTTHandle *handle, char *topic, MQTTQosLevel qos_leve
|
|||
|
||||
MQTTStatus mqtt_unsubscribe(MQTTHandle *handle, char *topic) {
|
||||
if (!handle->reader_alive) {
|
||||
handle->error_handler(handle, MQTT_Error_Connection_Reset);
|
||||
handle->error_handler(handle, handle->config, MQTT_Error_Connection_Reset);
|
||||
return MQTT_STATUS_ERROR;
|
||||
}
|
||||
remove_subscription(handle, topic);
|
||||
|
@ -241,7 +241,7 @@ MQTTStatus mqtt_unsubscribe(MQTTHandle *handle, char *topic) {
|
|||
|
||||
MQTTStatus mqtt_publish(MQTTHandle *handle, char *topic, char *payload, MQTTQosLevel qos_level) {
|
||||
if (!handle->reader_alive) {
|
||||
handle->error_handler(handle, MQTT_Error_Connection_Reset);
|
||||
handle->error_handler(handle, handle->config, MQTT_Error_Connection_Reset);
|
||||
return MQTT_STATUS_ERROR;
|
||||
}
|
||||
return (send_publish_packet(handle, topic, payload, qos_level) ? MQTT_STATUS_OK : MQTT_STATUS_ERROR);
|
||||
|
|
|
@ -45,7 +45,7 @@ typedef enum {
|
|||
*
|
||||
* Return true if the handle should be freed, false to keep it
|
||||
*/
|
||||
typedef bool (*MQTTErrorHandler)(MQTTHandle *handle, MQTTErrorCode code);
|
||||
typedef bool (*MQTTErrorHandler)(MQTTHandle *handle, MQTTConfig *config, MQTTErrorCode code);
|
||||
|
||||
/** Event handler callback */
|
||||
typedef void (*MQTTEventHandler)(MQTTHandle *handle, void *context);
|
||||
|
|
|
@ -8,7 +8,7 @@ bool leave = false;
|
|||
|
||||
#define LOG(fmt, ...) fprintf(stdout, fmt "\n", ## __VA_ARGS__)
|
||||
|
||||
bool err_handler(MQTTHandle *handle, MQTTErrorCode error) {
|
||||
bool err_handler(MQTTHandle *handle, MQTTConfig *config, MQTTErrorCode error) {
|
||||
LOG("Error received: %d", error);
|
||||
exit(1);
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ bool leave = false;
|
|||
|
||||
#define LOG(fmt, ...) fprintf(stdout, fmt "\n", ## __VA_ARGS__)
|
||||
|
||||
bool err_handler(MQTTHandle *handle, MQTTErrorCode error) {
|
||||
bool err_handler(MQTTHandle *handle, MQTTConfig *config, MQTTErrorCode error) {
|
||||
LOG("Error received: %d", error);
|
||||
|
||||
return 1;
|
||||
|
|
|
@ -286,6 +286,7 @@ TestResult test_encode_publish_dup_qos0(void) {
|
|||
Buffer *encoded = mqtt_packet_encode(&(MQTTPacket){ PacketTypePublish, payload });
|
||||
free(payload);
|
||||
TESTASSERT(encoded == NULL, "DUP and QoS level 0 is an incompatible combination");
|
||||
TEST_OK();
|
||||
}
|
||||
|
||||
TestResult test_encode_publish_with_msg(void) {
|
||||
|
|
Loading…
Reference in a new issue