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