Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
gseDecodeBasic.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 #include "ctypes.h" 00022 #include "datatypes.h" 00023 #include "ied.h" 00024 #include "gseDecodeBasic.h" 00025 #include <string.h> 00026 00027 // GSE decoding of basic types 00028 int BER_DECODE_CTYPE_FLOAT32(unsigned char *buf, CTYPE_FLOAT32 *value) { 00029 CTYPE_INT16U offset = 0; 00030 CTYPE_INT16U len = 0; 00031 00032 if (buf[offset++] == 0x87) { 00033 len += decodeLength(&buf[offset]); 00034 offset += getLengthFieldSize(buf[offset]); 00035 00036 // check for fixed-length GOOSE. If not, check for 8 bits for exponent 00037 if (len == 5 && buf[offset] == 0x08) { 00038 netmemcpy(value, &buf[offset + 1], len - 1); 00039 } 00040 else if (len == 4) { 00041 netmemcpy(value, &buf[offset], len); 00042 } 00043 } 00044 00045 return offset + len; 00046 } 00047 00048 int BER_DECODE_CTYPE_FLOAT64(unsigned char *buf, CTYPE_FLOAT64 *value) { 00049 CTYPE_INT16U offset = 0; 00050 CTYPE_INT16U len = 0; 00051 00052 if (buf[offset++] == 0x87) { 00053 len += decodeLength(&buf[offset]); 00054 offset += getLengthFieldSize(buf[offset]); 00055 00056 // check for fixed-length GOOSE. If not, check for 11 bits for exponent 00057 if (len == 9 && buf[offset] == 0x0B) { 00058 netmemcpy(value, &buf[offset + 1], len - 1); 00059 } 00060 else if (len == 8) { 00061 netmemcpy(value, &buf[offset], len); 00062 } 00063 } 00064 00065 return offset + len; 00066 } 00067 int BER_DECODE_CTYPE_QUALITY(unsigned char *buf, CTYPE_QUALITY *value) { 00068 CTYPE_INT16U offset = 0; 00069 CTYPE_INT16U len = 0; 00070 00071 if (buf[offset] == ASN1_TAG_BIT_STRING) { 00072 offset++; 00073 len += decodeLength(&buf[offset]); 00074 offset += getLengthFieldSize(buf[offset]); 00075 00076 netmemcpy(value, &buf[offset + 1], len - 1); // skip over one byte (which contains number of unused bits) 00077 } 00078 00079 return offset + len; 00080 } 00081 int BER_DECODE_CTYPE_TIMESTAMP(unsigned char *buf, CTYPE_TIMESTAMP *value) { 00082 CTYPE_INT16U offset = 0; 00083 CTYPE_INT16U len = 0; 00084 00085 if (buf[offset++] == 0x89) { 00086 len += decodeLength(&buf[offset]); 00087 offset += getLengthFieldSize(buf[offset]); 00088 00089 netmemcpy(value, &buf[offset], len); 00090 } 00091 00092 return offset + len; 00093 } 00094 int BER_DECODE_CTYPE_ENUM(unsigned char *buf, CTYPE_ENUM *value) { // assuming enum is an int - allows any enum type to be used 00095 CTYPE_INT16U offset = 0; 00096 CTYPE_INT16U len = 0; 00097 00098 if (buf[offset++] == ASN1_TAG_UNSIGNED) { 00099 len += decodeLength(&buf[offset]); 00100 offset += getLengthFieldSize(buf[offset]); 00101 00102 #if GOOSE_FIXED_SIZE == 1 00103 ber_decode_integer(&buf[offset], len, value, SV_GET_LENGTH_INT8); 00104 #else 00105 ber_decode_integer(&buf[offset], len, value, SV_GET_LENGTH_INT32U); 00106 #endif 00107 } 00108 00109 return offset + len; 00110 } 00111 int BER_DECODE_CTYPE_INT8(unsigned char *buf, CTYPE_INT8 *value) { 00112 CTYPE_INT16U offset = 0; 00113 CTYPE_INT16U len = 0; 00114 00115 if (buf[offset++] == ASN1_TAG_INTEGER) { 00116 len += decodeLength(&buf[offset]); 00117 offset += getLengthFieldSize(buf[offset]); 00118 00119 ber_decode_integer(&buf[offset], len, value, SV_GET_LENGTH_INT8); 00120 } 00121 00122 return offset + len; 00123 } 00124 int BER_DECODE_CTYPE_INT16(unsigned char *buf, CTYPE_INT16 *value) { 00125 CTYPE_INT16U offset = 0; 00126 CTYPE_INT16U len = 0; 00127 00128 if (buf[offset++] == ASN1_TAG_INTEGER) { 00129 len += decodeLength(&buf[offset]); 00130 offset += getLengthFieldSize(buf[offset]); 00131 00132 ber_decode_integer(&buf[offset], len, value, SV_GET_LENGTH_INT16); 00133 } 00134 00135 return offset + len; 00136 } 00137 int BER_DECODE_CTYPE_INT32(unsigned char *buf, CTYPE_INT32 *value) { 00138 CTYPE_INT16U offset = 0; 00139 CTYPE_INT16U len = 0; 00140 00141 if (buf[offset++] == ASN1_TAG_INTEGER) { 00142 len += decodeLength(&buf[offset]); 00143 offset += getLengthFieldSize(buf[offset]); 00144 00145 ber_decode_integer(&buf[offset], len, value, SV_GET_LENGTH_INT32); 00146 } 00147 00148 return offset + len; 00149 } 00150 int BER_DECODE_CTYPE_INT16U(unsigned char *buf, CTYPE_INT16U *value) { 00151 CTYPE_INT16U offset = 0; 00152 CTYPE_INT16U len = 0; 00153 00154 if (buf[offset++] == ASN1_TAG_UNSIGNED) { 00155 len += decodeLength(&buf[offset]); 00156 offset += getLengthFieldSize(buf[offset]); 00157 00158 ber_decode_integer(&buf[offset], len, value, SV_GET_LENGTH_INT16U); 00159 } 00160 00161 return offset + len; 00162 } 00163 int BER_DECODE_CTYPE_INT32U(unsigned char *buf, CTYPE_INT32U *value) { 00164 CTYPE_INT16U offset = 0; 00165 CTYPE_INT16U len = 0; 00166 00167 if (buf[offset++] == ASN1_TAG_UNSIGNED) { 00168 len += decodeLength(&buf[offset]); 00169 offset += getLengthFieldSize(buf[offset]); 00170 00171 ber_decode_integer(&buf[offset], len, value, SV_GET_LENGTH_INT32U); 00172 } 00173 00174 return offset + len; 00175 } 00176 int BER_DECODE_CTYPE_VISSTRING255(unsigned char *buf, CTYPE_VISSTRING255 *value) { 00177 netmemcpy(value, buf, SV_GET_LENGTH_VISSTRING255); 00178 00179 return SV_GET_LENGTH_VISSTRING255; 00180 } 00181 int BER_DECODE_CTYPE_BOOLEAN(unsigned char *buf, CTYPE_BOOLEAN *value) { 00182 CTYPE_INT16U offset = 0; 00183 CTYPE_INT16U len = 0; 00184 00185 if (buf[offset++] == ASN1_TAG_BOOLEAN) { 00186 len += decodeLength(&buf[offset]); 00187 offset += getLengthFieldSize(buf[offset]); 00188 00189 netmemcpy(value, &buf[offset], len); 00190 } 00191 00192 return offset + len; 00193 } 00194 int BER_DECODE_CTYPE_DBPOS(unsigned char *buf, CTYPE_DBPOS *value) { 00195 netmemcpy(value, buf, SV_GET_LENGTH_DBPOS); 00196 00197 return SV_GET_LENGTH_DBPOS; 00198 }
Generated on Sat Jul 23 2022 01:15:10 by
1.7.2