blob: 0bf6432f2953c1fa7874e4230c49cfc262970f96 [file] [log] [blame]
Adrien BĂ©raud612b55b2023-05-29 10:42:04 -04001/*
2 * Copyright (C) 2004-2023 Savoir-faire Linux Inc.
3 *
4 * Author: Guillaume Roguez <guillaume.roguez@savoirfairelinux.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20
21#pragma once
22
23#include "ice_options.h"
24#include "ice_socket.h"
25#include "ip_utils.h"
26
27#include <pjnath.h>
28#include <pjlib.h>
29#include <pjlib-util.h>
30
31#include <functional>
32#include <memory>
33#include <msgpack.hpp>
34#include <vector>
35
36namespace dht {
37namespace log {
38class Logger;
39}
40}
41
42namespace jami {
43
44using Logger = dht::log::Logger;
45
46namespace upnp {
47class Controller;
48}
49
50class IceTransport;
51
52using IceRecvCb = std::function<ssize_t(unsigned char* buf, size_t len)>;
53using IceCandidate = pj_ice_sess_cand;
54using onShutdownCb = std::function<void(void)>;
55
56struct ICESDP
57{
58 std::vector<IceCandidate> rem_candidates;
59 std::string rem_ufrag;
60 std::string rem_pwd;
61};
62
63struct SDP
64{
65 std::string ufrag;
66 std::string pwd;
67
68 std::vector<std::string> candidates;
69 MSGPACK_DEFINE(ufrag, pwd, candidates)
70};
71
72class IceTransport
73{
74public:
75 using Attribute = struct
76 {
77 std::string ufrag;
78 std::string pwd;
79 };
80
81 /**
82 * Constructor
83 */
84 IceTransport(std::string_view name);
85 ~IceTransport();
86
87 const std::shared_ptr<Logger>& logger() const;
88
89 void initIceInstance(const IceTransportOptions& options);
90
91 /**
92 * Get current state
93 */
94 bool isInitiator() const;
95
96 /**
97 * Start transport negotiation between local candidates and given remote
98 * to find the right candidate pair.
99 * This function doesn't block, the callback on_negodone_cb will be called
100 * with the negotiation result when operation is really done.
101 * Return false if negotiation cannot be started else true.
102 */
103 bool startIce(const Attribute& rem_attrs, std::vector<IceCandidate>&& rem_candidates);
104 bool startIce(const SDP& sdp);
105
106 /**
107 * Cancel operations
108 */
109 void cancelOperations();
110
111 /**
112 * Returns true if ICE transport has been initialized
113 * [mutex protected]
114 */
115 bool isInitialized() const;
116
117 /**
118 * Returns true if ICE negotiation has been started
119 * [mutex protected]
120 */
121 bool isStarted() const;
122
123 /**
124 * Returns true if ICE negotiation has completed with success
125 * [mutex protected]
126 */
127 bool isRunning() const;
128
129 /**
130 * Returns true if ICE transport is in failure state
131 * [mutex protected]
132 */
133 bool isFailed() const;
134
135 IpAddr getLocalAddress(unsigned comp_id) const;
136
137 IpAddr getRemoteAddress(unsigned comp_id) const;
138
139 IpAddr getDefaultLocalAddress() const { return getLocalAddress(1); }
140
141 /**
142 * Return ICE session attributes
143 */
144 const Attribute getLocalAttributes() const;
145
146 /**
147 * Return ICE session attributes
148 */
149 std::vector<std::string> getLocalCandidates(unsigned comp_id) const;
150
151 /**
152 * Return ICE session attributes
153 */
154 std::vector<std::string> getLocalCandidates(unsigned streamIdx, unsigned compId) const;
155
156 bool parseIceAttributeLine(unsigned streamIdx,
157 const std::string& line,
158 IceCandidate& cand) const;
159
160 bool getCandidateFromSDP(const std::string& line, IceCandidate& cand) const;
161
162 // I/O methods
163
164 void setOnRecv(unsigned comp_id, IceRecvCb cb);
165 void setOnShutdown(onShutdownCb&& cb);
166
167 ssize_t recv(unsigned comp_id, unsigned char* buf, size_t len, std::error_code& ec);
168 ssize_t recvfrom(unsigned comp_id, char* buf, size_t len, std::error_code& ec);
169
170 ssize_t send(unsigned comp_id, const unsigned char* buf, size_t len);
171
172 bool waitForInitialization(std::chrono::milliseconds timeout);
173
174 int waitForNegotiation(std::chrono::milliseconds timeout);
175
176 ssize_t waitForData(unsigned comp_id, std::chrono::milliseconds timeout, std::error_code& ec);
177
178 unsigned getComponentCount() const;
179
180 // Set session state
181 bool setSlaveSession();
182 bool setInitiatorSession();
183
184 bool isTCPEnabled();
185
186 ICESDP parseIceCandidates(std::string_view sdp_msg);
187
188 void setDefaultRemoteAddress(unsigned comp_id, const IpAddr& addr);
189
190 std::string link() const;
191
192private:
193 class Impl;
194 std::unique_ptr<Impl> pimpl_;
195};
196
197class IceTransportFactory
198{
199public:
200 IceTransportFactory();
201 ~IceTransportFactory();
202
203 std::shared_ptr<IceTransport> createTransport(std::string_view name);
204
205 std::unique_ptr<IceTransport> createUTransport(std::string_view name);
206
207 /**
208 * PJSIP specifics
209 */
210 pj_ice_strans_cfg getIceCfg() const { return ice_cfg_; }
211 pj_pool_factory* getPoolFactory() { return &cp_->factory; }
212 std::shared_ptr<pj_caching_pool> getPoolCaching() { return cp_; }
213
214private:
215 std::shared_ptr<pj_caching_pool> cp_;
216 pj_ice_strans_cfg ice_cfg_;
217};
218
219}; // namespace jami