Commit da1dc998 authored by alexandre burton's avatar alexandre burton
Browse files

Code formatting and README tweaks

parent c313f1a5
......@@ -2,31 +2,36 @@
**MQTT client based on libmosquitto**
This object provides a Max interface to a treaded instance of the [libmosquitto](http://mosquitto.org/man/libmosquitto-3.html) client.
In Memoriam W protocol
v20210101 was developped, tested and signed on macOS 10.14.6. It covers the features our application required; more work to follow (see below).
This object provides a Max interface to a treaded instance of the [libmosquitto](http://mosquitto.org/man/libmosquitto-3.html) client.
It bundles a static libmosquitto binary (TLS support was giving errors so it was simply disabled through CMake). You can probably swap the .a in the .mxo with your own library if you wish.
v20210101 was developped, tested and signed on macOS 10.14.6 with a mosquitto broker running on debian in a well-connected north american data center. It covers the features our application required; more work to follow (see below).
Signing seems to be OK; not sure how the Xcode project will present itself to someone else, but as long as the bundled libmosquitto.a gets signed (there a scripting step for that), it works fine on unrelated computers.
It bundles a static libmosquitto binary (TLS support was giving errors so it was simply disabled through CMake). You can probably swap the .a in the .mxo with your own signed library if you wish. (Not sure how the Xcode project will present itself to someone else vs signing identities).
## TODO
Max interface:
- QOS, persistence and will
- complete MQTT callback support
- ~~QOS, persistence~~
- will
- complete attribute support
- auto-connection
- complete max type support on publish (how to allow arbitrary length vs QOS/persistence?)
- auto-connection on object creation if attributes are set
- "enable" toggle (to "mute" traffic at the max level)
Bundled library:
- TLS support
- (maybe) auto-discovery of dynamic system-level dylib support, vs bundled as fallback (?)
- or should the MQTT CMake-based source be included / compiled with the object?
- ... or should the MQTT CMake-based source be included & compiled with the object? Best practice vs open source Max objects?
Other features:
- max package
- internal preprocessing of the received message (detect JSON dict, or list or ...?)
- thorough MQTT callback and message support
- support for MQTT ping
- max package; better examples/docs
- scan payloads for binary or structured data (jitter matrices, msp vectors, json dicts)
- ... otherwise preprocess as a list (string, float, int) to spare gensym()s and reduce pressure on [fromsymbol]
- optimize lifecycle of the mosquitto instance? (re-use vs re-create)
Windows version:
......
......@@ -21,7 +21,7 @@ typedef struct _mqtt {
t_symbol *a_user; // MQTT username
t_symbol *a_pw; // MQTT password
t_symbol *a_id; // Client ID
} t_mqtt;
#define MQTT_DEFAULT_PORT 1883
......@@ -73,6 +73,8 @@ void message_callback(struct mosquitto *mosq, void *obj, const struct mosquitto_
{
t_mqtt * x = obj;
t_atom a[1];
// asssumes something that fits in a max symbol -- should check for cues or magic numbers and generates json dicts, jitter matrices, or vectors of audio
atom_setsym(a+0, gensym((char*) message->payload));
outlet_anything(x->p_main_outlet, gensym(message->topic), 1,a);
}
......@@ -93,7 +95,7 @@ void mosquitto_free_client(t_mqtt *x) {
mosquitto_disconnect(x->mosq);
mosquitto_loop_stop(x->mosq, true);
mosquitto_destroy(x->mosq);
}
void mqtt_free(t_mqtt *x)
......@@ -118,16 +120,16 @@ void ext_main(void *r)
CLASS_ATTR_SYM(c, "id", 0, t_mqtt, a_id);
CLASS_ATTR_ACCESSORS(c, "id", NULL, mqtt_set_id);
CLASS_ATTR_CHAR(c, "verbose", 0, t_mqtt, a_verbose);
CLASS_ATTR_STYLE_LABEL(c, "verbose",0,"onoff","Verbose");
// CLASS_ATTR_SYM(c, "autoconnect", 0, t_mqtt, a_autoconnect);
// CLASS_ATTR_SYM(c, "autoconnect", 0, t_mqtt, a_autoconnect);
CLASS_ATTR_SYM(c, "user", 0, t_mqtt, a_user);
CLASS_ATTR_SYM(c, "password", 0, t_mqtt, a_pw);
CLASS_ATTR_LONG(c, "port", 0, t_mqtt, a_port);
class_register(CLASS_BOX, c);
mqtt_class = c;
......@@ -158,8 +160,8 @@ void mqtt_connect_method(t_mqtt *x, t_symbol *s, long argc, t_atom *argv) {
} else {
if (argv[0].a_type==A_SYM) {
// mosquitto_reinitialise(x->mosq, x->clientid, false, x);
// mosquitto_reinitialise(x->mosq, x->clientid, false, x);
if (x->mosq != NULL) {
mosquitto_free_client(x);
}
......@@ -197,19 +199,19 @@ void mqtt_connect_method(t_mqtt *x, t_symbol *s, long argc, t_atom *argv) {
// error ("Mosquitto loop error!\n");
// } else {
int res = mosquitto_connect(x->mosq, host, port, 60);
// post("Mosquitto Instance id %s starting loop",x->a_id->s_name );
// int rloop = mosquitto_loop_start(x->mosq);
// if (rloop==MOSQ_ERR_INVAL) {
// error("Mosquitto <%s> could not start thread [MOSQ_ERR_INVAL]", x->clientid);
// } else if (rloop==MOSQ_ERR_NOT_SUPPORTED) {
// error("Mosquitto <%s> could not start thread [MOSQ_ERR_NOT_SUPPORTED]", x->clientid);
// } else {
// post("Mosquitto <%s> started event thread",x->clientid);
// }
// // }
//
// post("Mosquitto Instance id %s starting loop",x->a_id->s_name );
// int rloop = mosquitto_loop_start(x->mosq);
// if (rloop==MOSQ_ERR_INVAL) {
// error("Mosquitto <%s> could not start thread [MOSQ_ERR_INVAL]", x->clientid);
// } else if (rloop==MOSQ_ERR_NOT_SUPPORTED) {
// error("Mosquitto <%s> could not start thread [MOSQ_ERR_NOT_SUPPORTED]", x->clientid);
// } else {
// post("Mosquitto <%s> started event thread",x->clientid);
// }
// // }
//
// mosquitto_disconnect(x->mosq);
......@@ -221,14 +223,14 @@ void mqtt_connect_method(t_mqtt *x, t_symbol *s, long argc, t_atom *argv) {
// if(rc){
// error ("Mosquitto connection error!\n");
// } else {
rloop = mosquitto_loop_start(x->mosq);
if (rloop==MOSQ_ERR_INVAL) {
error("Mosquitto <%s> could not start thread [MOSQ_ERR_INVAL]", x->a_id->s_name);
} else if (rloop==MOSQ_ERR_NOT_SUPPORTED) {
error("Mosquitto <%s> could not start thread [MOSQ_ERR_NOT_SUPPORTED]", x->a_id->s_name);
} else {
if (x->a_verbose) post("Mosquitto <%s> started event thread",x->a_id->s_name);
}
rloop = mosquitto_loop_start(x->mosq);
if (rloop==MOSQ_ERR_INVAL) {
error("Mosquitto <%s> could not start thread [MOSQ_ERR_INVAL]", x->a_id->s_name);
} else if (rloop==MOSQ_ERR_NOT_SUPPORTED) {
error("Mosquitto <%s> could not start thread [MOSQ_ERR_NOT_SUPPORTED]", x->a_id->s_name);
} else {
if (x->a_verbose) post("Mosquitto <%s> started event thread",x->a_id->s_name);
}
// }
break;
case MOSQ_ERR_INVAL: error("Mosquitto::connect <%s> invalid parameters [MOSQ_ERR_INVAL]", x->a_id); break;
......@@ -323,7 +325,7 @@ void *mqtt_new(t_symbol *s, long argc, t_atom *argv) // n = int argument typed
{
t_mqtt *x;
x = (t_mqtt *)object_alloc(mqtt_class);
char hostname[100];
char random_id[100];
hostname[99] = '\0';
......@@ -332,10 +334,10 @@ void *mqtt_new(t_symbol *s, long argc, t_atom *argv) // n = int argument typed
x->a_id = gensym(random_id);
x->a_verbose = 0;
attr_args_process(x, argc, argv);
x->p_status_outlet = outlet_new(x, NULL);
x->p_main_outlet = outlet_new(x, NULL);
return(x);
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment