Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions Configuration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/ini_parser.hpp>
#include <boost/format.hpp>
#include <boost/foreach.hpp>

using namespace config;

Expand Down Expand Up @@ -50,4 +51,15 @@ std::string config::Configuration::getString(const std::string &property) {
return get<std::string>(impl->ptree, property);
}

// TODO: return set
std::unordered_map<std::string, std::string> config::Configuration::getChildren(const std::string &property) {
std::unordered_map<std::string, std::string> pins;
BOOST_FOREACH(boost::property_tree::ptree::value_type &v,
impl->ptree.get_child(property)) {
//pins[v.first.data()] = get<std::string>(impl->ptree, property + "." + v.second.data());
pins[v.first.data()] = v.second.data();
}
return pins;
}


3 changes: 3 additions & 0 deletions Configuration.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <vector>
#include <string>
#include <stdexcept>
#include <unordered_map>

namespace config {

Expand All @@ -31,6 +32,8 @@ namespace config {

std::string getString(const std::string &property);

std::unordered_map<std::string, std::string> getChildren(const std::string &property);

private:
ConfigurationImpl *impl;
};
Expand Down
33 changes: 33 additions & 0 deletions MumbleChannelJoiner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,20 @@ using namespace std;

mumble::MumbleChannelJoiner::MumbleChannelJoiner(std::string channelNameRegex) : channelNameRegex(boost::regex(channelNameRegex)),
logger(log4cpp::Category::getInstance("MumbleChannelJoiner")){
//std::vector<ChannelEntry> *channels = new std::vector<ChannelEntry>();
}

std::vector<mumble::MumbleChannelJoiner::ChannelEntry> mumble::MumbleChannelJoiner::channels;

void mumble::MumbleChannelJoiner::checkChannel(std::string channel_name, int channel_id) {
boost::smatch s;
ChannelEntry ent;
logger.debug("Channel %s available (%d)", channel_name.c_str(), channel_id);

ent.name = channel_name;
ent.id = channel_id;

channels.push_back(ent);

if(boost::regex_match(channel_name, s, channelNameRegex)) {
this->channel_id = channel_id;
Expand All @@ -23,3 +31,28 @@ void mumble::MumbleChannelJoiner::maybeJoinChannel(mumble::MumbleCommunicator *m
}
}

/* This is a secondary channel-switching object that relys on updates to the
* class variable 'channels' for the channel list from the server.
*/
void mumble::MumbleChannelJoiner::findJoinChannel(mumble::MumbleCommunicator *mc) {
boost::smatch s;

int found = -1;

for(std::vector<ChannelEntry>::iterator it = channels.begin(); it != channels.end(); ++it) {
if(boost::regex_match(it->name, s, channelNameRegex)) {
found = it->id;
}
}

if(found > -1) {
mc->joinChannel(found);
}
}

void mumble::MumbleChannelJoiner::joinOtherChannel(mumble::MumbleCommunicator *mc, std::string channelNameRegex) {
this->channelNameRegex = boost::regex(channelNameRegex);
findJoinChannel(mc);
}


10 changes: 10 additions & 0 deletions MumbleChannelJoiner.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,31 @@
#include <boost/noncopyable.hpp>
#include <log4cpp/Category.hh>

#include <vector>
#include <string>
#include <boost/regex.hpp>
#include "MumbleCommunicator.hpp"

namespace mumble {
class MumbleChannelJoiner : boost::noncopyable {

struct ChannelEntry {
int id;
std::string name;
};

public:
MumbleChannelJoiner(std::string channelNameRegex);

void checkChannel(std::string channel_name, int channel_id);
void maybeJoinChannel(mumble::MumbleCommunicator *mc);
void findJoinChannel(mumble::MumbleCommunicator *mc);
void joinOtherChannel(mumble::MumbleCommunicator *mc, std::string channelNameRegex);

private:
log4cpp::Category &logger;
boost::regex channelNameRegex;
int channel_id;
static std::vector<ChannelEntry> channels;
};
}
102 changes: 100 additions & 2 deletions MumbleCommunicator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,14 @@ namespace mumble {
std::shared_ptr<mumlib::Mumlib> mum;
MumbleCommunicator *communicator;

// called by Mumlib when receiving audio from mumble server
virtual void audio(
int target,
int sessionId,
int sequenceNumber,
int16_t *pcm_data,
uint32_t pcm_data_size) override {
communicator->onIncomingPcmSamples(sessionId, sequenceNumber, pcm_data, pcm_data_size);
communicator->onIncomingPcmSamples(communicator->callId, sessionId, sequenceNumber, pcm_data, pcm_data_size);
}

virtual void channelState(
Expand All @@ -39,6 +40,26 @@ namespace mumble {
communicator->onServerSync();
};

/*
virtual void onUserState(
int32_t session,
int32_t actor,
std::string name,
int32_t user_id,
int32_t channel_id,
int32_t mute,
int32_t deaf,
int32_t suppress,
int32_t self_mute,
int32_t self_deaf,
std::string comment,
int32_t priority_speaker,
int32_t recording
) override {
communicator->onUserState();
};
*/

};
}

Expand All @@ -51,14 +72,48 @@ void mumble::MumbleCommunicator::connect(MumbleCommunicatorConfig &config) {

callback.reset(new MumlibCallback());

mumbleConf = config;

mumConfig = mumlib::MumlibConfiguration();
mumConfig.opusEncoderBitrate = config.opusEncoderBitrate;
mumConfig.cert_file = config.cert_file;
mumConfig.privkey_file = config.privkey_file;

mum.reset(new mumlib::Mumlib(*callback, ioService, mumConfig));
callback->communicator = this;
callback->mum = mum;

mum->connect(config.host, config.port, config.user, config.password);
// IMPORTANT: comment these out when experimenting with onConnect
if ( ! MUM_DELAYED_CONNECT ) {
mum->connect(config.host, config.port, config.user, config.password);
if ( mumbleConf.autodeaf ) {
mum->sendUserState(mumlib::UserState::SELF_DEAF, true);
}
}
}

void mumble::MumbleCommunicator::onConnect() {
if ( MUM_DELAYED_CONNECT ) {
mum->connect(mumbleConf.host, mumbleConf.port, mumbleConf.user, mumbleConf.password);
}

if ( mumbleConf.comment.size() > 0 ) {
mum->sendUserState(mumlib::UserState::COMMENT, mumbleConf.comment);
}
if ( mumbleConf.autodeaf ) {
mum->sendUserState(mumlib::UserState::SELF_DEAF, true);
}
}

void mumble::MumbleCommunicator::onDisconnect() {
if ( MUM_DELAYED_CONNECT ) {
mum->disconnect();
} else {
}
}

void mumble::MumbleCommunicator::onCallerAuth() {
//onServerSync();
}

void mumble::MumbleCommunicator::sendPcmSamples(int16_t *samples, unsigned int length) {
Expand All @@ -73,6 +128,49 @@ void mumble::MumbleCommunicator::sendTextMessage(std::string message) {
mum->sendTextMessage(message);
}

/*
void mumble::MumbleCommunicator::onUserState(
int32_t session,
int32_t actor,
std::string name,
int32_t user_id,
int32_t channel_id,
int32_t mute,
int32_t deaf,
int32_t suppress,
int32_t self_mute,
int32_t self_deaf,
std::string comment,
int32_t priority_speaker,
int32_t recording) {

logger::notice("Entered onUserState(...)");

userState.mute = mute;
userState.deaf = deaf;
userState.suppress = suppress;
userState.self_mute = self_mute;
userState.self_deaf = self_deaf;
userState.priority_speaker = priority_speaker;
userState.recording = recording;
}
*/


void mumble::MumbleCommunicator::joinChannel(int channel_id) {
mum->joinChannel(channel_id);

if ( mumbleConf.autodeaf ) {
mum->sendUserState(mumlib::UserState::SELF_DEAF, true);
}
}


void mumble::MumbleCommunicator::sendUserState(mumlib::UserState field, bool val) {
mum->sendUserState(field, val);
}

void mumble::MumbleCommunicator::sendUserState(mumlib::UserState field, std::string val) {
mum->sendUserState(field, val);
}

43 changes: 41 additions & 2 deletions MumbleCommunicator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,13 @@
#include <string>
#include <stdexcept>

// 0 = mumble users connected at start; 1 = connect at dial-in
// TODO: fix mumlib::TransportException when this option is enabled
#define MUM_DELAYED_CONNECT 0

namespace mumble {


class Exception : public std::runtime_error {
public:
Exception(const char *message) : std::runtime_error(message) { }
Expand All @@ -21,8 +26,25 @@ namespace mumble {
std::string user;
std::string password;
std::string host;
std::string cert_file;
std::string privkey_file;
int opusEncoderBitrate;
int port = 0;
bool autodeaf;
std::string comment;
int max_calls = 1;
std::string authchan; // config.ini: channelAuthExpression
};

// This is the subset that is of interest to us
struct MumbleUserState {
int32_t mute;
int32_t deaf;
int32_t suppress;
int32_t self_mute;
int32_t self_deaf;
int32_t priority_speaker;
int32_t recording;
};

class MumbleCommunicator : boost::noncopyable {
Expand All @@ -31,16 +53,20 @@ namespace mumble {
boost::asio::io_service &ioService);

void connect(MumbleCommunicatorConfig &config);
void onConnect();
void onDisconnect();
void onCallerAuth();
//void onCallerUnauth();

virtual ~MumbleCommunicator();

void sendPcmSamples(int16_t *samples, unsigned int length);

/**
* This callback is called when communicator has received samples.
* Arguments: session ID, sequence number, PCM samples, length of samples
* Arguments: call ID, session ID, sequence number, PCM samples, length of samples
*/
std::function<void(int, int, int16_t *, int)> onIncomingPcmSamples;
std::function<void(int, int, int, int16_t *, int)> onIncomingPcmSamples;

/**
* This callback is called when a channel state message (e.g. Channel
Expand All @@ -50,21 +76,34 @@ namespace mumble {

std::function<void()> onServerSync;

std::function<void()> onUserState;

void sendTextMessage(std::string message);

void joinChannel(int channel_id);

void sendUserState(mumlib::UserState field, bool val);

void sendUserState(mumlib::UserState field, std::string val);

MumbleUserState userState;

int callId;

private:
boost::asio::io_service &ioService;

log4cpp::Category &logger;

MumbleCommunicatorConfig mumbleConf;

mumlib::MumlibConfiguration mumConfig;

std::shared_ptr<mumlib::Mumlib> mum;

std::unique_ptr<MumlibCallback> callback;

friend class MumlibCallback;

};
}
Loading