Skip to content

Commit

Permalink
data channel support
Browse files Browse the repository at this point in the history
  • Loading branch information
Quarken committed Jun 28, 2024
1 parent 7998174 commit b504ad4
Show file tree
Hide file tree
Showing 3 changed files with 141 additions and 23 deletions.
58 changes: 58 additions & 0 deletions Sources/NabtoEdgeClientWebRTC/Impl/EdgeDataChannel.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
//
// File.swift
//
//
// Created by Ahmad Saleh on 24/06/2024.
//

import Foundation
import WebRTC

public class EdgeDataChannelImpl: NSObject, EdgeDataChannel, RTCDataChannelDelegate {
internal var dc: RTCDataChannel!
public var onMessage: EdgeOnMessageCallback? = nil
public var onOpened: EdgeOnOpenedCallback? = nil
public var onClosed: EdgeOnClosedCallback? = nil

public init(_ dataChannel: RTCDataChannel) {
self.dc = dataChannel
super.init()

self.dc.delegate = self
}

public func send(_ data: Data) async {
let buffer = RTCDataBuffer(data: data, isBinary: true)
self.dc.sendData(buffer)
}

public func close() async {
self.dc.close()
}

public func dataChannelDidChangeState(_ dataChannel: RTCDataChannel) {
EdgeLogger.info("Data channel \(dataChannel.channelId) state changed to \(dataChannel.readyState)")
switch dataChannel.readyState {
case .connecting:
break

case .open:
self.onOpened?()
break

case .closing:
break

case .closed:
self.onClosed?()
break

@unknown default:
break
}
}

public func dataChannel(_ dataChannel: RTCDataChannel, didReceiveMessageWith buffer: RTCDataBuffer) {
self.onMessage?(buffer.data)
}
}
14 changes: 10 additions & 4 deletions Sources/NabtoEdgeClientWebRTC/Impl/EdgePeerConnection.swift
Original file line number Diff line number Diff line change
Expand Up @@ -51,15 +51,15 @@ internal class EdgePeerConnectionImpl: NSObject, EdgePeerConnection {

let coap = try conn.createCoapRequest(method: "GET", path: "/p2p/webrtc-info")
let coapResult = try await coap.executeAsync()

if coapResult.status != 205 {
EdgeLogger.error("Unexpected /p2p/webrtc-info return code \(coapResult.status). Failed to initialize signaling service.")
throw EdgeWebrtcError.signalingFailedToInitialize
}

var rtcInfo: RTCInfo
let stream = try conn.createStream()

let cborDecoder = CBORDecoder()
let jsonDecoder = JSONDecoder()
if coapResult.contentFormat == 50 {
Expand All @@ -71,7 +71,7 @@ internal class EdgePeerConnectionImpl: NSObject, EdgePeerConnection {
try stream.close()
throw EdgeWebrtcError.signalingFailedToInitialize
}

try await stream.openAsync(streamPort: rtcInfo.signalingStreamPort)

self.signaling = try await EdgeStreamSignaling(stream)
Expand All @@ -86,6 +86,12 @@ internal class EdgePeerConnectionImpl: NSObject, EdgePeerConnection {
self.conn = nil
}

func createDataChannel(_ label: String) throws -> EdgeDataChannel {
let config = RTCDataChannelConfiguration()
let dc = peerConnection?.dataChannel(forLabel: label, configuration: config)
return EdgeDataChannelImpl(dc!)
}

private func error(_ err: EdgeWebrtcError, _ msg: String?) {
if let msg = msg {
EdgeLogger.error(msg)
Expand Down
92 changes: 73 additions & 19 deletions Sources/NabtoEdgeClientWebRTC/Interface.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,36 @@
import Foundation
import WebRTC

/**
* Callback invoked when the remote peer has added a Track to the WebRTC connection
*
* @param track [in] The newly added Track
* @param trackId [in] The device repoted ID for this Track
*/
public typealias EdgeOnTrackCallback = (_ track: EdgeMediaTrack, _ trackId: String?) -> ()

/**
* Callback invoked when the object (e.g. a data channel) has opened.
*/
public typealias EdgeOnOpenedCallback = () -> ()

/**
* Callback invoked when a WebRTC connection has been closed
*/
public typealias EdgeOnClosedCallback = () -> ()

/**
* Callback invoked when an error occurs in the WebRTC connection
*
* @param error [in] The Error that occured
*/
public typealias EdgeOnErrorCallback = (_ error: EdgeWebrtcError) -> ()

/**
* Callback invoked when a data channel has received a message.
*/
public typealias EdgeOnMessageCallback = (_ data: Data) -> ()

/**
* Errors emitted by the onErrorCallback
*/
Expand Down Expand Up @@ -91,27 +121,43 @@ public protocol EdgeAudioTrack: EdgeMediaTrack {
func setEnabled(_ enabled: Bool)
}


/**
* Callback invoked when the remote peer has added a Track to the WebRTC connection
*
* @param track [in] The newly added Track
* @param trackId [in] The device repoted ID for this Track
*/
public typealias EdgeOnTrackCallback = (_ track: EdgeMediaTrack, _ trackId: String?) -> ()

/**
* Callback invoked when a WebRTC connection has been closed
* Data channel for sending and receiving bytes on a webrtc connection
*/
public typealias EdgeOnClosedCallback = () -> ()

/**
* Callback invoked when an error occurs in the WebRTC connection
*
* @param error [in] The Error that occured
*/
public typealias EdgeOnErrorCallback = (_ error: EdgeWebrtcError) -> ()

public protocol EdgeDataChannel {
/**
* Set the callback to be invoked when the data channel receives a message.
*
* @param cb The callback to set
*/
var onMessage: EdgeOnMessageCallback? { get set }

/**
* Set the callback to be invoked when the data channel is open and ready to send/receive messages.
*
* @param cb The callback to set
*/
var onOpened: EdgeOnOpenedCallback? { get set }

/**
* Set the callback to be invoked when the data channel is closed.
*
* @param cb The callback to set
*/
var onClosed: EdgeOnClosedCallback? { get set }

/**
* Send a Data byte buffer over the data channel.
*
* @param data The binary data to be sent.
*/
func send(_ data: Data) async

/**
* Closes the data channel.
*/
func close() async
}

/**
* Main Connection interface used to connect to a device and interact with it.
Expand All @@ -138,6 +184,14 @@ public protocol EdgePeerConnection {
* @param cb The callback to set
*/
var onError: EdgeOnErrorCallback? { get set }

/**
* Create a new data channel
* WARNING: Data channels are experimental and may not work as expected..
*
* @param label A string that describes the data channel.
*/
func createDataChannel(_ label: String) throws -> EdgeDataChannel

/**
* Establish a WebRTC connection to the other peer
Expand Down

0 comments on commit b504ad4

Please sign in to comment.