From a59c42e5caa76a5ea1d5e79b7820a1a012f9a3a4 Mon Sep 17 00:00:00 2001 From: cbdev Date: Sat, 14 Nov 2020 15:21:53 +0100 Subject: MQTT backend skeleton --- backends/mqtt.c | 108 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ backends/mqtt.h | 48 +++++++++++++++++++++++++ 2 files changed, 156 insertions(+) create mode 100644 backends/mqtt.c create mode 100644 backends/mqtt.h diff --git a/backends/mqtt.c b/backends/mqtt.c new file mode 100644 index 0000000..4f56aa6 --- /dev/null +++ b/backends/mqtt.c @@ -0,0 +1,108 @@ +#define BACKEND_NAME "mqtt" + +#include +#include "mqtt.h" + +MM_PLUGIN_API int init(){ + backend mqtt = { + .name = BACKEND_NAME, + .conf = mqtt_configure, + .create = mqtt_instance, + .conf_instance = mqtt_configure_instance, + .channel = mqtt_channel, + .handle = mqtt_set, + .process = mqtt_handle, + .start = mqtt_start, + .shutdown = mqtt_shutdown + }; + + //register backend + if(mm_backend_register(mqtt)){ + LOG("Failed to register backend"); + return 1; + } + return 0; +} + +static size_t mqtt_varint_decode(uint8_t* buffer, uint32_t* result){ + //TODO + return 0; +} + +static int mqtt_configure(char* option, char* value){ + LOG("This backend does not take global configuration"); + return 1; +} + +static int mqtt_configure_instance(instance* inst, char* option, char* value){ + mqtt_instance_data* data = (mqtt_instance_data*) inst->impl; + char* token = value; + + if(!strcmp(option, "user")){ + free(data->user); + data->user = strdup(value); + return 0; + } + else if(!strcmp(option, "password")){ + free(data->password); + data->user = strdup(value); + return 0; + } + else if(!strcmp(option, "host")){ + //mqtt url may be of the form + //mqtt[s]://[username][:password]@host.domain[:port] + token = strchr(value, ':'); + //TODO + } + + LOGPF("Unknown instance configuration option %s on instance %s", option, inst->name); + return 1; +} + +static int mqtt_instance(instance* inst){ + //TODO + return 0; +} + +static channel* mqtt_channel(instance* inst, char* spec, uint8_t flags){ + //TODO + return NULL; +} + +static int mqtt_set(instance* inst, size_t num, channel** c, channel_value* v){ + //TODO + return 0; +} + +static int mqtt_handle(size_t num, managed_fd* fds){ + //TODO + return 0; +} + +static int mqtt_start(size_t n, instance** inst){ + //TODO + return 0; +} + +static int mqtt_shutdown(size_t n, instance** inst){ + size_t u, p; + mqtt_instance_data* data = NULL; + + for(u = 0; u < n; u++){ + data = (mqtt_instance_data*) inst[u]->impl; + for(p = 0; p < data->nchannels; p++){ + free(data->channel[p]); + } + free(data->channel); + free(data->host); + free(data->port); + free(data->user); + free(data->password); + + free(inst[u]->impl); + inst[u]->impl = NULL; + } + + LOG("Backend shut down"); + return 0; +} diff --git a/backends/mqtt.h b/backends/mqtt.h new file mode 100644 index 0000000..165f2ba --- /dev/null +++ b/backends/mqtt.h @@ -0,0 +1,48 @@ +#include "midimonster.h" + +MM_PLUGIN_API int init(); +static int mqtt_configure(char* option, char* value); +static int mqtt_configure_instance(instance* inst, char* option, char* value); +static int mqtt_instance(instance* inst); +static channel* mqtt_channel(instance* inst, char* spec, uint8_t flags); +static int mqtt_set(instance* inst, size_t num, channel** c, channel_value* v); +static int mqtt_handle(size_t num, managed_fd* fds); +static int mqtt_start(size_t n, instance** inst); +static int mqtt_shutdown(size_t n, instance** inst); + +#define MQTT_PORT "1883" +#define MQTT_TLS_PORT "8883" + +enum { + MSG_RESERVED = 0x00, + MSG_CONNECT = 0x10, + MSG_CONNACK = 0x20, + MSG_PUBLISH = 0x30, + MSG_PUBACK = 0x40, + MSG_PUBREC = 0x50, + MSG_PUBREL = 0x60, + MSG_PUBCOMP = 0x70, + MSG_SUBSCRIBE = 0x80, + MSG_SUBACK = 0x90, + MSG_UNSUBSCRIBE = 0xA0, + MSG_UNSUBACK = 0xB0, + MSG_PINGREQ = 0xC0, + MSG_PINGRESP = 0xD0, + MSG_DISCONNECT = 0xE0, + MSG_AUTH = 0xF0 +}; + +typedef struct /*_mqtt_instance_data*/ { + uint8_t tls; + char* host; + char* port; + + char* user; + char* password; + + size_t nchannels; + char** channel; +} mqtt_instance_data; + +//per-channel +//qos, subscribe -- cgit v1.2.3