#include #include #include #include #include #include #include #include #include #include "json.h" /* Callback called when the client receives a CONNACK message from the broker. */ void on_connect(struct mosquitto *mosq, void *obj, int reason_code) { int rc; /* Print out the connection result. mosquitto_connack_string() produces an * appropriate string for MQTT v3.x clients, the equivalent for MQTT v5.0 * clients is mosquitto_reason_string(). */ if(reason_code != 0){ /* If the connection fails for any reason, we don't want to keep on * retrying in this example, so disconnect. Without this, the client * will attempt to reconnect. */ mosquitto_disconnect(mosq); } /* Making subscriptions in the on_connect() callback means that if the * connection drops and is automatically resumed by the client, then the * subscriptions will be recreated when the client reconnects. */ rc = mosquitto_subscribe(mosq, NULL, "tele/linky_F3643C/SENSOR", 1); if(rc != MOSQ_ERR_SUCCESS){ warnx("Error subscribing: %s", mosquitto_strerror(rc)); /* We might as well disconnect if we were unable to subscribe */ mosquitto_disconnect(mosq); } } /* Callback called when the broker sends a SUBACK in response to a SUBSCRIBE. */ void on_subscribe(struct mosquitto *mosq, void *obj, int mid, int qos_count, const int *granted_qos) { int i; bool have_subscription = false; /* In this example we only subscribe to a single topic at once, but a * SUBSCRIBE can contain many topics at once, so this is one way to check * them all. */ for(i=0; itopic, msg->qos, (char *)msg->payload); int tokcount = jsmn_parse(&p, msg->payload, strlen(msg->payload), NULL, 0); if (tokcount < 0) { warn("Invalid data"); return; } tok = calloc(tokcount, sizeof(*tok)); if (tok == NULL) err(1, "Memory error"); jsmn_init(&p); tokcount = jsmn_parse(&p, msg->payload, strlen(msg->payload), tok, tokcount); if (tokcount < 0) { warn("Invalid data"); return; } tokcount = p.toknext; if (tok->type != JSMN_OBJECT) { warn("Invalid data (expecting a json object)"); free(tok); return; } int i = 0; while ((i = jsmntok_nextchild(tok, tokcount, 0, i)) > 0) { jsmntok_t *key = tok + i; jsmntok_t *value = tok + i + 1; if (key->type != JSMN_STRING) continue; if (jsmntok_stringeq(key, msg->payload, "TIC")) { if (value->type != JSMN_OBJECT) { warn("Invalid data, expecting object for TIC"); free(tok); return; } int j = i + 1; int64_t isousc, base, iinst, imax, papp; while ((j = jsmntok_nextchild(tok, tokcount, i+1, j)) > 0) { jsmntok_t *k = tok + j; jsmntok_t *v = tok + j + 1; if (jsmntok_stringeq(k, msg->payload, "ISOUSC")) isousc = strtoimax(msg->payload + v->start, NULL, 10); else if (jsmntok_stringeq(k, msg->payload, "BASE")) base = strtoimax(msg->payload + v->start, NULL, 10); else if (jsmntok_stringeq(k, msg->payload, "IINST")) iinst = strtoimax(msg->payload + v->start, NULL, 10); else if (jsmntok_stringeq(k, msg->payload, "IMAX")) imax = strtoimax(msg->payload + v->start, NULL, 10); else if (jsmntok_stringeq(k, msg->payload, "PAPP")) papp = strtoimax(msg->payload + v->start, NULL, 10); } if (sqlite3_open("/home/bapt/linky.db", &db) != SQLITE_OK) { err(1, "Impossible to open database"); } sqlite3_stmt *stmt; sqlite3_prepare_v2(db, "insert into linky (DATE, ISOUSC, BASE, IINST, IMAX, PAPP) values " "(unixepoch('now'), ?1, ?2, ?3, ?4, ?5)", -1, &stmt, NULL); sqlite3_bind_int64(stmt, 1, isousc); sqlite3_bind_int64(stmt, 2, base); sqlite3_bind_int64(stmt, 3, iinst); sqlite3_bind_int64(stmt, 4, imax); sqlite3_bind_int64(stmt, 5, papp); if (sqlite3_step(stmt) != SQLITE_DONE) { err(1, "Impossible to write in db '%s': '%s'", sqlite3_errmsg(db), sqlite3_expanded_sql(stmt)); } sqlite3_finalize(stmt); sqlite3_close(db); } } free(tok); } int main(int argc, char *argv[]) { struct mosquitto *mosq; int rc; /* Required before calling other mosquitto functions */ mosquitto_lib_init(); /* Create a new client instance. * id = NULL -> ask the broker to generate a client id for us * clean session = true -> the broker should remove old sessions when we connect * obj = NULL -> we aren't passing any of our private data for callbacks */ mosq = mosquitto_new(NULL, true, NULL); if(mosq == NULL) err(1, "Error: Out of memory."); /* Configure callbacks. This should be done before connecting ideally. */ mosquitto_connect_callback_set(mosq, on_connect); mosquitto_subscribe_callback_set(mosq, on_subscribe); mosquitto_message_callback_set(mosq, on_message); /* Connect to test.mosquitto.org on port 1883, with a keepalive of 60 seconds. * This call makes the socket connection only, it does not complete the MQTT * CONNECT/CONNACK flow, you should use mosquitto_loop_start() or * mosquitto_loop_forever() for processing net traffic. */ rc = mosquitto_connect(mosq, "192.168.1.48", 1883, 60); if(rc != MOSQ_ERR_SUCCESS){ mosquitto_destroy(mosq); errx(1, "Error: %s", mosquitto_strerror(rc)); } /* Run the network loop in a blocking call. The only thing we do in this * example is to print incoming messages, so a blocking call here is fine. * * This call will continue forever, carrying automatic reconnections if * necessary, until the user calls mosquitto_disconnect(). */ mosquitto_loop_forever(mosq, -1, 1); mosquitto_lib_cleanup(); return 0; }