• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 *  Copyright 2015 The WebRTC project authors. All Rights Reserved.
3 *
4 *  Use of this source code is governed by a BSD-style license
5 *  that can be found in the LICENSE file in the root of the source
6 *  tree. An additional intellectual property rights grant can be found
7 *  in the file PATENTS.  All contributing project authors may
8 *  be found in the AUTHORS file in the root of the source tree.
9 */
10
11#import "RTCDataChannel+Private.h"
12
13#import "helpers/NSString+StdString.h"
14
15#include <memory>
16
17namespace webrtc {
18
19class DataChannelDelegateAdapter : public DataChannelObserver {
20 public:
21  DataChannelDelegateAdapter(RTC_OBJC_TYPE(RTCDataChannel) * channel) { channel_ = channel; }
22
23  void OnStateChange() override {
24    [channel_.delegate dataChannelDidChangeState:channel_];
25  }
26
27  void OnMessage(const DataBuffer& buffer) override {
28    RTC_OBJC_TYPE(RTCDataBuffer) *data_buffer =
29        [[RTC_OBJC_TYPE(RTCDataBuffer) alloc] initWithNativeBuffer:buffer];
30    [channel_.delegate dataChannel:channel_
31       didReceiveMessageWithBuffer:data_buffer];
32  }
33
34  void OnBufferedAmountChange(uint64_t previousAmount) override {
35    id<RTC_OBJC_TYPE(RTCDataChannelDelegate)> delegate = channel_.delegate;
36    SEL sel = @selector(dataChannel:didChangeBufferedAmount:);
37    if ([delegate respondsToSelector:sel]) {
38      [delegate dataChannel:channel_ didChangeBufferedAmount:previousAmount];
39    }
40  }
41
42 private:
43  __weak RTC_OBJC_TYPE(RTCDataChannel) * channel_;
44};
45}
46
47@implementation RTC_OBJC_TYPE (RTCDataBuffer) {
48  std::unique_ptr<webrtc::DataBuffer> _dataBuffer;
49}
50
51- (instancetype)initWithData:(NSData *)data isBinary:(BOOL)isBinary {
52  NSParameterAssert(data);
53  if (self = [super init]) {
54    rtc::CopyOnWriteBuffer buffer(
55        reinterpret_cast<const uint8_t*>(data.bytes), data.length);
56    _dataBuffer.reset(new webrtc::DataBuffer(buffer, isBinary));
57  }
58  return self;
59}
60
61- (NSData *)data {
62  return [NSData dataWithBytes:_dataBuffer->data.data()
63                        length:_dataBuffer->data.size()];
64}
65
66- (BOOL)isBinary {
67  return _dataBuffer->binary;
68}
69
70#pragma mark - Private
71
72- (instancetype)initWithNativeBuffer:(const webrtc::DataBuffer&)nativeBuffer {
73  if (self = [super init]) {
74    _dataBuffer.reset(new webrtc::DataBuffer(nativeBuffer));
75  }
76  return self;
77}
78
79- (const webrtc::DataBuffer *)nativeDataBuffer {
80  return _dataBuffer.get();
81}
82
83@end
84
85@implementation RTC_OBJC_TYPE (RTCDataChannel) {
86  RTC_OBJC_TYPE(RTCPeerConnectionFactory) * _factory;
87  rtc::scoped_refptr<webrtc::DataChannelInterface> _nativeDataChannel;
88  std::unique_ptr<webrtc::DataChannelDelegateAdapter> _observer;
89  BOOL _isObserverRegistered;
90}
91
92@synthesize delegate = _delegate;
93
94- (void)dealloc {
95  // Handles unregistering the observer properly. We need to do this because
96  // there may still be other references to the underlying data channel.
97  _nativeDataChannel->UnregisterObserver();
98}
99
100- (NSString *)label {
101  return [NSString stringForStdString:_nativeDataChannel->label()];
102}
103
104- (BOOL)isReliable {
105  return _nativeDataChannel->reliable();
106}
107
108- (BOOL)isOrdered {
109  return _nativeDataChannel->ordered();
110}
111
112- (NSUInteger)maxRetransmitTime {
113  return self.maxPacketLifeTime;
114}
115
116- (uint16_t)maxPacketLifeTime {
117  return _nativeDataChannel->maxRetransmitTime();
118}
119
120- (uint16_t)maxRetransmits {
121  return _nativeDataChannel->maxRetransmits();
122}
123
124- (NSString *)protocol {
125  return [NSString stringForStdString:_nativeDataChannel->protocol()];
126}
127
128- (BOOL)isNegotiated {
129  return _nativeDataChannel->negotiated();
130}
131
132- (NSInteger)streamId {
133  return self.channelId;
134}
135
136- (int)channelId {
137  return _nativeDataChannel->id();
138}
139
140- (RTCDataChannelState)readyState {
141  return [[self class] dataChannelStateForNativeState:
142      _nativeDataChannel->state()];
143}
144
145- (uint64_t)bufferedAmount {
146  return _nativeDataChannel->buffered_amount();
147}
148
149- (void)close {
150  _nativeDataChannel->Close();
151}
152
153- (BOOL)sendData:(RTC_OBJC_TYPE(RTCDataBuffer) *)data {
154  return _nativeDataChannel->Send(*data.nativeDataBuffer);
155}
156
157- (NSString *)description {
158  return [NSString stringWithFormat:@"RTC_OBJC_TYPE(RTCDataChannel):\n%ld\n%@\n%@",
159                                    (long)self.channelId,
160                                    self.label,
161                                    [[self class] stringForState:self.readyState]];
162}
163
164#pragma mark - Private
165
166- (instancetype)initWithFactory:(RTC_OBJC_TYPE(RTCPeerConnectionFactory) *)factory
167              nativeDataChannel:
168                  (rtc::scoped_refptr<webrtc::DataChannelInterface>)nativeDataChannel {
169  NSParameterAssert(nativeDataChannel);
170  if (self = [super init]) {
171    _factory = factory;
172    _nativeDataChannel = nativeDataChannel;
173    _observer.reset(new webrtc::DataChannelDelegateAdapter(self));
174    _nativeDataChannel->RegisterObserver(_observer.get());
175  }
176  return self;
177}
178
179+ (webrtc::DataChannelInterface::DataState)
180    nativeDataChannelStateForState:(RTCDataChannelState)state {
181  switch (state) {
182    case RTCDataChannelStateConnecting:
183      return webrtc::DataChannelInterface::DataState::kConnecting;
184    case RTCDataChannelStateOpen:
185      return webrtc::DataChannelInterface::DataState::kOpen;
186    case RTCDataChannelStateClosing:
187      return webrtc::DataChannelInterface::DataState::kClosing;
188    case RTCDataChannelStateClosed:
189      return webrtc::DataChannelInterface::DataState::kClosed;
190  }
191}
192
193+ (RTCDataChannelState)dataChannelStateForNativeState:
194    (webrtc::DataChannelInterface::DataState)nativeState {
195  switch (nativeState) {
196    case webrtc::DataChannelInterface::DataState::kConnecting:
197      return RTCDataChannelStateConnecting;
198    case webrtc::DataChannelInterface::DataState::kOpen:
199      return RTCDataChannelStateOpen;
200    case webrtc::DataChannelInterface::DataState::kClosing:
201      return RTCDataChannelStateClosing;
202    case webrtc::DataChannelInterface::DataState::kClosed:
203      return RTCDataChannelStateClosed;
204  }
205}
206
207+ (NSString *)stringForState:(RTCDataChannelState)state {
208  switch (state) {
209    case RTCDataChannelStateConnecting:
210      return @"Connecting";
211    case RTCDataChannelStateOpen:
212      return @"Open";
213    case RTCDataChannelStateClosing:
214      return @"Closing";
215    case RTCDataChannelStateClosed:
216      return @"Closed";
217  }
218}
219
220@end
221