aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--backends/mqtt.c108
-rw-r--r--backends/mqtt.h48
2 files changed, 156 insertions, 0 deletions
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 <string.h>
+#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