Skip to main content
Home
for DLMS smart meters

Main navigation

  • Home
  • Products
  • About us
  • Open Source
  • Community
  • Forum
  • Downloads
User account menu
  • Log in

Breadcrumb

  1. Home
  2. DLMS PDU Fails

DLMS PDU fails

By Pablo1610, 12 February, 2024
Forums
Gurux.DLMS

Hi,

I'm using the DLMS C stack for a DLMS server, and I'm getting an error related to the PDU size. I get the not enough memory available when I ask from the DLMS director for a profile generic.

I have configured the DLMS server as the following sentece, where the PDU size is 1024, and the wrapper size is 8 + PDU_SIZE (1032)

svr_init(&settings, 1, DLMS_INTERFACE_TYPE_WRAPPER, WRAPPER_BUFFER_SIZE, PDU_BUFFER_SIZE, tcp_ipframeBuff, WRAPPER_BUFFER_SIZE, pduBuff, sizeof(pduBuff));

It looks like the server is sending more information that it should, but I don't know where the problem comes from.

Can anyone explain to me how the PDU works to understand and resize the buffer to the size that I need?

Thanks in advance,
Pablo

Profile picture for user Kurumi

Kurumi

1 year 5 months ago

Hi Pablo, The problem is…

Hi Pablo,

The problem is that all your data can't fit into one PDU. The problem is that you try to add too much data to the profile generic buffer or the last row is not complete.
Only full rows can be added to the PDU. The PDU is not complete, but this makes life easier.

You should add only rows that can fit totally into the PDU. If the row doesn't fit the PDU you need to ignore that row and it's added to the next PDU.

Check this:

https://github.com/Gurux/GuruxDLMS.c/blob/fa855d2e82db1a7d27c419d09ed7a…

BR,
Mikko

Pablo1610

1 year 5 months ago

Hi, I have that part of code…

Hi,

I have that part of code in my readProfileGeneric function, that handles the out of memory code Error. I'm using the DLMS C stack library for the server, and I'm not sure that is handle when the PDU buffer is full.

Do I have to do anything to handle this error, send the data that I have and generate a new packet with the missing data?

Here is the code for the readProfileGeneric function, maybe I'm missing something important.

int readProfileGeneric(
dlmsSettings* settings,
gxProfileGeneric* pg,
unsigned char type,
gxValueEventArg* e)
{
unsigned char first = e->transactionEndIndex == 0;
int ret = 0;
gxArray captureObjects;

e->byteArray = 1;
e->handled = 1;
// If reading first time.
if (first)
{
//Read all.
if (e->selector == 0)
{
e->transactionStartIndex = 1;
e->transactionEndIndex = pg->entriesInUse;
}
else if (e->selector == 1)
{
//Read by entry. Find start and end index from the ring buffer.
if ((ret = getProfileGenericDataByRangeFromRingBuffer(settings, type, e)) != 0 ||
(ret = cosem_getColumns(&pg->captureObjects, e->selector, &e->parameters, &captureObjects)) != 0)
{
e->transactionStartIndex = e->transactionEndIndex = 0;
}
}
else if (e->selector == 2)
{
if ((ret = cosem_checkStructure(e->parameters.byteArr, 4)) != 0 ||
(ret = cosem_getUInt32(e->parameters.byteArr, &e->transactionStartIndex)) != 0 ||
(ret = cosem_getUInt32(e->parameters.byteArr, &e->transactionEndIndex)) != 0 ||
(ret = cosem_getColumns(&pg->captureObjects, e->selector, &e->parameters, &captureObjects)) != 0)
{
e->transactionStartIndex = e->transactionEndIndex = 0;
}
else
{
//If start index is too high.
if (e->transactionStartIndex > pg->entriesInUse)
{
e->transactionStartIndex = e->transactionEndIndex = 0;
}
//If end index is too high.
if (e->transactionEndIndex > pg->entriesInUse)
{
e->transactionEndIndex = pg->entriesInUse;
}
}
}
}
bb_clear(e->value.byteArr);
if (ret == 0 && first)
{
if (e->transactionEndIndex == 0)
{
ret = cosem_setArray(e->value.byteArr, 0);
}
else
{
ret = cosem_setArray(e->value.byteArr, (uint16_t)(e->transactionEndIndex - e->transactionStartIndex + 1));
}
}
if (ret == 0 && e->transactionEndIndex != 0)
{
//Loop items.
uint32_t pos;
gxtime tm;
gxtime tm2;
uint16_t pduSize;
for (pos = e->transactionStartIndex - 1; pos != e->transactionEndIndex; ++pos)
{
pduSize = e->value.byteArr->size;
//Load data from EEPROM.
if (type == LD1_PROFILE)
{
//SERIALIZER_LOAD(SETTINGS_BUFFER_SIZE + (pos * sizeof(gxLoadProfile1)), sizeof(gxLoadProfile1), &lp);
readEntry(&profileMem[LD1_PROFILE],&lp,pos);
time_initUnix(&tm, lp.time);
if ((ret = cosem_setStructure(e->value.byteArr, 8)) != 0 ||
(ret = cosem_setDateTimeAsOctetString(e->value.byteArr, &tm)) != 0 ||
(ret = cosem_setUInt8(e->value.byteArr, lp.status)) != 0 ||
(ret = cosem_setUInt32(e->value.byteArr, lp.activeImport)) != 0 ||
(ret = cosem_setUInt32(e->value.byteArr, lp.activeExport)) != 0 ||
(ret = cosem_setUInt32(e->value.byteArr, lp.reactiveQI)) != 0 ||
(ret = cosem_setUInt32(e->value.byteArr, lp.reactiveQII)) != 0 ||
(ret = cosem_setUInt32(e->value.byteArr, lp.reactiveQIII)) != 0 ||
(ret = cosem_setUInt32(e->value.byteArr, lp.reactiveQIV)) != 0)
{
//Error is handled later.
}
}
else if (type == LD2_PROFILE)
{
readEntry(&profileMem[LD2_PROFILE],&lp1,pos);
time_initUnix(&tm, lp1.time);
if ((ret = cosem_setStructure(e->value.byteArr, 27)) != 0 ||
(ret = cosem_setDateTimeAsOctetString(e->value.byteArr, &tm)) != 0 ||
(ret = cosem_setUInt8(e->value.byteArr, lp1.status)) != 0 ||
(ret = cosem_setUInt32(e->value.byteArr, lp1.avgVR)) != 0 ||
(ret = cosem_setUInt16(e->value.byteArr, lp1.avgVS)) != 0 ||
(ret = cosem_setUInt16(e->value.byteArr, lp1.avgVT)) != 0 ||
(ret = cosem_setUInt16(e->value.byteArr, lp1.avgIR)) != 0 ||
(ret = cosem_setInt32(e->value.byteArr, lp1.avgIS)) != 0 ||
(ret = cosem_setInt32(e->value.byteArr, lp1.avgIT)) != 0 ||
(ret = cosem_setInt32(e->value.byteArr, lp1.avgIN)) != 0 ||
(ret = cosem_setUInt32(e->value.byteArr, lp1.avg3PAImported)) != 0 ||
(ret = cosem_setUInt32(e->value.byteArr, lp1.avg3PAExported)) != 0 ||
(ret = cosem_setUInt32(e->value.byteArr, lp1.avg3PQImported)) != 0 ||
(ret = cosem_setUInt32(e->value.byteArr, lp1.avg3PQExported)) != 0 ||
(ret = cosem_setUInt16(e->value.byteArr, lp1.maxVR)) != 0 ||
(ret = cosem_setUInt16(e->value.byteArr, lp1.maxVS)) != 0 ||
(ret = cosem_setUInt16(e->value.byteArr, lp1.maxVT)) != 0 ||
(ret = cosem_setUInt16(e->value.byteArr, lp1.minVR)) != 0 ||
(ret = cosem_setUInt16(e->value.byteArr, lp1.minVS)) != 0 ||
(ret = cosem_setUInt16(e->value.byteArr, lp1.minVT)) != 0 ||
(ret = cosem_setInt32(e->value.byteArr, lp1.maxIR)) != 0 ||
(ret = cosem_setInt32(e->value.byteArr, lp1.maxIS)) != 0 ||
(ret = cosem_setInt32(e->value.byteArr, lp1.maxIT)) != 0 ||
(ret = cosem_setInt32(e->value.byteArr, lp1.maxIN)) != 0 ||
(ret = cosem_setInt32(e->value.byteArr, lp1.minIR)) != 0 ||
(ret = cosem_setInt32(e->value.byteArr, lp1.minIS)) != 0 ||
(ret = cosem_setInt32(e->value.byteArr, lp1.minIT)) != 0 ||
(ret = cosem_setInt32(e->value.byteArr, lp1.minIN)) != 0)
{
//Error is handled later.
}
}
else if (type == LD4_PROFILE)
{
readEntry(&profileMem[LD4_PROFILE],&lp2,pos);
time_initUnix(&tm, lp2.time);
if ((ret = cosem_setStructure(e->value.byteArr, 5)) != 0 ||
(ret = cosem_setDateTimeAsOctetString(e->value.byteArr, &tm)) != 0 ||
(ret = cosem_setUInt8(e->value.byteArr, lp2.status)) != 0 ||
(ret = cosem_setInt32(e->value.byteArr, lp2.instantIR)) != 0 ||
(ret = cosem_setInt32(e->value.byteArr, lp2.instantIS)) != 0 ||
(ret = cosem_setInt32(e->value.byteArr, lp2.instantIT)))
{
//Error is handled later.
}
}
else if (type == LD5_PROFILE)
{
readEntry(&profileMem[LD5_PROFILE],&lp3,pos);
time_initUnix(&tm, lp3.time);
if ((ret = cosem_setStructure(e->value.byteArr, 20)) != 0 ||
(ret = cosem_setDateTimeAsOctetString(e->value.byteArr, &tm)) != 0 ||
(ret = cosem_setUInt8(e->value.byteArr, lp3.status)) != 0 ||
(ret = cosem_setInt32(e->value.byteArr, lp3.activeImportR)) != 0 ||
(ret = cosem_setInt32(e->value.byteArr, lp3.activeExportR)) != 0 ||
(ret = cosem_setInt32(e->value.byteArr, lp3.reactiveQIR)) != 0 ||
(ret = cosem_setInt32(e->value.byteArr, lp3.reactiveQIIR)) != 0 ||
(ret = cosem_setInt32(e->value.byteArr, lp3.reactiveQIIIR)) != 0 ||
(ret = cosem_setInt32(e->value.byteArr, lp3.reactiveQIVR)) != 0 ||
(ret = cosem_setInt32(e->value.byteArr, lp3.activeImportS)) != 0 ||
(ret = cosem_setInt32(e->value.byteArr, lp3.activeExportS)) != 0 ||
(ret = cosem_setInt32(e->value.byteArr, lp3.reactiveQIS)) != 0 ||
(ret = cosem_setInt32(e->value.byteArr, lp3.reactiveQIIS)) != 0 ||
(ret = cosem_setInt32(e->value.byteArr, lp3.reactiveQIIIS)) != 0 ||
(ret = cosem_setInt32(e->value.byteArr, lp3.reactiveQIVS)) != 0 ||
(ret = cosem_setInt32(e->value.byteArr, lp3.activeImportT)) != 0 ||
(ret = cosem_setInt32(e->value.byteArr, lp3.activeExportT)) != 0 ||
(ret = cosem_setInt32(e->value.byteArr, lp3.reactiveQIT)) != 0 ||
(ret = cosem_setInt32(e->value.byteArr, lp3.reactiveQIIT)) != 0 ||
(ret = cosem_setInt32(e->value.byteArr, lp3.reactiveQIIIT)) != 0 ||
(ret = cosem_setInt32(e->value.byteArr, lp3.reactiveQIVT)))
{
//Error is handled later.
}
}
else if (type == INSTVAL_PROFILE)
{
readEntry(&profileMem[INSTVAL_PROFILE],&lp4,pos);
time_initUnix(&tm, lp4.time);
if ((ret = cosem_setStructure(e->value.byteArr, 31)) != 0 ||
(ret = cosem_setDateTimeAsOctetString(e->value.byteArr, &tm)) != 0 ||
(ret = cosem_setUInt16(e->value.byteArr, lp4.instVR)) != 0 ||
(ret = cosem_setInt32(e->value.byteArr, lp4.instIR)) != 0 ||
(ret = cosem_setUInt16(e->value.byteArr, lp4.intVS)) != 0 ||
(ret = cosem_setInt32(e->value.byteArr, lp4.instIS)) != 0 ||
(ret = cosem_setUInt16(e->value.byteArr, lp4.intVT)) != 0 ||
(ret = cosem_setInt32(e->value.byteArr, lp4.instIT)) != 0 ||
(ret = cosem_setInt32(e->value.byteArr, lp4.intIRST)) != 0 ||
(ret = cosem_setInt32(e->value.byteArr, lp4.instIN)) != 0 ||
(ret = cosem_setUInt32(e->value.byteArr, lp4.instEFC)) != 0 ||
(ret = cosem_setInt32(e->value.byteArr, lp4.instPRST)) != 0 ||
(ret = cosem_setInt32(e->value.byteArr, lp4.instPR)) != 0 ||
(ret = cosem_setInt32(e->value.byteArr, lp4.instPS)) != 0 ||
(ret = cosem_setInt32(e->value.byteArr, lp4.instPT)) != 0 ||
(ret = cosem_setInt32(e->value.byteArr, lp4.instQRST)) != 0 ||
(ret = cosem_setInt32(e->value.byteArr, lp4.instQR)) != 0 ||
(ret = cosem_setInt32(e->value.byteArr, lp4.instQS)) != 0 ||
(ret = cosem_setInt32(e->value.byteArr, lp4.instQT)) != 0 ||
(ret = cosem_setUInt16(e->value.byteArr, lp4.instPF)) != 0 ||
(ret = cosem_setUInt16(e->value.byteArr, lp4.instPFR)) != 0 ||
(ret = cosem_setUInt16(e->value.byteArr, lp4.instPFS)) != 0 ||
(ret = cosem_setUInt16(e->value.byteArr, lp4.instPFT)) != 0 ||
(ret = cosem_setUInt8(e->value.byteArr, lp4.instPhase)) != 0 ||
(ret = cosem_setUInt32(e->value.byteArr, lp4.instAngU1)) != 0 ||
(ret = cosem_setUInt32(e->value.byteArr, lp4.instAngU2)) != 0 ||
(ret = cosem_setUInt32(e->value.byteArr, lp4.instAngU3)) != 0 ||
(ret = cosem_setUInt32(e->value.byteArr, lp4.instAngI1)) != 0 ||
(ret = cosem_setUInt32(e->value.byteArr, lp4.instAngI2)) != 0 ||
(ret = cosem_setUInt32(e->value.byteArr, lp4.instAngI3)) != 0 ||
(ret = cosem_setUInt32(e->value.byteArr, lp4.instAngIN)) != 0 ||
(ret = cosem_setUInt32(e->value.byteArr, lp4.instAngEF)))
{
//Error is handled later.
}
}
else if (type == OSC_PROFILE)
{
readEntry(&profileMem[OSC_PROFILE],&lp5,pos);
time_initUnix(&tm, lp5.time);
time_initUnix(&tm2, lp5.timestamp);
if ((ret = cosem_setStructure(e->value.byteArr, 9)) != 0 ||
(ret = cosem_setDateTimeAsOctetString(e->value.byteArr, &tm)) != 0 ||
(ret = cosem_setUInt8(e->value.byteArr, lp5.status)) != 0 ||
(ret = cosem_setDateTimeAsOctetString(e->value.byteArr, &tm2)) != 0 ||
(ret = cosem_setUInt16(e->value.byteArr, lp5.freq)) != 0 ||
(ret = cosem_setUInt16(e->value.byteArr, lp5.samples)) != 0 ||
(ret = cosem_setUInt16(e->value.byteArr, lp5.refV)) != 0 ||
(ret = cosem_setUInt16(e->value.byteArr, lp5.trafoNUM)) != 0 ||
(ret = cosem_setUInt16(e->value.byteArr, lp5.trafoDEN)) != 0 ||
(ret = cosem_setVariant(e->value.byteArr, &lp5.OscWave)))
{
//Error is handled later.
}
}
else if (type == DEVTEMP_PROFILE)
{
readEntry(&profileMem[DEVTEMP_PROFILE],(uint8_t *)&lp6,pos);
time_initUnix(&tm, lp6.time);
if ((ret = cosem_setStructure(e->value.byteArr, 3)) != 0 ||
(ret = cosem_setDateTimeAsOctetString(e->value.byteArr, &tm)) != 0 ||
(ret = cosem_setUInt8(e->value.byteArr, lp6.status)) != 0 ||
(ret = cosem_setInt16(e->value.byteArr, lp6.temp)))
{
//Error is handled later.
}
}
else if (type == INSTVAL_1_PROFILE)
{
lp7.time = time_current();
time_initUnix(&tm, lp7.time);
if ((ret = cosem_setStructure(e->value.byteArr, 31)) != 0 ||
(ret = cosem_setDateTimeAsOctetString(e->value.byteArr, &tm)) != 0 ||
(ret = cosem_setUInt16(e->value.byteArr, instantVR.value.uiVal)) != 0 ||
(ret = cosem_setInt32(e->value.byteArr, instantIR.value.lVal)) != 0 ||
(ret = cosem_setUInt16(e->value.byteArr, instantVS.value.uiVal)) != 0 ||
(ret = cosem_setInt32(e->value.byteArr, instantIS.value.lVal)) != 0 ||
(ret = cosem_setUInt16(e->value.byteArr, instantVT.value.uiVal)) != 0 ||
(ret = cosem_setInt32(e->value.byteArr, instantIT.value.lVal)) != 0 ||
(ret = cosem_setInt32(e->value.byteArr, instantIRST.value.lVal)) != 0 ||
(ret = cosem_setInt32(e->value.byteArr, instantIN.value.lVal)) != 0 ||
(ret = cosem_setUInt32(e->value.byteArr, instantEFC.value.ulVal)) != 0 ||
(ret = cosem_setInt32(e->value.byteArr, instantPRST.value.lVal)) != 0 ||
(ret = cosem_setInt32(e->value.byteArr, instantPR.value.lVal)) != 0 ||
(ret = cosem_setInt32(e->value.byteArr, instantPS.value.lVal)) != 0 ||
(ret = cosem_setInt32(e->value.byteArr, instantPT.value.lVal)) != 0 ||
(ret = cosem_setInt32(e->value.byteArr, instantQRST.value.lVal)) != 0 ||
(ret = cosem_setInt32(e->value.byteArr, instantQR.value.lVal)) != 0 ||
(ret = cosem_setInt32(e->value.byteArr, instantQS.value.lVal)) != 0 ||
(ret = cosem_setInt32(e->value.byteArr, instantQT.value.lVal)) != 0 ||
(ret = cosem_setUInt16(e->value.byteArr, instantPF.value.uiVal)) != 0 ||
(ret = cosem_setUInt16(e->value.byteArr, instantPFR.value.uiVal)) != 0 ||
(ret = cosem_setUInt16(e->value.byteArr, instantPFS.value.uiVal)) != 0 ||
(ret = cosem_setUInt16(e->value.byteArr, instantPFT.value.uiVal)) != 0 ||
(ret = cosem_setUInt8(e->value.byteArr, instantEFC.value.bVal)) != 0 ||
(ret = cosem_setUInt32(e->value.byteArr, phaseAngleFI_U1.value.uiVal)) != 0 ||
(ret = cosem_setUInt32(e->value.byteArr, phaseAngleFI_U2.value.uiVal)) != 0 ||
(ret = cosem_setUInt32(e->value.byteArr, phaseAngleFI_U3.value.uiVal)) != 0 ||
(ret = cosem_setUInt32(e->value.byteArr, phaseAngleFI_I1.value.uiVal)) != 0 ||
(ret = cosem_setUInt32(e->value.byteArr, phaseAngleFI_I2.value.uiVal)) != 0 ||
(ret = cosem_setUInt32(e->value.byteArr, phaseAngleFI_I3.value.uiVal)) != 0 ||
(ret = cosem_setUInt32(e->value.byteArr, phaseAngleFI_IN.value.uiVal)) != 0 ||
(ret = cosem_setUInt32(e->value.byteArr, phaseAngleFI_EF.value.uiVal)))
{
//Error is handled later.
}
}
else if (type == EVSTD_PROFILE)
{
readEntry(&profileMem[EVSTD_PROFILE],&lp8,pos);
time_initUnix(&tm, lp8.time);
if ((ret = cosem_setStructure(e->value.byteArr, 3)) != 0 ||
(ret = cosem_setDateTimeAsOctetString(e->value.byteArr, &tm)) != 0 ||
(ret = cosem_setUInt8(e->value.byteArr, lp8.evID)) != 0 ||
(ret = cosem_setUInt16(e->value.byteArr, lp8.evCode)))
{
//Error is handled later.
}
}
else if (type == EVCMN_PROFILE)
{
readEntry(&profileMem[EVCMN_PROFILE],&lp9,pos);
time_initUnix(&tm, lp9.time);
if ((ret = cosem_setStructure(e->value.byteArr, 4)) != 0 ||
(ret = cosem_setDateTimeAsOctetString(e->value.byteArr, &tm)) != 0 ||
(ret = cosem_setUInt8(e->value.byteArr, lp9.evID)) != 0 ||
(ret = cosem_setUInt8(e->value.byteArr, lp9.evCode)) != 0 ||
(ret = cosem_setVariant(e->value.byteArr, &lp9.usrID)))
{
//Error is handled later.
}
}
else if (type == EVSYNC_PROFILE)
{
readEntry(&profileMem[EVSYNC_PROFILE],&lp10,pos);
time_initUnix(&tm, lp10.time);
if ((ret = cosem_setStructure(e->value.byteArr, 3)) != 0 ||
(ret = cosem_setDateTimeAsOctetString(e->value.byteArr, &tm)) != 0 ||
(ret = cosem_setUInt8(e->value.byteArr, lp10.evCode)) != 0 ||
(ret = cosem_setUInt8(e->value.byteArr, lp10.evID)))
{
//Error is handled later.
}
}
else if (type == EVSECURITY_PROFILE)
{
readEntry(&profileMem[EVSECURITY_PROFILE],&lp11,pos);
time_initUnix(&tm, lp11.time);
if ((ret = cosem_setStructure(e->value.byteArr, 8)) != 0 ||
(ret = cosem_setDateTimeAsOctetString(e->value.byteArr, &tm)) != 0 ||
(ret = cosem_setUInt8(e->value.byteArr, lp11.evCode)) != 0 ||
(ret = cosem_setUInt8(e->value.byteArr, lp11.evID)) != 0 ||
(ret = cosem_setVariant(e->value.byteArr, lp11.usrID)) != 0 ||
(ret = cosem_setVariant(e->value.byteArr, lp11.AccsType)) != 0 ||
(ret = cosem_setVariant(e->value.byteArr, lp11.AccsName)) != 0 ||
(ret = cosem_setVariant(e->value.byteArr, lp11.AccsOld)) != 0 ||
(ret = cosem_setVariant(e->value.byteArr, lp11.AccsNew)))
{
//Error is handled later.
}
}
else if (type == EVBLOWNFUSE_PROFILE)
{
readEntry(&profileMem[EVBLOWNFUSE_PROFILE],&lp12,pos);
time_initUnix(&tm, lp12.time);
if ((ret = cosem_setStructure(e->value.byteArr, 12)) != 0 ||
(ret = cosem_setDateTimeAsOctetString(e->value.byteArr, &tm)) != 0 ||
(ret = cosem_setUInt8(e->value.byteArr, lp12.evCode)) != 0 ||
(ret = cosem_setUInt8(e->value.byteArr, lp12.evID)) != 0 ||
(ret = cosem_setInt32(e->value.byteArr, lp12.maxIRBF)) != 0 ||
(ret = cosem_setInt32(e->value.byteArr, lp12.maxISBF)) != 0 ||
(ret = cosem_setInt32(e->value.byteArr, lp12.maxITBF)) != 0 ||
(ret = cosem_setInt32(e->value.byteArr, lp12.maxIR3OL)) != 0 ||
(ret = cosem_setInt32(e->value.byteArr, lp12.maxIS3OL)) != 0 ||
(ret = cosem_setInt32(e->value.byteArr, lp12.maxIT3OL)) != 0 ||
(ret = cosem_setVariant(e->value.byteArr, lp12.evBFAct)) != 0 ||
(ret = cosem_setVariant(e->value.byteArr, lp12.evBFActEv)) != 0 ||
(ret = cosem_setUInt16(e->value.byteArr, lp12.refV)))
{
//Error is handled later.
}
}
else if (type == EVOVERCUR_PROFILE)
{
readEntry(&profileMem[EVOVERCUR_PROFILE],&lp13,pos);
time_initUnix(&tm, lp13.time);
if ((ret = cosem_setStructure(e->value.byteArr, 15)) != 0 ||
(ret = cosem_setDateTimeAsOctetString(e->value.byteArr, &tm)) != 0 ||
(ret = cosem_setUInt8(e->value.byteArr, lp13.evCode)) != 0 ||
(ret = cosem_setUInt8(e->value.byteArr, lp13.evID)) != 0 ||
(ret = cosem_setInt32(e->value.byteArr, lp13.instI2R)) != 0 ||
(ret = cosem_setInt32(e->value.byteArr, lp13.instI2S)) != 0 ||
(ret = cosem_setInt32(e->value.byteArr, lp13.instI2T)) != 0 ||
(ret = cosem_setInt32(e->value.byteArr, lp13.instIR)) != 0 ||
(ret = cosem_setInt32(e->value.byteArr, lp13.instIS)) != 0 ||
(ret = cosem_setInt32(e->value.byteArr, lp13.instIT)) != 0 ||
(ret = cosem_setInt32(e->value.byteArr, lp13.maxIR)) != 0 ||
(ret = cosem_setInt32(e->value.byteArr, lp13.maxIS)) != 0 ||
(ret = cosem_setInt32(e->value.byteArr, lp13.maxIT)) != 0 ||
(ret = cosem_setVariant(e->value.byteArr, lp13.evOCAct)) != 0 ||
(ret = cosem_setVariant(e->value.byteArr, lp13.evOCActEv)) != 0 ||
(ret = cosem_setUInt16(e->value.byteArr, lp13.refV)))
{
//Error is handled later.
}

}
else if (type == EVOVERLOAD_PROFILE)
{
readEntry(&profileMem[EVOVERLOAD_PROFILE],&lp14,pos);
time_initUnix(&tm, lp14.time);
if ((ret = cosem_setStructure(e->value.byteArr, 14)) != 0 ||
(ret = cosem_setDateTimeAsOctetString(e->value.byteArr, &tm)) != 0 ||
(ret = cosem_setUInt8(e->value.byteArr, lp14.evCode)) != 0 ||
(ret = cosem_setUInt8(e->value.byteArr, lp14.evID)) != 0 ||
(ret = cosem_setInt32(e->value.byteArr, lp14.avgI2R)) != 0 ||
(ret = cosem_setInt32(e->value.byteArr, lp14.avgI2S)) != 0 ||
(ret = cosem_setInt32(e->value.byteArr, lp14.avgI2T)) != 0 ||
(ret = cosem_setInt32(e->value.byteArr, lp14.avgIR)) != 0 ||
(ret = cosem_setInt32(e->value.byteArr, lp14.avgIS)) != 0 ||
(ret = cosem_setInt32(e->value.byteArr, lp14.avgIT)) != 0 ||
(ret = cosem_setInt32(e->value.byteArr, lp14.maxIR)) != 0 ||
(ret = cosem_setInt32(e->value.byteArr, lp14.maxIS)) != 0 ||
(ret = cosem_setInt32(e->value.byteArr, lp14.maxIT)) != 0 ||
(ret = cosem_setVariant(e->value.byteArr, lp14.evOLActEv)) != 0 ||
(ret = cosem_setUInt16(e->value.byteArr, lp14.refV)))
{
//Error is handled later.
}
}
else if (type == ALARM_PROFILE)
{
readEntry(&profileMem[ALARM_PROFILE],&lp15,pos);
time_initUnix(&tm, lp15.time);
if ((ret = cosem_setStructure(e->value.byteArr, 2)) != 0 ||
(ret = cosem_setDateTimeAsOctetString(e->value.byteArr, &tm)) != 0 ||
(ret = cosem_setUInt32(e->value.byteArr, lp15.alarm)) != 0)
{
//Error is handled later.
}
}
if (ret != 0)
{
//Don't set error if PDU is full,
if (ret == DLMS_ERROR_CODE_OUTOFMEMORY)
{
--e->transactionStartIndex;
e->value.byteArr->size = pduSize;
ret = 0;
}
else
{
break;
}
break;
}
++e->transactionStartIndex;
}
}
return ret;
}

  • Log in or register to post comments
  • Create new account
  • Reset your password

Hire Us!

Latest Releases

  • Wed, 07/09/2025 - 16:41
    Gurux.Serial.Android 2.0.13
  • Wed, 07/09/2025 - 12:07
    gurux.dlms.c 9.0.2507.0901
  • Sat, 07/05/2025 - 15:04
    Gurux.DLMS.Python 1.0.188
  • Tue, 07/01/2025 - 10:09
    Gurux.DLMS.Python 1.0.187
  • Tue, 07/01/2025 - 09:54
    gurux.dlms.c 9.0.2507.0101

New forum topics

  • DLMS communication issue when routing through VPN on Android
  • ESP32-Based Smart Meter Interface via DLMS/COSEM
  • svr_postWrite: args->size Always Zero
  • DLMS over LoraWan in water metering
  • Update High password - any way to cipher new password
More
RSS feed
Privacy FAQ GXDN Issues Contact
Follow Gurux on Twitter Follow Gurux on Linkedin