1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
/*
OxiRush
Copyright 2025-2026 Valentin D'Emmanuele
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
//! What the OxiRush crates share: the identities of 3GPP networks as values, and one
//! tree with paths for the messages of every family. `no_std`, without a dependency
//! unless a feature asks for one.
//!
//! ```rust
//! use oxirush_utils::identity::{Guti5g, Plmn};
//!
//! fn main() -> Result<(), Box<dyn std::error::Error>> {
//! let plmn: Plmn = "310-410".parse()?;
//! let guti = Guti5g::new(plmn, 0xca, 0x3fe, 0x01, 0xdead_beef)?;
//!
//! // The three octets of a PLMN in a NAS message, and in an NGAP or S1AP message
//! println!("{plmn}: {:02x?} in NAS, {:02x?} in NGAP", plmn.to_nas_octets(), plmn.to_ap_octets());
//!
//! // A 5G-GUTI as text, and as a 5GS mobile identity
//! println!("{guti}: {:02x?}", guti.to_nas_octets());
//! Ok(())
//! }
//! ```
//!
//! ```text
//! 310-410: [13, 00, 14] in NAS, [13, 40, 01] in NGAP
//! 5g-guti-310410caff81deadbeef: [f2, 13, 00, 14, ca, ff, 81, de, ad, be, ef]
//! ```
//!
//! # Tasks
//!
//! The [README](https://github.com/linouxis9/oxirush-utils#readme) has an example of
//! each, with what it prints, except the rules of a family of messages: the
//! documentation of [`tree::Family`] has theirs.
//!
//! | Task | Items |
//! |------|-------|
//! | An identity through its forms | [`Imsi`](identity::Imsi), [`Plmn`](identity::Plmn), [`ImsiSuci`](identity::ImsiSuci), [`Supi`](identity::Supi), [`Guti5g`](identity::Guti5g), [`STmsi5g`](identity::STmsi5g) |
//! | IMEI, IMEISV, and the identities of EPS | [`Imei`](identity::Imei), [`Imeisv`](identity::Imeisv), [`GutiEps`](identity::GutiEps), [`Tai5gs`](identity::Tai5gs), [`TaiEps`](identity::TaiEps) |
//! | The SUCI in the form of a NAI | [`NaiSuci`](identity::NaiSuci), [`nai::check_realm`](identity::nai::check_realm) |
//! | What other implementations send | [`Imeisv::from_nas_octets_tolerant`](identity::Imeisv::from_nas_octets_tolerant), [`Fault`](identity::Fault) |
//! | A type as a tree | [`tree::Tree`], [`tree!`], [`tree::to_value`], [`tree::from_value`] |
//! | Paths | [`tree::select`], [`tree::paths`], [`tree::set`], [`tree::insert`], [`tree::remove`] |
//! | The rules of a family of messages | [`tree::Family`], [`tree::select_in`], [`tree::written_as`] |
//! | Any format of serde | [`impl_serde!`] |
//!
// Without its feature an item of the tasks is plain text: the links are checked in the
// build of every feature, which docs.rs makes.
//! # Modules
//!
//! | Module | Has | Feature |
//! |--------|-----|---------|
//! | [`identity`] | The PLMN with its two codings, TBCD digits, IMSI, IMEI, IMEISV, the SUPI with its type, the SUCI of an IMSI and the SUCI in the form of a NAI with the grammar of a NAI, the GUTI and the S-TMSI of 5GS and of EPS, the tracking area identities, the types of identity | none |
// A module that a feature turns on is a link when the build has it.
//!
//! The crate is `no_std` with `alloc`, has no dependency without a feature, and no
//! `unsafe`. With the feature `idna`, the realm and the username of a NAI are also
//! checked as internationalized names (see [`identity::nai::check_realm`]).
//!
//! A tree keeps the order of the specification by itself: the crate turns on no
//! feature of `serde_json` that orders a map, and the JSON of a program that depends on
//! it keeps the order that the program chose.
//!
//! # The OxiRush family
//!
//! - [oxirush-utils](https://docs.rs/oxirush-utils): the 3GPP identities, and the JSON tree with its paths that the others share.
//! - [oxirush-aper](https://docs.rs/oxirush-aper): aligned PER, the runtime of the NGAP and S1AP codecs.
//! - [oxirush-nas](https://docs.rs/oxirush-nas): the NAS messages of 5GS and EPS.
//! - [oxirush-security](https://docs.rs/oxirush-security): NAS security, AKA and the derivation of keys.
//! - [oxirush-ngap](https://docs.rs/oxirush-ngap): NGAP, between a gNB and an AMF.
//! - [oxirush-s1ap](https://docs.rs/oxirush-s1ap): S1AP, between an eNB and an MME.
//! - [oxirush-gtp-u](https://docs.rs/oxirush-gtp-u): GTP-U tunnels, with a test UPF.
//! - [oxirush-sctp](https://docs.rs/oxirush-sctp): SCTP sockets, which carry NGAP and S1AP.
extern crate alloc;
/// The blocks of the README, which are compiled and run with the documentation tests.
;