Commit 6a503b14 authored by DESKTOP-MC5UL36\dell's avatar DESKTOP-MC5UL36\dell

可以发送mqtt开启关闭tailscale vpn, unix_server,go程序更新和根据后台配置开启go视频或浏览器

parent b77cdb0a
...@@ -51,6 +51,9 @@ include_directories( ...@@ -51,6 +51,9 @@ include_directories(
modules/mqtt modules/mqtt
modules/http modules/http
modules/browser modules/browser
modules/ipc
modules/go_deploy
modules/tailscale_deploy
third_party/zlog/src third_party/zlog/src
third_party/mosquitto/include third_party/mosquitto/include
third_party/mosquitto/lib third_party/mosquitto/lib
...@@ -70,6 +73,9 @@ file(GLOB_RECURSE SOURCES ...@@ -70,6 +73,9 @@ file(GLOB_RECURSE SOURCES
modules/mqtt/*.c modules/mqtt/*.c
modules/http/*.c modules/http/*.c
modules/browser/*.c modules/browser/*.c
modules/ipc/*.c
modules/go_deploy/*.c
modules/tailscale_deploy/*.c
app/device_identity/*.c app/device_identity/*.c
app/device_change/*.c app/device_change/*.c
app/main/*.c app/main/*.c
......
#include "main.h" #include "main.h"
int main(){ int main()
if(mylog_init()!=0){ {
my_zlog_error("日志初始化失败,错误代码:%d",mylog_init()); if (mylog_init() != 0)
return -1; {
my_zlog_error("日志初始化失败,错误代码:%d", mylog_init());
return -1;
} }
if(wiringPiSetup() == -1) { if (wiringPiSetup() == -1)
my_zlog_fatal("WiringPi setup failed!"); {
return -2; my_zlog_fatal("WiringPi setup failed!");
return -2;
} }
if(device_id_file_init()!=0){ if (device_id_file_init() != 0)
my_zlog_error("设备id读取失败"); {
return -3; my_zlog_error("设备id读取失败");
} return -3;
if(device_mqtt_topic_init()!=0){ }
if (device_mqtt_topic_init() != 0)
{
my_zlog_error("设备id判断失败"); my_zlog_error("设备id判断失败");
return -4; return -4;
} }
if(request_date() !=0){ if (request_date() != 0)
my_zlog_error("请求数据失败"); {
return -5; my_zlog_error("请求数据失败");
} return -5;
}
if(http_mqtt_video_init() !=0){ if (http_mqtt_video_init() != 0)
{
my_zlog_error("请求mqtt服务器和video数据失败"); my_zlog_error("请求mqtt服务器和video数据失败");
return -6; return -6;
} }
if(audio_config_init()!=0){ // 检查并更新 Go 程序
if (go_deploy_check_and_update() != 0)
{
my_zlog_warn("Go 程序检查/部署失败");
}
// 启动 Unix Socket 服务,用于 C 和 Go 程序通信
if (ipc_start_unix_server(NULL) != 0)
{
my_zlog_warn("IPC Unix Socket Server 启动失败");
return -8;
}
if (audio_config_init() != 0)
{
my_zlog_warn("音频配置初始化失败"); my_zlog_warn("音频配置初始化失败");
} }
if(hardware_iic_init()!=0){ if (hardware_iic_init() != 0)
{
my_zlog_error("硬件iic初始化失败"); my_zlog_error("硬件iic初始化失败");
return -7; return -7;
} }
if(device_shot_cooling_init()!=0){ if (device_shot_cooling_init() != 0)
{
my_zlog_warn("该设备没有冷却"); my_zlog_warn("该设备没有冷却");
} }
if (audio_init()==0){ if (audio_init() == 0)
{
my_zlog_info("音频命令执行初始化成功"); my_zlog_info("音频命令执行初始化成功");
} }
int thread_rc=thread_start_init( thread_exit_time,thread_mqtt_beat, int thread_rc = thread_start_init(thread_exit_time, thread_mqtt_beat,
thread_open_browser,thread_mqtt_reconnect,thread_time_calculation,thread_play_mp3); thread_open_browser, thread_mqtt_reconnect, thread_time_calculation, thread_play_mp3);
if(thread_rc != 0){ if (thread_rc != 0)
{
my_zlog_warn("多线程初始化失败"); my_zlog_warn("多线程初始化失败");
return -7; return -7;
} }
thread_end_close(); thread_end_close();
device_end_close(g_device_type); device_end_close(g_device_type);
self_control_thread_close();//销毁自控的线程 self_control_thread_close(); // 销毁自控的线程
my_log_close();//关闭日志 my_log_close(); // 关闭日志
hardware_iic_close(); hardware_iic_close();
my_zlog_info("程序关闭成功"); my_zlog_info("程序关闭成功");
return 0; return 0;
} }
\ No newline at end of file
This diff is collapsed.
...@@ -7,5 +7,8 @@ ...@@ -7,5 +7,8 @@
#include "mylog.h" #include "mylog.h"
#include "mqtt_common.h" #include "mqtt_common.h"
#include "pthrpoll.h" #include "pthrpoll.h"
#include "unix_socket_server.h"
#include "go_deploy.h"
#include "tailscale_deploy.h"
#endif #endif
\ No newline at end of file
This diff is collapsed.
#ifndef GO_DEPLOY_H
#define GO_DEPLOY_H
#ifdef __cplusplus
extern "C" {
#endif
/*
* 检查并更新/部署 Go 程序
* 返回值: 0 成功, -1 失败
*/
int go_deploy_check_and_update(void);
extern char g_webrtc_mode[32];
#ifdef __cplusplus
}
#endif
#endif // GO_DEPLOY_H
#include "unix_socket_server.h"
#include "mqtt_infor_handle.h"
#include "mylog.h"
#include <pthread.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/un.h>
#include <unistd.h>
#define IPC_SOCKET_PATH "/tmp/device_msg.sock"
#define IPC_BUFFER_SIZE 4096
static int g_ipc_server_fd = -1;
static pthread_t g_ipc_thread;
static int g_ipc_running = 0;
static void *ipc_server_thread(void *arg);
int ipc_start_unix_server(const char *socket_path) {
if (g_ipc_running) {
return 0;
}
const char *path = socket_path ? socket_path : IPC_SOCKET_PATH;
g_ipc_server_fd = socket(AF_UNIX, SOCK_STREAM, 0);
if (g_ipc_server_fd < 0) {
my_zlog_error("unix socket 创建失败");
return -1;
}
struct sockaddr_un addr;
memset(&addr, 0, sizeof(addr));
addr.sun_family = AF_UNIX;
strncpy(addr.sun_path, path, sizeof(addr.sun_path) - 1);
unlink(path);
if (bind(g_ipc_server_fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
my_zlog_error("unix socket 绑定失败");
close(g_ipc_server_fd);
g_ipc_server_fd = -1;
return -1;
}
// 设置 socket 文件权限为 0777,允许所有用户读写
if (chmod(path, 0777) < 0) {
my_zlog_warn("设置 socket 文件权限失败");
}
if (listen(g_ipc_server_fd, 5) < 0) {
my_zlog_error("unix socket 监听失败");
close(g_ipc_server_fd);
g_ipc_server_fd = -1;
return -1;
}
g_ipc_running = 1;
if (pthread_create(&g_ipc_thread, NULL, ipc_server_thread, (void *)path) != 0) {
my_zlog_error("unix socket 线程创建失败");
close(g_ipc_server_fd);
g_ipc_server_fd = -1;
g_ipc_running = 0;
return -1;
}
my_zlog_info("IPC Unix socket 服务已启动: %s", path);
return 0;
}
void ipc_stop_unix_server(void) {
if (!g_ipc_running) return;
g_ipc_running = 0;
shutdown(g_ipc_server_fd, SHUT_RDWR);
close(g_ipc_server_fd);
g_ipc_server_fd = -1;
pthread_join(g_ipc_thread, NULL);
}
static void *ipc_server_thread(void *arg) {
char buffer[IPC_BUFFER_SIZE];
while (g_ipc_running) {
int client_fd = accept(g_ipc_server_fd, NULL, NULL);
if (client_fd < 0) {
if (g_ipc_running) {
my_zlog_warn("IPC accept 失败");
}
continue;
}
ssize_t len = read(client_fd, buffer, sizeof(buffer) - 1);
if (len > 0) {
buffer[len] = '\0';
cJSON *root = cJSON_Parse(buffer);
if (root) {
device_message_receive(root);
cJSON_Delete(root);
} else {
my_zlog_warn("IPC 收到无效 JSON");
}
}
close(client_fd);
}
return NULL;
}
\ No newline at end of file
#ifndef IPC_UNIX_SOCKET_SERVER_H
#define IPC_UNIX_SOCKET_SERVER_H
int ipc_start_unix_server(const char *socket_path);
void ipc_stop_unix_server(void);
#endif
\ No newline at end of file
This diff is collapsed.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <cJSON.h>
#include "tailscale_deploy.h"
#include "common.h"
int tailscale_control(cJSON *body) {
if (body == NULL) {
my_zlog_error("tailscale_control: body is NULL");
return -1;
}
cJSON *authkey_json = cJSON_GetObjectItem(body, "authkey");
if (!cJSON_IsString(authkey_json) || (authkey_json->valuestring == NULL)) {
my_zlog_error("tailscale_control: authkey is missing or invalid");
return -2;
}
char *authkey = authkey_json->valuestring;
if (strcmp(authkey, "stop") == 0) {
my_zlog_info("tailscale_control: Stopping Tailscale...");
// 尝试停止 tailscale并捕获输出
FILE *fp = popen("sudo tailscale down 2>&1", "r");
if (fp != NULL) {
char buf[256];
while (fgets(buf, sizeof(buf), fp) != NULL) {
// 去除换行符让日志更整洁
size_t len = strlen(buf);
if (len > 0 && buf[len-1] == '\n') buf[len-1] = '\0';
my_zlog_info("tailscale output: %s", buf);
}
int ret = pclose(fp);
if (WEXITSTATUS(ret) == 0) {
my_zlog_info("tailscale_control: Tailscale stopped successfully");
} else {
my_zlog_error("tailscale_control: Failed to stop Tailscale, ret=%d", WEXITSTATUS(ret));
return -3;
}
} else {
my_zlog_error("tailscale_control: Failed to execute stop command");
return -3;
}
} else {
// 检查 tailscale 是否安装
if (system("which tailscale > /dev/null 2>&1") != 0) {
my_zlog_info("tailscale_control: Tailscale not found. Installing...");
// 安装 tailscale
int install_ret = system("curl -fsSL https://tailscale.com/install.sh | sh");
if (install_ret != 0) {
my_zlog_error("tailscale_control: Failed to install Tailscale, ret=%d", install_ret);
return -4;
}
// 用户要求不开机自启,因此先 disable
system("sudo systemctl disable tailscaled > /dev/null 2>&1");
my_zlog_info("tailscale_control: Tailscale installed successfully");
}
// 确保服务已启动
system("sudo systemctl start tailscaled > /dev/null 2>&1");
// 启动 tailscale
char cmd[512];
snprintf(cmd, sizeof(cmd), "sudo tailscale up --authkey %s --hostname orangepi-01 2>&1", authkey);
my_zlog_info("tailscale_control: Starting Tailscale...");
FILE *fp_up = popen(cmd, "r");
if (fp_up != NULL) {
char buf[256];
while (fgets(buf, sizeof(buf), fp_up) != NULL) {
size_t len = strlen(buf);
if (len > 0 && buf[len-1] == '\n') buf[len-1] = '\0';
my_zlog_info("tailscale up output: %s", buf);
}
int start_ret = pclose(fp_up);
if (WEXITSTATUS(start_ret) == 0) {
my_zlog_info("tailscale_control: Tailscale started successfully");
} else {
my_zlog_error("tailscale_control: Failed to start Tailscale, ret=%d", WEXITSTATUS(start_ret));
return -5;
}
} else {
my_zlog_error("tailscale_control: Failed to execute start command");
return -5;
}
}
return 0;
}
#ifndef TAILSCALE_DEPLOY_H
#define TAILSCALE_DEPLOY_H
#include <cJSON.h>
int tailscale_control(cJSON *body);
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment