Rabbit Remote Control 0.0.30
Loading...
Searching...
No Matches
ChannelIce.cpp
1
2
3#include "ChannelIce.h"
4#include "rtc/rtc.hpp"
5#include <QThread>
6
8
9QLoggingCategory CLibDataChannelLogCallback::m_Log = QLoggingCategory("Channel.ICE.LibDataChannel");
10CLibDataChannelLogCallback::CLibDataChannelLogCallback(QObject *parent)
11 : QObject(parent)
12{
13 rtc::InitLogger(rtc::LogLevel::Debug, logCallback);
14}
15
16void CLibDataChannelLogCallback::slotEnable(bool enable)
17{
18 m_bEnable = enable;
19}
20
21void CLibDataChannelLogCallback::logCallback(rtc::LogLevel level, std::string message)
22{
23 if(!m_bEnable) return;
24 switch (level) {
25 case rtc::LogLevel::Verbose:
26 case rtc::LogLevel::Debug:
27 qDebug(m_Log) << message.c_str();
28 break;
29 case rtc::LogLevel::Info:
30 qInfo(m_Log) << message.c_str();
31 break;
32 case rtc::LogLevel::Warning:
33 qWarning(m_Log) << message.c_str();
34 break;
35 case rtc::LogLevel::Error:
36 case rtc::LogLevel::Fatal:
37 qCritical(m_Log) << message.c_str();
38 break;
39 case rtc::LogLevel::None:
40 break;
41 }
42}
43
44bool CLibDataChannelLogCallback::m_bEnable = true;
45// Set libdatachannel log callback function
46CLibDataChannelLogCallback g_LogCallback;
48
49CChannelIce::CChannelIce(QObject* parent) : CChannel(parent),
50 m_Log("Channel.ICE")
51{}
52
53CChannelIce::CChannelIce(CIceSignal* pSignal, QObject *parent)
54 : CChannel(parent),
55 m_pSignal(pSignal),
56 m_Log("Channel.ICE")
57{
58 SetSignal(pSignal);
59}
60
61CChannelIce::~CChannelIce()
62{
63 qDebug(m_Log) << "CChannelIce::~CChannelIce()";
64}
65
66int CChannelIce::SetSignal(CIceSignal *signal)
67{
68 bool check = false;
69 m_pSignal = signal;
70 if(m_pSignal)
71 {
72 check = connect(m_pSignal, SIGNAL(sigConnected()),
73 this, SLOT(slotSignalConnected()));
74 Q_ASSERT(check);
75 check = connect(m_pSignal, SIGNAL(sigDisconnected()),
76 this, SLOT(slotSignalDisconnected()));
77 Q_ASSERT(check);
78 check = connect(m_pSignal,
79 SIGNAL(sigDescription(const QString&,
80 const QString&,
81 const QString&,
82 const QString&,
83 const QString&)),
84 this,
85 SLOT(slotSignalReceiverDescription(const QString&,
86 const QString&,
87 const QString&,
88 const QString&,
89 const QString&)));
90 Q_ASSERT(check);
91 check = connect(m_pSignal,
92 SIGNAL(sigCandidate(const QString&,
93 const QString&,
94 const QString&,
95 const QString&,
96 const QString&)),
97 this,
98 SLOT(slotSignalReceiverCandidate(const QString&,
99 const QString&,
100 const QString&,
101 const QString&,
102 const QString&)));
103 Q_ASSERT(check);
104 check = connect(m_pSignal, SIGNAL(sigError(int, const QString&)),
105 this, SLOT(slotSignalError(int, const QString&)));
106 Q_ASSERT(check);
107 }
108 return 0;
109}
110
111QString CChannelIce::GetUser()
112{
113 return m_szUser;
114}
115
116QString CChannelIce::GetPeerUser()
117{
118 return m_szPeerUser;
119}
120
121QString CChannelIce::GetChannelId()
122{
123 return m_szChannelId;
124}
125
126int CChannelIce::SetConfigure(const rtc::Configuration &config)
127{
128 m_Config = config;
129 return 0;
130}
131
132int CChannelIce::SetDataChannel(std::shared_ptr<rtc::DataChannel> dc)
133{
134 //qDebug(m_Log) << "onDataChannel: DataCannel label:" << dc->label().c_str();
135 Q_ASSERT(dc);
136 if(!dc) return -1;
137
138 m_dataChannel = dc;
139
140 dc->onOpen([this]() {
141 qInfo(m_Log) << "Open data channel user:" << GetUser()
142 << ";peer:" << GetPeerUser()
143 << ";channelId:" << GetChannelId()
144 << ";label:" << m_dataChannel->label().c_str();
145 if(QIODevice::open(QIODevice::ReadWrite))
146 emit sigConnected();
147 else
148 qInfo(m_Log) << "Open Device fail:user:" << GetUser()
149 << ";peer:" << GetPeerUser()
150 << ";channelId:" << GetChannelId()
151 << ";label:" << m_dataChannel->label().c_str();
152 });
153
154 dc->onClosed([this]() {
155 qInfo(m_Log) << "Close data channel user:" << GetUser()
156 << ";peer:" << GetPeerUser()
157 << ";channelId:" << GetChannelId()
158 << ";label:" << m_dataChannel->label().c_str();
159 emit sigDisconnected();
160 });
161
162 dc->onError([this](std::string error){
163 qInfo(m_Log) << "Data channel error:" << error.c_str();
164 emit sigError(-1, error.c_str());
165 });
166
167 dc->onMessage([dc, this](std::variant<rtc::binary, std::string> data) {
168 /*
169 if (std::holds_alternative<std::string>(data))
170 qDebug(m_Log) << "From remote data:"
171 << std::get<std::string>(data).c_str();
172 else
173 qDebug(m_Log) << "From remote Received, size="
174 << std::get<rtc::binary>(data).size(); //*/
175 m_MutexData.lock();
176 rtc::binary d = std::get<rtc::binary>(data);
177 m_data.append((char*)d.data(), d.size());
178 m_MutexData.unlock();
179 emit this->readyRead();
180 });
181
182 return 0;
183}
184
185int CChannelIce::CreateDataChannel(bool bDataChannel)
186{
187 m_peerConnection = std::make_shared<rtc::PeerConnection>(m_Config);
188 if(!m_peerConnection)
189 {
190 qDebug(m_Log) << "Peer connect don't open";
191 return -1;
192 }
193 m_peerConnection->onStateChange([this](rtc::PeerConnection::State state) {
194 qDebug(m_Log) << "PeerConnection State:" << (int)state;
195 });
196 m_peerConnection->onGatheringStateChange(
197 [this](rtc::PeerConnection::GatheringState state) {
198 Q_UNUSED(state)
199 qDebug(m_Log) << "Gathering status:" << (int)state;
200 });
201 m_peerConnection->onLocalDescription(
202 [this](rtc::Description description) {
203 //qDebug(m_Log) << "The thread id:" << QThread::currentThreadId();
204 /*
205 qDebug(m_Log) << "user:" << GetUser()
206 << "peer:" << GetPeerUser()
207 << "channel:" << GetChannelId()
208 << "onLocalDescription:"
209 << std::string(description).c_str());//*/
210 // Send to the peer through the signal channel
211 if(m_szPeerUser.isEmpty() || m_szChannelId.isEmpty())
212 {
213 qCritical(m_Log) << "Please set peer user and channel id";
214 return;
215 }
216 m_pSignal->SendDescription(GetPeerUser(), GetChannelId(), description, GetUser());
217 });
218 m_peerConnection->onLocalCandidate(
219 [this](rtc::Candidate candidate){
220 //qDebug(m_Log) << "The thread id:" << QThread::currentThreadId();
221 /*
222 qDebug(m_Log) << "user:" << GetUser()
223 << "peer:" << GetPeerUser()
224 << "channel:" << GetChannelId()
225 << "onLocalCandidate:" << std::string(candidate).c_str()
226 << "mid:" << candidate.mid().c_str();//*/
227 // Send to the peer through the signal channel
228 if(m_szPeerUser.isEmpty() || m_szChannelId.isEmpty())
229 {
230 qDebug(m_Log) << "Please set peer user and channel id";
231 return;
232 }
233 m_pSignal->SendCandidate(m_szPeerUser, m_szChannelId, candidate);
234 });
235 m_peerConnection->onDataChannel([this](std::shared_ptr<rtc::DataChannel> dc) {
236 qInfo(m_Log) << "Open data channel:" << dc->label().c_str();
237 if(dc->label().c_str() != GetChannelId())
238 {
239 qDebug(m_Log) << "Channel label different:" << GetChannelId()
240 << dc->label().c_str();
241 return;
242 }
243
244 SetDataChannel(dc);
245 });
246
247 if(bDataChannel)
248 {
249 auto dc = m_peerConnection->createDataChannel(GetChannelId().toStdString());
250 SetDataChannel(dc);
251 }
252 return 0;
253}
254
255bool CChannelIce::open(const QString &user, const QString &peer, bool bChannelId)
256{
257 bool bRet = false;
258 m_szPeerUser = peer;
259 m_szUser = user;
260 if(bChannelId)
261 m_szChannelId = GenerateID("c_");
262 int nRet = CreateDataChannel(bChannelId);
263 if(nRet) return false;
264 return true;
265}
266
267bool CChannelIce::open(const QString &fromUser, const QString &toUser,
268 const QString &channelId, const QString &type,
269 const QString &sdp)
270{
271 m_szChannelId = channelId;
272 if(!open(toUser, fromUser, false))
273 return false;
274 slotSignalReceiverDescription(fromUser, toUser, channelId, type, sdp);
275 return true;
276}
277
278void CChannelIce::close()
279{
280 qDebug(m_Log) << "CChannelIce::Close()";
281
282 m_pSignal->disconnect(this);
283
284 if(m_dataChannel)
285 {
286 m_dataChannel->close();
287 m_dataChannel.reset();
288 }
289 if(m_peerConnection)
290 {
291 m_peerConnection->close();
292 m_peerConnection.reset();
293 }
294
295 CChannel::close();
296 return;
297}
298
299#define DEFAULT_MAX_MESSAGE_SIZE 0x7FFF
300qint64 CChannelIce::writeData(const char *data, qint64 len)
301{
302 if(!m_dataChannel)
303 {
304 qDebug(m_Log) << "m_dataChannel is nullptr";
305 return -1;
306 }
307
308 if(m_dataChannel->isClosed())
309 {
310 qDebug(m_Log) << "m_dataChannel->isClosed():peer:" << GetPeerUser()
311 << "channel:" << GetChannelId();
312 return -2;
313 }
314
315 if(!isOpen())
316 {
317 qCritical(m_Log) << "The data channel isn't open";
318 return -3;
319 }
320
321 bool bSend = false;
322
323 if(0 == len)
324 {
325 qWarning(m_Log) << "WriteData len is zero";
326 return 0;
327 }
328 qint64 n = len;
329 while(n > DEFAULT_MAX_MESSAGE_SIZE)
330 {
331 bSend = m_dataChannel->send((const std::byte*)data, DEFAULT_MAX_MESSAGE_SIZE);
332 if(!bSend)
333 {
334 qCritical(m_Log) << "Send fail. len:" << len << "n:" << n;
335 return -4;
336 }
337 n -= DEFAULT_MAX_MESSAGE_SIZE;
338 }
339 if(n > 0)
340 {
341 bSend = m_dataChannel->send((const std::byte*)data, n);
342 if(bSend) return len;
343 }
344 qCritical(m_Log) << "Send fail. Len:" << len << "n:" << n;
345 return -5;
346}
347
348qint64 CChannelIce::readData(char *data, qint64 maxlen)
349{
350 if(!m_dataChannel || m_dataChannel->isClosed() || !isOpen()) return -1;
351
352 QMutexLocker lock(&m_MutexData);
353
354 if(m_data.size() == 0)
355 return 0;
356
357 qint64 n = maxlen;
358 if(static_cast<int>(maxlen) > m_data.size())
359 n = m_data.size();
360 memcpy(data, m_data.data(), n);
361 if(m_data.size() == n)
362 m_data.clear();
363 else
364 m_data.remove(0, n);
365 return n;
366}
367
368bool CChannelIce::isSequential() const
369{
370 return true;
371}
372
373void CChannelIce::slotSignalConnected()
374{
375}
376
377void CChannelIce::slotSignalDisconnected()
378{
379 //emit sigError(-1, tr("Signal disconnected"));
380}
381
382void CChannelIce::slotSignalReceiverCandidate(const QString& fromUser,
383 const QString &toUser,
384 const QString &channelId,
385 const QString& mid,
386 const QString& sdp)
387{
388 /*
389 qDebug(m_Log, "slotSignalReceiverCandidate fromUser:%s; toUser:%s; channelId:%s; mid:%s; sdp:%s",
390 fromUser.toStdString().c_str(),
391 toUser.toStdString().c_str(),
392 channelId.toStdString().c_str(),
393 mid.toStdString().c_str(),
394 sdp.toStdString().c_str()); //*/
395 if(GetPeerUser() != fromUser || GetUser() != toUser
396 || GetChannelId() != channelId) return;
397 if(m_peerConnection)
398 {
399 rtc::Candidate Candidate(sdp.toStdString(), mid.toStdString());
400 m_peerConnection->addRemoteCandidate(Candidate);
401 }
402}
403
404void CChannelIce::slotSignalReceiverDescription(const QString& fromUser,
405 const QString &toUser,
406 const QString &channelId,
407 const QString &type,
408 const QString &sdp)
409{
410 /*
411 qDebug(m_Log, "slotSignalReceiverDescription fromUser:%s; toUser:%s; channelId:%s; type:%s; sdp:%s",
412 fromUser.toStdString().c_str(),
413 toUser.toStdString().c_str(),
414 channelId.toStdString().c_str(),
415 type.toStdString().c_str(),
416 sdp.toStdString().c_str()); //*/
417
418 if(GetPeerUser() != fromUser
419 || GetUser() != toUser
420 || GetChannelId() != channelId)
421 return;
422
423 rtc::Description des(sdp.toStdString(), type.toStdString());
424 if(m_peerConnection)
425 m_peerConnection->setRemoteDescription(des);
426}
427
428void CChannelIce::slotSignalError(int error, const QString& szError)
429{
430 //emit sigError(error, tr("Signal error: %1").arg(szError));
431}
432
433QString CChannelIce::GenerateID(const QString &label)
434{
435 static qint64 id = 0;
436 static QMutex mutex;
437 QMutexLocker locker(&mutex);
438 QString szId = label;
439 szId += QString::number(id++);
440 return szId;
441}
virtual bool open(const QString &user, const QString &peer, bool bChannelId)
Open channel. for activating calls.
int SetConfigure(const rtc::Configuration &config)
The channel interface class.
Definition Channel.h:25
void sigConnected()
emit when the channel is connected.
void sigDisconnected()
emit when the channel is disconnected
void sigError(int nErr, const QString &szErr)
emit when the channel is error
The ICE signal interface class.
Definition IceSignal.h:26
static QLoggingCategory m_Log
Definition ChannelIce.h:126