754 lines
27 KiB
C
754 lines
27 KiB
C
/*****************************************************************************
|
||
* @copyright Copyright (c) 2025-2055 Gary. All rights reserved.
|
||
* @file app_parse.c
|
||
* @brief 解析所有配置文件的入口
|
||
* @author Gary
|
||
* @date 2024-09-04
|
||
* @remark
|
||
*****************************************************************************/
|
||
|
||
#include "app_parse.h"
|
||
|
||
// 设备管理数组全局变量
|
||
proto_dev_point_map_t protoTable[kProto_Master_End] = {0};
|
||
// 北向配置协议数组全局变量
|
||
north_config_t NorthProtoTable[kProto_Slave_End] = {0};
|
||
// 高级设置数组全局变量
|
||
advanced_setting_t AdvancedSettingTable[kAdvanced_Setting_Type_End] = {0};
|
||
|
||
static void parse_protocol_type_TCP(cJSON *json_obj, dev_protocol_u *protocol_u);
|
||
static void parse_protocol_type_RTU(cJSON *json_obj, dev_protocol_u *protocol_u);
|
||
static dev_protocol_u parse_json(const char protoContent[MAX_CONFIG_CONTENT_LEN], protocol_type_master_e protocolType);
|
||
static north_protocol_u parse_json_north(const char protoContent[MAX_CONFIG_CONTENT_LEN], protocol_type_slave_e protocolType);
|
||
|
||
// 接入EMS的所有设备类型数量
|
||
uint16_t gStDevTypeNum[kDev_Type_End] = {0};
|
||
uint16_t gStDevTypePointNum[kDev_Type_End] =
|
||
{
|
||
kEms_DataEnd,
|
||
kPccMeter_DataEnd,
|
||
kBsMeter_DataEnd,
|
||
kBsu_DataEnd,
|
||
kBcu_DataEnd,
|
||
kPcs_DataEnd,
|
||
kAcLiquidMac_DataEnd,
|
||
kTHSenor_DataEnd,
|
||
kWater_DataEnd,
|
||
kYg_DataEnd,
|
||
kFireprotect_DataEnd,
|
||
kDiDoSign_DataEnd,
|
||
kUps_DataEnd,
|
||
kRev2_DataEnd,
|
||
kRev3_DataEnd,
|
||
kRev4_DataEnd,
|
||
kRev5_DataEnd
|
||
};
|
||
|
||
/*********************************************************************
|
||
* @brief 累加设备数量
|
||
* @param[in] typeNo: 协议类型
|
||
* @return devNum:设备数量
|
||
*********************************************************************/
|
||
void addDevType_Num(dev_type_e typeNo)
|
||
{
|
||
if (typeNo >= kDev_Type_End)
|
||
{
|
||
return;
|
||
}
|
||
gStDevTypeNum[typeNo]++;
|
||
}
|
||
|
||
/*********************************************************************
|
||
* @brief 读取系统配置的设备数量
|
||
* @return 0-成功 1-失败
|
||
*********************************************************************/
|
||
int initDevInfo()
|
||
{
|
||
UT_array *devPointInfo = NULL;
|
||
// 获取数据库ID、设备类型、设备编号、协议类型
|
||
if (0 != kit_get_dev_db_data(&devPointInfo))
|
||
{
|
||
KITLOG(LOG_APP_EN, ERROR_EN, "kit_get_dev_db_data 执行失败!");
|
||
return 1;
|
||
}
|
||
|
||
// 遍历设备
|
||
utarray_foreach(devPointInfo, dev_info_t *, p_dev)
|
||
{
|
||
UT_array *points = NULL;
|
||
char protoContent[MAX_CONFIG_CONTENT_LEN];
|
||
// 通过设备数据库Id获取到对应协议配置内容
|
||
if (0 != kit_get_protocol_db_data(kTemplate_Type_Device, p_dev->devDbId, protoContent))
|
||
{
|
||
printf("load protoContent fail\n");
|
||
if (devPointInfo != NULL)
|
||
{
|
||
utarray_free(devPointInfo); // 释放已分配的内存
|
||
devPointInfo = NULL;
|
||
}
|
||
return 1;
|
||
}
|
||
// 解析协议配置内容
|
||
p_dev->devProtocol = parse_json(protoContent, p_dev->protocolType);
|
||
// 通过设备使用的模板Id获取到对应设备的所有点位
|
||
if (0 != kit_get_point_db_data(p_dev->templateId, &points))
|
||
{
|
||
printf("load protoContent fail");
|
||
if (devPointInfo != NULL)
|
||
{
|
||
utarray_free(devPointInfo); // 释放已分配的内存
|
||
devPointInfo = NULL;
|
||
}
|
||
return 1;
|
||
}
|
||
// 获取点位数量
|
||
p_dev->pointNum = utarray_len(points);
|
||
|
||
if(p_dev->pointNum <= 0)
|
||
{
|
||
if (points != NULL)
|
||
{
|
||
utarray_free(points); // 释放已分配的内存
|
||
points = NULL;
|
||
}
|
||
continue;
|
||
}
|
||
|
||
p_dev->pointArr = calloc(p_dev->pointNum, sizeof(point_t));
|
||
if (p_dev->pointArr == NULL)
|
||
{
|
||
printf("Memory allocation for pointArr failed\n");
|
||
if (points != NULL)
|
||
{
|
||
utarray_free(points); // 释放已分配的内存
|
||
points = NULL;
|
||
}
|
||
if (devPointInfo != NULL)
|
||
{
|
||
utarray_free(devPointInfo); // 释放已分配的内存
|
||
devPointInfo = NULL;
|
||
}
|
||
return 1;
|
||
}
|
||
int i = 0;
|
||
// 遍历点位
|
||
utarray_foreach(points, point_t *, tag)
|
||
{
|
||
if(i < p_dev->pointNum)
|
||
{
|
||
p_dev->pointArr[i] = *tag; // 使用结构体直接赋值
|
||
//strncpy((char *)p_dev->pointArr[i].pointName, (char *)tag->pointName, MAX_POINT_NAME_LEN);
|
||
i++;
|
||
}
|
||
}
|
||
|
||
if (points != NULL)
|
||
{
|
||
utarray_free(points); // 释放已分配的内存
|
||
points = NULL;
|
||
}
|
||
|
||
// 将设备信息存储到 protoTable 中
|
||
protocol_type_master_e protocolType = p_dev->protocolType;
|
||
proto_dev_point_map_t *protoEntry = &protoTable[protocolType];
|
||
|
||
// 检查并动态扩展设备数组
|
||
if (protoEntry->devNum == 0)
|
||
{
|
||
protoEntry->devPointMapArr = (dev_info_t *)calloc(1, sizeof(dev_info_t));
|
||
if (protoEntry->devPointMapArr == NULL)
|
||
{
|
||
printf("Memory allocation failed for devPointMapArr\n");
|
||
if (devPointInfo != NULL)
|
||
{
|
||
utarray_free(devPointInfo); // 释放已分配的内存
|
||
devPointInfo = NULL;
|
||
}
|
||
return 1;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// 动态扩展设备数组的大小以存储新设备
|
||
dev_info_t *newArr = (dev_info_t *)realloc(protoEntry->devPointMapArr, (protoEntry->devNum + 1) * sizeof(dev_info_t));
|
||
if (newArr == NULL)
|
||
{
|
||
printf("Memory allocation failed during realloc");
|
||
if (devPointInfo != NULL)
|
||
{
|
||
utarray_free(devPointInfo); // 释放已分配的内存
|
||
devPointInfo = NULL;
|
||
}
|
||
return 1;
|
||
}
|
||
protoEntry->devPointMapArr = newArr;
|
||
}
|
||
|
||
// 防止配置端并没有配置任何的测点也导致设备加1
|
||
if (p_dev->pointNum > 0)
|
||
{
|
||
addDevType_Num(p_dev->devType);
|
||
// 将设备信息复制到协议设备数组
|
||
memcpy(&protoEntry->devPointMapArr[protoEntry->devNum], p_dev, sizeof(dev_info_t));
|
||
protoEntry->devNum++;
|
||
}
|
||
}
|
||
|
||
if (devPointInfo != NULL)
|
||
{
|
||
utarray_free(devPointInfo); // 释放已分配的内存
|
||
devPointInfo = NULL;
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
/*********************************************************************
|
||
* @brief 读取系统配置的北向协议
|
||
* @return 0-成功 1-失败
|
||
*********************************************************************/
|
||
int initNorthInfo()
|
||
{
|
||
UT_array *northInfoArr = NULL;
|
||
// 获取数据库ID、设备类型、设备编号、协议类型
|
||
if (0 != kit_get_north_config_arr(&northInfoArr))
|
||
{
|
||
|
||
return 1;
|
||
}
|
||
// 遍历设备
|
||
utarray_foreach(northInfoArr, north_config_t *, p_northInfo)
|
||
{
|
||
char protoContent[MAX_CONFIG_CONTENT_LEN];
|
||
// 通过设备数据库Id获取到对应协议配置内容
|
||
if (0 != kit_get_protocol_db_data(kTemplate_Type_North, p_northInfo->dbId, protoContent))
|
||
{
|
||
|
||
KITLOG(LOG_APP_EN, ERROR_EN, "获取北向协议连接配置失败!");
|
||
if (northInfoArr != NULL)
|
||
{
|
||
utarray_free(northInfoArr); // 释放已分配的内存
|
||
northInfoArr = NULL;
|
||
}
|
||
|
||
return 1;
|
||
}
|
||
// 解析协议配置内容
|
||
p_northInfo->northProtocol = parse_json_north(protoContent, p_northInfo->protocolType);
|
||
|
||
// 将查到的北向配置数据复制给全局变量
|
||
north_config_t *protoEntry = &NorthProtoTable[p_northInfo->protocolType];
|
||
memcpy(protoEntry, p_northInfo, sizeof(north_config_t));
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|
||
/*********************************************************************
|
||
* @brief 读取高级设置的信息
|
||
* @return 0-成功 1-失败
|
||
*********************************************************************/
|
||
int initAdvancedSettingInfo()
|
||
{
|
||
UT_array *advancedSettings = NULL;
|
||
|
||
//给个默认值
|
||
snprintf((char *)AdvancedSettingTable[kLinux_Password].value, MAX_VALUE_LEN, "%s", "forlinx"); // value值
|
||
|
||
// 获取高级设置项
|
||
if (0 != kit_get_advanced_setting(&advancedSettings))
|
||
{
|
||
return 1;
|
||
}
|
||
// 遍历设备
|
||
utarray_foreach(advancedSettings, advanced_setting_t *, p_advancedSetting)
|
||
{
|
||
// EMS工作模式
|
||
if (strncmp((const char *)p_advancedSetting->key, "ems_mode", 8) == 0)
|
||
{
|
||
snprintf((char *)AdvancedSettingTable[kEms_Mode].key, MAX_KEY_LEN, "%s", p_advancedSetting->key); // key值
|
||
snprintf((char *)AdvancedSettingTable[kEms_Mode].value, MAX_VALUE_LEN, "%s", p_advancedSetting->value); // value值
|
||
}
|
||
// Linux密码
|
||
else if (strncmp((const char *)p_advancedSetting->key, "linux_password", 14) == 0)
|
||
{
|
||
snprintf((char *)AdvancedSettingTable[kLinux_Password].key, MAX_KEY_LEN, "%s", p_advancedSetting->key); // key值
|
||
snprintf((char *)AdvancedSettingTable[kLinux_Password].value, MAX_VALUE_LEN, "%s", p_advancedSetting->value); // value值
|
||
}
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|
||
|
||
/*********************************************************************
|
||
* @brief 解析协议类型 TCP 的 JSON 字符串,并将解析结果赋值给联合体
|
||
* @param[in] json_obj: JSON 对象
|
||
* @param[out] protocol_u: 联合体指针,存储解析结果
|
||
* @return none
|
||
*********************************************************************/
|
||
static void parse_protocol_type_TCP(cJSON *json_obj, dev_protocol_u *protocol_u)
|
||
{
|
||
cJSON *host = cJSON_GetObjectItem(json_obj, "ip");
|
||
cJSON *port = cJSON_GetObjectItem(json_obj, "port");
|
||
cJSON *netId = cJSON_GetObjectItem(json_obj, "netId");
|
||
cJSON *timeout = cJSON_GetObjectItem(json_obj, "timeout");
|
||
cJSON *uId = cJSON_GetObjectItem(json_obj, "uId");
|
||
if (host && cJSON_IsString(host))
|
||
{
|
||
// 赋值给联合体的 tcpClientLib 成员的 host 字段
|
||
strcpy(protocol_u->tcpClientLib.ip, host->valuestring);
|
||
}
|
||
if (port && cJSON_IsNumber(port))
|
||
{
|
||
// 赋值给联合体的 tcpClientLib 成员的 port 字段
|
||
protocol_u->tcpClientLib.port = port->valueint;
|
||
}
|
||
if (netId && cJSON_IsNumber(netId))
|
||
{
|
||
// 赋值给联合体的 tcpClientLib 成员的 port 字段
|
||
protocol_u->tcpClientLib.netId = netId->valueint;
|
||
}
|
||
if (timeout && cJSON_IsNumber(timeout))
|
||
{
|
||
// 赋值给联合体的 tcpClientLib 成员的 timeout 字段
|
||
protocol_u->tcpClientLib.timeout = timeout->valueint;
|
||
}
|
||
if (uId && cJSON_IsNumber(uId))
|
||
{
|
||
protocol_u->tcpClientLib.uId = uId->valueint;
|
||
}
|
||
}
|
||
|
||
/*********************************************************************
|
||
* @brief 解析协议类型 RTU 的 JSON 字符串,并将解析结果赋值给联合体
|
||
* @param[in] json_obj: JSON 对象
|
||
* @param[out] protocol_u: 联合体指针,存储解析结果
|
||
* @return none
|
||
*********************************************************************/
|
||
static void parse_protocol_type_RTU(cJSON *json_obj, dev_protocol_u *protocol_u)
|
||
{
|
||
cJSON *address = cJSON_GetObjectItem(json_obj, "address");
|
||
cJSON *timeout = cJSON_GetObjectItem(json_obj, "timeout");
|
||
cJSON *stop = cJSON_GetObjectItem(json_obj, "stop");
|
||
cJSON *parity = cJSON_GetObjectItem(json_obj, "parity");
|
||
cJSON *baud = cJSON_GetObjectItem(json_obj, "baud");
|
||
cJSON *data = cJSON_GetObjectItem(json_obj, "data");
|
||
cJSON *uartId = cJSON_GetObjectItem(json_obj, "uartId");
|
||
cJSON *uId = cJSON_GetObjectItem(json_obj, "uId");
|
||
|
||
if (address && cJSON_IsString(address))
|
||
{
|
||
// 赋值给联合体的 uartLib 成员的 address 字段
|
||
strncpy((char *)protocol_u->uartLib.address, address->valuestring, MAX_ADDR_LEN - 1);
|
||
protocol_u->uartLib.address[MAX_ADDR_LEN - 1] = '\0'; // 确保以 null 结尾
|
||
}
|
||
if (uId && cJSON_IsNumber(uId))
|
||
{
|
||
// 赋值给联合体的 uartLib 成员的 timeout 字段
|
||
protocol_u->uartLib.uId = uId->valueint;
|
||
}
|
||
if (timeout && cJSON_IsNumber(timeout))
|
||
{
|
||
// 赋值给联合体的 uartLib 成员的 timeout 字段
|
||
protocol_u->uartLib.timeout = timeout->valueint;
|
||
}
|
||
if (stop && cJSON_IsNumber(stop))
|
||
{
|
||
// 赋值给联合体的 uartLib 成员的 stop 字段
|
||
protocol_u->uartLib.stop = stop->valueint;
|
||
}
|
||
if (parity && cJSON_IsNumber(parity))
|
||
{
|
||
// 赋值给联合体的 uartLib 成员的 parity 字段
|
||
protocol_u->uartLib.parity = parity->valueint;
|
||
}
|
||
if (baud && cJSON_IsNumber(baud))
|
||
{
|
||
// 赋值给联合体的 uartLib 成员的 baud 字段
|
||
protocol_u->uartLib.baud = baud->valueint;
|
||
}
|
||
if (data && cJSON_IsNumber(data))
|
||
{
|
||
// 赋值给联合体的 uartLib 成员的 data 字段
|
||
protocol_u->uartLib.data = data->valueint;
|
||
}
|
||
if (uartId && cJSON_IsNumber(uartId))
|
||
{
|
||
// 赋值给联合体的 uartLib 成员的 串口号 字段
|
||
protocol_u->uartLib.uartId = uartId->valueint;
|
||
}
|
||
}
|
||
|
||
/*********************************************************************
|
||
* @brief 解析 JSON 字符串
|
||
* @param[in] protoContent: JSON 字符串
|
||
* @param[in] protocolType: 协议类型
|
||
* @return none
|
||
*********************************************************************/
|
||
static dev_protocol_u parse_json(const char protoContent[MAX_CONFIG_CONTENT_LEN], protocol_type_master_e protocolType)
|
||
{
|
||
// 解析 JSON 字符串
|
||
cJSON *json_obj = cJSON_Parse(protoContent);
|
||
if (json_obj == NULL)
|
||
{
|
||
fprintf(stderr, "Error parsing JSON\n");
|
||
dev_protocol_u emptyProtocol = {0}; // 如果解析失败,返回一个空的联合体
|
||
return emptyProtocol;
|
||
}
|
||
|
||
dev_protocol_u tempProtocol_u = {0};
|
||
|
||
switch (protocolType)
|
||
{
|
||
case kProto_ModbusTCP_Master:
|
||
parse_protocol_type_TCP(json_obj, &tempProtocol_u);
|
||
break;
|
||
|
||
case kProto_ModbusRTU_Master:
|
||
parse_protocol_type_RTU(json_obj, &tempProtocol_u);
|
||
break;
|
||
default:
|
||
fprintf(stderr, "Unsupported protocol type: %d\n", protocolType);
|
||
break;
|
||
}
|
||
|
||
// 释放 JSON 解析对象
|
||
cJSON_Delete(json_obj);
|
||
return tempProtocol_u; // 返回解析后的联合体
|
||
}
|
||
/*********************************************************************
|
||
* @brief 用指定内容替换源字符串中的指定位置
|
||
* @param[in] source: 源字符串
|
||
* @param[in] replacement: 需要写入源字符串的字符串
|
||
* @param[in] wordIndex: 被分隔符分割的子串索引,例如a/b/c/d,abcd的索引依次为1234
|
||
* @param[in] divide: 分隔符
|
||
* @return 修改后的字符串
|
||
*********************************************************************/
|
||
char *replaceSubStrByIndexAndTag(const char *source, const char *replacement, int wordIndex, char divide)
|
||
{
|
||
if (wordIndex <= 0)
|
||
{
|
||
// 如果wordIndex无效,返回source的副本
|
||
size_t source_len = strlen(source);
|
||
char *result = (char *)malloc(source_len + 1);
|
||
if (result)
|
||
{
|
||
strcpy(result, source);
|
||
}
|
||
return result;
|
||
}
|
||
|
||
const char *start_position = source, *end_position = NULL;
|
||
int current_word = 0;
|
||
|
||
// 定位要替换部分的起始和结束位置
|
||
for (const char *p = source; *p != '\0'; p++)
|
||
{
|
||
if (*p == divide)
|
||
{
|
||
current_word++;
|
||
if (current_word == wordIndex - 1)
|
||
{
|
||
start_position = p + 1;
|
||
}
|
||
else if (current_word == wordIndex)
|
||
{
|
||
end_position = p;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
// 如果在字符串中找不到足够多的分隔符
|
||
if (current_word < wordIndex)
|
||
{
|
||
end_position = source + strlen(source);
|
||
}
|
||
|
||
// 计算新字符串的长度
|
||
size_t new_length = (start_position - source) + strlen(replacement) + strlen(end_position);
|
||
|
||
// 为新字符串分配内存
|
||
char *result = (char *)malloc(new_length + 1);
|
||
if (!result)
|
||
{
|
||
return NULL; // 处理内存分配错误
|
||
}
|
||
|
||
// 复制第一部分
|
||
strncpy(result, source, start_position - source);
|
||
result[start_position - source] = '\0'; // null终止新字符串
|
||
|
||
// 连接替换字符串
|
||
strcat(result, replacement);
|
||
|
||
// 连接第二部分
|
||
strcat(result, end_position);
|
||
|
||
return result;
|
||
}
|
||
/*********************************************************************
|
||
* @brief 读取设备序列号填入主题
|
||
* @param[in] src:源字符串
|
||
* @return 带EMS序列号的主题
|
||
*********************************************************************/
|
||
static char *getTopicWithEMSSN(char *const src)
|
||
{
|
||
char serial[128];
|
||
int rc = kit_get_ems_sn(serial);
|
||
if (rc != 0)
|
||
{
|
||
return src;
|
||
}
|
||
char *topic = (char *)malloc(MAX_TOPIC_LEN); // 动态分配内存
|
||
if (!topic)
|
||
{
|
||
return NULL; // 内存分配失败处理
|
||
}
|
||
topic[0] = '\0'; // 初始化第一个字符为 null,以防止拷贝操作中读到未初始化的数据
|
||
|
||
if (src)
|
||
{
|
||
char *modifiedString = replaceSubStrByIndexAndTag(src, serial, 3, '/');
|
||
if (modifiedString)
|
||
{
|
||
strncpy(topic, modifiedString, MAX_TOPIC_LEN - 1);
|
||
topic[MAX_TOPIC_LEN - 1] = '\0'; // 确保字符串以 null 结尾
|
||
free(modifiedString); // 不要忘记释放动态内存
|
||
}
|
||
}
|
||
#ifdef MQTTPRINT
|
||
printf("topic is %s\n", topic);
|
||
printf("topic length is %ld\n", strlen(topic));
|
||
#endif
|
||
return topic; // 返回 heap 分配的指针给调用者,这样它在退出后依然有效
|
||
}
|
||
/*********************************************************************
|
||
* @brief 解析协议类型 MQTT_Slave 的 JSON 字符串,并将解析结果赋值给联合体
|
||
* @param[in] json_obj: JSON 对象
|
||
* @param[out] protocol_u: 联合体指针,存储解析结果
|
||
* @return none
|
||
*********************************************************************/
|
||
static void parse_protocol_type_MQTT_slave(cJSON *json_obj, north_protocol_u *protocol_u)
|
||
{
|
||
cJSON *clientId = cJSON_GetObjectItem(json_obj, "clientId");
|
||
cJSON *rootTopic = cJSON_GetObjectItem(json_obj, "rootTopic");
|
||
cJSON *periodTopic = cJSON_GetObjectItem(json_obj, "periodTopic");
|
||
cJSON *changeTopic = cJSON_GetObjectItem(json_obj, "changeTopic");
|
||
cJSON *historyTopic = cJSON_GetObjectItem(json_obj, "historyTopic");
|
||
cJSON *controlTopic = cJSON_GetObjectItem(json_obj, "controlTopic");
|
||
cJSON *readTopic = cJSON_GetObjectItem(json_obj, "readTopic");
|
||
cJSON *replyControlTopic = cJSON_GetObjectItem(json_obj, "replyControlTopic");
|
||
cJSON *replyReadTopic = cJSON_GetObjectItem(json_obj, "replyReadTopic");
|
||
cJSON *tSendTaskPeriod = cJSON_GetObjectItem(json_obj, "tSendTaskPeriod");
|
||
cJSON *ip = cJSON_GetObjectItem(json_obj, "ip");
|
||
cJSON *qos = cJSON_GetObjectItem(json_obj, "qos");
|
||
cJSON *port = cJSON_GetObjectItem(json_obj, "port");
|
||
cJSON *isSsl = cJSON_GetObjectItem(json_obj, "isSsl");
|
||
cJSON *username = cJSON_GetObjectItem(json_obj, "username");
|
||
cJSON *password = cJSON_GetObjectItem(json_obj, "password");
|
||
cJSON *caCert = cJSON_GetObjectItem(json_obj, "caCert");
|
||
cJSON *x509Cert = cJSON_GetObjectItem(json_obj, "x509Cert");
|
||
cJSON *keyCert = cJSON_GetObjectItem(json_obj, "keyCert");
|
||
|
||
if (clientId && cJSON_IsString(clientId))
|
||
{
|
||
strcpy((char *)protocol_u->mqttLib.clientId, clientId->valuestring);
|
||
}
|
||
char *strwithsn = getTopicWithEMSSN(rootTopic->valuestring);
|
||
strcpy((char *)protocol_u->mqttLib.rootTopic, strwithsn);
|
||
|
||
strwithsn = getTopicWithEMSSN(periodTopic->valuestring);
|
||
strcpy((char *)protocol_u->mqttLib.periodTopic, strwithsn);
|
||
|
||
strwithsn = getTopicWithEMSSN(changeTopic->valuestring);
|
||
strcpy((char *)protocol_u->mqttLib.changeTopic, strwithsn);
|
||
|
||
strwithsn = getTopicWithEMSSN(historyTopic->valuestring);
|
||
strcpy((char *)protocol_u->mqttLib.historyTopic, strwithsn);
|
||
|
||
strwithsn = getTopicWithEMSSN(controlTopic->valuestring);
|
||
strcpy((char *)protocol_u->mqttLib.controlTopic, strwithsn);
|
||
|
||
strwithsn = getTopicWithEMSSN(readTopic->valuestring);
|
||
strcpy((char *)protocol_u->mqttLib.readTopic, strwithsn);
|
||
|
||
strwithsn = getTopicWithEMSSN(replyControlTopic->valuestring);
|
||
strcpy((char *)protocol_u->mqttLib.replycontrolTopic, strwithsn);
|
||
|
||
strwithsn = getTopicWithEMSSN(replyReadTopic->valuestring);
|
||
strcpy((char *)protocol_u->mqttLib.replyreadTopic, strwithsn);
|
||
#ifdef MQTTPRINT
|
||
printf("%s\n", protocol_u->mqttLib.rootTopic);
|
||
printf("%s\n", protocol_u->mqttLib.periodTopic);
|
||
printf("%s\n", protocol_u->mqttLib.changeTopic);
|
||
printf("%s\n", protocol_u->mqttLib.controlTopic);
|
||
printf("%s\n", protocol_u->mqttLib.readTopic);
|
||
printf("%s\n", protocol_u->mqttLib.replycontrolTopic);
|
||
printf("%s\n", protocol_u->mqttLib.replyreadTopic);
|
||
#endif
|
||
// if (rootTopic && cJSON_IsString(rootTopic))
|
||
// {
|
||
// strcpy((char *)protocol_u->mqttLib.rootTopic, rootTopic->valuestring);
|
||
// }
|
||
// if (periodTopic && cJSON_IsString(periodTopic))
|
||
// {
|
||
// strcpy((char *)protocol_u->mqttLib.periodTopic, periodTopic->valuestring);
|
||
// }
|
||
// if (changeTopic && cJSON_IsString(changeTopic))
|
||
// {
|
||
// strcpy((char *)protocol_u->mqttLib.changeTopic, changeTopic->valuestring);
|
||
// }
|
||
// if (historyTopic && cJSON_IsString(historyTopic))
|
||
// {
|
||
// strcpy((char *)protocol_u->mqttLib.historyTopic, historyTopic->valuestring);
|
||
// }
|
||
// if (controlTopic && cJSON_IsString(controlTopic))
|
||
// {
|
||
// strcpy((char *)protocol_u->mqttLib.controlTopic, controlTopic->valuestring);
|
||
// }
|
||
// if (readTopic && cJSON_IsString(readTopic))
|
||
// {
|
||
// strcpy((char *)protocol_u->mqttLib.readTopic, readTopic->valuestring);
|
||
// }
|
||
// if (replyControlTopic && cJSON_IsString(replyControlTopic))
|
||
// {
|
||
// strcpy((char *)protocol_u->mqttLib.replycontrolTopic, replyControlTopic->valuestring);
|
||
// }
|
||
// if (replyReadTopic && cJSON_IsString(replyReadTopic))
|
||
// {
|
||
// strcpy((char*)protocol_u->mqttLib.replyreadTopic, replyReadTopic->valuestring);
|
||
// }
|
||
if (tSendTaskPeriod && cJSON_IsNumber(tSendTaskPeriod))
|
||
{
|
||
protocol_u->mqttLib.tSendTaskPeriod = tSendTaskPeriod->valueint;
|
||
}
|
||
else
|
||
{
|
||
protocol_u->mqttLib.tSendTaskPeriod = 5; // 先给个默认值5s
|
||
}
|
||
if (ip && cJSON_IsString(ip))
|
||
{
|
||
strcpy((char *)protocol_u->mqttLib.url, ip->valuestring);
|
||
}
|
||
if (qos && cJSON_IsNumber(qos))
|
||
{
|
||
protocol_u->mqttLib.qos = qos->valueint;
|
||
}
|
||
if (port && cJSON_IsNumber(port))
|
||
{
|
||
protocol_u->mqttLib.port = port->valueint;
|
||
}
|
||
if (isSsl && cJSON_IsNumber(isSsl))
|
||
{
|
||
protocol_u->mqttLib.isSsl = isSsl->valueint;
|
||
}
|
||
if (username && cJSON_IsString(username))
|
||
{
|
||
strcpy((char *)protocol_u->mqttLib.username, username->valuestring);
|
||
}
|
||
if (password && cJSON_IsString(password))
|
||
{
|
||
strcpy((char *)protocol_u->mqttLib.password, password->valuestring);
|
||
}
|
||
if (caCert && cJSON_IsString(caCert))
|
||
{
|
||
strcpy((char *)protocol_u->mqttLib.caCert, caCert->valuestring);
|
||
}
|
||
if (x509Cert && cJSON_IsString(x509Cert))
|
||
{
|
||
strcpy((char *)protocol_u->mqttLib.x509Cert, x509Cert->valuestring);
|
||
}
|
||
if (keyCert && cJSON_IsString(keyCert))
|
||
{
|
||
strcpy((char *)protocol_u->mqttLib.keyCert, keyCert->valuestring);
|
||
}
|
||
}
|
||
|
||
/*********************************************************************
|
||
* @brief 解析 JSON 字符串
|
||
* @param[in] protoContent: JSON 字符串
|
||
* @param[in] protocolType: 协议类型
|
||
* @return none
|
||
*********************************************************************/
|
||
static north_protocol_u parse_json_north(const char protoContent[MAX_CONFIG_CONTENT_LEN], protocol_type_slave_e protocolType)
|
||
{
|
||
// 解析 JSON 字符串
|
||
cJSON *json = cJSON_Parse(protoContent);
|
||
if (json == NULL)
|
||
{
|
||
fprintf(stderr, "Error parsing JSON\n");
|
||
north_protocol_u emptyProtocol = {0}; // 如果解析失败,返回一个空的联合体
|
||
return emptyProtocol;
|
||
}
|
||
|
||
north_protocol_u tempProtocol = {0};
|
||
|
||
switch (protocolType)
|
||
{
|
||
case kProto_MQTT_Slave:
|
||
{
|
||
parse_protocol_type_MQTT_slave(json, &tempProtocol);
|
||
break;
|
||
}
|
||
// Add other cases for different protocol types
|
||
default:
|
||
fprintf(stderr, "Unsupported protocol type: %d\n", protocolType);
|
||
break;
|
||
}
|
||
|
||
// 释放 JSON 解析对象
|
||
cJSON_Delete(json);
|
||
return tempProtocol; // 返回解析后的联合体
|
||
}
|
||
|
||
/*********************************************************************
|
||
* @brief 根据设备类型和设备ID获取设备的点位数组
|
||
* @param[in] devType 设备类型
|
||
* @param[in] devId 设备ID
|
||
* @return 返回匹配设备的点位数组,未找到返回 NULL
|
||
*********************************************************************/
|
||
point_t *get_pointArr(dev_type_e devType, uint16_t devArrayId)
|
||
{
|
||
for (int i = 0; i < kProto_Master_End; i++)
|
||
{
|
||
if (protoTable[i].devPointMapArr == NULL)
|
||
{
|
||
continue; // 跳过空协议
|
||
}
|
||
for (int j = 0; j < protoTable[i].devNum; j++)
|
||
{
|
||
if (protoTable[i].devPointMapArr[j].devType == devType && (protoTable[i].devPointMapArr[j].devId == devArrayId + 1))
|
||
{
|
||
return protoTable[i].devPointMapArr[j].pointArr; // 返回匹配设备的 pointArr
|
||
}
|
||
}
|
||
}
|
||
return NULL; // 未找到匹配设备,返回 NULL
|
||
}
|
||
|
||
/*********************************************************************
|
||
* @brief 根据设备类型和设备ID获取设备的点位数组
|
||
* @param[in] devType 设备类型
|
||
* @param[in] devId 设备ID
|
||
* @return 返回匹配设备的点位数组,未找到返回 NULL
|
||
*********************************************************************/
|
||
dev_info_t *get_devPointMapArr(dev_type_e devType, uint16_t devArrayId)
|
||
{
|
||
for (int i = 0; i < kProto_Master_End; i++)
|
||
{
|
||
if (protoTable[i].devPointMapArr == NULL)
|
||
{
|
||
continue; // 跳过空协议
|
||
}
|
||
for (int j = 0; j < protoTable[i].devNum; j++)
|
||
{
|
||
if (protoTable[i].devPointMapArr[j].devType == devType && (protoTable[i].devPointMapArr[j].devId == devArrayId + 1))
|
||
{
|
||
return &protoTable[i].devPointMapArr[j]; // 返回匹配设备的 pointArr
|
||
}
|
||
}
|
||
}
|
||
return NULL; // 未找到匹配设备,返回 NULL
|
||
}
|