Static Webview - RTC - UDP - TCP - WSS
This commit is contained in:
232
Sources/rtc_bridge.cpp
Normal file
232
Sources/rtc_bridge.cpp
Normal file
@ -0,0 +1,232 @@
|
||||
#include "rtc_bridge.h"
|
||||
|
||||
#include <rtc/rtc.h>
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#include <bcrypt.h>
|
||||
#else
|
||||
#include <cstdio>
|
||||
#endif
|
||||
|
||||
static std::mutex *g_rtc_mutex = new std::mutex;
|
||||
static std::deque<RtcEvent> *g_rtc_events = new std::deque<RtcEvent>;
|
||||
|
||||
static void rtc_push(RtcEvent &&ev) {
|
||||
std::lock_guard<std::mutex> lock(*g_rtc_mutex);
|
||||
g_rtc_events->push_back(std::move(ev));
|
||||
}
|
||||
|
||||
bool runt_rtc_poll_event(RtcEvent &out) {
|
||||
std::lock_guard<std::mutex> lock(*g_rtc_mutex);
|
||||
if (g_rtc_events->empty()) return false;
|
||||
out = std::move(g_rtc_events->front());
|
||||
g_rtc_events->pop_front();
|
||||
return true;
|
||||
}
|
||||
|
||||
static void RTC_API rtc_description_cb(int pc, const char *sdp, const char *type, void *ptr) {
|
||||
RtcEvent ev;
|
||||
ev.type = RtcEventType::LocalDescription;
|
||||
ev.id = pc;
|
||||
ev.s1 = sdp != nullptr ? sdp : "";
|
||||
ev.s2 = type != nullptr ? type : "";
|
||||
rtc_push(std::move(ev));
|
||||
}
|
||||
|
||||
static void RTC_API rtc_candidate_cb(int pc, const char *cand, const char *mid, void *ptr) {
|
||||
RtcEvent ev;
|
||||
ev.type = RtcEventType::LocalCandidate;
|
||||
ev.id = pc;
|
||||
ev.s1 = cand != nullptr ? cand : "";
|
||||
ev.s2 = mid != nullptr ? mid : "";
|
||||
rtc_push(std::move(ev));
|
||||
}
|
||||
|
||||
static void RTC_API rtc_open_cb(int id, void *ptr);
|
||||
static void RTC_API rtc_closed_cb(int id, void *ptr);
|
||||
static void RTC_API rtc_error_cb(int id, const char *error, void *ptr);
|
||||
static void RTC_API rtc_message_cb(int id, const char *message, int size, void *ptr);
|
||||
|
||||
static void RTC_API rtc_state_cb(int pc, rtcState state, void *ptr) {
|
||||
RtcEvent ev;
|
||||
ev.type = RtcEventType::StateChange;
|
||||
ev.id = pc;
|
||||
ev.arg = (int)state;
|
||||
rtc_push(std::move(ev));
|
||||
}
|
||||
|
||||
static void RTC_API rtc_gathering_cb(int pc, rtcGatheringState state, void *ptr) {
|
||||
RtcEvent ev;
|
||||
ev.type = RtcEventType::GatheringState;
|
||||
ev.id = pc;
|
||||
ev.arg = (int)state;
|
||||
rtc_push(std::move(ev));
|
||||
}
|
||||
|
||||
static void rtc_register_dc_callbacks(int dc) {
|
||||
rtcSetOpenCallback(dc, rtc_open_cb);
|
||||
rtcSetClosedCallback(dc, rtc_closed_cb);
|
||||
rtcSetErrorCallback(dc, rtc_error_cb);
|
||||
rtcSetMessageCallback(dc, rtc_message_cb);
|
||||
}
|
||||
|
||||
static void RTC_API rtc_datachannel_cb(int pc, int dc, void *ptr) {
|
||||
rtc_register_dc_callbacks(dc);
|
||||
RtcEvent ev;
|
||||
ev.type = RtcEventType::DataChannel;
|
||||
ev.id = pc;
|
||||
ev.arg = dc;
|
||||
rtc_push(std::move(ev));
|
||||
}
|
||||
|
||||
static void RTC_API rtc_open_cb(int id, void *ptr) {
|
||||
RtcEvent ev;
|
||||
ev.type = RtcEventType::Open;
|
||||
ev.id = id;
|
||||
rtc_push(std::move(ev));
|
||||
}
|
||||
|
||||
static void RTC_API rtc_closed_cb(int id, void *ptr) {
|
||||
RtcEvent ev;
|
||||
ev.type = RtcEventType::Closed;
|
||||
ev.id = id;
|
||||
rtc_push(std::move(ev));
|
||||
}
|
||||
|
||||
static void RTC_API rtc_error_cb(int id, const char *error, void *ptr) {
|
||||
RtcEvent ev;
|
||||
ev.type = RtcEventType::Error;
|
||||
ev.id = id;
|
||||
ev.s1 = error != nullptr ? error : "";
|
||||
rtc_push(std::move(ev));
|
||||
}
|
||||
|
||||
static void RTC_API rtc_message_cb(int id, const char *message, int size, void *ptr) {
|
||||
RtcEvent ev;
|
||||
ev.type = RtcEventType::Message;
|
||||
ev.id = id;
|
||||
if (size < 0) {
|
||||
ev.isString = true;
|
||||
ev.s1 = message != nullptr ? message : "";
|
||||
} else {
|
||||
ev.data.assign(message, message + size);
|
||||
}
|
||||
rtc_push(std::move(ev));
|
||||
}
|
||||
|
||||
int runt_rtc_init() {
|
||||
return rtcPreload() ? 0 : -1;
|
||||
}
|
||||
|
||||
void runt_rtc_cleanup() {
|
||||
rtcCleanup();
|
||||
}
|
||||
|
||||
int runt_rtc_create_peer_connection(const std::vector<std::string> &iceServers) {
|
||||
rtcConfiguration conf;
|
||||
memset(&conf, 0, sizeof(conf));
|
||||
std::vector<const char *> servers(iceServers.size());
|
||||
for (size_t i = 0; i < iceServers.size(); i++) {
|
||||
servers[i] = iceServers[i].c_str();
|
||||
}
|
||||
conf.iceServers = servers.data();
|
||||
conf.iceServersCount = (int)servers.size();
|
||||
int pc = rtcCreatePeerConnection(&conf);
|
||||
if (pc < 0) return pc;
|
||||
rtcSetLocalDescriptionCallback(pc, rtc_description_cb);
|
||||
rtcSetLocalCandidateCallback(pc, rtc_candidate_cb);
|
||||
rtcSetStateChangeCallback(pc, rtc_state_cb);
|
||||
rtcSetGatheringStateChangeCallback(pc, rtc_gathering_cb);
|
||||
rtcSetDataChannelCallback(pc, rtc_datachannel_cb);
|
||||
return pc;
|
||||
}
|
||||
|
||||
void runt_rtc_close_peer_connection(int pc) {
|
||||
rtcClosePeerConnection(pc);
|
||||
}
|
||||
|
||||
void runt_rtc_delete_peer_connection(int pc) {
|
||||
rtcDeletePeerConnection(pc);
|
||||
}
|
||||
|
||||
void runt_rtc_set_local_description(int pc, const char *type) {
|
||||
rtcSetLocalDescription(pc, type);
|
||||
}
|
||||
|
||||
int runt_rtc_set_remote_description(int pc, const char *sdp, const char *type) {
|
||||
return rtcSetRemoteDescription(pc, sdp, type);
|
||||
}
|
||||
|
||||
int runt_rtc_add_remote_candidate(int pc, const char *cand, const char *mid) {
|
||||
return rtcAddRemoteCandidate(pc, cand, mid);
|
||||
}
|
||||
|
||||
std::string runt_rtc_get_local_description(int pc) {
|
||||
int size = rtcGetLocalDescription(pc, nullptr, 0);
|
||||
if (size <= 0) return "";
|
||||
std::string buf(size, '\0');
|
||||
rtcGetLocalDescription(pc, buf.data(), size);
|
||||
return std::string(buf.data(), strnlen(buf.data(), buf.size()));
|
||||
}
|
||||
|
||||
std::string runt_rtc_get_local_description_type(int pc) {
|
||||
char buf[64];
|
||||
int size = rtcGetLocalDescriptionType(pc, buf, sizeof(buf));
|
||||
if (size <= 0) return "";
|
||||
return std::string(buf, strnlen(buf, sizeof(buf)));
|
||||
}
|
||||
|
||||
int runt_rtc_create_data_channel(int pc, const char *label, bool unordered,
|
||||
int maxRetransmits) {
|
||||
rtcDataChannelInit init;
|
||||
memset(&init, 0, sizeof(init));
|
||||
init.reliability.unordered = unordered;
|
||||
init.reliability.unreliable = maxRetransmits >= 0;
|
||||
init.reliability.maxRetransmits =
|
||||
maxRetransmits >= 0 ? (unsigned int)maxRetransmits : 0;
|
||||
int dc = rtcCreateDataChannelEx(pc, label, &init);
|
||||
if (dc < 0) return dc;
|
||||
rtc_register_dc_callbacks(dc);
|
||||
return dc;
|
||||
}
|
||||
|
||||
void runt_rtc_delete_data_channel(int dc) {
|
||||
rtcDeleteDataChannel(dc);
|
||||
}
|
||||
|
||||
int runt_rtc_send_message(int id, const char *data, int size) {
|
||||
return rtcSendMessage(id, data, size);
|
||||
}
|
||||
|
||||
void runt_rtc_close(int id) {
|
||||
rtcClose(id);
|
||||
}
|
||||
|
||||
void runt_rtc_delete(int id) {
|
||||
rtcDelete(id);
|
||||
}
|
||||
|
||||
bool runt_rtc_is_open(int id) {
|
||||
return rtcIsOpen(id);
|
||||
}
|
||||
|
||||
int runt_rtc_get_buffered_amount(int id) {
|
||||
return rtcGetBufferedAmount(id);
|
||||
}
|
||||
|
||||
bool runt_rtc_random_bytes(char *out, int len) {
|
||||
#ifdef _WIN32
|
||||
return BCryptGenRandom(nullptr, reinterpret_cast<PUCHAR>(out),
|
||||
static_cast<ULONG>(len),
|
||||
BCRYPT_USE_SYSTEM_PREFERRED_RNG) == 0;
|
||||
#else
|
||||
FILE *f = fopen("/dev/urandom", "rb");
|
||||
if (f == nullptr) return false;
|
||||
size_t n = fread(out, 1, static_cast<size_t>(len), f);
|
||||
fclose(f);
|
||||
return n == static_cast<size_t>(len);
|
||||
#endif
|
||||
}
|
||||
Reference in New Issue
Block a user