Explorar el Código

merge: retain v1.1.0 history, take v1.2.0 (Pi5) as authoritative

steven_roc hace 2 días
padre
commit
40c44c38ee
Se han modificado 6 ficheros con 215 adiciones y 0 borrados
  1. 0 0
      docs/.gitkeep
  2. 0 0
      libs/.gitkeep
  3. 0 0
      scripts/.gitkeep
  4. 75 0
      scripts/deploy.sh
  5. 140 0
      src/utils.c
  6. 0 0
      tests/.gitkeep

+ 0 - 0
docs/.gitkeep


+ 0 - 0
libs/.gitkeep


+ 0 - 0
scripts/.gitkeep


+ 75 - 0
scripts/deploy.sh

@@ -0,0 +1,75 @@
+#!/bin/bash
+# ============================================================
+# Deployment script for Hikvision ISUP Client
+# ============================================================
+
+set -e
+
+SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
+INSTALL_DIR="/usr/local/bin"
+CONFIG_DIR="/etc/hikvision-isup"
+
+BINARY_NAME="${1:-hikvision-isup-client}"
+
+echo "=== Deploying $BINARY_NAME ==="
+
+# Check if binary exists
+if [ ! -f "$PROJECT_DIR/$BINARY_NAME" ]; then
+    echo "Binary not found: $PROJECT_DIR/$BINARY_NAME"
+    echo "Running make first..."
+    cd "$PROJECT_DIR"
+    make
+fi
+
+# Create config directory
+sudo mkdir -p "$CONFIG_DIR"
+
+# Install binary
+sudo install -m 755 "$PROJECT_DIR/$BINARY_NAME" "$INSTALL_DIR/$BINARY_NAME"
+echo "Binary installed to $INSTALL_DIR/$BINARY_NAME"
+
+# Copy config
+if [ -f "$PROJECT_DIR/config.ini" ]; then
+    sudo cp "$PROJECT_DIR/config.ini" "$CONFIG_DIR/config.ini"
+    echo "Config copied to $CONFIG_DIR/config.ini"
+fi
+
+# Create necessary directories
+sudo mkdir -p /var/log/hikvision-isup
+sudo mkdir -p /var/lib/hikvision-isup/recordings
+sudo mkdir -p /var/lib/hikvision-isup/sim_images
+
+# Create systemd service file
+sudo tee "/etc/systemd/system/hikvision-isup-client.service" > /dev/null << 'EOF'
+[Unit]
+Description=Hikvision ISUP Client - Platform Registration and Stream Management
+After=network.target
+
+[Service]
+Type=simple
+User=root
+WorkingDirectory=/opt/hikvision-isup
+ExecStart=/usr/local/bin/hikvision-isup-client -c /etc/hikvision-isup/config.ini -d
+Restart=on-failure
+RestartSec=5
+StandardOutput=journal
+StandardError=journal
+
+[Install]
+WantedBy=multi-user.target
+EOF
+
+echo "Systemd service file created"
+echo ""
+echo "To enable and start the service:"
+echo "  sudo systemctl daemon-reload"
+echo "  sudo systemctl enable hikvision-isup-client"
+echo "  sudo systemctl start hikvision-isup-client"
+echo ""
+echo "To check status:"
+echo "  sudo systemctl status hikvision-isup-client"
+echo "  journalctl -u hikvision-isup-client -f"
+
+echo ""
+echo "=== Deployment complete ==="

+ 140 - 0
src/utils.c

@@ -0,0 +1,140 @@
+#include "common.h"
+#include <ctype.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+/* 全局日志回调 */
+LogCallback g_log_callback = NULL;
+
+void set_log_callback(LogCallback cb) {
+    g_log_callback = cb;
+}
+
+char* get_timestamp(char* buf, size_t bufsize, const char* fmt) {
+    time_t now = time(NULL);
+    struct tm* tm_info = localtime(&now);
+    
+    if (fmt == NULL) {
+        fmt = "%Y-%m-%d %H:%M:%S";
+    }
+    
+    strftime(buf, bufsize, fmt, tm_info);
+    return buf;
+}
+
+char* str_tolower(char* str) {
+    char* p = str;
+    while (*p) {
+        *p = tolower((unsigned char)*p);
+        p++;
+    }
+    return str;
+}
+
+size_t safe_strcpy(char* dest, const char* src, size_t size) {
+    if (size == 0 || src == NULL) return 0;
+    
+    size_t len = strlen(src);
+    if (len >= size) {
+        len = size - 1;
+    }
+    memcpy(dest, src, len);
+    dest[len] = '\0';
+    return len;
+}
+
+/* 简单的文件写入工具 */
+int write_file(const char* path, const char* content) {
+    FILE* fp = fopen(path, "w");
+    if (fp == NULL) {
+        LOG_ERROR("Failed to open file: %s, error: %s", path, strerror(errno));
+        return FAILURE;
+    }
+    
+    fprintf(fp, "%s", content);
+    fclose(fp);
+    return SUCCESS;
+}
+
+/* 读取配置文件(简单键值对格式) */
+char* read_config_value(const char* file, const char* key) {
+    static char value[256];
+    FILE* fp = fopen(file, "r");
+    if (fp == NULL) {
+        LOG_ERROR("Failed to open config file: %s", file);
+        return NULL;
+    }
+    
+    char line[512];
+    while (fgets(line, sizeof(line), fp)) {
+        /* 跳过注释和空行 */
+        if (line[0] == '#' || line[0] == ';' || line[0] == '\n') continue;
+        
+        /* 移除换行符 */
+        line[strcspn(line, "\n")] = '\0';
+        
+        char* eq = strchr(line, '=');
+        if (eq != NULL) {
+            *eq = '\0';
+            if (strcmp(line, key) == 0) {
+                safe_strcpy(value, eq + 1, sizeof(value));
+                fclose(fp);
+                return value;
+            }
+        }
+    }
+    
+    fclose(fp);
+    return NULL;
+}
+
+/* 确保目录存在 */
+int ensure_directory(const char* path) {
+    struct stat st;
+    if (stat(path, &st) == 0) {
+        return S_ISDIR(st.st_mode) ? SUCCESS : FAILURE;
+    }
+    
+    /* 递归创建目录 */
+    char tmp[MAX_PATH_SIZE];
+    safe_strcpy(tmp, path, sizeof(tmp));
+    
+    char* p = tmp;
+    while (*p) {
+        if (*p == '/') {
+            *p = '\0';
+            mkdir(tmp, 0755);
+            *p = '/';
+        }
+        p++;
+    }
+    mkdir(tmp, 0755);
+    return SUCCESS;
+}
+
+/* 生成唯一ID */
+static int g_id_counter = 0;
+int generate_id(void) {
+    return ++g_id_counter;
+}
+
+/* 睡眠(可中断) */
+int sleep_milliseconds(int ms) {
+    struct timespec ts;
+    ts.tv_sec = ms / 1000;
+    ts.tv_nsec = (ms % 1000) * 1000000L;
+    return nanosleep(&ts, NULL);
+}
+
+/* 获取当前毫秒时间戳 */
+long long get_current_ms(void) {
+    struct timeval tv;
+    gettimeofday(&tv, NULL);
+    return (long long)tv.tv_sec * 1000 + tv.tv_usec / 1000;
+}
+
+/* 获取当前秒时间戳 */
+long long get_current_s(void) {
+    return (long long)time(NULL);
+}

+ 0 - 0
tests/.gitkeep