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