35 static int last_mid = -1; |
35 static int last_mid = -1; |
36 static int last_mid_sent = -1; |
36 static int last_mid_sent = -1; |
37 static bool connected = true; |
37 static bool connected = true; |
38 static bool disconnect_sent = false; |
38 static bool disconnect_sent = false; |
39 static bool shutdown = false; |
39 static bool shutdown = false; |
|
40 static pid_t pgrp, mypid; |
40 |
41 |
41 extern bool debug; |
42 extern bool debug; |
42 extern sys_config Config; |
43 extern sys_config Config; |
43 |
44 |
44 int server(void); |
45 int server(void); |
46 void die(int); |
47 void die(int); |
47 |
48 |
48 |
49 |
49 void help(void) |
50 void help(void) |
50 { |
51 { |
|
52 fprintf(stdout, "mbsePi-apps thermometers v%s starting\n\n", VERSION); |
51 fprintf(stdout, "Usage: thermomeneters [-d] [-h]\n"); |
53 fprintf(stdout, "Usage: thermomeneters [-d] [-h]\n"); |
52 fprintf(stdout, " -d --debug Debug on\n"); |
54 fprintf(stdout, " -d --debug Debug and run in foreground\n"); |
53 fprintf(stdout, " -h --help Display this help\n"); |
55 fprintf(stdout, " -h --help Display this help\n"); |
54 } |
56 } |
55 |
57 |
56 |
58 |
57 |
59 |
116 |
118 |
117 |
119 |
118 |
120 |
119 int main(int argc, char *argv[]) |
121 int main(int argc, char *argv[]) |
120 { |
122 { |
121 int rc, c, i; |
123 int rc, c, i; |
|
124 pid_t frk; |
122 |
125 |
123 while (1) { |
126 while (1) { |
124 int option_index = 0; |
127 int option_index = 0; |
125 static struct option long_options[] = { |
128 static struct option long_options[] = { |
126 {"debug", 0, 0, 'c'}, |
129 {"debug", 0, 0, 'c'}, |
140 } |
143 } |
141 } |
144 } |
142 |
145 |
143 openlog("thermometers", LOG_PID|LOG_CONS|LOG_NOWAIT, LOG_USER); |
146 openlog("thermometers", LOG_PID|LOG_CONS|LOG_NOWAIT, LOG_USER); |
144 syslog(LOG_NOTICE, "mbsePi-apps thermometers v%s starting", VERSION); |
147 syslog(LOG_NOTICE, "mbsePi-apps thermometers v%s starting", VERSION); |
|
148 if (debug) |
|
149 fprintf(stdout, "mbsePi-apps thermometers v%s starting\n", VERSION); |
145 |
150 |
146 if (rdconfig()) { |
151 if (rdconfig()) { |
147 fprintf(stderr, "Error reading configuration\n"); |
152 fprintf(stderr, "Error reading configuration\n"); |
148 syslog(LOG_NOTICE, "halted"); |
153 syslog(LOG_NOTICE, "halted"); |
149 return 1; |
154 return 1; |
157 for (i = 0; i < NSIG; i++) { |
162 for (i = 0; i < NSIG; i++) { |
158 if ((i != SIGCHLD) && (i != SIGKILL) && (i != SIGSTOP)) |
163 if ((i != SIGCHLD) && (i != SIGKILL) && (i != SIGSTOP)) |
159 signal(i, (void (*))die); |
164 signal(i, (void (*))die); |
160 } |
165 } |
161 |
166 |
162 rc = server(); |
167 |
|
168 if (debug) { |
|
169 /* |
|
170 * For debugging run in foreground. |
|
171 */ |
|
172 rc = server(); |
|
173 } else { |
|
174 /* |
|
175 * Server initialization is complete. Now we can fork the |
|
176 * daemon and return to the user. We need to do a setpgrp |
|
177 * so that the daemon will no longer be assosiated with the |
|
178 * users control terminal. This is done before the fork, so |
|
179 * that the child will not be a process group leader. Otherwise, |
|
180 * if the child were to open a terminal, it would become |
|
181 * associated with that terminal as its control terminal. |
|
182 */ |
|
183 if ((pgrp = setpgid(0, 0)) == -1) { |
|
184 syslog(LOG_NOTICE, "setpgpid failed"); |
|
185 } |
|
186 |
|
187 frk = fork(); |
|
188 switch (frk) { |
|
189 case -1: |
|
190 syslog(LOG_NOTICE, "Daemon fork failed: %s", strerror(errno)); |
|
191 syslog(LOG_NOTICE, "Finished, rc=1"); |
|
192 exit(1); |
|
193 case 0: /* |
|
194 * Run the daemon |
|
195 */ |
|
196 fclose(stdin); |
|
197 if (open("/dev/null", O_RDONLY) != 0) { |
|
198 syslog(LOG_NOTICE, "Reopen of stdin to /dev/null failed"); |
|
199 _exit(2); |
|
200 } |
|
201 fclose(stdout); |
|
202 if (open("/dev/null", O_WRONLY | O_APPEND | O_CREAT,0600) != 1) { |
|
203 syslog(LOG_NOTICE, "Reopen of stdout to /dev/null failed"); |
|
204 _exit(2); |
|
205 } |
|
206 fclose(stderr); |
|
207 if (open("/dev/null", O_WRONLY | O_APPEND | O_CREAT,0600) != 2) { |
|
208 syslog(LOG_NOTICE, "Reopen of stderr to /dev/null failed"); |
|
209 _exit(2); |
|
210 } |
|
211 mypid = getpid(); |
|
212 rc = server(); |
|
213 break; |
|
214 /* Not reached */ |
|
215 default: |
|
216 /* |
|
217 * Here we detach this process and let the child |
|
218 * run the deamon process. |
|
219 */ |
|
220 syslog(LOG_NOTICE, "Starting daemon with pid %d", frk); |
|
221 exit(0); |
|
222 } |
|
223 } |
|
224 |
163 syslog(LOG_NOTICE, "Finished, rc=%d", rc); |
225 syslog(LOG_NOTICE, "Finished, rc=%d", rc); |
164 return rc; |
226 return rc; |
165 } |
227 } |
166 |
228 |
167 |
229 |
222 */ |
284 */ |
223 state = xstrcpy((char *)"clients/"); |
285 state = xstrcpy((char *)"clients/"); |
224 state = xstrcat(state, hostname); |
286 state = xstrcat(state, hostname); |
225 state = xstrcat(state, (char *)"/thermometers/state"); |
287 state = xstrcat(state, (char *)"/thermometers/state"); |
226 sprintf(buf, "0"); |
288 sprintf(buf, "0"); |
227 |
289 if ((rc = mosquitto_will_set(mosq, state, strlen(buf), buf, qos, true))) { |
228 rc = mosquitto_will_set(mosq, state, strlen(buf), buf, qos, true); |
|
229 if (rc) { |
|
230 if (rc == MOSQ_ERR_INVAL) { |
290 if (rc == MOSQ_ERR_INVAL) { |
231 syslog(LOG_NOTICE, "mosquitto_will_set: input parameters invalid"); |
291 syslog(LOG_NOTICE, "mosquitto_will_set: input parameters invalid"); |
232 } else if (rc == MOSQ_ERR_NOMEM) { |
292 } else if (rc == MOSQ_ERR_NOMEM) { |
233 syslog(LOG_NOTICE, "mosquitto_will_set: Out of Memory"); |
293 syslog(LOG_NOTICE, "mosquitto_will_set: Out of Memory"); |
234 } else if (rc == MOSQ_ERR_PAYLOAD_SIZE) { |
294 } else if (rc == MOSQ_ERR_PAYLOAD_SIZE) { |
241 mosquitto_max_inflight_messages_set(mosq, max_inflight); |
301 mosquitto_max_inflight_messages_set(mosq, max_inflight); |
242 mosquitto_connect_callback_set(mosq, my_connect_callback); |
302 mosquitto_connect_callback_set(mosq, my_connect_callback); |
243 mosquitto_disconnect_callback_set(mosq, my_disconnect_callback); |
303 mosquitto_disconnect_callback_set(mosq, my_disconnect_callback); |
244 mosquitto_publish_callback_set(mosq, my_publish_callback); |
304 mosquitto_publish_callback_set(mosq, my_publish_callback); |
245 |
305 |
246 rc = mosquitto_connect(mosq, Config.mosq_host, Config.mosq_port, keepalive); |
306 if ((rc = mosquitto_connect(mosq, Config.mosq_host, Config.mosq_port, keepalive))) { |
247 if (rc) { |
|
248 if (rc == MOSQ_ERR_ERRNO) { |
307 if (rc == MOSQ_ERR_ERRNO) { |
249 strerror_r(errno, err, 1024); |
308 strerror_r(errno, err, 1024); |
250 syslog(LOG_NOTICE, "mosquitto_connect: error: %s", err); |
309 syslog(LOG_NOTICE, "mosquitto_connect: error: %s", err); |
251 } else { |
310 } else { |
252 syslog(LOG_NOTICE, "mosquitto_connect: unable to connect (%d)", rc); |
311 syslog(LOG_NOTICE, "mosquitto_connect: unable to connect (%d)", rc); |
261 */ |
320 */ |
262 mosquitto_loop_start(mosq); |
321 mosquitto_loop_start(mosq); |
263 sprintf(buf, "1"); |
322 sprintf(buf, "1"); |
264 rc = mosquitto_publish(mosq, &mid_sent, state, strlen(buf), buf, qos, 1); |
323 rc = mosquitto_publish(mosq, &mid_sent, state, strlen(buf), buf, qos, 1); |
265 |
324 |
266 fprintf(stdout, (char *)"Enter loop, connected %d\n", connected); |
325 if (debug) |
|
326 fprintf(stdout, (char *)"Enter loop, connected %d\n", connected); |
|
327 |
267 do { |
328 do { |
268 if (status == STATUS_CONNACK_RECVD) { |
329 if (status == STATUS_CONNACK_RECVD) { |
269 /* |
330 /* |
270 * Here send our sensors values |
331 * Here send our 1-wire sensors values |
271 */ |
332 */ |
272 for (tmp1 = Config.w1therms; tmp1; tmp1 = old1) { |
333 for (tmp1 = Config.w1therms; tmp1; tmp1 = old1) { |
273 old1 = tmp1->next; |
334 old1 = tmp1->next; |
274 |
335 |
275 /* |
336 /* |
359 mosquitto_publish(mosq, &mid_sent, state, strlen(buf), buf, qos, true); |
421 mosquitto_publish(mosq, &mid_sent, state, strlen(buf), buf, qos, true); |
360 last_mid = mid_sent; |
422 last_mid = mid_sent; |
361 status = STATUS_WAITING; |
423 status = STATUS_WAITING; |
362 } |
424 } |
363 } else if (status == STATUS_WAITING) { |
425 } else if (status == STATUS_WAITING) { |
364 fprintf(stdout, (char *)"Waiting\n"); |
426 if (debug) |
|
427 fprintf(stdout, (char *)"Waiting\n"); |
365 if (last_mid_sent == last_mid && disconnect_sent == false) { |
428 if (last_mid_sent == last_mid && disconnect_sent == false) { |
366 mosquitto_disconnect(mosq); |
429 mosquitto_disconnect(mosq); |
367 disconnect_sent = true; |
430 disconnect_sent = true; |
368 } |
431 } |
369 usleep(100000); |
432 usleep(100000); |
370 } |
433 } |
371 rc = MOSQ_ERR_SUCCESS; |
434 rc = MOSQ_ERR_SUCCESS; |
372 |
435 |
373 } while(rc == MOSQ_ERR_SUCCESS && connected); |
436 } while (rc == MOSQ_ERR_SUCCESS && connected); |
374 fprintf(stdout, (char *)"Out of loop\n"); |
437 |
|
438 if (debug) |
|
439 fprintf(stdout, (char *)"Out of loop\n"); |
375 |
440 |
376 mosquitto_loop_stop(mosq, false); |
441 mosquitto_loop_stop(mosq, false); |
377 |
|
378 mosquitto_destroy(mosq); |
442 mosquitto_destroy(mosq); |
379 mosquitto_lib_cleanup(); |
443 mosquitto_lib_cleanup(); |
380 |
444 |
381 return 0; |
445 return rc; |
382 } |
446 } |
383 |
447 |