2025-01-16 16:17:01 +08:00
/**
* @ file : $ RCSfile : mmscli_rpt . c , v $
* @ brief : $ IEC 61850 Protocol
*
* @ version : $ Revision : 1.12 $
* @ date : $ Date : 2022 / 11 / 28 07 : 13 : 13 $
* @ author : $ Author : lizhongming $
* @ state : $ State : Exp $
*
* @ latest : $ Id : mmscli_rpt . c , v 1.12 2022 / 11 / 28 07 : 13 : 13 lizhongming Exp $
*
*/
//$Header: /JoyProject/jspqfe/src/pt61850netd_pqfe/source/mms/mmscli_rpt.c,v 1.12 2022/11/28 07:13:13 lizhongming Exp $
/************************************************************************/
/* SISCO SOFTWARE MODULE HEADER *****************************************/
/************************************************************************/
/* (c) Copyright Systems Integration Specialists Company, Inc., */
/* 2003 - 2005, All Rights Reserved */
/* */
/* MODULE NAME : cli_rpt.c */
/* PRODUCT(S) : MMSEASE-LITE */
/* */
/* MODULE DESCRIPTION : */
/* Functions to perform "client" processing of IEC-61850 Reports */
/* and UCA Reports received from "servers". */
/* */
/* GLOBAL FUNCTIONS DEFINED IN THIS MODULE : */
/* rpt_typeids_find */
/* rcb_info_create */
/* rcb_info_destroy */
/* u_iec_rpt_ind */
/* u_iec_rpt_ind_data (user modify or replace) */
/* */
/* MODIFICATION LOG : */
/* Date Who Rev Comments */
/* -------- --- ------ ------------------------------------------- */
/* 07/22/05 JRB 08 Allow one conn to control multiple RCBs */
/* (user_info must point to ALL_RCB_INFO). */
/* Save varNameArray in rcb_info to use later. */
/* Chg u_iec_rpt_ind_data 4th arg to (RCB_INFO *).*/
/* 12/03/04 JRB 07 Extract domain name of NVL from dataSetName. */
/* Increase RptID length to vstring65. */
/* 08/04/04 EJV 06 rcb_info_create: added typecast for Inclusion*/
/* 06/29/04 JRB 05 Del mvl_tdl_to_type_id & instead use new */
/* mvl_type_id_create_from_tdl. */
/* 05/13/04 JRB 04 Chg SqNum to INT16U to match 61850-7-2. */
/* 01/23/04 JRB 03 Use ms_local_to_text. */
/* 12/17/03 JRB 02 61850-8-1 FDIS changes: */
/* Decode ConfRev in rpt if enabled by OptFlds. */
/* Move SubSeqNum, MoreSegmentsFollow to just */
/* before inclusion bitstring. */
/* Chg OptFlds from bvstring9 to bvstring10. */
/* 10/24/03 JRB 01 New */
/************************************************************************/
# include "rdb_client.h"
# include "db_interface.h"
# include "../json/mms_json_inter.h"
2025-03-04 17:29:04 +08:00
# include "../cfg_parse/custom_printf.h"//lnk20250225
2025-01-16 16:17:01 +08:00
/************************************************************************/
/* 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 ) {
2025-03-11 11:29:24 +08:00
apr_time_t t = convert_btime6_to_apr_time ( & ( mms_dec_data . data_item [ ii ] . u . data_bTime6 ) ) ; //<> <CEA2>
2025-01-16 16:17:01 +08:00
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 " ) ) {
2025-03-11 11:29:24 +08:00
processQVVR_time ( LD_info , t / 1000 ) ; //<2F> <> <EFBFBD> <EFBFBD>
2025-01-16 16:17:01 +08:00
not_set_rpt_TimeID_this = FALSE ;
}
}
else if ( strstr ( rcb_info - > RptID , " RDRE " ) ) { //CZY 2023-08-17 WW 2022-11-14<31> <EFBFBD> <DEB8> ж<EFBFBD> LLN0$BR$brcbRDRE
//need do nothing!
not_set_rpt_TimeID_this = FALSE ;
}
else {
json_block_create_time ( LD_info - > mp_id , t / 1000 , rptinfo - > flickerflag ) ;
printf ( " rcb_info->RptID=%s ,LineId=%d , Timestamp= %lld \n " , rcb_info - > RptID , LD_info - > line_id , t / 1000 ) ;
not_set_rpt_TimeID_this = FALSE ;
if ( strstr ( rcb_info - > RptID , " LLN0$RP$urcbRealData " ) ) {
//20241223lnk<6E> <6B> <EFBFBD> <EFBFBD> <EFBFBD> ն˺Ų<CBBA> <C5B2> <EFBFBD>
ied_usr_t * ied_usr = GET_IEDEXT_ADDR ( ied ) ;
if ( urcbRealDataHasReceived ( ied_usr - > dev_idx , LD_info , t / 1000 ) )
return ;
}
}
}
}
else {
double v = 0.0 ;
if ( mms_dec_data . data_item [ ii ] . type = = DATA_INT_TYPE )
v = mms_dec_data . data_item [ ii ] . u . data_int ;
else if ( mms_dec_data . data_item [ ii ] . type = = DATA_UINT_TYPE )
v = mms_dec_data . data_item [ ii ] . u . data_uint ;
else if ( mms_dec_data . data_item [ ii ] . type = = DATA_INT64_TYPE )
v = ( double ) mms_dec_data . data_item [ ii ] . u . data_int64 ;
else if ( mms_dec_data . data_item [ ii ] . type = = DATA_UINT64_TYPE )
v = ( double ) mms_dec_data . data_item [ ii ] . u . data_uint64 ;
else if ( mms_dec_data . data_item [ ii ] . type = = DATA_DOUBLE_TYPE )
v = mms_dec_data . data_item [ ii ] . u . data_double ;
else if ( mms_dec_data . data_item [ ii ] . type = = DATA_STR_TYPE )
v = strtol ( mms_dec_data . data_item [ ii ] . u . data_str , NULL , 2 ) ;
//set_db_value(RPT_IDX,FULL_FCDA_Name,v, is_rpt_Time_exact_hour() );
if ( strstr ( rcb_info - > RptID , " QVVR " ) ) { //CZY 2023-08-17 WW 2022-11-14 <20> <EFBFBD> <DEB8> ж<EFBFBD> LLN0$BR$brcbQVVR
processQVVR_data ( LD_info , FULL_FCDA_Name , v ) ;
}
else if ( strstr ( rcb_info - > RptID , " RDRE " ) ) { //CZY 2023-08-17 WW 2022-11-14 <20> <EFBFBD> <DEB8> ж<EFBFBD> LLN0$BR$brcbRDRE
processRDRE_data ( LD_info , FULL_FCDA_Name , v ) ;
}
else
json_block_create_data ( LD_info - > mp_id , FULL_FCDA_Name , v , rptinfo - > flickerflag ) ;
} //else
}
}
}
if ( LD_info - > line_id > 0 ) {
//set_rpt_LineID(LD_info->line_id);
//set_line_info(RPT_IDX,LD_info->line_id,LD_info->SubV_Index,LD_info->Dev_Index,LD_info->Sub_Index,LD_info->GD_Index);
//write_updatetime_to_db(chnl_usr->chnl->addr);
if ( strstr ( rcb_info - > RptID , " QVVR " ) ) { //CZY 2023-08-17 WW 2022-11-14 <20> <EFBFBD> <DEB8> ж<EFBFBD> LLN0$BR$brcbQVVR
processQVVR_end ( LD_info ) ;
}
else if ( strstr ( rcb_info - > RptID , " RDRE " ) ) { //CZY 2023-08-17 WW 2022-11-14 <20> <EFBFBD> <DEB8> ж<EFBFBD> LLN0$BR$brcbRDRE
processRDRE_end ( LD_info ) ;
}
else {
printf ( " %d : %d " , LD_info - > rptRecvFlag , LD_info - > rptRecvCheckFlag ) ;
//append_db_records(RPT_IDX);
if ( rptinfo - > flickerflag = = 1 ) //CZY 2023-08-17 WW 2022-11-14 <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ־
{
//ied_usr_t* ied_usr = ied->usr_ext;//CZY 2023-08-17 WW 2022<32> <32> 12<31> <32> 6<EFBFBD> <36> 14:09:08 <20> <> <EFBFBD> Ӷ<EFBFBD> <D3B6> <EFBFBD> ICD֧<44> <D6A7>
//int devkind = ied_usr->dev_flag;
2025-02-14 16:44:38 +08:00
json_block_create_end ( LD_info - > v_wiring_type , LD_info - > mp_id , rptinfo - > flickerflag ) ; //lnk2024-8-16<31> <36> <EFBFBD> ӽ<EFBFBD> <D3BD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ͳ<EFBFBD> <CDB2> <EFBFBD>
2025-01-16 16:17:01 +08:00
}
else if ( rptinfo - > flickerflag = = 0 ) { //CZY 2023-08-17 WW 2022-11-14 <20> <> <EFBFBD> Ӷ<EFBFBD> <D3B6> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ж<EFBFBD>
if ( LD_info - > rptRecvFlag = = LD_info - > rptRecvCheckFlag ) {
//ied_usr_t* ied_usr = ied->usr_ext;//CZY 2023-08-17 WW 2022<32> <32> 12<31> <32> 6<EFBFBD> <36> 14:09:08 <20> <> <EFBFBD> Ӷ<EFBFBD> <D3B6> <EFBFBD> ICD֧<44> <D6A7>
//int devkind = ied_usr->dev_flag;
2025-02-14 16:44:38 +08:00
json_block_create_end ( LD_info - > v_wiring_type , LD_info - > mp_id , rptinfo - > flickerflag ) ; //lnk2024-8-16<31> <36> <EFBFBD> ӽ<EFBFBD> <D3BD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ͳ<EFBFBD> <CDB2> <EFBFBD>
2025-01-16 16:17:01 +08:00
LD_info - > rptRecvCheckFlag = 0 ;
}
}
else if ( rptinfo - > flickerflag = = 2 ) { //CZY 2023-08-17 WW 2022-11-14 <20> <> <EFBFBD> Ӷ<EFBFBD> <D3B6> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ж<EFBFBD>
if ( LD_info - > rptPstRecvFlag = = LD_info - > rptPstRecvCheckFlag ) {
//ied_usr_t* ied_usr = ied->usr_ext;//CZY 2023-08-17 WW 2022<32> <32> 12<31> <32> 6<EFBFBD> <36> 14:09:08 <20> <> <EFBFBD> Ӷ<EFBFBD> <D3B6> <EFBFBD> ICD֧<44> <D6A7>
//int devkind = ied_usr->dev_flag;
2025-02-14 16:44:38 +08:00
json_block_create_end ( LD_info - > v_wiring_type , LD_info - > mp_id , rptinfo - > flickerflag ) ; //lnk2024-8-16<31> <36> <EFBFBD> ӽ<EFBFBD> <D3BD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ͳ<EFBFBD> <CDB2> <EFBFBD>
2025-01-16 16:17:01 +08:00
LD_info - > rptPstRecvCheckFlag = 0 ;
}
}
}
}
else {
echo_err3 ( " Ignore this report due to line_id invalid , Report From %s %s %s !!! " ,
APR_EGENERAL , chnl_usr - > ip_str , LD_info - > LD_name , rcb_info - > RptID ) ;
}
printf ( " [END Process] Report From %s:%d %s %s ,va_total = %i ,<2C> <> count = %i<> <69> \n " ,
chnl_usr - > ip_str , chnl_usr - > chnl - > port , LD_info - > LD_name , rcb_info - > RptID , va_total , rptinfo - > count ) ;
//apr_time_t previousTimeend = apr_time_now();//
//apr_time_exp_t localTimeend;
//apr_time_exp_gmt(&localTimeend, previousTimeend);
//printf("\n ------>>>>>>> end time %d %d:%d:%d.%d \n",
// localTimeend.tm_mday, localTimeend.tm_hour, localTimeend.tm_min, localTimeend.tm_sec, localTimeend.tm_usec);
//printf("\n ----6-%d--\n", va_num);
/* If "reason" enabled, check "Inclusion" to figure out what is being received.*/
if ( BSTR_BIT_GET ( OptFldsData , OPTFLD_BITNUM_REASON ) ) {
for ( j = 0 ; j < rcb_info - > numDsVar ; + + j ) {
if ( BSTR_BIT_GET ( InclusionData , j ) ) {
// SLOGCALWAYS2("Var# %02d: Reason# %d", va_num, j);
//log_var_data (info_va[va_num],&mms_dec_data);
va_num + + ;
}
}
}
//<2F> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ӧʱ<D3A6> 䣬<EFBFBD> <E4A3AC> <EFBFBD> <EFBFBD> Ƶ<EFBFBD> <C6B5> <EFBFBD> ٻ<EFBFBD> װ<EFBFBD> <D7B0> <EFBFBD> <EFBFBD> <EFBFBD> ƣ<EFBFBD> <C6A3> <EFBFBD> <EFBFBD> ¶<EFBFBD> <C2B6> <EFBFBD> add on Aug 3 for testing of guangdong CRITICAL
chnl_usr - > m_LastPosRespTime = sGetMsTime ( ) ;
//assert (va_num==va_total); /* Did we count right? */
if ( va_num ! = va_total )
echo_err5 ( " va_num!=va_total! Report From %s %s %s , %d!=%d !!! " ,
APR_EGENERAL , chnl_usr - > ip_str , LD_info - > LD_name , rcb_info - > RptID , va_num , va_total ) ;
}
ST_VOID u_iec_rpt_ind_data ( MVL_VAR_ASSOC * * info_va ,
ST_UINT8 * OptFldsData , /* ptr to data part of OptFlds bvstring */
ST_UINT8 * InclusionData , /* ptr to Inclusion bstring */
RCB_INFO * rcb_info ,
ST_INT va_total ,
MVL_NET_INFO * net_info )
{
ST_INT va_num = 0 ;
ST_INT j ;
MMS_DECODE_DATA mms_dec_data ;
//uint32_t add_mms_dec_data = &mms_dec_data;
ied_t * ied ;
rptinfo_t * rptinfo ;
// element_t* pDataOMSObject;
LD_info_t * LD_info ;
chnl_usr_t * chnl_usr ;
char * * DataObjectFullName ;
// LD_info_t* LD_info_of_Data;
ST_INT not_set_rpt_TimeID_this ;
ST_INT not_set_rpt_q_this ;
//printf("Var# %02d: RptId", va_num);
log_var_data ( info_va [ va_num ] , & mms_dec_data ) ;
//assert(add_mms_dec_data== (uint32_t)&mms_dec_data);
rptinfo = find_rptinfo_from_net_rcb_info ( net_info , rcb_info ) ;
//rptinfo->m_LastDataTime = sGetMsTime();//WW 2023-08-29 ȥ<> <C8A5>
LD_info = rptinfo - > LD_info ;
chnl_usr = net_info - > user_ext ;
ied = chnl_usr - > chnl - > ied ;
not_set_rpt_TimeID_this = TRUE ;
not_set_rpt_q_this = TRUE ;
//g_db_inf_clear_data(RPT_IDX);
rptinfo - > count + + ;
printf ( " [BEGIND Process] Received Report From %s:%d %s %s ,va_total = %i ,<2C> <> count = %i<> <69> mp_id=%s \n " ,
chnl_usr - > ip_str , chnl_usr - > chnl - > port , LD_info - > LD_name , rcb_info - > RptID , va_total , rptinfo - > count , LD_info - > mp_id ) ;
//apr_time_t previousTime = apr_time_now();//
//apr_time_exp_t localTime;
//apr_time_exp_gmt(&localTime, previousTime);
//printf("\n ------>>>>>>> begind time %d %d:%d:%d.%d \n",
// localTime.tm_mday, localTime.tm_hour, localTime.tm_min, localTime.tm_sec, localTime.tm_usec);
va_num + + ;
// SLOGCALWAYS1("Var# %02d: OptFlds", va_num);
log_var_data ( info_va [ va_num ] , & mms_dec_data ) ;
//assert(add_mms_dec_data== (uint32_t)&mms_dec_data);
va_num + + ;
/* NOTE: Don't change initial entries in "info_va". Add these right after "OptFlds".*/
if ( BSTR_BIT_GET ( OptFldsData , OPTFLD_BITNUM_SQNUM ) )
{
// SLOGCALWAYS1("Var# %02d: SqNum", va_num);
log_var_data ( info_va [ va_num ] , & mms_dec_data ) ;
//assert(add_mms_dec_data== (uint32_t)&mms_dec_data);
printf ( " \n ------>>>>>>> SqNum received in Report From %s %s %s ,SqNum = %d \n " ,
chnl_usr - > ip_str , LD_info - > LD_name , rcb_info - > RptID , mms_dec_data . data_item [ 0 ] . u . data_uint ) ;
va_num + + ;
}
if ( BSTR_BIT_GET ( OptFldsData , OPTFLD_BITNUM_TIMESTAMP ) )
{
// SLOGCALWAYS1("Var# %02d: TimeOfEntry", va_num);
log_var_data ( info_va [ va_num ] , & mms_dec_data ) ;
//assert(add_mms_dec_data== (uint32_t)&mms_dec_data);
va_num + + ;
//set_rpt_TimeID(convert_btime6_to_apr_time(&(mms_dec_data.data_item[0].u.data_bTime6)) );
}
if ( BSTR_BIT_GET ( OptFldsData , OPTFLD_BITNUM_DATSETNAME ) )
{
// SLOGCALWAYS1("Var# %02d: DatSetNa", va_num);
log_var_data ( info_va [ va_num ] , & mms_dec_data ) ;
//assert(add_mms_dec_data== (uint32_t)&mms_dec_data);
va_num + + ;
}
if ( BSTR_BIT_GET ( OptFldsData , OPTFLD_BITNUM_BUFOVFL ) )
{
// SLOGCALWAYS1("Var# %02d: BufOvfl", va_num);
log_var_data ( info_va [ va_num ] , & mms_dec_data ) ;
//assert(add_mms_dec_data== (uint32_t)&mms_dec_data);
va_num + + ;
}
if ( BSTR_BIT_GET ( OptFldsData , OPTFLD_BITNUM_ENTRYID ) )
{
char * EntryIDStr ;
int i ;
log_var_data ( info_va [ va_num ] , & mms_dec_data ) ;
//assert(add_mms_dec_data== (uint32_t)&mms_dec_data);
EntryIDStr = mms_dec_data . data_item [ 0 ] . u . data_str ;
printf ( " \n ------>>>>>>> EntryID received in Report From %s %s %s ,EntryID = %s \n \n \n " ,
chnl_usr - > ip_str , LD_info - > LD_name , rcb_info - > RptID , EntryIDStr ) ;
for ( i = 0 ; i < 8 ; i + + ) {
EntryIDStr [ 2 ] = ' \0 ' ;
rptinfo - > m_EntryID [ i ] = ( byte_t ) strtol ( EntryIDStr , NULL , 16 ) ;
EntryIDStr + = 3 ; //skip a blank
}
va_num + + ;
}
printf ( " \n -------------rptinfo->m_EntryID %02x %02x %02x %02x %02x %02x %02x %02x -------- EntryID \n \n \n " ,
* rptinfo - > m_EntryID , * ( rptinfo - > m_EntryID + 1 ) , * ( rptinfo - > m_EntryID + 2 ) ,
* ( rptinfo - > m_EntryID + 3 ) , * ( rptinfo - > m_EntryID + 4 ) , * ( rptinfo - > m_EntryID + 5 ) ,
* ( rptinfo - > m_EntryID + 6 ) , * ( rptinfo - > m_EntryID + 7 ) ) ;
if ( BSTR_BIT_GET ( OptFldsData , OPTFLD_BITNUM_CONFREV ) )
{
// SLOGCALWAYS1("Var# %02d: ConfRev", va_num);
log_var_data ( info_va [ va_num ] , & mms_dec_data ) ;
//assert(add_mms_dec_data== (uint32_t)&mms_dec_data);
va_num + + ;
}
//printf("\n ----1--va_num %d -\n", va_num);
if ( BSTR_BIT_GET ( OptFldsData , OPTFLD_BITNUM_SUBSEQNUM ) )
{
// SLOGCALWAYS1("Var# %02d: SubSeqNum", va_num);
log_var_data ( info_va [ va_num ] , & mms_dec_data ) ;
//assert(add_mms_dec_data== (uint32_t)&mms_dec_data);
va_num + + ;
// SLOGCALWAYS1("Var# %02d: MoreSegmentsFollow", va_num);
log_var_data ( info_va [ va_num ] , & mms_dec_data ) ;
//assert(add_mms_dec_data== (uint32_t)&mms_dec_data);
va_num + + ;
}
//printf("\n ----2---va_num %d \n", va_num);
// SLOGCALWAYS1("Var# %02d: Inclusion", va_num);
log_var_data ( info_va [ va_num ] , & mms_dec_data ) ;
//assert(add_mms_dec_data== (uint32_t)&mms_dec_data);
va_num + + ;
/* If data-Ref enabled, check "Inclusion" to figure out what is being received.*/
if ( BSTR_BIT_GET ( OptFldsData , OPTFLD_BITNUM_DATAREF ) )
{
for ( j = 0 ; j < rcb_info - > numDsVar ; + + j )
{
if ( BSTR_BIT_GET ( InclusionData , j ) )
{
// SLOGCALWAYS2("Var# %02d: DataRefName# %d", va_num, j);
log_var_data ( info_va [ va_num ] , & mms_dec_data ) ;
//assert(add_mms_dec_data== (uint32_t)&mms_dec_data);
va_num + + ;
}
}
}
//printf("\n ----3---%d \n", va_num);
//rcb_info->numDsVar+1 just to avoid rcb_info->numDsVar==0 ,waste a little memory
DataObjectFullName = apr_pcalloc ( g_pt61850app - > tmp_pool , ( rcb_info - > numDsVar + 1 ) * sizeof ( char * ) ) ;
//RWCStringVec DataName(rcb_info->numDsVar+1);
//RWCStringVec AttrName(rcb_info->numDsVar+1);
//RWTValVector<CDataOMSObject*> pDataOMSObjects(rcb_info->numDsVar+1);
//printf("\n ----4--%d rcb_info->numDsVar %d -\n", va_num, rcb_info->numDsVar);
for ( j = 0 ; j < rcb_info - > numDsVar ; + + j )
{
if ( BSTR_BIT_GET ( InclusionData , j ) )
{
DataObjectFullName [ j ] = apr_pstrdup ( g_pt61850app - > tmp_pool , rcb_info - > varNameArray [ j ] - > obj_name . vmd_spec ) ;
}
}
//printf("\n ----5--%d-\n", va_num);
// if (g_pt61850app->IsCallEvtDes )
// cout<<"pEquipment->m_OMSObject_FULL_FCDA_Map.entries() = "<<pEquipment->m_OMSObject_FULL_FCDA_Map.entries()<<endl
//assert(0);
if ( LD_info - > line_id > 0 ) {
if ( strstr ( rcb_info - > RptID , " QVVR " ) ) //CZY 2023-08-17 WW 2022-11-14 <20> <EFBFBD> <DEB8> ж<EFBFBD> LLN0$BR$brcbQVVR
processQVVR_start ( LD_info ) ; //<2F> <> <EFBFBD> ͵ı <CDB5> <C4B1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ļ<EFBFBD> <C4BC> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
else if ( strstr ( rcb_info - > RptID , " RDRE " ) ) //CZY 2023-08-17 WW 2022-11-14 <20> <EFBFBD> <DEB8> ж<EFBFBD> LLN0$BR$brcbRDRE
processRDRE_start ( LD_info ) ;
else {
ied_t * ied ;
ied = find_ied_from_dev_code ( LD_info - > terminal_code ) ;
ied_usr_t * ied_usr = ( ied_usr_t * ) ied - > usr_ext ;
if ( rptinfo - > flickerflag = = 1 ) //CZY 2023-08-17 WW 2022-11-14 ֻ<> <D6BB> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ͵<EFBFBD> һ <EFBFBD> ν <EFBFBD> <CEBD> <EFBFBD> <EFBFBD> Ż<EFBFBD> <C5BB> <EFBFBD> ʼ <EFBFBD> <CABC> json_block_create_start(LD_info->line_id);
json_block_create_start ( LD_info - > voltage_level , LD_info - > mp_id , rptinfo - > flickerflag , ied_usr - > dev_type , LD_info - > line_id ) ;
else if ( rptinfo - > flickerflag = = 0 ) {
if ( LD_info - > rptRecvCheckFlag = = 0 )
json_block_create_start ( LD_info - > voltage_level , LD_info - > mp_id , rptinfo - > flickerflag , ied_usr - > dev_type , LD_info - > line_id ) ;
LD_info - > rptRecvCheckFlag | = 0x01 < < rptinfo - > rptNo ;
}
else if ( rptinfo - > flickerflag = = 2 ) {
if ( LD_info - > rptPstRecvCheckFlag = = 0 )
json_block_create_start ( LD_info - > voltage_level , LD_info - > mp_id , rptinfo - > flickerflag , ied_usr - > dev_type , LD_info - > line_id ) ;
LD_info - > rptPstRecvCheckFlag | = 0x01 < < rptinfo - > rptNo ;
}
}
}
/* HERE'S THE DATA. Check "Inclusion" to figure out what is being received.*/
for ( j = 0 ; j < rcb_info - > numDsVar ; + + j )
{
/*if (rcb_info->numDsVar==13) {
printf ( " bbbbbbbbbbbbbbbbbbbbbbbbb \n " ) ;
} */
if ( BSTR_BIT_GET ( InclusionData , j ) )
{
int ii ;
// SLOGCALWAYS3("Var# %02d: DataSet Var# %d: Name=%s", va_num, j,
// rcb_info->varNameArray[j]->obj_name.vmd_spec);
//printf("\n ----5.0--%d-\n", va_num);
log_var_data ( info_va [ va_num ] , & mms_dec_data ) ;
//assert(add_mms_dec_data== (uint32_t)&mms_dec_data);
va_num + + ;
//printf("\n ----5.1--%d-%d\n", va_num,mms_dec_data.item_num);
// if ( !pDataOMSObjects[j] ) continue;
//cout<<endl<<j<<" $ "<<AttrName[j]<<" $ "<<DataName[j]<<" = ";
//cout<<endl<<j<<" "<<DataObjectFullName[j]<<" "<<endl;
// cout<<" mms_dec_data.item_num ="<<(int)mms_dec_data.item_num<<endl;
long long time ;
for ( ii = 0 ; ii < mms_dec_data . item_num ; + + ii )
{
char * FULL_FCDA_Name ;
int length_FCDA ;
if ( strcmp ( mms_dec_data . data_item [ ii ] . comp_name , " " ) = = 0 )
FULL_FCDA_Name = apr_pstrdup ( g_pt61850app - > tmp_pool , DataObjectFullName [ j ] ) ;
else
FULL_FCDA_Name = apr_pstrcat ( g_pt61850app - > tmp_pool , DataObjectFullName [ j ] , " $ " , mms_dec_data . data_item [ ii ] . comp_name , NULL ) ;
length_FCDA = strlen ( FULL_FCDA_Name ) ;
if ( ( ' $ ' = = FULL_FCDA_Name [ length_FCDA - 2 ] ) & & ( ' t ' = = FULL_FCDA_Name [ length_FCDA - 1 ] ) )
{
apr_time_t t = convert_btime6_to_apr_time ( & ( mms_dec_data . data_item [ ii ] . u . data_bTime6 ) ) ;
time = t / 1000 ;
break ;
}
}
for ( ii = 0 ; ii < mms_dec_data . item_num ; + + ii ) //<2F> <> <EFBFBD> <EFBFBD> FCDA
{
char * FULL_FCDA_Name ;
int length_FCDA ;
//printf("\n ----5.11--%d-%s\n", va_num, mms_dec_data.data_item[ii].comp_name);
if ( strcmp ( mms_dec_data . data_item [ ii ] . comp_name , " " ) = = 0 )
FULL_FCDA_Name = apr_pstrdup ( g_pt61850app - > tmp_pool , DataObjectFullName [ j ] ) ;
else
FULL_FCDA_Name = apr_pstrcat ( g_pt61850app - > tmp_pool , DataObjectFullName [ j ] , " $ " , mms_dec_data . data_item [ ii ] . comp_name , NULL ) ;
// cout<<" FULL_FCDA_Name "<< FULL_FCDA_Name <<endl;
//printf("\n ----5.12--%d- %s \n", va_num, FULL_FCDA_Name);
length_FCDA = strlen ( FULL_FCDA_Name ) ;
//11 08 beijing <20> <> <EFBFBD> <EFBFBD> װ<EFBFBD> ò<EFBFBD> <C3B2> <EFBFBD> <EFBFBD> <EFBFBD> q
if ( ( ' $ ' = = FULL_FCDA_Name [ length_FCDA - 2 ] ) & & ( ' q ' = = FULL_FCDA_Name [ length_FCDA - 1 ] ) ) {
if ( not_set_rpt_q_this ) {
int flag = Set_q_from_61850rpt ( mms_dec_data . data_item [ ii ] . u . data_str ) ;
if ( strstr ( rcb_info - > RptID , " QVVR " ) ) { //CZY 2023-08-17 WW 2022-11-14 <20> <EFBFBD> <DEB8> ж<EFBFBD> LLN0$BR$brcbQVVR
//need do nothing!
not_set_rpt_q_this = FALSE ;
}
else if ( strstr ( rcb_info - > RptID , " RDRE " ) ) { //CZY 2023-08-17 WW 2022-11-14<31> <EFBFBD> <DEB8> ж<EFBFBD> LLN0$BR$brcbRDRE
//need do nothing!
not_set_rpt_q_this = FALSE ;
}
else if ( strstr ( FULL_FCDA_Name , " GGIO " ) )
{
not_set_rpt_q_this = FALSE ;
}
else {
json_block_create_flag ( LD_info - > mp_id , flag , rptinfo - > flickerflag ) ;
not_set_rpt_q_this = FALSE ;
}
}
}
else if ( ( ' $ ' = = FULL_FCDA_Name [ length_FCDA - 2 ] ) & & ( ' t ' = = FULL_FCDA_Name [ length_FCDA - 1 ] ) ) {
if ( not_set_rpt_TimeID_this ) {
apr_time_t t = convert_btime6_to_apr_time ( & ( mms_dec_data . data_item [ ii ] . u . data_bTime6 ) ) ;
if ( strstr ( rcb_info - > RptID , " QVVR " ) ) { //CZY 2023-08-17 WW 2022-11-14 <20> <EFBFBD> <DEB8> ж<EFBFBD> LLN0$BR$brcbQVVR
if ( strstr ( FULL_FCDA_Name , " VarStr$t " ) ) {
processQVVR_time ( LD_info , t / 1000 ) ;
not_set_rpt_TimeID_this = FALSE ;
}
}
else if ( strstr ( rcb_info - > RptID , " RDRE " ) ) { //CZY 2023-08-17 WW 2022-11-14<31> <EFBFBD> <DEB8> ж<EFBFBD> LLN0$BR$brcbRDRE
//need do nothing!
not_set_rpt_TimeID_this = FALSE ;
}
else if ( strstr ( FULL_FCDA_Name , " GGIO " ) ) { //CZY 2023-08-17 WW 2022-11-14<31> <EFBFBD> <DEB8> ж<EFBFBD> LLN0$BR$brcbRDRE
//need do nothing!
not_set_rpt_TimeID_this = FALSE ;
}
else {
json_block_create_time ( LD_info - > mp_id , t / 1000 , rptinfo - > flickerflag ) ;
printf ( " rcb_info->RptID=%s ,LineId=%d , Timestamp= %lld \n " , rcb_info - > RptID , LD_info - > line_id , t / 1000 ) ;
not_set_rpt_TimeID_this = FALSE ;
if ( strstr ( rcb_info - > RptID , " LLN0$RP$urcbRealData " ) ) {
//20241223lnk<6E> <6B> <EFBFBD> <EFBFBD> <EFBFBD> ն˺Ų<CBBA> <C5B2> <EFBFBD>
ied_usr_t * ied_usr = GET_IEDEXT_ADDR ( ied ) ;
if ( urcbRealDataHasReceived ( ied_usr - > dev_idx , LD_info , t / 1000 ) ) //<2F> ж<EFBFBD> ʱ<EFBFBD> <CAB1> <EFBFBD> ظ<EFBFBD>
return ;
}
}
}
}
else {
double v = 0.0 ;
if ( mms_dec_data . data_item [ ii ] . type = = DATA_INT_TYPE )
v = mms_dec_data . data_item [ ii ] . u . data_int ;
else if ( mms_dec_data . data_item [ ii ] . type = = DATA_UINT_TYPE )
v = mms_dec_data . data_item [ ii ] . u . data_uint ;
else if ( mms_dec_data . data_item [ ii ] . type = = DATA_INT64_TYPE )
v = ( double ) mms_dec_data . data_item [ ii ] . u . data_int64 ;
else if ( mms_dec_data . data_item [ ii ] . type = = DATA_UINT64_TYPE )
v = ( double ) mms_dec_data . data_item [ ii ] . u . data_uint64 ;
else if ( mms_dec_data . data_item [ ii ] . type = = DATA_DOUBLE_TYPE )
v = mms_dec_data . data_item [ ii ] . u . data_double ;
else if ( mms_dec_data . data_item [ ii ] . type = = DATA_STR_TYPE )
v = strtol ( mms_dec_data . data_item [ ii ] . u . data_str , NULL , 2 ) ;
//set_db_value(RPT_IDX,FULL_FCDA_Name,v, is_rpt_Time_exact_hour() );
if ( strstr ( rcb_info - > RptID , " QVVR " ) ) { //CZY 2023-08-17 WW 2022-11-14 <20> <EFBFBD> <DEB8> ж<EFBFBD> LLN0$BR$brcbQVVR
processQVVR_data ( LD_info , FULL_FCDA_Name , v ) ;
}
else if ( strstr ( rcb_info - > RptID , " RDRE " ) ) { //CZY 2023-08-17 WW 2022-11-14 <20> <EFBFBD> <DEB8> ж<EFBFBD> LLN0$BR$brcbRDRE
processRDRE_data ( LD_info , FULL_FCDA_Name , v ) ;
}
else if ( strstr ( FULL_FCDA_Name , " GGIO " ) )
{
ied_t * ied = LD_info - > ied ;
ied_usr_t * ied_usr = GET_IEDEXT_ADDR ( ied ) ;
processGGIO_start_data_end ( LD_info - > mp_id , FULL_FCDA_Name , v , time , ied_usr - > dev_type , LD_info - > line_id ) ; //GGIO<49> <4F> <EFBFBD> <EFBFBD> ȫ<EFBFBD> ״<EFBFBD> <D7B4> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
}
else
json_block_create_data ( LD_info - > mp_id , FULL_FCDA_Name , v , rptinfo - > flickerflag ) ;
} //else
}
}
}
if ( LD_info - > line_id > 0 ) {
//set_rpt_LineID(LD_info->line_id);
//set_line_info(RPT_IDX,LD_info->line_id,LD_info->SubV_Index,LD_info->Dev_Index,LD_info->Sub_Index,LD_info->GD_Index);
//write_updatetime_to_db(chnl_usr->chnl->addr);
if ( strstr ( rcb_info - > RptID , " QVVR " ) ) { //CZY 2023-08-17 WW 2022-11-14 <20> <EFBFBD> <DEB8> ж<EFBFBD> LLN0$BR$brcbQVVR
processQVVR_end ( LD_info ) ;
}
else if ( strstr ( rcb_info - > RptID , " RDRE " ) ) { //CZY 2023-08-17 WW 2022-11-14 <20> <EFBFBD> <DEB8> ж<EFBFBD> LLN0$BR$brcbRDRE
processRDRE_end ( LD_info ) ;
}
else {
printf ( " %d : %d " , LD_info - > rptRecvFlag , LD_info - > rptRecvCheckFlag ) ;
//append_db_records(RPT_IDX);
if ( rptinfo - > flickerflag = = 1 ) //CZY 2023-08-17 WW 2022-11-14 <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ־
{
//ied_usr_t* ied_usr = ied->usr_ext;//CZY 2023-08-17 WW 2022<32> <32> 12<31> <32> 6<EFBFBD> <36> 14:09:08 <20> <> <EFBFBD> Ӷ<EFBFBD> <D3B6> <EFBFBD> ICD֧<44> <D6A7>
//int devkind = ied_usr->dev_flag;
2025-02-14 16:44:38 +08:00
json_block_create_end ( LD_info - > v_wiring_type , LD_info - > mp_id , rptinfo - > flickerflag ) ; //lnk<6E> <6B> <EFBFBD> δ<EFBFBD> <CEB4> <EFBFBD>
2025-01-16 16:17:01 +08:00
}
else if ( rptinfo - > flickerflag = = 0 ) { //CZY 2023-08-17 WW 2022-11-14 <20> <> <EFBFBD> Ӷ<EFBFBD> <D3B6> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ж<EFBFBD>
if ( LD_info - > rptRecvFlag = = LD_info - > rptRecvCheckFlag ) {
//ied_usr_t* ied_usr = ied->usr_ext;//CZY 2023-08-17 WW 2022<32> <32> 12<31> <32> 6<EFBFBD> <36> 14:09:08 <20> <> <EFBFBD> Ӷ<EFBFBD> <D3B6> <EFBFBD> ICD֧<44> <D6A7>
//int devkind = ied_usr->dev_flag;
2025-02-14 16:44:38 +08:00
json_block_create_end ( LD_info - > v_wiring_type , LD_info - > mp_id , rptinfo - > flickerflag ) ; //lnk<6E> <6B> <EFBFBD> δ<EFBFBD> <CEB4> <EFBFBD>
2025-01-16 16:17:01 +08:00
LD_info - > rptRecvCheckFlag = 0 ;
}
}
else if ( rptinfo - > flickerflag = = 2 ) { //CZY 2023-08-17 WW 2022-11-14 <20> <> <EFBFBD> Ӷ<EFBFBD> <D3B6> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ж<EFBFBD>
if ( LD_info - > rptPstRecvFlag = = LD_info - > rptPstRecvCheckFlag ) {
//ied_usr_t* ied_usr = ied->usr_ext;//CZY 2023-08-17 WW 2022<32> <32> 12<31> <32> 6<EFBFBD> <36> 14:09:08 <20> <> <EFBFBD> Ӷ<EFBFBD> <D3B6> <EFBFBD> ICD֧<44> <D6A7>
//int devkind = ied_usr->dev_flag;
2025-02-14 16:44:38 +08:00
json_block_create_end ( LD_info - > v_wiring_type , LD_info - > mp_id , rptinfo - > flickerflag ) ; //lnk<6E> <6B> <EFBFBD> δ<EFBFBD> <CEB4> <EFBFBD>
2025-01-16 16:17:01 +08:00
LD_info - > rptPstRecvCheckFlag = 0 ;
}
}
}
}
else {
echo_err3 ( " Ignore this report due to line_id invalid , Report From %s %s %s !!! " ,
APR_EGENERAL , chnl_usr - > ip_str , LD_info - > LD_name , rcb_info - > RptID ) ;
}
printf ( " [END Process] Report From %s:%d %s %s ,va_total = %i ,<2C> <> count = %i<> <69> \n " ,
chnl_usr - > ip_str , chnl_usr - > chnl - > port , LD_info - > LD_name , rcb_info - > RptID , va_total , rptinfo - > count ) ;
//apr_time_t previousTimeend = apr_time_now();//
//apr_time_exp_t localTimeend;
//apr_time_exp_gmt(&localTimeend, previousTimeend);
//printf("\n ------>>>>>>> end time %d %d:%d:%d.%d \n",
// localTimeend.tm_mday, localTimeend.tm_hour, localTimeend.tm_min, localTimeend.tm_sec, localTimeend.tm_usec);
//printf("\n ----6-%d--\n", va_num);
/* If "reason" enabled, check "Inclusion" to figure out what is being received.*/
if ( BSTR_BIT_GET ( OptFldsData , OPTFLD_BITNUM_REASON ) ) {
for ( j = 0 ; j < rcb_info - > numDsVar ; + + j ) {
if ( BSTR_BIT_GET ( InclusionData , j ) ) {
// SLOGCALWAYS2("Var# %02d: Reason# %d", va_num, j);
//log_var_data (info_va[va_num],&mms_dec_data);
va_num + + ;
}
}
}
//<2F> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ӧʱ<D3A6> 䣬<EFBFBD> <E4A3AC> <EFBFBD> <EFBFBD> Ƶ<EFBFBD> <C6B5> <EFBFBD> ٻ<EFBFBD> װ<EFBFBD> <D7B0> <EFBFBD> <EFBFBD> <EFBFBD> ƣ<EFBFBD> <C6A3> <EFBFBD> <EFBFBD> ¶<EFBFBD> <C2B6> <EFBFBD> add on Aug 3 for testing of guangdong CRITICAL
chnl_usr - > m_LastPosRespTime = sGetMsTime ( ) ;
//assert (va_num==va_total); /* Did we count right? */
if ( va_num ! = va_total )
echo_err5 ( " va_num!=va_total! Report From %s %s %s , %d!=%d !!! " ,
APR_EGENERAL , chnl_usr - > ip_str , LD_info - > LD_name , rcb_info - > RptID , va_num , va_total ) ;
}
/************************************************************************/
/* object_name_clone_create */
/* Create clone of OBJECT_NAME struct. Can't just copy struct because */
/* struct contains pointers to strings. */
/* The function "object_name_clone_destroy" should be called to destroy */
/* the clone. */
/************************************************************************/
OBJECT_NAME * object_name_clone_create ( OBJECT_NAME * srcobj )
{
OBJECT_NAME * dstobj ;
size_t extended_size ;
ST_CHAR * extended_ptr ;
/* Allocate OBJECT_NAME structure plus extra room for additional data.
* This effectively combines 3 allocations into one .
* Set pointers in OBJECT_NAME structure to point into the extra space .
*/
extended_size = sizeof ( OBJECT_NAME )
+ MAX_IDENT_LEN + 1 /* dstobj->obj_name.vmd_spec */
+ MAX_IDENT_LEN + 1 ; /* dstobj->domain_id */
dstobj = ( OBJECT_NAME * ) chk_malloc ( extended_size ) ;
/* Copy old struct to new struct (before setting ptrs in new struct). */
memcpy ( dstobj , srcobj , sizeof ( OBJECT_NAME ) ) ;
/* Fix ptrs to strings in new struct */
extended_ptr = ( ST_CHAR * ) ( dstobj + 1 ) ; /* point after dstobj struct */
dstobj - > obj_name . vmd_spec = extended_ptr ;
extended_ptr + = ( MAX_IDENT_LEN + 1 ) ; /* point after dstobj->obj_name.vmd_spec*/
dstobj - > domain_id = extended_ptr ;
/* Copy strings to the new struct. */
strcpy ( dstobj - > obj_name . vmd_spec , srcobj - > obj_name . vmd_spec ) ;
if ( dstobj - > object_tag = = DOM_SPEC )
strcpy ( dstobj - > domain_id , srcobj - > domain_id ) ;
return ( dstobj ) ;
}
/************************************************************************/
/* object_name_clone_destroy */
/* Destroy OBJECT_NAME clone created by "object_name_clone_create". */
/************************************************************************/
ST_VOID object_name_clone_destroy ( OBJECT_NAME * obj )
{
/* allocated by object_name_clone_create using chk_malloc, so use chk_free.*/
chk_free ( obj ) ;
}
ST_RET check_va_count_too_big ( ST_INT va_current_count , ST_INT va_total )
{
if ( va_current_count < va_total ) {
return SD_SUCCESS ;
}
else {
echo_warn1 ( " report va total %d is so small,may be error \n " , va_total ) ;
return SD_FAILURE ;
}
}
/************************************************************************/
/* u_iec_rpt_ind */
/* This function processes ONLY IEC-61850 and UCA Reports. If any */
/* other InformationReport is received, it logs an error message and */
/* ignores it. */
/* CRITICAL: this function assumes that a pointer to an ALL_RCB_INFO */
/* structure has been saved in the */
/* user_info member of the MVL_NET_INFO structure for this conn. */
/************************************************************************/
ST_RET u_iec_rpt_ind_by_devtype ( MVL_COMM_EVENT * event )
{
INFO_REQ_INFO * info_ptr ;
ST_INT j , va_num , va_total ;
VAR_ACC_SPEC * va_spec ;
MVL_VAR_ASSOC * * info_va ;
RCB_INFO * rcb_info ;
ST_UINT8 * OptFldsData ; /* ptr to data part of OptFlds bvstring */
ST_UINT8 * InclusionData ; /* ptr to Inclusion bstring */
ST_CHAR saveRptID [ 66 ] ;
ALL_RCB_INFO * all_rcb_info ;
ST_RET retcode = SD_SUCCESS ;
info_ptr = ( INFO_REQ_INFO * ) event - > u . mms . dec_rslt . data_ptr ;
va_spec = & info_ptr - > va_spec ;
va_total = info_ptr - > num_of_acc_result ;
/* An IEC-61850 or UCA report must be a NamedVariableList named "RPT".
* Ignore any other InformationReport .
*/
if ( va_spec - > var_acc_tag ! = VAR_ACC_NAMEDLIST
| | strcmp ( va_spec - > vl_name . obj_name . vmd_spec , " RPT " ) ! = 0 )
{
echo_warn ( " Received InformationReport is not a IEC-61850 Report or UCA Report. Ignored. " ) ;
return ( SD_FAILURE ) ;
}
//////////////////
//WW 2023-08-29 <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ն<EFBFBD> <D5B6> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> 뱨<EFBFBD> <EBB1A8> rcb_info<66> <EFBFBD> <F3B6A8B4> <EFBFBD>
int port ; //<2F> ˿<EFBFBD>
RCB_INFO * rcb_info1 ;
ST_CHAR rptID [ MVL61850_MAX_RPTID_LEN + 1 ] = { 0 } ; //<2F> <> <EFBFBD> <EFBFBD> ID 66
ST_ULONG a_ip = get_rem_ip_addr_inline ( event - > net_info - > acse_conn_id , & port ) ; //WW 2023-08-29 <20> <> ȡװ<C8A1> <D7B0> IP<49> <50> <EFBFBD> ˿ں<CBBF>
ST_CHAR * p_ip = _convert_ip_2_char ( htonl ( a_ip ) ) ; //WW 2023-08-29 <20> <> IPתΪ<D7AA> ַ<EFBFBD> <D6B7> <EFBFBD> ָ<EFBFBD> <D6B8> <20> <> <EFBFBD> <EFBFBD> 192.168.1.238
if ( gDev_rcb_list . dev_rcb_info_Head = = NULL ) //ȫ<> ֱ<EFBFBD> <D6B1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ƿ<EFBFBD> ָ<EFBFBD> <D6B8> || gDev_rcb_list->rcb_info_list == NULL
{
//SLOGALWAYS0 ("Received InformationReport. No IEC-61850 or UCA RCB enabled. Ignored.");
//LOG_INFO("<22> յ<EFBFBD> <D5B5> <EFBFBD> <EFBFBD> 棬δ<E6A3AC> <CEB4> <EFBFBD> <EFBFBD> IEC-61850<35> <30> UCA RCBʹ <42> ܡ<EFBFBD> <DCA1> <EFBFBD> <EFBFBD> ԣ<EFBFBD> "); //<2F> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʹ <EFBFBD> ã<EFBFBD> zl 2019-1-23 09:10:39
return ( SD_FAILURE ) ;
}
//<2F> <EFBFBD> <DFBC> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> װ<EFBFBD> <D7B0> IP<49> <50> <EFBFBD> ˿ںţ<DABA> <C5A3> <EFBFBD> <EFBFBD> ҵ<EFBFBD> װ<EFBFBD> <D7B0> <EFBFBD> <EFBFBD> <EFBFBD> ͣ<EFBFBD> <CDA3> <EFBFBD> ƥ<EFBFBD> 䱨<EFBFBD> <E4B1A8> <EFBFBD> <EFBFBD> Ϣ<EFBFBD> <CFA2> <EFBFBD> ٽ<EFBFBD> <D9BD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> 棡2019-12-24 17:27:29
//װ<> <D7B0> <EFBFBD> <EFBFBD> <EFBFBD> Ͳ<EFBFBD> <CDB2> <EFBFBD> <EFBFBD> ж<EFBFBD> ------------------------------------------------------------------------------------------------------------------------------
Dev_RCB_INFO * dev_rcb = NULL ; //װ<> ñ<EFBFBD> <C3B1> <EFBFBD> <EFBFBD> ṹָ<E1B9B9> <D6B8>
Dev_IP_Port_INFO * dev_info = NULL ; //װ<> <D7B0> IP<49> <50> <EFBFBD> ˿ںŽṹָ<E1B9B9> <D6B8>
ST_BOOLEAN bFindIpPort = 0 ; //<2F> Ƿ<EFBFBD> <C7B7> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ƥ<EFBFBD> 䵽װ<E4B5BD> <D7B0> IP<49> <50> <EFBFBD> ˿ں<CBBF>
for ( dev_rcb = gDev_rcb_list . dev_rcb_info_Head ; dev_rcb ! = NULL ; dev_rcb = ( Dev_RCB_INFO * ) list_get_next ( gDev_rcb_list . dev_rcb_info_Head , dev_rcb ) ) //<2F> ٱ<EFBFBD> <D9B1> <EFBFBD> ȫ<> <C8AB> װ<EFBFBD> ñ<EFBFBD> <C3B1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ƿ<EFBFBD> <C6BF> <EFBFBD> <EFBFBD> <EFBFBD>
{
//LOG_INFO("(<28> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> )<29> <> <EFBFBD> <EFBFBD> gDev_rcb_list<73> <74> <EFBFBD> <EFBFBD> , dev_type_name= %s", dev_rcb->dev_type_name); //<2F> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʹ <EFBFBD> ã<EFBFBD> zl 2019-12-24 00:16:31
//װ<> <D7B0> IP<49> <50> <EFBFBD> ˿ںŲ<DABA> <C5B2> <EFBFBD> <EFBFBD> ж<EFBFBD> -------------------------------------------------------------------------------------------------------------------------------------------------------------------
for ( dev_info = dev_rcb - > dev_ip_port_list ; dev_info ! = NULL ; dev_info = ( Dev_IP_Port_INFO * ) list_get_next ( dev_rcb - > dev_ip_port_list , dev_info ) ) //<2F> ڱ<EFBFBD> <DAB1> <EFBFBD> ȫ<> <C8AB> װ<EFBFBD> <D7B0> IP<49> <50> <EFBFBD> ˿<EFBFBD> <CBBF> <EFBFBD> <EFBFBD> <EFBFBD>
{
//LOG_INFO("(<28> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> )<29> <> <EFBFBD> <EFBFBD> dev_ip_port_list<73> <74> <EFBFBD> <EFBFBD> , dev_type_name= %s, ip= %s, port= %d", dev_rcb->dev_type_name, dev_info->IP, dev_info->Port); //<2F> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʹ <EFBFBD> ã<EFBFBD> zl 2019-12-24 00:16:31
if ( ( strcmp ( dev_info - > IP , p_ip ) = = 0 ) & & ( dev_info - > Port = = port ) ) //ƥ<> <C6A5> װ<> <D7B0> IP && <20> ˿ں<CBBF>
{
bFindIpPort = 1 ; //<2F> <> <EFBFBD> ҵ<EFBFBD> װ<EFBFBD> <D7B0> IP && <20> ˿ں<CBBF>
//LOG_INFO("(<28> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> )ƥ<> 䵽װ<E4B5BD> <D7B0> dev_type_name= %s, IP= %s<> <73> Port= %d", dev_rcb->dev_type_name, dev_info->IP, dev_info->Port); //<2F> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʹ <EFBFBD> ã<EFBFBD> zl 2019-12-24 00:23:55
//strcpy(dev_rcb->dev_type_name, dev_rcb->dev_type_name); //ƥ<> <C6A5> װ<> <D7B0> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
break ;
}
} //<2F> <> <EFBFBD> <EFBFBD> װ<> <D7B0> IP<49> <50> <EFBFBD> ˿<EFBFBD> <CBBF> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD>
if ( bFindIpPort ) //<2F> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ƥ<EFBFBD> 䵽װ<E4B5BD> <D7B0> IP<49> <50> <EFBFBD> ˿ں<CBBF>
break ;
} //<2F> <> <EFBFBD> <EFBFBD> ȫ<> <C8AB> װ<EFBFBD> ñ<EFBFBD> <C3B1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ƿ<EFBFBD> <C6BF> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD>
if ( ! bFindIpPort ) //δ<> <CEB4> <EFBFBD> ҵ<EFBFBD> װ<EFBFBD> <D7B0> IP<49> <50> <EFBFBD> ˿<EFBFBD>
{
//LOG_INFO("(<28> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> )dev_type_name= %sδƥ<CEB4> 䵽IP= %s<> <73> Port= %d<> <64> װ<EFBFBD> <D7B0> <EFBFBD> <EFBFBD> <EFBFBD> ͣ<EFBFBD> goto CLEANUP<55> <50> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ", dev_rcb->dev_type_name, p_ip, port); //<2F> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʹ <EFBFBD> ã<EFBFBD> zl 2019-12-24 00:23:55
retcode = SD_FAILURE ;
goto END ; //<2F> <> ת<EFBFBD> <D7AA> CLEANUP<55> <50> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> retcode<64> <65> <EFBFBD> <EFBFBD>
}
rcb_info = dev_rcb - > rcb_info_list ; //<2F> <> <EFBFBD> <EFBFBD> װ<EFBFBD> <D7B0> <EFBFBD> <EFBFBD> <EFBFBD> ͣ<EFBFBD> ƥ<EFBFBD> 䱨<EFBFBD> <E4B1A8> <EFBFBD> <EFBFBD> <EFBFBD> ƿ<EFBFBD> <C6BF> <EFBFBD> Ϣ
//WW 2023-08-29 end
//////////////////////////////
/* Get "all_rcb_info" from "user_info". User must set "user_info" when conn established.*/
//////////////////////
//WW 2023-08-29ע<39> <D7A2>
//all_rcb_info = (ALL_RCB_INFO*)event->net_info->user_info;
///* Check "all_rcb_info" to see if any RCB has been enabled. */
//if (all_rcb_info == NULL || all_rcb_info->rcb_info_list == NULL)
//{
// echo_warn("Received InformationReport. No IEC-61850 or UCA RCB enabled. Ignored.");
// return (SD_FAILURE);
//}
//WW 2023-08-29 end
////////////////////////
/* Create array of (MVL_VAR_ASSOC *) needed for converting the received
* data to local format .
* Use variables created earlier to fill in the array . These variables will
* hold the decoded data .
* NOTE : any return after this must free info_va ( see CLEANUP label ) .
*/
info_va = ( MVL_VAR_ASSOC * * ) chk_calloc ( va_total ,
sizeof ( MVL_VAR_ASSOC * ) ) ;
//////////////////
//WW 2023-08-29 <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ն<EFBFBD> <D5B6> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> 뱨<EFBFBD> <EBB1A8> rcb_info<66> <EFBFBD> <F3B6A8B4> <EFBFBD>
rcb_info = dev_rcb - > rcb_info_list ; //<2F> <> <EFBFBD> <EFBFBD> װ<EFBFBD> <D7B0> <EFBFBD> <EFBFBD> <EFBFBD> ͣ<EFBFBD> ƥ<EFBFBD> 䱨<EFBFBD> <E4B1A8> <EFBFBD> <EFBFBD> <EFBFBD> ƿ<EFBFBD> <C6BF> <EFBFBD> Ϣ
va_num = 0 ;
info_va [ va_num + + ] = rcb_info - > rcb_var . RptID ;
//LOG_INFO("va_num = %d", va_num); //<2F> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʹ <EFBFBD> ã<EFBFBD> zl 2019-1-23 09:10:39
all_rcb_info = ( ALL_RCB_INFO * ) chk_calloc ( 1 , sizeof ( ALL_RCB_INFO ) ) ;
all_rcb_info - > rpt_typeids = & g_rpt_typeids ;
all_rcb_info - > rcb_info_list = dev_rcb - > rcb_info_list ;
event - > net_info - > user_info = all_rcb_info ;
rcb_info = all_rcb_info - > rcb_info_list ;
rcb_info - > rcb_data . RptID [ 0 ] = ' \0 ' ; /* start with empty string */
mvl_info_data_to_local ( event , va_num , info_va ) ; //<2F> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ת<EFBFBD> <D7AA> Ϊ<EFBFBD> <CEAA> <EFBFBD> ظ<EFBFBD> ʽ
/* NOTE: decoded RptID is now in "rcb_info->rcb_data.RptID". Save it.*/
strcpy ( saveRptID , rcb_info - > rcb_data . RptID ) ; //װ<> <D7B0> <EFBFBD> <EFBFBD> <EFBFBD> ͱ<EFBFBD> <CDB1> <EFBFBD> ID <20> <> <EFBFBD> <EFBFBD> PQM2/LLN0$BR$brcbStatisticData01
//LOG_INFO("װ<> <D7B0> <EFBFBD> <EFBFBD> <EFBFBD> ͱ<EFBFBD> <CDB1> <EFBFBD> saveRptID<49> <44> %s", saveRptID); //<2F> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʹ <EFBFBD> ã<EFBFBD> zl 2019-1-23 09:10:39
chk_free ( all_rcb_info ) ;
event - > net_info - > user_info = NULL ;
/* Search list of "rcb_info" to find one with matching RptID. If not found, rcb_info will be == NULL. */
//װ<> ñ<EFBFBD> <C3B1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ƿ<EFBFBD> <C6BF> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ж<EFBFBD> -----------------------------------------------------------------------------------------------------------------------------------------------------
for ( rcb_info = dev_rcb - > rcb_info_list ; rcb_info ! = NULL ; rcb_info = ( RCB_INFO * ) list_get_next ( dev_rcb - > rcb_info_list , rcb_info ) ) //<2F> <> <EFBFBD> <EFBFBD> ȫ<> ֱ<EFBFBD> <D6B1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ƿ<EFBFBD> <C6BF> <EFBFBD> <EFBFBD> <EFBFBD>
{
//LOG_INFO("<22> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ƿ<EFBFBD> <C6BF> <EFBFBD> <EFBFBD> <EFBFBD> RptID<49> <44> %s<> <73> saveRptID<49> <44> %s", rcb_info->RptID, saveRptID); //<2F> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʹ <EFBFBD> ã<EFBFBD> zl 2019-1-23 09:10:39
if ( strcmp ( rcb_info - > RptID , saveRptID ) = = 0 )
break ; /* rcb_info now points to right structure */
}
if ( ! rcb_info ) //<2F> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ƿ<EFBFBD> ָ<EFBFBD> <D6B8> Ϊ<EFBFBD> գ <EFBFBD>
{
//SLOGALWAYS1 ("RptID '%s' not recognized on this connection. Received report ignored.", saveRptID);
//LOG_INFO("(<28> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> )<29> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ƿ<EFBFBD> <C6BF> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ҳ<EFBFBD> <D2B2> <EFBFBD> RptID= '%s'<27> <> goto CLEANUP<55> <50> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ", saveRptID); //<2F> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʹ <EFBFBD> ã<EFBFBD> zl 2019-12-23 15:09:36
retcode = SD_FAILURE ;
goto CLEANUP ; //<2F> <> ת<EFBFBD> <D7AA> CLEANUP<55> <50> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> retcode<64> <65> <EFBFBD> <EFBFBD>
}
//WW 2023-08-29 end
//////////////////////////////
//////////////////////
//WW 2023-08-29ע<39> <D7A2>
///* Must decode the RptID first to find the correct RCB_INFO. Could decode into
//* any "vstring65" variable. We just use the RptID variable from the first
//* rcb_info on the list.
//*/
//rcb_info = all_rcb_info->rcb_info_list; /* use first rcb_info on list*/
//va_num = 0;
//info_va[va_num++] = rcb_info->rcb_var.RptID;
//rcb_info->rcb_data.RptID[0] = '\0'; /* start with empty string */
//mvl_info_data_to_local(event, va_num, info_va);
///* NOTE: decoded RptID is now in "rcb_info->rcb_data.RptID". Save it.*/
//strcpy(saveRptID, rcb_info->rcb_data.RptID);
///* Search list of "rcb_info" to find one with matching RptID. */
///* If not found, rcb_info will be == NULL. */
//for (rcb_info = all_rcb_info->rcb_info_list;
// rcb_info != NULL;
// rcb_info = (RCB_INFO*)list_get_next(all_rcb_info->rcb_info_list, rcb_info))
//{
// if (strcmp(rcb_info->RptID, saveRptID) == 0)
// break; /* rcb_info now points to right structure */
//}
//if (!rcb_info)
//{
// echo_warn1("RptID '%s' not recognized on this connection. Received report ignored.", saveRptID);
// retcode = SD_FAILURE;
// goto CLEANUP;
//}
//WW 2023-08-29 end
////////////////////////
va_num = 0 ;
info_va [ va_num + + ] = rcb_info - > rcb_var . RptID ;
if ( ( retcode = check_va_count_too_big ( va_num , va_total ) ) = = SD_FAILURE ) goto CLEANUP ;
info_va [ va_num + + ] = rcb_info - > rcb_var . OptFlds ;
if ( ( retcode = check_va_count_too_big ( va_num , va_total ) ) = = SD_FAILURE ) goto CLEANUP ;
/* Perform 1st decode (up through "OptFlds"). Need "OptFlds" to figure
* out what comes next .
*/
mvl_info_data_to_local ( event , va_num , info_va ) ;
/* Examine "OptFlds", and set up 2nd decode to decode all options */
OptFldsData = rcb_info - > rcb_data . OptFlds . data_1 ; /* use local var */
// printf ("OptFlds = 0x%02x 0x%02x\n", OptFldsData[0],OptFldsData[1]); /* 9 bit bstr (2 bytes) */
/* NOTE: Don't change initial entries in "info_va". Add these right after "OptFlds".*/
if ( BSTR_BIT_GET ( OptFldsData , OPTFLD_BITNUM_SQNUM ) )
info_va [ va_num + + ] = rcb_info - > rcb_var . SqNum ;
if ( ( retcode = check_va_count_too_big ( va_num , va_total ) ) = = SD_FAILURE ) goto CLEANUP ;
if ( BSTR_BIT_GET ( OptFldsData , OPTFLD_BITNUM_TIMESTAMP ) )
info_va [ va_num + + ] = rcb_info - > rcb_var . TimeOfEntry ;
if ( ( retcode = check_va_count_too_big ( va_num , va_total ) ) = = SD_FAILURE ) goto CLEANUP ;
if ( BSTR_BIT_GET ( OptFldsData , OPTFLD_BITNUM_DATSETNAME ) )
{
info_va [ va_num + + ] = rcb_info - > rcb_var . DatSetNa ;
///////////////////
//WW 2023-08-29
log_var_to_data ( rcb_info - > rcb_var . DatSetNa , rptID ) ;
//for (rcb_info1 = all_rcb_info->rcb_info_list;
// rcb_info1 != NULL;
// rcb_info1 = (RCB_INFO *) list_get_next (all_rcb_info->rcb_info_list, rcb_info1)) //<2F> <> <EFBFBD> <EFBFBD> װ<> ñ<EFBFBD> <C3B1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ƿ<EFBFBD> <C6BF> <EFBFBD> <EFBFBD> <EFBFBD>
for ( rcb_info1 = dev_rcb - > rcb_info_list ;
rcb_info1 ! = NULL ;
rcb_info1 = ( RCB_INFO * ) list_get_next ( dev_rcb - > rcb_info_list , rcb_info1 ) ) //<2F> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ƿ<EFBFBD> <C6BF> <EFBFBD> <EFBFBD> <EFBFBD>
{
if ( strcmp ( rcb_info1 - > ds_Nam , rptID ) = = 0 ) //<2F> <> <EFBFBD> <EFBFBD> ID<49> <44> <EFBFBD> <EFBFBD> Ϊ<EFBFBD> <CEAA> ͬ<EFBFBD> <CDAC> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ψһ <CEA8> <D2BB> ʶ<EFBFBD> <CAB6>
{
//SLOGALWAYS3 ("Num of var received in RPT (%d) does not match expected (%d)dateSet=%s ", va_total, va_num,rptID);
//LOG_INFO("(<28> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> )<29> <> <EFBFBD> ձ<EFBFBD> <D5B1> <EFBFBD> RptID= '%s'<27> <> <EFBFBD> ݼ<EFBFBD> rptID= %s<> <73> <EFBFBD> <EFBFBD> С (%d)<29> <> Ԥ<EFBFBD> ڴ<EFBFBD> С (%d)<29> <> ƥ<EFBFBD> 䣬brak<61> <6B> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ", saveRptID, rptID, va_total, va_num); //<2F> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʹ <EFBFBD> ã<EFBFBD> zl 2019-12-23 15:09:30
rcb_info = rcb_info1 ;
break ;
}
}
//WW 2023-08-29 en
///////////////////////////
}
if ( ( retcode = check_va_count_too_big ( va_num , va_total ) ) = = SD_FAILURE ) goto CLEANUP ;
/* The following optional vars are supported by IEC-61850 but they are
* NOT supported by UCA . This client must NOT set these OptFlds bits
* when connected to a UCA server , and these variables will NOT be
* included in a report received from a UCA server .
*/
if ( BSTR_BIT_GET ( OptFldsData , OPTFLD_BITNUM_BUFOVFL ) )
info_va [ va_num + + ] = rcb_info - > rcb_var . BufOvfl ;
if ( ( retcode = check_va_count_too_big ( va_num , va_total ) ) = = SD_FAILURE ) goto CLEANUP ;
if ( BSTR_BIT_GET ( OptFldsData , OPTFLD_BITNUM_ENTRYID ) )
info_va [ va_num + + ] = rcb_info - > rcb_var . EntryID ;
if ( ( retcode = check_va_count_too_big ( va_num , va_total ) ) = = SD_FAILURE ) goto CLEANUP ;
if ( BSTR_BIT_GET ( OptFldsData , OPTFLD_BITNUM_CONFREV ) )
info_va [ va_num + + ] = rcb_info - > rcb_var . ConfRev ;
if ( ( retcode = check_va_count_too_big ( va_num , va_total ) ) = = SD_FAILURE ) goto CLEANUP ;
if ( BSTR_BIT_GET ( OptFldsData , OPTFLD_BITNUM_SUBSEQNUM ) )
{
info_va [ va_num + + ] = rcb_info - > rcb_var . SubSeqNum ;
if ( ( retcode = check_va_count_too_big ( va_num , va_total ) ) = = SD_FAILURE ) goto CLEANUP ;
info_va [ va_num + + ] = rcb_info - > rcb_var . MoreSegmentsFollow ;
if ( ( retcode = check_va_count_too_big ( va_num , va_total ) ) = = SD_FAILURE ) goto CLEANUP ;
}
info_va [ va_num + + ] = rcb_info - > rcb_var . Inclusion ;
if ( ( retcode = check_va_count_too_big ( va_num , va_total ) ) = = SD_FAILURE ) goto CLEANUP ;
assert ( va_num < va_total ) ;
/* Perform 2nd decode (up through "Inclusion"). */
mvl_info_data_to_local ( event , va_num , info_va ) ;
/* Examine "Inclusion", and set up 3rd decode to decode all data. */
InclusionData = rcb_info - > rcb_data . Inclusion ; /* use local var */
// printf ("\nThe 1st byte Inclusion = 0x%02X\n", InclusionData[0]); /* Just print 1st byte */
/* NOTE: Don't change initial entries in "info_va". Add these right after "Inclusion".*/
/* If "data-Ref" enabled, check "Inclusion" to figure out what is being received.*/
if ( BSTR_BIT_GET ( OptFldsData , OPTFLD_BITNUM_DATAREF ) )
{
for ( j = 0 ; j < rcb_info - > numDsVar ; + + j )
{
if ( BSTR_BIT_GET ( InclusionData , j ) ) {
info_va [ va_num + + ] = rcb_info - > rcb_var . dataRefName [ j ] ;
if ( ( retcode = check_va_count_too_big ( va_num , va_total ) ) = = SD_FAILURE ) goto CLEANUP ;
}
}
}
/* HERE'S THE DATA. Check "Inclusion" to figure out what is being received.*/
for ( j = 0 ; j < rcb_info - > numDsVar ; + + j )
{
if ( BSTR_BIT_GET ( InclusionData , j ) ) {
info_va [ va_num + + ] = rcb_info - > rcb_var . dataValue [ j ] ;
if ( ( retcode = check_va_count_too_big ( va_num , va_total ) ) = = SD_FAILURE ) goto CLEANUP ;
}
}
/* If "reason" enabled, check "Inclusion" to figure out what is being received.*/
if ( BSTR_BIT_GET ( OptFldsData , OPTFLD_BITNUM_REASON ) )
{
for ( j = 0 ; j < rcb_info - > numDsVar ; + + j )
{
if ( BSTR_BIT_GET ( InclusionData , j ) ) {
info_va [ va_num + + ] = rcb_info - > rcb_var . Reason [ j ] ;
}
}
}
/* Does num of variables received match expected num.*/
if ( va_num ! = va_total )
{
echo_warn2 ( " Num of var received in RPT (%d) does not match expected (%d). Possibly incorrect OptFlds or inclusion bitstring " , va_total , va_num ) ;
// printf ("Num of var received in RPT (%d) does not match expected (%d). Possibly incorrect OptFlds or inclusion bitstring\n", va_total, va_num);
}
else
{
/* Perform 3rd decode (everything). */
mvl_info_data_to_local ( event , va_num , info_va ) ;
u_iec_rpt_ind_data_by_devtype ( info_va , OptFldsData , InclusionData , rcb_info , va_total , event - > net_info ) ;
}
CLEANUP :
chk_free ( info_va ) ;
END :
return ( retcode ) ;
}
ST_RET u_iec_rpt_ind ( MVL_COMM_EVENT * event )
{
INFO_REQ_INFO * info_ptr ;
ST_INT j , va_num , va_total ;
VAR_ACC_SPEC * va_spec ;
MVL_VAR_ASSOC * * info_va ;
RCB_INFO * rcb_info , * rcb_info1 ;
ST_UINT8 * OptFldsData ; /* ptr to data part of OptFlds bvstring */
ST_UINT8 * InclusionData ; /* ptr to Inclusion bstring */
ST_CHAR saveRptID [ 66 ] ;
ALL_RCB_INFO * all_rcb_info ;
ST_RET retcode = SD_SUCCESS ;
info_ptr = ( INFO_REQ_INFO * ) event - > u . mms . dec_rslt . data_ptr ;
va_spec = & info_ptr - > va_spec ;
va_total = info_ptr - > num_of_acc_result ;
/* An IEC-61850 or UCA report must be a NamedVariableList named "RPT".
* Ignore any other InformationReport .
*/
if ( va_spec - > var_acc_tag ! = VAR_ACC_NAMEDLIST
| | strcmp ( va_spec - > vl_name . obj_name . vmd_spec , " RPT " ) ! = 0 )
{
echo_warn ( " Received InformationReport is not a IEC-61850 Report or UCA Report. Ignored. " ) ;
return ( SD_FAILURE ) ;
}
/* Get "all_rcb_info" from "user_info". User must set "user_info" when conn established.*/
all_rcb_info = ( ALL_RCB_INFO * ) event - > net_info - > user_info ;
/* Check "all_rcb_info" to see if any RCB has been enabled. */
if ( all_rcb_info = = NULL | | all_rcb_info - > rcb_info_list = = NULL )
{
echo_warn ( " Received InformationReport. No IEC-61850 or UCA RCB enabled. Ignored. " ) ;
return ( SD_FAILURE ) ;
}
/* Create array of (MVL_VAR_ASSOC *) needed for converting the received
* data to local format .
* Use variables created earlier to fill in the array . These variables will
* hold the decoded data .
* NOTE : any return after this must free info_va ( see CLEANUP label ) .
*/
info_va = ( MVL_VAR_ASSOC * * ) chk_calloc ( va_total ,
sizeof ( MVL_VAR_ASSOC * ) ) ;
/* Must decode the RptID first to find the correct RCB_INFO. Could decode into
* any " vstring65 " variable . We just use the RptID variable from the first
* rcb_info on the list .
*/
rcb_info = all_rcb_info - > rcb_info_list ; /* use first rcb_info on list*/
va_num = 0 ;
info_va [ va_num + + ] = rcb_info - > rcb_var . RptID ;
rcb_info - > rcb_data . RptID [ 0 ] = ' \0 ' ; /* start with empty string */
mvl_info_data_to_local ( event , va_num , info_va ) ;
/* NOTE: decoded RptID is now in "rcb_info->rcb_data.RptID". Save it.*/
strcpy ( saveRptID , rcb_info - > rcb_data . RptID ) ;
/* Search list of "rcb_info" to find one with matching RptID. */
/* If not found, rcb_info will be == NULL. */
for ( rcb_info = all_rcb_info - > rcb_info_list ;
rcb_info ! = NULL ;
rcb_info = ( RCB_INFO * ) list_get_next ( all_rcb_info - > rcb_info_list , rcb_info ) )
{
if ( strcmp ( rcb_info - > RptID , saveRptID ) = = 0 )
break ; /* rcb_info now points to right structure */
}
if ( ! rcb_info )
{
echo_warn1 ( " RptID '%s' not recognized on this connection. Received report ignored. " , saveRptID ) ;
retcode = SD_FAILURE ;
goto CLEANUP ;
}
va_num = 0 ;
info_va [ va_num + + ] = rcb_info - > rcb_var . RptID ;
if ( ( retcode = check_va_count_too_big ( va_num , va_total ) ) = = SD_FAILURE ) goto CLEANUP ;
info_va [ va_num + + ] = rcb_info - > rcb_var . OptFlds ;
if ( ( retcode = check_va_count_too_big ( va_num , va_total ) ) = = SD_FAILURE ) goto CLEANUP ;
/* Perform 1st decode (up through "OptFlds"). Need "OptFlds" to figure
* out what comes next .
*/
mvl_info_data_to_local ( event , va_num , info_va ) ;
/* Examine "OptFlds", and set up 2nd decode to decode all options */
OptFldsData = rcb_info - > rcb_data . OptFlds . data_1 ; /* use local var */
// printf ("OptFlds = 0x%02x 0x%02x\n", OptFldsData[0],OptFldsData[1]); /* 9 bit bstr (2 bytes) */
/* NOTE: Don't change initial entries in "info_va". Add these right after "OptFlds".*/
if ( BSTR_BIT_GET ( OptFldsData , OPTFLD_BITNUM_SQNUM ) )
info_va [ va_num + + ] = rcb_info - > rcb_var . SqNum ;
if ( ( retcode = check_va_count_too_big ( va_num , va_total ) ) = = SD_FAILURE ) goto CLEANUP ;
if ( BSTR_BIT_GET ( OptFldsData , OPTFLD_BITNUM_TIMESTAMP ) )
info_va [ va_num + + ] = rcb_info - > rcb_var . TimeOfEntry ;
if ( ( retcode = check_va_count_too_big ( va_num , va_total ) ) = = SD_FAILURE ) goto CLEANUP ;
//WW 2024-09-02 <20> <> <EFBFBD> ݼ<EFBFBD> <DDBC> <EFBFBD> <EFBFBD> <EFBFBD> ȷ<EFBFBD> <C8B7>
if ( BSTR_BIT_GET ( OptFldsData , OPTFLD_BITNUM_DATSETNAME ) )
info_va [ va_num + + ] = rcb_info - > rcb_var . DatSetNa ;
mvl_info_data_to_local ( event , va_num , info_va ) ;
//WW 2024-09-02 endss
if ( BSTR_BIT_GET ( OptFldsData , OPTFLD_BITNUM_DATSETNAME ) )
{
//info_va[va_num++] = rcb_info->rcb_var.DatSetNa; //WW 2024-09-02 ע<> <D7A2>
///////////////////
//WW 2023-08-29
log_var_to_data ( rcb_info - > rcb_var . DatSetNa , saveRptID ) ;
for ( rcb_info1 = all_rcb_info - > rcb_info_list ;
rcb_info1 ! = NULL ;
rcb_info1 = ( RCB_INFO * ) list_get_next ( all_rcb_info - > rcb_info_list , rcb_info1 ) ) //<2F> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ƿ<EFBFBD> <C6BF> <EFBFBD> <EFBFBD> <EFBFBD>
{
if ( strcmp ( rcb_info1 - > ds_Nam , saveRptID ) = = 0 ) //<2F> <> <EFBFBD> <EFBFBD> ID<49> <44> <EFBFBD> <EFBFBD> Ϊ<EFBFBD> <CEAA> ͬ<EFBFBD> <CDAC> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ψһ <CEA8> <D2BB> ʶ<EFBFBD> <CAB6>
{
printf ( " ds_name '%s' ! Recive name %s WWTest \n " , rcb_info1 - > ds_Nam , saveRptID ) ;
//SLOGALWAYS3 ("Num of var received in RPT (%d) does not match expected (%d)dateSet=%s ", va_total, va_num,rptID);
//LOG_INFO("(<28> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> )<29> <> <EFBFBD> ձ<EFBFBD> <D5B1> <EFBFBD> RptID= '%s'<27> <> <EFBFBD> ݼ<EFBFBD> rptID= %s<> <73> <EFBFBD> <EFBFBD> С (%d)<29> <> Ԥ<EFBFBD> ڴ<EFBFBD> С (%d)<29> <> ƥ<EFBFBD> 䣬brak<61> <6B> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ", saveRptID, rptID, va_total, va_num); //<2F> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʹ <EFBFBD> ã<EFBFBD> zl 2019-12-23 15:09:30
rcb_info = rcb_info1 ;
break ;
}
}
//WW 2023-08-29 en
///////////////////////////
}
if ( ( retcode = check_va_count_too_big ( va_num , va_total ) ) = = SD_FAILURE ) goto CLEANUP ;
/* The following optional vars are supported by IEC-61850 but they are
* NOT supported by UCA . This client must NOT set these OptFlds bits
* when connected to a UCA server , and these variables will NOT be
* included in a report received from a UCA server .
*/
if ( BSTR_BIT_GET ( OptFldsData , OPTFLD_BITNUM_BUFOVFL ) )
info_va [ va_num + + ] = rcb_info - > rcb_var . BufOvfl ;
if ( ( retcode = check_va_count_too_big ( va_num , va_total ) ) = = SD_FAILURE ) goto CLEANUP ;
if ( BSTR_BIT_GET ( OptFldsData , OPTFLD_BITNUM_ENTRYID ) )
info_va [ va_num + + ] = rcb_info - > rcb_var . EntryID ;
if ( ( retcode = check_va_count_too_big ( va_num , va_total ) ) = = SD_FAILURE ) goto CLEANUP ;
if ( BSTR_BIT_GET ( OptFldsData , OPTFLD_BITNUM_CONFREV ) )
info_va [ va_num + + ] = rcb_info - > rcb_var . ConfRev ;
if ( ( retcode = check_va_count_too_big ( va_num , va_total ) ) = = SD_FAILURE ) goto CLEANUP ;
if ( BSTR_BIT_GET ( OptFldsData , OPTFLD_BITNUM_SUBSEQNUM ) )
{
info_va [ va_num + + ] = rcb_info - > rcb_var . SubSeqNum ;
if ( ( retcode = check_va_count_too_big ( va_num , va_total ) ) = = SD_FAILURE ) goto CLEANUP ;
info_va [ va_num + + ] = rcb_info - > rcb_var . MoreSegmentsFollow ;
if ( ( retcode = check_va_count_too_big ( va_num , va_total ) ) = = SD_FAILURE ) goto CLEANUP ;
}
info_va [ va_num + + ] = rcb_info - > rcb_var . Inclusion ;
if ( ( retcode = check_va_count_too_big ( va_num , va_total ) ) = = SD_FAILURE ) goto CLEANUP ;
assert ( va_num < va_total ) ;
/* Perform 2nd decode (up through "Inclusion"). */
mvl_info_data_to_local ( event , va_num , info_va ) ;
/* Examine "Inclusion", and set up 3rd decode to decode all data. */
InclusionData = rcb_info - > rcb_data . Inclusion ; /* use local var */
// printf ("\nThe 1st byte Inclusion = 0x%02X\n", InclusionData[0]); /* Just print 1st byte */
/* NOTE: Don't change initial entries in "info_va". Add these right after "Inclusion".*/
/* If "data-Ref" enabled, check "Inclusion" to figure out what is being received.*/
if ( BSTR_BIT_GET ( OptFldsData , OPTFLD_BITNUM_DATAREF ) )
{
for ( j = 0 ; j < rcb_info - > numDsVar ; + + j )
{
if ( BSTR_BIT_GET ( InclusionData , j ) ) {
info_va [ va_num + + ] = rcb_info - > rcb_var . dataRefName [ j ] ;
if ( ( retcode = check_va_count_too_big ( va_num , va_total ) ) = = SD_FAILURE ) goto CLEANUP ;
}
}
}
/* HERE'S THE DATA. Check "Inclusion" to figure out what is being received.*/
for ( j = 0 ; j < rcb_info - > numDsVar ; + + j )
{
if ( BSTR_BIT_GET ( InclusionData , j ) ) {
info_va [ va_num + + ] = rcb_info - > rcb_var . dataValue [ j ] ;
if ( ( retcode = check_va_count_too_big ( va_num , va_total ) ) = = SD_FAILURE ) goto CLEANUP ;
}
}
/* If "reason" enabled, check "Inclusion" to figure out what is being received.*/
if ( BSTR_BIT_GET ( OptFldsData , OPTFLD_BITNUM_REASON ) )
{
for ( j = 0 ; j < rcb_info - > numDsVar ; + + j )
{
if ( BSTR_BIT_GET ( InclusionData , j ) ) {
info_va [ va_num + + ] = rcb_info - > rcb_var . Reason [ j ] ;
}
}
}
/* Does num of variables received match expected num.*/
if ( va_num ! = va_total )
{
echo_warn2 ( " Num of var received in RPT (%d) does not match expected (%d). Possibly incorrect OptFlds or inclusion bitstring " , va_total , va_num ) ;
// printf ("Num of var received in RPT (%d) does not match expected (%d). Possibly incorrect OptFlds or inclusion bitstring\n", va_total, va_num);
}
else
{
/* Perform 3rd decode (everything). */
mvl_info_data_to_local ( event , va_num , info_va ) ;
//<2F> <> <EFBFBD> 洦<EFBFBD> <E6B4A6> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> lnk20250114
2025-02-24 16:45:42 +08:00
//pthread_mutex_lock(&mtx); printf("rpt hold lock !!!!!!!!!!!");
2025-01-16 16:17:01 +08:00
u_iec_rpt_ind_data ( info_va , OptFldsData , InclusionData , rcb_info , va_total , event - > net_info ) ;
2025-02-24 16:45:42 +08:00
//pthread_mutex_unlock(&mtx); printf("rpt free lock !!!!!!!!!!!");
2025-01-16 16:17:01 +08:00
}
CLEANUP :
chk_free ( info_va ) ;
return ( retcode ) ;
}
/************************************************************************/
//61850<35> <30> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ϊ<EFBFBD> <CEAA> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
/************************************************************************/
void log_var_to_data ( MVL_VAR_ASSOC * var , char * pdata )
{
static char text_buf [ 30000 ] ; /* increase size if ms_local_to_text fails */
// ST_CHAR tdl_buf [500]; /* increase size if complex TDL expected*/
MVL_TYPE_CTRL * type_ctrl ;
ST_CHAR * data_text ; /* var data converted to text */
text_buf [ 0 ] = 0 ;
type_ctrl = mvl_type_ctrl_find ( var - > type_id ) ;
if ( type_ctrl )
{
//if (ms_runtime_to_tdl(type_ctrl->rt,type_ctrl->num_rt,tdl_buf,sizeof(tdl_buf))>0)
// RTP_PRI (" TYPE: %s\r\n", tdl_buf);
//else RTP_PRI (" TYPE: unknown\r\n");
data_text = ms_local_to_text ( ( char * ) var - > data , type_ctrl - > rt , type_ctrl - > num_rt , text_buf , sizeof ( text_buf ) ) ;
if ( data_text ) { strcpy ( pdata , data_text ) ; }
else * pdata = ' 0 ' ;
}
else * pdata = ' 0 ' ;
}
/************************************************************************/
/* LocToTextBs */
/************************************************************************/
# define TEMP_DATA_BUF_SIZE 1024
static ST_RET myLocToTextBs ( ST_UCHAR * pSrc , RUNTIME_TYPE * rt , ST_CHAR * text )
{
int i ;
int j ;
int k ;
int numBits ;
ST_INT16 * sp ;
ST_CHAR * destBuf ;
ST_UCHAR mask ;
2025-03-11 21:07:17 +08:00
//<2F> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
//printf("pSrc[0]: 0x%X, pSrc[1]: 0x%X, text: %s\n", pSrc[0], pSrc[1], text);
2025-01-16 16:17:01 +08:00
//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 ;
2025-03-11 21:07:17 +08:00
//<2F> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
//printf("pSrc[0]: 0x%X, pSrc[1]: 0x%X, text: %s\n", pSrc[0], pSrc[1], text);
2025-01-16 16:17:01 +08:00
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 :
2025-03-10 21:26:17 +08:00
myLocToTextBs ( ( ST_UCHAR * ) datptr , rt_ptr , tmpBuf ) ; //<2F> <> <EFBFBD> 洢<EFBFBD> <E6B4A2> <EFBFBD> ڴ<EFBFBD> <DAB4> е ı <D0B5> <C4B1> ش<EFBFBD> ת<EFBFBD> <D7AA> Ϊ<EFBFBD> <CEAA> Ӧ<EFBFBD> <D3A6> <EFBFBD> ı <EFBFBD> <C4B1> ַ<EFBFBD> <D6B7> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ַ<EFBFBD> '1' <20> <> '0' <20> <> <EFBFBD> ɣ <EFBFBD>
2025-01-16 16:17:01 +08:00
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 */
}
}