static int encodeVariableAccessSpecification(VarAccessSpec* accessSpec, uint8_t* buffer, int bufPos, bool encode) { /* determine size */ int varAccessSpecSize = 0; int itemIdLen = strlen(accessSpec->itemId); varAccessSpecSize += itemIdLen + BerEncoder_determineLengthSize(itemIdLen) + 1; if (accessSpec->domainId != NULL) { int domainIdLen = strlen(accessSpec->domainId); varAccessSpecSize += domainIdLen + BerEncoder_determineLengthSize(domainIdLen) + 1; } int specificityLength = varAccessSpecSize; varAccessSpecSize += 1 + BerEncoder_determineLengthSize(specificityLength); int variableListNameLength = varAccessSpecSize; varAccessSpecSize += 1 + BerEncoder_determineLengthSize(variableListNameLength); int varAccessSpecLength = varAccessSpecSize; varAccessSpecSize += 1 + BerEncoder_determineLengthSize(varAccessSpecLength); if (encode == false) return varAccessSpecSize; /* encode to buffer */ bufPos = BerEncoder_encodeTL(0xa0, varAccessSpecLength, buffer, bufPos); if (accessSpec->isNamedVariableList == true) { bufPos = BerEncoder_encodeTL(0xa1, variableListNameLength, buffer, bufPos); if (accessSpec->specific == 0) { /* vmd-specific */ bufPos = BerEncoder_encodeTL(0xa0, specificityLength, buffer, bufPos); } else if (accessSpec->specific == 1) { /* domain-specific */ bufPos = BerEncoder_encodeTL(0xa1, specificityLength, buffer, bufPos); } else { /* association-specific */ bufPos = BerEncoder_encodeTL(0xa2, specificityLength, buffer, bufPos); } if (accessSpec->domainId != NULL) bufPos = BerEncoder_encodeStringWithTag(0x1a, accessSpec->domainId, buffer, bufPos); bufPos = BerEncoder_encodeStringWithTag(0x1a, accessSpec->itemId, buffer, bufPos); } return 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; }
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; }