summaryrefslogtreecommitdiff
path: root/src/main.c
blob: 9f76ab2a904a6a4713217b337c677b9295f0cb3d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
// Standard C
#include <signal.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>

// System
#include <unistd.h>

// Project
#include <mosquitto.h>

#ifndef UNUSED
#	define UNUSED(x) (void) (x)
#endif

#define CLIENT_ID "my-client-id"
#define HOST "192.168.77.2"
#define PORT 1883
#define USERNAME "zigbee2mqtt"
#define PASSWORD "xoorei2uk2booSudies4Numoek1uot"
#define TOPIC "zigbee2mqtt/Kontaktsensor"
#define KEEPALIVE 10
#define WAIT_UNTIL_RECONNECT 10

static volatile bool terminate = false; // NOLINT

static void
handler(int signal)
{
	if ( signal == SIGINT ) {
		terminate = true;
	}
}

static void
cleanup(void)
{
	mosquitto_lib_cleanup();
}

static void
init(void)
{
	(void) signal(SIGINT, handler);

	mosquitto_lib_init();
	(void) atexit(cleanup);
}

static void
message_callback(struct mosquitto *mosq, void *obj, const struct mosquitto_message *message)
{
	UNUSED(obj);
	UNUSED(mosq);
	printf("message '%.*s' for topic '%s'\n",
	       message->payloadlen, (const char *) message->payload,
	       message->topic);
}

static struct mosquitto *
setup(void)
{
	struct mosquitto *client = mosquitto_new(CLIENT_ID, true, NULL);
	if ( client == NULL ) {
		(void) fprintf(stderr, "error on new client...\n");
		return NULL;
	}

	int err = mosquitto_username_pw_set(client, USERNAME, PASSWORD);
	if ( err != MOSQ_ERR_SUCCESS ) {
		(void) fprintf(stderr, "error: %s\n", mosquitto_strerror(err));
		mosquitto_destroy(client);
		return NULL;
	}

	mosquitto_message_callback_set(client, message_callback);

	err = mosquitto_connect(client, HOST, PORT, KEEPALIVE);
	if ( err != MOSQ_ERR_SUCCESS ) {
		(void) fprintf(stderr, "error: %s\n", mosquitto_strerror(err));
		mosquitto_destroy(client);
		return NULL;
	}

	return client;
}

static void
run(struct mosquitto *client)
{
	mosquitto_subscribe(client, NULL, TOPIC, 0);

	while ( !terminate ) {
		static const int defaultTimeout = -1; // 1000ms

		int err = mosquitto_loop(client, defaultTimeout, 1);
		if ( !terminate && err ) {
			(void) fprintf(stderr, "connection error: %s\n", mosquitto_strerror(err));
			sleep(WAIT_UNTIL_RECONNECT); // NOLINT
			mosquitto_reconnect(client);
		}
	}
}

static void
shutdown(struct mosquitto *client)
{
	mosquitto_disconnect(client);
	mosquitto_destroy(client);
}

int
main(void)
{
	init();

	struct mosquitto *client = setup();
	if ( client ) {
		run(client);
		shutdown(client);
	}

	return EXIT_SUCCESS;
}