/********************************************************************************* * Copyright: (C) 2019 LingYun IoT System Studio * All rights reserved. * * Filename: main.c * Description: This file * * Version: 1.0.0(29/01/19) * Author: Guo Wenxue * ChangeLog: 1, Release initial version on "29/01/19 15:34:41" * ********************************************************************************/ #include #include #include #include #include #include #include #include #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 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("-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 rv; char *progname=NULL; char *logfile="sock_client.log"; int loglevel=LOG_LEVEL_INFO; int logsize=10; /* logfile size max to 10K */ 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'}, {NULL, 0, NULL, 0} }; progname = (char *)basename(argv[0]); /* Parser the command line parameters */ while( (rv=getopt_long(argc, argv, "i:p:I:dvh", opts, NULL)) != -1 ) { switch (rv) { 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 */ printf("%s version %s\n", progname, PROG_VERSION); return 0; 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 ) { fprintf(stderr, "Initial log system failed\n"); return 1; } install_default_signal(); 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 ) { /* +----------------------------------+ * | 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, sizeof(pack_info.devid), 88); get_time(&pack_info.sample_time); pack_bytes = pack_proc(&pack_info, (uint8_t *)pack_buf, sizeof(pack_buf)); log_dump(LOG_LEVEL_DEBUG, NULL, pack_buf, pack_bytes); 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: 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; }