RaspberrPi project source code
guowenxue
2024-03-14 7fa125e56f1de17c2f6aeb9a410ff02ac4e78e85
commit | author | age
13d8a8 1 /*********************************************************************************
G 2  *      Copyright:  (C) 2019 LingYun IoT System Studio
3  *                  All rights reserved.
4  *
5  *       Filename:  main.c
6  *    Description:  This file
7  *
8  *        Version:  1.0.0(29/01/19)
9  *         Author:  Guo Wenxue <guowenxue@gmail.com>
10  *      ChangeLog:  1, Release initial version on "29/01/19 15:34:41"
11  *
12  ********************************************************************************/
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <unistd.h>
16 #include <time.h>
17 #include <getopt.h>
18 #include <libgen.h>
19 #include <string.h>
20 #include <errno.h>
21
22 #include "logger.h"
23 #include "ds18b20.h"
24 #include "proc.h"
bffa2b 25 #include "packet.h"
GW 26 #include "socket.h"
27 #include "database.h"
13d8a8 28
G 29 #define PROG_VERSION               "v1.0.0"
30 #define DAEMON_PIDFILE             "/tmp/.socketd.pid"
31
bffa2b 32 static void print_usage(char *progname)
13d8a8 33 {
G 34     printf("Usage: %s [OPTION]...\n", progname);
35     printf(" %s is LingYun studio temperature socket client program running on RaspberryPi\n", progname);
36
37     printf("\nMandatory arguments to long options are mandatory for short options too:\n");
bffa2b 38     printf("-i(ipaddr)    : sepcify server IP address\n");
GW 39     printf("-p(--port)    : sepcify server port.\n");
40     printf("-I(--interval): sepcify report time interval, default 60 seconds\n");
41     printf("-d(--debug)   : running in debug mode\n");
42     printf("-h(--help)    : display this help information\n");
43     printf("-v(--version) : display the program version\n");
13d8a8 44
G 45     printf("\n%s version %s\n", progname, PROG_VERSION);
46     return;
47 }
48
bffa2b 49 int check_sample_time(time_t *last_time, int interval);
GW 50
13d8a8 51 int main (int argc, char **argv)
G 52 {
53     int                daemon = 1;
bffa2b 54     int                rv;
GW 55
13d8a8 56     char              *progname=NULL;
bffa2b 57     char              *logfile="sock_client.log";
29b331 58     int                loglevel=LOG_LEVEL_INFO;
GW 59     int                logsize=10; /* logfile size max to 10K */
13d8a8 60
bffa2b 61     char              *serverip = NULL;
GW 62     int                port = 0;
63     int                interval = 60; /* default report termperature every 60 seconds */
64
65     socket_ctx_t         sock;
66     time_t               last_time = 0;
67     int                  sample_flag = 0;
68
69     char                 pack_buf[1024];
70     int                  pack_bytes = 0;
71     pack_info_t          pack_info;
72     pack_proc_t          pack_proc = packet_segmented_pack; /* use string packet */
73
74     struct option opts[] = {
75         {"ipaddr", required_argument, NULL, 'i'},
76         {"port", required_argument, NULL, 'p'},
77         {"interval", required_argument, NULL, 'I'},
13d8a8 78         {"debug", no_argument, NULL, 'd'},
G 79         {"version", no_argument, NULL, 'v'},
80         {"help", no_argument, NULL, 'h'},
81         {NULL, 0, NULL, 0}
82     };
83
84     progname = (char *)basename(argv[0]);
85
86     /* Parser the command line parameters */
bffa2b 87     while( (rv=getopt_long(argc, argv, "i:p:I:dvh", opts, NULL)) != -1 )
13d8a8 88     {
bffa2b 89         switch (rv)
13d8a8 90         {
bffa2b 91             case 'i': /* set socket server hostname or IP address */
GW 92                 serverip=optarg;
93                 break;
94
95             case 'p': /* set socket server listen port */
96                 port=atoi(optarg);
97                 break;
98
99             case 'I': /* set report time interval */
100                 interval=atoi(optarg);
101                 break;
102
103
104             case 'd': /* set debug running */
13d8a8 105                 daemon = 0;
29b331 106                 logfile="console";
GW 107                 loglevel=LOG_LEVEL_DEBUG;
13d8a8 108                 break;
G 109
bffa2b 110             case 'v':  /* get software version */
13d8a8 111                 printf("%s version %s\n", progname, PROG_VERSION);
G 112                 return 0;
113
bffa2b 114             case 'h':  /* get help information */
GW 115                 print_usage(progname);
13d8a8 116                 return 0;
G 117
118             default:
119                 break;
120         }
121
bffa2b 122     }
GW 123
124     if( !serverip || !port )
125     {
126         print_usage(argv[0]);
127         return 0;
13d8a8 128     }
G 129
29b331 130     if( log_open(logfile, loglevel, logsize, THREAD_LOCK_NONE) < 0 )
GW 131     {
132         fprintf(stderr, "Initial log system failed\n");
133         return 1;
134     }
13d8a8 135
G 136     install_default_signal();
137
138     if( check_set_program_running(daemon, DAEMON_PIDFILE) < 0 )
139         goto cleanup;
140
bffa2b 141     log_info("program start running.\n");
GW 142
143     if( database_init("sock_client.db") < 0 )
144     {
145         return 2;
146     }
147
148     socket_init(&sock, serverip, port);
149
13d8a8 150     while( ! g_signal.stop )
G 151     {
bffa2b 152         /* +----------------------------------+
GW 153          * |  check and sample temperature    |
154          * +----------------------------------+*/
155
156         sample_flag = 0; /* clear sample flag */
157
158         if( check_sample_time(&last_time, interval) )
159         {
160             log_debug("start DS18B20 sample termperature\n");
161
162             if( (rv=ds18b20_get_temperature(&pack_info.temper)) < 0 )
163             {
164                 log_error("DS18B20 sample temperature failure, rv=%d\n", rv);
165                 continue;
166             }
167             log_info("DS18B20 sample termperature %.3f oC\n", pack_info.temper);
168
169             get_devid(pack_info.devid, DEVID_LEN, 40);
170             get_time(&pack_info.sample_time);
171
172             pack_bytes = pack_proc(&pack_info, pack_buf, sizeof(pack_buf));
173             sample_flag = 1; /* set sample flag */
174         }
175
176         /* +---------------------------------+
177          * |  check and do socket connect    |
178          * +---------------------------------+*/
179
180         /* start connect to server if not connected */
181         if( sock.fd < 0 )
182         {
183             socket_connect(&sock);
184         }
185
186         /* check socket connected or not  */
187         if( sock_check_connect(sock.fd) < 0 )
188         {
189             if( sock.fd > 0 )
190             {
191                 log_error("socket got disconnected, terminate it and reconnect now.\n");
192                 socket_term(&sock); /* close the soket */
193             }
194         }
195
196         /* +-------------------------------+
197          * |      socket disconnect        |
198          * +-------------------------------+*/
199         if( sock.fd < 0 )
200         {
201             if( sample_flag )
202             {
203                 database_push_packet(pack_buf, pack_bytes);
204             }
205
206             continue;
207         }
208
209         /* +-------------------------------+
210          * |      socket connected         |
211          * +-------------------------------+*/
212
213         /*  socket send sample packet */
214         if( sample_flag )
215         {
216             log_debug("socket send sample packet bytes[%d]: %s\n", pack_bytes, pack_buf);
217             if( socket_send(&sock, pack_buf, pack_bytes) < 0 )
218             {
219                 log_warn("socket send sample packet failure, save it in database now.\n");
220                 database_push_packet(pack_buf, pack_bytes);
221                 socket_term(&sock); /* close the soket */
222             }
223         }
224
225         /*  socket send packet in database  */
226         if( !database_pop_packet(pack_buf, sizeof(pack_buf), &pack_bytes) )
227         {
228             log_debug("socket send database packet bytes[%d]: %s\n", pack_bytes, pack_buf);
229             if( socket_send(&sock, pack_buf, pack_bytes) < 0 )
230             {
231                 log_error("socket send database packet failure");
232                 socket_term(&sock); /* close the soket */
233             }
234             else
235             {
236                 log_warn("socket send database packet okay, remove it from database now.\n");
237                 database_del_packet();
238             }
239         }
240
241         msleep(50);
13d8a8 242     }
G 243
244 cleanup:
bffa2b 245     socket_term(&sock);
GW 246     database_term();
29b331 247     unlink(DAEMON_PIDFILE);
bffa2b 248     log_close();
13d8a8 249
G 250     return 0;
251 }
bffa2b 252
GW 253 int check_sample_time(time_t *last_time, int interval)
254 {
255     int                  need = 0; /* no need sample now */
256     time_t               now;
257
258     time(&now);
259
260     if( now >= *last_time+interval )
261     {
262         need = 1; /* need sample now  */
263         *last_time = now;
264     }
265
266     return need;
267 }