The goal of this software is to automatically generate C/C++ code which reads and writes GOOSE and Sampled Value packets. Any valid IEC 61850 Substation Configuration Description (SCD) file, describing GOOSE and/or SV communications, can be used as the input. The output code is lightweight and platform-independent, so it can run on a variety of devices, including low-cost microcontrollers. It\'s ideal for rapid-prototyping new protection and control systems that require communications. This mbed project is a simple example of this functionality. Other code: https://github.com/stevenblair/rapid61850 Project homepage: http://personal.strath.ac.uk/steven.m.blair/

Committer:
sblair
Date:
Fri Oct 07 13:41:08 2011 +0000
Revision:
0:230c10b228ea
Child:
1:9399d44c2b1a

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
sblair 0:230c10b228ea 1 #include "gseDecodeBasic.h"
sblair 0:230c10b228ea 2 #include "ied.h"
sblair 0:230c10b228ea 3 #include "gseDecode.h"
sblair 0:230c10b228ea 4 #include "gsePacketData.h"
sblair 0:230c10b228ea 5 #include "decodePacket.h"
sblair 0:230c10b228ea 6 #include <stddef.h>
sblair 0:230c10b228ea 7
sblair 0:230c10b228ea 8
sblair 0:230c10b228ea 9
sblair 0:230c10b228ea 10 //temp
sblair 0:230c10b228ea 11 //#include <stdio.h>
sblair 0:230c10b228ea 12 //#include <stdlib.h>
sblair 0:230c10b228ea 13
sblair 0:230c10b228ea 14
sblair 0:230c10b228ea 15
sblair 0:230c10b228ea 16 unsigned char datasetName[65] = {0}; // maximum length of 65 bytes
sblair 0:230c10b228ea 17 CTYPE_INT16U datasetNameLength = 0;
sblair 0:230c10b228ea 18
sblair 0:230c10b228ea 19
sblair 0:230c10b228ea 20 void gseDecodePDU(unsigned char *buf) {
sblair 0:230c10b228ea 21 unsigned char tag = (unsigned char) buf[0]; // assumes only one byte is used
sblair 0:230c10b228ea 22 CTYPE_INT16U lengthFieldSize = getLengthFieldSize((unsigned char) buf[1]);
sblair 0:230c10b228ea 23 CTYPE_INT16U lengthValue = decodeLength((unsigned char *) &buf[1]);
sblair 0:230c10b228ea 24 CTYPE_INT16U offsetForSequence = 1 + lengthFieldSize;
sblair 0:230c10b228ea 25 CTYPE_INT16U offsetForNonSequence = 1 + lengthFieldSize + lengthValue;
sblair 0:230c10b228ea 26
sblair 0:230c10b228ea 27 //printf("tag: %x, lengthFieldSize: %i, lengthValue: %i, offset: %i\n", tag, lengthFieldSize, lengthValue, offsetForNonSequence);
sblair 0:230c10b228ea 28
sblair 0:230c10b228ea 29 switch (tag) {
sblair 0:230c10b228ea 30 case 0x61:
sblair 0:230c10b228ea 31 gseDecodePDU(&buf[offsetForSequence]);
sblair 0:230c10b228ea 32 break;
sblair 0:230c10b228ea 33 case 0x82:
sblair 0:230c10b228ea 34 // save dataset name
sblair 0:230c10b228ea 35 memcpy(datasetName, &buf[offsetForSequence], lengthValue);
sblair 0:230c10b228ea 36 datasetNameLength = lengthValue;
sblair 0:230c10b228ea 37 //printf("%s, %d\n", datasetName, datasetNameLength);
sblair 0:230c10b228ea 38 //fflush(stdout);
sblair 0:230c10b228ea 39
sblair 0:230c10b228ea 40 gseDecodePDU(&buf[offsetForNonSequence]);
sblair 0:230c10b228ea 41 break;
sblair 0:230c10b228ea 42 case 0xAB:
sblair 0:230c10b228ea 43 gseDecodeDataset(&buf[offsetForSequence], lengthValue, datasetName, datasetNameLength);
sblair 0:230c10b228ea 44 return;
sblair 0:230c10b228ea 45 //break;
sblair 0:230c10b228ea 46 default:
sblair 0:230c10b228ea 47 gseDecodePDU(&buf[offsetForNonSequence]);
sblair 0:230c10b228ea 48 break;
sblair 0:230c10b228ea 49 }
sblair 0:230c10b228ea 50 }
sblair 0:230c10b228ea 51
sblair 0:230c10b228ea 52 void gseDecode(unsigned char *buf, int len) {
sblair 0:230c10b228ea 53 gseDecodePDU(&buf[26]); // cuts out frame header (fixed size of 26 bytes before start of APDU)
sblair 0:230c10b228ea 54 }