Java-декодирование байтов с устройства GPS с помощью ByteBuffer - PullRequest
0 голосов
/ 20 января 2019

У меня проблемы с декодированием байтов, отправленных с устройства GPS в мою программу прослушивания java UDP.Я могу извлечь часть информации, но для другой информации я не могу понять, как это сделать.Формат данных из руководства по устройству следующий:

Name       | Type          | Length
length:    | short         | 2
cmd:       | short         | 2
enabled:   | unsigned char | 1
alarm:     | unsigned char | 1
speed:     | char          | 1
direction: | short         | 2
longitude: | double        | 4
latitude:  | double        | 4
datetime:  | long          | 4
userid:    | char          | 11
iostate:   | char          | 1
oilstate:  | char          | 1

В моей программе я могу декодировать длину, команду, сигнал тревоги, скорость, направление и устройство.Я застрял на широте, долготе и дате и мне потребуется помощь.Значения, которые я получаю, совершенно далеки от того, какими должны быть правильные.Это работало без проблем на python с функцией struct.unpack.

Код в функции выглядит следующим образом:

private void SetupUDP() throws IOException {
        String message;
        // Setup UDP Stuff and listen on all interfaces
        DatagramSocket serverSocket = new DatagramSocket(9876, InetAddress.getByName("0.0.0.0"));
        byte[] receiveData = new byte[1024];
        while(true) {
            // Start receiving UDP packets from devices
            DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
            serverSocket.receive(receivePacket);

            ByteBuffer data = ByteBuffer.wrap(receivePacket.getData());
            data.order(ByteOrder.LITTLE_ENDIAN);
            if (receivePacket.getLength() == 15) {
                short len = data.getShort(0);
                short cmd = data.getShort(2);
                String device = "";
                for (int x=4; x < 14; x++) {
                    byte b = data.get(x);
                    device += (char) b;
                }
                System.out.println(len + " " + cmd + " -- " + device);
            }
            if (receivePacket.getLength() == 34) {
                short len = data.getShort(0);
                short cmd = data.getShort(2);
                byte benabled = data.get(4);
                int enabled = (int) benabled;
                byte balarm = data.get(5);
                // Alarm (OK)
                int alarm =  Math.abs((int) balarm);
                // Speed (OK)
                byte bspeed = data.get(6);
                int speed = (int) bspeed;
                // Direction (OK)
                short direction = data.getShort(7);
                // Coordinates
                double longitude = data.getDouble(9);
                double latitude = data.getDouble(13);
                // Device ID (OK)
                String device = "";
                for (int x=21; x < 31; x++) {
                    byte bdevice = data.get(x);
                    device += (char) bdevice;
                }

                // Datetime (testing)
                int ddatetime = data.get(17);
                Date datetime = new Date(ddatetime * 1000);
                //System.out.println("-->" + datetime + ", " + longitude);
                System.out.println(len + " " + cmd + " " + enabled + " " + alarm + " " + speed + " " + direction + " " + longitude + " " + latitude + " " + datetime + " " + device);
            }
        }
    }

1 Ответ

0 голосов
/ 20 января 2019

Вы читаете широту и долготу как 8 байтов каждый, спецификация у вас говорит 4. double s в Java и getDouble в ByteBuffer, это 8 байтов, вы хотите getFloat.

Это также приводит к повреждению данных после того, как вы прочитали слишком далеко.

...