Files
microser/mms/mmscli_rpt.c

2665 lines
105 KiB
C
Raw Normal View History

2025-01-16 16:17:01 +08:00
/**
* @file: $RCSfile: mmscli_rpt.c,v $
* @brief: $IEC 61850 Protocol
*
* @version: $Revision: 1.12 $
* @date: $Date: 2022/11/28 07:13:13 $
* @author: $Author: lizhongming $
* @state: $State: Exp $
*
* @latest: $Id: mmscli_rpt.c,v 1.12 2022/11/28 07:13:13 lizhongming Exp $
*
*/
//$Header: /JoyProject/jspqfe/src/pt61850netd_pqfe/source/mms/mmscli_rpt.c,v 1.12 2022/11/28 07:13:13 lizhongming Exp $
/************************************************************************/
/* SISCO SOFTWARE MODULE HEADER *****************************************/
/************************************************************************/
/* (c) Copyright Systems Integration Specialists Company, Inc., */
/* 2003 - 2005, All Rights Reserved */
/* */
/* MODULE NAME : cli_rpt.c */
/* PRODUCT(S) : MMSEASE-LITE */
/* */
/* MODULE DESCRIPTION : */
/* Functions to perform "client" processing of IEC-61850 Reports */
/* and UCA Reports received from "servers". */
/* */
/* GLOBAL FUNCTIONS DEFINED IN THIS MODULE : */
/* rpt_typeids_find */
/* rcb_info_create */
/* rcb_info_destroy */
/* u_iec_rpt_ind */
/* u_iec_rpt_ind_data (user modify or replace) */
/* */
/* MODIFICATION LOG : */
/* Date Who Rev Comments */
/* -------- --- ------ ------------------------------------------- */
/* 07/22/05 JRB 08 Allow one conn to control multiple RCBs */
/* (user_info must point to ALL_RCB_INFO). */
/* Save varNameArray in rcb_info to use later. */
/* Chg u_iec_rpt_ind_data 4th arg to (RCB_INFO *).*/
/* 12/03/04 JRB 07 Extract domain name of NVL from dataSetName. */
/* Increase RptID length to vstring65. */
/* 08/04/04 EJV 06 rcb_info_create: added typecast for Inclusion*/
/* 06/29/04 JRB 05 Del mvl_tdl_to_type_id & instead use new */
/* mvl_type_id_create_from_tdl. */
/* 05/13/04 JRB 04 Chg SqNum to INT16U to match 61850-7-2. */
/* 01/23/04 JRB 03 Use ms_local_to_text. */
/* 12/17/03 JRB 02 61850-8-1 FDIS changes: */
/* Decode ConfRev in rpt if enabled by OptFlds. */
/* Move SubSeqNum, MoreSegmentsFollow to just */
/* before inclusion bitstring. */
/* Chg OptFlds from bvstring9 to bvstring10. */
/* 10/24/03 JRB 01 New */
/************************************************************************/
#include "rdb_client.h"
#include "db_interface.h"
#include "../json/mms_json_inter.h"
/************************************************************************/
/* For debug version, use a static pointer to avoid duplication of */
/* __FILE__ strings. */
/************************************************************************/
#ifdef DEBUG_SISCO
SD_CONST static ST_CHAR* SD_CONST thisFileName = __FILE__;
#endif
extern pt61850app_t* g_pt61850app;
extern RPT_TYPEIDS g_rpt_typeids;
//lnk20250115
extern pthread_mutex_t mtx;
/************************************************************************/
/* Global variables. */
/************************************************************************/
/* NONE */
/************************************************************************/
/* Static function prototypes. */
/************************************************************************/
static OBJECT_NAME** nvl_var_name_array_create(MVL_NET_INFO* net_info, ST_CHAR* domName,
ST_CHAR* nvlName, ST_INT* numVarOut, ST_INT timeOut);
static ST_VOID nvl_var_name_array_destroy(OBJECT_NAME** varNameArray, ST_INT numVar);
static ST_INT var_type_create(MVL_NET_INFO* net_info, OBJECT_NAME* varObj,
ST_INT timeOut);
static ST_RET rcb_info_var_create(RCB_INFO* rcb_info, RPT_TYPEIDS* rpt_typeids);
static ST_VOID rcb_info_var_destroy(RCB_INFO* rcb_info);
static ST_VOID log_var_data(MVL_VAR_ASSOC* var, MMS_DECODE_DATA* data);
/* DEBUG: move these functions to library modules? */
OBJECT_NAME* object_name_clone_create(OBJECT_NAME* srcobj);
ST_VOID object_name_clone_destroy(OBJECT_NAME* obj);
static ST_ULONG a_get_rem_ip_addr_inline(ST_LONG acse_conn_id, int* nPort);
static char* _convert_ip_2_char(unsigned long dwIP);
#if 1 //<2F><><EFBFBD><EFBFBD> <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>IP WW 2023-08-29
static char* _convert_ip_2_char(unsigned long dwIP)
{
static char buf[64] = { 0 };
sprintf(buf, "%d.%d.%d.%d", (dwIP >> 24) & 0xff, (dwIP >> 16) & 0xff, (dwIP >> 8) & 0xff, (dwIP) & 0xff);
return buf;
}
#if defined (TP0_ENABLED)
/************************************************************************/
/* a_get_rem_ip_addr */
/* This function returns the remote IP Address as an unsigned long in */
/* "network byte order", just like the "standard sockets" function */
/* "inet_addr" does. If there is an error, it returns */
/* "htonl (INADDR_NONE)", just like "inet_addr" does. */
/* The return value can be stored in the appropriate union member */
/* in the structure "in_addr", which can be passed to "inet_ntoa". */
/************************************************************************/
#include "tp4.h" /* Need internal TP4 defines */
#include "tp0_sock.h" /* Need "sockets" defines */
#include "acse2.h" /* Need "sockets" defines */
#define MAX_PATH 256
static ST_ULONG get_rem_ip_addr_inline(ST_LONG acse_conn_id, int* nPort)
{
ACSE_CONN *acse_conn;
ST_LONG tp_conn_id;
TP0_CONN *tp0_conn;
ST_INT ret;
SOCKADDR_IN sockaddr_in;
SOCK_ADDRLEN addr_len;
char buf[MAX_PATH] = { 0 };
acse_conn = (ACSE_CONN *)acse_conn_id;
tp_conn_id = acse_conn->tp4_conn_id;
if (tp_conn_id >= MIN_TP0_CONN_ID &&
tp_conn_id < tp0_cfg.max_num_conns + MIN_TP0_CONN_ID)
{ /* Conn id is a legal TP0 conn id */
tp0_conn = &tp0_conn_arr[tp_conn_id - MIN_TP0_CONN_ID];
addr_len = sizeof(SOCKADDR_IN); /* CRITICAL: set to expected len.*/
ret = getpeername(tp0_conn->sock_info->genSock->hSock, (SOCKADDR *)&sockaddr_in, &addr_len);
*nPort = htons(sockaddr_in.sin_port);
if (ret == 0)
return (sockaddr_in.sin_addr.s_addr);
}
return (htonl(INADDR_NONE)); /* something failed */
}
#endif /* defined (TP0_ENABLED) */
#endif
/************************************************************************/
/* rpt_typeids_find */
/* Find ALL types needed for controlling & decoding IEC/UCA reports. */
/* These types must be defined in the ODF file and created by Foundry. */
/* RETURN: SD_SUCCESS or SD_FAILURE (if ANY type is NOT found) */
/* NOTE: this function based on "mvlu_rpt_find_typeids" in "mvlu_rpt.c".*/
/************************************************************************/
ST_RET rpt_typeids_find(RPT_TYPEIDS* rpt_typeids)
{
ST_RET retCode = SD_FAILURE; /* assume FAILURE for now */
ST_CHAR* type_name; /* name of type to be found */
/* stop on any error */
do
{ /* "one-time" loop: just to have something to break out of */
if ((rpt_typeids->mmsbool = mvl_typename_to_typeid(type_name = "RTYP_BOOL")) < 0)
break;
if ((rpt_typeids->bstr6 = mvl_typename_to_typeid(type_name = "RTYP_BSTR6")) < 0)
break;
if ((rpt_typeids->bstr8 = mvl_typename_to_typeid(type_name = "RTYP_BSTR8")) < 0)
break;
if ((rpt_typeids->bstr9 = mvl_typename_to_typeid(type_name = "RTYP_BSTR9")) < 0)
break;
if ((rpt_typeids->bvstring6 = mvl_typename_to_typeid(type_name = "RTYP_BVSTR6")) < 0)
break;
if ((rpt_typeids->bvstring8 = mvl_typename_to_typeid(type_name = "RTYP_BVSTR8")) < 0)
break;
if ((rpt_typeids->bvstring10 = mvl_typename_to_typeid(type_name = "RTYP_BVSTR10")) < 0)
break;
if ((rpt_typeids->btime6 = mvl_typename_to_typeid(type_name = "RTYP_BTIME6")) < 0)
break;
if ((rpt_typeids->int8u = mvl_typename_to_typeid(type_name = "RTYP_INT8U")) < 0)
break;
if ((rpt_typeids->int16u = mvl_typename_to_typeid(type_name = "RTYP_INT16U")) < 0)
break;
if ((rpt_typeids->int32u = mvl_typename_to_typeid(type_name = "RTYP_INT32U")) < 0)
break;
if ((rpt_typeids->ostring8 = mvl_typename_to_typeid(type_name = "RTYP_OSTR8")) < 0)
break;
if ((rpt_typeids->vstring32 = mvl_typename_to_typeid(type_name = "RTYP_VSTR32")) < 0)
break;
if ((rpt_typeids->vstring65 = mvl_typename_to_typeid(type_name = "RTYP_VSTR65")) < 0)
break;
retCode = SD_SUCCESS; /* If we get here, all were successful */
} while (0); /* end of "one-time" loop */
if (retCode)
MVL_LOG_ERR1("Can't find type '%s'", type_name);
return (retCode); /* If ANY find failed, SD_FAILURE is returned */
}
/************************************************************************/
/* rcb_info_create */
/************************************************************************/
RCB_INFO* rcb_info_create(MVL_NET_INFO* net_info, ST_CHAR* domName,
ST_CHAR* rcbName, RPT_TYPEIDS* rpt_typeids, ST_INT timeOut)
{
RCB_INFO* rcb_info;
ST_CHAR varName[MAX_IDENT_LEN + 1];
ST_CHAR datSetName[65 + 1]; /* data set name (Vstring65) */
ST_CHAR datdomName[65 + 1]; /* data set name (Vstring65) */
ST_CHAR RptID[65 + 1]; /* RptID (Vstring65) */
ST_CHAR* nvlName;
ST_INT numDsVar; /* num variables in NVL */
OBJECT_NAME** varNameArray; /* array of variable names in NVL */
ST_INT j;
size_t extended_size;
ST_CHAR* extended_ptr;
ST_CHAR InclusionTdl[30]; /* place to create TDL for inclusion bstr*/
ST_RET status = SD_SUCCESS; /* set to SD_FAILURE if anything fails. */
ST_CHAR* nvlDomName;
ST_INT rcb_type;
assert(rpt_typeids->mmsbool || rpt_typeids->int8u); /* make sure global struct initialized*/
/* Read "RptID" from the server & save in "RptID" local variable. */
/* Copy to "rcb_info" struct later. */
strcpy(varName, rcbName);
strcat(varName, "$RptID");
if (mms_named_var_read(net_info, varName, DOM_SPEC, domName, rpt_typeids->vstring65, RptID, timeOut))
{
echo_warn2("Error reading RptID '%s' in domain '%s'\n", varName, domName);
return (NULL);
}
/* Figure out RCB type from 'rcbName'. */
if (strstr(rcbName, "$BR$") != NULL)
rcb_type = RCB_TYPE_IEC_BRCB;
else if (strstr(rcbName, "$RP$") != NULL)
{
/* This could be IEC URCB or UCA URCB. Only IEC contains "Resv" attr.*/
/* Try to read "Resv". If successful, RCB is IEC_URCB, else it is UCA.*/
/* NOTE: "RptID" read was successful, so we know this RCB exists. */
ST_BOOLEAN tmpResv;
strcpy(varName, rcbName);
strcat(varName, "$Resv");
if (mms_named_var_read(net_info, varName, DOM_SPEC, domName, rpt_typeids->mmsbool, &tmpResv, timeOut) == SD_SUCCESS)
rcb_type = RCB_TYPE_IEC_URCB;
else
rcb_type = RCB_TYPE_UCA;
}
else
{
echo_warn1("RCB name '%s' invalid. Must contain 'BR' or 'RP'.\n", rcbName);
return (NULL);
}
/* Read "DatSet" from the server. */
strcpy(varName, rcbName);
strcat(varName, "$DatSet");
if (mms_named_var_read(net_info, varName, DOM_SPEC, domName, rpt_typeids->vstring65, datSetName, timeOut))
{ /* can't read data set name */
echo_warn2("Error reading data set name ('%s' in domain '%s')\n", varName, domName);
return (NULL);
}
/* datSetName should now be set */
strcpy(datdomName, datSetName);//WW 2023-10-23
nvlDomName = strtok(datdomName, "/");/* extract domain name of NVL */
nvlName = strtok(NULL, ""); /* extract NVL name */
if (nvlName == NULL) /* "/" not found */
{
echo_warn1("datSetName '%s' invalid. Does not contain '/' character.", datSetName);
return (NULL);
}
/* Get NVL Attributes from the server */
/* NOTE: Resources allocated by this funct are freed by calling */
/* nvl_var_name_array_destroy (called from rcb_info_destroy). */
varNameArray = nvl_var_name_array_create(net_info, nvlDomName, nvlName, &numDsVar, timeOut);
if (varNameArray == NULL)
{
echo_warn2("GetNamedVariableListAttributes request failed for '%s' in domain '%s'",
nvlName, domName);
return (NULL);
}
/* Allocate RCB_INFO structure plus extra room for additional data
* that depends on "numDsVar". This effectively combines 8 allocations into one.
* Set pointers in RCB_INFO structure to point into the extra space.
* CRITICAL: use chk_calloc to start with clean structure
*/
extended_size = sizeof(RCB_INFO)
+ numDsVar * sizeof(ST_INT) /* rcb_info->typeIdArr */
+ numDsVar * sizeof(MVL_VAR_ASSOC*) /* rcb_info->rcb_var.dataRefName*/
+ numDsVar * sizeof(MVL_VAR_ASSOC*) /* rcb_info->rcb_var.dataValue */
+ numDsVar * sizeof(MVL_VAR_ASSOC*) /* rcb_info->rcb_var.Reason */
+ numDsVar * 66 /* rcb_info->rcb_data.dataRefName*/
+ numDsVar * sizeof(MMS_BVSTRING) /* rcb_info->rcb_data.Reason */
+ BSTR_NUMBITS_TO_NUMBYTES(numDsVar); /* rcb_info->rcb_data.Inclusion */
rcb_info = (RCB_INFO*)chk_calloc(1, extended_size);
strcpy(rcb_info->dom_Name, domName); //WW 2023-08-29 <20>߼<EFBFBD><DFBC><EFBFBD><E8B1B8><EFBFBD><EFBFBD>
strcpy(rcb_info->rcb_name, rcbName); //WW 2023-08-29 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƿ<EFBFBD><C6BF><EFBFBD><EFBFBD><EFBFBD>
//////////////////////////////////////////////////////////////////////////
strcpy(rcb_info->ds_Nam, datSetName); //WW 2023-08-29 <20><><EFBFBD>ݼ<EFBFBD><DDBC><EFBFBD><EFBFBD><EFBFBD>
//////////////////////////////////////////////////////////////////////////
echo_msg4("Client RCB info 0x%X created for '%s' in domain '%s'.datasetnam '%s' \n", rcb_info, rcbName, domName, datSetName);
extended_ptr = (ST_CHAR*)(rcb_info + 1); /* point after RCB_INFO struct */
rcb_info->typeIdArr = (ST_INT*)extended_ptr;
extended_ptr += numDsVar * sizeof(ST_INT); /* point after rcb_info->typeIdArr*/
rcb_info->rcb_var.dataRefName = (MVL_VAR_ASSOC**)extended_ptr;
extended_ptr += numDsVar * sizeof(MVL_VAR_ASSOC*); /* rcb_info->rcb_var.dataRefName*/
rcb_info->rcb_var.dataValue = (MVL_VAR_ASSOC**)extended_ptr;
extended_ptr += numDsVar * sizeof(MVL_VAR_ASSOC*); /* rcb_info->rcb_var.dataValue */
rcb_info->rcb_var.Reason = (MVL_VAR_ASSOC**)extended_ptr;
extended_ptr += numDsVar * sizeof(MVL_VAR_ASSOC*); /* rcb_info->rcb_var.Reason */
rcb_info->rcb_data.dataRefName = extended_ptr;
extended_ptr += numDsVar * 66; /* rcb_info->rcb_data.dataRefName*/
rcb_info->rcb_data.Reason = (MMS_BVSTRING*)extended_ptr;
extended_ptr += numDsVar * sizeof(MMS_BVSTRING); /* rcb_info->rcb_data.Reason */
rcb_info->rcb_data.Inclusion = (ST_UINT8*)extended_ptr;
extended_ptr += BSTR_NUMBITS_TO_NUMBYTES(numDsVar); /* rcb_info->rcb_data.Inclusion */
/* Make sure we computed sizes correctly. */
assert(extended_ptr == (ST_CHAR*)rcb_info + extended_size);
/* Fill in other rcb_info structure members. */
rcb_info->rcb_type = rcb_type;
strcpy(rcb_info->RptID, RptID); /* save RptID to compare when RPTs received*/
rcb_info->varNameArray = varNameArray;
rcb_info->numDsVar = numDsVar;
/* Create all necessary types. */
/* Try to create all types even if one fails. */
/* This way, we can later destroy all without remembering which */
/* were successfully created. */
/* Create a Type for the Inclusion bitstring. Save it in "rcb_info->InclusionTypeid" */
apr_snprintf(InclusionTdl, sizeof(InclusionTdl), "Bstring%d", rcb_info->numDsVar);
rcb_info->InclusionTypeid = mvl_type_id_create_from_tdl(NULL, InclusionTdl);
if (rcb_info->InclusionTypeid < 0)
{
echo_warn("Error - could not add type for 'Inclusion'.");
status = SD_FAILURE;
}
/* Create types and fill in rcb_info->typeIdArr */
/* Start with all set to invalid, so if some fail, cleanup is easier. */
for (j = 0; j < numDsVar; j++)
rcb_info->typeIdArr[j] = -1; /* invalid type_id */
for (j = 0; j < numDsVar; j++)
{
if ((rcb_info->typeIdArr[j] = var_type_create(net_info, varNameArray[j], timeOut))
< 0)
{ /* couldn't create this type, so stop */
echo_warn1("Error creating type for variable '%s'",
varNameArray[j]->obj_name.vmd_spec);
status = SD_FAILURE;
break;
}
}
if (status == SD_SUCCESS)
{
/* Types created OK, so create variables */
status = rcb_info_var_create(rcb_info, rpt_typeids); /* returns SD_SUCCESS or SD_FAILURE*/
}
if (status != SD_SUCCESS)
{ /* something failed. Destroy anything created. */
rcb_info_destroy(rcb_info);
rcb_info = NULL;
}
return (rcb_info);
}
/************************************************************************/
/* rcb_info_destroy */
/************************************************************************/
ST_VOID rcb_info_destroy(RCB_INFO* rcb_info)
{
ST_INT j;
/* Free up array of variable names saved in rcb_info_create */
nvl_var_name_array_destroy(rcb_info->varNameArray, rcb_info->numDsVar);
/* Destroy all variables. */
rcb_info_var_destroy(rcb_info);
/* Destroy "Inclusion" Type (this should be AFTER destroying "Inclusion" Variable).*/
if (rcb_info->InclusionTypeid > 0) /* 0=never created. -1=error */
mvl_type_id_destroy(rcb_info->InclusionTypeid);
/* Destroy "dataValue" Types (this should be AFTER destroying "dataValue" variables). */
for (j = 0; j < rcb_info->numDsVar; j++)
{
/* All types were initialized to -1. They are also set to -1 if create failed.*/
/* Only destroy types that are NOT (-1). */
if (rcb_info->typeIdArr[j] >= 0)
mvl_type_id_destroy(rcb_info->typeIdArr[j]);
}
chk_free(rcb_info);
echo_warn1("Client RCB info 0x%X destroyed", rcb_info);
}
/************************************************************************/
/* nvl_var_name_array_create */
/* Send a GetNamedVariableListAttributes request to get a list of */
/* variable names in a NamedVariableList (NVL). */
/* Assume the NVL is domain-specific */
/* RETURN: ptr to array of ptrs to variable names (OBJECT_NAME structs).*/
/* Also the variable pointed to by numVarOut contains the number*/
/* of variables in the NVL. */
/* NOTE: this function allocates memory for the (OBJECT_NAME *) array. */
/* Call "nvl_var_name_array_destroy" to free the memory. */
/************************************************************************/
static OBJECT_NAME** nvl_var_name_array_create(MVL_NET_INFO* net_info, ST_CHAR* domName, ST_CHAR* nvlName,
ST_INT* numVarOut,
ST_INT timeOut)
{
MVL_REQ_PEND* reqCtrl;
GETVLIST_REQ_INFO getvlist_req;
GETVLIST_RESP_INFO* getvlist_resp; /* set to reqCtrl->u.getvlist_resp_info*/
VARIABLE_LIST* variable_list;
OBJECT_NAME** varNameArray; /* Ptr to array of ptrs to var names */
ST_RET ret; /* general purpose return code */
ST_INT j;
getvlist_req.vl_name.object_tag = DOM_SPEC;
getvlist_req.vl_name.domain_id = domName;
getvlist_req.vl_name.obj_name.vmd_spec = nvlName;
ret = mvla_getvlist(net_info, &getvlist_req, &reqCtrl);
if (ret == SD_SUCCESS)
ret = waitReqDone(reqCtrl, timeOut);
if (ret != SD_SUCCESS)
{
echo_warn1("mvla_getvlist Error = 0x%X.", ret);
varNameArray = NULL;
}
else
{
getvlist_resp = reqCtrl->u.getvlist.resp_info;
variable_list = (VARIABLE_LIST*)(getvlist_resp + 1);
/* Allocate array of variable names. */
*numVarOut = getvlist_resp->num_of_variables;
varNameArray = (OBJECT_NAME**)chk_malloc(getvlist_resp->num_of_variables * sizeof(OBJECT_NAME*));
/* Copy info from response to allocated array */
for (j = 0; j < getvlist_resp->num_of_variables; j++, variable_list++)
{
/* Assume all variables are named. */
assert(variable_list->var_spec.var_spec_tag == VA_SPEC_NAMED);
varNameArray[j] = object_name_clone_create(&variable_list->var_spec.vs.name);
}
}
mvl_free_req_ctrl(reqCtrl); /* CRITICAL: */
return (varNameArray);
}
/************************************************************************/
/* nvl_var_name_array_destroy */
/* Free up all resources allocated by "nvl_var_name_array_create". */
/************************************************************************/
static ST_VOID nvl_var_name_array_destroy(OBJECT_NAME** varNameArray, ST_INT numVar)
{
ST_INT j;
for (j = 0; j < numVar; j++)
object_name_clone_destroy(varNameArray[j]);
chk_free(varNameArray);
}
/************************************************************************/
/* var_type_create */
/* Send GetVariableAccessAttributes request. Wait for response. When */
/* response received, create new type. Pass NULL as type_name arg to */
/* "mvl_type_id_create" (this avoids the problem of duplicate names). */
/* RETURN: Type ID */
/* NOTE: Call "mvl_type_id_destroy" to destroy the type created here. */
/************************************************************************/
static ST_INT 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; /* invalid. If anything fails, this value returned*/
ST_RET ret;
getvar_req.req_tag = GETVAR_NAME;
getvar_req.name = *varObj;
/* Send GetVariableAccessAttributes request & wait for response. */
ret = mvla_getvar(net_info, &getvar_req, &reqCtrl);
if (ret == SD_SUCCESS)
ret = waitReqDone(reqCtrl, timeOut);
if (ret != SD_SUCCESS)
echo_warn1("GetVariableAccessAttributes error = 0x%x.", ret);
else
{
type_spec = &reqCtrl->u.getvar.resp_info->type_spec;
/* First arg (type_name) is NULL to avoid duplicate names. */
type_id = mvl_type_id_create(NULL, type_spec->data, type_spec->len);
}
mvl_free_req_ctrl(reqCtrl);
return (type_id);
}
/************************************************************************/
/* rcb_info_var_create */
/* Create dummy variables to be used later when a report is received. */
/* These variables are needed to decode the data received in a report. */
/* This function fills in "rcb_info->rcb_data" and "rcb_info->rcb_var". */
/************************************************************************/
static ST_RET rcb_info_var_create(RCB_INFO* rcb_info, RPT_TYPEIDS* rpt_typeids)
{
OBJECT_NAME dummyvar_objname; /* dummy variable object name */
ST_INT j;
ST_INT incSize; /* num bytes for inclusion bitstring */
/* CRITICAL: "mvl_var_create" is used (NOT "mvl_var_add") to create
* local variables to store data received later in IEC/UCA Reports.
* These are NOT real variables, so remote MMS nodes cannot access them.
* All variables use the same name (dummyvar): that's OK because
* "mvl_var_create" does NOT add them to the database and nothing needs
* to use the name.
*/
/* NOTE: last arg to mvl_var_create is always SD_FALSE, so the name is
* NOT copied. This is OK because all names here are fixed strings.
*/
/* Set up one OBJECT_NAME to use for all variables. */
dummyvar_objname.object_tag = VMD_SPEC;
dummyvar_objname.obj_name.vmd_spec = "dummyvar"; /* all vars use same name */
if ((rcb_info->rcb_var.RptID = mvl_var_create(&dummyvar_objname, rpt_typeids->vstring65,
&rcb_info->rcb_data.RptID, NULL, SD_FALSE)) == NULL)
return (SD_FAILURE);
if ((rcb_info->rcb_var.OptFlds = mvl_var_create(&dummyvar_objname, rpt_typeids->bvstring10,
&rcb_info->rcb_data.OptFlds, NULL, SD_FALSE)) == NULL)
return (SD_FAILURE);
if ((rcb_info->rcb_var.SqNum = mvl_var_create(&dummyvar_objname, rpt_typeids->int16u,
&rcb_info->rcb_data.SqNum, NULL, SD_FALSE)) == NULL)
return (SD_FAILURE);
if ((rcb_info->rcb_var.TimeOfEntry = mvl_var_create(&dummyvar_objname, rpt_typeids->btime6,
&rcb_info->rcb_data.TimeOfEntry, NULL, SD_FALSE)) == NULL)
return (SD_FAILURE);
if ((rcb_info->rcb_var.DatSetNa = mvl_var_create(&dummyvar_objname, rpt_typeids->vstring65,
&rcb_info->rcb_data.DatSetNa, NULL, SD_FALSE)) == NULL)
return (SD_FAILURE);
if ((rcb_info->rcb_var.BufOvfl = mvl_var_create(&dummyvar_objname, rpt_typeids->mmsbool,
&rcb_info->rcb_data.BufOvfl, NULL, SD_FALSE)) == NULL)
return (SD_FAILURE);
if ((rcb_info->rcb_var.SubSeqNum = mvl_var_create(&dummyvar_objname, rpt_typeids->int16u,
&rcb_info->rcb_data.SubSeqNum, NULL, SD_FALSE)) == NULL)
return (SD_FAILURE);
if ((rcb_info->rcb_var.MoreSegmentsFollow = mvl_var_create(&dummyvar_objname, rpt_typeids->mmsbool,
&rcb_info->rcb_data.MoreSegmentsFollow, NULL, SD_FALSE)) == NULL)
return (SD_FAILURE);
if ((rcb_info->rcb_var.EntryID = mvl_var_create(&dummyvar_objname, rpt_typeids->ostring8,
&rcb_info->rcb_data.EntryID, NULL, SD_FALSE)) == NULL)
return (SD_FAILURE);
if ((rcb_info->rcb_var.ConfRev = mvl_var_create(&dummyvar_objname, rpt_typeids->int32u,
&rcb_info->rcb_data.ConfRev, NULL, SD_FALSE)) == NULL)
return (SD_FAILURE);
incSize = BSTR_NUMBITS_TO_NUMBYTES(rcb_info->numDsVar);
/* Note: rcb_info->rcb_data.Inclusion is a "ptr" to data, so don't add "&". */
if ((rcb_info->rcb_var.Inclusion = mvl_var_create(&dummyvar_objname, rcb_info->InclusionTypeid,
rcb_info->rcb_data.Inclusion, NULL, SD_FALSE)) == NULL)
return (SD_FAILURE);
/* Allocate array of DataRefName (vstring65) */
/* & array of (MVL_VAR_ASSOC *). */
/* Can't alloc array of strings, so we just allocate one big buffer */
/* and use [j*66] to find postion for each string in the buffer. */
/* Create separate variable for each array entry. */
for (j = 0; j < rcb_info->numDsVar; j++)
{
if ((rcb_info->rcb_var.dataRefName[j] = mvl_var_create(&dummyvar_objname, rpt_typeids->vstring65,
&rcb_info->rcb_data.dataRefName[j * 66], NULL, SD_FALSE)) == NULL)
return (SD_FAILURE);
}
/* Create variable for each DataSet variable. */
for (j = 0; j < rcb_info->numDsVar; j++)
{
ST_VOID* remote_data; /* buffer to store remote data */
MVL_TYPE_CTRL* type_ctrl;
type_ctrl = mvl_type_ctrl_find(rcb_info->typeIdArr[j]);
assert(type_ctrl); /* find should never fail */
/* Allocate buffer to store remote data. */
remote_data = chk_malloc(type_ctrl->data_size);
if ((rcb_info->rcb_var.dataValue[j] = mvl_var_create(&dummyvar_objname,
rcb_info->typeIdArr[j], /* Use type just created */
remote_data, /* buffer for data */
NULL, /* proc funs */
SD_FALSE)) /* DON'T copy name */
== NULL)
{ /* couldn't create this variable, so stop */
return (SD_FAILURE);
}
}
/* Allocate array of Reason (bstr6)(one byte for each Reason) */
/* & array of (MVL_VAR_ASSOC *). */
/* Create separate variable for each array entry. */
for (j = 0; j < rcb_info->numDsVar; j++)
{
/* Use bvstring8 because IEC sends bstr6 and UCA sends bstr8. */
if ((rcb_info->rcb_var.Reason[j] = mvl_var_create(&dummyvar_objname, rpt_typeids->bvstring8,
&rcb_info->rcb_data.Reason[j], NULL, SD_FALSE)) == NULL)
return (SD_FAILURE);
}
/* If we get this far, everything was successful. */
return (SD_SUCCESS);
}
/************************************************************************/
/* rcb_info_var_destroy */
/* Destroy everything created in "rcb_info_var_create". */
/* Check that each was successfully creating before destroying. Any one */
/* of the "mvl_var_create" calls in "rcb_info_var_create" may have failed.*/
/************************************************************************/
static ST_VOID rcb_info_var_destroy(RCB_INFO* rcb_info)
{
ST_INT j;
if (rcb_info->rcb_var.RptID)
mvl_var_destroy(rcb_info->rcb_var.RptID);
if (rcb_info->rcb_var.OptFlds)
mvl_var_destroy(rcb_info->rcb_var.OptFlds);
if (rcb_info->rcb_var.SqNum)
mvl_var_destroy(rcb_info->rcb_var.SqNum);
if (rcb_info->rcb_var.TimeOfEntry)
mvl_var_destroy(rcb_info->rcb_var.TimeOfEntry);
if (rcb_info->rcb_var.DatSetNa)
mvl_var_destroy(rcb_info->rcb_var.DatSetNa);
if (rcb_info->rcb_var.BufOvfl)
mvl_var_destroy(rcb_info->rcb_var.BufOvfl);
if (rcb_info->rcb_var.SubSeqNum)
mvl_var_destroy(rcb_info->rcb_var.SubSeqNum);
if (rcb_info->rcb_var.MoreSegmentsFollow)
mvl_var_destroy(rcb_info->rcb_var.MoreSegmentsFollow);
if (rcb_info->rcb_var.EntryID)
mvl_var_destroy(rcb_info->rcb_var.EntryID);
if (rcb_info->rcb_var.ConfRev)
mvl_var_destroy(rcb_info->rcb_var.ConfRev);
if (rcb_info->rcb_var.Inclusion)
mvl_var_destroy(rcb_info->rcb_var.Inclusion);
/* Destroy "dataRefName" variables. */
for (j = 0; j < rcb_info->numDsVar; j++)
{
if (rcb_info->rcb_var.dataRefName[j])
mvl_var_destroy(rcb_info->rcb_var.dataRefName[j]);
}
/* Destroy "dataValue" variables. */
for (j = 0; j < rcb_info->numDsVar; j++)
{
if (rcb_info->rcb_var.dataValue[j] != NULL)
{
chk_free(rcb_info->rcb_var.dataValue[j]->data);
mvl_var_destroy(rcb_info->rcb_var.dataValue[j]);
}
}
/* Destroy "Reason" variables. */
for (j = 0; j < rcb_info->numDsVar; j++)
{
if (rcb_info->rcb_var.Reason[j])
mvl_var_destroy(rcb_info->rcb_var.Reason[j]);
}
}
/************************************************************************/
/* This sample function sets some options and enables the RCB. */
/* If any write fails, stop. */
/* If more options needed, add more arguments to this function. */
/************************************************************************/
ST_RET rcb_enable(MVL_NET_INFO* netInfo, ST_CHAR* domName,
ST_CHAR* rcbName, ST_UCHAR* OptFlds, ST_UCHAR* TrgOps,
ST_UINT32 IntgPd, RPT_TYPEIDS* rpt_typeids, ST_INT timeOut)
{
ST_BOOLEAN RptEna = 1; /* 1 = enable the report */
ST_RET ret = SD_SUCCESS;
ST_CHAR varName[MAX_IDENT_LEN + 1];
//if (ret == SD_SUCCESS)
//{
// apr_snprintf (varName,sizeof(varName),"%s$IntgPd", rcbName);
// ret = mms_named_var_write (netInfo, varName, DOM_SPEC, domName, rpt_typeids->int32u, (ST_CHAR *) &IntgPd, timeOut);
//}
if (ret == SD_SUCCESS)
{
/* NOTE: only write 9 bits. 10th bit (segmentation) is read-only. */
apr_snprintf(varName, sizeof(varName), "%s$OptFlds", rcbName);
ret = mms_named_var_write(netInfo, varName, DOM_SPEC, domName, rpt_typeids->bstr9, OptFlds, timeOut);
}
if (ret == SD_SUCCESS)
{
apr_snprintf(varName, sizeof(varName), "%s$TrgOps", rcbName);
ret = mms_named_var_write(netInfo, varName, DOM_SPEC, domName, rpt_typeids->bstr6, TrgOps, timeOut);
if (ret != SD_SUCCESS) {
printf("%s Write Error!!!", varName);
echo_warn1("Reportע<EFBFBD><EFBFBD> %s Write Error!!!", varName);
}
}
#if 0 /* Add something like this if other options needed. ???????? BufTm <20><>??*/
if (ret == SD_SUCCESS)
{
apr_snprintf(varName, sizeof(varName), "%s$Trgs", rcbName);
ret = mms_named_var_write(netInfo, varName, DOM_SPEC, domName, rpt_typeids->int16u, (ST_CHAR*)&Trgs, timeOut);
}
#endif
if (ret == SD_SUCCESS)
{
apr_snprintf(varName, sizeof(varName), "%s$RptEna", rcbName);
ret = mms_named_var_write(netInfo, varName, DOM_SPEC, domName, rpt_typeids->mmsbool, (ST_CHAR*)&RptEna, timeOut);
}
return (ret);
}
ST_RET rcb_disable(MVL_NET_INFO* netInfo, ST_CHAR* domName,
ST_CHAR* rcbName, RPT_TYPEIDS* rpt_typeids, ST_INT timeOut)
{
ST_BOOLEAN RptEna = 0; /* 0 = disable the report */
ST_UINT32 IntgPd = 0;
ST_RET ret = SD_SUCCESS;
ST_CHAR varName[MAX_IDENT_LEN + 1];
if (ret == SD_SUCCESS)
{
apr_snprintf(varName, sizeof(varName), "%s$RptEna", rcbName);
ret = mms_named_var_write(netInfo, varName, DOM_SPEC, domName, rpt_typeids->mmsbool, (ST_CHAR*)&RptEna, timeOut);
}
if (ret == SD_SUCCESS)
{
apr_snprintf(varName, sizeof(varName), "%s$IntgPd", rcbName);
ret = mms_named_var_write(netInfo, varName, DOM_SPEC, domName, rpt_typeids->int32u, (ST_CHAR*)&IntgPd, timeOut);
}
return (ret);
}
/************************************************************************/
/************************************************************************/
static ST_VOID log_var_data(MVL_VAR_ASSOC* var, MMS_DECODE_DATA* data)
{
ST_CHAR tdl_buf[500]; /* increase size if complex TDL expected*/
MVL_TYPE_CTRL* type_ctrl;
type_ctrl = mvl_type_ctrl_find(var->type_id);
if (type_ctrl)
{
/* If the TDL produced is longer than max_tdl_len, this function */
/* "gracefully" fails (i.e. returns 0). */
if (ms_runtime_to_tdl(type_ctrl->rt, type_ctrl->num_rt, tdl_buf, sizeof(tdl_buf)) > 0)
;//SLOGCALWAYS1 (" TYPE: %s", tdl_buf);
else
echo_warn(" TYPE: unknown");
//printf ("\nTYPE: %s \n", tdl_buf);
//printf("type_ctrl->num_rt %d %x %x \n", type_ctrl->num_rt , &data, &(var->data));
my_local_to_data((ST_CHAR*)var->data, type_ctrl->rt, type_ctrl->num_rt, data);
if (data->item_num == 0) {
echo_warn("!!!!!!!!!!!!!!!!!!!data num is 0 !!!!!!!!!!!!!!!!\n");
}
}
else
echo_warn(" ERR: type_id is invalid");
}
/************************************************************************/
/* u_iec_rpt_ind_data */
/* User function to process the received report data. This example */
/* function simply writes the data to the log file. */
/* */
/* It should be easy to modify or rewrite this function to do whatever */
/* is appropriate for your application. */
/************************************************************************/
ST_VOID u_iec_rpt_ind_data_by_devtype(MVL_VAR_ASSOC** info_va,
ST_UINT8* OptFldsData, /* ptr to data part of OptFlds bvstring */
ST_UINT8* InclusionData, /* ptr to Inclusion bstring */
RCB_INFO* rcb_info,
ST_INT va_total,
MVL_NET_INFO* net_info)
{
ST_INT va_num = 0;
ST_INT j;
MMS_DECODE_DATA mms_dec_data;
//uint32_t add_mms_dec_data = &mms_dec_data;
ied_t* ied;
rptinfo_t* rptinfo;
// element_t* pDataOMSObject;
LD_info_t* LD_info;
chnl_usr_t* chnl_usr;
char** DataObjectFullName;
// LD_info_t* LD_info_of_Data;
ST_INT not_set_rpt_TimeID_this;
ST_INT not_set_rpt_q_this;
//printf("Var# %02d: RptId", va_num);
log_var_data(info_va[va_num], &mms_dec_data);
//assert(add_mms_dec_data== (uint32_t)&mms_dec_data);
rptinfo = find_rptinfo_from_net_rpt_info_name(net_info, rcb_info);
//rptinfo->m_LastDataTime = sGetMsTime();//WW 2023-08-29 ȥ<><C8A5>
LD_info = rptinfo->LD_info;
chnl_usr = net_info->user_ext;
ied = chnl_usr->chnl->ied;
not_set_rpt_TimeID_this = TRUE;
not_set_rpt_q_this = TRUE;
//g_db_inf_clear_data(RPT_IDX);
rptinfo->count++;
printf("[BEGIND Process] Received Report From %s:%d %s %s ,va_total = %i ,<2C><>count = %i<><69> \n",
chnl_usr->ip_str, chnl_usr->chnl->port, LD_info->LD_name, rcb_info->RptID, va_total, rptinfo->count);
//apr_time_t previousTime = apr_time_now();//
//apr_time_exp_t localTime;
//apr_time_exp_gmt(&localTime, previousTime);
//printf("\n ------>>>>>>> begind time %d %d:%d:%d.%d \n",
// localTime.tm_mday, localTime.tm_hour, localTime.tm_min, localTime.tm_sec, localTime.tm_usec);
va_num++;
// SLOGCALWAYS1("Var# %02d: OptFlds", va_num);
log_var_data(info_va[va_num], &mms_dec_data);
//assert(add_mms_dec_data== (uint32_t)&mms_dec_data);
va_num++;
/* NOTE: Don't change initial entries in "info_va". Add these right after "OptFlds".*/
if (BSTR_BIT_GET(OptFldsData, OPTFLD_BITNUM_SQNUM))
{
// SLOGCALWAYS1("Var# %02d: SqNum", va_num);
log_var_data(info_va[va_num], &mms_dec_data);
//assert(add_mms_dec_data== (uint32_t)&mms_dec_data);
printf("\n ------>>>>>>> SqNum received in Report From %s %s %s ,SqNum = %d \n",
chnl_usr->ip_str, LD_info->LD_name, rcb_info->RptID, mms_dec_data.data_item[0].u.data_uint);
va_num++;
}
if (BSTR_BIT_GET(OptFldsData, OPTFLD_BITNUM_TIMESTAMP))
{
// SLOGCALWAYS1("Var# %02d: TimeOfEntry", va_num);
log_var_data(info_va[va_num], &mms_dec_data);
//assert(add_mms_dec_data== (uint32_t)&mms_dec_data);
va_num++;
//set_rpt_TimeID(convert_btime6_to_apr_time(&(mms_dec_data.data_item[0].u.data_bTime6)) );
}
if (BSTR_BIT_GET(OptFldsData, OPTFLD_BITNUM_DATSETNAME))
{
// SLOGCALWAYS1("Var# %02d: DatSetNa", va_num);
log_var_data(info_va[va_num], &mms_dec_data);
//assert(add_mms_dec_data== (uint32_t)&mms_dec_data);
va_num++;
}
if (BSTR_BIT_GET(OptFldsData, OPTFLD_BITNUM_BUFOVFL))
{
// SLOGCALWAYS1("Var# %02d: BufOvfl", va_num);
log_var_data(info_va[va_num], &mms_dec_data);
//assert(add_mms_dec_data== (uint32_t)&mms_dec_data);
va_num++;
}
if (BSTR_BIT_GET(OptFldsData, OPTFLD_BITNUM_ENTRYID))
{
char* EntryIDStr;
int i;
log_var_data(info_va[va_num], &mms_dec_data);
//assert(add_mms_dec_data== (uint32_t)&mms_dec_data);
EntryIDStr = mms_dec_data.data_item[0].u.data_str;
printf("\n ------>>>>>>> EntryID received in Report From %s %s %s ,EntryID = %s\n\n\n",
chnl_usr->ip_str, LD_info->LD_name, rcb_info->RptID, EntryIDStr);
for (i = 0; i < 8; i++) {
EntryIDStr[2] = '\0';
rptinfo->m_EntryID[i] = (byte_t)strtol(EntryIDStr, NULL, 16);
EntryIDStr += 3; //skip a blank
}
va_num++;
}
printf("\n -------------rptinfo->m_EntryID %02x %02x %02x %02x %02x %02x %02x %02x -------- EntryID\n\n\n",
*rptinfo->m_EntryID, *(rptinfo->m_EntryID + 1), *(rptinfo->m_EntryID + 2),
*(rptinfo->m_EntryID + 3), *(rptinfo->m_EntryID + 4), *(rptinfo->m_EntryID + 5),
*(rptinfo->m_EntryID + 6), *(rptinfo->m_EntryID + 7));
if (BSTR_BIT_GET(OptFldsData, OPTFLD_BITNUM_CONFREV))
{
// SLOGCALWAYS1("Var# %02d: ConfRev", va_num);
log_var_data(info_va[va_num], &mms_dec_data);
//assert(add_mms_dec_data== (uint32_t)&mms_dec_data);
va_num++;
}
//printf("\n ----1--va_num %d -\n", va_num);
if (BSTR_BIT_GET(OptFldsData, OPTFLD_BITNUM_SUBSEQNUM))
{
// SLOGCALWAYS1("Var# %02d: SubSeqNum", va_num);
log_var_data(info_va[va_num], &mms_dec_data);
//assert(add_mms_dec_data== (uint32_t)&mms_dec_data);
va_num++;
// SLOGCALWAYS1("Var# %02d: MoreSegmentsFollow", va_num);
log_var_data(info_va[va_num], &mms_dec_data);
//assert(add_mms_dec_data== (uint32_t)&mms_dec_data);
va_num++;
}
//printf("\n ----2---va_num %d \n", va_num);
// SLOGCALWAYS1("Var# %02d: Inclusion", va_num);
log_var_data(info_va[va_num], &mms_dec_data);
//assert(add_mms_dec_data== (uint32_t)&mms_dec_data);
va_num++;
/* If data-Ref enabled, check "Inclusion" to figure out what is being received.*/
if (BSTR_BIT_GET(OptFldsData, OPTFLD_BITNUM_DATAREF))
{
for (j = 0; j < rcb_info->numDsVar; ++j)
{
if (BSTR_BIT_GET(InclusionData, j))
{
// SLOGCALWAYS2("Var# %02d: DataRefName# %d", va_num, j);
log_var_data(info_va[va_num], &mms_dec_data);
//assert(add_mms_dec_data== (uint32_t)&mms_dec_data);
va_num++;
}
}
}
//printf("\n ----3---%d \n", va_num);
//rcb_info->numDsVar+1 just to avoid rcb_info->numDsVar==0 ,waste a little memory
DataObjectFullName = apr_pcalloc(g_pt61850app->tmp_pool, (rcb_info->numDsVar + 1) * sizeof(char*));
//RWCStringVec DataName(rcb_info->numDsVar+1);
//RWCStringVec AttrName(rcb_info->numDsVar+1);
//RWTValVector<CDataOMSObject*> pDataOMSObjects(rcb_info->numDsVar+1);
//printf("\n ----4--%d rcb_info->numDsVar %d -\n", va_num, rcb_info->numDsVar);
for (j = 0; j < rcb_info->numDsVar; ++j)
{
if (BSTR_BIT_GET(InclusionData, j))
{
DataObjectFullName[j] = apr_pstrdup(g_pt61850app->tmp_pool, rcb_info->varNameArray[j]->obj_name.vmd_spec);
}
}
//printf("\n ----5--%d-\n", va_num);
// if (g_pt61850app->IsCallEvtDes )
// cout<<"pEquipment->m_OMSObject_FULL_FCDA_Map.entries() = "<<pEquipment->m_OMSObject_FULL_FCDA_Map.entries()<<endl
//assert(0);
if (LD_info->line_id > 0) {
if (strstr(rcb_info->RptID, "QVVR"))//CZY 2023-08-17 WW 2022-11-14 <20>޸<EFBFBD><DEB8>ж<EFBFBD>LLN0$BR$brcbQVVR
processQVVR_start(LD_info);
else if (strstr(rcb_info->RptID, "RDRE"))//CZY 2023-08-17 WW 2022-11-14 <20>޸<EFBFBD><DEB8>ж<EFBFBD>LLN0$BR$brcbRDRE
processRDRE_start(LD_info);
else {
ied_t* ied;
ied = find_ied_from_dev_code(LD_info->terminal_code);
ied_usr_t* ied_usr = (ied_usr_t*)ied->usr_ext;
if (rptinfo->flickerflag==1)//CZY 2023-08-17 WW 2022-11-14 ֻ<><D6BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>͵<EFBFBD>һ<EFBFBD>ν<EFBFBD><CEBD><EFBFBD><EFBFBD>Ż<EFBFBD><C5BB><EFBFBD>ʼ<EFBFBD><CABC> json_block_create_start(LD_info->line_id);
json_block_create_start( LD_info->voltage_level, LD_info->mp_id, rptinfo->flickerflag, ied_usr->dev_type, LD_info->line_id);
else if(rptinfo->flickerflag == 0) {
if (LD_info->rptRecvCheckFlag == 0)
json_block_create_start( LD_info->voltage_level, LD_info->mp_id, rptinfo->flickerflag, ied_usr->dev_type, LD_info->line_id);
LD_info->rptRecvCheckFlag |= 0x01 << rptinfo->rptNo;
}
else if (rptinfo->flickerflag == 2) {
if (LD_info->rptPstRecvCheckFlag == 0)
json_block_create_start(LD_info->voltage_level, LD_info->mp_id, rptinfo->flickerflag, ied_usr->dev_type, LD_info->line_id);
LD_info->rptPstRecvCheckFlag |= 0x01 << rptinfo->rptNo;
}
}
}
/* HERE'S THE DATA. Check "Inclusion" to figure out what is being received.*/
for (j = 0; j < rcb_info->numDsVar; ++j)
{
/*if (rcb_info->numDsVar==13) {
printf("bbbbbbbbbbbbbbbbbbbbbbbbb\n");
}*/
if (BSTR_BIT_GET(InclusionData, j))
{
int ii;
// SLOGCALWAYS3("Var# %02d: DataSet Var# %d: Name=%s", va_num, j,
// rcb_info->varNameArray[j]->obj_name.vmd_spec);
//printf("\n ----5.0--%d-\n", va_num);
log_var_data(info_va[va_num], &mms_dec_data);
//assert(add_mms_dec_data== (uint32_t)&mms_dec_data);
va_num++;
//printf("\n ----5.1--%d-%d\n", va_num,mms_dec_data.item_num);
// if ( !pDataOMSObjects[j] ) continue;
//cout<<endl<<j<<" $ "<<AttrName[j]<<" $ "<<DataName[j]<<" = ";
//cout<<endl<<j<<" "<<DataObjectFullName[j]<<" "<<endl;
// cout<<" mms_dec_data.item_num ="<<(int)mms_dec_data.item_num<<endl;
for (ii = 0; ii < mms_dec_data.item_num; ++ii)
{
char* FULL_FCDA_Name;
int length_FCDA;
//printf("\n ----5.11--%d-%s\n", va_num, mms_dec_data.data_item[ii].comp_name);
if (strcmp(mms_dec_data.data_item[ii].comp_name, "") == 0)
FULL_FCDA_Name = apr_pstrdup(g_pt61850app->tmp_pool, DataObjectFullName[j]);
else
FULL_FCDA_Name = apr_pstrcat(g_pt61850app->tmp_pool, DataObjectFullName[j], "$", mms_dec_data.data_item[ii].comp_name, NULL);
// cout<<" FULL_FCDA_Name "<< FULL_FCDA_Name <<endl;
//printf("\n ----5.12--%d- %s \n", va_num, FULL_FCDA_Name);
length_FCDA = strlen(FULL_FCDA_Name);
//11 08 beijing <20><><EFBFBD><EFBFBD>װ<EFBFBD>ò<EFBFBD><C3B2><EFBFBD><EFBFBD><EFBFBD>q
if (('$' == FULL_FCDA_Name[length_FCDA - 2]) && ('q' == FULL_FCDA_Name[length_FCDA - 1])) {
if (not_set_rpt_q_this) {
int flag = Set_q_from_61850rpt(mms_dec_data.data_item[ii].u.data_str);
if (strstr(rcb_info->RptID, "QVVR")) {//CZY 2023-08-17 WW 2022-11-14 <20>޸<EFBFBD><DEB8>ж<EFBFBD>LLN0$BR$brcbQVVR
//need do nothing!
not_set_rpt_q_this = FALSE;
}
else if (strstr(rcb_info->RptID, "RDRE")) {//CZY 2023-08-17 WW 2022-11-14<31>޸<EFBFBD><DEB8>ж<EFBFBD> LLN0$BR$brcbRDRE
//need do nothing!
not_set_rpt_q_this = FALSE;
}
else {
json_block_create_flag(LD_info->mp_id, flag, rptinfo->flickerflag);
not_set_rpt_q_this = FALSE;
}
}
}
else if (('$' == FULL_FCDA_Name[length_FCDA - 2]) && ('t' == FULL_FCDA_Name[length_FCDA - 1])) {
if (not_set_rpt_TimeID_this) {
apr_time_t t = convert_btime6_to_apr_time(&(mms_dec_data.data_item[ii].u.data_bTime6));
if (strstr(rcb_info->RptID, "QVVR")) {//CZY 2023-08-17 WW 2022-11-14 <20>޸<EFBFBD><DEB8>ж<EFBFBD>LLN0$BR$brcbQVVR
if (strstr(FULL_FCDA_Name, "VarStr$t")) {
processQVVR_time(LD_info, t / 1000);
not_set_rpt_TimeID_this = FALSE;
}
}
else if (strstr(rcb_info->RptID, "RDRE")) {//CZY 2023-08-17 WW 2022-11-14<31>޸<EFBFBD><DEB8>ж<EFBFBD> LLN0$BR$brcbRDRE
//need do nothing!
not_set_rpt_TimeID_this = FALSE;
}
else {
json_block_create_time(LD_info->mp_id, t / 1000, rptinfo->flickerflag);
printf("rcb_info->RptID=%s ,LineId=%d , Timestamp= %lld \n", rcb_info->RptID, LD_info->line_id, t / 1000);
not_set_rpt_TimeID_this = FALSE;
if (strstr(rcb_info->RptID, "LLN0$RP$urcbRealData")) {
//20241223lnk<6E><6B><EFBFBD><EFBFBD><EFBFBD>ն˺Ų<CBBA><C5B2><EFBFBD>
ied_usr_t *ied_usr = GET_IEDEXT_ADDR(ied);
if (urcbRealDataHasReceived(ied_usr->dev_idx,LD_info, t / 1000))
return;
}
}
}
}
else {
double v = 0.0;
if (mms_dec_data.data_item[ii].type == DATA_INT_TYPE)
v = mms_dec_data.data_item[ii].u.data_int;
else if (mms_dec_data.data_item[ii].type == DATA_UINT_TYPE)
v = mms_dec_data.data_item[ii].u.data_uint;
else if (mms_dec_data.data_item[ii].type == DATA_INT64_TYPE)
v = (double)mms_dec_data.data_item[ii].u.data_int64;
else if (mms_dec_data.data_item[ii].type == DATA_UINT64_TYPE)
v = (double)mms_dec_data.data_item[ii].u.data_uint64;
else if (mms_dec_data.data_item[ii].type == DATA_DOUBLE_TYPE)
v = mms_dec_data.data_item[ii].u.data_double;
else if (mms_dec_data.data_item[ii].type == DATA_STR_TYPE)
v = strtol(mms_dec_data.data_item[ii].u.data_str, NULL, 2);
//set_db_value(RPT_IDX,FULL_FCDA_Name,v, is_rpt_Time_exact_hour() );
if (strstr(rcb_info->RptID, "QVVR")) {//CZY 2023-08-17 WW 2022-11-14 <20>޸<EFBFBD><DEB8>ж<EFBFBD>LLN0$BR$brcbQVVR
processQVVR_data(LD_info, FULL_FCDA_Name, v);
}
else if (strstr(rcb_info->RptID, "RDRE")) {//CZY 2023-08-17 WW 2022-11-14 <20>޸<EFBFBD><DEB8>ж<EFBFBD>LLN0$BR$brcbRDRE
processRDRE_data(LD_info, FULL_FCDA_Name, v);
}
else
json_block_create_data(LD_info->mp_id, FULL_FCDA_Name, v, rptinfo->flickerflag);
}//else
}
}
}
if (LD_info->line_id > 0) {
//set_rpt_LineID(LD_info->line_id);
//set_line_info(RPT_IDX,LD_info->line_id,LD_info->SubV_Index,LD_info->Dev_Index,LD_info->Sub_Index,LD_info->GD_Index);
//write_updatetime_to_db(chnl_usr->chnl->addr);
if (strstr(rcb_info->RptID, "QVVR")) {//CZY 2023-08-17 WW 2022-11-14 <20>޸<EFBFBD><DEB8>ж<EFBFBD>LLN0$BR$brcbQVVR
processQVVR_end(LD_info);
}
else if (strstr(rcb_info->RptID, "RDRE")) {//CZY 2023-08-17 WW 2022-11-14 <20>޸<EFBFBD><DEB8>ж<EFBFBD>LLN0$BR$brcbRDRE
processRDRE_end(LD_info);
}
else {
printf("%d : %d", LD_info->rptRecvFlag, LD_info->rptRecvCheckFlag);
//append_db_records(RPT_IDX);
if (rptinfo->flickerflag==1)//CZY 2023-08-17 WW 2022-11-14 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>־
{
//ied_usr_t* ied_usr = ied->usr_ext;//CZY 2023-08-17 WW 2022<32><32>12<31><32>6<EFBFBD><36>14:09:08 <20><><EFBFBD>Ӷ<EFBFBD><D3B6><EFBFBD>ICD֧<44><D6A7>
//int devkind = ied_usr->dev_flag;
2025-02-14 16:44:38 +08:00
json_block_create_end(LD_info->v_wiring_type, LD_info->mp_id, rptinfo->flickerflag); //lnk2024-8-16<31><36><EFBFBD>ӽ<EFBFBD><D3BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ͳ<EFBFBD><CDB2><EFBFBD>
2025-01-16 16:17:01 +08:00
}
else if(rptinfo->flickerflag == 0){//CZY 2023-08-17 WW 2022-11-14 <20><><EFBFBD>Ӷ<EFBFBD><D3B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD>
if (LD_info->rptRecvFlag == LD_info->rptRecvCheckFlag) {
//ied_usr_t* ied_usr = ied->usr_ext;//CZY 2023-08-17 WW 2022<32><32>12<31><32>6<EFBFBD><36>14:09:08 <20><><EFBFBD>Ӷ<EFBFBD><D3B6><EFBFBD>ICD֧<44><D6A7>
//int devkind = ied_usr->dev_flag;
2025-02-14 16:44:38 +08:00
json_block_create_end(LD_info->v_wiring_type, LD_info->mp_id, rptinfo->flickerflag); //lnk2024-8-16<31><36><EFBFBD>ӽ<EFBFBD><D3BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ͳ<EFBFBD><CDB2><EFBFBD>
2025-01-16 16:17:01 +08:00
LD_info->rptRecvCheckFlag = 0;
}
}
else if (rptinfo->flickerflag == 2) {//CZY 2023-08-17 WW 2022-11-14 <20><><EFBFBD>Ӷ<EFBFBD><D3B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD>
if (LD_info->rptPstRecvFlag == LD_info->rptPstRecvCheckFlag) {
//ied_usr_t* ied_usr = ied->usr_ext;//CZY 2023-08-17 WW 2022<32><32>12<31><32>6<EFBFBD><36>14:09:08 <20><><EFBFBD>Ӷ<EFBFBD><D3B6><EFBFBD>ICD֧<44><D6A7>
//int devkind = ied_usr->dev_flag;
2025-02-14 16:44:38 +08:00
json_block_create_end(LD_info->v_wiring_type, LD_info->mp_id, rptinfo->flickerflag); //lnk2024-8-16<31><36><EFBFBD>ӽ<EFBFBD><D3BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ͳ<EFBFBD><CDB2><EFBFBD>
2025-01-16 16:17:01 +08:00
LD_info->rptPstRecvCheckFlag = 0;
}
}
}
}
else {
echo_err3("Ignore this report due to line_id invalid , Report From %s %s %s !!!",
APR_EGENERAL, chnl_usr->ip_str, LD_info->LD_name, rcb_info->RptID);
}
printf("[END Process] Report From %s:%d %s %s ,va_total = %i ,<2C><>count = %i<><69> \n",
chnl_usr->ip_str, chnl_usr->chnl->port, LD_info->LD_name, rcb_info->RptID, va_total, rptinfo->count);
//apr_time_t previousTimeend = apr_time_now();//
//apr_time_exp_t localTimeend;
//apr_time_exp_gmt(&localTimeend, previousTimeend);
//printf("\n ------>>>>>>> end time %d %d:%d:%d.%d \n",
// localTimeend.tm_mday, localTimeend.tm_hour, localTimeend.tm_min, localTimeend.tm_sec, localTimeend.tm_usec);
//printf("\n ----6-%d--\n", va_num);
/* If "reason" enabled, check "Inclusion" to figure out what is being received.*/
if (BSTR_BIT_GET(OptFldsData, OPTFLD_BITNUM_REASON)) {
for (j = 0; j < rcb_info->numDsVar; ++j) {
if (BSTR_BIT_GET(InclusionData, j)) {
// SLOGCALWAYS2("Var# %02d: Reason# %d", va_num, j);
//log_var_data (info_va[va_num],&mms_dec_data);
va_num++;
}
}
}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧʱ<D3A6><EFBFBD><E4A3AC><EFBFBD><EFBFBD>Ƶ<EFBFBD><C6B5><EFBFBD>ٻ<EFBFBD>װ<EFBFBD><D7B0><EFBFBD><EFBFBD><EFBFBD>ƣ<EFBFBD><C6A3><EFBFBD><EFBFBD><EFBFBD><C2B6><EFBFBD> add on Aug 3 for testing of guangdong CRITICAL
chnl_usr->m_LastPosRespTime = sGetMsTime();
//assert (va_num==va_total); /* Did we count right? */
if (va_num != va_total)
echo_err5("va_num!=va_total! Report From %s %s %s , %d!=%d !!!",
APR_EGENERAL, chnl_usr->ip_str, LD_info->LD_name, rcb_info->RptID, va_num, va_total);
}
ST_VOID u_iec_rpt_ind_data(MVL_VAR_ASSOC** info_va,
ST_UINT8* OptFldsData, /* ptr to data part of OptFlds bvstring */
ST_UINT8* InclusionData, /* ptr to Inclusion bstring */
RCB_INFO* rcb_info,
ST_INT va_total,
MVL_NET_INFO* net_info)
{
ST_INT va_num = 0;
ST_INT j;
MMS_DECODE_DATA mms_dec_data;
//uint32_t add_mms_dec_data = &mms_dec_data;
ied_t* ied;
rptinfo_t* rptinfo;
// element_t* pDataOMSObject;
LD_info_t* LD_info;
chnl_usr_t* chnl_usr;
char** DataObjectFullName;
// LD_info_t* LD_info_of_Data;
ST_INT not_set_rpt_TimeID_this;
ST_INT not_set_rpt_q_this;
//printf("Var# %02d: RptId", va_num);
log_var_data(info_va[va_num], &mms_dec_data);
//assert(add_mms_dec_data== (uint32_t)&mms_dec_data);
rptinfo = find_rptinfo_from_net_rcb_info(net_info, rcb_info);
//rptinfo->m_LastDataTime = sGetMsTime();//WW 2023-08-29 ȥ<><C8A5>
LD_info = rptinfo->LD_info;
chnl_usr = net_info->user_ext;
ied = chnl_usr->chnl->ied;
not_set_rpt_TimeID_this = TRUE;
not_set_rpt_q_this = TRUE;
//g_db_inf_clear_data(RPT_IDX);
rptinfo->count++;
printf("[BEGIND Process] Received Report From %s:%d %s %s ,va_total = %i ,<2C><>count = %i<><69> mp_id=%s\n",
chnl_usr->ip_str, chnl_usr->chnl->port, LD_info->LD_name, rcb_info->RptID, va_total, rptinfo->count, LD_info->mp_id);
//apr_time_t previousTime = apr_time_now();//
//apr_time_exp_t localTime;
//apr_time_exp_gmt(&localTime, previousTime);
//printf("\n ------>>>>>>> begind time %d %d:%d:%d.%d \n",
// localTime.tm_mday, localTime.tm_hour, localTime.tm_min, localTime.tm_sec, localTime.tm_usec);
va_num++;
// SLOGCALWAYS1("Var# %02d: OptFlds", va_num);
log_var_data(info_va[va_num], &mms_dec_data);
//assert(add_mms_dec_data== (uint32_t)&mms_dec_data);
va_num++;
/* NOTE: Don't change initial entries in "info_va". Add these right after "OptFlds".*/
if (BSTR_BIT_GET(OptFldsData, OPTFLD_BITNUM_SQNUM))
{
// SLOGCALWAYS1("Var# %02d: SqNum", va_num);
log_var_data(info_va[va_num], &mms_dec_data);
//assert(add_mms_dec_data== (uint32_t)&mms_dec_data);
printf("\n ------>>>>>>> SqNum received in Report From %s %s %s ,SqNum = %d \n",
chnl_usr->ip_str, LD_info->LD_name, rcb_info->RptID, mms_dec_data.data_item[0].u.data_uint);
va_num++;
}
if (BSTR_BIT_GET(OptFldsData, OPTFLD_BITNUM_TIMESTAMP))
{
// SLOGCALWAYS1("Var# %02d: TimeOfEntry", va_num);
log_var_data(info_va[va_num], &mms_dec_data);
//assert(add_mms_dec_data== (uint32_t)&mms_dec_data);
va_num++;
//set_rpt_TimeID(convert_btime6_to_apr_time(&(mms_dec_data.data_item[0].u.data_bTime6)) );
}
if (BSTR_BIT_GET(OptFldsData, OPTFLD_BITNUM_DATSETNAME))
{
// SLOGCALWAYS1("Var# %02d: DatSetNa", va_num);
log_var_data(info_va[va_num], &mms_dec_data);
//assert(add_mms_dec_data== (uint32_t)&mms_dec_data);
va_num++;
}
if (BSTR_BIT_GET(OptFldsData, OPTFLD_BITNUM_BUFOVFL))
{
// SLOGCALWAYS1("Var# %02d: BufOvfl", va_num);
log_var_data(info_va[va_num], &mms_dec_data);
//assert(add_mms_dec_data== (uint32_t)&mms_dec_data);
va_num++;
}
if (BSTR_BIT_GET(OptFldsData, OPTFLD_BITNUM_ENTRYID))
{
char* EntryIDStr;
int i;
log_var_data(info_va[va_num], &mms_dec_data);
//assert(add_mms_dec_data== (uint32_t)&mms_dec_data);
EntryIDStr = mms_dec_data.data_item[0].u.data_str;
printf("\n ------>>>>>>> EntryID received in Report From %s %s %s ,EntryID = %s\n\n\n",
chnl_usr->ip_str, LD_info->LD_name, rcb_info->RptID, EntryIDStr);
for (i = 0; i < 8; i++) {
EntryIDStr[2] = '\0';
rptinfo->m_EntryID[i] = (byte_t)strtol(EntryIDStr, NULL, 16);
EntryIDStr += 3; //skip a blank
}
va_num++;
}
printf("\n -------------rptinfo->m_EntryID %02x %02x %02x %02x %02x %02x %02x %02x -------- EntryID\n\n\n",
*rptinfo->m_EntryID, *(rptinfo->m_EntryID + 1), *(rptinfo->m_EntryID + 2),
*(rptinfo->m_EntryID + 3), *(rptinfo->m_EntryID + 4), *(rptinfo->m_EntryID + 5),
*(rptinfo->m_EntryID + 6), *(rptinfo->m_EntryID + 7));
if (BSTR_BIT_GET(OptFldsData, OPTFLD_BITNUM_CONFREV))
{
// SLOGCALWAYS1("Var# %02d: ConfRev", va_num);
log_var_data(info_va[va_num], &mms_dec_data);
//assert(add_mms_dec_data== (uint32_t)&mms_dec_data);
va_num++;
}
//printf("\n ----1--va_num %d -\n", va_num);
if (BSTR_BIT_GET(OptFldsData, OPTFLD_BITNUM_SUBSEQNUM))
{
// SLOGCALWAYS1("Var# %02d: SubSeqNum", va_num);
log_var_data(info_va[va_num], &mms_dec_data);
//assert(add_mms_dec_data== (uint32_t)&mms_dec_data);
va_num++;
// SLOGCALWAYS1("Var# %02d: MoreSegmentsFollow", va_num);
log_var_data(info_va[va_num], &mms_dec_data);
//assert(add_mms_dec_data== (uint32_t)&mms_dec_data);
va_num++;
}
//printf("\n ----2---va_num %d \n", va_num);
// SLOGCALWAYS1("Var# %02d: Inclusion", va_num);
log_var_data(info_va[va_num], &mms_dec_data);
//assert(add_mms_dec_data== (uint32_t)&mms_dec_data);
va_num++;
/* If data-Ref enabled, check "Inclusion" to figure out what is being received.*/
if (BSTR_BIT_GET(OptFldsData, OPTFLD_BITNUM_DATAREF))
{
for (j = 0; j < rcb_info->numDsVar; ++j)
{
if (BSTR_BIT_GET(InclusionData, j))
{
// SLOGCALWAYS2("Var# %02d: DataRefName# %d", va_num, j);
log_var_data(info_va[va_num], &mms_dec_data);
//assert(add_mms_dec_data== (uint32_t)&mms_dec_data);
va_num++;
}
}
}
//printf("\n ----3---%d \n", va_num);
//rcb_info->numDsVar+1 just to avoid rcb_info->numDsVar==0 ,waste a little memory
DataObjectFullName = apr_pcalloc(g_pt61850app->tmp_pool, (rcb_info->numDsVar + 1) * sizeof(char*));
//RWCStringVec DataName(rcb_info->numDsVar+1);
//RWCStringVec AttrName(rcb_info->numDsVar+1);
//RWTValVector<CDataOMSObject*> pDataOMSObjects(rcb_info->numDsVar+1);
//printf("\n ----4--%d rcb_info->numDsVar %d -\n", va_num, rcb_info->numDsVar);
for (j = 0; j < rcb_info->numDsVar; ++j)
{
if (BSTR_BIT_GET(InclusionData, j))
{
DataObjectFullName[j] = apr_pstrdup(g_pt61850app->tmp_pool, rcb_info->varNameArray[j]->obj_name.vmd_spec);
}
}
//printf("\n ----5--%d-\n", va_num);
// if (g_pt61850app->IsCallEvtDes )
// cout<<"pEquipment->m_OMSObject_FULL_FCDA_Map.entries() = "<<pEquipment->m_OMSObject_FULL_FCDA_Map.entries()<<endl
//assert(0);
if (LD_info->line_id > 0) {
if (strstr(rcb_info->RptID, "QVVR"))//CZY 2023-08-17 WW 2022-11-14 <20>޸<EFBFBD><DEB8>ж<EFBFBD>LLN0$BR$brcbQVVR
processQVVR_start(LD_info);//<2F><><EFBFBD>͵ı<CDB5><C4B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
else if (strstr(rcb_info->RptID, "RDRE"))//CZY 2023-08-17 WW 2022-11-14 <20>޸<EFBFBD><DEB8>ж<EFBFBD>LLN0$BR$brcbRDRE
processRDRE_start(LD_info);
else {
ied_t* ied;
ied = find_ied_from_dev_code(LD_info->terminal_code);
ied_usr_t* ied_usr = (ied_usr_t*)ied->usr_ext;
if (rptinfo->flickerflag == 1)//CZY 2023-08-17 WW 2022-11-14 ֻ<><D6BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>͵<EFBFBD>һ<EFBFBD>ν<EFBFBD><CEBD><EFBFBD><EFBFBD>Ż<EFBFBD><C5BB><EFBFBD>ʼ<EFBFBD><CABC> json_block_create_start(LD_info->line_id);
json_block_create_start(LD_info->voltage_level, LD_info->mp_id, rptinfo->flickerflag, ied_usr->dev_type, LD_info->line_id);
else if (rptinfo->flickerflag == 0) {
if (LD_info->rptRecvCheckFlag == 0)
json_block_create_start(LD_info->voltage_level, LD_info->mp_id, rptinfo->flickerflag, ied_usr->dev_type, LD_info->line_id);
LD_info->rptRecvCheckFlag |= 0x01 << rptinfo->rptNo;
}
else if (rptinfo->flickerflag == 2) {
if (LD_info->rptPstRecvCheckFlag == 0)
json_block_create_start(LD_info->voltage_level, LD_info->mp_id, rptinfo->flickerflag, ied_usr->dev_type, LD_info->line_id);
LD_info->rptPstRecvCheckFlag |= 0x01 << rptinfo->rptNo;
}
}
}
/* HERE'S THE DATA. Check "Inclusion" to figure out what is being received.*/
for (j = 0; j < rcb_info->numDsVar; ++j)
{
/*if (rcb_info->numDsVar==13) {
printf("bbbbbbbbbbbbbbbbbbbbbbbbb\n");
}*/
if (BSTR_BIT_GET(InclusionData, j))
{
int ii;
// SLOGCALWAYS3("Var# %02d: DataSet Var# %d: Name=%s", va_num, j,
// rcb_info->varNameArray[j]->obj_name.vmd_spec);
//printf("\n ----5.0--%d-\n", va_num);
log_var_data(info_va[va_num], &mms_dec_data);
//assert(add_mms_dec_data== (uint32_t)&mms_dec_data);
va_num++;
//printf("\n ----5.1--%d-%d\n", va_num,mms_dec_data.item_num);
// if ( !pDataOMSObjects[j] ) continue;
//cout<<endl<<j<<" $ "<<AttrName[j]<<" $ "<<DataName[j]<<" = ";
//cout<<endl<<j<<" "<<DataObjectFullName[j]<<" "<<endl;
// cout<<" mms_dec_data.item_num ="<<(int)mms_dec_data.item_num<<endl;
long long time;
for (ii = 0; ii < mms_dec_data.item_num; ++ii)
{
char* FULL_FCDA_Name;
int length_FCDA;
if (strcmp(mms_dec_data.data_item[ii].comp_name, "") == 0)
FULL_FCDA_Name = apr_pstrdup(g_pt61850app->tmp_pool, DataObjectFullName[j]);
else
FULL_FCDA_Name = apr_pstrcat(g_pt61850app->tmp_pool, DataObjectFullName[j], "$", mms_dec_data.data_item[ii].comp_name, NULL);
length_FCDA = strlen(FULL_FCDA_Name);
if (('$' == FULL_FCDA_Name[length_FCDA - 2]) && ('t' == FULL_FCDA_Name[length_FCDA - 1]))
{
apr_time_t t = convert_btime6_to_apr_time(&(mms_dec_data.data_item[ii].u.data_bTime6));
time = t / 1000;
break;
}
}
for (ii = 0; ii < mms_dec_data.item_num; ++ii)//<2F><><EFBFBD><EFBFBD>FCDA
{
char* FULL_FCDA_Name;
int length_FCDA;
//printf("\n ----5.11--%d-%s\n", va_num, mms_dec_data.data_item[ii].comp_name);
if (strcmp(mms_dec_data.data_item[ii].comp_name, "") == 0)
FULL_FCDA_Name = apr_pstrdup(g_pt61850app->tmp_pool, DataObjectFullName[j]);
else
FULL_FCDA_Name = apr_pstrcat(g_pt61850app->tmp_pool, DataObjectFullName[j], "$", mms_dec_data.data_item[ii].comp_name, NULL);
// cout<<" FULL_FCDA_Name "<< FULL_FCDA_Name <<endl;
//printf("\n ----5.12--%d- %s \n", va_num, FULL_FCDA_Name);
length_FCDA = strlen(FULL_FCDA_Name);
//11 08 beijing <20><><EFBFBD><EFBFBD>װ<EFBFBD>ò<EFBFBD><C3B2><EFBFBD><EFBFBD><EFBFBD>q
if (('$' == FULL_FCDA_Name[length_FCDA - 2]) && ('q' == FULL_FCDA_Name[length_FCDA - 1])) {
if (not_set_rpt_q_this) {
int flag = Set_q_from_61850rpt(mms_dec_data.data_item[ii].u.data_str);
if (strstr(rcb_info->RptID, "QVVR")) {//CZY 2023-08-17 WW 2022-11-14 <20>޸<EFBFBD><DEB8>ж<EFBFBD>LLN0$BR$brcbQVVR
//need do nothing!
not_set_rpt_q_this = FALSE;
}
else if (strstr(rcb_info->RptID, "RDRE")) {//CZY 2023-08-17 WW 2022-11-14<31>޸<EFBFBD><DEB8>ж<EFBFBD> LLN0$BR$brcbRDRE
//need do nothing!
not_set_rpt_q_this = FALSE;
}
else if (strstr(FULL_FCDA_Name, "GGIO"))
{
not_set_rpt_q_this = FALSE;
}
else {
json_block_create_flag(LD_info->mp_id, flag, rptinfo->flickerflag);
not_set_rpt_q_this = FALSE;
}
}
}
else if (('$' == FULL_FCDA_Name[length_FCDA - 2]) && ('t' == FULL_FCDA_Name[length_FCDA - 1])) {
if (not_set_rpt_TimeID_this) {
apr_time_t t = convert_btime6_to_apr_time(&(mms_dec_data.data_item[ii].u.data_bTime6));
if (strstr(rcb_info->RptID, "QVVR")) {//CZY 2023-08-17 WW 2022-11-14 <20>޸<EFBFBD><DEB8>ж<EFBFBD>LLN0$BR$brcbQVVR
if (strstr(FULL_FCDA_Name, "VarStr$t")) {
processQVVR_time(LD_info, t / 1000);
not_set_rpt_TimeID_this = FALSE;
}
}
else if (strstr(rcb_info->RptID, "RDRE")) {//CZY 2023-08-17 WW 2022-11-14<31>޸<EFBFBD><DEB8>ж<EFBFBD> LLN0$BR$brcbRDRE
//need do nothing!
not_set_rpt_TimeID_this = FALSE;
}
else if (strstr(FULL_FCDA_Name, "GGIO")) {//CZY 2023-08-17 WW 2022-11-14<31>޸<EFBFBD><DEB8>ж<EFBFBD> LLN0$BR$brcbRDRE
//need do nothing!
not_set_rpt_TimeID_this = FALSE;
}
else {
json_block_create_time(LD_info->mp_id, t / 1000, rptinfo->flickerflag);
printf("rcb_info->RptID=%s ,LineId=%d , Timestamp= %lld \n", rcb_info->RptID, LD_info->line_id, t / 1000);
not_set_rpt_TimeID_this = FALSE;
if (strstr(rcb_info->RptID, "LLN0$RP$urcbRealData")) {
//20241223lnk<6E><6B><EFBFBD><EFBFBD><EFBFBD>ն˺Ų<CBBA><C5B2><EFBFBD>
ied_usr_t *ied_usr = GET_IEDEXT_ADDR(ied);
if (urcbRealDataHasReceived(ied_usr->dev_idx,LD_info, t / 1000))//<2F>ж<EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD>ظ<EFBFBD>
return;
}
}
}
}
else {
double v = 0.0;
if (mms_dec_data.data_item[ii].type == DATA_INT_TYPE)
v = mms_dec_data.data_item[ii].u.data_int;
else if (mms_dec_data.data_item[ii].type == DATA_UINT_TYPE)
v = mms_dec_data.data_item[ii].u.data_uint;
else if (mms_dec_data.data_item[ii].type == DATA_INT64_TYPE)
v = (double)mms_dec_data.data_item[ii].u.data_int64;
else if (mms_dec_data.data_item[ii].type == DATA_UINT64_TYPE)
v = (double)mms_dec_data.data_item[ii].u.data_uint64;
else if (mms_dec_data.data_item[ii].type == DATA_DOUBLE_TYPE)
v = mms_dec_data.data_item[ii].u.data_double;
else if (mms_dec_data.data_item[ii].type == DATA_STR_TYPE)
v = strtol(mms_dec_data.data_item[ii].u.data_str, NULL, 2);
//set_db_value(RPT_IDX,FULL_FCDA_Name,v, is_rpt_Time_exact_hour() );
if (strstr(rcb_info->RptID, "QVVR")) {//CZY 2023-08-17 WW 2022-11-14 <20>޸<EFBFBD><DEB8>ж<EFBFBD>LLN0$BR$brcbQVVR
processQVVR_data(LD_info, FULL_FCDA_Name, v);
}
else if (strstr(rcb_info->RptID, "RDRE")) {//CZY 2023-08-17 WW 2022-11-14 <20>޸<EFBFBD><DEB8>ж<EFBFBD>LLN0$BR$brcbRDRE
processRDRE_data(LD_info, FULL_FCDA_Name, v);
}
else if (strstr(FULL_FCDA_Name, "GGIO"))
{
ied_t* ied = LD_info->ied;
ied_usr_t* ied_usr = GET_IEDEXT_ADDR(ied);
processGGIO_start_data_end(LD_info->mp_id, FULL_FCDA_Name, v, time, ied_usr->dev_type, LD_info->line_id);//GGIO<49><4F><EFBFBD><EFBFBD>ȫ<EFBFBD>״<EFBFBD><D7B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
}
else
json_block_create_data(LD_info->mp_id, FULL_FCDA_Name, v, rptinfo->flickerflag);
}//else
}
}
}
if (LD_info->line_id > 0) {
//set_rpt_LineID(LD_info->line_id);
//set_line_info(RPT_IDX,LD_info->line_id,LD_info->SubV_Index,LD_info->Dev_Index,LD_info->Sub_Index,LD_info->GD_Index);
//write_updatetime_to_db(chnl_usr->chnl->addr);
if (strstr(rcb_info->RptID, "QVVR")) {//CZY 2023-08-17 WW 2022-11-14 <20>޸<EFBFBD><DEB8>ж<EFBFBD>LLN0$BR$brcbQVVR
processQVVR_end(LD_info);
}
else if (strstr(rcb_info->RptID, "RDRE")) {//CZY 2023-08-17 WW 2022-11-14 <20>޸<EFBFBD><DEB8>ж<EFBFBD>LLN0$BR$brcbRDRE
processRDRE_end(LD_info);
}
else {
printf("%d : %d", LD_info->rptRecvFlag, LD_info->rptRecvCheckFlag);
//append_db_records(RPT_IDX);
if (rptinfo->flickerflag == 1)//CZY 2023-08-17 WW 2022-11-14 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>־
{
//ied_usr_t* ied_usr = ied->usr_ext;//CZY 2023-08-17 WW 2022<32><32>12<31><32>6<EFBFBD><36>14:09:08 <20><><EFBFBD>Ӷ<EFBFBD><D3B6><EFBFBD>ICD֧<44><D6A7>
//int devkind = ied_usr->dev_flag;
2025-02-14 16:44:38 +08:00
json_block_create_end(LD_info->v_wiring_type, LD_info->mp_id, rptinfo->flickerflag);//lnk<6E><6B><EFBFBD>δ<EFBFBD><CEB4><EFBFBD>
2025-01-16 16:17:01 +08:00
}
else if (rptinfo->flickerflag == 0) {//CZY 2023-08-17 WW 2022-11-14 <20><><EFBFBD>Ӷ<EFBFBD><D3B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD>
if (LD_info->rptRecvFlag == LD_info->rptRecvCheckFlag) {
//ied_usr_t* ied_usr = ied->usr_ext;//CZY 2023-08-17 WW 2022<32><32>12<31><32>6<EFBFBD><36>14:09:08 <20><><EFBFBD>Ӷ<EFBFBD><D3B6><EFBFBD>ICD֧<44><D6A7>
//int devkind = ied_usr->dev_flag;
2025-02-14 16:44:38 +08:00
json_block_create_end(LD_info->v_wiring_type, LD_info->mp_id, rptinfo->flickerflag);//lnk<6E><6B><EFBFBD>δ<EFBFBD><CEB4><EFBFBD>
2025-01-16 16:17:01 +08:00
LD_info->rptRecvCheckFlag = 0;
}
}
else if (rptinfo->flickerflag == 2) {//CZY 2023-08-17 WW 2022-11-14 <20><><EFBFBD>Ӷ<EFBFBD><D3B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD>
if (LD_info->rptPstRecvFlag == LD_info->rptPstRecvCheckFlag) {
//ied_usr_t* ied_usr = ied->usr_ext;//CZY 2023-08-17 WW 2022<32><32>12<31><32>6<EFBFBD><36>14:09:08 <20><><EFBFBD>Ӷ<EFBFBD><D3B6><EFBFBD>ICD֧<44><D6A7>
//int devkind = ied_usr->dev_flag;
2025-02-14 16:44:38 +08:00
json_block_create_end(LD_info->v_wiring_type, LD_info->mp_id, rptinfo->flickerflag);//lnk<6E><6B><EFBFBD>δ<EFBFBD><CEB4><EFBFBD>
2025-01-16 16:17:01 +08:00
LD_info->rptPstRecvCheckFlag = 0;
}
}
}
}
else {
echo_err3("Ignore this report due to line_id invalid , Report From %s %s %s !!!",
APR_EGENERAL, chnl_usr->ip_str, LD_info->LD_name, rcb_info->RptID);
}
printf("[END Process] Report From %s:%d %s %s ,va_total = %i ,<2C><>count = %i<><69> \n",
chnl_usr->ip_str, chnl_usr->chnl->port, LD_info->LD_name, rcb_info->RptID, va_total, rptinfo->count);
//apr_time_t previousTimeend = apr_time_now();//
//apr_time_exp_t localTimeend;
//apr_time_exp_gmt(&localTimeend, previousTimeend);
//printf("\n ------>>>>>>> end time %d %d:%d:%d.%d \n",
// localTimeend.tm_mday, localTimeend.tm_hour, localTimeend.tm_min, localTimeend.tm_sec, localTimeend.tm_usec);
//printf("\n ----6-%d--\n", va_num);
/* If "reason" enabled, check "Inclusion" to figure out what is being received.*/
if (BSTR_BIT_GET(OptFldsData, OPTFLD_BITNUM_REASON)) {
for (j = 0; j < rcb_info->numDsVar; ++j) {
if (BSTR_BIT_GET(InclusionData, j)) {
// SLOGCALWAYS2("Var# %02d: Reason# %d", va_num, j);
//log_var_data (info_va[va_num],&mms_dec_data);
va_num++;
}
}
}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧʱ<D3A6><EFBFBD><E4A3AC><EFBFBD><EFBFBD>Ƶ<EFBFBD><C6B5><EFBFBD>ٻ<EFBFBD>װ<EFBFBD><D7B0><EFBFBD><EFBFBD><EFBFBD>ƣ<EFBFBD><C6A3><EFBFBD><EFBFBD><EFBFBD><C2B6><EFBFBD> add on Aug 3 for testing of guangdong CRITICAL
chnl_usr->m_LastPosRespTime = sGetMsTime();
//assert (va_num==va_total); /* Did we count right? */
if (va_num != va_total)
echo_err5("va_num!=va_total! Report From %s %s %s , %d!=%d !!!",
APR_EGENERAL, chnl_usr->ip_str, LD_info->LD_name, rcb_info->RptID, va_num, va_total);
}
/************************************************************************/
/* object_name_clone_create */
/* Create clone of OBJECT_NAME struct. Can't just copy struct because */
/* struct contains pointers to strings. */
/* The function "object_name_clone_destroy" should be called to destroy */
/* the clone. */
/************************************************************************/
OBJECT_NAME* object_name_clone_create(OBJECT_NAME* srcobj)
{
OBJECT_NAME* dstobj;
size_t extended_size;
ST_CHAR* extended_ptr;
/* Allocate OBJECT_NAME structure plus extra room for additional data.
* This effectively combines 3 allocations into one.
* Set pointers in OBJECT_NAME structure to point into the extra space.
*/
extended_size = sizeof(OBJECT_NAME)
+ MAX_IDENT_LEN + 1 /* dstobj->obj_name.vmd_spec */
+ MAX_IDENT_LEN + 1; /* dstobj->domain_id */
dstobj = (OBJECT_NAME*)chk_malloc(extended_size);
/* Copy old struct to new struct (before setting ptrs in new struct). */
memcpy(dstobj, srcobj, sizeof(OBJECT_NAME));
/* Fix ptrs to strings in new struct */
extended_ptr = (ST_CHAR*)(dstobj + 1); /* point after dstobj struct */
dstobj->obj_name.vmd_spec = extended_ptr;
extended_ptr += (MAX_IDENT_LEN + 1); /* point after dstobj->obj_name.vmd_spec*/
dstobj->domain_id = extended_ptr;
/* Copy strings to the new struct. */
strcpy(dstobj->obj_name.vmd_spec, srcobj->obj_name.vmd_spec);
if (dstobj->object_tag == DOM_SPEC)
strcpy(dstobj->domain_id, srcobj->domain_id);
return (dstobj);
}
/************************************************************************/
/* object_name_clone_destroy */
/* Destroy OBJECT_NAME clone created by "object_name_clone_create". */
/************************************************************************/
ST_VOID object_name_clone_destroy(OBJECT_NAME* obj)
{
/* allocated by object_name_clone_create using chk_malloc, so use chk_free.*/
chk_free(obj);
}
ST_RET check_va_count_too_big(ST_INT va_current_count, ST_INT va_total)
{
if (va_current_count < va_total) {
return SD_SUCCESS;
}
else {
echo_warn1("report va total %d is so small,may be error\n", va_total);
return SD_FAILURE;
}
}
/************************************************************************/
/* u_iec_rpt_ind */
/* This function processes ONLY IEC-61850 and UCA Reports. If any */
/* other InformationReport is received, it logs an error message and */
/* ignores it. */
/* CRITICAL: this function assumes that a pointer to an ALL_RCB_INFO */
/* structure has been saved in the */
/* user_info member of the MVL_NET_INFO structure for this conn. */
/************************************************************************/
ST_RET u_iec_rpt_ind_by_devtype(MVL_COMM_EVENT* event)
{
INFO_REQ_INFO* info_ptr;
ST_INT j, va_num, va_total;
VAR_ACC_SPEC* va_spec;
MVL_VAR_ASSOC** info_va;
RCB_INFO* rcb_info;
ST_UINT8* OptFldsData; /* ptr to data part of OptFlds bvstring */
ST_UINT8* InclusionData; /* ptr to Inclusion bstring */
ST_CHAR saveRptID[66];
ALL_RCB_INFO* all_rcb_info;
ST_RET retcode = SD_SUCCESS;
info_ptr = (INFO_REQ_INFO*)event->u.mms.dec_rslt.data_ptr;
va_spec = &info_ptr->va_spec;
va_total = info_ptr->num_of_acc_result;
/* An IEC-61850 or UCA report must be a NamedVariableList named "RPT".
* Ignore any other InformationReport.
*/
if (va_spec->var_acc_tag != VAR_ACC_NAMEDLIST
|| strcmp(va_spec->vl_name.obj_name.vmd_spec, "RPT") != 0)
{
echo_warn("Received InformationReport is not a IEC-61850 Report or UCA Report. Ignored.");
return (SD_FAILURE);
}
//////////////////
//WW 2023-08-29 <20><><EFBFBD><EFBFBD><EFBFBD>ն<EFBFBD><D5B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EBB1A8>rcb_info<66>󶨴<EFBFBD><F3B6A8B4><EFBFBD>
int port; //<2F>˿<EFBFBD>
RCB_INFO *rcb_info1;
ST_CHAR rptID[MVL61850_MAX_RPTID_LEN + 1] = { 0 }; //<2F><><EFBFBD><EFBFBD>ID 66
ST_ULONG a_ip = get_rem_ip_addr_inline(event->net_info->acse_conn_id, &port); //WW 2023-08-29 <20><>ȡװ<C8A1><D7B0>IP<49><50><EFBFBD>˿ں<CBBF>
ST_CHAR *p_ip = _convert_ip_2_char(htonl(a_ip)); //WW 2023-08-29 <20><>IPתΪ<D7AA>ַ<EFBFBD><D6B7><EFBFBD>ָ<EFBFBD><D6B8> <20><><EFBFBD><EFBFBD>192.168.1.238
if (gDev_rcb_list.dev_rcb_info_Head == NULL) //ȫ<>ֱ<EFBFBD><D6B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƿ<EFBFBD>ָ<EFBFBD><D6B8> || gDev_rcb_list->rcb_info_list == NULL
{
//SLOGALWAYS0 ("Received InformationReport. No IEC-61850 or UCA RCB enabled. Ignored.");
//LOG_INFO("<22>յ<EFBFBD><D5B5><EFBFBD><EFBFBD>棬δ<E6A3AC><CEB4><EFBFBD><EFBFBD>IEC-61850<35><30>UCA RCBʹ<42>ܡ<EFBFBD><DCA1><EFBFBD><EFBFBD>ԣ<EFBFBD>"); //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD>ã<EFBFBD> zl 2019-1-23 09:10:39
return (SD_FAILURE);
}
//<2F>߼<EFBFBD><DFBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>װ<EFBFBD><D7B0>IP<49><50><EFBFBD>˿ںţ<DABA><C5A3><EFBFBD><EFBFBD>ҵ<EFBFBD>װ<EFBFBD><D7B0><EFBFBD><EFBFBD><EFBFBD>ͣ<EFBFBD><CDA3><EFBFBD>ƥ<EFBFBD><EFBFBD><E4B1A8><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2><EFBFBD>ٽ<EFBFBD><D9BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>棡2019-12-24 17:27:29
//װ<><D7B0><EFBFBD><EFBFBD><EFBFBD>Ͳ<EFBFBD><CDB2><EFBFBD><EFBFBD>ж<EFBFBD>------------------------------------------------------------------------------------------------------------------------------
Dev_RCB_INFO *dev_rcb = NULL;//װ<>ñ<EFBFBD><C3B1><EFBFBD><EFBFBD>ṹָ<E1B9B9><D6B8>
Dev_IP_Port_INFO *dev_info = NULL; //װ<><D7B0>IP<49><50><EFBFBD>˿ںŽṹָ<E1B9B9><D6B8>
ST_BOOLEAN bFindIpPort = 0; //<2F>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƥ<EFBFBD>䵽װ<E4B5BD><D7B0>IP<49><50><EFBFBD>˿ں<CBBF>
for (dev_rcb = gDev_rcb_list.dev_rcb_info_Head; dev_rcb != NULL; dev_rcb = (Dev_RCB_INFO *)list_get_next(gDev_rcb_list.dev_rcb_info_Head, dev_rcb)) //<2F>ٱ<EFBFBD><D9B1><EFBFBD> ȫ<><C8AB>װ<EFBFBD>ñ<EFBFBD><C3B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƿ<EFBFBD><C6BF><EFBFBD><EFBFBD><EFBFBD>
{
//LOG_INFO("(<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)<29><><EFBFBD><EFBFBD>gDev_rcb_list<73><74><EFBFBD><EFBFBD>, dev_type_name= %s", dev_rcb->dev_type_name); //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD>ã<EFBFBD> zl 2019-12-24 00:16:31
//װ<><D7B0>IP<49><50><EFBFBD>˿ںŲ<DABA><C5B2><EFBFBD><EFBFBD>ж<EFBFBD>-------------------------------------------------------------------------------------------------------------------------------------------------------------------
for (dev_info = dev_rcb->dev_ip_port_list; dev_info != NULL; dev_info = (Dev_IP_Port_INFO *)list_get_next(dev_rcb->dev_ip_port_list, dev_info)) //<2F>ڱ<EFBFBD><DAB1><EFBFBD> ȫ<><C8AB>װ<EFBFBD><D7B0>IP<49><50><EFBFBD>˿<EFBFBD><CBBF><EFBFBD><EFBFBD><EFBFBD>
{
//LOG_INFO("(<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)<29><><EFBFBD><EFBFBD>dev_ip_port_list<73><74><EFBFBD><EFBFBD>, dev_type_name= %s, ip= %s, port= %d", dev_rcb->dev_type_name, dev_info->IP, dev_info->Port); //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD>ã<EFBFBD> zl 2019-12-24 00:16:31
if ((strcmp(dev_info->IP, p_ip) == 0) && (dev_info->Port == port)) //ƥ<><C6A5> װ<><D7B0>IP && <20>˿ں<CBBF>
{
bFindIpPort = 1; //<2F><><EFBFBD>ҵ<EFBFBD>װ<EFBFBD><D7B0>IP && <20>˿ں<CBBF>
//LOG_INFO("(<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><>䵽װ<E4B5BD><D7B0>dev_type_name= %s, IP= %s<><73>Port= %d", dev_rcb->dev_type_name, dev_info->IP, dev_info->Port); //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD>ã<EFBFBD> zl 2019-12-24 00:23:55
//strcpy(dev_rcb->dev_type_name, dev_rcb->dev_type_name); //ƥ<><C6A5> װ<><D7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
break;
}
} //<2F><><EFBFBD><EFBFBD> װ<><D7B0>IP<49><50><EFBFBD>˿<EFBFBD><CBBF><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
if (bFindIpPort) //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƥ<EFBFBD>䵽װ<E4B5BD><D7B0>IP<49><50><EFBFBD>˿ں<CBBF>
break;
} //<2F><><EFBFBD><EFBFBD> ȫ<><C8AB>װ<EFBFBD>ñ<EFBFBD><C3B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƿ<EFBFBD><C6BF><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
if (!bFindIpPort) //δ<><CEB4><EFBFBD>ҵ<EFBFBD>װ<EFBFBD><D7B0>IP<49><50><EFBFBD>˿<EFBFBD>
{
//LOG_INFO("(<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)dev_type_name= %sδƥ<CEB4>䵽IP= %s<><73>Port= %d<><64>װ<EFBFBD><D7B0><EFBFBD><EFBFBD><EFBFBD>ͣ<EFBFBD>goto CLEANUP<55><50><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", dev_rcb->dev_type_name, p_ip, port); //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD>ã<EFBFBD> zl 2019-12-24 00:23:55
retcode = SD_FAILURE;
goto END; //<2F><>ת<EFBFBD><D7AA> CLEANUP<55><50><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>retcode<64><65><EFBFBD><EFBFBD>
}
rcb_info = dev_rcb->rcb_info_list; //<2F><><EFBFBD><EFBFBD>װ<EFBFBD><D7B0><EFBFBD><EFBFBD><EFBFBD>ͣ<EFBFBD>ƥ<EFBFBD><EFBFBD><E4B1A8><EFBFBD><EFBFBD><EFBFBD>ƿ<EFBFBD><C6BF><EFBFBD>Ϣ
//WW 2023-08-29 end
//////////////////////////////
/* Get "all_rcb_info" from "user_info". User must set "user_info" when conn established.*/
//////////////////////
//WW 2023-08-29ע<39><D7A2>
//all_rcb_info = (ALL_RCB_INFO*)event->net_info->user_info;
///* Check "all_rcb_info" to see if any RCB has been enabled. */
//if (all_rcb_info == NULL || all_rcb_info->rcb_info_list == NULL)
//{
// echo_warn("Received InformationReport. No IEC-61850 or UCA RCB enabled. Ignored.");
// return (SD_FAILURE);
//}
//WW 2023-08-29 end
////////////////////////
/* Create array of (MVL_VAR_ASSOC *) needed for converting the received
* data to local format.
* Use variables created earlier to fill in the array. These variables will
* hold the decoded data.
* NOTE: any return after this must free info_va (see CLEANUP label).
*/
info_va = (MVL_VAR_ASSOC**)chk_calloc(va_total,
sizeof(MVL_VAR_ASSOC*));
//////////////////
//WW 2023-08-29 <20><><EFBFBD><EFBFBD><EFBFBD>ն<EFBFBD><D5B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EBB1A8>rcb_info<66>󶨴<EFBFBD><F3B6A8B4><EFBFBD>
rcb_info = dev_rcb->rcb_info_list; //<2F><><EFBFBD><EFBFBD>װ<EFBFBD><D7B0><EFBFBD><EFBFBD><EFBFBD>ͣ<EFBFBD>ƥ<EFBFBD><EFBFBD><E4B1A8><EFBFBD><EFBFBD><EFBFBD>ƿ<EFBFBD><C6BF><EFBFBD>Ϣ
va_num = 0;
info_va[va_num++] = rcb_info->rcb_var.RptID;
//LOG_INFO("va_num = %d", va_num); //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD>ã<EFBFBD> zl 2019-1-23 09:10:39
all_rcb_info = (ALL_RCB_INFO*)chk_calloc(1, sizeof(ALL_RCB_INFO));
all_rcb_info->rpt_typeids = &g_rpt_typeids;
all_rcb_info->rcb_info_list = dev_rcb->rcb_info_list;
event->net_info->user_info = all_rcb_info;
rcb_info = all_rcb_info->rcb_info_list;
rcb_info->rcb_data.RptID[0] = '\0'; /* start with empty string */
mvl_info_data_to_local(event, va_num, info_va); //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ת<EFBFBD><D7AA>Ϊ<EFBFBD><CEAA><EFBFBD>ظ<EFBFBD>ʽ
/* NOTE: decoded RptID is now in "rcb_info->rcb_data.RptID". Save it.*/
strcpy(saveRptID, rcb_info->rcb_data.RptID); //װ<><D7B0><EFBFBD><EFBFBD><EFBFBD>ͱ<EFBFBD><CDB1><EFBFBD>ID <20><><EFBFBD><EFBFBD>PQM2/LLN0$BR$brcbStatisticData01
//LOG_INFO("װ<><D7B0><EFBFBD><EFBFBD><EFBFBD>ͱ<EFBFBD><CDB1><EFBFBD>saveRptID<49><44>%s", saveRptID); //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD>ã<EFBFBD> zl 2019-1-23 09:10:39
chk_free(all_rcb_info);
event->net_info->user_info = NULL;
/* Search list of "rcb_info" to find one with matching RptID. If not found, rcb_info will be == NULL. */
//װ<>ñ<EFBFBD><C3B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƿ<EFBFBD><C6BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD>-----------------------------------------------------------------------------------------------------------------------------------------------------
for (rcb_info = dev_rcb->rcb_info_list; rcb_info != NULL; rcb_info = (RCB_INFO *)list_get_next(dev_rcb->rcb_info_list, rcb_info)) //<2F><><EFBFBD><EFBFBD> ȫ<>ֱ<EFBFBD><D6B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƿ<EFBFBD><C6BF><EFBFBD><EFBFBD><EFBFBD>
{
//LOG_INFO("<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƿ<EFBFBD><C6BF><EFBFBD><EFBFBD><EFBFBD>RptID<49><44>%s<><73>saveRptID<49><44>%s", rcb_info->RptID, saveRptID); //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD>ã<EFBFBD> zl 2019-1-23 09:10:39
if (strcmp(rcb_info->RptID, saveRptID) == 0)
break; /* rcb_info now points to right structure */
}
if (!rcb_info) //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƿ<EFBFBD>ָ<EFBFBD><D6B8>Ϊ<EFBFBD>գ<EFBFBD>
{
//SLOGALWAYS1 ("RptID '%s' not recognized on this connection. Received report ignored.", saveRptID);
//LOG_INFO("(<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)<29><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƿ<EFBFBD><C6BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҳ<EFBFBD><D2B2><EFBFBD>RptID= '%s'<27><>goto CLEANUP<55><50><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", saveRptID); //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD>ã<EFBFBD> zl 2019-12-23 15:09:36
retcode = SD_FAILURE;
goto CLEANUP; //<2F><>ת<EFBFBD><D7AA> CLEANUP<55><50><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>retcode<64><65><EFBFBD><EFBFBD>
}
//WW 2023-08-29 end
//////////////////////////////
//////////////////////
//WW 2023-08-29ע<39><D7A2>
///* Must decode the RptID first to find the correct RCB_INFO. Could decode into
//* any "vstring65" variable. We just use the RptID variable from the first
//* rcb_info on the list.
//*/
//rcb_info = all_rcb_info->rcb_info_list; /* use first rcb_info on list*/
//va_num = 0;
//info_va[va_num++] = rcb_info->rcb_var.RptID;
//rcb_info->rcb_data.RptID[0] = '\0'; /* start with empty string */
//mvl_info_data_to_local(event, va_num, info_va);
///* NOTE: decoded RptID is now in "rcb_info->rcb_data.RptID". Save it.*/
//strcpy(saveRptID, rcb_info->rcb_data.RptID);
///* Search list of "rcb_info" to find one with matching RptID. */
///* If not found, rcb_info will be == NULL. */
//for (rcb_info = all_rcb_info->rcb_info_list;
// rcb_info != NULL;
// rcb_info = (RCB_INFO*)list_get_next(all_rcb_info->rcb_info_list, rcb_info))
//{
// if (strcmp(rcb_info->RptID, saveRptID) == 0)
// break; /* rcb_info now points to right structure */
//}
//if (!rcb_info)
//{
// echo_warn1("RptID '%s' not recognized on this connection. Received report ignored.", saveRptID);
// retcode = SD_FAILURE;
// goto CLEANUP;
//}
//WW 2023-08-29 end
////////////////////////
va_num = 0;
info_va[va_num++] = rcb_info->rcb_var.RptID;
if ((retcode = check_va_count_too_big(va_num, va_total)) == SD_FAILURE) goto CLEANUP;
info_va[va_num++] = rcb_info->rcb_var.OptFlds;
if ((retcode = check_va_count_too_big(va_num, va_total)) == SD_FAILURE) goto CLEANUP;
/* Perform 1st decode (up through "OptFlds"). Need "OptFlds" to figure
* out what comes next.
*/
mvl_info_data_to_local(event, va_num, info_va);
/* Examine "OptFlds", and set up 2nd decode to decode all options */
OptFldsData = rcb_info->rcb_data.OptFlds.data_1; /* use local var */
// printf ("OptFlds = 0x%02x 0x%02x\n", OptFldsData[0],OptFldsData[1]); /* 9 bit bstr (2 bytes) */
/* NOTE: Don't change initial entries in "info_va". Add these right after "OptFlds".*/
if (BSTR_BIT_GET(OptFldsData, OPTFLD_BITNUM_SQNUM))
info_va[va_num++] = rcb_info->rcb_var.SqNum;
if ((retcode = check_va_count_too_big(va_num, va_total)) == SD_FAILURE) goto CLEANUP;
if (BSTR_BIT_GET(OptFldsData, OPTFLD_BITNUM_TIMESTAMP))
info_va[va_num++] = rcb_info->rcb_var.TimeOfEntry;
if ((retcode = check_va_count_too_big(va_num, va_total)) == SD_FAILURE) goto CLEANUP;
if (BSTR_BIT_GET(OptFldsData, OPTFLD_BITNUM_DATSETNAME))
{
info_va[va_num++] = rcb_info->rcb_var.DatSetNa;
///////////////////
//WW 2023-08-29
log_var_to_data(rcb_info->rcb_var.DatSetNa, rptID);
//for (rcb_info1 = all_rcb_info->rcb_info_list;
// rcb_info1 != NULL;
// rcb_info1 = (RCB_INFO *) list_get_next (all_rcb_info->rcb_info_list, rcb_info1)) //<2F><><EFBFBD><EFBFBD> װ<>ñ<EFBFBD><C3B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƿ<EFBFBD><C6BF><EFBFBD><EFBFBD><EFBFBD>
for (rcb_info1 = dev_rcb->rcb_info_list;
rcb_info1 != NULL;
rcb_info1 = (RCB_INFO *)list_get_next(dev_rcb->rcb_info_list, rcb_info1)) //<2F><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƿ<EFBFBD><C6BF><EFBFBD><EFBFBD><EFBFBD>
{
if (strcmp(rcb_info1->ds_Nam, rptID) == 0) //<2F><><EFBFBD><EFBFBD>ID<49><44><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA>ͬ<EFBFBD><CDAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ψһ<CEA8><D2BB>ʶ<EFBFBD><CAB6>
{
//SLOGALWAYS3 ("Num of var received in RPT (%d) does not match expected (%d)dateSet=%s ", va_total, va_num,rptID);
//LOG_INFO("(<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)<29><><EFBFBD>ձ<EFBFBD><D5B1><EFBFBD>RptID= '%s'<27><><EFBFBD>ݼ<EFBFBD>rptID= %s<><73><EFBFBD><EFBFBD>С(%d)<29><>Ԥ<EFBFBD>ڴ<EFBFBD>С(%d)<29><>ƥ<EFBFBD>䣬brak<61><6B><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", saveRptID, rptID, va_total, va_num); //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD>ã<EFBFBD> zl 2019-12-23 15:09:30
rcb_info = rcb_info1;
break;
}
}
//WW 2023-08-29 en
///////////////////////////
}
if ((retcode = check_va_count_too_big(va_num, va_total)) == SD_FAILURE) goto CLEANUP;
/* The following optional vars are supported by IEC-61850 but they are
* NOT supported by UCA. This client must NOT set these OptFlds bits
* when connected to a UCA server, and these variables will NOT be
* included in a report received from a UCA server.
*/
if (BSTR_BIT_GET(OptFldsData, OPTFLD_BITNUM_BUFOVFL))
info_va[va_num++] = rcb_info->rcb_var.BufOvfl;
if ((retcode = check_va_count_too_big(va_num, va_total)) == SD_FAILURE) goto CLEANUP;
if (BSTR_BIT_GET(OptFldsData, OPTFLD_BITNUM_ENTRYID))
info_va[va_num++] = rcb_info->rcb_var.EntryID;
if ((retcode = check_va_count_too_big(va_num, va_total)) == SD_FAILURE) goto CLEANUP;
if (BSTR_BIT_GET(OptFldsData, OPTFLD_BITNUM_CONFREV))
info_va[va_num++] = rcb_info->rcb_var.ConfRev;
if ((retcode = check_va_count_too_big(va_num, va_total)) == SD_FAILURE) goto CLEANUP;
if (BSTR_BIT_GET(OptFldsData, OPTFLD_BITNUM_SUBSEQNUM))
{
info_va[va_num++] = rcb_info->rcb_var.SubSeqNum;
if ((retcode = check_va_count_too_big(va_num, va_total)) == SD_FAILURE) goto CLEANUP;
info_va[va_num++] = rcb_info->rcb_var.MoreSegmentsFollow;
if ((retcode = check_va_count_too_big(va_num, va_total)) == SD_FAILURE) goto CLEANUP;
}
info_va[va_num++] = rcb_info->rcb_var.Inclusion;
if ((retcode = check_va_count_too_big(va_num, va_total)) == SD_FAILURE) goto CLEANUP;
assert(va_num < va_total);
/* Perform 2nd decode (up through "Inclusion"). */
mvl_info_data_to_local(event, va_num, info_va);
/* Examine "Inclusion", and set up 3rd decode to decode all data. */
InclusionData = rcb_info->rcb_data.Inclusion; /* use local var */
// printf ("\nThe 1st byte Inclusion = 0x%02X\n", InclusionData[0]); /* Just print 1st byte */
/* NOTE: Don't change initial entries in "info_va". Add these right after "Inclusion".*/
/* If "data-Ref" enabled, check "Inclusion" to figure out what is being received.*/
if (BSTR_BIT_GET(OptFldsData, OPTFLD_BITNUM_DATAREF))
{
for (j = 0; j < rcb_info->numDsVar; ++j)
{
if (BSTR_BIT_GET(InclusionData, j)) {
info_va[va_num++] = rcb_info->rcb_var.dataRefName[j];
if ((retcode = check_va_count_too_big(va_num, va_total)) == SD_FAILURE) goto CLEANUP;
}
}
}
/* HERE'S THE DATA. Check "Inclusion" to figure out what is being received.*/
for (j = 0; j < rcb_info->numDsVar; ++j)
{
if (BSTR_BIT_GET(InclusionData, j)) {
info_va[va_num++] = rcb_info->rcb_var.dataValue[j];
if ((retcode = check_va_count_too_big(va_num, va_total)) == SD_FAILURE) goto CLEANUP;
}
}
/* If "reason" enabled, check "Inclusion" to figure out what is being received.*/
if (BSTR_BIT_GET(OptFldsData, OPTFLD_BITNUM_REASON))
{
for (j = 0; j < rcb_info->numDsVar; ++j)
{
if (BSTR_BIT_GET(InclusionData, j)) {
info_va[va_num++] = rcb_info->rcb_var.Reason[j];
}
}
}
/* Does num of variables received match expected num.*/
if (va_num != va_total)
{
echo_warn2("Num of var received in RPT (%d) does not match expected (%d). Possibly incorrect OptFlds or inclusion bitstring", va_total, va_num);
// printf ("Num of var received in RPT (%d) does not match expected (%d). Possibly incorrect OptFlds or inclusion bitstring\n", va_total, va_num);
}
else
{
/* Perform 3rd decode (everything). */
mvl_info_data_to_local(event, va_num, info_va);
u_iec_rpt_ind_data_by_devtype(info_va, OptFldsData, InclusionData, rcb_info, va_total, event->net_info);
}
CLEANUP:
chk_free(info_va);
END:
return (retcode);
}
ST_RET u_iec_rpt_ind(MVL_COMM_EVENT* event)
{
INFO_REQ_INFO* info_ptr;
ST_INT j, va_num, va_total;
VAR_ACC_SPEC* va_spec;
MVL_VAR_ASSOC** info_va;
RCB_INFO* rcb_info, * rcb_info1;
ST_UINT8* OptFldsData; /* ptr to data part of OptFlds bvstring */
ST_UINT8* InclusionData; /* ptr to Inclusion bstring */
ST_CHAR saveRptID[66];
ALL_RCB_INFO* all_rcb_info;
ST_RET retcode = SD_SUCCESS;
info_ptr = (INFO_REQ_INFO*)event->u.mms.dec_rslt.data_ptr;
va_spec = &info_ptr->va_spec;
va_total = info_ptr->num_of_acc_result;
/* An IEC-61850 or UCA report must be a NamedVariableList named "RPT".
* Ignore any other InformationReport.
*/
if (va_spec->var_acc_tag != VAR_ACC_NAMEDLIST
|| strcmp(va_spec->vl_name.obj_name.vmd_spec, "RPT") != 0)
{
echo_warn("Received InformationReport is not a IEC-61850 Report or UCA Report. Ignored.");
return (SD_FAILURE);
}
/* Get "all_rcb_info" from "user_info". User must set "user_info" when conn established.*/
all_rcb_info = (ALL_RCB_INFO*)event->net_info->user_info;
/* Check "all_rcb_info" to see if any RCB has been enabled. */
if (all_rcb_info == NULL || all_rcb_info->rcb_info_list == NULL)
{
echo_warn("Received InformationReport. No IEC-61850 or UCA RCB enabled. Ignored.");
return (SD_FAILURE);
}
/* Create array of (MVL_VAR_ASSOC *) needed for converting the received
* data to local format.
* Use variables created earlier to fill in the array. These variables will
* hold the decoded data.
* NOTE: any return after this must free info_va (see CLEANUP label).
*/
info_va = (MVL_VAR_ASSOC**)chk_calloc(va_total,
sizeof(MVL_VAR_ASSOC*));
/* Must decode the RptID first to find the correct RCB_INFO. Could decode into
* any "vstring65" variable. We just use the RptID variable from the first
* rcb_info on the list.
*/
rcb_info = all_rcb_info->rcb_info_list; /* use first rcb_info on list*/
va_num = 0;
info_va[va_num++] = rcb_info->rcb_var.RptID;
rcb_info->rcb_data.RptID[0] = '\0'; /* start with empty string */
mvl_info_data_to_local(event, va_num, info_va);
/* NOTE: decoded RptID is now in "rcb_info->rcb_data.RptID". Save it.*/
strcpy(saveRptID, rcb_info->rcb_data.RptID);
/* Search list of "rcb_info" to find one with matching RptID. */
/* If not found, rcb_info will be == NULL. */
for (rcb_info = all_rcb_info->rcb_info_list;
rcb_info != NULL;
rcb_info = (RCB_INFO*)list_get_next(all_rcb_info->rcb_info_list, rcb_info))
{
if (strcmp(rcb_info->RptID, saveRptID) == 0)
break; /* rcb_info now points to right structure */
}
if (!rcb_info)
{
echo_warn1("RptID '%s' not recognized on this connection. Received report ignored.", saveRptID);
retcode = SD_FAILURE;
goto CLEANUP;
}
va_num = 0;
info_va[va_num++] = rcb_info->rcb_var.RptID;
if ((retcode = check_va_count_too_big(va_num, va_total)) == SD_FAILURE) goto CLEANUP;
info_va[va_num++] = rcb_info->rcb_var.OptFlds;
if ((retcode = check_va_count_too_big(va_num, va_total)) == SD_FAILURE) goto CLEANUP;
/* Perform 1st decode (up through "OptFlds"). Need "OptFlds" to figure
* out what comes next.
*/
mvl_info_data_to_local(event, va_num, info_va);
/* Examine "OptFlds", and set up 2nd decode to decode all options */
OptFldsData = rcb_info->rcb_data.OptFlds.data_1; /* use local var */
// printf ("OptFlds = 0x%02x 0x%02x\n", OptFldsData[0],OptFldsData[1]); /* 9 bit bstr (2 bytes) */
/* NOTE: Don't change initial entries in "info_va". Add these right after "OptFlds".*/
if (BSTR_BIT_GET(OptFldsData, OPTFLD_BITNUM_SQNUM))
info_va[va_num++] = rcb_info->rcb_var.SqNum;
if ((retcode = check_va_count_too_big(va_num, va_total)) == SD_FAILURE) goto CLEANUP;
if (BSTR_BIT_GET(OptFldsData, OPTFLD_BITNUM_TIMESTAMP))
info_va[va_num++] = rcb_info->rcb_var.TimeOfEntry;
if ((retcode = check_va_count_too_big(va_num, va_total)) == SD_FAILURE) goto CLEANUP;
//WW 2024-09-02 <20><><EFBFBD>ݼ<EFBFBD><DDBC><EFBFBD><EFBFBD><EFBFBD>ȷ<EFBFBD><C8B7>
if (BSTR_BIT_GET(OptFldsData, OPTFLD_BITNUM_DATSETNAME))
info_va[va_num++] = rcb_info->rcb_var.DatSetNa;
mvl_info_data_to_local(event, va_num, info_va);
//WW 2024-09-02 endss
if (BSTR_BIT_GET(OptFldsData, OPTFLD_BITNUM_DATSETNAME))
{
//info_va[va_num++] = rcb_info->rcb_var.DatSetNa; //WW 2024-09-02 ע<><D7A2>
///////////////////
//WW 2023-08-29
log_var_to_data(rcb_info->rcb_var.DatSetNa, saveRptID);
for (rcb_info1 = all_rcb_info->rcb_info_list;
rcb_info1 != NULL;
rcb_info1 = (RCB_INFO*)list_get_next(all_rcb_info->rcb_info_list, rcb_info1)) //<2F><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƿ<EFBFBD><C6BF><EFBFBD><EFBFBD><EFBFBD>
{
if (strcmp(rcb_info1->ds_Nam, saveRptID) == 0) //<2F><><EFBFBD><EFBFBD>ID<49><44><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA>ͬ<EFBFBD><CDAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ψһ<CEA8><D2BB>ʶ<EFBFBD><CAB6>
{
printf("ds_name '%s' ! Recive name %s WWTest \n", rcb_info1->ds_Nam, saveRptID);
//SLOGALWAYS3 ("Num of var received in RPT (%d) does not match expected (%d)dateSet=%s ", va_total, va_num,rptID);
//LOG_INFO("(<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)<29><><EFBFBD>ձ<EFBFBD><D5B1><EFBFBD>RptID= '%s'<27><><EFBFBD>ݼ<EFBFBD>rptID= %s<><73><EFBFBD><EFBFBD>С(%d)<29><>Ԥ<EFBFBD>ڴ<EFBFBD>С(%d)<29><>ƥ<EFBFBD>䣬brak<61><6B><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", saveRptID, rptID, va_total, va_num); //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD>ã<EFBFBD> zl 2019-12-23 15:09:30
rcb_info = rcb_info1;
break;
}
}
//WW 2023-08-29 en
///////////////////////////
}
if ((retcode = check_va_count_too_big(va_num, va_total)) == SD_FAILURE) goto CLEANUP;
/* The following optional vars are supported by IEC-61850 but they are
* NOT supported by UCA. This client must NOT set these OptFlds bits
* when connected to a UCA server, and these variables will NOT be
* included in a report received from a UCA server.
*/
if (BSTR_BIT_GET(OptFldsData, OPTFLD_BITNUM_BUFOVFL))
info_va[va_num++] = rcb_info->rcb_var.BufOvfl;
if ((retcode = check_va_count_too_big(va_num, va_total)) == SD_FAILURE) goto CLEANUP;
if (BSTR_BIT_GET(OptFldsData, OPTFLD_BITNUM_ENTRYID))
info_va[va_num++] = rcb_info->rcb_var.EntryID;
if ((retcode = check_va_count_too_big(va_num, va_total)) == SD_FAILURE) goto CLEANUP;
if (BSTR_BIT_GET(OptFldsData, OPTFLD_BITNUM_CONFREV))
info_va[va_num++] = rcb_info->rcb_var.ConfRev;
if ((retcode = check_va_count_too_big(va_num, va_total)) == SD_FAILURE) goto CLEANUP;
if (BSTR_BIT_GET(OptFldsData, OPTFLD_BITNUM_SUBSEQNUM))
{
info_va[va_num++] = rcb_info->rcb_var.SubSeqNum;
if ((retcode = check_va_count_too_big(va_num, va_total)) == SD_FAILURE) goto CLEANUP;
info_va[va_num++] = rcb_info->rcb_var.MoreSegmentsFollow;
if ((retcode = check_va_count_too_big(va_num, va_total)) == SD_FAILURE) goto CLEANUP;
}
info_va[va_num++] = rcb_info->rcb_var.Inclusion;
if ((retcode = check_va_count_too_big(va_num, va_total)) == SD_FAILURE) goto CLEANUP;
assert(va_num < va_total);
/* Perform 2nd decode (up through "Inclusion"). */
mvl_info_data_to_local(event, va_num, info_va);
/* Examine "Inclusion", and set up 3rd decode to decode all data. */
InclusionData = rcb_info->rcb_data.Inclusion; /* use local var */
// printf ("\nThe 1st byte Inclusion = 0x%02X\n", InclusionData[0]); /* Just print 1st byte */
/* NOTE: Don't change initial entries in "info_va". Add these right after "Inclusion".*/
/* If "data-Ref" enabled, check "Inclusion" to figure out what is being received.*/
if (BSTR_BIT_GET(OptFldsData, OPTFLD_BITNUM_DATAREF))
{
for (j = 0; j < rcb_info->numDsVar; ++j)
{
if (BSTR_BIT_GET(InclusionData, j)) {
info_va[va_num++] = rcb_info->rcb_var.dataRefName[j];
if ((retcode = check_va_count_too_big(va_num, va_total)) == SD_FAILURE) goto CLEANUP;
}
}
}
/* HERE'S THE DATA. Check "Inclusion" to figure out what is being received.*/
for (j = 0; j < rcb_info->numDsVar; ++j)
{
if (BSTR_BIT_GET(InclusionData, j)) {
info_va[va_num++] = rcb_info->rcb_var.dataValue[j];
if ((retcode = check_va_count_too_big(va_num, va_total)) == SD_FAILURE) goto CLEANUP;
}
}
/* If "reason" enabled, check "Inclusion" to figure out what is being received.*/
if (BSTR_BIT_GET(OptFldsData, OPTFLD_BITNUM_REASON))
{
for (j = 0; j < rcb_info->numDsVar; ++j)
{
if (BSTR_BIT_GET(InclusionData, j)) {
info_va[va_num++] = rcb_info->rcb_var.Reason[j];
}
}
}
/* Does num of variables received match expected num.*/
if (va_num != va_total)
{
echo_warn2("Num of var received in RPT (%d) does not match expected (%d). Possibly incorrect OptFlds or inclusion bitstring", va_total, va_num);
// printf ("Num of var received in RPT (%d) does not match expected (%d). Possibly incorrect OptFlds or inclusion bitstring\n", va_total, va_num);
}
else
{
/* Perform 3rd decode (everything). */
mvl_info_data_to_local(event, va_num, info_va);
//<2F><><EFBFBD><EFBFBD><E6B4A6><EFBFBD><EFBFBD><EFBFBD><EFBFBD>lnk20250114
2025-02-24 16:45:42 +08:00
//pthread_mutex_lock(&mtx); printf("rpt hold lock !!!!!!!!!!!");
2025-01-16 16:17:01 +08:00
u_iec_rpt_ind_data(info_va, OptFldsData, InclusionData, rcb_info, va_total, event->net_info);
2025-02-24 16:45:42 +08:00
//pthread_mutex_unlock(&mtx); printf("rpt free lock !!!!!!!!!!!");
2025-01-16 16:17:01 +08:00
}
CLEANUP:
chk_free(info_va);
return (retcode);
}
/************************************************************************/
//61850<35><30><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/************************************************************************/
void log_var_to_data(MVL_VAR_ASSOC *var, char *pdata)
{
static char text_buf[30000]; /* increase size if ms_local_to_text fails */
// ST_CHAR tdl_buf [500]; /* increase size if complex TDL expected*/
MVL_TYPE_CTRL *type_ctrl;
ST_CHAR *data_text; /* var data converted to text */
text_buf[0] = 0;
type_ctrl = mvl_type_ctrl_find(var->type_id);
if (type_ctrl)
{
//if (ms_runtime_to_tdl(type_ctrl->rt,type_ctrl->num_rt,tdl_buf,sizeof(tdl_buf))>0)
// RTP_PRI (" TYPE: %s\r\n", tdl_buf);
//else RTP_PRI (" TYPE: unknown\r\n");
data_text = ms_local_to_text((char *)var->data, type_ctrl->rt, type_ctrl->num_rt, text_buf, sizeof(text_buf));
if (data_text) { strcpy(pdata, data_text); }
else *pdata = '0';
}
else *pdata = '0';
}
/************************************************************************/
/* LocToTextBs */
/************************************************************************/
#define TEMP_DATA_BUF_SIZE 1024
static ST_RET myLocToTextBs(ST_UCHAR* pSrc, RUNTIME_TYPE* rt, ST_CHAR* text)
{
int i;
int j;
int k;
int numBits;
ST_INT16* sp;
ST_CHAR* destBuf;
ST_UCHAR mask;
//printf("%s text_len %d %d pSrc %d %d \n", text, strlen(text), rt->u.p.el_len, pSrc[0], pSrc[1]);
text[0] = 0;
numBits = rt->u.p.el_len;
/* We take 1 dest byte per bit, make sure it fits */
if (numBits > TEMP_DATA_BUF_SIZE - 1)
{
MLOG_NERR1("Bit String (%d bits) too long to encode", numBits);
return (SD_FAILURE);
}
if (numBits < 0) /* a variable length bit string */
{
sp = (ST_INT16*)pSrc;
numBits = *sp;
//printf("numBits %d \n", numBits);
if ((numBits > TEMP_DATA_BUF_SIZE - 1) || (numBits <= 0)) {
if (numBits != 0) //add by lzm @2018.11.1,to avoid too many print message!!!
echo_warn1("Bit String (%d bits) too long to encode\n", numBits);
return (SD_FAILURE);
}
k = 2;
}
else
k = 0;
destBuf = text;
for (i = 0; i < numBits; ++k) /* for each byte, while bits remain */
{
mask = 0x80;
for (j = 0; j < 8 && i < numBits; ++i, ++j)
{
if (pSrc[k] & mask)
destBuf[i] = '1';
else
destBuf[i] = '0';
mask >>= 1;
}
}
destBuf[i] = 0;
return (SD_SUCCESS);
}
/************************************************************************/
/* LocToTextOct */
/************************************************************************/
static ST_RET myLocToTextOct(ST_UCHAR* pSrc, RUNTIME_TYPE* rt, ST_CHAR* text)
{
int i, k;
int numBytes;
ST_INT16* sp;
ST_CHAR* destBuf;
text[0] = 0;
numBytes = rt->u.p.el_len;
if (numBytes < 0) /* a variable length octet string */
{
sp = (ST_INT16*)pSrc;
numBytes = *sp;
k = 2;
}
else
k = 0;
/* We take 3 bytes per octet, make sure it fits */
if (numBytes > TEMP_DATA_BUF_SIZE / 3)
{
MLOG_NERR1("Octet String (%d bytes) too long to encode", numBytes);
return SD_FAILURE;
}
destBuf = text;
for (i = 0; i < numBytes; ++i, ++k)
{
apr_snprintf(destBuf, sizeof(destBuf), "%02x ", (unsigned int)pSrc[k]);
destBuf += 3;
}
/* Eliminate the trailing space */
*(destBuf - 1) = 0;
return (SD_SUCCESS);
}
/************************************************************************/
/* asn1_convert_utc_to_btod */
/* This function converts MMS_UTC_TIME (time relative to 1/1/1970) to */
/* the MMS_BTOD (time relative to 1/1/1984). */
/* The form field in the MMS_BTOD is set to MMS_BTOD6 by this function. */
/* Parameters: */
/* utc pointer to MMS_UTC_TIME struct that should be converted */
/* to the MMS_BTOD */
/* btod pointer to MMS_BTOD struct where the result of the */
/* conversion will be placed */
/* Return: */
/* SD_SUCCESS if function successful */
/* SD_FAILURE otherwise */
/************************************************************************/
ST_RET my_asn1_convert_utc_to_btod(MMS_UTC_TIME* utc, MMS_BTOD* btod)
{
time_t tJan84 = TIME_T_1984_JAN_1;
/* Now compute the MMS_BTOD time */
btod->day = (long)(utc->secs - tJan84) / SECONDS_PER_DAY; /* num of days since 1/1/1984 */
btod->ms = (long)((utc->secs - tJan84) % SECONDS_PER_DAY) * 1000; /* num milliseconds since midnight */
/* NOTE: use 0x01000000 (2**24) in fraction computations. */
// Ҫ<><D2AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EBB5BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 28.9999Ӧ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>29ms
btod->ms += (ST_INT32)(0.5 + (ST_DOUBLE)utc->fraction * 1000.0 / (ST_DOUBLE)0x01000000);
/* add the milliseconds left in a sec */
btod->form = MMS_BTOD6;
return (SD_SUCCESS);
}
/************************************************************************/
/* ms_local_to_text */
/* NOTE: tmpBuf is passed to most "LocToText.." static functions. These */
/* functions must NOT write past end of tmpBuf. */
/************************************************************************/
void my_local_to_data(ST_CHAR* datptr, SD_CONST RUNTIME_TYPE* rt_head,
ST_INT rt_num, MMS_DECODE_DATA* data)
{
RUNTIME_TYPE* rt_ptr;
RUNTIME_TYPE* rt_end;
ST_RET uDataRet;
ST_INT arr_loop_level = 0;
ST_INT arr_loops[ASN1_MAX_LEVEL];
//ST_CHAR *ret_ptr;
ST_CHAR tmpBuf[TEMP_DATA_BUF_SIZE];
//ST_UINT nStrLen = 0; /* Current text total length */
ST_UINT valid_item_num = 0;
SD_CONST ST_CHAR* comp_name; /* component name *///add by lzm
//ST_INT comp_name_len; /* len of component name*/
ST_UINT deep = 0; // deep of structure
unsigned int jjj;
char attr_str[256];
char comp_str[32][256];
int cur_array_deep = -1;
ST_UINT cur_array_idx;
if (data == NULL) {
echo_warn("error ~~~~~~~ my_local_to_data MMS_DECODE_DATA data is NULL return \n");
return;
}
if (rt_num <= 0) {
echo_warn1("error !!!!!!! my_local_to_data rt_num %d = return \n", rt_num);
return;
}
if (rt_head->el_tag > RT_ARR_END) {
echo_warn2("error @@@@@@@ my_local_to_data rt_head->el_tag %d size %d = return \n", rt_head->el_tag, rt_head->el_size);
return;
}
data->item_num = 0;
rt_ptr = (RUNTIME_TYPE*)rt_head; /* point to head rt_block */
rt_end = rt_ptr + rt_num; /* done when pointer is here */
if (rt_end == NULL) {
echo_warn("error XXXXXX my_local_to_data rt_end \n");
return;
}
// SLOGCALWAYS1(" rt_num = %i",rt_num);
uDataRet = SD_SUCCESS;
while (rt_ptr < rt_end && uDataRet == SD_SUCCESS)
{
if (rt_ptr == NULL) {
echo_warn("error !!!!!!! my_local_to_data rt_ptr is NULL error,return \n");
return;
}
if (valid_item_num >= MAX_DATA_ITEMS_IN_ONE_DATA) {
echo_warn2("my_local_to_data RUNTIME_TYPE valid_item_num % >= %d \n", valid_item_num, MAX_DATA_ITEMS_IN_ONE_DATA);
return;
}
if (rt_ptr->el_tag == RT_ARR_END) /* treat case of array ending */
{
if (--arr_loops[arr_loop_level] > 0) /* if need to do next ar elmnt */
rt_ptr -= rt_ptr->u.arr.num_rt_blks; /* mv rt_ptr to start of arr */
else
--arr_loop_level;
}
if (rt_ptr->el_tag == RT_ARR_START) /* treat case of array starting */
{
/* initialize the loop counter for the array */
++arr_loop_level;
arr_loops[arr_loop_level] = rt_ptr->u.arr.num_elmnts;
}
comp_name = ms_comp_name_find(rt_ptr);//add by lzm
//printf ("\n %i, comp_name = %s cur_array_deep/deep: %d/%d \n",rt_ptr->el_tag,comp_name,cur_array_deep,deep);
// if (comp_name != NULL && comp_name[0] != 0)
// SLOGCALWAYS2 (" comp_name= %s, rt_ptr->el_tag =%i ",comp_name,rt_ptr->el_tag); // add by lzm
memset(attr_str, 0, sizeof(attr_str));
if (deep == (cur_array_deep + 1))
cur_array_idx++;
for (jjj = 0; jjj < deep; jjj++)
{
if (strcmp(comp_str[jjj], "")) {
strcat(attr_str, comp_str[jjj]);
}
if (jjj == cur_array_deep) {
char tmp_str[8];
apr_snprintf(tmp_str, sizeof(tmp_str), "[%d]", cur_array_idx);
strcat(attr_str, tmp_str);
}
if (strcmp(comp_str[jjj], "")) {
strcat(attr_str, "$");
}
//if (strcmp (comp_str[jjj], "")) {
//}
}
strcat(attr_str, comp_name);
switch (rt_ptr->el_tag)
{
case RT_ARR_START:
strcpy(comp_str[deep], comp_name);
cur_array_deep = deep;
cur_array_idx = -1;
assert(++deep < 32);
break; /* do nothing */
case RT_ARR_END: /* array done */
assert(--deep >= 0);
memset(comp_str[deep], 0, sizeof(comp_str[deep]));
cur_array_deep = -1;
cur_array_idx = -1;
break; /* do nothing */
case RT_STR_START:
strcpy(comp_str[deep], comp_name);
assert(++deep < 32);
//uDataRet = AddString ("{", textBuf, textBufSize, &nStrLen);
break;
case RT_STR_END: /* structure done */
assert(--deep >= 0);
memset(comp_str[deep], 0, sizeof(comp_str[deep]));
//uDataRet = AddString ("}", textBuf, textBufSize, &nStrLen);
break;
case RT_BOOL:
strcpy(data->data_item[valid_item_num].comp_name, (const char*)attr_str);
data->data_item[valid_item_num].size = 1;
data->data_item[valid_item_num].type = DATA_INT_TYPE;
data->data_item[valid_item_num].u.data_int = *((ST_BOOLEAN*)datptr);
valid_item_num++;
// SLOGCALWAYS2("valid_item_num = %i , value=%i",valid_item_num, *((ST_BOOLEAN *) datptr) );
data->item_num = valid_item_num;
break;
case RT_BIT_STRING:
myLocToTextBs((ST_UCHAR*)datptr, rt_ptr, tmpBuf);
strcpy(data->data_item[valid_item_num].comp_name, (const char*)attr_str);
data->data_item[valid_item_num].size = abs(rt_ptr->u.p.el_len);
data->data_item[valid_item_num].type = DATA_STR_TYPE;
strcpy(data->data_item[valid_item_num].u.data_str, tmpBuf);
valid_item_num++;
// SLOGCALWAYS2("valid_item_num = %i , value=%s",valid_item_num, tmpBuf );
data->item_num = valid_item_num;
break;
case RT_INTEGER:
case RT_BCD:
switch (rt_ptr->u.p.el_len) /* determine length */
{
case 1: /* one byte int */
case 2: /* two byte int */
case 4: /* four byte integer */
strcpy(data->data_item[valid_item_num].comp_name, (const char*)attr_str);
data->data_item[valid_item_num].size = (unsigned char)rt_ptr->u.p.el_len;
data->data_item[valid_item_num].type = DATA_INT_TYPE;
if (rt_ptr->u.p.el_len == 1)
data->data_item[valid_item_num].u.data_int = *((ST_INT8*)datptr);
else if (rt_ptr->u.p.el_len == 2)
data->data_item[valid_item_num].u.data_int = *((ST_INT16*)datptr);
else if (rt_ptr->u.p.el_len == 4)
data->data_item[valid_item_num].u.data_int = *((ST_INT32*)datptr);
// SLOGCALWAYS1("value=%i",data->data_item[valid_item_num].u.data_int );
valid_item_num++;
// SLOGCALWAYS1("valid_item_num = %i ",valid_item_num );
data->item_num = valid_item_num;
break;
#ifdef INT64_SUPPORT
case 8: /* eight byte integer */
strcpy(data->data_item[valid_item_num].comp_name, (const char*)attr_str);
data->data_item[valid_item_num].size = (unsigned char)rt_ptr->u.p.el_len;
data->data_item[valid_item_num].type = DATA_INT64_TYPE;
data->data_item[valid_item_num].u.data_int64 = *((ST_INT64*)datptr);
// SLOGCALWAYS1(" value=%lld ",data->data_item[valid_item_num].u.data_int64 );
valid_item_num++;
// SLOGCALWAYS1("valid_item_num = %i ",valid_item_num );
data->item_num = valid_item_num;
break;
#endif
default:
echo_warn1("δ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>RT_INTEGER<EFBFBD><EFBFBD>RT_BCD <20><><EFBFBD><EFBFBD> size = %i \n", rt_ptr->u.p.el_len);
break;
}
break;
case RT_UNSIGNED:
switch (rt_ptr->u.p.el_len) /* determine length */
{
case 1: /* one byte int */
case 2: /* two byte int */
case 4: /* four byte integer */
strcpy(data->data_item[valid_item_num].comp_name, (const char*)attr_str);
data->data_item[valid_item_num].size = (unsigned char)rt_ptr->u.p.el_len;
data->data_item[valid_item_num].type = DATA_UINT_TYPE;
if (rt_ptr->u.p.el_len == 1)
data->data_item[valid_item_num].u.data_uint = *((ST_UCHAR*)datptr);
else if (rt_ptr->u.p.el_len == 2)
data->data_item[valid_item_num].u.data_uint = *((ST_UINT16*)datptr);
else if (rt_ptr->u.p.el_len == 4)
data->data_item[valid_item_num].u.data_uint = *((ST_UINT32*)datptr);
// SLOGCALWAYS1("value=%u",data->data_item[valid_item_num].u.data_uint );
valid_item_num++;
// SLOGCALWAYS1("valid_item_num = %i ",valid_item_num );
data->item_num = valid_item_num;
break;
#ifdef INT64_SUPPORT
case 8: /* eight byte integer */
strcpy(data->data_item[valid_item_num].comp_name, (const char*)attr_str);
data->data_item[valid_item_num].size = (unsigned char)rt_ptr->u.p.el_len;
data->data_item[valid_item_num].type = DATA_UINT64_TYPE;
data->data_item[valid_item_num].u.data_int64 = *((ST_UINT64*)datptr);
// SLOGCALWAYS1(" value=%llu ",data->data_item[valid_item_num].u.data_uint64 );
valid_item_num++;
// SLOGCALWAYS1("valid_item_num = %i ",valid_item_num );
data->item_num = valid_item_num;
break;
#endif /* INT64_SUPPORT */
default:
echo_warn1("δ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>޷<EFBFBD><DEB7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> size = %i \n", rt_ptr->u.p.el_len);
break;
}
break;
#ifdef FLOAT_DATA_SUPPORT
case RT_FLOATING_POINT:
strcpy(data->data_item[valid_item_num].comp_name, (const char*)attr_str);
data->data_item[valid_item_num].size = (unsigned char)rt_ptr->u.p.el_len;
data->data_item[valid_item_num].type = DATA_DOUBLE_TYPE;
if (rt_ptr->u.p.el_len != sizeof(ST_FLOAT))
data->data_item[valid_item_num].u.data_double = *((ST_DOUBLE*)datptr);
else
data->data_item[valid_item_num].u.data_double = *((ST_FLOAT*)datptr);
// SLOGCALWAYS1(" value=%.16g ",data->data_item[valid_item_num].u.data_double );
valid_item_num++;
// SLOGCALWAYS1("valid_item_num = %i ",valid_item_num );
data->item_num = valid_item_num;
break;
#endif
case RT_OCTET_STRING:
myLocToTextOct((ST_UCHAR*)datptr, rt_ptr, tmpBuf);
strcpy(data->data_item[valid_item_num].comp_name, (const char*)attr_str);
data->data_item[valid_item_num].size = abs(rt_ptr->u.p.el_len);
data->data_item[valid_item_num].type = DATA_STR_TYPE;
strcpy(data->data_item[valid_item_num].u.data_str, tmpBuf);
valid_item_num++;
//SLOGCALWAYS2("valid_item_num = %i , value=%s",valid_item_num, tmpBuf );
data->item_num = valid_item_num;
break;
case RT_VISIBLE_STRING: /* No conversion needed. Just add to working text*/
strcpy(data->data_item[valid_item_num].comp_name, (const char*)attr_str);
data->data_item[valid_item_num].size = abs(rt_ptr->u.p.el_len);
data->data_item[valid_item_num].type = DATA_STR_TYPE;
strcpy(data->data_item[valid_item_num].u.data_str, datptr);
valid_item_num++;
// SLOGCALWAYS2("valid_item_num = %i , value=%s",valid_item_num, datptr );
data->item_num = valid_item_num;
break;
#ifdef TIME_DATA_SUPPORT
case RT_GENERAL_TIME:
strcpy(data->data_item[valid_item_num].comp_name, (const char*)attr_str);
data->data_item[valid_item_num].size = abs(rt_ptr->u.p.el_len);
data->data_item[valid_item_num].type = DATA_TIME_TYPE;
asn1_convert_timet_to_btime6(*((time_t*)datptr),
&(data->data_item[valid_item_num].u.data_bTime6));
valid_item_num++;
data->item_num = valid_item_num;
break;
#endif
#ifdef BTOD_DATA_SUPPORT
case RT_BINARY_TIME:
switch (rt_ptr->u.p.el_len) /* determine length */
{
MMS_BTIME6 btime6;
case 4:
asn1_convert_timet_to_btime6(time(NULL), &btime6);
btime6.ms = *((ST_INT32*)datptr);
strcpy(data->data_item[valid_item_num].comp_name, (const char*)attr_str);
data->data_item[valid_item_num].size = 4;
data->data_item[valid_item_num].type = DATA_TIME_TYPE;
data->data_item[valid_item_num].u.data_bTime6 = btime6;
valid_item_num++;
data->item_num = valid_item_num;
break;
case 6:
strcpy(data->data_item[valid_item_num].comp_name, (const char*)attr_str);
data->data_item[valid_item_num].size = 6;
data->data_item[valid_item_num].type = DATA_TIME_TYPE;
data->data_item[valid_item_num].u.data_bTime6 = *((MMS_BTIME6*)datptr);
valid_item_num++;
data->item_num = valid_item_num;
break;
}
break;
#endif
case RT_UTC_TIME:
{
MMS_BTOD btod;
//cout<<"((MMS_UTC_TIME *) datptr)->fraction = "<<((MMS_UTC_TIME *) datptr)->fraction;
//cout<<"((MMS_UTC_TIME *)datptr)->qflags = "<<((MMS_UTC_TIME *)datptr)->qflags<<endl;
my_asn1_convert_utc_to_btod((MMS_UTC_TIME*)datptr, &btod);
strcpy(data->data_item[valid_item_num].comp_name, (const char*)attr_str);
data->data_item[valid_item_num].size = 1;
data->data_item[valid_item_num].type = DATA_TIME_TYPE;
data->data_item[valid_item_num].u.data_bTime6.day = btod.day;
data->data_item[valid_item_num].u.data_bTime6.ms = btod.ms;
valid_item_num++;
// SLOGALWAYS3("valid_item_num = %i , UTC TIME seconds=%lu, fraction=%lu",
// valid_item_num, ((MMS_UTC_TIME *) datptr)->fraction,
// ((MMS_UTC_TIME *) datptr)->secs );
data->item_num = valid_item_num;
}
break;
case RT_UTF8_STRING:
strcpy(data->data_item[valid_item_num].comp_name, (const char*)attr_str);
data->data_item[valid_item_num].size = abs(rt_ptr->u.p.el_len);
data->data_item[valid_item_num].type = DATA_STR_TYPE;
strcpy(data->data_item[valid_item_num].u.data_str, datptr);
valid_item_num++;
// SLOGCALWAYS2("valid_item_num = %i , value=%s",valid_item_num, datptr );
data->item_num = valid_item_num;
break;
default: /* should not be any other tag */
MLOG_ERR1("Invalid tag: %d", (int)rt_ptr->el_tag);
uDataRet = SD_FAILURE;
break;
}
assert(strlen(tmpBuf) < sizeof(tmpBuf)); /* Must not exceed buffer*/
datptr += rt_ptr->el_size; /* Adjust data pointer */
rt_ptr++; /* point to next rt element */
}
}