Files
microser/mms/mmscli_rpt.c
2025-01-16 16:17:01 +08:00

2664 lines
104 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

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

/**
* @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;
json_block_create_end(LD_info->mp_id, rptinfo->flickerflag);
}
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;
json_block_create_end(LD_info->mp_id, rptinfo->flickerflag);
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;
json_block_create_end(LD_info->mp_id, rptinfo->flickerflag);
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;
json_block_create_end(LD_info->mp_id, rptinfo->flickerflag);
}
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;
json_block_create_end(LD_info->mp_id, rptinfo->flickerflag);
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;
json_block_create_end(LD_info->mp_id, rptinfo->flickerflag);
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
pthread_mutex_lock(&mtx);
u_iec_rpt_ind_data(info_va, OptFldsData, InclusionData, rcb_info, va_total, event->net_info);
pthread_mutex_unlock(&mtx);
}
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 */
}
}