rust_rcs_client/connection/
p_cscf_connection_config.rs1use std::net::{IpAddr, Ipv4Addr};
16
17use rust_rcs_core::{
18 dns::DnsConfig,
19 ffi::net_ctrl::{get_active_network_info, get_dns_info, get_dns_servers, get_network_type},
20};
21
22use crate::provisioning::ims_application::{ImsApplication, SignallingProtocol, TransportProto};
23
24pub enum ServiceType {
25 SipD2U,
26 SipD2T,
27 SipsD2T,
28}
29
30impl ServiceType {
31 pub fn get_string_repr(&self) -> String {
32 match self {
33 ServiceType::SipD2U => String::from("SIP+D2U"),
34
35 ServiceType::SipD2T => String::from("SIP+D2T"),
36
37 ServiceType::SipsD2T => String::from("SIPS+D2T"),
38 }
39 }
40}
41
42pub struct PCscfConnectionConfig {
43 p: usize,
44 p_cscf_addresses: Vec<(String, String)>,
45 transport_proto: TransportProto,
46}
47
48impl PCscfConnectionConfig {
49 pub fn new() -> PCscfConnectionConfig {
50 PCscfConnectionConfig {
51 p: 0,
52 p_cscf_addresses: Vec::new(),
53 transport_proto: TransportProto::create_default(),
54 }
55 }
56
57 pub fn update_configuration(&mut self, ims_app: &ImsApplication) {
58 let mut p_cscf_addresses = Vec::new();
59
60 for (address, address_type) in ims_app.get_lbo_p_cscf_addresses() {
61 p_cscf_addresses.push((String::from(address), String::from(address_type)));
62 }
63
64 let mut transport_proto = TransportProto::create_default();
65 if let Some(gsma_ext) = ims_app.get_ims_gsma_extension() {
66 if let Some(proto) = gsma_ext.get_info().get_transport_proto_info() {
67 transport_proto = proto;
68 }
69 }
70
71 self.p = 0;
72 self.p_cscf_addresses = p_cscf_addresses;
73 self.transport_proto = transport_proto;
74 }
75
76 pub fn get_next(
77 &mut self,
78 ) -> Option<(
79 DnsConfig,
80 ServiceType,
81 String,
82 Option<String>,
83 Option<IpAddr>,
84 Option<u16>,
85 )> {
86 if let Some(network_info) = get_active_network_info() {
87 let network_type = get_network_type(&network_info);
88
89 let dns_info = get_dns_info(&network_info);
90
91 if let Some(dns_info) = dns_info {
92 let dns_servers = get_dns_servers(&dns_info);
93
94 let dns_config = DnsConfig {
95 server_addrs: dns_servers,
96 };
97
98 if self.p_cscf_addresses.len() > 0 {
99 self.p = if self.p_cscf_addresses.len() > 1 {
100 self.p % self.p_cscf_addresses.len()
101 } else {
102 0
103 };
104 let p_cscf_address = self.p_cscf_addresses.get(self.p);
105 self.p += 1;
106 if let Some((address, address_type)) = p_cscf_address {
107 let proto = if network_type == 2 {
108 &self.transport_proto.ps_signalling
109 } else if network_type == 3 {
110 &self.transport_proto.ps_signalling_roaming
111 } else {
112 &self.transport_proto.wifi_signalling
113 };
114
115 let mut host: Option<String> = None;
116 let mut addr: Option<IpAddr> = None;
117 let mut port: Option<u16> = None;
118 if address_type == "FQDN" {
119 host = Some(String::from(address));
120 } else if address_type == "IPv4" {
121 if let Some(idx) = address.find(':') {
122 let v4_addr = &address[..idx];
123 let v4_port = &address[idx + 1..];
124 let v4_addr: Result<Ipv4Addr, _> = v4_addr.parse();
125 if let Ok(v4_addr) = v4_addr {
126 addr = Some(IpAddr::V4(v4_addr));
127 } else {
128 return self.get_next();
129 }
130 let v4_port: Result<u16, _> = v4_port.parse();
131 if let Ok(v4_port) = v4_port {
132 port = Some(v4_port);
133 } else {
134 return self.get_next();
135 }
136 } else {
137 let v4_addr: Result<Ipv4Addr, _> = address.parse();
138 if let Ok(v4_addr) = v4_addr {
139 addr = Some(IpAddr::V4(v4_addr));
140 } else {
141 return self.get_next();
142 }
143 }
144 } else {
145 return self.get_next();
146 }
147
148 let service_type = match proto {
149 SignallingProtocol::SIPoUDP => ServiceType::SipD2U,
150
151 SignallingProtocol::SIPoTCP => ServiceType::SipD2T,
152
153 SignallingProtocol::SIPoTLS => ServiceType::SipsD2T,
154 };
155
156 return Some((
157 dns_config,
158 service_type,
159 String::from(address),
160 host,
161 addr,
162 port,
163 ));
164 }
165 }
166 }
167 }
168
169 None
170 }
171}