1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
#![deny(missing_debug_implementations)]

#[macro_use]
extern crate bitflags;
extern crate jansson_sys;
extern crate janus_plugin_sys as ffi;
extern crate glib_sys as glib;
extern crate libc;

pub use debug::LogLevel;
pub use debug::log;
pub use ffi::JANUS_PLUGIN_API_VERSION as API_VERSION;
pub use ffi::janus_callbacks as PluginCallbacks;
pub use ffi::janus_plugin as Plugin;
pub use ffi::janus_plugin_result as PluginResultInfo;
pub use ffi::janus_plugin_result_type as PluginResultType;
pub use ffi::janus_plugin_session as PluginSession;
pub use jansson::{JanssonDecodingFlags, JanssonEncodingFlags, JanssonValue, RawJanssonValue};
pub use session::SessionWrapper;
use std::error::Error;
use std::ffi::CStr;
use std::os::raw::{c_char, c_int};
use std::ptr;

pub mod debug;
pub mod sdp;
pub mod session;
pub mod jansson;
pub mod utils;

/// Converts a Janus gateway result code to either success or a potential error.
pub fn get_result(error: i32) -> Result<(), Box<Error>> {
    match error {
        0 => Ok(()),
        e => {
            let msg = unsafe { CStr::from_ptr(ffi::janus_get_api_error(e)).to_str()? };
            Err(From::from(format!("{} (code: {})", msg, e)))
        }
    }
}

/// Allocates a Janus plugin result. Should be destroyed with destroy_result.
pub fn create_result(type_: PluginResultType, text: *const c_char, content: Option<JanssonValue>) -> Box<PluginResultInfo> {
    let content_ptr = match content {
        Some(x) => x.into_raw(),
        None => ptr::null_mut(),
    };
    unsafe { Box::from_raw(ffi::janus_plugin_result_new(type_, text, content_ptr)) }
}

/// Destroys a Janus plugin result.
pub fn destroy_result(result: Box<PluginResultInfo>) {
    unsafe { ffi::janus_plugin_result_destroy(Box::into_raw(result)) }
}

#[derive(Debug)]
/// Represents metadata about this plugin which Janus can query at runtime.
pub struct PluginMetadata {
    pub version: c_int,
    pub version_str: *const c_char,
    pub description: *const c_char,
    pub name: *const c_char,
    pub author: *const c_char,
    pub package: *const c_char,
}

/// Helper macro to produce a Janus plugin instance. Should be called with
/// a PluginMetadata instance and a series of exported plugin event handlers.
#[macro_export]
macro_rules! build_plugin {
    ($md:expr, $($cb:ident),*) => {{
        extern "C" fn get_api_compatibility() -> c_int { $crate::API_VERSION }
        extern "C" fn get_version() -> c_int { $md.version }
        extern "C" fn get_version_string() -> *const c_char { $md.version_str }
        extern "C" fn get_description() -> *const c_char { $md.description }
        extern "C" fn get_name() -> *const c_char { $md.name }
        extern "C" fn get_author() -> *const c_char { $md.author }
        extern "C" fn get_package() -> *const c_char { $md.package }
        $crate::Plugin {
            get_api_compatibility,
            get_version,
            get_version_string,
            get_description,
            get_name,
            get_author,
            get_package,
            $($cb,)*
        }
    }}
}

/// Macro to export a Janus plugin instance from this module.
#[macro_export]
macro_rules! export_plugin {
    ($pl:expr) => {
        /// Called by Janus to create an instance of this plugin, using the provided callbacks to dispatch events.
        #[no_mangle]
        pub extern "C" fn create() -> *const $crate::Plugin { $pl }
    }
}