При поиске неисправностей в сервисных интерфейсах ядра 5G инженеры часто сталкиваются с одной и той же проблемой. Тело запроса, отправленного от AMF к SMF, может содержать знакомые поля SUPI, DNN, S-NSSAI, TAI, PDU Session ID и 5QI, однако определить, действительно ли сообщение корректно, всё равно бывает непросто. Должно ли поле кодироваться как строка или целое число? Имеет ли оно заданный диапазон значений? Допустимо ли любое значение или оно должно выбираться из заранее определённого перечисления? Может ли объект содержать другие вложенные параметры?
Ответы задаются общими типами данных SBI. Сервисные интерфейсы охватывают такие сетевые функции, как AMF, SMF, UDM, PCF и NRF, однако многие базовые параметры не относятся исключительно к одной NF. Если бы каждый сервис определял эти значения самостоятельно, спецификации содержали бы ненужные дублирования, а один и тот же идентификатор абонента или параметр QoS мог бы представляться по-разному в разных API. Поэтому анализ трафика SBI требует большего, чем проверка HTTP-методов и URI ресурсов. HTTP/2 определяет способ транспортировки запросов, JSON — способ представления данных, а общие типы данных отвечают на более фундаментальный вопрос: какому формату и каким правилам проверки должен соответствовать каждый параметр JSON.
Какие задачи решают общие типы данных?
Их можно рассматривать как общий «словарь данных» для всей сервисной API-среды 5GC. Один и тот же тип данных может встречаться в запросе AMF и одновременно использоваться SMF, UDM или PCF. Он не принадлежит одному интерфейсу, а предоставляет стандартизированное определение, которое можно повторно использовать в разных сервисах.
Рассмотрим IPv4-адрес. Каждая NF не должна самостоятельно определять, как представлять такой адрес строкой. То же относится к информации PLMN, где MCC и MNC имеют определённую длину и формат, а также к идентификаторам абонента и оборудования, таким как SUPI, GPSI и PEI, для которых действуют собственные правила кодирования. Единообразные определения позволяют RESTful API разных NF надёжно обмениваться информацией.
Общие типы данных также следует отличать от типов, специфичных для конкретной NF. Общие типы описывают объекты, которые многократно используются в разных интерфейсах, тогда как бизнес-объекты, характерные только для определённой сетевой функции, определяются в соответствующих спецификациях серии 29. На практике один SBI API часто ссылается на оба вида типов данных.
Их область применения намного шире сетевых адресов. Общие определения охватывают универсальные параметры, данные подписки и идентификации, сетевые данные 5G, QoS, тарификацию, информацию трассировки и другие повторно используемые объекты. В совокупности они образуют базовую модель данных для параметров сообщений SBI.
Чем отличаются три основные структуры данных?
С точки зрения структуры параметры SBI обычно можно разделить на три категории: простые типы данных, перечисления и структурированные типы данных. Понимание этих трёх категорий полезнее заучивания отдельных имён параметров, поскольку большинство полей в захватах Wireshark, документации API и определениях OpenAPI укладываются именно в эту модель.
Простые типы данных — это базовые строительные блоки самого нижнего уровня. К ним относятся строка, целое число, число, дата, дата-время и логическое значение. В 5GC эти базовые типы обычно дополняются ограничениями, такими как диапазоны значений, форматы кодирования или шаблоны регулярных выражений.
Например, IPv4-адрес технически представляется строкой, но произвольная строка недопустима. Она должна соответствовать требуемому формату IPv4. Адреса IPv6, префиксы IPv6 и MAC-адреса имеют собственные требования к формату. Uint16, Uint32 и Uint64 задают диапазоны беззнаковых целых чисел. URI должен соответствовать правилам формата URI, а значения DateTime должны использовать установленный формат даты и времени.
В спецификациях также часто определяются типы с суффиксом Rm, например Ipv4AddrRm, DateTimeRm и Uint32Rm. Они используют тот же базовый формат, что и соответствующие обычные типы, но включают свойство nullable OpenAPI, поэтому поле может содержать значение null.
Типы-перечисления работают как поля с выбором из списка: значение должно быть взято из заранее определённого набора. Например, AccessType различает 3GPP_ACCESS и NON_3GPP_ACCESS. PduSessionType может принимать IPV4, IPV6, IPV4V6, UNSTRUCTURED или ETHERNET. CoreNetworkType может указывать 5GC или EPC.
Назначение перечисления — исключить неоднозначность. Потребитель сервиса не может придумать другую строку с похожим смыслом, а должен использовать одно из значений, явно заданных спецификацией. Это частая ситуация при диагностике: имя поля указано верно, но значение перечисления недопустимо, поэтому API всё равно отклоняет запрос или трактует его неправильно.
Структурированные типы данных объединяют несколько атрибутов в цельный объект. Сами атрибуты могут ссылаться на простые типы, перечисления или другие структурированные объекты, формируя иерархическую модель.
ProblemDetails — типичный пример. Он может содержать поля type, title, status, detail, instance, cause и invalidParams. Другой пример — TAI, объединяющий PLMN ID и TAC. GUAMI идёт на уровень выше и объединяет PLMN ID с AMF ID. На этом уровне анализа SBI уже недостаточно рассматривать отдельные поля — важны и связи между атрибутами внутри объекта.
Как строятся параметры идентификации и сети?
В реальных пакетных трассах данные подписки, идентификации и сети 5G относятся к наиболее распространённым параметрам SBI. SUPI идентифицирует абонента, GPSI представляет внешний идентификатор абонента, PEI — постоянный идентификатор оборудования, DNN обозначает сеть передачи данных, а NF Instance ID однозначно идентифицирует экземпляр NF.
Большинство этих полей выглядят как простые строки, но важнее всего правило кодирования внутри строки. SUPI может содержать представление IMSI или NAI, а GPSI — MSISDN или External Identifier. Иными словами, если поле определено как строка, это не означает, что допустима любая строка.
Типы, связанные с сетью 5G, используют эти базовые идентификаторы для представления данных сеанса и местоположения. PduSessionId идентифицирует PDU Session. MCC и MNC входят в состав идентичности PLMN. TAC обозначает Tracking Area Code, а NrCellId и EutraCellId идентифицируют соответственно соты NR и E-UTRA.
Затем структурированные объекты объединяют базовые параметры в модели более высокого уровня. S-NSSAI использует SST и необязательный SD для представления сетевого среза. TAI объединяет PLMN ID и TAC. NCGI объединяет PLMN ID с NR Cell ID для идентификации соты NR, а ECGI выполняет аналогичную функцию для E-UTRA.
UserLocation является ещё более высокоуровневой абстракцией. В зависимости от типа доступа он может содержать NR Location, E-UTRA Location или Non-3GPP Access Location. В свою очередь, NR Location может включать TAI, NCGI, временную метку местоположения и географические данные.
Это демонстрирует модульную архитектуру моделей данных SBI. Сначала стандартизируются базовые элементы, такие как MCC, MNC, TAC и Cell ID, затем они объединяются в объекты более высокого уровня — PLMN ID, TAI, NCGI и UserLocation. API могут повторно использовать готовые объекты вместо того, чтобы заново определять полный набор параметров местоположения для каждого сервиса.
Почему данные QoS, тарификации и трассировки тоже нужно стандартизировать?
Трафик SBI передаёт намного больше, чем идентичности абонентов и сетевое местоположение. Политики QoS, сведения об использовании и данные сетевой трассировки также передаются между несколькими NF, поэтому для этих значений тоже нужны единообразные определения.
Среди параметров QoS QFI идентифицирует QoS Flow, 5QI представляет 5G QoS Identifier, BitRate задаёт скорость с помощью значения и единицы измерения, Packet Delay Budget определяет бюджет задержки, а Packet Error Rate и Packet Loss Rate описывают качество передачи.
Политики QoS также используют множество перечислений. PreemptionCapability показывает, может ли сервис вытеснять ресурсы, назначенные другим сервисам. PreemptionVulnerability показывает, могут ли существующие ресурсы быть отобраны сервисом с более высоким приоритетом. QosResourceType различает значения NON_GBR, NON_CRITICAL_GBR и CRITICAL_GBR.
Затем эти базовые поля объединяются в структурированные объекты, такие как ARP, AMBR, Dynamic 5QI и Non-Dynamic 5QI. Благодаря этому SMF, PCF и другие связанные сетевые функции используют единое представление при обмене такими понятиями, как приоритет, скорость передачи, задержка и поведение при вытеснении ресурсов.
Данные тарификации строятся по тому же принципу. ChargingId, RatingGroup и ServiceId — относительно простые типы данных, тогда как QoSFlowUsageReport может содержать QFI, временные метки начала и окончания сбора, а также объёмы восходящего и нисходящего трафика. VolumeTimedReport может отражать использование PDU Session за заданный интервал времени.
Типы, относящиеся к трассировке, стандартизируют информацию сетевого отслеживания. TraceDepth использует значения перечисления для описания различных уровней трассировки, а TraceData объединяет параметры Trace Reference, Trace Depth и NE Type. Это не позволяет каждой NF определять собственный несовместимый набор полей трассировки.
Эти примеры показывают, что общие типы данных делают гораздо больше, чем стандартизируют «несколько полей JSON». Они стандартизируют то, как разные сервисы ядра сети понимают одни и те же бизнес- и сетевые понятия. Если QoS, местоположение, сведения о тарификации или идентификаторы абонентов должны передаваться между несколькими NF, им прежде всего нужна согласованная модель данных.
Как использовать типы данных при практической диагностике?
Одна из самых распространённых инженерных ошибок — проверять в сообщении JSON только наличие поля, не анализируя его тип данных и связанные ограничения. Более эффективный подход — рассматривать HTTP-уровень и модель данных вместе.
Сначала определите вызываемый сервис и URI ресурса. Затем найдите целевое поле в теле запроса или ответа. После этого не ограничивайтесь самим значением: проверьте, на какой тип данных ссылается поле, является ли оно обязательным или необязательным, какова его Cardinality, относится ли оно к перечислению и есть ли ограничения Format или Pattern.
Поле IPv4 может выглядеть для человека как IP-адрес, но если оно не соответствует определённому формату, оно всё равно является некорректным вводом. Аналогично, значение PduSessionType может быть понятно по смыслу, но если оно отсутствует среди разрешённых значений перечисления, оно не соответствует определению API.
Структурированные данные нужно раскрывать рекурсивно. При появлении UserLocation следует определить, содержит ли объект данные местоположения NR, E-UTRA или Non-3GPP. При появлении TAI нужно проверить PLMN ID и TAC. При появлении S-NSSAI — SST и необязательный SD. Только последовательное прохождение по ссылкам типов позволяет определить, соответствует ли объект JSON модели API.
Когда сервер отклоняет запрос, также следует внимательно проверить ProblemDetails. Помимо HTTP-кода состояния, он может содержать detail, cause и invalidParams. Если эти поля присутствуют, диагностику можно начать с конкретного параметра, нарушившего требования API, а не останавливаться на общей ошибке HTTP 4xx.
Почему мышление моделью данных полезнее, чем запоминание таблиц параметров?
Количество общих типов данных SBI в 5GC настолько велико, что запоминание каждого поля, регулярного выражения и диапазона значений быстро становится неэффективным. Более практичный подход — мыслить моделью данных: простые типы определяют минимальные единицы данных, перечисления ограничивают допустимые состояния, а структурированные типы объединяют эти единицы в объекты, которые сервисы 5GC могут использовать напрямую.
В этой модели SUPI, MCC, TAC и QFI перестают быть отдельными параметрами. Они становятся строительными блоками моделей абонента, местоположения, сеанса, QoS, тарификации и трассировки. Одна из причин, по которой разные NF могут единообразно вызывать сервисы через SBI, заключается в том, что общие типы обеспечивают стабильную и повторно используемую семантику данных.
Поэтому при чтении незнакомого 5GC API полезнее сначала спросить не «Сколько полей в этом сообщении?», а определить, на какие типы ссылаются эти поля, как вложены объекты и какие ограничения определяют корректность итогового JSON. Освоив этот подход, даже ранее неизвестный SBI-сервис можно анализировать, последовательно переходя по определениям OpenAPI и типов данных, вместо заучивания новой таблицы параметров.
Часто задаваемые вопросы
Какая спецификация 3GPP определяет общие типы данных SBI?
Они в основном определены в TS 29.571, 5G System; Common Data Types for Service Based Interfaces. Эта спецификация описывает повторно используемые структуры данных, общие для сервисов SBI. Сервисы и типы данных, специфичные для отдельных NF, определяются в соответствующих спецификациях серии 29.5xx, например TS 29.502 для сервисов SMF и TS 29.503 для сервисов UDM.
Как свойство nullable из OpenAPI выглядит в реальном сообщении JSON?
Поле, определённое как nullable, обычно через тип с суффиксом Rm, может явно содержать значение null в теле JSON, указывая, что в данный момент ему не присвоено допустимое значение. Это отличается от полного отсутствия поля. Отсутствующее поле может означать, что параметр неприменим или не был передан, а явное null может иметь конкретное семантическое значение, например очистку ранее настроенного значения.
Могут ли общие типы данных SBI различаться у разных производителей?
На уровне спецификации определения стандартизированы, однако в реальных продуктах возможны различия реализации. Некоторые производители могут поддерживать только часть необязательных полей, отдельные API могут содержать фирменные расширения, а строгость проверки значений перечислений может отличаться. Такие различия часто проверяются при тестировании совместимости.
Как быстро определить, использует поле общий или NF-специфичный тип?
Самый прямой способ — проверить путь $ref в определении OpenAPI. Если ссылка указывает на общую схему из TS 29.571, обычно это общий тип данных SBI. Если она указывает на схему, определённую в текущей спецификации сервиса, тип, как правило, является NF-специфичным. Знание часто используемых типов, таких как SUPI, TAI, S-NSSAI и ProblemDetails, также облегчает их распознавание при анализе пакетов.
Чем тип Rm отличается от обычного типа в пакетном захвате?
Если значение не равно null, его представление в JSON практически одинаково для обоих типов, поскольку они используют один базовый формат. Различие существует на уровне модели OpenAPI: тип Rm разрешает полю содержать null. Если захваченное поле явно содержит null, оно должно использовать nullable-определение. Если поле содержит обычное корректное значение, одного значения недостаточно, чтобы определить, ссылается ли схема на обычный тип или на соответствующий тип Rm.