Реализация протокола 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, но немного отличается:
Существует как минимум 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:
У меня нет практического опыта реализации физического уровня. Однако, то, как он описан, вполне может быть реализовано с помощью моей библиотеки 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

Операции
Операции очень хорошо описаны в виде таблиц и графов. Однако, для понимания общей картины взаимодействия лучше использовать диаграммы последовательностей. Помимо этого интересно посмотреть как та или иная операция будет выглядеть на спектограмме. Для этого я приложил справа схематичное изображение спектограммы.
Дуплексный режим
Установка соединения
Изменение параметров сессии
Завершение сессии
Полудуплексный режим
Установка соединения
Обмен данными
Для передачи данных в полудуплексном режиме используется “transmit” токен, который передаётся туда-сюда.
Завершение сессии
К сожалению, в данном случае диаграмма последовательностей не может отобразить всю сложность операции, так как команда Termination может прийти в разные фазы приёма-передачи и для каждого случая своя последовательность действий.
В результате появляются две машины состояний: одна - ответственна за переключение между приёмом (Rx) и передачей (Tx), а другая - за переход между фазами завершения сессии. Завершение сессии считается, когда отправитель и получатель явно указали, что данных для отправки больше нет.
В такой схеме получается достаточно странная ситуация. Допустим, отправитель отправил все данные и отправил команду на завершение сессии. После этого получатель доотправляет данные и отвечает командой завершения сессии. А может ли получится так, что отправитель получает последние данные и должен как то среагировать на них?
Послесловие
В данный момент я заканчиваю реализацию спецификации и основные компоненты и классы уже не должны сильно меняться. На текущий момент получилось около 11 тысяч строчек кода. Но самое сложное ещё впереди - тестирование производительности и машин состояний.