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.
gseEncodeBasic.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 #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 #include <stdlib.h> 00030 #include <stdio.h> 00031 00032 // BER encoding of basic types 00033 int BER_ENCODE_CTYPE_FLOAT32(unsigned char *buf, CTYPE_FLOAT32 *value) { 00034 CTYPE_INT16U offset = 0; 00035 CTYPE_INT16U len = BER_GET_LENGTH_CTYPE_FLOAT32(value); 00036 00037 buf[offset++] = ASN1_TAG_FLOATING_POINT; 00038 offset += encodeLength(&buf[offset], len); 00039 00040 buf[offset++] = 0x08; // bits for exponent 00041 netmemcpy(&buf[offset], value, len - 1); 00042 00043 return offset + len - 1; 00044 } 00045 int BER_ENCODE_CTYPE_FLOAT64(unsigned char *buf, CTYPE_FLOAT64 *value) { 00046 CTYPE_INT16U offset = 0; 00047 CTYPE_INT16U len = BER_GET_LENGTH_CTYPE_FLOAT64(value); 00048 00049 buf[offset++] = ASN1_TAG_FLOATING_POINT; 00050 offset += encodeLength(&buf[offset], len); 00051 00052 buf[offset++] = 0x0B; // bits for exponent 00053 netmemcpy(&buf[offset], value, len - 1); 00054 00055 return offset + len - 1; 00056 } 00057 int BER_ENCODE_CTYPE_QUALITY(unsigned char *buf, CTYPE_QUALITY *value) { 00058 CTYPE_INT16U offset = 0; 00059 CTYPE_INT16U len = BER_GET_LENGTH_CTYPE_QUALITY(value); 00060 00061 buf[offset++] = ASN1_TAG_BIT_STRING; 00062 offset += encodeLength(&buf[offset], len - 1); 00063 00064 buf[offset++] = QUALITY_UNUSED_BITS; // number of unused bits 00065 netmemcpy(&buf[offset], value, len - 1); 00066 00067 return offset + len - 1; 00068 } 00069 int BER_ENCODE_CTYPE_TIMESTAMP(unsigned char *buf, CTYPE_TIMESTAMP *value) { 00070 CTYPE_INT16U offset = 0; 00071 CTYPE_INT16U len = BER_GET_LENGTH_CTYPE_TIMESTAMP(value); 00072 00073 buf[offset++] = ASN1_TAG_OCTET_STRING; 00074 offset += encodeLength(&buf[offset], len); 00075 00076 memcpy(&buf[offset], value, len); //TODO should be memcpy, because already in big-endian? 00077 00078 return offset + len; 00079 } 00080 int BER_ENCODE_CTYPE_ENUM(unsigned char *buf, CTYPE_ENUM *value) { // assuming enum is an int - allows any enum type to be used 00081 CTYPE_INT16U offset = 0; 00082 CTYPE_INT16U len = BER_GET_LENGTH_CTYPE_ENUM(value); 00083 00084 buf[offset++] = ASN1_TAG_INTEGER; 00085 offset += encodeLength(&buf[offset], len); 00086 00087 ber_encode_integer(&buf[offset], value, SV_GET_LENGTH_INT32U); 00088 //netmemcpy(&buf[offset], value, len); 00089 00090 return offset + len; 00091 } 00092 int BER_ENCODE_CTYPE_INT16(unsigned char *buf, CTYPE_INT16 *value) { 00093 CTYPE_INT16U offset = 0; 00094 CTYPE_INT16U len = BER_GET_LENGTH_CTYPE_INT16(value); 00095 00096 buf[offset++] = ASN1_TAG_INTEGER; 00097 offset += encodeLength(&buf[offset], len); 00098 00099 ber_encode_integer(&buf[offset], value, SV_GET_LENGTH_INT16); 00100 //netmemcpy(&buf[offset], value, len); 00101 00102 return offset + len; 00103 } 00104 int BER_ENCODE_CTYPE_INT32(unsigned char *buf, CTYPE_INT32 *value) { 00105 CTYPE_INT16U offset = 0; 00106 CTYPE_INT16U len = BER_GET_LENGTH_CTYPE_INT32(value); 00107 00108 buf[offset++] = ASN1_TAG_INTEGER; 00109 offset += encodeLength(&buf[offset], len); 00110 00111 printf("INT32 value: %u, len: %i, total: %i\n", *value, len, offset + len); 00112 fflush(stdout); 00113 ber_encode_integer(&buf[offset], value, SV_GET_LENGTH_INT32); 00114 //netmemcpy(&buf[offset], value, len); 00115 00116 return offset + len; 00117 } 00118 int BER_ENCODE_CTYPE_INT16U(unsigned char *buf, CTYPE_INT16U *value) { 00119 CTYPE_INT16U offset = 0; 00120 CTYPE_INT16U len = BER_GET_LENGTH_CTYPE_INT16U(value); 00121 00122 buf[offset++] = ASN1_TAG_UNSIGNED; 00123 offset += encodeLength(&buf[offset], len); 00124 00125 printf("INT16U value: %u, len: %i, total: %i\n", *value, len, offset + len); 00126 fflush(stdout); 00127 ber_encode_integer(&buf[offset], value, SV_GET_LENGTH_INT16U); 00128 //netmemcpy(&buf[offset], value, len); 00129 00130 return offset + len; 00131 } 00132 int BER_ENCODE_CTYPE_INT32U(unsigned char *buf, CTYPE_INT32U *value) { 00133 CTYPE_INT16U offset = 0; 00134 CTYPE_INT16U len = BER_GET_LENGTH_CTYPE_INT32U(value); 00135 00136 buf[offset++] = ASN1_TAG_UNSIGNED; 00137 offset += encodeLength(&buf[offset], len); 00138 00139 ber_encode_integer(&buf[offset], value, SV_GET_LENGTH_INT32U); 00140 00141 printf("INT32U value: %u, len: %i, total: %i\n", *value, len, offset + len); 00142 fflush(stdout); 00143 //netmemcpy(&buf[offset], value, len); 00144 00145 return offset + len; 00146 } 00147 int BER_ENCODE_CTYPE_VISSTRING255(unsigned char *buf, CTYPE_VISSTRING255 *value) { 00148 netmemcpy(buf, value, BER_GET_LENGTH_CTYPE_VISSTRING255(value)); 00149 00150 return BER_GET_LENGTH_CTYPE_VISSTRING255(value); 00151 } 00152 int BER_ENCODE_CTYPE_BOOLEAN(unsigned char *buf, CTYPE_BOOLEAN *value) { 00153 CTYPE_INT16U offset = 0; 00154 CTYPE_INT16U len = BER_GET_LENGTH_CTYPE_BOOLEAN(value); 00155 00156 buf[offset++] = ASN1_TAG_BOOLEAN; 00157 offset += encodeLength(&buf[offset], len); 00158 00159 netmemcpy(&buf[offset], value, len); 00160 00161 return offset + len; 00162 } 00163 int BER_ENCODE_CTYPE_DBPOS(unsigned char *buf, CTYPE_DBPOS *value) { 00164 CTYPE_INT16U offset = 0; 00165 CTYPE_INT16U len = BER_GET_LENGTH_CTYPE_DBPOS(value); 00166 00167 buf[offset++] = 0x85; 00168 offset += encodeLength(&buf[offset], len); 00169 00170 netmemcpy(&buf[offset], value, len); //TODO should be memcpy, because already in big-endian? 00171 00172 return offset + len; 00173 } 00174 00175 #endif
Generated on Mon Jul 18 2022 18:17:52 by
1.7.2