static MmsValue* getOperParameterCtlNum(MmsValue* operParameters) { if (MmsValue_getType(operParameters) == MMS_STRUCTURE) { if (MmsValue_getArraySize(operParameters) == 7) return MmsValue_getElement(operParameters, 3); else if (MmsValue_getArraySize(operParameters) == 6) return MmsValue_getElement(operParameters, 2); } return NULL; }
static MmsValue* getCancelParameterOrigin(MmsValue* operParameters) { if (MmsValue_getType(operParameters) == MMS_STRUCTURE) { if (MmsValue_getArraySize(operParameters) == 6) return MmsValue_getElement(operParameters, 2); else if (MmsValue_getArraySize(operParameters) == 5) return MmsValue_getElement(operParameters, 1); } return NULL; }
static int encodeArrayAccessResult(MmsValue* value, uint8_t* buffer, int bufPos, bool encode) { int elementsSize = 0; int i; int arraySize = MmsValue_getArraySize(value); for (i = 0; i < arraySize; i++) { MmsValue* element = MmsValue_getElement(value, i); elementsSize += mmsServer_encodeAccessResult(element, NULL, 0, false); } if (encode) { buffer[bufPos++] = 0xa1; /* tag for array */ bufPos = BerEncoder_encodeLength(elementsSize, buffer, bufPos); for (i = 0; i < arraySize; i++) { MmsValue* element = MmsValue_getElement(value, i); bufPos = mmsServer_encodeAccessResult(element, buffer, bufPos, true); } return bufPos; } else { int size = 1 + elementsSize + BerEncoder_determineLengthSize(elementsSize); return size; } }
//INFO: function can be removed if no certification is required static bool checkValidityOfOriginParameter(MmsValue* origin) { if (MmsValue_getType(origin) != MMS_STRUCTURE) return false; if (MmsValue_getArraySize(origin) != 2) return false; MmsValue* orIdent = MmsValue_getElement(origin, 1); if (MmsValue_getType(orIdent) != MMS_OCTET_STRING) return false; if (MmsValue_getOctetStringSize(orIdent) > 64) return false; MmsValue* orCat = MmsValue_getElement(origin, 0); if (MmsValue_getType(orCat) != MMS_INTEGER) return false; int orCatIntValue = MmsValue_toInt32(orCat); if ((orCatIntValue < 0) || (orCatIntValue > 8)) return false; return true; }
static bool private_ClientGooseControlBlock_updateValues(ClientGooseControlBlock self, MmsValue* values) { int elementCount = MmsValue_getArraySize(values); if (elementCount > 5) { updateOrClone(&(self->goEna), values, 0); updateOrClone(&(self->goID), values, 1); updateOrClone(&(self->datSet), values, 2); updateOrClone(&(self->confRev), values, 3); updateOrClone(&(self->ndsCom), values, 4); updateOrClone(&(self->dstAddress), values, 5); } else return false; if (elementCount > 6) updateOrClone(&(self->minTime), values, 6); if (elementCount > 7) updateOrClone(&(self->maxTime), values, 7); if (elementCount > 8) updateOrClone(&(self->fixedOffs), values, 8); return true; }
int ClientDataSet_getDataSetSize(ClientDataSet self) { if (self->dataSetValues != NULL) { return MmsValue_getArraySize(self->dataSetValues); } else return 0; }
static MmsValue* getOperParameterTime(MmsValue* operParameters) { MmsValue* timeParameter = NULL; if (MmsValue_getType(operParameters) == MMS_STRUCTURE) { if (MmsValue_getArraySize(operParameters) == 7) timeParameter = MmsValue_getElement(operParameters, 4); else if (MmsValue_getArraySize(operParameters) == 6) timeParameter = MmsValue_getElement(operParameters, 3); } if (timeParameter != NULL) if ((MmsValue_getType(timeParameter) == MMS_UTC_TIME) || (MmsValue_getType(timeParameter) == MMS_BINARY_TIME)) return timeParameter; return NULL; }
static MmsValue* getCtlVal(MmsValue* operParameters) { if (MmsValue_getType(operParameters) == MMS_STRUCTURE) { if (MmsValue_getArraySize(operParameters) > 5) { return MmsValue_getElement(operParameters, 0); } } return NULL; }
static MmsValue* getOperParameterOperTime(MmsValue* operParameters) { if (MmsValue_getType(operParameters) == MMS_STRUCTURE) { if (MmsValue_getArraySize(operParameters) == 7) return MmsValue_getElement(operParameters, 1); } return NULL; }
bool private_ClientReportControlBlock_updateValues(ClientReportControlBlock self, MmsValue* values) { int rcbElementCount = MmsValue_getArraySize(values); updateOrClone(&(self->rptId), values, 0); updateOrClone(&(self->rptEna), values, 1); if (self->isBuffered) { updateOrClone(&(self->datSet), values, 2); updateOrClone(&(self->confRev), values, 3); updateOrClone(&(self->optFlds), values, 4); updateOrClone(&(self->bufTm), values, 5); updateOrClone(&(self->sqNum), values, 6); updateOrClone(&(self->trgOps), values,7); updateOrClone(&(self->intgPd), values, 8); updateOrClone(&(self->gi), values, 9); updateOrClone(&(self->purgeBuf), values, 10); updateOrClone(&(self->entryId), values, 11); updateOrClone(&(self->timeOfEntry), values, 12); if (rcbElementCount > 13) { MmsValue* element13 = MmsValue_getElement(values, 13); if (MmsValue_getType(element13) == MMS_OCTET_STRING) updateOrClone(&(self->owner), values, 13); else { updateOrClone(&(self->resvTms), values, 13); if (rcbElementCount > 14) updateOrClone(&(self->owner), values, 14); } } } else { updateOrClone(&(self->resv), values, 2); updateOrClone(&(self->datSet), values, 3); updateOrClone(&(self->confRev), values, 4); updateOrClone(&(self->optFlds), values, 5); updateOrClone(&(self->bufTm), values, 6); updateOrClone(&(self->sqNum), values, 7); updateOrClone(&(self->trgOps), values, 8); updateOrClone(&(self->intgPd), values, 9); updateOrClone(&(self->gi), values, 10); if (rcbElementCount == 12) /* owner is optional */ updateOrClone(&(self->owner), values, 11); } return true; }
Data_t* mmsMsg_createBasicDataElement(MmsValue* value) { Data_t* dataElement = (Data_t*) GLOBAL_CALLOC(1, sizeof(Data_t)); switch (value->type) { case MMS_ARRAY: { int size = MmsValue_getArraySize(value); dataElement->present = Data_PR_array; dataElement->choice.array = (DataSequence_t*) GLOBAL_CALLOC(1, sizeof(DataSequence_t)); dataElement->choice.array->list.count = size; dataElement->choice.array->list.size = size; dataElement->choice.array->list.array = (Data_t**) GLOBAL_CALLOC(size, sizeof(Data_t*)); int i; for (i = 0; i < size; i++) { dataElement->choice.array->list.array[i] = mmsMsg_createBasicDataElement(MmsValue_getElement(value, i)); } } break; case MMS_STRUCTURE: { int size = value->value.structure.size; dataElement->present = Data_PR_structure; dataElement->choice.structure = (DataSequence_t*) GLOBAL_CALLOC(1, sizeof(DataSequence_t)); dataElement->choice.structure->list.count = size; dataElement->choice.structure->list.size = size; dataElement->choice.structure->list.array = (Data_t**) GLOBAL_CALLOC(size, sizeof(Data_t*)); int i; for (i = 0; i < size; i++) { dataElement->choice.structure->list.array[i] = mmsMsg_createBasicDataElement( value->value.structure.components[i]); } } break; case MMS_BIT_STRING: { dataElement->present = Data_PR_bitstring; dataElement->choice.bitstring.buf = value->value.bitString.buf; int size = (value->value.bitString.size / 8) + ((value->value.bitString.size % 8) > 0); int unused = 8 - (value->value.bitString.size % 8); dataElement->choice.bitstring.size = size; /* size in bytes */ dataElement->choice.bitstring.bits_unused = unused; } break; case MMS_BOOLEAN: dataElement->present = Data_PR_boolean; dataElement->choice.boolean = value->value.boolean; break; case MMS_FLOAT: dataElement->present = Data_PR_floatingpoint; mmsMsg_createFloatData(value, &dataElement->choice.floatingpoint.size, &dataElement->choice.floatingpoint.buf); break; case MMS_UTC_TIME: dataElement->present = Data_PR_utctime; dataElement->choice.utctime.buf = (uint8_t*) GLOBAL_MALLOC(8); memcpy(dataElement->choice.utctime.buf, value->value.utcTime, 8); dataElement->choice.utctime.size = 8; break; case MMS_INTEGER: dataElement->present = Data_PR_integer; dataElement->choice.integer.size = value->value.integer->size; dataElement->choice.integer.buf = value->value.integer->octets; break; case MMS_UNSIGNED: dataElement->present = Data_PR_unsigned; dataElement->choice.Unsigned.size = value->value.integer->size; dataElement->choice.Unsigned.buf = value->value.integer->octets; break; case MMS_VISIBLE_STRING: dataElement->present = Data_PR_visiblestring; if (value->value.visibleString.buf != NULL ) { dataElement->choice.visiblestring.buf = (uint8_t*) value->value.visibleString.buf; dataElement->choice.visiblestring.size = strlen(value->value.visibleString.buf); } else dataElement->choice.visiblestring.size = 0; break; case MMS_OCTET_STRING: dataElement->present = Data_PR_octetstring; if (value->value.octetString.buf != NULL ) { dataElement->choice.octetstring.buf = value->value.octetString.buf; dataElement->choice.octetstring.size = value->value.octetString.size; } else dataElement->choice.octetstring.size = 0; break; case MMS_STRING: dataElement->present = Data_PR_mMSString; if (value->value.visibleString.buf != NULL ) { dataElement->choice.mMSString.buf = (uint8_t*) value->value.visibleString.buf; dataElement->choice.mMSString.size = strlen(value->value.visibleString.buf); } else dataElement->choice.mMSString.size = 0; break; case MMS_BINARY_TIME: dataElement->present = Data_PR_binarytime; dataElement->choice.binarytime.size = value->value.binaryTime.size; dataElement->choice.binarytime.buf = value->value.binaryTime.buf; break; default: dataElement->present = Data_PR_NOTHING; break; } return dataElement; }
static int parseAllData(uint8_t* buffer, int allDataLength, MmsValue* dataSetValues) { int bufPos = 0; int elementLength = 0; int elementIndex = 0; int maxIndex = MmsValue_getArraySize(dataSetValues) - 1; while (bufPos < allDataLength) { uint8_t tag = buffer[bufPos++]; if (elementIndex > maxIndex) { if (DEBUG_GOOSE_SUBSCRIBER) printf("GOOSE_SUBSCRIBER: Malformed message: too much elements!\n"); return 0; } MmsValue* value = MmsValue_getElement(dataSetValues, elementIndex); bufPos = BerDecoder_decodeLength(buffer, &elementLength, bufPos, allDataLength); if (bufPos + elementLength > allDataLength) { if (DEBUG_GOOSE_SUBSCRIBER) printf("GOOSE_SUBSCRIBER: Malformed message: sub element is too large!\n"); return 0; } switch (tag) { case 0x80: /* reserved for access result */ printf("GOOSE_SUBSCRIBER: found reserved value (tag 0x80)!\n"); break; case 0xa1: /* array */ if (DEBUG_GOOSE_SUBSCRIBER) printf("GOOSE_SUBSCRIBER: found array\n"); if (MmsValue_getType(value) == MMS_ARRAY) { if (!parseAllData(buffer + bufPos, elementLength, value)) return -1; } break; case 0xa2: /* structure */ if (DEBUG_GOOSE_SUBSCRIBER) printf("GOOSE_SUBSCRIBER: found structure\n"); if (MmsValue_getType(value) == MMS_STRUCTURE) { if (!parseAllData(buffer + bufPos, elementLength, value)) return -1; } break; case 0x83: /* boolean */ if (DEBUG_GOOSE_SUBSCRIBER) printf("GOOSE_SUBSCRIBER: found boolean\n"); if (MmsValue_getType(value) == MMS_BOOLEAN) { MmsValue_setBoolean(value, BerDecoder_decodeBoolean(buffer, bufPos)); } else if (DEBUG_GOOSE_SUBSCRIBER) printf("GOOSE_SUBSCRIBER: message contains value of wrong type!\n"); break; case 0x84: /* BIT STRING */ if (MmsValue_getType(value) == MMS_BIT_STRING) { int padding = buffer[bufPos]; int bitStringLength = (8 * (elementLength - 1)) - padding; if (bitStringLength == value->value.bitString.size) { memcpy(value->value.bitString.buf, buffer + bufPos + 1, elementLength - 1); } else if (DEBUG_GOOSE_SUBSCRIBER) printf("bit-string is of wrong size"); } break; case 0x85: /* integer */ if (MmsValue_getType(value) == MMS_INTEGER) { if (elementLength <= value->value.integer->maxSize) { value->value.integer->size = elementLength; memcpy(value->value.integer->octets, buffer + bufPos, elementLength); } } break; case 0x86: /* unsigned integer */ if (MmsValue_getType(value) == MMS_UNSIGNED) { if (elementLength <= value->value.integer->maxSize) { value->value.integer->size = elementLength; memcpy(value->value.integer->octets, buffer + bufPos, elementLength); } } break; case 0x87: /* Float */ if (MmsValue_getType(value) == MMS_FLOAT) { if (elementLength == 9) { MmsValue_setDouble(value, BerDecoder_decodeDouble(buffer, bufPos)); } else if (elementLength == 5) { MmsValue_setFloat(value, BerDecoder_decodeFloat(buffer, bufPos)); } } break; case 0x89: /* octet string */ if (MmsValue_getType(value) == MMS_OCTET_STRING) { if (elementLength <= value->value.octetString.maxSize) { value->value.octetString.size = elementLength; memcpy(value->value.octetString.buf, buffer + bufPos, elementLength); } } break; case 0x8a: /* visible string */ if (MmsValue_getType(value) == MMS_VISIBLE_STRING) { if (value->value.visibleString.buf != NULL) { if ((int32_t) value->value.visibleString.size >= elementLength) { memcpy(value->value.visibleString.buf, buffer + bufPos, elementLength); value->value.visibleString.buf[elementLength] = 0; } else { GLOBAL_FREEMEM(value->value.visibleString.buf); createNewStringFromBufferElement(value, buffer + bufPos, elementLength); } } else createNewStringFromBufferElement(value, buffer + bufPos, elementLength); } break; case 0x8c: /* binary time */ if (MmsValue_getType(value) == MMS_BINARY_TIME) { if ((elementLength == 4) || (elementLength == 6)) { memcpy(value->value.binaryTime.buf, buffer + bufPos, elementLength); } } break; case 0x91: /* Utctime */ if (elementLength == 8) { if (MmsValue_getType(value) == MMS_UTC_TIME) { MmsValue_setUtcTimeByBuffer(value, buffer + bufPos); } else if (DEBUG_GOOSE_SUBSCRIBER) printf("GOOSE_SUBSCRIBER: message contains value of wrong type!\n"); } else if (DEBUG_GOOSE_SUBSCRIBER) printf("GOOSE_SUBSCRIBER: UTCTime element is of wrong size!\n"); break; default: if (DEBUG_GOOSE_SUBSCRIBER) printf("GOOSE_SUBSCRIBER: found unkown tag %02x\n", tag); break; } bufPos += elementLength; elementIndex++; } return 1; }