intelij hack
This commit is contained in:
parent
993ea209c7
commit
7d64b05e3c
@ -11,6 +11,7 @@
|
|||||||
namespace mumlib {
|
namespace mumlib {
|
||||||
|
|
||||||
constexpr int DEFAULT_OPUS_ENCODER_BITRATE = 16000;
|
constexpr int DEFAULT_OPUS_ENCODER_BITRATE = 16000;
|
||||||
|
constexpr int DEFAULT_OPUS_SAMPLE_RATE = 48000;
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace boost::asio;
|
using namespace boost::asio;
|
||||||
@ -22,6 +23,7 @@ namespace mumlib {
|
|||||||
|
|
||||||
struct MumlibConfiguration {
|
struct MumlibConfiguration {
|
||||||
int opusEncoderBitrate = DEFAULT_OPUS_ENCODER_BITRATE;
|
int opusEncoderBitrate = DEFAULT_OPUS_ENCODER_BITRATE;
|
||||||
|
int opusSampleRate = DEFAULT_OPUS_SAMPLE_RATE;
|
||||||
// additional fields will be added in the future
|
// additional fields will be added in the future
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -30,7 +32,7 @@ namespace mumlib {
|
|||||||
|
|
||||||
class Mumlib : boost::noncopyable {
|
class Mumlib : boost::noncopyable {
|
||||||
public:
|
public:
|
||||||
Mumlib(Callback &callback);
|
explicit Mumlib(Callback &callback);
|
||||||
|
|
||||||
Mumlib(Callback &callback, io_service &ioService);
|
Mumlib(Callback &callback, io_service &ioService);
|
||||||
|
|
||||||
@ -44,10 +46,14 @@ namespace mumlib {
|
|||||||
|
|
||||||
void disconnect();
|
void disconnect();
|
||||||
|
|
||||||
|
void reconnect();
|
||||||
|
|
||||||
void run();
|
void run();
|
||||||
|
|
||||||
ConnectionState getConnectionState();
|
ConnectionState getConnectionState();
|
||||||
|
|
||||||
|
int getChannelId();
|
||||||
|
|
||||||
void sendAudioData(int16_t *pcmData, int pcmLength);
|
void sendAudioData(int16_t *pcmData, int pcmLength);
|
||||||
|
|
||||||
void sendAudioDataTarget(int targetId, int16_t *pcmData, int pcmLength);
|
void sendAudioDataTarget(int targetId, int16_t *pcmData, int pcmLength);
|
||||||
|
@ -2,19 +2,17 @@
|
|||||||
|
|
||||||
#include "Transport.hpp"
|
#include "Transport.hpp"
|
||||||
|
|
||||||
#include <opus.h>
|
#include <opus/opus.h>
|
||||||
|
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
|
||||||
namespace mumlib {
|
namespace mumlib {
|
||||||
|
|
||||||
constexpr int SAMPLE_RATE = 48000;
|
|
||||||
|
|
||||||
class MumlibException;
|
class MumlibException;
|
||||||
|
|
||||||
class AudioException : public MumlibException {
|
class AudioException : public MumlibException {
|
||||||
public:
|
public:
|
||||||
AudioException(string message) : MumlibException(message) { }
|
explicit AudioException(string message) : MumlibException(message) { }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct IncomingAudioPacket {
|
struct IncomingAudioPacket {
|
||||||
@ -27,8 +25,8 @@ namespace mumlib {
|
|||||||
};
|
};
|
||||||
|
|
||||||
class Audio : boost::noncopyable {
|
class Audio : boost::noncopyable {
|
||||||
public:
|
public:
|
||||||
Audio(int opusEncoderBitrate = DEFAULT_OPUS_ENCODER_BITRATE);
|
Audio(int opusSampleRate, int opusEncoderBitrate);
|
||||||
|
|
||||||
virtual ~Audio();
|
virtual ~Audio();
|
||||||
|
|
||||||
@ -59,6 +57,7 @@ namespace mumlib {
|
|||||||
OpusEncoder *opusEncoder;
|
OpusEncoder *opusEncoder;
|
||||||
|
|
||||||
int64_t outgoingSequenceNumber;
|
int64_t outgoingSequenceNumber;
|
||||||
|
int sampleRate;
|
||||||
|
|
||||||
std::chrono::time_point<std::chrono::system_clock> lastEncodedAudioPacketTimestamp;
|
std::chrono::time_point<std::chrono::system_clock> lastEncodedAudioPacketTimestamp;
|
||||||
};
|
};
|
||||||
|
@ -153,7 +153,7 @@ namespace mumlib {
|
|||||||
|
|
||||||
~BasicCallback();
|
~BasicCallback();
|
||||||
|
|
||||||
virtual void version(
|
void version(
|
||||||
uint16_t major,
|
uint16_t major,
|
||||||
uint8_t minor,
|
uint8_t minor,
|
||||||
uint8_t patch,
|
uint8_t patch,
|
||||||
@ -161,29 +161,29 @@ namespace mumlib {
|
|||||||
string os,
|
string os,
|
||||||
string os_version) override;
|
string os_version) override;
|
||||||
|
|
||||||
virtual void audio(
|
void audio(
|
||||||
int target,
|
int target,
|
||||||
int sessionId,
|
int sessionId,
|
||||||
int sequenceNumber,
|
int sequenceNumber,
|
||||||
int16_t *pcm_data,
|
int16_t *pcm_data,
|
||||||
uint32_t pcm_data_size) override;
|
uint32_t pcm_data_size) override;
|
||||||
|
|
||||||
virtual void unsupportedAudio(
|
void unsupportedAudio(
|
||||||
int target,
|
int target,
|
||||||
int sessionId,
|
int sessionId,
|
||||||
int sequenceNumber,
|
int sequenceNumber,
|
||||||
uint8_t *encoded_audio_data,
|
uint8_t *encoded_audio_data,
|
||||||
uint32_t encoded_audio_data_size) override;
|
uint32_t encoded_audio_data_size) override;
|
||||||
|
|
||||||
virtual void serverSync(
|
void serverSync(
|
||||||
string welcome_text,
|
string welcome_text,
|
||||||
int32_t session,
|
int32_t session,
|
||||||
int32_t max_bandwidth,
|
int32_t max_bandwidth,
|
||||||
int64_t permissions) override;
|
int64_t permissions) override;
|
||||||
|
|
||||||
virtual void channelRemove(uint32_t channel_id) override;
|
void channelRemove(uint32_t channel_id) override;
|
||||||
|
|
||||||
virtual void channelState(
|
void channelState(
|
||||||
string name,
|
string name,
|
||||||
int32_t channel_id,
|
int32_t channel_id,
|
||||||
int32_t parent,
|
int32_t parent,
|
||||||
@ -194,13 +194,13 @@ namespace mumlib {
|
|||||||
bool temporary,
|
bool temporary,
|
||||||
int32_t position) override;
|
int32_t position) override;
|
||||||
|
|
||||||
virtual void userRemove(
|
void userRemove(
|
||||||
uint32_t session,
|
uint32_t session,
|
||||||
int32_t actor,
|
int32_t actor,
|
||||||
string reason,
|
string reason,
|
||||||
bool ban) override;
|
bool ban) override;
|
||||||
|
|
||||||
virtual void userState(
|
void userState(
|
||||||
int32_t session,
|
int32_t session,
|
||||||
int32_t actor,
|
int32_t actor,
|
||||||
string name,
|
string name,
|
||||||
@ -215,7 +215,7 @@ namespace mumlib {
|
|||||||
int32_t priority_speaker,
|
int32_t priority_speaker,
|
||||||
int32_t recording) override;
|
int32_t recording) override;
|
||||||
|
|
||||||
virtual void banList(
|
void banList(
|
||||||
const uint8_t *ip_data,
|
const uint8_t *ip_data,
|
||||||
uint32_t ip_data_size,
|
uint32_t ip_data_size,
|
||||||
uint32_t mask,
|
uint32_t mask,
|
||||||
@ -225,14 +225,14 @@ namespace mumlib {
|
|||||||
string start,
|
string start,
|
||||||
int32_t duration) override;
|
int32_t duration) override;
|
||||||
|
|
||||||
virtual void textMessage(
|
void textMessage(
|
||||||
uint32_t actor,
|
uint32_t actor,
|
||||||
std::vector<uint32_t> session,
|
std::vector<uint32_t> session,
|
||||||
std::vector<uint32_t> channel_id,
|
std::vector<uint32_t> channel_id,
|
||||||
std::vector<uint32_t> tree_id,
|
std::vector<uint32_t> tree_id,
|
||||||
string message) override;
|
string message) override;
|
||||||
|
|
||||||
virtual void permissionDenied(
|
void permissionDenied(
|
||||||
int32_t permission,
|
int32_t permission,
|
||||||
int32_t channel_id,
|
int32_t channel_id,
|
||||||
int32_t session,
|
int32_t session,
|
||||||
@ -240,48 +240,48 @@ namespace mumlib {
|
|||||||
int32_t deny_type,
|
int32_t deny_type,
|
||||||
string name) override;
|
string name) override;
|
||||||
|
|
||||||
virtual void queryUsers(
|
void queryUsers(
|
||||||
uint32_t n_ids,
|
uint32_t n_ids,
|
||||||
uint32_t *ids,
|
uint32_t *ids,
|
||||||
uint32_t n_names,
|
uint32_t n_names,
|
||||||
string *names) override;
|
string *names) override;
|
||||||
|
|
||||||
virtual void contextActionModify(
|
void contextActionModify(
|
||||||
string action,
|
string action,
|
||||||
string text,
|
string text,
|
||||||
uint32_t m_context,
|
uint32_t m_context,
|
||||||
uint32_t operation) override;
|
uint32_t operation) override;
|
||||||
|
|
||||||
virtual void contextAction(
|
void contextAction(
|
||||||
int32_t session,
|
int32_t session,
|
||||||
int32_t channel_id,
|
int32_t channel_id,
|
||||||
string action) override;
|
string action) override;
|
||||||
|
|
||||||
virtual void userList(
|
void userList(
|
||||||
uint32_t user_id,
|
uint32_t user_id,
|
||||||
string name,
|
string name,
|
||||||
string last_seen,
|
string last_seen,
|
||||||
int32_t last_channel) override;
|
int32_t last_channel) override;
|
||||||
|
|
||||||
virtual void permissionQuery(
|
void permissionQuery(
|
||||||
int32_t channel_id,
|
int32_t channel_id,
|
||||||
uint32_t permissions,
|
uint32_t permissions,
|
||||||
int32_t flush) override;
|
int32_t flush) override;
|
||||||
|
|
||||||
virtual void codecVersion(
|
void codecVersion(
|
||||||
int32_t alpha,
|
int32_t alpha,
|
||||||
int32_t beta,
|
int32_t beta,
|
||||||
uint32_t prefer_alpha,
|
uint32_t prefer_alpha,
|
||||||
int32_t opus) override;
|
int32_t opus) override;
|
||||||
|
|
||||||
virtual void serverConfig(
|
void serverConfig(
|
||||||
uint32_t max_bandwidth,
|
uint32_t max_bandwidth,
|
||||||
string welcome_text,
|
string welcome_text,
|
||||||
uint32_t allow_html,
|
uint32_t allow_html,
|
||||||
uint32_t message_length,
|
uint32_t message_length,
|
||||||
uint32_t image_message_length) override;
|
uint32_t image_message_length) override;
|
||||||
|
|
||||||
virtual void suggestConfig(
|
void suggestConfig(
|
||||||
uint32_t version,
|
uint32_t version,
|
||||||
uint32_t positional,
|
uint32_t positional,
|
||||||
uint32_t push_to_talk) override;
|
uint32_t push_to_talk) override;
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
#include <google/protobuf/message.h>
|
#include <google/protobuf/message.h>
|
||||||
|
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
namespace mumlib {
|
namespace mumlib {
|
||||||
|
|
||||||
@ -30,7 +31,7 @@ namespace mumlib {
|
|||||||
|
|
||||||
class TransportException : public MumlibException {
|
class TransportException : public MumlibException {
|
||||||
public:
|
public:
|
||||||
TransportException(string message) : MumlibException(message) { }
|
TransportException(string message) : MumlibException(std::move(message)) { }
|
||||||
};
|
};
|
||||||
|
|
||||||
class Transport : boost::noncopyable {
|
class Transport : boost::noncopyable {
|
||||||
@ -49,6 +50,8 @@ namespace mumlib {
|
|||||||
|
|
||||||
void disconnect();
|
void disconnect();
|
||||||
|
|
||||||
|
void reconnect();
|
||||||
|
|
||||||
ConnectionState getConnectionState() {
|
ConnectionState getConnectionState() {
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,6 @@ namespace mumlib {
|
|||||||
private:
|
private:
|
||||||
const int64_t value;
|
const int64_t value;
|
||||||
|
|
||||||
int64_t parseVariant(uint8_t *buffer);
|
long parseVariant(const uint8_t *buffer);
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -4,20 +4,21 @@
|
|||||||
|
|
||||||
static boost::posix_time::seconds RESET_SEQUENCE_NUMBER_INTERVAL(5);
|
static boost::posix_time::seconds RESET_SEQUENCE_NUMBER_INTERVAL(5);
|
||||||
|
|
||||||
mumlib::Audio::Audio(int opusEncoderBitrate)
|
mumlib::Audio::Audio(int opusSampleRate, int opusEncoderBitrate)
|
||||||
: logger(log4cpp::Category::getInstance("mumlib.Audio")),
|
: logger(log4cpp::Category::getInstance("mumlib.Audio")),
|
||||||
opusDecoder(nullptr),
|
opusDecoder(nullptr),
|
||||||
opusEncoder(nullptr),
|
opusEncoder(nullptr),
|
||||||
outgoingSequenceNumber(0) {
|
outgoingSequenceNumber(0) {
|
||||||
|
|
||||||
int error;
|
int error;
|
||||||
|
this->sampleRate = opusSampleRate;
|
||||||
|
|
||||||
opusDecoder = opus_decoder_create(SAMPLE_RATE, 1, &error);
|
opusDecoder = opus_decoder_create(opusSampleRate, 1, &error);
|
||||||
if (error != OPUS_OK) {
|
if (error != OPUS_OK) {
|
||||||
throw AudioException((boost::format("failed to initialize OPUS decoder: %s") % opus_strerror(error)).str());
|
throw AudioException((boost::format("failed to initialize OPUS decoder: %s") % opus_strerror(error)).str());
|
||||||
}
|
}
|
||||||
|
|
||||||
opusEncoder = opus_encoder_create(SAMPLE_RATE, 1, OPUS_APPLICATION_VOIP, &error);
|
opusEncoder = opus_encoder_create(opusSampleRate, 1, OPUS_APPLICATION_VOIP, &error);
|
||||||
if (error != OPUS_OK) {
|
if (error != OPUS_OK) {
|
||||||
throw AudioException((boost::format("failed to initialize OPUS encoder: %s") % opus_strerror(error)).str());
|
throw AudioException((boost::format("failed to initialize OPUS encoder: %s") % opus_strerror(error)).str());
|
||||||
}
|
}
|
||||||
@ -108,7 +109,7 @@ int mumlib::Audio::encodeAudioPacket(int target, int16_t *inputPcmBuffer, int in
|
|||||||
|
|
||||||
std::vector<uint8_t> header;
|
std::vector<uint8_t> header;
|
||||||
|
|
||||||
header.push_back(0x80 | target);
|
header.push_back(static_cast<unsigned char &&>(0x80 | target));
|
||||||
|
|
||||||
auto sequenceNumberEnc = VarInt(outgoingSequenceNumber).getEncoded();
|
auto sequenceNumberEnc = VarInt(outgoingSequenceNumber).getEncoded();
|
||||||
header.insert(header.end(), sequenceNumberEnc.begin(), sequenceNumberEnc.end());
|
header.insert(header.end(), sequenceNumberEnc.begin(), sequenceNumberEnc.end());
|
||||||
@ -130,15 +131,15 @@ int mumlib::Audio::encodeAudioPacket(int target, int16_t *inputPcmBuffer, int in
|
|||||||
header.insert(header.end(), outputSizeEnc.begin(), outputSizeEnc.end());
|
header.insert(header.end(), outputSizeEnc.begin(), outputSizeEnc.end());
|
||||||
|
|
||||||
memcpy(outputBuffer, &header[0], header.size());
|
memcpy(outputBuffer, &header[0], header.size());
|
||||||
memcpy(outputBuffer + header.size(), tmpOpusBuffer, outputSize);
|
memcpy(outputBuffer + header.size(), tmpOpusBuffer, (size_t) outputSize);
|
||||||
|
|
||||||
int incrementNumber = 100 * inputLength / SAMPLE_RATE;
|
int incrementNumber = 100 * inputLength / this->sampleRate;
|
||||||
|
|
||||||
outgoingSequenceNumber += incrementNumber;
|
outgoingSequenceNumber += incrementNumber;
|
||||||
|
|
||||||
lastEncodedAudioPacketTimestamp = std::chrono::system_clock::now();
|
lastEncodedAudioPacketTimestamp = std::chrono::system_clock::now();
|
||||||
|
|
||||||
return outputSize + header.size();
|
return static_cast<int>(outputSize + header.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
void mumlib::Audio::resetEncoder() {
|
void mumlib::Audio::resetEncoder() {
|
||||||
@ -152,7 +153,7 @@ void mumlib::Audio::resetEncoder() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mumlib::IncomingAudioPacket mumlib::Audio::decodeIncomingAudioPacket(uint8_t *inputBuffer, int inputBufferLength) {
|
mumlib::IncomingAudioPacket mumlib::Audio::decodeIncomingAudioPacket(uint8_t *inputBuffer, int inputBufferLength) {
|
||||||
mumlib::IncomingAudioPacket incomingAudioPacket;
|
mumlib::IncomingAudioPacket incomingAudioPacket{};
|
||||||
|
|
||||||
incomingAudioPacket.type = static_cast<AudioPacketType >((inputBuffer[0] & 0xE0) >> 5);
|
incomingAudioPacket.type = static_cast<AudioPacketType >((inputBuffer[0] & 0xE0) >> 5);
|
||||||
incomingAudioPacket.target = inputBuffer[0] & 0x1F;
|
incomingAudioPacket.target = inputBuffer[0] & 0x1F;
|
||||||
|
@ -35,7 +35,7 @@ void mumlib::BasicCallback::version(
|
|||||||
os_version.c_str());
|
os_version.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void mumlib::BasicCallback::audio(
|
void BasicCallback::audio(
|
||||||
int target,
|
int target,
|
||||||
int sessionId,
|
int sessionId,
|
||||||
int sequenceNumber,
|
int sequenceNumber,
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#include "Mumble.pb.h"
|
#include "Mumble.pb.h"
|
||||||
|
|
||||||
#include <boost/format.hpp>
|
#include <boost/format.hpp>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
@ -32,15 +33,15 @@ mumlib::Transport::Transport(
|
|||||||
bool noUdp) :
|
bool noUdp) :
|
||||||
logger(log4cpp::Category::getInstance("mumlib.Transport")),
|
logger(log4cpp::Category::getInstance("mumlib.Transport")),
|
||||||
ioService(ioService),
|
ioService(ioService),
|
||||||
processMessageFunction(processMessageFunc),
|
processMessageFunction(std::move(processMessageFunc)),
|
||||||
processEncodedAudioPacketFunction(processEncodedAudioPacketFunction),
|
processEncodedAudioPacketFunction(std::move(processEncodedAudioPacketFunction)),
|
||||||
noUdp(noUdp),
|
noUdp(noUdp),
|
||||||
state(ConnectionState::NOT_CONNECTED),
|
state(ConnectionState::NOT_CONNECTED),
|
||||||
udpSocket(ioService),
|
udpSocket(ioService),
|
||||||
sslContext(ssl::context::sslv23),
|
sslContext(ssl::context::sslv23),
|
||||||
sslSocket(ioService, sslContext),
|
sslSocket(ioService, sslContext),
|
||||||
pingTimer(ioService, PING_INTERVAL),
|
pingTimer(ioService, PING_INTERVAL),
|
||||||
asyncBufferPool(max(MAX_UDP_LENGTH, MAX_TCP_LENGTH)) {
|
asyncBufferPool(static_cast<const unsigned long>(max(MAX_UDP_LENGTH, MAX_TCP_LENGTH))) {
|
||||||
|
|
||||||
sslIncomingBuffer = new uint8_t[MAX_TCP_LENGTH];
|
sslIncomingBuffer = new uint8_t[MAX_TCP_LENGTH];
|
||||||
|
|
||||||
@ -118,6 +119,15 @@ void mumlib::Transport::disconnect() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void mumlib::Transport::reconnect() {
|
||||||
|
boost::system::error_code errorCode;
|
||||||
|
|
||||||
|
udpSocket.close(errorCode);
|
||||||
|
if (errorCode) {
|
||||||
|
logger.warn("SSL socket close return an error: %s.", errorCode.message().c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void mumlib::Transport::sendVersion() {
|
void mumlib::Transport::sendVersion() {
|
||||||
MumbleProto::Version version;
|
MumbleProto::Version version;
|
||||||
@ -185,10 +195,10 @@ void mumlib::Transport::doReceiveUdp() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint8_t plainBuffer[1024];
|
uint8_t plainBuffer[1024];
|
||||||
const int plainBufferLength = bytesTransferred - 4;
|
const int plainBufferLength = static_cast<const int>(bytesTransferred - 4);
|
||||||
|
|
||||||
bool success = cryptState.decrypt(
|
bool success = cryptState.decrypt(
|
||||||
udpIncomingBuffer, plainBuffer, bytesTransferred);
|
udpIncomingBuffer, plainBuffer, static_cast<unsigned int>(bytesTransferred));
|
||||||
|
|
||||||
if (not success) {
|
if (not success) {
|
||||||
throwTransportException("UDP packet decryption failed");
|
throwTransportException("UDP packet decryption failed");
|
||||||
@ -263,12 +273,12 @@ void mumlib::Transport::sendUdpAsync(uint8_t *buff, int length) {
|
|||||||
auto *encryptedMsgBuff = asyncBufferPool.malloc();
|
auto *encryptedMsgBuff = asyncBufferPool.malloc();
|
||||||
const int encryptedMsgLength = length + 4;
|
const int encryptedMsgLength = length + 4;
|
||||||
|
|
||||||
cryptState.encrypt(buff, reinterpret_cast<uint8_t *>(encryptedMsgBuff), length);
|
cryptState.encrypt(buff, reinterpret_cast<uint8_t *>(encryptedMsgBuff), static_cast<unsigned int>(length));
|
||||||
|
|
||||||
logger.debug("Sending %d B of data UDP asynchronously.", encryptedMsgLength);
|
logger.debug("Sending %d B of data UDP asynchronously.", encryptedMsgLength);
|
||||||
|
|
||||||
udpSocket.async_send_to(
|
udpSocket.async_send_to(
|
||||||
boost::asio::buffer(encryptedMsgBuff, length + 4),
|
boost::asio::buffer(encryptedMsgBuff, static_cast<size_t>(length + 4)),
|
||||||
udpReceiverEndpoint,
|
udpReceiverEndpoint,
|
||||||
[this, encryptedMsgBuff](const boost::system::error_code &ec, size_t bytesTransferred) {
|
[this, encryptedMsgBuff](const boost::system::error_code &ec, size_t bytesTransferred) {
|
||||||
asyncBufferPool.free(encryptedMsgBuff);
|
asyncBufferPool.free(encryptedMsgBuff);
|
||||||
@ -318,7 +328,7 @@ void mumlib::Transport::doReceiveSsl() {
|
|||||||
processMessageInternal(
|
processMessageInternal(
|
||||||
static_cast<MessageType>(messageType),
|
static_cast<MessageType>(messageType),
|
||||||
&sslIncomingBuffer[6],
|
&sslIncomingBuffer[6],
|
||||||
bytesTransferred - 6);
|
static_cast<int>(bytesTransferred - 6));
|
||||||
|
|
||||||
doReceiveSsl();
|
doReceiveSsl();
|
||||||
} else {
|
} else {
|
||||||
@ -438,10 +448,10 @@ void mumlib::Transport::sendUdpPing() {
|
|||||||
vector<uint8_t> message;
|
vector<uint8_t> message;
|
||||||
message.push_back(0x20);
|
message.push_back(0x20);
|
||||||
|
|
||||||
auto timestampVarint = VarInt(time(nullptr)).getEncoded();
|
auto timestampVarint = VarInt(static_cast<int64_t>(time(nullptr))).getEncoded();
|
||||||
message.insert(message.end(), timestampVarint.begin(), timestampVarint.end());
|
message.insert(message.end(), timestampVarint.begin(), timestampVarint.end());
|
||||||
|
|
||||||
sendUdpAsync(&message[0], message.size());
|
sendUdpAsync(&message[0], static_cast<int>(message.size()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void mumlib::Transport::sendSsl(uint8_t *buff, int length) {
|
void mumlib::Transport::sendSsl(uint8_t *buff, int length) {
|
||||||
@ -453,7 +463,7 @@ void mumlib::Transport::sendSsl(uint8_t *buff, int length) {
|
|||||||
logger.debug("Sending %d bytes of data.", length);
|
logger.debug("Sending %d bytes of data.", length);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
write(sslSocket, boost::asio::buffer(buff, length));
|
write(sslSocket, boost::asio::buffer(buff, static_cast<size_t>(length)));
|
||||||
} catch (boost::system::system_error &err) {
|
} catch (boost::system::system_error &err) {
|
||||||
throwTransportException(std::string("SSL send failed: ") + err.what());
|
throwTransportException(std::string("SSL send failed: ") + err.what());
|
||||||
}
|
}
|
||||||
@ -467,13 +477,13 @@ void mumlib::Transport::sendSslAsync(uint8_t *buff, int length) {
|
|||||||
|
|
||||||
auto *asyncBuff = asyncBufferPool.malloc();
|
auto *asyncBuff = asyncBufferPool.malloc();
|
||||||
|
|
||||||
memcpy(asyncBuff, buff, length);
|
memcpy(asyncBuff, buff, static_cast<size_t>(length));
|
||||||
|
|
||||||
logger.debug("Sending %d B of data asynchronously.", length);
|
logger.debug("Sending %d B of data asynchronously.", length);
|
||||||
|
|
||||||
async_write(
|
async_write(
|
||||||
sslSocket,
|
sslSocket,
|
||||||
boost::asio::buffer(asyncBuff, length),
|
boost::asio::buffer(asyncBuff, static_cast<size_t>(length)),
|
||||||
[this, asyncBuff](const boost::system::error_code &ec, size_t bytesTransferred) {
|
[this, asyncBuff](const boost::system::error_code &ec, size_t bytesTransferred) {
|
||||||
asyncBufferPool.free(asyncBuff);
|
asyncBufferPool.free(asyncBuff);
|
||||||
logger.debug("Sent %d B.", bytesTransferred);
|
logger.debug("Sent %d B.", bytesTransferred);
|
||||||
@ -499,7 +509,7 @@ void mumlib::Transport::sendControlMessagePrivate(MessageType type, google::prot
|
|||||||
const uint16_t type_network = htons(static_cast<uint16_t>(type));
|
const uint16_t type_network = htons(static_cast<uint16_t>(type));
|
||||||
|
|
||||||
const int size = message.ByteSize();
|
const int size = message.ByteSize();
|
||||||
const uint32_t size_network = htonl(size);
|
const uint32_t size_network = htonl((uint32_t) size);
|
||||||
|
|
||||||
const int length = sizeof(type_network) + sizeof(size_network) + size;
|
const int length = sizeof(type_network) + sizeof(size_network) + size;
|
||||||
|
|
||||||
@ -517,7 +527,7 @@ void mumlib::Transport::sendControlMessagePrivate(MessageType type, google::prot
|
|||||||
void mumlib::Transport::throwTransportException(string message) {
|
void mumlib::Transport::throwTransportException(string message) {
|
||||||
state = ConnectionState::FAILED;
|
state = ConnectionState::FAILED;
|
||||||
|
|
||||||
throw TransportException(message);
|
throw TransportException(std::move(message));
|
||||||
}
|
}
|
||||||
|
|
||||||
void mumlib::Transport::sendEncodedAudioPacket(uint8_t *buffer, int length) {
|
void mumlib::Transport::sendEncodedAudioPacket(uint8_t *buffer, int length) {
|
||||||
@ -534,7 +544,7 @@ void mumlib::Transport::sendEncodedAudioPacket(uint8_t *buffer, int length) {
|
|||||||
|
|
||||||
const uint16_t netUdptunnelType = htons(static_cast<uint16_t>(MessageType::UDPTUNNEL));
|
const uint16_t netUdptunnelType = htons(static_cast<uint16_t>(MessageType::UDPTUNNEL));
|
||||||
|
|
||||||
const uint32_t netLength = htonl(length);
|
const uint32_t netLength = htonl(static_cast<uint32_t>(length));
|
||||||
|
|
||||||
const int packet = sizeof(netUdptunnelType) + sizeof(netLength) + length;
|
const int packet = sizeof(netUdptunnelType) + sizeof(netLength) + length;
|
||||||
|
|
||||||
@ -542,14 +552,14 @@ void mumlib::Transport::sendEncodedAudioPacket(uint8_t *buffer, int length) {
|
|||||||
|
|
||||||
memcpy(packetBuff, &netUdptunnelType, sizeof(netUdptunnelType));
|
memcpy(packetBuff, &netUdptunnelType, sizeof(netUdptunnelType));
|
||||||
memcpy(packetBuff + sizeof(netUdptunnelType), &netLength, sizeof(netLength));
|
memcpy(packetBuff + sizeof(netUdptunnelType), &netLength, sizeof(netLength));
|
||||||
memcpy(packetBuff + sizeof(netUdptunnelType) + sizeof(netLength), buffer, length);
|
memcpy(packetBuff + sizeof(netUdptunnelType) + sizeof(netLength), buffer, static_cast<size_t>(length));
|
||||||
|
|
||||||
sendSslAsync(packetBuff, length + sizeof(netUdptunnelType) + sizeof(netLength));
|
sendSslAsync(packetBuff, length + sizeof(netUdptunnelType) + sizeof(netLength));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void mumlib::Transport::processAudioPacket(uint8_t *buff, int length) {
|
void mumlib::Transport::processAudioPacket(uint8_t *buff, int length) {
|
||||||
AudioPacketType type = static_cast<AudioPacketType >((buff[0] & 0xE0) >> 5);
|
auto type = static_cast<AudioPacketType >((buff[0] & 0xE0) >> 5);
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case AudioPacketType::CELT_Alpha:
|
case AudioPacketType::CELT_Alpha:
|
||||||
case AudioPacketType::Speex:
|
case AudioPacketType::Speex:
|
||||||
|
@ -12,7 +12,7 @@ mumlib::VarInt::VarInt(std::vector<uint8_t> encoded) : value(parseVariant(&encod
|
|||||||
* This code was taken from Mumble source code
|
* This code was taken from Mumble source code
|
||||||
* https://github.com/mumble-voip/mumble/blob/master/src/PacketDataStream.h
|
* https://github.com/mumble-voip/mumble/blob/master/src/PacketDataStream.h
|
||||||
*/
|
*/
|
||||||
int64_t mumlib::VarInt::parseVariant(uint8_t *buffer) {
|
int64_t mumlib::VarInt::parseVariant(const uint8_t *buffer) {
|
||||||
int64_t v = buffer[0];
|
int64_t v = buffer[0];
|
||||||
if ((v & 0x80) == 0x00) {
|
if ((v & 0x80) == 0x00) {
|
||||||
return (v & 0x7F);
|
return (v & 0x7F);
|
||||||
@ -36,6 +36,7 @@ int64_t mumlib::VarInt::parseVariant(uint8_t *buffer) {
|
|||||||
return (v & 0x1F) << 16 | buffer[1] << 8 | buffer[2];
|
return (v & 0x1F) << 16 | buffer[1] << 8 | buffer[2];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
throw VarIntException("invalid varint");
|
throw VarIntException("invalid varint");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,7 +47,7 @@ std::vector<uint8_t> mumlib::VarInt::getEncoded() const {
|
|||||||
if ((i & 0x8000000000000000LL) && (~i < 0x100000000LL)) {
|
if ((i & 0x8000000000000000LL) && (~i < 0x100000000LL)) {
|
||||||
i = ~i;
|
i = ~i;
|
||||||
if (i <= 0x3) {
|
if (i <= 0x3) {
|
||||||
encoded.push_back(0xFC | i);
|
encoded.push_back(static_cast<unsigned char &&>(0xFC | i));
|
||||||
return encoded;
|
return encoded;
|
||||||
} else {
|
} else {
|
||||||
encoded.push_back(0xF8);
|
encoded.push_back(0xF8);
|
||||||
@ -54,29 +55,29 @@ std::vector<uint8_t> mumlib::VarInt::getEncoded() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (i < 0x80) {
|
if (i < 0x80) {
|
||||||
encoded.push_back(i);
|
encoded.push_back(static_cast<unsigned char &&>(i));
|
||||||
} else if (i < 0x4000) {
|
} else if (i < 0x4000) {
|
||||||
encoded.push_back(0x80 | (i >> 8));
|
encoded.push_back(static_cast<unsigned char &&>(0x80 | (i >> 8)));
|
||||||
encoded.push_back(i & 0xFF);
|
encoded.push_back(static_cast<unsigned char &&>(i & 0xFF));
|
||||||
} else if (i < 0x200000) {
|
} else if (i < 0x200000) {
|
||||||
encoded.push_back(0xC0 | (i >> 16));
|
encoded.push_back(static_cast<unsigned char &&>(0xC0 | (i >> 16)));
|
||||||
encoded.push_back((i >> 8) & 0xFF);
|
encoded.push_back(static_cast<unsigned char &&>((i >> 8) & 0xFF));
|
||||||
encoded.push_back(i & 0xFF);
|
encoded.push_back(static_cast<unsigned char &&>(i & 0xFF));
|
||||||
} else if (i < 0x10000000) {
|
} else if (i < 0x10000000) {
|
||||||
encoded.push_back(0xE0 | (i >> 24));
|
encoded.push_back(static_cast<unsigned char &&>(0xE0 | (i >> 24)));
|
||||||
encoded.push_back((i >> 16) & 0xFF);
|
encoded.push_back(static_cast<unsigned char &&>((i >> 16) & 0xFF));
|
||||||
encoded.push_back((i >> 8) & 0xFF);
|
encoded.push_back(static_cast<unsigned char &&>((i >> 8) & 0xFF));
|
||||||
encoded.push_back(i & 0xFF);
|
encoded.push_back(static_cast<unsigned char &&>(i & 0xFF));
|
||||||
} else {
|
} else {
|
||||||
encoded.push_back(0xF4);
|
encoded.push_back(0xF4);
|
||||||
encoded.push_back((i >> 56) & 0xFF);
|
encoded.push_back(static_cast<unsigned char &&>((i >> 56) & 0xFF));
|
||||||
encoded.push_back((i >> 48) & 0xFF);
|
encoded.push_back(static_cast<unsigned char &&>((i >> 48) & 0xFF));
|
||||||
encoded.push_back((i >> 40) & 0xFF);
|
encoded.push_back(static_cast<unsigned char &&>((i >> 40) & 0xFF));
|
||||||
encoded.push_back((i >> 32) & 0xFF);
|
encoded.push_back(static_cast<unsigned char &&>((i >> 32) & 0xFF));
|
||||||
encoded.push_back((i >> 24) & 0xFF);
|
encoded.push_back(static_cast<unsigned char &&>((i >> 24) & 0xFF));
|
||||||
encoded.push_back((i >> 16) & 0xFF);
|
encoded.push_back(static_cast<unsigned char &&>((i >> 16) & 0xFF));
|
||||||
encoded.push_back((i >> 8) & 0xFF);
|
encoded.push_back(static_cast<unsigned char &&>((i >> 8) & 0xFF));
|
||||||
encoded.push_back(i & 0xFF);
|
encoded.push_back(static_cast<unsigned char &&>(i & 0xFF));
|
||||||
}
|
}
|
||||||
|
|
||||||
return encoded;
|
return encoded;
|
||||||
|
@ -43,7 +43,8 @@ namespace mumlib {
|
|||||||
ioService(ioService),
|
ioService(ioService),
|
||||||
externalIoService(true),
|
externalIoService(true),
|
||||||
transport(ioService, boost::bind(&_Mumlib_Private::processIncomingTcpMessage, this, _1, _2, _3),
|
transport(ioService, boost::bind(&_Mumlib_Private::processIncomingTcpMessage, this, _1, _2, _3),
|
||||||
boost::bind(&_Mumlib_Private::processAudioPacket, this, _1, _2, _3)) {
|
boost::bind(&_Mumlib_Private::processAudioPacket, this, _1, _2, _3)),
|
||||||
|
audio(configuration.opusSampleRate, configuration.opusEncoderBitrate) {
|
||||||
|
|
||||||
audio.setOpusEncoderBitrate(configuration.opusEncoderBitrate);
|
audio.setOpusEncoderBitrate(configuration.opusEncoderBitrate);
|
||||||
}
|
}
|
||||||
@ -363,6 +364,10 @@ namespace mumlib {
|
|||||||
return impl->transport.getConnectionState();
|
return impl->transport.getConnectionState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Mumlib::getChannelId() {
|
||||||
|
return impl->channelId;
|
||||||
|
}
|
||||||
|
|
||||||
void Mumlib::connect(string host, int port, string user, string password) {
|
void Mumlib::connect(string host, int port, string user, string password) {
|
||||||
impl->transport.connect(host, port, user, password);
|
impl->transport.connect(host, port, user, password);
|
||||||
}
|
}
|
||||||
@ -376,6 +381,15 @@ namespace mumlib {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Mumlib::reconnect() {
|
||||||
|
if (not impl->externalIoService) {
|
||||||
|
impl->ioService.reset();
|
||||||
|
}
|
||||||
|
if (impl->transport.getConnectionState() != ConnectionState::NOT_CONNECTED) {
|
||||||
|
impl->transport.disconnect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Mumlib::run() {
|
void Mumlib::run() {
|
||||||
if (impl->externalIoService) {
|
if (impl->externalIoService) {
|
||||||
throw MumlibException("can't call run() when using external io_service");
|
throw MumlibException("can't call run() when using external io_service");
|
||||||
|
Loading…
Reference in New Issue
Block a user