An mbed implementation of IEC 61850-9-2LE Sample Values. Creating using the rapid61850 library, available at: https://github.com/stevenblair/rapid61850.

Dependencies:   mbed

An mbed implementation of IEC 61850-9-2LE Sample Values. Creating using the rapid61850 library, available at: https://github.com/stevenblair/rapid61850.

Committer:
sblair
Date:
Tue Oct 02 21:31:05 2012 +0000
Revision:
0:f09b7bb8bcce
converted library to folder

Who changed what in which revision?

UserRevisionLine numberNew contents of line
sblair 0:f09b7bb8bcce 1 /**
sblair 0:f09b7bb8bcce 2 * Rapid-prototyping protection schemes with IEC 61850
sblair 0:f09b7bb8bcce 3 *
sblair 0:f09b7bb8bcce 4 * Copyright (c) 2012 Steven Blair
sblair 0:f09b7bb8bcce 5 *
sblair 0:f09b7bb8bcce 6 * This program is free software; you can redistribute it and/or
sblair 0:f09b7bb8bcce 7 * modify it under the terms of the GNU General Public License
sblair 0:f09b7bb8bcce 8 * as published by the Free Software Foundation; either version 2
sblair 0:f09b7bb8bcce 9 * of the License, or (at your option) any later version.
sblair 0:f09b7bb8bcce 10
sblair 0:f09b7bb8bcce 11 * This program is distributed in the hope that it will be useful,
sblair 0:f09b7bb8bcce 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
sblair 0:f09b7bb8bcce 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
sblair 0:f09b7bb8bcce 14 * GNU General Public License for more details.
sblair 0:f09b7bb8bcce 15
sblair 0:f09b7bb8bcce 16 * You should have received a copy of the GNU General Public License
sblair 0:f09b7bb8bcce 17 * along with this program; if not, write to the Free Software
sblair 0:f09b7bb8bcce 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
sblair 0:f09b7bb8bcce 19 */
sblair 0:f09b7bb8bcce 20
sblair 0:f09b7bb8bcce 21
sblair 0:f09b7bb8bcce 22 #include "gseDecodeBasic.h"
sblair 0:f09b7bb8bcce 23 #include "ied.h"
sblair 0:f09b7bb8bcce 24 #include "gseDecode.h"
sblair 0:f09b7bb8bcce 25 #include "gsePacketData.h"
sblair 0:f09b7bb8bcce 26 #include "decodePacket.h"
sblair 0:f09b7bb8bcce 27 #include <stddef.h>
sblair 0:f09b7bb8bcce 28
sblair 0:f09b7bb8bcce 29 void gseDecodePDU(unsigned char *buf) {
sblair 0:f09b7bb8bcce 30 unsigned char tag = 0;
sblair 0:f09b7bb8bcce 31 CTYPE_INT16U lengthFieldSize = 0;
sblair 0:f09b7bb8bcce 32 CTYPE_INT16U lengthValue = 0;
sblair 0:f09b7bb8bcce 33 CTYPE_INT16U offsetForSequence = 0;
sblair 0:f09b7bb8bcce 34 CTYPE_INT16U offsetForNonSequence = 0;
sblair 0:f09b7bb8bcce 35 unsigned char *gocbRef = NULL;
sblair 0:f09b7bb8bcce 36 CTYPE_INT16U gocbRefLength = 0;
sblair 0:f09b7bb8bcce 37 CTYPE_INT32U timeAllowedToLive = 0;
sblair 0:f09b7bb8bcce 38 CTYPE_TIMESTAMP T = 0;
sblair 0:f09b7bb8bcce 39 CTYPE_INT32U sqNum = 0;
sblair 0:f09b7bb8bcce 40 CTYPE_INT32U stNum = 0;
sblair 0:f09b7bb8bcce 41
sblair 0:f09b7bb8bcce 42 while (1) {
sblair 0:f09b7bb8bcce 43 tag = (unsigned char) buf[0]; // assumes only one byte is used
sblair 0:f09b7bb8bcce 44 lengthFieldSize = getLengthFieldSize((unsigned char) buf[1]);
sblair 0:f09b7bb8bcce 45 lengthValue = decodeLength((unsigned char *) &buf[1]);
sblair 0:f09b7bb8bcce 46 offsetForSequence = 1 + lengthFieldSize;
sblair 0:f09b7bb8bcce 47 offsetForNonSequence = 1 + lengthFieldSize + lengthValue;
sblair 0:f09b7bb8bcce 48
sblair 0:f09b7bb8bcce 49 switch (tag) {
sblair 0:f09b7bb8bcce 50 case GSE_TAG_GOCBREF:
sblair 0:f09b7bb8bcce 51 // save pointer to gocbRef name
sblair 0:f09b7bb8bcce 52 gocbRef = &buf[offsetForSequence];
sblair 0:f09b7bb8bcce 53 gocbRefLength = lengthValue;
sblair 0:f09b7bb8bcce 54
sblair 0:f09b7bb8bcce 55 buf = &buf[offsetForNonSequence];
sblair 0:f09b7bb8bcce 56 break;
sblair 0:f09b7bb8bcce 57 case GSE_TAG_TIME_ALLOWED_TO_LIVE:
sblair 0:f09b7bb8bcce 58 ber_decode_integer(&buf[offsetForSequence], lengthValue, &timeAllowedToLive, SV_GET_LENGTH_INT32U);
sblair 0:f09b7bb8bcce 59 buf = &buf[offsetForNonSequence];
sblair 0:f09b7bb8bcce 60 break;
sblair 0:f09b7bb8bcce 61 case ASN1_TAG_SEQUENCE:
sblair 0:f09b7bb8bcce 62 buf = &buf[offsetForSequence];
sblair 0:f09b7bb8bcce 63 break;
sblair 0:f09b7bb8bcce 64 case GSE_TAG_DATSET:
sblair 0:f09b7bb8bcce 65 buf = &buf[offsetForNonSequence];
sblair 0:f09b7bb8bcce 66 break;
sblair 0:f09b7bb8bcce 67 case GSE_TAG_T:
sblair 0:f09b7bb8bcce 68 memcpy(&T, &buf[offsetForSequence], BER_GET_LENGTH_CTYPE_TIMESTAMP(&T));
sblair 0:f09b7bb8bcce 69 buf = &buf[offsetForNonSequence];
sblair 0:f09b7bb8bcce 70 break;
sblair 0:f09b7bb8bcce 71 case GSE_TAG_STNUM:
sblair 0:f09b7bb8bcce 72 ber_decode_integer(&buf[offsetForSequence], lengthValue, &stNum, SV_GET_LENGTH_INT32U);
sblair 0:f09b7bb8bcce 73 buf = &buf[offsetForNonSequence];
sblair 0:f09b7bb8bcce 74 break;
sblair 0:f09b7bb8bcce 75 case GSE_TAG_SQNUM:
sblair 0:f09b7bb8bcce 76 ber_decode_integer(&buf[offsetForSequence], lengthValue, &sqNum, SV_GET_LENGTH_INT32U);
sblair 0:f09b7bb8bcce 77 buf = &buf[offsetForNonSequence];
sblair 0:f09b7bb8bcce 78 break;
sblair 0:f09b7bb8bcce 79 case GSE_TAG_ALLDATA:
sblair 0:f09b7bb8bcce 80 gseDecodeDataset(&buf[offsetForSequence], lengthValue, gocbRef, gocbRefLength, timeAllowedToLive, T, stNum, sqNum);
sblair 0:f09b7bb8bcce 81 return;
sblair 0:f09b7bb8bcce 82 default:
sblair 0:f09b7bb8bcce 83 buf = &buf[offsetForNonSequence];
sblair 0:f09b7bb8bcce 84 break;
sblair 0:f09b7bb8bcce 85 }
sblair 0:f09b7bb8bcce 86 }
sblair 0:f09b7bb8bcce 87 }
sblair 0:f09b7bb8bcce 88
sblair 0:f09b7bb8bcce 89 void gseDecode(unsigned char *buf, int len) {
sblair 0:f09b7bb8bcce 90 int offset = 22;
sblair 0:f09b7bb8bcce 91
sblair 0:f09b7bb8bcce 92 // check for VLAN tag
sblair 0:f09b7bb8bcce 93 if (buf[12] == 0x81 && buf[13] == 0x00) {
sblair 0:f09b7bb8bcce 94 offset = 26;
sblair 0:f09b7bb8bcce 95 }
sblair 0:f09b7bb8bcce 96
sblair 0:f09b7bb8bcce 97 gseDecodePDU(&buf[offset]); // cuts out frame header
sblair 0:f09b7bb8bcce 98 }