From bff1ab4c717851b01d995dc283a205ef5412f368 Mon Sep 17 00:00:00 2001 From: Davide Icardi Date: Fri, 5 Apr 2019 20:20:18 +0200 Subject: [PATCH] Added OPAQUE text encoding/decoding, using base64 Signed-off-by: Davide Icardi --- .gitignore | 3 +++ .../node/codec/text/LwM2mNodeTextDecoder.java | 6 +++++- .../node/codec/text/LwM2mNodeTextEncoder.java | 5 +++++ .../core/node/codec/LwM2mNodeDecoderTest.java | 21 +++++++++++++++++++ .../core/node/codec/LwM2mNodeEncoderTest.java | 9 ++++++++ 5 files changed, 43 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index f343806138..c445f4aeae 100644 --- a/.gitignore +++ b/.gitignore @@ -20,6 +20,9 @@ bin/ .idea/ *.iml +# Visual Studio Code files # +.vscode/ + # Package Files # *.jar *.war diff --git a/leshan-core/src/main/java/org/eclipse/leshan/core/node/codec/text/LwM2mNodeTextDecoder.java b/leshan-core/src/main/java/org/eclipse/leshan/core/node/codec/text/LwM2mNodeTextDecoder.java index 166aa4ad71..1289073b1e 100644 --- a/leshan-core/src/main/java/org/eclipse/leshan/core/node/codec/text/LwM2mNodeTextDecoder.java +++ b/leshan-core/src/main/java/org/eclipse/leshan/core/node/codec/text/LwM2mNodeTextDecoder.java @@ -27,6 +27,7 @@ import org.eclipse.leshan.core.node.LwM2mSingleResource; import org.eclipse.leshan.core.node.ObjectLink; import org.eclipse.leshan.core.node.codec.CodecException; +import org.eclipse.leshan.util.Base64; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -96,7 +97,10 @@ private static Object parseTextValue(String value, Type type, LwM2mPath path) th path); } case OPAQUE: - // not specified + if (!Base64.isBase64(value)) { + throw new CodecException("Invalid value for opaque resource [%s], base64 expected", path); + } + return Base64.decodeBase64(value); default: throw new CodecException("Could not handle %s value with TEXT encoder for resource %s", type, path); } diff --git a/leshan-core/src/main/java/org/eclipse/leshan/core/node/codec/text/LwM2mNodeTextEncoder.java b/leshan-core/src/main/java/org/eclipse/leshan/core/node/codec/text/LwM2mNodeTextEncoder.java index f323671eba..2627ba6f2b 100644 --- a/leshan-core/src/main/java/org/eclipse/leshan/core/node/codec/text/LwM2mNodeTextEncoder.java +++ b/leshan-core/src/main/java/org/eclipse/leshan/core/node/codec/text/LwM2mNodeTextEncoder.java @@ -30,6 +30,7 @@ import org.eclipse.leshan.core.node.ObjectLink; import org.eclipse.leshan.core.node.codec.CodecException; import org.eclipse.leshan.core.node.codec.LwM2mValueConverter; +import org.eclipse.leshan.util.Base64; import org.eclipse.leshan.util.Validate; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -100,6 +101,10 @@ public void visit(LwM2mResource resource) { ObjectLink objlnk = (ObjectLink) val; strValue = String.valueOf(objlnk.getObjectId() + ":" + objlnk.getObjectInstanceId()); break; + case OPAQUE: + byte[] binaryValue = (byte[]) val; + strValue = Base64.encodeBase64String(binaryValue); + break; default: throw new CodecException("Cannot encode %s in text format for %s", val, path); } diff --git a/leshan-core/src/test/java/org/eclipse/leshan/core/node/codec/LwM2mNodeDecoderTest.java b/leshan-core/src/test/java/org/eclipse/leshan/core/node/codec/LwM2mNodeDecoderTest.java index 355a0b4cde..47bdd54849 100644 --- a/leshan-core/src/test/java/org/eclipse/leshan/core/node/codec/LwM2mNodeDecoderTest.java +++ b/leshan-core/src/test/java/org/eclipse/leshan/core/node/codec/LwM2mNodeDecoderTest.java @@ -225,6 +225,27 @@ public void text_battery_resource() throws CodecException { assertEquals(100, ((Number) resource.getValue()).intValue()); } + @Test + public void text_decode_opaque_from_base64_string() throws CodecException { + // Using Firmware Update/Package + LwM2mSingleResource resource = (LwM2mSingleResource) decoder.decode("AQIDBAU=".getBytes(StandardCharsets.UTF_8), + ContentFormat.TEXT, new LwM2mPath(5, 0, 0), model); + + byte[] expectedValue = new byte[] { 0x1, 0x2, 0x3, 0x4, 0x5 }; + + assertEquals(0, resource.getId()); + assertFalse(resource.isMultiInstances()); + assertEquals(Type.OPAQUE, resource.getType()); + assertArrayEquals(expectedValue, ((byte[]) resource.getValue())); + } + + @Test(expected = CodecException.class) + public void text_decode_should_throw_an_exception_for_invalid_base64() throws CodecException { + // Using Firmware Update/Package + decoder.decode("!,-INVALID$_'".getBytes(StandardCharsets.UTF_8), + ContentFormat.TEXT, new LwM2mPath(5, 0, 0), model); + } + @Test public void tlv_manufacturer_resource() throws CodecException { String value = "MyManufacturer"; diff --git a/leshan-core/src/test/java/org/eclipse/leshan/core/node/codec/LwM2mNodeEncoderTest.java b/leshan-core/src/test/java/org/eclipse/leshan/core/node/codec/LwM2mNodeEncoderTest.java index 07ac20a0be..7de5ed1627 100644 --- a/leshan-core/src/test/java/org/eclipse/leshan/core/node/codec/LwM2mNodeEncoderTest.java +++ b/leshan-core/src/test/java/org/eclipse/leshan/core/node/codec/LwM2mNodeEncoderTest.java @@ -89,6 +89,15 @@ public void text_encode_multiple_instances() { model); } + @Test + public void text_encode_opaque_as_base64_string() { + byte[] opaqueValue = new byte[] { 0x1, 0x2, 0x3, 0x4, 0x5 }; + byte[] encoded = encoder.encode(LwM2mSingleResource.newBinaryResource(0, opaqueValue), ContentFormat.TEXT, + new LwM2mPath("/5/0/0"), model); + + Assert.assertEquals("AQIDBAU=", new String(encoded, StandardCharsets.UTF_8)); + } + // tlv content for instance 0 of device object (encoded as an array of resource TLVs) // Example from LWM2M spec ยง4.3.1 private final static byte[] ENCODED_DEVICE_WITHOUT_INSTANCE = Hex.decodeHex(