Hello,
I have a DLMS server running on a 32-bit MCU and a DLMS host also running on a 32-bit MCU, communicating via PLC. Both work correctly: I have created several objects on the server and can successfully connect, get the association view, perform read/write operations, and close the connection properly.
The issue begins when I define a new object called uInvControl. When I perform a read operation, everything works correctly — I’m able to read the object and receive its data without any problems. But when i perform a write operation:
C1 01 C1 00 01 01 00 2A 00 05 FF 02 00 0A 05 00 00 00 00 00
<SetRequest>
<SetRequestNormal>
<!--Priority: HIGH ServiceClass: CONFIRMED invokeID: 1-->
<InvokeIdAndPriority Value="C1" />
<AttributeDescriptor>
<!--DATA-->
<ClassId Value="0001" />
<!--1.0.42.0.5.255-->
<InstanceId Value="01002A0005FF" />
<AttributeId Value="02" />
</AttributeDescriptor>
<Value>
<String Value="
I receive from the server "ReadWriteDenied":
C5 01 C1 03
<SetResponse>
<SetResponseNormal>
<!--Priority: HIGH ServiceClass: CONFIRMED invokeID: 1-->
<InvokeIdAndPriority Value="C1" />
<Result Value="ReadWriteDenied" />
</SetResponseNormal>
</SetResponse>
To give some context, here are the more relevants parts about this object on the server.
I add this object to my list as follows:
gxObject* ALL_OBJECTS[] = { BASE(associationLow), BASE(myDATA), BASE(pvPower1), BASE(pvPower2), BASE(pvPower3), BASE(pvPower4), BASE(uInvControl) };
And I register the object using this function:
int addDataObject()
{
int ret;
const unsigned char ln[6] = { 1, 0, 99, 199, 0, 255 }; // myDATA
const unsigned char ln1[6] = { 1, 0, 42, 0, 5, 255 }; // uInvControl
if ((ret = INIT_OBJECT(myDATA, DLMS_OBJECT_TYPE_DATA, ln)) == 0 &&
(ret = INIT_OBJECT(uInvControl, DLMS_OBJECT_TYPE_DATA, ln1)) == 0)
{
GX_STRING(myDATA.value, (uint8_t*)myDATAValue, sizeof(myDATAValue));
GX_STRING(uInvControl.value, (uint8_t*)uInvControlValue, sizeof(uInvControlValue));
}
return ret;
}
In the svr_getAttributeAccess() function, I'm correctly configuring the object access as DLMS_ACCESS_MODE_READ_WRITE.
After debugging deeply, I identified the root cause. In the dlms.c file, within the getString() function:
int getString(gxByteBuffer* buff, gxDataInfo* info, unsigned char knownType, dlmsVARIANT* value)
The issue occurs because value->capacity < len, which causes it to return DLMS_ERROR_CODE_OUTOFMEMORY. This error then propagates through the server.c file in the svr_handleSetRequest() function, resulting in:
p.status = DLMS_ERROR_CODE_READ_WRITE_DENIED;
I've also tried using GXDLMS Director as a host, and the same issue occurs:
"Exception Response: Service not allowed"
Could you please advise on how to solve this issue?
Thank you so much.
Pablo
Hi Pablo, How have you…
Hi Pablo,
How have you defined myDATAValue?
Remove also uint8_t*. The compiler doesn't know the myDATAValue capacity if you cast it to uint8_t*.
GX_STRING(myDATA.value, myDATAValue, sizeof(myDATAValue));
BR,
Mikko
Hello Kurumi, Thank you very…
Hello Kurumi,
Thank you very much for your reply.
Apparently, the cast to uint8_t was the problem. Now I’m able to set/get the uinvControl variable.
Best regards,
Pablo