blob: 706e43e2ed5a984ffdbc5a6b7183e490a2a70332 [file] [log] [blame]
hjone373dc22016-01-22 14:04:27 -08001/*
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
tkchin9eeb6242016-04-27 01:54:20 -070011#import "RTCDataChannel+Private.h"
hjone373dc22016-01-22 14:04:27 -080012
tkchin9eeb6242016-04-27 01:54:20 -070013#import "NSString+StdString.h"
hjone373dc22016-01-22 14:04:27 -080014
kwibergbfefb032016-05-01 14:53:46 -070015#include <memory>
kwiberg8fb35572016-02-11 13:36:43 -080016
hjone373dc22016-01-22 14:04:27 -080017namespace webrtc {
18
19class DataChannelDelegateAdapter : public DataChannelObserver {
20 public:
21 DataChannelDelegateAdapter(RTCDataChannel *channel) { channel_ = channel; }
22
23 void OnStateChange() override {
24 [channel_.delegate dataChannelDidChangeState:channel_];
25 }
26
27 void OnMessage(const DataBuffer& buffer) override {
28 RTCDataBuffer *data_buffer =
29 [[RTCDataBuffer alloc] initWithNativeBuffer:buffer];
30 [channel_.delegate dataChannel:channel_
31 didReceiveMessageWithBuffer:data_buffer];
32 }
33
34 void OnBufferedAmountChange(uint64_t previousAmount) override {
35 id<RTCDataChannelDelegate> delegate = channel_.delegate;
tkchin121ac122016-03-21 09:08:40 -070036 SEL sel = @selector(dataChannel:didChangeBufferedAmount:);
37 if ([delegate respondsToSelector:sel]) {
hjone373dc22016-01-22 14:04:27 -080038 [delegate dataChannel:channel_ didChangeBufferedAmount:previousAmount];
39 }
40 }
41
42 private:
43 __weak RTCDataChannel *channel_;
44};
45}
46
47
48@implementation RTCDataBuffer {
kwibergbfefb032016-05-01 14:53:46 -070049 std::unique_ptr<webrtc::DataBuffer> _dataBuffer;
hjone373dc22016-01-22 14:04:27 -080050}
51
52- (instancetype)initWithData:(NSData *)data isBinary:(BOOL)isBinary {
53 NSParameterAssert(data);
54 if (self = [super init]) {
jbaucheec21bd2016-03-20 06:15:43 -070055 rtc::CopyOnWriteBuffer buffer(
56 reinterpret_cast<const uint8_t*>(data.bytes), data.length);
hjone373dc22016-01-22 14:04:27 -080057 _dataBuffer.reset(new webrtc::DataBuffer(buffer, isBinary));
58 }
59 return self;
60}
61
62- (NSData *)data {
63 return [NSData dataWithBytes:_dataBuffer->data.data()
64 length:_dataBuffer->data.size()];
65}
66
67- (BOOL)isBinary {
68 return _dataBuffer->binary;
69}
70
71#pragma mark - Private
72
73- (instancetype)initWithNativeBuffer:(const webrtc::DataBuffer&)nativeBuffer {
74 if (self = [super init]) {
75 _dataBuffer.reset(new webrtc::DataBuffer(nativeBuffer));
76 }
77 return self;
78}
79
80- (const webrtc::DataBuffer *)nativeDataBuffer {
81 return _dataBuffer.get();
82}
83
84@end
85
86
87@implementation RTCDataChannel {
tkchin8b9ca952016-03-31 12:08:03 -070088 rtc::scoped_refptr<webrtc::DataChannelInterface> _nativeDataChannel;
kwibergbfefb032016-05-01 14:53:46 -070089 std::unique_ptr<webrtc::DataChannelDelegateAdapter> _observer;
hjone373dc22016-01-22 14:04:27 -080090 BOOL _isObserverRegistered;
91}
92
93@synthesize delegate = _delegate;
94
95- (void)dealloc {
96 // Handles unregistering the observer properly. We need to do this because
97 // there may still be other references to the underlying data channel.
skvlad630d9ba2016-05-06 16:10:44 -070098 _nativeDataChannel->UnregisterObserver();
hjone373dc22016-01-22 14:04:27 -080099}
100
101- (NSString *)label {
tkchin8b9ca952016-03-31 12:08:03 -0700102 return [NSString stringForStdString:_nativeDataChannel->label()];
103}
104
105- (BOOL)isReliable {
106 return _nativeDataChannel->reliable();
hjone373dc22016-01-22 14:04:27 -0800107}
108
109- (BOOL)isOrdered {
tkchin8b9ca952016-03-31 12:08:03 -0700110 return _nativeDataChannel->ordered();
111}
112
113- (NSUInteger)maxRetransmitTime {
114 return self.maxPacketLifeTime;
hjone373dc22016-01-22 14:04:27 -0800115}
116
117- (uint16_t)maxPacketLifeTime {
tkchin8b9ca952016-03-31 12:08:03 -0700118 return _nativeDataChannel->maxRetransmitTime();
hjone373dc22016-01-22 14:04:27 -0800119}
120
121- (uint16_t)maxRetransmits {
tkchin8b9ca952016-03-31 12:08:03 -0700122 return _nativeDataChannel->maxRetransmits();
hjone373dc22016-01-22 14:04:27 -0800123}
124
125- (NSString *)protocol {
tkchin8b9ca952016-03-31 12:08:03 -0700126 return [NSString stringForStdString:_nativeDataChannel->protocol()];
hjone373dc22016-01-22 14:04:27 -0800127}
128
129- (BOOL)isNegotiated {
tkchin8b9ca952016-03-31 12:08:03 -0700130 return _nativeDataChannel->negotiated();
131}
132
133- (NSInteger)streamId {
134 return self.channelId;
hjone373dc22016-01-22 14:04:27 -0800135}
136
hjona2f77982016-03-04 07:09:09 -0800137- (int)channelId {
tkchin8b9ca952016-03-31 12:08:03 -0700138 return _nativeDataChannel->id();
hjone373dc22016-01-22 14:04:27 -0800139}
140
141- (RTCDataChannelState)readyState {
142 return [[self class] dataChannelStateForNativeState:
tkchin8b9ca952016-03-31 12:08:03 -0700143 _nativeDataChannel->state()];
hjone373dc22016-01-22 14:04:27 -0800144}
145
146- (uint64_t)bufferedAmount {
tkchin8b9ca952016-03-31 12:08:03 -0700147 return _nativeDataChannel->buffered_amount();
hjone373dc22016-01-22 14:04:27 -0800148}
149
hjone373dc22016-01-22 14:04:27 -0800150- (void)close {
tkchin8b9ca952016-03-31 12:08:03 -0700151 _nativeDataChannel->Close();
hjone373dc22016-01-22 14:04:27 -0800152}
153
154- (BOOL)sendData:(RTCDataBuffer *)data {
tkchin8b9ca952016-03-31 12:08:03 -0700155 return _nativeDataChannel->Send(*data.nativeDataBuffer);
hjone373dc22016-01-22 14:04:27 -0800156}
157
158- (NSString *)description {
159 return [NSString stringWithFormat:@"RTCDataChannel:\n%ld\n%@\n%@",
hjona2f77982016-03-04 07:09:09 -0800160 (long)self.channelId,
hjone373dc22016-01-22 14:04:27 -0800161 self.label,
162 [[self class]
163 stringForState:self.readyState]];
164}
165
166#pragma mark - Private
167
168- (instancetype)initWithNativeDataChannel:
169 (rtc::scoped_refptr<webrtc::DataChannelInterface>)nativeDataChannel {
170 NSParameterAssert(nativeDataChannel);
171 if (self = [super init]) {
tkchin8b9ca952016-03-31 12:08:03 -0700172 _nativeDataChannel = nativeDataChannel;
hjone373dc22016-01-22 14:04:27 -0800173 _observer.reset(new webrtc::DataChannelDelegateAdapter(self));
skvlad630d9ba2016-05-06 16:10:44 -0700174 _nativeDataChannel->RegisterObserver(_observer.get());
hjone373dc22016-01-22 14:04:27 -0800175 }
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