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 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; 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#[derive(Debug, Clone, Copy)]
51pub struct JanusError {
52 pub code: i32
53}
54
55pub type JanusResult = Result<(), JanusError>;
57
58impl JanusError {
59 pub fn to_cstr(self) -> &'static CStr {
61 unsafe { CStr::from_ptr(ffi::janus_get_api_error(self.code)) }
62 }
63 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#[derive(Debug)]
83pub struct PluginResult {
84 ptr: *mut RawPluginResult,
85}
86
87impl PluginResult {
88 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 pub fn ok(response: JanssonValue) -> Self {
96 unsafe { Self::new(PluginResultType::JANUS_PLUGIN_OK, ptr::null(), response.into_raw()) }
97 }
98
99 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 pub fn error(msg: &'static CStr) -> Self {
109 unsafe { Self::new(PluginResultType::JANUS_PLUGIN_ERROR, msg.as_ptr(), ptr::null_mut()) }
110 }
111
112 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)]
138pub 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#[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_export]
176macro_rules! export_plugin {
177 ($pl:expr) => {
178 #[no_mangle]
180 pub extern "C" fn create() -> *const $crate::Plugin { $pl }
181 }
182}
183
184#[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_export]
212macro_rules! export_eventhandler {
213 ($evh:expr) => {
214 #[no_mangle]
216 pub extern "C" fn create() -> *const $crate::EventHandler { $evh }
217 }
218}