janus_plugin/
lib.rs

1#![deny(missing_debug_implementations)]
2
3use janus_plugin_sys as ffi;
4use bitflags::bitflags;
5pub use debug::LogLevel;
6pub use debug::log;
7pub use jansson::{JanssonDecodingFlags, JanssonEncodingFlags, JanssonValue, RawJanssonValue};
8pub use session::SessionWrapper;
9pub use ffi::events::janus_eventhandler as EventHandler;
10pub use ffi::plugin::janus_callbacks as PluginCallbacks;
11pub use ffi::plugin::janus_plugin as Plugin;
12pub use ffi::plugin::janus_plugin_result as RawPluginResult;
13pub use ffi::plugin::janus_plugin_session as PluginSession;
14pub use ffi::plugin::janus_plugin_rtp as PluginRtpPacket;
15pub use ffi::plugin::janus_plugin_rtcp as PluginRtcpPacket;
16pub use ffi::plugin::janus_plugin_data as PluginDataPacket;
17pub use ffi::plugin::janus_plugin_rtp_extensions as PluginRtpExtensions;
18use ffi::plugin::janus_plugin_result_type as PluginResultType;
19use std::error::Error;
20use std::fmt;
21use std::ffi::CStr;
22use std::mem;
23use std::ops::Deref;
24use std::os::raw::{c_char, c_int};
25use std::ptr;
26
27pub mod debug;
28pub mod rtcp;
29pub mod sdp;
30pub mod session;
31pub mod jansson;
32pub mod utils;
33pub mod refcount;
34
35bitflags! {
36    /// Flags that control which events an event handler receives.
37    pub struct JanusEventType: u32 {
38        const JANUS_EVENT_TYPE_SESSION   = 1 << 0;
39        const JANUS_EVENT_TYPE_HANDLE    = 1 << 1;
40        const JANUS_EVENT_TYPE_JSEP      = 1 << 3; // yes, really
41        const JANUS_EVENT_TYPE_WEBRTC    = 1 << 4;
42        const JANUS_EVENT_TYPE_MEDIA     = 1 << 5;
43        const JANUS_EVENT_TYPE_PLUGIN    = 1 << 6;
44        const JANUS_EVENT_TYPE_TRANSPORT = 1 << 7;
45        const JANUS_EVENT_TYPE_CORE      = 1 << 8;
46    }
47}
48
49/// An error emitted by the Janus core in response to a plugin pushing an event.
50#[derive(Debug, Clone, Copy)]
51pub struct JanusError {
52    pub code: i32
53}
54
55/// A result from pushing an event to Janus core.
56pub type JanusResult = Result<(), JanusError>;
57
58impl JanusError {
59    /// Returns Janus's description text for this error.
60    pub fn to_cstr(self) -> &'static CStr {
61        unsafe { CStr::from_ptr(ffi::janus_get_api_error(self.code)) }
62    }
63    /// Converts a Janus result code to either success or a potential error.
64    pub fn from(val: i32) -> JanusResult {
65        match val {
66            0 => Ok(()),
67            e => Err(JanusError { code: e })
68        }
69    }
70}
71
72impl Error for JanusError {}
73
74impl fmt::Display for JanusError {
75    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
76        write!(f, "{} (code: {})", self.to_cstr().to_str().unwrap()
77, self.code)
78    }
79}
80
81/// A Janus plugin result; what a plugin returns to the gateway as a direct response to a signalling message.
82#[derive(Debug)]
83pub struct PluginResult {
84    ptr: *mut RawPluginResult,
85}
86
87impl PluginResult {
88    /// Creates a new plugin result.
89    pub unsafe fn new(type_: PluginResultType, text: *const c_char, content: *mut RawJanssonValue) -> Self {
90        Self { ptr: ffi::plugin::janus_plugin_result_new(type_, text, content) }
91    }
92
93    /// Creates a plugin result indicating a synchronously successful request. The provided response
94    /// JSON will be passed back to the client.
95    pub fn ok(response: JanssonValue) -> Self {
96        unsafe { Self::new(PluginResultType::JANUS_PLUGIN_OK, ptr::null(), response.into_raw()) }
97    }
98
99    /// Creates a plugin result indicating an asynchronous request in progress. If provided, the hint text
100    /// will be synchronously passed back to the client in the acknowledgement.
101    pub fn ok_wait(hint: Option<&'static CStr>) -> Self {
102        let hint_ptr = hint.map(|x| x.as_ptr()).unwrap_or_else(ptr::null);
103        unsafe { Self::new(PluginResultType::JANUS_PLUGIN_OK_WAIT, hint_ptr, ptr::null_mut()) }
104    }
105
106    /// Creates a plugin result indicating an error. The provided error text will be synchronously passed
107    /// back to the client.
108    pub fn error(msg: &'static CStr) -> Self {
109        unsafe { Self::new(PluginResultType::JANUS_PLUGIN_ERROR, msg.as_ptr(), ptr::null_mut()) }
110    }
111
112    /// Transfers ownership of this result to the wrapped raw pointer. The consumer is responsible for calling
113    /// `janus_plugin_result_destroy` on the pointer when finished.
114    pub fn into_raw(self) -> *mut RawPluginResult {
115        let ptr = self.ptr;
116        mem::forget(self);
117        ptr
118    }
119}
120
121impl Deref for PluginResult {
122    type Target = RawPluginResult;
123
124    fn deref(&self) -> &RawPluginResult {
125        unsafe { &*self.ptr }
126    }
127}
128
129impl Drop for PluginResult {
130    fn drop(&mut self) {
131        unsafe { ffi::plugin::janus_plugin_result_destroy(self.ptr) }
132    }
133}
134
135unsafe impl Send for PluginResult {}
136
137#[derive(Debug)]
138/// Represents metadata about this library which Janus can query at runtime.
139pub struct LibraryMetadata<'a> {
140    pub api_version: c_int,
141    pub version: c_int,
142    pub version_str: &'a CStr,
143    pub description: &'a CStr,
144    pub name: &'a CStr,
145    pub author: &'a CStr,
146    pub package: &'a CStr,
147}
148
149/// Helper macro to produce a Janus plugin instance. Should be called with
150/// a `LibraryMetadata` instance and a series of exported plugin callbacks.
151#[macro_export]
152macro_rules! build_plugin {
153    ($md:expr, $($cb:ident),*) => {{
154        extern "C" fn get_api_compatibility() -> c_int { $md.api_version }
155        extern "C" fn get_version() -> c_int { $md.version }
156        extern "C" fn get_version_string() -> *const c_char { $md.version_str.as_ptr() }
157        extern "C" fn get_description() -> *const c_char { $md.description.as_ptr() }
158        extern "C" fn get_name() -> *const c_char { $md.name.as_ptr() }
159        extern "C" fn get_author() -> *const c_char { $md.author.as_ptr() }
160        extern "C" fn get_package() -> *const c_char { $md.package.as_ptr() }
161        $crate::Plugin {
162            get_api_compatibility,
163            get_version,
164            get_version_string,
165            get_description,
166            get_name,
167            get_author,
168            get_package,
169            $($cb,)*
170        }
171    }}
172}
173
174/// Macro to export a Janus plugin instance from this module.
175#[macro_export]
176macro_rules! export_plugin {
177    ($pl:expr) => {
178        /// Called by Janus to create an instance of this plugin, using the provided callbacks to dispatch events.
179        #[no_mangle]
180        pub extern "C" fn create() -> *const $crate::Plugin { $pl }
181    }
182}
183
184/// Helper macro to produce a Janus event handler instance. Should be called with
185/// a `LibraryMetadata` instance and a series of exported event handler callbacks.
186#[macro_export]
187macro_rules! build_eventhandler {
188    ($md:expr, $mask:expr, $($cb:ident),*) => {{
189        extern "C" fn get_api_compatibility() -> c_int { $md.api_version }
190        extern "C" fn get_version() -> c_int { $md.version }
191        extern "C" fn get_version_string() -> *const c_char { $md.version_str.as_ptr() }
192        extern "C" fn get_description() -> *const c_char { $md.description.as_ptr() }
193        extern "C" fn get_name() -> *const c_char { $md.name.as_ptr() }
194        extern "C" fn get_author() -> *const c_char { $md.author.as_ptr() }
195        extern "C" fn get_package() -> *const c_char { $md.package.as_ptr() }
196        $crate::EventHandler {
197            events_mask: $mask,
198            get_api_compatibility,
199            get_version,
200            get_version_string,
201            get_description,
202            get_name,
203            get_author,
204            get_package,
205            $($cb,)*
206        }
207    }}
208}
209
210/// Macro to export a Janus event handler instance from this module.
211#[macro_export]
212macro_rules! export_eventhandler {
213    ($evh:expr) => {
214        /// Called by Janus to create an instance of this event handler, using the provided callbacks to dispatch events.
215        #[no_mangle]
216        pub extern "C" fn create() -> *const $crate::EventHandler { $evh }
217    }
218}