Bugfix: Expose config to error handler to be able to change and reconnect

Re #16
This commit is contained in:
Johannes Schriewer 2018-07-30 22:34:28 +02:00
parent 745485dde3
commit 315e45803f
6 changed files with 21 additions and 14 deletions

View file

@ -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

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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;

View file

@ -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) {