添加装置重启功能和控制位写入功能
This commit is contained in:
@@ -4204,6 +4204,18 @@ int terminal_ledger_web(QMap<QString, terminal_dev*>* terminal_dev_map,
|
|||||||
return 0; // 确保函数有返回值
|
return 0; // 确保函数有返回值
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void init_oper_type_cache(ied_usr_t *ied_usr)
|
||||||
|
{
|
||||||
|
if (ied_usr == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ied_usr->oper_type_cache.inited = SD_FALSE;
|
||||||
|
|
||||||
|
ied_usr->oper_type_cache.ledrs_oper_type_id = -1;
|
||||||
|
ied_usr->oper_type_cache.reboot_oper_type_id = -1;
|
||||||
|
ied_usr->oper_type_cache.reset_oper_type_id = -1;
|
||||||
|
}
|
||||||
|
|
||||||
int parse_device_cfg_web()
|
int parse_device_cfg_web()
|
||||||
{
|
{
|
||||||
std::cout << "parse_device_cfg_web" << endl;
|
std::cout << "parse_device_cfg_web" << endl;
|
||||||
@@ -4437,6 +4449,10 @@ int parse_device_cfg_web()
|
|||||||
apr_snprintf(ied_usr->dev_key, sizeof(ied_usr->dev_key), "%s", "");//DEV_Key
|
apr_snprintf(ied_usr->dev_key, sizeof(ied_usr->dev_key), "%s", "");//DEV_Key
|
||||||
cout << "defalut dev_key:" << ied_usr->dev_key << endl;
|
cout << "defalut dev_key:" << ied_usr->dev_key << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//lnk20260512
|
||||||
|
init_oper_type_cache(ied_usr);
|
||||||
|
|
||||||
//lnk20260304
|
//lnk20260304
|
||||||
ied_usr->log_level = log_level;//日志等级
|
ied_usr->log_level = log_level;//日志等级
|
||||||
cout << "ied_usr->log_level:" << ied_usr->log_level << endl;
|
cout << "ied_usr->log_level:" << ied_usr->log_level << endl;
|
||||||
@@ -5600,6 +5616,15 @@ int DownloadFileWeb(const std::string& strUrl,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (chmod(localpath, 0777) != 0)
|
||||||
|
{
|
||||||
|
std::cerr << "chmod 777 failed: " << localpath << std::endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cout << "chmod 777 success: " << localpath << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5733,6 +5758,9 @@ int update_one_terminal_ledger(terminal* update, int i,ied_t* ied,int terminal_i
|
|||||||
chnl_usr->m_state = CHANNEL_DISCONNECTED;
|
chnl_usr->m_state = CHANNEL_DISCONNECTED;
|
||||||
chnl_usr->m_ClosedMsTime = NEXT_CONNECT_TIME * (-1);
|
chnl_usr->m_ClosedMsTime = NEXT_CONNECT_TIME * (-1);
|
||||||
|
|
||||||
|
//lnk20260512
|
||||||
|
init_oper_type_cache(ied_usr);
|
||||||
|
|
||||||
// 将 monitorData 中的数据写入到 LD_info 中
|
// 将 monitorData 中的数据写入到 LD_info 中
|
||||||
int count_real_monitor = 0; //遍历监测点台账的计数器
|
int count_real_monitor = 0; //遍历监测点台账的计数器
|
||||||
int j;
|
int j;
|
||||||
|
|||||||
@@ -166,6 +166,7 @@ public:
|
|||||||
QString WavePhasicB;
|
QString WavePhasicB;
|
||||||
QString WavePhasicC;
|
QString WavePhasicC;
|
||||||
QString TypeOfData; //闪变和统计是否合并 0-分开 1-合并
|
QString TypeOfData; //闪变和统计是否合并 0-分开 1-合并
|
||||||
|
QString IEDControl; //例:LD0 lnk2026-5-13
|
||||||
QString UnitOfTimeUnit; //暂态事件持续事件单位:0 - 毫秒 1 - 秒 lnk20260127
|
QString UnitOfTimeUnit; //暂态事件持续事件单位:0 - 毫秒 1 - 秒 lnk20260127
|
||||||
QString ValueOfTimeUnit; //上送值的时间:UTC-UTC时间 beijing-北京时间
|
QString ValueOfTimeUnit; //上送值的时间:UTC-UTC时间 beijing-北京时间
|
||||||
QString WaveTimeFlag; //录波文件的时间:UTC-UTC时间 beijing-北京时间
|
QString WaveTimeFlag; //录波文件的时间:UTC-UTC时间 beijing-北京时间
|
||||||
@@ -384,6 +385,7 @@ bool get_xml_config_by_dev_type(const char* dev_type, XmlConfigC* out_cfg) {
|
|||||||
strncpy(out_cfg->TypeOfData, cfg.TypeOfData.toUtf8().constData(), sizeof(out_cfg->TypeOfData) - 1); out_cfg->TypeOfData[sizeof(out_cfg->TypeOfData) - 1] = '\0';//lnk20260127
|
strncpy(out_cfg->TypeOfData, cfg.TypeOfData.toUtf8().constData(), sizeof(out_cfg->TypeOfData) - 1); out_cfg->TypeOfData[sizeof(out_cfg->TypeOfData) - 1] = '\0';//lnk20260127
|
||||||
strncpy(out_cfg->ValueOfTimeUnit, cfg.ValueOfTimeUnit.toUtf8().constData(),sizeof(out_cfg->ValueOfTimeUnit) - 1);
|
strncpy(out_cfg->ValueOfTimeUnit, cfg.ValueOfTimeUnit.toUtf8().constData(),sizeof(out_cfg->ValueOfTimeUnit) - 1);
|
||||||
strncpy(out_cfg->WaveTimeFlag, cfg.WaveTimeFlag.toUtf8().constData(), sizeof(out_cfg->WaveTimeFlag) - 1);
|
strncpy(out_cfg->WaveTimeFlag, cfg.WaveTimeFlag.toUtf8().constData(), sizeof(out_cfg->WaveTimeFlag) - 1);
|
||||||
|
strncpy(out_cfg->IEDControl, cfg.IEDControl.toUtf8().constData(), sizeof(out_cfg->IEDControl) - 1);//lnk2026-5-13
|
||||||
strncpy(out_cfg->IEDname, cfg.IEDname.toUtf8().constData(), sizeof(out_cfg->IEDname) - 1);
|
strncpy(out_cfg->IEDname, cfg.IEDname.toUtf8().constData(), sizeof(out_cfg->IEDname) - 1);
|
||||||
strncpy(out_cfg->LDevicePrefix, cfg.LDevicePrefix.toUtf8().constData(), sizeof(out_cfg->LDevicePrefix) - 1);
|
strncpy(out_cfg->LDevicePrefix, cfg.LDevicePrefix.toUtf8().constData(), sizeof(out_cfg->LDevicePrefix) - 1);
|
||||||
|
|
||||||
@@ -1036,6 +1038,10 @@ bool ParseXMLConfig2(int xml_flag, XmlConfig *cfg, list<CTopic*> *ctopiclist,QSt
|
|||||||
cfg->WaveTimeFlag.append(e.attribute("WaveTimeFlag"));
|
cfg->WaveTimeFlag.append(e.attribute("WaveTimeFlag"));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
if ("IEDControl" == strTag)
|
||||||
|
{
|
||||||
|
cfg->IEDControl.append(e.attribute("name"));
|
||||||
|
}
|
||||||
if ("IED" == strTag)
|
if ("IED" == strTag)
|
||||||
{
|
{
|
||||||
cfg->IEDname.append(e.attribute("name"));
|
cfg->IEDname.append(e.attribute("name"));
|
||||||
@@ -1255,6 +1261,7 @@ int transfer_json_block_data(char v_wiring_type[], json_block_data *data) //json
|
|||||||
printf("TypeOfData = '%s'\n", cfg1.TypeOfData);
|
printf("TypeOfData = '%s'\n", cfg1.TypeOfData);
|
||||||
printf("ValueOfTimeUnit = '%s'\n", cfg1.ValueOfTimeUnit);
|
printf("ValueOfTimeUnit = '%s'\n", cfg1.ValueOfTimeUnit);
|
||||||
printf("WaveTimeFlag = '%s'\n", cfg1.WaveTimeFlag);
|
printf("WaveTimeFlag = '%s'\n", cfg1.WaveTimeFlag);
|
||||||
|
printf("IEDControl = '%s'\n", cfg1.IEDControl);
|
||||||
printf("IEDname = '%s'\n", cfg1.IEDname);
|
printf("IEDname = '%s'\n", cfg1.IEDname);
|
||||||
printf("LDevicePrefix = '%s'\n", cfg1.LDevicePrefix);
|
printf("LDevicePrefix = '%s'\n", cfg1.LDevicePrefix);
|
||||||
printf("=====================================\n");
|
printf("=====================================\n");
|
||||||
|
|||||||
@@ -91,10 +91,18 @@ extern "C" {
|
|||||||
|
|
||||||
extern ST_RET mms_mvla_fdelete (MVL_NET_INFO *net_info,ST_CHAR *file_to_delete,int iTimeout);
|
extern ST_RET mms_mvla_fdelete (MVL_NET_INFO *net_info,ST_CHAR *file_to_delete,int iTimeout);
|
||||||
|
|
||||||
extern ST_RET write_ledrs_oper(MVL_NET_INFO* netInfo,//netInfo:客户端和 MMS 服务器之间的网络连接信息
|
extern ST_RET write_common_oper(chnl_usr_t *chnl_usr,
|
||||||
ST_CHAR* domName, //域名 iedname+0
|
ST_CHAR *domName,
|
||||||
ST_INT oper_type_id, //数据类型 这里是boolean
|
const char *ctlName,
|
||||||
ST_INT timeOut); //响应时长
|
ST_INT oper_type_id,
|
||||||
|
ST_INT timeOut);
|
||||||
|
extern ST_RET write_mod_stval(chnl_usr_t *chnl_usr,
|
||||||
|
ST_CHAR *domName,
|
||||||
|
ST_INT timeOut);
|
||||||
|
|
||||||
|
extern ST_RET mms_conclude_disconnect(MVL_NET_INFO *net_info, ST_INT timeOut);
|
||||||
|
|
||||||
|
extern int BuildResetDomName(ied_usr_t *ied_usr, char *domName, size_t domNameSize);
|
||||||
|
|
||||||
extern pt61850app_t *g_pt61850app;
|
extern pt61850app_t *g_pt61850app;
|
||||||
|
|
||||||
@@ -2225,7 +2233,7 @@ static int BuildTempLocalPath(char* outPath,
|
|||||||
|
|
||||||
const char* fileName = GetFileNameOnly(remotePath);
|
const char* fileName = GetFileNameOnly(remotePath);
|
||||||
if (fileName == NULL || fileName[0] == '\0')
|
if (fileName == NULL || fileName[0] == '\0')
|
||||||
fileName = "tmp_file.dat";
|
fileName = "tmp_file";
|
||||||
|
|
||||||
const char* ipStr = chnl_usr->ip_str;
|
const char* ipStr = chnl_usr->ip_str;
|
||||||
if (ipStr == NULL || ipStr[0] == '\0')
|
if (ipStr == NULL || ipStr[0] == '\0')
|
||||||
@@ -2235,7 +2243,7 @@ static int BuildTempLocalPath(char* outPath,
|
|||||||
SafePathName(ipStr, safeIp, sizeof(safeIp));
|
SafePathName(ipStr, safeIp, sizeof(safeIp));
|
||||||
|
|
||||||
char dirPath[512] = {0};
|
char dirPath[512] = {0};
|
||||||
snprintf(dirPath, sizeof(dirPath), "/tmp/%s", safeIp);
|
snprintf(dirPath, sizeof(dirPath), "/FeProject/dat/filetodevice/%s", safeIp);
|
||||||
|
|
||||||
/* 目录不存在则创建 */
|
/* 目录不存在则创建 */
|
||||||
if (MakeDirRecursive(dirPath) != 0)
|
if (MakeDirRecursive(dirPath) != 0)
|
||||||
@@ -2244,8 +2252,16 @@ static int BuildTempLocalPath(char* outPath,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
snprintf(outPath, outSize, "%s/%s", dirPath, fileName);
|
int n = snprintf(outPath, outSize, "%s/%s", dirPath, fileName);
|
||||||
return 0;
|
if (n < 0 || (size_t)n >= outSize)
|
||||||
|
{
|
||||||
|
printf("BuildTempLocalPath path too long, outSize=%zu, dir=%s, fileName=%s\n",
|
||||||
|
outSize, dirPath, fileName);
|
||||||
|
outPath[0] = '\0';
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int HandleTypeDownloadAndUpload(chnl_usr_t* chnl_usr,
|
static int HandleTypeDownloadAndUpload(chnl_usr_t* chnl_usr,
|
||||||
@@ -2347,7 +2363,7 @@ static int HandleTypeTransferToDevice(chnl_usr_t* chnl_usr,
|
|||||||
if (chnl_usr == NULL || req == NULL || chnl_usr->net_info == NULL)
|
if (chnl_usr == NULL || req == NULL || chnl_usr->net_info == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
char localpath[512] = {0};
|
char localpath[1024] = {0};
|
||||||
if (BuildTempLocalPath(localpath, sizeof(localpath), chnl_usr, req->remote_path) != 0)
|
if (BuildTempLocalPath(localpath, sizeof(localpath), chnl_usr, req->remote_path) != 0)
|
||||||
{
|
{
|
||||||
DIY_ERRORLOG_CODE(req->devid,1, LOG_CODE_FILE_CONTROL,
|
DIY_ERRORLOG_CODE(req->devid,1, LOG_CODE_FILE_CONTROL,
|
||||||
@@ -2451,6 +2467,163 @@ static int HandleDeleteFileInDevice(chnl_usr_t* chnl_usr,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
==============================================================================
|
||||||
|
TYPE ID DUMP
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
[TYPE] id=0 name=RTYP_BOOL size=1 num_rt=1
|
||||||
|
[TYPE] id=1 name=RTYP_BTIME6 size=8 num_rt=1
|
||||||
|
[TYPE] id=2 name=RTYP_BSTR6 size=1 num_rt=1
|
||||||
|
[TYPE] id=3 name=RTYP_BSTR8 size=1 num_rt=1
|
||||||
|
[TYPE] id=4 name=RTYP_BSTR9 size=2 num_rt=1
|
||||||
|
[TYPE] id=5 name=RTYP_BVSTR6 size=3 num_rt=1
|
||||||
|
[TYPE] id=6 name=RTYP_BVSTR8 size=3 num_rt=1
|
||||||
|
[TYPE] id=7 name=RTYP_BVSTR10 size=4 num_rt=1
|
||||||
|
[TYPE] id=8 name=RTYP_INT8U size=1 num_rt=1
|
||||||
|
[TYPE] id=9 name=RTYP_INT16U size=2 num_rt=1
|
||||||
|
[TYPE] id=10 name=RTYP_OSTR8 size=8 num_rt=1
|
||||||
|
[TYPE] id=11 name=RTYP_VSTR32 size=33 num_rt=1
|
||||||
|
[TYPE] id=12 name=RTYP_VSTR65 size=66 num_rt=1
|
||||||
|
[TYPE] id=13 name=RTYP_INT32U size=4 num_rt=1
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
自定义/业务类型
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
[TYPE] id=14 name=I16 size=2 num_rt=1
|
||||||
|
[TYPE] id=15 name=U32 size=4 num_rt=1
|
||||||
|
[TYPE] id=16 name=UTF8VSTRING13 size=28 num_rt=1
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
复杂结构体类型
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
[TYPE] id=17 name=phv_type size=312 num_rt=152
|
||||||
|
[TYPE] id=18 name=phsx_type size=52 num_rt=25
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
LEDRs Oper 动态创建结果
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
例如:
|
||||||
|
[CTRL_INIT] success dom=PQPQLD0 type_id=19*/
|
||||||
|
/////////////////////////////控制类消息处理
|
||||||
|
|
||||||
|
|
||||||
|
static int HandleTypeControlDevice(chnl_usr_t *chnl_usr,
|
||||||
|
ied_usr_t *ied_usr,
|
||||||
|
file_dir_req_t *req,
|
||||||
|
std::string &jsonString)
|
||||||
|
{
|
||||||
|
if (chnl_usr == NULL || chnl_usr->net_info == NULL ||
|
||||||
|
ied_usr == NULL || req == NULL)
|
||||||
|
{
|
||||||
|
jsonString = BuildSingleFileRespJson(req, NULL, "control", 1, -1);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
char domName[256] = {0};
|
||||||
|
BuildResetDomName(ied_usr, domName, sizeof(domName));
|
||||||
|
|
||||||
|
const char *controlName = NULL;
|
||||||
|
ST_INT operTypeId = -1;
|
||||||
|
ST_RET ret = SD_FAILURE;
|
||||||
|
|
||||||
|
if (strcmp(req->path, "return") == 0)
|
||||||
|
{
|
||||||
|
controlName = "CO$LEDRs$Oper";
|
||||||
|
operTypeId = ied_usr->oper_type_cache.ledrs_oper_type_id;
|
||||||
|
|
||||||
|
if (ied_usr->oper_type_cache.inited != SD_TRUE || operTypeId < 0)
|
||||||
|
{
|
||||||
|
jsonString = BuildSingleFileRespJson(req, NULL, "control", 1, -1);
|
||||||
|
DIY_ERRORLOG_CODE(req->devid, 1, LOG_CODE_FILE_CONTROL,
|
||||||
|
"【ERROR】控制操作失败,LEDRs Oper type_id 未初始化 terminal_id=%s type_id=%d",
|
||||||
|
req->devid, operTypeId);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("[CONTROL] before write_common_oper control=%s type_id=%d\n",
|
||||||
|
controlName, operTypeId);
|
||||||
|
|
||||||
|
ret = write_common_oper(chnl_usr,
|
||||||
|
domName,
|
||||||
|
controlName,
|
||||||
|
operTypeId,
|
||||||
|
g_pt61850app->mmsOpTimeout);
|
||||||
|
|
||||||
|
printf("[CONTROL] after write_common_oper control=%s ret=0x%X\n",
|
||||||
|
controlName, ret);
|
||||||
|
}
|
||||||
|
else if (strcmp(req->path, "reboot") == 0)
|
||||||
|
{
|
||||||
|
controlName = "CO$Reboot$Oper";
|
||||||
|
operTypeId = ied_usr->oper_type_cache.reboot_oper_type_id;
|
||||||
|
|
||||||
|
if (ied_usr->oper_type_cache.inited != SD_TRUE || operTypeId < 0)
|
||||||
|
{
|
||||||
|
jsonString = BuildSingleFileRespJson(req, NULL, "control", 1, -1);
|
||||||
|
DIY_ERRORLOG_CODE(req->devid, 1, LOG_CODE_FILE_CONTROL,
|
||||||
|
"【ERROR】控制操作失败,Reboot Oper type_id 未初始化 terminal_id=%s type_id=%d",
|
||||||
|
req->devid, operTypeId);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("[CONTROL] before write_common_oper control=%s type_id=%d\n",
|
||||||
|
controlName, operTypeId);
|
||||||
|
|
||||||
|
ret = write_common_oper(chnl_usr,
|
||||||
|
domName,
|
||||||
|
controlName,
|
||||||
|
operTypeId,
|
||||||
|
g_pt61850app->mmsOpTimeout);
|
||||||
|
|
||||||
|
printf("[CONTROL] after write_common_oper control=%s ret=0x%X\n",
|
||||||
|
controlName, ret);
|
||||||
|
}
|
||||||
|
else if (strcmp(req->path, "reset") == 0)
|
||||||
|
{
|
||||||
|
controlName = "ST$Mod$stVal";
|
||||||
|
|
||||||
|
printf("[CONTROL] before write_mod_stval control=%s\n", controlName);
|
||||||
|
|
||||||
|
ret = write_mod_stval(chnl_usr,
|
||||||
|
domName,
|
||||||
|
g_pt61850app->mmsOpTimeout);
|
||||||
|
|
||||||
|
printf("[CONTROL] after write_mod_stval ret=0x%X\n", ret);
|
||||||
|
|
||||||
|
if (ret == SD_SUCCESS)
|
||||||
|
{
|
||||||
|
ST_RET discRet = mms_conclude_disconnect(chnl_usr->net_info,
|
||||||
|
g_pt61850app->mmsOpTimeout);
|
||||||
|
|
||||||
|
printf("[CONTROL] disconnect after reset ret=0x%X\n", discRet);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("[CONTROL] unknown path=%s\n", req->path);
|
||||||
|
jsonString = BuildSingleFileRespJson(req, NULL, "control", 1, -1);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret == SD_SUCCESS)
|
||||||
|
{
|
||||||
|
jsonString = BuildSingleFileRespJson(req, NULL, "control", 1, 0);
|
||||||
|
DIY_WARNLOG_CODE(req->devid, 1, LOG_CODE_FILE_CONTROL,
|
||||||
|
"【WARN】控制操作成功 terminal_id=%s path=%s", req->devid, req->path);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
jsonString = BuildSingleFileRespJson(req, NULL, "control", 1, -1);
|
||||||
|
DIY_ERRORLOG_CODE(req->devid, 1, LOG_CODE_FILE_CONTROL,
|
||||||
|
"【ERROR】控制操作失败 terminal_id=%s path=%s ret=0x%X",
|
||||||
|
req->devid, req->path, ret);
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
void HandleFileDirReqForChannel(chnl_usr_t *chnl_usr)
|
void HandleFileDirReqForChannel(chnl_usr_t *chnl_usr)
|
||||||
{
|
{
|
||||||
if (chnl_usr == NULL) {
|
if (chnl_usr == NULL) {
|
||||||
@@ -2480,12 +2653,12 @@ void HandleFileDirReqForChannel(chnl_usr_t *chnl_usr)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << "[FILEDIR] checking req for terminal_id="
|
if(DEBUGOPEN)std::cout << "[FILEDIR] checking req for terminal_id="
|
||||||
<< ied_usr->terminal_id << std::endl;
|
<< ied_usr->terminal_id << std::endl;
|
||||||
|
|
||||||
file_dir_req_t *req = PopMatchedFileDirReq(ied_usr->terminal_id);
|
file_dir_req_t *req = PopMatchedFileDirReq(ied_usr->terminal_id);
|
||||||
if (req == NULL) {
|
if (req == NULL) {
|
||||||
std::cout << "[FILEDIR] no matched request, terminal_id="
|
if(DEBUGOPEN)std::cout << "[FILEDIR] no matched request, terminal_id="
|
||||||
<< ied_usr->terminal_id << std::endl;
|
<< ied_usr->terminal_id << std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -2541,54 +2714,10 @@ void HandleFileDirReqForChannel(chnl_usr_t *chnl_usr)
|
|||||||
handleRet = HandleDeleteFileInDevice(chnl_usr, req, jsonString);
|
handleRet = HandleDeleteFileInDevice(chnl_usr, req, jsonString);
|
||||||
}
|
}
|
||||||
else if (req->type == 4){ //复位
|
else if (req->type == 4){ //复位
|
||||||
char domName[256] = {0}; //构造ied+0的domName
|
handleRet = HandleTypeControlDevice(chnl_usr,
|
||||||
|
ied_usr,
|
||||||
// 取第一个 LD
|
req,
|
||||||
if (ied_usr->LD_info &&
|
jsonString);
|
||||||
ied_usr->LD_info[0].LD_name)
|
|
||||||
{
|
|
||||||
snprintf(domName,
|
|
||||||
sizeof(domName),
|
|
||||||
"%s",
|
|
||||||
ied_usr->LD_info[0].LD_name);
|
|
||||||
|
|
||||||
// 把末尾数字改成0
|
|
||||||
int len = strlen(domName);
|
|
||||||
|
|
||||||
if (len > 0 && isdigit(domName[len - 1]))
|
|
||||||
{
|
|
||||||
domName[len - 1] = '0';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else //没取到则使用默认的domName "PQMonitorPQM0"
|
|
||||||
{
|
|
||||||
strcpy(domName, "PQMonitorPQM0");
|
|
||||||
std::cout << "use default domName=PQMonitorPQM0"
|
|
||||||
<< std::endl;
|
|
||||||
DIY_ERRORLOG_CODE(req->devid,1, LOG_CODE_FILE_CONTROL,
|
|
||||||
"【ERROR】未取到 LD 信息,使用默认 domName=%s terminal_id=%s",
|
|
||||||
domName, req->devid);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::cout << "[CTRL] domName="
|
|
||||||
<< domName
|
|
||||||
<< std::endl;
|
|
||||||
|
|
||||||
handleRet = write_ledrs_oper(chnl_usr->net_info,
|
|
||||||
domName,
|
|
||||||
g_rpt_typeids.mmsbool, //数据类型,使用全局配置的mmsbool类型
|
|
||||||
g_pt61850app->mmsOpTimeout);
|
|
||||||
|
|
||||||
if(handleRet == 0){
|
|
||||||
jsonString = BuildSingleFileRespJson(req, NULL, "file", 1, 0);
|
|
||||||
DIY_WARNLOG_CODE(req->devid,1, LOG_CODE_FILE_CONTROL,
|
|
||||||
"【WARN】复位操作成功 terminal_id=%s", req->devid);
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
jsonString = BuildSingleFileRespJson(req, NULL, "file", 1, -1);
|
|
||||||
DIY_ERRORLOG_CODE(req->devid,1, LOG_CODE_FILE_CONTROL,
|
|
||||||
"【ERROR】复位操作失败 terminal_id=%s ret=0x%X", req->devid, handleRet);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -113,12 +113,12 @@ extern LOG_TLS int g_log_code_tls; // 声明为 TLS 变量,定义见 log4.cpp
|
|||||||
int __old_code__ = g_log_code_tls; \
|
int __old_code__ = g_log_code_tls; \
|
||||||
g_log_code_tls = (int)(CODE_INT); \
|
g_log_code_tls = (int)(CODE_INT); \
|
||||||
\
|
\
|
||||||
char __msg_buf__[256]; \
|
char __msg_buf__[512]; \
|
||||||
format_log_msg(__msg_buf__, sizeof(__msg_buf__), __VA_ARGS__); \
|
format_log_msg(__msg_buf__, sizeof(__msg_buf__), __VA_ARGS__); \
|
||||||
\
|
\
|
||||||
const char* __key_raw__ = (KEY); \
|
const char* __key_raw__ = (KEY); \
|
||||||
\
|
\
|
||||||
char __key_buf__[256]; \
|
char __key_buf__[512]; \
|
||||||
switch ((int)(KEY_TYPE)) { \
|
switch ((int)(KEY_TYPE)) { \
|
||||||
case 0: \
|
case 0: \
|
||||||
snprintf(__key_buf__, sizeof(__key_buf__), "process"); \
|
snprintf(__key_buf__, sizeof(__key_buf__), "process"); \
|
||||||
|
|||||||
@@ -165,6 +165,7 @@ typedef struct {
|
|||||||
char TypeOfData[64];
|
char TypeOfData[64];
|
||||||
char ValueOfTimeUnit[64];
|
char ValueOfTimeUnit[64];
|
||||||
char WaveTimeFlag[64];
|
char WaveTimeFlag[64];
|
||||||
|
char IEDControl[64];
|
||||||
char IEDname[64];
|
char IEDname[64];
|
||||||
char LDevicePrefix[64];
|
char LDevicePrefix[64];
|
||||||
} XmlConfigC;
|
} XmlConfigC;
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ extern apr_pool_t* g_cfg_pool;
|
|||||||
extern apr_pool_t* g_init_pool;
|
extern apr_pool_t* g_init_pool;
|
||||||
|
|
||||||
extern int g_DevFlag; //日志配置中读取的参数,暂无特定使用lnk20250121
|
extern int g_DevFlag; //日志配置中读取的参数,暂无特定使用lnk20250121
|
||||||
|
extern bool DEBUGOPEN;//调试开关,控制是否输出调试日志,默认关闭
|
||||||
extern int IED_COUNT;
|
extern int IED_COUNT;
|
||||||
extern int RECALL_ONLY_FLAG; //lnk20260309添加一个全局变量,标志是否只运行补招程序
|
extern int RECALL_ONLY_FLAG; //lnk20260309添加一个全局变量,标志是否只运行补招程序
|
||||||
|
|
||||||
@@ -1531,7 +1531,8 @@ void CheckAllConnectedChannel()
|
|||||||
if(chnl_usr->m_state == CHANNEL_CONNECTED)
|
if(chnl_usr->m_state == CHANNEL_CONNECTED)
|
||||||
{
|
{
|
||||||
if(g_node_id == THREE_SECS_DATA_BASE_NODE_ID) {
|
if(g_node_id == THREE_SECS_DATA_BASE_NODE_ID) {
|
||||||
printf("[FILEDIR] enter HandleFileDirReqForChannel");
|
InitLedrsOperTypeForChannel(chnl_usr);//写特殊控制的初始化
|
||||||
|
if(DEBUGOPEN)printf("[FILEDIR] enter HandleFileDirReqForChannel");
|
||||||
HandleFileDirReqForChannel(chnl_usr);//文件目录请求
|
HandleFileDirReqForChannel(chnl_usr);//文件目录请求
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
506
mms/mmsclient.c
506
mms/mmsclient.c
@@ -80,6 +80,9 @@
|
|||||||
|
|
||||||
#include <ctype.h> //lnk20241119
|
#include <ctype.h> //lnk20241119
|
||||||
#include "../cfg_parse/custom_printf.h"//lnk20250225
|
#include "../cfg_parse/custom_printf.h"//lnk20250225
|
||||||
|
|
||||||
|
#include "../log4cplus/log4.h"
|
||||||
|
|
||||||
extern uint32_t g_node_id;
|
extern uint32_t g_node_id;
|
||||||
extern char subdir[128];
|
extern char subdir[128];
|
||||||
unsigned int g_no_auth = 0;
|
unsigned int g_no_auth = 0;
|
||||||
@@ -132,6 +135,8 @@ IDENT_RESP_INFO identify_response_info =
|
|||||||
|
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
|
|
||||||
|
extern pt61850app_t *g_pt61850app;
|
||||||
|
|
||||||
extern TP0_CONN *tp0_conn_arr; /* ptr to array of "max_num_conns" structs */
|
extern TP0_CONN *tp0_conn_arr; /* ptr to array of "max_num_conns" structs */
|
||||||
|
|
||||||
static ST_VOID disc_ind_fun (MVL_NET_INFO *cc, ST_INT discType);
|
static ST_VOID disc_ind_fun (MVL_NET_INFO *cc, ST_INT discType);
|
||||||
@@ -269,12 +274,25 @@ MY_CONTROL_INFO my_control_info;
|
|||||||
ST_INT mms_var_type_id_create (MVL_NET_INFO *clientNetInfo, ST_INT scope,
|
ST_INT mms_var_type_id_create (MVL_NET_INFO *clientNetInfo, ST_INT scope,
|
||||||
ST_CHAR *dom_name, ST_CHAR *var_name, int iTimeOut)
|
ST_CHAR *dom_name, ST_CHAR *var_name, int iTimeOut)
|
||||||
{
|
{
|
||||||
MVL_REQ_PEND *reqCtrl;
|
//MVL_REQ_PEND *reqCtrl;
|
||||||
|
//reqCtrl 必须初始化为 NULL,防止 mvla_getvar 失败后释放野指针
|
||||||
|
MVL_REQ_PEND *reqCtrl = NULL;
|
||||||
|
|
||||||
GETVAR_REQ_INFO getvar_req;
|
GETVAR_REQ_INFO getvar_req;
|
||||||
ST_INT type_id = -1; /* start with invalid type id */
|
ST_INT type_id = -1; /* start with invalid type id */
|
||||||
ST_RET ret;
|
ST_RET ret;
|
||||||
|
|
||||||
|
//参数合法性检查
|
||||||
|
if (clientNetInfo == NULL || dom_name == NULL || var_name == NULL)
|
||||||
|
{
|
||||||
|
printf("[GETVAR] invalid arg netInfo=%p dom=%p var=%p\n",
|
||||||
|
clientNetInfo, dom_name, var_name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//结构体清零,避免未初始化字段导致异常
|
||||||
|
memset(&getvar_req, 0, sizeof(getvar_req));
|
||||||
|
|
||||||
/* Get the type of this "Oper" attribute & create type. */
|
/* Get the type of this "Oper" attribute & create type. */
|
||||||
/* Would be more efficient to do this just once before this function.*/
|
/* Would be more efficient to do this just once before this function.*/
|
||||||
getvar_req.req_tag = GETVAR_NAME;
|
getvar_req.req_tag = GETVAR_NAME;
|
||||||
@@ -284,18 +302,52 @@ ST_RET ret;
|
|||||||
getvar_req.name.domain_id= dom_name;
|
getvar_req.name.domain_id= dom_name;
|
||||||
getvar_req.name.obj_name.vmd_spec = var_name;
|
getvar_req.name.obj_name.vmd_spec = var_name;
|
||||||
|
|
||||||
|
//增加调试打印,确认崩溃点
|
||||||
|
printf("[GETVAR] start dom=%s var=%s\n", dom_name, var_name);
|
||||||
|
|
||||||
ret = mvla_getvar (clientNetInfo, &getvar_req, &reqCtrl);
|
ret = mvla_getvar (clientNetInfo, &getvar_req, &reqCtrl);
|
||||||
if (ret == SD_SUCCESS)
|
|
||||||
|
//打印 mvla_getvar 返回值和 reqCtrl
|
||||||
|
printf("[GETVAR] mvla_getvar ret=0x%X reqCtrl=%p\n", ret, reqCtrl);
|
||||||
|
|
||||||
|
if (ret == SD_SUCCESS){
|
||||||
ret = waitReqDone (reqCtrl, iTimeOut);
|
ret = waitReqDone (reqCtrl, iTimeOut);
|
||||||
if (ret != SD_SUCCESS)
|
//打印 waitReqDone 返回值
|
||||||
|
printf("[GETVAR] wait ret=0x%X\n", ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret != SD_SUCCESS){
|
||||||
echo_warn2 ("Error getting type of variable '%s' in domain '%s'\n", var_name, dom_name);
|
echo_warn2 ("Error getting type of variable '%s' in domain '%s'\n", var_name, dom_name);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Don't care about name so pass NULL. */
|
/* Don't care about name so pass NULL. */
|
||||||
type_id = mvl_type_id_create (NULL, reqCtrl->u.getvar.resp_info->type_spec.data,
|
//type_id = mvl_type_id_create (NULL, reqCtrl->u.getvar.resp_info->type_spec.data,
|
||||||
reqCtrl->u.getvar.resp_info->type_spec.len);
|
// reqCtrl->u.getvar.resp_info->type_spec.len);
|
||||||
|
//严格检查 resp_info/type_spec,避免空指针崩溃
|
||||||
|
if (ret == SD_SUCCESS &&
|
||||||
|
reqCtrl != NULL &&
|
||||||
|
reqCtrl->u.getvar.resp_info != NULL &&
|
||||||
|
reqCtrl->u.getvar.resp_info->type_spec.data != NULL &&
|
||||||
|
reqCtrl->u.getvar.resp_info->type_spec.len > 0)
|
||||||
|
{
|
||||||
|
type_id = mvl_type_id_create(
|
||||||
|
NULL,
|
||||||
|
reqCtrl->u.getvar.resp_info->type_spec.data,
|
||||||
|
reqCtrl->u.getvar.resp_info->type_spec.len);
|
||||||
|
|
||||||
|
printf("[GETVAR] create type_id=%d len=%d\n",
|
||||||
|
type_id,
|
||||||
|
reqCtrl->u.getvar.resp_info->type_spec.len);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("[GETVAR] failed dom=%s var=%s ret=0x%X\n",
|
||||||
|
dom_name, var_name, ret);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
mvl_free_req_ctrl (reqCtrl); /* Done with request struct */
|
//只有 reqCtrl 非空才释放
|
||||||
|
if (reqCtrl != NULL)mvl_free_req_ctrl (reqCtrl); /* Done with request struct */
|
||||||
return (type_id);
|
return (type_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1683,20 +1735,20 @@ static ST_VOID *my_realloc_err (ST_VOID *old, ST_UINT size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////
|
||||||
//#define MAX_FILE_HANDLE_NUM (256)
|
#define MAX_FILE_HANDLE_NUM (256)
|
||||||
//static FILE *fp_arr[MAX_FILE_HANDLE_NUM];
|
static FILE *fp_arr[MAX_FILE_HANDLE_NUM];
|
||||||
//static ST_INT32 cur_handle = 0;
|
static ST_INT32 cur_handle = 0;
|
||||||
//ST_INT32 set_file_pointer( FILE *fp)
|
ST_INT32 set_file_pointer( FILE *fp)
|
||||||
//{
|
{
|
||||||
// ST_INT32 the_handle = cur_handle;
|
ST_INT32 the_handle = cur_handle;
|
||||||
// fp_arr[cur_handle++] = fp;
|
fp_arr[cur_handle++] = fp;
|
||||||
// cur_handle %= MAX_FILE_HANDLE_NUM;
|
cur_handle %= MAX_FILE_HANDLE_NUM;
|
||||||
// return the_handle;
|
return the_handle;
|
||||||
//}
|
}
|
||||||
//FILE* get_file_pointer(ST_INT32 handle)
|
FILE* get_file_pointer(ST_INT32 handle)
|
||||||
//{
|
{
|
||||||
// return fp_arr[handle];
|
return fp_arr[handle];
|
||||||
//}
|
}
|
||||||
///////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#if (MMS_FOPEN_EN & RESP_EN)
|
#if (MMS_FOPEN_EN & RESP_EN)
|
||||||
@@ -1705,39 +1757,39 @@ static ST_VOID *my_realloc_err (ST_VOID *old, ST_UINT size)
|
|||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
ST_VOID u_mvl_fopen_ind (MVL_IND_PEND *indCtrl)
|
ST_VOID u_mvl_fopen_ind (MVL_IND_PEND *indCtrl)
|
||||||
{
|
{
|
||||||
//FILE *fp;
|
FILE *fp;
|
||||||
//FOPEN_RESP_INFO resp_info;
|
FOPEN_RESP_INFO resp_info;
|
||||||
//struct stat stat_buf;
|
struct stat stat_buf;
|
||||||
|
|
||||||
//fp = fopen (indCtrl->u.fopen.filename, "rb"); /* CRITICAL: use "b" flag for binary transfer*/
|
fp = fopen (indCtrl->u.fopen.filename, "rb"); /* CRITICAL: use "b" flag for binary transfer*/
|
||||||
//if (fp == NULL)
|
if (fp == NULL)
|
||||||
// {
|
{
|
||||||
// _mplas_err_resp (indCtrl,11,6); /* File-access denied */
|
_mplas_err_resp (indCtrl,11,6); /* File-access denied */
|
||||||
// return;
|
return;
|
||||||
// }
|
}
|
||||||
//if (fseek (fp, indCtrl->u.fopen.init_pos, SEEK_SET))
|
if (fseek (fp, indCtrl->u.fopen.init_pos, SEEK_SET))
|
||||||
// {
|
{
|
||||||
// _mplas_err_resp (indCtrl,11,5); /* Position invalid */
|
_mplas_err_resp (indCtrl,11,5); /* Position invalid */
|
||||||
// return;
|
return;
|
||||||
// }
|
}
|
||||||
|
|
||||||
///* WARNING: this only works if (FILE *) is a 32-bit pointer. */
|
/* WARNING: this only works if (FILE *) is a 32-bit pointer. */
|
||||||
//resp_info.frsmid = set_file_pointer(fp); //(ST_INT32) fp;
|
resp_info.frsmid = set_file_pointer(fp); //(ST_INT32) fp;
|
||||||
|
|
||||||
//if (fstat (fileno (fp), &stat_buf))
|
if (fstat (fileno (fp), &stat_buf))
|
||||||
// { /* Can't get file size or time */
|
{ /* Can't get file size or time */
|
||||||
// _mplas_err_resp (indCtrl,11,0); /* File Problem, Other */
|
_mplas_err_resp (indCtrl,11,0); /* File Problem, Other */
|
||||||
// return;
|
return;
|
||||||
// }
|
}
|
||||||
//else
|
else
|
||||||
// {
|
{
|
||||||
// resp_info.ent.fsize = stat_buf.st_size;
|
resp_info.ent.fsize = stat_buf.st_size;
|
||||||
// resp_info.ent.mtimpres = SD_TRUE;
|
resp_info.ent.mtimpres = SD_TRUE;
|
||||||
// resp_info.ent.mtime = stat_buf.st_mtime;
|
resp_info.ent.mtime = stat_buf.st_mtime;
|
||||||
// }
|
}
|
||||||
|
|
||||||
//indCtrl->u.fopen.resp_info = &resp_info;
|
indCtrl->u.fopen.resp_info = &resp_info;
|
||||||
//mplas_fopen_resp (indCtrl);
|
mplas_fopen_resp (indCtrl);
|
||||||
}
|
}
|
||||||
#endif /* MMS_FOPEN_EN & RESP_EN */
|
#endif /* MMS_FOPEN_EN & RESP_EN */
|
||||||
|
|
||||||
@@ -1748,31 +1800,31 @@ ST_VOID u_mvl_fopen_ind (MVL_IND_PEND *indCtrl)
|
|||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
ST_VOID u_mvl_fread_ind (MVL_IND_PEND *indCtrl)
|
ST_VOID u_mvl_fread_ind (MVL_IND_PEND *indCtrl)
|
||||||
{
|
{
|
||||||
//FILE *fp;
|
FILE *fp;
|
||||||
//ST_UCHAR *tmp_buf;
|
ST_UCHAR *tmp_buf;
|
||||||
//MVLAS_FREAD_CTRL *fread_ctrl = &indCtrl->u.fread;
|
MVLAS_FREAD_CTRL *fread_ctrl = &indCtrl->u.fread;
|
||||||
//FREAD_RESP_INFO resp_info;
|
FREAD_RESP_INFO resp_info;
|
||||||
|
|
||||||
//fp = get_file_pointer(fread_ctrl->req_info->frsmid);// (FILE *) fread_ctrl->req_info->frsmid;
|
fp = get_file_pointer(fread_ctrl->req_info->frsmid);// (FILE *) fread_ctrl->req_info->frsmid;
|
||||||
///* Do NOT read more than "max_size". */
|
/* Do NOT read more than "max_size". */
|
||||||
//tmp_buf = (ST_UCHAR *) chk_malloc (fread_ctrl->max_size);
|
tmp_buf = (ST_UCHAR *) chk_malloc (fread_ctrl->max_size);
|
||||||
|
|
||||||
//resp_info.fd_len = fread (tmp_buf, 1, fread_ctrl->max_size, fp);
|
resp_info.fd_len = fread (tmp_buf, 1, fread_ctrl->max_size, fp);
|
||||||
//if (resp_info.fd_len == 0 && ferror (fp))
|
if (resp_info.fd_len == 0 && ferror (fp))
|
||||||
// {
|
{
|
||||||
// _mplas_err_resp (indCtrl, 3, 0);
|
_mplas_err_resp (indCtrl, 3, 0);
|
||||||
// return;
|
return;
|
||||||
// }
|
}
|
||||||
|
|
||||||
//resp_info.filedata = tmp_buf;
|
resp_info.filedata = tmp_buf;
|
||||||
//if (resp_info.fd_len == fread_ctrl->max_size)
|
if (resp_info.fd_len == fread_ctrl->max_size)
|
||||||
// resp_info.more_follows = SD_TRUE;
|
resp_info.more_follows = SD_TRUE;
|
||||||
//else
|
else
|
||||||
// resp_info.more_follows = SD_FALSE;
|
resp_info.more_follows = SD_FALSE;
|
||||||
|
|
||||||
//fread_ctrl->resp_info = &resp_info;
|
fread_ctrl->resp_info = &resp_info;
|
||||||
//mplas_fread_resp (indCtrl);
|
mplas_fread_resp (indCtrl);
|
||||||
//chk_free (tmp_buf); /* Temporary buffer */
|
chk_free (tmp_buf); /* Temporary buffer */
|
||||||
}
|
}
|
||||||
#endif /* #if (MMS_FREAD_EN & RESP_EN) */
|
#endif /* #if (MMS_FREAD_EN & RESP_EN) */
|
||||||
|
|
||||||
@@ -1782,15 +1834,15 @@ ST_VOID u_mvl_fread_ind (MVL_IND_PEND *indCtrl)
|
|||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
ST_VOID u_mvl_fclose_ind (MVL_IND_PEND *indCtrl)
|
ST_VOID u_mvl_fclose_ind (MVL_IND_PEND *indCtrl)
|
||||||
{
|
{
|
||||||
//FILE *fp;
|
FILE *fp;
|
||||||
//MVLAS_FCLOSE_CTRL *fclose_ctrl = &indCtrl->u.fclose;
|
MVLAS_FCLOSE_CTRL *fclose_ctrl = &indCtrl->u.fclose;
|
||||||
|
|
||||||
//fp = get_file_pointer(fclose_ctrl->req_info->frsmid);//(FILE *) fclose_ctrl->req_info->frsmid;
|
fp = get_file_pointer(fclose_ctrl->req_info->frsmid);//(FILE *) fclose_ctrl->req_info->frsmid;
|
||||||
|
|
||||||
//if (fclose (fp))
|
if (fclose (fp))
|
||||||
// _mplas_err_resp (indCtrl, 11, 0); /* File problem, other */
|
_mplas_err_resp (indCtrl, 11, 0); /* File problem, other */
|
||||||
//else
|
else
|
||||||
// mplas_fclose_resp (indCtrl);
|
mplas_fclose_resp (indCtrl);
|
||||||
}
|
}
|
||||||
#endif /* #if (MMS_FCLOSE_EN & RESP_EN) */
|
#endif /* #if (MMS_FCLOSE_EN & RESP_EN) */
|
||||||
|
|
||||||
@@ -1946,44 +1998,294 @@ MVL_REQ_PEND *reqCtrl;
|
|||||||
}
|
}
|
||||||
|
|
||||||
//lnk20260508添加重启装置函数
|
//lnk20260508添加重启装置函数
|
||||||
ST_RET write_ledrs_oper(MVL_NET_INFO* netInfo,//netInfo:客户端和 MMS 服务器之间的网络连接信息
|
int BuildResetDomName(ied_usr_t *ied_usr, char *domName, size_t domNameSize)
|
||||||
ST_CHAR* domName, //域名 iedname+0
|
|
||||||
ST_INT oper_type_id, //数据类型 这里是boolean
|
|
||||||
ST_INT timeOut) //响应时长
|
|
||||||
{
|
{
|
||||||
|
if (ied_usr == NULL || domName == NULL || domNameSize == 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
domName[0] = '\0';
|
||||||
|
|
||||||
|
XmlConfigC cfg1;
|
||||||
|
memset(&cfg1, 0, sizeof(cfg1));
|
||||||
|
|
||||||
|
if (get_xml_config_by_dev_type(ied_usr->dev_type, &cfg1))
|
||||||
|
{
|
||||||
|
printf("========== XmlConfigC dump ==========\n");
|
||||||
|
printf("IEDControl = '%s'\n", cfg1.IEDControl);
|
||||||
|
printf("IEDname = '%s'\n", cfg1.IEDname);
|
||||||
|
printf("LDevicePrefix = '%s'\n", cfg1.LDevicePrefix);
|
||||||
|
printf("=====================================\n");
|
||||||
|
|
||||||
|
if (cfg1.IEDControl[0] != '\0')
|
||||||
|
{
|
||||||
|
snprintf(domName, domNameSize, "%s", cfg1.IEDControl);
|
||||||
|
printf("[RESET] use cfg1.IEDControl=%s\n", domName);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ied_usr->LD_info && ied_usr->LD_info[0].LD_name)
|
||||||
|
{
|
||||||
|
snprintf(domName, domNameSize, "%s", ied_usr->LD_info[0].LD_name);
|
||||||
|
|
||||||
|
int len = strlen(domName);
|
||||||
|
if (len > 0 && isdigit(domName[len - 1]))
|
||||||
|
domName[len - 1] = '0';
|
||||||
|
|
||||||
|
printf("[RESET] use LD_name domName=%s\n", domName);
|
||||||
|
|
||||||
|
DIY_WARNLOG_CODE(ied_usr->terminal_id, 1, LOG_CODE_FILE_CONTROL,
|
||||||
|
"【WARN】未取到 IEDControl 信息,使用 LD_name=%s terminal_id=%s",
|
||||||
|
domName, ied_usr->terminal_id);
|
||||||
|
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(domName, domNameSize, "%s", "PQMonitorPQM0");
|
||||||
|
printf("[RESET] use default domName=%s\n", domName);
|
||||||
|
DIY_ERRORLOG_CODE(ied_usr->terminal_id, 1, LOG_CODE_FILE_CONTROL,
|
||||||
|
"【ERROR】未取到 LD 信息,使用默认 domName=%s terminal_id=%s",
|
||||||
|
domName, ied_usr->terminal_id);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ST_INT ledrs_var_type_create(MVL_NET_INFO* net_info,
|
||||||
|
OBJECT_NAME* varObj,
|
||||||
|
ST_INT timeOut)
|
||||||
|
{
|
||||||
|
MVL_REQ_PEND* reqCtrl;
|
||||||
|
GETVAR_REQ_INFO getvar_req;
|
||||||
|
VAR_ACC_TSPEC* type_spec;
|
||||||
|
ST_INT type_id = -1;
|
||||||
ST_RET ret;
|
ST_RET ret;
|
||||||
|
|
||||||
|
memset(&getvar_req, 0, sizeof(getvar_req));
|
||||||
|
|
||||||
|
getvar_req.req_tag = GETVAR_NAME;
|
||||||
|
getvar_req.name = *varObj;
|
||||||
|
|
||||||
|
ret = mvla_getvar(net_info, &getvar_req, &reqCtrl);
|
||||||
|
|
||||||
|
if (ret == SD_SUCCESS)
|
||||||
|
ret = waitReqDone(reqCtrl, timeOut);
|
||||||
|
|
||||||
|
if (ret == SD_SUCCESS)
|
||||||
|
{
|
||||||
|
type_spec = &reqCtrl->u.getvar.resp_info->type_spec;
|
||||||
|
|
||||||
|
type_id = mvl_type_id_create(NULL,
|
||||||
|
type_spec->data,
|
||||||
|
type_spec->len);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reqCtrl)
|
||||||
|
mvl_free_req_ctrl(reqCtrl);
|
||||||
|
|
||||||
|
return type_id;
|
||||||
|
}
|
||||||
|
static ST_INT create_oper_type_id(MVL_NET_INFO *net_info,
|
||||||
|
ST_CHAR *domName,
|
||||||
|
const char *ctlName,
|
||||||
|
ST_INT timeOut)
|
||||||
|
{
|
||||||
|
OBJECT_NAME obj;
|
||||||
ST_CHAR varName[MAX_IDENT_LEN + 1];
|
ST_CHAR varName[MAX_IDENT_LEN + 1];
|
||||||
|
|
||||||
LEDRs_Oper_t oper;
|
if (net_info == NULL || domName == NULL || ctlName == NULL)
|
||||||
memset(&oper, 0, sizeof(oper));
|
return -1;
|
||||||
|
|
||||||
oper.ctlVal = SD_TRUE; //618050抓包显示为true
|
memset(&obj, 0, sizeof(obj));
|
||||||
|
|
||||||
oper.origin.orCat = 3; //61850抓包显示为3
|
|
||||||
oper.origin.orIdent[0] = '\0'; //618050抓包显示为missing
|
|
||||||
|
|
||||||
oper.ctlNum = 1; //618050抓包显示为1
|
|
||||||
|
|
||||||
u_get_current_utc_time(&oper.T);//618050抓包显示为当前时间
|
|
||||||
|
|
||||||
oper.Test = SD_FALSE; //618050抓包显示为false
|
|
||||||
oper.Check[0] = 0x00; //618050抓包显示为bitstring 00
|
|
||||||
|
|
||||||
apr_snprintf(varName,
|
apr_snprintf(varName,
|
||||||
sizeof(varName),
|
sizeof(varName),
|
||||||
"LLN0$CO$LEDRs$Oper"); //61850抓包显示为LLN0$CO$LEDRs$Oper
|
"LLN0$%s",
|
||||||
|
ctlName);
|
||||||
|
|
||||||
ret = mms_named_var_write(netInfo,
|
obj.object_tag = DOM_SPEC;
|
||||||
varName, //itemid
|
obj.domain_id = domName;
|
||||||
DOM_SPEC, //统一使用DOM_SPEC作为域名标识符
|
obj.obj_name.vmd_spec = varName;
|
||||||
domName,
|
|
||||||
oper_type_id,
|
printf("[CTRL_INIT] create type dom=%s var=%s\n",
|
||||||
(ST_CHAR*)&oper, //数据源 这里是封装好的LEDRs_Oper_t结构体
|
domName, varName);
|
||||||
timeOut);
|
|
||||||
|
return ledrs_var_type_create(net_info, &obj, timeOut);
|
||||||
|
}
|
||||||
|
void InitLedrsOperTypeForChannel(chnl_usr_t *chnl_usr)
|
||||||
|
{
|
||||||
|
printf("[CTRL_INIT] enter\n");
|
||||||
|
|
||||||
|
if (chnl_usr == NULL || chnl_usr->chnl == NULL ||
|
||||||
|
chnl_usr->chnl->ied == NULL || chnl_usr->net_info == NULL)
|
||||||
|
{
|
||||||
|
printf("[CTRL_INIT] invalid chnl_usr\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ied_t *ied = chnl_usr->chnl->ied;
|
||||||
|
ied_usr_t *ied_usr = GET_IEDEXT_ADDR(ied);
|
||||||
|
|
||||||
|
if (ied_usr == NULL || ied_usr->LD_info == NULL)
|
||||||
|
{
|
||||||
|
printf("[CTRL_INIT] invalid ied_usr or LD_info\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("[CTRL_INIT] current inited=%d ledrs=%d reboot=%d reset=%d\n",
|
||||||
|
(int)ied_usr->oper_type_cache.inited,
|
||||||
|
ied_usr->oper_type_cache.ledrs_oper_type_id,
|
||||||
|
ied_usr->oper_type_cache.reboot_oper_type_id,
|
||||||
|
ied_usr->oper_type_cache.reset_oper_type_id);
|
||||||
|
|
||||||
|
if (ied_usr->oper_type_cache.inited == SD_TRUE)
|
||||||
|
{
|
||||||
|
printf("[CTRL_INIT] already inited\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
char domName[256] = {0};
|
||||||
|
|
||||||
|
BuildResetDomName(ied_usr,
|
||||||
|
domName,
|
||||||
|
sizeof(domName));
|
||||||
|
|
||||||
|
printf("[CTRL_INIT] final dom=%s\n", domName);
|
||||||
|
|
||||||
|
ied_usr->oper_type_cache.ledrs_oper_type_id =
|
||||||
|
create_oper_type_id(chnl_usr->net_info,
|
||||||
|
domName,
|
||||||
|
"CO$LEDRs$Oper",
|
||||||
|
g_pt61850app->mmsOpTimeout);
|
||||||
|
|
||||||
|
printf("[CTRL_INIT] LEDRs type_id=%d\n",
|
||||||
|
ied_usr->oper_type_cache.ledrs_oper_type_id);
|
||||||
|
|
||||||
|
ied_usr->oper_type_cache.reboot_oper_type_id =
|
||||||
|
create_oper_type_id(chnl_usr->net_info,
|
||||||
|
domName,
|
||||||
|
"CO$Reboot$Oper",
|
||||||
|
g_pt61850app->mmsOpTimeout);
|
||||||
|
|
||||||
|
printf("[CTRL_INIT] Reboot type_id=%d\n",
|
||||||
|
ied_usr->oper_type_cache.reboot_oper_type_id);
|
||||||
|
|
||||||
|
ied_usr->oper_type_cache.reset_oper_type_id =
|
||||||
|
create_oper_type_id(chnl_usr->net_info,
|
||||||
|
domName,
|
||||||
|
"ST$Mod$stVal",
|
||||||
|
g_pt61850app->mmsOpTimeout);
|
||||||
|
|
||||||
|
printf("[CTRL_INIT] Reset type_id=%d\n",
|
||||||
|
ied_usr->oper_type_cache.reset_oper_type_id);
|
||||||
|
|
||||||
|
/* 无论成功失败,都不再重复初始化 */
|
||||||
|
ied_usr->oper_type_cache.inited = SD_TRUE;
|
||||||
|
|
||||||
|
printf("[CTRL_INIT] finish inited=%d\n",
|
||||||
|
(int)ied_usr->oper_type_cache.inited);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ST_RET write_common_oper(chnl_usr_t *chnl_usr,
|
||||||
|
ST_CHAR *domName,
|
||||||
|
const char *ctlName,
|
||||||
|
ST_INT oper_type_id,
|
||||||
|
ST_INT timeOut)
|
||||||
|
{
|
||||||
|
if (chnl_usr == NULL ||
|
||||||
|
chnl_usr->net_info == NULL ||
|
||||||
|
domName == NULL ||
|
||||||
|
ctlName == NULL ||
|
||||||
|
oper_type_id < 0)
|
||||||
|
{
|
||||||
|
printf("[OPER_WRITE] invalid param\n");
|
||||||
|
return SD_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
ST_CHAR varName[MAX_IDENT_LEN + 1];
|
||||||
|
apr_snprintf(varName,
|
||||||
|
sizeof(varName),
|
||||||
|
"LLN0$%s",
|
||||||
|
ctlName);
|
||||||
|
|
||||||
|
Control_Oper_t oper;
|
||||||
|
memset(&oper, 0, sizeof(oper));
|
||||||
|
|
||||||
|
oper.ctlVal = SD_TRUE;
|
||||||
|
oper.origin.orCat = 3;
|
||||||
|
oper.origin.orIdent.len = 0;
|
||||||
|
oper.ctlNum = 1;
|
||||||
|
u_get_current_utc_time(&oper.T);
|
||||||
|
oper.Test = SD_FALSE;
|
||||||
|
oper.Check[0] = 0x00;
|
||||||
|
oper.Check[1] = 0x00;
|
||||||
|
|
||||||
|
if ((int)sizeof(Control_Oper_t) !=
|
||||||
|
mvl_type_ctrl[oper_type_id].data_size)
|
||||||
|
{
|
||||||
|
printf("[OPER_WRITE] SIZE MISMATCH ctl=%s local=%d runtime=%d\n",
|
||||||
|
ctlName,
|
||||||
|
(int)sizeof(Control_Oper_t),
|
||||||
|
mvl_type_ctrl[oper_type_id].data_size);
|
||||||
|
return SD_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("[OPER_WRITE] dom=%s var=%s type_id=%d\n",
|
||||||
|
domName, varName, oper_type_id);
|
||||||
|
|
||||||
|
return mms_named_var_write(chnl_usr->net_info,
|
||||||
|
varName,
|
||||||
|
DOM_SPEC,
|
||||||
|
domName,
|
||||||
|
oper_type_id,
|
||||||
|
(ST_CHAR *)&oper,
|
||||||
|
timeOut);
|
||||||
|
}
|
||||||
|
|
||||||
|
ST_RET mms_conclude_disconnect(MVL_NET_INFO *net_info, ST_INT timeOut)
|
||||||
|
{
|
||||||
|
MVL_REQ_PEND *reqCtrl = NULL;
|
||||||
|
ST_RET ret;
|
||||||
|
|
||||||
|
if (net_info == NULL)
|
||||||
|
return SD_FAILURE;
|
||||||
|
|
||||||
|
printf("[RESET] before mvl_concl\n");
|
||||||
|
|
||||||
|
ret = mvl_concl(net_info, &reqCtrl);
|
||||||
|
|
||||||
|
printf("[RESET] after mvl_concl ret=0x%X reqCtrl=%p\n",
|
||||||
|
ret, reqCtrl);
|
||||||
|
|
||||||
|
if (ret == SD_SUCCESS && reqCtrl != NULL)
|
||||||
|
{
|
||||||
|
ret = waitReqDone(reqCtrl, timeOut);
|
||||||
|
|
||||||
|
printf("[RESET] conclude wait ret=0x%X\n", ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reqCtrl != NULL)
|
||||||
|
mvl_free_req_ctrl(reqCtrl);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ST_RET write_mod_stval(chnl_usr_t *chnl_usr,
|
||||||
|
ST_CHAR *domName,
|
||||||
|
ST_INT timeOut)
|
||||||
|
{
|
||||||
|
ST_CHAR varName[MAX_IDENT_LEN + 1];
|
||||||
|
ST_INT16 value = 88;
|
||||||
|
|
||||||
|
apr_snprintf(varName, sizeof(varName), "LLN0$ST$Mod$stVal");
|
||||||
|
|
||||||
|
return mms_named_var_write(chnl_usr->net_info,
|
||||||
|
varName,
|
||||||
|
DOM_SPEC,
|
||||||
|
domName,
|
||||||
|
14, //int
|
||||||
|
(ST_CHAR *)&value,
|
||||||
|
timeOut);
|
||||||
|
}
|
||||||
|
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
/* init_log_cfg */
|
/* init_log_cfg */
|
||||||
|
|||||||
@@ -320,6 +320,17 @@ struct LD_info_t{
|
|||||||
//录波
|
//录波
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//装置控制初始化
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
ST_BOOLEAN inited;
|
||||||
|
|
||||||
|
ST_INT ledrs_oper_type_id;
|
||||||
|
ST_INT reboot_oper_type_id;
|
||||||
|
ST_INT reset_oper_type_id;
|
||||||
|
|
||||||
|
} MMS_OPER_TYPE_CACHE;
|
||||||
|
|
||||||
struct ied_usr_t{
|
struct ied_usr_t{
|
||||||
LD_info_t *LD_info; /**< LD数组 */
|
LD_info_t *LD_info; /**< LD数组 */
|
||||||
int dev_idx; /**< 设备序号 */
|
int dev_idx; /**< 设备序号 */
|
||||||
@@ -346,6 +357,8 @@ struct ied_usr_t{
|
|||||||
|
|
||||||
bool lastconnectstat;//lnk20250704
|
bool lastconnectstat;//lnk20250704
|
||||||
bool has_logged_disconnect;//lnk20250704
|
bool has_logged_disconnect;//lnk20250704
|
||||||
|
|
||||||
|
MMS_OPER_TYPE_CACHE oper_type_cache;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -533,24 +546,35 @@ int parse_file_names_by_fltnum(int fltnum, char* domname, char** filenames, int
|
|||||||
QVVR_t* find_qvvr_by_trig_tm(LD_info_t* LD_info,long long trig_tm);
|
QVVR_t* find_qvvr_by_trig_tm(LD_info_t* LD_info,long long trig_tm);
|
||||||
|
|
||||||
void HandleFileDirReqForChannel(chnl_usr_t *chnl_usr);
|
void HandleFileDirReqForChannel(chnl_usr_t *chnl_usr);
|
||||||
|
void InitLedrsOperTypeForChannel(chnl_usr_t *chnl_usr);
|
||||||
|
|
||||||
//lnk20250508添加重启装置函数
|
//lnk20250508添加重启装置函数
|
||||||
//根据抓包显示oper的data结构有6个item
|
//根据抓包显示oper的data结构有6个item
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
ST_BOOLEAN ctlVal; //0:不重启 1:重启
|
ST_BOOLEAN ctlVal;
|
||||||
|
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
ST_INT8 orCat;
|
ST_INT16 orCat;
|
||||||
ST_CHAR orIdent[1]; // 空字符串
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
ST_INT16 len;
|
||||||
|
ST_UINT8 data[64];
|
||||||
|
} orIdent;
|
||||||
|
|
||||||
} origin;
|
} origin;
|
||||||
|
|
||||||
ST_UINT8 ctlNum;
|
ST_UINT32 ctlNum;
|
||||||
|
|
||||||
MMS_UTC_TIME T;
|
MMS_UTC_TIME T;
|
||||||
|
|
||||||
ST_BOOLEAN Test;
|
ST_BOOLEAN Test;
|
||||||
ST_UCHAR Check[1]; // bit-string 00
|
|
||||||
} LEDRs_Oper_t;
|
ST_UCHAR Check[2];
|
||||||
|
|
||||||
|
} Control_Oper_t;
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user