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