static void
createDeleteNamedVariableListResponse(uint32_t invokeId, ByteBuffer* response,
        uint32_t numberMatched, uint32_t numberDeleted)
{
    uint32_t invokeIdSize = BerEncoder_UInt32determineEncodedSize(invokeId) + 2;

    uint32_t numberMatchedSize =
            2 + BerEncoder_UInt32determineEncodedSize(numberMatched);

    uint32_t numberDeletedSize =
            2 + BerEncoder_UInt32determineEncodedSize(numberDeleted);

    uint32_t deleteNVLSize = 2 + numberMatchedSize + numberDeletedSize;

    uint32_t confirmedResponsePDUSize = invokeIdSize + deleteNVLSize;

    int bufPos = 0;
    uint8_t* buffer = response->buffer;

    bufPos = BerEncoder_encodeTL(0xa1, confirmedResponsePDUSize, buffer, bufPos);

    bufPos = BerEncoder_encodeTL(0x02, invokeIdSize - 2, buffer, bufPos);
    bufPos = BerEncoder_encodeUInt32(invokeId, buffer, bufPos);

    bufPos = BerEncoder_encodeTL(0xad, numberMatchedSize + numberDeletedSize, buffer, bufPos);

    bufPos = BerEncoder_encodeTL(0x80, numberMatchedSize - 2, buffer, bufPos);
    bufPos = BerEncoder_encodeUInt32(numberMatched, buffer, bufPos);

    bufPos = BerEncoder_encodeTL(0x81, numberDeletedSize - 2, buffer, bufPos);
    bufPos = BerEncoder_encodeUInt32(numberDeleted, buffer, bufPos);

    response->size = bufPos;
}
Esempio n. 2
0
void
mmsServer_handleStatusRequest(
        MmsServerConnection connection,
        uint8_t* requestBuffer,
        int bufPos,
        int invokeId,
        ByteBuffer* response)
{
    /* check for extended derivation */
    bool extendedDerivation = BerDecoder_decodeBoolean(requestBuffer, bufPos);

    if (DEBUG_MMS_SERVER)
        printf("mms_status_service.c: statusRequest (extendedDerivation: %i)\n", extendedDerivation);

    bufPos = 0;
    uint8_t* buffer = response->buffer;

    uint32_t invokeIdLength = BerEncoder_UInt32determineEncodedSize(invokeId);

    MmsServer mmsServer = connection->server;

    /* Invoke user provided callback */
    if (mmsServer->statusRequestListener != NULL)
        mmsServer->statusRequestListener(mmsServer->statusRequestListenerParameter, mmsServer, connection, extendedDerivation);

    uint32_t vmdPhysicalStatusLength = BerEncoder_UInt32determineEncodedSize((uint32_t) mmsServer->vmdPhysicalStatus);
    uint32_t vmdLogicalStatusLength = BerEncoder_UInt32determineEncodedSize((uint32_t) mmsServer->vmdLogicalStatus);

    uint32_t statusLength = 2 + vmdPhysicalStatusLength + 2 + vmdLogicalStatusLength;

    uint32_t statusResponseLength = invokeIdLength + 2 + 1 + BerEncoder_determineLengthSize(statusLength) + statusLength;

    /* Status response pdu */
    bufPos = BerEncoder_encodeTL(0xa1, statusResponseLength, buffer, bufPos);

    /* invokeId */
    bufPos = BerEncoder_encodeTL(0x02, invokeIdLength, buffer, bufPos);
    bufPos = BerEncoder_encodeUInt32(invokeId, buffer, bufPos);

    bufPos = BerEncoder_encodeTL(0xa0, statusLength, buffer, bufPos);
    bufPos = BerEncoder_encodeTL(0x80, vmdLogicalStatusLength, buffer, bufPos);
    bufPos = BerEncoder_encodeUInt32((uint32_t) mmsServer->vmdLogicalStatus, buffer, bufPos);
    bufPos = BerEncoder_encodeTL(0x81, vmdPhysicalStatusLength, buffer, bufPos);
    bufPos = BerEncoder_encodeUInt32((uint32_t) mmsServer->vmdPhysicalStatus, buffer, bufPos);

    response->size = bufPos;
}
Esempio n. 3
0
void
mmsClient_createIdentifyRequest(uint32_t invokeId, ByteBuffer* request)
{
    uint32_t invokeIdSize = BerEncoder_UInt32determineEncodedSize(invokeId);
    uint32_t confirmedRequestPduSize = 2 + 2 + invokeIdSize;

    int bufPos = 0;
    uint8_t* buffer = request->buffer;

    bufPos = BerEncoder_encodeTL(0xa0, confirmedRequestPduSize, buffer, bufPos);
    bufPos = BerEncoder_encodeTL(0x02, invokeIdSize, buffer, bufPos);
    bufPos = BerEncoder_encodeUInt32(invokeId, buffer, bufPos);

    bufPos = BerEncoder_encodeTL(0x82, 0, buffer, bufPos);

    request->size = bufPos;
}
static void
createDefineNamedVariableListResponse(uint32_t invokeId, ByteBuffer* response)
{
    uint32_t invokeIdSize = BerEncoder_UInt32determineEncodedSize((uint32_t) invokeId) + 2;

    uint32_t confirmedResponsePDUSize = 2 + invokeIdSize;

    int bufPos = 0;
    uint8_t* buffer = response->buffer;

    bufPos = BerEncoder_encodeTL(0xa1, confirmedResponsePDUSize, buffer, bufPos);

    bufPos = BerEncoder_encodeTL(0x02, invokeIdSize - 2, buffer, bufPos);
    bufPos = BerEncoder_encodeUInt32((uint32_t) invokeId, buffer, bufPos);

    bufPos = BerEncoder_encodeTL(0x8b, 0, buffer, bufPos);

    response->size = bufPos;
}
static void
handleIdentifyRequest(
        MmsServerConnection* connection,
        int invokeId,
        ByteBuffer* response)
{
    int bufPos = 0;
    uint8_t* buffer = response->buffer;

    uint32_t invokeIdLength = BerEncoder_UInt32determineEncodedSize(invokeId);

    MmsServer mmsServer = connection->server;

    uint32_t vendorNameLength = strlen(MmsServer_getVendorName(mmsServer));
    uint32_t modelNameLength = strlen(MmsServer_getModelName(mmsServer));
    uint32_t revisionLength = strlen(MmsServer_getRevision(mmsServer));

    uint32_t identityLength = 3 +  BerEncoder_determineLengthSize(vendorNameLength)
            + BerEncoder_determineLengthSize(modelNameLength) + BerEncoder_determineLengthSize(revisionLength)
            + vendorNameLength + modelNameLength + revisionLength;

    uint32_t identifyResponseLength = invokeIdLength + 2 + 1 + BerEncoder_determineLengthSize(identityLength)
            + identityLength;

    /* Identify response pdu */
    bufPos = BerEncoder_encodeTL(0xa1, identifyResponseLength, buffer, bufPos);

    /* invokeId */
    bufPos = BerEncoder_encodeTL(0x02, invokeIdLength, buffer, bufPos);
    bufPos = BerEncoder_encodeUInt32(invokeId, buffer, bufPos);

    bufPos = BerEncoder_encodeTL(0xa2, identityLength, buffer, bufPos);
    bufPos = BerEncoder_encodeStringWithTag(0x80, MmsServer_getVendorName(mmsServer), buffer, bufPos);
    bufPos = BerEncoder_encodeStringWithTag(0x81, MmsServer_getModelName(mmsServer), buffer, bufPos);
    bufPos = BerEncoder_encodeStringWithTag(0x82, MmsServer_getRevision(mmsServer), buffer, bufPos);

    response->size = bufPos;
}
Esempio n. 6
0
static void
encodeReadResponse(MmsServerConnection* connection,
		uint32_t invokeId, ByteBuffer* response, LinkedList values,
		VarAccessSpec* accessSpec)
{
	int i;

	int variableCount = LinkedList_size(values);

	int varAccessSpecSize = 0;

	if (accessSpec != NULL) {
		varAccessSpecSize = encodeVariableAccessSpecification(accessSpec, NULL, 0, false);
	}

	/* determine BER encoded message sizes */
	int accessResultSize = 0;

	/* iterate values list to determine encoded size  */
	LinkedList value = LinkedList_getNext(values);

	for (i = 0; i < variableCount; i++) {

	   MmsValue* data = (MmsValue*) value->data;

	   accessResultSize += mmsServer_encodeAccessResult(data, NULL, 0, false);

		value = LinkedList_getNext(value);
	}

	int listOfAccessResultsLength = 1 +
									BerEncoder_determineLengthSize(accessResultSize) +
									accessResultSize;


	int confirmedServiceResponseContentLength = listOfAccessResultsLength  + varAccessSpecSize;

	int confirmedServiceResponseLength = 1 +
						BerEncoder_determineLengthSize(confirmedServiceResponseContentLength) +
						confirmedServiceResponseContentLength;

	int invokeIdSize = BerEncoder_UInt32determineEncodedSize(invokeId) + 2;

	int confirmedResponseContentSize = confirmedServiceResponseLength + invokeIdSize;

	int mmsPduSize = 1 + BerEncoder_determineLengthSize(confirmedResponseContentSize) +
			confirmedResponseContentSize;

	/* Check if message would fit in the MMS PDU */
	if (mmsPduSize > connection->maxPduSize) {
		if (DEBUG)
			printf("MMS read: message to large! send error PDU!\n");

		mmsServer_createConfirmedErrorPdu(invokeId, response,
					  MMS_ERROR_TYPE_RESPONSE_EXCEEDS_MAX_PDU_SIZE);
		return;
	}

	/* encode message */

	uint8_t* buffer = response->buffer;
	int bufPos = 0;

	/* confirmed response PDU */
	bufPos = BerEncoder_encodeTL(0xa1, confirmedResponseContentSize, buffer, bufPos);

	/* invoke id */
	bufPos = BerEncoder_encodeTL(0x02, invokeIdSize - 2, buffer, bufPos);
	bufPos = BerEncoder_encodeUInt32(invokeId, buffer, bufPos);

	/* confirmed-service-response read */
	bufPos = BerEncoder_encodeTL(0xa4, confirmedServiceResponseContentLength, buffer, bufPos);

	/* encode variable access specification */
	if (accessSpec != NULL)
		bufPos = encodeVariableAccessSpecification(accessSpec, buffer, bufPos, true);

	/* encode list of access results */
	bufPos = BerEncoder_encodeTL(0xa1, accessResultSize, buffer, bufPos);

	/* encode access results */
	value = LinkedList_getNext(values);

	for (i = 0; i < variableCount; i++) {
		MmsValue* data = (MmsValue*) value->data;

		bufPos = mmsServer_encodeAccessResult(data, buffer, bufPos, true);

		value = LinkedList_getNext(value);
	}

	response->size = bufPos;

	if (DEBUG)
		printf("MMS read: sent message for request with id %u (size = %i)\n", invokeId, bufPos);

}
int
mmsServer_encodeAccessResult(MmsValue* value, uint8_t* buffer, int bufPos, bool encode)
{
    int size;

    switch (value->type) {
    case MMS_STRUCTURE:
        if (encode)
            bufPos = encodeStructuredAccessResult(value, buffer, bufPos, true);
        else
            size = encodeStructuredAccessResult(value, buffer, bufPos, false);

        break;

    case MMS_ARRAY:
        if (encode)
            bufPos = encodeArrayAccessResult(value, buffer, bufPos, true);
        else
            size = encodeArrayAccessResult(value, buffer, bufPos, false);
        break;

    case MMS_DATA_ACCESS_ERROR:
        if (encode) {
            int length = BerEncoder_UInt32determineEncodedSize(value->value.dataAccessError.code);

            bufPos = BerEncoder_encodeTL(0x80, length, buffer, bufPos);
            bufPos = BerEncoder_encodeUInt32(value->value.dataAccessError.code, buffer, bufPos);
        }
        else
            size = 2 + BerEncoder_UInt32determineEncodedSize(value->value.dataAccessError.code);
        break;

    case MMS_VISIBLE_STRING:
        if (encode)
            bufPos = BerEncoder_encodeStringWithTag(0x8a, value->value.visibleString, buffer, bufPos);
        else
            size = BerEncoder_determineEncodedStringSize(value->value.visibleString);
        break;
    case MMS_UNSIGNED:
        if (encode)
            bufPos = BerEncoder_encodeAsn1PrimitiveValue(0x86, value->value.unsignedInteger, buffer, bufPos);
        else
            size = 2 + value->value.unsignedInteger->size;
        break;
    case MMS_INTEGER:
        if (encode)
            bufPos = BerEncoder_encodeAsn1PrimitiveValue(0x85, value->value.integer, buffer, bufPos);
        else
            size = 2 + value->value.integer->size;
        break;
    case MMS_UTC_TIME:
        if (encode)
            bufPos = BerEncoder_encodeOctetString(0x91, value->value.utcTime, 8, buffer, bufPos);
        else
            size = 10;
        break;
    case MMS_BIT_STRING:
        if (encode)
            bufPos = BerEncoder_encodeBitString(0x84, value->value.bitString.size,
                    value->value.bitString.buf, buffer, bufPos);
        else
            size = BerEncoder_determineEncodedBitStringSize(value->value.bitString.size);
        break;
    case MMS_BOOLEAN:
        if (encode)
            bufPos = BerEncoder_encodeBoolean(0x83, value->value.boolean, buffer, bufPos);
        else
            size = 3;
        break;
    case MMS_BINARY_TIME:
        if (encode)
            bufPos = BerEncoder_encodeOctetString(0x8c, value->value.binaryTime.buf,
                    value->value.binaryTime.size, buffer, bufPos);
        else
            size = 2 + value->value.binaryTime.size;
        break;
    case MMS_OCTET_STRING:
        if (encode)
            bufPos = BerEncoder_encodeOctetString(0x89, value->value.octetString.buf,
                    value->value.octetString.size, buffer, bufPos);
        else
            size = 1 + BerEncoder_determineLengthSize(value->value.octetString.size)
                        + value->value.octetString.size;
        break;

    case MMS_FLOAT:
        {
            int floatSize = (value->value.floatingPoint.formatWidth / 8) + 1;

            if (encode) {
                bufPos = BerEncoder_encodeTL(0x87, floatSize, buffer, bufPos);
                bufPos = BerEncoder_encodeFloat(value->value.floatingPoint.buf,
                        value->value.floatingPoint.formatWidth,
                        value->value.floatingPoint.exponentWidth,
                        buffer, bufPos);
            }
            else
                size = floatSize + 2; /* 2 for tag and length */
        }
        break;
    case MMS_STRING:
        if (encode)
            bufPos = BerEncoder_encodeStringWithTag(0x90, value->value.mmsString, buffer, bufPos);
        else
            size = BerEncoder_determineEncodedStringSize(value->value.mmsString);
        break;
    default:
        printf("encodeAccessResult: error unsupported type!\n");
        break;
    }

    if (encode)
        return bufPos;
    else
        return size;
}