Beispiel #1
0
void gseDecodePDU(unsigned char *buf) {
	unsigned char	tag = 0;
	CTYPE_INT16U	lengthFieldSize = 0;
	CTYPE_INT16U	lengthValue = 0;
	CTYPE_INT16U	offsetForSequence = 0;
	CTYPE_INT16U	offsetForNonSequence = 0;
	unsigned char	*gocbRef = NULL;
	CTYPE_INT16U	gocbRefLength = 0;
	CTYPE_INT32U	timeAllowedToLive = 0;
	CTYPE_TIMESTAMP	T = 0;
	CTYPE_INT32U	sqNum = 0;
	CTYPE_INT32U	stNum = 0;

	while (1) {
		tag = (unsigned char) buf[0];	// assumes only one byte is used
		lengthFieldSize = getLengthFieldSize((unsigned char) buf[1]);
		lengthValue = decodeLength((unsigned char *) &buf[1]);
		offsetForSequence = 1 + lengthFieldSize;
		offsetForNonSequence = 1 + lengthFieldSize + lengthValue;

		switch (tag) {
		case GSE_TAG_GOCBREF:
			// save pointer to gocbRef name
			gocbRef = &buf[offsetForSequence];
			gocbRefLength = lengthValue;

			buf = &buf[offsetForNonSequence];
			break;
		case GSE_TAG_TIME_ALLOWED_TO_LIVE:
			ber_decode_integer(&buf[offsetForSequence], lengthValue, &timeAllowedToLive, SV_GET_LENGTH_INT32U);
			buf = &buf[offsetForNonSequence];
			break;
		case ASN1_TAG_SEQUENCE:
			buf = &buf[offsetForSequence];
			break;
		case GSE_TAG_DATSET:
			buf = &buf[offsetForNonSequence];
			break;
		case GSE_TAG_T:
			memcpy(&T, &buf[offsetForSequence], BER_GET_LENGTH_CTYPE_TIMESTAMP(&T));
			buf = &buf[offsetForNonSequence];
			break;
		case GSE_TAG_STNUM:
			ber_decode_integer(&buf[offsetForSequence], lengthValue, &stNum, SV_GET_LENGTH_INT32U);
			buf = &buf[offsetForNonSequence];
			break;
		case GSE_TAG_SQNUM:
			ber_decode_integer(&buf[offsetForSequence], lengthValue, &sqNum, SV_GET_LENGTH_INT32U);
			buf = &buf[offsetForNonSequence];
			break;
		case GSE_TAG_ALLDATA:
			gseDecodeDataset(&buf[offsetForSequence], lengthValue, gocbRef, gocbRefLength, timeAllowedToLive, T, stNum, sqNum);
			return;
		default:
			buf = &buf[offsetForNonSequence];
			break;
		}
	}
}
Beispiel #2
0
int ber_decode_myHealth(unsigned char *buf, struct myHealth *myHealth) {
    int offset = 0;

    if (buf[offset++] == 0xA2) {
        offset += getLengthFieldSize(buf[offset]);

        offset += BER_DECODE_CTYPE_ENUM(&buf[offset], (CTYPE_ENUM *) &myHealth->stVal);
    }

    return offset;
}
Beispiel #3
0
int ber_decode_myAnalogValue(unsigned char *buf, struct myAnalogValue *myAnalogValue) {
    int offset = 0;

    if (buf[offset++] == 0xA2) {
        offset += getLengthFieldSize(buf[offset]);

        offset += BER_DECODE_CTYPE_FLOAT32(&buf[offset], &myAnalogValue->f);
    }

    return offset;
}
Beispiel #4
0
int ber_decode_myINS(unsigned char *buf, struct myINS *myINS) {
    int offset = 0;

    if (buf[offset++] == 0xA2) {
        offset += getLengthFieldSize(buf[offset]);

        offset += BER_DECODE_CTYPE_INT32(&buf[offset], &myINS->stVal);
    }

    return offset;
}
Beispiel #5
0
int ber_decode_ScaledValueConfig(unsigned char *buf, struct ScaledValueConfig *ScaledValueConfig) {
    int offset = 0;

    if (buf[offset++] == 0xA2) {
        offset += getLengthFieldSize(buf[offset]);

        offset += BER_DECODE_CTYPE_FLOAT32(&buf[offset], &ScaledValueConfig->scaleFactor);
        offset += BER_DECODE_CTYPE_FLOAT32(&buf[offset], &ScaledValueConfig->offset);
    }

    return offset;
}
Beispiel #6
0
int ber_decode_myDPL(unsigned char *buf, struct myDPL *myDPL) {
    int offset = 0;

    if (buf[offset++] == 0xA2) {
        offset += getLengthFieldSize(buf[offset]);

        offset += BER_DECODE_CTYPE_VISSTRING255(&buf[offset], &myDPL->vendor);
        offset += BER_DECODE_CTYPE_VISSTRING255(&buf[offset], &myDPL->hwRev);
    }

    return offset;
}
Beispiel #7
0
int ber_decode_simpleVector(unsigned char *buf, struct simpleVector *simpleVector) {
    int offset = 0;

    if (buf[offset++] == 0xA2) {
        offset += getLengthFieldSize(buf[offset]);

        offset += ber_decode_myAnalogValue(&buf[offset], &simpleVector->mag);
        offset += ber_decode_myAnalogValue(&buf[offset], &simpleVector->ang);
    }

    return offset;
}
Beispiel #8
0
int ber_decode_simpleSAV(unsigned char *buf, struct simpleSAV *simpleSAV) {
    int offset = 0;

    if (buf[offset++] == 0xA2) {
        offset += getLengthFieldSize(buf[offset]);

        offset += ber_decode_myAnalogValue(&buf[offset], &simpleSAV->instMag);
        offset += BER_DECODE_CTYPE_QUALITY(&buf[offset], &simpleSAV->q);
    }

    return offset;
}
Beispiel #9
0
int ber_decode_myCMV(unsigned char *buf, struct myCMV *myCMV) {
    int offset = 0;

    if (buf[offset++] == 0xA2) {
        offset += getLengthFieldSize(buf[offset]);

        offset += ber_decode_myVector(&buf[offset], &myCMV->cVal);
        offset += BER_DECODE_CTYPE_QUALITY(&buf[offset], &myCMV->q);
        offset += BER_DECODE_CTYPE_TIMESTAMP(&buf[offset], &myCMV->t);
    }

    return offset;
}
Beispiel #10
0
int ber_decode_simpleWYE(unsigned char *buf, struct simpleWYE *simpleWYE) {
    int offset = 0;

    if (buf[offset++] == 0xA2) {
        offset += getLengthFieldSize(buf[offset]);

        offset += ber_decode_simpleCMV(&buf[offset], &simpleWYE->phsA);
        offset += ber_decode_simpleCMV(&buf[offset], &simpleWYE->phsB);
        offset += ber_decode_simpleCMV(&buf[offset], &simpleWYE->phsC);
    }

    return offset;
}
Beispiel #11
0
int BER_DECODE_CTYPE_INT32U(unsigned char *buf, CTYPE_INT32U *value) {
	CTYPE_INT16U offset = 0;
	CTYPE_INT16U len = 0;

	if (buf[offset++] == ASN1_TAG_UNSIGNED) {
		len += decodeLength(&buf[offset]);
		offset += getLengthFieldSize(buf[offset]);

		ber_decode_integer(&buf[offset], len, value, SV_GET_LENGTH_INT32U);
	}

	return offset + len;
}
Beispiel #12
0
int ber_decode_mySPS(unsigned char *buf, struct mySPS *mySPS) {
    int offset = 0;

    if (buf[offset++] == 0xA2) {
        offset += getLengthFieldSize(buf[offset]);

        offset += BER_DECODE_CTYPE_INT32(&buf[offset], &mySPS->stVal);
        offset += BER_DECODE_CTYPE_QUALITY(&buf[offset], &mySPS->q);
        offset += BER_DECODE_CTYPE_TIMESTAMP(&buf[offset], &mySPS->t);
    }

    return offset;
}
Beispiel #13
0
int BER_DECODE_CTYPE_TIMESTAMP(unsigned char *buf, CTYPE_TIMESTAMP *value) {
	CTYPE_INT16U offset = 0;
	CTYPE_INT16U len = 0;

	if (buf[offset++] == 0x89) {
		len += decodeLength(&buf[offset]);
		offset += getLengthFieldSize(buf[offset]);

		netmemcpy(value, &buf[offset], len);
	}

	return offset + len;
}
Beispiel #14
0
int BER_DECODE_CTYPE_BOOLEAN(unsigned char *buf, CTYPE_BOOLEAN *value) {
	CTYPE_INT16U offset = 0;
	CTYPE_INT16U len = 0;

	if (buf[offset++] == ASN1_TAG_BOOLEAN) {
		len += decodeLength(&buf[offset]);
		offset += getLengthFieldSize(buf[offset]);

		netmemcpy(value, &buf[offset], len);
	}

	return offset + len;
}
Beispiel #15
0
int ber_decode_mySEQ(unsigned char *buf, struct mySEQ *mySEQ) {
    int offset = 0;

    if (buf[offset++] == 0xA2) {
        offset += getLengthFieldSize(buf[offset]);

        offset += ber_decode_myCMV(&buf[offset], &mySEQ->c1);
        offset += ber_decode_myCMV(&buf[offset], &mySEQ->c2);
        offset += ber_decode_myCMV(&buf[offset], &mySEQ->c3);
        offset += BER_DECODE_CTYPE_ENUM(&buf[offset], (CTYPE_ENUM *) &mySEQ->seqT);
    }

    return offset;
}
Beispiel #16
0
int ber_decode_myPos(unsigned char *buf, struct myPos *myPos) {
    int offset = 0;

    if (buf[offset++] == 0xA2) {
        offset += getLengthFieldSize(buf[offset]);

        offset += BER_DECODE_CTYPE_DBPOS(&buf[offset], &myPos->stVal);
        offset += BER_DECODE_CTYPE_QUALITY(&buf[offset], &myPos->q);
        offset += BER_DECODE_CTYPE_TIMESTAMP(&buf[offset], &myPos->t);
        offset += BER_DECODE_CTYPE_BOOLEAN(&buf[offset], &myPos->ctlVal);
    }

    return offset;
}
Beispiel #17
0
int BER_DECODE_CTYPE_QUALITY(unsigned char *buf, CTYPE_QUALITY *value) {
	CTYPE_INT16U offset = 0;
	CTYPE_INT16U len = 0;

	if (buf[offset] == ASN1_TAG_BIT_STRING) {
		offset++;
		len += decodeLength(&buf[offset]);
		offset += getLengthFieldSize(buf[offset]);

		netmemcpy(value, &buf[offset + 1], len - 1);	// skip over one byte (which contains number of unused bits)
	}

	return offset + len;
}
Beispiel #18
0
int ber_decode_simpleMV(unsigned char *buf, struct simpleMV *simpleMV) {
    int offset = 0;

    if (buf[offset++] == 0xA2) {
        offset += getLengthFieldSize(buf[offset]);

        offset += BER_DECODE_CTYPE_FLOAT32(&buf[offset], &simpleMV->mag);
        offset += BER_DECODE_CTYPE_QUALITY(&buf[offset], &simpleMV->q);
        offset += BER_DECODE_CTYPE_TIMESTAMP(&buf[offset], &simpleMV->t);
        offset += ber_decode_ScaledValueConfig(&buf[offset], &simpleMV->sVC);
    }

    return offset;
}
Beispiel #19
0
int ber_decode_myMod(unsigned char *buf, struct myMod *myMod) {
    int offset = 0;

    if (buf[offset++] == 0xA2) {
        offset += getLengthFieldSize(buf[offset]);

        offset += BER_DECODE_CTYPE_ENUM(&buf[offset], (CTYPE_ENUM *) &myMod->ctlVal);
        offset += BER_DECODE_CTYPE_ENUM(&buf[offset], (CTYPE_ENUM *) &myMod->stVal);
        offset += BER_DECODE_CTYPE_QUALITY(&buf[offset], &myMod->q);
        offset += BER_DECODE_CTYPE_TIMESTAMP(&buf[offset], &myMod->t);
    }

    return offset;
}
Beispiel #20
0
int ber_decode_simpleCMV(unsigned char *buf, struct simpleCMV *simpleCMV) {
    int offset = 0;

    if (buf[offset++] == 0xA2) {
        offset += getLengthFieldSize(buf[offset]);

        offset += ber_decode_simpleVector(&buf[offset], &simpleCMV->cVal);
        offset += BER_DECODE_CTYPE_QUALITY(&buf[offset], &simpleCMV->q);
        offset += BER_DECODE_CTYPE_TIMESTAMP(&buf[offset], &simpleCMV->t);
        offset += ber_decode_mySPS(&buf[offset], &simpleCMV->testSecondLayerSDO);
        offset += BER_DECODE_CTYPE_INT32(&buf[offset], &simpleCMV->testInteger);
        offset += BER_DECODE_CTYPE_BOOLEAN(&buf[offset], &simpleCMV->testBoolean);
    }

    return offset;
}
Beispiel #21
0
int ber_decode_myMV(unsigned char *buf, struct myMV *myMV) {
    int offset = 0;

    if (buf[offset++] == 0xA2) {
        offset += getLengthFieldSize(buf[offset]);

        offset += ber_decode_myAnalogValue(&buf[offset], &myMV->mag);
        offset += BER_DECODE_CTYPE_QUALITY(&buf[offset], &myMV->q);
        offset += BER_DECODE_CTYPE_TIMESTAMP(&buf[offset], &myMV->t);
        offset += ber_decode_ScaledValueConfig(&buf[offset], &myMV->sVC);
        offset += BER_DECODE_CTYPE_INT32(&buf[offset], &myMV->int1);
        offset += BER_DECODE_CTYPE_INT32(&buf[offset], &myMV->int2);
        offset += BER_DECODE_CTYPE_INT32(&buf[offset], &myMV->int3);
    }

    return offset;
}
Beispiel #22
0
int BER_DECODE_CTYPE_ENUM(unsigned char *buf, CTYPE_ENUM *value) {	// assuming enum is an int - allows any enum type to be used
	CTYPE_INT16U offset = 0;
	CTYPE_INT16U len = 0;

	if (buf[offset++] == ASN1_TAG_UNSIGNED) {
		len += decodeLength(&buf[offset]);
		offset += getLengthFieldSize(buf[offset]);

#if GOOSE_FIXED_SIZE == 1
		ber_decode_integer(&buf[offset], len, value, SV_GET_LENGTH_INT8);
#else
		ber_decode_integer(&buf[offset], len, value, SV_GET_LENGTH_INT32U);
#endif
	}

	return offset + len;
}
Beispiel #23
0
int BER_DECODE_CTYPE_FLOAT64(unsigned char *buf, CTYPE_FLOAT64 *value) {
	CTYPE_INT16U offset = 0;
	CTYPE_INT16U len = 0;

	if (buf[offset++] == 0x87) {
		len += decodeLength(&buf[offset]);
		offset += getLengthFieldSize(buf[offset]);

		// check for fixed-length GOOSE. If not, check for 11 bits for exponent
		if (len == 9 && buf[offset] == 0x0B) {
			netmemcpy(value, &buf[offset + 1], len - 1);
		}
		else if (len == 8) {
			netmemcpy(value, &buf[offset], len);
		}
	}

	return offset + len - 1;
}