Ao diagnosticar Interfaces Baseadas em Serviços em um núcleo 5G, muitos engenheiros encontram o mesmo problema. O corpo de uma requisição enviada de um AMF para um SMF pode conter campos conhecidos como SUPI, DNN, S-NSSAI, TAI, PDU Session ID e 5QI e, ainda assim, pode ser difícil determinar se a mensagem é realmente válida. Um campo deve ser codificado como string ou inteiro? Existe uma faixa de valores definida? Qualquer valor pode ser usado ou ele precisa vir de uma enumeração predefinida? Um objeto pode conter outros parâmetros aninhados?
As respostas são definidas pelos tipos de dados comuns da SBI. As Interfaces Baseadas em Serviços abrangem funções de rede como AMF, SMF, UDM, PCF e NRF, mas muitos dos parâmetros subjacentes não são específicos de uma única NF. Se cada serviço definisse esses valores de forma independente, as especificações teriam duplicações desnecessárias e o mesmo identificador de assinante ou parâmetro de QoS poderia ser representado de forma diferente entre APIs. Por isso, analisar o tráfego SBI exige mais do que verificar métodos HTTP e URIs de recursos. O HTTP/2 define como as requisições são transportadas, o JSON define como os dados são representados e os tipos de dados comuns respondem a uma questão mais fundamental: qual formato e quais regras de validação cada parâmetro JSON deve seguir.
Quais problemas os tipos de dados comuns resolvem?
Eles podem ser entendidos como um “vocabulário de dados” compartilhado por todo o ambiente de APIs baseadas em serviços do 5GC. Um tipo de dado pode aparecer em uma requisição do AMF e também ser referenciado pelo SMF, UDM ou PCF. Ele não pertence a uma única interface; fornece uma definição padronizada que pode ser reutilizada em vários serviços.
Considere um endereço IPv4. Cada NF não deveria definir sua própria maneira de representar esse endereço como string. O mesmo vale para informações de PLMN, em que MCC e MNC têm comprimentos e formatos específicos, e para identificadores de assinante e equipamento, como SUPI, GPSI e PEI, que seguem regras próprias de codificação. Definições consistentes permitem que APIs RESTful entre diferentes NFs troquem informações de forma confiável.
Os tipos de dados comuns também devem ser diferenciados dos tipos específicos de uma NF. Os tipos comuns abrangem objetos que aparecem repetidamente em várias interfaces, enquanto objetos de negócio exclusivos de determinada função de rede são definidos nas especificações correspondentes da série 29. Na prática, uma única API SBI costuma referenciar os dois tipos de dados.
O escopo vai muito além de endereços de rede. As definições comuns abrangem parâmetros genéricos, informações de assinatura e identidade, dados de rede 5G, QoS, cobrança, informações de rastreamento e outros objetos reutilizáveis. Em conjunto, formam um modelo de dados fundamental para os parâmetros das mensagens SBI.
Qual é a diferença entre as três estruturas básicas de dados?
Do ponto de vista estrutural, os parâmetros SBI podem ser agrupados, de modo geral, em três categorias: tipos de dados simples, enumerações e tipos de dados estruturados. Entender essas três categorias é mais útil do que memorizar nomes de parâmetros individuais, porque a maioria dos campos vistos em capturas do Wireshark, documentação de APIs e definições OpenAPI se encaixa nesse modelo.
Os tipos de dados simples são os blocos fundamentais de nível mais baixo. Eles incluem string, inteiro, número, data, data e hora e booleano. No 5GC, esses tipos básicos normalmente são combinados com restrições adicionais, como faixas de valores, formatos de codificação ou padrões de expressões regulares.
Um endereço IPv4, por exemplo, é tecnicamente representado como string, mas nem toda string arbitrária é válida. Ela precisa seguir o formato IPv4 exigido. Endereços IPv6, prefixos IPv6 e endereços MAC têm seus próprios requisitos de formato. Uint16, Uint32 e Uint64 definem faixas para inteiros sem sinal. Uma URI deve seguir as regras de formatação de URI, enquanto valores DateTime devem usar o formato de data e hora especificado.
As especificações também definem com frequência tipos com o sufixo Rm, como Ipv4AddrRm, DateTimeRm e Uint32Rm. Esses tipos usam o mesmo formato subjacente dos tipos-base correspondentes, mas incluem a propriedade nullable do OpenAPI, permitindo que o campo contenha um valor null.
Os tipos de enumeração funcionam como campos de múltipla escolha: o valor precisa ser selecionado de um conjunto predefinido. AccessType, por exemplo, diferencia 3GPP_ACCESS de NON_3GPP_ACCESS. PduSessionType pode assumir valores como IPV4, IPV6, IPV4V6, UNSTRUCTURED ou ETHERNET. CoreNetworkType pode indicar 5GC ou EPC.
O objetivo de uma enumeração é eliminar ambiguidades. Um consumidor não pode inventar outra string que por acaso tenha o mesmo significado; precisa usar um dos valores explicitamente definidos pela especificação. Esse é um cenário comum de diagnóstico: o nome do campo está correto, mas o valor da enumeração é inválido, então a API continua rejeitando ou interpretando incorretamente a requisição.
Os tipos de dados estruturados combinam vários atributos em um objeto completo. Esses atributos podem, por sua vez, referenciar tipos simples, enumerações ou outros objetos estruturados, criando um modelo hierárquico.
ProblemDetails é um exemplo típico. Ele pode incluir campos como type, title, status, detail, instance, cause e invalidParams. TAI é outro exemplo, combinando um PLMN ID com um TAC. GUAMI vai um nível além ao combinar um PLMN ID com um AMF ID. Nesse nível, a análise de SBI não pode mais se concentrar apenas em campos individuais; as relações entre os atributos dentro do objeto também importam.
Como os parâmetros de identidade e rede são construídos?
Em capturas de pacotes reais, dados de assinatura, identidade e rede 5G estão entre os parâmetros SBI mais frequentes. SUPI identifica um assinante, GPSI representa uma identidade externa de assinante, PEI representa um identificador permanente de equipamento, DNN identifica uma rede de dados e um NF Instance ID identifica de forma única uma instância de NF.
A maioria desses campos pode parecer simples strings, mas o ponto importante é a regra de codificação dentro da string. Um SUPI pode conter uma representação IMSI ou NAI, enquanto um GPSI pode conter um MSISDN ou External Identifier. Em outras palavras, ser definido como string não significa que qualquer string seja válida.
Tipos relacionados à rede 5G usam esses identificadores básicos para representar informações de sessão e localização. PduSessionId identifica uma PDU Session. MCC e MNC fazem parte de uma identidade PLMN. TAC identifica um Tracking Area Code, enquanto NrCellId e EutraCellId identificam, respectivamente, células NR e E-UTRA.
Objetos estruturados combinam esses parâmetros básicos em modelos de dados de nível superior. S-NSSAI usa um SST e um SD opcional para representar uma fatia de rede. TAI combina um PLMN ID e um TAC. NCGI combina um PLMN ID com um NR Cell ID para identificar uma célula NR, enquanto ECGI desempenha função semelhante para E-UTRA.
UserLocation é uma abstração de nível ainda mais alto. Dependendo do tipo de acesso, pode conter uma NR Location, E-UTRA Location ou Non-3GPP Access Location. Uma NR Location pode, por sua vez, conter TAI, NCGI, um carimbo de data e hora da localização e informações geográficas.
Isso demonstra o projeto modular dos modelos de dados SBI. Elementos básicos como MCC, MNC, TAC e Cell ID são padronizados primeiro e depois combinados em objetos de nível superior, como PLMN ID, TAI, NCGI e UserLocation. As APIs podem reutilizar esses objetos diretamente em vez de redefinir um conjunto completo de parâmetros de localização para cada serviço.
Por que dados de QoS, cobrança e rastreamento também precisam ser padronizados?
O tráfego SBI transporta muito mais do que identidades de assinantes e localização de rede. Políticas de QoS, informações de uso e dados de rastreamento da rede também circulam entre várias NFs, portanto esses valores também precisam de definições de dados consistentes.
Entre os parâmetros de QoS, QFI identifica um QoS Flow, 5QI representa o 5G QoS Identifier, BitRate representa uma taxa usando um valor e uma unidade, Packet Delay Budget expressa um orçamento de atraso, e Packet Error Rate e Packet Loss Rate descrevem a qualidade da transmissão.
As políticas de QoS também usam muitos tipos de enumeração. PreemptionCapability indica se um serviço pode preemptar recursos atribuídos a outros serviços. PreemptionVulnerability indica se recursos existentes podem ser retirados por um serviço de prioridade mais alta. QosResourceType diferencia valores como NON_GBR, NON_CRITICAL_GBR e CRITICAL_GBR.
Esses campos básicos são então combinados em objetos estruturados como ARP, AMBR, Dynamic 5QI e Non-Dynamic 5QI. Isso permite que SMF, PCF e outras funções de rede relacionadas usem a mesma representação ao trocar conceitos como prioridade, taxa de bits, atraso e comportamento de preempção.
Os dados de cobrança seguem o mesmo princípio de projeto. ChargingId, RatingGroup e ServiceId são tipos de dados simples relativamente diretos, enquanto QoSFlowUsageReport pode incluir QFI, carimbos de data e hora de início e fim da coleta e volumes de tráfego de uplink e downlink. VolumeTimedReport pode representar o uso de uma PDU Session durante um intervalo de tempo definido.
Os tipos relacionados ao rastreamento padronizam informações de rastreio da rede. TraceDepth usa valores enumerados para descrever diferentes níveis de rastreamento, enquanto TraceData combina parâmetros como Trace Reference, Trace Depth e NE Type. Isso evita que cada NF defina seu próprio conjunto incompatível de campos de rastreamento.
Esses exemplos mostram que os tipos de dados comuns fazem mais do que padronizar “alguns campos JSON”. Eles padronizam como diferentes serviços do núcleo da rede entendem os mesmos conceitos de negócio e de rede. Se QoS, localização, informações de cobrança ou identificadores de assinante precisam circular entre várias NFs, primeiro é necessário um modelo de dados consistente.
Como usar tipos de dados no diagnóstico prático?
Um dos erros de engenharia mais comuns é examinar uma mensagem JSON apenas para verificar se um campo está presente, sem conferir o tipo de dado e as restrições associadas. Um método de diagnóstico mais eficaz é analisar em conjunto a camada HTTP e o modelo de dados.
Comece identificando o serviço chamado e a URI do recurso. Em seguida, localize o campo desejado no corpo da requisição ou resposta. Depois de encontrar o campo, não pare no valor em si. Verifique qual tipo de dado ele referencia, se é obrigatório ou opcional, sua Cardinality, se é uma enumeração e se existem restrições de formato ou Pattern.
Um campo IPv4 pode parecer um endereço IP para um leitor humano, mas, se não atender ao formato definido, ainda será uma entrada inválida. Da mesma forma, um valor PduSessionType pode ser compreensível em linguagem comum, porém, se não estiver entre os valores de enumeração especificados, não estará de acordo com a definição da API.
Dados estruturados devem ser expandidos recursivamente. Quando UserLocation aparecer, determine se o objeto contém informações de localização NR, E-UTRA ou Non-3GPP. Quando TAI aparecer, examine o PLMN ID e o TAC. Quando S-NSSAI aparecer, verifique o SST e o SD opcional. Somente seguindo as referências de tipo camada por camada é possível determinar se o objeto JSON corresponde ao modelo da API.
Quando um servidor rejeita uma requisição, também vale examinar atentamente ProblemDetails. Além do código de status HTTP, ele pode fornecer informações em detail, cause e invalidParams. Quando esses campos estão presentes, o diagnóstico pode começar pelo parâmetro específico que violou os requisitos da API, em vez de parar em uma resposta HTTP 4xx genérica.
Por que pensar em modelo de dados é mais útil do que memorizar tabelas de parâmetros?
A quantidade de tipos de dados comuns da SBI do 5GC é grande o suficiente para que memorizar cada campo, expressão regular e faixa de valores se torne rapidamente ineficiente. Uma abordagem melhor é adotar uma mentalidade de modelo de dados: tipos simples definem as menores unidades de dados, enumerações restringem estados válidos e tipos estruturados combinam essas unidades em objetos que podem ser usados diretamente pelos serviços 5GC.
Nesse contexto, SUPI, MCC, TAC e QFI deixam de ser parâmetros isolados. Eles se tornam blocos de construção para modelos de assinante, localização, sessão, QoS, cobrança e rastreamento. Uma das razões pelas quais diferentes NFs conseguem invocar serviços de forma consistente por meio da SBI é que esses tipos comuns fornecem uma semântica de dados estável e reutilizável.
Ao ler uma API 5GC desconhecida, a primeira pergunta mais útil não é “quantos campos existem nesta mensagem?”. Em vez disso, determine a quais tipos esses campos fazem referência, como os objetos são aninhados e quais restrições definem se o JSON resultante é válido. Quando esse método se torna familiar, até um serviço SBI nunca visto pode ser analisado seguindo as definições OpenAPI e de tipos de dados camada por camada, sem precisar memorizar uma tabela totalmente nova de parâmetros.
Perguntas frequentes
Qual especificação 3GPP define os tipos de dados comuns da SBI?
Eles são definidos principalmente na TS 29.571, 5G System; Common Data Types for Service Based Interfaces. Essa especificação define estruturas de dados reutilizáveis compartilhadas entre serviços SBI. Serviços e tipos de dados específicos de uma NF são definidos nas especificações 29.5xx correspondentes, como TS 29.502 para serviços SMF e TS 29.503 para serviços UDM.
Como a propriedade nullable do OpenAPI aparece em uma mensagem JSON real?
Um campo definido como nullable, normalmente por meio de um tipo com sufixo Rm, pode conter explicitamente um valor null no corpo JSON para indicar que nenhum valor válido está atualmente atribuído. Isso é diferente de o campo estar totalmente ausente. Um campo ausente pode significar que o parâmetro não se aplica ou não foi fornecido, enquanto um null explícito pode ter um significado semântico específico, como limpar um valor configurado anteriormente.
Os tipos de dados comuns da SBI podem variar entre fornecedores?
As definições são padronizadas no nível da especificação, mas diferenças de implementação ainda podem aparecer em produtos reais. Alguns fornecedores podem implementar apenas um subconjunto dos campos opcionais, determinadas APIs podem incluir extensões específicas do fornecedor e o rigor da validação das enumerações pode variar. Essas diferenças são pontos comuns de investigação em testes de interoperabilidade.
Como identificar rapidamente se um campo usa um tipo comum ou um tipo específico de NF?
O método mais direto é inspecionar o caminho $ref na definição OpenAPI. Se a referência apontar para um schema comum definido pela TS 29.571, normalmente se trata de um tipo de dado SBI compartilhado. Se apontar para um schema definido dentro da especificação do serviço atual, em geral é específico da NF. Familiaridade com tipos frequentemente reutilizados, como SUPI, TAI, S-NSSAI e ProblemDetails, também facilita sua identificação durante a análise de pacotes.
Qual é a diferença entre um tipo Rm e um tipo normal em uma captura de pacotes?
Quando o valor não é null, a representação JSON é praticamente a mesma porque os dois tipos usam o mesmo formato subjacente. A diferença existe no nível do modelo OpenAPI: um tipo Rm permite que o campo contenha null. Se um campo capturado contiver explicitamente um valor null, ele deve estar usando uma definição nullable. Se contiver um valor normal e válido, o valor sozinho não é suficiente para determinar se o schema referencia o tipo regular ou o tipo Rm correspondente.