forked from gary/ems
2
0
Fork 0
sun_ems/ems_c/app/app_task_regedit.c

516 lines
18 KiB
C
Raw Permalink Normal View History

2025-05-13 17:49:49 +08:00
/*****************************************************************************
* @copyright 1997-2050, . POWER SUPPLY CO., LTD.
* @file app_task_regedit.c
* @brief xx功能
* @author Gary
* @date 2024-09-05
* @remark
*****************************************************************************/
#define _XOPEN_SOURCE 700
#include <errno.h>
#include "kit_db.h"
#include "drv_4g.h"
#include "drv_wifi.h"
#include "mw_schedule_handle.h"
#include "app_task_regedit.h"
// /*****************************************************************************
// * @brief 将 YYYY/DD/MM HH:MM:SS 格式的字符串转换为 timeval 结构体
// * @param[in] timeString: YYYY/DD/MM HH:MM:SS 格式的时间字符串
// * @param[out] tv: 转换后的 timeval 结构体指针
// * @return 0: 成功1: 失败 (无效的时间字符串格式或转换错误)
// *****************************************************************************/
// static int stringToTimeval(const char *timeString, struct timeval *tv)
// {
// struct tm tm = {0}; // 初始化 tm 结构体
// char *strptime_result;
// time_t t;
// // 检查字符串长度
// if (strlen(timeString) != 19)
// {
// KITLOG(LOG_APP_EN, ERROR_EN, "错误:时间字符串长度错误: %s\n", timeString);
// return 1;
// }
// // 使用 strptime 解析时间字符串,注意格式字符串要与 timeString 格式完全匹配
// strptime_result = strptime(timeString, "%Y/%m/%d %H:%M:%S", &tm); // 修改为 %m/%d
// if (strptime_result == NULL)
// {
// KITLOG(LOG_APP_EN, ERROR_EN, "错误strptime 解析时间字符串失败: %s\n", timeString);
// return 1;
// }
// // 将 struct tm 转换为 time_t
// t = mktime(&tm);
// if (t == -1)
// {
// KITLOG(LOG_APP_EN, ERROR_EN, "错误mktime 转换失败: %s\n", timeString);
// return 1;
// }
// tv->tv_sec = t;
// tv->tv_usec = 0;
// return 0;
// }
/*********************************************************************
* @brief EMS时间处理初始化函数NTP或手动
* @param[in] rtc_dev_config: (NTP和手动时间设置参数JSON格式)
* @return 0: 1: (JSON解析失败NTP同步失败)
*********************************************************************/
static int systimeInitHandle(ems_dev_config_t *rtc_dev_config)
{
int ret = 0;
ems_dev_rtc_config_t rtcInfo = {0}; // 使用局部变量,函数结束时自动释放内存
cJSON *json_obj = cJSON_Parse((const char *)rtc_dev_config->content); // 解析JSON配置字符串
if (json_obj == NULL)
{
KITLOG(LOG_APP_EN, ERROR_EN, "错误解析JSON配置失败: %s\n", cJSON_GetErrorPtr());
return 1;
}
cJSON *item;
// 安全地获取JSON对象中的各个字段
item = cJSON_GetObjectItem(json_obj, "isNtp");
rtcInfo.isNtp = (item != NULL && cJSON_IsNumber(item)) ? item->valueint : 0;
// 判断是否使用 NTP 自动对时
if (rtcInfo.isNtp)
{
item = cJSON_GetObjectItem(json_obj, "port");
rtcInfo.port = (item != NULL && cJSON_IsNumber(item)) ? item->valueint : 0;
item = cJSON_GetObjectItem(json_obj, "address");
strncpy((char *)rtcInfo.address, (item != NULL && cJSON_IsString(item)) ? item->valuestring : "", MAX_ADDR_LEN);
rtcInfo.address[MAX_ADDR_LEN - 1] = '\0'; // 确保字符串以'\0'结尾
ret = sync_ntp_timestamp((char *)rtcInfo.address, rtcInfo.port, (char *)AdvancedSettingTable[kLinux_Password].value); // 调用NTP对时函数
if (ret != 0)
{
KITLOG(LOG_APP_EN, ERROR_EN, "错误NTP同步失败: %s\n", strerror(errno));
}
}
// 自启动时不进行手动对时
// else
// {
// item = cJSON_GetObjectItem(json_obj, "manualTime");
// strncpy((char *)rtcInfo.manualTime, (item != NULL && cJSON_IsString(item)) ? item->valuestring : "", sizeof(rtcInfo.manualTime));
// rtcInfo.manualTime[sizeof(rtcInfo.manualTime) - 1] = '\0'; // 确保字符串以'\0'结尾
// struct timeval tv;
// if (stringToTimeval((const char *)rtcInfo.manualTime, &tv) != 0)
// {
// return 1; // stringToTimeval函数已经打印了错误信息
// }
// time_t seconds = tv.tv_sec;
// ret = setSysTime(seconds); // 使用bsp_rtc.c中的setSysTime函数设置系统时间
// if (ret != 0)
// {
// KITLOG(LOG_APP_EN, ERROR_EN, "错误:设置系统时间失败\n");
// return 1;
// }
// }
cJSON_Delete(json_obj); // 释放JSON对象
return ret;
}
/*********************************************************************
* @brief IPmack地址
* @param[in] eth_dev_config:
* @return 0- 1-
*********************************************************************/
static int netInitHandble(ems_dev_config_t *eth_dev_config)
{
int ret = 0;
ems_dev_eth_config_t ethInfo = {0}; // 使用局部变量,函数结束时自动释放内存
cJSON *json_obj = cJSON_Parse((const char *)eth_dev_config->content); // 解析JSON配置字符串
if (json_obj == NULL)
{
KITLOG(LOG_APP_EN, ERROR_EN, "错误解析JSON配置失败: %s\n", cJSON_GetErrorPtr());
return 1;
}
cJSON *item;
// 安全地获取JSON对象中的各个字段
item = cJSON_GetObjectItem(json_obj, "netId");
ethInfo.netId = (item != NULL && cJSON_IsNumber(item)) ? item->valueint : 0;
item = cJSON_GetObjectItem(json_obj, "isDHCP");
ethInfo.isDHCP = (item != NULL && cJSON_IsNumber(item)) ? item->valueint : 0;
item = cJSON_GetObjectItem(json_obj, "address");
strncpy((char *)ethInfo.address, (item != NULL && cJSON_IsString(item)) ? item->valuestring : "", MAX_ADDR_LEN);
ethInfo.address[MAX_ADDR_LEN - 1] = '\0'; // 确保字符串以'\0'结尾
char temp[300] = {0}; // 命令缓冲区
char buffer[256]; // 获取执行返回结果
// 关闭netplan自动覆盖IP配置
snprintf(temp, sizeof(temp), "systemctl stop systemd-networkd.service"); // 使用 DHCP 获取 IP
ret = kit_popen_exec(temp, buffer, sizeof(buffer));
if (ret != 0)
{
KITLOG(LOG_APP_EN, ERROR_EN, "systemctl 执行失败: %s\n", temp);
return 1;
}
// 判断是否使用 DHCP 动态分配 IP
if (ethInfo.isDHCP == 1)
{
snprintf(temp, sizeof(temp), "udhcpc -i eth%d -n", ethInfo.netId); // 使用 DHCP 获取 IP
ret = kit_popen_exec(temp, buffer, sizeof(buffer));
if (ret != 0)
{
KITLOG(LOG_APP_EN, ERROR_EN, "udhcpc 执行失败: %s\n", temp);
return 1;
}
}
else
{
item = cJSON_GetObjectItem(json_obj, "ip");
strncpy((char *)ethInfo.ip, (item != NULL && cJSON_IsString(item)) ? item->valuestring : "", MAX_IP_LEN);
ethInfo.ip[MAX_IP_LEN - 1] = '\0'; // 确保字符串以'\0'结尾
item = cJSON_GetObjectItem(json_obj, "mask");
strncpy((char *)ethInfo.mask, (item != NULL && cJSON_IsString(item)) ? item->valuestring : "", MAX_IP_LEN);
ethInfo.mask[MAX_IP_LEN - 1] = '\0'; // 确保字符串以'\0'结尾
item = cJSON_GetObjectItem(json_obj, "gateway");
strncpy((char *)ethInfo.gateway, (item != NULL && cJSON_IsString(item)) ? item->valuestring : "", MAX_IP_LEN);
ethInfo.gateway[MAX_IP_LEN - 1] = '\0'; // 确保字符串以'\0'结尾
snprintf(temp, sizeof(temp), "ifconfig eth%d %s netmask %s",
ethInfo.netId, ethInfo.ip, ethInfo.mask); // 静态分配 IP 地址和子网掩码
KITPTF(LOG_APP_EN, INFO_EN, "执行IP设置%s", temp);
ret = kit_popen_exec(temp, buffer, sizeof(buffer));
if (ret != 0)
{
KITLOG(LOG_APP_EN, ERROR_EN, "ifconfig 执行失败: %s\n", temp);
return 1;
}
// 设置网关(暂时不用网关地址)
// memset(temp, 0, sizeof(temp));
// snprintf(temp, sizeof(temp), "route add default gw %s eth%d", config->gateway, config->netId);
// ret = kit_popen_exec(temp, buffer, sizeof(buffer));
// if (ret != 0) {
// KITLOG(LOG_APP_EN, ERROR_EN, "route add default gw 执行失败: %s\n", temp);
// return 1;
// }
}
cJSON_Delete(json_obj); // 释放JSON对象
return ret;
}
/*********************************************************************
* @brief Wifi配置
* @param[in] wifi_dev_config: wifi配置信息
* @return 0- 1-
*********************************************************************/
static int sysWifiInitHandle(ems_dev_config_t *wifi_dev_config)
{
int ret = 0;
drv_wifi_t wifiInfo = {0}; // 使用局部变量,函数结束时自动释放内存
cJSON *json_obj = cJSON_Parse((const char *)wifi_dev_config->content); // 解析JSON配置字符串
if (json_obj == NULL)
{
KITLOG(LOG_APP_EN, ERROR_EN, "错误解析JSON配置失败: %s\n", cJSON_GetErrorPtr());
return 1;
}
cJSON *item;
// 安全地获取JSON对象中的各个字段
item = cJSON_GetObjectItem(json_obj, "enable");
wifiInfo.enable = (item != NULL && cJSON_IsNumber(item)) ? item->valueint : 0;
// 在使能关闭时,直接返回
if (wifiInfo.enable == 0)
{
return ret;
}
item = cJSON_GetObjectItem(json_obj, "wifiName");
strncpy((char *)wifiInfo.wifiName, (item != NULL && cJSON_IsString(item)) ? item->valuestring : "", MAX_WIFI_NAME_LEN);
wifiInfo.wifiName[MAX_WIFI_NAME_LEN - 1] = '\0'; // 确保字符串以'\0'结尾
item = cJSON_GetObjectItem(json_obj, "wifiPassword");
strncpy((char *)wifiInfo.wifiPassword, (item != NULL && cJSON_IsString(item)) ? item->valuestring : "", MAX_WIFI_PASS_LEN);
wifiInfo.wifiPassword[MAX_WIFI_PASS_LEN - 1] = '\0'; // 确保字符串以'\0'结尾
cJSON_Delete(json_obj); // 释放JSON对象
ret = drvOpenWifi(&wifiInfo);
if (ret != 0)
{
KITLOG(LOG_APP_EN, ERROR_EN, "错误:设置系统时间失败\n");
return 1;
}
return ret;
}
/*********************************************************************
* @brief 4G配置
* @param[in] fourthg_dev_config4G相关配置
* @return 0- 1-
*********************************************************************/
static int sys4GInitHandle(ems_dev_config_t *fourthg_dev_config)
{
int ret = 0;
drv_4g_t fourthgInfo = {0}; // 使用局部变量,函数结束时自动释放内存
cJSON *json_obj = cJSON_Parse((const char *)fourthg_dev_config->content); // 解析JSON配置字符串
if (json_obj == NULL)
{
KITLOG(LOG_APP_EN, ERROR_EN, "错误解析JSON配置失败: %s\n", cJSON_GetErrorPtr());
return 1;
}
cJSON *item;
// 安全地获取JSON对象中的各个字段
item = cJSON_GetObjectItem(json_obj, "enable");
fourthgInfo.enable = (item != NULL && cJSON_IsNumber(item)) ? item->valueint : 0;
// 在使能关闭时,直接返回
if (fourthgInfo.enable == 0)
{
return ret;
}
item = cJSON_GetObjectItem(json_obj, "cmdContent");
strncpy((char *)fourthgInfo.cmdContent, (item != NULL && cJSON_IsString(item)) ? item->valuestring : "", MAX_CMD_4G_LEN);
fourthgInfo.cmdContent[MAX_CMD_4G_LEN - 1] = '\0'; // 确保字符串以'\0'结尾
cJSON_Delete(json_obj); // 释放JSON对象
ret = drvOpen4G(&fourthgInfo);
if (ret != 0)
{
KITLOG(LOG_APP_EN, ERROR_EN, "错误:设置系统时间失败\n");
return 1;
}
return ret;
}
/*********************************************************************
* @brief ems配置
* @param[in] void
* @return 0- 1-
*********************************************************************/
int initEmsConfig(void)
{
UT_array *emsDevConfigs = {0};
int ret = 0;
if (0 != kit_get_config_db_data(&emsDevConfigs))
{
return 1;
}
utarray_foreach(emsDevConfigs, ems_dev_config_t *, p_emsDevConfig)
{
switch (p_emsDevConfig->type)
{
case kEms_Config_Uart:
// 系统串口不需要初始化
break;
case kEms_Config_Net:
// 初始化系统的IP、MAC地址、网关等配置
ret = netInitHandble(p_emsDevConfig);
break;
case kEms_Config_DI:
break;
case kEms_Config_DO:
break;
case kEms_Config_Rtc:
// 初始化系统时间将rtc时钟同步到linux系统
ret = systimeInitHandle(p_emsDevConfig);
break;
case kEms_Config_Wifi:
ret = sysWifiInitHandle(p_emsDevConfig);
break;
case kEms_Config_4G:
ret = sys4GInitHandle(p_emsDevConfig);
break;
default:
printf("Unknown EMS device config type: %d\n", p_emsDevConfig->type);
ret = 1;
break;
}
if (ret != 0)
{
// 初始化失败,释放资源并返回错误
utarray_free(emsDevConfigs);
return 1;
}
}
// 释放数组内存
utarray_free(emsDevConfigs);
// gpio口初始化
ret = drvGpioOpen();
if (ret != 0)
{
return 1;
}
return ret;
}
/*********************************************************************
* @brief
* @param[in] void
* @return 0- 1-
*********************************************************************/
int initSqliteDb(void) // 初始化系统时间
{
int ret = 0;
// 初始化数据库,"./config"是打包里的sql文件路径
ret = kit_init_db("../initsql");
return ret;
}
/*********************************************************************
* @brief EMS初始化
* @param[in] arg
* @return 0- 1-
*********************************************************************/
uint8_t initEmsSystem(void *arg)
{
int ret = 0;
ret = initSqliteDb();
if (ret != 0)
{
KITPTF(LOG_APP_EN, ERROR_EN, "Sqlite数据库初始化失败");
KITLOG(LOG_APP_EN, ERROR_EN, "Sqlite数据库初始化失败");
return ret;
}
#if HARDWARE_TYPE == -99
ret = initEmsConfig();
if (ret != 0)
{
KITPTF(LOG_APP_EN, ERROR_EN, "EMS盒子配置初始化失败");
KITLOG(LOG_APP_EN, ERROR_EN, "EMS盒子配置初始化失败");
return ret;
}
#endif
ret = initDevInfo();
if (ret != 0)
{
KITPTF(LOG_APP_EN, ERROR_EN, "读取设备配置、电位配置信息失败!");
KITLOG(LOG_APP_EN, ERROR_EN, "读取设备配置、电位配置信息失败!");
return ret;
}
ret = initNorthInfo();
if (ret != 0)
{
KITPTF(LOG_APP_EN, ERROR_EN, "读取北向配置失败!");
KITLOG(LOG_APP_EN, ERROR_EN, "读取北向配置失败!");
return ret;
}
ret = initAdvancedSettingInfo();
if (ret != 0)
{
KITPTF(LOG_APP_EN, ERROR_EN, "读取高级配置失败!");
KITLOG(LOG_APP_EN, ERROR_EN, "读取高级配置失败!");
return ret;
}
ret = initRtdb(rtdbType, NULL, kEE_SHM_CREAT);
if (ret != 0)
{
KITLOG(LOG_APP_EN, ERROR_EN, "RTDB初始化失败");
KITPTF(LOG_APP_EN, ERROR_EN, "RTDB初始化失败");
return ret;
}
ret = initWebSign(kSign_ShMem, kEE_SHM_CREAT);
if (ret != 0)
{
KITLOG(LOG_APP_EN, ERROR_EN, "websign初始化失败");
KITPTF(LOG_APP_EN, ERROR_EN, "websign初始化失败");
return ret;
}
return ret;
}
/*********************************************************************
* @brief
* @param[in] arg
* @return void
*********************************************************************/
void regeditThreadEntry(void *map_t) // 创建线程入口
{
// 创建各种采集任务
creatUartModbusTaskEntry(&protoTable[kProto_ModbusRTU_Master]);
creatNetModbusTaskEntry(&protoTable[kProto_ModbusTCP_Master]);
creatGetLocalParamTaskEntry(100); // 100*50 ms 换算5秒执行一次
/* 创建各种转发任务 */
2025-06-21 16:57:11 +08:00
//creatNetMqttTaskEntry();
2025-05-13 17:49:49 +08:00
/*创建存储任务*/
creatScheduledStorageTask();
/*创建gpio任务*/
2025-06-21 16:57:11 +08:00
//creatGpioModTaskEntry(10); // 初始化 GPIO模块 10*50 ms 换算500ms执行一次
2025-05-13 17:49:49 +08:00
/*创建温控任务*/
2025-06-21 16:57:11 +08:00
//creatLogicTempCtrlEntry();
2025-05-13 17:49:49 +08:00
/*创建策略任务*/
2025-06-21 16:57:11 +08:00
//creatLogicCtrTaskEntry();
2025-05-13 17:49:49 +08:00
}
/*********************************************************************
* @brief EMS的web后台
* @return void
*********************************************************************/
// void runEmsWebApi()
// {
// char temp[300] = {0};
// char buffer[256] = {0};
// char original_dir[500];
// // 获取当前工作目录
// if (getcwd(original_dir, sizeof(original_dir)) == NULL)
// {
// KITLOG(LOG_APP_EN, ERROR_EN, "获取当前工作目录失败: %s\n", strerror(errno));
// return;
// }
// // 更改工作目录
// if (chdir("/opt/ems") != 0)
// {
// KITLOG(LOG_APP_EN, ERROR_EN, "更改工作目录失败: %s\n", strerror(errno));
// return;
// }
// snprintf(temp, sizeof(temp), "nohup /opt/ems/edge-ems-server > /opt/ems/output.log 2>&1 &");
// int ret = kit_popen_exec(temp, buffer, sizeof(buffer));
// if (ret != 0)
// {
// KITLOG(LOG_APP_EN, ERROR_EN, "启动 Ems Web 失败: %s\n", buffer);
// }
// // 恢复原始工作目录
// if (chdir(original_dir) != 0)
// {
// KITLOG(LOG_APP_EN, ERROR_EN, "恢复原始工作目录失败: %s\n", strerror(errno));
// }
// }