添加装置重启功能和控制位写入功能

This commit is contained in:
lnk
2026-05-14 16:16:16 +08:00
parent 2f584fda30
commit c6ca57a204
8 changed files with 664 additions and 172 deletions

View File

@@ -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 write_ledrs_oper(MVL_NET_INFO* netInfo,//netInfo客户端和 MMS 服务器之间的网络连接信息
ST_CHAR* domName, //域名 iedname+0
ST_INT oper_type_id, //数据类型 这里是boolean
ST_INT timeOut); //响应时长
extern ST_RET write_common_oper(chnl_usr_t *chnl_usr,
ST_CHAR *domName,
const char *ctlName,
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;
@@ -2225,7 +2233,7 @@ static int BuildTempLocalPath(char* outPath,
const char* fileName = GetFileNameOnly(remotePath);
if (fileName == NULL || fileName[0] == '\0')
fileName = "tmp_file.dat";
fileName = "tmp_file";
const char* ipStr = chnl_usr->ip_str;
if (ipStr == NULL || ipStr[0] == '\0')
@@ -2235,7 +2243,7 @@ static int BuildTempLocalPath(char* outPath,
SafePathName(ipStr, safeIp, sizeof(safeIp));
char dirPath[512] = {0};
snprintf(dirPath, sizeof(dirPath), "/tmp/%s", safeIp);
snprintf(dirPath, sizeof(dirPath), "/FeProject/dat/filetodevice/%s", safeIp);
/* 目录不存在则创建 */
if (MakeDirRecursive(dirPath) != 0)
@@ -2244,8 +2252,16 @@ static int BuildTempLocalPath(char* outPath,
return -1;
}
snprintf(outPath, outSize, "%s/%s", dirPath, fileName);
return 0;
int n = snprintf(outPath, outSize, "%s/%s", dirPath, fileName);
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,
@@ -2347,7 +2363,7 @@ static int HandleTypeTransferToDevice(chnl_usr_t* chnl_usr,
if (chnl_usr == NULL || req == NULL || chnl_usr->net_info == NULL)
return -1;
char localpath[512] = {0};
char localpath[1024] = {0};
if (BuildTempLocalPath(localpath, sizeof(localpath), chnl_usr, req->remote_path) != 0)
{
DIY_ERRORLOG_CODE(req->devid,1, LOG_CODE_FILE_CONTROL,
@@ -2451,6 +2467,163 @@ static int HandleDeleteFileInDevice(chnl_usr_t* chnl_usr,
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)
{
if (chnl_usr == NULL) {
@@ -2480,12 +2653,12 @@ void HandleFileDirReqForChannel(chnl_usr_t *chnl_usr)
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;
file_dir_req_t *req = PopMatchedFileDirReq(ied_usr->terminal_id);
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;
return;
}
@@ -2541,54 +2714,10 @@ void HandleFileDirReqForChannel(chnl_usr_t *chnl_usr)
handleRet = HandleDeleteFileInDevice(chnl_usr, req, jsonString);
}
else if (req->type == 4){ //复位
char domName[256] = {0}; //构造ied+0的domName
// 取第一个 LD
if (ied_usr->LD_info &&
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);
}
handleRet = HandleTypeControlDevice(chnl_usr,
ied_usr,
req,
jsonString);
}
else
{