Data_t* mmsMsg_createDataElement(MmsValue* value) { if (value->type == MMS_STRUCTURE) { Data_t* dataElement = (Data_t*) GLOBAL_CALLOC(1, sizeof(Data_t)); dataElement->present = Data_PR_structure; int elementCount = value->value.structure.size; dataElement->choice.structure = (DataSequence_t*) GLOBAL_CALLOC(1, sizeof(DataSequence_t)); dataElement->choice.structure->list.size = elementCount; dataElement->choice.structure->list.count = elementCount; dataElement->choice.structure->list.array = (Data_t**) GLOBAL_CALLOC(elementCount, sizeof(Data_t*)); int i; for (i = 0; i < elementCount; i++) { dataElement->choice.structure->list.array[i] = mmsMsg_createDataElement(value->value.structure.components[i]); } return dataElement; } else { return mmsMsg_createBasicDataElement(value); } }
int mmsClient_createWriteRequest(uint32_t invokeId, char* domainId, char* itemId, MmsValue* value, ByteBuffer* writeBuffer) { //TODO reuse code to send information report! MmsPdu_t* mmsPdu = mmsClient_createConfirmedRequestPdu(invokeId); mmsPdu->choice.confirmedRequestPdu.confirmedServiceRequest.present = ConfirmedServiceRequest_PR_write; WriteRequest_t* request = &(mmsPdu->choice.confirmedRequestPdu.confirmedServiceRequest.choice.write); /* Create list of variable specifications */ request->variableAccessSpecification.present = VariableAccessSpecification_PR_listOfVariable; request->variableAccessSpecification.choice.listOfVariable.list.count = 1; request->variableAccessSpecification.choice.listOfVariable.list.size = 1; request->variableAccessSpecification.choice.listOfVariable.list.array = (ListOfVariableSeq_t**) calloc(1, sizeof(ListOfVariableSeq_t*)); request->variableAccessSpecification.choice.listOfVariable.list.array[0] = (ListOfVariableSeq_t*) createNewDomainVariableSpecification(domainId, itemId); /* Create list of typed data values */ request->listOfData.list.count = 1; request->listOfData.list.size = 1; request->listOfData.list.array = (Data_t**) calloc(1, sizeof(struct Data*)); request->listOfData.list.array[0] = mmsMsg_createBasicDataElement(value); asn_enc_rval_t rval; rval = der_encode(&asn_DEF_MmsPdu, mmsPdu, (asn_app_consume_bytes_f*) mmsClient_write_out, (void*) writeBuffer); if (DEBUG) xer_fprint(stdout, &asn_DEF_MmsPdu, mmsPdu); /* Free ASN structure */ request->variableAccessSpecification.choice.listOfVariable.list.count = 0; free(request->variableAccessSpecification.choice.listOfVariable.list.array[0]); free(request->variableAccessSpecification.choice.listOfVariable.list.array); request->variableAccessSpecification.choice.listOfVariable.list.array = 0; request->listOfData.list.count = 0; deleteDataElement(request->listOfData.list.array[0]); free(request->listOfData.list.array); request->listOfData.list.array = 0; asn_DEF_MmsPdu.free_struct(&asn_DEF_MmsPdu, mmsPdu, 0); return rval.encoded; }
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; }
int mmsClient_createWriteMultipleItemsRequest(uint32_t invokeId, char* domainId, LinkedList itemIds, LinkedList values, ByteBuffer* writeBuffer) { MmsPdu_t* mmsPdu = mmsClient_createConfirmedRequestPdu(invokeId); mmsPdu->choice.confirmedRequestPdu.confirmedServiceRequest.present = ConfirmedServiceRequest_PR_write; WriteRequest_t* request = &(mmsPdu->choice.confirmedRequestPdu.confirmedServiceRequest.choice.write); int numberOfItems = LinkedList_size(itemIds); /* Create list of variable specifications */ request->variableAccessSpecification.present = VariableAccessSpecification_PR_listOfVariable; request->variableAccessSpecification.choice.listOfVariable.list.count = numberOfItems; request->variableAccessSpecification.choice.listOfVariable.list.size = numberOfItems; request->variableAccessSpecification.choice.listOfVariable.list.array = (ListOfVariableSeq_t**) calloc(numberOfItems, sizeof(ListOfVariableSeq_t*)); /* Create list of data values */ request->listOfData.list.count = numberOfItems; request->listOfData.list.size = numberOfItems; request->listOfData.list.array = (Data_t**) calloc(numberOfItems, sizeof(struct Data*)); int i; LinkedList item = LinkedList_getNext(itemIds); LinkedList valueElement = LinkedList_getNext(values); for (i = 0; i < numberOfItems; i++) { if (item == NULL) return -1; if (valueElement == NULL) return -1; char* itemId = (char*) item->data; MmsValue* value = (MmsValue*) valueElement->data; request->variableAccessSpecification.choice.listOfVariable.list.array[i] = (ListOfVariableSeq_t*) createNewDomainVariableSpecification(domainId, itemId); request->listOfData.list.array[i] = mmsMsg_createBasicDataElement(value); item = LinkedList_getNext(item); } asn_enc_rval_t rval; rval = der_encode(&asn_DEF_MmsPdu, mmsPdu, (asn_app_consume_bytes_f*) mmsClient_write_out, (void*) writeBuffer); if (DEBUG) xer_fprint(stdout, &asn_DEF_MmsPdu, mmsPdu); /* Free ASN structure */ request->variableAccessSpecification.choice.listOfVariable.list.count = 0; for (i = 0; i < numberOfItems; i++) { free(request->variableAccessSpecification.choice.listOfVariable.list.array[i]); deleteDataElement(request->listOfData.list.array[i]); } free(request->variableAccessSpecification.choice.listOfVariable.list.array); request->variableAccessSpecification.choice.listOfVariable.list.array = 0; request->listOfData.list.count = 0; free(request->listOfData.list.array); request->listOfData.list.array = 0; asn_DEF_MmsPdu.free_struct(&asn_DEF_MmsPdu, mmsPdu, 0); return rval.encoded; }