From 5d9a1be2024a7cfcd4313833c32c25feea2075fb Mon Sep 17 00:00:00 2001 From: mreenen Date: Sun, 5 Mar 2023 17:32:32 +0100 Subject: [PATCH] update alot --- Makefile | 18 ++- mqttClient | Bin 0 -> 45880 bytes relayClient.service | 11 +- src/conf.h | 8 +- src/main.c | 62 ++------ src/module.c | 66 ++++++++ src/module.h | 19 +++ src/modules/buttons.c | 33 ++++ src/mqtt.c | 344 ++++++++++++++++++++++++++---------------- src/mqtt.h | 4 +- 10 files changed, 366 insertions(+), 199 deletions(-) create mode 100755 mqttClient create mode 100644 src/module.c create mode 100644 src/module.h create mode 100644 src/modules/buttons.c diff --git a/Makefile b/Makefile index b4d97c7..ea37fca 100644 --- a/Makefile +++ b/Makefile @@ -1,9 +1,21 @@ -SRC := src/main.c src/mqtt.c +SRC := src/main.c src/mqtt.c src/module.c src/modules/*.c INC := -I src -I include/paho-mqtt -LIBS := -Llibs/paho-mqtt -lpthread -lpaho-mqtt3a -lpaho-mqtt3c +LIBS := -Llibs/paho-mqtt -lpthread -lpaho-mqtt3a -lpaho-mqtt3c -lpthread all: build build: $(SRC) - gcc $(SRC) $(LIBS) -o relayClient $(INC) + gcc $(SRC) $(LIBS) -o mqttClient $(INC) + +debug: $(SRC) + gcc $(SRC) $(LIBS) -g -o mqttClient $(INC) + +install: + mkdir -p $$HOME/.local/bin + cp mqttClient $$HOME/.local/bin/mqttClient + chmod +x $$HOME/.local/bin/mqttClient + # sed -e "s//$$(id -un)/g" mqttClient.service >/etc/systemd/system/mqttClient.service + +clean: + rm mqttClient diff --git a/mqttClient b/mqttClient new file mode 100755 index 0000000000000000000000000000000000000000..bd6b0e181c260a7394085a9e3f53a2052925dc72 GIT binary patch literal 45880 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 Uqq`l8{?Z2}#!VgqPty4R0N7n5od5s; literal 0 HcmV?d00001 diff --git a/relayClient.service b/relayClient.service index c77edf9..64c6cdc 100644 --- a/relayClient.service +++ b/relayClient.service @@ -1,18 +1,17 @@ # systemd service file to start relayClient [Unit] -Description=MQTT client for switching relays +Description=MQTT client #After=network.target After=mosquitto.service [Service] Type=simple -# Run as normal pi user - change to the user name you wish to run relayClient -User=mreenen -Group=mreenen -WorkingDirectory=/home/mreenen/relayClient +User= +Group= +WorkingDirectory=/home/ -ExecStart=/home/mreenen/relayClient/relayClient +ExecStart=/home//.local/bin/relayClient # Use SIGINT to stop KillSignal=SIGINT # Auto restart on crash diff --git a/src/conf.h b/src/conf.h index 47b2c98..2920098 100644 --- a/src/conf.h +++ b/src/conf.h @@ -1,12 +1,12 @@ #if !defined(CONF_H) #define CONF_H -#define ADDRESS "tcp://localhost:1883" -#define CLIENTID "mqttClock" -#define TOPIC "coolhaven/clock" +#define ADDRESS "tcp://10.2.0.3:1883" +#define CLIENTID "mqttClient" +#define BASE_TOPIC "/cool/" #define TIMEOUT 10000L -#define RECON_TIMEOUT 60 +#define RECON_TIMEOUT 60 // seconds #if defined(_WIN32) #define SLEEP(n) Sleep(n*10) diff --git a/src/main.c b/src/main.c index 1892e76..8daa456 100644 --- a/src/main.c +++ b/src/main.c @@ -7,64 +7,24 @@ #include "MQTTAsync.h" #include "mqtt.h" - -void onConnect(void* context){ - return; -} - -void onMessage(char* topicName, int topicLen, MQTTAsync_message* message){ - return; -} - -void sendTick(char* name, struct tm* t) -{ - - char topic[100] = TOPIC "/"; - strcat(&topic[0], name); - - char payload[50]; - sprintf(&payload[0], "%04d-%02d-%02dT%02d:%02d:%02d", - t->tm_year, - t->tm_mon + 1, - t->tm_mday, - t->tm_hour, - t->tm_min, - t->tm_sec - ); - - MQTT_publish(topic, &payload[0], 1); -} +#include "module.h" int main(int argc, char* argv[]){ printf("==============================\n" - "=== mqttClock ================\n" + "=== mqttClient ===============\n" "==============================\n\n"); - clientConf_t* client = MQTT_connect(&onConnect, &onMessage); - - if(client != NULL){ - int lastMin = 0; - int lastHour = 0; + clientConf_t* client = MQTT_connect(NULL); + if(client != NULL) + { + usleep((int)500e3); + Modules_Init(); + Modules_StartAll(); + int returnCode = 1; - while (returnCode = 1) + while(returnCode == 1) { - time_t rowNow = time(NULL); - struct tm* now = gmtime(&rowNow); - - sendTick("second", now); - if (now->tm_min != lastMin) - { - sendTick("minute", now); - lastMin = now->tm_min; - - if (now->tm_hour != lastHour) - { - sendTick("hour", now); - lastHour = now->tm_hour; - } - } - char ch = getchar(); switch (ch) { case 'q': @@ -76,7 +36,7 @@ int main(int argc, char* argv[]){ } else { - printf("failt to connect to mqtt\n"); + printf("CRITICAL: main(): failt to connect to mqtt\n"); return -1; } diff --git a/src/module.c b/src/module.c new file mode 100644 index 0000000..28c89f2 --- /dev/null +++ b/src/module.c @@ -0,0 +1,66 @@ +#include +#include +#include + +#include "module.h" + +Module_t *Modules = NULL; +unsigned int Modules_len = 0; +unsigned int Modules_alloc = 0; + +void Modules_Add(Module_t module) +{ + printf("INFO: Modules_Add(): add module '%s' to the list\n", module.Name); + if (Modules == NULL) + { + Modules = (Module_t*) malloc(sizeof(Module_t) * 5); + Modules_alloc = 5; + } + + if (Modules_len >= Modules_alloc) + { + Module_t *new_subs = (Module_t *) malloc(sizeof(Module_t) * (Modules_alloc + 5)); + memcpy(new_subs, Modules, sizeof(Module_t) * Modules_alloc); + Module_t *old_subs = Modules; + Modules = new_subs; + free(old_subs); + } + + memcpy(Modules + sizeof(Module_t)*Modules_len, &module, sizeof(Module_t)); + Modules_len++; +} + +void Modules_Init() +{ + // extern Module_t Module_Clock(); + // Modules_Add(Module_Clock()); + extern Module_t Module_Button(); + Modules_Add(Module_Button()); +} + +void Modules_StartOne(Module_t module) +{ + printf("INFO: Modules_StartOne(): starting module '%s'\n", module.Name); + (*(module.Start))(); +} + +void Modules_StopOne(Module_t module) +{ + (*(module.Stop))(); +} + +void Modules_StartAll() +{ + for (int i=0; i +#include +#include +#include + +#include "conf.h" +#include "module.h" +#include "mqtt.h" + +void button1(char *topicName, int topicLen, MQTTAsync_message *message) +{ + printf("DEBUG: buttons.button1(): payload = %s", (char*)message->payload); +} + +void Buttons_Stop() +{ + return; +} + +void Buttons_Start() +{ + MQTT_subscribe("button1", 1, &button1); + return; +} + +Module_t Module_Button() +{ + Module_t module; + module.Name = "buttons"; + module.Start = &Buttons_Start; + module.Stop = &Buttons_Stop; + return module; +} diff --git a/src/mqtt.c b/src/mqtt.c index 5783327..4624a8d 100644 --- a/src/mqtt.c +++ b/src/mqtt.c @@ -1,5 +1,6 @@ #include #include +#include #include #include "conf.h" @@ -8,136 +9,17 @@ #include "MQTTAsync.h" #include "mqtt.h" -clientConf_t* client; - -void reconnect(){ - int rc; - - if(client->last_reconn.t + RECON_TIMEOUT > time(NULL)){ - if(client->last_reconn.c < 10){ - printf("Wait %d seconds until reconect. reconect counter on %d\n", RECON_TIMEOUT, client->last_reconn.c); - SLEEP(RECON_TIMEOUT); - } else { - printf("Wait one hour until reconect. reconect counter on %d\n", client->last_reconn.c); - SLEEP(3600); - } - } - - printf("Reconnecting to MQTT server\n"); - rc = MQTTAsync_connect(client->client, &(client->conn_opts)); - if (rc != MQTTASYNC_SUCCESS){ - printf("ERROR: Failed to reconnect, return code %d\n", rc); - client->last_reconn.t = time(NULL); - client->last_reconn.c++; - } else { - client->last_reconn.c = 0; - } -} - -void connlost(void *context, char *cause){ - printf("\nERROR: Lost connection to MQTT\n"); - if(cause){ - printf(" cause: %s\n", cause); - } - - reconnect(); -} - -int msgarrvd(void *context, char *topicName, int topicLen, MQTTAsync_message *message){ - printf("Message arrived\n"); - printf(" topic: %s\n", topicName); - printf(" message: %.*s\n", message->payloadlen, (char*)message->payload); - - (*(client->onMessage))(topicName, topicLen, message); - - MQTTAsync_freeMessage(&message); - MQTTAsync_free(topicName); - return 1; -} - -void onConnectFailure(void* context, MQTTAsync_failureData* response){ - printf("Connect failed, rc %d\n", response->code); - reconnect(); -} - -void onConn(void* context, MQTTAsync_successData* response){ - printf("connected to MQTT server\n"); - (*(client->onConnect))(client); -} - - -clientConf_t* MQTT_connect(void (*onConnect_cb)(void* context), void (*onMessage)(char* topicName, int topicLen, MQTTAsync_message* message)){ - client = (clientConf_t*) malloc(sizeof(clientConf_t)); // keep this util i say so - int rc; - int ch; - - rc = MQTTAsync_create(&(client->client), ADDRESS, CLIENTID, MQTTCLIENT_PERSISTENCE_NONE, NULL); - if (rc != MQTTASYNC_SUCCESS){ - printf("Failed to create client, return code %d\n", rc); - free(client); - return NULL; - } - - client->onMessage = onMessage; - client->onConnect = onConnect_cb; - client->last_reconn.c = 0; - client->last_reconn.t = 0; - - rc = MQTTAsync_setCallbacks(client->client, client, &connlost, &msgarrvd, NULL); - if (rc != MQTTASYNC_SUCCESS){ - printf("Failed to set callbacks, return code %d\n", rc); - MQTTAsync_destroy(&(client->client)); - free(client); - return NULL; - } - - MQTTAsync_connectOptions conn_opts = MQTTAsync_connectOptions_initializer; - client->conn_opts = conn_opts; - client->conn_opts.keepAliveInterval = 20; - client->conn_opts.cleansession = 1; - client->conn_opts.onSuccess = onConn; - client->conn_opts.onFailure = onConnectFailure; - client->conn_opts.context = &client; - printf("connecting to MQTT server (%s)\n", ADDRESS); - rc = MQTTAsync_connect(client->client, &(client->conn_opts)); - if(rc != MQTTASYNC_SUCCESS){ - printf("Failed to start connect, return code %d\n", rc); - MQTTAsync_destroy(&(client->client)); - free(client); - return NULL; - } - - return client; -} - - - -void onDisconnectFailure(void* context, MQTTAsync_failureData* response){ - printf("Faild to discontect from MQTT, rc %d\n", response->code); - MQTTAsync_destroy(client->client); - free(client); -} - -void onDisconnect(void* context, MQTTAsync_successData* response){ - printf("disconnected from MQTT server\n"); - MQTTAsync_destroy(client->client); - free(client); -} - -void MQTT_disconnect(){ - int rc; - MQTTAsync_disconnectOptions disc_opts = MQTTAsync_disconnectOptions_initializer; - disc_opts.onSuccess = &onDisconnect; - disc_opts.onFailure = &onDisconnectFailure; - rc = MQTTAsync_disconnect(client->client, &disc_opts); - if (rc != MQTTASYNC_SUCCESS){ - printf("Failed to start disconnect, return code %d\n", rc); - MQTTAsync_destroy(client->client); - return; - } -} +typedef struct Subscription_s { + char* topic; + char qos; + void (*onMessage)(char* topicName, int topicLen, MQTTAsync_message* message); +} Subscription_t; +clientConf_t* Client; +Subscription_t *Subscriptions = NULL; +unsigned int Subscriptions_len = 0; +unsigned int Subscriptions_aloc = 0; void onSubscribe(void* context, MQTTAsync_successData* response){ // printf("Successful subscribed to %s\n", (char*) context); @@ -148,15 +30,57 @@ void onSubscribeFailure(void* context, MQTTAsync_failureData* response){ printf("ERROR: Subscribe failed, rc %d\n", response->code); } -void MQTT_subscribe(char* topic, int qos){ +void MQTT_subscribe(char* topic, int qos, void (*onMessage)(char* topicName, int topicLen, MQTTAsync_message* message)) +{ int rc; - printf("Subscribing to topic %s (QoS%d)\n", topic, qos); + + if (Subscriptions == NULL) + { + Subscriptions = (Subscription_t *) malloc(sizeof(Subscription_t) * 5); + Subscriptions_aloc = 5; + } + + if (Subscriptions_len >= Subscriptions_aloc) + { + Subscription_t *new_subs = (Subscription_t *) malloc(sizeof(Subscription_t) * (Subscriptions_aloc + 5)); + memcpy(new_subs, Subscriptions, sizeof(Subscription_t) * Subscriptions_aloc); + Subscription_t *old_subs = Subscriptions; + Subscriptions = new_subs; + free(old_subs); + } + + Subscription_t sub; + sub.qos = qos; + sub.onMessage = onMessage; + + if (topic[0] != '/') + { + char *newTopic = malloc(strlen(BASE_TOPIC) + strlen(topic) + 1); + memcpy(newTopic, BASE_TOPIC, strlen(BASE_TOPIC)); + memcpy(newTopic + strlen(BASE_TOPIC), topic, strlen(topic) + 1); + sub.topic = newTopic; + } + else + { + // copy topic to allow passing local variable + char *newTopic = malloc(strlen(topic) + 1); + memcpy(newTopic, topic, strlen(topic) + 1); + sub.topic = newTopic; + } + + memcpy(Subscriptions + sizeof(Subscription_t)*(Subscriptions_len), &sub, sizeof(Subscription_t)); + Subscriptions_len++; + + printf("INFO: MQTT_subscribe(): Subscribing to topic %s (QoS%d)\n", sub.topic, sub.qos); + MQTTAsync_responseOptions opts = MQTTAsync_responseOptions_initializer; opts.onSuccess = &onSubscribe; opts.onFailure = &onSubscribeFailure; - opts.context = topic; - rc = MQTTAsync_subscribe(client->client, topic, qos, &opts); + opts.context = ⊂ + rc = MQTTAsync_subscribe(Client->client, "#", qos, &opts); + // rc = MQTTAsync_subscribe(Client->client, topic, qos, &opts); + if (rc != MQTTASYNC_SUCCESS){ printf("ERROR: Failed to start subscribe, return code %d\n", rc); } @@ -164,5 +88,159 @@ void MQTT_subscribe(char* topic, int qos){ void MQTT_publish(char* topic, char* payload, int qos) { - MQTTClient_publish(client->client, topic, len(topic), payload, qos, 0, NULL); + printf("Publishing to %s", topic); + MQTTClient_publish(Client->client, topic, strlen(payload), payload, qos, 0, NULL); } + +int msgarrvd(void *context, char *topicName, int topicLen, MQTTAsync_message *message){ + printf("Message arrived\n"); + printf(" topic: %s\n", topicName); + printf(" message: %.*s\n", message->payloadlen, (char*)message->payload); + + //(*(Client->onMessage))(topicName, topicLen, message); + + MQTTAsync_freeMessage(&message); + MQTTAsync_free(topicName); + return 1; +} + +void reconnect(){ + int rc; + + if(Client->last_reconn.t + RECON_TIMEOUT > time(NULL)){ + if(Client->last_reconn.c < 10){ + printf("INFO: MQTT.reconnect(): Wait %d seconds until reconect. reconect counter on %d\n", RECON_TIMEOUT, Client->last_reconn.c); + sleep(RECON_TIMEOUT); + } else { + printf("INFO: MQTT.reconnect(): Wait min minutes until reconect. reconect counter on %d\n", Client->last_reconn.c); + sleep(60 * 10); + } + } + + printf("INFO: MQTT.reconnect(): Reconnecting to MQTT server\n"); + rc = MQTTAsync_connect(Client->client, &(Client->conn_opts)); + if (rc != MQTTASYNC_SUCCESS){ + printf("ERROR: MQTT.reconnect(): Failed to reconnect, return code %d\n", rc); + } else { + printf("INFO: MQTT.reconnect(): Reconnect sucsesfull\n"); + } + Client->last_reconn.t = time(NULL); + Client->last_reconn.c++; +} + +void onConnectFailure(void* context, MQTTAsync_failureData* response){ + printf("ERROR: MQTT.onConnectFailure(): Connection failed, rc %d\n", response->code); + reconnect(); +} + +void connlost(void *context, char *cause){ + printf("\nERROR: MQTT.connlost(): Lost connection to MQTT\n"); + if (cause != NULL) + { + printf(" cause: %s\n", cause); + } + + reconnect(); +} + +void onConn(void* context, MQTTAsync_successData* response){ + printf("INFO: MQTT.onConn(): connected to MQTT server\n"); + + Client->last_reconn.c = 0; + + int rc; + for (int i=0; i < Subscriptions_len; i++) + { + Subscription_t sub = *(Subscriptions + sizeof(Subscription_t)*i); + + printf("INFO: MQTT.onConn(): Subscribing to topic %s (QoS%d)\n", sub.topic, sub.qos); + + MQTTAsync_responseOptions opts = MQTTAsync_responseOptions_initializer; + opts.onSuccess = &onSubscribe; + opts.onFailure = &onSubscribeFailure; + opts.context = ⊂ + rc = MQTTAsync_subscribe(Client->client, sub.topic, sub.qos, &opts); + + if (rc != MQTTASYNC_SUCCESS){ + printf("ERROR: MQTT.onConn(): Failed to start subscribe, return code %d\n", rc); + } + } + + if (Client->onConnect != NULL) + { + (*(Client->onConnect))(Client); + } +} + + +clientConf_t* MQTT_connect(void (*onConnect_cb)(void* context)){ + Client = (clientConf_t*) malloc(sizeof(clientConf_t)); // keep this util i say so + int rc; + int ch; + + rc = MQTTAsync_create(&(Client->client), ADDRESS, CLIENTID, MQTTCLIENT_PERSISTENCE_NONE, NULL); + if (rc != MQTTASYNC_SUCCESS){ + printf("Failed to create client, return code %d\n", rc); + free(Client); + return NULL; + } + + Client->onConnect = onConnect_cb; + Client->last_reconn.c = 0; + Client->last_reconn.t = time(NULL); + + rc = MQTTAsync_setCallbacks(Client->client, Client, &connlost, &msgarrvd, NULL); + if (rc != MQTTASYNC_SUCCESS){ + printf("Failed to set callbacks, return code %d\n", rc); + MQTTAsync_destroy(&(Client->client)); + free(Client); + return NULL; + } + + MQTTAsync_connectOptions conn_opts = MQTTAsync_connectOptions_initializer; + Client->conn_opts = conn_opts; + Client->conn_opts.keepAliveInterval = 20; + Client->conn_opts.cleansession = 1; + Client->conn_opts.onSuccess = onConn; + Client->conn_opts.onFailure = onConnectFailure; + Client->conn_opts.context = &Client; + printf("connecting to MQTT server (%s)\n", ADDRESS); + rc = MQTTAsync_connect(Client->client, &(Client->conn_opts)); + if(rc != MQTTASYNC_SUCCESS){ + printf("Failed to start connect, return code %d\n", rc); + MQTTAsync_destroy(&(Client->client)); + free(Client); + return NULL; + } + + return Client; +} + + + +void onDisconnectFailure(void* context, MQTTAsync_failureData* response){ + printf("Faild to discontect from MQTT, rc %d\n", response->code); + MQTTAsync_destroy(Client->client); + free(Client); +} + +void onDisconnect(void* context, MQTTAsync_successData* response){ + printf("disconnected from MQTT server\n"); + MQTTAsync_destroy(Client->client); + free(Client); +} + +void MQTT_disconnect(){ + int rc; + MQTTAsync_disconnectOptions disc_opts = MQTTAsync_disconnectOptions_initializer; + disc_opts.onSuccess = &onDisconnect; + disc_opts.onFailure = &onDisconnectFailure; + rc = MQTTAsync_disconnect(Client->client, &disc_opts); + if (rc != MQTTASYNC_SUCCESS){ + printf("Failed to start disconnect, return code %d\n", rc); + MQTTAsync_destroy(Client->client); + return; + } +} + + diff --git a/src/mqtt.h b/src/mqtt.h index 9d6068b..f551adc 100644 --- a/src/mqtt.h +++ b/src/mqtt.h @@ -16,10 +16,10 @@ typedef struct clientConf_s { } clientConf_t; -clientConf_t* MQTT_connect(void (*onConnect)(void* context), void (*onMessage)(char* topicName, int topicLen, MQTTAsync_message* message)); +clientConf_t* MQTT_connect(void (*onConnect)(void* context)); void MQTT_disconnect(); -void MQTT_subscribe(char* topic, int qos); +void MQTT_subscribe(char* topic, int qos, void (*onMessage)(char* topicName, int topicLen, MQTTAsync_message* message)); void MQTT_publish(char* topic, char* payload, int qos); #endif