active_call/useragent/
registration.rs1use 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}