/* * \param createArray if multiple variables should be read (e.g. if a data set is read) an array should * be created that contains the access results. */ MmsValue* mmsClient_parseReadResponse(ByteBuffer* message, uint32_t* invokeId, bool createArray) { MmsPdu_t* mmsPdu = 0; /* allow asn1c to allocate structure */ MmsValue* valueList = NULL; asn_dec_rval_t rval = ber_decode(NULL, &asn_DEF_MmsPdu, (void**) &mmsPdu, ByteBuffer_getBuffer(message), ByteBuffer_getSize(message)); if (rval.code != RC_OK) return NULL; if (mmsPdu->present == MmsPdu_PR_confirmedResponsePdu) { if (invokeId != NULL) *invokeId = mmsClient_getInvokeId(&mmsPdu->choice.confirmedResponsePdu); if (mmsPdu->choice.confirmedResponsePdu.confirmedServiceResponse.present == ConfirmedServiceResponse_PR_read) { ReadResponse_t* response = &(mmsPdu->choice.confirmedResponsePdu.confirmedServiceResponse.choice.read); int elementCount = response->listOfAccessResult.list.count; valueList = mmsClient_parseListOfAccessResults(response->listOfAccessResult.list.array, elementCount, createArray); } } asn_DEF_MmsPdu.free_struct(&asn_DEF_MmsPdu, mmsPdu, 0); return valueList; }
bool mmsClient_parseInitiateResponse(MmsConnection self) { bool result = false; MmsPdu_t* mmsPdu = 0; asn_dec_rval_t rval = ber_decode(NULL, &asn_DEF_MmsPdu, (void**) &mmsPdu, ByteBuffer_getBuffer(self->lastResponse), ByteBuffer_getSize(self->lastResponse)); if (rval.code != RC_OK) goto exit_function; if (mmsPdu->present == MmsPdu_PR_initiateResponsePdu) { InitiateResponsePdu_t* initiateResponse = &(mmsPdu->choice.initiateResponsePdu); if (initiateResponse->localDetailCalled != NULL) self->parameters.maxPduSize = *(initiateResponse->localDetailCalled); if (initiateResponse->negotiatedDataStructureNestingLevel != NULL) self->parameters.dataStructureNestingLevel = *(initiateResponse->negotiatedDataStructureNestingLevel);; self->parameters.maxServOutstandingCalled = initiateResponse->negotiatedMaxServOutstandingCalled; self->parameters.maxServOutstandingCalling = initiateResponse->negotiatedMaxServOutstandingCalling; result = true; } else result = false; asn_DEF_MmsPdu.free_struct(&asn_DEF_MmsPdu, mmsPdu, 0); exit_function: return result; }
MmsVariableSpecification* mmsClient_parseGetVariableAccessAttributesResponse(ByteBuffer* message, uint32_t* invokeId) { MmsPdu_t* mmsPdu = 0; /* allow asn1c to allocate structure */ MmsVariableSpecification* typeSpec = NULL; asn_dec_rval_t rval = ber_decode(NULL, &asn_DEF_MmsPdu, (void**) &mmsPdu, ByteBuffer_getBuffer(message), ByteBuffer_getSize(message)); if (rval.code != RC_OK) return NULL; if (mmsPdu->present == MmsPdu_PR_confirmedResponsePdu) { if (invokeId != NULL) *invokeId = mmsClient_getInvokeId(&mmsPdu->choice.confirmedResponsePdu); if (mmsPdu->choice.confirmedResponsePdu.confirmedServiceResponse.present == ConfirmedServiceResponse_PR_getVariableAccessAttributes) { GetVariableAccessAttributesResponse_t* response; response = &(mmsPdu->choice.confirmedResponsePdu.confirmedServiceResponse.choice.getVariableAccessAttributes); TypeSpecification_t* asnTypeSpec = &response->typeSpecification; typeSpec = createTypeSpecification(asnTypeSpec); } } asn_DEF_MmsPdu.free_struct(&asn_DEF_MmsPdu, mmsPdu, 0); return typeSpec; }
bool mmsClient_parseGetNameListResponse(LinkedList* nameList, ByteBuffer* message, uint32_t* invokeId) { MmsPdu_t* mmsPdu = 0; bool moreFollows = false; asn_dec_rval_t rval; /* Decoder return value */ rval = ber_decode(NULL, &asn_DEF_MmsPdu, (void**) &mmsPdu, ByteBuffer_getBuffer(message), ByteBuffer_getSize(message)); if (DEBUG) xer_fprint(stdout, &asn_DEF_MmsPdu, mmsPdu); if (mmsPdu->present == MmsPdu_PR_confirmedResponsePdu) { *invokeId = mmsClient_getInvokeId(&mmsPdu->choice.confirmedResponsePdu); if (mmsPdu->choice.confirmedResponsePdu.confirmedServiceResponse.present == ConfirmedServiceResponse_PR_getNameList) { GetNameListResponse_t* response = &(mmsPdu->choice.confirmedResponsePdu.confirmedServiceResponse.choice.getNameList); int variableCount; int i; LinkedList element; if ((response->moreFollows != NULL) && (*(response->moreFollows) != 0)) moreFollows = true; if (*nameList == NULL) *nameList = LinkedList_create(); variableCount = response->listOfIdentifier.list.count; element = LinkedList_getLastElement(*nameList); for (i = 0; i < variableCount; i++) { char* variableName = createStringFromBuffer(response->listOfIdentifier.list.array[i]->buf, response->listOfIdentifier.list.array[i]->size); element = LinkedList_insertAfter(element, variableName); } } else { printf("parseMmsGetNameListResponse: NOT A GetNameList RESPONSE!\n"); } } else { printf("parseMmsGetNameListResponse: NOT A CONFIRMED RESPONSE!\n"); } asn_DEF_MmsPdu.free_struct(&asn_DEF_MmsPdu, mmsPdu, 0); return moreFollows; }
static bool sendBuffer(CotpConnection* self) { int writeBufferPosition = ByteBuffer_getSize(self->writeBuffer); bool retVal = false; if (Socket_write(self->socket, ByteBuffer_getBuffer(self->writeBuffer), writeBufferPosition) == writeBufferPosition) retVal = true; ByteBuffer_setSize(self->writeBuffer, 0); return retVal; }
int ByteStream_sendBuffer(ByteStream self) { int writeBufferPosition = ByteBuffer_getSize(self->writeBuffer); if (Socket_write(self->socket, ByteBuffer_getBuffer(self->writeBuffer), writeBufferPosition) == writeBufferPosition) { ByteBuffer_setSize(self->writeBuffer, 0); return 1; } else return -1; }
LinkedList mmsClient_parseGetNameListResponse(ByteBuffer* message, uint32_t* invokeId) { MmsPdu_t* mmsPdu = 0; /* allow asn1c to allocate structure */ LinkedList returnList = NULL; asn_dec_rval_t rval; /* Decoder return value */ rval = ber_decode(NULL, &asn_DEF_MmsPdu, (void**) &mmsPdu, ByteBuffer_getBuffer(message), ByteBuffer_getSize(message)); if (DEBUG) xer_fprint(stdout, &asn_DEF_MmsPdu, mmsPdu); if (mmsPdu->present == MmsPdu_PR_confirmedResponsePdu) { *invokeId = mmsClient_getInvokeId(&mmsPdu->choice.confirmedResponsePdu); if (mmsPdu->choice.confirmedResponsePdu.confirmedServiceResponse.present == ConfirmedServiceResponse_PR_getNameList) { GetNameListResponse_t* response = &(mmsPdu->choice.confirmedResponsePdu.confirmedServiceResponse.choice.getNameList); LinkedList variableNameList = LinkedList_create(); int variableCount = response->listOfIdentifier.list.count; int i; for (i = 0; i < variableCount; i++) { char* variableName = createStringFromBuffer(response->listOfIdentifier.list.array[i]->buf, response->listOfIdentifier.list.array[i]->size); LinkedList_add(variableNameList, variableName); } returnList = variableNameList; } else { printf("parseMmsGetNameListResponse: NOT A GetNameList RESPONSE!\n"); } } else { printf("parseMmsGetNameListResponse: NOT A CONFIRMED RESPONSE!\n"); } asn_DEF_MmsPdu.free_struct(&asn_DEF_MmsPdu, mmsPdu, 0); return returnList; }
MmsIndication mmsClient_parseWriteResponse(ByteBuffer* message) { MmsPdu_t* mmsPdu = 0; MmsIndication retVal = MMS_OK; asn_dec_rval_t rval; rval = ber_decode(NULL, &asn_DEF_MmsPdu, (void**) &mmsPdu, ByteBuffer_getBuffer(message), ByteBuffer_getSize(message)); if (rval.code != RC_OK) { retVal = MMS_ERROR; goto cleanUp; } if (DEBUG) xer_fprint(stdout, &asn_DEF_MmsPdu, mmsPdu); if (mmsPdu->present == MmsPdu_PR_confirmedResponsePdu) { if (mmsPdu->choice.confirmedResponsePdu.confirmedServiceResponse.present == ConfirmedServiceResponse_PR_write) { WriteResponse_t* response = &(mmsPdu->choice.confirmedResponsePdu.confirmedServiceResponse.choice.write); if (response->list.count > 0) { if (response->list.array[0]->present == WriteResponse__Member_PR_success) retVal = MMS_OK; else retVal = MMS_ERROR; } else retVal = MMS_ERROR; } else { retVal = MMS_ERROR; } } else { retVal = MMS_ERROR; } cleanUp: asn_DEF_MmsPdu.free_struct(&asn_DEF_MmsPdu, mmsPdu, 0); return retVal; }
MmsValue* mmsClient_parseReadResponse(ByteBuffer* message, uint32_t* invokeId) { MmsPdu_t* mmsPdu = 0; /* allow asn1c to allocate structure */ MmsIndication retVal = MMS_OK; MmsValue* valueList = NULL; MmsValue* value = NULL; asn_dec_rval_t rval; rval = ber_decode(NULL, &asn_DEF_MmsPdu, (void**) &mmsPdu, ByteBuffer_getBuffer(message), ByteBuffer_getSize(message)); if (DEBUG) xer_fprint(stdout, &asn_DEF_MmsPdu, mmsPdu); if (mmsPdu->present == MmsPdu_PR_confirmedResponsePdu) { *invokeId = mmsClient_getInvokeId(&mmsPdu->choice.confirmedResponsePdu); if (mmsPdu->choice.confirmedResponsePdu.confirmedServiceResponse.present == ConfirmedServiceResponse_PR_read) { ReadResponse_t* response = &(mmsPdu->choice.confirmedResponsePdu.confirmedServiceResponse.choice.read); int elementCount = response->listOfAccessResult.list.count; if (elementCount > 1) valueList = MmsValue_createEmtpyArray(elementCount); int i = 0; for (i = 0; i < elementCount; i++) { value = NULL; AccessResult_PR presentType = response->listOfAccessResult.list.array[i]->present; if (presentType == AccessResult_PR_failure) { if (DEBUG) printf("access error!\n"); retVal = MMS_ERROR; } else if (presentType == AccessResult_PR_array) { value = calloc(1, sizeof(MmsValue)); value->type = MMS_ARRAY; int elementCount = response->listOfAccessResult.list.array[i]->choice.array.list.count; value->value.array.size = elementCount; value->value.array.components = calloc(elementCount, sizeof(MmsValue*)); int j; for (j = 0; j < elementCount; j++) { value->value.array.components[j] = mmsMsg_parseDataElement( response->listOfAccessResult.list.array[i]->choice.array.list.array[j]); } } else if (presentType == AccessResult_PR_structure) { value = calloc(1, sizeof(MmsValue)); value->type = MMS_STRUCTURE; int componentCount = response->listOfAccessResult.list.array[i]->choice.structure.list.count; value->value.structure.componentCount = componentCount; value->value.structure.components = calloc(componentCount, sizeof(MmsValue*)); int j; for (j = 0; j < componentCount; j++) { value->value.structure.components[j] = mmsMsg_parseDataElement( response->listOfAccessResult.list.array[i]->choice.structure.list.array[j]); } } else if (presentType == AccessResult_PR_bitstring) { value = calloc(1, sizeof(MmsValue)); value->type = MMS_BIT_STRING; int size = response->listOfAccessResult.list.array[i]->choice.bitstring.size; value->value.bitString.size = (size * 8) - response->listOfAccessResult.list.array[i]->choice.bitstring.bits_unused; value->value.bitString.buf = malloc(size); memcpy(value->value.bitString.buf, response->listOfAccessResult.list.array[i]->choice.bitstring.buf, size); } else if (presentType == AccessResult_PR_integer) { long integerValue; asn_INTEGER2long(&response->listOfAccessResult.list.array[i]->choice.integer, &integerValue); value = MmsValue_newIntegerFromInt32((int32_t) integerValue); } else if (presentType == AccessResult_PR_floatingpoint) { int size = response->listOfAccessResult.list.array[i]->choice.floatingpoint.size; value = calloc(1, sizeof(MmsValue)); value->type = MMS_FLOAT; if (size == 5) { /* FLOAT32 */ value->value.floatingPoint.formatWidth = 32; value->value.floatingPoint.exponentWidth = response->listOfAccessResult.list.array[i]->choice.floatingpoint.buf[0]; uint8_t* floatBuf = (response->listOfAccessResult.list.array[i]->choice.floatingpoint.buf + 1); value->value.floatingPoint.buf = malloc(4); #ifdef ORDER_LITTLE_ENDIAN memcpyReverseByteOrder(value->value.floatingPoint.buf, floatBuf, 4); #else memcpy(value->value.floatingPoint.buf, floatBuf, 4); #endif } if (size == 9) { /* FLOAT64 */ value->value.floatingPoint.formatWidth = 64; value->value.floatingPoint.exponentWidth = response->listOfAccessResult.list.array[i]->choice.floatingpoint.buf[0]; uint8_t* floatBuf = (response->listOfAccessResult.list.array[i]->choice.floatingpoint.buf + 1); value->value.floatingPoint.buf = malloc(8); #ifdef ORDER_LITTLE_ENDIAN memcpyReverseByteOrder(value->value.floatingPoint.buf, floatBuf, 8); #else memcpy(value->value.floatingPoint.buf, floatBuf, 8); #endif } } else if (presentType == AccessResult_PR_utctime) { value->type = MMS_UTC_TIME; memcpy(value->value.utcTime, response->listOfAccessResult.list.array[i]->choice.utctime.buf, 8); } else { printf("unknown type\n"); retVal = MMS_ERROR; } if (elementCount > 1) MmsValue_setArrayElement(valueList, i, value); } } else { retVal = MMS_ERROR; } } else { retVal = MMS_ERROR; } asn_DEF_MmsPdu.free_struct(&asn_DEF_MmsPdu, mmsPdu, 0); if (valueList == NULL) valueList = value; return valueList; }
void IsoClientConnection_associate(IsoClientConnection self, IsoConnectionParameters* params, ByteBuffer* payload) { Socket socket = TcpSocket_create(); self->socket = socket; if (!Socket_connect(socket, params->hostname, params->tcpPort)) goto returnError; self->cotpBuf = malloc(ISO_CLIENT_BUFFER_SIZE); self->cotpBuffer = calloc(1, sizeof(ByteBuffer)); ByteBuffer_wrap(self->cotpBuffer, self->cotpBuf, 0, ISO_CLIENT_BUFFER_SIZE); self->cotpConnection = calloc(1, sizeof(CotpConnection)); CotpConnection_init(self->cotpConnection, socket, self->cotpBuffer); /* COTP handshake */ CotpIndication cotpIndication = CotpConnection_sendConnectionRequestMessage(self->cotpConnection); cotpIndication = CotpConnection_parseIncomingMessage(self->cotpConnection); if (cotpIndication != CONNECT_INDICATION) goto returnError; /* Upper layers handshake */ AcseConnection acse; ByteBuffer acseBuffer; ByteBuffer_wrap(&acseBuffer, self->buffer1, 0, ISO_CLIENT_BUFFER_SIZE); AcseConnection_init(&acse); if (params != NULL) AcseConnection_setAuthenticationParameter(&acse, params->acseAuthParameter); AcseConnection_createAssociateRequestMessage(&acse, &acseBuffer, payload); ByteBuffer presentationBuffer; ByteBuffer_wrap(&presentationBuffer, self->buffer2, 0, ISO_CLIENT_BUFFER_SIZE); self->presentation = calloc(1, sizeof(IsoPresentation)); IsoPresentation_init(self->presentation); IsoPresentation_createConnectPdu(self->presentation, &presentationBuffer, &acseBuffer); ByteBuffer sessionBuffer; ByteBuffer_wrap(&sessionBuffer, self->buffer1, 0, ISO_CLIENT_BUFFER_SIZE); self->session = calloc(1, sizeof(IsoSession)); IsoSession_init(self->session); IsoSession_createConnectSpdu(self->session, &sessionBuffer, ByteBuffer_getSize(&presentationBuffer)); ByteBuffer_append(&sessionBuffer, ByteBuffer_getBuffer(&presentationBuffer), ByteBuffer_getSize(&presentationBuffer)); CotpConnection_sendDataMessage(self->cotpConnection, &sessionBuffer); cotpIndication = CotpConnection_parseIncomingMessage(self->cotpConnection); if (cotpIndication != DATA_INDICATION) goto returnError; IsoSessionIndication sessionIndication; sessionIndication = IsoSession_parseMessage(self->session, CotpConnection_getPayload(self->cotpConnection)); if (sessionIndication != SESSION_CONNECT) { if (DEBUG) printf("IsoClientConnection_associate: no session connect indication\n"); goto returnError; } IsoPresentationIndication presentationIndication; presentationIndication = IsoPresentation_parseAcceptMessage(self->presentation, IsoSession_getUserData(self->session)); if (presentationIndication != PRESENTATION_OK) { if (DEBUG) printf("IsoClientConnection_associate: no presentation ok indication\n"); goto returnError; } AcseIndication acseIndication; acseIndication = AcseConnection_parseMessage(&acse, &self->presentation->nextPayload); if (acseIndication != ACSE_ASSOCIATE) { if (DEBUG) printf("IsoClientConnection_associate: no ACSE_ASSOCIATE indication\n"); goto returnError; } ByteBuffer acsePayload; //TODO allocate buffer dynamically??? ByteBuffer_wrap(&acsePayload, acse.userDataBuffer, acse.userDataBufferSize, 1024); self->callback(ISO_IND_ASSOCIATION_SUCCESS, self->callbackParameter, &acsePayload); self->state = STATE_ASSOCIATED; AcseConnection_destroy(&acse); self->thread = Thread_create(connectionHandlingThread, self, false); Thread_start(self->thread); return; returnError: self->callback(ISO_IND_ASSOCIATION_FAILED, self->callbackParameter, &acsePayload); AcseConnection_destroy(&acse); self->state = STATE_ERROR; return; }
MmsIndication mmsClient_parseWriteMultipleItemsResponse(ByteBuffer* message, int itemCount, LinkedList* accessResults) { MmsPdu_t* mmsPdu = 0; MmsIndication retVal = MMS_OK; asn_dec_rval_t rval; rval = ber_decode(NULL, &asn_DEF_MmsPdu, (void**) &mmsPdu, ByteBuffer_getBuffer(message), ByteBuffer_getSize(message)); if (rval.code != RC_OK) { retVal = MMS_ERROR; goto cleanUp; } if (DEBUG) xer_fprint(stdout, &asn_DEF_MmsPdu, mmsPdu); if (mmsPdu->present == MmsPdu_PR_confirmedResponsePdu) { if (mmsPdu->choice.confirmedResponsePdu.confirmedServiceResponse.present == ConfirmedServiceResponse_PR_write) { WriteResponse_t* response = &(mmsPdu->choice.confirmedResponsePdu.confirmedServiceResponse.choice.write); if (response->list.count == itemCount) { int i; *accessResults = LinkedList_create(); for (i = 0; i < itemCount; i++) { MmsValue* value; if (response->list.array[i]->present == WriteResponse__Member_PR_success) { MmsDataAccessError error; value = MmsValue_newDataAccessError(DATA_ACCESS_ERROR_SUCCESS); } else { long errorCode; asn_INTEGER2long(&response->list.array[i]->choice.failure, &errorCode); value = MmsValue_newDataAccessError((MmsDataAccessError) errorCode); } LinkedList_add(*accessResults, (void*) value); } } else retVal = MMS_ERROR; } else { retVal = MMS_ERROR; } } else { retVal = MMS_ERROR; } cleanUp: asn_DEF_MmsPdu.free_struct(&asn_DEF_MmsPdu, mmsPdu, 0); return retVal; }