从 Java 创建设备驱动程序数据包
Creating device driver packets from Java
既然我手上有空闲时间,我决定创建一个 Java 程序来将我的 XBee(即 zigbee)芯片连接到我的新 SmartThings 集线器。我通过手动创建数据包找到了一个很好的教程 (https://nzfalco.jimdofree.com/electronic-projects/xbee-to-smartthings/)。我的下一个任务是创建一组 Java 例程来创建、发送、接收和访问所需的数据包(即字节序列)。
在 C 语言中为其他项目做过类似的工作后,我的第一个想法是简单地创建一个具有数据包结构的 class 并发送它。像这样:
class DeviceAnnounce {
public byte frameId;
public byte addr64[];
public byte addr16[];
public byte capability;
};
问题是似乎没有办法将此 "structure" 转换为字节数组以发送到设备。
接下来我想到,我们在 Java 运行时中内置了序列化功能。因此,我将 Serializable 添加到 class 并使用 writeObject() 方法将实例转换为字节流。这里的问题是 writeObject() 不仅会转换您的字节,还会在编码中包含对象的定义。非常适合将对象读写到磁盘,但它不会创建我需要发送到 xbee 设备的数据包。
我终于用困难的方式对其进行了编码,明确地向我的 class 添加了一个创建字节数组的方法。
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 转换为简单字节 stream/array?
要构建用于传输的字节块,我建议使用内置的 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
}
既然我手上有空闲时间,我决定创建一个 Java 程序来将我的 XBee(即 zigbee)芯片连接到我的新 SmartThings 集线器。我通过手动创建数据包找到了一个很好的教程 (https://nzfalco.jimdofree.com/electronic-projects/xbee-to-smartthings/)。我的下一个任务是创建一组 Java 例程来创建、发送、接收和访问所需的数据包(即字节序列)。
在 C 语言中为其他项目做过类似的工作后,我的第一个想法是简单地创建一个具有数据包结构的 class 并发送它。像这样:
class DeviceAnnounce {
public byte frameId;
public byte addr64[];
public byte addr16[];
public byte capability;
};
问题是似乎没有办法将此 "structure" 转换为字节数组以发送到设备。
接下来我想到,我们在 Java 运行时中内置了序列化功能。因此,我将 Serializable 添加到 class 并使用 writeObject() 方法将实例转换为字节流。这里的问题是 writeObject() 不仅会转换您的字节,还会在编码中包含对象的定义。非常适合将对象读写到磁盘,但它不会创建我需要发送到 xbee 设备的数据包。
我终于用困难的方式对其进行了编码,明确地向我的 class 添加了一个创建字节数组的方法。
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 转换为简单字节 stream/array?
要构建用于传输的字节块,我建议使用内置的 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
}