diameter/
dictionary.rs

1use crate::ApplicationId;
2use crate::CommandCode;
3use lazy_static::lazy_static;
4use serde::Deserialize;
5use serde_xml_rs::from_str;
6use std::collections::BTreeMap;
7use std::collections::HashMap;
8use std::sync::RwLock;
9
10use crate::avp::AvpType;
11
12#[derive(Debug, Clone)]
13pub struct Dictionary {
14    avps: BTreeMap<AvpKey, AvpDefinition>,
15    applications: HashMap<String, ApplicationId>,
16    commands: HashMap<String, CommandCode>,
17}
18
19#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
20pub enum AvpKey {
21    Code(u32),
22    CodeAndVendor(u32, u32),
23}
24
25#[derive(Debug, Clone)]
26pub struct AvpDefinition {
27    pub code: u32,
28    pub vendor_id: Option<u32>,
29    pub name: String,
30    pub avp_type: AvpType,
31    pub m_flag: bool,
32}
33
34impl Dictionary {
35    pub fn new(xmls: &[&str]) -> Self {
36        let mut dict = Dictionary {
37            avps: BTreeMap::new(),
38            applications: HashMap::new(),
39            commands: HashMap::new(),
40        };
41
42        for xml in xmls {
43            dict.load_xml(xml)
44        }
45
46        dict
47    }
48
49    pub fn load_xml(&mut self, xml: &str) {
50        parse(xml, self);
51    }
52
53    pub fn add_avp(&mut self, avp: AvpDefinition) {
54        let code: u32 = avp.code;
55        match avp.vendor_id {
56            Some(vendor_id) => {
57                self.avps
58                    .insert(AvpKey::CodeAndVendor(code, vendor_id), avp);
59            }
60            None => {
61                self.avps.insert(AvpKey::Code(code), avp);
62            }
63        }
64    }
65
66    pub fn get_avp(&self, code: u32, vendor_id: Option<u32>) -> Option<&AvpDefinition> {
67        let key = match vendor_id {
68            Some(vendor_id) => AvpKey::CodeAndVendor(code, vendor_id),
69            None => AvpKey::Code(code),
70        };
71        self.avps.get(&key)
72    }
73
74    pub fn get_avp_by_name(&self, name: &str) -> Option<&AvpDefinition> {
75        // Might consider indexing avp.name
76        self.avps.values().find(|avp| avp.name == name)
77    }
78
79    pub fn get_avp_type(&self, code: u32, vendor_id: Option<u32>) -> Option<&AvpType> {
80        let key = match vendor_id {
81            Some(vendor_id) => AvpKey::CodeAndVendor(code, vendor_id),
82            None => AvpKey::Code(code),
83        };
84        match self.avps.get(&key) {
85            Some(avp) => Some(&avp.avp_type),
86            None => None,
87        }
88    }
89
90    pub fn get_avp_name(&self, code: u32, vendor_id: Option<u32>) -> Option<&str> {
91        let key = match vendor_id {
92            Some(vendor_id) => AvpKey::CodeAndVendor(code, vendor_id),
93            None => AvpKey::Code(code),
94        };
95        match self.avps.get(&key) {
96            Some(avp) => Some(&avp.name),
97            None => None,
98        }
99    }
100
101    pub fn get_application_id_by_name(&self, name: &str) -> Option<ApplicationId> {
102        self.applications.get(name).map(|app| *app)
103    }
104
105    pub fn get_command_code_by_name(&self, name: &str) -> Option<CommandCode> {
106        self.commands.get(name).map(|code| *code)
107    }
108}
109
110#[derive(Debug, Deserialize, PartialEq)]
111struct Diameter {
112    #[serde(rename = "application")]
113    applications: Vec<Application>,
114}
115
116#[derive(Debug, Deserialize, PartialEq)]
117struct Application {
118    id: String,
119    name: String,
120    #[serde(rename = "command", default)]
121    commands: Vec<Command>,
122    #[serde(rename = "avp", default)]
123    avps: Vec<Avp>,
124}
125
126#[derive(Debug, Deserialize, PartialEq)]
127struct Command {
128    code: String,
129    short: String,
130    name: String,
131    request: CommandDetail,
132    answer: CommandDetail,
133}
134
135#[derive(Debug, Deserialize, PartialEq)]
136struct CommandDetail {
137    #[serde(rename = "rule", default)]
138    rules: Vec<Rule>,
139}
140
141#[derive(Debug, Deserialize, PartialEq)]
142struct Rule {
143    avp: String,
144    required: String,
145    max: Option<String>,
146    min: Option<String>,
147}
148
149#[derive(Debug, Deserialize, PartialEq)]
150struct Avp {
151    name: String,
152    code: String,
153    must: Option<String>,
154    may: Option<String>,
155    #[serde(rename = "must-not")]
156    must_not: Option<String>,
157    #[serde(rename = "may-encrypt")]
158    may_encrypt: Option<String>,
159    #[serde(rename = "vendor-id")]
160    vendor_id: Option<String>,
161    data: Data,
162}
163
164#[derive(Debug, Deserialize, PartialEq)]
165struct Data {
166    #[serde(rename = "type")]
167    data_type: String,
168    #[serde(default)]
169    item: Vec<Item>,
170}
171
172#[derive(Debug, Deserialize, PartialEq)]
173struct Item {
174    code: String,
175    name: String,
176}
177
178pub fn parse(xml: &str, dictionary: &mut Dictionary) {
179    let dict: Diameter = from_str(xml).unwrap();
180
181    // TODO Dictionary need to include avp that matches its application and command code
182
183    dict.applications.iter().for_each(|app| {
184        let app_id = app.id.parse::<u32>().unwrap();
185        let app_id: ApplicationId = ApplicationId::from_u32(app_id).unwrap();
186        dictionary.applications.insert(app.name.clone(), app_id);
187
188        app.commands.iter().for_each(|cmd| {
189            let cmd_code = cmd.code.parse::<u32>().unwrap();
190            let cmd_code: CommandCode = CommandCode::from_u32(cmd_code).unwrap();
191            dictionary.commands.insert(cmd.name.clone(), cmd_code);
192        });
193
194        app.avps.iter().for_each(|avp| {
195            let avp_type = match avp.data.data_type.as_str() {
196                "UTF8String" => AvpType::UTF8String,
197                "OctetString" => AvpType::OctetString,
198                "Integer32" => AvpType::Integer32,
199                "Integer64" => AvpType::Integer64,
200                "Unsigned32" => AvpType::Unsigned32,
201                "Unsigned64" => AvpType::Unsigned64,
202                "Enumerated" => AvpType::Enumerated,
203                "Grouped" => AvpType::Grouped,
204                "DiameterIdentity" => AvpType::Identity,
205                "DiameterURI" => AvpType::DiameterURI,
206                "Time" => AvpType::Time,
207                "Address" => AvpType::Address,
208                "IPv4" => AvpType::AddressIPv4,
209                "IPv6" => AvpType::AddressIPv6,
210                "Float32" => AvpType::Float32,
211                "Float64" => AvpType::Float64,
212                _ => AvpType::Unknown,
213            };
214
215            let flags: Vec<&str> = match avp.must {
216                Some(ref s) => s.split(',').collect(),
217                None => vec![],
218            };
219            let m_flag = if flags.contains(&"M") { true } else { false };
220
221            let vendor_id = match avp.vendor_id {
222                Some(ref s) => Some(s.parse::<u32>().unwrap()),
223                None => None,
224            };
225
226            let avp_definition = AvpDefinition {
227                code: avp.code.parse::<u32>().unwrap(),
228                vendor_id,
229                name: avp.name.clone(),
230                avp_type,
231                m_flag,
232            };
233
234            dictionary.add_avp(avp_definition);
235        });
236    });
237}
238
239lazy_static! {
240    pub static ref DEFAULT_DICT: RwLock<Dictionary> = {
241        let xml = &DEFAULT_DICT_XML;
242        let dictionary = Dictionary::new(&[&xml]);
243        RwLock::new(dictionary)
244    };
245    pub static ref DEFAULT_DICT_XML: &'static str = {
246        let xml = r#"
247<diameter>
248	<application id="4" type="auth" name="Charging Control">
249		<!-- Diameter Credit Control Application -->
250		<!-- http://tools.ietf.org/html/rfc4006 -->
251
252		<command code="272" short="CC" name="Credit-Control">
253			<request>
254				<!-- http://tools.ietf.org/html/rfc4006#section-3.1 -->
255				<rule avp="Session-Id" required="true" max="1"/>
256				<rule avp="Origin-Host" required="true" max="1"/>
257				<rule avp="Origin-Realm" required="true" max="1"/>
258				<rule avp="Destination-Realm" required="true" max="1"/>
259				<rule avp="Auth-Application-Id" required="true" max="1"/>
260				<rule avp="Service-Context-Id" required="true" max="1"/>
261				<rule avp="CC-Request-Type" required="true" max="1"/>
262				<rule avp="CC-Request-Number" required="true" max="1"/>
263				<rule avp="Destination-Host" required="false" max="1"/>
264				<rule avp="User-Name" required="false" max="1"/>
265				<rule avp="CC-Sub-Session-Id" required="false" max="1"/>
266				<rule avp="Acct-Multi-Session-Id" required="false" max="1"/>
267				<rule avp="Origin-State-Id" required="false" max="1"/>
268				<rule avp="Event-Timestamp" required="false" max="1"/>
269				<rule avp="Subscription-Id" required="false" max="1"/>
270				<rule avp="Service-Identifier" required="false" max="1"/>
271				<rule avp="Termination-Cause" required="false" max="1"/>
272				<rule avp="Requested-Service-Unit" required="false" max="1"/>
273				<rule avp="Requested-Action" required="false" max="1"/>
274				<rule avp="Used-Service-Unit" required="false" max="1"/>
275				<rule avp="Multiple-Services-Indicator" required="false" max="1"/>
276				<rule avp="Multiple-Services-Credit-Control" required="false" max="1"/>
277				<rule avp="Service-Parameter-Info" required="false" max="1"/>
278				<rule avp="CC-Correlation-Id" required="false" max="1"/>
279				<rule avp="User-Equipment-Info" required="false" max="1"/>
280				<rule avp="Proxy-Info" required="false" max="1"/>
281				<rule avp="Route-Record" required="false" max="1"/>
282				<rule avp="Service-Information" required="false" max="1"/>
283			</request>
284			<answer>
285				<!-- http://tools.ietf.org/html/rfc4006#section-3.2 -->
286				<rule avp="Session-Id" required="true" max="1"/>
287				<rule avp="Result-Code" required="true" max="1"/>
288				<rule avp="Origin-Host" required="true" max="1"/>
289				<rule avp="Origin-Realm" required="true" max="1"/>
290				<rule avp="CC-Request-Type" required="true" max="1"/>
291				<rule avp="CC-Request-Number" required="true" max="1"/>
292				<rule avp="User-Name" required="false" max="1"/>
293				<rule avp="CC-Session-Failover" required="false" max="1"/>
294				<rule avp="CC-Sub-Session-Id" required="false" max="1"/>
295				<rule avp="Acct-Multi-Session-Id" required="false" max="1"/>
296				<rule avp="Origin-State-Id" required="false" max="1"/>
297				<rule avp="Event-Timestamp" required="false" max="1"/>
298				<rule avp="Granted-Service-Unit" required="false" max="1"/>
299				<rule avp="Multiple-Services-Credit-Control" required="false" max="1"/>
300				<rule avp="Cost-Information" required="false" max="1"/>
301				<rule avp="Final-Unit-Indication" required="false" max="1"/>
302				<rule avp="Check-Balance-Result" required="false" max="1"/>
303				<rule avp="Credit-Control-Failure-Handling" required="false" max="1"/>
304				<rule avp="Direct-Debiting-Failure-Handling" required="false" max="1"/>
305				<rule avp="Validity-Time" required="false" max="1"/>
306				<rule avp="Redirect-Host" required="false" max="1"/>
307				<rule avp="Redirect-Host-Usage" required="false" max="1"/>
308				<rule avp="Redirect-Max-Cache-Time" required="false" max="1"/>
309				<rule avp="Proxy-Info" required="false" max="1"/>
310				<rule avp="Route-Record" required="false" max="1"/>
311				<rule avp="Failed-AVP" required="false" max="1"/>
312			</answer>
313		</command>
314    </application>
315
316    <application id="0" name="Base">
317		<command code="257" short="CE" name="Capabilities-Exchange">
318			<request>
319				<rule avp="Origin-Host" required="true" max="1"/>
320				<rule avp="Origin-Realm" required="true" max="1"/>
321				<rule avp="Host-IP-Address" required="true" min="1"/>
322				<rule avp="Vendor-Id" required="true" max="1"/>
323				<rule avp="Product-Name" required="true" max="1"/>
324				<rule avp="Origin-State-Id" required="false" max="1"/>
325				<rule avp="Supported-Vendor-Id" required="False"/>
326				<rule avp="Auth-Application-Id" required="False"/>
327				<rule avp="Inband-Security-Id" required="False"/>
328				<rule avp="Acct-Application-Id" required="False"/>
329				<rule avp="Vendor-Specific-Application-Id" required="False"/>
330				<rule avp="Firmware-Revision" required="False" max="1"/>
331			</request>
332			<answer>
333				<rule avp="Result-Code" required="true" max="1"/>
334				<rule avp="Origin-Host" required="true" max="1"/>
335				<rule avp="Origin-Realm" required="true" max="1"/>
336				<rule avp="Host-IP-Address" required="true" min="1"/>
337				<rule avp="Vendor-Id" required="true" max="1"/>
338				<rule avp="Product-Name" required="true" max="1"/>
339				<rule avp="Origin-State-Id" required="false" max="1"/>
340				<rule avp="Error-Message" required="false" max="1"/>
341				<rule avp="Failed-AVP" required="false" max="1"/>
342				<rule avp="Supported-Vendor-Id" required="False"/>
343				<rule avp="Auth-Application-Id" required="False"/>
344				<rule avp="Inband-Security-Id" required="False"/>
345				<rule avp="Acct-Application-Id" required="False"/>
346				<rule avp="Vendor-Specific-Application-Id" required="False"/>
347				<rule avp="Firmware-Revision" required="False" max="1"/>
348			</answer>
349		</command>
350
351		<command code="258" short="RA" name="Re-Auth">
352			<request>
353				<rule avp="Session-Id" required="true" max="1"/>
354				<rule avp="Origin-Host" required="true" max="1"/>
355				<rule avp="Origin-Realm" required="true" max="1"/>
356				<rule avp="Destination-Realm" required="true" max="1"/>
357				<rule avp="Destination-Host" required="true" max="1"/>
358				<rule avp="Auth-Application-Id" required="true" max="1"/>
359				<rule avp="Re-Auth-Request-Type" required="true" max="1"/>
360				<rule avp="User-Name" required="false" max="1"/>
361				<rule avp="Origin-State-Id" required="false" max="1"/>
362				<rule avp="Proxy-Info" required="false"/>
363				<rule avp="Route-Record" required="false"/>
364			</request>
365			<answer>
366				<rule avp="Session-Id" required="true" max="1"/>
367				<rule avp="Result-Code" required="true" max="1"/>
368				<rule avp="Origin-Host" required="true" max="1"/>
369				<rule avp="Origin-Realm" required="true" max="1"/>
370				<rule avp="User-Name" required="false" max="1"/>
371				<rule avp="Origin-State-Id" required="false" max="1"/>
372				<rule avp="Error-Message" required="false" max="1"/>
373				<rule avp="Error-Reporting-Host" required="false" max="1"/>
374				<rule avp="Failed-AVP" required="false" max="1"/>
375				<rule avp="Redirect-Host" required="false"/>
376				<rule avp="Redirect-Host-Usage" required="false" max="1"/>
377				<rule avp="Redirect-Max-Cache-Time" required="false" max="1"/>
378				<rule avp="Proxy-Info" required="false"/>
379			</answer>
380		</command>
381
382		<command code="271" short="AC" name="Accounting">
383			<request>
384				<rule avp="Session-Id" required="true" max="1"/>
385				<rule avp="Origin-Host" required="true" max="1"/>
386				<rule avp="Origin-Realm" required="true" max="1"/>
387				<rule avp="Destination-Realm" required="true" max="1"/>
388				<rule avp="Accounting-Record-Type" required="true" max="1"/>
389				<rule avp="Accounting-Record-Number" required="true" max="1"/>
390				<rule avp="Acct-Application-Id" required="false" max="1"/>
391				<rule avp="Vendor-Specific-Application-Id" required="false" max="1"/>
392				<rule avp="User-Name" required="false" max="1"/>
393				<rule avp="Destination-Host" required="false" max="1"/>
394				<rule avp="Accounting-Sub-Session-Id" required="false" max="1"/>
395				<rule avp="Acct-Session-Id" required="false" max="1"/>
396				<rule avp="Acct-Multi-Session-Id" required="false" max="1"/>
397				<rule avp="Acct-Interim-Interval" required="false" max="1"/>
398				<rule avp="Accounting-Realtime-Required" required="false" max="1"/>
399				<rule avp="Origin-State-Id" required="false" max="1"/>
400				<rule avp="Event-Timestamp" required="false" max="1"/>
401				<rule avp="Proxy-Info" required="false"/>
402				<rule avp="Route-Record" required="false"/>
403			</request>
404			<answer>
405				<rule avp="Session-Id" required="true" max="1"/>
406				<rule avp="Result-Code" required="true" max="1"/>
407				<rule avp="Origin-Host" required="true" max="1"/>
408				<rule avp="Origin-Realm" required="true" max="1"/>
409				<rule avp="Accounting-Record-Type" required="true" max="1"/>
410				<rule avp="Accounting-Record-Number" required="true" max="1"/>
411				<rule avp="Acct-Application-Id" required="false" max="1"/>
412				<rule avp="Vendor-Specific-Application-Id" required="false" max="1"/>
413				<rule avp="User-Name" required="false" max="1"/>
414				<rule avp="Accounting-Sub-Session-Id" required="false" max="1"/>
415				<rule avp="Acct-Session-Id" required="false" max="1"/>
416				<rule avp="Acct-Multi-Session-Id" required="false" max="1"/>
417				<rule avp="Error-Message" required="false" max="1"/>
418				<rule avp="Error-Reporting-Host" required="false" max="1"/>
419				<rule avp="Failed-AVP" required="false" max="1"/>
420				<rule avp="Acct-Interim-Interval" required="false" max="1"/>
421				<rule avp="Accounting-Realtime-Required" required="false" max="1"/>
422				<rule avp="Origin-State-Id" required="false" max="1"/>
423				<rule avp="Event-Timestamp" required="false" max="1"/>
424				<rule avp="Proxy-Info" required="false"/>
425			</answer>
426		</command>
427
428		<command code="274" short="AS" name="Abort-Session">
429			<request>
430				<rule avp="Session-Id" required="true" max="1"/>
431				<rule avp="Origin-Host" required="true" max="1"/>
432				<rule avp="Origin-Realm" required="true" max="1"/>
433				<rule avp="Destination-Realm" required="true" max="1"/>
434				<rule avp="Destination-Host" required="true" max="1"/>
435				<rule avp="Auth-Application-Id" required="true" max="1"/>
436				<rule avp="User-Name" required="false" max="1"/>
437				<rule avp="Origin-State-Id" required="false" max="1"/>
438				<rule avp="Proxy-Info" required="false"/>
439				<rule avp="Route-Record" required="false"/>
440			</request>
441			<answer>
442				<rule avp="Session-Id" required="true" max="1"/>
443				<rule avp="Result-Code" required="true" max="1"/>
444				<rule avp="Origin-Host" required="true" max="1"/>
445				<rule avp="Origin-Realm" required="true" max="1"/>
446				<rule avp="User-Name" required="false" max="1"/>
447				<rule avp="Origin-State-Id" required="false" max="1"/>
448				<rule avp="Error-Message" required="false" max="1"/>
449				<rule avp="Error-Reporting-Host" required="false" max="1"/>
450				<rule avp="Failed-AVP" required="false" max="1"/>
451				<rule avp="Redirect-Host" required="false"/>
452				<rule avp="Redirect-Host-Usage" required="false" max="1"/>
453				<rule avp="Redirect-Max-Cache-Time" required="false" max="1"/>
454				<rule avp="Proxy-Info" required="false"/>
455			</answer>
456		</command>
457
458		<command code="275" short="ST" name="Session-Termination">
459			<request>
460				<rule avp="Session-Id" required="true" max="1"/>
461				<rule avp="Origin-Host" required="true" max="1"/>
462				<rule avp="Origin-Realm" required="true" max="1"/>
463				<rule avp="Destination-Realm" required="true" max="1"/>
464				<rule avp="Auth-Application-Id" required="true" max="1"/>
465				<rule avp="Termination-Cause" required="true" max="1"/>
466				<rule avp="User-Name" required="false" max="1"/>
467				<rule avp="Destination-Host" required="false" max="1"/>
468				<rule avp="Class" required="false"/>
469				<rule avp="Origin-State-Id" required="false" max="1"/>
470				<rule avp="Proxy-Info" required="false"/>
471				<rule avp="Route-Record" required="false"/>
472			</request>
473			<answer>
474				<rule avp="Session-Id" required="true" max="1"/>
475				<rule avp="Result-Code" required="true" max="1"/>
476				<rule avp="Origin-Host" required="true" max="1"/>
477				<rule avp="Origin-Realm" required="true" max="1"/>
478				<rule avp="User-Name" required="false" max="1"/>
479				<rule avp="Class" required="false"/>
480				<rule avp="Error-Message" required="false" max="1"/>
481				<rule avp="Error-Reporting-Host" required="false" max="1"/>
482				<rule avp="Failed-AVP" required="false" max="1"/>
483				<rule avp="Origin-State-Id" required="false" max="1"/>
484				<rule avp="Redirect-Host" required="false"/>
485				<rule avp="Redirect-Host-Usage" required="false" max="1"/>
486				<rule avp="Redirect-Max-Cache-Time" required="false" max="1"/>
487				<rule avp="Proxy-Info" required="false"/>
488			</answer>
489		</command>
490
491		<command code="280" short="DW" name="Device-Watchdog">
492			<request>
493				<rule avp="Origin-Host" required="true" max="1"/>
494				<rule avp="Origin-Realm" required="true" max="1"/>
495				<rule avp="Origin-State-Id" required="false" max="1"/>
496			</request>
497			<answer>
498				<rule avp="Result-Code" required="true" max="1"/>
499				<rule avp="Origin-Host" required="true" max="1"/>
500				<rule avp="Origin-Realm" required="true" max="1"/>
501				<rule avp="Error-Message" required="false" max="1"/>
502				<rule avp="Failed-AVP" required="false" max="1"/>
503				<rule avp="Origin-State-Id" required="false" max="1"/>
504			</answer>
505		</command>
506
507		<command code="282" short="DP" name="Disconnect-Peer">
508			<request>
509				<rule avp="Origin-Host" required="true" max="1"/>
510				<rule avp="Origin-Realm" required="true" max="1"/>
511				<rule avp="Disconnect-Cause" required="false" max="1"/>
512			</request>
513			<answer>
514				<rule avp="Result-Code" required="true" max="1"/>
515				<rule avp="Origin-Host" required="true" max="1"/>
516				<rule avp="Origin-Realm" required="true" max="1"/>
517				<rule avp="Error-Message" required="false" max="1"/>
518				<rule avp="Failed-AVP" required="false" max="1"/>
519			</answer>
520		</command>
521
522		<avp name="Acct-Interim-Interval" code="85" must="M" may="P" must-not="V" may-encrypt="Y">
523			<data type="Unsigned32"/>
524		</avp>
525
526		<avp name="Accounting-Realtime-Required" code="483" must="M" may="P" must-not="V" may-encrypt="Y">
527			<data type="Enumerated">
528				<item code="1" name="DELIVER_AND_GRANT"/>
529				<item code="2" name="GRANT_AND_STORE"/>
530				<item code="3" name="GRANT_AND_LOSE"/>
531			</data>
532		</avp>
533
534		<avp name="Acct-Multi-Session-Id" code="50" must="M" may="P" must-not="V" may-encrypt="Y">
535			<data type="UTF8String"/>
536		</avp>
537
538		<avp name="Accounting-Record-Number" code="485" must="M" may="P" must-not="V" may-encrypt="Y">
539			<data type="Unsigned32"/>
540		</avp>
541
542		<avp name="Accounting-Record-Type" code="480" must="M" may="P" must-not="V" may-encrypt="Y">
543			<data type="Enumerated">
544				<item code="1" name="EVENT_RECORD"/>
545				<item code="2" name="START_RECORD"/>
546				<item code="3" name="INTERIM_RECORD"/>
547				<item code="4" name="STOP_RECORD"/>
548			</data>
549		</avp>
550
551		<avp name="Accounting-Session-Id" code="44" must="M" may="P" must-not="V" may-encrypt="Y">
552			<data type="OctetString"/>
553		</avp>
554
555		<avp name="Accounting-Sub-Session-Id" code="287" must="M" may="P" must-not="V" may-encrypt="Y">
556			<data type="Unsigned64"/>
557		</avp>
558
559		<avp name="Acct-Application-Id" code="259" must="M" may="P" must-not="V" may-encrypt="-">
560			<data type="Unsigned32"/>
561		</avp>
562
563		<avp name="Auth-Application-Id" code="258" must="M" may="P" must-not="V" may-encrypt="-">
564			<data type="Unsigned32"/>
565		</avp>
566
567		<avp name="Auth-Request-Type" code="274" must="M" may="P" must-not="V" may-encrypt="-">
568			<data type="Enumerated">
569				<item code="1" name="AUTHENTICATE_ONLY"/>
570				<item code="2" name="AUTHORIZE_ONLY"/>
571				<item code="3" name="AUTHORIZE_AUTHENTICATE"/>
572			</data>
573		</avp>
574
575		<avp name="Authorization-Lifetime" code="291" must="M" may="P" must-not="V" may-encrypt="-">
576			<data type="Unsigned32"/>
577		</avp>
578
579		<avp name="Auth-Grace-Period" code="276" must="M" may="P" must-not="V" may-encrypt="-">
580			<data type="Unsigned32"/>
581		</avp>
582
583		<avp name="Auth-Session-State" code="277" must="M" may="P" must-not="V" may-encrypt="-">
584			<data type="Enumerated">
585				<item code="0" name="STATE_MAINTAINED"/>
586				<item code="1" name="NO_STATE_MAINTAINED"/>
587			</data>
588		</avp>
589
590		<avp name="Re-Auth-Request-Type" code="285" must="M" may="P" must-not="V" may-encrypt="-">
591			<data type="Enumerated">
592				<item code="0" name="AUTHORIZE_ONLY"/>
593				<item code="1" name="AUTHORIZE_AUTHENTICATE"/>
594			</data>
595		</avp>
596
597		<avp name="Class" code="25" must="M" may="P" must-not="V" may-encrypt="Y">
598			<data type="OctetString"/>
599		</avp>
600
601		<avp name="Destination-Host" code="293" must="M" may="P" must-not="V" may-encrypt="-">
602			<data type="DiameterIdentity"/>
603		</avp>
604
605		<avp name="Destination-Realm" code="283" must="M" may="P" must-not="V" may-encrypt="-">
606			<data type="DiameterIdentity"/>
607		</avp>
608
609		<avp name="Disconnect-Cause" code="273" must="M" may="P" must-not="V" may-encrypt="-">
610			<data type="Enumerated">
611				<item code="0" name="REBOOTING"/>
612				<item code="1" name="BUSY"/>
613				<item code="2" name="DO_NOT_WANT_TO_TALK_TO_YOU"/>
614			</data>
615		</avp>
616
617		<avp name="Error-Message" code="281" must="-" may="P" must-not="V,M" may-encrypt="-">
618			<data type="UTF8String"/>
619		</avp>
620
621		<avp name="Error-Reporting-Host" code="294" must="-" may="P" must-not="V,M" may-encrypt="-">
622			<data type="DiameterIdentity"/>
623		</avp>
624
625		<avp name="Event-Timestamp" code="55" must="M" may="P" must-not="V" may-encrypt="-">
626			<data type="Time"/>
627		</avp>
628
629		<avp name="Experimental-Result" code="297" must="M" may="P" must-not="V" may-encrypt="-">
630			<data type="Grouped">
631				<rule avp="Vendor-Id" required="true" max="1"/>
632				<rule avp="Experimental-Result-Code" required="true" max="1"/>
633			</data>
634		</avp>
635
636		<avp name="Experimental-Result-Code" code="298" must="M" may="P" must-not="V" may-encrypt="-">
637			<data type="Unsigned32"/>
638		</avp>
639
640		<avp name="Failed-AVP" code="279" must="M" may="P" must-not="V" may-encrypt="-">
641			<data type="Grouped"/>
642		</avp>
643
644		<avp name="Firmware-Revision" code="267" must="-" may="-" must-not="P,V,M" may-encrypt="-">
645			<data type="Unsigned32"/>
646		</avp>
647
648		<avp name="Host-IP-Address" code="257" must="M" may="P" must-not="V" may-encrypt="-">
649			<data type="Address"/>
650		</avp>
651
652		<avp name="Inband-Security-Id" code="299" must="M" may="P" must-not="V" may-encrypt="-">
653			<data type="Unsigned32"/>
654		</avp>
655
656		<avp name="Multi-Round-Time-Out" code="272" must="M" may="P" must-not="V" may-encrypt="Y">
657			<data type="Unsigned32"/>
658		</avp>
659
660		<avp name="Origin-Host" code="264" must="M" may="P" must-not="V" may-encrypt="-">
661			<data type="DiameterIdentity"/>
662		</avp>
663
664		<avp name="Origin-Realm" code="296" must="M" may="P" must-not="V" may-encrypt="-">
665			<data type="DiameterIdentity"/>
666		</avp>
667
668		<avp name="Origin-State-Id" code="278" must="M" may="P" must-not="V" may-encrypt="-">
669			<data type="Unsigned32"/>
670		</avp>
671
672		<avp name="Product-Name" code="269" must="-" may="-" must-not="P,V,M" may-encrypt="-">
673			<data type="UTF8String"/>
674		</avp>
675
676		<avp name="Proxy-Host" code="280" must="M" may="-" must-not="P,V" may-encrypt="-">
677			<data type="DiameterIdentity"/>
678		</avp>
679
680		<avp name="Proxy-Info" code="284" must="M" may="-" must-not="P,V" may-encrypt="-">
681			<data type="Grouped">
682				<rule avp="Proxy-Host" required="true" max="1"/>
683				<rule avp="Proxy-State" required="true" max="1"/>
684			</data>
685		</avp>
686
687		<avp name="Proxy-State" code="33" must="M" may="-" must-not="P,V" may-encrypt="-">
688			<data type="OctetString"/>
689		</avp>
690
691		<avp name="Redirect-Host" code="292" must="M" may="P" must-not="V" may-encrypt="-">
692			<data type="DiameterURI"/>
693		</avp>
694
695		<avp name="Redirect-Host-Usage" code="261" must="M" may="P" must-not="V" may-encrypt="-">
696			<data type="Enumerated">
697				<item code="0" name="DONT_CACHE"/>
698				<item code="1" name="ALL_SESSION"/>
699				<item code="2" name="ALL_REALM"/>
700				<item code="3" name="REALM_AND_APPLICATION"/>
701				<item code="4" name="ALL_APPLICATION"/>
702				<item code="5" name="ALL_HOST"/>
703				<item code="6" name="ALL_USER"/>
704			</data>
705		</avp>
706
707		<avp name="Redirect-Max-Cache-Time" code="262" must="M" may="P" must-not="V" may-encrypt="-">
708			<data type="Unsigned32"/>
709		</avp>
710
711		<avp name="Result-Code" code="268" must="M" may="P" must-not="V" may-encrypt="-">
712			<data type="Unsigned32"/>
713		</avp>
714
715		<avp name="Route-Record" code="282" must="M" may="-" must-not="P,V" may-encrypt="-">
716			<data type="DiameterIdentity"/>
717		</avp>
718
719		<avp name="Session-Id" code="263" must="M" may="P" must-not="V" may-encrypt="Y">
720			<data type="UTF8String"/>
721		</avp>
722
723		<avp name="Session-Timeout" code="27" must="M" may="P" must-not="V" may-encrypt="-">
724			<data type="Unsigned32"/>
725		</avp>
726
727		<avp name="Session-Binding" code="270" must="M" may="P" must-not="V" may-encrypt="Y">
728			<data type="Unsigned32"/>
729		</avp>
730
731		<avp name="Session-Server-Failover" code="271" must="M" may="P" must-not="V" may-encrypt="Y">
732			<data type="Enumerated">
733				<item code="0" name="REFUSE_SERVICE"/>
734				<item code="1" name="TRY_AGAIN"/>
735				<item code="2" name="ALLOW_SERVICE"/>
736				<item code="3" name="TRY_AGAIN_ALLOW_SERVICE"/>
737			</data>
738		</avp>
739
740		<avp name="Supported-Vendor-Id" code="265" must="M" may="P" must-not="V" may-encrypt="-">
741			<data type="Unsigned32"/>
742		</avp>
743
744		<avp name="Termination-Cause" code="295" must="M" may="P" must-not="V" may-encrypt="-">
745			<data type="Enumerated">
746				<item code="1" name="DIAMETER_LOGOUT"/>
747				<item code="2" name="DIAMETER_SERVICE_NOT_PROVIDED"/>
748				<item code="3" name="DIAMETER_BAD_ANSWER"/>
749				<item code="4" name="DIAMETER_ADMINISTRATIVE"/>
750				<item code="5" name="DIAMETER_LINK_BROKEN"/>
751				<item code="6" name="DIAMETER_AUTH_EXPIRED"/>
752				<item code="7" name="DIAMETER_USER_MOVED"/>
753				<item code="8" name="DIAMETER_SESSION_TIMEOUT"/>
754			</data>
755		</avp>
756
757		<avp name="User-Name" code="1" must="M" may="P" must-not="V" may-encrypt="Y">
758			<data type="UTF8String"/>
759		</avp>
760
761		<avp name="Vendor-Id" code="266" must="M" may="P" must-not="V" may-encrypt="-">
762			<data type="Unsigned32"/>
763		</avp>
764
765		<avp name="Vendor-Specific-Application-Id" code="260" must="M" may="P" must-not="V" may-encrypt="-">
766			<data type="Grouped">
767				<rule avp="Vendor-Id" required="false" max="1"/>
768				<rule avp="Auth-Application-Id" required="true" max="1"/>
769				<rule avp="Acct-Application-Id" required="true" max="1"/>
770			</data>
771		</avp>
772
773		<!-- IETF RFC 7683 - https://tools.ietf.org/html/rfc7683 -->
774		<avp name="OC-Supported-Features" code="621" must-not="V">
775			<data type="Grouped">
776				<rule avp="OC-Feature-Vector" required="false"/>
777				<rule avp="AVP" required="false"/>
778			</data>
779		</avp>
780
781		<avp name="OC-Feature-Vector" code="622" must-not="V">
782			<data type="Unsigned64"/>
783		</avp>
784
785		<avp name="OC-OLR" code="623" must-not="V">
786			<data type="Grouped">
787				<rule avp="OC-Sequence-Number" required="true" max="1"/>
788				<rule avp="OC-Report-Type" required="true" max="1"/>
789				<rule avp="OC-Reduction-Percentage" required="false" max="1"/>
790				<rule avp="OC-Validity-Duration" required="false" max="1"/>
791				<rule avp="AVP" required="false"/>
792			</data>
793		</avp>
794
795		<avp name="OC-Sequence-Number" code="624" must-not="V">
796			<data type="Unsigned64"/>
797		</avp>
798
799		<avp name="OC-Validity-Duration" code="625" must-not="V">
800			<data type="Unsigned32"/>
801		</avp>
802
803		<avp name="OC-Report-Type" code="626" must-not="V">
804			<data type="Enumerated">
805				<item code="0" name="HOST_REPORT"/>
806				<item code="1" name="REALM_REPORT"/>
807			</data>
808		</avp>
809
810		<avp name="OC-Reduction-Percentage" code="627" must-not="V">
811			<data type="Unsigned32"/>
812		</avp>
813
814		<!-- IETF RFC 7944 - https://tools.ietf.org/html/rfc7944 -->
815		<avp name="DRMP" code="301" must-not="V">
816			<data type="Enumerated">
817				<item code="0" name="PRIORITY_0"/>
818				<item code="1" name="PRIORITY_1"/>
819				<item code="2" name="PRIORITY_2"/>
820				<item code="3" name="PRIORITY_3"/>
821				<item code="4" name="PRIORITY_4"/>
822				<item code="5" name="PRIORITY_5"/>
823				<item code="6" name="PRIORITY_6"/>
824				<item code="7" name="PRIORITY_7"/>
825				<item code="8" name="PRIORITY_8"/>
826				<item code="9" name="PRIORITY_9"/>
827				<item code="10" name="PRIORITY_10"/>
828				<item code="11" name="PRIORITY_11"/>
829				<item code="12" name="PRIORITY_12"/>
830				<item code="13" name="PRIORITY_13"/>
831				<item code="14" name="PRIORITY_14"/>
832				<item code="15" name="PRIORITY_15"/>
833			</data>
834		</avp>
835		
836		<avp name="CC-Request-Number" code="415" must="M" may="P" must-not="V" may-encrypt="Y">
837			<!-- http://tools.ietf.org/html/rfc4006#section-8.2 -->
838			<data type="Unsigned32"/>
839		</avp>
840
841		<avp name="Service-Information" code="873" must="V,M" may="P" must-not="-" may-encrypt="N" vendor-id="10415">
842			<data type="Grouped">
843				<rule avp="Subscription-Id" required="false"/>
844				<rule avp="AoC-Information" required="false" max="1"/>
845				<rule avp="PS-Information" required="false" max="1"/>
846				<rule avp="IMS-Information" required="false" max="1"/>
847				<rule avp="MMS-Information" required="false" max="1"/>
848				<rule avp="LCS-Information" required="false" max="1"/>
849				<rule avp="PoC-Information" required="false" max="1"/>
850				<rule avp="MBMS-Information" required="false" max="1"/>
851				<rule avp="SMS-Information" required="false" max="1"/>
852				<rule avp="VCS-Information" required="false" max="1"/>
853				<rule avp="MMTel-Information" required="false" max="1"/>
854				<rule avp="Service-Generic-Information" required="false" max="1"/>
855				<rule avp="IM-Information" required="false" max="1"/>
856				<rule avp="DCD-Information" required="false" max="1"/>
857			</data>
858		</avp>
859
860		<avp name="PS-Information" code="874" must="V,M" may="P" must-not="-" may-encrypt="N" vendor-id="10415">
861			<data type="Grouped">
862				<rule avp="TGPP-Charging-Id" required="false" max="1"/>
863				<rule avp="PDN-Connection-Charging-Id" required="false" max="1"/>
864				<rule avp="Node-Id" required="false" max="1"/>
865				<rule avp="TGPP-PDP-Type" required="false" max="1"/>
866				<rule avp="PDP-Address" required="false"/>
867				<rule avp="PDP-Address-Prefix-Length" required="false" max="1"/>
868				<rule avp="Dynamic-Address-Flag" required="false" max="1"/>
869				<rule avp="Dynamic-Address-Flag-Extension" required="false" max="1"/>
870				<rule avp="QoS-Information" required="false" max="1"/>
871				<rule avp="SGSN-Address" required="false"/>
872				<rule avp="GGSN-Address" required="false"/>
873				<rule avp="TDF-IP-Address" required="false"/>
874				<rule avp="SGW-Address" required="false"/>
875				<rule avp="ePDG-Address" required="false"/>
876				<rule avp="CG-Address" required="false" max="1"/>
877				<rule avp="Serving-Node-Type" required="false" max="1"/>
878				<rule avp="SGW-Change" required="false" max="1"/>
879				<rule avp="TGPP-IMSI-MCC-MNC" required="false" max="1"/>
880				<rule avp="IMSI-Unauthenticated-Flag" required="false" max="1"/>
881				<rule avp="TGPP-GGSN-MCC-MNC" required="false" max="1"/>
882				<rule avp="TGPP-NSAPI" required="false" max="1"/>
883				<rule avp="Called-Station-Id" required="false" max="1"/>
884				<rule avp="TGPP-Session-Stop-Indicator" required="false" max="1"/>
885				<rule avp="TGPP-Selection-Mode" required="false" max="1"/>
886				<rule avp="TGPP-Charging-Characteristics" required="false" max="1"/>
887				<rule avp="Charging-Characteristics-Selection-Mode" required="false" max="1"/>
888				<rule avp="TGPP-SGSN-MCC-MNC" required="false" max="1"/>
889				<rule avp="TGPP-MS-TimeZone" required="false" max="1"/>
890				<rule avp="Charging-Rule-Base-Name" required="false" max="1"/>
891				<rule avp="ADC-Rule-Base-Name" required="false" max="1"/>
892				<rule avp="TGPP-User-Location-Info" required="false" max="1"/>
893				<rule avp="User-Location-Info-Time" required="false" max="1"/>
894				<rule avp="User-CSG-Information" required="false" max="1"/>
895				<rule avp="Presence-Reporting-Area-Information" required="false" max="1"/>
896				<rule avp="TGPP2-BSID" required="false" max="1"/>
897				<rule avp="TWAN-User-Location-Info" required="false" max="1"/>
898				<rule avp="TGPP-RAT-Type" required="false" max="1"/>
899				<rule avp="PS-Furnish-Charging-Information" required="false" max="1"/>
900				<rule avp="PDP-Context-Type" required="false" max="1"/>
901				<rule avp="Offline-Charging" required="false" max="1"/>
902				<rule avp="Traffic-Data-Volumes" required="false"/>
903				<rule avp="Service-Data-Container" required="false"/>
904				<rule avp="User-Equipment-Info" required="false" max="1"/>
905				<rule avp="Terminal-Information" required="false" max="1"/>
906				<rule avp="Start-Time" required="false" max="1"/>
907				<rule avp="Stop-Time" required="false" max="1"/>
908				<rule avp="Change-Condition" required="false" max="1"/>
909				<rule avp="Diagnostics" required="false" max="1"/>
910				<rule avp="Low-Priority-Indicator" required="false" max="1"/>
911				<rule avp="MME-Number-for-MT-SMS" required="false" max="1"/>
912				<rule avp="MME-Name" required="false" max="1"/>
913				<rule avp="MME-Realm" required="false" max="1"/>
914				<rule avp="Logical-Access-Id" required="false" max="1"/>
915				<rule avp="Physical-Access-Id" required="false" max="1"/>
916				<rule avp="Fixed-User-Location-Info" required="false" max="1"/>
917				<rule avp="CN-Operator-Selection-Entity" required="false" max="1"/>
918			</data>
919		</avp>
920
921		<avp name="Called-Station-Id" code="30" must="M" may="-" must-not="V" may-encrypt="Y">
922            <data type="UTF8String"/>
923        </avp>
924	
925		<avp name="CC-Correlation-Id" code="411" must="-" may="P,M" must-not="V" may-encrypt="Y">
926			<!-- http://tools.ietf.org/html/rfc4006#section-8.1 -->
927			<data type="OctetString"/>
928		</avp>
929
930		<avp name="CC-Input-Octets" code="412" must="M" may="P" must-not="V" may-encrypt="Y">
931			<!-- http://tools.ietf.org/html/rfc4006#section-8.24 -->
932			<data type="Unsigned64"/>
933		</avp>
934
935		<avp name="CC-Money" code="413" must="M" may="P" must-not="V" may-encrypt="Y">
936			<!-- http://tools.ietf.org/html/rfc4006#section-8.22 -->
937			<data type="Grouped">
938				<rule avp="Unit-Value" required="true" max="1"/>
939				<rule avp="Currency-Code" required="true" max="1"/>
940			</data>
941		</avp>
942
943		<avp name="CC-Output-Octets" code="414" must="M" may="P" must-not="V" may-encrypt="Y">
944			<!-- http://tools.ietf.org/html/rfc4006#section-8.25 -->
945			<data type="Unsigned64"/>
946		</avp>
947
948		<avp name="CC-Request-Number" code="415" must="M" may="P" must-not="V" may-encrypt="Y">
949			<!-- http://tools.ietf.org/html/rfc4006#section-8.2 -->
950			<data type="Unsigned32"/>
951		</avp>
952
953		<avp name="CC-Request-Type" code="416" must="M" may="P" must-not="V" may-encrypt="Y">
954			<!-- http://tools.ietf.org/html/rfc4006#section-8.3 -->
955			<data type="Enumerated">
956				<item code="1" name="INITIAL_REQUEST"/>
957				<item code="2" name="UPDATE_REQUEST"/>
958				<item code="3" name="TERMINATION_REQUEST"/>
959			</data>
960		</avp>
961
962		<avp name="CC-Service-Specific-Units" code="417" must="M" may="P" must-not="V" may-encrypt="Y">
963			<data type="Unsigned64"/>
964		</avp>
965
966		<avp name="CC-Session-Failover" code="418" must="M" may="P" must-not="V" may-encrypt="Y">
967			<!-- http://tools.ietf.org/html/rfc4006#section-8.4 -->
968			<data type="Enumerated">
969				<item code="0" name="FAILOVER_NOT_SUPPORTED"/>
970				<item code="1" name="FAILOVER_SUPPORTED"/>
971			</data>
972		</avp>
973
974		<avp name="CC-Sub-Session-Id" code="419" must="M" may="P" must-not="V" may-encrypt="Y">
975			<!-- http://tools.ietf.org/html/rfc4006#section-8.5 -->
976			<data type="Unsigned64"/>
977		</avp>
978
979		<avp name="CC-Time" code="420" must="M" may="P" must-not="V" may-encrypt="Y">
980			<!-- http://tools.ietf.org/html/rfc4006#section-8.21 -->
981			<data type="Unsigned32"/>
982		</avp>
983
984		<avp name="CC-Total-Octets" code="421" must="M" may="P" must-not="V" may-encrypt="Y">
985			<!-- http://tools.ietf.org/html/rfc4006#section-8.23 -->
986			<data type="Unsigned64"/>
987		</avp>
988
989		<avp name="CC-Unit-Type" code="454" must="M" may="P" must-not="V" may-encrypt="Y">
990			<!-- http://tools.ietf.org/html/rfc4006#section-8.32 -->
991			<data type="Enumerated">
992				<item code="0" name="TIME"/>
993				<item code="1" name="MONEY"/>
994				<item code="2" name="TOTAL-OCTETS"/>
995				<item code="3" name="INPUT-OCTETS"/>
996				<item code="4" name="OUTPUT-OCTETS"/>
997				<item code="5" name="SERVICE-SPECIFIC-UNITS"/>
998			</data>
999		</avp>
1000
1001		<avp name="Check-Balance-Result" code="422" must="M" may="P" must-not="V" may-encrypt="Y">
1002			<!-- http://tools.ietf.org/html/rfc4006#section-8.6 -->
1003			<data type="Enumerated">
1004				<item code="0" name="ENOUGH_CREDIT"/>
1005				<item code="1" name="NO_CREDIT"/>
1006			</data>
1007		</avp>
1008
1009		<avp name="Cost-Information" code="423" must="M" may="P" must-not="V" may-encrypt="Y">
1010			<!-- http://tools.ietf.org/html/rfc4006#section-8.7 -->
1011			<data type="Grouped">
1012				<rule avp="Unit-Value" required="true" max="1"/>
1013				<rule avp="Currency-Code" required="true" max="1"/>
1014				<rule avp="Cost-Unit" required="true" max="1"/>
1015			</data>
1016		</avp>
1017
1018		<avp name="Cost-Unit" code="424" must="M" may="P" must-not="V" may-encrypt="Y">
1019			<!-- http://tools.ietf.org/html/rfc4006#section-8.12 -->
1020			<data type="UTF8String"/>
1021		</avp>
1022
1023		<avp name="Credit-Control" code="426" must="M" may="P" must-not="V" may-encrypt="Y">
1024			<!-- http://tools.ietf.org/html/rfc4006#section-8.13 -->
1025			<data type="Enumerated">
1026				<item code="0" name="CREDIT_AUTHORIZATION"/>
1027				<item code="1" name="RE_AUTHORIZATION"/>
1028			</data>
1029		</avp>
1030
1031		<avp name="Credit-Control-Failure-Handling" code="427" must="M" may="P" must-not="V" may-encrypt="Y">
1032			<!-- http://tools.ietf.org/html/rfc4006#section-8.14 -->
1033			<data type="Enumerated">
1034				<item code="0" name="TERMINATE"/>
1035				<item code="1" name="CONTINUE"/>
1036				<item code="2" name="RETRY_AND_TERMINATE"/>
1037			</data>
1038		</avp>
1039
1040		<avp name="Currency-Code" code="425" must="M" may="P" must-not="V" may-encrypt="Y">
1041			<!-- http://tools.ietf.org/html/rfc4006#section-8.11 -->
1042			<data type="Unsigned32"/>
1043		</avp>
1044
1045		<avp name="Direct-Debiting-Failure-Handling" code="428" must="M" may="P" must-not="V" may-encrypt="Y">
1046			<!-- http://tools.ietf.org/html/rfc4006#section-8.15 -->
1047			<data type="Enumerated">
1048				<item code="0" name="TERMINATE_OR_BUFFER"/>
1049				<item code="1" name="CONTINUE"/>
1050			</data>
1051		</avp>
1052
1053		<avp name="Exponent" code="429" must="M" may="P" must-not="V" may-encrypt="Y">
1054			<!-- http://tools.ietf.org/html/rfc4006#section-8.9 -->
1055			<data type="Integer32"/>
1056		</avp>
1057
1058		<avp name="Final-Unit-Action" code="449" must="M" may="P" must-not="V" may-encrypt="Y">
1059			<!-- http://tools.ietf.org/html/rfc4006#section-8.35 -->
1060			<data type="Enumerated">
1061				<item code="0" name="TERMINATE"/>
1062				<item code="1" name="REDIRECT"/>
1063				<item code="2" name="RESTRICT_ACCESS"/>
1064			</data>
1065		</avp>
1066
1067		<avp name="Final-Unit-Indication" code="430" must="M" may="P" must-not="V" may-encrypt="Y">
1068			<!-- http://tools.ietf.org/html/rfc4006#section-8.34 -->
1069			<data type="Grouped">
1070				<rule avp="Final-Unit-Action" required="true" max="1"/>
1071				<rule avp="Restriction-Filter-Rule" required="false" max="1"/>
1072				<rule avp="Filter-Id" required="false" max="1"/>
1073				<rule avp="Redirect-Server" required="false" max="1"/>
1074			</data>
1075		</avp>
1076
1077		<avp name="Granted-Service-Unit" code="431" must="M" may="P" must-not="V" may-encrypt="Y">
1078			<!-- http://tools.ietf.org/html/rfc4006#section-8.17 -->
1079			<data type="Grouped">
1080				<rule avp="Tariff-Time-Change" required="false" max="1"/>
1081				<rule avp="CC-Time" required="false" max="1"/>
1082				<rule avp="CC-Money" required="false" max="1"/>
1083				<rule avp="CC-Total-Octets" required="false" max="1"/>
1084				<rule avp="CC-Input-Octets" required="false" max="1"/>
1085				<rule avp="CC-Output-Octets" required="false" max="1"/>
1086				<rule avp="CC-Service-Specific-Units" required="false" max="1"/>
1087				<!-- *[ AVP ]-->
1088			</data>
1089		</avp>
1090
1091		<avp name="G-S-U-Pool-Identifier" code="453" must="M" may="P" must-not="V" may-encrypt="Y">
1092			<!-- http://tools.ietf.org/html/rfc4006#section-8.31 -->
1093			<data type="Unsigned32"/>
1094		</avp>
1095
1096		<avp name="G-S-U-Pool-Reference" code="457" must="M" may="P" must-not="V" may-encrypt="Y">
1097			<!-- http://tools.ietf.org/html/rfc4006#section-8.30 -->
1098			<data type="Grouped">
1099				<rule avp="G-S-U-Pool-Identifier" required="true" max="1"/>
1100				<rule avp="CC-Unit-Type" required="true" max="1"/>
1101				<rule avp="Unit-Value" required="true" max="1"/>
1102			</data>
1103		</avp>
1104
1105		<avp name="Multiple-Services-Credit-Control" code="456" must="M" may="P" must-not="V" may-encrypt="Y">
1106			<!-- http://tools.ietf.org/html/rfc4006#section-8.16 -->
1107			<data type="Grouped">
1108				<rule avp="Granted-Service-Unit" required="false" max="1"/>
1109				<rule avp="Requested-Service-Unit" required="false" max="1"/>
1110				<rule avp="Used-Service-Unit" required="false" max="1"/>
1111				<rule avp="Tariff-Change-Usage" required="false" max="1"/>
1112				<rule avp="Service-Identifier" required="false" max="1"/>
1113				<rule avp="Rating-Group" required="false" max="1"/>
1114				<rule avp="G-S-U-Pool-Reference" required="false" max="1"/>
1115				<rule avp="Validity-Time" required="false" max="1"/>
1116				<rule avp="Result-Code" required="false" max="1"/>
1117				<rule avp="Final-Unit-Indication" required="false" max="1"/>
1118				<!-- *[ AVP ]-->
1119			</data>
1120		</avp>
1121
1122		<avp name="Multiple-Services-Indicator" code="455" must="M" may="P" must-not="V" may-encrypt="Y">
1123			<!-- http://tools.ietf.org/html/rfc4006#section-8.40 -->
1124			<data type="Enumerated">
1125				<item code="0" name="MULTIPLE_SERVICES_NOT_SUPPORTED"/>
1126				<item code="1" name="MULTIPLE_SERVICES_SUPPORTED"/>
1127			</data>
1128		</avp>
1129
1130		<avp name="Rating-Group" code="432" must="M" may="P" must-not="V" may-encrypt="Y">
1131			<!-- http://tools.ietf.org/html/rfc4006#section-8.29 -->
1132			<data type="Unsigned32"/>
1133		</avp>
1134
1135		<avp name="Redirect-Address-Type" code="433" must="M" may="P" must-not="V" may-encrypt="Y">
1136			<!-- http://tools.ietf.org/html/rfc4006#section-8.38 -->
1137			<data type="Enumerated">
1138				<item code="0" name="IPv4 Address"/>
1139				<item code="1" name="IPv6 Address"/>
1140				<item code="2" name="URL"/>
1141				<item code="3" name="SIP URI"/>
1142			</data>
1143		</avp>
1144
1145		<avp name="Redirect-Server" code="434" must="M" may="P" must-not="V" may-encrypt="Y">
1146			<!-- http://tools.ietf.org/html/rfc4006#section-8.37 -->
1147			<data type="Grouped">
1148				<rule avp="Redirect-Address-Type" required="true" max="1"/>
1149				<rule avp="Redirect-Server-Address" required="true" max="1"/>
1150			</data>
1151		</avp>
1152
1153		<avp name="Redirect-Server-Address" code="435" must="M" may="P" must-not="V" may-encrypt="Y">
1154			<!-- http://tools.ietf.org/html/rfc4006#section-8.39 -->
1155			<data type="UTF8String"/>
1156		</avp>
1157
1158		<avp name="Requested-Action" code="436" must="M" may="P" must-not="V" may-encrypt="Y">
1159			<!-- http://tools.ietf.org/html/rfc4006#section-8.41 -->
1160			<data type="Enumerated">
1161				<item code="0" name="DIRECT_DEBITING"/>
1162				<item code="1" name="REFUND_ACCOUNT"/>
1163				<item code="2" name="CHECK_BALANCE"/>
1164				<item code="3" name="PRICE_ENQUIRY"/>
1165			</data>
1166		</avp>
1167
1168		<avp name="Requested-Service-Unit" code="437" must="M" may="P" must-not="V" may-encrypt="Y">
1169			<!-- http://tools.ietf.org/html/rfc4006#section-8.18-->
1170			<data type="Grouped">
1171				<rule avp="CC-Time" required="false" max="1"/>
1172				<rule avp="CC-Money" required="false" max="1"/>
1173				<rule avp="CC-Total-Octets" required="false" max="1"/>
1174				<rule avp="CC-Input-Octets" required="false" max="1"/>
1175				<rule avp="CC-Output-Octets" required="false" max="1"/>
1176				<rule avp="CC-Service-Specific-Units" required="false" max="1"/>
1177				<!-- *[ AVP ]-->
1178			</data>
1179		</avp>
1180
1181		<avp name="Restriction-Filter-Rule" code="438" must="M" may="P" must-not="V" may-encrypt="Y">
1182			<!-- http://tools.ietf.org/html/rfc4006#section-8.36-->
1183			<data type="IPFilterRule"/>
1184		</avp>
1185
1186		<avp name="Service-Context-Id" code="461" must="M" may="P" must-not="V" may-encrypt="Y">
1187			<!-- http://tools.ietf.org/html/rfc4006#section-8.42-->
1188			<data type="UTF8String"/>
1189		</avp>
1190
1191		<avp name="Service-Identifier" code="439" must="M" may="P" must-not="V" may-encrypt="Y">
1192			<!-- http://tools.ietf.org/html/rfc4006#section-8.28-->
1193			<data type="Unsigned32"/>
1194		</avp>
1195
1196		<avp name="Service-Parameter-Info" code="440" must="-" may="P,M" must-not="V" may-encrypt="Y">
1197			<!-- http://tools.ietf.org/html/rfc4006#section-8.43-->
1198			<data type="Grouped">
1199				<rule avp="Service-Parameter-Type" required="true" max="1"/>
1200				<rule avp="Service-Parameter-Value" required="true" max="1"/>
1201			</data>
1202		</avp>
1203
1204		<avp name="Service-Parameter-Type" code="441" must="-" may="P,M" must-not="V" may-encrypt="Y">
1205			<!-- http://tools.ietf.org/html/rfc4006#section-8.44-->
1206			<data type="Unsigned32"/>
1207		</avp>
1208
1209		<avp name="Service-Parameter-Value" code="442" must="-" may="P,M" must-not="V" may-encrypt="Y">
1210			<!-- http://tools.ietf.org/html/rfc4006#section-8.45-->
1211			<data type="OctetString"/>
1212		</avp>
1213
1214		<avp name="Subscription-Id" code="443" must="M" may="P" must-not="V" may-encrypt="Y">
1215			<!-- http://tools.ietf.org/html/rfc4006#section-8.46-->
1216			<data type="Grouped">
1217				<rule avp="Subscription-Id-Type" required="true" max="1"/>
1218				<rule avp="Subscription-Id-Data" required="true" max="1"/>
1219			</data>
1220		</avp>
1221
1222		<avp name="Subscription-Id-Data" code="444" must="M" may="P" must-not="V" may-encrypt="Y">
1223			<!-- http://tools.ietf.org/html/rfc4006#section-8.48-->
1224			<data type="UTF8String"/>
1225		</avp>
1226
1227		<avp name="Subscription-Id-Type" code="450" must="M" may="P" must-not="V" may-encrypt="Y">
1228			<!-- http://tools.ietf.org/html/rfc4006#section-8.47-->
1229			<data type="Enumerated">
1230				<item code="0" name="END_USER_E164"/>
1231				<item code="1" name="END_USER_IMSI"/>
1232				<item code="2" name="END_USER_SIP_URI"/>
1233				<item code="3" name="END_USER_NAI"/>
1234			</data>
1235		</avp>
1236
1237		<avp name="Tariff-Change-Usage" code="452" must="M" may="P" must-not="V" may-encrypt="Y">
1238			<!-- http://tools.ietf.org/html/rfc4006#section-8.27-->
1239			<data type="Enumerated">
1240				<item code="0" name="UNIT_BEFORE_TARIFF_CHANGE"/>
1241				<item code="1" name="UNIT_AFTER_TARIFF_CHANGE"/>
1242				<item code="2" name="UNIT_INDETERMINATE"/>
1243			</data>
1244		</avp>
1245
1246		<avp name="Tariff-Time-Change" code="451" must="M" may="P" must-not="V" may-encrypt="Y">
1247			<!-- http://tools.ietf.org/html/rfc4006#section-8.20-->
1248			<data type="Time"/>
1249		</avp>
1250
1251		<avp name="Unit-Value" code="445" must="M" may="P" must-not="V" may-encrypt="Y">
1252			<!-- http://tools.ietf.org/html/rfc4006#section-8.8-->
1253			<data type="Grouped">
1254				<rule avp="Value-Digits" required="true" max="1"/>
1255				<rule avp="Exponent" required="true" max="1"/>
1256			</data>
1257		</avp>
1258
1259		<avp name="Used-Service-Unit" code="446" must="M" may="P" must-not="V" may-encrypt="Y">
1260			<!-- http://tools.ietf.org/html/rfc4006#section-8.19-->
1261			<data type="Grouped">
1262				<rule avp="Tariff-Change-Usage" required="false" max="1"/>
1263				<rule avp="CC-Time" required="false" max="1"/>
1264				<rule avp="CC-Money" required="false" max="1"/>
1265				<rule avp="CC-Total-Octets" required="false" max="1"/>
1266				<rule avp="CC-Input-Octets" required="false" max="1"/>
1267				<rule avp="CC-Output-Octets" required="false" max="1"/>
1268				<rule avp="CC-Service-Specific-Units" required="false" max="1"/>
1269				<!-- *[ AVP ]-->
1270			</data>
1271		</avp>
1272
1273		<avp name="User-Equipment-Info" code="458" must="-" may="P,M" must-not="V" may-encrypt="Y">
1274			<!-- http://tools.ietf.org/html/rfc4006#section-8.49-->
1275			<data type="Grouped">
1276				<rule avp="User-Equipment-Info-Type" required="true" max="1"/>
1277				<rule avp="User-Equipment-Info-Value" required="true" max="1"/>
1278			</data>
1279		</avp>
1280
1281		<avp name="User-Equipment-Info-Type" code="459" must="-" may="P,M" must-not="V" may-encrypt="Y">
1282			<!-- http://tools.ietf.org/html/rfc4006#section-8.50-->
1283			<data type="Enumerated">
1284				<item code="0" name="IMEISV"/>
1285				<item code="1" name="MAC"/>
1286				<item code="2" name="EUI64"/>
1287				<item code="3" name="MODIFIED_EUI64"/>
1288			</data>
1289		</avp>
1290
1291		<avp name="User-Equipment-Info-Value" code="460" must="-" may="P,M" must-not="V" may-encrypt="Y">
1292			<!-- http://tools.ietf.org/html/rfc4006#section-8.51-->
1293			<data type="OctetString"/>
1294		</avp>
1295
1296		<avp name="Value-Digits" code="447" must="M" may="P" must-not="V" may-encrypt="Y">
1297			<!-- http://tools.ietf.org/html/rfc4006#section-8.10-->
1298			<data type="Integer64"/>
1299		</avp>
1300
1301		<avp name="Validity-Time" code="448" must="M" may="P" must-not="V" may-encrypt="Y">
1302			<!-- http://tools.ietf.org/html/rfc4006#section-8.33-->
1303			<data type="Unsigned32"/>
1304		</avp>
1305
1306		<avp name="Timezone-Offset" code="571" vendor-id="10415" must="V" may-encrypt="Y">
1307			<data type="Integer32"/>
1308		</avp>
1309    </application>
1310</diameter>
1311    "#;
1312        xml
1313    };
1314}
1315
1316#[cfg(test)]
1317mod tests {
1318    use super::*;
1319
1320    #[test]
1321    fn test_default_dict() {
1322        let dict = Dictionary::new(&[&DEFAULT_DICT_XML]);
1323
1324        assert_eq!(dict.get_avp(416, None).unwrap().name, "CC-Request-Type");
1325        assert_eq!(dict.get_avp(264, None).unwrap().name, "Origin-Host");
1326        assert_eq!(dict.get_avp(263, None).unwrap().name, "Session-Id");
1327        assert_eq!(dict.get_avp(1, None).unwrap().name, "User-Name");
1328        assert_eq!(dict.get_avp(258, None).unwrap().name, "Auth-Application-Id");
1329
1330        println!("Total AVP definitions {}", dict.avps.len());
1331
1332        assert_eq!(
1333            dict.get_application_id_by_name("Charging Control"),
1334            Some(ApplicationId::CreditControl)
1335        );
1336        assert_eq!(
1337            dict.get_command_code_by_name("Credit-Control"),
1338            Some(CommandCode::CreditControl)
1339        );
1340
1341        let timezone_offset_avp = dict.get_avp_by_name("Timezone-Offset").unwrap();
1342
1343        assert_eq!(timezone_offset_avp.code, 571);
1344        assert_eq!(timezone_offset_avp.vendor_id, Some(10415));
1345    }
1346
1347    #[test]
1348    fn test_add_avp() {
1349        let mut dict = Dictionary::new(&[&DEFAULT_DICT_XML]);
1350
1351        dict.add_avp(AvpDefinition {
1352            code: 602,
1353            vendor_id: Some(10415),
1354            avp_type: AvpType::UTF8String,
1355            name: "Server-Name".into(),
1356            m_flag: true,
1357        });
1358
1359        assert_eq!(dict.get_avp(602, Some(10415)).unwrap().name, "Server-Name");
1360    }
1361
1362    #[test]
1363    fn test_load_additional_xml() {
1364        let mut dict = DEFAULT_DICT.write().unwrap();
1365
1366        let xml = r#"
1367<diameter>
1368	<application id="16777302" type="auth" name="Diameter Sy">
1369		<!-- Diameter Credit Control Application -->
1370		<!-- http://tools.ietf.org/html/rfc4006 -->
1371
1372		<command code="8388635" short="SL" name="Spending-Limit">
1373			<request>
1374				<!-- http://tools.ietf.org/html/rfc4006#section-3.1 -->
1375				<rule avp="Session-Id" required="true" max="1"/>
1376				<rule avp="Auth-Application-Id" required="true" max="1"/>
1377				<rule avp="Origin-Host" required="true" max="1"/>
1378				<rule avp="Origin-Realm" required="true" max="1"/>
1379				<rule avp="Destination-Realm" required="true" max="1"/>
1380				<rule avp="SL-Request-Type" required="true" max="1"/>
1381				<rule avp="Destination-Host" required="false" max="1"/>
1382				<rule avp="Origin-State-Id" required="false" max="1"/>
1383				<rule avp="Subscription-Id" required="false" max="1"/>
1384				<rule avp="Policy-Counter-Identifier" required="false" max="1"/>
1385				<rule avp="Proxy-Info" required="false" max="1"/>
1386				<rule avp="Route-Record" required="false" max="1"/>
1387				<rule avp="Service-Information" required="false" max="1"/>
1388			</request>
1389			<answer>
1390				<!-- http://tools.ietf.org/html/rfc4006#section-3.2 -->
1391				<rule avp="Session-Id" required="true" max="1"/>
1392				<rule avp="Result-Code" required="true" max="1"/>
1393				<rule avp="Origin-Host" required="true" max="1"/>
1394				<rule avp="Origin-Realm" required="true" max="1"/>
1395				<rule avp="Origin-State-Id" required="false" max="1"/>
1396				<rule avp="Redirect-Host" required="false" max="1"/>
1397				<rule avp="Redirect-Host-Usage" required="false" max="1"/>
1398				<rule avp="Redirect-Max-Cache-Time" required="false" max="1"/>
1399				<rule avp="Proxy-Info" required="false" max="1"/>
1400				<rule avp="Route-Record" required="false" max="1"/>
1401				<rule avp="Failed-AVP" required="false" max="1"/>
1402			</answer>
1403		</command>
1404
1405		<avp name="SL-Request-Type" code="2904" must="M" may="P" must-not="V" may-encrypt="-">
1406			<data type="Enumerated">
1407				<item code="0" name="INITIAL_REQUEST"/>
1408				<item code="1" name="INTERMEDIATE_REQUEST"/>
1409			</data>
1410		</avp>
1411		
1412    </application>
1413</diameter>
1414    "#;
1415
1416        dict.load_xml(xml);
1417
1418        assert_eq!(
1419            dict.get_application_id_by_name("Diameter Sy"),
1420            Some(ApplicationId::Sy)
1421        );
1422        assert_eq!(
1423            dict.get_command_code_by_name("Spending-Limit"),
1424            Some(CommandCode::SpendingLimit)
1425        );
1426
1427        assert_eq!(dict.get_avp(2904, None).unwrap().name, "SL-Request-Type");
1428    }
1429}