From d81310d55b9b7d07904c19f879f50e52fd7be489 Mon Sep 17 00:00:00 2001
From: guowenxue <guowenxue@gmail.com>
Date: Mon, 06 Nov 2023 16:52:08 +0800
Subject: [PATCH] Add new code

---
 prj1_tlv/tlv_client.c |  211 +++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 204 insertions(+), 7 deletions(-)

diff --git a/prj1_tlv/tlv_client.c b/prj1_tlv/tlv_client.c
index 4f00ac2..a8108bc 100644
--- a/prj1_tlv/tlv_client.c
+++ b/prj1_tlv/tlv_client.c
@@ -19,10 +19,21 @@
 
 #include "logger.h"
 #include "proc.h"
+#include "ds18b20.h"
+#include "socket.h"
+#include "tlv_pack.h"
+#include "sqlite_cli.h"
 
 #define PROG_VERSION     "1.0.0"
+#define RPI_SN           "RPI00001"
 
 #define DEF_LOG_FILE     "tlv_client.log"
+
+#define DEF_ACK_TIMEOUT  2  /* wait for ACK timeout value */
+#define DEF_RETRYTIMES   3  /* receive ACK timeout or get NAK, retry to send times */
+int socket_send_tlv_pack(socket_t *sock, tlv_buf_t *tlv, int timeout, int retry_times);
+
+int packtlv_msg(tlv_buf_t *tlv, char *sn, uint16_t temp, struct tm *tm);
 
 static void banner(void)
 {
@@ -38,6 +49,7 @@
     printf("This program used to connect to server and send RPi's temperature by TLV protocal.\n");
 
     printf("\nMandatory arguments to long options are mandatory for short options too:\n");
+    printf(" -H[Host    ]  Specify host server address and port, foramt as \"127.0.0.1:9000\"\n");
     printf(" -d[debug   ]  Running in debug mode\n");
     printf(" -l[level   ]  Set the log level as [0..%d]\n", LOG_LEVEL_MAX-1); 
     printf(" -h[help    ]  Display this help information\n"); 
@@ -52,17 +64,27 @@
 { 
     int                   opt; 
     int                   i = 0; 
-    //int                   rv = 0; 
+    int                   rv = 0; 
     int                   debug = 0;
 
     char                  pid_file[64] = { 0 }; /* The file used to record the PID */
     const char           *progname=NULL;
 
+    char                 *host = "127.0.0.1:10086";
+    //char                 *host = "baidu.com:10086";
     int                   log_level = LOG_LEVEL_NRML;
     char                 *log_file = DEF_LOG_FILE;
+
     logger_t              logger;
+    socket_t              sock;
+    tlv_buf_t             tlv;
+
+    uint16_t              temp;
+    struct                tm *tm;
+    time_t                cur_time, last_time = 0;
 
     struct option long_options[] = { 
+        {"Host", required_argument, NULL, 'H'}, 
         {"debug", no_argument, NULL, 'd'}, 
         {"level", required_argument, NULL, 'l'}, 
         {"version", no_argument, NULL, 'v'}, 
@@ -70,15 +92,19 @@
         {NULL, 0, NULL, 0}
     };
 
+    memset(&sock, 0, sizeof(sock));
     memset(&logger, 0, sizeof(logger));
 
     progname = basename(argv[0]); /* get program name */
 
     /* parser the command line parameters */ 
-    while ((opt = getopt_long(argc, argv, "c:dl:vh", long_options, NULL)) != -1) 
+    while ((opt = getopt_long(argc, argv, "H:dl:vh", long_options, NULL)) != -1) 
     { 
         switch (opt) 
         {
+            case 'H':
+                host=optarg;
+                break;
 
             case 'd': /* set debug running */
                 debug = 1;
@@ -105,8 +131,14 @@
         } 
     }
 
+    if( !host )
+    {
+        printf("ERROR: No argument specify host server address and port, please refer to usage\n");
+        return 1;
+    }
+
     /* check program already running or not, if already running then exit, or set running as daemon */
-    snprintf(pid_file, sizeof(pid_file), "/var/run/%s.pid", progname);
+    snprintf(pid_file, sizeof(pid_file), "/tmp/%s.pid", progname);
     if( !debug )
     {
         if( check_daemon_running(pid_file) )
@@ -114,29 +146,194 @@
             printf("Programe already running, exit now.\n");
             return -1;
         }
+
+        set_daemon_running(pid_file);
     }
+
+    record_daemon_pid(pid_file);
 
     /* initial and open logger system */
     if( logger_init(&logger, log_file, log_level, 512)<0 || logger_open()<0 )
     {
         printf("ERROR: Initialise logger system failure\n");
-        return -1;
+        return 2;
     }
+
+    log_nrml("Program start running\n");
 
     /* install signal proc handler */
     install_proc_signal();
 
-    log_nrml("Program start running\n");
+    if( clidb_init("./tlv_client.db")< 0) 
+    {
+        log_err("initial sqlite database failure\n");
+        return 3;
+    }
+
+    last_time = 0;
 
     /* g_signal.stop defined in proc.c, and will be set when catch stop signal */
     while( !g_signal.stop )
     {
-        log_dbg("Program still running\n");
-        sleep(3);
+        time(&cur_time);
+        if( cur_time-last_time > 10)
+        {
+            log_nrml("start sample temperature now.\n");
+            rv = 0;
+            temp = 0x1122;
+            //rv = ds18b20_get_temperature(&temp);
+            if( 0 == rv )
+            {
+                /* convert time_t to tm format  */ 
+                tm=localtime(&cur_time);
+                last_time = cur_time;
+
+                packtlv_msg(&tlv, RPI_SN, temp, tm);
+                logger_dump(LOG_LEVEL_DEBUG, tlv.buf, tlv.len);
+
+                /* this message need to be transmit and saved in database if send failure */
+                tlv.flag = TLV_FLAG_TX | TLV_FLAG_DB;
+            }
+            else
+            {
+                log_err("DS18B20 get temperature failure\n");
+            }
+        }
+
+        if( SOCK_STAT_CONNECTED != sock.status )
+        {
+            if( socket_connect(&sock, -1, host, MODE_NONBLOCK) < 0)
+            {
+                log_err("connect to server [%s:%d] failure\n", sock.raddr, sock.rport);
+            }
+        }
+
+        if( SOCK_STAT_CONNECTED == sock.status )
+        {
+            /* send current new sample TLV packet  */
+            if( tlv.flag&TLV_FLAG_TX )
+            { 
+                if(0 == socket_send_tlv_pack(&sock, &tlv, DEF_ACK_TIMEOUT, DEF_RETRYTIMES) ) 
+                {
+                    tlv.flag = 0;
+                }
+            }
+
+            /* get TLV apcket from database and send it by socket, maxim 5 records  */ 
+            for(i=0; i<5; i++)
+            {
+                int            id;
+                tlv_buf_t      tmp;
+
+                if( clidb_pop_tlvpack(&tmp, &id) <= 0 ) 
+                {
+                    break;
+                }
+
+                /* send the TLV packet from database */
+                if(0 == socket_send_tlv_pack(&sock, &tmp, DEF_ACK_TIMEOUT, DEF_RETRYTIMES) ) 
+                {
+                    /* delete the record from DB */
+                    clidb_del_tlvpack(id);
+                }
+            }
+
+        }
+
+        if( tlv.flag & TLV_FLAG_DB )
+        {
+            clidb_push_tlvpack(&tlv);
+            tlv.flag = 0;
+        }
+
+        sleep(1);
     }
 
     logger_term();
+    clidb_term();
 
     return 0;
 } 
 
+/*  Packet 3 TLV message together: with SN, temperature, date&time */ 
+int packtlv_msg(tlv_buf_t *tlv, char *sn, uint16_t temp, struct tm *tm)
+{
+    int               rv;
+
+    if( !tlv )
+    {
+        log_err("Invalid input arguments\n");
+        return -1;
+    }
+
+    memset(tlv->buf, 0, sizeof(tlv->buf)); /* clear data in buffer */
+    tlv->size = sizeof(tlv->buf); /* buffer free space size */
+    tlv->len = 0; /* buffer data length */
+
+    if( sn )
+    {
+        rv = packtlv_sn(&tlv->buf[tlv->len], tlv->size, sn);
+        if( rv > 0 )
+        {
+            tlv->len += rv;
+            tlv->size -= rv;
+        }
+    }
+
+    if( temp )
+    {
+        rv = packtlv_temp(&tlv->buf[tlv->len], tlv->size, temp);
+        if( rv > 0 )
+        {
+            tlv->len += rv;
+            tlv->size -= rv;
+        }
+    }
+
+    if( tm )
+    {
+        rv = packtlv_time(&tlv->buf[tlv->len], tlv->size, tm);
+        if( rv > 0 )
+        {
+            tlv->len += rv;
+            tlv->size -= rv;
+        }
+    }
+
+    return 0;
+}
+
+int socket_send_tlv_pack(socket_t *sock, tlv_buf_t *tlv, int timeout, int retry_times)
+{
+    int            i;
+    int            rv = 0; 
+    char           buf[128];
+
+    if( sock->status != SOCK_STAT_CONNECTED )
+        return -1;
+
+    log_info("start to send tlv packet from socket now\n");
+
+    for(i=0; i<retry_times; i++)
+    { 
+        if( (rv=socket_send(sock, tlv->buf, tlv->len)) < 0 )
+        {
+            log_err("send tlv packet failure, rv=%d\n", rv);
+            return -1; 
+        }
+
+        if( (rv=socket_recv(sock, buf, sizeof(buf), timeout)) < 0 )
+        {
+            log_err("read ACK from server failure, rv=%d\n", rv);
+            return 0;
+        }
+
+        /* todo: parser ACK from buf  */
+        if( ACK )
+            break;
+    }
+
+    return 0;
+}
+
+

--
Gitblit v1.9.1