From 5ca0fc451b8be23f5a2435239fe55e9c27a2d961 Mon Sep 17 00:00:00 2001 From: MaD_CaT Date: Tue, 5 Mar 2024 09:14:01 +0300 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D1=80=D0=B0=D0=B1=D0=BE=D1=82?= =?UTF-8?q?=D0=BA=D0=B0.=20=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=20=D1=80=D0=B0=D0=B7=D0=B1=D0=BE=D1=80=20=D0=BF=D1=80?= =?UTF-8?q?=D0=B8=D0=BD=D1=8F=D1=82=D0=BE=D0=B3=D0=BE=20=D0=BF=D0=B0=D0=BA?= =?UTF-8?q?=D0=B5=D1=82=D0=B0=20=D0=BE=D1=82=205=D0=9F-28?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/repnetwork.gd | 10 ++++++- scripts/tcp5p28.gd | 65 +++++++++++++++++++++++++++++++++++++------ scripts/threats.gd | 11 ++++++-- 3 files changed, 74 insertions(+), 12 deletions(-) diff --git a/scripts/repnetwork.gd b/scripts/repnetwork.gd index 9208c78..29a2904 100644 --- a/scripts/repnetwork.gd +++ b/scripts/repnetwork.gd @@ -11,6 +11,9 @@ class Socket extends PacketPeerUDP: class SocketTCP extends TCPServer: + func send_to(): + pass + const RX_TIMEOUT: int = 1000 # Время сброса счётчика принятия части пакета var peerstream: = PacketPeerStream.new() var unit_key: Array # Клюс юнита @@ -103,12 +106,13 @@ func poll_receive_tcp(sock: SocketTCP, tick: int) -> bool: if sock.is_connection_available(): # check if someone's trying to connect var client = sock.take_connection() # accept connection sock.peerstream.set_stream_peer(client) # bind peerstream to new client + print_debug('client_is_connected') var peer = sock.peerstream.get_stream_peer() if peer: var peer_len_data = peer.get_available_bytes() if peer_len_data > 0: get_client_data(sock, peer_len_data, peer, tick) - if sock.unit_key in units and sock.rx_all: units[sock.unit_key].parse(sock.rx_data, tick) + if sock.unit_key in units_tcp and sock.rx_all: units_tcp[sock.unit_key].parse(sock.rx_data, tick) return false @@ -151,5 +155,9 @@ func _process(_delta: float) -> void: match unit.process(tick): Error.OK: sock_unicast.send_to(addr, unit.tx_data) Error.FAILED: emit_signal('socket_error', 'ошибка: %s %s:%d' % [unit, addr[0], addr[1]]) + for addr in units_tcp: + var unit = units_tcp[addr] + match unit.process(tick): + Error.OK: unit.send_to(addr, unit.tx_data) poll_sockets.any(func(sock): poll_receive(sock, tick)) tcp_sockets.any(func(sock): poll_receive_tcp(sock, tick)) diff --git a/scripts/tcp5p28.gd b/scripts/tcp5p28.gd index 7981316..ba0fdac 100644 --- a/scripts/tcp5p28.gd +++ b/scripts/tcp5p28.gd @@ -1,38 +1,47 @@ extends Node ## Реализация "Протокол информационного сопряжения -## СПО АСУ изделия «МП‑550» с СПО 5П28" +## СПО АСУ изделия «МП‑550» с СПО 5П-28" -const ONLINE_TIMEOUT = 3000 ## Время ожидания пакета от КАПС РПБ, мс +const ONLINE_TIMEOUT = 5000 ## Время ожидания пакета от 5П-28, мс const BUFFER_SIZE = 2048 ## Размер приёмного буфера для датаграмм class TCP5P28: + const PACK_TYPE_CMD: int = 1 + const PACK_TYPE_RES: int = 2 + const CMD_TYPE_STATE: int = 1 + const CMD_TYPE_TH: int = 2 + const CMD_TYPE_IN: int = 3 + signal line_changed(unit: TCP5P28) ## Сигнал состояние связи изменилось signal data_received(unit: TCP5P28) ## Сигнал данные приняты signal command_fail(unit: TCP5P28) ## Сигнал при не выполнении команды signal parse_error(unit: TCP5P28, msg: String) ## Сигнал ошибки разбора сообщения + signal get_threats(unit: TCP5P28) ## Сигнал запрос целей - static var json_conv: = JSON.new() var online: = false ## Состояние связи с источником сообщений var name: String ## Имя экземпляра - var json_dic: Dictionary ## Аппарат для разбора сообщений - var tick: = 0 ## Тик время последнего обновления, мс + var rx_tick: = 0 ## Тик время последнего приёма, мс var tx_data: = PackedByteArray() ## Пакет для отправки - var tx_stack: Array ## Массив пакетов для отправки + var tx_stack: Array ## Массив пакетов для отправки func _to_string() -> String: return String('капсрпб: "%s" %s ' % [self.name, ['отключен', 'на связи'][int(online)]]) func _init(nm): self.name = nm func parse(data: PackedByteArray, now_tick: int): - tick = now_tick + rx_tick = now_tick if not online: online = true emit_signal('line_changed', self) - + var pack_type = data.decode_u8(2) + if pack_type == PACK_TYPE_CMD: + var cmd_type = data.decode_u8(8) + if cmd_type == CMD_TYPE_TH: + emit_signal('get_threats') func process(now_tick: int): - if online and ((now_tick - tick) > ONLINE_TIMEOUT): + if online and ((now_tick - rx_tick) > ONLINE_TIMEOUT): online = false emit_signal('line_changed', self) if len(tx_stack): @@ -41,3 +50,41 @@ class TCP5P28: return Error.OK else: return Error.ERR_UNAVAILABLE + + func pack_threats(threats): + var data = PackedByteArray() + var data_len = 4 + len(threats) * 80 # длинна блока данных в байтах + var tick = Time.get_ticks_msec() + data.resize(4) + data.encode_u16(0, 0) # Код ошибки + data.encode_u16(2, len(threats)) # Количество целей + for th in threats.values(): + print_debug(th) + data.append_array(get_threats_data(th, int(tick))) + + func get_threats_data(th, tick): + var th_data = PackedByteArray() + th_data.resize(80) # Количество байт в массиве + th_data.encode_u64(0, tick) + print_debug(th.fflags) + var flags: int = 0 # с 0 по 7 бит рекомендованная помеха + flags |= 0 << 8 # Флаг рекомендуемой помехи + flags |= int(th.fflags['aoa']) << 9 # Флаг доставерности пеленга + flags |= int(th.fflags['alt']) << 10 # Флаг доставерности высоты + flags |= int(th.fflags['power']) << 11 # Флаг доставерности мощности + flags |= int(th.fflags['baud']) << 12 # Флаг доставерности ск. мод. + flags |= int(th.fflags['slon']) << 13 # Флаг доставерности долготы ст. позиции + flags |= int(th.fflags['slat']) << 14 # Флаг доставерности широты ст. позиции + flags |= int(th.fflags['lat']) << 15 # Флаг доставерности долготы + flags |= int(th.fflags['lot']) << 16 # Флаг доставерности широты + flags |= int(0) << 30 # Флаг признак назначения помехи на цель + flags |= int(0) << 31 # Флаг признак назначения опасной цель + th_data.encode_u32(8, flags) # Флаги + return th_data + + func create_header(data_len): + var head_len: int = 8 # длинна заголовка в байтах + pass + + + diff --git a/scripts/threats.gd b/scripts/threats.gd index cb4f4ca..653a836 100644 --- a/scripts/threats.gd +++ b/scripts/threats.gd @@ -13,8 +13,8 @@ class Threat: var freq: float ## Частота несущей или центральная частота, МГц. var freqm: String ## Режим смены частоты. var id: int ## Идентификатор цели. - var lat: float ## Текущие координаты, долгота в градусах. - var lon: float ## Текущие координаты, широта в градусах. + var lat: float ## Текущие координаты, широта в градусах. + var lon: float ## Текущие координаты, долгота в градусах. var power: float ## Уровень принимаемого сигнала, дБм. var proto: String ## Тип протокола источника сигнала. var rkrp: String ## Рекомендуемый режим помехи. @@ -48,9 +48,12 @@ func _ready() -> void: var threats = {} ## Список целей. Индекс - <номер цели> var unit_key = repsettings.get_unit_key('уарэп-капсрпб-отп') var unit = repnetwork.units[unit_key] + var unit_5p28_key = repsettings.get_unit_key('уарэп-5п28') + var unit_5p28 = repnetwork.units_tcp[unit_5p28_key] var timer_check_lost: = Timer.new() add_child(timer_check_lost) unit.connect('data_received', Callable(self, 'on_data_capsrpb_received').bind(threats)) + unit_5p28.connect('get_threats', Callable(self, 'on_get_threats').bind(unit_5p28, threats)) timer_check_lost.connect('timeout', Callable(self, 'on_timer_check_lost').bind(repsettings.ThreatParams.time_lost, threats)) timer_check_lost.start(repsettings.ThreatParams.time_lost / 1000.0) signaller.connect('rto_threat_sel', Callable(self, 'on_rto_threat_sel').bind(threats)) @@ -71,6 +74,10 @@ func on_timer_check_lost(time_lost: int, threats: Dictionary): call_deferred('emit_signal', 'threats_resized', threats) +## отправляет словапь целей в юнит, для запаковки и отправки в 5П28 +func on_get_threats(unit, threats): unit.pack_threats(threats) + + ## Снимает выделение с цели, если нажать по отметке цели. func on_rto_threat_unsel(th_id, threats): threats[th_id].selected = false