thermometers/main.c

changeset 6
9db76e20e21e
parent 3
e854e3d704de
child 7
d74b26b2f217
equal deleted inserted replaced
5:8c44725dc4ad 6:9db76e20e21e
24 #include <stdlib.h> 24 #include <stdlib.h>
25 #include <unistd.h> 25 #include <unistd.h>
26 #include <getopt.h> 26 #include <getopt.h>
27 #include <sys/types.h> 27 #include <sys/types.h>
28 #include <signal.h> 28 #include <signal.h>
29 #include <string.h>
30 #include <errno.h>
31
32 #include <mosquitto.h>
29 33
30 34
31 #include "main.h" 35 #include "main.h"
36
37
38 #define STATUS_CONNECTING 0
39 #define STATUS_CONNACK_RECVD 1
40 #define STATUS_WAITING 2
41
42 /* Global variables for use in callbacks. See sub_client.c for an example of
43 * using a struct to hold variables for use in callbacks. */
44 static char *topic = NULL;
45 //static char *message = NULL;
46 //static long msglen = 0;
47 static int qos = 0;
48 //static int retain = 0;
49 static int status = STATUS_CONNECTING;
50 static int mid_sent = 0;
51 static int last_mid = -1;
52 static int last_mid_sent = -1;
53 static bool connected = true;
54 //static char *username = NULL;
55 //static char *password = NULL;
56 static bool disconnect_sent = false;
57 static bool quiet = false;
58 static bool debug = false;
59 static bool shutdown = false;
60
32 61
33 62
34 void help(void) 63 void help(void)
35 { 64 {
36 fprintf(stdout, "Usage: thermomeneters [-d] [-h]\n"); 65 fprintf(stdout, "Usage: thermomeneters [-d] [-h]\n");
41 70
42 71
43 void die(int onsig) 72 void die(int onsig)
44 { 73 {
45 switch (onsig) { 74 switch (onsig) {
46 case SIGHUP: fprintf(stdout, "[main] Hangup detected"); 75 case SIGHUP: fprintf(stdout, "[main] Hangup detected\n");
47 break; 76 break;
48 case SIGINT: fprintf(stdout, "[main] Interrupt from keyboard"); 77 case SIGINT: fprintf(stdout, "[main] Interrupt from keyboard\n");
49 break; 78 break;
50 case SIGTERM: fprintf(stdout, "[main] Termination signal received"); 79 case SIGTERM: fprintf(stdout, "[main] Termination signal received\n");
51 break; 80 break;
52 default: fprintf(stdout, "[main] die on signal %d", onsig); 81 default: fprintf(stdout, "[main] die on signal %d\n", onsig);
53 } 82 }
54 83
55 exit(onsig); 84 shutdown = true;
85 }
86
87
88
89 void my_connect_callback(struct mosquitto *mosq, void *obj, int result)
90 {
91 int rc = MOSQ_ERR_SUCCESS;
92
93 fprintf(stdout, (char *)"my_connect_callback result=%d\n", result);
94 if (!result) {
95 status = STATUS_CONNACK_RECVD;
96 } else {
97 fprintf(stderr, "%s\n", mosquitto_connack_string(result));
98 }
99 }
100
101
102
103 void my_disconnect_callback(struct mosquitto *mosq, void *obj, int rc)
104 {
105 fprintf(stdout, (char *)"my_disconnect_callback\n");
106 connected = false;
107 }
108
109
110
111 void my_publish_callback(struct mosquitto *mosq, void *obj, int mid)
112 {
113 fprintf(stdout, (char *)"my_publish_callback mid=%d\n", mid);
114
115 last_mid_sent = mid;
116 // if(mode == MSGMODE_STDIN_LINE){
117 // if(mid == last_mid){
118 // mosquitto_disconnect(mosq);
119 // disconnect_sent = true;
120 // }
121 // }else if(disconnect_sent == false){
122 // mosquitto_disconnect(mosq);
123 // disconnect_sent = true;
124 // }
125 }
126
127
128
129 void my_log_callback(struct mosquitto *mosq, void *obj, int level, const char *str)
130 {
131 printf("%s\n", str);
56 } 132 }
57 133
58 134
59 135
60 int main(int argc, char *argv[]) 136 int main(int argc, char *argv[])
61 { 137 {
62 int i, c; 138 int i, c, len, rc, rc2;
139 char *id = NULL;
140 char *host = (char *)"lx02.mbse.ym";
141 int port = 1883;
142 struct mosquitto *mosq = NULL;
143 char hostname[256], buf[1024];
144 int keepalive = 60;
145 unsigned int max_inflight = 20;
146 char err[1024];
63 147
64 while (1) { 148 while (1) {
65 int option_index = 0; 149 int option_index = 0;
66 static struct option long_options[] = { 150 static struct option long_options[] = {
67 {"debug", 0, 0, 'c'}, 151 {"debug", 0, 0, 'c'},
72 c = getopt_long(argc, argv, "dh", long_options, &option_index); 156 c = getopt_long(argc, argv, "dh", long_options, &option_index);
73 if (c == -1) 157 if (c == -1)
74 break; 158 break;
75 159
76 switch (c) { 160 switch (c) {
77 case 'd': 161 case 'd': debug = true;
78 break; 162 break;
79 case 'h': help(); 163 case 'h': help();
80 return 1; 164 return 1;
81 } 165 }
82 } 166 }
89 for (i = 0; i < NSIG; i++) { 173 for (i = 0; i < NSIG; i++) {
90 if ((i != SIGCHLD) && (i != SIGKILL) && (i != SIGSTOP)) 174 if ((i != SIGCHLD) && (i != SIGKILL) && (i != SIGSTOP))
91 signal(i, (void (*))die); 175 signal(i, (void (*))die);
92 } 176 }
93 177
94 178 /*
179 * Initialize mosquitto communication
180 */
181 mosquitto_lib_init();
182 hostname[0] = '\0';
183 gethostname(hostname, 256);
184 hostname[255] = '\0';
185 len = strlen("thermometers/") + 1 + strlen(hostname);
186 id = malloc(len);
187 if(!id) {
188 if (!quiet)
189 fprintf(stderr, "Error: Out of memory.\n");
190 mosquitto_lib_cleanup();
191 return 1;
192 }
193 snprintf(id, len, "thermometers/%s", hostname);
194 if(strlen(id) > MOSQ_MQTT_ID_MAX_LENGTH) {
195 /*
196 * Enforce maximum client id length of 23 characters
197 */
198 id[MOSQ_MQTT_ID_MAX_LENGTH] = '\0';
199 }
200
201 fprintf(stdout, "id: %s\n", id);
202
203 mosq = mosquitto_new(id, true, NULL);
204 if(!mosq) {
205 switch(errno) {
206 case ENOMEM:
207 if (!quiet)
208 fprintf(stderr, "Error: Out of memory.\n");
209 break;
210 case EINVAL:
211 if (!quiet)
212 fprintf(stderr, "Error: Invalid id.\n");
213 break;
214 }
215 mosquitto_lib_cleanup();
216 return 1;
217 }
218
219 if(debug) {
220 mosquitto_log_callback_set(mosq, my_log_callback);
221 }
222
223 /*
224 * Set our will
225 */
226 topic = malloc(28 + strlen(hostname));
227 sprintf(topic, "clients/%s/thermometers/state", hostname);
228 sprintf(buf, "0");
229 rc = mosquitto_will_set(mosq, topic, strlen(buf), buf, qos, true);
230 if (rc) {
231 if (rc == MOSQ_ERR_INVAL) {
232 fprintf(stderr, "Input parameters invalid\n");
233 } else if (rc == MOSQ_ERR_NOMEM) {
234 fprintf(stderr, "Out of Memory\n");
235 } else if (rc == MOSQ_ERR_PAYLOAD_SIZE) {
236 fprintf(stderr, "Invalid payload size\n");
237 }
238 mosquitto_lib_cleanup();
239 return rc;
240 }
241
242 mosquitto_max_inflight_messages_set(mosq, max_inflight);
243 mosquitto_connect_callback_set(mosq, my_connect_callback);
244 mosquitto_disconnect_callback_set(mosq, my_disconnect_callback);
245 mosquitto_publish_callback_set(mosq, my_publish_callback);
246
247 rc = mosquitto_connect(mosq, host, port, keepalive);
248 if (rc) {
249 if (rc == MOSQ_ERR_ERRNO) {
250 strerror_r(errno, err, 1024);
251 fprintf(stderr, "Error: %s\n", err);
252 } else {
253 fprintf(stderr, "Unable to connect (%d).\n", rc);
254 }
255 mosquitto_lib_cleanup();
256 return rc;
257 }
258
259 /*
260 * Initialise is complete, report our presence state
261 */
262 mosquitto_loop_start(mosq);
263
264 // topic = malloc(28 + strlen(hostname));
265 sprintf(topic, "clients/%s/thermometers/state", hostname);
266 sprintf(buf, "1");
267 rc2 = mosquitto_publish(mosq, &mid_sent, topic, strlen(buf), buf, qos, 1);
268 free(topic);
269
270
271 fprintf(stdout, (char *)"Enter loop, connected %d\n", connected);
272 do {
273 if (status == STATUS_CONNACK_RECVD) {
274 // fprintf(stdout, (char *)"Ok\n");
275 // if(fgets(buf, 1024, stdin)){
276 // buf[strlen(buf)-1] = '\0';
277 // rc2 = mosquitto_publish(mosq, &mid_sent, topic, strlen(buf), buf, qos, retain);
278 // if(rc2){
279 // if(!quiet) fprintf(stderr, "Error: Publish returned %d, disconnecting.\n", rc2);
280 // mosquitto_disconnect(mosq);
281 // }
282 // } else
283 if (shutdown) {
284 fprintf(stdout, (char *)"Shutdown\n");
285 topic = malloc(28 + strlen(hostname));
286 sprintf(topic, "clients/%s/thermometers/state", hostname);
287 sprintf(buf, "0");
288 rc2 = mosquitto_publish(mosq, &mid_sent, topic, strlen(buf), buf, qos, true);
289 free(topic);
290 last_mid = mid_sent;
291 status = STATUS_WAITING;
292 }
293 } else if (status == STATUS_WAITING) {
294 fprintf(stdout, (char *)"Waiting\n");
295 if (last_mid_sent == last_mid && disconnect_sent == false) {
296 mosquitto_disconnect(mosq);
297 disconnect_sent = true;
298 }
299 usleep(100000);
300 }
301 rc = MOSQ_ERR_SUCCESS;
302
303 } while(rc == MOSQ_ERR_SUCCESS && connected);
304 fprintf(stdout, (char *)"Out of loop\n");
305
306 mosquitto_loop_stop(mosq, false);
307
308 mosquitto_destroy(mosq);
309 mosquitto_lib_cleanup();
310
311 fprintf(stdout, (char *)"Bye Bye\n");
95 return 0; 312 return 0;
96 } 313 }
97 314

mercurial