An mbed implementation of IEC 61850-9-2LE Sample Values. Creating using the rapid61850 library, available at: https://github.com/stevenblair/rapid61850.
gseEncodeBasic.c
00001 /** 00002 * Rapid-prototyping protection schemes with IEC 61850 00003 * 00004 * Copyright (c) 2012 Steven Blair 00005 * 00006 * This program is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU General Public License 00008 * as published by the Free Software Foundation; either version 2 00009 * of the License, or (at your option) any later version. 00010 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software 00018 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00019 */ 00020 00021 #ifndef GSE_BER_ENCODE_BASIC_C 00022 #define GSE_BER_ENCODE_BASIC_C 00023 00024 #include "ctypes.h" 00025 #include "datatypes.h" 00026 #include "ied.h" 00027 #include "gseEncodeBasic.h" 00028 00029 // BER encoding of basic types 00030 int BER_ENCODE_CTYPE_FLOAT32(unsigned char *buf, CTYPE_FLOAT32 *value) { 00031 CTYPE_INT16U offset = 0; 00032 CTYPE_INT16U len = BER_GET_LENGTH_CTYPE_FLOAT32(value); 00033 00034 buf[offset++] = ASN1_TAG_FLOATING_POINT; 00035 offset += encodeLength(&buf[offset], len); 00036 00037 buf[offset++] = 0x08; // bits for exponent 00038 netmemcpy(&buf[offset], value, len - 1); 00039 00040 return offset + len - 1; 00041 } 00042 int BER_ENCODE_CTYPE_FLOAT64(unsigned char *buf, CTYPE_FLOAT64 *value) { 00043 CTYPE_INT16U offset = 0; 00044 CTYPE_INT16U len = BER_GET_LENGTH_CTYPE_FLOAT64(value); 00045 00046 buf[offset++] = ASN1_TAG_FLOATING_POINT; 00047 offset += encodeLength(&buf[offset], len); 00048 00049 buf[offset++] = 0x0B; // bits for exponent 00050 netmemcpy(&buf[offset], value, len - 1); 00051 00052 return offset + len - 1; 00053 } 00054 00055 int BER_ENCODE_CTYPE_QUALITY(unsigned char *buf, CTYPE_QUALITY *value) { 00056 CTYPE_INT16U offset = 0; 00057 CTYPE_INT16U len = BER_GET_LENGTH_CTYPE_QUALITY(value); 00058 00059 buf[offset++] = ASN1_TAG_BIT_STRING; 00060 offset += encodeLength(&buf[offset], len); 00061 00062 buf[offset++] = QUALITY_UNUSED_BITS; // number of unused bits 00063 netmemcpy(&buf[offset], value, len - 1); 00064 00065 return offset + len - 1; 00066 } 00067 int BER_ENCODE_CTYPE_TIMESTAMP(unsigned char *buf, CTYPE_TIMESTAMP *value) { 00068 CTYPE_INT16U offset = 0; 00069 CTYPE_INT16U len = BER_GET_LENGTH_CTYPE_TIMESTAMP(value); 00070 00071 buf[offset++] = ASN1_TAG_OCTET_STRING; 00072 offset += encodeLength(&buf[offset], len); 00073 00074 memcpy(&buf[offset], value, len); 00075 00076 return offset + len; 00077 } 00078 int BER_ENCODE_CTYPE_ENUM(unsigned char *buf, CTYPE_ENUM *value) { 00079 CTYPE_INT16U offset = 0; 00080 CTYPE_INT16U len = BER_GET_LENGTH_CTYPE_ENUM(value); 00081 00082 buf[offset++] = ASN1_TAG_INTEGER; 00083 offset += encodeLength(&buf[offset], len); 00084 00085 #if GOOSE_FIXED_SIZE == 1 00086 ber_encode_integer_fixed_size(&buf[offset], value, SV_GET_LENGTH_INT8); 00087 #else 00088 ber_encode_integer(&buf[offset], value, SV_GET_LENGTH_INT32U); // assuming enum is an int - allows any enum type to be used 00089 #endif 00090 00091 return offset + len; 00092 } 00093 int BER_ENCODE_CTYPE_INT8(unsigned char *buf, CTYPE_INT8 *value) { 00094 CTYPE_INT16U offset = 0; 00095 CTYPE_INT16U len = BER_GET_LENGTH_CTYPE_INT8(value); 00096 00097 buf[offset++] = ASN1_TAG_INTEGER; 00098 offset += encodeLength(&buf[offset], len); 00099 00100 #if GOOSE_FIXED_SIZE == 1 00101 ber_encode_integer_fixed_size(&buf[offset], value, SV_GET_LENGTH_INT8); 00102 #else 00103 ber_encode_integer(&buf[offset], value, SV_GET_LENGTH_INT8); 00104 #endif 00105 00106 return offset + len; 00107 } 00108 int BER_ENCODE_CTYPE_INT16(unsigned char *buf, CTYPE_INT16 *value) { 00109 CTYPE_INT16U offset = 0; 00110 CTYPE_INT16U len = BER_GET_LENGTH_CTYPE_INT16(value); 00111 00112 buf[offset++] = ASN1_TAG_INTEGER; 00113 offset += encodeLength(&buf[offset], len); 00114 00115 #if GOOSE_FIXED_SIZE == 1 00116 ber_encode_integer_fixed_size(&buf[offset], value, SV_GET_LENGTH_INT16); 00117 #else 00118 ber_encode_integer(&buf[offset], value, SV_GET_LENGTH_INT16); 00119 #endif 00120 00121 return offset + len; 00122 } 00123 int BER_ENCODE_CTYPE_INT32(unsigned char *buf, CTYPE_INT32 *value) { 00124 CTYPE_INT16U offset = 0; 00125 CTYPE_INT16U len = BER_GET_LENGTH_CTYPE_INT32(value); 00126 00127 buf[offset++] = ASN1_TAG_INTEGER; 00128 offset += encodeLength(&buf[offset], len); 00129 00130 #if GOOSE_FIXED_SIZE == 1 00131 ber_encode_integer_fixed_size(&buf[offset], value, SV_GET_LENGTH_INT32); 00132 #else 00133 ber_encode_integer(&buf[offset], value, SV_GET_LENGTH_INT32); 00134 #endif 00135 00136 return offset + len; 00137 } 00138 int BER_ENCODE_CTYPE_INT16U(unsigned char *buf, CTYPE_INT16U *value) { 00139 CTYPE_INT16U offset = 0; 00140 CTYPE_INT16U len = BER_GET_LENGTH_CTYPE_INT16U(value); 00141 00142 buf[offset++] = ASN1_TAG_UNSIGNED; 00143 offset += encodeLength(&buf[offset], len); 00144 00145 #if GOOSE_FIXED_SIZE == 1 00146 ber_encode_integer_fixed_size(&buf[offset], value, SV_GET_LENGTH_INT16U); 00147 #else 00148 ber_encode_integer(&buf[offset], value, SV_GET_LENGTH_INT16U); 00149 #endif 00150 00151 return offset + len; 00152 } 00153 int BER_ENCODE_CTYPE_INT32U(unsigned char *buf, CTYPE_INT32U *value) { 00154 CTYPE_INT16U offset = 0; 00155 CTYPE_INT16U len = BER_GET_LENGTH_CTYPE_INT32U(value); 00156 00157 buf[offset++] = ASN1_TAG_UNSIGNED; 00158 offset += encodeLength(&buf[offset], len); 00159 00160 #if GOOSE_FIXED_SIZE == 1 00161 ber_encode_integer_fixed_size(&buf[offset], value, SV_GET_LENGTH_INT32U); 00162 #else 00163 ber_encode_integer(&buf[offset], value, SV_GET_LENGTH_INT32U); 00164 #endif 00165 00166 return offset + len; 00167 } 00168 int BER_ENCODE_CTYPE_VISSTRING255(unsigned char *buf, CTYPE_VISSTRING255 *value) { 00169 netmemcpy(buf, value, BER_GET_LENGTH_CTYPE_VISSTRING255(value)); 00170 00171 return BER_GET_LENGTH_CTYPE_VISSTRING255(value); 00172 } 00173 int BER_ENCODE_CTYPE_BOOLEAN(unsigned char *buf, CTYPE_BOOLEAN *value) { 00174 CTYPE_INT16U offset = 0; 00175 CTYPE_INT16U len = BER_GET_LENGTH_CTYPE_BOOLEAN(value); 00176 00177 buf[offset++] = ASN1_TAG_BOOLEAN; 00178 offset += encodeLength(&buf[offset], len); 00179 00180 netmemcpy(&buf[offset], value, len); 00181 00182 return offset + len; 00183 } 00184 int BER_ENCODE_CTYPE_DBPOS(unsigned char *buf, CTYPE_DBPOS *value) { 00185 CTYPE_INT16U offset = 0; 00186 CTYPE_INT16U len = BER_GET_LENGTH_CTYPE_DBPOS(value); 00187 00188 buf[offset++] = 0x85; 00189 offset += encodeLength(&buf[offset], len); 00190 00191 netmemcpy(&buf[offset], value, len); 00192 00193 return offset + len; 00194 } 00195 00196 #endif
Generated on Sat Jul 23 2022 01:15:10 by 1.7.2