a-zlm/webrtc/IceSession.cpp

140 lines
3.9 KiB
C++

/*
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
*
* Use of this source code is governed by MIT-like license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/
#include "IceSession.hpp"
#include "Util/util.h"
#include "Common/config.h"
#include "WebRtcTransport.h"
using namespace std;
using namespace toolkit;
namespace mediakit {
static IceSession::Ptr queryIceTransport(uint8_t *data, size_t size) {
auto packet = RTC::StunPacket::parse((const uint8_t *)data, size);
if (!packet) {
WarnL << "parse stun error";
return nullptr;
}
auto username = packet->getUsername();
return IceSessionManager::Instance().getItem(username);
}
//////////// IceSession //////////////////////////
IceSession::IceSession(const Socket::Ptr &sock) : Session(sock) {
TraceL << getIdentifier();
_over_tcp = sock->sockType() == SockNum::Sock_TCP;
GET_CONFIG(string, iceUfrag, Rtc::kIceUfrag);
GET_CONFIG(string, icePwd, Rtc::kIcePwd);
_ice_transport = std::make_shared<IceServer>(this, iceUfrag, icePwd, getPoller());
_ice_transport->initialize();
}
IceSession::~IceSession() {
TraceL << getIdentifier();
}
EventPoller::Ptr IceSession::queryPoller(const Buffer::Ptr &buffer) {
auto transport = queryIceTransport((uint8_t *)buffer->data(), buffer->size());
return transport ? transport->getPoller() : nullptr;
}
void IceSession::onRecv(const Buffer::Ptr &buffer) {
// TraceL;
if (_over_tcp) {
input(buffer->data(), buffer->size());
}
else{
onRecv_l(buffer->data(), buffer->size());
}
}
void IceSession::onRecv_l(const char* buffer, size_t size) {
if (!_session_pair) {
_session_pair = std::make_shared<IceTransport::Pair>(shared_from_this());
}
_ice_transport->processSocketData((const uint8_t *)buffer, size, _session_pair);
}
void IceSession::onError(const SockException &err) {
InfoL;
// 消除循环引用
_session_pair = nullptr;
}
void IceSession::onManager() {
}
ssize_t IceSession::onRecvHeader(const char *data, size_t len) {
onRecv_l(data + 2, len - 2);
return 0;
}
const char *IceSession::onSearchPacketTail(const char *data, size_t len) {
if (len < 2) {
// Not enough data
return nullptr;
}
uint16_t length = (((uint8_t *)data)[0] << 8) | ((uint8_t *)data)[1];
if (len < (size_t)(length + 2)) {
// Not enough data
return nullptr;
}
// Return the end of the RTP packet
return data + 2 + length;
}
void IceSession::onIceTransportRecvData(const toolkit::Buffer::Ptr& buffer, const IceTransport::Pair::Ptr& pair) {
_ice_transport->processSocketData((const uint8_t *)buffer->data(), buffer->size(), pair);
}
void IceSession::onIceTransportGatheringCandidate(const IceTransport::Pair::Ptr& pair, const CandidateInfo& candidate) {
DebugL << candidate.dumpString();
}
void IceSession::onIceTransportDisconnected() {
InfoL << getIdentifier();
}
void IceSession::onIceTransportCompleted() {
InfoL << getIdentifier();
}
//////////// IceSessionManager //////////////////////////
IceSessionManager &IceSessionManager::Instance() {
static IceSessionManager s_instance;
return s_instance;
}
void IceSessionManager::addItem(const std::string& key, const IceSession::Ptr &ptr) {
std::lock_guard<std::mutex> lck(_mtx);
_map[key] = ptr;
}
IceSession::Ptr IceSessionManager::getItem(const std::string& key) {
assert(!key.empty());
std::lock_guard<std::mutex> lck(_mtx);
auto it = _map.find(key);
if (it == _map.end()) {
return nullptr;
}
return it->second.lock();
}
void IceSessionManager::removeItem(const std::string& key) {
std::lock_guard<std::mutex> lck(_mtx);
_map.erase(key);
}
}// namespace mediakit