iec61850-90-5/inc/iec_90_5.h

481 lines
23 KiB
C
Raw Permalink Normal View History

/****************************************************************************/
/* SISCO SOFTWARE MODULE HEADER *********************************************/
/****************************************************************************/
/* (c) Copyright 2012 Systems Integration Specialists Company, Inc. (SISCO) */
/* 6605 19 1/2 Mile Road, Sterling Heights, Michigan, 48314 USA */
/* Tel: +1-586-254-0020 http://www.sisconet.com */
/* */
/* This Work consists of voluntary contributions made by SISCO and */
/* individuals on behalf of SISCO and then contributed to the */
/* community in support of furthering market acceptance of */
/* IEC TR 61850-90-5. Please support the community by submitting */
/* your modifications and contributions at: */
/* */
/* http://iec61850.ucaiug.org/90-5/default.aspx */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); you may */
/* not use this Work except in compliance with the License. */
/* */
/* You may obtain a copy of the License at */
/* */
/* http://www.apache.org/licenses/LICENSE-2.0 */
/* */
/* A copy of the License is included in the distribution of this Work */
/* in the file named <20>90-5_License.txt<78>. */
/* */
/* Unless required by applicable law or agreed to in writing, software */
/* distributed under the License is distributed on an "AS IS" BASIS, */
/* WITHOUT, WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
/* implied. See the License for the specific language governing */
/* permissions andlimitations under the License. */
/* */
/* */
/* MODULE NAME : iec_90_5.h */
/* */
/* MODULE DESCRIPTION : */
/* Structures and functions declarations for 90-5. */
/* */
/* MODIFICATION LOG : */
/* Date Who Comments */
/* -------- --- ------ ------------------------------------------- */
/* 08/11/12 HSF Modified header to include Apache License */
/* 02/18/12 HSF Added optflds to sv initialize function */
/* 12/01/11 HSF Initial revision */
/****************************************************************************/
#ifndef IEC_90_5_INCLUDED
#define IEC_90_5_INCLUDED
#define SECURITY_INFO_SIZE 8 /* num bytes for Security info */
typedef struct iec_61850_90_5_hdr_info{
#define IEC_90_5_SI_TYPE_TUNNEL 0xA0
#define IEC_90_5_SI_TYPE_GOOSE 0xA1
#define IEC_90_5_SI_TYPE_SV 0xA2
#define IEC_90_5_SI_TYPE_MNGT 0x83
ST_UINT8 SessionIdentifer;
/*the following is a set of security related information*/
ST_UINT32 timeOfCurrentKey;
ST_UINT16 timeToNextKey;
#define SEC_ALG_NONE 0
#define SEC_ALG_AES_128_GCM 1
#define SEC_ALG_AES_256_GCM 2
ST_UCHAR secAlgType;
#define HMAC_ALG_None 0
#define HMAC_ALG_SHA_256_80 1
#define HMAC_ALG_SHA_256_128 2
#define HMAC_ALG_SHA_256_256 3
#define HMAC_ALG_AES_GMAC_64 4
#define HMAC_ALG_AES_GMAC_128 5
ST_UCHAR hmacAlg;
ST_ULONG keyLen; //length of the key
ST_CHAR *pKey; //pointer to the key to be used
#define IEC_90_5_SIZE_OF_KEY_ID 4
ST_CHAR *pKeyID; //pointer to the key reference for the key being used
}IEC905_SESS_PDU_HDR_INFO;
typedef struct IEC905_SESS_PAYLOAD_DEF{
struct IEC905_SESS_PAYLOAD_DEF *next; /*if not NULL, points to another structure. This allows for the encoding*/
/*of multiple payload packets*/
#define GOOSE_PAYLOAD_TYPE_TAG 0x81 /*tag for a GOOSE Payload*/
#define SV_PAYLOAD_TYPE_TAG 0x82 /*tag for a sv payload*/
#define TUNNEL_PAYLOAD_TYPE_TAG 0x83 /*tag for a tunnelled payload*/
#define MNGT_PAYLOAD_TYPE_TAG 0x84 /*tag for mngt request/response payload*/
//the payload tag, simulationBit, and AppID are common information for all payloads*/
//and must be present as does the pdu_len and pdu_ptr*/
ST_UINT8 payload_tag; /*tag for the payload type*/
ST_BOOLEAN simulationBit; /*True indicates that packet is in simulation mode*/
ST_UINT16 appID; /*ApplicationID*/
ST_UINT16 pduLen; /*pointer to the length of the encoded PDU*/
ST_UCHAR *pPDU; /*pointer to previously encoded goose/sv packet APDU only*/
/*the following fields are for tunnelled payloads only */
ST_UCHAR *dst_mac; /* DST MAC (must be 6 bytes) */
ST_UINT16 tpid; /* TPID from original message */
ST_UINT16 tci; /* TCI from original message*/
ST_UINT16 etype_id; /* Ethertype ID from original message*/
}IEC905_SESS_PAYLOAD_DEF;
typedef struct iec_90_5_rx
{
IEC905_SESS_PDU_HDR_INFO *pHDR; /*pointer to allocated header information rxd */
IEC905_SESS_PAYLOAD_DEF *pPayload; /*pointer to the first payload definition in the payload chain */
ST_UCHAR *pRXDbuffer; /* pointer to the buffer that was received and decoded - filled in by calling application*/
ST_UCHAR lenRXDBuffer; /*length of the buffer - filled in by calling application*/
}IEC_90_5_RX;
/*function definition to call in order to encode a 90_5 PDU */
/* returns a pointer to the encoded buffer that includes CLTP */
extern ST_UCHAR *iec905_sess_enc (
IEC905_SESS_PDU_HDR_INFO *pHDR, /*points to the header information*/
IEC905_SESS_PAYLOAD_DEF *pPayload, /*points to the first in the chain of payload information (freeing of the information is reponsibility of the caller*/
#define PAYLOAD_TYPE_UNKNOWN 0
#define PAYLOAD_TYPE_SINGLE_GOOSE 1
#define PAYLOAD_TYPE_SINGLE_SV 2
#define PAYLOAD_TYPE_TUNNEL 3
ST_UINT32 *pEncLen, /*pointer to where the length of the encoded buffer is to be stored. */
ST_UINT32 *SPDUnum /*pointer to the SPDU number to be used. Value will be incremented if encode succeeds*/
);
#define SIZEOF_IPV4_ADDRESS 4
// the following is used to store keys
#define SIZEOF_IPV6_ADDRESS 16
//this structure is used to store the IP Address, typically destination
#define IP_V4_ADDRESS_TYPE 0
#define IP_DNS_NAME_TYPE 1 //this option shall not be used for key management. It is up to the application to convert a DNSName to an
//actual IP Address. The define is being provided for completeness and traceability to the standard.
#define IP_V6_ADDRESS_TYPE 2
#define ETHERNET_MAC_ADDRESS_TYPE 3 //not for use in 90-5, for use with 62351-6
#define NO_ADDRESS_TYPE 4
typedef struct iec_comm_address{
ST_UINT8 typeOfAddress;
ST_UINT8 lenOfAddress;
ST_UCHAR *pAddress;
}IEC_COMM_ADDRESS;
IEC_COMM_ADDRESS *create_address_structure(int typeOfAddress, char *pAddress); //function used to fill in the structure and hide nasty functions
void destroy_address_structure(IEC_COMM_ADDRESS *pAddress); //destroys the structure created in the create funciton
typedef struct iec905_key_info{
struct iec905_key_info *pNext;
struct iec905_key_info *pPrev;
struct iec_chain_info *pChain; //pointer to the chain that it belongs in.
#define SIZE_OF_KEY_ID 4
unsigned char key_id[SIZE_OF_KEY_ID];
#define KEY_TYPE_AES_128 0 //these are the defines used for type_of_key value, these are the allows values from 90-5
#define KEY_TYPE_AES_256 1
ST_UINT8 typeOfKey;
ST_UINT16 keyLen;
ST_UCHAR *pKey; //pointer to the actual key
time_t timeOfInitialUse;
time_t timeOfexpiration; //seconds of century at which time the key expires (timeof key acquisition + GDOI expiration time)
#define MAX_ALLOWED_KEY_EXPIRATION_SECONDS 172800 // 48 hours * 60 minutes * 60 seconds , from 90-5
ST_UINT32 elapsedTimeUntilExpiration; //seconds remaining prior to expiration (returned via GDOI)
struct iec905_msg_cntrl *pUsedBy; //pointer to what makes use of the key
} IEC905_KEY_INFO;
typedef struct iec905_statistics { //structure used for statistic tracking
unsigned long int TotalTxPktCnt;
unsigned long int TotalRxPktCnt;
unsigned long int TotalRxMissingPktCnt;
unsigned long int TotalRxPktWithBadHMAC;
} IEC905_STATISTICS;
typedef struct iec905_msg_cntrl{
struct iec905_msg_cntrl *pPrev;
struct iec905_msg_cntrl *pNext;
#define IEC_KEY_USAGE_TYPE_SV 0
#define IEC_KEY_USAGE_TYPE_GOOSE 1
#define IEC_KEY_USAGE_TYPE_TUNNEL 2
#define MAX_IEC_KEY_USAGE_TYPE 2
ST_UINT8 keyUsageType;
IEC_COMM_ADDRESS keyAddress; //value for the destination (tx or subscription)
IEC_COMM_ADDRESS srcKeyAddress; //value for the src address for IGMPV3 (subscription only)
ST_UINT8 dataSetRefLen;
ST_UCHAR *pDataSetRef;
IEC905_KEY_INFO *pCurrentKey;
IEC905_KEY_INFO *pNextKey;
ST_UINT32 kdcRefNum;
void *pKDCReserved;
#define IEC_ALLOW_NO_HASH 0 //is the default and won't declare a tamper if PDU is received with no hash
#define IEC_REQUIRE_HASH 1 //requires a HASH, if not present, then there has been a tamper
int hashExpected;
int requestedUpdate; //used to indicate that the user has been notified that the keys need to be updated (internal use only).
unsigned long spdu_num_tx; //used to control the SPDU number on encode
unsigned long last_spdu_num_rxd; //last spdu number received with valid decode
IEC905_STATISTICS stats;
} IEC905_MSG_CNTRL;
extern IEC_90_5_RX * iec905_create_dec_info( );
extern int iec905_sess_dec( IEC_90_5_RX *rx_ptr, struct iec_comm_address *pDestAddress); /* pointer to a user allocated structure */
extern int iec905_destroy_dec_info( IEC_90_5_RX * stuff_to_free);
extern ST_UCHAR *udp_tunnel_dec (ST_UCHAR *udp_pdu_ptr, ST_INT udp_pdu_len, ST_UCHAR *dst_mac, ST_UINT16 *tci_ptr, ST_UINT *dec_len_ptr);
extern ST_UCHAR *usr_encrypt_payloads( IEC905_SESS_PDU_HDR_INFO *hdr, ST_UCHAR *unencrypted_buffer, ST_UINT32 *payload_len );
extern ST_BOOLEAN usr_create_HMAC( IEC905_SESS_PDU_HDR_INFO *hdr, ST_UCHAR *pData, ST_UINT32 DataLen, ST_UCHAR *pOutHash, ST_UINT32 *enc_len_ptr );
extern ST_BOOLEAN usr_compare_HMAC( IEC905_SESS_PDU_HDR_INFO *hdr, ST_UCHAR *pData, ST_UINT32 DataLen, ST_UCHAR *pCmpHash);
void iec905_init_key_storage(); //initializes the key storage for the stack
IEC905_MSG_CNTRL *iec905_create_msg_cntrl_rx( ST_UINT8 usageType, IEC_COMM_ADDRESS *pAddress, IEC_COMM_ADDRESS *pSrcAddress, ST_CHAR *pDatSetRef); //used to allocate key storage and put it into the appropriate chain
IEC905_MSG_CNTRL *iec905_create_msg_cntrl_tx( ST_UINT8 usageType, IEC_COMM_ADDRESS *pAddress, IEC_COMM_ADDRESS *pSrcAddress, ST_CHAR *pDatSetRef);
ST_BOOLEAN iec905_destroy_msg_cntrl (IEC905_MSG_CNTRL *pKeyRoot); //used to destroy and recover allocated resources and deletes any associated keys
IEC905_KEY_INFO * iec905_add_current_key( IEC905_MSG_CNTRL *pKeyRoot, ST_UINT8 typeOfAlg,ST_UINT16 key_len, ST_UCHAR *pKey, ST_UCHAR *pKeyID, ST_UINT32 time_remaining);
IEC905_KEY_INFO * iec905_add_next_key( IEC905_MSG_CNTRL *pKeyRoot, ST_UINT8 typeOfAlg,ST_UINT16 key_len, ST_UCHAR *pKey, ST_UCHAR *pKeyID,ST_UINT32 time_remaining);
IEC905_MSG_CNTRL *iec905_find_rxd_msg_cntrl(ST_UCHAR pduSI, IEC_COMM_ADDRESS *pDestAddress , ST_UCHAR *pKeyID);
void iec905_getStats(IEC905_STATISTICS *pRetStatistics, int resetStats);
int iec905_manage_keys(IEC905_MSG_CNTRL *pKeyRoot);
ST_BOOLEAN iec905_destroy_key (IEC905_MSG_CNTRL *pKeyRoot) ;
//IGMP3 functions -- located in udp_rx.c
IEC905_MSG_CNTRL *iec905_igmpv3_group_enroll(ST_UINT8 usageType, ST_UINT8 typeOfAddress, char *pMultiAddress, char *pSrcAddress, char *pDatSetRef, SOCKET pReceivingSocket);
IEC905_MSG_CNTRL *iec905_igmpv3_group_destroy(IEC905_MSG_CNTRL *pPayload,SOCKET pReceivingSocket);
/**************************************************/
/* The following are functions found in the */
/* udp_tx.c module */
typedef struct ethertype_8021Q {
USHORT priority; //priority specification
USHORT vlanID; //vlanID Setting
}ETHERTYPE_8021Q;
#define MAX_NUM_TC_INTERFACES_SUPPORTED 20
#define MAX_PEAK_RATE 1000000 //bits per second used in Traffic FlowSpec
#define MAX_TOKEN_RATE 100000 //token rate for sending TC.
typedef struct iecsocket_info{
HANDLE FlowHandle;
HANDLE FilterHandle;
SOCKET SendingSocket;
}IECSOCKET_TX_INFO;
#define MAX_KEY_SIZE_TO_GENERATE (2048/8) //2048 bits divide by 8 gives the number of bytes required.
ST_UCHAR *generate_symmetric_key(int algorithmID, int size);
//*********************************Functions in iec90_5_udp_rx.c *************************************
//udp/socket functions
int iec905_ip_init(); //used to initialize the ip socket interface, MUST BE CALLED before any other socket activity
#define IEC_61850_90_5_UDP_RX_PORT 102 //port specified for use by 90-5
int iec905_rx_init(SOCKET *pReceivingSocket,unsigned long UDPSckBufSize); //function used to initialize the UDP RX port used for 90-5
void iec905_close_socket(ReceivingSocket);
int iec905_tx_pdu_init();
int iec905_tx_pdu_open_socket_with_priorities(IECSOCKET_TX_INFO ** pSocketInfo, char *pInterfaceName, ETHERTYPE_8021Q *p8021Q, USHORT *pIP_TOS_DSCP, IEC_COMM_ADDRESS *pDestAddress);
int iec905_tx_pdu_close_socket (IECSOCKET_TX_INFO *SendingInfo);
#define UDP_HDR_SIZE_IPV6 16 //V6 is the worst case for pseudo HDR size
#define MAX_ALLOWED_UDP_PACKET_LENGTH (65535 - UDP_HDR_SIZE_IPV6) //maximum size allowed, in order to avoid Jumbo packets
int iec905_tx_pdu (IECSOCKET_TX_INFO *SendingInfo, IEC_COMM_ADDRESS *pMyAddressInfo, ST_INT IPPort, ST_UCHAR *pEnc, ST_UINT encLen, IEC905_MSG_CNTRL *pTxStats);
//***********************************************/
// error code definitions */
typedef struct errorTracking{
int inUse; //TRUE if there is a valid errorCode in the structure
int errorCode; //Error that was passed into the ErrorHandler Function
char * fileName; //Name of the file that called the ErrorHandler funciton. May be NULL.
unsigned long lineNumber; //Number of the line, in the file, that called the ErrorHandler function.
time_t timeOfError;
}ERROR_TRACKING;
int IEC905_ErrorHandler (int errorCode, char * fileName, unsigned long int lineNumber); //function to call in case of error
char *IEC905_XlatErrorCode(int errorCode); //called to translate and error code to a string
ERROR_TRACKING *IEC905_GetSpecificEntry(unsigned int entryNumber); //called to retrieve other errors. The maximum number is
//determined by MAX_ALLOWED_LAST_ERRORS. EntryNumber starts
//numbering at zero(0). EntryNumber=0 is the same as GetLastError
ERROR_TRACKING *IEC905_GetLastError(); //used to get the last error
#define MAX_ALLOWED_LAST_ERRORS 10 //defines the depth of errors that will be maintained
#define SUCCESS_IEC905 0
#define FAILURE_IEC905 -1
#define OK_IEC905 0
#define NOK_IEC905 -1
#define INVALID_INPUT_PARAMETER -2
#define COMM_RELATED_ERROR_OFFSET -100
#define UNABLE_TO_INTIALIZE_IP_INTERFACE (COMM_RELATED_ERROR_OFFSET-0)
#define IP_PORT_INCORRECT_IEC905 (COMM_RELATED_ERROR_OFFSET-1)
#define UNABLE_TO_OPEN_UDP_SOCKET_IEC905 (COMM_RELATED_ERROR_OFFSET-2)
#define UDP_RX_BIND_FAILED_IEC905 (COMM_RELATED_ERROR_OFFSET-3)
#define ETHERNET_INTERFACE_NOT_FOUND (COMM_RELATED_ERROR_OFFSET-4)
#define ETHERNET_INTERFACE_OPEN_FAILED (COMM_RELATED_ERROR_OFFSET-5)
#define UNABLE_TO_CREATE_SENDING_SOCKET (COMM_RELATED_ERROR_OFFSET-6)
#define UNABLE_TO_CONVERT_IP_ADDRESS (COMM_RELATED_ERROR_OFFSET-7)
#define SUBSCRIPTION_AND_TRAFFIC_CONTROL_OFFSET -200
#define INVALID_IGMP_GROUP_ENROLL_PARAMETERS_IEC905 (SUBSCRIPTION_AND_TRAFFIC_CONTROL_OFFSET-1)
#define DUPLICATE_PAYLOAD_DETECTED_IEC905 (SUBSCRIPTION_AND_TRAFFIC_CONTROL_OFFSET-2)
#define IGMPV3_GROUP_MEMBERSHIP_ENROLL_FAILED_IEC905 (SUBSCRIPTION_AND_TRAFFIC_CONTROL_OFFSET-3)
#define IGMPV2_GROUP_MEMBERSHIP_ENROLL_FAILED_IEC905 (SUBSCRIPTION_AND_TRAFFIC_CONTROL_OFFSET-4)
#define INVALID_IGMP_GROUP_UNSUB_PARAMETER_IEC905 (SUBSCRIPTION_AND_TRAFFIC_CONTROL_OFFSET-5)
#define INVALID_IGMP_GROUP_UNSUBV2_FAILURE_IEC905 (SUBSCRIPTION_AND_TRAFFIC_CONTROL_OFFSET-6)
#define INVALID_IGMP_GROUP_UNSUBV3_FAILURE_IEC905 (SUBSCRIPTION_AND_TRAFFIC_CONTROL_OFFSET-7)
#define WINDOWS_FLOW_OBJECT_ALLOCATON_ERROR (SUBSCRIPTION_AND_TRAFFIC_CONTROL_OFFSET-8)
#define TC_REGISTRATION_ERROR (SUBSCRIPTION_AND_TRAFFIC_CONTROL_OFFSET-9)
//must have administrative priviledges to access the Traffic Control API
#define TC_OPEN_FAILED_CHK_ADMIN_PRIV (SUBSCRIPTION_AND_TRAFFIC_CONTROL_OFFSET-10)
#define TC_INTERFACE_LISTING_FALIED (SUBSCRIPTION_AND_TRAFFIC_CONTROL_OFFSET-11)
#define INTERFACE_DIFFSERV_FAILED (SUBSCRIPTION_AND_TRAFFIC_CONTROL_OFFSET-12)
#define TC_FLOWADD_FAILED (SUBSCRIPTION_AND_TRAFFIC_CONTROL_OFFSET-13)
#define UNABLE_TO_ADD_TCFILTER (SUBSCRIPTION_AND_TRAFFIC_CONTROL_OFFSET-14)
#define UNABLE_TO_DELETE_TC_FLOW (SUBSCRIPTION_AND_TRAFFIC_CONTROL_OFFSET-15)
#define CRYPTO_API_ERROR_OFFSET -300
#define CRYPTO_PROVIDER_OPEN_ERROR (CRYPTO_API_ERROR_OFFSET-0)
#define CRYPTO_RND_NUM_GEN_ERROR (CRYPTO_API_ERROR_OFFSET-1)
#define GENERAL_CRYPTO_PROBLEM (CRYPTO_API_ERROR_OFFSET-2)
#define CRYPTO_BLOCK_LEN_PROBLEM (CRYPTO_API_ERROR_OFFSET-3)
#define ENCODE_DECODE_ERROR_OFFSET -400
#define LARGER_THAN_ALLOWED_PDU (ENCODE_DECODE_ERROR_OFFSET -0)
#define MEMORY_ALLOCATION_ERROR (ENCODE_DECODE_ERROR_OFFSET -1)
#define DECODE_ERROR_TOO_LARGE (ENCODE_DECODE_ERROR_OFFSET -2)
#define DECODE_UNKNOWN_TAG (ENCODE_DECODE_ERROR_OFFSET -3)
#define DECODE_ERROR_IN_PAYLOADS (ENCODE_DECODE_ERROR_OFFSET -4)
#define IEC_90_5_NO_CLTP (ENCODE_DECODE_ERROR_OFFSET -5)
#define IEC_90_5_TAMPERDECTECT_HDR (ENCODE_DECODE_ERROR_OFFSET -6)
#define IEC_90_5_INVALID_HDR (ENCODE_DECODE_ERROR_OFFSET -7)
#define IEC_90_5_INVALID_HDR_LI (ENCODE_DECODE_ERROR_OFFSET -8)
#define IEC_90_5_TAMPERDECTECT_NO_SIG (ENCODE_DECODE_ERROR_OFFSET -9)
#define IEC_90_5UNEXPECTED_PDU_RXD (ENCODE_DECODE_ERROR_OFFSET -10)
#define IEC_90_5_DUPLICATE_PACKET_RXD (ENCODE_DECODE_ERROR_OFFSET -11)
#define INTERNAL_SECURITY_ERROR_OFFSET -500
#define UNABLE_TO_ADD_KEY (INTERNAL_SECURITY_ERROR_OFFSET+0)
#define KEYS_NOK (INTERNAL_SECURITY_ERROR_OFFSET -1) //indicates that neither the primary nor next key are valid
#define PRIME_KEY_OK_NEXT_KEY_NOK (INTERNAL_SECURITY_ERROR_OFFSET -2) //indicates that the primary key is OK, but there is no next key
//************* SV ENCODE and DECODE FUNCTIONS And Defines ************************
//The following are supported Data Types as defined in IEC 61850-9-2 ED.2
enum SV_DATATYPES {
SV_BOOLEAN,
SV_INT8,
SV_INT16,
SV_INT32,
SV_INT64,
SV_INT8U,
SV_INT16U,
SV_INT24U, //do not use
SV_INT32U,
SV_FLOAT32,
SV_FLOAT64,
SV_ENUMERATED,
SV_CODEDENUM,
SV_OCTETSTRING,
SV_VISIBLESTRING,
SV_UNICODESTRING,
SV_OBJECTNAME,
SV_OBJECTREFERENCE,
SV_TIMESTAMP,
SV_ENTRYTIME
};
typedef struct asdu_enc_info{
char * pASDU; //pointer to the beginning of the ASDU;
ST_UINT16 *pSmpCntValue; //pointer to where to place the SMPCNT value
ST_UCHAR *pSmpSynch; //pointer to the SMPSNYC Value
char * pASDU_data; //pointer to the beginning of the ASDU data
char * pASDU_TimeStamp; //pointer to the UTC timestamp;
} ASDU_ENC_INFO;
typedef struct sv_enc_struct {
ST_UINT16 length_to_send; //Actual PDU size to send
unsigned char * pSVbuffer; //pointer to the allocated buffer
unsigned int max_num_ASDUs_allocated;
ST_UINT16 size_of_asdu;
ST_UINT16 *pPDULen; //pointer to where the PDU len is located
ST_UCHAR *pNumASDUVal; //pointer to where the number of ASDUs is located
ST_UINT16 *pASDUSeqLen; //pointer to the sequence length for ASDUs
ST_UINT16 asdu_data_size; //size in octets of the ASDU
ASDU_ENC_INFO asdus[0]; //begining of the ASDU arrays, will be allocated to the max_num_ASDUs;
}SV_ENC_STRUCT;
SV_ENC_STRUCT * initialize_sv_encode_struct (char * pMsvid, //pointer to a NULL terminated MSVID value may not be more than 127
char * pDatSetRef, //pointer to a NULL terminated DataSetReference string, may not be more than 127
unsigned int max_num_asdus, //maximum number of ASDUs, may not be more than 127
ST_UINT32 confrev,
ST_UCHAR smpSync,
ST_UINT16 smpRate,
ST_UINT16 *smpMod,
ST_UINT16 size_of_asdu_data, //size of ASDU data in bytes
#define SV_INCLUDE_REFRESH_TIME 0x80
#define SV_INCLUDE_SAMPLE_SYNC 0x40 //do not used, just provided for backward compatibility with V1
#define SV_INCLUDE_SAMPLE_RATE 0x20
#define SV_INCLUDE_DATA_SET 0x10
#define SV_INCLUDE_SECURITY 0x08 //ignored, not used
#define SV_INCLUDE_UTC_TIME 0x04 //added by 90-5
ST_UINT8 sv_optflds
);
int sv_enc_update_lengths( SV_ENC_STRUCT *pCntrlStruc, //pointer the the control structure for the buffer
unsigned int num_asdus_to_use //number of the actual ASDUs that will be used
);
int destroy_sv_encode_struct (SV_ENC_STRUCT * pDestroy);
int sv_data_helper_prim(unsigned int dataType, int initial_data_offset, int *ret_len);
int sv_data_helper_calculate_samples_size_prim (unsigned int dataType, int initial_data_offset, int *ret_len, int *total_calc_len);
typedef struct asn1Info{
ST_UINT16 len;
unsigned char *pValue;
}SV_ASDUINFO;
typedef struct asdu_dec_info{
SV_ASDUINFO msvID;
SV_ASDUINFO datSetRef;
SV_ASDUINFO smpCnt;
SV_ASDUINFO confRev;
SV_ASDUINFO refrTm;
SV_ASDUINFO smpSynch;
SV_ASDUINFO smpRate;
SV_ASDUINFO samples;
SV_ASDUINFO smpMod;
SV_ASDUINFO utcTimeStamp;
} ASDU_DEC_INFO;
typedef struct sv_dec_struct {
unsigned int num_ASDUs;
ASDU_DEC_INFO asdus[0]; //begining of the ASDU arrays, will be allocated to the max_num_ASDUs;
}SV_DEC_STRUCT;
SV_DEC_STRUCT * sv_decode (unsigned char * pSVPdu, //pointer to the SVPDU to be decoded
ST_UINT16 SVPDULen //length of the PDU to be decoded
);
/**************** functions used to interact with the KDC ****************/
typedef struct kdc_credentials{ // a placeholder for what needs to be done eventually. Anticipate certificate information, but that may change.
char * certificate_info;
}KDC_CREDENTIALS;
typedef struct kdc_ref{
void *pReserved; //reserved for internal use
ST_UINT32 refNum; //alternat reference number
char *pUserRef; //pointer to the user reference for the KDC Pair
}KDC_REF;
int iec905_destroy_kdc_credential(KDC_CREDENTIALS *pCredential); //destroys and frees a created KDC Credential structure
int iec905_init_kdc_interface(KDC_CREDENTIALS *pLocalCredential, int maxNumOfKDCPairs); //function is called in order to initialize what needs to be initialized for the KDC interface
KDC_REF *iec905_create_KDC_pair(char *userRef,
IEC_COMM_ADDRESS *pPrimary, //addressing information for the primary KDC
KDC_CREDENTIALS *pPrimaryCredentials, //pointer to the primary KDCs credentials that need to be used in phase 1 of GDOI
IEC_COMM_ADDRESS *pSecondary, //addressing information for the secondary KDC
KDC_CREDENTIALS *pSecondaryCredentials //pointer to the secondary KDCs credentials that need to be used in phase 1 of GDOI
);
int iec905_destroy_KDC_pair(ST_UINT32 refNum);
int iec905_kdc_bind (IEC905_MSG_CNTRL *pMsgCntrl, KDC_REF *pKDCRef);
int iec905_get_kdc_tx_keys(IEC905_MSG_CNTRL * pMsgCntrl);
int iec905_get_kdc_rx_keys(IEC905_MSG_CNTRL * pMsgCntrl);
//***********************************************************************
// REQUIRED FUNCTIONS TO BE SUPPLIED BY THE USER
void usr_notify_of_key_updated_needed(IEC905_MSG_CNTRL *pCntrl); //called if keys need to be updated by the KDC
void usr_notify_of_error(int errorCode,char *fileName,unsigned long int lineNumber);
#endif /* !IEC_90_5_INCLUDED */