- improved MmsValue handling; fixed MmsValue(OCTET-STRIG) maximum size problem (LIB61850-150)

pull/383/head
Michael Zillgith 3 years ago
parent 9d9f03585f
commit f60ff65fc4

@ -273,7 +273,7 @@ parseAllData(uint8_t* buffer, int allDataLength, MmsValue* dataSetValues)
case 0x89: /* octet string */
if (MmsValue_getType(value) == MMS_OCTET_STRING) {
if (elementLength <= value->value.octetString.maxSize) {
if (elementLength <= abs(value->value.octetString.maxSize)) {
value->value.octetString.size = elementLength;
memcpy(value->value.octetString.buf, buffer + bufPos, elementLength);
}
@ -286,7 +286,7 @@ parseAllData(uint8_t* buffer, int allDataLength, MmsValue* dataSetValues)
uint8_t* oldBuf = value->value.octetString.buf;
value->value.octetString.buf = newBuf;
value->value.octetString.maxSize = elementLength;
value->value.octetString.maxSize = -elementLength;
value->value.octetString.size = elementLength;
GLOBAL_FREEMEM(oldBuf);

@ -45,7 +45,7 @@ struct ATTRIBUTE_PACKED sMmsValue {
} floatingPoint;
struct {
uint16_t size;
uint16_t maxSize;
int maxSize;
uint8_t* buf;
} octetString;
struct {

@ -331,7 +331,7 @@ mmsClient_parseListOfAccessResults(AccessResult_t** accessResultList, int listSi
if (size >= 0) {
value = (MmsValue*) GLOBAL_CALLOC(1, sizeof(MmsValue));
value->type = MMS_OCTET_STRING;
value->value.octetString.maxSize = size;
value->value.octetString.maxSize = -size;
value->value.octetString.size = size;
value->value.octetString.buf = (uint8_t*) GLOBAL_MALLOC(size);
memcpy(value->value.octetString.buf, accessResultList[i]->choice.octetstring.buf, size);

@ -192,20 +192,22 @@ mmsMsg_parseDataElement(Data_t* dataElement)
if (componentCount > 0) {
value = (MmsValue*) GLOBAL_CALLOC(1, sizeof(MmsValue));
value->type = MMS_ARRAY;
value->value.structure.size = componentCount;
value->value.structure.components = (MmsValue**) GLOBAL_CALLOC(componentCount, sizeof(MmsValue*));
int i;
for (i = 0; i < componentCount; i++) {
value->value.structure.components[i] =
mmsMsg_parseDataElement(dataElement->choice.array->list.array[i]);
if (value->value.structure.components[i] == NULL) {
MmsValue_delete(value);
value = NULL;
break;
if (value) {
value->type = MMS_ARRAY;
value->value.structure.size = componentCount;
value->value.structure.components = (MmsValue**) GLOBAL_CALLOC(componentCount, sizeof(MmsValue*));
int i;
for (i = 0; i < componentCount; i++) {
value->value.structure.components[i] =
mmsMsg_parseDataElement(dataElement->choice.array->list.array[i]);
if (value->value.structure.components[i] == NULL) {
MmsValue_delete(value);
value = NULL;
break;
}
}
}
}
@ -222,20 +224,22 @@ mmsMsg_parseDataElement(Data_t* dataElement)
if (componentCount > 0) {
value = (MmsValue*) GLOBAL_CALLOC(1, sizeof(MmsValue));
value->type = MMS_STRUCTURE;
value->value.structure.size = componentCount;
value->value.structure.components = (MmsValue**) GLOBAL_CALLOC(componentCount, sizeof(MmsValue*));
if (value) {
value->type = MMS_STRUCTURE;
value->value.structure.size = componentCount;
value->value.structure.components = (MmsValue**) GLOBAL_CALLOC(componentCount, sizeof(MmsValue*));
int i;
int i;
for (i = 0; i < componentCount; i++) {
value->value.structure.components[i] =
mmsMsg_parseDataElement(dataElement->choice.structure->list.array[i]);
for (i = 0; i < componentCount; i++) {
value->value.structure.components[i] =
mmsMsg_parseDataElement(dataElement->choice.structure->list.array[i]);
if (value->value.structure.components[i] == NULL) {
MmsValue_delete(value);
value = NULL;
break;
if (value->value.structure.components[i] == NULL) {
MmsValue_delete(value);
value = NULL;
break;
}
}
}
}
@ -251,7 +255,8 @@ mmsMsg_parseDataElement(Data_t* dataElement)
Asn1PrimitiveValue* berInteger = BerInteger_createFromBuffer(
dataElement->choice.integer.buf, dataElement->choice.integer.size);
value = MmsValue_newIntegerFromBerInteger(berInteger);
if (berInteger)
value = MmsValue_newIntegerFromBerInteger(berInteger);
}
else {
if (DEBUG_MMS_CLIENT)
@ -264,7 +269,8 @@ mmsMsg_parseDataElement(Data_t* dataElement)
Asn1PrimitiveValue* berInteger = BerInteger_createFromBuffer(
dataElement->choice.Unsigned.buf, dataElement->choice.Unsigned.size);
value = MmsValue_newUnsignedFromBerInteger(berInteger);
if (berInteger)
value = MmsValue_newUnsignedFromBerInteger(berInteger);
}
else {
if (DEBUG_MMS_CLIENT)
@ -297,20 +303,32 @@ mmsMsg_parseDataElement(Data_t* dataElement)
if ((bitSize > 0) && (maxSize >= bitSize)) {
value = (MmsValue*) GLOBAL_CALLOC(1, sizeof(MmsValue));
value->type = MMS_BIT_STRING;
if (value) {
value->type = MMS_BIT_STRING;
value->value.bitString.size = bitSize;
value->value.bitString.size = bitSize;
value->value.bitString.buf = (uint8_t*) GLOBAL_MALLOC(size);
memcpy(value->value.bitString.buf,
dataElement->choice.bitstring.buf, size);
value->value.bitString.buf = (uint8_t*) GLOBAL_MALLOC(size);
if (value->value.bitString.buf) {
memcpy(value->value.bitString.buf,
dataElement->choice.bitstring.buf, size);
}
else {
GLOBAL_FREEMEM(value);
value = 0;
}
}
}
else if (bitSize == 0) {
value = (MmsValue*) GLOBAL_CALLOC(1, sizeof(MmsValue));
value->type = MMS_BIT_STRING;
value->value.bitString.size = 0;
value->value.bitString.buf = NULL;
if (value) {
value->type = MMS_BIT_STRING;
value->value.bitString.size = 0;
value->value.bitString.buf = NULL;
}
}
else {
if (DEBUG_MMS_CLIENT)
@ -329,35 +347,41 @@ mmsMsg_parseDataElement(Data_t* dataElement)
if (size == 5) { /* FLOAT32 */
value = (MmsValue*) GLOBAL_CALLOC(1, sizeof(MmsValue));
value->type = MMS_FLOAT;
value->value.floatingPoint.formatWidth = 32;
value->value.floatingPoint.exponentWidth = dataElement->choice.floatingpoint.buf[0];
if (value) {
value->type = MMS_FLOAT;
value->value.floatingPoint.formatWidth = 32;
value->value.floatingPoint.exponentWidth = dataElement->choice.floatingpoint.buf[0];
uint8_t* floatBuf = (dataElement->choice.floatingpoint.buf + 1);
uint8_t* floatBuf = (dataElement->choice.floatingpoint.buf + 1);
#if (ORDER_LITTLE_ENDIAN == 1)
memcpyReverseByteOrder(value->value.floatingPoint.buf, floatBuf, 4);
memcpyReverseByteOrder(value->value.floatingPoint.buf, floatBuf, 4);
#else
memcpy(value->value.floatingPoint.buf, floatBuf, 4);
memcpy(value->value.floatingPoint.buf, floatBuf, 4);
#endif
}
}
if (size == 9) { /* FLOAT64 */
value = (MmsValue*) GLOBAL_CALLOC(1, sizeof(MmsValue));
value->type = MMS_FLOAT;
value->value.floatingPoint.formatWidth = 64;
value->value.floatingPoint.exponentWidth = dataElement->choice.floatingpoint.buf[0];
if (value) {
value->type = MMS_FLOAT;
uint8_t* floatBuf = (dataElement->choice.floatingpoint.buf + 1);
value->value.floatingPoint.formatWidth = 64;
value->value.floatingPoint.exponentWidth = dataElement->choice.floatingpoint.buf[0];
uint8_t* floatBuf = (dataElement->choice.floatingpoint.buf + 1);
#if (ORDER_LITTLE_ENDIAN == 1)
memcpyReverseByteOrder(value->value.floatingPoint.buf, floatBuf, 8);
memcpyReverseByteOrder(value->value.floatingPoint.buf, floatBuf, 8);
#else
memcpy(value->value.floatingPoint.buf, floatBuf, 8);
memcpy(value->value.floatingPoint.buf, floatBuf, 8);
#endif
}
}
}
else if (dataElement->present == Data_PR_utctime) {
@ -366,8 +390,11 @@ mmsMsg_parseDataElement(Data_t* dataElement)
if (size == 8) {
value = (MmsValue*) GLOBAL_CALLOC(1, sizeof(MmsValue));
value->type = MMS_UTC_TIME;
memcpy(value->value.utcTime, dataElement->choice.utctime.buf, 8);
if (value) {
value->type = MMS_UTC_TIME;
memcpy(value->value.utcTime, dataElement->choice.utctime.buf, 8);
}
}
else {
if (DEBUG_MMS_CLIENT)
@ -378,12 +405,28 @@ mmsMsg_parseDataElement(Data_t* dataElement)
if (dataElement->choice.octetstring.size >= 0) {
value = (MmsValue*) GLOBAL_CALLOC(1, sizeof(MmsValue));
value->type = MMS_OCTET_STRING;
int size = dataElement->choice.octetstring.size;
value->value.octetString.size = size;
value->value.octetString.maxSize = size;
value->value.octetString.buf = (uint8_t*) GLOBAL_MALLOC(size);
memcpy(value->value.octetString.buf, dataElement->choice.octetstring.buf, size);
if (value) {
value->type = MMS_OCTET_STRING;
int size = dataElement->choice.octetstring.size;
value->value.octetString.size = size;
if (size > 0)
value->value.octetString.maxSize = -size;
else
value->value.octetString.maxSize = -8;
value->value.octetString.buf = (uint8_t*) GLOBAL_MALLOC(abs(value->value.octetString.maxSize));
if (value->value.octetString.buf) {
memcpy(value->value.octetString.buf, dataElement->choice.octetstring.buf, size);
}
else {
GLOBAL_FREEMEM(value);
value = NULL;
}
}
}
}
@ -392,9 +435,12 @@ mmsMsg_parseDataElement(Data_t* dataElement)
if ((size == 4) || (size == 6)) {
value = (MmsValue*) GLOBAL_CALLOC(1, sizeof(MmsValue));
value->type = MMS_BINARY_TIME;
value->value.binaryTime.size = size;
memcpy(value->value.binaryTime.buf, dataElement->choice.binarytime.buf, size);
if (value) {
value->type = MMS_BINARY_TIME;
value->value.binaryTime.size = size;
memcpy(value->value.binaryTime.buf, dataElement->choice.binarytime.buf, size);
}
}
else {
if (DEBUG_MMS_CLIENT)

@ -240,9 +240,11 @@ MmsValue_update(MmsValue* self, const MmsValue* update)
if (updateStructuredComponent(self, update) == false)
return false;
break;
case MMS_BOOLEAN:
self->value.boolean = update->value.boolean;
break;
case MMS_FLOAT:
if (self->value.floatingPoint.formatWidth == update->value.floatingPoint.formatWidth) {
self->value.floatingPoint.exponentWidth = update->value.floatingPoint.exponentWidth;
@ -252,6 +254,7 @@ MmsValue_update(MmsValue* self, const MmsValue* update)
else
return false;
break;
case MMS_INTEGER:
case MMS_UNSIGNED:
if (BerInteger_setFromBerInteger(self->value.integer, update->value.integer))
@ -259,9 +262,11 @@ MmsValue_update(MmsValue* self, const MmsValue* update)
else
return false;
break;
case MMS_UTC_TIME:
memcpy(self->value.utcTime, update->value.utcTime, 8);
break;
case MMS_BIT_STRING:
if (self->value.bitString.size == update->value.bitString.size)
memcpy(self->value.bitString.buf, update->value.bitString.buf, bitStringByteSize(self));
@ -278,40 +283,55 @@ MmsValue_update(MmsValue* self, const MmsValue* update)
else
return false;
break;
case MMS_OCTET_STRING:
{
int size = update->value.octetString.size;
if (size > self->value.octetString.maxSize) {
if ((self->value.octetString.maxSize < 0) && (size > abs(self->value.octetString.maxSize))) {
GLOBAL_FREEMEM(self->value.octetString.buf);
self->value.octetString.buf = (uint8_t*) GLOBAL_MALLOC(size);
if (self->value.octetString.buf == NULL)
return false;
self->value.octetString.maxSize = size;
if (self->value.octetString.maxSize < 0)
self->value.octetString.maxSize = -size;
else
self->value.octetString.maxSize = size;
}
memcpy(self->value.octetString.buf, update->value.octetString.buf, size);
if (size <= abs(self->value.octetString.maxSize)) {
memcpy(self->value.octetString.buf, update->value.octetString.buf, size);
self->value.octetString.size = size;
self->value.octetString.size = size;
}
else {
return false;
}
}
break;
case MMS_VISIBLE_STRING:
MmsValue_setVisibleString(self, update->value.visibleString.buf);
break;
case MMS_STRING:
MmsValue_setMmsString(self, update->value.visibleString.buf);
break;
case MMS_BINARY_TIME:
self->value.binaryTime.size = update->value.binaryTime.size;
memcpy(self->value.binaryTime.buf, update->value.binaryTime.buf,
update->value.binaryTime.size);
break;
default:
return false;
break;
}
return true;
}
else
@ -1046,7 +1066,7 @@ MmsValue_getSizeInMemory(const MmsValue* self)
break;
case MMS_OCTET_STRING:
memorySize += MemoryAllocator_getAlignedSize(self->value.octetString.maxSize);
memorySize += MemoryAllocator_getAlignedSize(abs(self->value.octetString.maxSize));
break;
case MMS_STRING:
@ -1106,8 +1126,8 @@ MmsValue_cloneToBuffer(const MmsValue* self, uint8_t* destinationAddress)
case MMS_OCTET_STRING:
newValue->value.octetString.buf = destinationAddress;
memcpy(destinationAddress, self->value.octetString.buf, self->value.octetString.maxSize);
destinationAddress += MemoryAllocator_getAlignedSize(self->value.octetString.maxSize);
memcpy(destinationAddress, self->value.octetString.buf, abs(self->value.octetString.maxSize));
destinationAddress += MemoryAllocator_getAlignedSize(abs(self->value.octetString.maxSize));
break;
case MMS_STRING:
@ -1201,7 +1221,15 @@ MmsValue_clone(const MmsValue* self)
newValue->value.bitString.size = self->value.bitString.size;
size = bitStringByteSize(self);
newValue->value.bitString.buf = (uint8_t*) GLOBAL_MALLOC(size);
memcpy(newValue->value.bitString.buf, self->value.bitString.buf, size);
if (newValue->value.bitString.buf) {
memcpy(newValue->value.bitString.buf, self->value.bitString.buf, size);
}
else {
GLOBAL_FREEMEM(newValue);
newValue = NULL;
}
break;
case MMS_BOOLEAN:
@ -1212,8 +1240,16 @@ MmsValue_clone(const MmsValue* self)
size = self->value.octetString.size;
newValue->value.octetString.size = size;
newValue->value.octetString.maxSize = self->value.octetString.maxSize;
newValue->value.octetString.buf = (uint8_t*) GLOBAL_MALLOC(self->value.octetString.maxSize);
memcpy(newValue->value.octetString.buf, self->value.octetString.buf, size);
newValue->value.octetString.buf = (uint8_t*) GLOBAL_MALLOC(abs(self->value.octetString.maxSize));
if (newValue->value.octetString.buf) {
memcpy(newValue->value.octetString.buf, self->value.octetString.buf, size);
}
else {
GLOBAL_FREEMEM(newValue);
newValue = NULL;
}
break;
case MMS_UTC_TIME:
@ -1229,8 +1265,16 @@ MmsValue_clone(const MmsValue* self)
case MMS_STRING:
size = self->value.visibleString.size;
newValue->value.visibleString.buf = (char*) GLOBAL_MALLOC(size + 1);
newValue->value.visibleString.size = size;
strcpy(newValue->value.visibleString.buf, self->value.visibleString.buf);
if (newValue->value.visibleString.buf) {
newValue->value.visibleString.size = size;
strcpy(newValue->value.visibleString.buf, self->value.visibleString.buf);
}
else {
GLOBAL_FREEMEM(newValue);
newValue = NULL;
}
break;
case MMS_DATA_ACCESS_ERROR:
@ -1409,7 +1453,7 @@ MmsValue_newOctetString(int size, int maxSize)
self->type = MMS_OCTET_STRING;
self->value.octetString.size = size;
self->value.octetString.maxSize = maxSize;
self->value.octetString.buf = (uint8_t*) GLOBAL_CALLOC(1, maxSize);
self->value.octetString.buf = (uint8_t*) GLOBAL_CALLOC(1, abs(maxSize));
if (self->value.octetString.buf == NULL) {
GLOBAL_FREEMEM(self);
@ -1423,7 +1467,7 @@ MmsValue_newOctetString(int size, int maxSize)
void
MmsValue_setOctetString(MmsValue* self, const uint8_t* buf, int size)
{
if (size <= self->value.octetString.maxSize) {
if (size <= abs(self->value.octetString.maxSize)) {
memcpy(self->value.octetString.buf, buf, size);
self->value.octetString.size = size;
}
@ -1432,7 +1476,7 @@ MmsValue_setOctetString(MmsValue* self, const uint8_t* buf, int size)
void
MmsValue_setOctetStringOctet(MmsValue* self, int octetPos, uint8_t value)
{
if ((octetPos >= 0) && (octetPos < self->value.octetString.maxSize)) {
if ((octetPos >= 0) && (octetPos < abs(self->value.octetString.maxSize))) {
self->value.octetString.buf[octetPos] = value;
if (octetPos >= self->value.octetString.size) {
@ -1450,7 +1494,7 @@ MmsValue_getOctetStringSize(const MmsValue* self)
uint16_t
MmsValue_getOctetStringMaxSize(MmsValue* self)
{
return self->value.octetString.maxSize;
return abs(self->value.octetString.maxSize);
}
uint8_t*

@ -394,7 +394,7 @@ MmsValue_getMaxEncodedSize(MmsValue* self)
size = 2 + self->value.binaryTime.size;
break;
case MMS_OCTET_STRING:
elementSize = self->value.octetString.maxSize;
elementSize = abs(self->value.octetString.maxSize);
size = 1 + BerEncoder_determineLengthSize(elementSize) + elementSize;
break;
case MMS_FLOAT:

Loading…
Cancel
Save