use wasm_bindgen::JsValue;
use crate::messages::ServerOffer;
use crate::p2p_connection::P2PConnection;
use crate::peer_connection::{RtcPeerConnection, SDP};
use crate::signaling::Signaling;
use crate::{ice_server::IceServer, peer_connection::wait_channel_open};
pub struct P2P {
signaling: Signaling,
ice_servers: Vec<IceServer>,
}
impl P2P {
pub async fn new(url: &str) -> Result<P2P, JsValue> {
let p2p = P2P {
signaling: Signaling::new(url).await?,
ice_servers: vec![IceServer::from("stun:stun.l.google.com:19302")],
};
return Ok(p2p);
}
pub fn id(&self) -> String {
self.signaling.id()
}
pub async fn connect(&mut self, peer_id: &str) -> Result<P2PConnection, JsValue> {
let connection = RtcPeerConnection::new(&self.ice_servers)?;
let channel = connection.create_data_channel("channel");
let sdp = connection.create_sdp(SDP::Offer).await?;
let sdp = connection.set_local_sdp(sdp).await?;
self.signaling.send_offer(peer_id, &sdp)?;
let remote_sdp = self.signaling.receive_answer_from(peer_id).await;
connection.set_remote_sdp(remote_sdp, SDP::Answer).await?;
wait_channel_open(&channel).await;
return Ok(P2PConnection::new(peer_id.to_string(), channel));
}
pub fn receive_offer(&mut self) -> Option<ServerOffer> {
return self.signaling.receive_offer();
}
pub async fn create_connection(
&mut self,
offer: ServerOffer,
) -> Result<P2PConnection, JsValue> {
let connection = RtcPeerConnection::new(&self.ice_servers)?;
connection.set_remote_sdp(offer.sdp, SDP::Offer).await?;
let sdp = connection.create_sdp(SDP::Answer).await?;
let sdp = connection.set_local_sdp(sdp).await?;
self.signaling.send_answer(&offer.from, &sdp)?;
let channel = connection.on_channel().await;
wait_channel_open(&channel).await;
return Ok(P2PConnection::new(offer.from, channel));
}
}