Доработка. Добавлен разбор принятого пакета от 5П-28

This commit is contained in:
MaD_CaT
2024-03-05 09:14:01 +03:00
parent 0d0c557655
commit 5ca0fc451b
3 changed files with 74 additions and 12 deletions

View File

@@ -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))

View File

@@ -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

View File

@@ -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