Lors du dépannage des interfaces basées sur les services dans un cœur 5G, de nombreux ingénieurs rencontrent le même problème. Le corps d'une requête envoyée d'un AMF vers un SMF peut contenir des champs familiers tels que SUPI, DNN, S-NSSAI, TAI, PDU Session ID et 5QI, sans qu'il soit pour autant facile de déterminer si le message est réellement valide. Un champ doit-il être codé sous forme de chaîne ou d'entier ? Possède-t-il une plage de valeurs définie ? Toute valeur peut-elle être utilisée ou doit-elle provenir d'une énumération prédéfinie ? Un objet peut-il contenir d'autres paramètres imbriqués ?
Les réponses sont définies par les types de données communs des SBI. Les interfaces basées sur les services couvrent des fonctions réseau telles que l'AMF, le SMF, l'UDM, le PCF et le NRF, mais de nombreux paramètres sous-jacents ne sont propres à aucune NF en particulier. Si chaque service définissait ces valeurs indépendamment, les spécifications comporteraient des duplications inutiles et un même identifiant d'abonné ou paramètre de QoS pourrait être représenté différemment selon les API. C'est pourquoi l'analyse du trafic SBI ne se limite pas à vérifier les méthodes HTTP et les URI de ressources. HTTP/2 définit la manière dont les requêtes sont transportées, JSON définit la représentation des données, et les types de données communs répondent à une question plus fondamentale : quel format et quelles règles de validation chaque paramètre JSON doit respecter.
Quels problèmes les types de données communs résolvent-ils ?
On peut les considérer comme un « vocabulaire de données » partagé par l'ensemble de l'environnement d'API basées sur les services du 5GC. Un type de données peut apparaître dans une requête AMF et être également référencé par le SMF, l'UDM ou le PCF. Il n'appartient pas à une interface unique ; il fournit une définition normalisée réutilisable dans plusieurs services.
Prenons une adresse IPv4. Chaque NF ne devrait pas définir sa propre manière de représenter l'adresse sous forme de chaîne. Il en va de même pour les informations PLMN, pour lesquelles MCC et MNC ont des longueurs et des formats précis, ainsi que pour les identifiants d'abonné et d'équipement tels que SUPI, GPSI et PEI, qui suivent leurs propres règles de codage. Des définitions cohérentes permettent aux API RESTful entre différentes NF d'échanger des informations de manière fiable.
Les types de données communs doivent également être distingués des types propres à une NF. Les types communs couvrent les objets qui apparaissent de manière répétée sur plusieurs interfaces, tandis que les objets métier spécifiques à une fonction réseau donnée sont définis dans les spécifications correspondantes de la série 29. En pratique, une même API SBI référence souvent les deux catégories de types de données.
Leur portée va bien au-delà des adresses réseau. Les définitions communes couvrent les paramètres génériques, les informations d'abonnement et d'identité, les données réseau 5G, la QoS, la taxation, les informations de trace et d'autres objets réutilisables. Ensemble, elles constituent un modèle de données fondamental pour les paramètres des messages SBI.
Quelles sont les différences entre les trois structures de données de base ?
D'un point de vue structurel, les paramètres SBI peuvent généralement être regroupés en trois catégories : types de données simples, énumérations et types de données structurés. Comprendre ces trois catégories est plus utile que mémoriser des noms de paramètres isolés, car la plupart des champs observés dans les captures Wireshark, la documentation d'API et les définitions OpenAPI s'inscrivent dans ce modèle.
Les types de données simples sont les briques élémentaires de plus bas niveau. Ils comprennent les chaînes, les entiers, les nombres, les dates, les dates-heures et les booléens. Dans le 5GC, ces types de base sont généralement associés à des contraintes supplémentaires telles que des plages de valeurs, des formats de codage ou des motifs d'expressions régulières.
Une adresse IPv4, par exemple, est techniquement représentée par une chaîne, mais n'importe quelle chaîne arbitraire n'est pas valide. Elle doit respecter le format IPv4 requis. Les adresses IPv6, les préfixes IPv6 et les adresses MAC ont chacun leurs propres exigences de format. Uint16, Uint32 et Uint64 définissent des plages pour les entiers non signés. Un URI doit respecter les règles de format des URI, tandis que les valeurs DateTime doivent utiliser le format date-heure spécifié.
Les spécifications définissent aussi fréquemment des types portant le suffixe Rm, tels que Ipv4AddrRm, DateTimeRm et Uint32Rm. Ces types utilisent le même format sous-jacent que leurs types de base correspondants, mais intègrent la propriété nullable d'OpenAPI, qui permet au champ de contenir une valeur null.
Les types énumérés fonctionnent comme des champs à choix : la valeur doit être sélectionnée dans un ensemble prédéfini. AccessType, par exemple, distingue 3GPP_ACCESS de NON_3GPP_ACCESS. PduSessionType peut prendre des valeurs telles que IPV4, IPV6, IPV4V6, UNSTRUCTURED ou ETHERNET. CoreNetworkType peut indiquer 5GC ou EPC.
L'objectif d'une énumération est de supprimer toute ambiguïté. Un consommateur ne peut pas inventer une autre chaîne qui signifierait approximativement la même chose ; il doit utiliser l'une des valeurs explicitement définies par la spécification. C'est un cas de dépannage fréquent : le nom du champ est correct, mais la valeur d'énumération est invalide, de sorte que l'API rejette encore la requête ou l'interprète de façon erronée.
Les types de données structurés combinent plusieurs attributs pour former un objet complet. Ces attributs peuvent eux-mêmes faire référence à des types simples, des énumérations ou d'autres objets structurés, ce qui crée un modèle hiérarchique.
ProblemDetails en est un exemple typique. Il peut inclure des champs tels que type, title, status, detail, instance, cause et invalidParams. TAI est un autre exemple, puisqu'il combine un PLMN ID et un TAC. GUAMI va un niveau plus loin en combinant un PLMN ID avec un AMF ID. À ce niveau, l'analyse SBI ne peut plus se concentrer sur les champs individuellement ; les relations entre les attributs de l'objet comptent également.
Comment les paramètres d'identité et de réseau sont-ils construits ?
Dans les captures de paquets réelles, les données liées à l'abonnement, à l'identité et au réseau 5G figurent parmi les paramètres SBI les plus courants. SUPI identifie un abonné, GPSI représente une identité externe d'abonné, PEI représente un identifiant permanent d'équipement, DNN identifie un réseau de données et un NF Instance ID identifie de façon unique une instance NF.
La plupart de ces champs peuvent sembler être de simples chaînes, mais l'élément important est la règle de codage à l'intérieur de la chaîne. Un SUPI peut contenir une représentation IMSI ou NAI, tandis qu'un GPSI peut contenir un MSISDN ou un External Identifier. Autrement dit, être défini comme une chaîne ne signifie pas que n'importe quelle chaîne est valide.
Les types liés au réseau 5G s'appuient sur ces identifiants de base pour représenter les informations de session et de localisation. PduSessionId identifie une PDU Session. MCC et MNC constituent une partie de l'identité PLMN. TAC identifie un Tracking Area Code, tandis que NrCellId et EutraCellId identifient respectivement des cellules NR et E-UTRA.
Des objets structurés combinent ensuite ces paramètres de base en modèles de données de niveau supérieur. S-NSSAI utilise un SST et un SD facultatif pour représenter une tranche de réseau. TAI combine un PLMN ID et un TAC. NCGI combine un PLMN ID avec un NR Cell ID pour identifier une cellule NR, tandis qu'ECGI remplit un rôle similaire pour E-UTRA.
UserLocation constitue une abstraction encore plus élevée. Selon le type d'accès, il peut contenir une NR Location, une E-UTRA Location ou une Non-3GPP Access Location. Une NR Location peut elle-même contenir TAI, NCGI, un horodatage de localisation et des informations géographiques.
Cela illustre la conception modulaire des modèles de données SBI. Des éléments de base tels que MCC, MNC, TAC et Cell ID sont normalisés en premier, puis combinés en objets de niveau supérieur tels que PLMN ID, TAI, NCGI et UserLocation. Les API peuvent réutiliser directement ces objets au lieu de redéfinir un ensemble complet de paramètres de localisation pour chaque service.
Pourquoi les données de QoS, de taxation et de trace doivent-elles aussi être normalisées ?
Le trafic SBI transporte bien plus que les identités d'abonné et la localisation réseau. Les politiques de QoS, les informations d'utilisation et les données de trace réseau circulent également entre plusieurs NF ; ces valeurs nécessitent donc elles aussi des définitions de données cohérentes.
Parmi les paramètres de QoS, QFI identifie un QoS Flow, 5QI représente le 5G QoS Identifier, BitRate représente un débit au moyen d'une valeur et d'une unité, Packet Delay Budget exprime un budget de délai, et Packet Error Rate ainsi que Packet Loss Rate décrivent la qualité de transmission.
Les politiques de QoS utilisent également de nombreux types énumérés. PreemptionCapability indique si un service peut préempter des ressources attribuées ailleurs. PreemptionVulnerability indique si des ressources existantes peuvent être retirées par un service de priorité supérieure. QosResourceType distingue des valeurs telles que NON_GBR, NON_CRITICAL_GBR et CRITICAL_GBR.
Ces champs de base sont ensuite combinés dans des objets structurés tels qu'ARP, AMBR, Dynamic 5QI et Non-Dynamic 5QI. Cela permet au SMF, au PCF et aux autres fonctions réseau concernées d'utiliser la même représentation lorsqu'ils échangent des notions telles que la priorité, le débit, le délai et le comportement de préemption.
Les données de taxation suivent le même principe de conception. ChargingId, RatingGroup et ServiceId sont des types de données simples relativement directs, tandis que QoSFlowUsageReport peut inclure QFI, les horodatages de début et de fin de collecte ainsi que les volumes de trafic montant et descendant. VolumeTimedReport peut représenter l'utilisation d'une PDU Session sur un intervalle de temps défini.
Les types liés à la trace normalisent les informations de suivi réseau. TraceDepth utilise des valeurs énumérées pour décrire différents niveaux de trace, tandis que TraceData combine des paramètres tels que Trace Reference, Trace Depth et NE Type. Cela évite que chaque NF définisse son propre ensemble incompatible de champs de trace.
Ces exemples montrent que les types de données communs font bien plus que normaliser « quelques champs JSON ». Ils normalisent la manière dont différents services du cœur de réseau comprennent les mêmes concepts métier et réseau. Si la QoS, la localisation, les informations de taxation ou les identifiants d'abonné doivent circuler entre plusieurs NF, ils ont d'abord besoin d'un modèle de données cohérent.
Comment utiliser les types de données pour le dépannage pratique ?
L'une des erreurs d'ingénierie les plus fréquentes consiste à examiner un message JSON uniquement pour vérifier la présence d'un champ, sans contrôler son type de données et les contraintes associées. Une méthode de dépannage plus efficace consiste à examiner ensemble la couche HTTP et le modèle de données.
Commencez par identifier le service appelé et l'URI de ressource. Localisez ensuite le champ cible dans le corps de la requête ou de la réponse. Une fois le champ trouvé, ne vous arrêtez pas à sa valeur. Vérifiez le type de données auquel il fait référence, s'il est obligatoire ou facultatif, sa Cardinality, s'il s'agit d'une énumération et s'il comporte des restrictions de format ou de Pattern.
Un champ IPv4 peut ressembler à une adresse IP pour un lecteur humain, mais s'il ne respecte pas le format défini, il reste une entrée invalide. De même, une valeur PduSessionType peut être compréhensible en langage courant, mais si elle ne fait pas partie des valeurs d'énumération spécifiées, elle n'est pas conforme à la définition de l'API.
Les données structurées doivent être développées récursivement. Lorsque UserLocation apparaît, déterminez si l'objet contient des informations de localisation NR, E-UTRA ou Non-3GPP. Lorsque TAI apparaît, inspectez le PLMN ID et le TAC. Lorsque S-NSSAI apparaît, vérifiez le SST et le SD facultatif. Ce n'est qu'en suivant les références de type couche par couche qu'un ingénieur peut déterminer si l'objet JSON correspond au modèle de l'API.
Lorsqu'un serveur rejette une requête, ProblemDetails mérite également une attention particulière. En plus du code de statut HTTP, il peut fournir des informations detail, cause et invalidParams. Lorsque ces champs sont présents, le dépannage peut commencer par le paramètre précis qui a enfreint les exigences de l'API, au lieu de s'arrêter à une réponse HTTP 4xx générique.
Pourquoi une approche par modèle de données est-elle plus utile que la mémorisation de tableaux de paramètres ?
Le nombre de types de données communs des SBI du 5GC est suffisamment élevé pour que mémoriser chaque champ, expression régulière et plage de valeurs devienne rapidement inefficace. Une meilleure approche consiste à adopter une logique de modèle de données : les types simples définissent les plus petites unités de données, les énumérations limitent les états valides et les types structurés combinent ces unités en objets directement utilisables par les services 5GC.
Dans ce cadre, SUPI, MCC, TAC et QFI ne sont plus des paramètres isolés. Ils deviennent les briques des modèles d'abonné, de localisation, de session, de QoS, de taxation et de trace. Si différentes NF peuvent invoquer des services de manière cohérente via SBI, c'est notamment parce que ces types communs fournissent une sémantique de données stable et réutilisable.
Lors de la lecture d'une API 5GC inconnue, la première question la plus utile n'est donc pas « Combien de champs contient ce message ? ». Il faut plutôt déterminer à quels types ces champs font référence, comment les objets sont imbriqués et quelles contraintes déterminent si le JSON obtenu est valide. Une fois cette méthode maîtrisée, même un service SBI jamais rencontré auparavant peut être analysé en suivant, couche par couche, les définitions OpenAPI et les types de données, plutôt qu'en mémorisant un tout nouveau tableau de paramètres.
FAQ
Quelle spécification 3GPP définit les types de données communs des SBI ?
Ils sont principalement définis dans la TS 29.571, 5G System; Common Data Types for Service Based Interfaces. Cette spécification définit des structures de données réutilisables partagées entre les services SBI. Les services et types de données propres à une NF sont définis dans les spécifications 29.5xx correspondantes, par exemple TS 29.502 pour les services SMF et TS 29.503 pour les services UDM.
Comment la propriété nullable d'OpenAPI apparaît-elle dans un message JSON réel ?
Un champ défini comme nullable, généralement au moyen d'un type portant le suffixe Rm, peut explicitement contenir une valeur null dans le corps JSON pour indiquer qu'aucune valeur valide n'est actuellement attribuée. Cela diffère d'un champ totalement absent. L'absence d'un champ peut signifier que le paramètre n'est pas applicable ou qu'il n'a pas été fourni, tandis qu'un null explicite peut avoir une signification sémantique précise, par exemple effacer une valeur précédemment configurée.
Les types de données communs des SBI peuvent-ils différer selon les fournisseurs ?
Les définitions sont normalisées au niveau des spécifications, mais des différences d'implémentation peuvent encore apparaître dans les produits réels. Certains fournisseurs peuvent ne mettre en œuvre qu'un sous-ensemble de champs facultatifs, certaines API peuvent inclure des extensions propres au fournisseur et la rigueur de validation des énumérations peut varier. Ces différences sont des points de vérification courants lors des tests d'interopérabilité.
Comment savoir rapidement si un champ utilise un type commun ou un type propre à une NF ?
La méthode la plus directe consiste à examiner le chemin $ref dans la définition OpenAPI. Si la référence pointe vers un schéma commun défini pour TS 29.571, il s'agit normalement d'un type de données SBI partagé. Si elle pointe vers un schéma défini dans la spécification du service courant, il s'agit généralement d'un type propre à la NF. La connaissance des types fréquemment réutilisés, comme SUPI, TAI, S-NSSAI et ProblemDetails, permet aussi de les reconnaître plus facilement pendant l'analyse de paquets.
Quelle est la différence entre un type Rm et un type normal dans une capture de paquets ?
Lorsque la valeur n'est pas null, la représentation JSON est pratiquement identique, car les deux types utilisent le même format sous-jacent. La différence se situe au niveau du modèle OpenAPI : un type Rm autorise le champ à contenir null. Si un champ capturé contient explicitement une valeur null, il doit utiliser une définition nullable. S'il contient une valeur normale valide, cette valeur seule ne suffit pas à déterminer si le schéma référence le type standard ou le type Rm correspondant.