forked from eclipse-leshan/leshan
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
eclipse-leshan#682: Add SenML-CBOR encoder in leshan-core + unit tests.
Signed-off-by: Boya Zhang <zhangboya@gmail.com>
- Loading branch information
1 parent
4feb9bb
commit 85eeb21
Showing
14 changed files
with
374 additions
and
185 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
26 changes: 26 additions & 0 deletions
26
leshan-core/src/main/java/org/eclipse/leshan/senml/SenMLCbor.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
/******************************************************************************* | ||
* All rights reserved. This program and the accompanying materials | ||
* are made available under the terms of the Eclipse Public License v1.0 | ||
* and Eclipse Distribution License v1.0 which accompany this distribution. | ||
* | ||
* The Eclipse Public License is available at | ||
* http://www.eclipse.org/legal/epl-v10.html | ||
* and the Eclipse Distribution License is available at | ||
* http://www.eclipse.org/org/documents/edl-v10.html. | ||
* | ||
* Contributors: | ||
* Boya Zhang - initial API and implementation | ||
*******************************************************************************/ | ||
|
||
package org.eclipse.leshan.senml; | ||
|
||
/** | ||
* Helper for encoding/decoding SenML CBOR format | ||
*/ | ||
public class SenMLCbor { | ||
private static final SenMLCborPackSerDes serDes = new SenMLCborPackSerDes(); | ||
|
||
public static byte[] toSenMLCbor(SenMLPack pack) throws SenMLCborException { | ||
return serDes.serializeToCbor(pack); | ||
} | ||
} |
32 changes: 32 additions & 0 deletions
32
leshan-core/src/main/java/org/eclipse/leshan/senml/SenMLCborException.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
/******************************************************************************* | ||
* All rights reserved. This program and the accompanying materials | ||
* are made available under the terms of the Eclipse Public License v1.0 | ||
* and Eclipse Distribution License v1.0 which accompany this distribution. | ||
* | ||
* The Eclipse Public License is available at | ||
* http://www.eclipse.org/legal/epl-v10.html | ||
* and the Eclipse Distribution License is available at | ||
* http://www.eclipse.org/org/documents/edl-v10.html. | ||
* | ||
* Contributors: | ||
* Boya Zhang - initial API and implementation | ||
*******************************************************************************/ | ||
|
||
package org.eclipse.leshan.senml; | ||
|
||
/** | ||
* Exception thrown in case of Cbor encoding error | ||
*/ | ||
public class SenMLCborException extends Exception { | ||
|
||
private static final long serialVersionUID = 1L; | ||
|
||
public SenMLCborException(String message) { | ||
super(message); | ||
} | ||
|
||
public SenMLCborException(String message, Exception cause) { | ||
super(message, cause); | ||
} | ||
|
||
} |
119 changes: 119 additions & 0 deletions
119
leshan-core/src/main/java/org/eclipse/leshan/senml/SenMLCborPackSerDes.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
/******************************************************************************* | ||
* All rights reserved. This program and the accompanying materials | ||
* are made available under the terms of the Eclipse Public License v1.0 | ||
* and Eclipse Distribution License v1.0 which accompany this distribution. | ||
* | ||
* The Eclipse Public License is available at | ||
* http://www.eclipse.org/legal/epl-v10.html | ||
* and the Eclipse Distribution License is available at | ||
* http://www.eclipse.org/org/documents/edl-v10.html. | ||
* | ||
* Contributors: | ||
* Boya Zhang - initial API and implementation | ||
*******************************************************************************/ | ||
|
||
package org.eclipse.leshan.senml; | ||
|
||
import java.io.ByteArrayOutputStream; | ||
|
||
import org.eclipse.leshan.core.model.ResourceModel.Type; | ||
|
||
import com.fasterxml.jackson.dataformat.cbor.CBORFactory; | ||
import com.fasterxml.jackson.dataformat.cbor.CBORGenerator; | ||
|
||
public class SenMLCborPackSerDes { | ||
|
||
public byte[] serializeToCbor(SenMLPack pack) throws SenMLCborException { | ||
CBORFactory factory = new CBORFactory(); | ||
ByteArrayOutputStream out = new ByteArrayOutputStream(); | ||
|
||
try { | ||
CBORGenerator generator = factory.createGenerator(out); | ||
generator.writeStartArray(pack.getRecords().size()); | ||
|
||
for (SenMLRecord record : pack.getRecords()) { | ||
boolean hasBaseName = false; | ||
boolean hasBaseTime = false; | ||
boolean hasName = false; | ||
boolean hasTime = false; | ||
int objectSize = 1; | ||
|
||
if (record.getBaseName() != null && !record.getBaseName().isEmpty()) { | ||
hasBaseName = true; | ||
objectSize++; | ||
} | ||
|
||
if (record.getBaseTime() != null) { | ||
hasBaseTime = true; | ||
objectSize++; | ||
} | ||
|
||
if (record.getName() != null && !record.getName().isEmpty()) { | ||
hasName = true; | ||
objectSize++; | ||
} | ||
|
||
if (record.getTime() != null) { | ||
hasTime = true; | ||
objectSize++; | ||
} | ||
|
||
generator.writeStartObject(objectSize); | ||
|
||
if (hasBaseName) { | ||
generator.writeFieldId(-2); | ||
generator.writeString(record.getBaseName()); | ||
} | ||
|
||
if (hasBaseTime) { | ||
generator.writeFieldId(-3); | ||
generator.writeNumber(record.getBaseTime()); | ||
} | ||
|
||
if (hasName) { | ||
generator.writeFieldId(0); | ||
generator.writeString(record.getName()); | ||
} | ||
|
||
if (hasTime) { | ||
generator.writeFieldId(6); | ||
generator.writeNumber(record.getTime()); | ||
} | ||
|
||
Type type = record.getType(); | ||
if (type != null) { | ||
switch (record.getType()) { | ||
case FLOAT: | ||
generator.writeFieldId(2); | ||
generator.writeNumber(record.getFloatValue().intValue()); | ||
break; | ||
case BOOLEAN: | ||
generator.writeFieldId(4); | ||
generator.writeBoolean(record.getBooleanValue()); | ||
break; | ||
case OBJLNK: | ||
generator.writeStringField("vlo", record.getObjectLinkValue()); | ||
break; | ||
case OPAQUE: | ||
generator.writeFieldId(8); | ||
generator.writeBinary(record.getOpaqueValue()); | ||
case STRING: | ||
generator.writeFieldId(3); | ||
generator.writeString(record.getStringValue()); | ||
break; | ||
default: | ||
break; | ||
} | ||
} | ||
generator.writeEndObject(); | ||
} | ||
|
||
generator.writeEndArray(); | ||
generator.close(); | ||
} catch (Exception ex) { | ||
throw new SenMLCborException("Impossible to encode pack to CBOR: \n" + pack, ex); | ||
} | ||
|
||
return out.toByteArray(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
88 changes: 88 additions & 0 deletions
88
leshan-core/src/test/java/org/eclipse/leshan/senml/AbstractSenMLTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
/******************************************************************************* | ||
* All rights reserved. This program and the accompanying materials | ||
* are made available under the terms of the Eclipse Public License v1.0 | ||
* and Eclipse Distribution License v1.0 which accompany this distribution. | ||
* | ||
* The Eclipse Public License is available at | ||
* http://www.eclipse.org/legal/epl-v10.html | ||
* and the Eclipse Distribution License is available at | ||
* http://www.eclipse.org/org/documents/edl-v10.html. | ||
* | ||
* Contributors: | ||
* Boya Zhang - initial API and implementation | ||
*******************************************************************************/ | ||
|
||
package org.eclipse.leshan.senml; | ||
|
||
public abstract class AbstractSenMLTest { | ||
protected void givenResourceWithFloatValue(SenMLPack pack, String n, Number value) { | ||
SenMLRecord elt = new SenMLRecord(); | ||
elt.setName(n); | ||
elt.setFloatValue(value); | ||
pack.addRecord(elt); | ||
} | ||
|
||
protected void givenResourceWithStringValue(SenMLPack pack, String n, String value) { | ||
givenResourceWithStringValue(pack, null, n, value); | ||
} | ||
|
||
protected void givenResourceWithStringValue(SenMLPack pack, String bn, String n, String value) { | ||
SenMLRecord elt = new SenMLRecord(); | ||
if (bn != null) { | ||
elt.setBaseName(bn); | ||
} | ||
|
||
elt.setName(n); | ||
elt.setStringValue(value); | ||
pack.addRecord(elt); | ||
} | ||
|
||
/** | ||
* Example of JSON payload request to Device Object of the LwM2M example client (Read /3/0) | ||
* | ||
* @return JSON payload | ||
*/ | ||
protected String givenSenMLJsonExample() { | ||
StringBuilder b = new StringBuilder(); | ||
b.append("[{\"bn\":\"/3/0/\",\"n\":\"0\",\"vs\":\"Open Mobile Alliance\"},"); | ||
b.append("{\"n\":\"1\",\"vs\":\"Lightweight M2M Client\"},"); | ||
b.append("{\"n\":\"2\",\"vs\":\"345000123\"},"); | ||
b.append("{\"n\":\"3\",\"vs\":\"1.0\"},"); | ||
b.append("{\"n\":\"6/0\",\"v\":1},{\"n\":\"6/1\",\"v\":5},"); | ||
b.append("{\"n\":\"7/0\",\"v\":3800},{\"n\":\"7/1\",\"v\":5000},"); | ||
b.append("{\"n\":\"8/0\",\"v\":125},{\"n\":\"8/1\",\"v\":900},"); | ||
b.append("{\"n\":\"9\",\"v\":100},"); | ||
b.append("{\"n\":\"10\",\"v\":15},"); | ||
b.append("{\"n\":\"11/0\",\"v\":0},"); | ||
b.append("{\"n\":\"13\",\"v\":1.3674912E9},"); | ||
b.append("{\"n\":\"14\",\"vs\":\"+02:00\"},"); | ||
b.append("{\"n\":\"16\",\"vs\":\"U\"}]"); | ||
return b.toString(); | ||
} | ||
|
||
protected SenMLPack givenDeviceObjectInstance() { | ||
SenMLPack pack = new SenMLPack(); | ||
|
||
givenResourceWithStringValue(pack, "/3/0/", "0", "Open Mobile Alliance"); | ||
givenResourceWithStringValue(pack, "1", "Lightweight M2M Client"); | ||
givenResourceWithStringValue(pack, "2", "345000123"); | ||
givenResourceWithStringValue(pack, "3", "1.0"); | ||
|
||
givenResourceWithFloatValue(pack, "6/0", 1); | ||
givenResourceWithFloatValue(pack, "6/1", 5); | ||
givenResourceWithFloatValue(pack, "7/0", 3800); | ||
givenResourceWithFloatValue(pack, "7/1", 5000); | ||
givenResourceWithFloatValue(pack, "8/0", 125); | ||
givenResourceWithFloatValue(pack, "8/1", 900); | ||
|
||
givenResourceWithFloatValue(pack, "9", 100); | ||
givenResourceWithFloatValue(pack, "10", 15); | ||
givenResourceWithFloatValue(pack, "11/0", 0); | ||
givenResourceWithFloatValue(pack, "13", 1367491215l); | ||
|
||
givenResourceWithStringValue(pack, "14", "+02:00"); | ||
givenResourceWithStringValue(pack, "16", "U"); | ||
|
||
return pack; | ||
} | ||
} |
34 changes: 34 additions & 0 deletions
34
leshan-core/src/test/java/org/eclipse/leshan/senml/SenMLCborSerializerTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
/******************************************************************************* | ||
* All rights reserved. This program and the accompanying materials | ||
* are made available under the terms of the Eclipse Public License v1.0 | ||
* and Eclipse Distribution License v1.0 which accompany this distribution. | ||
* | ||
* The Eclipse Public License is available at | ||
* http://www.eclipse.org/legal/epl-v10.html | ||
* and the Eclipse Distribution License is available at | ||
* http://www.eclipse.org/org/documents/edl-v10.html. | ||
* | ||
* Contributors: | ||
* Boya Zhang - initial API and implementation | ||
*******************************************************************************/ | ||
|
||
package org.eclipse.leshan.senml; | ||
|
||
import org.eclipse.leshan.util.Hex; | ||
import org.junit.Assert; | ||
import org.junit.Test; | ||
|
||
public class SenMLCborSerializerTest extends AbstractSenMLTest { | ||
|
||
@Test | ||
public void serialize_device_object_to_senml_cbor() throws Exception { | ||
byte[] cbor = SenMLCbor.toSenMLCbor(givenDeviceObjectInstance()); | ||
|
||
String expectedValue = "90a321652f332f302f00613003744f70656e204d6f62696c6520416c6c69616e6365a200613103764c696768747765696768" | ||
+ "74204d324d20436c69656e74a20061320369333435303030313233a20061330363312e30a20063362f300201a20063362f310205a20063372f" | ||
+ "3002190ed8a20063372f3102191388a20063382f3002187da20063382f3102190384a2006139021864a200623130020fa2006431312f300200" | ||
+ "a200623133021a5182428fa20062313403662b30323a3030a200623136036155"; | ||
|
||
Assert.assertTrue(expectedValue.equals(Hex.encodeHexString(cbor))); | ||
} | ||
} |
Oops, something went wrong.