| | |
| | | #include "logger.h" |
| | | #include "ds18b20.h" |
| | | #include "proc.h" |
| | | #include "packet.h" |
| | | #include "socket.h" |
| | | #include "database.h" |
| | | |
| | | #define PROG_VERSION "v1.0.0" |
| | | #define DAEMON_PIDFILE "/tmp/.socketd.pid" |
| | | |
| | | static void program_usage(char *progname) |
| | | static void print_usage(char *progname) |
| | | { |
| | | |
| | | printf("Usage: %s [OPTION]...\n", progname); |
| | | printf(" %s is LingYun studio temperature socket client program running on RaspberryPi\n", progname); |
| | | |
| | | printf("\nMandatory arguments to long options are mandatory for short options too:\n"); |
| | | printf(" -d[debug ] Running in debug mode\n"); |
| | | printf(" -h[help ] Display this help information\n"); |
| | | printf(" -v[version ] Display the program version\n"); |
| | | printf("-i(ipaddr) : sepcify server IP address\n"); |
| | | printf("-p(--port) : sepcify server port.\n"); |
| | | printf("-I(--interval): sepcify report time interval, default 60 seconds\n"); |
| | | printf("-d(--debug) : running in debug mode\n"); |
| | | printf("-h(--help) : display this help information\n"); |
| | | printf("-v(--version) : display the program version\n"); |
| | | |
| | | printf("\n%s version %s\n", progname, PROG_VERSION); |
| | | return; |
| | | } |
| | | |
| | | int check_sample_time(time_t *last_time, int interval); |
| | | |
| | | int main (int argc, char **argv) |
| | | { |
| | | int daemon = 1; |
| | | int opt; |
| | | int rv; |
| | | |
| | | char *progname=NULL; |
| | | char *logfile="client.log"; |
| | | char *logfile="sock_client.log"; |
| | | int loglevel=LOG_LEVEL_INFO; |
| | | int logsize=10; /* logfile size max to 10K */ |
| | | |
| | | struct option long_options[] = { |
| | | char *serverip = NULL; |
| | | int port = 0; |
| | | int interval = 60; /* default report termperature every 60 seconds */ |
| | | |
| | | socket_ctx_t sock; |
| | | time_t last_time = 0; |
| | | int sample_flag = 0; |
| | | |
| | | char pack_buf[1024]; |
| | | int pack_bytes = 0; |
| | | pack_info_t pack_info; |
| | | pack_proc_t pack_proc = packet_segmented_pack; /* use string packet */ |
| | | |
| | | struct option opts[] = { |
| | | {"ipaddr", required_argument, NULL, 'i'}, |
| | | {"port", required_argument, NULL, 'p'}, |
| | | {"interval", required_argument, NULL, 'I'}, |
| | | {"debug", no_argument, NULL, 'd'}, |
| | | {"version", no_argument, NULL, 'v'}, |
| | | {"help", no_argument, NULL, 'h'}, |
| | |
| | | progname = (char *)basename(argv[0]); |
| | | |
| | | /* Parser the command line parameters */ |
| | | while ((opt = getopt_long(argc, argv, "dvh", long_options, NULL)) != -1) |
| | | while( (rv=getopt_long(argc, argv, "i:p:I:dvh", opts, NULL)) != -1 ) |
| | | { |
| | | switch (opt) |
| | | switch (rv) |
| | | { |
| | | case 'd': /* Set debug running */ |
| | | case 'i': /* set socket server hostname or IP address */ |
| | | serverip=optarg; |
| | | break; |
| | | |
| | | case 'p': /* set socket server listen port */ |
| | | port=atoi(optarg); |
| | | break; |
| | | |
| | | case 'I': /* set report time interval */ |
| | | interval=atoi(optarg); |
| | | break; |
| | | |
| | | |
| | | case 'd': /* set debug running */ |
| | | daemon = 0; |
| | | logfile="console"; |
| | | loglevel=LOG_LEVEL_DEBUG; |
| | | break; |
| | | |
| | | case 'v': /* Get software version */ |
| | | case 'v': /* get software version */ |
| | | printf("%s version %s\n", progname, PROG_VERSION); |
| | | return 0; |
| | | |
| | | case 'h': /* Get help information */ |
| | | program_usage(progname); |
| | | case 'h': /* get help information */ |
| | | print_usage(progname); |
| | | return 0; |
| | | |
| | | default: |
| | | break; |
| | | } |
| | | |
| | | } |
| | | |
| | | if( !serverip || !port ) |
| | | { |
| | | print_usage(argv[0]); |
| | | return 0; |
| | | } |
| | | |
| | | if( log_open(logfile, loglevel, logsize, THREAD_LOCK_NONE) < 0 ) |
| | |
| | | if( check_set_program_running(daemon, DAEMON_PIDFILE) < 0 ) |
| | | goto cleanup; |
| | | |
| | | log_info("program start running.\n"); |
| | | |
| | | if( database_init("sock_client.db") < 0 ) |
| | | { |
| | | return 2; |
| | | } |
| | | |
| | | socket_init(&sock, serverip, port); |
| | | |
| | | while( ! g_signal.stop ) |
| | | { |
| | | msleep(1000); |
| | | /* +----------------------------------+ |
| | | * | check and sample temperature | |
| | | * +----------------------------------+*/ |
| | | |
| | | sample_flag = 0; /* clear sample flag */ |
| | | |
| | | if( check_sample_time(&last_time, interval) ) |
| | | { |
| | | log_debug("start DS18B20 sample termperature\n"); |
| | | |
| | | if( (rv=ds18b20_get_temperature(&pack_info.temper)) < 0 ) |
| | | { |
| | | log_error("DS18B20 sample temperature failure, rv=%d\n", rv); |
| | | continue; |
| | | } |
| | | log_info("DS18B20 sample termperature %.3f oC\n", pack_info.temper); |
| | | |
| | | get_devid(pack_info.devid, DEVID_LEN, 40); |
| | | get_time(&pack_info.sample_time); |
| | | |
| | | pack_bytes = pack_proc(&pack_info, pack_buf, sizeof(pack_buf)); |
| | | sample_flag = 1; /* set sample flag */ |
| | | } |
| | | |
| | | /* +---------------------------------+ |
| | | * | check and do socket connect | |
| | | * +---------------------------------+*/ |
| | | |
| | | /* start connect to server if not connected */ |
| | | if( sock.fd < 0 ) |
| | | { |
| | | socket_connect(&sock); |
| | | } |
| | | |
| | | /* check socket connected or not */ |
| | | if( sock_check_connect(sock.fd) < 0 ) |
| | | { |
| | | if( sock.fd > 0 ) |
| | | { |
| | | log_error("socket got disconnected, terminate it and reconnect now.\n"); |
| | | socket_term(&sock); /* close the soket */ |
| | | } |
| | | } |
| | | |
| | | /* +-------------------------------+ |
| | | * | socket disconnect | |
| | | * +-------------------------------+*/ |
| | | if( sock.fd < 0 ) |
| | | { |
| | | if( sample_flag ) |
| | | { |
| | | database_push_packet(pack_buf, pack_bytes); |
| | | } |
| | | |
| | | continue; |
| | | } |
| | | |
| | | /* +-------------------------------+ |
| | | * | socket connected | |
| | | * +-------------------------------+*/ |
| | | |
| | | /* socket send sample packet */ |
| | | if( sample_flag ) |
| | | { |
| | | log_debug("socket send sample packet bytes[%d]: %s\n", pack_bytes, pack_buf); |
| | | if( socket_send(&sock, pack_buf, pack_bytes) < 0 ) |
| | | { |
| | | log_warn("socket send sample packet failure, save it in database now.\n"); |
| | | database_push_packet(pack_buf, pack_bytes); |
| | | socket_term(&sock); /* close the soket */ |
| | | } |
| | | } |
| | | |
| | | /* socket send packet in database */ |
| | | if( !database_pop_packet(pack_buf, sizeof(pack_buf), &pack_bytes) ) |
| | | { |
| | | log_debug("socket send database packet bytes[%d]: %s\n", pack_bytes, pack_buf); |
| | | if( socket_send(&sock, pack_buf, pack_bytes) < 0 ) |
| | | { |
| | | log_error("socket send database packet failure"); |
| | | socket_term(&sock); /* close the soket */ |
| | | } |
| | | else |
| | | { |
| | | log_warn("socket send database packet okay, remove it from database now.\n"); |
| | | database_del_packet(); |
| | | } |
| | | } |
| | | |
| | | msleep(50); |
| | | } |
| | | |
| | | cleanup: |
| | | log_close(); |
| | | socket_term(&sock); |
| | | database_term(); |
| | | unlink(DAEMON_PIDFILE); |
| | | log_close(); |
| | | |
| | | return 0; |
| | | } |
| | | |
| | | int check_sample_time(time_t *last_time, int interval) |
| | | { |
| | | int need = 0; /* no need sample now */ |
| | | time_t now; |
| | | |
| | | time(&now); |
| | | |
| | | if( now >= *last_time+interval ) |
| | | { |
| | | need = 1; /* need sample now */ |
| | | *last_time = now; |
| | | } |
| | | |
| | | return need; |
| | | } |