The goal of this software is to automatically generate C/C++ code which reads and writes GOOSE and Sampled Value packets. Any valid IEC 61850 Substation Configuration Description (SCD) file, describing GOOSE and/or SV communications, can be used as the input. The output code is lightweight and platform-independent, so it can run on a variety of devices, including low-cost microcontrollers. It\'s ideal for rapid-prototyping new protection and control systems that require communications. This mbed project is a simple example of this functionality. Other code: https://github.com/stevenblair/rapid61850 Project homepage: http://personal.strath.ac.uk/steven.m.blair/
Revision 1:9399d44c2b1a, committed 2011-10-07
- Comitter:
- sblair
- Date:
- Fri Oct 07 13:48:18 2011 +0000
- Parent:
- 0:230c10b228ea
- Commit message:
Changed in this revision
diff -r 230c10b228ea -r 9399d44c2b1a ctypes.c --- a/ctypes.c Fri Oct 07 13:41:08 2011 +0000 +++ b/ctypes.c Fri Oct 07 13:48:18 2011 +0000 @@ -1,3 +1,23 @@ +/** + * Rapid-prototyping protection schemes with IEC 61850 + * + * Copyright (c) 2011 Steven Blair + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + #include "ctypes.h" #include "gse.h" #include "sv.h"
diff -r 230c10b228ea -r 9399d44c2b1a ctypes.h --- a/ctypes.h Fri Oct 07 13:41:08 2011 +0000 +++ b/ctypes.h Fri Oct 07 13:48:18 2011 +0000 @@ -1,3 +1,23 @@ +/** + * Rapid-prototyping protection schemes with IEC 61850 + * + * Copyright (c) 2011 Steven Blair + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + #ifndef CTYPES_H #define CTYPES_H @@ -7,65 +27,65 @@ #include <string.h> -#define LITTLE_ENDIAN 1 +#define LITTLE_ENDIAN 1 // platform-specific data types to conform to SV type sizes (Table 14 in IEC 61850-9-2) -#define CTYPE_BOOLEAN unsigned char -#define CTYPE_INT8 char -#define CTYPE_INT16 short -#define CTYPE_INT32 int -#define CTYPE_INT8U unsigned char -#define CTYPE_INT16U unsigned short -#define CTYPE_INT32U unsigned int -#define CTYPE_ENUM CTYPE_INT32 -#define CTYPE_FLOAT32 float -#define CTYPE_FLOAT64 double -#define CTYPE_VISSTRING255 char * -#define CTYPE_DBPOS int -#define CTYPE_QUALITY CTYPE_INT16U -#define CTYPE_TIMESTAMP long long +#define CTYPE_BOOLEAN unsigned char +#define CTYPE_INT8 char +#define CTYPE_INT16 short +#define CTYPE_INT32 int +#define CTYPE_INT8U unsigned char +#define CTYPE_INT16U unsigned short +#define CTYPE_INT32U unsigned int +#define CTYPE_ENUM CTYPE_INT32 +#define CTYPE_FLOAT32 float +#define CTYPE_FLOAT64 double +#define CTYPE_VISSTRING255 char * +#define CTYPE_DBPOS int +#define CTYPE_QUALITY CTYPE_INT16U +#define CTYPE_TIMESTAMP long long // sampled value dataset type sizes, in bytes -#define SV_GET_LENGTH_FLOAT32 4 -#define SV_GET_LENGTH_FLOAT64 8 -#define SV_GET_LENGTH_TIMESTAMP 8 -#define SV_GET_LENGTH_INT16 2 -#define SV_GET_LENGTH_INT32 4 -#define SV_GET_LENGTH_INT16U 2 -#define SV_GET_LENGTH_INT32U 4 -#define SV_GET_LENGTH_VISSTRING255 35 -#define SV_GET_LENGTH_BOOLEAN 1 -#define SV_GET_LENGTH_ENUM 4 -#define SV_GET_LENGTH_QUALITY 4 -#define SV_GET_LENGTH_DBPOS 4 +#define SV_GET_LENGTH_FLOAT32 4 +#define SV_GET_LENGTH_FLOAT64 8 +#define SV_GET_LENGTH_TIMESTAMP 8 +#define SV_GET_LENGTH_INT16 2 +#define SV_GET_LENGTH_INT32 4 +#define SV_GET_LENGTH_INT16U 2 +#define SV_GET_LENGTH_INT32U 4 +#define SV_GET_LENGTH_VISSTRING255 35 +#define SV_GET_LENGTH_BOOLEAN 1 +#define SV_GET_LENGTH_ENUM 4 +#define SV_GET_LENGTH_QUALITY 4 +#define SV_GET_LENGTH_DBPOS 4 // BER datatype sizes, which are dependent on the actual data -#define BER_GET_LENGTH_CTYPE_FLOAT32(x) (SV_GET_LENGTH_FLOAT32 + 1) // + 1 byte for number of exponent bits -#define BER_GET_LENGTH_CTYPE_FLOAT64(x) (SV_GET_LENGTH_FLOAT64 + 1) // + 1 byte for number of exponent bits -#define BER_GET_LENGTH_CTYPE_TIMESTAMP(x) (SV_GET_LENGTH_TIMESTAMP) -#define BER_GET_LENGTH_CTYPE_INT16(x) (ber_integer_length((x), SV_GET_LENGTH_INT16)) -#define BER_GET_LENGTH_CTYPE_INT32(x) (ber_integer_length((x), SV_GET_LENGTH_INT32)) -#define BER_GET_LENGTH_CTYPE_INT16U(x) (ber_integer_length((x), SV_GET_LENGTH_INT16U)) -#define BER_GET_LENGTH_CTYPE_INT32U(x) (ber_integer_length((x), SV_GET_LENGTH_INT32U)) -#define BER_GET_LENGTH_CTYPE_VISSTRING255(x) (SV_GET_LENGTH_VISSTRING255) -#define BER_GET_LENGTH_CTYPE_BOOLEAN(x) (SV_GET_LENGTH_BOOLEAN) -#define BER_GET_LENGTH_CTYPE_ENUM(x) (ber_integer_length((x), SV_GET_LENGTH_ENUM)) -#define BER_GET_LENGTH_CTYPE_QUALITY(x) (/*SV_GET_LENGTH_QUALITY*/2 + 1) // + 1 byte for padding -#define BER_GET_LENGTH_CTYPE_DBPOS(x) (SV_GET_LENGTH_DBPOS) +#define BER_GET_LENGTH_CTYPE_FLOAT32(x) (SV_GET_LENGTH_FLOAT32 + 1) // + 1 byte for number of exponent bits +#define BER_GET_LENGTH_CTYPE_FLOAT64(x) (SV_GET_LENGTH_FLOAT64 + 1) // + 1 byte for number of exponent bits +#define BER_GET_LENGTH_CTYPE_TIMESTAMP(x) (SV_GET_LENGTH_TIMESTAMP) +#define BER_GET_LENGTH_CTYPE_INT16(x) (ber_integer_length((x), SV_GET_LENGTH_INT16)) +#define BER_GET_LENGTH_CTYPE_INT32(x) (ber_integer_length((x), SV_GET_LENGTH_INT32)) +#define BER_GET_LENGTH_CTYPE_INT16U(x) (ber_integer_length((x), SV_GET_LENGTH_INT16U)) +#define BER_GET_LENGTH_CTYPE_INT32U(x) (ber_integer_length((x), SV_GET_LENGTH_INT32U)) +#define BER_GET_LENGTH_CTYPE_VISSTRING255(x) (SV_GET_LENGTH_VISSTRING255) +#define BER_GET_LENGTH_CTYPE_BOOLEAN(x) (SV_GET_LENGTH_BOOLEAN) +#define BER_GET_LENGTH_CTYPE_ENUM(x) (ber_integer_length((x), SV_GET_LENGTH_ENUM)) +#define BER_GET_LENGTH_CTYPE_QUALITY(x) (/*SV_GET_LENGTH_QUALITY*/2 + 1) // + 1 byte for padding +#define BER_GET_LENGTH_CTYPE_DBPOS(x) (SV_GET_LENGTH_DBPOS) -#define ASN1_TAG_ARRAY 0x81 -#define ASN1_TAG_STRUCTURE 0x82 -#define ASN1_TAG_BOOLEAN 0x83 -#define ASN1_TAG_BIT_STRING 0x84 -#define ASN1_TAG_INTEGER 0x85 -#define ASN1_TAG_UNSIGNED 0x86 -#define ASN1_TAG_FLOATING_POINT 0x87 -#define ASN1_TAG_REAL 0x88 -#define ASN1_TAG_OCTET_STRING 0x89 -#define ASN1_TAG_VISIBLE_STRING 0x8A +#define ASN1_TAG_ARRAY 0x81 +#define ASN1_TAG_STRUCTURE 0x82 +#define ASN1_TAG_BOOLEAN 0x83 +#define ASN1_TAG_BIT_STRING 0x84 +#define ASN1_TAG_INTEGER 0x85 +#define ASN1_TAG_UNSIGNED 0x86 +#define ASN1_TAG_FLOATING_POINT 0x87 +#define ASN1_TAG_REAL 0x88 +#define ASN1_TAG_OCTET_STRING 0x89 +#define ASN1_TAG_VISIBLE_STRING 0x8A -#define QUALITY_UNUSED_BITS 3 // total_bits (16) - used_bits (13) = 3 +#define QUALITY_UNUSED_BITS 3 // total_bits (16) - used_bits (13) = 3 int ber_integer_length(void *value, int maxLength); int ber_encode_integer(unsigned char *bufDst, void *value, int maxLength); @@ -79,16 +99,16 @@ void gse_sv_packet_filter(unsigned char *buf, int len); struct UtcTime { - unsigned char bytes[8]; // format: ssssssssssssssssssssssssssssssssffffffffffffffffffffffffqqqqqqqq + unsigned char bytes[8]; // format: ssssssssssssssssssssssssssssssssffffffffffffffffffffffffqqqqqqqq }; extern unsigned char LOCAL_MAC_ADDRESS[]; struct ethHeaderData { - unsigned char destMACAddress[6]; // stored in big-endian format - CTYPE_INT16U APPID; - CTYPE_INT16U VLAN_ID; - CTYPE_INT16U VLAN_PRIORITY; + unsigned char destMACAddress[6]; // stored in big-endian format + CTYPE_INT16U APPID; + CTYPE_INT16U VLAN_ID; + CTYPE_INT16U VLAN_PRIORITY; }; #ifdef __cplusplus /* If this is a C++ compiler, end C linkage */
diff -r 230c10b228ea -r 9399d44c2b1a datatypes.c --- a/datatypes.c Fri Oct 07 13:41:08 2011 +0000 +++ b/datatypes.c Fri Oct 07 13:48:18 2011 +0000 @@ -1,77 +1,95 @@ -#include "ctypes.h" -#include "datatypes.h" -#include "ied.h" +/** + * Rapid-prototyping protection schemes with IEC 61850 + * + * Copyright (c) 2011 Steven Blair + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "ctypes.h" +#include "datatypes.h" +#include "ied.h" #include <stdlib.h> - +void init_myAnalogValue(struct myAnalogValue *myAnalogValue) { + myAnalogValue->f = 1.024; +} +void init_ScaledValueConfig(struct ScaledValueConfig *ScaledValueConfig) { +} +void init_myVector(struct myVector *myVector) { +} +void init_simpleVector(struct simpleVector *simpleVector) { +} +void init_myMod(struct myMod *myMod) { +} +void init_myHealth(struct myHealth *myHealth) { +} +void init_myBeh(struct myBeh *myBeh) { +} +void init_myINS(struct myINS *myINS) { +} +void init_myLPL(struct myLPL *myLPL) { + myLPL->ldNs = (CTYPE_VISSTRING255) malloc(18); + strncpy(myLPL->ldNs, "IEC61850-7-4:2003\0", 18); + myLPL->configRev = (CTYPE_VISSTRING255) malloc(9); + strncpy(myLPL->configRev, "Rev 3.45\0", 9); +} +void init_myDPL(struct myDPL *myDPL) { + myDPL->vendor = (CTYPE_VISSTRING255) malloc(13); + strncpy(myDPL->vendor, "myVendorName\0", 13); + myDPL->hwRev = (CTYPE_VISSTRING255) malloc(9); + strncpy(myDPL->hwRev, "Rev 1.23\0", 9); +} +void init_myPos(struct myPos *myPos) { +} +void init_mySPS(struct mySPS *mySPS) { +} +void init_myMV(struct myMV *myMV) { +} +void init_simpleMV(struct simpleMV *simpleMV) { +} +void init_simpleCMV(struct simpleCMV *simpleCMV) { +} +void init_simpleWYE(struct simpleWYE *simpleWYE) { +} +void init_myCMV(struct myCMV *myCMV) { +} +void init_mySEQ(struct mySEQ *mySEQ) { +} +void init_mySAV(struct mySAV *mySAV) { +} +void init_simpleSAV(struct simpleSAV *simpleSAV) { +} +void init_datatypes() { + init_myLPL(&E1Q1SB1.S1.C1.LLN0.NamPlt); + init_myLPL(&E1Q1SB1.S1.C1.LLN0.NamPlt); + init_myLPL(&E1Q1SB1.S1.C1.LLN0.NamPlt); + init_myLPL(&E1Q1SB1.S1.C1.LLN0.NamPlt); + init_myAnalogValue(&E1Q1SB1.S1.C1.RMXU_1.AmpLocPhsA.instMag); + init_myAnalogValue(&E1Q1SB1.S1.C1.RMXU_1.AmpLocPhsB.instMag); + init_myAnalogValue(&E1Q1SB1.S1.C1.RMXU_1.AmpLocPhsC.instMag); + init_myLPL(&E1Q1SB1.S1.C1.LPHD_1.NamPlt); + init_myDPL(&E1Q1SB1.S1.C1.LPHD_1.PhyNam); + init_myAnalogValue(&E1Q1SB1.S1.C1.MMXU_1.Amps.mag); + init_myAnalogValue(&E1Q1SB1.S1.C1.MMXU_1.Volts.mag); + init_myAnalogValue(&E1Q1SB1.S1.C1.TVTR_1.Vol.instMag); + init_myLPL(&D1Q1SB4.S1.C1.LLN0.NamPlt); + init_myLPL(&D1Q1SB4.S1.C1.LLN0.NamPlt); + init_myLPL(&D1Q1SB4.S1.C1.LPHD_1.NamPlt); + init_myDPL(&D1Q1SB4.S1.C1.LPHD_1.PhyNam); + init_myLPL(&D1Q1SB4.S1.C1.RSYN_1.NamPlt); +} -void init_myAnalogValue(struct myAnalogValue *myAnalogValue) { - myAnalogValue->f = 1.024; -} -void init_ScaledValueConfig(struct ScaledValueConfig *ScaledValueConfig) { -} -void init_myVector(struct myVector *myVector) { -} -void init_simpleVector(struct simpleVector *simpleVector) { -} -void init_myMod(struct myMod *myMod) { -} -void init_myHealth(struct myHealth *myHealth) { -} -void init_myBeh(struct myBeh *myBeh) { -} -void init_myINS(struct myINS *myINS) { -} -void init_myLPL(struct myLPL *myLPL) { - myLPL->ldNs = (CTYPE_VISSTRING255) malloc(18); - strncpy(myLPL->ldNs, "IEC61850-7-4:2003\0", 18); - myLPL->configRev = (CTYPE_VISSTRING255) malloc(9); - strncpy(myLPL->configRev, "Rev 3.45\0", 9); -} -void init_myDPL(struct myDPL *myDPL) { - myDPL->vendor = (CTYPE_VISSTRING255) malloc(13); - strncpy(myDPL->vendor, "myVendorName\0", 13); - myDPL->hwRev = (CTYPE_VISSTRING255) malloc(9); - strncpy(myDPL->hwRev, "Rev 1.23\0", 9); -} -void init_myPos(struct myPos *myPos) { -} -void init_mySPS(struct mySPS *mySPS) { -} -void init_myMV(struct myMV *myMV) { -} -void init_simpleMV(struct simpleMV *simpleMV) { -} -void init_simpleCMV(struct simpleCMV *simpleCMV) { -} -void init_simpleWYE(struct simpleWYE *simpleWYE) { -} -void init_myCMV(struct myCMV *myCMV) { -} -void init_mySEQ(struct mySEQ *mySEQ) { -} -void init_mySAV(struct mySAV *mySAV) { -} -void init_simpleSAV(struct simpleSAV *simpleSAV) { -} -void init_datatypes() { - init_myLPL(&E1Q1SB1.S1.C1.LLN0.NamPlt); - init_myLPL(&E1Q1SB1.S1.C1.LLN0.NamPlt); - init_myLPL(&E1Q1SB1.S1.C1.LLN0.NamPlt); - init_myLPL(&E1Q1SB1.S1.C1.LLN0.NamPlt); - init_myAnalogValue(&E1Q1SB1.S1.C1.RMXU_1.AmpLocPhsA.instMag); - init_myAnalogValue(&E1Q1SB1.S1.C1.RMXU_1.AmpLocPhsB.instMag); - init_myAnalogValue(&E1Q1SB1.S1.C1.RMXU_1.AmpLocPhsC.instMag); - init_myLPL(&E1Q1SB1.S1.C1.LPHD_1.NamPlt); - init_myDPL(&E1Q1SB1.S1.C1.LPHD_1.PhyNam); - init_myAnalogValue(&E1Q1SB1.S1.C1.MMXU_1.Amps.mag); - init_myAnalogValue(&E1Q1SB1.S1.C1.MMXU_1.Volts.mag); - init_myAnalogValue(&E1Q1SB1.S1.C1.TVTR_1.Vol.instMag); - init_myLPL(&D1Q1SB4.S1.C1.LLN0.NamPlt); - init_myLPL(&D1Q1SB4.S1.C1.LLN0.NamPlt); - init_myLPL(&D1Q1SB4.S1.C1.LPHD_1.NamPlt); - init_myDPL(&D1Q1SB4.S1.C1.LPHD_1.PhyNam); - init_myLPL(&D1Q1SB4.S1.C1.RSYN_1.NamPlt); -} -
diff -r 230c10b228ea -r 9399d44c2b1a datatypes.h --- a/datatypes.h Fri Oct 07 13:41:08 2011 +0000 +++ b/datatypes.h Fri Oct 07 13:48:18 2011 +0000 @@ -1,3 +1,23 @@ +/** + * Rapid-prototyping protection schemes with IEC 61850 + * + * Copyright (c) 2011 Steven Blair + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + #ifndef DATATYPES_H #define DATATYPES_H @@ -7,238 +27,238 @@ #include "ctypes.h" -// enums -enum ACDdir { - ACDDIR_UNKNOWN, - ACDDIR_FORWARD, - ACDDIR_BACKWARD, - ACDDIR_BOTH -}; -enum seqT { - SEQT_POS_NEG_ZERO, - SEQT_DIR_QUAD_ZERO -}; -enum Dbpos { - DBPOS_INTERMEDIATE, - DBPOS_OFF, - DBPOS_ON, - DBPOS_BAD -}; -enum Tcmd { - TCMD_STOP, - TCMD_LOWER, - TCMD_HIGHER, - TCMD_RESERVED -}; -enum Beh { - BEH_ON, - BEH_BLOCKED, - BEH_TEST, - BEH_TEST_BLOCKED, - BEH_OFF -}; -enum Mod { - MOD_ON, - MOD_BLOCKED, - MOD_TEST, - MOD_TEST_BLOCKED, - MOD_OFF -}; -enum Health { - HEALTH_OK, - HEALTH_WARNING, - HEALTH_ALARM -}; - -// data attributes -struct myAnalogValue { - CTYPE_FLOAT32 f; -}; -struct ScaledValueConfig { - CTYPE_FLOAT32 scaleFactor; - CTYPE_FLOAT32 offset; -}; -struct myVector { - struct myAnalogValue mag; - struct myAnalogValue ang; -}; -struct simpleVector { - struct myAnalogValue mag; - struct myAnalogValue ang; -}; - -// data objects -struct myMod { - enum Mod ctlVal; - enum Mod stVal; - CTYPE_QUALITY q; - CTYPE_TIMESTAMP t; -}; -struct myHealth { - enum Health stVal; -}; -struct myBeh { - enum Beh stVal; -}; -struct myINS { - CTYPE_INT32 stVal; -}; -struct myLPL { - CTYPE_VISSTRING255 ldNs; - CTYPE_VISSTRING255 configRev; -}; -struct myDPL { - CTYPE_VISSTRING255 vendor; - CTYPE_VISSTRING255 hwRev; -}; -struct myPos { - CTYPE_DBPOS stVal; - CTYPE_QUALITY q; - CTYPE_TIMESTAMP t; - CTYPE_BOOLEAN ctlVal; -}; -struct mySPS { - CTYPE_INT32 stVal; - CTYPE_QUALITY q; - CTYPE_TIMESTAMP t; -}; -struct myMV { - struct myAnalogValue mag; - CTYPE_QUALITY q; - CTYPE_TIMESTAMP t; - struct ScaledValueConfig sVC; -}; -struct simpleMV { - CTYPE_FLOAT32 mag; - CTYPE_QUALITY q; - CTYPE_TIMESTAMP t; - struct ScaledValueConfig sVC; -}; -struct simpleCMV { - struct simpleVector cVal; - CTYPE_QUALITY q; - CTYPE_TIMESTAMP t; -}; -struct simpleWYE { - struct simpleCMV phsA; - struct simpleCMV phsB; - struct simpleCMV phsC; -}; -struct myCMV { - struct myVector cVal; - CTYPE_QUALITY q; - CTYPE_TIMESTAMP t; -}; -struct mySEQ { - struct myCMV c1; - struct myCMV c2; - struct myCMV c3; - enum seqT seqT; -}; -struct mySAV { - struct myAnalogValue instMag; - CTYPE_QUALITY q; -}; -struct simpleSAV { - struct myAnalogValue instMag; - CTYPE_QUALITY q; -}; - -// logical nodes -struct LN0 { - struct myMod Mod; - struct myHealth Health; - struct myBeh Beh; - struct myLPL NamPlt; -}; -struct LPHDa { - struct myMod Mod; - struct myHealth Health; - struct myBeh Beh; - struct myLPL NamPlt; - struct myDPL PhyNam; - struct myINS PhyHealth; - struct mySPS Proxy; - struct { - struct myAnalogValue instMag_1[2]; - struct myMod Mod_1[2]; - enum Mod stVal_1[2]; - CTYPE_QUALITY q_1[2]; - struct myMV Amps_1[2]; - struct myPos Pos_2[2]; - } sv_inputs; -}; -struct CSWIa { - struct myMod Mod; - struct myHealth Health; - struct myBeh Beh; - struct myPos Pos; - struct mySPS GrpAl; -}; -struct MMXUa { - struct myMod Mod; - struct myHealth Beh; - struct myBeh Health; - struct myMV Amps; - struct myMV Volts; -}; -struct exampleMMXU { - struct myMod Mod; - struct myHealth Beh; - struct myBeh Health; - struct simpleWYE A; - struct { - struct simpleSAV AmpLocPhsA_1[16]; - struct simpleSAV AmpLocPhsB_1[16]; - struct simpleSAV AmpLocPhsC_1[16]; - } sv_inputs; -}; -struct exampleRMXU { - struct myMod Mod; - struct myHealth Beh; - struct myBeh Health; - struct simpleSAV AmpLocPhsA; - struct simpleSAV AmpLocPhsB; - struct simpleSAV AmpLocPhsC; -}; -struct CILOa { - struct myHealth Mod; - struct myBeh Beh; - struct myINS Health; - struct mySPS EnaOpen; - struct mySPS EnaClose; -}; -struct TVTRa { - struct myMod Mod; - struct myHealth Health; - struct myBeh Beh; - struct mySAV Vol; -}; -struct RSYNa { - struct myMod Mod; - struct myHealth Health; - struct myBeh Beh; - struct myLPL NamPlt; - struct mySPS Rel; - struct { - struct myAnalogValue instMag_1[2]; - struct myMod Mod_1[2]; - enum Mod stVal_1[2]; - CTYPE_QUALITY q_1[2]; - struct myMV Amps_1[2]; - struct myPos Pos_2[2]; - } sv_inputs; - struct { - struct myAnalogValue instMag_1; - struct myPos Pos_1; - struct myPos Pos_2; - enum Mod stVal_1; - struct myMV Amps_1; - struct myMV Volts_1; - } gse_inputs; +// enums +enum ACDdir { + ACDDIR_UNKNOWN, + ACDDIR_FORWARD, + ACDDIR_BACKWARD, + ACDDIR_BOTH +}; +enum seqT { + SEQT_POS_NEG_ZERO, + SEQT_DIR_QUAD_ZERO +}; +enum Dbpos { + DBPOS_INTERMEDIATE, + DBPOS_OFF, + DBPOS_ON, + DBPOS_BAD +}; +enum Tcmd { + TCMD_STOP, + TCMD_LOWER, + TCMD_HIGHER, + TCMD_RESERVED +}; +enum Beh { + BEH_ON, + BEH_BLOCKED, + BEH_TEST, + BEH_TEST_BLOCKED, + BEH_OFF +}; +enum Mod { + MOD_ON, + MOD_BLOCKED, + MOD_TEST, + MOD_TEST_BLOCKED, + MOD_OFF +}; +enum Health { + HEALTH_OK, + HEALTH_WARNING, + HEALTH_ALARM +}; + +// data attributes +struct myAnalogValue { + CTYPE_FLOAT32 f; +}; +struct ScaledValueConfig { + CTYPE_FLOAT32 scaleFactor; + CTYPE_FLOAT32 offset; +}; +struct myVector { + struct myAnalogValue mag; + struct myAnalogValue ang; +}; +struct simpleVector { + struct myAnalogValue mag; + struct myAnalogValue ang; }; -void init_datatypes(); +// data objects +struct myMod { + enum Mod ctlVal; + enum Mod stVal; + CTYPE_QUALITY q; + CTYPE_TIMESTAMP t; +}; +struct myHealth { + enum Health stVal; +}; +struct myBeh { + enum Beh stVal; +}; +struct myINS { + CTYPE_INT32 stVal; +}; +struct myLPL { + CTYPE_VISSTRING255 ldNs; + CTYPE_VISSTRING255 configRev; +}; +struct myDPL { + CTYPE_VISSTRING255 vendor; + CTYPE_VISSTRING255 hwRev; +}; +struct myPos { + CTYPE_DBPOS stVal; + CTYPE_QUALITY q; + CTYPE_TIMESTAMP t; + CTYPE_BOOLEAN ctlVal; +}; +struct mySPS { + CTYPE_INT32 stVal; + CTYPE_QUALITY q; + CTYPE_TIMESTAMP t; +}; +struct myMV { + struct myAnalogValue mag; + CTYPE_QUALITY q; + CTYPE_TIMESTAMP t; + struct ScaledValueConfig sVC; +}; +struct simpleMV { + CTYPE_FLOAT32 mag; + CTYPE_QUALITY q; + CTYPE_TIMESTAMP t; + struct ScaledValueConfig sVC; +}; +struct simpleCMV { + struct simpleVector cVal; + CTYPE_QUALITY q; + CTYPE_TIMESTAMP t; +}; +struct simpleWYE { + struct simpleCMV phsA; + struct simpleCMV phsB; + struct simpleCMV phsC; +}; +struct myCMV { + struct myVector cVal; + CTYPE_QUALITY q; + CTYPE_TIMESTAMP t; +}; +struct mySEQ { + struct myCMV c1; + struct myCMV c2; + struct myCMV c3; + enum seqT seqT; +}; +struct mySAV { + struct myAnalogValue instMag; + CTYPE_QUALITY q; +}; +struct simpleSAV { + struct myAnalogValue instMag; + CTYPE_QUALITY q; +}; + +// logical nodes +struct LN0 { + struct myMod Mod; + struct myHealth Health; + struct myBeh Beh; + struct myLPL NamPlt; +}; +struct LPHDa { + struct myMod Mod; + struct myHealth Health; + struct myBeh Beh; + struct myLPL NamPlt; + struct myDPL PhyNam; + struct myINS PhyHealth; + struct mySPS Proxy; + struct { + struct myAnalogValue instMag_1[2]; + struct myMod Mod_1[2]; + enum Mod stVal_1[2]; + CTYPE_QUALITY q_1[2]; + struct myMV Amps_1[2]; + struct myPos Pos_2[2]; + } sv_inputs; +}; +struct CSWIa { + struct myMod Mod; + struct myHealth Health; + struct myBeh Beh; + struct myPos Pos; + struct mySPS GrpAl; +}; +struct MMXUa { + struct myMod Mod; + struct myHealth Beh; + struct myBeh Health; + struct myMV Amps; + struct myMV Volts; +}; +struct exampleMMXU { + struct myMod Mod; + struct myHealth Beh; + struct myBeh Health; + struct simpleWYE A; + struct { + struct simpleSAV AmpLocPhsA_1[16]; + struct simpleSAV AmpLocPhsB_1[16]; + struct simpleSAV AmpLocPhsC_1[16]; + } sv_inputs; +}; +struct exampleRMXU { + struct myMod Mod; + struct myHealth Beh; + struct myBeh Health; + struct simpleSAV AmpLocPhsA; + struct simpleSAV AmpLocPhsB; + struct simpleSAV AmpLocPhsC; +}; +struct CILOa { + struct myHealth Mod; + struct myBeh Beh; + struct myINS Health; + struct mySPS EnaOpen; + struct mySPS EnaClose; +}; +struct TVTRa { + struct myMod Mod; + struct myHealth Health; + struct myBeh Beh; + struct mySAV Vol; +}; +struct RSYNa { + struct myMod Mod; + struct myHealth Health; + struct myBeh Beh; + struct myLPL NamPlt; + struct mySPS Rel; + struct { + struct myAnalogValue instMag_1[2]; + struct myMod Mod_1[2]; + enum Mod stVal_1[2]; + CTYPE_QUALITY q_1[2]; + struct myMV Amps_1[2]; + struct myPos Pos_2[2]; + } sv_inputs; + struct { + struct myAnalogValue instMag_1; + struct myPos Pos_1; + struct myPos Pos_2; + enum Mod stVal_1; + struct myMV Amps_1; + struct myMV Volts_1; + } gse_inputs; +}; + +void init_datatypes();
diff -r 230c10b228ea -r 9399d44c2b1a decodePacket.c --- a/decodePacket.c Fri Oct 07 13:41:08 2011 +0000 +++ b/decodePacket.c Fri Oct 07 13:48:18 2011 +0000 @@ -1,32 +1,52 @@ +/** + * Rapid-prototyping protection schemes with IEC 61850 + * + * Copyright (c) 2011 Steven Blair + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + #include "decodePacket.h" //#include "svEncodeBasic.h" // returns size of length field, from first byte int getLengthFieldSize(unsigned char byte) { - if (byte <= 126) { - return 1; - } - else { - return 1 + (byte & 0x7F); - } + if (byte <= 126) { + return 1; + } + else { + return 1 + (byte & 0x7F); + } } -//TODO check this works for all inputs, e.g., buf[1] = 0xFF +//TODO check this works for all inputs, e.g., buf[1] = 0xFF int decodeLength(unsigned char *buf) { - if (buf[0] <= 126) { - return buf[0]; - } - else { - int bytes = (buf[0] & 0x7F); + if (buf[0] <= 126) { + return buf[0]; + } + else { + int bytes = (buf[0] & 0x7F); - if (bytes == 1) { - return buf[1]; - } - else if (bytes == 2) { // assumes max length of 2^15 - return ((buf[1] & 0xFF) << 8) | (buf[2] & 0xFF); - } - } + if (bytes == 1) { + return buf[1]; + } + else if (bytes == 2) { // assumes max length of 2^15 + return ((buf[1] & 0xFF) << 8) | (buf[2] & 0xFF); + } + } - return 0; + return 0; }
diff -r 230c10b228ea -r 9399d44c2b1a decodePacket.h --- a/decodePacket.h Fri Oct 07 13:41:08 2011 +0000 +++ b/decodePacket.h Fri Oct 07 13:48:18 2011 +0000 @@ -1,3 +1,23 @@ +/** + * Rapid-prototyping protection schemes with IEC 61850 + * + * Copyright (c) 2011 Steven Blair + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + #ifndef DECODE_PACKET_H #define DECODE_PACKET_H
diff -r 230c10b228ea -r 9399d44c2b1a encodePacket.c --- a/encodePacket.c Fri Oct 07 13:41:08 2011 +0000 +++ b/encodePacket.c Fri Oct 07 13:48:18 2011 +0000 @@ -1,34 +1,54 @@ +/** + * Rapid-prototyping protection schemes with IEC 61850 + * + * Copyright (c) 2011 Steven Blair + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + #include "encodePacket.h" #include "svEncodeBasic.h" int getLengthBytes(int len) { - if (len <= 126) { - return 1; - } - else if (len <= 255) { - return 2; - } - else { - return 3; - } + if (len <= 126) { + return 1; + } + else if (len <= 255) { + return 2; + } + else { + return 3; + } } int encodeLength(unsigned char *buf, CTYPE_INT16U len) { - if (len <= 126) { - buf[0] = (unsigned char) len; - return 1; - } - else if (len <= 255) { - buf[0] = (unsigned char) 0x81; // 0x80 specifies larger than one byte; 0x02 is number of length bytes to follow - buf[1] = (unsigned char) len; + if (len <= 126) { + buf[0] = (unsigned char) len; + return 1; + } + else if (len <= 255) { + buf[0] = (unsigned char) 0x81; // 0x80 specifies larger than one byte; 0x02 is number of length bytes to follow + buf[1] = (unsigned char) len; - return 2; - } - else { - // assume length is not greater than 2^15 - buf[0] = (unsigned char) 0x82; // 0x80 specifies larger than one byte; 0x02 is number of length bytes to follow - ENCODE_CTYPE_INT16U(&buf[1], &len); + return 2; + } + else { + // assume length is not greater than 2^15 + buf[0] = (unsigned char) 0x82; // 0x80 specifies larger than one byte; 0x02 is number of length bytes to follow + ENCODE_CTYPE_INT16U(&buf[1], &len); - return 3; - } + return 3; + } }
diff -r 230c10b228ea -r 9399d44c2b1a encodePacket.h --- a/encodePacket.h Fri Oct 07 13:41:08 2011 +0000 +++ b/encodePacket.h Fri Oct 07 13:48:18 2011 +0000 @@ -1,3 +1,23 @@ +/** + * Rapid-prototyping protection schemes with IEC 61850 + * + * Copyright (c) 2011 Steven Blair + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + #ifndef ENCODE_PACKET_H #define ENCODE_PACKET_H
diff -r 230c10b228ea -r 9399d44c2b1a gse.c --- a/gse.c Fri Oct 07 13:41:08 2011 +0000 +++ b/gse.c Fri Oct 07 13:48:18 2011 +0000 @@ -1,155 +1,175 @@ -#include "gsePacketData.h" -#include "gseDecode.h" +/** + * Rapid-prototyping protection schemes with IEC 61850 + * + * Copyright (c) 2011 Steven Blair + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "gsePacketData.h" +#include "gseDecode.h" #include "gseEncode.h" -struct gseData ItlPositions_Itl; -struct gseData SyckResult_SynChk; -struct gseData MMXUResult_MMXUResult; +struct gseData ItlPositions_Itl; +struct gseData SyckResult_SynChk; +struct gseData MMXUResult_MMXUResult; + - -// returns 1 if buf contains valid packet data -int gse_send_ItlPositions_Itl(unsigned char *buf, CTYPE_BOOLEAN statusChange, CTYPE_INT32U timeAllowedToLive) { - ItlPositions_Itl.timeAllowedToLive = timeAllowedToLive; - - if (statusChange) { - ItlPositions_Itl.stNum++; - if (ItlPositions_Itl.stNum == 0) { - ItlPositions_Itl.stNum = 1; - } - ItlPositions_Itl.sqNum = 0; - } - else { - ItlPositions_Itl.sqNum++; - if (ItlPositions_Itl.sqNum == 0) { - ItlPositions_Itl.sqNum = 1; - } - } - - return gseEncodePacket(&ItlPositions_Itl, buf); -} - -// returns 1 if buf contains valid packet data -int gse_send_SyckResult_SynChk(unsigned char *buf, CTYPE_BOOLEAN statusChange, CTYPE_INT32U timeAllowedToLive) { - SyckResult_SynChk.timeAllowedToLive = timeAllowedToLive; - - if (statusChange) { - SyckResult_SynChk.stNum++; - if (SyckResult_SynChk.stNum == 0) { - SyckResult_SynChk.stNum = 1; - } - SyckResult_SynChk.sqNum = 0; - } - else { - SyckResult_SynChk.sqNum++; - if (SyckResult_SynChk.sqNum == 0) { - SyckResult_SynChk.sqNum = 1; - } - } - - return gseEncodePacket(&SyckResult_SynChk, buf); -} - -// returns 1 if buf contains valid packet data -int gse_send_MMXUResult_MMXUResult(unsigned char *buf, CTYPE_BOOLEAN statusChange, CTYPE_INT32U timeAllowedToLive) { - MMXUResult_MMXUResult.timeAllowedToLive = timeAllowedToLive; - - if (statusChange) { - MMXUResult_MMXUResult.stNum++; - if (MMXUResult_MMXUResult.stNum == 0) { - MMXUResult_MMXUResult.stNum = 1; - } - MMXUResult_MMXUResult.sqNum = 0; - } - else { - MMXUResult_MMXUResult.sqNum++; - if (MMXUResult_MMXUResult.sqNum == 0) { - MMXUResult_MMXUResult.sqNum = 1; - } - } - - return gseEncodePacket(&MMXUResult_MMXUResult, buf); -} - -void init_gse() { - ItlPositions_Itl.ethHeaderData.destMACAddress[0] = 0x01; - ItlPositions_Itl.ethHeaderData.destMACAddress[1] = 0x0C; - ItlPositions_Itl.ethHeaderData.destMACAddress[2] = 0xCD; - ItlPositions_Itl.ethHeaderData.destMACAddress[3] = 0x01; - ItlPositions_Itl.ethHeaderData.destMACAddress[4] = 0x00; - ItlPositions_Itl.ethHeaderData.destMACAddress[5] = 0x04; - ItlPositions_Itl.ethHeaderData.APPID = 0x3000; - ItlPositions_Itl.ethHeaderData.VLAN_PRIORITY = 0x4; - ItlPositions_Itl.ethHeaderData.VLAN_ID = 4; - ItlPositions_Itl.goID = (unsigned char *) malloc(4); - strncpy((char *) ItlPositions_Itl.goID, "Itl\0", 4); - ItlPositions_Itl.t = 0; - ItlPositions_Itl.gocbRef = (unsigned char *) malloc(28); - strncpy((char *) ItlPositions_Itl.gocbRef, "E1Q1SB1C1/LLN0$ItlPositions\0", 28); - ItlPositions_Itl.datSet = (unsigned char *) malloc(25); - strncpy((char *) ItlPositions_Itl.datSet, "E1Q1SB1C1/LLN0$Positions\0", 25); - ItlPositions_Itl.timeAllowedToLive = 0; - ItlPositions_Itl.stNum = 0; - ItlPositions_Itl.sqNum = 0; - ItlPositions_Itl.test = 0; - ItlPositions_Itl.confRev = 1; - ItlPositions_Itl.ndsCom = 0; - ItlPositions_Itl.numDatSetEntries = 6; - ItlPositions_Itl.encodeDataset = &ber_encode_Itl; - ItlPositions_Itl.getDatasetLength = &ber_get_length_Itl; - - SyckResult_SynChk.ethHeaderData.destMACAddress[0] = 0x01; - SyckResult_SynChk.ethHeaderData.destMACAddress[1] = 0x0C; - SyckResult_SynChk.ethHeaderData.destMACAddress[2] = 0xCD; - SyckResult_SynChk.ethHeaderData.destMACAddress[3] = 0x01; - SyckResult_SynChk.ethHeaderData.destMACAddress[4] = 0x00; - SyckResult_SynChk.ethHeaderData.destMACAddress[5] = 0x02; - SyckResult_SynChk.ethHeaderData.APPID = 0x3001; - SyckResult_SynChk.ethHeaderData.VLAN_PRIORITY = 0x4; - SyckResult_SynChk.ethHeaderData.VLAN_ID = 4; - SyckResult_SynChk.goID = (unsigned char *) malloc(7); - strncpy((char *) SyckResult_SynChk.goID, "SynChk\0", 7); - SyckResult_SynChk.t = 0; - SyckResult_SynChk.gocbRef = (unsigned char *) malloc(26); - strncpy((char *) SyckResult_SynChk.gocbRef, "D1Q1SB4C1/LLN0$SyckResult\0", 26); - SyckResult_SynChk.datSet = (unsigned char *) malloc(26); - strncpy((char *) SyckResult_SynChk.datSet, "D1Q1SB4C1/LLN0$SyckResult\0", 26); - SyckResult_SynChk.timeAllowedToLive = 0; - SyckResult_SynChk.stNum = 0; - SyckResult_SynChk.sqNum = 0; - SyckResult_SynChk.test = 0; - SyckResult_SynChk.confRev = 0; - SyckResult_SynChk.ndsCom = 0; - SyckResult_SynChk.numDatSetEntries = 1; - SyckResult_SynChk.encodeDataset = &ber_encode_SynChk; - SyckResult_SynChk.getDatasetLength = &ber_get_length_SynChk; - - MMXUResult_MMXUResult.ethHeaderData.destMACAddress[0] = 0x01; - MMXUResult_MMXUResult.ethHeaderData.destMACAddress[1] = 0x0C; - MMXUResult_MMXUResult.ethHeaderData.destMACAddress[2] = 0xCD; - MMXUResult_MMXUResult.ethHeaderData.destMACAddress[3] = 0x01; - MMXUResult_MMXUResult.ethHeaderData.destMACAddress[4] = 0x00; - MMXUResult_MMXUResult.ethHeaderData.destMACAddress[5] = 0x02; - MMXUResult_MMXUResult.ethHeaderData.APPID = 0x3001; - MMXUResult_MMXUResult.ethHeaderData.VLAN_PRIORITY = 0x4; - MMXUResult_MMXUResult.ethHeaderData.VLAN_ID = 4; - MMXUResult_MMXUResult.goID = (unsigned char *) malloc(11); - strncpy((char *) MMXUResult_MMXUResult.goID, "MMXUResult\0", 11); - MMXUResult_MMXUResult.t = 0; - MMXUResult_MMXUResult.gocbRef = (unsigned char *) malloc(26); - strncpy((char *) MMXUResult_MMXUResult.gocbRef, "D1Q1SB4C1/LLN0$MMXUResult\0", 26); - MMXUResult_MMXUResult.datSet = (unsigned char *) malloc(26); - strncpy((char *) MMXUResult_MMXUResult.datSet, "D1Q1SB4C1/LLN0$MMXUResult\0", 26); - MMXUResult_MMXUResult.timeAllowedToLive = 0; - MMXUResult_MMXUResult.stNum = 0; - MMXUResult_MMXUResult.sqNum = 0; - MMXUResult_MMXUResult.test = 0; - MMXUResult_MMXUResult.confRev = 0; - MMXUResult_MMXUResult.ndsCom = 0; - MMXUResult_MMXUResult.numDatSetEntries = 1; - MMXUResult_MMXUResult.encodeDataset = &ber_encode_MMXUResult; - MMXUResult_MMXUResult.getDatasetLength = &ber_get_length_MMXUResult; - -} +// returns 1 if buf contains valid packet data +int gse_send_ItlPositions_Itl(unsigned char *buf, CTYPE_BOOLEAN statusChange, CTYPE_INT32U timeAllowedToLive) { + ItlPositions_Itl.timeAllowedToLive = timeAllowedToLive; + + if (statusChange) { + ItlPositions_Itl.stNum++; + if (ItlPositions_Itl.stNum == 0) { + ItlPositions_Itl.stNum = 1; + } + ItlPositions_Itl.sqNum = 0; + } + else { + ItlPositions_Itl.sqNum++; + if (ItlPositions_Itl.sqNum == 0) { + ItlPositions_Itl.sqNum = 1; + } + } + + return gseEncodePacket(&ItlPositions_Itl, buf); +} + +// returns 1 if buf contains valid packet data +int gse_send_SyckResult_SynChk(unsigned char *buf, CTYPE_BOOLEAN statusChange, CTYPE_INT32U timeAllowedToLive) { + SyckResult_SynChk.timeAllowedToLive = timeAllowedToLive; + + if (statusChange) { + SyckResult_SynChk.stNum++; + if (SyckResult_SynChk.stNum == 0) { + SyckResult_SynChk.stNum = 1; + } + SyckResult_SynChk.sqNum = 0; + } + else { + SyckResult_SynChk.sqNum++; + if (SyckResult_SynChk.sqNum == 0) { + SyckResult_SynChk.sqNum = 1; + } + } + + return gseEncodePacket(&SyckResult_SynChk, buf); +} + +// returns 1 if buf contains valid packet data +int gse_send_MMXUResult_MMXUResult(unsigned char *buf, CTYPE_BOOLEAN statusChange, CTYPE_INT32U timeAllowedToLive) { + MMXUResult_MMXUResult.timeAllowedToLive = timeAllowedToLive; + + if (statusChange) { + MMXUResult_MMXUResult.stNum++; + if (MMXUResult_MMXUResult.stNum == 0) { + MMXUResult_MMXUResult.stNum = 1; + } + MMXUResult_MMXUResult.sqNum = 0; + } + else { + MMXUResult_MMXUResult.sqNum++; + if (MMXUResult_MMXUResult.sqNum == 0) { + MMXUResult_MMXUResult.sqNum = 1; + } + } + + return gseEncodePacket(&MMXUResult_MMXUResult, buf); +} +void init_gse() { + ItlPositions_Itl.ethHeaderData.destMACAddress[0] = 0x01; + ItlPositions_Itl.ethHeaderData.destMACAddress[1] = 0x0C; + ItlPositions_Itl.ethHeaderData.destMACAddress[2] = 0xCD; + ItlPositions_Itl.ethHeaderData.destMACAddress[3] = 0x01; + ItlPositions_Itl.ethHeaderData.destMACAddress[4] = 0x00; + ItlPositions_Itl.ethHeaderData.destMACAddress[5] = 0x04; + ItlPositions_Itl.ethHeaderData.APPID = 0x3000; + ItlPositions_Itl.ethHeaderData.VLAN_PRIORITY = 0x4; + ItlPositions_Itl.ethHeaderData.VLAN_ID = 4; + ItlPositions_Itl.goID = (unsigned char *) malloc(4); + strncpy((char *) ItlPositions_Itl.goID, "Itl\0", 4); + ItlPositions_Itl.t = 0; + ItlPositions_Itl.gocbRef = (unsigned char *) malloc(28); + strncpy((char *) ItlPositions_Itl.gocbRef, "E1Q1SB1C1/LLN0$ItlPositions\0", 28); + ItlPositions_Itl.datSet = (unsigned char *) malloc(25); + strncpy((char *) ItlPositions_Itl.datSet, "E1Q1SB1C1/LLN0$Positions\0", 25); + ItlPositions_Itl.timeAllowedToLive = 0; + ItlPositions_Itl.stNum = 0; + ItlPositions_Itl.sqNum = 0; + ItlPositions_Itl.test = 0; + ItlPositions_Itl.confRev = 1; + ItlPositions_Itl.ndsCom = 0; + ItlPositions_Itl.numDatSetEntries = 6; + ItlPositions_Itl.encodeDataset = &ber_encode_Itl; + ItlPositions_Itl.getDatasetLength = &ber_get_length_Itl; + + SyckResult_SynChk.ethHeaderData.destMACAddress[0] = 0x01; + SyckResult_SynChk.ethHeaderData.destMACAddress[1] = 0x0C; + SyckResult_SynChk.ethHeaderData.destMACAddress[2] = 0xCD; + SyckResult_SynChk.ethHeaderData.destMACAddress[3] = 0x01; + SyckResult_SynChk.ethHeaderData.destMACAddress[4] = 0x00; + SyckResult_SynChk.ethHeaderData.destMACAddress[5] = 0x02; + SyckResult_SynChk.ethHeaderData.APPID = 0x3001; + SyckResult_SynChk.ethHeaderData.VLAN_PRIORITY = 0x4; + SyckResult_SynChk.ethHeaderData.VLAN_ID = 4; + SyckResult_SynChk.goID = (unsigned char *) malloc(7); + strncpy((char *) SyckResult_SynChk.goID, "SynChk\0", 7); + SyckResult_SynChk.t = 0; + SyckResult_SynChk.gocbRef = (unsigned char *) malloc(26); + strncpy((char *) SyckResult_SynChk.gocbRef, "D1Q1SB4C1/LLN0$SyckResult\0", 26); + SyckResult_SynChk.datSet = (unsigned char *) malloc(26); + strncpy((char *) SyckResult_SynChk.datSet, "D1Q1SB4C1/LLN0$SyckResult\0", 26); + SyckResult_SynChk.timeAllowedToLive = 0; + SyckResult_SynChk.stNum = 0; + SyckResult_SynChk.sqNum = 0; + SyckResult_SynChk.test = 0; + SyckResult_SynChk.confRev = 0; + SyckResult_SynChk.ndsCom = 0; + SyckResult_SynChk.numDatSetEntries = 1; + SyckResult_SynChk.encodeDataset = &ber_encode_SynChk; + SyckResult_SynChk.getDatasetLength = &ber_get_length_SynChk; + + MMXUResult_MMXUResult.ethHeaderData.destMACAddress[0] = 0x01; + MMXUResult_MMXUResult.ethHeaderData.destMACAddress[1] = 0x0C; + MMXUResult_MMXUResult.ethHeaderData.destMACAddress[2] = 0xCD; + MMXUResult_MMXUResult.ethHeaderData.destMACAddress[3] = 0x01; + MMXUResult_MMXUResult.ethHeaderData.destMACAddress[4] = 0x00; + MMXUResult_MMXUResult.ethHeaderData.destMACAddress[5] = 0x02; + MMXUResult_MMXUResult.ethHeaderData.APPID = 0x3001; + MMXUResult_MMXUResult.ethHeaderData.VLAN_PRIORITY = 0x4; + MMXUResult_MMXUResult.ethHeaderData.VLAN_ID = 4; + MMXUResult_MMXUResult.goID = (unsigned char *) malloc(11); + strncpy((char *) MMXUResult_MMXUResult.goID, "MMXUResult\0", 11); + MMXUResult_MMXUResult.t = 0; + MMXUResult_MMXUResult.gocbRef = (unsigned char *) malloc(26); + strncpy((char *) MMXUResult_MMXUResult.gocbRef, "D1Q1SB4C1/LLN0$MMXUResult\0", 26); + MMXUResult_MMXUResult.datSet = (unsigned char *) malloc(26); + strncpy((char *) MMXUResult_MMXUResult.datSet, "D1Q1SB4C1/LLN0$MMXUResult\0", 26); + MMXUResult_MMXUResult.timeAllowedToLive = 0; + MMXUResult_MMXUResult.stNum = 0; + MMXUResult_MMXUResult.sqNum = 0; + MMXUResult_MMXUResult.test = 0; + MMXUResult_MMXUResult.confRev = 0; + MMXUResult_MMXUResult.ndsCom = 0; + MMXUResult_MMXUResult.numDatSetEntries = 1; + MMXUResult_MMXUResult.encodeDataset = &ber_encode_MMXUResult; + MMXUResult_MMXUResult.getDatasetLength = &ber_get_length_MMXUResult; + +} +
diff -r 230c10b228ea -r 9399d44c2b1a gse.h --- a/gse.h Fri Oct 07 13:41:08 2011 +0000 +++ b/gse.h Fri Oct 07 13:48:18 2011 +0000 @@ -1,16 +1,31 @@ +/** + * Rapid-prototyping protection schemes with IEC 61850 + * + * Copyright (c) 2011 Steven Blair + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + #ifndef GSE_H #define GSE_H -//#ifdef __cplusplus /* If this is a C++ compiler, use C linkage */ -//extern "C" { -//#endif - #include "gseEncode.h" #include "gseDecode.h" #include "gsePacketData.h" - void init_gse(); int gse_send_ItlPositions_Itl(unsigned char *buf, CTYPE_BOOLEAN statusChange, CTYPE_INT32U timeAllowedToLive); int gse_send_SyckResult_SynChk(unsigned char *buf, CTYPE_BOOLEAN statusChange, CTYPE_INT32U timeAllowedToLive); @@ -18,10 +33,4 @@ void gseDecode(unsigned char *buf, int len); - - -//#ifdef __cplusplus /* If this is a C++ compiler, end C linkage */ -//} -//#endif - #endif
diff -r 230c10b228ea -r 9399d44c2b1a gseDecode.c --- a/gseDecode.c Fri Oct 07 13:41:08 2011 +0000 +++ b/gseDecode.c Fri Oct 07 13:48:18 2011 +0000 @@ -1,3 +1,23 @@ +/** + * Rapid-prototyping protection schemes with IEC 61850 + * + * Copyright (c) 2011 Steven Blair + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + #include "gseDecodeBasic.h" #include "ied.h" #include "gseDecode.h"
diff -r 230c10b228ea -r 9399d44c2b1a gseDecode.h --- a/gseDecode.h Fri Oct 07 13:41:08 2011 +0000 +++ b/gseDecode.h Fri Oct 07 13:48:18 2011 +0000 @@ -1,3 +1,23 @@ +/** + * Rapid-prototyping protection schemes with IEC 61850 + * + * Copyright (c) 2011 Steven Blair + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + #ifndef GSE_DECODE_H #define GSE_DECODE_H @@ -9,8 +29,8 @@ -int ber_decode_Positions_RSYN_1(unsigned char *buf); - +int ber_decode_Positions_RSYN_1(unsigned char *buf); + void gseDecodeDataset(unsigned char *dataset, int datasetLength, unsigned char *datSet, int datSetLength);
diff -r 230c10b228ea -r 9399d44c2b1a gseDecodeBasic.c --- a/gseDecodeBasic.c Fri Oct 07 13:41:08 2011 +0000 +++ b/gseDecodeBasic.c Fri Oct 07 13:48:18 2011 +0000 @@ -1,3 +1,23 @@ +/** + * Rapid-prototyping protection schemes with IEC 61850 + * + * Copyright (c) 2011 Steven Blair + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + #include "ctypes.h" #include "datatypes.h" #include "ied.h" @@ -6,150 +26,150 @@ // GSE decoding of basic types int BER_DECODE_CTYPE_FLOAT32(unsigned char *buf, CTYPE_FLOAT32 *value) { - CTYPE_INT16U offset = 0; - CTYPE_INT16U len = 0; + CTYPE_INT16U offset = 0; + CTYPE_INT16U len = 0; - if (buf[offset++] == 0x87) { - len += decodeLength(&buf[offset]); - offset += getLengthFieldSize(buf[offset]); + if (buf[offset++] == 0x87) { + len += decodeLength(&buf[offset]); + offset += getLengthFieldSize(buf[offset]); - // check for 8 bits for exponent - if (buf[offset++] == 0x08) { - netmemcpy(value, &buf[offset], len - 1); - } - } + // check for 8 bits for exponent + if (buf[offset++] == 0x08) { + netmemcpy(value, &buf[offset], len - 1); + } + } - return offset + len - 1; + return offset + len - 1; } // GSE decoding of basic types int BER_DECODE_CTYPE_FLOAT64(unsigned char *buf, CTYPE_FLOAT64 *value) { - CTYPE_INT16U offset = 0; - CTYPE_INT16U len = 0; + CTYPE_INT16U offset = 0; + CTYPE_INT16U len = 0; - if (buf[offset++] == 0x87) { - len += decodeLength(&buf[offset]); - offset += getLengthFieldSize(buf[offset]); + if (buf[offset++] == 0x87) { + len += decodeLength(&buf[offset]); + offset += getLengthFieldSize(buf[offset]); - // check for 11 bits for exponent - if (buf[offset++] == 0x0B) { - netmemcpy(value, &buf[offset], len - 1); - } - } + // check for 11 bits for exponent + if (buf[offset++] == 0x0B) { + netmemcpy(value, &buf[offset], len - 1); + } + } - return offset + len - 1; + return offset + len - 1; } int BER_DECODE_CTYPE_QUALITY(unsigned char *buf, CTYPE_QUALITY *value) { - CTYPE_INT16U offset = 0; - CTYPE_INT16U len = 0; + CTYPE_INT16U offset = 0; + CTYPE_INT16U len = 0; - if (buf[offset++] == 0x85) { - len += decodeLength(&buf[offset]); - offset += getLengthFieldSize(buf[offset]); + if (buf[offset++] == 0x85) { + len += decodeLength(&buf[offset]); + offset += getLengthFieldSize(buf[offset]); - netmemcpy(value, buf, len); //TODO check if memcpy should be used here, and elsewhere - } + netmemcpy(value, buf, len); //TODO check if memcpy should be used here, and elsewhere + } - return offset + len; + return offset + len; } int BER_DECODE_CTYPE_TIMESTAMP(unsigned char *buf, CTYPE_TIMESTAMP *value) { - CTYPE_INT16U offset = 0; - CTYPE_INT16U len = 0; + CTYPE_INT16U offset = 0; + CTYPE_INT16U len = 0; - if (buf[offset++] == 0x89) { - len += decodeLength(&buf[offset]); - offset += getLengthFieldSize(buf[offset]); + if (buf[offset++] == 0x89) { + len += decodeLength(&buf[offset]); + offset += getLengthFieldSize(buf[offset]); - netmemcpy(value, buf, len); - } + netmemcpy(value, buf, len); + } - return offset + len; + return offset + len; } -int BER_DECODE_CTYPE_ENUM(unsigned char *buf, CTYPE_ENUM *value) { // assuming enum is an int - allows any enum type to be used - CTYPE_INT16U offset = 0; - CTYPE_INT16U len = 0; +int BER_DECODE_CTYPE_ENUM(unsigned char *buf, CTYPE_ENUM *value) { // assuming enum is an int - allows any enum type to be used + CTYPE_INT16U offset = 0; + CTYPE_INT16U len = 0; - if (buf[offset++] == ASN1_TAG_UNSIGNED) { - len += decodeLength(&buf[offset]); - offset += getLengthFieldSize(buf[offset]); + if (buf[offset++] == ASN1_TAG_UNSIGNED) { + len += decodeLength(&buf[offset]); + offset += getLengthFieldSize(buf[offset]); - ber_decode_integer(&buf[offset], len, value, SV_GET_LENGTH_INT32U); - } + ber_decode_integer(&buf[offset], len, value, SV_GET_LENGTH_INT32U); + } - return offset + len; + return offset + len; } int BER_DECODE_CTYPE_INT16(unsigned char *buf, CTYPE_INT16 *value) { - CTYPE_INT16U offset = 0; - CTYPE_INT16U len = 0; + CTYPE_INT16U offset = 0; + CTYPE_INT16U len = 0; - if (buf[offset++] == ASN1_TAG_INTEGER) { - len += decodeLength(&buf[offset]); - offset += getLengthFieldSize(buf[offset]); + if (buf[offset++] == ASN1_TAG_INTEGER) { + len += decodeLength(&buf[offset]); + offset += getLengthFieldSize(buf[offset]); - ber_decode_integer(&buf[offset], len, value, SV_GET_LENGTH_INT16); - } + ber_decode_integer(&buf[offset], len, value, SV_GET_LENGTH_INT16); + } - return offset + len; + return offset + len; } int BER_DECODE_CTYPE_INT32(unsigned char *buf, CTYPE_INT32 *value) { - CTYPE_INT16U offset = 0; - CTYPE_INT16U len = 0; + CTYPE_INT16U offset = 0; + CTYPE_INT16U len = 0; - if (buf[offset++] == ASN1_TAG_INTEGER) { - len += decodeLength(&buf[offset]); - offset += getLengthFieldSize(buf[offset]); + if (buf[offset++] == ASN1_TAG_INTEGER) { + len += decodeLength(&buf[offset]); + offset += getLengthFieldSize(buf[offset]); - ber_decode_integer(&buf[offset], len, value, SV_GET_LENGTH_INT32); - } + ber_decode_integer(&buf[offset], len, value, SV_GET_LENGTH_INT32); + } - return offset + len; + return offset + len; } int BER_DECODE_CTYPE_INT16U(unsigned char *buf, CTYPE_INT16U *value) { - CTYPE_INT16U offset = 0; - CTYPE_INT16U len = 0; + CTYPE_INT16U offset = 0; + CTYPE_INT16U len = 0; - if (buf[offset++] == ASN1_TAG_UNSIGNED) { - len += decodeLength(&buf[offset]); - offset += getLengthFieldSize(buf[offset]); + if (buf[offset++] == ASN1_TAG_UNSIGNED) { + len += decodeLength(&buf[offset]); + offset += getLengthFieldSize(buf[offset]); - ber_decode_integer(&buf[offset], len, value, SV_GET_LENGTH_INT16U); - } + ber_decode_integer(&buf[offset], len, value, SV_GET_LENGTH_INT16U); + } - return offset + len; + return offset + len; } int BER_DECODE_CTYPE_INT32U(unsigned char *buf, CTYPE_INT32U *value) { - CTYPE_INT16U offset = 0; - CTYPE_INT16U len = 0; + CTYPE_INT16U offset = 0; + CTYPE_INT16U len = 0; - if (buf[offset++] == ASN1_TAG_UNSIGNED) { - len += decodeLength(&buf[offset]); - offset += getLengthFieldSize(buf[offset]); + if (buf[offset++] == ASN1_TAG_UNSIGNED) { + len += decodeLength(&buf[offset]); + offset += getLengthFieldSize(buf[offset]); - ber_decode_integer(&buf[offset], len, value, SV_GET_LENGTH_INT32U); - } + ber_decode_integer(&buf[offset], len, value, SV_GET_LENGTH_INT32U); + } - return offset + len; + return offset + len; } int BER_DECODE_CTYPE_VISSTRING255(unsigned char *buf, CTYPE_VISSTRING255 *value) { - netmemcpy(value, buf, SV_GET_LENGTH_VISSTRING255); + netmemcpy(value, buf, SV_GET_LENGTH_VISSTRING255); - return SV_GET_LENGTH_VISSTRING255; + return SV_GET_LENGTH_VISSTRING255; } int BER_DECODE_CTYPE_BOOLEAN(unsigned char *buf, CTYPE_BOOLEAN *value) { - CTYPE_INT16U offset = 0; - CTYPE_INT16U len = 0; + CTYPE_INT16U offset = 0; + CTYPE_INT16U len = 0; - if (buf[offset++] == ASN1_TAG_BOOLEAN) { - len += decodeLength(&buf[offset]); - offset += getLengthFieldSize(buf[offset]); + if (buf[offset++] == ASN1_TAG_BOOLEAN) { + len += decodeLength(&buf[offset]); + offset += getLengthFieldSize(buf[offset]); - netmemcpy(value, buf, len); - } + netmemcpy(value, buf, len); + } - return offset + len; + return offset + len; } int BER_DECODE_CTYPE_DBPOS(unsigned char *buf, CTYPE_DBPOS *value) { - netmemcpy(value, buf, SV_GET_LENGTH_DBPOS); + netmemcpy(value, buf, SV_GET_LENGTH_DBPOS); - return SV_GET_LENGTH_DBPOS; + return SV_GET_LENGTH_DBPOS; }
diff -r 230c10b228ea -r 9399d44c2b1a gseDecodeBasic.h --- a/gseDecodeBasic.h Fri Oct 07 13:41:08 2011 +0000 +++ b/gseDecodeBasic.h Fri Oct 07 13:48:18 2011 +0000 @@ -1,3 +1,23 @@ +/** + * Rapid-prototyping protection schemes with IEC 61850 + * + * Copyright (c) 2011 Steven Blair + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + #ifndef GSE_BER_DECODE_BASIC_H #define GSE_BER_DECODE_BASIC_H
diff -r 230c10b228ea -r 9399d44c2b1a gseDecodePacket.c --- a/gseDecodePacket.c Fri Oct 07 13:41:08 2011 +0000 +++ b/gseDecodePacket.c Fri Oct 07 13:48:18 2011 +0000 @@ -1,3 +1,23 @@ +/** + * Rapid-prototyping protection schemes with IEC 61850 + * + * Copyright (c) 2011 Steven Blair + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + #include "gseDecodeBasic.h" #include "ied.h" #include "gseDecode.h" @@ -6,13 +26,6 @@ #include <stddef.h> - -//temp -//#include <stdio.h> -//#include <stdlib.h> - - - unsigned char datasetName[65] = {0}; // maximum length of 65 bytes CTYPE_INT16U datasetNameLength = 0;
diff -r 230c10b228ea -r 9399d44c2b1a gseEncode.c --- a/gseEncode.c Fri Oct 07 13:41:08 2011 +0000 +++ b/gseEncode.c Fri Oct 07 13:48:18 2011 +0000 @@ -1,541 +1,561 @@ -#include "gseEncodeBasic.h" -#include "ied.h" +/** + * Rapid-prototyping protection schemes with IEC 61850 + * + * Copyright (c) 2011 Steven Blair + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "gseEncodeBasic.h" +#include "ied.h" #include "gseEncode.h" -int ber_get_length_myAnalogValue(struct myAnalogValue *myAnalogValue) { - int total = 0; - int len = 0; - - len = BER_GET_LENGTH_CTYPE_FLOAT32(&myAnalogValue->f); - total += len + getLengthBytes(len) + 1; - - return total; +int ber_get_length_myAnalogValue(struct myAnalogValue *myAnalogValue) { + int total = 0; + int len = 0; + + len = BER_GET_LENGTH_CTYPE_FLOAT32(&myAnalogValue->f); + total += len + getLengthBytes(len) + 1; + + return total; } -int ber_encode_myAnalogValue(unsigned char *buf, struct myAnalogValue *myAnalogValue) { - int offset = 0; - - buf[offset++] = 0xA2; - offset += encodeLength(&buf[offset], ber_get_length_myAnalogValue(myAnalogValue)); - - offset += BER_ENCODE_CTYPE_FLOAT32(&buf[offset], &myAnalogValue->f); - - return offset; +int ber_encode_myAnalogValue(unsigned char *buf, struct myAnalogValue *myAnalogValue) { + int offset = 0; + + buf[offset++] = 0xA2; + offset += encodeLength(&buf[offset], ber_get_length_myAnalogValue(myAnalogValue)); + + offset += BER_ENCODE_CTYPE_FLOAT32(&buf[offset], &myAnalogValue->f); + + return offset; } -int ber_get_length_ScaledValueConfig(struct ScaledValueConfig *ScaledValueConfig) { - int total = 0; - int len = 0; - - len = BER_GET_LENGTH_CTYPE_FLOAT32(&ScaledValueConfig->scaleFactor); - total += len + getLengthBytes(len) + 1; - len = BER_GET_LENGTH_CTYPE_FLOAT32(&ScaledValueConfig->offset); - total += len + getLengthBytes(len) + 1; - - return total; +int ber_get_length_ScaledValueConfig(struct ScaledValueConfig *ScaledValueConfig) { + int total = 0; + int len = 0; + + len = BER_GET_LENGTH_CTYPE_FLOAT32(&ScaledValueConfig->scaleFactor); + total += len + getLengthBytes(len) + 1; + len = BER_GET_LENGTH_CTYPE_FLOAT32(&ScaledValueConfig->offset); + total += len + getLengthBytes(len) + 1; + + return total; } -int ber_encode_ScaledValueConfig(unsigned char *buf, struct ScaledValueConfig *ScaledValueConfig) { - int offset = 0; - - buf[offset++] = 0xA2; - offset += encodeLength(&buf[offset], ber_get_length_ScaledValueConfig(ScaledValueConfig)); - - offset += BER_ENCODE_CTYPE_FLOAT32(&buf[offset], &ScaledValueConfig->scaleFactor); - offset += BER_ENCODE_CTYPE_FLOAT32(&buf[offset], &ScaledValueConfig->offset); - - return offset; +int ber_encode_ScaledValueConfig(unsigned char *buf, struct ScaledValueConfig *ScaledValueConfig) { + int offset = 0; + + buf[offset++] = 0xA2; + offset += encodeLength(&buf[offset], ber_get_length_ScaledValueConfig(ScaledValueConfig)); + + offset += BER_ENCODE_CTYPE_FLOAT32(&buf[offset], &ScaledValueConfig->scaleFactor); + offset += BER_ENCODE_CTYPE_FLOAT32(&buf[offset], &ScaledValueConfig->offset); + + return offset; } -int ber_get_length_myVector(struct myVector *myVector) { - int total = 0; - int len = 0; - - len = ber_get_length_myAnalogValue(&myVector->mag); - total += len + getLengthBytes(len) + 1; - len = ber_get_length_myAnalogValue(&myVector->ang); - total += len + getLengthBytes(len) + 1; - - return total; +int ber_get_length_myVector(struct myVector *myVector) { + int total = 0; + int len = 0; + + len = ber_get_length_myAnalogValue(&myVector->mag); + total += len + getLengthBytes(len) + 1; + len = ber_get_length_myAnalogValue(&myVector->ang); + total += len + getLengthBytes(len) + 1; + + return total; } -int ber_encode_myVector(unsigned char *buf, struct myVector *myVector) { - int offset = 0; - - buf[offset++] = 0xA2; - offset += encodeLength(&buf[offset], ber_get_length_myVector(myVector)); - - offset += ber_encode_myAnalogValue(&buf[offset], &myVector->mag); - offset += ber_encode_myAnalogValue(&buf[offset], &myVector->ang); - - return offset; +int ber_encode_myVector(unsigned char *buf, struct myVector *myVector) { + int offset = 0; + + buf[offset++] = 0xA2; + offset += encodeLength(&buf[offset], ber_get_length_myVector(myVector)); + + offset += ber_encode_myAnalogValue(&buf[offset], &myVector->mag); + offset += ber_encode_myAnalogValue(&buf[offset], &myVector->ang); + + return offset; } -int ber_get_length_simpleVector(struct simpleVector *simpleVector) { - int total = 0; - int len = 0; - - len = ber_get_length_myAnalogValue(&simpleVector->mag); - total += len + getLengthBytes(len) + 1; - len = ber_get_length_myAnalogValue(&simpleVector->ang); - total += len + getLengthBytes(len) + 1; - - return total; +int ber_get_length_simpleVector(struct simpleVector *simpleVector) { + int total = 0; + int len = 0; + + len = ber_get_length_myAnalogValue(&simpleVector->mag); + total += len + getLengthBytes(len) + 1; + len = ber_get_length_myAnalogValue(&simpleVector->ang); + total += len + getLengthBytes(len) + 1; + + return total; } -int ber_encode_simpleVector(unsigned char *buf, struct simpleVector *simpleVector) { - int offset = 0; - - buf[offset++] = 0xA2; - offset += encodeLength(&buf[offset], ber_get_length_simpleVector(simpleVector)); - - offset += ber_encode_myAnalogValue(&buf[offset], &simpleVector->mag); - offset += ber_encode_myAnalogValue(&buf[offset], &simpleVector->ang); - - return offset; +int ber_encode_simpleVector(unsigned char *buf, struct simpleVector *simpleVector) { + int offset = 0; + + buf[offset++] = 0xA2; + offset += encodeLength(&buf[offset], ber_get_length_simpleVector(simpleVector)); + + offset += ber_encode_myAnalogValue(&buf[offset], &simpleVector->mag); + offset += ber_encode_myAnalogValue(&buf[offset], &simpleVector->ang); + + return offset; } -int ber_get_length_myMod(struct myMod *myMod) { - int total = 0; - int len = 0; - - len = BER_GET_LENGTH_CTYPE_ENUM((CTYPE_ENUM *) &myMod->ctlVal); - total += len + getLengthBytes(len) + 1; - len = BER_GET_LENGTH_CTYPE_ENUM((CTYPE_ENUM *) &myMod->stVal); - total += len + getLengthBytes(len) + 1; - len = BER_GET_LENGTH_CTYPE_QUALITY(&myMod->q); - total += len + getLengthBytes(len) + 1; - len = BER_GET_LENGTH_CTYPE_TIMESTAMP(&myMod->t); - total += len + getLengthBytes(len) + 1; - - return total; +int ber_get_length_myMod(struct myMod *myMod) { + int total = 0; + int len = 0; + + len = BER_GET_LENGTH_CTYPE_ENUM((CTYPE_ENUM *) &myMod->ctlVal); + total += len + getLengthBytes(len) + 1; + len = BER_GET_LENGTH_CTYPE_ENUM((CTYPE_ENUM *) &myMod->stVal); + total += len + getLengthBytes(len) + 1; + len = BER_GET_LENGTH_CTYPE_QUALITY(&myMod->q); + total += len + getLengthBytes(len) + 1; + len = BER_GET_LENGTH_CTYPE_TIMESTAMP(&myMod->t); + total += len + getLengthBytes(len) + 1; + + return total; } -int ber_encode_myMod(unsigned char *buf, struct myMod *myMod) { - int offset = 0; - - buf[offset++] = 0xA2; - offset += encodeLength(&buf[offset], ber_get_length_myMod(myMod)); - - offset += BER_ENCODE_CTYPE_ENUM(&buf[offset], (CTYPE_ENUM *) &myMod->ctlVal); - offset += BER_ENCODE_CTYPE_ENUM(&buf[offset], (CTYPE_ENUM *) &myMod->stVal); - offset += BER_ENCODE_CTYPE_QUALITY(&buf[offset], &myMod->q); - offset += BER_ENCODE_CTYPE_TIMESTAMP(&buf[offset], &myMod->t); - - return offset; +int ber_encode_myMod(unsigned char *buf, struct myMod *myMod) { + int offset = 0; + + buf[offset++] = 0xA2; + offset += encodeLength(&buf[offset], ber_get_length_myMod(myMod)); + + offset += BER_ENCODE_CTYPE_ENUM(&buf[offset], (CTYPE_ENUM *) &myMod->ctlVal); + offset += BER_ENCODE_CTYPE_ENUM(&buf[offset], (CTYPE_ENUM *) &myMod->stVal); + offset += BER_ENCODE_CTYPE_QUALITY(&buf[offset], &myMod->q); + offset += BER_ENCODE_CTYPE_TIMESTAMP(&buf[offset], &myMod->t); + + return offset; } -int ber_get_length_myHealth(struct myHealth *myHealth) { - int total = 0; - int len = 0; - - len = BER_GET_LENGTH_CTYPE_ENUM((CTYPE_ENUM *) &myHealth->stVal); - total += len + getLengthBytes(len) + 1; - - return total; +int ber_get_length_myHealth(struct myHealth *myHealth) { + int total = 0; + int len = 0; + + len = BER_GET_LENGTH_CTYPE_ENUM((CTYPE_ENUM *) &myHealth->stVal); + total += len + getLengthBytes(len) + 1; + + return total; } -int ber_encode_myHealth(unsigned char *buf, struct myHealth *myHealth) { - int offset = 0; - - buf[offset++] = 0xA2; - offset += encodeLength(&buf[offset], ber_get_length_myHealth(myHealth)); - - offset += BER_ENCODE_CTYPE_ENUM(&buf[offset], (CTYPE_ENUM *) &myHealth->stVal); - - return offset; +int ber_encode_myHealth(unsigned char *buf, struct myHealth *myHealth) { + int offset = 0; + + buf[offset++] = 0xA2; + offset += encodeLength(&buf[offset], ber_get_length_myHealth(myHealth)); + + offset += BER_ENCODE_CTYPE_ENUM(&buf[offset], (CTYPE_ENUM *) &myHealth->stVal); + + return offset; } -int ber_get_length_myBeh(struct myBeh *myBeh) { - int total = 0; - int len = 0; - - len = BER_GET_LENGTH_CTYPE_ENUM((CTYPE_ENUM *) &myBeh->stVal); - total += len + getLengthBytes(len) + 1; - - return total; +int ber_get_length_myBeh(struct myBeh *myBeh) { + int total = 0; + int len = 0; + + len = BER_GET_LENGTH_CTYPE_ENUM((CTYPE_ENUM *) &myBeh->stVal); + total += len + getLengthBytes(len) + 1; + + return total; } -int ber_encode_myBeh(unsigned char *buf, struct myBeh *myBeh) { - int offset = 0; - - buf[offset++] = 0xA2; - offset += encodeLength(&buf[offset], ber_get_length_myBeh(myBeh)); - - offset += BER_ENCODE_CTYPE_ENUM(&buf[offset], (CTYPE_ENUM *) &myBeh->stVal); - - return offset; +int ber_encode_myBeh(unsigned char *buf, struct myBeh *myBeh) { + int offset = 0; + + buf[offset++] = 0xA2; + offset += encodeLength(&buf[offset], ber_get_length_myBeh(myBeh)); + + offset += BER_ENCODE_CTYPE_ENUM(&buf[offset], (CTYPE_ENUM *) &myBeh->stVal); + + return offset; } -int ber_get_length_myINS(struct myINS *myINS) { - int total = 0; - int len = 0; - - len = BER_GET_LENGTH_CTYPE_INT32(&myINS->stVal); - total += len + getLengthBytes(len) + 1; - - return total; +int ber_get_length_myINS(struct myINS *myINS) { + int total = 0; + int len = 0; + + len = BER_GET_LENGTH_CTYPE_INT32(&myINS->stVal); + total += len + getLengthBytes(len) + 1; + + return total; } -int ber_encode_myINS(unsigned char *buf, struct myINS *myINS) { - int offset = 0; - - buf[offset++] = 0xA2; - offset += encodeLength(&buf[offset], ber_get_length_myINS(myINS)); - - offset += BER_ENCODE_CTYPE_INT32(&buf[offset], &myINS->stVal); - - return offset; +int ber_encode_myINS(unsigned char *buf, struct myINS *myINS) { + int offset = 0; + + buf[offset++] = 0xA2; + offset += encodeLength(&buf[offset], ber_get_length_myINS(myINS)); + + offset += BER_ENCODE_CTYPE_INT32(&buf[offset], &myINS->stVal); + + return offset; } -int ber_get_length_myLPL(struct myLPL *myLPL) { - int total = 0; - int len = 0; - - len = BER_GET_LENGTH_CTYPE_VISSTRING255(&myLPL->ldNs); - total += len + getLengthBytes(len) + 1; - len = BER_GET_LENGTH_CTYPE_VISSTRING255(&myLPL->configRev); - total += len + getLengthBytes(len) + 1; - - return total; +int ber_get_length_myLPL(struct myLPL *myLPL) { + int total = 0; + int len = 0; + + len = BER_GET_LENGTH_CTYPE_VISSTRING255(&myLPL->ldNs); + total += len + getLengthBytes(len) + 1; + len = BER_GET_LENGTH_CTYPE_VISSTRING255(&myLPL->configRev); + total += len + getLengthBytes(len) + 1; + + return total; } -int ber_encode_myLPL(unsigned char *buf, struct myLPL *myLPL) { - int offset = 0; - - buf[offset++] = 0xA2; - offset += encodeLength(&buf[offset], ber_get_length_myLPL(myLPL)); - - offset += BER_ENCODE_CTYPE_VISSTRING255(&buf[offset], &myLPL->ldNs); - offset += BER_ENCODE_CTYPE_VISSTRING255(&buf[offset], &myLPL->configRev); - - return offset; +int ber_encode_myLPL(unsigned char *buf, struct myLPL *myLPL) { + int offset = 0; + + buf[offset++] = 0xA2; + offset += encodeLength(&buf[offset], ber_get_length_myLPL(myLPL)); + + offset += BER_ENCODE_CTYPE_VISSTRING255(&buf[offset], &myLPL->ldNs); + offset += BER_ENCODE_CTYPE_VISSTRING255(&buf[offset], &myLPL->configRev); + + return offset; } -int ber_get_length_myDPL(struct myDPL *myDPL) { - int total = 0; - int len = 0; - - len = BER_GET_LENGTH_CTYPE_VISSTRING255(&myDPL->vendor); - total += len + getLengthBytes(len) + 1; - len = BER_GET_LENGTH_CTYPE_VISSTRING255(&myDPL->hwRev); - total += len + getLengthBytes(len) + 1; - - return total; +int ber_get_length_myDPL(struct myDPL *myDPL) { + int total = 0; + int len = 0; + + len = BER_GET_LENGTH_CTYPE_VISSTRING255(&myDPL->vendor); + total += len + getLengthBytes(len) + 1; + len = BER_GET_LENGTH_CTYPE_VISSTRING255(&myDPL->hwRev); + total += len + getLengthBytes(len) + 1; + + return total; } -int ber_encode_myDPL(unsigned char *buf, struct myDPL *myDPL) { - int offset = 0; - - buf[offset++] = 0xA2; - offset += encodeLength(&buf[offset], ber_get_length_myDPL(myDPL)); - - offset += BER_ENCODE_CTYPE_VISSTRING255(&buf[offset], &myDPL->vendor); - offset += BER_ENCODE_CTYPE_VISSTRING255(&buf[offset], &myDPL->hwRev); - - return offset; +int ber_encode_myDPL(unsigned char *buf, struct myDPL *myDPL) { + int offset = 0; + + buf[offset++] = 0xA2; + offset += encodeLength(&buf[offset], ber_get_length_myDPL(myDPL)); + + offset += BER_ENCODE_CTYPE_VISSTRING255(&buf[offset], &myDPL->vendor); + offset += BER_ENCODE_CTYPE_VISSTRING255(&buf[offset], &myDPL->hwRev); + + return offset; } -int ber_get_length_myPos(struct myPos *myPos) { - int total = 0; - int len = 0; - - len = BER_GET_LENGTH_CTYPE_DBPOS(&myPos->stVal); - total += len + getLengthBytes(len) + 1; - len = BER_GET_LENGTH_CTYPE_QUALITY(&myPos->q); - total += len + getLengthBytes(len) + 1; - len = BER_GET_LENGTH_CTYPE_TIMESTAMP(&myPos->t); - total += len + getLengthBytes(len) + 1; - len = BER_GET_LENGTH_CTYPE_BOOLEAN(&myPos->ctlVal); - total += len + getLengthBytes(len) + 1; - - return total; +int ber_get_length_myPos(struct myPos *myPos) { + int total = 0; + int len = 0; + + len = BER_GET_LENGTH_CTYPE_DBPOS(&myPos->stVal); + total += len + getLengthBytes(len) + 1; + len = BER_GET_LENGTH_CTYPE_QUALITY(&myPos->q); + total += len + getLengthBytes(len) + 1; + len = BER_GET_LENGTH_CTYPE_TIMESTAMP(&myPos->t); + total += len + getLengthBytes(len) + 1; + len = BER_GET_LENGTH_CTYPE_BOOLEAN(&myPos->ctlVal); + total += len + getLengthBytes(len) + 1; + + return total; } -int ber_encode_myPos(unsigned char *buf, struct myPos *myPos) { - int offset = 0; - - buf[offset++] = 0xA2; - offset += encodeLength(&buf[offset], ber_get_length_myPos(myPos)); - - offset += BER_ENCODE_CTYPE_DBPOS(&buf[offset], &myPos->stVal); - offset += BER_ENCODE_CTYPE_QUALITY(&buf[offset], &myPos->q); - offset += BER_ENCODE_CTYPE_TIMESTAMP(&buf[offset], &myPos->t); - offset += BER_ENCODE_CTYPE_BOOLEAN(&buf[offset], &myPos->ctlVal); - - return offset; +int ber_encode_myPos(unsigned char *buf, struct myPos *myPos) { + int offset = 0; + + buf[offset++] = 0xA2; + offset += encodeLength(&buf[offset], ber_get_length_myPos(myPos)); + + offset += BER_ENCODE_CTYPE_DBPOS(&buf[offset], &myPos->stVal); + offset += BER_ENCODE_CTYPE_QUALITY(&buf[offset], &myPos->q); + offset += BER_ENCODE_CTYPE_TIMESTAMP(&buf[offset], &myPos->t); + offset += BER_ENCODE_CTYPE_BOOLEAN(&buf[offset], &myPos->ctlVal); + + return offset; } -int ber_get_length_mySPS(struct mySPS *mySPS) { - int total = 0; - int len = 0; - - len = BER_GET_LENGTH_CTYPE_INT32(&mySPS->stVal); - total += len + getLengthBytes(len) + 1; - len = BER_GET_LENGTH_CTYPE_QUALITY(&mySPS->q); - total += len + getLengthBytes(len) + 1; - len = BER_GET_LENGTH_CTYPE_TIMESTAMP(&mySPS->t); - total += len + getLengthBytes(len) + 1; - - return total; +int ber_get_length_mySPS(struct mySPS *mySPS) { + int total = 0; + int len = 0; + + len = BER_GET_LENGTH_CTYPE_INT32(&mySPS->stVal); + total += len + getLengthBytes(len) + 1; + len = BER_GET_LENGTH_CTYPE_QUALITY(&mySPS->q); + total += len + getLengthBytes(len) + 1; + len = BER_GET_LENGTH_CTYPE_TIMESTAMP(&mySPS->t); + total += len + getLengthBytes(len) + 1; + + return total; } -int ber_encode_mySPS(unsigned char *buf, struct mySPS *mySPS) { - int offset = 0; - - buf[offset++] = 0xA2; - offset += encodeLength(&buf[offset], ber_get_length_mySPS(mySPS)); - - offset += BER_ENCODE_CTYPE_INT32(&buf[offset], &mySPS->stVal); - offset += BER_ENCODE_CTYPE_QUALITY(&buf[offset], &mySPS->q); - offset += BER_ENCODE_CTYPE_TIMESTAMP(&buf[offset], &mySPS->t); - - return offset; +int ber_encode_mySPS(unsigned char *buf, struct mySPS *mySPS) { + int offset = 0; + + buf[offset++] = 0xA2; + offset += encodeLength(&buf[offset], ber_get_length_mySPS(mySPS)); + + offset += BER_ENCODE_CTYPE_INT32(&buf[offset], &mySPS->stVal); + offset += BER_ENCODE_CTYPE_QUALITY(&buf[offset], &mySPS->q); + offset += BER_ENCODE_CTYPE_TIMESTAMP(&buf[offset], &mySPS->t); + + return offset; } -int ber_get_length_myMV(struct myMV *myMV) { - int total = 0; - int len = 0; - - len = ber_get_length_myAnalogValue(&myMV->mag); - total += len + getLengthBytes(len) + 1; - len = BER_GET_LENGTH_CTYPE_QUALITY(&myMV->q); - total += len + getLengthBytes(len) + 1; - len = BER_GET_LENGTH_CTYPE_TIMESTAMP(&myMV->t); - total += len + getLengthBytes(len) + 1; - len = ber_get_length_ScaledValueConfig(&myMV->sVC); - total += len + getLengthBytes(len) + 1; - - return total; +int ber_get_length_myMV(struct myMV *myMV) { + int total = 0; + int len = 0; + + len = ber_get_length_myAnalogValue(&myMV->mag); + total += len + getLengthBytes(len) + 1; + len = BER_GET_LENGTH_CTYPE_QUALITY(&myMV->q); + total += len + getLengthBytes(len) + 1; + len = BER_GET_LENGTH_CTYPE_TIMESTAMP(&myMV->t); + total += len + getLengthBytes(len) + 1; + len = ber_get_length_ScaledValueConfig(&myMV->sVC); + total += len + getLengthBytes(len) + 1; + + return total; } -int ber_encode_myMV(unsigned char *buf, struct myMV *myMV) { - int offset = 0; - - buf[offset++] = 0xA2; - offset += encodeLength(&buf[offset], ber_get_length_myMV(myMV)); - - offset += ber_encode_myAnalogValue(&buf[offset], &myMV->mag); - offset += BER_ENCODE_CTYPE_QUALITY(&buf[offset], &myMV->q); - offset += BER_ENCODE_CTYPE_TIMESTAMP(&buf[offset], &myMV->t); - offset += ber_encode_ScaledValueConfig(&buf[offset], &myMV->sVC); - - return offset; +int ber_encode_myMV(unsigned char *buf, struct myMV *myMV) { + int offset = 0; + + buf[offset++] = 0xA2; + offset += encodeLength(&buf[offset], ber_get_length_myMV(myMV)); + + offset += ber_encode_myAnalogValue(&buf[offset], &myMV->mag); + offset += BER_ENCODE_CTYPE_QUALITY(&buf[offset], &myMV->q); + offset += BER_ENCODE_CTYPE_TIMESTAMP(&buf[offset], &myMV->t); + offset += ber_encode_ScaledValueConfig(&buf[offset], &myMV->sVC); + + return offset; } -int ber_get_length_simpleMV(struct simpleMV *simpleMV) { - int total = 0; - int len = 0; - - len = BER_GET_LENGTH_CTYPE_FLOAT32(&simpleMV->mag); - total += len + getLengthBytes(len) + 1; - len = BER_GET_LENGTH_CTYPE_QUALITY(&simpleMV->q); - total += len + getLengthBytes(len) + 1; - len = BER_GET_LENGTH_CTYPE_TIMESTAMP(&simpleMV->t); - total += len + getLengthBytes(len) + 1; - len = ber_get_length_ScaledValueConfig(&simpleMV->sVC); - total += len + getLengthBytes(len) + 1; - - return total; +int ber_get_length_simpleMV(struct simpleMV *simpleMV) { + int total = 0; + int len = 0; + + len = BER_GET_LENGTH_CTYPE_FLOAT32(&simpleMV->mag); + total += len + getLengthBytes(len) + 1; + len = BER_GET_LENGTH_CTYPE_QUALITY(&simpleMV->q); + total += len + getLengthBytes(len) + 1; + len = BER_GET_LENGTH_CTYPE_TIMESTAMP(&simpleMV->t); + total += len + getLengthBytes(len) + 1; + len = ber_get_length_ScaledValueConfig(&simpleMV->sVC); + total += len + getLengthBytes(len) + 1; + + return total; } -int ber_encode_simpleMV(unsigned char *buf, struct simpleMV *simpleMV) { - int offset = 0; - - buf[offset++] = 0xA2; - offset += encodeLength(&buf[offset], ber_get_length_simpleMV(simpleMV)); - - offset += BER_ENCODE_CTYPE_FLOAT32(&buf[offset], &simpleMV->mag); - offset += BER_ENCODE_CTYPE_QUALITY(&buf[offset], &simpleMV->q); - offset += BER_ENCODE_CTYPE_TIMESTAMP(&buf[offset], &simpleMV->t); - offset += ber_encode_ScaledValueConfig(&buf[offset], &simpleMV->sVC); - - return offset; +int ber_encode_simpleMV(unsigned char *buf, struct simpleMV *simpleMV) { + int offset = 0; + + buf[offset++] = 0xA2; + offset += encodeLength(&buf[offset], ber_get_length_simpleMV(simpleMV)); + + offset += BER_ENCODE_CTYPE_FLOAT32(&buf[offset], &simpleMV->mag); + offset += BER_ENCODE_CTYPE_QUALITY(&buf[offset], &simpleMV->q); + offset += BER_ENCODE_CTYPE_TIMESTAMP(&buf[offset], &simpleMV->t); + offset += ber_encode_ScaledValueConfig(&buf[offset], &simpleMV->sVC); + + return offset; } -int ber_get_length_simpleCMV(struct simpleCMV *simpleCMV) { - int total = 0; - int len = 0; - - len = ber_get_length_simpleVector(&simpleCMV->cVal); - total += len + getLengthBytes(len) + 1; - len = BER_GET_LENGTH_CTYPE_QUALITY(&simpleCMV->q); - total += len + getLengthBytes(len) + 1; - len = BER_GET_LENGTH_CTYPE_TIMESTAMP(&simpleCMV->t); - total += len + getLengthBytes(len) + 1; - - return total; +int ber_get_length_simpleCMV(struct simpleCMV *simpleCMV) { + int total = 0; + int len = 0; + + len = ber_get_length_simpleVector(&simpleCMV->cVal); + total += len + getLengthBytes(len) + 1; + len = BER_GET_LENGTH_CTYPE_QUALITY(&simpleCMV->q); + total += len + getLengthBytes(len) + 1; + len = BER_GET_LENGTH_CTYPE_TIMESTAMP(&simpleCMV->t); + total += len + getLengthBytes(len) + 1; + + return total; } -int ber_encode_simpleCMV(unsigned char *buf, struct simpleCMV *simpleCMV) { - int offset = 0; - - buf[offset++] = 0xA2; - offset += encodeLength(&buf[offset], ber_get_length_simpleCMV(simpleCMV)); - - offset += ber_encode_simpleVector(&buf[offset], &simpleCMV->cVal); - offset += BER_ENCODE_CTYPE_QUALITY(&buf[offset], &simpleCMV->q); - offset += BER_ENCODE_CTYPE_TIMESTAMP(&buf[offset], &simpleCMV->t); - - return offset; +int ber_encode_simpleCMV(unsigned char *buf, struct simpleCMV *simpleCMV) { + int offset = 0; + + buf[offset++] = 0xA2; + offset += encodeLength(&buf[offset], ber_get_length_simpleCMV(simpleCMV)); + + offset += ber_encode_simpleVector(&buf[offset], &simpleCMV->cVal); + offset += BER_ENCODE_CTYPE_QUALITY(&buf[offset], &simpleCMV->q); + offset += BER_ENCODE_CTYPE_TIMESTAMP(&buf[offset], &simpleCMV->t); + + return offset; } -int ber_get_length_simpleWYE(struct simpleWYE *simpleWYE) { - int total = 0; - int len = 0; - - len = ber_get_length_simpleCMV(&simpleWYE->phsA); - total += len + getLengthBytes(len) + 1; - len = ber_get_length_simpleCMV(&simpleWYE->phsB); - total += len + getLengthBytes(len) + 1; - len = ber_get_length_simpleCMV(&simpleWYE->phsC); - total += len + getLengthBytes(len) + 1; - - return total; +int ber_get_length_simpleWYE(struct simpleWYE *simpleWYE) { + int total = 0; + int len = 0; + + len = ber_get_length_simpleCMV(&simpleWYE->phsA); + total += len + getLengthBytes(len) + 1; + len = ber_get_length_simpleCMV(&simpleWYE->phsB); + total += len + getLengthBytes(len) + 1; + len = ber_get_length_simpleCMV(&simpleWYE->phsC); + total += len + getLengthBytes(len) + 1; + + return total; } -int ber_encode_simpleWYE(unsigned char *buf, struct simpleWYE *simpleWYE) { - int offset = 0; - - buf[offset++] = 0xA2; - offset += encodeLength(&buf[offset], ber_get_length_simpleWYE(simpleWYE)); - - offset += ber_encode_simpleCMV(&buf[offset], &simpleWYE->phsA); - offset += ber_encode_simpleCMV(&buf[offset], &simpleWYE->phsB); - offset += ber_encode_simpleCMV(&buf[offset], &simpleWYE->phsC); - - return offset; +int ber_encode_simpleWYE(unsigned char *buf, struct simpleWYE *simpleWYE) { + int offset = 0; + + buf[offset++] = 0xA2; + offset += encodeLength(&buf[offset], ber_get_length_simpleWYE(simpleWYE)); + + offset += ber_encode_simpleCMV(&buf[offset], &simpleWYE->phsA); + offset += ber_encode_simpleCMV(&buf[offset], &simpleWYE->phsB); + offset += ber_encode_simpleCMV(&buf[offset], &simpleWYE->phsC); + + return offset; } -int ber_get_length_myCMV(struct myCMV *myCMV) { - int total = 0; - int len = 0; - - len = ber_get_length_myVector(&myCMV->cVal); - total += len + getLengthBytes(len) + 1; - len = BER_GET_LENGTH_CTYPE_QUALITY(&myCMV->q); - total += len + getLengthBytes(len) + 1; - len = BER_GET_LENGTH_CTYPE_TIMESTAMP(&myCMV->t); - total += len + getLengthBytes(len) + 1; - - return total; +int ber_get_length_myCMV(struct myCMV *myCMV) { + int total = 0; + int len = 0; + + len = ber_get_length_myVector(&myCMV->cVal); + total += len + getLengthBytes(len) + 1; + len = BER_GET_LENGTH_CTYPE_QUALITY(&myCMV->q); + total += len + getLengthBytes(len) + 1; + len = BER_GET_LENGTH_CTYPE_TIMESTAMP(&myCMV->t); + total += len + getLengthBytes(len) + 1; + + return total; } -int ber_encode_myCMV(unsigned char *buf, struct myCMV *myCMV) { - int offset = 0; - - buf[offset++] = 0xA2; - offset += encodeLength(&buf[offset], ber_get_length_myCMV(myCMV)); - - offset += ber_encode_myVector(&buf[offset], &myCMV->cVal); - offset += BER_ENCODE_CTYPE_QUALITY(&buf[offset], &myCMV->q); - offset += BER_ENCODE_CTYPE_TIMESTAMP(&buf[offset], &myCMV->t); - - return offset; +int ber_encode_myCMV(unsigned char *buf, struct myCMV *myCMV) { + int offset = 0; + + buf[offset++] = 0xA2; + offset += encodeLength(&buf[offset], ber_get_length_myCMV(myCMV)); + + offset += ber_encode_myVector(&buf[offset], &myCMV->cVal); + offset += BER_ENCODE_CTYPE_QUALITY(&buf[offset], &myCMV->q); + offset += BER_ENCODE_CTYPE_TIMESTAMP(&buf[offset], &myCMV->t); + + return offset; } -int ber_get_length_mySEQ(struct mySEQ *mySEQ) { - int total = 0; - int len = 0; - - len = ber_get_length_myCMV(&mySEQ->c1); - total += len + getLengthBytes(len) + 1; - len = ber_get_length_myCMV(&mySEQ->c2); - total += len + getLengthBytes(len) + 1; - len = ber_get_length_myCMV(&mySEQ->c3); - total += len + getLengthBytes(len) + 1; - len = BER_GET_LENGTH_CTYPE_ENUM((CTYPE_ENUM *) &mySEQ->seqT); - total += len + getLengthBytes(len) + 1; - - return total; +int ber_get_length_mySEQ(struct mySEQ *mySEQ) { + int total = 0; + int len = 0; + + len = ber_get_length_myCMV(&mySEQ->c1); + total += len + getLengthBytes(len) + 1; + len = ber_get_length_myCMV(&mySEQ->c2); + total += len + getLengthBytes(len) + 1; + len = ber_get_length_myCMV(&mySEQ->c3); + total += len + getLengthBytes(len) + 1; + len = BER_GET_LENGTH_CTYPE_ENUM((CTYPE_ENUM *) &mySEQ->seqT); + total += len + getLengthBytes(len) + 1; + + return total; } -int ber_encode_mySEQ(unsigned char *buf, struct mySEQ *mySEQ) { - int offset = 0; - - buf[offset++] = 0xA2; - offset += encodeLength(&buf[offset], ber_get_length_mySEQ(mySEQ)); - - offset += ber_encode_myCMV(&buf[offset], &mySEQ->c1); - offset += ber_encode_myCMV(&buf[offset], &mySEQ->c2); - offset += ber_encode_myCMV(&buf[offset], &mySEQ->c3); - offset += BER_ENCODE_CTYPE_ENUM(&buf[offset], (CTYPE_ENUM *) &mySEQ->seqT); - - return offset; +int ber_encode_mySEQ(unsigned char *buf, struct mySEQ *mySEQ) { + int offset = 0; + + buf[offset++] = 0xA2; + offset += encodeLength(&buf[offset], ber_get_length_mySEQ(mySEQ)); + + offset += ber_encode_myCMV(&buf[offset], &mySEQ->c1); + offset += ber_encode_myCMV(&buf[offset], &mySEQ->c2); + offset += ber_encode_myCMV(&buf[offset], &mySEQ->c3); + offset += BER_ENCODE_CTYPE_ENUM(&buf[offset], (CTYPE_ENUM *) &mySEQ->seqT); + + return offset; } -int ber_get_length_mySAV(struct mySAV *mySAV) { - int total = 0; - int len = 0; - - len = ber_get_length_myAnalogValue(&mySAV->instMag); - total += len + getLengthBytes(len) + 1; - len = BER_GET_LENGTH_CTYPE_QUALITY(&mySAV->q); - total += len + getLengthBytes(len) + 1; - - return total; +int ber_get_length_mySAV(struct mySAV *mySAV) { + int total = 0; + int len = 0; + + len = ber_get_length_myAnalogValue(&mySAV->instMag); + total += len + getLengthBytes(len) + 1; + len = BER_GET_LENGTH_CTYPE_QUALITY(&mySAV->q); + total += len + getLengthBytes(len) + 1; + + return total; } -int ber_encode_mySAV(unsigned char *buf, struct mySAV *mySAV) { - int offset = 0; - - buf[offset++] = 0xA2; - offset += encodeLength(&buf[offset], ber_get_length_mySAV(mySAV)); - - offset += ber_encode_myAnalogValue(&buf[offset], &mySAV->instMag); - offset += BER_ENCODE_CTYPE_QUALITY(&buf[offset], &mySAV->q); - - return offset; +int ber_encode_mySAV(unsigned char *buf, struct mySAV *mySAV) { + int offset = 0; + + buf[offset++] = 0xA2; + offset += encodeLength(&buf[offset], ber_get_length_mySAV(mySAV)); + + offset += ber_encode_myAnalogValue(&buf[offset], &mySAV->instMag); + offset += BER_ENCODE_CTYPE_QUALITY(&buf[offset], &mySAV->q); + + return offset; } -int ber_get_length_simpleSAV(struct simpleSAV *simpleSAV) { - int total = 0; - int len = 0; - - len = ber_get_length_myAnalogValue(&simpleSAV->instMag); - total += len + getLengthBytes(len) + 1; - len = BER_GET_LENGTH_CTYPE_QUALITY(&simpleSAV->q); - total += len + getLengthBytes(len) + 1; - - return total; +int ber_get_length_simpleSAV(struct simpleSAV *simpleSAV) { + int total = 0; + int len = 0; + + len = ber_get_length_myAnalogValue(&simpleSAV->instMag); + total += len + getLengthBytes(len) + 1; + len = BER_GET_LENGTH_CTYPE_QUALITY(&simpleSAV->q); + total += len + getLengthBytes(len) + 1; + + return total; } -int ber_encode_simpleSAV(unsigned char *buf, struct simpleSAV *simpleSAV) { - int offset = 0; - - buf[offset++] = 0xA2; - offset += encodeLength(&buf[offset], ber_get_length_simpleSAV(simpleSAV)); - - offset += ber_encode_myAnalogValue(&buf[offset], &simpleSAV->instMag); - offset += BER_ENCODE_CTYPE_QUALITY(&buf[offset], &simpleSAV->q); - - return offset; +int ber_encode_simpleSAV(unsigned char *buf, struct simpleSAV *simpleSAV) { + int offset = 0; + + buf[offset++] = 0xA2; + offset += encodeLength(&buf[offset], ber_get_length_simpleSAV(simpleSAV)); + + offset += ber_encode_myAnalogValue(&buf[offset], &simpleSAV->instMag); + offset += BER_ENCODE_CTYPE_QUALITY(&buf[offset], &simpleSAV->q); + + return offset; } -int ber_get_length_Itl() { - int total = 0; - int len = 0; - - len = ber_get_length_myAnalogValue(&E1Q1SB1.S1.C1.TVTR_1.Vol.instMag); - total += len + getLengthBytes(len) + 1; - len = ber_get_length_myPos(&E1Q1SB1.S1.C1.CSWI_1.Pos); - total += len + getLengthBytes(len) + 1; - len = ber_get_length_myPos(&E1Q1SB1.S1.C1.CSWI_2.Pos); - total += len + getLengthBytes(len) + 1; - len = BER_GET_LENGTH_CTYPE_ENUM((CTYPE_ENUM *) &E1Q1SB1.S1.C1.MMXU_1.Mod.stVal); - total += len + getLengthBytes(len) + 1; - len = ber_get_length_myMV(&E1Q1SB1.S1.C1.MMXU_1.Amps); - total += len + getLengthBytes(len) + 1; - len = ber_get_length_myMV(&E1Q1SB1.S1.C1.MMXU_1.Volts); - total += len + getLengthBytes(len) + 1; - - return total; +int ber_get_length_Itl() { + int total = 0; + int len = 0; + + len = ber_get_length_myAnalogValue(&E1Q1SB1.S1.C1.TVTR_1.Vol.instMag); + total += len + getLengthBytes(len) + 1; + len = ber_get_length_myPos(&E1Q1SB1.S1.C1.CSWI_1.Pos); + total += len + getLengthBytes(len) + 1; + len = ber_get_length_myPos(&E1Q1SB1.S1.C1.CSWI_2.Pos); + total += len + getLengthBytes(len) + 1; + len = BER_GET_LENGTH_CTYPE_ENUM((CTYPE_ENUM *) &E1Q1SB1.S1.C1.MMXU_1.Mod.stVal); + total += len + getLengthBytes(len) + 1; + len = ber_get_length_myMV(&E1Q1SB1.S1.C1.MMXU_1.Amps); + total += len + getLengthBytes(len) + 1; + len = ber_get_length_myMV(&E1Q1SB1.S1.C1.MMXU_1.Volts); + total += len + getLengthBytes(len) + 1; + + return total; } -int ber_encode_Itl(unsigned char *buf) { - int offset = 0; - - offset += ber_encode_myAnalogValue(&buf[offset], &E1Q1SB1.S1.C1.TVTR_1.Vol.instMag); - offset += ber_encode_myPos(&buf[offset], &E1Q1SB1.S1.C1.CSWI_1.Pos); - offset += ber_encode_myPos(&buf[offset], &E1Q1SB1.S1.C1.CSWI_2.Pos); - offset += BER_ENCODE_CTYPE_ENUM(&buf[offset], (CTYPE_ENUM *) &E1Q1SB1.S1.C1.MMXU_1.Mod.stVal); - offset += ber_encode_myMV(&buf[offset], &E1Q1SB1.S1.C1.MMXU_1.Amps); - offset += ber_encode_myMV(&buf[offset], &E1Q1SB1.S1.C1.MMXU_1.Volts); - - return offset; +int ber_encode_Itl(unsigned char *buf) { + int offset = 0; + + offset += ber_encode_myAnalogValue(&buf[offset], &E1Q1SB1.S1.C1.TVTR_1.Vol.instMag); + offset += ber_encode_myPos(&buf[offset], &E1Q1SB1.S1.C1.CSWI_1.Pos); + offset += ber_encode_myPos(&buf[offset], &E1Q1SB1.S1.C1.CSWI_2.Pos); + offset += BER_ENCODE_CTYPE_ENUM(&buf[offset], (CTYPE_ENUM *) &E1Q1SB1.S1.C1.MMXU_1.Mod.stVal); + offset += ber_encode_myMV(&buf[offset], &E1Q1SB1.S1.C1.MMXU_1.Amps); + offset += ber_encode_myMV(&buf[offset], &E1Q1SB1.S1.C1.MMXU_1.Volts); + + return offset; } -int ber_get_length_SynChk() { - int total = 0; - int len = 0; - - len = ber_get_length_mySPS(&D1Q1SB4.S1.C1.RSYN_1.Rel); - total += len + getLengthBytes(len) + 1; - - return total; +int ber_get_length_SynChk() { + int total = 0; + int len = 0; + + len = ber_get_length_mySPS(&D1Q1SB4.S1.C1.RSYN_1.Rel); + total += len + getLengthBytes(len) + 1; + + return total; } -int ber_encode_SynChk(unsigned char *buf) { - int offset = 0; - - offset += ber_encode_mySPS(&buf[offset], &D1Q1SB4.S1.C1.RSYN_1.Rel); - - return offset; +int ber_encode_SynChk(unsigned char *buf) { + int offset = 0; + + offset += ber_encode_mySPS(&buf[offset], &D1Q1SB4.S1.C1.RSYN_1.Rel); + + return offset; } -int ber_get_length_MMXUResult() { - int total = 0; - int len = 0; - - len = ber_get_length_simpleWYE(&D1Q1SB4.S1.C1.MMXU_1.A); - total += len + getLengthBytes(len) + 1; - - return total; +int ber_get_length_MMXUResult() { + int total = 0; + int len = 0; + + len = ber_get_length_simpleWYE(&D1Q1SB4.S1.C1.MMXU_1.A); + total += len + getLengthBytes(len) + 1; + + return total; } -int ber_encode_MMXUResult(unsigned char *buf) { - int offset = 0; - - offset += ber_encode_simpleWYE(&buf[offset], &D1Q1SB4.S1.C1.MMXU_1.A); - - return offset; +int ber_encode_MMXUResult(unsigned char *buf) { + int offset = 0; + + offset += ber_encode_simpleWYE(&buf[offset], &D1Q1SB4.S1.C1.MMXU_1.A); + + return offset; }
diff -r 230c10b228ea -r 9399d44c2b1a gseEncode.h --- a/gseEncode.h Fri Oct 07 13:41:08 2011 +0000 +++ b/gseEncode.h Fri Oct 07 13:48:18 2011 +0000 @@ -1,3 +1,23 @@ +/** + * Rapid-prototyping protection schemes with IEC 61850 + * + * Copyright (c) 2011 Steven Blair + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + #ifndef GSE_ENCODE_H #define GSE_ENCODE_H
diff -r 230c10b228ea -r 9399d44c2b1a gseEncodeBasic.c --- a/gseEncodeBasic.c Fri Oct 07 13:41:08 2011 +0000 +++ b/gseEncodeBasic.c Fri Oct 07 13:48:18 2011 +0000 @@ -1,3 +1,23 @@ +/** + * Rapid-prototyping protection schemes with IEC 61850 + * + * Copyright (c) 2011 Steven Blair + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + #ifndef GSE_BER_ENCODE_BASIC_C #define GSE_BER_ENCODE_BASIC_C @@ -11,145 +31,145 @@ // BER encoding of basic types int BER_ENCODE_CTYPE_FLOAT32(unsigned char *buf, CTYPE_FLOAT32 *value) { - CTYPE_INT16U offset = 0; - CTYPE_INT16U len = BER_GET_LENGTH_CTYPE_FLOAT32(value); + CTYPE_INT16U offset = 0; + CTYPE_INT16U len = BER_GET_LENGTH_CTYPE_FLOAT32(value); - buf[offset++] = ASN1_TAG_FLOATING_POINT; - offset += encodeLength(&buf[offset], len); + buf[offset++] = ASN1_TAG_FLOATING_POINT; + offset += encodeLength(&buf[offset], len); - buf[offset++] = 0x08; // bits for exponent - netmemcpy(&buf[offset], value, len - 1); + buf[offset++] = 0x08; // bits for exponent + netmemcpy(&buf[offset], value, len - 1); - return offset + len - 1; + return offset + len - 1; } int BER_ENCODE_CTYPE_FLOAT64(unsigned char *buf, CTYPE_FLOAT64 *value) { - CTYPE_INT16U offset = 0; - CTYPE_INT16U len = BER_GET_LENGTH_CTYPE_FLOAT64(value); + CTYPE_INT16U offset = 0; + CTYPE_INT16U len = BER_GET_LENGTH_CTYPE_FLOAT64(value); - buf[offset++] = ASN1_TAG_FLOATING_POINT; - offset += encodeLength(&buf[offset], len); + buf[offset++] = ASN1_TAG_FLOATING_POINT; + offset += encodeLength(&buf[offset], len); - buf[offset++] = 0x0B; // bits for exponent - netmemcpy(&buf[offset], value, len - 1); + buf[offset++] = 0x0B; // bits for exponent + netmemcpy(&buf[offset], value, len - 1); - return offset + len - 1; + return offset + len - 1; } int BER_ENCODE_CTYPE_QUALITY(unsigned char *buf, CTYPE_QUALITY *value) { - CTYPE_INT16U offset = 0; - CTYPE_INT16U len = BER_GET_LENGTH_CTYPE_QUALITY(value); + CTYPE_INT16U offset = 0; + CTYPE_INT16U len = BER_GET_LENGTH_CTYPE_QUALITY(value); - buf[offset++] = ASN1_TAG_BIT_STRING; - offset += encodeLength(&buf[offset], len - 1); + buf[offset++] = ASN1_TAG_BIT_STRING; + offset += encodeLength(&buf[offset], len - 1); - buf[offset++] = QUALITY_UNUSED_BITS; // number of unused bits - netmemcpy(&buf[offset], value, len - 1); + buf[offset++] = QUALITY_UNUSED_BITS; // number of unused bits + netmemcpy(&buf[offset], value, len - 1); - return offset + len - 1; + return offset + len - 1; } int BER_ENCODE_CTYPE_TIMESTAMP(unsigned char *buf, CTYPE_TIMESTAMP *value) { - CTYPE_INT16U offset = 0; - CTYPE_INT16U len = BER_GET_LENGTH_CTYPE_TIMESTAMP(value); + CTYPE_INT16U offset = 0; + CTYPE_INT16U len = BER_GET_LENGTH_CTYPE_TIMESTAMP(value); - buf[offset++] = ASN1_TAG_OCTET_STRING; - offset += encodeLength(&buf[offset], len); + buf[offset++] = ASN1_TAG_OCTET_STRING; + offset += encodeLength(&buf[offset], len); - memcpy(&buf[offset], value, len); //TODO should be memcpy, because already in big-endian? + memcpy(&buf[offset], value, len); //TODO should be memcpy, because already in big-endian? - return offset + len; + return offset + len; } -int BER_ENCODE_CTYPE_ENUM(unsigned char *buf, CTYPE_ENUM *value) { // assuming enum is an int - allows any enum type to be used - CTYPE_INT16U offset = 0; - CTYPE_INT16U len = BER_GET_LENGTH_CTYPE_ENUM(value); +int BER_ENCODE_CTYPE_ENUM(unsigned char *buf, CTYPE_ENUM *value) { // assuming enum is an int - allows any enum type to be used + CTYPE_INT16U offset = 0; + CTYPE_INT16U len = BER_GET_LENGTH_CTYPE_ENUM(value); - buf[offset++] = ASN1_TAG_INTEGER; - offset += encodeLength(&buf[offset], len); + buf[offset++] = ASN1_TAG_INTEGER; + offset += encodeLength(&buf[offset], len); - ber_encode_integer(&buf[offset], value, SV_GET_LENGTH_INT32U); - //netmemcpy(&buf[offset], value, len); + ber_encode_integer(&buf[offset], value, SV_GET_LENGTH_INT32U); + //netmemcpy(&buf[offset], value, len); - return offset + len; + return offset + len; } int BER_ENCODE_CTYPE_INT16(unsigned char *buf, CTYPE_INT16 *value) { - CTYPE_INT16U offset = 0; - CTYPE_INT16U len = BER_GET_LENGTH_CTYPE_INT16(value); + CTYPE_INT16U offset = 0; + CTYPE_INT16U len = BER_GET_LENGTH_CTYPE_INT16(value); - buf[offset++] = ASN1_TAG_INTEGER; - offset += encodeLength(&buf[offset], len); + buf[offset++] = ASN1_TAG_INTEGER; + offset += encodeLength(&buf[offset], len); - ber_encode_integer(&buf[offset], value, SV_GET_LENGTH_INT16); - //netmemcpy(&buf[offset], value, len); + ber_encode_integer(&buf[offset], value, SV_GET_LENGTH_INT16); + //netmemcpy(&buf[offset], value, len); - return offset + len; + return offset + len; } int BER_ENCODE_CTYPE_INT32(unsigned char *buf, CTYPE_INT32 *value) { - CTYPE_INT16U offset = 0; - CTYPE_INT16U len = BER_GET_LENGTH_CTYPE_INT32(value); + CTYPE_INT16U offset = 0; + CTYPE_INT16U len = BER_GET_LENGTH_CTYPE_INT32(value); - buf[offset++] = ASN1_TAG_INTEGER; - offset += encodeLength(&buf[offset], len); + buf[offset++] = ASN1_TAG_INTEGER; + offset += encodeLength(&buf[offset], len); - printf("INT32 value: %u, len: %i, total: %i\n", *value, len, offset + len); - fflush(stdout); - ber_encode_integer(&buf[offset], value, SV_GET_LENGTH_INT32); - //netmemcpy(&buf[offset], value, len); + printf("INT32 value: %u, len: %i, total: %i\n", *value, len, offset + len); + fflush(stdout); + ber_encode_integer(&buf[offset], value, SV_GET_LENGTH_INT32); + //netmemcpy(&buf[offset], value, len); - return offset + len; + return offset + len; } int BER_ENCODE_CTYPE_INT16U(unsigned char *buf, CTYPE_INT16U *value) { - CTYPE_INT16U offset = 0; - CTYPE_INT16U len = BER_GET_LENGTH_CTYPE_INT16U(value); + CTYPE_INT16U offset = 0; + CTYPE_INT16U len = BER_GET_LENGTH_CTYPE_INT16U(value); - buf[offset++] = ASN1_TAG_UNSIGNED; - offset += encodeLength(&buf[offset], len); + buf[offset++] = ASN1_TAG_UNSIGNED; + offset += encodeLength(&buf[offset], len); - printf("INT16U value: %u, len: %i, total: %i\n", *value, len, offset + len); - fflush(stdout); - ber_encode_integer(&buf[offset], value, SV_GET_LENGTH_INT16U); - //netmemcpy(&buf[offset], value, len); + printf("INT16U value: %u, len: %i, total: %i\n", *value, len, offset + len); + fflush(stdout); + ber_encode_integer(&buf[offset], value, SV_GET_LENGTH_INT16U); + //netmemcpy(&buf[offset], value, len); - return offset + len; + return offset + len; } int BER_ENCODE_CTYPE_INT32U(unsigned char *buf, CTYPE_INT32U *value) { - CTYPE_INT16U offset = 0; - CTYPE_INT16U len = BER_GET_LENGTH_CTYPE_INT32U(value); + CTYPE_INT16U offset = 0; + CTYPE_INT16U len = BER_GET_LENGTH_CTYPE_INT32U(value); - buf[offset++] = ASN1_TAG_UNSIGNED; - offset += encodeLength(&buf[offset], len); + buf[offset++] = ASN1_TAG_UNSIGNED; + offset += encodeLength(&buf[offset], len); - ber_encode_integer(&buf[offset], value, SV_GET_LENGTH_INT32U); + ber_encode_integer(&buf[offset], value, SV_GET_LENGTH_INT32U); - printf("INT32U value: %u, len: %i, total: %i\n", *value, len, offset + len); - fflush(stdout); - //netmemcpy(&buf[offset], value, len); + printf("INT32U value: %u, len: %i, total: %i\n", *value, len, offset + len); + fflush(stdout); + //netmemcpy(&buf[offset], value, len); - return offset + len; + return offset + len; } int BER_ENCODE_CTYPE_VISSTRING255(unsigned char *buf, CTYPE_VISSTRING255 *value) { - netmemcpy(buf, value, BER_GET_LENGTH_CTYPE_VISSTRING255(value)); + netmemcpy(buf, value, BER_GET_LENGTH_CTYPE_VISSTRING255(value)); - return BER_GET_LENGTH_CTYPE_VISSTRING255(value); + return BER_GET_LENGTH_CTYPE_VISSTRING255(value); } int BER_ENCODE_CTYPE_BOOLEAN(unsigned char *buf, CTYPE_BOOLEAN *value) { - CTYPE_INT16U offset = 0; - CTYPE_INT16U len = BER_GET_LENGTH_CTYPE_BOOLEAN(value); + CTYPE_INT16U offset = 0; + CTYPE_INT16U len = BER_GET_LENGTH_CTYPE_BOOLEAN(value); - buf[offset++] = ASN1_TAG_BOOLEAN; - offset += encodeLength(&buf[offset], len); + buf[offset++] = ASN1_TAG_BOOLEAN; + offset += encodeLength(&buf[offset], len); - netmemcpy(&buf[offset], value, len); + netmemcpy(&buf[offset], value, len); - return offset + len; + return offset + len; } int BER_ENCODE_CTYPE_DBPOS(unsigned char *buf, CTYPE_DBPOS *value) { - CTYPE_INT16U offset = 0; - CTYPE_INT16U len = BER_GET_LENGTH_CTYPE_DBPOS(value); + CTYPE_INT16U offset = 0; + CTYPE_INT16U len = BER_GET_LENGTH_CTYPE_DBPOS(value); - buf[offset++] = 0x85; - offset += encodeLength(&buf[offset], len); + buf[offset++] = 0x85; + offset += encodeLength(&buf[offset], len); - netmemcpy(&buf[offset], value, len); //TODO should be memcpy, because already in big-endian? + netmemcpy(&buf[offset], value, len); //TODO should be memcpy, because already in big-endian? - return offset + len; + return offset + len; } #endif
diff -r 230c10b228ea -r 9399d44c2b1a gseEncodeBasic.h --- a/gseEncodeBasic.h Fri Oct 07 13:41:08 2011 +0000 +++ b/gseEncodeBasic.h Fri Oct 07 13:48:18 2011 +0000 @@ -1,3 +1,23 @@ +/** + * Rapid-prototyping protection schemes with IEC 61850 + * + * Copyright (c) 2011 Steven Blair + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + #ifndef GSE_ENCODE_BASIC_H #define GSE_ENCODE_BASIC_H
diff -r 230c10b228ea -r 9399d44c2b1a gseEncodePacket.c --- a/gseEncodePacket.c Fri Oct 07 13:41:08 2011 +0000 +++ b/gseEncodePacket.c Fri Oct 07 13:48:18 2011 +0000 @@ -1,148 +1,168 @@ +/** + * Rapid-prototyping protection schemes with IEC 61850 + * + * Copyright (c) 2011 Steven Blair + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + #include "encodePacket.h" #include "gsePacketData.h" #include "gseEncode.h" #include "svEncode.h" int getGseHeaderLength(struct gseData *gseData) { - int size = 0; - int len = 0; + int size = 0; + int len = 0; - size = strlen((const char *) gseData->gocbRef); - len += size + getLengthBytes(size) + 1; + size = strlen((const char *) gseData->gocbRef); + len += size + getLengthBytes(size) + 1; - size = BER_GET_LENGTH_CTYPE_INT32U(&gseData->timeAllowedToLive); - len += size + getLengthBytes(size) + 1; + size = BER_GET_LENGTH_CTYPE_INT32U(&gseData->timeAllowedToLive); + len += size + getLengthBytes(size) + 1; - size = strlen((const char *) gseData->datSet); - len += size + getLengthBytes(size) + 1; + size = strlen((const char *) gseData->datSet); + len += size + getLengthBytes(size) + 1; - size = strlen((const char *) gseData->goID); - len += size + getLengthBytes(size) + 1; + size = strlen((const char *) gseData->goID); + len += size + getLengthBytes(size) + 1; - size = BER_GET_LENGTH_CTYPE_TIMESTAMP(&gseData->t); - len += size + getLengthBytes(size) + 1; + size = BER_GET_LENGTH_CTYPE_TIMESTAMP(&gseData->t); + len += size + getLengthBytes(size) + 1; - size = BER_GET_LENGTH_CTYPE_INT32U(&gseData->stNum); - len += size + getLengthBytes(size) + 1; + size = BER_GET_LENGTH_CTYPE_INT32U(&gseData->stNum); + len += size + getLengthBytes(size) + 1; - size = BER_GET_LENGTH_CTYPE_INT32U(&gseData->sqNum); - len += size + getLengthBytes(size) + 1; + size = BER_GET_LENGTH_CTYPE_INT32U(&gseData->sqNum); + len += size + getLengthBytes(size) + 1; - size = BER_GET_LENGTH_CTYPE_BOOLEAN(&gseData->test); - len += size + getLengthBytes(size) + 1; + size = BER_GET_LENGTH_CTYPE_BOOLEAN(&gseData->test); + len += size + getLengthBytes(size) + 1; - size = BER_GET_LENGTH_CTYPE_INT32U(&gseData->confRev); - len += size + getLengthBytes(size) + 1; + size = BER_GET_LENGTH_CTYPE_INT32U(&gseData->confRev); + len += size + getLengthBytes(size) + 1; - size = BER_GET_LENGTH_CTYPE_BOOLEAN(&gseData->ndsCom); - len += size + getLengthBytes(size) + 1; + size = BER_GET_LENGTH_CTYPE_BOOLEAN(&gseData->ndsCom); + len += size + getLengthBytes(size) + 1; - size = BER_GET_LENGTH_CTYPE_INT32U(&gseData->numDatSetEntries); - len += size + getLengthBytes(size) + 1; + size = BER_GET_LENGTH_CTYPE_INT32U(&gseData->numDatSetEntries); + len += size + getLengthBytes(size) + 1; - size = (gseData->getDatasetLength)(); - len += size + getLengthBytes(size) + 1; + size = (gseData->getDatasetLength)(); + len += size + getLengthBytes(size) + 1; - return len; + return len; } // creates a GSE packet, including frame header. returns 0 on fail; number of bytes on success int gseEncodePacket(struct gseData *gseData, unsigned char *buf) { - int offset = 0; - int size = 0; - int ADPULength = getGseHeaderLength(gseData); - int len = ADPULength + 9 + getLengthBytes(ADPULength); // APDU tag size (1 byte), plus 8 "header" bytes + int offset = 0; + int size = 0; + int ADPULength = getGseHeaderLength(gseData); + int len = ADPULength + 9 + getLengthBytes(ADPULength); // APDU tag size (1 byte), plus 8 "header" bytes - //printf("ADPULength: %i, len: %i\n", ADPULength, len); + //printf("ADPULength: %i, len: %i\n", ADPULength, len); - // frame header - memcpy(&buf[offset], gseData->ethHeaderData.destMACAddress, 6); // destination MAC addresses - offset += 6; - memcpy(&buf[offset], LOCAL_MAC_ADDRESS, 6); // source MAC addresses - offset += 6; + // frame header + memcpy(&buf[offset], gseData->ethHeaderData.destMACAddress, 6); // destination MAC addresses + offset += 6; + memcpy(&buf[offset], LOCAL_MAC_ADDRESS, 6); // source MAC addresses + offset += 6; - buf[offset++] = 0x81; // TPID - buf[offset++] = 0x00; + buf[offset++] = 0x81; // TPID + buf[offset++] = 0x00; - netmemcpy(&buf[offset], &gseData->ethHeaderData.VLAN_ID, 2); // TCI - buf[offset] |= (gseData->ethHeaderData.VLAN_PRIORITY << 5); - offset += 2; + netmemcpy(&buf[offset], &gseData->ethHeaderData.VLAN_ID, 2); // TCI + buf[offset] |= (gseData->ethHeaderData.VLAN_PRIORITY << 5); + offset += 2; - buf[offset++] = 0x88; // EtherType - buf[offset++] = 0xB8; + buf[offset++] = 0x88; // EtherType + buf[offset++] = 0xB8; - netmemcpy(&buf[offset], &gseData->ethHeaderData.APPID, 2); // APPID - offset += 2; + netmemcpy(&buf[offset], &gseData->ethHeaderData.APPID, 2); // APPID + offset += 2; - netmemcpy(&buf[offset], &len, 2); // length - offset += 2; + netmemcpy(&buf[offset], &len, 2); // length + offset += 2; - buf[offset++] = 0x00; // reserved 1 - buf[offset++] = 0x00; - buf[offset++] = 0x00; // reserved 2 - buf[offset++] = 0x00; + buf[offset++] = 0x00; // reserved 1 + buf[offset++] = 0x00; + buf[offset++] = 0x00; // reserved 2 + buf[offset++] = 0x00; - buf[offset++] = 0x61; - offset += encodeLength(&buf[offset], ADPULength /*+ getLengthBytes(ADPULength) + 1*/); + buf[offset++] = 0x61; + offset += encodeLength(&buf[offset], ADPULength /*+ getLengthBytes(ADPULength) + 1*/); - buf[offset++] = 0x80; - size = strlen((const char *) gseData->gocbRef); - buf[offset++] = size; - memcpy(&buf[offset], gseData->gocbRef, size); - offset += size; + buf[offset++] = 0x80; + size = strlen((const char *) gseData->gocbRef); + buf[offset++] = size; + memcpy(&buf[offset], gseData->gocbRef, size); + offset += size; - buf[offset++] = 0x81; - offset += encodeLength(&buf[offset], BER_GET_LENGTH_CTYPE_INT32U(&gseData->timeAllowedToLive)); - //offset += BER_ENCODE_CTYPE_INT32U(&buf[offset], &gseData->timeAllowedToLive); - offset += ber_encode_integer(&buf[offset], &gseData->timeAllowedToLive, SV_GET_LENGTH_INT32U); + buf[offset++] = 0x81; + offset += encodeLength(&buf[offset], BER_GET_LENGTH_CTYPE_INT32U(&gseData->timeAllowedToLive)); + //offset += BER_ENCODE_CTYPE_INT32U(&buf[offset], &gseData->timeAllowedToLive); + offset += ber_encode_integer(&buf[offset], &gseData->timeAllowedToLive, SV_GET_LENGTH_INT32U); - buf[offset++] = 0x82; - size = strlen((const char *) gseData->datSet); - buf[offset++] = size; - memcpy(&buf[offset], gseData->datSet, size); - offset += size; + buf[offset++] = 0x82; + size = strlen((const char *) gseData->datSet); + buf[offset++] = size; + memcpy(&buf[offset], gseData->datSet, size); + offset += size; - buf[offset++] = 0x83; - size = strlen((const char *) gseData->goID); - buf[offset++] = size; - memcpy(&buf[offset], gseData->goID, size); - offset += size; + buf[offset++] = 0x83; + size = strlen((const char *) gseData->goID); + buf[offset++] = size; + memcpy(&buf[offset], gseData->goID, size); + offset += size; - buf[offset++] = 0x84; - offset += encodeLength(&buf[offset], BER_GET_LENGTH_CTYPE_TIMESTAMP(&gseData->t)); - setTimestamp(&gseData->t); - memcpy(&buf[offset], &gseData->t, BER_GET_LENGTH_CTYPE_TIMESTAMP(&gseData->t)); - offset += BER_GET_LENGTH_CTYPE_TIMESTAMP(&gseData->t); + buf[offset++] = 0x84; + offset += encodeLength(&buf[offset], BER_GET_LENGTH_CTYPE_TIMESTAMP(&gseData->t)); + setTimestamp(&gseData->t); + memcpy(&buf[offset], &gseData->t, BER_GET_LENGTH_CTYPE_TIMESTAMP(&gseData->t)); + offset += BER_GET_LENGTH_CTYPE_TIMESTAMP(&gseData->t); - buf[offset++] = 0x85; - offset += encodeLength(&buf[offset], BER_GET_LENGTH_CTYPE_INT32U(&gseData->stNum)); - offset += ber_encode_integer(&buf[offset], &gseData->stNum, SV_GET_LENGTH_INT32U); + buf[offset++] = 0x85; + offset += encodeLength(&buf[offset], BER_GET_LENGTH_CTYPE_INT32U(&gseData->stNum)); + offset += ber_encode_integer(&buf[offset], &gseData->stNum, SV_GET_LENGTH_INT32U); - buf[offset++] = 0x86; - offset += encodeLength(&buf[offset], BER_GET_LENGTH_CTYPE_INT32U(&gseData->sqNum)); - offset += ber_encode_integer(&buf[offset], &gseData->sqNum, SV_GET_LENGTH_INT32U); + buf[offset++] = 0x86; + offset += encodeLength(&buf[offset], BER_GET_LENGTH_CTYPE_INT32U(&gseData->sqNum)); + offset += ber_encode_integer(&buf[offset], &gseData->sqNum, SV_GET_LENGTH_INT32U); - buf[offset++] = 0x87; - offset += encodeLength(&buf[offset], BER_GET_LENGTH_CTYPE_BOOLEAN(&gseData->test)); - offset += ber_encode_integer(&buf[offset], &gseData->test, SV_GET_LENGTH_BOOLEAN); + buf[offset++] = 0x87; + offset += encodeLength(&buf[offset], BER_GET_LENGTH_CTYPE_BOOLEAN(&gseData->test)); + offset += ber_encode_integer(&buf[offset], &gseData->test, SV_GET_LENGTH_BOOLEAN); - buf[offset++] = 0x88; - offset += encodeLength(&buf[offset], BER_GET_LENGTH_CTYPE_INT32U(&gseData->confRev)); - offset += ber_encode_integer(&buf[offset], &gseData->confRev, SV_GET_LENGTH_INT32U); + buf[offset++] = 0x88; + offset += encodeLength(&buf[offset], BER_GET_LENGTH_CTYPE_INT32U(&gseData->confRev)); + offset += ber_encode_integer(&buf[offset], &gseData->confRev, SV_GET_LENGTH_INT32U); - buf[offset++] = 0x89; - offset += encodeLength(&buf[offset], BER_GET_LENGTH_CTYPE_BOOLEAN(&gseData->ndsCom)); - offset += ber_encode_integer(&buf[offset], &gseData->ndsCom, SV_GET_LENGTH_BOOLEAN); + buf[offset++] = 0x89; + offset += encodeLength(&buf[offset], BER_GET_LENGTH_CTYPE_BOOLEAN(&gseData->ndsCom)); + offset += ber_encode_integer(&buf[offset], &gseData->ndsCom, SV_GET_LENGTH_BOOLEAN); - buf[offset++] = 0x8A; - offset += encodeLength(&buf[offset], BER_GET_LENGTH_CTYPE_INT32U(&gseData->numDatSetEntries)); - offset += ber_encode_integer(&buf[offset], &gseData->numDatSetEntries, SV_GET_LENGTH_INT32U); + buf[offset++] = 0x8A; + offset += encodeLength(&buf[offset], BER_GET_LENGTH_CTYPE_INT32U(&gseData->numDatSetEntries)); + offset += ber_encode_integer(&buf[offset], &gseData->numDatSetEntries, SV_GET_LENGTH_INT32U); - buf[offset++] = 0xAB; - offset += encodeLength(&buf[offset], (gseData->getDatasetLength)()); - offset += (gseData->encodeDataset)(&buf[offset]); + buf[offset++] = 0xAB; + offset += encodeLength(&buf[offset], (gseData->getDatasetLength)()); + offset += (gseData->encodeDataset)(&buf[offset]); - // assume network interface, such as WinPcap, generates CRC bytes + // assume network interface, such as WinPcap, generates CRC bytes - return offset; + return offset; }
diff -r 230c10b228ea -r 9399d44c2b1a gsePacketData.h --- a/gsePacketData.h Fri Oct 07 13:41:08 2011 +0000 +++ b/gsePacketData.h Fri Oct 07 13:48:18 2011 +0000 @@ -1,3 +1,23 @@ +/** + * Rapid-prototyping protection schemes with IEC 61850 + * + * Copyright (c) 2011 Steven Blair + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + #ifndef GSE_PACKET_DATA_H #define GSE_PACKET_DATA_H
diff -r 230c10b228ea -r 9399d44c2b1a iec61850.c --- a/iec61850.c Fri Oct 07 13:41:08 2011 +0000 +++ b/iec61850.c Fri Oct 07 13:48:18 2011 +0000 @@ -1,10 +1,27 @@ +/** + * Rapid-prototyping protection schemes with IEC 61850 + * + * Copyright (c) 2011 Steven Blair + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + #include "iec61850.h" void initialise_iec61850() { - init_datatypes(); - init_sv(); - init_gse(); - - //E1Q1SB1.S1.C1.MMXU_1.Volts.sVC.offset = 10; - //E1Q1SB1.S1.C1.MMXU_1.Volts.sVC.scaleFactor = 200; + init_datatypes(); + init_sv(); + init_gse(); }
diff -r 230c10b228ea -r 9399d44c2b1a iec61850.h --- a/iec61850.h Fri Oct 07 13:41:08 2011 +0000 +++ b/iec61850.h Fri Oct 07 13:48:18 2011 +0000 @@ -1,3 +1,23 @@ +/** + * Rapid-prototyping protection schemes with IEC 61850 + * + * Copyright (c) 2011 Steven Blair + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + #ifndef IEC61850_H #define IEC61850_H
diff -r 230c10b228ea -r 9399d44c2b1a ied.c --- a/ied.c Fri Oct 07 13:41:08 2011 +0000 +++ b/ied.c Fri Oct 07 13:48:18 2011 +0000 @@ -1,18 +1,38 @@ -#include "ied.h" +/** + * Rapid-prototyping protection schemes with IEC 61850 + * + * Copyright (c) 2011 Steven Blair + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "ied.h" #include "datatypes.h" -struct E1Q1SB1 E1Q1SB1; -struct E1Q1BP2 E1Q1BP2; -struct E1Q1BP3 E1Q1BP3; -struct E1Q2SB1 E1Q2SB1; -struct E1Q3SB1 E1Q3SB1; -struct E1Q3KA1 E1Q3KA1; -struct E1Q3KA2 E1Q3KA2; -struct E1Q3KA3 E1Q3KA3; -struct D1Q1SB1 D1Q1SB1; -struct D1Q1BP2 D1Q1BP2; -struct D1Q1BP3 D1Q1BP3; -struct D1Q1SB4 D1Q1SB4; +struct E1Q1SB1 E1Q1SB1; +struct E1Q1BP2 E1Q1BP2; +struct E1Q1BP3 E1Q1BP3; +struct E1Q2SB1 E1Q2SB1; +struct E1Q3SB1 E1Q3SB1; +struct E1Q3KA1 E1Q3KA1; +struct E1Q3KA2 E1Q3KA2; +struct E1Q3KA3 E1Q3KA3; +struct D1Q1SB1 D1Q1SB1; +struct D1Q1BP2 D1Q1BP2; +struct D1Q1BP3 D1Q1BP3; +struct D1Q1SB4 D1Q1SB4;
diff -r 230c10b228ea -r 9399d44c2b1a ied.h --- a/ied.h Fri Oct 07 13:41:08 2011 +0000 +++ b/ied.h Fri Oct 07 13:48:18 2011 +0000 @@ -1,3 +1,23 @@ +/** + * Rapid-prototyping protection schemes with IEC 61850 + * + * Copyright (c) 2011 Steven Blair + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + #ifndef IED_H #define IED_H @@ -7,96 +27,96 @@ #include "datatypes.h" -struct E1Q1SB1 { - struct { - struct { - struct LN0 LLN0; - struct exampleRMXU RMXU_1; - struct LPHDa LPHD_1; - struct CSWIa CSWI_1; - struct CSWIa CSWI_2; - struct MMXUa MMXU_1; - struct TVTRa TVTR_1; - } C1; - } S1; -}; - -struct E1Q1BP2 { - struct { - } S1; -}; - -struct E1Q1BP3 { - struct { - } S1; -}; - -struct E1Q2SB1 { - struct { - } S1; -}; - -struct E1Q3SB1 { - struct { - } S1; -}; - -struct E1Q3KA1 { - struct { - } S1; -}; - -struct E1Q3KA2 { - struct { - } S1; -}; - -struct E1Q3KA3 { - struct { - } S1; -}; - -struct D1Q1SB1 { - struct { - } S1; -}; - -struct D1Q1BP2 { - struct { - } S1; -}; - -struct D1Q1BP3 { - struct { - } S1; -}; - -struct D1Q1SB4 { - struct { - struct { - struct LN0 LLN0; - struct exampleMMXU MMXU_1; - struct LPHDa LPHD_1; - struct RSYNa RSYN_1; - } C1; - } S1; -}; +struct E1Q1SB1 { + struct { + struct { + struct LN0 LLN0; + struct exampleRMXU RMXU_1; + struct LPHDa LPHD_1; + struct CSWIa CSWI_1; + struct CSWIa CSWI_2; + struct MMXUa MMXU_1; + struct TVTRa TVTR_1; + } C1; + } S1; +}; + +struct E1Q1BP2 { + struct { + } S1; +}; + +struct E1Q1BP3 { + struct { + } S1; +}; + +struct E1Q2SB1 { + struct { + } S1; +}; + +struct E1Q3SB1 { + struct { + } S1; +}; + +struct E1Q3KA1 { + struct { + } S1; +}; + +struct E1Q3KA2 { + struct { + } S1; +}; + +struct E1Q3KA3 { + struct { + } S1; +}; + +struct D1Q1SB1 { + struct { + } S1; +}; + +struct D1Q1BP2 { + struct { + } S1; +}; + +struct D1Q1BP3 { + struct { + } S1; +}; + +struct D1Q1SB4 { + struct { + struct { + struct LN0 LLN0; + struct exampleMMXU MMXU_1; + struct LPHDa LPHD_1; + struct RSYNa RSYN_1; + } C1; + } S1; +}; -extern struct E1Q1SB1 E1Q1SB1; -extern struct E1Q1BP2 E1Q1BP2; -extern struct E1Q1BP3 E1Q1BP3; -extern struct E1Q2SB1 E1Q2SB1; -extern struct E1Q3SB1 E1Q3SB1; -extern struct E1Q3KA1 E1Q3KA1; -extern struct E1Q3KA2 E1Q3KA2; -extern struct E1Q3KA3 E1Q3KA3; -extern struct D1Q1SB1 D1Q1SB1; -extern struct D1Q1BP2 D1Q1BP2; -extern struct D1Q1BP3 D1Q1BP3; -extern struct D1Q1SB4 D1Q1SB4; +extern struct E1Q1SB1 E1Q1SB1; +extern struct E1Q1BP2 E1Q1BP2; +extern struct E1Q1BP3 E1Q1BP3; +extern struct E1Q2SB1 E1Q2SB1; +extern struct E1Q3SB1 E1Q3SB1; +extern struct E1Q3KA1 E1Q3KA1; +extern struct E1Q3KA2 E1Q3KA2; +extern struct E1Q3KA3 E1Q3KA3; +extern struct D1Q1SB1 D1Q1SB1; +extern struct D1Q1BP2 D1Q1BP2; +extern struct D1Q1BP3 D1Q1BP3; +extern struct D1Q1SB4 D1Q1SB4; #ifdef __cplusplus /* If this is a C++ compiler, end C linkage */
diff -r 230c10b228ea -r 9399d44c2b1a main.cpp --- a/main.cpp Fri Oct 07 13:41:08 2011 +0000 +++ b/main.cpp Fri Oct 07 13:48:18 2011 +0000 @@ -1,3 +1,23 @@ +/** + * Rapid-prototyping protection schemes with IEC 61850 + * + * Copyright (c) 2011 Steven Blair + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + #include "mbed.h" #include "iec61850.h" @@ -20,7 +40,6 @@ void setFault() { MAGNITUDE_NEG_SEQ = 50.0; MAGNITUDE_ZERO_SEQ = 25.0; - //offset = TWO_PI / 6; } void setNormal() { @@ -67,11 +86,6 @@ wait(1); - /*LPC_EMAC->MAXF = 0x0600; - LPC_EMAC->MAC2 |= (1 << 2); - LPC_EMAC->MAC2 &= 0xFFFD; - wait(1);*/ - sv.attach_us(&svSnapshot, 1250); wait(5); @@ -84,7 +98,7 @@ eth.read((char *) bufIn, lenIn); gseDecode(bufIn, lenIn); - //printf("%f\n", D1Q1SB4.S1.C1.RSYN_1.gse_inputs.instMag_1.f); + //printf("%f\n", D1Q1SB4.S1.C1.RSYN_1.gse_inputs.instMag_1.f); // monitor values from serial port if (D1Q1SB4.S1.C1.RSYN_1.gse_inputs.instMag_1.f > 0) { setFault();
diff -r 230c10b228ea -r 9399d44c2b1a sv.c --- a/sv.c Fri Oct 07 13:41:08 2011 +0000 +++ b/sv.c Fri Oct 07 13:48:18 2011 +0000 @@ -1,95 +1,115 @@ -#include "sv.h" -#include "svPacketData.h" -#include "svDecode.h" +/** + * Rapid-prototyping protection schemes with IEC 61850 + * + * Copyright (c) 2011 Steven Blair + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "sv.h" +#include "svPacketData.h" +#include "svDecode.h" #include "svEncode.h" -struct svData Volt_11; -struct svData rmxuCB_rmxu; +struct svData Volt_11; +struct svData rmxuCB_rmxu; + - -// returns 1 if buf contains valid packet data -int sv_update_Volt_11(unsigned char *buf) { - int size = encode_11(Volt_11.ASDU[Volt_11.ASDUCount].data.data); - Volt_11.ASDU[Volt_11.ASDUCount].data.size = size; - - Volt_11.ASDU[Volt_11.ASDUCount].smpCnt = Volt_11.sampleCountMaster; - Volt_11.sampleCountMaster++; - - if (++Volt_11.ASDUCount == Volt_11.noASDU) { - Volt_11.ASDUCount = 0; - return svEncodePacket(&Volt_11, buf); - } - - return 0; -} - -// returns 1 if buf contains valid packet data -int sv_update_rmxuCB_rmxu(unsigned char *buf) { - int size = encode_rmxu(rmxuCB_rmxu.ASDU[rmxuCB_rmxu.ASDUCount].data.data); - rmxuCB_rmxu.ASDU[rmxuCB_rmxu.ASDUCount].data.size = size; - - rmxuCB_rmxu.ASDU[rmxuCB_rmxu.ASDUCount].smpCnt = rmxuCB_rmxu.sampleCountMaster; - rmxuCB_rmxu.sampleCountMaster++; - - if (++rmxuCB_rmxu.ASDUCount == rmxuCB_rmxu.noASDU) { - rmxuCB_rmxu.ASDUCount = 0; - return svEncodePacket(&rmxuCB_rmxu, buf); - } - - return 0; -} - -void init_sv() { - int i = 0; - - Volt_11.noASDU = 2; - Volt_11.ethHeaderData.destMACAddress[0] = 0x01; - Volt_11.ethHeaderData.destMACAddress[1] = 0x0C; - Volt_11.ethHeaderData.destMACAddress[2] = 0xCD; - Volt_11.ethHeaderData.destMACAddress[3] = 0x04; - Volt_11.ethHeaderData.destMACAddress[4] = 0x00; - Volt_11.ethHeaderData.destMACAddress[5] = 0x01; - Volt_11.ethHeaderData.APPID = 0x4000; - Volt_11.ethHeaderData.VLAN_ID = 0x123; - Volt_11.ethHeaderData.VLAN_PRIORITY = 0x4; - Volt_11.ASDU = (struct ASDU *) malloc(2 * sizeof(struct ASDU)); - for (i = 0; i < 2; i++) { - Volt_11.ASDU[i].svID = (unsigned char *) malloc(3); - strncpy((char *) Volt_11.ASDU[i].svID, "11\0", 3); - Volt_11.ASDU[i].datset = (unsigned char *) malloc(4); - strncpy((char *) Volt_11.ASDU[i].datset, "smv\0", 4); - Volt_11.ASDU[i].smpCnt = 0; - Volt_11.ASDU[i].confRev = 1; - Volt_11.ASDU[i].smpSynch = 1; - Volt_11.ASDU[i].smpRate = 4800; - Volt_11.ASDU[i].data.size = 0; - } - Volt_11.ASDUCount = 0; - - rmxuCB_rmxu.noASDU = 16; - rmxuCB_rmxu.ethHeaderData.destMACAddress[0] = 0x01; - rmxuCB_rmxu.ethHeaderData.destMACAddress[1] = 0x0C; - rmxuCB_rmxu.ethHeaderData.destMACAddress[2] = 0xCD; - rmxuCB_rmxu.ethHeaderData.destMACAddress[3] = 0x04; - rmxuCB_rmxu.ethHeaderData.destMACAddress[4] = 0x00; - rmxuCB_rmxu.ethHeaderData.destMACAddress[5] = 0x01; - rmxuCB_rmxu.ethHeaderData.APPID = 0x4000; - rmxuCB_rmxu.ethHeaderData.VLAN_ID = 0x123; - rmxuCB_rmxu.ethHeaderData.VLAN_PRIORITY = 0x4; - rmxuCB_rmxu.ASDU = (struct ASDU *) malloc(16 * sizeof(struct ASDU)); - for (i = 0; i < 16; i++) { - rmxuCB_rmxu.ASDU[i].svID = (unsigned char *) malloc(5); - strncpy((char *) rmxuCB_rmxu.ASDU[i].svID, "rmxu\0", 5); - rmxuCB_rmxu.ASDU[i].datset = (unsigned char *) malloc(5); - strncpy((char *) rmxuCB_rmxu.ASDU[i].datset, "rmxu\0", 5); - rmxuCB_rmxu.ASDU[i].smpCnt = 0; - rmxuCB_rmxu.ASDU[i].confRev = 1; - rmxuCB_rmxu.ASDU[i].smpSynch = 1; - rmxuCB_rmxu.ASDU[i].smpRate = 16; - rmxuCB_rmxu.ASDU[i].data.size = 0; - } - rmxuCB_rmxu.ASDUCount = 0; -} +// returns 1 if buf contains valid packet data +int sv_update_Volt_11(unsigned char *buf) { + int size = encode_11(Volt_11.ASDU[Volt_11.ASDUCount].data.data); + Volt_11.ASDU[Volt_11.ASDUCount].data.size = size; + + Volt_11.ASDU[Volt_11.ASDUCount].smpCnt = Volt_11.sampleCountMaster; + Volt_11.sampleCountMaster++; + + if (++Volt_11.ASDUCount == Volt_11.noASDU) { + Volt_11.ASDUCount = 0; + return svEncodePacket(&Volt_11, buf); + } + + return 0; +} + +// returns 1 if buf contains valid packet data +int sv_update_rmxuCB_rmxu(unsigned char *buf) { + int size = encode_rmxu(rmxuCB_rmxu.ASDU[rmxuCB_rmxu.ASDUCount].data.data); + rmxuCB_rmxu.ASDU[rmxuCB_rmxu.ASDUCount].data.size = size; + + rmxuCB_rmxu.ASDU[rmxuCB_rmxu.ASDUCount].smpCnt = rmxuCB_rmxu.sampleCountMaster; + rmxuCB_rmxu.sampleCountMaster++; + + if (++rmxuCB_rmxu.ASDUCount == rmxuCB_rmxu.noASDU) { + rmxuCB_rmxu.ASDUCount = 0; + return svEncodePacket(&rmxuCB_rmxu, buf); + } + + return 0; +} + +void init_sv() { + int i = 0; + Volt_11.noASDU = 2; + Volt_11.ethHeaderData.destMACAddress[0] = 0x01; + Volt_11.ethHeaderData.destMACAddress[1] = 0x0C; + Volt_11.ethHeaderData.destMACAddress[2] = 0xCD; + Volt_11.ethHeaderData.destMACAddress[3] = 0x04; + Volt_11.ethHeaderData.destMACAddress[4] = 0x00; + Volt_11.ethHeaderData.destMACAddress[5] = 0x01; + Volt_11.ethHeaderData.APPID = 0x4000; + Volt_11.ethHeaderData.VLAN_ID = 0x123; + Volt_11.ethHeaderData.VLAN_PRIORITY = 0x4; + Volt_11.ASDU = (struct ASDU *) malloc(2 * sizeof(struct ASDU)); + for (i = 0; i < 2; i++) { + Volt_11.ASDU[i].svID = (unsigned char *) malloc(3); + strncpy((char *) Volt_11.ASDU[i].svID, "11\0", 3); + Volt_11.ASDU[i].datset = (unsigned char *) malloc(4); + strncpy((char *) Volt_11.ASDU[i].datset, "smv\0", 4); + Volt_11.ASDU[i].smpCnt = 0; + Volt_11.ASDU[i].confRev = 1; + Volt_11.ASDU[i].smpSynch = 1; + Volt_11.ASDU[i].smpRate = 4800; + Volt_11.ASDU[i].data.size = 0; + } + Volt_11.ASDUCount = 0; + + rmxuCB_rmxu.noASDU = 16; + rmxuCB_rmxu.ethHeaderData.destMACAddress[0] = 0x01; + rmxuCB_rmxu.ethHeaderData.destMACAddress[1] = 0x0C; + rmxuCB_rmxu.ethHeaderData.destMACAddress[2] = 0xCD; + rmxuCB_rmxu.ethHeaderData.destMACAddress[3] = 0x04; + rmxuCB_rmxu.ethHeaderData.destMACAddress[4] = 0x00; + rmxuCB_rmxu.ethHeaderData.destMACAddress[5] = 0x01; + rmxuCB_rmxu.ethHeaderData.APPID = 0x4000; + rmxuCB_rmxu.ethHeaderData.VLAN_ID = 0x123; + rmxuCB_rmxu.ethHeaderData.VLAN_PRIORITY = 0x4; + rmxuCB_rmxu.ASDU = (struct ASDU *) malloc(16 * sizeof(struct ASDU)); + for (i = 0; i < 16; i++) { + rmxuCB_rmxu.ASDU[i].svID = (unsigned char *) malloc(5); + strncpy((char *) rmxuCB_rmxu.ASDU[i].svID, "rmxu\0", 5); + rmxuCB_rmxu.ASDU[i].datset = (unsigned char *) malloc(5); + strncpy((char *) rmxuCB_rmxu.ASDU[i].datset, "rmxu\0", 5); + rmxuCB_rmxu.ASDU[i].smpCnt = 0; + rmxuCB_rmxu.ASDU[i].confRev = 1; + rmxuCB_rmxu.ASDU[i].smpSynch = 1; + rmxuCB_rmxu.ASDU[i].smpRate = 16; + rmxuCB_rmxu.ASDU[i].data.size = 0; + } + rmxuCB_rmxu.ASDUCount = 0; +} +
diff -r 230c10b228ea -r 9399d44c2b1a sv.h --- a/sv.h Fri Oct 07 13:41:08 2011 +0000 +++ b/sv.h Fri Oct 07 13:48:18 2011 +0000 @@ -1,3 +1,23 @@ +/** + * Rapid-prototyping protection schemes with IEC 61850 + * + * Copyright (c) 2011 Steven Blair + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + #ifndef SV_H #define SV_H
diff -r 230c10b228ea -r 9399d44c2b1a svDecode.c --- a/svDecode.c Fri Oct 07 13:41:08 2011 +0000 +++ b/svDecode.c Fri Oct 07 13:48:18 2011 +0000 @@ -1,194 +1,214 @@ -#include "svDecodeBasic.h" -#include "ied.h" +/** + * Rapid-prototyping protection schemes with IEC 61850 + * + * Copyright (c) 2011 Steven Blair + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "svDecodeBasic.h" +#include "ied.h" #include "svDecode.h" -int decode_myAnalogValue(unsigned char *buf, struct myAnalogValue *myAnalogValue) { - int offset = 0; - - offset += DECODE_CTYPE_FLOAT32(&buf[offset], &myAnalogValue->f); - - return offset; +int decode_myAnalogValue(unsigned char *buf, struct myAnalogValue *myAnalogValue) { + int offset = 0; + + offset += DECODE_CTYPE_FLOAT32(&buf[offset], &myAnalogValue->f); + + return offset; } -int decode_ScaledValueConfig(unsigned char *buf, struct ScaledValueConfig *ScaledValueConfig) { - int offset = 0; - - offset += DECODE_CTYPE_FLOAT32(&buf[offset], &ScaledValueConfig->scaleFactor); - offset += DECODE_CTYPE_FLOAT32(&buf[offset], &ScaledValueConfig->offset); - - return offset; +int decode_ScaledValueConfig(unsigned char *buf, struct ScaledValueConfig *ScaledValueConfig) { + int offset = 0; + + offset += DECODE_CTYPE_FLOAT32(&buf[offset], &ScaledValueConfig->scaleFactor); + offset += DECODE_CTYPE_FLOAT32(&buf[offset], &ScaledValueConfig->offset); + + return offset; } -int decode_myVector(unsigned char *buf, struct myVector *myVector) { - int offset = 0; - - offset += decode_myAnalogValue(&buf[offset], &myVector->mag); - offset += decode_myAnalogValue(&buf[offset], &myVector->ang); - - return offset; +int decode_myVector(unsigned char *buf, struct myVector *myVector) { + int offset = 0; + + offset += decode_myAnalogValue(&buf[offset], &myVector->mag); + offset += decode_myAnalogValue(&buf[offset], &myVector->ang); + + return offset; } -int decode_simpleVector(unsigned char *buf, struct simpleVector *simpleVector) { - int offset = 0; - - offset += decode_myAnalogValue(&buf[offset], &simpleVector->mag); - offset += decode_myAnalogValue(&buf[offset], &simpleVector->ang); - - return offset; +int decode_simpleVector(unsigned char *buf, struct simpleVector *simpleVector) { + int offset = 0; + + offset += decode_myAnalogValue(&buf[offset], &simpleVector->mag); + offset += decode_myAnalogValue(&buf[offset], &simpleVector->ang); + + return offset; } -int decode_myMod(unsigned char *buf, struct myMod *myMod) { - int offset = 0; - - offset += DECODE_CTYPE_ENUM(&buf[offset], (CTYPE_ENUM *) &myMod->ctlVal); - offset += DECODE_CTYPE_ENUM(&buf[offset], (CTYPE_ENUM *) &myMod->stVal); - offset += DECODE_CTYPE_QUALITY(&buf[offset], &myMod->q); - offset += DECODE_CTYPE_TIMESTAMP(&buf[offset], &myMod->t); - - return offset; +int decode_myMod(unsigned char *buf, struct myMod *myMod) { + int offset = 0; + + offset += DECODE_CTYPE_ENUM(&buf[offset], (CTYPE_ENUM *) &myMod->ctlVal); + offset += DECODE_CTYPE_ENUM(&buf[offset], (CTYPE_ENUM *) &myMod->stVal); + offset += DECODE_CTYPE_QUALITY(&buf[offset], &myMod->q); + offset += DECODE_CTYPE_TIMESTAMP(&buf[offset], &myMod->t); + + return offset; } -int decode_myHealth(unsigned char *buf, struct myHealth *myHealth) { - int offset = 0; - - offset += DECODE_CTYPE_ENUM(&buf[offset], (CTYPE_ENUM *) &myHealth->stVal); - - return offset; +int decode_myHealth(unsigned char *buf, struct myHealth *myHealth) { + int offset = 0; + + offset += DECODE_CTYPE_ENUM(&buf[offset], (CTYPE_ENUM *) &myHealth->stVal); + + return offset; } -int decode_myBeh(unsigned char *buf, struct myBeh *myBeh) { - int offset = 0; - - offset += DECODE_CTYPE_ENUM(&buf[offset], (CTYPE_ENUM *) &myBeh->stVal); - - return offset; +int decode_myBeh(unsigned char *buf, struct myBeh *myBeh) { + int offset = 0; + + offset += DECODE_CTYPE_ENUM(&buf[offset], (CTYPE_ENUM *) &myBeh->stVal); + + return offset; } -int decode_myINS(unsigned char *buf, struct myINS *myINS) { - int offset = 0; - - offset += DECODE_CTYPE_INT32(&buf[offset], &myINS->stVal); - - return offset; +int decode_myINS(unsigned char *buf, struct myINS *myINS) { + int offset = 0; + + offset += DECODE_CTYPE_INT32(&buf[offset], &myINS->stVal); + + return offset; } -int decode_myLPL(unsigned char *buf, struct myLPL *myLPL) { - int offset = 0; - - offset += DECODE_CTYPE_VISSTRING255(&buf[offset], &myLPL->ldNs); - offset += DECODE_CTYPE_VISSTRING255(&buf[offset], &myLPL->configRev); - - return offset; +int decode_myLPL(unsigned char *buf, struct myLPL *myLPL) { + int offset = 0; + + offset += DECODE_CTYPE_VISSTRING255(&buf[offset], &myLPL->ldNs); + offset += DECODE_CTYPE_VISSTRING255(&buf[offset], &myLPL->configRev); + + return offset; } -int decode_myDPL(unsigned char *buf, struct myDPL *myDPL) { - int offset = 0; - - offset += DECODE_CTYPE_VISSTRING255(&buf[offset], &myDPL->vendor); - offset += DECODE_CTYPE_VISSTRING255(&buf[offset], &myDPL->hwRev); - - return offset; +int decode_myDPL(unsigned char *buf, struct myDPL *myDPL) { + int offset = 0; + + offset += DECODE_CTYPE_VISSTRING255(&buf[offset], &myDPL->vendor); + offset += DECODE_CTYPE_VISSTRING255(&buf[offset], &myDPL->hwRev); + + return offset; } -int decode_myPos(unsigned char *buf, struct myPos *myPos) { - int offset = 0; - - offset += DECODE_CTYPE_DBPOS(&buf[offset], &myPos->stVal); - offset += DECODE_CTYPE_QUALITY(&buf[offset], &myPos->q); - offset += DECODE_CTYPE_TIMESTAMP(&buf[offset], &myPos->t); - offset += DECODE_CTYPE_BOOLEAN(&buf[offset], &myPos->ctlVal); - - return offset; +int decode_myPos(unsigned char *buf, struct myPos *myPos) { + int offset = 0; + + offset += DECODE_CTYPE_DBPOS(&buf[offset], &myPos->stVal); + offset += DECODE_CTYPE_QUALITY(&buf[offset], &myPos->q); + offset += DECODE_CTYPE_TIMESTAMP(&buf[offset], &myPos->t); + offset += DECODE_CTYPE_BOOLEAN(&buf[offset], &myPos->ctlVal); + + return offset; } -int decode_mySPS(unsigned char *buf, struct mySPS *mySPS) { - int offset = 0; - - offset += DECODE_CTYPE_INT32(&buf[offset], &mySPS->stVal); - offset += DECODE_CTYPE_QUALITY(&buf[offset], &mySPS->q); - offset += DECODE_CTYPE_TIMESTAMP(&buf[offset], &mySPS->t); - - return offset; +int decode_mySPS(unsigned char *buf, struct mySPS *mySPS) { + int offset = 0; + + offset += DECODE_CTYPE_INT32(&buf[offset], &mySPS->stVal); + offset += DECODE_CTYPE_QUALITY(&buf[offset], &mySPS->q); + offset += DECODE_CTYPE_TIMESTAMP(&buf[offset], &mySPS->t); + + return offset; } -int decode_myMV(unsigned char *buf, struct myMV *myMV) { - int offset = 0; - - offset += decode_myAnalogValue(&buf[offset], &myMV->mag); - offset += DECODE_CTYPE_QUALITY(&buf[offset], &myMV->q); - offset += DECODE_CTYPE_TIMESTAMP(&buf[offset], &myMV->t); - offset += decode_ScaledValueConfig(&buf[offset], &myMV->sVC); - - return offset; +int decode_myMV(unsigned char *buf, struct myMV *myMV) { + int offset = 0; + + offset += decode_myAnalogValue(&buf[offset], &myMV->mag); + offset += DECODE_CTYPE_QUALITY(&buf[offset], &myMV->q); + offset += DECODE_CTYPE_TIMESTAMP(&buf[offset], &myMV->t); + offset += decode_ScaledValueConfig(&buf[offset], &myMV->sVC); + + return offset; } -int decode_simpleMV(unsigned char *buf, struct simpleMV *simpleMV) { - int offset = 0; - - offset += DECODE_CTYPE_FLOAT32(&buf[offset], &simpleMV->mag); - offset += DECODE_CTYPE_QUALITY(&buf[offset], &simpleMV->q); - offset += DECODE_CTYPE_TIMESTAMP(&buf[offset], &simpleMV->t); - offset += decode_ScaledValueConfig(&buf[offset], &simpleMV->sVC); - - return offset; +int decode_simpleMV(unsigned char *buf, struct simpleMV *simpleMV) { + int offset = 0; + + offset += DECODE_CTYPE_FLOAT32(&buf[offset], &simpleMV->mag); + offset += DECODE_CTYPE_QUALITY(&buf[offset], &simpleMV->q); + offset += DECODE_CTYPE_TIMESTAMP(&buf[offset], &simpleMV->t); + offset += decode_ScaledValueConfig(&buf[offset], &simpleMV->sVC); + + return offset; } -int decode_simpleCMV(unsigned char *buf, struct simpleCMV *simpleCMV) { - int offset = 0; - - offset += decode_simpleVector(&buf[offset], &simpleCMV->cVal); - offset += DECODE_CTYPE_QUALITY(&buf[offset], &simpleCMV->q); - offset += DECODE_CTYPE_TIMESTAMP(&buf[offset], &simpleCMV->t); - - return offset; +int decode_simpleCMV(unsigned char *buf, struct simpleCMV *simpleCMV) { + int offset = 0; + + offset += decode_simpleVector(&buf[offset], &simpleCMV->cVal); + offset += DECODE_CTYPE_QUALITY(&buf[offset], &simpleCMV->q); + offset += DECODE_CTYPE_TIMESTAMP(&buf[offset], &simpleCMV->t); + + return offset; } -int decode_simpleWYE(unsigned char *buf, struct simpleWYE *simpleWYE) { - int offset = 0; - - offset += decode_simpleCMV(&buf[offset], &simpleWYE->phsA); - offset += decode_simpleCMV(&buf[offset], &simpleWYE->phsB); - offset += decode_simpleCMV(&buf[offset], &simpleWYE->phsC); - - return offset; +int decode_simpleWYE(unsigned char *buf, struct simpleWYE *simpleWYE) { + int offset = 0; + + offset += decode_simpleCMV(&buf[offset], &simpleWYE->phsA); + offset += decode_simpleCMV(&buf[offset], &simpleWYE->phsB); + offset += decode_simpleCMV(&buf[offset], &simpleWYE->phsC); + + return offset; } -int decode_myCMV(unsigned char *buf, struct myCMV *myCMV) { - int offset = 0; - - offset += decode_myVector(&buf[offset], &myCMV->cVal); - offset += DECODE_CTYPE_QUALITY(&buf[offset], &myCMV->q); - offset += DECODE_CTYPE_TIMESTAMP(&buf[offset], &myCMV->t); - - return offset; +int decode_myCMV(unsigned char *buf, struct myCMV *myCMV) { + int offset = 0; + + offset += decode_myVector(&buf[offset], &myCMV->cVal); + offset += DECODE_CTYPE_QUALITY(&buf[offset], &myCMV->q); + offset += DECODE_CTYPE_TIMESTAMP(&buf[offset], &myCMV->t); + + return offset; } -int decode_mySEQ(unsigned char *buf, struct mySEQ *mySEQ) { - int offset = 0; - - offset += decode_myCMV(&buf[offset], &mySEQ->c1); - offset += decode_myCMV(&buf[offset], &mySEQ->c2); - offset += decode_myCMV(&buf[offset], &mySEQ->c3); - offset += DECODE_CTYPE_ENUM(&buf[offset], (CTYPE_ENUM *) &mySEQ->seqT); - - return offset; +int decode_mySEQ(unsigned char *buf, struct mySEQ *mySEQ) { + int offset = 0; + + offset += decode_myCMV(&buf[offset], &mySEQ->c1); + offset += decode_myCMV(&buf[offset], &mySEQ->c2); + offset += decode_myCMV(&buf[offset], &mySEQ->c3); + offset += DECODE_CTYPE_ENUM(&buf[offset], (CTYPE_ENUM *) &mySEQ->seqT); + + return offset; } -int decode_mySAV(unsigned char *buf, struct mySAV *mySAV) { - int offset = 0; - - offset += decode_myAnalogValue(&buf[offset], &mySAV->instMag); - offset += DECODE_CTYPE_QUALITY(&buf[offset], &mySAV->q); - - return offset; +int decode_mySAV(unsigned char *buf, struct mySAV *mySAV) { + int offset = 0; + + offset += decode_myAnalogValue(&buf[offset], &mySAV->instMag); + offset += DECODE_CTYPE_QUALITY(&buf[offset], &mySAV->q); + + return offset; } -int decode_simpleSAV(unsigned char *buf, struct simpleSAV *simpleSAV) { - int offset = 0; - - offset += decode_myAnalogValue(&buf[offset], &simpleSAV->instMag); - offset += DECODE_CTYPE_QUALITY(&buf[offset], &simpleSAV->q); - - return offset; +int decode_simpleSAV(unsigned char *buf, struct simpleSAV *simpleSAV) { + int offset = 0; + + offset += decode_myAnalogValue(&buf[offset], &simpleSAV->instMag); + offset += DECODE_CTYPE_QUALITY(&buf[offset], &simpleSAV->q); + + return offset; } -int decode_rmxu_MMXU_1(unsigned char *buf, int noASDU) { - int offset = 0; - - offset += decode_simpleSAV(&buf[offset], &D1Q1SB4.S1.C1.MMXU_1.sv_inputs.AmpLocPhsA_1[noASDU]); - offset += decode_simpleSAV(&buf[offset], &D1Q1SB4.S1.C1.MMXU_1.sv_inputs.AmpLocPhsB_1[noASDU]); - offset += decode_simpleSAV(&buf[offset], &D1Q1SB4.S1.C1.MMXU_1.sv_inputs.AmpLocPhsC_1[noASDU]); - - return offset; +int decode_rmxu_MMXU_1(unsigned char *buf, int noASDU) { + int offset = 0; + + offset += decode_simpleSAV(&buf[offset], &D1Q1SB4.S1.C1.MMXU_1.sv_inputs.AmpLocPhsA_1[noASDU]); + offset += decode_simpleSAV(&buf[offset], &D1Q1SB4.S1.C1.MMXU_1.sv_inputs.AmpLocPhsB_1[noASDU]); + offset += decode_simpleSAV(&buf[offset], &D1Q1SB4.S1.C1.MMXU_1.sv_inputs.AmpLocPhsC_1[noASDU]); + + return offset; } -void svDecodeDataset(unsigned char *dataset, int datasetLength, int ASDU, unsigned char *svID, int svIDLength) { - - if (strncmp((const char *) svID, "rmxu", svIDLength) == 0) { - decode_rmxu_MMXU_1(dataset, ASDU); - } -} - +void svDecodeDataset(unsigned char *dataset, int datasetLength, int ASDU, unsigned char *svID, int svIDLength) { + if (strncmp((const char *) svID, "rmxu", svIDLength) == 0) { + decode_rmxu_MMXU_1(dataset, ASDU); + } +} + +
diff -r 230c10b228ea -r 9399d44c2b1a svDecode.h --- a/svDecode.h Fri Oct 07 13:41:08 2011 +0000 +++ b/svDecode.h Fri Oct 07 13:48:18 2011 +0000 @@ -1,3 +1,23 @@ +/** + * Rapid-prototyping protection schemes with IEC 61850 + * + * Copyright (c) 2011 Steven Blair + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + #ifndef SV_DECODE_H #define SV_DECODE_H @@ -9,8 +29,8 @@ -int decode_rmxu_MMXU_1(unsigned char *buf, int noASDU); - +int decode_rmxu_MMXU_1(unsigned char *buf, int noASDU); + void svDecodeDataset(unsigned char *dataset, int datasetLength, int ASDU, unsigned char *svID, int svIDLength);
diff -r 230c10b228ea -r 9399d44c2b1a svDecodeBasic.c --- a/svDecodeBasic.c Fri Oct 07 13:41:08 2011 +0000 +++ b/svDecodeBasic.c Fri Oct 07 13:48:18 2011 +0000 @@ -1,3 +1,23 @@ +/** + * Rapid-prototyping protection schemes with IEC 61850 + * + * Copyright (c) 2011 Steven Blair + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + #include "ctypes.h" #include "datatypes.h" #include "ied.h" @@ -6,62 +26,62 @@ // SV encoding of basic types int DECODE_CTYPE_FLOAT32(unsigned char *buf, CTYPE_FLOAT32 *value) { - netmemcpy(value, buf, SV_GET_LENGTH_FLOAT32); + netmemcpy(value, buf, SV_GET_LENGTH_FLOAT32); - return SV_GET_LENGTH_FLOAT32; + return SV_GET_LENGTH_FLOAT32; } int DECODE_CTYPE_FLOAT64(unsigned char *buf, CTYPE_FLOAT64 *value) { - netmemcpy(value, buf, SV_GET_LENGTH_FLOAT64); + netmemcpy(value, buf, SV_GET_LENGTH_FLOAT64); - return SV_GET_LENGTH_FLOAT64; + return SV_GET_LENGTH_FLOAT64; } int DECODE_CTYPE_QUALITY(unsigned char *buf, CTYPE_QUALITY *value) { - netmemcpy(value, buf, SV_GET_LENGTH_QUALITY); + netmemcpy(value, buf, SV_GET_LENGTH_QUALITY); - return SV_GET_LENGTH_QUALITY; + return SV_GET_LENGTH_QUALITY; } int DECODE_CTYPE_TIMESTAMP(unsigned char *buf, CTYPE_TIMESTAMP *value) { - netmemcpy(value, buf, SV_GET_LENGTH_TIMESTAMP); + netmemcpy(value, buf, SV_GET_LENGTH_TIMESTAMP); - return SV_GET_LENGTH_TIMESTAMP; + return SV_GET_LENGTH_TIMESTAMP; } -int DECODE_CTYPE_ENUM(unsigned char *buf, CTYPE_ENUM *value) { // assuming enum is an int - allows any enum type to be used - netmemcpy(value, buf, SV_GET_LENGTH_ENUM); +int DECODE_CTYPE_ENUM(unsigned char *buf, CTYPE_ENUM *value) { // assuming enum is an int - allows any enum type to be used + netmemcpy(value, buf, SV_GET_LENGTH_ENUM); - return SV_GET_LENGTH_ENUM; + return SV_GET_LENGTH_ENUM; } int DECODE_CTYPE_INT16(unsigned char *buf, CTYPE_INT16 *value) { - netmemcpy(value, buf, SV_GET_LENGTH_INT16); + netmemcpy(value, buf, SV_GET_LENGTH_INT16); - return SV_GET_LENGTH_INT16; + return SV_GET_LENGTH_INT16; } int DECODE_CTYPE_INT32(unsigned char *buf, CTYPE_INT32 *value) { - netmemcpy(value, buf, SV_GET_LENGTH_INT32); + netmemcpy(value, buf, SV_GET_LENGTH_INT32); - return SV_GET_LENGTH_INT32; + return SV_GET_LENGTH_INT32; } int DECODE_CTYPE_INT16U(unsigned char *buf, CTYPE_INT16U *value) { - netmemcpy(value, buf, SV_GET_LENGTH_INT16U); + netmemcpy(value, buf, SV_GET_LENGTH_INT16U); - return SV_GET_LENGTH_INT16U; + return SV_GET_LENGTH_INT16U; } int DECODE_CTYPE_INT32U(unsigned char *buf, CTYPE_INT32U *value) { - netmemcpy(value, buf, SV_GET_LENGTH_INT32U); + netmemcpy(value, buf, SV_GET_LENGTH_INT32U); - return SV_GET_LENGTH_INT32U; + return SV_GET_LENGTH_INT32U; } int DECODE_CTYPE_VISSTRING255(unsigned char *buf, CTYPE_VISSTRING255 *value) { - netmemcpy(value, buf, SV_GET_LENGTH_VISSTRING255); + netmemcpy(value, buf, SV_GET_LENGTH_VISSTRING255); - return SV_GET_LENGTH_VISSTRING255; + return SV_GET_LENGTH_VISSTRING255; } int DECODE_CTYPE_BOOLEAN(unsigned char *buf, CTYPE_BOOLEAN *value) { - netmemcpy(value, buf, SV_GET_LENGTH_BOOLEAN); + netmemcpy(value, buf, SV_GET_LENGTH_BOOLEAN); - return SV_GET_LENGTH_BOOLEAN; + return SV_GET_LENGTH_BOOLEAN; } int DECODE_CTYPE_DBPOS(unsigned char *buf, CTYPE_DBPOS *value) { - netmemcpy(value, buf, SV_GET_LENGTH_DBPOS); + netmemcpy(value, buf, SV_GET_LENGTH_DBPOS); - return SV_GET_LENGTH_DBPOS; + return SV_GET_LENGTH_DBPOS; }
diff -r 230c10b228ea -r 9399d44c2b1a svDecodeBasic.h --- a/svDecodeBasic.h Fri Oct 07 13:41:08 2011 +0000 +++ b/svDecodeBasic.h Fri Oct 07 13:48:18 2011 +0000 @@ -1,3 +1,23 @@ +/** + * Rapid-prototyping protection schemes with IEC 61850 + * + * Copyright (c) 2011 Steven Blair + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + #ifndef SV_DECODE_BASIC_H #define SV_DECODE_BASIC_H
diff -r 230c10b228ea -r 9399d44c2b1a svDecodePacket.c --- a/svDecodePacket.c Fri Oct 07 13:41:08 2011 +0000 +++ b/svDecodePacket.c Fri Oct 07 13:48:18 2011 +0000 @@ -1,3 +1,23 @@ +/** + * Rapid-prototyping protection schemes with IEC 61850 + * + * Copyright (c) 2011 Steven Blair + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + #include "svDecodeBasic.h" #include "ied.h" #include "svDecode.h" @@ -7,93 +27,93 @@ void svDecodeASDU(unsigned char *buf, int len, int noASDU) { - unsigned char tag; // assumes only one byte is used - int lengthFieldSize; - int lengthValue; - int offsetForNonSequence; - unsigned char *svID = NULL; - int svIDLength = 0; + unsigned char tag; // assumes only one byte is used + int lengthFieldSize; + int lengthValue; + int offsetForNonSequence; + unsigned char *svID = NULL; + int svIDLength = 0; - int i = 0; - for (i = 0; i < len;) { - tag = (unsigned char) buf[i]; - lengthFieldSize = getLengthFieldSize((unsigned char) buf[i + 1]); - lengthValue = decodeLength((unsigned char *) &buf[i + 1]); - offsetForNonSequence = 1 + lengthFieldSize + lengthValue; + int i = 0; + for (i = 0; i < len;) { + tag = (unsigned char) buf[i]; + lengthFieldSize = getLengthFieldSize((unsigned char) buf[i + 1]); + lengthValue = decodeLength((unsigned char *) &buf[i + 1]); + offsetForNonSequence = 1 + lengthFieldSize + lengthValue; - //printf("\ttag: %x, noASDU: %u, lengthFieldSize: %i, lengthValue: %i, offset: %i\n", tag, noASDU, lengthFieldSize, lengthValue, offsetForNonSequence); + //printf("\ttag: %x, noASDU: %u, lengthFieldSize: %i, lengthValue: %i, offset: %i\n", tag, noASDU, lengthFieldSize, lengthValue, offsetForNonSequence); - switch (tag) { - case 0x80: - svID = &buf[i + 1 + lengthFieldSize]; - svIDLength = lengthValue; - break; - case 0x81: + switch (tag) { + case 0x80: + svID = &buf[i + 1 + lengthFieldSize]; + svIDLength = lengthValue; + break; + case 0x81: - break; - case 0x82: - // TODO: may be useful to store smpCnt value - break; - case 0x83: + break; + case 0x82: + // TODO: may be useful to store smpCnt value + break; + case 0x83: - break; - case 0x84: + break; + case 0x84: - break; - case 0x85: + break; + case 0x85: - break; - case 0x86: + break; + case 0x86: - break; - case 0x87: - if (svID != NULL) { - svDecodeDataset(&buf[i + 1 + lengthFieldSize], lengthValue, noASDU, svID, svIDLength); - } - break; - default: - break; - } + break; + case 0x87: + if (svID != NULL) { + svDecodeDataset(&buf[i + 1 + lengthFieldSize], lengthValue, noASDU, svID, svIDLength); + } + break; + default: + break; + } - i += offsetForNonSequence; - } + i += offsetForNonSequence; + } } void svDecodeAPDU(unsigned char *buf, int len) { - unsigned char tag = (unsigned char) buf[0]; // assumes only one byte is used - int lengthFieldSize = getLengthFieldSize((unsigned char) buf[1]); - int lengthValue = decodeLength((unsigned char *) &buf[1]); - int offsetForSequence = 1 + lengthFieldSize; - int offsetForNonSequence = 1 + lengthFieldSize + lengthValue; - //static unsigned int noASDU = 0; - static unsigned int ASDU = 0; + unsigned char tag = (unsigned char) buf[0]; // assumes only one byte is used + int lengthFieldSize = getLengthFieldSize((unsigned char) buf[1]); + int lengthValue = decodeLength((unsigned char *) &buf[1]); + int offsetForSequence = 1 + lengthFieldSize; + int offsetForNonSequence = 1 + lengthFieldSize + lengthValue; + //static unsigned int noASDU = 0; + static unsigned int ASDU = 0; - //printf("tag: %x, noASDU: %u, lengthFieldSize: %i, lengthValue: %i, offset: %i\n", tag, noASDU, lengthFieldSize, lengthValue, offsetForNonSequence); + //printf("tag: %x, noASDU: %u, lengthFieldSize: %i, lengthValue: %i, offset: %i\n", tag, noASDU, lengthFieldSize, lengthValue, offsetForNonSequence); - switch (tag) { - case 0x60: - svDecodeAPDU(&buf[offsetForSequence], lengthValue); - break; - case 0x80: - //noASDU = (unsigned int) buf[1 + lengthFieldSize]; // assuming noASDU is < 126 - ASDU = 0; - svDecodeAPDU(&buf[offsetForNonSequence], len - offsetForNonSequence); - break; - case 0xA2: - svDecodeAPDU(&buf[offsetForSequence], lengthValue); - break; - case 0x30: - svDecodeASDU(&buf[offsetForSequence], lengthValue, ASDU++); + switch (tag) { + case 0x60: + svDecodeAPDU(&buf[offsetForSequence], lengthValue); + break; + case 0x80: + //noASDU = (unsigned int) buf[1 + lengthFieldSize]; // assuming noASDU is < 126 + ASDU = 0; + svDecodeAPDU(&buf[offsetForNonSequence], len - offsetForNonSequence); + break; + case 0xA2: + svDecodeAPDU(&buf[offsetForSequence], lengthValue); + break; + case 0x30: + svDecodeASDU(&buf[offsetForSequence], lengthValue, ASDU++); - svDecodeAPDU(&buf[offsetForNonSequence], len - offsetForNonSequence); - break; - default: - break; - } + svDecodeAPDU(&buf[offsetForNonSequence], len - offsetForNonSequence); + break; + default: + break; + } } void svDecode(unsigned char *buf, int len) { - unsigned short APDULength = ((buf[21] << 8) | buf[22]) - 8; // must use length in PDU because total bytes (len) may contain CRC + unsigned short APDULength = ((buf[21] << 8) | buf[22]) - 8; // must use length in PDU because total bytes (len) may contain CRC - svDecodeAPDU(&buf[26], APDULength); // cuts out frame header (fixed size of 26 bytes before start of APDU) + svDecodeAPDU(&buf[26], APDULength); // cuts out frame header (fixed size of 26 bytes before start of APDU) }
diff -r 230c10b228ea -r 9399d44c2b1a svEncode.c --- a/svEncode.c Fri Oct 07 13:41:08 2011 +0000 +++ b/svEncode.c Fri Oct 07 13:48:18 2011 +0000 @@ -1,199 +1,219 @@ -#include "svEncodeBasic.h" -#include "ied.h" +/** + * Rapid-prototyping protection schemes with IEC 61850 + * + * Copyright (c) 2011 Steven Blair + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "svEncodeBasic.h" +#include "ied.h" #include "svEncode.h" -int encode_myAnalogValue(unsigned char *buf, struct myAnalogValue *myAnalogValue) { - int offset = 0; - - offset += ENCODE_CTYPE_FLOAT32(&buf[offset], &myAnalogValue->f); - - return offset; +int encode_myAnalogValue(unsigned char *buf, struct myAnalogValue *myAnalogValue) { + int offset = 0; + + offset += ENCODE_CTYPE_FLOAT32(&buf[offset], &myAnalogValue->f); + + return offset; } -int encode_ScaledValueConfig(unsigned char *buf, struct ScaledValueConfig *ScaledValueConfig) { - int offset = 0; - - offset += ENCODE_CTYPE_FLOAT32(&buf[offset], &ScaledValueConfig->scaleFactor); - offset += ENCODE_CTYPE_FLOAT32(&buf[offset], &ScaledValueConfig->offset); - - return offset; +int encode_ScaledValueConfig(unsigned char *buf, struct ScaledValueConfig *ScaledValueConfig) { + int offset = 0; + + offset += ENCODE_CTYPE_FLOAT32(&buf[offset], &ScaledValueConfig->scaleFactor); + offset += ENCODE_CTYPE_FLOAT32(&buf[offset], &ScaledValueConfig->offset); + + return offset; } -int encode_myVector(unsigned char *buf, struct myVector *myVector) { - int offset = 0; - - offset += encode_myAnalogValue(&buf[offset], &myVector->mag); - offset += encode_myAnalogValue(&buf[offset], &myVector->ang); - - return offset; +int encode_myVector(unsigned char *buf, struct myVector *myVector) { + int offset = 0; + + offset += encode_myAnalogValue(&buf[offset], &myVector->mag); + offset += encode_myAnalogValue(&buf[offset], &myVector->ang); + + return offset; } -int encode_simpleVector(unsigned char *buf, struct simpleVector *simpleVector) { - int offset = 0; - - offset += encode_myAnalogValue(&buf[offset], &simpleVector->mag); - offset += encode_myAnalogValue(&buf[offset], &simpleVector->ang); - - return offset; +int encode_simpleVector(unsigned char *buf, struct simpleVector *simpleVector) { + int offset = 0; + + offset += encode_myAnalogValue(&buf[offset], &simpleVector->mag); + offset += encode_myAnalogValue(&buf[offset], &simpleVector->ang); + + return offset; } -int encode_myMod(unsigned char *buf, struct myMod *myMod) { - int offset = 0; - - offset += ENCODE_CTYPE_ENUM(&buf[offset], (CTYPE_ENUM *) &myMod->ctlVal); - offset += ENCODE_CTYPE_ENUM(&buf[offset], (CTYPE_ENUM *) &myMod->stVal); - offset += ENCODE_CTYPE_QUALITY(&buf[offset], &myMod->q); - offset += ENCODE_CTYPE_TIMESTAMP(&buf[offset], &myMod->t); - - return offset; +int encode_myMod(unsigned char *buf, struct myMod *myMod) { + int offset = 0; + + offset += ENCODE_CTYPE_ENUM(&buf[offset], (CTYPE_ENUM *) &myMod->ctlVal); + offset += ENCODE_CTYPE_ENUM(&buf[offset], (CTYPE_ENUM *) &myMod->stVal); + offset += ENCODE_CTYPE_QUALITY(&buf[offset], &myMod->q); + offset += ENCODE_CTYPE_TIMESTAMP(&buf[offset], &myMod->t); + + return offset; } -int encode_myHealth(unsigned char *buf, struct myHealth *myHealth) { - int offset = 0; - - offset += ENCODE_CTYPE_ENUM(&buf[offset], (CTYPE_ENUM *) &myHealth->stVal); - - return offset; +int encode_myHealth(unsigned char *buf, struct myHealth *myHealth) { + int offset = 0; + + offset += ENCODE_CTYPE_ENUM(&buf[offset], (CTYPE_ENUM *) &myHealth->stVal); + + return offset; } -int encode_myBeh(unsigned char *buf, struct myBeh *myBeh) { - int offset = 0; - - offset += ENCODE_CTYPE_ENUM(&buf[offset], (CTYPE_ENUM *) &myBeh->stVal); - - return offset; +int encode_myBeh(unsigned char *buf, struct myBeh *myBeh) { + int offset = 0; + + offset += ENCODE_CTYPE_ENUM(&buf[offset], (CTYPE_ENUM *) &myBeh->stVal); + + return offset; } -int encode_myINS(unsigned char *buf, struct myINS *myINS) { - int offset = 0; - - offset += ENCODE_CTYPE_INT32(&buf[offset], &myINS->stVal); - - return offset; +int encode_myINS(unsigned char *buf, struct myINS *myINS) { + int offset = 0; + + offset += ENCODE_CTYPE_INT32(&buf[offset], &myINS->stVal); + + return offset; } -int encode_myLPL(unsigned char *buf, struct myLPL *myLPL) { - int offset = 0; - - offset += ENCODE_CTYPE_VISSTRING255(&buf[offset], &myLPL->ldNs); - offset += ENCODE_CTYPE_VISSTRING255(&buf[offset], &myLPL->configRev); - - return offset; +int encode_myLPL(unsigned char *buf, struct myLPL *myLPL) { + int offset = 0; + + offset += ENCODE_CTYPE_VISSTRING255(&buf[offset], &myLPL->ldNs); + offset += ENCODE_CTYPE_VISSTRING255(&buf[offset], &myLPL->configRev); + + return offset; } -int encode_myDPL(unsigned char *buf, struct myDPL *myDPL) { - int offset = 0; - - offset += ENCODE_CTYPE_VISSTRING255(&buf[offset], &myDPL->vendor); - offset += ENCODE_CTYPE_VISSTRING255(&buf[offset], &myDPL->hwRev); - - return offset; +int encode_myDPL(unsigned char *buf, struct myDPL *myDPL) { + int offset = 0; + + offset += ENCODE_CTYPE_VISSTRING255(&buf[offset], &myDPL->vendor); + offset += ENCODE_CTYPE_VISSTRING255(&buf[offset], &myDPL->hwRev); + + return offset; } -int encode_myPos(unsigned char *buf, struct myPos *myPos) { - int offset = 0; - - offset += ENCODE_CTYPE_DBPOS(&buf[offset], &myPos->stVal); - offset += ENCODE_CTYPE_QUALITY(&buf[offset], &myPos->q); - offset += ENCODE_CTYPE_TIMESTAMP(&buf[offset], &myPos->t); - offset += ENCODE_CTYPE_BOOLEAN(&buf[offset], &myPos->ctlVal); - - return offset; +int encode_myPos(unsigned char *buf, struct myPos *myPos) { + int offset = 0; + + offset += ENCODE_CTYPE_DBPOS(&buf[offset], &myPos->stVal); + offset += ENCODE_CTYPE_QUALITY(&buf[offset], &myPos->q); + offset += ENCODE_CTYPE_TIMESTAMP(&buf[offset], &myPos->t); + offset += ENCODE_CTYPE_BOOLEAN(&buf[offset], &myPos->ctlVal); + + return offset; } -int encode_mySPS(unsigned char *buf, struct mySPS *mySPS) { - int offset = 0; - - offset += ENCODE_CTYPE_INT32(&buf[offset], &mySPS->stVal); - offset += ENCODE_CTYPE_QUALITY(&buf[offset], &mySPS->q); - offset += ENCODE_CTYPE_TIMESTAMP(&buf[offset], &mySPS->t); - - return offset; +int encode_mySPS(unsigned char *buf, struct mySPS *mySPS) { + int offset = 0; + + offset += ENCODE_CTYPE_INT32(&buf[offset], &mySPS->stVal); + offset += ENCODE_CTYPE_QUALITY(&buf[offset], &mySPS->q); + offset += ENCODE_CTYPE_TIMESTAMP(&buf[offset], &mySPS->t); + + return offset; } -int encode_myMV(unsigned char *buf, struct myMV *myMV) { - int offset = 0; - - offset += encode_myAnalogValue(&buf[offset], &myMV->mag); - offset += ENCODE_CTYPE_QUALITY(&buf[offset], &myMV->q); - offset += ENCODE_CTYPE_TIMESTAMP(&buf[offset], &myMV->t); - offset += encode_ScaledValueConfig(&buf[offset], &myMV->sVC); - - return offset; +int encode_myMV(unsigned char *buf, struct myMV *myMV) { + int offset = 0; + + offset += encode_myAnalogValue(&buf[offset], &myMV->mag); + offset += ENCODE_CTYPE_QUALITY(&buf[offset], &myMV->q); + offset += ENCODE_CTYPE_TIMESTAMP(&buf[offset], &myMV->t); + offset += encode_ScaledValueConfig(&buf[offset], &myMV->sVC); + + return offset; } -int encode_simpleMV(unsigned char *buf, struct simpleMV *simpleMV) { - int offset = 0; - - offset += ENCODE_CTYPE_FLOAT32(&buf[offset], &simpleMV->mag); - offset += ENCODE_CTYPE_QUALITY(&buf[offset], &simpleMV->q); - offset += ENCODE_CTYPE_TIMESTAMP(&buf[offset], &simpleMV->t); - offset += encode_ScaledValueConfig(&buf[offset], &simpleMV->sVC); - - return offset; +int encode_simpleMV(unsigned char *buf, struct simpleMV *simpleMV) { + int offset = 0; + + offset += ENCODE_CTYPE_FLOAT32(&buf[offset], &simpleMV->mag); + offset += ENCODE_CTYPE_QUALITY(&buf[offset], &simpleMV->q); + offset += ENCODE_CTYPE_TIMESTAMP(&buf[offset], &simpleMV->t); + offset += encode_ScaledValueConfig(&buf[offset], &simpleMV->sVC); + + return offset; } -int encode_simpleCMV(unsigned char *buf, struct simpleCMV *simpleCMV) { - int offset = 0; - - offset += encode_simpleVector(&buf[offset], &simpleCMV->cVal); - offset += ENCODE_CTYPE_QUALITY(&buf[offset], &simpleCMV->q); - offset += ENCODE_CTYPE_TIMESTAMP(&buf[offset], &simpleCMV->t); - - return offset; +int encode_simpleCMV(unsigned char *buf, struct simpleCMV *simpleCMV) { + int offset = 0; + + offset += encode_simpleVector(&buf[offset], &simpleCMV->cVal); + offset += ENCODE_CTYPE_QUALITY(&buf[offset], &simpleCMV->q); + offset += ENCODE_CTYPE_TIMESTAMP(&buf[offset], &simpleCMV->t); + + return offset; } -int encode_simpleWYE(unsigned char *buf, struct simpleWYE *simpleWYE) { - int offset = 0; - - offset += encode_simpleCMV(&buf[offset], &simpleWYE->phsA); - offset += encode_simpleCMV(&buf[offset], &simpleWYE->phsB); - offset += encode_simpleCMV(&buf[offset], &simpleWYE->phsC); - - return offset; +int encode_simpleWYE(unsigned char *buf, struct simpleWYE *simpleWYE) { + int offset = 0; + + offset += encode_simpleCMV(&buf[offset], &simpleWYE->phsA); + offset += encode_simpleCMV(&buf[offset], &simpleWYE->phsB); + offset += encode_simpleCMV(&buf[offset], &simpleWYE->phsC); + + return offset; } -int encode_myCMV(unsigned char *buf, struct myCMV *myCMV) { - int offset = 0; - - offset += encode_myVector(&buf[offset], &myCMV->cVal); - offset += ENCODE_CTYPE_QUALITY(&buf[offset], &myCMV->q); - offset += ENCODE_CTYPE_TIMESTAMP(&buf[offset], &myCMV->t); - - return offset; +int encode_myCMV(unsigned char *buf, struct myCMV *myCMV) { + int offset = 0; + + offset += encode_myVector(&buf[offset], &myCMV->cVal); + offset += ENCODE_CTYPE_QUALITY(&buf[offset], &myCMV->q); + offset += ENCODE_CTYPE_TIMESTAMP(&buf[offset], &myCMV->t); + + return offset; } -int encode_mySEQ(unsigned char *buf, struct mySEQ *mySEQ) { - int offset = 0; - - offset += encode_myCMV(&buf[offset], &mySEQ->c1); - offset += encode_myCMV(&buf[offset], &mySEQ->c2); - offset += encode_myCMV(&buf[offset], &mySEQ->c3); - offset += ENCODE_CTYPE_ENUM(&buf[offset], (CTYPE_ENUM *) &mySEQ->seqT); - - return offset; +int encode_mySEQ(unsigned char *buf, struct mySEQ *mySEQ) { + int offset = 0; + + offset += encode_myCMV(&buf[offset], &mySEQ->c1); + offset += encode_myCMV(&buf[offset], &mySEQ->c2); + offset += encode_myCMV(&buf[offset], &mySEQ->c3); + offset += ENCODE_CTYPE_ENUM(&buf[offset], (CTYPE_ENUM *) &mySEQ->seqT); + + return offset; } -int encode_mySAV(unsigned char *buf, struct mySAV *mySAV) { - int offset = 0; - - offset += encode_myAnalogValue(&buf[offset], &mySAV->instMag); - offset += ENCODE_CTYPE_QUALITY(&buf[offset], &mySAV->q); - - return offset; +int encode_mySAV(unsigned char *buf, struct mySAV *mySAV) { + int offset = 0; + + offset += encode_myAnalogValue(&buf[offset], &mySAV->instMag); + offset += ENCODE_CTYPE_QUALITY(&buf[offset], &mySAV->q); + + return offset; } -int encode_simpleSAV(unsigned char *buf, struct simpleSAV *simpleSAV) { - int offset = 0; - - offset += encode_myAnalogValue(&buf[offset], &simpleSAV->instMag); - offset += ENCODE_CTYPE_QUALITY(&buf[offset], &simpleSAV->q); - - return offset; +int encode_simpleSAV(unsigned char *buf, struct simpleSAV *simpleSAV) { + int offset = 0; + + offset += encode_myAnalogValue(&buf[offset], &simpleSAV->instMag); + offset += ENCODE_CTYPE_QUALITY(&buf[offset], &simpleSAV->q); + + return offset; } -int encode_11(unsigned char *buf) { - int offset = 0; - - offset += encode_myAnalogValue(&buf[offset], &E1Q1SB1.S1.C1.TVTR_1.Vol.instMag); - offset += encode_myMod(&buf[offset], &E1Q1SB1.S1.C1.CSWI_1.Mod); - offset += ENCODE_CTYPE_ENUM(&buf[offset], (CTYPE_ENUM *) &E1Q1SB1.S1.C1.MMXU_1.Mod.stVal); - offset += ENCODE_CTYPE_QUALITY(&buf[offset], &E1Q1SB1.S1.C1.MMXU_1.Volts.q); - offset += encode_myMV(&buf[offset], &E1Q1SB1.S1.C1.MMXU_1.Amps); - offset += encode_myPos(&buf[offset], &E1Q1SB1.S1.C1.CSWI_2.Pos); - - return offset; +int encode_11(unsigned char *buf) { + int offset = 0; + + offset += encode_myAnalogValue(&buf[offset], &E1Q1SB1.S1.C1.TVTR_1.Vol.instMag); + offset += encode_myMod(&buf[offset], &E1Q1SB1.S1.C1.CSWI_1.Mod); + offset += ENCODE_CTYPE_ENUM(&buf[offset], (CTYPE_ENUM *) &E1Q1SB1.S1.C1.MMXU_1.Mod.stVal); + offset += ENCODE_CTYPE_QUALITY(&buf[offset], &E1Q1SB1.S1.C1.MMXU_1.Volts.q); + offset += encode_myMV(&buf[offset], &E1Q1SB1.S1.C1.MMXU_1.Amps); + offset += encode_myPos(&buf[offset], &E1Q1SB1.S1.C1.CSWI_2.Pos); + + return offset; } -int encode_rmxu(unsigned char *buf) { - int offset = 0; - - offset += encode_simpleSAV(&buf[offset], &E1Q1SB1.S1.C1.RMXU_1.AmpLocPhsA); - offset += encode_simpleSAV(&buf[offset], &E1Q1SB1.S1.C1.RMXU_1.AmpLocPhsB); - offset += encode_simpleSAV(&buf[offset], &E1Q1SB1.S1.C1.RMXU_1.AmpLocPhsC); - - return offset; +int encode_rmxu(unsigned char *buf) { + int offset = 0; + + offset += encode_simpleSAV(&buf[offset], &E1Q1SB1.S1.C1.RMXU_1.AmpLocPhsA); + offset += encode_simpleSAV(&buf[offset], &E1Q1SB1.S1.C1.RMXU_1.AmpLocPhsB); + offset += encode_simpleSAV(&buf[offset], &E1Q1SB1.S1.C1.RMXU_1.AmpLocPhsC); + + return offset; }
diff -r 230c10b228ea -r 9399d44c2b1a svEncode.h --- a/svEncode.h Fri Oct 07 13:41:08 2011 +0000 +++ b/svEncode.h Fri Oct 07 13:48:18 2011 +0000 @@ -1,3 +1,23 @@ +/** + * Rapid-prototyping protection schemes with IEC 61850 + * + * Copyright (c) 2011 Steven Blair + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + #ifndef SV_ENCODE_H #define SV_ENCODE_H @@ -5,18 +25,18 @@ extern "C" { #endif -#include "svEncodeBasic.h" +#include "svEncodeBasic.h" #include "svPacketData.h" -int encode_11(unsigned char *buf); -int encode_rmxu(unsigned char *buf); - +int encode_11(unsigned char *buf); +int encode_rmxu(unsigned char *buf); + int svEncodePacket(struct svData *svData, unsigned char *buf); -extern struct svData Volt_11; -extern struct svData rmxuCB_rmxu; +extern struct svData Volt_11; +extern struct svData rmxuCB_rmxu; #ifdef __cplusplus /* If this is a C++ compiler, end C linkage */
diff -r 230c10b228ea -r 9399d44c2b1a svEncodeBasic.c --- a/svEncodeBasic.c Fri Oct 07 13:41:08 2011 +0000 +++ b/svEncodeBasic.c Fri Oct 07 13:48:18 2011 +0000 @@ -1,3 +1,23 @@ +/** + * Rapid-prototyping protection schemes with IEC 61850 + * + * Copyright (c) 2011 Steven Blair + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + #include "ctypes.h" #include "datatypes.h" #include "ied.h" @@ -5,62 +25,62 @@ // SV encoding of basic types int ENCODE_CTYPE_FLOAT32(unsigned char *buf, CTYPE_FLOAT32 *value) { - netmemcpy(buf, value, SV_GET_LENGTH_FLOAT32); + netmemcpy(buf, value, SV_GET_LENGTH_FLOAT32); - return SV_GET_LENGTH_FLOAT32; + return SV_GET_LENGTH_FLOAT32; } int ENCODE_CTYPE_FLOAT64(unsigned char *buf, CTYPE_FLOAT64 *value) { - netmemcpy(buf, value, SV_GET_LENGTH_FLOAT64); + netmemcpy(buf, value, SV_GET_LENGTH_FLOAT64); - return SV_GET_LENGTH_FLOAT64; + return SV_GET_LENGTH_FLOAT64; } int ENCODE_CTYPE_QUALITY(unsigned char *buf, CTYPE_QUALITY *value) { - netmemcpy(buf, value, SV_GET_LENGTH_QUALITY); + netmemcpy(buf, value, SV_GET_LENGTH_QUALITY); - return SV_GET_LENGTH_QUALITY; + return SV_GET_LENGTH_QUALITY; } int ENCODE_CTYPE_TIMESTAMP(unsigned char *buf, CTYPE_TIMESTAMP *value) { - netmemcpy(buf, value, SV_GET_LENGTH_TIMESTAMP); + netmemcpy(buf, value, SV_GET_LENGTH_TIMESTAMP); - return SV_GET_LENGTH_TIMESTAMP; + return SV_GET_LENGTH_TIMESTAMP; } -int ENCODE_CTYPE_ENUM(unsigned char *buf, CTYPE_ENUM *value) { // assuming enum is an int - allows any enum type to be used - netmemcpy(buf, value, SV_GET_LENGTH_ENUM); +int ENCODE_CTYPE_ENUM(unsigned char *buf, CTYPE_ENUM *value) { // assuming enum is an int - allows any enum type to be used + netmemcpy(buf, value, SV_GET_LENGTH_ENUM); - return SV_GET_LENGTH_ENUM; + return SV_GET_LENGTH_ENUM; } int ENCODE_CTYPE_INT16(unsigned char *buf, CTYPE_INT16 *value) { - netmemcpy(buf, value, SV_GET_LENGTH_INT16); + netmemcpy(buf, value, SV_GET_LENGTH_INT16); - return SV_GET_LENGTH_INT16; + return SV_GET_LENGTH_INT16; } int ENCODE_CTYPE_INT32(unsigned char *buf, CTYPE_INT32 *value) { - netmemcpy(buf, value, SV_GET_LENGTH_INT32); + netmemcpy(buf, value, SV_GET_LENGTH_INT32); - return SV_GET_LENGTH_INT32; + return SV_GET_LENGTH_INT32; } int ENCODE_CTYPE_INT16U(unsigned char *buf, CTYPE_INT16U *value) { - netmemcpy(buf, value, SV_GET_LENGTH_INT16U); + netmemcpy(buf, value, SV_GET_LENGTH_INT16U); - return SV_GET_LENGTH_INT16U; + return SV_GET_LENGTH_INT16U; } int ENCODE_CTYPE_INT32U(unsigned char *buf, CTYPE_INT32U *value) { - netmemcpy(buf, value, SV_GET_LENGTH_INT32U); + netmemcpy(buf, value, SV_GET_LENGTH_INT32U); - return SV_GET_LENGTH_INT32U; + return SV_GET_LENGTH_INT32U; } int ENCODE_CTYPE_VISSTRING255(unsigned char *buf, CTYPE_VISSTRING255 *value) { - netmemcpy(buf, value, SV_GET_LENGTH_VISSTRING255); + netmemcpy(buf, value, SV_GET_LENGTH_VISSTRING255); - return SV_GET_LENGTH_VISSTRING255; + return SV_GET_LENGTH_VISSTRING255; } int ENCODE_CTYPE_BOOLEAN(unsigned char *buf, CTYPE_BOOLEAN *value) { - netmemcpy(buf, value, SV_GET_LENGTH_BOOLEAN); + netmemcpy(buf, value, SV_GET_LENGTH_BOOLEAN); - return SV_GET_LENGTH_BOOLEAN; + return SV_GET_LENGTH_BOOLEAN; } int ENCODE_CTYPE_DBPOS(unsigned char *buf, CTYPE_DBPOS *value) { - netmemcpy(buf, value, SV_GET_LENGTH_DBPOS); + netmemcpy(buf, value, SV_GET_LENGTH_DBPOS); - return SV_GET_LENGTH_DBPOS; + return SV_GET_LENGTH_DBPOS; }
diff -r 230c10b228ea -r 9399d44c2b1a svEncodeBasic.h --- a/svEncodeBasic.h Fri Oct 07 13:41:08 2011 +0000 +++ b/svEncodeBasic.h Fri Oct 07 13:48:18 2011 +0000 @@ -1,3 +1,23 @@ +/** + * Rapid-prototyping protection schemes with IEC 61850 + * + * Copyright (c) 2011 Steven Blair + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + #ifndef SV_ENCODE_BASIC_H #define SV_ENCODE_BASIC_H
diff -r 230c10b228ea -r 9399d44c2b1a svEncodePacket.c --- a/svEncodePacket.c Fri Oct 07 13:41:08 2011 +0000 +++ b/svEncodePacket.c Fri Oct 07 13:48:18 2011 +0000 @@ -1,3 +1,23 @@ +/** + * Rapid-prototyping protection schemes with IEC 61850 + * + * Copyright (c) 2011 Steven Blair + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + #include "svPacketData.h" #include "svEncode.h" #include "gseEncode.h" @@ -5,132 +25,132 @@ int svASDULength(struct svData *svData) { - int len = 0; + int len = 0; - len += strlen((const char *) svData->ASDU[0].svID) + 2; - //printf("%i, %s\n", strlen(svData->ASDU[0].svID), svData->ASDU[0].svID); - //len += strlen((const char *) svData->ASDU[0].datset) + 2; - len += BER_GET_LENGTH_CTYPE_INT16U(&svData->ASDU[0].smpCnt) + 2; - len += BER_GET_LENGTH_CTYPE_INT32U(&svData->ASDU[0].confRev) + 2; - len += SV_GET_LENGTH_BOOLEAN + 2; - //len += BER_GET_LENGTH_CTYPE_INT16U(&svData->ASDU[0].smpRate) + 2; - len += svData->ASDU[0].data.size + getLengthBytes(svData->ASDU[0].data.size); - len++; + len += strlen((const char *) svData->ASDU[0].svID) + 2; + //printf("%i, %s\n", strlen(svData->ASDU[0].svID), svData->ASDU[0].svID); + //len += strlen((const char *) svData->ASDU[0].datset) + 2; + len += BER_GET_LENGTH_CTYPE_INT16U(&svData->ASDU[0].smpCnt) + 2; + len += BER_GET_LENGTH_CTYPE_INT32U(&svData->ASDU[0].confRev) + 2; + len += SV_GET_LENGTH_BOOLEAN + 2; + //len += BER_GET_LENGTH_CTYPE_INT16U(&svData->ASDU[0].smpRate) + 2; + len += svData->ASDU[0].data.size + getLengthBytes(svData->ASDU[0].data.size); + len++; - return len; + return len; } int svSeqLength(struct svData *svData) { - int len = svASDULength(svData); - len += getLengthBytes(len); - len++; - len = len * svData->noASDU; // assume all ASDUs are the same size + int len = svASDULength(svData); + len += getLengthBytes(len); + len++; + len = len * svData->noASDU; // assume all ASDUs are the same size - return len; + return len; } int svAPDULength(struct svData *svData) { - int len = svSeqLength(svData); - len += getLengthBytes(len); - len++; + int len = svSeqLength(svData); + len += getLengthBytes(len); + len++; - len += 3; + len += 3; - return len; + return len; } //TODO: convert to proper BER sizes // creates an SV packet, including frame header. returns 0 on fail; number of bytes on success int svEncodePacket(struct svData *svData, unsigned char *buf) { - int offset = 0; - int len = svAPDULength(svData); - len += getLengthBytes(len); - len += 9; // savPdu tag size (1 byte), plus 8 "header" bytes + int offset = 0; + int len = svAPDULength(svData); + len += getLengthBytes(len); + len += 9; // savPdu tag size (1 byte), plus 8 "header" bytes - // frame header - memcpy(&buf[offset], svData->ethHeaderData.destMACAddress, 6); // destination MAC addresses - offset += 6; - memcpy(&buf[offset], LOCAL_MAC_ADDRESS, 6); // source MAC addresses - offset += 6; + // frame header + memcpy(&buf[offset], svData->ethHeaderData.destMACAddress, 6); // destination MAC addresses + offset += 6; + memcpy(&buf[offset], LOCAL_MAC_ADDRESS, 6); // source MAC addresses + offset += 6; - buf[offset++] = 0x81; // TPID - buf[offset++] = 0x00; + buf[offset++] = 0x81; // TPID + buf[offset++] = 0x00; - netmemcpy(&buf[offset], &svData->ethHeaderData.VLAN_ID, 2); // TCI - buf[offset] |= (svData->ethHeaderData.VLAN_PRIORITY << 5); - offset += 2; + netmemcpy(&buf[offset], &svData->ethHeaderData.VLAN_ID, 2); // TCI + buf[offset] |= (svData->ethHeaderData.VLAN_PRIORITY << 5); + offset += 2; - buf[offset++] = 0x88; // EtherType - buf[offset++] = 0xBA; + buf[offset++] = 0x88; // EtherType + buf[offset++] = 0xBA; - netmemcpy(&buf[offset], &svData->ethHeaderData.APPID, 2); // APPID - offset += 2; + netmemcpy(&buf[offset], &svData->ethHeaderData.APPID, 2); // APPID + offset += 2; - netmemcpy(&buf[offset], &len, 2); // length - offset += 2; + netmemcpy(&buf[offset], &len, 2); // length + offset += 2; - buf[offset++] = 0x00; // reserved 1 - buf[offset++] = 0x00; - buf[offset++] = 0x00; // reserved 2 - buf[offset++] = 0x00; + buf[offset++] = 0x00; // reserved 1 + buf[offset++] = 0x00; + buf[offset++] = 0x00; // reserved 2 + buf[offset++] = 0x00; - buf[offset++] = 0x60; - offset += encodeLength(&buf[offset], svAPDULength(svData)); + buf[offset++] = 0x60; + offset += encodeLength(&buf[offset], svAPDULength(svData)); - //TODO noASDU may be > 126? - buf[offset++] = 0x80; - buf[offset++] = 1; - buf[offset++] = (unsigned char) svData->noASDU; + //TODO noASDU may be > 126? + buf[offset++] = 0x80; + buf[offset++] = 1; + buf[offset++] = (unsigned char) svData->noASDU; - buf[offset++] = 0xA2; - offset += encodeLength(&buf[offset], svSeqLength(svData)); + buf[offset++] = 0xA2; + offset += encodeLength(&buf[offset], svSeqLength(svData)); - int i = 0; - int size = 0; - for (i = 0; i < svData->noASDU; i++) { - buf[offset++] = 0x30; - offset += encodeLength(&buf[offset], svASDULength(svData)); + int i = 0; + int size = 0; + for (i = 0; i < svData->noASDU; i++) { + buf[offset++] = 0x30; + offset += encodeLength(&buf[offset], svASDULength(svData)); - size = strlen((const char *) svData->ASDU[i].svID); - buf[offset++] = 0x80; - buf[offset++] = size; - memcpy(&buf[offset], svData->ASDU[i].svID, size); - offset += size; + size = strlen((const char *) svData->ASDU[i].svID); + buf[offset++] = 0x80; + buf[offset++] = size; + memcpy(&buf[offset], svData->ASDU[i].svID, size); + offset += size; - /*size = strlen(svData->ASDU[i].datset); - buf[offset++] = 0x81; - buf[offset++] = size; - memcpy(&buf[offset], svData->ASDU[i].datset, size); - offset += size;*/ + /*size = strlen(svData->ASDU[i].datset); + buf[offset++] = 0x81; + buf[offset++] = size; + memcpy(&buf[offset], svData->ASDU[i].datset, size); + offset += size;*/ - buf[offset++] = 0x82; - offset += encodeLength(&buf[offset], BER_GET_LENGTH_CTYPE_INT16U(&svData->ASDU[i].smpCnt)); - offset += ber_encode_integer(&buf[offset], &svData->ASDU[i].smpCnt, SV_GET_LENGTH_INT16U); - //buf[offset++] = BER_GET_LENGTH_CTYPE_INT16U(&svData->ASDU[i].smpCnt); - //offset += BER_ENCODE_CTYPE_INT16U(&buf[offset], &svData->ASDU[i].smpCnt); + buf[offset++] = 0x82; + offset += encodeLength(&buf[offset], BER_GET_LENGTH_CTYPE_INT16U(&svData->ASDU[i].smpCnt)); + offset += ber_encode_integer(&buf[offset], &svData->ASDU[i].smpCnt, SV_GET_LENGTH_INT16U); + //buf[offset++] = BER_GET_LENGTH_CTYPE_INT16U(&svData->ASDU[i].smpCnt); + //offset += BER_ENCODE_CTYPE_INT16U(&buf[offset], &svData->ASDU[i].smpCnt); - buf[offset++] = 0x83; - offset += encodeLength(&buf[offset], BER_GET_LENGTH_CTYPE_INT32U(&svData->ASDU[i].confRev)); - offset += ber_encode_integer(&buf[offset], &svData->ASDU[i].confRev, SV_GET_LENGTH_INT32U); - //buf[offset++] = BER_GET_LENGTH_CTYPE_INT32U(&svData->ASDU[i].confRev); - //offset += BER_ENCODE_CTYPE_INT32U(&buf[offset], &svData->ASDU[i].confRev); + buf[offset++] = 0x83; + offset += encodeLength(&buf[offset], BER_GET_LENGTH_CTYPE_INT32U(&svData->ASDU[i].confRev)); + offset += ber_encode_integer(&buf[offset], &svData->ASDU[i].confRev, SV_GET_LENGTH_INT32U); + //buf[offset++] = BER_GET_LENGTH_CTYPE_INT32U(&svData->ASDU[i].confRev); + //offset += BER_ENCODE_CTYPE_INT32U(&buf[offset], &svData->ASDU[i].confRev); - buf[offset++] = 0x85; - buf[offset++] = SV_GET_LENGTH_BOOLEAN; - offset += ENCODE_CTYPE_BOOLEAN(&buf[offset], &svData->ASDU[i].smpSynch); + buf[offset++] = 0x85; + buf[offset++] = SV_GET_LENGTH_BOOLEAN; + offset += ENCODE_CTYPE_BOOLEAN(&buf[offset], &svData->ASDU[i].smpSynch); - /*buf[offset++] = 0x86; - buf[offset++] = SV_GET_LENGTH_INT16U; - offset += ENCODE_CTYPE_INT16U(&buf[offset], &svData->ASDU[i].smpRate);*/ + /*buf[offset++] = 0x86; + buf[offset++] = SV_GET_LENGTH_INT16U; + offset += ENCODE_CTYPE_INT16U(&buf[offset], &svData->ASDU[i].smpRate);*/ - buf[offset++] = 0x87; - offset += encodeLength(&buf[offset], svData->ASDU[i].data.size); - memcpy(&buf[offset], svData->ASDU[i].data.data, svData->ASDU[i].data.size); - offset += svData->ASDU[i].data.size; - } + buf[offset++] = 0x87; + offset += encodeLength(&buf[offset], svData->ASDU[i].data.size); + memcpy(&buf[offset], svData->ASDU[i].data.data, svData->ASDU[i].data.size); + offset += svData->ASDU[i].data.size; + } - // assume network interface, such as WinPcap, generates CRC bytes + // assume network interface, such as WinPcap, generates CRC bytes - return offset; + return offset; }
diff -r 230c10b228ea -r 9399d44c2b1a svPacketData.h --- a/svPacketData.h Fri Oct 07 13:41:08 2011 +0000 +++ b/svPacketData.h Fri Oct 07 13:48:18 2011 +0000 @@ -1,3 +1,23 @@ +/** + * Rapid-prototyping protection schemes with IEC 61850 + * + * Copyright (c) 2011 Steven Blair + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + #ifndef SV_PACKET_DATA_H #define SV_PACKET_DATA_H