Skip to main content

active_call/useragent/
registration.rs

1use anyhow::Result;
2use rsip::{Response, StatusCodeKind};
3use rsipstack::{
4    dialog::{authenticate::Credential, registration::Registration},
5    rsip_ext::RsipResponseExt,
6};
7use serde::{Deserialize, Serialize};
8use std::{sync::Arc, time::Instant};
9use tokio::sync::Mutex;
10use tokio_util::sync::CancellationToken;
11use tracing::{debug, warn};
12
13#[derive(Debug, Deserialize, Clone, Serialize)]
14pub struct UserCredential {
15    pub username: String,
16    pub password: String,
17    pub realm: Option<String>,
18}
19
20#[derive(Debug, Deserialize, Clone, Serialize)]
21pub struct RegisterOption {
22    pub server: String,
23    pub username: String,
24    pub display_name: Option<String>,
25    pub disabled: Option<bool>,
26    pub credential: Option<UserCredential>,
27}
28
29impl From<UserCredential> for Credential {
30    fn from(val: UserCredential) -> Self {
31        Credential {
32            username: val.username,
33            password: val.password,
34            realm: val.realm,
35        }
36    }
37}
38
39impl RegisterOption {
40    pub fn aor(&self) -> String {
41        format!("{}@{}", self.username, self.server)
42    }
43}
44
45pub struct RegistrationHandleInner {
46    pub registration: Mutex<Registration>,
47    pub option: RegisterOption,
48    pub cancel_token: CancellationToken,
49    pub start_time: Mutex<Instant>,
50    pub last_update: Mutex<Instant>,
51    pub last_response: Mutex<Option<Response>>,
52}
53#[derive(Clone)]
54pub struct RegistrationHandle {
55    pub inner: Arc<RegistrationHandleInner>,
56}
57
58impl RegistrationHandle {
59    pub fn stop(&self) {
60        self.inner.cancel_token.cancel();
61    }
62
63    pub async fn do_register(&self, sip_server: &rsip::Uri, expires: Option<u32>) -> Result<u32> {
64        let mut registration = self.inner.registration.lock().await;
65        let resp = match registration
66            .register(sip_server.clone(), expires)
67            .await
68            .map_err(|e| anyhow::anyhow!("Registration failed: {}", e))
69        {
70            Ok(resp) => resp,
71            Err(e) => {
72                warn!("registration failed: {}", e);
73                return Err(anyhow::anyhow!("Registration failed: {}", e));
74            }
75        };
76
77        debug!(
78            user = self.inner.option.aor(),
79            "registration response: {:?}", resp
80        );
81        match resp.status_code().kind() {
82            StatusCodeKind::Successful => {
83                *self.inner.last_update.lock().await = Instant::now();
84                *self.inner.last_response.lock().await = Some(resp);
85                Ok(registration.expires())
86            }
87            _ => Err(anyhow::anyhow!("{:?}", resp.reason_phrase())),
88        }
89    }
90}