Создание пакетов драйверов устройств из Java - PullRequest
0 голосов
/ 09 апреля 2020

Теперь, когда у меня есть свободное время, я решил создать программу 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 в простой байтовый поток / массив?

1 Ответ

1 голос
/ 09 апреля 2020

Чтобы построить блок байтов для передачи, я рекомендую использовать встроенный ByteBuffer, который, например, имеет помощники для 16-, 32- и 64-битных целых чисел в больших или малых -endian.

Затем вы должны сохранить значения так, как вы их используете, например,

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
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...