【问题标题】:Creating device driver packets from Java从 Java 创建设备驱动程序包
【发布时间】:2020-04-09 15:40:42
【问题描述】:

现在我手头有一些空闲时间,我决定创建一个 Java 程序来将我的 XBee(即 zigbee)芯片连接到我的新 SmartThings 集线器。我通过手动创建数据包找到了一个很好的教程(https://nzfalco.jimdofree.com/electronic-projects/xbee-to-smartthings/)。我的下一个任务是创建一组 Java 例程来创建、发送、接收和访问所需的数据包(即字节序列)。

在 C 语言中为其他项目做过类似的事情后,我的第一个想法是简单地创建一个具有数据包结构的类并发送它。像这样的:

class DeviceAnnounce {
    public byte frameId;
    public byte addr64[];
    public byte addr16[];
    public byte capability;
};

问题是似乎没有办法将此“结构”转换为字节数组以发送到设备。

接下来我想,我们在 Java 运行时中内置了序列化功能。所以我在类中添加了 Serializable,并使用 writeObject() 方法将实例转换为字节流。这里的问题是 writeObject() 不仅转换您的字节,而且在编码中包含对象的定义。非常适合读取和写入对象到磁盘,但它不会创建我需要发送到 xbee 设备的数据包。

我最终以艰难的方式对其进行了编码,明确地向我的类添加了一个创建字节数组的方法。

class DeviceAnnounce {
public DeviceAnnounce(byte frameId, byte[] addr64, byte[] addr16, byte capability) {
    super();
    this.frameId = frameId;
    this.addr64 = addr64;
    this.addr16 = addr16;
    this.capability = capability;
}

public byte frameId;
public byte addr64[];
public byte addr16[];
public byte capability;

byte[] getBytes() throws IOException {
    byte[] data=new byte[12];
    data[0]=frameId;
    data[1]=addr64[7];
    data[2]=addr64[6];
    data[3]=addr64[5];
    data[4]=addr64[4];
    data[5]=addr64[3];
    data[6]=addr64[2];
    data[7]=addr64[1];
    data[8]=addr64[0];
    data[9]=addr16[1];
    data[10]=addr16[0];
    data[11]=capability;
    return data;
}

@Override
public String toString() {
    return "DeviceAnnounce [frameId=" + frameId + ", addr64=" + HexUtils.prettyHexString(addr64) + ", addr16="
            + HexUtils.prettyHexString(addr16) + ", capability=" + capability + "]";
}

}

它有效,但我一直认为必须有更好的方法。现在是 64 美元(或比特)的问题。有没有办法将 POJO 转换为简单的字节流/数组?

【问题讨论】:

    标签: java serialization deserialization packet device-driver


    【解决方案1】:

    要构建一个字节块进行传输,我建议使用内置的ByteBuffer,例如具有大端或小端的 16 位、32 位和 64 位整数的助手。

    然后您应该在使用它们时存储这些值,例如

    public byte frameId;
    public long addr64;
    public short addr16;
    public byte capability;
    
    byte[] getBytes() throws IOException {
        ByteBuffer buf = ByteBuffer.allocate(12)
                .order(ByteOrder.BIG_ENDIAN/*Network Byte Order*/);
        buf.put(frameId);
        buf.putLong(addr64);
        buf.putShort(addr16);
        buf.put(capability);
        return buf.array(); // or return the ByteBuffer itself
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-10-06
      • 2012-05-28
      • 1970-01-01
      • 2012-05-26
      • 2020-02-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多