Untitled

 avatar
unknown
plain_text
2 months ago
8.7 kB
2
Indexable
package org.stupor.deviceInteractiion;

import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.springframework.stereotype.Service;
import org.stupor.model.FinishedMessageAboutObject;
import org.stupor.model.MessageAboutObject;
import org.stupor.model.SynchroMessage;
import org.stupor.service.UDPMessageProcessor;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.Arrays;

@Service
public class UDPServer {

    private static final int PORT = 9098;
    private final UDPMessageProcessor messageProcessor;

    public UDPServer(UDPMessageProcessor messageProcessor) {
        this.messageProcessor = messageProcessor;
        new Thread(this::start).start();
    }

    public static String bytesToHex(byte[] bytes) {
        StringBuilder sb = new StringBuilder();
        for (byte b : bytes) {
            sb.append(String.format("%02X ", b));
        }
        return sb.toString().trim();
    }

    public void start() {
        try (DatagramSocket socket = new DatagramSocket(PORT)) {
            System.out.println("UDP сервер запущен на порту " + PORT);

            while (true) {
                byte[] buffer = new byte[1024];
                DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
                socket.receive(packet);

                int length = packet.getLength();
                // Копируем ровно те байты, что пришли (без пустоты из конца buffer)
                byte[] data = Arrays.copyOf(buffer, length);

                // Для отладки
                System.out.println("Получены данные: " + Arrays.toString(data));
                System.out.println("Полученные данные (Hex): " + bytesToHex(data));
                System.out.println("Полный пакет: " + Arrays.toString(data));

                /*
                 * Предположим, что первые 4 байта (0..3) — это не «настоящие» данные,
                 * а заголовок (10 02 3A 03). Тогда сам тип сообщения находится в байте [4].
                 * Если у вас он реально лежит в [7] (как было раньше),
                 * значит надо сдвигать не на 4, а на 7 (или иные значения, в зависимости от протокола).
                 */

                // Пример: тип сообщения лежит в data[4]
                int typeMessage = data[4] & 0xFF;

                System.out.println("Определённый тип сообщения: " + typeMessage);
                System.out.println("Ожидаемые типы: 1 (объект), 2 (окончание), 3 (синхро)");

                switch (typeMessage) {
                    case 1: {
                        // Парсим сообщение об объекте.
                        // Создадим ByteBuffer c Little Endian, пропустив «заголовочные» байты (4 штуки).
                        ByteBuffer bb = ByteBuffer.wrap(data).order(ByteOrder.LITTLE_ENDIAN);

                        // Ниже — ПРИМЕРНЫЕ смещения!
                        // Если после 4 байт заголовка сразу идёт typeMessage (1 байт),
                        // то далее поля идут так:
                        // [5..8]   (4 байта) => numberOfMessages
                        // [9..12]  (4 байта) => numberObject
                        // [13..20] (8 байт)  => latitude
                        // [21..28] (8 байт)  => longitude
                        // [29..32] (4 байта) => altitude
                        // [33..36] (4 байта) => speed
                        // [37..40] (4 байта) => course
                        // [41]     (1 байт)  => typeTarget
                        // [42..45] (4 байта) => epr
                        // [46]     (1 байт)  => updateTarget
                        // [47..54] (8 байт)  => time
                        // и т.д.
                        // Точные офсеты зависят от реального формата вашего пакета!

                        int typeMessage2       = Byte.toUnsignedInt(bb.get(4));    // байт [4]
                        int numberOfMessages   = bb.getInt(5);                     // байты [5..8]
                        int numberObject       = bb.getInt(9);                     // байты [9..12]
                        double latitude        = bb.getDouble(13);                 // байты [13..20]
                        double longitude       = bb.getDouble(21);                 // байты [21..28]
                        int altitude           = bb.getInt(29);                    // байты [29..32]
                        float speed            = bb.getFloat(33);                  // байты [33..36]
                        float course           = bb.getFloat(37);                  // байты [37..40]
                        int typeTarget         = Byte.toUnsignedInt(bb.get(41));   // байт  [41]
                        float epr              = bb.getFloat(42);                  // байты [42..45]
                        int updateTarget       = Byte.toUnsignedInt(bb.get(46));   // байт  [46]
                        double time            = bb.getDouble(47);                 // байты [47..54]

                        // Выводим для проверки
                        System.out.println("Тип сообщения: " + typeMessage2);
                        System.out.println("Счетчик сообщений: " + numberOfMessages);
                        System.out.println("Номер объекта: " + numberObject);
                        System.out.println("Широта: " + latitude);
                        System.out.println("Долгота: " + longitude);
                        System.out.println("Высота: " + altitude);
                        System.out.println("Скорость: " + speed);
                        System.out.println("Курс: " + course);
                        System.out.println("Код типа цели: " + typeTarget);
                        System.out.println("ЭПР: " + epr);
                        System.out.println("Признак новой цели: " + updateTarget);
                        System.out.println("Время: " + time);

                        // Можно собрать свой объект. Либо использовать ваш MessageParser.
                        MessageAboutObject objectMessage = new MessageAboutObject(
                                typeMessage2,
                                numberOfMessages,
                                numberObject,
                                latitude,
                                longitude,
                                altitude,
                                speed,
                                course,
                                typeTarget,
                                epr,
                                updateTarget,
                                time
                        );

                        // Отправляем дальше в вашу логику
                        messageProcessor.processMessage(objectMessage);
                        break;
                    }

                    case 2: {
                        FinishedMessageAboutObject finishedMessage = MessageParser.parseFinishedMessage(data);
                        System.out.println("Сообщение об окончании: " + finishedMessage);
                        messageProcessor.processMessage(finishedMessage);
                        break;
                    }

                    case 3: {
                        SynchroMessage syncMessage = MessageParser.parseSynchroMessage(data);
                        System.out.println("Синхросообщение: " + syncMessage);
                        messageProcessor.processMessage(syncMessage);
                        break;
                    }

                    default:
                        System.out.println("Неизвестный тип сообщения: " + typeMessage);
                        break;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
Leave a Comment