mod registration;
pub use self::registration::RegistrationManager;
mod messaging;
pub use self::messaging::{MessageHelper, MessageWriter};
mod invite;
pub use self::invite::{InviteHelper, InviteWriter};
use crate::{Header, Headers, Method, SipMessage, Uri};
use std::{
collections::HashMap,
io::{Error as IoError, ErrorKind as IoErrorKind, Result as IoResult},
};
pub struct HeaderWriteConfig {
pub user_agent: Option<String>,
pub allowed_methods: Option<Vec<Method>>,
}
impl HeaderWriteConfig {
pub fn write_headers_vec(&self, m: &mut Vec<Header>) {
if let Some(agent) = &self.user_agent {
m.push(Header::UserAgent(agent.into()));
}
if let Some(allowed) = &self.allowed_methods {
m.push(Header::Allow(allowed.clone()));
}
}
pub fn write_headers(&self, m: &mut Headers) {
if let Some(agent) = &self.user_agent {
m.push(Header::UserAgent(agent.into()));
}
if let Some(allowed) = &self.allowed_methods {
m.push(Header::Allow(allowed.clone()));
}
}
}
impl Default for HeaderWriteConfig {
fn default() -> HeaderWriteConfig {
HeaderWriteConfig {
user_agent: Some(format!("libsip {}", env!("CARGO_PKG_VERSION"))),
allowed_methods: Some(vec![
Method::Invite,
Method::Cancel,
Method::Bye,
Method::Message,
]),
}
}
}
pub struct SoftPhone {
header_cfg: HeaderWriteConfig,
msg: MessageWriter,
invite: InviteWriter,
reg: RegistrationManager,
calls: HashMap<String, InviteHelper>,
}
impl SoftPhone {
pub fn new(local_uri: Uri, account_uri: Uri) -> SoftPhone {
SoftPhone {
header_cfg: HeaderWriteConfig::default(),
msg: MessageWriter::new(account_uri.clone()),
invite: InviteWriter::new(account_uri.clone()),
reg: RegistrationManager::new(account_uri, local_uri),
calls: HashMap::new(),
}
}
pub fn registry(&self) -> &RegistrationManager {
&self.reg
}
pub fn registry_mut(&mut self) -> &mut RegistrationManager {
&mut self.reg
}
pub fn messaging(&self) -> &MessageWriter {
&self.msg
}
pub fn messaging_mut(&mut self) -> &mut MessageWriter {
&mut self.msg
}
pub fn invite(&self) -> &InviteWriter {
&self.invite
}
pub fn invite_mut(&mut self) -> &mut InviteWriter {
&mut self.invite
}
pub fn header_cfg(&self) -> &HeaderWriteConfig {
&self.header_cfg
}
pub fn header_cfg_mut(&mut self) -> &mut HeaderWriteConfig {
&mut self.header_cfg
}
pub fn get_register_request(&mut self) -> IoResult<SipMessage> {
Ok(self.reg.get_request(&self.header_cfg)?)
}
pub fn set_register_challenge(&mut self, c: SipMessage) -> IoResult<()> {
self.reg.set_challenge(c)?;
Ok(())
}
pub fn write_message(&mut self, b: Vec<u8>, uri: Uri) -> IoResult<SipMessage> {
Ok(self
.msg
.write_message(b, uri, self.reg.via_header(), &self.header_cfg)?)
}
pub fn send_invite(&mut self, body: Vec<u8>, uri: Uri) -> IoResult<SipMessage> {
self.invite.generate_invite(uri, body)
}
pub fn get_received_request(&mut self, msg: SipMessage) -> IoResult<SipMessage> {
let invite = InviteHelper::new(msg)?;
let call_id = invite.call_id()?;
let received = invite.ringing(&self.header_cfg)?;
self.calls.insert(call_id, invite);
Ok(received)
}
pub fn get_accept_request(&mut self, body: Vec<u8>, call: &str) -> IoResult<SipMessage> {
if let Some(invite) = self.calls.get_mut(call) {
Ok(invite.accept(body, &self.header_cfg)?)
} else {
Err(IoError::new(IoErrorKind::NotFound, "Call not found"))
}
}
pub fn get_bye_request(&mut self, call: &str) -> IoResult<SipMessage> {
if let Some(invite) = self.calls.get_mut(call) {
Ok(invite.bye(&self.header_cfg)?)
} else {
Err(IoError::new(IoErrorKind::NotFound, "Call not found"))
}
}
pub fn get_cancel_request(&mut self, call: &str) -> IoResult<(SipMessage, SipMessage)> {
if let Some(invite) = self.calls.get_mut(call) {
invite.cancel(&self.header_cfg)
} else {
Err(IoError::new(IoErrorKind::NotFound, "Call not found"))
}
}
}