1mod registration;
6pub use self::registration::RegistrationManager;
7
8mod messaging;
9pub use self::messaging::{MessageHelper, MessageWriter};
10
11mod invite;
12pub use self::invite::{InviteHelper, InviteWriter};
13
14use crate::{Header, Headers, Method, SipMessage, Uri};
15
16use std::{
17 collections::HashMap,
18 io::{Error as IoError, ErrorKind as IoErrorKind, Result as IoResult},
19};
20
21pub struct HeaderWriteConfig {
25 pub user_agent: Option<String>,
29 pub allowed_methods: Option<Vec<Method>>,
33}
34
35impl HeaderWriteConfig {
36 pub fn write_headers_vec(&self, m: &mut Vec<Header>) {
38 if let Some(agent) = &self.user_agent {
39 m.push(Header::UserAgent(agent.into()));
40 }
41 if let Some(allowed) = &self.allowed_methods {
42 m.push(Header::Allow(allowed.clone()));
43 }
44 }
45
46 pub fn write_headers(&self, m: &mut Headers) {
48 if let Some(agent) = &self.user_agent {
49 m.push(Header::UserAgent(agent.into()));
50 }
51 if let Some(allowed) = &self.allowed_methods {
52 m.push(Header::Allow(allowed.clone()));
53 }
54 }
55}
56
57impl Default for HeaderWriteConfig {
58 fn default() -> HeaderWriteConfig {
59 HeaderWriteConfig {
60 user_agent: Some(format!("libsip {}", env!("CARGO_PKG_VERSION"))),
61 allowed_methods: Some(vec![
62 Method::Invite,
63 Method::Cancel,
64 Method::Bye,
65 Method::Message,
66 ]),
67 }
68 }
69}
70
71pub struct SoftPhone {
76 header_cfg: HeaderWriteConfig,
79 msg: MessageWriter,
82 invite: InviteWriter,
85 reg: RegistrationManager,
87 calls: HashMap<String, InviteHelper>,
89}
90
91impl SoftPhone {
92 pub fn new(local_uri: Uri, account_uri: Uri) -> SoftPhone {
95 SoftPhone {
96 header_cfg: HeaderWriteConfig::default(),
97 msg: MessageWriter::new(account_uri.clone()),
98 invite: InviteWriter::new(account_uri.clone()),
99 reg: RegistrationManager::new(account_uri, local_uri),
100 calls: HashMap::new(),
101 }
102 }
103
104 pub fn registry(&self) -> &RegistrationManager {
106 &self.reg
107 }
108
109 pub fn registry_mut(&mut self) -> &mut RegistrationManager {
111 &mut self.reg
112 }
113
114 pub fn messaging(&self) -> &MessageWriter {
116 &self.msg
117 }
118
119 pub fn messaging_mut(&mut self) -> &mut MessageWriter {
121 &mut self.msg
122 }
123
124 pub fn invite(&self) -> &InviteWriter {
126 &self.invite
127 }
128
129 pub fn invite_mut(&mut self) -> &mut InviteWriter {
131 &mut self.invite
132 }
133
134 pub fn header_cfg(&self) -> &HeaderWriteConfig {
136 &self.header_cfg
137 }
138
139 pub fn header_cfg_mut(&mut self) -> &mut HeaderWriteConfig {
141 &mut self.header_cfg
142 }
143
144 pub fn get_register_request(&mut self) -> IoResult<SipMessage> {
146 Ok(self.reg.get_request(&self.header_cfg)?)
147 }
148
149 pub fn set_register_challenge(&mut self, c: SipMessage) -> IoResult<()> {
151 self.reg.set_challenge(c)?;
152 Ok(())
153 }
154
155 pub fn write_message(&mut self, b: Vec<u8>, uri: Uri) -> IoResult<SipMessage> {
157 Ok(self
158 .msg
159 .write_message(b, uri, self.reg.via_header(), &self.header_cfg)?)
160 }
161
162 pub fn send_invite(&mut self, body: Vec<u8>, uri: Uri) -> IoResult<SipMessage> {
164 self.invite.generate_invite(uri, body)
165 }
166
167 pub fn get_received_request(&mut self, msg: SipMessage) -> IoResult<SipMessage> {
170 let invite = InviteHelper::new(msg)?;
171 let call_id = invite.call_id()?;
172 let received = invite.ringing(&self.header_cfg)?;
173 self.calls.insert(call_id, invite);
174 Ok(received)
175 }
176
177 pub fn get_accept_request(&mut self, body: Vec<u8>, call: &str) -> IoResult<SipMessage> {
180 if let Some(invite) = self.calls.get_mut(call) {
181 Ok(invite.accept(body, &self.header_cfg)?)
182 } else {
183 Err(IoError::new(IoErrorKind::NotFound, "Call not found"))
184 }
185 }
186
187 pub fn get_bye_request(&mut self, call: &str) -> IoResult<SipMessage> {
190 if let Some(invite) = self.calls.get_mut(call) {
191 Ok(invite.bye(&self.header_cfg)?)
192 } else {
193 Err(IoError::new(IoErrorKind::NotFound, "Call not found"))
194 }
195 }
196
197 pub fn get_cancel_request(&mut self, call: &str) -> IoResult<(SipMessage, SipMessage)> {
199 if let Some(invite) = self.calls.get_mut(call) {
200 invite.cancel(&self.header_cfg)
201 } else {
202 Err(IoError::new(IoErrorKind::NotFound, "Call not found"))
203 }
204 }
205}