RaspberrPi project source code
Guo Wenxue
6 days ago f7889e2ceddbc3e15ea4b5377d831f4432169f76
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;
b74ad5 72     pack_proc_t          pack_proc = packet_segmented_pack; /* use segmented string packet */
GW 73   //pack_proc_t          pack_proc = packet_json_pack;      /* use JSON string packet */
74   //pack_proc_t          pack_proc = packet_tlv_pack;       /* use TLV(Tag Length Value) packet */
bffa2b 75
GW 76     struct option opts[] = {
77         {"ipaddr", required_argument, NULL, 'i'},
78         {"port", required_argument, NULL, 'p'},
79         {"interval", required_argument, NULL, 'I'},
13d8a8 80         {"debug", no_argument, NULL, 'd'},
G 81         {"version", no_argument, NULL, 'v'},
82         {"help", no_argument, NULL, 'h'},
83         {NULL, 0, NULL, 0}
84     };
85
86     progname = (char *)basename(argv[0]);
87
88     /* Parser the command line parameters */
bffa2b 89     while( (rv=getopt_long(argc, argv, "i:p:I:dvh", opts, NULL)) != -1 )
13d8a8 90     {
bffa2b 91         switch (rv)
13d8a8 92         {
bffa2b 93             case 'i': /* set socket server hostname or IP address */
GW 94                 serverip=optarg;
95                 break;
96
97             case 'p': /* set socket server listen port */
98                 port=atoi(optarg);
99                 break;
100
101             case 'I': /* set report time interval */
102                 interval=atoi(optarg);
103                 break;
104
105
106             case 'd': /* set debug running */
13d8a8 107                 daemon = 0;
29b331 108                 logfile="console";
GW 109                 loglevel=LOG_LEVEL_DEBUG;
13d8a8 110                 break;
G 111
bffa2b 112             case 'v':  /* get software version */
13d8a8 113                 printf("%s version %s\n", progname, PROG_VERSION);
G 114                 return 0;
115
bffa2b 116             case 'h':  /* get help information */
GW 117                 print_usage(progname);
13d8a8 118                 return 0;
G 119
120             default:
121                 break;
122         }
123
bffa2b 124     }
GW 125
126     if( !serverip || !port )
127     {
128         print_usage(argv[0]);
129         return 0;
13d8a8 130     }
G 131
29b331 132     if( log_open(logfile, loglevel, logsize, THREAD_LOCK_NONE) < 0 )
GW 133     {
134         fprintf(stderr, "Initial log system failed\n");
135         return 1;
136     }
13d8a8 137
G 138     install_default_signal();
139
140     if( check_set_program_running(daemon, DAEMON_PIDFILE) < 0 )
141         goto cleanup;
142
bffa2b 143     log_info("program start running.\n");
GW 144
145     if( database_init("sock_client.db") < 0 )
146     {
147         return 2;
148     }
149
150     socket_init(&sock, serverip, port);
151
13d8a8 152     while( ! g_signal.stop )
G 153     {
bffa2b 154         /* +----------------------------------+
GW 155          * |  check and sample temperature    |
156          * +----------------------------------+*/
157
158         sample_flag = 0; /* clear sample flag */
159
160         if( check_sample_time(&last_time, interval) )
161         {
162             log_debug("start DS18B20 sample termperature\n");
163
164             if( (rv=ds18b20_get_temperature(&pack_info.temper)) < 0 )
165             {
166                 log_error("DS18B20 sample temperature failure, rv=%d\n", rv);
167                 continue;
168             }
169             log_info("DS18B20 sample termperature %.3f oC\n", pack_info.temper);
170
5b381c 171             get_devid(pack_info.devid, sizeof(pack_info.devid), 88);
bffa2b 172             get_time(&pack_info.sample_time);
GW 173
5b381c 174             pack_bytes = pack_proc(&pack_info, (uint8_t *)pack_buf, sizeof(pack_buf));
GW 175             log_dump(LOG_LEVEL_DEBUG, NULL, pack_buf, pack_bytes);
176
bffa2b 177             sample_flag = 1; /* set sample flag */
GW 178         }
179
180         /* +---------------------------------+
181          * |  check and do socket connect    |
182          * +---------------------------------+*/
183
184         /* start connect to server if not connected */
b74ad5 185         if( !socket_connected(&sock) )
bffa2b 186         {
GW 187             socket_connect(&sock);
188         }
189
190         /* +-------------------------------+
191          * |      socket disconnect        |
192          * +-------------------------------+*/
b74ad5 193         if( !socket_connected(&sock) )
bffa2b 194         {
GW 195             if( sample_flag )
196             {
197                 database_push_packet(pack_buf, pack_bytes);
198             }
199
200             continue;
201         }
202
203         /* +-------------------------------+
204          * |      socket connected         |
205          * +-------------------------------+*/
206
207         /*  socket send sample packet */
208         if( sample_flag )
209         {
210             log_debug("socket send sample packet bytes[%d]: %s\n", pack_bytes, pack_buf);
211             if( socket_send(&sock, pack_buf, pack_bytes) < 0 )
212             {
213                 log_warn("socket send sample packet failure, save it in database now.\n");
214                 database_push_packet(pack_buf, pack_bytes);
b74ad5 215                 continue;
bffa2b 216             }
GW 217         }
218
219         /*  socket send packet in database  */
220         if( !database_pop_packet(pack_buf, sizeof(pack_buf), &pack_bytes) )
221         {
222             log_debug("socket send database packet bytes[%d]: %s\n", pack_bytes, pack_buf);
223             if( socket_send(&sock, pack_buf, pack_bytes) < 0 )
224             {
225                 log_error("socket send database packet failure");
b74ad5 226                 continue;
bffa2b 227             }
GW 228             else
229             {
230                 log_warn("socket send database packet okay, remove it from database now.\n");
231                 database_del_packet();
232             }
233         }
234
b74ad5 235         msleep(5);
13d8a8 236     }
G 237
238 cleanup:
bffa2b 239     socket_term(&sock);
GW 240     database_term();
29b331 241     unlink(DAEMON_PIDFILE);
bffa2b 242     log_close();
13d8a8 243
G 244     return 0;
245 }
bffa2b 246
GW 247 int check_sample_time(time_t *last_time, int interval)
248 {
249     int                  need = 0; /* no need sample now */
250     time_t               now;
251
252     time(&now);
253
b74ad5 254     if( difftime(now, *last_time)>interval )
bffa2b 255     {
GW 256         need = 1; /* need sample now  */
257         *last_time = now;
258     }
259
260     return need;
261 }