diff --git a/include/mumlib/Audio.hpp b/include/mumlib/Audio.hpp index a71d73f..2010fdc 100644 --- a/include/mumlib/Audio.hpp +++ b/include/mumlib/Audio.hpp @@ -8,6 +8,8 @@ namespace mumlib { constexpr int SAMPLE_RATE = 48000; + class MumlibException; + class AudioException : public MumlibException { public: AudioException(string message) : MumlibException(message) { } diff --git a/include/mumlib/Callback.hpp b/include/mumlib/Callback.hpp index 896f5b1..ebb712e 100644 --- a/include/mumlib/Callback.hpp +++ b/include/mumlib/Callback.hpp @@ -10,7 +10,7 @@ namespace mumlib { class Callback { public: - virtual void version_callback( + virtual void version( uint16_t major, uint8_t minor, uint8_t patch, @@ -18,23 +18,23 @@ namespace mumlib { string os, string os_version) { }; - virtual void audio_callback( - uint8_t *pcm_data, + virtual void audio( + int16_t *pcm_data, uint32_t pcm_data_size) { }; - virtual void unsupported_audio_callback( + virtual void unsupportedAudio( uint8_t *encoded_audio_data, uint32_t encoded_audio_data_size) { }; - virtual void serversync_callback( + virtual void serverSync( string welcome_text, int32_t session, int32_t max_bandwidth, int64_t permissions) { }; - virtual void channelremove_callback(uint32_t channel_id) { }; + virtual void channelRemove(uint32_t channel_id) { }; - virtual void channelstate_callback( + virtual void channelState( string name, int32_t channel_id, int32_t parent, @@ -45,13 +45,13 @@ namespace mumlib { bool temporary, int32_t position) { }; - virtual void userremove_callback( + virtual void userRemove( uint32_t session, int32_t actor, string reason, bool ban) { }; - virtual void userstate_callback( + virtual void userState( int32_t session, int32_t actor, string name, @@ -66,8 +66,8 @@ namespace mumlib { int32_t priority_speaker, int32_t recording) { }; - virtual void banlist_callback( - uint8_t *ip_data, + virtual void banList( + const uint8_t *ip_data, uint32_t ip_data_size, uint32_t mask, string name, @@ -76,17 +76,14 @@ namespace mumlib { string start, int32_t duration) { }; - virtual void textmessage_callback( + virtual void textMessage( uint32_t actor, - uint32_t n_session, - uint32_t *session, - uint32_t n_channel_id, - uint32_t *channel_id, - uint32_t n_tree_id, - uint32_t *tree_id, + std::vector session, + std::vector channel_id, + std::vector tree_id, string message) { }; - virtual void permissiondenied_callback( + virtual void permissionDenied( int32_t permission, int32_t channel_id, int32_t session, @@ -94,64 +91,48 @@ namespace mumlib { int32_t deny_type, string name) { }; - virtual void acl_callback() { }; - - virtual void queryusers_callback( + virtual void queryUsers( uint32_t n_ids, uint32_t *ids, uint32_t n_names, string *names) { }; - virtual void cryptsetup_callback( - uint32_t key_size, - uint8_t *key, - uint32_t client_nonce_size, - uint8_t *client_nonce, - uint32_t server_nonce_size, - uint8_t *server_nonce) { }; - - virtual void contextactionmodify_callback( + virtual void contextActionModify( string action, string text, uint32_t m_context, uint32_t operation) { }; - virtual void contextaction_callback( + virtual void contextAction( int32_t session, int32_t channel_id, string action) { }; - virtual void userlist_callback( + virtual void userList( uint32_t user_id, string name, string last_seen, int32_t last_channel) { }; - virtual void voicetarget_callback() { }; - - virtual void permissionquery_callback( + virtual void permissionQuery( int32_t channel_id, uint32_t permissions, int32_t flush) { }; - virtual void codecversion_callback( + virtual void codecVersion( int32_t alpha, int32_t beta, uint32_t prefer_alpha, int32_t opus) { }; - virtual void userstats_callback() { }; - - virtual void requestblob_callback() { }; - - virtual void serverconfig_callback( + virtual void serverConfig( uint32_t max_bandwidth, string welcome_text, uint32_t allow_html, uint32_t message_length, uint32_t image_message_length) { }; - virtual void suggestconfig_callback( + virtual void suggestConfig( uint32_t version, uint32_t positional, uint32_t push_to_talk) { }; @@ -166,7 +147,7 @@ namespace mumlib { ~BasicCallback(); - virtual void version_callback( + virtual void version( uint16_t major, uint8_t minor, uint8_t patch, @@ -174,23 +155,23 @@ namespace mumlib { string os, string os_version); - virtual void audio_callback( - uint8_t *pcm_data, + virtual void audio( + int16_t *pcm_data, uint32_t pcm_data_size); - virtual void unsupported_audio_callback( + virtual void unsupportedAudio( uint8_t *encoded_audio_data, uint32_t encoded_audio_data_size); - virtual void serversync_callback( + virtual void serverSync( string welcome_text, int32_t session, int32_t max_bandwidth, int64_t permissions); - virtual void channelremove_callback(uint32_t channel_id); + virtual void channelRemove(uint32_t channel_id); - virtual void channelstate_callback( + virtual void channelState( string name, int32_t channel_id, int32_t parent, @@ -201,13 +182,13 @@ namespace mumlib { bool temporary, int32_t position); - virtual void userremove_callback( + virtual void userRemove( uint32_t session, int32_t actor, string reason, bool ban); - virtual void userstate_callback( + virtual void userState( int32_t session, int32_t actor, string name, @@ -222,8 +203,8 @@ namespace mumlib { int32_t priority_speaker, int32_t recording); - virtual void banlist_callback( - uint8_t *ip_data, + virtual void banList( + const uint8_t *ip_data, uint32_t ip_data_size, uint32_t mask, string name, @@ -232,17 +213,14 @@ namespace mumlib { string start, int32_t duration); - virtual void textmessage_callback( + virtual void textMessage( uint32_t actor, - uint32_t n_session, - uint32_t *session, - uint32_t n_channel_id, - uint32_t *channel_id, - uint32_t n_tree_id, - uint32_t *tree_id, + std::vector session, + std::vector channel_id, + std::vector tree_id, string message); - virtual void permissiondenied_callback( + virtual void permissionDenied( int32_t permission, int32_t channel_id, int32_t session, @@ -250,64 +228,48 @@ namespace mumlib { int32_t deny_type, string name); - virtual void acl_callback(); - - virtual void queryusers_callback( + virtual void queryUsers( uint32_t n_ids, uint32_t *ids, uint32_t n_names, string *names); - virtual void cryptsetup_callback( - uint32_t key_size, - uint8_t *key, - uint32_t client_nonce_size, - uint8_t *client_nonce, - uint32_t server_nonce_size, - uint8_t *server_nonce); - - virtual void contextactionmodify_callback( + virtual void contextActionModify( string action, string text, uint32_t m_context, uint32_t operation); - virtual void contextaction_callback( + virtual void contextAction( int32_t session, int32_t channel_id, string action); - virtual void userlist_callback( + virtual void userList( uint32_t user_id, string name, string last_seen, int32_t last_channel); - virtual void voicetarget_callback(); - - virtual void permissionquery_callback( + virtual void permissionQuery( int32_t channel_id, uint32_t permissions, int32_t flush); - virtual void codecversion_callback( + virtual void codecVersion( int32_t alpha, int32_t beta, uint32_t prefer_alpha, int32_t opus); - virtual void userstats_callback(); - - virtual void requestblob_callback(); - - virtual void serverconfig_callback( + virtual void serverConfig( uint32_t max_bandwidth, string welcome_text, uint32_t allow_html, uint32_t message_length, uint32_t image_message_length); - virtual void suggestconfig_callback( + virtual void suggestConfig( uint32_t version, uint32_t positional, uint32_t push_to_talk); diff --git a/mumlib_example.cpp b/mumlib_example.cpp index 86c162f..b41b8bb 100644 --- a/mumlib_example.cpp +++ b/mumlib_example.cpp @@ -31,7 +31,7 @@ int main(int argc, char *argv[]) { log4cpp::Appender *appender1 = new log4cpp::OstreamAppender("console", &std::cout); appender1->setLayout(new log4cpp::BasicLayout()); log4cpp::Category &logger = log4cpp::Category::getRoot(); - logger.setPriority(log4cpp::Priority::WARN); + logger.setPriority(log4cpp::Priority::DEBUG); logger.addAppender(appender1); if (argc < 3) { diff --git a/src/Audio.cpp b/src/Audio.cpp index 7b54f9a..6052f06 100644 --- a/src/Audio.cpp +++ b/src/Audio.cpp @@ -4,7 +4,7 @@ mumlib::Audio::Audio() : - logger(log4cpp::Category::getInstance("Mumlib.Audio")), + logger(log4cpp::Category::getInstance("mumlib.Audio")), opusDecoder(nullptr), opusEncoder(nullptr), outgoingSequenceNumber(1) { diff --git a/src/Callback.cpp b/src/Callback.cpp index b330231..f98f7de 100644 --- a/src/Callback.cpp +++ b/src/Callback.cpp @@ -9,10 +9,11 @@ using namespace mumlib; namespace mumlib { struct _BasicCallback_Private : boost::noncopyable { public: - _BasicCallback_Private() : logger(log4cpp::Category::getInstance("BasicCallback")) { } + _BasicCallback_Private() : logger(log4cpp::Category::getInstance("mumlib.BasicCallback")) { } log4cpp::Category &logger; }; + } mumlib::BasicCallback::BasicCallback() { @@ -23,160 +24,102 @@ mumlib::BasicCallback::~BasicCallback() { delete impl; } -void mumlib::BasicCallback::version_callback( +void mumlib::BasicCallback::version( uint16_t major, uint8_t minor, uint8_t patch, string release, string os, string os_version) { - impl->logger.debug("Version Callback: v%d.%d.%d. %s/%s/%s\n", major, minor, patch, release.c_str(), os.c_str(), + impl->logger.debug("version: v%d.%d.%d. %s/%s/%s\n", major, minor, patch, release.c_str(), os.c_str(), os_version.c_str()); } -void mumlib::BasicCallback::audio_callback( - uint8_t *pcm_data, +void mumlib::BasicCallback::audio( + int16_t *pcmData, uint32_t pcm_data_size) { - impl->logger.debug("Received %d bytes of raw PCM data.", pcm_data_size); + impl->logger.debug("audio: %d bytes of raw PCM data.", pcm_data_size); } -void mumlib::BasicCallback::unsupported_audio_callback( - uint8_t *encoded_audio_data, - uint32_t encoded_audio_data_size) { - impl->logger.debug("Received %d bytes of encoded audio data.", encoded_audio_data_size); +void BasicCallback::unsupportedAudio(uint8_t *encoded_audio_data, uint32_t encoded_audio_data_size) { + impl->logger.debug("unsupportedAudio: received %d bytes of encoded data.", encoded_audio_data_size); } -void mumlib::BasicCallback::serversync_callback( - string welcome_text, - int32_t session, - int32_t max_bandwidth, - int64_t permissions) { - impl->logger.debug("Text: %s, session: %d, max bandwidth: %d, permissions: %d", welcome_text.c_str(), session, +void BasicCallback::serverSync(string welcome_text, int32_t session, int32_t max_bandwidth, int64_t permissions) { + impl->logger.debug("serverSync: text: %s, session: %d, max bandwidth: %d, permissions: %d", welcome_text.c_str(), + session, max_bandwidth, permissions); } -void mumlib::BasicCallback::channelremove_callback(uint32_t channel_id) { } - -void mumlib::BasicCallback::channelstate_callback( - string name, - int32_t channel_id, - int32_t parent, - string description, - vector links, - vector inks_add, - vector links_remove, - bool temporary, - int32_t position) { - impl->logger.debug("Obtained channel state %d: %s, %s", channel_id, name.c_str(), description.c_str()); +void BasicCallback::channelRemove(uint32_t channel_id) { + impl->logger.debug("channelRemove: %d", channel_id); } -void mumlib::BasicCallback::userremove_callback( - uint32_t session, - int32_t actor, - string reason, - bool ban) { } +void BasicCallback::channelState(string name, int32_t channel_id, int32_t parent, string description, + vector links, vector inks_add, vector links_remove, + bool temporary, int32_t position) { + impl->logger.debug("channelState: %d: %s, %s", channel_id, name.c_str(), description.c_str()); +} -void mumlib::BasicCallback::userstate_callback( - int32_t session, - int32_t actor, - 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, - string comment, - int32_t priority_speaker, - int32_t recording) { } +void BasicCallback::userRemove(uint32_t session, int32_t actor, string reason, bool ban) { + impl->logger.debug("userRemove: session: %d, actor: %d, reason: %s, ban: %d.", session, actor, reason.c_str(), ban); +} -void mumlib::BasicCallback::banlist_callback( - uint8_t *ip_data, - uint32_t ip_data_size, - uint32_t mask, - string name, - string hash, - string reason, - string start, - int32_t duration) { } +void BasicCallback::userState(int32_t session, int32_t actor, 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, + string comment, int32_t priority_speaker, int32_t recording) { + impl->logger.debug("userState: %s: mute: %d, deaf: %d, suppress: %d, self mute: %d, self deaf: %d", + name.c_str(), mute, deaf, suppress, self_mute, self_deaf); +} -void mumlib::BasicCallback::textmessage_callback( +void BasicCallback::banList(const uint8_t *ip_data, uint32_t ip_data_size, uint32_t mask, string name, string hash, + string reason, string start, int32_t duration) { + impl->logger.debug("banList: %s, hash: %s, reason: %s", name.c_str(), hash.c_str(), reason.c_str()); +} + +void BasicCallback::textMessage( uint32_t actor, - uint32_t n_session, - uint32_t *session, - uint32_t n_channel_id, - uint32_t *channel_id, - uint32_t n_tree_id, - uint32_t *tree_id, - string message) { } + std::vector session, + std::vector channel_id, + std::vector tree_id, + string message) { + impl->logger.debug("textMessage: %d: %s", actor, message.c_str()); +} -void mumlib::BasicCallback::permissiondenied_callback( - int32_t permission, - int32_t channel_id, - int32_t session, - string reason, - int32_t deny_type, - string name) { } +void BasicCallback::permissionDenied(int32_t permission, int32_t channel_id, int32_t session, string reason, + int32_t deny_type, string name) { + impl->logger.debug("permissionDenied: %s %s", name.c_str(), reason.c_str()); +} -void mumlib::BasicCallback::acl_callback() { } +void BasicCallback::queryUsers(uint32_t n_ids, uint32_t *ids, uint32_t n_names, string *names) { + impl->logger.debug("queryUsers: %d users", n_names); //todo make it more high-level +} -void mumlib::BasicCallback::queryusers_callback( - uint32_t n_ids, - uint32_t *ids, - uint32_t n_names, - string *names) { } +void BasicCallback::contextActionModify(string action, string text, uint32_t m_context, uint32_t operation) { + impl->logger.debug("contextActionModify: "); +} -void mumlib::BasicCallback::cryptsetup_callback( - uint32_t key_size, - uint8_t *key, - uint32_t client_nonce_size, - uint8_t *client_nonce, - uint32_t server_nonce_size, - uint8_t *server_nonce) { } +void BasicCallback::contextAction(int32_t session, int32_t channel_id, string action) { + impl->logger.debug("contextAction."); +} -void mumlib::BasicCallback::contextactionmodify_callback( - string action, - string text, - uint32_t m_context, - uint32_t operation) { } +void BasicCallback::userList(uint32_t user_id, string name, string last_seen, int32_t last_channel) { + impl->logger.debug("userList."); +} -void mumlib::BasicCallback::contextaction_callback( - int32_t session, - int32_t channel_id, - string action) { } +void BasicCallback::permissionQuery(int32_t channel_id, uint32_t permissions, int32_t flush) { + impl->logger.debug("permissionQuery."); +} -void mumlib::BasicCallback::userlist_callback( - uint32_t user_id, - string name, - string last_seen, - int32_t last_channel) { } +void BasicCallback::codecVersion(int32_t alpha, int32_t beta, uint32_t prefer_alpha, int32_t opus) { + impl->logger.debug("codecVersion."); +} -void mumlib::BasicCallback::voicetarget_callback() { } +void BasicCallback::serverConfig(uint32_t max_bandwidth, string welcome_text, uint32_t allow_html, + uint32_t message_length, uint32_t image_message_length) { + impl->logger.debug("serverConfig: %s", welcome_text.c_str()); +} -void mumlib::BasicCallback::permissionquery_callback( - int32_t channel_id, - uint32_t permissions, - int32_t flush) { } - -void mumlib::BasicCallback::codecversion_callback( - int32_t alpha, - int32_t beta, - uint32_t prefer_alpha, - int32_t opus) { } - -void mumlib::BasicCallback::userstats_callback() { } - -void mumlib::BasicCallback::requestblob_callback() { } - -void mumlib::BasicCallback::serverconfig_callback( - uint32_t max_bandwidth, - string welcome_text, - uint32_t allow_html, - uint32_t message_length, - uint32_t image_message_length) { } - -void mumlib::BasicCallback::suggestconfig_callback( - uint32_t version, - uint32_t positional, - uint32_t push_to_talk) { } +void BasicCallback::suggestConfig(uint32_t version, uint32_t positional, uint32_t push_to_talk) { + impl->logger.debug("suggestConfig."); +} diff --git a/src/Transport.cpp b/src/Transport.cpp index fd88461..1909401 100644 --- a/src/Transport.cpp +++ b/src/Transport.cpp @@ -30,7 +30,7 @@ mumlib::Transport::Transport( mumlib::ProcessControlMessageFunction processMessageFunc, ProcessEncodedAudioPacketFunction processEncodedAudioPacketFunction, bool noUdp) : - logger(log4cpp::Category::getInstance("Mumlib.Transport")), + logger(log4cpp::Category::getInstance("mumlib.Transport")), ioService(ioService), processMessageFunction(processMessageFunc), processEncodedAudioPacketFunction(processEncodedAudioPacketFunction), @@ -154,7 +154,7 @@ void mumlib::Transport::doReceiveUdp() { if (udpActive == false) { udpActive = true; - logger.info("UDP is up."); + logger.notice("UDP is up."); } uint8_t plainBuffer[1024]; @@ -376,12 +376,6 @@ void mumlib::Transport::processMessageInternal(MessageType messageType, uint8_t } } break; - case MessageType::VOICETARGET: { - MumbleProto::VoiceTarget voiceTarget; - voiceTarget.ParseFromArray(buffer, length); - logger.warn("VoiceTarget Message: I don't think the server ever sends this structure...."); - } - break; default: { logger.debug("Calling external ProcessControlMessageFunction."); processMessageFunction(messageType, buffer, length); diff --git a/src/mumlib.cpp b/src/mumlib.cpp index 88faa1a..e912294 100644 --- a/src/mumlib.cpp +++ b/src/mumlib.cpp @@ -1,11 +1,11 @@ -#include "mumlib.hpp" - #include "mumlib/CryptState.hpp" #include "mumlib/VarInt.hpp" #include "mumlib/enums.hpp" #include "mumlib/Transport.hpp" #include "mumlib/Audio.hpp" +#include "mumlib.hpp" + #include #include #include @@ -35,7 +35,7 @@ namespace mumlib { case MessageType::VERSION: { MumbleProto::Version version; version.ParseFromArray(buffer, length); - callback->version_callback( + callback->version( version.version() >> 16, version.version() >> 8 & 0xff, version.version() & 0xff, @@ -47,7 +47,7 @@ namespace mumlib { case MessageType::SERVERSYNC: { MumbleProto::ServerSync serverSync; serverSync.ParseFromArray(buffer, length); - callback->serversync_callback( + callback->serverSync( serverSync.welcome_text(), serverSync.session(), serverSync.max_bandwidth(), @@ -58,7 +58,7 @@ namespace mumlib { case MessageType::CHANNELREMOVE: { MumbleProto::ChannelRemove channelRemove; channelRemove.ParseFromArray(buffer, length); - callback->channelremove_callback(channelRemove.channel_id()); + callback->channelRemove(channelRemove.channel_id()); } break; case MessageType::CHANNELSTATE: { @@ -83,7 +83,7 @@ namespace mumlib { std::copy(channelState.links_remove().begin(), channelState.links_remove().end(), links_remove.begin()); - callback->channelstate_callback( + callback->channelState( channelState.name(), channel_id, parent, @@ -104,7 +104,7 @@ namespace mumlib { bool ban = user_remove.has_ban() ? user_remove.ban() : false; //todo make sure it's correct to assume it's false - callback->userremove_callback( + callback->userRemove( user_remove.session(), actor, user_remove.reason(), @@ -112,64 +112,150 @@ namespace mumlib { ); } break; - case MessageType::USERSTATE: // 9 -// return MessageType::private_process_userstate(context, message, message_size); + case MessageType::USERSTATE: { + MumbleProto::UserState userState; + userState.ParseFromArray(buffer, length); + // There are far too many things in this structure. Culling to the ones that are probably important + int32_t session = userState.has_session() ? userState.session() : -1; + int32_t actor = userState.has_actor() ? userState.actor() : -1; + int32_t user_id = userState.has_user_id() ? userState.user_id() : -1; + int32_t channel_id = userState.has_channel_id() ? userState.channel_id() : -1; + int32_t mute = userState.has_mute() ? userState.mute() : -1; + int32_t deaf = userState.has_deaf() ? userState.deaf() : -1; + int32_t suppress = userState.has_suppress() ? userState.suppress() : -1; + int32_t self_mute = userState.has_self_mute() ? userState.self_mute() : -1; + int32_t self_deaf = userState.has_self_deaf() ? userState.self_deaf() : -1; + int32_t priority_speaker = userState.has_priority_speaker() ? userState.priority_speaker() : -1; + int32_t recording = userState.has_recording() ? userState.recording() : -1; + + callback->userState(session, + actor, + userState.name(), + user_id, + channel_id, + mute, + deaf, + suppress, + self_mute, + self_deaf, + userState.comment(), + priority_speaker, + recording); + } break; - case MessageType::BANLIST: // 10 -// return MessageType::private_process_banlist(context, message, message_size); + case MessageType::BANLIST: { + MumbleProto::BanList ban_list; + ban_list.ParseFromArray(buffer, length); + for (int i = 0; i < ban_list.bans_size(); i++) { + auto ban = ban_list.bans(i); + const uint8_t *ip_data = reinterpret_cast(ban.address().c_str()); + uint32_t ip_data_size = ban.address().size(); + int32_t duration = ban.has_duration() ? ban.duration() : -1; + + callback->banList( + ip_data, + ip_data_size, + ban.mask(), + ban.name(), + ban.hash(), + ban.reason(), + ban.start(), + duration); + } + } break; - case MessageType::TEXTMESSAGE: // 11 -// return MessageType::private_process_textmessage(context, message, message_size); + case MessageType::TEXTMESSAGE: { + MumbleProto::TextMessage text_message; + text_message.ParseFromArray(buffer, length); + int32_t actor = text_message.has_actor() ? text_message.actor() : -1; + + vector sessions; + for (int i = 0; i < text_message.session_size(); ++i) { + sessions.push_back(text_message.session(i)); + } + + vector channel_ids; + for (int i = 0; i < text_message.channel_id_size(); ++i) { + channel_ids.push_back(text_message.channel_id(i)); + } + + vector tree_ids; + for (int i = 0; i < text_message.tree_id_size(); ++i) { + tree_ids.push_back(text_message.tree_id(i)); + } + + callback->textMessage(actor, sessions, channel_ids, tree_ids, text_message.message()); + } break; case MessageType::PERMISSIONDENIED: // 12 -// return MessageType::private_process_permissiondenied(context, message, message_size); - + logger->warn("PermissionDenied Message: support not implemented yet"); break; case MessageType::ACL: // 13 -// return MessageType::private_process_acl(context, message, message_size); - + logger->warn("ACL Message: support not implemented yet."); break; case MessageType::QUERYUSERS: // 14 -// return MessageType::private_process_queryusers(context, message, message_size); - + logger->warn("QueryUsers Message: support not implemented yet"); break; case MessageType::CONTEXTACTIONMODIFY: // 16 -// return MessageType::private_process_contextactionmodify(context, message, message_size); - + logger->warn("ContextActionModify Message: support not implemented yet"); break; case MessageType::CONTEXTACTION: // 17 -// return MessageType::private_process_contextaction(context, message, message_size); - + logger->warn("ContextAction Message: support not implemented yet"); break; case MessageType::USERLIST: // 18 -// return MessageType::private_process_userlist(context, message, message_size); - + logger->warn("UserList Message: support not implemented yet"); break; - case MessageType::PERMISSIONQUERY: // 20 -// return MessageType::private_process_permission_query(context, message, message_size); - + case MessageType::VOICETARGET: + logger->warn("VoiceTarget Message: I don't think the server ever sends this structure."); break; - case MessageType::CODECVERSION: // 21 -// return MessageType::private_process_codecversion(context, message, message_size); + case MessageType::PERMISSIONQUERY: { + MumbleProto::PermissionQuery permissionQuery; + permissionQuery.ParseFromArray(buffer, length); + int32_t channel_id = permissionQuery.has_channel_id() ? permissionQuery.channel_id() : -1; + uint32_t permissions = permissionQuery.has_permissions() ? permissionQuery.permissions() : 0; + uint32_t flush = permissionQuery.has_flush() ? permissionQuery.flush() : -1; + + callback->permissionQuery(channel_id, permissions, flush); + } break; - case MessageType::USERSTATS: // 22 -// return MessageType::private_process_userstats(context, message, message_size); + case MessageType::CODECVERSION: { + MumbleProto::CodecVersion codecVersion; + codecVersion.ParseFromArray(buffer, length); + int32_t alpha = codecVersion.alpha(); + int32_t beta = codecVersion.beta(); + uint32_t prefer_alpha = codecVersion.prefer_alpha(); + int32_t opus = codecVersion.has_opus() ? codecVersion.opus() : 0; + + callback->codecVersion(alpha, beta, prefer_alpha, opus); + } + break; + case MessageType::USERSTATS: + logger->warn("UserStats Message: support not implemented yet"); break; case MessageType::REQUESTBLOB: // 23 -// return MessageType::private_process_requestblob(context, message, message_size); - + logger->warn("RequestBlob Message: I don't think this is sent by the server."); break; - case MessageType::SERVERCONFIG: // 24 -// return MessageType::private_process_serverconfig(context, message, message_size); + case MessageType::SERVERCONFIG: { + MumbleProto::ServerConfig serverConfig; + serverConfig.ParseFromArray(buffer, length); + uint32_t max_bandwidth = serverConfig.has_max_bandwidth() ? serverConfig.max_bandwidth() : 0; + uint32_t allow_html = serverConfig.has_allow_html() ? serverConfig.allow_html() : 0; + uint32_t message_length = serverConfig.has_message_length() ? serverConfig.message_length() : 0; + uint32_t image_message_length = serverConfig.has_image_message_length() + ? serverConfig.image_message_length() : 0; + + callback->serverConfig(max_bandwidth, serverConfig.welcome_text(), allow_html, message_length, + image_message_length); + } break; case MessageType::SUGGESTCONFIG: // 25 -// return MessageType::private_process_suggestconfig(context, message, message_size); + logger->warn("SuggestConfig Message: support not implemented yet"); break; default: throw MumlibException("unknown message type: " + to_string(static_cast(messageType))); @@ -179,8 +265,14 @@ namespace mumlib { bool processAudioPacket(AudioPacketType type, uint8_t *buffer, int length) { logger->info("Got %d B of encoded audio data.", length); - int16_t pcmData[5000]; - audio->decodeAudioPacket(type, buffer, length, pcmData, 5000); + try { + int16_t pcmData[5000]; + int pcmDataLength = audio->decodeAudioPacket(type, buffer, length, pcmData, 5000); + callback->audio(pcmData, pcmDataLength); + } catch (mumlib::AudioException &exp) { + logger->warn("Audio decode error: %s, calling unsupportedAudio callback.", exp.what()); + callback->unsupportedAudio(buffer, length); + } } }; @@ -192,7 +284,7 @@ namespace mumlib { } mumlib::Mumlib::Mumlib() : impl(new _Mumlib_Private) { - impl->logger = &(log4cpp::Category::getInstance("Mumlib.Mumlib")); + impl->logger = &(log4cpp::Category::getInstance("mumlib.Mumlib")); impl->externalIoService = false; impl->ioService = new io_service(); impl->audio = new Audio();