libsip/client/
mod.rs

1//! The client module contains all of the code for
2//! processing and generating SIP requests. Encapsulating
3//! all this functionality is the SoftPhone struct.
4
5mod 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
21/// This struct is used in the client module when creating sip messages
22/// it is used to specify some common values for the generated sip
23/// headers.
24pub struct HeaderWriteConfig {
25    /// The Value to set for the User Agent header.
26    /// By default this is set to libsip {version},
27    /// Set to None to disable adding a User Agent header.
28    pub user_agent: Option<String>,
29    /// The value for the Allowed Methods Header.
30    /// By default set to Invite, Cancel, Bye, Message.
31    /// Set to None to disable adding header.
32    pub allowed_methods: Option<Vec<Method>>,
33}
34
35impl HeaderWriteConfig {
36    /// Write configured headers into the provided Vec.
37    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    /// Write configured headers into the provided Headers Map.
47    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
71/// Simple SIP client for implementing softphones.
72/// Currently the only thing implemented is registration
73/// and sending text messages. The only other feature planned
74/// is an interface for sending & receiving calls.
75pub struct SoftPhone {
76    /// Header Configuration Used when adding default
77    /// headers on generated SIP messages.
78    header_cfg: HeaderWriteConfig,
79    /// Message writer instance used when generating
80    /// a SIP message.
81    msg: MessageWriter,
82    /// Invitation writer instance used when generating,
83    /// a SIP call.
84    invite: InviteWriter,
85    /// Registration manage instance.
86    reg: RegistrationManager,
87    /// List of ongoing calls.
88    calls: HashMap<String, InviteHelper>,
89}
90
91impl SoftPhone {
92    /// Create a new SoftPhone client. `local_uri` is the SipUri that you listen on
93    /// and `account_uri` is the uri of your SIP user account.
94    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    /// Return a reference to the sip registration manager.
105    pub fn registry(&self) -> &RegistrationManager {
106        &self.reg
107    }
108
109    /// Return a mutable reference tp the sip registration manager.
110    pub fn registry_mut(&mut self) -> &mut RegistrationManager {
111        &mut self.reg
112    }
113
114    /// Return a reference to the message writer.
115    pub fn messaging(&self) -> &MessageWriter {
116        &self.msg
117    }
118
119    /// Return a mutable reference to the MessageWriter.
120    pub fn messaging_mut(&mut self) -> &mut MessageWriter {
121        &mut self.msg
122    }
123
124    /// Return a reference to the invite writer.
125    pub fn invite(&self) -> &InviteWriter {
126        &self.invite
127    }
128
129    /// Return a mutable reference to the InviteWriter.
130    pub fn invite_mut(&mut self) -> &mut InviteWriter {
131        &mut self.invite
132    }
133
134    /// Return a reference to the used HeaderWriteConfig.
135    pub fn header_cfg(&self) -> &HeaderWriteConfig {
136        &self.header_cfg
137    }
138
139    /// Return a mutable reference to the used HeaderWriteConfig.
140    pub fn header_cfg_mut(&mut self) -> &mut HeaderWriteConfig {
141        &mut self.header_cfg
142    }
143
144    /// Simple pass through method to get a registration request.
145    pub fn get_register_request(&mut self) -> IoResult<SipMessage> {
146        Ok(self.reg.get_request(&self.header_cfg)?)
147    }
148
149    /// Set the received auth challenge request.
150    pub fn set_register_challenge(&mut self, c: SipMessage) -> IoResult<()> {
151        self.reg.set_challenge(c)?;
152        Ok(())
153    }
154
155    /// Send a new Message to `uri`.
156    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    /// Send a new Invite Request to `uri`.
163    pub fn send_invite(&mut self, body: Vec<u8>, uri: Uri) -> IoResult<SipMessage> {
164        self.invite.generate_invite(uri, body)
165    }
166
167    /// Give the softphone a received call, returns the
168    /// ringing response to be sent.
169    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    /// Get a SIP Message that will accept a previously
178    /// recieved invitation.
179    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    /// Get a SIP message that will close a previously
188    /// received invitation.
189    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    /// Get the messages required to cancel a invitation.
198    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}