blob: a2c2e182ed1ff306fe2b2cda47b838bad105c59e [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
11#import "RTCDataChannel.h"
12
13#import "webrtc/api/objc/RTCDataChannel+Private.h"
14#import "webrtc/base/objc/NSString+StdString.h"
15
kwiberg8fb35572016-02-11 13:36:43 -080016#include "webrtc/base/scoped_ptr.h"
17
hjone373dc22016-01-22 14:04:27 -080018namespace webrtc {
19
20class DataChannelDelegateAdapter : public DataChannelObserver {
21 public:
22 DataChannelDelegateAdapter(RTCDataChannel *channel) { channel_ = channel; }
23
24 void OnStateChange() override {
25 [channel_.delegate dataChannelDidChangeState:channel_];
26 }
27
28 void OnMessage(const DataBuffer& buffer) override {
29 RTCDataBuffer *data_buffer =
30 [[RTCDataBuffer alloc] initWithNativeBuffer:buffer];
31 [channel_.delegate dataChannel:channel_
32 didReceiveMessageWithBuffer:data_buffer];
33 }
34
35 void OnBufferedAmountChange(uint64_t previousAmount) override {
36 id<RTCDataChannelDelegate> delegate = channel_.delegate;
tkchin121ac122016-03-21 09:08:40 -070037 SEL sel = @selector(dataChannel:didChangeBufferedAmount:);
38 if ([delegate respondsToSelector:sel]) {
hjone373dc22016-01-22 14:04:27 -080039 [delegate dataChannel:channel_ didChangeBufferedAmount:previousAmount];
40 }
41 }
42
43 private:
44 __weak RTCDataChannel *channel_;
45};
46}
47
48
49@implementation RTCDataBuffer {
50 rtc::scoped_ptr<webrtc::DataBuffer> _dataBuffer;
51}
52
53- (instancetype)initWithData:(NSData *)data isBinary:(BOOL)isBinary {
54 NSParameterAssert(data);
55 if (self = [super init]) {
jbaucheec21bd2016-03-20 06:15:43 -070056 rtc::CopyOnWriteBuffer buffer(
57 reinterpret_cast<const uint8_t*>(data.bytes), data.length);
hjone373dc22016-01-22 14:04:27 -080058 _dataBuffer.reset(new webrtc::DataBuffer(buffer, isBinary));
59 }
60 return self;
61}
62
63- (NSData *)data {
64 return [NSData dataWithBytes:_dataBuffer->data.data()
65 length:_dataBuffer->data.size()];
66}
67
68- (BOOL)isBinary {
69 return _dataBuffer->binary;
70}
71
72#pragma mark - Private
73
74- (instancetype)initWithNativeBuffer:(const webrtc::DataBuffer&)nativeBuffer {
75 if (self = [super init]) {
76 _dataBuffer.reset(new webrtc::DataBuffer(nativeBuffer));
77 }
78 return self;
79}
80
81- (const webrtc::DataBuffer *)nativeDataBuffer {
82 return _dataBuffer.get();
83}
84
85@end
86
87
88@implementation RTCDataChannel {
tkchin8b9ca952016-03-31 12:08:03 -070089 rtc::scoped_refptr<webrtc::DataChannelInterface> _nativeDataChannel;
hjone373dc22016-01-22 14:04:27 -080090 rtc::scoped_ptr<webrtc::DataChannelDelegateAdapter> _observer;
91 BOOL _isObserverRegistered;
92}
93
94@synthesize delegate = _delegate;
95
96- (void)dealloc {
97 // Handles unregistering the observer properly. We need to do this because
98 // there may still be other references to the underlying data channel.
99 self.delegate = nil;
100}
101
102- (NSString *)label {
tkchin8b9ca952016-03-31 12:08:03 -0700103 return [NSString stringForStdString:_nativeDataChannel->label()];
104}
105
106- (BOOL)isReliable {
107 return _nativeDataChannel->reliable();
hjone373dc22016-01-22 14:04:27 -0800108}
109
110- (BOOL)isOrdered {
tkchin8b9ca952016-03-31 12:08:03 -0700111 return _nativeDataChannel->ordered();
112}
113
114- (NSUInteger)maxRetransmitTime {
115 return self.maxPacketLifeTime;
hjone373dc22016-01-22 14:04:27 -0800116}
117
118- (uint16_t)maxPacketLifeTime {
tkchin8b9ca952016-03-31 12:08:03 -0700119 return _nativeDataChannel->maxRetransmitTime();
hjone373dc22016-01-22 14:04:27 -0800120}
121
122- (uint16_t)maxRetransmits {
tkchin8b9ca952016-03-31 12:08:03 -0700123 return _nativeDataChannel->maxRetransmits();
hjone373dc22016-01-22 14:04:27 -0800124}
125
126- (NSString *)protocol {
tkchin8b9ca952016-03-31 12:08:03 -0700127 return [NSString stringForStdString:_nativeDataChannel->protocol()];
hjone373dc22016-01-22 14:04:27 -0800128}
129
130- (BOOL)isNegotiated {
tkchin8b9ca952016-03-31 12:08:03 -0700131 return _nativeDataChannel->negotiated();
132}
133
134- (NSInteger)streamId {
135 return self.channelId;
hjone373dc22016-01-22 14:04:27 -0800136}
137
hjona2f77982016-03-04 07:09:09 -0800138- (int)channelId {
tkchin8b9ca952016-03-31 12:08:03 -0700139 return _nativeDataChannel->id();
hjone373dc22016-01-22 14:04:27 -0800140}
141
142- (RTCDataChannelState)readyState {
143 return [[self class] dataChannelStateForNativeState:
tkchin8b9ca952016-03-31 12:08:03 -0700144 _nativeDataChannel->state()];
hjone373dc22016-01-22 14:04:27 -0800145}
146
147- (uint64_t)bufferedAmount {
tkchin8b9ca952016-03-31 12:08:03 -0700148 return _nativeDataChannel->buffered_amount();
hjone373dc22016-01-22 14:04:27 -0800149}
150
151- (void)setDelegate:(id<RTCDataChannelDelegate>)delegate {
152 if (_delegate == delegate) {
153 return;
154 }
155 if (_isObserverRegistered) {
tkchin8b9ca952016-03-31 12:08:03 -0700156 _nativeDataChannel->UnregisterObserver();
hjone373dc22016-01-22 14:04:27 -0800157 _isObserverRegistered = NO;
158 }
159 _delegate = delegate;
160 if (_delegate) {
tkchin8b9ca952016-03-31 12:08:03 -0700161 _nativeDataChannel->RegisterObserver(_observer.get());
hjone373dc22016-01-22 14:04:27 -0800162 _isObserverRegistered = YES;
163 }
164}
165
166- (void)close {
tkchin8b9ca952016-03-31 12:08:03 -0700167 _nativeDataChannel->Close();
hjone373dc22016-01-22 14:04:27 -0800168}
169
170- (BOOL)sendData:(RTCDataBuffer *)data {
tkchin8b9ca952016-03-31 12:08:03 -0700171 return _nativeDataChannel->Send(*data.nativeDataBuffer);
hjone373dc22016-01-22 14:04:27 -0800172}
173
174- (NSString *)description {
175 return [NSString stringWithFormat:@"RTCDataChannel:\n%ld\n%@\n%@",
hjona2f77982016-03-04 07:09:09 -0800176 (long)self.channelId,
hjone373dc22016-01-22 14:04:27 -0800177 self.label,
178 [[self class]
179 stringForState:self.readyState]];
180}
181
182#pragma mark - Private
183
184- (instancetype)initWithNativeDataChannel:
185 (rtc::scoped_refptr<webrtc::DataChannelInterface>)nativeDataChannel {
186 NSParameterAssert(nativeDataChannel);
187 if (self = [super init]) {
tkchin8b9ca952016-03-31 12:08:03 -0700188 _nativeDataChannel = nativeDataChannel;
hjone373dc22016-01-22 14:04:27 -0800189 _observer.reset(new webrtc::DataChannelDelegateAdapter(self));
190 }
191 return self;
192}
193
194+ (webrtc::DataChannelInterface::DataState)
195 nativeDataChannelStateForState:(RTCDataChannelState)state {
196 switch (state) {
197 case RTCDataChannelStateConnecting:
198 return webrtc::DataChannelInterface::DataState::kConnecting;
199 case RTCDataChannelStateOpen:
200 return webrtc::DataChannelInterface::DataState::kOpen;
201 case RTCDataChannelStateClosing:
202 return webrtc::DataChannelInterface::DataState::kClosing;
203 case RTCDataChannelStateClosed:
204 return webrtc::DataChannelInterface::DataState::kClosed;
205 }
206}
207
208+ (RTCDataChannelState)dataChannelStateForNativeState:
209 (webrtc::DataChannelInterface::DataState)nativeState {
210 switch (nativeState) {
211 case webrtc::DataChannelInterface::DataState::kConnecting:
212 return RTCDataChannelStateConnecting;
213 case webrtc::DataChannelInterface::DataState::kOpen:
214 return RTCDataChannelStateOpen;
215 case webrtc::DataChannelInterface::DataState::kClosing:
216 return RTCDataChannelStateClosing;
217 case webrtc::DataChannelInterface::DataState::kClosed:
218 return RTCDataChannelStateClosed;
219 }
220}
221
222+ (NSString *)stringForState:(RTCDataChannelState)state {
223 switch (state) {
224 case RTCDataChannelStateConnecting:
225 return @"Connecting";
226 case RTCDataChannelStateOpen:
227 return @"Open";
228 case RTCDataChannelStateClosing:
229 return @"Closing";
230 case RTCDataChannelStateClosed:
231 return @"Closed";
232 }
233}
234
235@end