Реализация протокола CCSDS 235.1

Введение

Несколько месяцев назад я решил поучаствовать в конкурсе от Европейского Космического Агенства (ESA). Цель конкурса - реализовать одну из спецификаций для связи в космосе. Я никогда не реализовывал никакой стандарт, поэтому решил попробовать. К тому же - это очень сильно пересекается с тем, что я делаю в рамках своего хобби проекта r2cloud: получение данных со спутников.

Внимание Целью этой статьи является исследование и анализ протокола. Это моя первая попытка реализовать протокол такого уровня. Не используйте информацию ниже в реальных миссиях, либо используйте её с крайней осторожностью.

Как известно, для того, чтобы запомнить или разобраться в чём-то, лучше всего научить этому кого-нибудь другого. К сожалению, не так много людей хотят узнать, как работает этот протокол, поэтому я постараюсь просто пересказать его своими словами ниже.

Спецификация CCSDS 235.1

Спецификация, которую я решил реализовать, называется CCSDS 235.1 “SPACE COMMUNICATIONS SESSION CONTROL”. Он предназначен для установления и поддержки сессии между двумя объектами. Это может быть спутник-спутник или спутник-земля. В общем случае сессия не обязательна: если известны параметры связи со спутником, то их можно вручную сконфигурировать на станции и начать обмениваться данными. Однако, этот подход не всегда работает:

  • Большое количество спутников и станций. Нужно заранее знать параметры каждого
  • Динамическое изменение параметров. Например, из-за плохой погоды или расстояния связь переключается на более медленную, но более надёжную

CCSDS 235.1 расширяет спецификацию CCSDS 211.0 “PROXIMITY-1 SPACE LINK PROTOCOL — DATA LINK LAYER”. Последняя активно используется на Марсе, но у неё есть ряд недостатков:

  • Низкие скорости передачи данных (UHF-band). Новая спецификация разрабатывается для лунных миссий, где можно использовать более высокие частоты (S-band) и более быстрые каналы
  • Нет возможности договариваться о канале передачи данных. Условия могут меняться в зависимости от погоды и расстояний.

В CCSDS 235.1 есть секция “Purpose”, но она сводится к тому, что сессионный протокол нужен и его надо стандартизировать. Явного перечисления недостатков старого протокола нет

Организация CCSDS пытается делать модульную архитектуру протоколов, поэтому существует множество маленьких стандартов, каждый из которых может отвечать лишь за небольшую часть. Полный стек протоколов похож на модель OSI, но немного отличается:

235.1
SPACE COMMUNICATIONS SESSION CONTROL
235.1...
211.2
PROXIMITY-1 SPACE LINK PROTOCOL—CODING AND SYNCHRONIZATION SUBLAYER
211.2...
131.0
TM SYNCHRONIZATION AND CHANNEL CODING
131.0...
211.1
PROXIMITY-1 SPACE LINK PROTOCOL — PHYSICAL LAYER
211.1...
Data Link Layer
Data Link Layer
732.0
AOS SPACE DATA LINK PROTOCOL
732.0...
PHYSICAL LAYER
PHYSICAL LAYER
732.1
UNIFIED SPACE DATA LINK PROTOCOL
732.1...
211.0
PROXIMITY-1 SPACE LINK PROTOCOL—DATA LINK LAYER
211.0...

Существует как минимум 3 разных Data Link протокола, каждый из которых разработан для разных целей. Например, AOS используется для обмена данными на большом расстоянии. Он однонаправленный и поддерживает передачу большого объёма данных. CCSDS 235.1 используется на небольших расстояниях, где задержка между приёмником и передатчиком позволяет передавать данные в две стороны и договариваться о протоколе.

В самом начале я задавался вопросом: “А почему не подходит один из существующих протоколов? Например, TCP”. Ответ на самом деле простой: TCP рассчитан на работу в сети Интернет, где множество участников используют один и тот же канал (провод). Связь спутник-спутник - это точка-точка с помощью радио. Эту особенность можно и нужно использовать для того, чтобы сделать связь более эффективной.

Возможности

В CCSDS 235.1 определены следующие операции:

  • Установка соединения и создание сессии (Hail)
  • Завершение сессии
  • Изменение параметров сессии. Например, переключение на другую частоту, уменьшение или увеличение скорости передачи данных
  • Восстановление сессии после потери синхронизации или фреймов

Каждая из этих операций описывается машиной состояний.

Запрос на установку соединения может содержать “Link Negotiation” параметр. Видимо подразумевается, что получатель может отклонить запрашиваемые параметры и отправитель пошлёт другие. Однако, в спецификации нет описания этого механизма и соответствующей машины состояний. Спецификация отталкивается от того, какие данные участники посылают друг другу, вместо того, какие существуют возможности.

Каждая из этих операций должна работать в трёх режимах передачи данных:

  • Дуплексный (две независимые частоты)
  • Полудуплексный
  • Симплексный

Режим передачи данных является параметром сессии и может переключаться в процессе работы.

В рамках сессии данные могут передаваться:

  • с гарантией. В таком случае отправитель узнает, если данные невозможно было послать
  • без гарантии. Отправительно не узнает, дошли ли данные до получателя или нет

С точки зрения передаваемых данных это могут быть:

  • служебные (для поддержания сессии)
  • пользовательские данные

Служебные данные могут быть нескольких видов:

  • Тип 1. Используются стандартом Proximity-1 (CCSDS 211.0).
  • Тип 4. Первая версия для лунного использования
  • Тип 5. Вторая версия для лунного использования Соломана

Если разница между первым и четвёртым типом понятна, то в каких случаях стоит использовать пятый, а в каких четвёртый непонятно. Причём они появились одновременно в CCSDS 235.1, а не перенеслись из других версий.

Пользовательские данные могут быть нескольких типов:

  • Пакетная передача: массивы данных переменной длины. Канальный уровень разбивает их на один или несколько фреймов и при получении пытается собрать воедино
  • Потоковая передача. Канальный уровень контролирует только порядок отправки и получения

Служебные и пользовательские данные упаковываются во фреймы. Эти фреймы могут быть нескольких версий и протокол должен их все поддерживать:

  • Версия 2, описывается в CCSDS 732.0 (AOS). Поддеживаются только пользовательские данные
  • Версия 3, описывается в CCSDS 211.0 (Proximity-1)
  • Версия 4, описывается в CCSDS 732.1 (USLP)

Выделение сессий в отдельную спецификацию - решение довольно спорное. Если раньше Proximity-1 определял сессии и тип фреймов, которыми обменивались участники, то в новой версии нужно поддерживать многие-ко-многим. Разные типы сессий (Proximity-1) с разными типами фреймов. Если марсоход поддерживает Proximity-1 и фреймы версии 3, то он никогда не будет поддерживать Proximity-1 и фреймы версии 4. А если добавляется поддержка фреймов версии 4, то почему нельзя обновить и сессионный протокол?

Далее фреймы упаковываются в PLTU, и уже они отправляются в физический канал.

Физический уровень

CCSDS 235.1 - это протокол канального уровня (Data Link). Ниже идёт CCSDS 211.2, в котором фреймы упаковываются в PLTU и происходит кодирование LDPC, Рида-Соломона и/или свёрточное. Взаимодействие с физическим уровнем очень хорошо представлено на схеме из CCSDS 211.1:

variables
MODE
DUPLEX
TRANSMIT
MODULATION
variables...
MAC sublayer
MAC sublayer
Data Link Layer
Data Link Layer
coded symbol
stream for
transmission
coded symbol...
C&S
C&S
Physical Layer
Physical Layer
received
coded symbol stream
received...
signals:
CARRIER_ACQUIRED
SYMBOL_INLOCK_STATUS
signals:...

У меня нет практического опыта реализации физического уровня. Однако, то, как он описан, вполне может быть реализовано с помощью моей библиотеки sx127x:

  • сигналы - это асинхронные прерывания. На практике это могут быть:
    • Carrier Acquired
    • Carrier Lost
    • Symbol lock
    • Symbol unlock
    • Rx - В случае пакетной передачи sx127x генерирует прерывание, сообщая о том что данные получены и контрольная сумма совпала
    • TxComplete - Прерывание, генерируемое, когда данные фактически отправились в эфир. В зависимости от скорости отправки данных, это может занять достаточно длительное время. Если добавить такой сигнал, то вызывающий поток можно разблокировать и не ждать результата отправки
  • переменные TRANSMIT, MODULATION можно заменить на переключение режима трансивера
  • sx127x может работать только в режиме HALF-DUPLEX
  • Часть фукнций C&S уровня можно перенести в sx127x: добавление ASM маркера, отправка пакета, FSK модуляция (хотя я не уверен в том, что CCSDS стандарты поддерживают её)
  • Некоторые функции C&S можно реализовать только в коде: добавление crc32 (sx127x поддерживает только crc16) и различные виды кодирования

Для меня большой неожиданностью стало то, что в CCSDS отсутствует модель трансивера. Стандарт определяет две булевые переменные: TRANSMIT и MODULATION - и достаточно сумбурную таблицу их комбинаций. Причём, очевидно, что некоторые комбинации не имеют смысла, и поэтому обозначаются как “N/A”. Насколько же понятнее было бы, если бы модель описывалась enum, как в sx127x

Операции

Операции очень хорошо описаны в виде таблиц и графов. Однако, для понимания общей картины взаимодействия лучше использовать диаграммы последовательностей. Помимо этого интересно посмотреть как та или иная операция будет выглядеть на спектограмме. Для этого я приложил справа схематичное изображение спектограммы.

Дуплексный режим

Установка соединения

Caller
Caller
Responder
Responder
Radiate Carrier
Radiate Carrier
Modulate idle
Modulate idle
Send hail
Send hail
Caller's
Transceiver
Caller's...
Carrier Timeout
Carrier Timeout
Idle Timeout
Idle Timeout
Complete
Complete
Tail Idle Timeout
Tail Idle Timeout
Hail Wait Timeout
Hail Wait Timeout
PLCW
PLCW
Carrier Timeout
Carrier Timeout
Acquisition Idle Timeout
Acquisition Idle Timeout
Carrier Timeout
Carrier Timeout
Acquisition Idle Timeout
Acquisition Idle Timeout
Responder's
Transceiver
Responder'...
Hail Received
Hail Received
PLCW
PLCW
Complete
Complete
Caller TX
Caller TX
Responder TX
Responder TX
Hail Channel
Hail Chann...
Caller TX
Caller TX
Responder TX
Responder TX
Comm Channel
Comm Chann...
Carrier locked
Carrier locked
Symbol locked
Symbol locked
Carrier locked
Carrier locked
Symbol locked
Symbol locked
Carrier locked
Carrier locked
Symbol locked
Symbol locked

Изменение параметров сессии

Caller
Caller
Responder
Responder
Caller's
Transceiver
Caller's...
Responder's
Transceiver
Responder'...
Caller TX
Caller TX
Responder TX
Responder TX
Old
Channel
Old...
Caller TX
Caller TX
Responder TX
Responder TX
Comm Channel
Comm Chann...
Send comm
parameters
Send comm...
Receive comm
parameters
Receive comm...
Complete
Complete
Comm Change 
timeout
Comm Change...
Symbol unlock
Symbol unlock
Symbol lock
Symbol lock
PLCW
PLCW
Apply New RX
Apply New RX
Apply New TX
Apply New TX
Carrier timeout
Carrier timeout
Acquisition Idle timeout
Acquisition Idle timeout
Previous TX 
complete
Previous TX...
Tail Idle timeout
Tail Idle timeout
Apply New Rx/Tx
Apply New Rx/Tx
Carrier timeout
Carrier timeout
PLCW
PLCW
Acquisition Idle timeout
Acquisition Idle timeout

Завершение сессии

Caller
Caller
Responder
Responder
Caller's
Transceiver
Caller's...
Responder's
Transceiver
Responder'...
Caller TX
Caller TX
Responder TX
Responder TX
Channel
Channel
PLCW
Rnmd=true
PLCW...
PLCW
Rnmd=true
PLCW...
Complete
Complete
PLCW
Rnmd=true
PLCW...
PLCW
Rnmd=true
PLCW...
Tail Idle timeout
Tail Idle timeout
Complete
Complete
Tail Idle timeout
Tail Idle timeout

Полудуплексный режим

Установка соединения

Caller
Caller
Responder
Responder
Radiate Carrier
Radiate Carrier
Modulate idle
Modulate idle
Send hail
Send hail
Caller's
Transceiver
Caller's...
Idle Timeout
Idle Timeout
Complete
Complete
Tail Idle Timeout
Tail Idle Timeout
Hail Wait Timeout
Hail Wait Timeout
PLCW
PLCW
Carrier Timeout
Carrier Timeout
Acquisition Idle Timeout
Acquisition Idle Timeout
Responder's
Transceiver
Responder'...
Hail Received
Hail Received
PLCW
PLCW
Caller TX
Caller TX
Responder TX
Responder TX
Hail Channel
Hail Chann...
Caller TX
Caller TX
Responder TX
Responder TX
Comm Channel
Comm Chann...
Carrier locked
Carrier locked
Symbol locked
Symbol locked
Tx on Hail Channel
Tx on Hail Channel
Rx on Comm Channel
Rx on Comm Channel
Apply Tx 
Comm Channel
Apply Tx...
Rx on Hail Channel
Rx on Hail Channel
Tx on Comm Channel
Tx on Comm Channel
Carrier Timeout
Carrier Timeout

Обмен данными

Для передачи данных в полудуплексном режиме используется “transmit” токен, который передаётся туда-сюда.

Caller
Caller
Responder
Responder
Caller's
Transceiver
Caller's...
Responder's
Transceiver
Responder'...
Tx Token
Tx Token
Data
Data
Switch to Tx
Switch to Tx
Complete
Complete
Receive timeout
Receive timeout
Data
Data
Carrier Timeout
Carrier Timeout
Acquisition Idle Timeout
Acquisition Idle Timeout
Send timeout
Send timeout
Data
Data
Data
Data
Complete
Complete
Tail Idle timeout
Tail Idle timeout
Switch to Rx
Switch to Rx
Tx Token
Tx Token
Carrier Locked
Carrier Locked
Symbol Locked
Symbol Locked

Завершение сессии

К сожалению, в данном случае диаграмма последовательностей не может отобразить всю сложность операции, так как команда Termination может прийти в разные фазы приёма-передачи и для каждого случая своя последовательность действий.

Caller
Caller
Responder
Responder
Caller's
Transceiver
Caller's...
Responder's
Transceiver
Responder'...
Terminate
Terminate
Switch to Rx
Switch to Rx
Frame
Frame
Frame
Frame
Switch to Tx
Switch to Tx
Frame
Frame
PLCW
Rnmd=true
PLCW...
Frame
Frame
Frame
Frame
Switch to Rx
Switch to Rx
Frame
Frame
PLCW
Rnmd=true
PLCW...
Switch to Tx
Switch to Tx
PLCW
Rnmd=true
PLCW...
PLCW
Rnmd=true
PLCW...
Frame
Frame
Frame
Frame
Terminate
Terminate
Switch to Rx
Switch to Rx
Tail Idle timeout
Tail Idle timeout
Tail Idle timeout
Tail Idle timeout

В результате появляются две машины состояний: одна - ответственна за переключение между приёмом (Rx) и передачей (Tx), а другая - за переход между фазами завершения сессии. Завершение сессии считается, когда отправитель и получатель явно указали, что данных для отправки больше нет.

В такой схеме получается достаточно странная ситуация. Допустим, отправитель отправил все данные и отправил команду на завершение сессии. После этого получатель доотправляет данные и отвечает командой завершения сессии. А может ли получится так, что отправитель получает последние данные и должен как то среагировать на них?

Послесловие

В данный момент я заканчиваю реализацию спецификации и основные компоненты и классы уже не должны сильно меняться. На текущий момент получилось около 11 тысяч строчек кода. Но самое сложное ещё впереди - тестирование производительности и машин состояний.