From 13d8a8696ac5b5b505be20f428fe64e22a134016 Mon Sep 17 00:00:00 2001
From: guowenxue <guowenxue@gmail.com>
Date: Thu, 07 Sep 2023 09:59:30 +0800
Subject: [PATCH] Add socketd example project
---
project/socketd/booster/proc.c | 432 ++++++++++++++++++
project/socketd/makefile | 67 ++
project/socketd/booster/ds18b20.h | 31 +
project/socketd/sqlite/makefile | 7
project/socketd/sqlite/build.sh | 181 +++++++
project/socketd/booster/ds18b20.c | 119 ++++
project/socketd/booster/logger.h | 70 ++
project/socketd/client.c | 107 ++++
project/socketd/booster/makefile | 35 +
project/socketd/booster/logger.c | 279 +++++++++++
project/socketd/booster/proc.h | 89 +++
11 files changed, 1,417 insertions(+), 0 deletions(-)
diff --git a/project/socketd/booster/ds18b20.c b/project/socketd/booster/ds18b20.c
new file mode 100644
index 0000000..5f279fe
--- /dev/null
+++ b/project/socketd/booster/ds18b20.c
@@ -0,0 +1,119 @@
+/*********************************************************************************
+ * Copyright: (C) 2023 LingYun IoT System Studio
+ * All rights reserved.
+ *
+ * Filename: ds18b20.c
+ * Description: This file is temperature sensor DS18B20 code
+ *
+ * Version: 1.0.0(2023/8/10)
+ * Author: Guo Wenxue <guowenxue@gmail.com>
+ * ChangeLog: 1, Release initial version on "2023/8/10 12:13:26"
+ *
+ * Pin connection:
+ *
+ * DS18B20 Module Raspberry Pi Board
+ * VCC <-----> #Pin1(3.3V)
+ * DQ <-----> #Pin7(BCM GPIO4)
+ * GND <-----> GND
+ *
+ * /boot/config.txt:
+ *
+ * dtoverlay=w1-gpio-pullup,gpiopin=4
+ *
+ ********************************************************************************/
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <string.h>
+#include <time.h>
+#include <errno.h>
+
+#include "logger.h"
+
+/* File Content:
+ pi@raspberrypi:~/guowenxue $ cat /sys/bus/w1/devices/28-041731f7c0ff/w1_slave
+ 3a 01 4b 46 7f ff 0c 10 a5 : crc=a5 YES
+ 3a 01 4b 46 7f ff 0c 10 a5 t=19625
+ */
+
+int ds18b20_get_temperature(float *temp)
+{
+ char w1_path[50] = "/sys/bus/w1/devices/";
+ char chip[20];
+ char buf[128];
+ DIR *dirp;
+ struct dirent *direntp;
+ int fd =-1;
+ char *ptr;
+ float value;
+ int found = 0;
+
+ if( !temp )
+ {
+ return -1;
+ }
+
+ /*+-------------------------------------------------------------------+
+ *| open dierectory /sys/bus/w1/devices to get chipset Serial Number |
+ *+-------------------------------------------------------------------+*/
+ if((dirp = opendir(w1_path)) == NULL)
+ {
+ log_error("opendir error: %s\n", strerror(errno));
+ return -2;
+ }
+
+ while((direntp = readdir(dirp)) != NULL)
+ {
+ if(strstr(direntp->d_name,"28-"))
+ {
+ /* find and get the chipset SN filename */
+ strcpy(chip,direntp->d_name);
+ found = 1;
+ break;
+ }
+ }
+ closedir(dirp);
+
+ if( !found )
+ {
+ log_error("Can not find ds18b20 in %s\n", w1_path);
+ return -3;
+ }
+
+ /* get DS18B20 sample file full path: /sys/bus/w1/devices/28-xxxx/w1_slave */
+ strncat(w1_path, chip, sizeof(w1_path)-strlen(w1_path));
+ strncat(w1_path, "/w1_slave", sizeof(w1_path)-strlen(w1_path));
+
+ /* open file /sys/bus/w1/devices/28-xxxx/w1_slave to get temperature */
+ if( (fd=open(w1_path, O_RDONLY)) < 0 )
+ {
+ log_error("open %s error: %s\n", w1_path, strerror(errno));
+ return -4;
+ }
+
+ if(read(fd, buf, sizeof(buf)) < 0)
+ {
+ log_error("read %s error: %s\n", w1_path, strerror(errno));
+ return -5;
+ }
+
+ ptr = strstr(buf, "t=");
+ if( !ptr )
+ {
+ log_error("ERROR: Can not get temperature\n");
+ return -6;
+ }
+
+ ptr+=2;
+
+ /* convert string value to float value */
+ *temp = atof(ptr)/1000;
+
+ close(fd);
+
+ return 0;
+}
diff --git a/project/socketd/booster/ds18b20.h b/project/socketd/booster/ds18b20.h
new file mode 100644
index 0000000..e756134
--- /dev/null
+++ b/project/socketd/booster/ds18b20.h
@@ -0,0 +1,31 @@
+/*********************************************************************************
+ * Copyright: (C) 2023 LingYun IoT System Studio
+ * All rights reserved.
+ *
+ * Filename: ds18b20.h
+ * Description: This file is temperature sensor DS18B20 code
+ *
+ * Version: 1.0.0(2023/8/10)
+ * Author: Guo Wenxue <guowenxue@gmail.com>
+ * ChangeLog: 1, Release initial version on "2023/8/10 12:13:26"
+ *
+ * Pin connection:
+ *
+ * DS18B20 Module Raspberry Pi Board
+ * VCC <-----> #Pin1(3.3V)
+ * DQ <-----> #Pin7(BCM GPIO4)
+ * GND <-----> GND
+ *
+ * /boot/config.txt:
+ *
+ * dtoverlay=w1-gpio-pullup,gpiopin=4
+ *
+ ********************************************************************************/
+
+#ifndef _DS18B20_H_
+#define _DS18B20_H_
+
+extern int ds18b20_get_temperature(float *temp);
+
+#endif /* ----- #ifndef _DS18B20_H_ ----- */
+
diff --git a/project/socketd/booster/logger.c b/project/socketd/booster/logger.c
new file mode 100644
index 0000000..217eb02
--- /dev/null
+++ b/project/socketd/booster/logger.c
@@ -0,0 +1,279 @@
+/*********************************************************************************
+ * Copyright: (C) 2023 LingYun IoT System Studio.
+ * All rights reserved.
+ *
+ * Filename: logger.c
+ * Description: This file is common logger API functions
+ *
+ * Version: 1.0.0(11/08/23)
+ * Author: Guo Wenxue <guowenxue@gmail.com>
+ * ChangeLog: 1, Release initial version on "11/08/23 16:18:43"
+ *
+ ********************************************************************************/
+
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <pthread.h>
+
+#include "logger.h"
+
+typedef void (*log_LockFn)(void *udata, int lock);
+
+static struct {
+ char file[32]; /* logger file name */
+ FILE *fp; /* logger file pointer */
+ long size; /* logger file max size */
+ int level; /* logger level */
+ log_LockFn lockfn; /* lock function */
+ void *udata; /* lock data */
+} L;
+
+static const char *level_names[] = {
+ "ERROR",
+ "WARN",
+ "INFO",
+ "DEBUG",
+ "TRACE"
+};
+
+static const char *level_colors[] = {
+ "\x1b[31m",
+ "\x1b[33m",
+ "\x1b[32m",
+ "\x1b[36m",
+ "\x1b[94m"
+};
+
+static inline void time_to_str(char *buf)
+{
+ struct timeval tv;
+ struct tm *tm;
+ int len;
+
+ gettimeofday(&tv, NULL);
+ tm = localtime(&tv.tv_sec);
+
+ len = sprintf(buf, "%04d-%02d-%02d %02d:%02d:%02d.%06d ",
+ tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
+ tm->tm_hour, tm->tm_min, tm->tm_sec, (int)tv.tv_usec);
+
+ buf[len] = '\0';
+}
+
+static void mutex_lock(void *udata, int lock)
+{
+ int err;
+ pthread_mutex_t *l = (pthread_mutex_t *) udata;
+
+ if (lock)
+ {
+ if ( (err = pthread_mutex_lock(l)) != 0 )
+ log_error("Unable to lock log lock: %s", strerror(err));
+ }
+ else
+ {
+ if ( (err = pthread_mutex_unlock(l) != 0) )
+ log_error("Unable to unlock log lock: %s", strerror(err));
+ }
+}
+
+int log_open(char *fname, int level, int size, int lock)
+{
+ FILE *fp;
+
+ L.level = level;
+ L.size = size*1024;
+
+ if( !fname || !strcmp(fname, "console") || !strcmp(fname, "stderr") )
+ {
+ strcpy(L.file, "console");
+ L.fp = stderr;
+ L.size = 0; /* console don't need rollback */
+ }
+ else
+ {
+ if ( !(fp = fopen(fname, "a+")) )
+ {
+ fprintf(stderr, "%s() failed: %s\n", __func__, strerror(errno));
+ return -2;
+ }
+ L.fp = fp;
+ strncpy(L.file, fname, sizeof(L.file));
+ }
+
+
+ if( lock )
+ {
+ static pthread_mutex_t log_lock;
+
+ pthread_mutex_init(&log_lock, NULL);
+ L.udata = (void *)&log_lock;
+ L.lockfn = mutex_lock;
+ }
+
+ fprintf(L.fp, "\n");
+ log_info("logger system(%s) start: file:\"%s\", level:%s, maxsize:%luKiB\n\n",
+ LOG_VERSION, L.file, level_names[level], size);
+
+ return 0;
+}
+
+void log_close(void)
+{
+ if( L.fp && L.fp!=stderr )
+ fclose(L.fp);
+
+ if (L.udata )
+ pthread_mutex_destroy( L.udata);
+}
+
+static void log_rollback(void)
+{
+ char cmd[128]={0};
+ long fsize;
+
+ /* don't need rollback */
+ if(L.size <= 0 )
+ return ;
+
+ fsize = ftell(L.fp);
+ if( fsize < L.size )
+ return ;
+
+ /* backup current log file */
+ snprintf(cmd, sizeof(cmd), "cp %s %s.bak", L.file, L.file);
+ system(cmd);
+
+ /* rollback file */
+ fseek(L.fp, 0, SEEK_SET);
+ truncate(L.file, 0);
+
+ fprintf(L.fp, "\n");
+ log_info("logger system(%s) rollback: file:\"%s\", level:%s, maxsize:%luKiB\n\n",
+ LOG_VERSION, L.file, level_names[L.level], L.size/1024);
+
+ return ;
+}
+
+void _log_write(int level, const char *file, int line, const char *fmt, ...)
+{
+ va_list args;
+ char time_string[100];
+
+ if ( !L.fp || level>L.level )
+ return;
+
+ /* Acquire lock */
+ if ( L.lockfn )
+ L.lockfn(L.udata, 1);
+
+ log_rollback();
+
+ /* check and rollback file */
+ time_to_str(time_string);
+
+ /* Log to stderr */
+ if ( L.fp == stderr )
+ {
+ fprintf(L.fp, "%s %s %-5s\x1b[0m \x1b[90m%s:%03d:\x1b[0m ",
+ time_string, level_colors[level], level_names[level], file, line);
+ }
+ else /* Log to file */
+ {
+ fprintf(L.fp, "%s %-5s %s:%03d: ", time_string, level_names[level], file, line);
+ }
+
+ va_start(args, fmt);
+ vfprintf(L.fp, fmt, args);
+ va_end(args);
+
+ fflush(L.fp);
+
+ /* Release lock */
+ if ( L.lockfn )
+ L.lockfn(L.udata, 0);
+}
+
+#define LINELEN 81
+#define CHARS_PER_LINE 16
+static char *print_char =
+" "
+" "
+" !\"#$%&'()*+,-./"
+"0123456789:;<=>?"
+"@ABCDEFGHIJKLMNO"
+"PQRSTUVWXYZ[\\]^_"
+"`abcdefghijklmno"
+"pqrstuvwxyz{|}~ "
+" "
+" "
+" ???????????????"
+"????????????????"
+"????????????????"
+"????????????????"
+"????????????????"
+"????????????????";
+
+void log_dump(int level, const char *prompt, char *buf, size_t len)
+{
+ int rc;
+ int idx;
+ char prn[LINELEN];
+ char lit[CHARS_PER_LINE + 2];
+ char hc[4];
+ short line_done = 1;
+
+ if (!L.fp || level>L.level)
+ return;
+
+ if( prompt )
+ _log_write(level, __FILE__, __LINE__, "%s", prompt);
+
+ rc = len;
+ idx = 0;
+ lit[CHARS_PER_LINE] = '\0';
+
+ while (rc > 0)
+ {
+ if (line_done)
+ snprintf(prn, LINELEN, "%08X: ", idx);
+
+ do
+ {
+ unsigned char c = buf[idx];
+ snprintf(hc, 4, "%02X ", c);
+ strncat(prn, hc, LINELEN);
+
+ lit[idx % CHARS_PER_LINE] = print_char[c];
+ }
+ while (--rc > 0 && (++idx % CHARS_PER_LINE != 0));
+
+ line_done = (idx % CHARS_PER_LINE) == 0;
+ if (line_done)
+ {
+ if (L.fp)
+ fprintf(L.fp, "%s %s\n", prn, lit);
+ }
+ }
+
+ if (!line_done)
+ {
+ int ldx = idx % CHARS_PER_LINE;
+ lit[ldx++] = print_char[(int)buf[idx]];
+ lit[ldx] = '\0';
+
+ while ((++idx % CHARS_PER_LINE) != 0)
+ strncat(prn, " ", sizeof(prn)-strlen(prn));
+
+ if (L.fp)
+ fprintf(L.fp, "%s %s\n", prn, lit);
+
+ }
+}
diff --git a/project/socketd/booster/logger.h b/project/socketd/booster/logger.h
new file mode 100644
index 0000000..484ac33
--- /dev/null
+++ b/project/socketd/booster/logger.h
@@ -0,0 +1,70 @@
+/*********************************************************************************
+ * Copyright: (C) 2023 LingYun IoT System Studio.
+ * All rights reserved.
+ *
+ * Filename: logger.h
+ * Description: This file is common logger API functions
+ *
+ * Version: 1.0.0(11/08/23)
+ * Author: Guo Wenxue <guowenxue@gmail.com>
+ * ChangeLog: 1, Release initial version on "11/08/23 16:18:43"
+ *
+ ********************************************************************************/
+
+#ifndef _LOGGER_H_
+#define _LOGGER_H_
+
+#include <stdio.h>
+#include <stdarg.h>
+
+#define LOG_VERSION "v0.1"
+
+/* log level */
+enum {
+ LOG_LEVEL_ERROR,
+ LOG_LEVEL_WARN,
+ LOG_LEVEL_INFO,
+ LOG_LEVEL_DEBUG,
+ LOG_LEVEL_TRACE,
+ LOG_LEVEL_MAX
+};
+
+enum {
+ LOG_LOCK_DISABLE, /* disable lock */
+ LOG_LOCK_ENABLE, /* enable lock */
+};
+
+#define ROLLBACK_NONE 0
+
+/* description: Initial the logger system
+ * arguments :
+ * $fname: logger file name, NULL/"console"/"stderr" will log to console
+ * $level: logger level above;
+ * $size : logger file max size in KiB
+ * $lock : thread lock enable or not
+ * return : <0: Failed ==0: Sucessfully
+ */
+#define THREAD_LOCK_NONE 0
+#define THREAD_LOCK_EN 1
+int log_open(char *fname, int level, int size, int lock);
+
+
+/* description: Terminate the logger system */
+void log_close(void);
+
+
+/* description: log message into log file. Don't call this function directly. */
+void _log_write(int level, const char *file, int line, const char *fmt, ...);
+
+
+/* description: dump a buffer in hex to logger file */
+void log_dump(int level, const char *prompt, char *buf, size_t len);
+
+/* function: log message into logger file with different log level */
+#define log_trace(...) _log_write(LOG_LEVEL_TRACE, __FILE__, __LINE__, __VA_ARGS__)
+#define log_debug(...) _log_write(LOG_LEVEL_DEBUG, __FILE__, __LINE__, __VA_ARGS__)
+#define log_info(...) _log_write(LOG_LEVEL_INFO, __FILE__, __LINE__, __VA_ARGS__)
+#define log_warn(...) _log_write(LOG_LEVEL_WARN, __FILE__, __LINE__, __VA_ARGS__)
+#define log_error(...) _log_write(LOG_LEVEL_ERROR, __FILE__, __LINE__, __VA_ARGS__)
+
+#endif
diff --git a/project/socketd/booster/makefile b/project/socketd/booster/makefile
new file mode 100644
index 0000000..b6ece0e
--- /dev/null
+++ b/project/socketd/booster/makefile
@@ -0,0 +1,35 @@
+#********************************************************************************
+# Copyright: (C) 2023 LingYun IoT System Studio
+# All rights reserved.
+#
+# Filename: Makefile
+# Description: This file used compile all the source code to static library
+#
+# Version: 1.0.0(11/08/23)
+# Author: Guo Wenxue <guowenxue@gmail.com>
+# ChangeLog: 1, Release initial version on "11/08/23 16:18:43"
+#
+#*******************************************************************************
+
+PWD=$(shell pwd )
+
+BUILD_ARCH=$(shell uname -m)
+ifneq ($(findstring $(BUILD_ARCH), "x86_64" "i386"),)
+ CROSS_COMPILE?=arm-linux-gnueabihf-
+endif
+
+LIBNAME=$(shell basename ${PWD} )
+TOPDIR=$(shell dirname ${PWD} )
+CFLAGS+=-D_GNU_SOURCE
+
+all: clean
+ @rm -f *.o
+ @${CROSS_COMPILE}gcc ${CFLAGS} -I${TOPDIR} -c *.c
+ ${CROSS_COMPILE}ar -rcs lib${LIBNAME}.a *.o
+
+clean:
+ @rm -f *.o
+ @rm -f *.a
+
+distclean:
+ @make clean
diff --git a/project/socketd/booster/proc.c b/project/socketd/booster/proc.c
new file mode 100644
index 0000000..d233d83
--- /dev/null
+++ b/project/socketd/booster/proc.c
@@ -0,0 +1,432 @@
+/*********************************************************************************
+ * Copyright: (C) 2020 LingYun IoT System Studio
+ * All rights reserved.
+ *
+ * Filename: proc.c
+ * Description: This file is the process API
+ *
+ * Version: 1.0.0(7/06/2020)
+ * Author: Guo Wenxue <guowenxue@gmail.com>
+ * ChangeLog: 1, Release initial version on "7/06/2020 09:19:02 PM"
+ *
+ ********************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <libgen.h>
+#include <pthread.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include "proc.h"
+#include "logger.h"
+
+proc_signal_t g_signal={0};
+
+void proc_default_sighandler(int sig)
+{
+ switch(sig)
+ {
+ case SIGINT:
+ log_warn("SIGINT - stopping\n");
+ g_signal.stop = 1;
+ break;
+
+ case SIGTERM:
+ log_warn("SIGTERM - stopping\n");
+ g_signal.stop = 1;
+ break;
+
+ case SIGSEGV:
+ log_warn("SIGSEGV - stopping\n");
+#if 0
+ if(g_signal.stop)
+ exit(0);
+
+ g_signal.stop = 1;
+#endif
+ break;
+
+ case SIGPIPE:
+ log_warn("SIGPIPE - warnning\n");
+ break;
+
+ default:
+ break;
+ }
+}
+
+
+/* install default signal process functions */
+void install_default_signal(void)
+{
+ struct sigaction sigact, sigign;
+
+ log_info("Install default signal handler.\n");
+
+ /* Initialize the catch signal structure. */
+ sigemptyset(&sigact.sa_mask);
+ sigact.sa_flags = 0;
+ sigact.sa_handler = proc_default_sighandler;
+
+ /* Setup the ignore signal. */
+ sigemptyset(&sigign.sa_mask);
+ sigign.sa_flags = 0;
+ sigign.sa_handler = SIG_IGN;
+
+ sigaction(SIGTERM, &sigact, 0); /* catch terminate signal "kill" command */
+ sigaction(SIGINT, &sigact, 0); /* catch interrupt signal CTRL+C */
+ //sigaction(SIGSEGV, &sigact, 0); /* catch segmentation faults */
+ sigaction(SIGPIPE, &sigact, 0); /* catch broken pipe */
+#if 0
+ sigaction(SIGCHLD, &sigact, 0); /* catch child process return */
+ sigaction(SIGUSR2, &sigact, 0); /* catch USER signal */
+#endif
+}
+
+
+/* ****************************************************************************
+ * FunctionName: daemonize
+ * Description : Set the programe runs as daemon in background
+ * Inputs : nodir: DON'T change the work directory to / : 1:NoChange 0:Change
+ * noclose: close the opened file descrtipion or not 1:Noclose 0:Close
+ * Output : NONE
+ * Return : NONE
+ * *****************************************************************************/
+void daemonize(int nochdir, int noclose)
+{
+ int rv, fd;
+ int i;
+
+ /* already a daemon */
+ if (1 == getppid())
+ return;
+
+ /* fork error */
+ rv = fork();
+ if (rv < 0) exit(1);
+
+ /* parent process exit */
+ if (rv > 0)
+ exit(0);
+
+ /* obtain a new process session group */
+ setsid();
+
+ if (!noclose)
+ {
+ /* close all descriptors */
+ for (i = getdtablesize(); i >= 0; --i)
+ {
+ //if (i != g_logPtr->fd)
+ close(i);
+ }
+
+ /* Redirect Standard input [0] to /dev/null */
+ fd = open("/dev/null", O_RDWR);
+
+ /* Redirect Standard output [1] to /dev/null */
+ dup(fd);
+
+ /* Redirect Standard error [2] to /dev/null */
+ dup(fd);
+ }
+
+ umask(0);
+
+ if (!nochdir)
+ chdir("/");
+
+ return;
+}
+
+/* ****************************************************************************
+ * FunctionName: check_set_program_running
+ * Description : check program already running or not, if not then run it and
+ * record pid into $pidfile
+ * Inputs : daemon: set program running in daemon or not
+ * pid_file:The record PID file path
+ * Output : NONE
+ * Return : 0: Record successfully Else: Failure
+ * *****************************************************************************/
+
+int check_set_program_running(int daemon, char *pidfile)
+{
+ if( !pidfile )
+ return 0;
+
+ if( check_daemon_running(pidfile) )
+ {
+ log_error("Program already running, process exit now");
+ return -1;
+ }
+
+ if( daemon )
+ {
+ if( set_daemon_running(pidfile) < 0 )
+ {
+ log_error("set program running as daemon failure\n");
+ return -2;
+ }
+ }
+ else
+ {
+ if( record_daemon_pid(pidfile) < 0 )
+ {
+ log_error("record program running PID failure\n");
+ return -3;
+ }
+ }
+
+ return 0;
+}
+
+
+
+/* ****************************************************************************
+ * FunctionName: record_daemon_pid
+ * Description : Record the running daemon program PID to the file "pid_file"
+ * Inputs : pid_file:The record PID file path
+ * Output : NONE
+ * Return : 0: Record successfully Else: Failure
+ * *****************************************************************************/
+int record_daemon_pid(const char *pid_file)
+{
+ struct stat fStatBuf;
+ int fd = -1;
+ int mode = S_IROTH | S_IXOTH | S_IRGRP | S_IXGRP | S_IRWXU;
+ char ipc_dir[64] = { 0 };
+
+ strncpy(ipc_dir, pid_file, 64);
+
+ /* dirname() will modify ipc_dir and save the result */
+ dirname(ipc_dir);
+
+ /* If folder pid_file PATH doesnot exist, then we will create it" */
+ if (stat(ipc_dir, &fStatBuf) < 0)
+ {
+ if (mkdir(ipc_dir, mode) < 0)
+ {
+ log_error("cannot create %s: %s\n", ipc_dir, strerror(errno));
+ return -1;
+ }
+
+ (void)chmod(ipc_dir, mode);
+ }
+
+ /* Create the process running PID file */
+ mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
+ if ((fd = open(pid_file, O_RDWR | O_CREAT | O_TRUNC, mode)) >= 0)
+ {
+ char pid[PID_ASCII_SIZE];
+ snprintf(pid, sizeof(pid), "%u\n", (unsigned)getpid());
+ write(fd, pid, strlen(pid));
+ close(fd);
+
+ log_debug("Record PID<%u> to file %s.\n", getpid(), pid_file);
+ }
+ else
+ {
+ log_error("cannot create %s: %s\n", pid_file, strerror(errno));
+ return -1;
+ }
+
+ return 0;
+}
+
+/* ****************************************************************************
+ * FunctionName: get_daemon_pid
+ * Description : Get the daemon process PID from the PID record file "pid_file"
+ * Inputs : pid_file: the PID record file
+ * Output : NONE
+ * Return : pid_t: The daemon process PID number
+ * *****************************************************************************/
+pid_t get_daemon_pid(const char *pid_file)
+{
+ FILE *f;
+ pid_t pid;
+
+ if ((f = fopen(pid_file, "rb")) != NULL)
+ {
+ char pid_ascii[PID_ASCII_SIZE];
+ (void)fgets(pid_ascii, PID_ASCII_SIZE, f);
+ (void)fclose(f);
+ pid = atoi(pid_ascii);
+ }
+ else
+ {
+ log_error("Can't open PID record file %s: %s\n", pid_file, strerror(errno));
+ return -1;
+ }
+ return pid;
+}
+
+/* ****************************************************************************
+ * FunctionName: check_daemon_running
+ * Description : Check the daemon program already running or not
+ * Inputs : pid_file: The record running daemon program PID
+ * Output : NONE
+ * Return : 1: The daemon program alread running 0: Not running
+ * *****************************************************************************/
+int check_daemon_running(const char *pid_file)
+{
+ int rv = -1;
+ struct stat fStatBuf;
+
+ rv = stat(pid_file, &fStatBuf);
+ if (0 == rv)
+ {
+ pid_t pid = -1;
+ printf("PID record file \"%s\" exist.\n", pid_file);
+
+ pid = get_daemon_pid(pid_file);
+ if (pid > 0) /* Process pid exist */
+ {
+ if ((rv = kill(pid, 0)) == 0)
+ {
+ printf("Program with PID[%d] seems running.\n", pid);
+ return 1;
+ }
+ else /* Send signal to the old process get no reply. */
+ {
+ printf("Program with PID[%d] seems exit.\n", pid);
+ remove(pid_file);
+ return 0;
+ }
+ }
+ else if (0 == pid)
+ {
+ printf("Can not read program PID form record file.\n");
+ remove(pid_file);
+ return 0;
+ }
+ else /* Read pid from file "pid_file" failure */
+ {
+ printf("Read record file \"%s\" failure, maybe program still running.\n", pid_file);
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+/* ****************************************************************************
+ * FunctionName: stop_daemon_running
+ * Description : Stop the daemon program running
+ * Inputs : pid_file: The record running daemon program PID
+ * Output : NONE
+ * Return : 1: The daemon program alread running 0: Not running
+ * *****************************************************************************/
+int stop_daemon_running(const char *pid_file)
+{
+ pid_t pid = -1;
+ struct stat fStatBuf;
+
+ if ( stat(pid_file, &fStatBuf) < 0)
+ return 0;
+
+ printf("PID record file \"%s\" exist.\n", pid_file);
+ pid = get_daemon_pid(pid_file);
+ if (pid > 0) /* Process pid exist */
+ {
+ while ( (kill(pid, 0) ) == 0)
+ {
+ kill(pid, SIGTERM);
+ sleep(1);
+ }
+
+ remove(pid_file);
+ }
+
+ return 0;
+}
+
+
+
+/* ****************************************************************************
+ * FunctionName: set_daemon_running
+ * Description : Set the programe running as daemon if it's not running and record
+ * its PID to the pid_file.
+ * Inputs : pid_file: The record running daemon program PID
+ * Output : NONE
+ * Return : 0: Successfully. 1: Failure
+ * *****************************************************************************/
+int set_daemon_running(const char *pid_file)
+{
+ daemonize(0, 1);
+ log_info("Program running as daemon [PID:%d].\n", getpid());
+
+ if (record_daemon_pid(pid_file) < 0)
+ {
+ log_error("Record PID to file \"%s\" failure.\n", pid_file);
+ return -2;
+ }
+
+ return 0;
+}
+
+/* start a new thread to run $thread_workbody point function */
+int thread_start(pthread_t *thread_id, thread_body_t thread_workbody, void *thread_arg)
+{
+ int rv = 0;
+ pthread_t tid;
+
+ pthread_attr_t thread_attr;
+
+ /* Initialize the thread attribute */
+ rv = pthread_attr_init(&thread_attr);
+ if(rv)
+ return -1;
+
+ /* Set the stack size of the thread */
+ rv = pthread_attr_setstacksize(&thread_attr, 120 * 1024);
+ if(rv)
+ goto CleanUp;
+
+ /* Set thread to detached state:Don`t need pthread_join */
+ rv = pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED);
+ if(rv)
+ goto CleanUp;
+
+ /* Create the thread */
+ rv = pthread_create(&tid, &thread_attr, thread_workbody, thread_arg);
+ if(rv)
+ goto CleanUp;
+
+CleanUp:
+
+
+ if( thread_id )
+ {
+ if( rv )
+ *thread_id = 0;
+ else
+ *thread_id = tid;
+ }
+
+ /* Destroy the attributes of thread */
+ pthread_attr_destroy(&thread_attr);
+ return rv;
+}
+
+
+/* excute a linux command by system() */
+void exec_system_cmd(const char *format, ...)
+{
+ char cmd[256];
+ va_list args;
+
+ memset(cmd, 0, sizeof(cmd));
+
+ va_start(args, format);
+ vsnprintf(cmd, sizeof(cmd), format, args);
+ va_end(args);
+
+ system(cmd);
+}
+
+
diff --git a/project/socketd/booster/proc.h b/project/socketd/booster/proc.h
new file mode 100644
index 0000000..1a8a14e
--- /dev/null
+++ b/project/socketd/booster/proc.h
@@ -0,0 +1,89 @@
+/********************************************************************************
+ * Copyright: (C) 2020 LingYun IoT System Studio
+ * All rights reserved.
+ *
+ * Filename: proc.h
+ * Description: This head file is for Linux process/thread API
+ *
+ * Version: 1.0.0(7/06/2012~)
+ * Author: Guo Wenxue <guowenxue@gmail.com>
+ * ChangeLog: 1, Release initial version on "7/06/2012 09:21:33 PM"
+ *
+ ********************************************************************************/
+
+#ifndef __PROC_H_
+#define __PROC_H_
+
+#include <signal.h>
+#include <time.h>
+
+#define PID_ASCII_SIZE 11
+
+typedef struct proc_signal_s
+{
+ int signal;
+ unsigned stop; /* 0: Not term 1: Stop */
+} proc_signal_t;
+
+typedef void *(* thread_body_t) (void *thread_arg);
+
+extern proc_signal_t g_signal;
+
+/* install default signal process functions */
+extern void install_default_signal(void);
+
+/* excute a linux command by system() */
+extern void exec_system_cmd(const char *format, ...);
+
+/* check program already running or not, if not then run it and record pid into $pidfile */
+extern int check_set_program_running(int daemon, char *pidfile);
+
+/* check program already running or not from $pid_file */
+extern int check_daemon_running(const char *pid_file);
+
+/* set program daemon running and record pid in $pid_file */
+extern int set_daemon_running(const char *pid_file);
+
+/* record proces ID into $pid_file */
+extern int record_daemon_pid(const char *pid_file);
+
+/* stop program running from $pid_file */
+extern int stop_daemon_running(const char *pid_file);
+
+/* my implementation for set program running in daemon */
+extern void daemonize(int nochdir, int noclose);
+
+/* start a new thread to run $thread_workbody point function */
+extern int thread_start(pthread_t *thread_id, thread_body_t thread_workbody, void *thread_arg);
+
+/* +---------------------+
+ * | Low level API |
+ * +---------------------+*/
+
+/* get daemon process ID from $pid_file */
+extern pid_t get_daemon_pid(const char *pid_file);
+
+/* +------------------------+
+ * | inline functions API |
+ * +------------------------+*/
+static inline void msleep(unsigned long ms)
+{
+ struct timespec cSleep;
+ unsigned long ulTmp;
+
+ cSleep.tv_sec = ms / 1000;
+ if (cSleep.tv_sec == 0)
+ {
+ ulTmp = ms * 10000;
+ cSleep.tv_nsec = ulTmp * 100;
+ }
+ else
+ {
+ cSleep.tv_nsec = 0;
+ }
+
+ nanosleep(&cSleep, 0);
+ return ;
+}
+
+#endif
diff --git a/project/socketd/client.c b/project/socketd/client.c
new file mode 100644
index 0000000..e350bef
--- /dev/null
+++ b/project/socketd/client.c
@@ -0,0 +1,107 @@
+/*********************************************************************************
+ * 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 <guowenxue@gmail.com>
+ * ChangeLog: 1, Release initial version on "29/01/19 15:34:41"
+ *
+ ********************************************************************************/
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <time.h>
+#include <getopt.h>
+#include <libgen.h>
+#include <string.h>
+#include <errno.h>
+
+#include "logger.h"
+#include "ds18b20.h"
+#include "proc.h"
+
+#define PROG_VERSION "v1.0.0"
+#define DAEMON_PIDFILE "/tmp/.socketd.pid"
+
+static void program_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("\n%s version %s\n", progname, PROG_VERSION);
+ return;
+}
+
+int main (int argc, char **argv)
+{
+ int daemon = 1;
+ int opt;
+ char *progname=NULL;
+ char *logfile="client.log";
+ int loglevel=LOG_LEVEL_INFO;
+ int logsize=10; /* logfile size max to 10K */
+
+ struct option long_options[] = {
+ {"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 ((opt = getopt_long(argc, argv, "dvh", long_options, NULL)) != -1)
+ {
+ switch (opt)
+ {
+ 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 */
+ program_usage(progname);
+ return 0;
+
+ default:
+ break;
+ }
+
+ }
+
+ 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;
+
+ while( ! g_signal.stop )
+ {
+ msleep(1000);
+ }
+
+cleanup:
+ log_close();
+
+ return 0;
+}
diff --git a/project/socketd/makefile b/project/socketd/makefile
new file mode 100644
index 0000000..2c72631
--- /dev/null
+++ b/project/socketd/makefile
@@ -0,0 +1,67 @@
+#********************************************************************************
+# Copyright: (C) 2023 LingYun IoT System Studio
+# All rights reserved.
+#
+# Filename: Makefile
+# Description: This file is the project top Makefie
+#
+# Version: 1.0.0(11/08/23)
+# Author: Guo Wenxue <guowenxue@gmail.com>
+# ChangeLog: 1, Release initial version on "11/08/23 16:18:43"
+#
+#*******************************************************************************
+
+PRJ_PATH=$(shell pwd)
+APP_NAME = client
+
+BUILD_ARCH=$(shell uname -m)
+ifneq ($(findstring $(BUILD_ARCH), "x86_64" "i386"),)
+ CROSS_COMPILE=arm-linux-gnueabihf-
+endif
+
+# C source files in top-level directory
+SRCFILES = $(wildcard *.c)
+
+# common CFLAGS for our source code
+CFLAGS = -Wall -Wshadow -Wundef -Wmaybe-uninitialized -D_GNU_SOURCE
+
+# sub-directory need to entry and compile
+SUBDIR=booster sqlite
+
+# sub-directory compiled to a library and need to link
+SRCS=booster
+SRCS_PATH=$(patsubst %,${PRJ_PATH}/%,$(SRCS))
+CFLAGS+=$(patsubst %,-I%,$(SRCS_PATH))
+LDFLAGS+=$(patsubst %,-L%,$(SRCS_PATH))
+LIBS=$(patsubst %,-l%,$(SRCS))
+LDFLAGS+=${LIBS}
+
+# Open source libraries
+CFLAGS+=-I ${PRJ_PATH}/sqlite/install/include
+LDFLAGS+=-L ${PRJ_PATH}/sqlite/install/lib
+LDFLAGS+=-lsqlite3
+
+LDFLAGS+=-lpthread
+
+all: entry subdir
+ ${CROSS_COMPILE}gcc ${CFLAGS} client.c -o client ${LDFLAGS}
+
+entry:
+ @echo "Building ${APP_NAME} on ${BUILD_ARCH}"
+
+subdir:
+ @for dir in ${SUBDIR} ; do if [ ! -e $${dir} ] ; then ln -s ../$${dir}; fi; done
+ @for dir in ${SUBDIR} ; do make -C $${dir} ; done
+
+install:
+ cp ${APP_NAME} /tftp
+
+clean:
+ @for dir in ${SRCS} ; do if [ -e $${dir} ] ; then make clean -C $${dir}; fi; done
+ @rm -f ${APP_NAME}
+
+distclean:
+ @for dir in ${SUBDIR} ; do if [ -e $${dir} ] ; then make clean -C $${dir}; fi; done
+ @rm -f ${APP_NAME}
+ @rm -f cscope.* tags
+
diff --git a/project/socketd/sqlite/build.sh b/project/socketd/sqlite/build.sh
new file mode 100755
index 0000000..53599b4
--- /dev/null
+++ b/project/socketd/sqlite/build.sh
@@ -0,0 +1,181 @@
+#!/bin/bash
+
+# library name and version
+# Official: https://www.sqlite.org/index.html
+LIB_NAME=sqlite-autoconf-3430000
+PACK_SUFIX=tar.gz
+
+# LingYun source code FTP server
+LY_FTP=http://main.iot-yun.club:2211/src/
+
+# library download URL address
+LIB_URL=$LY_FTP
+
+# Cross compiler for cross compile on Linux server
+CROSS_COMPILE=arm-linux-gnueabihf-
+
+# compile jobs
+JOBS=`cat /proc/cpuinfo |grep "processor"|wc -l`
+
+# this project absolute path
+PRJ_PATH=$(cd $(dirname "${BASH_SOURCE[0]}") && pwd)
+
+# top project absolute path
+TOP_PATH=$(realpath $PRJ_PATH/..)
+
+# binaries install path
+PREFIX_PATH=$PRJ_PATH/install
+BIN_PATH=$PREFIX_PATH/bin
+LIB_PATH=$PREFIX_PATH/lib
+INC_PATH=$PREFIX_PATH/include
+
+# check installed or not file
+INST_FILE=$PREFIX_PATH/bin/sqlite3
+
+# shell script will exit once get command error
+set -e
+
+#+-------------------------+
+#| Shell script functions |
+#+-------------------------+
+
+function pr_error() {
+ echo -e "\033[40;31m $1 \033[0m"
+}
+
+function pr_warn() {
+ echo -e "\033[40;33m $1 \033[0m"
+}
+
+function pr_info() {
+ echo -e "\033[40;32m $1 \033[0m"
+}
+
+function check_result()
+{
+ if [ $? != 0 ] ; then
+ pr_error $1
+ fi
+}
+# decompress a packet to destination path
+function do_unpack()
+{
+ tarball=$1
+ dstpath=`pwd`
+
+ if [[ $# == 2 ]] ; then
+ dstpath=$2
+ fi
+
+ pr_info "decompress $tarball => $dstpath"
+
+ mkdir -p $dstpath
+ case $tarball in
+ *.tar.gz)
+ tar -xzf $tarball -C $dstpath
+ ;;
+
+ *.tar.bz2)
+ tar -xjf $tarball -C $dstpath
+ ;;
+
+ *.tar.xz)
+ tar -xJf $tarball -C $dstpath
+ ;;
+
+ *.tar.zst)
+ tar -I zstd -xf $tarball -C $dstpath
+ ;;
+
+ *.tar)
+ tar -xf $tarball -C $dstpath
+ ;;
+
+ *.zip)
+ unzip -qo $tarball -d $dstpath
+ ;;
+
+ *)
+ pr_error "decompress Unsupport packet: $tarball"
+ return 1;
+ ;;
+ esac
+}
+
+function do_export()
+{
+ BUILD_ARCH=$(uname -m)
+ if [[ $BUILD_ARCH =~ "arm" ]] ; then
+ pr_warn "local($BUILD_ARCH) compile $LIB_NAME"
+ return ;
+ fi
+
+ pr_warn "cross(${CROSS_COMPILE}) compile $LIB_NAME"
+
+ # export cross toolchain
+ export CC=${CROSS_COMPILE}gcc
+ export CXX=${CROSS_COMPILE}g++
+ export AS=${CROSS_COMPILE}as
+ export AR=${CROSS_COMPILE}ar
+ export LD=${CROSS_COMPILE}ld
+ export NM=${CROSS_COMPILE}nm
+ export RANLIB=${CROSS_COMPILE}ranlib
+ export OBJDUMP=${CROSS_COMPILE}objdump
+ export STRIP=${CROSS_COMPILE}strip
+
+ # export cross configure
+ export CONFIG_CROSS=" --build=i686-pc-linux --host=arm-linux "
+
+ # Clear LDFLAGS and CFLAGS
+ export LDFLAGS=
+ export CFLAGS=
+}
+
+function do_fetch()
+{
+ if [ -e ${INST_FILE} ] ; then
+ pr_warn "$LIB_NAME compile and installed alredy"
+ exit ;
+ fi
+
+ if [ -d $LIB_NAME ] ; then
+ pr_warn "$LIB_NAME fetch already"
+ return ;
+ fi
+
+ if [ ! -f ${LIB_NAME}.${PACK_SUFIX} ] ; then
+ wget ${LIB_URL}/${LIB_NAME}.${PACK_SUFIX}
+ check_result "ERROR: download ${LIB_NAME} failure"
+ fi
+
+ do_unpack ${LIB_NAME}.${PACK_SUFIX}
+}
+
+function do_build()
+{
+ cd $LIB_NAME
+
+ do_export
+
+ ./configure --prefix=${PREFIX_PATH} ${CONFIG_CROSS} --enable-static --enable-static-shell
+ check_result "ERROR: configure ${LIB_NAME} failure"
+
+ make && make install
+ check_result "ERROR: compile ${LIB_NAME} failure"
+}
+
+function do_clean()
+{
+ rm -rf *${LIB_NAME}*
+}
+
+if [[ $# == 1 && $1 == -c ]] ;then
+ pr_warn "start clean ${LIB_NAME}"
+ do_clean
+ exit;
+fi
+
+do_fetch
+
+do_build
+
diff --git a/project/socketd/sqlite/makefile b/project/socketd/sqlite/makefile
new file mode 100644
index 0000000..4572f9f
--- /dev/null
+++ b/project/socketd/sqlite/makefile
@@ -0,0 +1,7 @@
+
+all:
+ ./build.sh
+
+clean:
+ rm -rf install
+ ./build.sh -c
--
Gitblit v1.9.1