5Gコアのサービスベースインターフェース(SBI)をトラブルシューティングしていると、多くのエンジニアが同じ問題に直面します。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パラメータが従うべき形式と検証ルールを定義します。
共通データ型はどのような問題を解決するのか?
共通データ型は、5GCのサービスベースAPI環境全体で共有される「データ語彙」と考えることができます。あるデータ型がAMFのリクエストに現れ、同時にSMF、UDM、PCFから参照されることもあります。特定の1つのインターフェースに属するのではなく、複数のサービスで再利用できる標準化された定義を提供します。
IPv4アドレスを例に考えてみましょう。各NFがアドレスを文字列としてどう表現するかを独自に定義すべきではありません。MCCとMNCに特定の長さと形式があるPLMN情報についても同様です。SUPI、GPSI、PEIなどの加入者・端末識別子にもそれぞれ固有の符号化ルールがあります。定義を統一することで、異なるNF間のRESTful APIが情報を確実に交換できます。
共通データ型はNF固有型とも区別する必要があります。共通型は複数のインターフェースで繰り返し登場するオブジェクトを対象とし、特定のネットワーク機能だけに固有の業務オブジェクトは対応する29シリーズ仕様で定義されます。実際には、1つのSBI APIが両方の種類のデータ型を参照することがよくあります。
対象範囲はネットワークアドレスだけにとどまりません。共通定義には汎用パラメータ、契約・ID情報、5Gネットワークデータ、QoS、課金、トレース情報、その他の再利用可能なオブジェクトが含まれます。これらを合わせることで、SBIメッセージパラメータの基盤となるデータモデルが構成されます。
3つの基本的なデータ構造はどう違うのか?
構造という観点では、SBIパラメータは一般に、単純データ型、列挙型、構造化データ型の3種類に分類できます。個々のパラメータ名を暗記するより、この3分類を理解する方が実用的です。Wiresharkのキャプチャ、APIドキュメント、OpenAPI定義で見かける多くのフィールドがこのモデルに当てはまるからです。
単純データ型は最も基本的な構成要素です。文字列、整数、数値、日付、日時、ブール値などが含まれます。5GCでは、これらの基本型に値域、符号化形式、正規表現パターンなどの追加制約が組み合わされるのが一般的です。
例えばIPv4アドレスは技術的には文字列として表現されますが、任意の文字列が有効なわけではありません。規定されたIPv4形式に従う必要があります。IPv6アドレス、IPv6プレフィックス、MACアドレスにもそれぞれ形式要件があります。Uint16、Uint32、Uint64は符号なし整数の値域を定義します。URIはURI形式の規則に従い、DateTime値は指定された日時形式を使用する必要があります。
仕様では、Ipv4AddrRm、DateTimeRm、Uint32RmのようにRmサフィックスを持つ型も頻繁に定義されています。これらは対応する基本型と同じ基礎形式を使いますが、OpenAPIのnullableプロパティを含むため、フィールドにnull値を設定できます。
列挙型は選択肢から値を選ぶフィールドのように機能します。値は事前定義された集合から選択しなければなりません。例えばAccessTypeは3GPP_ACCESSとNON_3GPP_ACCESSを区別します。PduSessionTypeはIPV4、IPV6、IPV4V6、UNSTRUCTURED、ETHERNETなどの値を取れます。CoreNetworkTypeは5GCまたはEPCを示します。
列挙型の目的は曖昧さをなくすことです。Consumer側が「意味は同じだから」と別の文字列を勝手に作ることはできず、仕様で明示された値のいずれかを使用する必要があります。これはトラブルシューティングでよくあるケースです。フィールド名は正しくても列挙値が無効であるため、APIがリクエストを拒否したり誤って解釈したりします。
構造化データ型は複数の属性を1つの完全なオブジェクトにまとめます。それぞれの属性が単純型、列挙型、別の構造化オブジェクトを参照することもあり、階層的なモデルが形成されます。
ProblemDetailsは代表例です。type、title、status、detail、instance、cause、invalidParamsなどのフィールドを含めることができます。TAIも構造化型の一例で、PLMN IDとTACを組み合わせます。GUAMIはさらに一段上で、PLMN IDとAMF IDを組み合わせます。この段階では、SBI解析は個々のフィールドだけを見るのではなく、オブジェクト内部の属性同士の関係も確認する必要があります。
IDとネットワークパラメータはどのように組み立てられるのか?
実際のパケットキャプチャでは、契約、ID、5Gネットワークに関するデータが最もよく見られるSBIパラメータの一部です。SUPIは加入者を識別し、GPSIは外部加入者ID、PEIは永続的な端末識別子、DNNはデータネットワークを示します。NF Instance IDはNFインスタンスを一意に識別します。
これらの多くは単純な文字列に見えますが、重要なのは文字列内部の符号化ルールです。SUPIはIMSIまたはNAI形式を含むことがあり、GPSIはMSISDNまたはExternal Identifierを含むことがあります。つまり、文字列型として定義されているからといって、どんな文字列でも有効という意味ではありません。
5Gネットワーク関連型は、これらの基本識別子を基にセッション情報や位置情報を表現します。PduSessionIdはPDU Sessionを識別します。MCCとMNCはPLMN IDの一部を構成します。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トラフィックが運ぶのは加入者IDやネットワーク位置情報だけではありません。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間でやり取りするには、まず一貫したデータモデルが必要です。
実際のトラブルシューティングでデータ型をどう使うのか?
エンジニアリングでよくあるミスの1つは、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を提供することがあります。これらが含まれていれば、一般的なHTTP 4xxレスポンスだけで止まるのではなく、API要件に違反した具体的なパラメータから調査を開始できます。
パラメータ表の暗記よりデータモデル思考が有効なのはなぜか?
5GC SBIの共通データ型は非常に多く、すべてのフィールド、正規表現、値域を暗記する方法はすぐに非効率になります。より良い方法はデータモデルとして考えることです。単純型が最小のデータ単位を定義し、列挙型が許可される状態を制限し、構造化型がそれらを組み合わせて5GCサービスが直接利用できるオブジェクトを構成します。
この枠組みではSUPI、MCC、TAC、QFIは孤立したパラメータではなくなり、加入者、位置、セッション、QoS、課金、トレースモデルの構成要素になります。異なるNFがSBIを通じて一貫してサービスを呼び出せる理由の1つは、これらの共通型が安定して再利用可能なデータセマンティクスを提供するためです。
したがって未知の5GC APIを読むとき、最初に「このメッセージにフィールドはいくつあるか」と考えるよりも、各フィールドがどの型を参照しているか、オブジェクトがどのようにネストされているか、どの制約が最終的なJSONの有効性を決めるかを確認する方が有効です。この方法に慣れれば、初めて見るSBIサービスでも、新しいパラメータ表を丸暗記せず、OpenAPIとデータ型定義を階層ごとに追って解析できます。
よくある質問
SBI共通データ型を定義している3GPP仕様はどれか?
主にTS 29.571、5G System; Common Data Types for Service Based Interfacesで定義されています。この仕様はSBIサービス間で共有される再利用可能なデータ構造を定義します。NF固有のサービスやデータ型は、SMFサービスのTS 29.502、UDMサービスのTS 29.503など、対応する29.5xx仕様で定義されます。
OpenAPIのnullableプロパティは実際のJSONメッセージでどう表れるのか?
nullableとして定義されたフィールドは、一般にRmサフィックス付きの型を介して、現在有効な値が割り当てられていないことを示すため、JSON本文に明示的にnullを含めることができます。これはフィールド自体が完全に存在しない場合とは異なります。フィールドがない場合は、そのパラメータが適用外または未提供であることを意味する場合があります。一方、明示的なnullには、以前設定された値を消去するなど、特定の意味を持たせることができます。
SBI共通データ型はベンダーによって異なることがあるか?
定義自体は仕様レベルで標準化されていますが、実際の製品では実装差が生じることがあります。オプションフィールドの一部だけを実装するベンダーや、ベンダー独自拡張を含むAPIもあり、列挙値の検証の厳密さにも差が出る場合があります。これらは相互接続試験でよく確認されるポイントです。
共通型かNF固有型かをすばやく判別する方法は?
最も直接的な方法は、OpenAPI定義の$refパスを確認することです。参照先がTS 29.571で定義された共通schemaであれば、通常は共有SBIデータ型です。現在のサービス仕様内で定義されたschemaを指していれば、一般にNF固有型です。SUPI、TAI、S-NSSAI、ProblemDetailsなど、よく再利用される型を把握しておくと、パケット解析時にも識別しやすくなります。
パケットキャプチャ上でRm型と通常型はどう違うのか?
値がnullでない場合、両者は同じ基礎形式を使うためJSON表現は実質的に同じです。違いはOpenAPIモデル上にあります。Rm型はフィールドにnullを許可します。キャプチャされたフィールドが明示的にnullを持っていればnullable定義を使っていると判断できます。一方、通常の有効値が入っているだけでは、schemaが通常型を参照しているのか、対応するRm型を参照しているのかを値だけから判別することはできません。