summaryrefslogtreecommitdiff
path: root/src/WebRTCPeer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/WebRTCPeer.cpp')
-rw-r--r--src/WebRTCPeer.cpp161
1 files changed, 143 insertions, 18 deletions
diff --git a/src/WebRTCPeer.cpp b/src/WebRTCPeer.cpp
index f7572ad..00455c0 100644
--- a/src/WebRTCPeer.cpp
+++ b/src/WebRTCPeer.cpp
@@ -3,7 +3,6 @@
using namespace godot_webrtc;
void WebRTCPeer::set_write_mode(godot_int mode) {
-
}
godot_int WebRTCPeer::get_write_mode() const {
@@ -19,59 +18,185 @@ godot_int WebRTCPeer::get_connection_state() const {
}
godot_error WebRTCPeer::create_offer() {
- return GODOT_FAILED;
+ peer_connection->CreateOffer(
+ ptr_csdo, // CreateSessionDescriptionObserver* observer,
+ nullptr // webrtc::PeerConnectionInterface::RTCOfferAnswerOptions() // const MediaConstraintsInterface* constraints
+ );
+ return GODOT_OK;
}
godot_error WebRTCPeer::set_remote_description(const char *type, const char *sdp) {
- return GODOT_FAILED;
+ godot_error err = set_description(type, sdp, false); //false meaning !isLocal because it is remote
+ peer_connection->CreateAnswer(ptr_csdo, webrtc::PeerConnectionInterface::RTCOfferAnswerOptions());
+ return err;
}
godot_error WebRTCPeer::set_local_description(const char *type, const char *sdp) {
- return GODOT_FAILED;
+ return set_description(type, sdp, true); // isLocal == true
}
godot_error WebRTCPeer::add_ice_candidate(const char *sdpMidName, int sdpMlineIndexName, const char *sdpName) {
- return GODOT_FAILED;
+ webrtc::SdpParseError *error = nullptr;
+ webrtc::IceCandidateInterface *candidate = webrtc::CreateIceCandidate(
+ sdpMidName,
+ sdpMlineIndexName,
+ sdpName,
+ error);
+
+ // @TODO do something if there's an error (if error, or if !candidate)
+ if (error || !candidate)
+ std::cout << "ERROR with creating ICE candidate (" << error << ")\n";
+
+ if (!peer_connection->AddIceCandidate(candidate))
+ ERR_PRINT("Error with adding ICE candidate");
+ return GODOT_OK;
}
godot_error WebRTCPeer::poll() {
- return GODOT_FAILED;
+ std::function<void()> signal;
+ while (!signal_queue.empty()) {
+ mutex_signal_queue->lock();
+ signal = signal_queue.front();
+ signal_queue.pop();
+ mutex_signal_queue->unlock();
+
+ signal();
+ }
+ return GODOT_OK;
}
godot_error WebRTCPeer::get_packet(const uint8_t **r_buffer, int &r_len) {
- printf("Get packet");
- r_len = 0;
+ if (packet_queue_size == 0)
+ return GODOT_ERR_UNAVAILABLE;
+ mutex_packet_queue->lock();
+ uint8_t *current_packet = packet_queue.front();
+ *r_buffer = current_packet;
+ r_len = packet_sizes_queue.front();
+
+ packet_queue.pop();
+ packet_sizes_queue.pop();
+ mutex_packet_queue->unlock();
+
+ --packet_queue_size;
return GODOT_OK;
}
godot_error WebRTCPeer::put_packet(const uint8_t *p_buffer, int p_len) {
- printf("Put packet");
- return GODOT_OK;
+ webrtc::DataBuffer webrtc_buffer(rtc::CopyOnWriteBuffer(p_buffer, p_len), true);
+ data_channel->Send(webrtc_buffer);
+ return GODOT_OK; // @TODO properly return any Error we may get.
}
godot_int WebRTCPeer::get_available_packet_count() const {
- printf("Get packet count");
- return 2;
+ return packet_queue_size;
}
godot_int WebRTCPeer::get_max_packet_size() const {
- printf("Get max packet size");
- return 1024;
+ return 1200;
}
-void WebRTCPeer::_register_methods() { }
+void WebRTCPeer::_register_methods() {
+}
void WebRTCPeer::_init() {
- printf("Binding PacketPeer interface");
register_interface(&interface);
+
+ // initialize variables:
+ mutex_signal_queue = new std::mutex;
+ mutex_packet_queue = new std::mutex;
+ packet_queue_size = 0;
+
+ // create a PeerConnectionFactoryInterface:
+ signaling_thread = new rtc::Thread;
+ signaling_thread->Start();
+ pc_factory = webrtc::CreateModularPeerConnectionFactory(
+ nullptr, // rtc::Thread* network_thread,
+ nullptr, // rtc::Thread* worker_thread,
+ signaling_thread,
+ nullptr, // std::unique_ptr<cricket::MediaEngineInterface> media_engine,
+ nullptr, // std::unique_ptr<CallFactoryInterface> call_factory,
+ nullptr // std::unique_ptr<RtcEventLogFactoryInterface> event_log_factory
+ );
+ if (pc_factory.get() == nullptr) { // PeerConnectionFactory couldn't be created. Fail the method call.
+ godot_print_error("PeerConnectionFactory could not be created", "_init", "WebRTCPeer.cpp", 80);
+ // return GODOT_FAILED;
+ }
+
+ // create PeerConnection configuration and add the ice servers:
+ webrtc::PeerConnectionInterface::RTCConfiguration configuration;
+ //webrtc::PeerConnectionInterface::IceServer ice_server;
+
+ //ice_server.uri = "stun:stun.l.google.com:19302"; // @FIXME allow user to input ice servers
+ //configuration.servers.push_back(ice_server);
+
+ // create a PeerConnection object:
+ peer_connection = pc_factory->CreatePeerConnection(configuration, nullptr, nullptr, &pco);
+ if (peer_connection.get() == nullptr) { // PeerConnection couldn't be created. Fail the method call.
+ godot_print_error("PeerConnection could not be created", "_init", "WebRTCPeer.cpp", 101);
+ // return GODOT_FAILED;
+ }
+
+ // create a DataChannel
+ webrtc::DataChannelInit data_channel_config;
+ data_channel_config.negotiated = true; // True if the channel has been externally negotiated
+ data_channel_config.id = 0;
+
+ data_channel = peer_connection->CreateDataChannel("channel", &data_channel_config);
+ // @TODO (NONESSENTIAL) create data_channel check. fail function call if data_channel isn't created
+ data_channel->RegisterObserver(&dco);
}
-WebRTCPeer::WebRTCPeer() {
+WebRTCPeer::WebRTCPeer() :
+ dco(this),
+ pco(this),
+ ptr_csdo(new rtc::RefCountedObject<GodotCSDO>(this)),
+ ptr_ssdo(new rtc::RefCountedObject<GodotSSDO>(this)) {
}
WebRTCPeer::~WebRTCPeer() {
if (_owner) {
- printf("Unbinding PacketPeer interface");
register_interface(NULL);
}
+ delete mutex_signal_queue;
+ delete mutex_packet_queue;
+}
+
+void WebRTCPeer::queue_signal(godot::String p_name, int p_argc, const godot::Variant &p_arg1, const godot::Variant &p_arg2, const godot::Variant &p_arg3) {
+ mutex_signal_queue->lock();
+ signal_queue.push(
+ [this, p_name, p_argc, p_arg1, p_arg2, p_arg3] {
+ if (p_argc == 2)
+ emit_signal(p_name, p_arg1, p_arg2);
+ else
+ emit_signal(p_name, p_arg1, p_arg2, p_arg3);
+ });
+ mutex_signal_queue->unlock();
+}
+
+void WebRTCPeer::queue_packet(uint8_t *buffer, int buffer_size) {
+ mutex_packet_queue->lock();
+ packet_queue.push(buffer);
+ packet_sizes_queue.push(buffer_size);
+ ++packet_queue_size;
+ mutex_packet_queue->unlock();
+}
+
+godot_error WebRTCPeer::set_description(const char *type, const char *sdp, bool isLocal) {
+ // webrtc::SdpType type = (isOffer) ? webrtc::SdpType::kOffer : webrtc::SdpType::kAnswer;
+ godot::String string_sdp = sdp;
+
+ webrtc::SdpType sdptype = (godot::String(type) == godot::String("offer")) ? webrtc::SdpType::kOffer : webrtc::SdpType::kAnswer;
+ std::unique_ptr<webrtc::SessionDescriptionInterface> desc =
+ webrtc::CreateSessionDescription(sdptype, sdp);
+
+ if (isLocal) {
+ peer_connection->SetLocalDescription(
+ ptr_ssdo, // @TODO (NONESSENTIAL, OPTIONAL) replace this with DummySetSessionDescriptionObserver::Create()
+ desc.release());
+ } else {
+ peer_connection->SetRemoteDescription(
+ ptr_ssdo, // @TODO (NONESSENTIAL, OPTIONAL) replace this with DummySetSessionDescriptionObserver::Create()
+ desc.release());
+ }
+ return GODOT_OK;
}