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

754 lines
27 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*****************************************************************************
* @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
}