From f407c6e6ca6cdfd8b2f2bcd6553405334a0b0c37 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Wed, 6 Dec 2017 16:06:37 +0800 Subject: [PATCH] sv: add support for decoding smpMod, smpRate and datSet attributes in ASDUs --- src/sampled_values/sv_subscriber.c | 67 ++++++++++++++++++++++++++++-- src/sampled_values/sv_subscriber.h | 54 ++++++++++++++++++++++++ 2 files changed, 118 insertions(+), 3 deletions(-) diff --git a/src/sampled_values/sv_subscriber.c b/src/sampled_values/sv_subscriber.c index 7c8be35..ca3ac08 100644 --- a/src/sampled_values/sv_subscriber.c +++ b/src/sampled_values/sv_subscriber.c @@ -70,20 +70,20 @@ struct sSVSubscriber { struct sSVSubscriber_ASDU { char* svId; + char* datSet; uint8_t* smpCnt; uint8_t* confRev; uint8_t* refrTm; uint8_t* smpSynch; - + uint8_t* smpMod; + uint8_t* smpRate; int dataBufferLength; uint8_t* dataBuffer; }; - - SVReceiver SVReceiver_create(void) { @@ -236,6 +236,7 @@ parseASDU(SVReceiver self, SVSubscriber subscriber, uint8_t* buffer, int length) { int bufPos = 0; int svIdLength = 0; + int datSetLength = 0; struct sSVSubscriber_ASDU asdu; memset(&asdu, 0, sizeof(struct sSVSubscriber_ASDU)); @@ -258,6 +259,11 @@ parseASDU(SVReceiver self, SVSubscriber subscriber, uint8_t* buffer, int length) svIdLength = elementLength; break; + case 0x81: + asdu.datSet = (char*) (buffer + bufPos); + datSetLength = elementLength; + break; + case 0x82: asdu.smpCnt = buffer + bufPos; break; @@ -274,11 +280,19 @@ parseASDU(SVReceiver self, SVSubscriber subscriber, uint8_t* buffer, int length) asdu.smpSynch = buffer + bufPos; break; + case 0x86: + asdu.smpRate = buffer + bufPos; + break; + case 0x87: asdu.dataBuffer = buffer + bufPos; asdu.dataBufferLength = elementLength; break; + case 0x88: + asdu.smpMod = buffer + bufPos; + break; + default: /* ignore unknown tag */ break; } @@ -288,6 +302,8 @@ parseASDU(SVReceiver self, SVSubscriber subscriber, uint8_t* buffer, int length) if (asdu.svId != NULL) asdu.svId[svIdLength] = 0; + if (asdu.datSet != NULL) + asdu.datSet[datSetLength] = 0; /* Call callback handler */ if (subscriber->listener != NULL) @@ -595,6 +611,23 @@ SVSubscriber_ASDU_hasRefrTm(SVSubscriber_ASDU self) return (self->refrTm != NULL); } +bool +SVSubscriber_ASDU_hasDatSet(SVSubscriber_ASDU self) +{ + return (self->datSet != NULL); +} + +bool +SVSubscriber_ASDU_hasSmpRate(SVSubscriber_ASDU self) +{ + return (self->smpRate != NULL); +} + +bool +SVSubscriber_ASDU_hasSmpMod(SVSubscriber_ASDU self) +{ + return (self->smpMod != NULL); +} const char* SVSubscriber_ASDU_getSvId(SVSubscriber_ASDU self) @@ -602,6 +635,12 @@ SVSubscriber_ASDU_getSvId(SVSubscriber_ASDU self) return self->svId; } +const char* +SVSubscriber_ASDU_getDatSet(SVSubscriber_ASDU self) +{ + return self->datSet; +} + uint32_t SVSubscriber_ASDU_getConfRev(SVSubscriber_ASDU self) { @@ -616,6 +655,28 @@ SVSubscriber_ASDU_getConfRev(SVSubscriber_ASDU self) return retVal; } +uint8_t +SVSubscriber_ASDU_getSmpMod(SVSubscriber_ASDU self) +{ + uint8_t retVal = *((uint8_t*) (self->smpMod)); + + return retVal; +} + +uint16_t +SVSubscriber_ASDU_getSmpRate(SVSubscriber_ASDU self) +{ + uint16_t retVal = *((uint16_t*) (self->smpRate)); + +#if (ORDER_LITTLE_ENDIAN == 1) + uint8_t* buf = (uint8_t*) (&retVal); + + BerEncoder_revertByteOrder(buf, 2); +#endif + + return retVal; +} + int8_t SVSubscriber_ASDU_getINT8(SVSubscriber_ASDU self, int index) { diff --git a/src/sampled_values/sv_subscriber.h b/src/sampled_values/sv_subscriber.h index fd4093e..ef5ab87 100644 --- a/src/sampled_values/sv_subscriber.h +++ b/src/sampled_values/sv_subscriber.h @@ -277,6 +277,14 @@ SVSubscriber_ASDU_getSmpCnt(SVSubscriber_ASDU self); const char* SVSubscriber_ASDU_getSvId(SVSubscriber_ASDU self); +/** + * \brief return the DatSet value included in the SV ASDU + * + * \param self ASDU object instance + */ +const char* +SVSubscriber_ASDU_getDatSet(SVSubscriber_ASDU self); + /** * \brief return the ConfRev value included in the SV ASDU * @@ -285,6 +293,32 @@ SVSubscriber_ASDU_getSvId(SVSubscriber_ASDU self); uint32_t SVSubscriber_ASDU_getConfRev(SVSubscriber_ASDU self); +/** + * \brief return the SmpMod value included in the SV ASDU + * + * \param self ASDU object instance + */ +uint8_t +SVSubscriber_ASDU_getSmpMod(SVSubscriber_ASDU self); + +/** + * \brief return the SmpRate value included in the SV ASDU + * + * \param self ASDU object instance + */ +uint16_t +SVSubscriber_ASDU_getSmpRate(SVSubscriber_ASDU self); + +/** + * \brief Check if DatSet value is included in the SV ASDU + * + * \param self ASDU object instance + * + * \return true if DatSet value is present, false otherwise + */ +bool +SVSubscriber_ASDU_hasDatSet(SVSubscriber_ASDU self); + /** * \brief Check if RefrTm value is included in the SV ASDU * @@ -295,6 +329,26 @@ SVSubscriber_ASDU_getConfRev(SVSubscriber_ASDU self); bool SVSubscriber_ASDU_hasRefrTm(SVSubscriber_ASDU self); +/** + * \brief Check if SmpMod value is included in the SV ASDU + * + * \param self ASDU object instance + * + * \return true if SmpMod value is present, false otherwise + */ +bool +SVSubscriber_ASDU_hasSmpMod(SVSubscriber_ASDU self); + +/** + * \brief Check if SmpRate value is included in the SV ASDU + * + * \param self ASDU object instance + * + * \return true if SmpRate value is present, false otherwise + */ +bool +SVSubscriber_ASDU_hasSmpRate(SVSubscriber_ASDU self); + /** * \brief Get the RefrTim value included in SV ASDU as ms timestamp *