@Override public void visit(LwM2mObject object) { LOG.trace("Encoding object instances {} into TLV", object); Tlv[] tlvs = null; ObjectModel objectModel = model.getObjectModel(object.getId()); if (objectModel != null && !objectModel.multiple) { // single instance object, the instance is level is not needed tlvs = encodeResources(object.getInstances().get(0).getResources().values()); } else { tlvs = new Tlv[object.getInstances().size()]; int i = 0; for (Entry<Integer, LwM2mObjectInstance> instance : object.getInstances().entrySet()) { Tlv[] resources = encodeResources(instance.getValue().getResources().values()); tlvs[i] = new Tlv(TlvType.OBJECT_INSTANCE, resources, null, instance.getKey()); i++; } } try { out.write(TlvEncoder.encode(tlvs).array()); } catch (IOException e) { throw new RuntimeException(e); } }
@Override public void visit(LwM2mResource resource) { LOG.trace("Encoding resource {} into TLV", resource); Tlv rTlv = encodeResource(resource); try { out.write(TlvEncoder.encode(new Tlv[] {rTlv}).array()); } catch (IOException e) { throw new RuntimeException(e); } }
@Override public void visit(LwM2mObjectInstance instance) { LOG.trace("Encoding object instance {} into TLV", instance); // The instance is encoded as an array of resource TLVs. Tlv[] rTlvs = encodeResources(instance.getResources().values()); try { out.write(TlvEncoder.encode(rTlvs).array()); } catch (IOException e) { throw new RuntimeException(e); } }
/** Encodes an array of TLV. */ public static ByteBuffer encode(Tlv[] tlvs) { int size = 0; LOG.trace("start"); for (Tlv tlv : tlvs) { int length = tlvEncodedLength(tlv); size += tlvEncodedSize(tlv, length); LOG.trace("tlv size : {}", size); } LOG.trace("done, size : {}", size); ByteBuffer b = ByteBuffer.allocate(size); b.order(ByteOrder.BIG_ENDIAN); for (Tlv tlv : tlvs) { encode(tlv, b); } b.flip(); return b; }
private static void encode(Tlv tlv, ByteBuffer b) { int length; length = tlvEncodedLength(tlv); int typeByte; switch (tlv.getType()) { case OBJECT_INSTANCE: typeByte = 0b00_000000; break; case RESOURCE_INSTANCE: typeByte = 0b01_000000; break; case MULTIPLE_RESOURCE: typeByte = 0b10_000000; break; case RESOURCE_VALUE: // encode the value typeByte = 0b11_000000; break; default: throw new IllegalArgumentException("unknown TLV type : '" + tlv.getType() + "'"); } // encode identifier length typeByte |= (tlv.getIdentifier() < MAX_LENGTH_8BIT) ? 0b00_0000 : 0b10_0000; // type of length if (length < 8) { typeByte |= length; } else if (length < MAX_LENGTH_8BIT) { typeByte |= 0b0000_1000; } else if (length < MAX_LENGTH_16BIT) { typeByte |= 0b0001_0000; } else { typeByte |= 0b0001_1000; } // fill the buffer b.put((byte) typeByte); if (tlv.getIdentifier() < MAX_LENGTH_8BIT) { b.put((byte) tlv.getIdentifier()); } else { b.putShort((short) tlv.getIdentifier()); } // write length if (length >= 8) { if (length < MAX_LENGTH_8BIT) { b.put((byte) length); } else if (length < MAX_LENGTH_16BIT) { b.putShort((short) length); } else { int msb = (length & 0xFF_00_00) >> 16; b.put((byte) msb); b.putShort((short) (length & 0xFF_FF)); typeByte |= 0b0001_1000; } } switch (tlv.getType()) { case RESOURCE_VALUE: case RESOURCE_INSTANCE: b.put(tlv.getValue()); break; default: for (Tlv child : tlv.getChildren()) { encode(child, b); } break; } }