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/

ctypes.h

Committer:
sblair
Date:
2011-10-07
Revision:
1:9399d44c2b1a
Parent:
0:230c10b228ea

File content as of revision 1:9399d44c2b1a:

/**
 * 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

#ifdef __cplusplus /* If this is a C++ compiler, use C linkage */
extern "C" {
#endif

#include <string.h>

#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

// 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

// 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 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

int ber_integer_length(void *value, int maxLength);
int ber_encode_integer(unsigned char *bufDst, void *value, int maxLength);
void ber_decode_integer(unsigned char *buf, int length, void *value, int maxLength);

void reversememcpy(unsigned char *dst, const unsigned char *src, unsigned int len);
void netmemcpy(void *dst, const void *src, unsigned int len);
void hostmemcpy(void *dst, const void *src, unsigned int len);

void setTimestamp(CTYPE_TIMESTAMP *t);
void gse_sv_packet_filter(unsigned char *buf, int len);

struct UtcTime {
    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;
};

#ifdef __cplusplus /* If this is a C++ compiler, end C linkage */
}
#endif

#endif