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) 2011 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 8 bits for exponent 00037 if (buf[offset++] == 0x08) { 00038 netmemcpy(value, &buf[offset], len - 1); 00039 } 00040 } 00041 00042 return offset + len - 1; 00043 } 00044 00045 // GSE decoding of basic types 00046 int BER_DECODE_CTYPE_FLOAT64(unsigned char *buf, CTYPE_FLOAT64 *value) { 00047 CTYPE_INT16U offset = 0; 00048 CTYPE_INT16U len = 0; 00049 00050 if (buf[offset++] == 0x87) { 00051 len += decodeLength(&buf[offset]); 00052 offset += getLengthFieldSize(buf[offset]); 00053 00054 // check for 11 bits for exponent 00055 if (buf[offset++] == 0x0B) { 00056 netmemcpy(value, &buf[offset], len - 1); 00057 } 00058 } 00059 00060 return offset + len - 1; 00061 } 00062 int BER_DECODE_CTYPE_QUALITY(unsigned char *buf, CTYPE_QUALITY *value) { 00063 CTYPE_INT16U offset = 0; 00064 CTYPE_INT16U len = 0; 00065 00066 if (buf[offset++] == 0x85) { 00067 len += decodeLength(&buf[offset]); 00068 offset += getLengthFieldSize(buf[offset]); 00069 00070 netmemcpy(value, buf, len); //TODO check if memcpy should be used here, and elsewhere 00071 } 00072 00073 return offset + len; 00074 } 00075 int BER_DECODE_CTYPE_TIMESTAMP(unsigned char *buf, CTYPE_TIMESTAMP *value) { 00076 CTYPE_INT16U offset = 0; 00077 CTYPE_INT16U len = 0; 00078 00079 if (buf[offset++] == 0x89) { 00080 len += decodeLength(&buf[offset]); 00081 offset += getLengthFieldSize(buf[offset]); 00082 00083 netmemcpy(value, buf, len); 00084 } 00085 00086 return offset + len; 00087 } 00088 int BER_DECODE_CTYPE_ENUM(unsigned char *buf, CTYPE_ENUM *value) { // assuming enum is an int - allows any enum type to be used 00089 CTYPE_INT16U offset = 0; 00090 CTYPE_INT16U len = 0; 00091 00092 if (buf[offset++] == ASN1_TAG_UNSIGNED) { 00093 len += decodeLength(&buf[offset]); 00094 offset += getLengthFieldSize(buf[offset]); 00095 00096 ber_decode_integer(&buf[offset], len, value, SV_GET_LENGTH_INT32U); 00097 } 00098 00099 return offset + len; 00100 } 00101 int BER_DECODE_CTYPE_INT16(unsigned char *buf, CTYPE_INT16 *value) { 00102 CTYPE_INT16U offset = 0; 00103 CTYPE_INT16U len = 0; 00104 00105 if (buf[offset++] == ASN1_TAG_INTEGER) { 00106 len += decodeLength(&buf[offset]); 00107 offset += getLengthFieldSize(buf[offset]); 00108 00109 ber_decode_integer(&buf[offset], len, value, SV_GET_LENGTH_INT16); 00110 } 00111 00112 return offset + len; 00113 } 00114 int BER_DECODE_CTYPE_INT32(unsigned char *buf, CTYPE_INT32 *value) { 00115 CTYPE_INT16U offset = 0; 00116 CTYPE_INT16U len = 0; 00117 00118 if (buf[offset++] == ASN1_TAG_INTEGER) { 00119 len += decodeLength(&buf[offset]); 00120 offset += getLengthFieldSize(buf[offset]); 00121 00122 ber_decode_integer(&buf[offset], len, value, SV_GET_LENGTH_INT32); 00123 } 00124 00125 return offset + len; 00126 } 00127 int BER_DECODE_CTYPE_INT16U(unsigned char *buf, CTYPE_INT16U *value) { 00128 CTYPE_INT16U offset = 0; 00129 CTYPE_INT16U len = 0; 00130 00131 if (buf[offset++] == ASN1_TAG_UNSIGNED) { 00132 len += decodeLength(&buf[offset]); 00133 offset += getLengthFieldSize(buf[offset]); 00134 00135 ber_decode_integer(&buf[offset], len, value, SV_GET_LENGTH_INT16U); 00136 } 00137 00138 return offset + len; 00139 } 00140 int BER_DECODE_CTYPE_INT32U(unsigned char *buf, CTYPE_INT32U *value) { 00141 CTYPE_INT16U offset = 0; 00142 CTYPE_INT16U len = 0; 00143 00144 if (buf[offset++] == ASN1_TAG_UNSIGNED) { 00145 len += decodeLength(&buf[offset]); 00146 offset += getLengthFieldSize(buf[offset]); 00147 00148 ber_decode_integer(&buf[offset], len, value, SV_GET_LENGTH_INT32U); 00149 } 00150 00151 return offset + len; 00152 } 00153 int BER_DECODE_CTYPE_VISSTRING255(unsigned char *buf, CTYPE_VISSTRING255 *value) { 00154 netmemcpy(value, buf, SV_GET_LENGTH_VISSTRING255); 00155 00156 return SV_GET_LENGTH_VISSTRING255; 00157 } 00158 int BER_DECODE_CTYPE_BOOLEAN(unsigned char *buf, CTYPE_BOOLEAN *value) { 00159 CTYPE_INT16U offset = 0; 00160 CTYPE_INT16U len = 0; 00161 00162 if (buf[offset++] == ASN1_TAG_BOOLEAN) { 00163 len += decodeLength(&buf[offset]); 00164 offset += getLengthFieldSize(buf[offset]); 00165 00166 netmemcpy(value, buf, len); 00167 } 00168 00169 return offset + len; 00170 } 00171 int BER_DECODE_CTYPE_DBPOS(unsigned char *buf, CTYPE_DBPOS *value) { 00172 netmemcpy(value, buf, SV_GET_LENGTH_DBPOS); 00173 00174 return SV_GET_LENGTH_DBPOS; 00175 }
Generated on Mon Jul 18 2022 18:17:52 by
1.7.2