Слияние фрагментов API XBee из последовательного порта

Я пытаюсь объединить фрагменты пакета, который я получаю своим Xbee (802.15.4) в режиме API через последовательный порт RS-232. Я получаю свой фрагмент методом readBytes из библиотеки jssc для java.

Вот мой код приема

    private static class PortReader implements SerialPortEventListener {

    @Override
    public void serialEvent(SerialPortEvent event) {
        if(event.isRXCHAR() && event.getEventValue() > 0) {
            try {
                byte[] receivedData = serialPort.readBytes(event.getEventValue());
                if(Utils.isConfirmPacket(Utils.toHex(receivedData))){
                    System.out.println("XBee confim that msg is sent!");
                }else{
                    System.out.println("Received response from port: " + Utils.toHex(receivedData));
                    int dataLength = Utils.toHex(receivedData).length();
                    receiveFile("testRx", receivedData, dataLength);
                }

            }
            catch (SerialPortException ex) {
                System.out.println("Error in receiving response from port: " + ex);
            }
        }
    }

Моему методу receiveFile () нужен полный пакет в одном фрагменте. Вот что я получаю в своей консоли:

Received response from port: 7e003c8100013200
Received response from port: 2000123200ff1200
Received response from port: 0001000500000000
Received response from port: 0000000020000000
Received response from port: 1251000012455222
Received response from port: 446174613a206365
Received response from port: 6369206573742075
Received response from port: 6e20746573743b90

Поскольку я использую режим API, мне не удалось отправить конечный разделитель, чтобы указать конец пакета, как я видел в других решениях (Прочитать полную строку последовательного порта Java).

Я думал использовать начальный разделитель следующего пакета, но не вышло.


person Flyingmath    schedule 22.01.2016    source источник
comment
Подумайте об использовании этой библиотеки вместо того, чтобы изобретать колесо. Это должно упростить работу с данными как с кадрами, а не с потоком. docs.digi.com/display/XBJLIB/XBee+Java+Library   -  person tomlogic    schedule 25.01.2016


Ответы (1)


Я разобрался, используя длину пакета api. Поскольку длина находится в позициях [1] и [2] первого массива, я могу использовать это значение для продолжения построения своего пакета по мере получения данных. Когда мое значение msgLengthLeft равно 0, я знаю, что весь пакет был получен, и могу вернуть полный пакет. Вот мой код:

private static class PortReader implements SerialPortEventListener {
    private short msgLength;
    private short msgLengthLeft;
    private byte[] receivedMsg = new byte[packetSize];
    ByteArrayOutputStream outputStream = new ByteArrayOutputStream( );

    @Override
    public void serialEvent(SerialPortEvent event) {
        if(event.isRXCHAR() && event.getEventValue() > 0) {
            try {
                byte[] receivedData = serialPort.readBytes(event.getEventValue());
                if(Utils.isConfirmPacket(Utils.toHex(receivedData))){
                    System.out.println("XBee confim that msg is sent!");
                }else{
                    if(receivedData[0] == 0x7e){    //0x7e is the start delimiter of a frame
                        ByteBuffer wrapped = ByteBuffer.wrap(receivedData,1,2); // big-endian by default
                        msgLength = (short) (wrapped.getShort()+4); //Need to add 4 to the value becaus some field are not include in the length field of the api packet
                        msgLengthLeft = (short) (msgLength - receivedData.length);
                        outputStream.write(receivedData);  
                        return;
                    }else{
                        msgLengthLeft = (short) (msgLengthLeft - receivedData.length);
                        outputStream.write(receivedData); 
                        if(msgLengthLeft != 0){
                            return;
                        }
                    }
                    System.out.println("Received response from port: " + Utils.toHex(outputStream.toByteArray( )));
                    int dataLength = Utils.toHex(receivedMsg).length();
                    //receiveFile("testRx", receivedData, dataLength);
                }

            }
            catch (SerialPortException | IOException ex) {
                System.out.println("Error in receiving response from port: " + ex);
            }
        }
    }
}
person Flyingmath    schedule 24.01.2016