Line data Source code
1 : /*
2 : * Copyright (C) 2004-2026 Savoir-faire Linux Inc.
3 : *
4 : * This program is free software: you can redistribute it and/or modify
5 : * it under the terms of the GNU General Public License as published by
6 : * the Free Software Foundation, either version 3 of the License, or
7 : * (at your option) any later version.
8 : *
9 : * This program is distributed in the hope that it will be useful,
10 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 : * GNU General Public License for more details.
13 : *
14 : * You should have received a copy of the GNU General Public License
15 : * along with this program. If not, see <https://www.gnu.org/licenses/>.
16 : */
17 : #pragma once
18 :
19 : #ifdef HAVE_CONFIG_H
20 : #include "config.h"
21 : #endif
22 :
23 : #include "noncopyable.h"
24 :
25 : #include <dhtnet/ip_utils.h>
26 :
27 : #include "connectivity/sip_utils.h"
28 : #include <pjsip.h>
29 : #include <pjlib.h>
30 : #include <pjsip_ua.h>
31 : #include <pjlib-util.h>
32 : #include <pjnath.h>
33 : #include <pjnath/stun_config.h>
34 :
35 : #include <memory>
36 : #include <functional>
37 : #include <thread>
38 : #include <atomic>
39 :
40 : namespace jami {
41 :
42 : class SIPCall;
43 : class SIPAccountBase;
44 : class SIPVoIPLink;
45 : class SipTransportBroker;
46 :
47 : /**
48 : * @file sipvoiplink.h
49 : * @brief Specific VoIPLink for SIP (SIP core for incoming and outgoing events).
50 : */
51 :
52 : class SIPVoIPLink
53 : {
54 : public:
55 : SIPVoIPLink();
56 : ~SIPVoIPLink();
57 :
58 : /**
59 : * Destroy structures
60 : */
61 : void shutdown();
62 :
63 : /**
64 : * Event listener. Each event send by the call manager is received and handled from here
65 : */
66 : void handleEvents();
67 :
68 : /**
69 : * Register a new keepalive registration timer to this endpoint
70 : */
71 : void registerKeepAliveTimer(pj_timer_entry& timer, pj_time_val& delay);
72 :
73 : /**
74 : * Abort currently registered timer
75 : */
76 : void cancelKeepAliveTimer(pj_timer_entry& timer);
77 :
78 : /**
79 : * Get the memory pool factory since each calls has its own memory pool
80 : */
81 : pj_caching_pool* getMemoryPoolFactory();
82 :
83 : /**
84 : * Create the default UDP transport according ot Ip2Ip profile settings
85 : */
86 : void createDefaultSipUdpTransport();
87 :
88 : public:
89 : static void createSDPOffer(pjsip_inv_session* inv);
90 :
91 : /**
92 : * Instance that maintain and manage transport (UDP, TLS)
93 : */
94 : std::unique_ptr<SipTransportBroker> sipTransportBroker;
95 :
96 : typedef std::function<void(std::vector<dhtnet::IpAddr>)> SrvResolveCallback;
97 : void resolveSrvName(const std::string& name, pjsip_transport_type_e type, SrvResolveCallback&& cb);
98 :
99 : /**
100 : * Guess the account related to an incoming SIP call.
101 : */
102 : std::shared_ptr<SIPAccountBase> guessAccount(std::string_view userName,
103 : std::string_view server,
104 : std::string_view fromUri) const;
105 :
106 : int getModId();
107 : pjsip_endpoint* getEndpoint();
108 : pjsip_module* getMod();
109 :
110 : pj_caching_pool* getCachingPool() noexcept;
111 : pj_pool_t* getPool() noexcept;
112 :
113 : /**
114 : * Get the correct address to use (ie advertised) from
115 : * a uri. The corresponding transport that should be used
116 : * with that uri will be discovered.
117 : *
118 : * @param uri The uri from which we want to discover the address to use
119 : * @param transport The transport to use to discover the address
120 : */
121 : void findLocalAddressFromTransport(pjsip_transport* transport,
122 : pjsip_transport_type_e transportType,
123 : const std::string& host,
124 : std::string& address,
125 : pj_uint16_t& port) const;
126 :
127 : bool findLocalAddressFromSTUN(pjsip_transport* transport,
128 : pj_str_t* stunServerName,
129 : int stunPort,
130 : std::string& address,
131 : pj_uint16_t& port) const;
132 :
133 : /**
134 : * Initialize the transport selector
135 : * @param transport A transport associated with an account
136 : * @return A transport selector structure
137 : */
138 146 : static inline pjsip_tpselector getTransportSelector(pjsip_transport* transport)
139 : {
140 : pjsip_tpselector tp;
141 146 : tp.type = PJSIP_TPSELECTOR_TRANSPORT;
142 146 : tp.u.transport = transport;
143 146 : return tp;
144 : }
145 :
146 : private:
147 : NON_COPYABLE(SIPVoIPLink);
148 :
149 : mutable pj_caching_pool cp_;
150 : sip_utils::PoolPtr pool_;
151 : std::atomic_bool running_ {true};
152 : std::thread sipThread_;
153 :
154 : friend class SIPTest;
155 : };
156 :
157 : } // namespace jami
|