blob: 35c009eb9629960ddcd540fad92e43af6a1ba1cb [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
Anders Carlsson7bca8ca2018-08-30 09:30:29 +020013#import "helpers/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 {
Yura Yaroshevichc75b35a2018-06-27 17:09:14 +030088 RTCPeerConnectionFactory *_factory;
tkchin8b9ca952016-03-31 12:08:03 -070089 rtc::scoped_refptr<webrtc::DataChannelInterface> _nativeDataChannel;
kwibergbfefb032016-05-01 14:53:46 -070090 std::unique_ptr<webrtc::DataChannelDelegateAdapter> _observer;
hjone373dc22016-01-22 14:04:27 -080091 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.
skvlad630d9ba2016-05-06 16:10:44 -070099 _nativeDataChannel->UnregisterObserver();
hjone373dc22016-01-22 14:04:27 -0800100}
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
hjone373dc22016-01-22 14:04:27 -0800151- (void)close {
tkchin8b9ca952016-03-31 12:08:03 -0700152 _nativeDataChannel->Close();
hjone373dc22016-01-22 14:04:27 -0800153}
154
155- (BOOL)sendData:(RTCDataBuffer *)data {
tkchin8b9ca952016-03-31 12:08:03 -0700156 return _nativeDataChannel->Send(*data.nativeDataBuffer);
hjone373dc22016-01-22 14:04:27 -0800157}
158
159- (NSString *)description {
160 return [NSString stringWithFormat:@"RTCDataChannel:\n%ld\n%@\n%@",
hjona2f77982016-03-04 07:09:09 -0800161 (long)self.channelId,
hjone373dc22016-01-22 14:04:27 -0800162 self.label,
163 [[self class]
164 stringForState:self.readyState]];
165}
166
167#pragma mark - Private
168
Yura Yaroshevichc75b35a2018-06-27 17:09:14 +0300169- (instancetype)initWithFactory:(RTCPeerConnectionFactory *)factory
170 nativeDataChannel:
171 (rtc::scoped_refptr<webrtc::DataChannelInterface>)nativeDataChannel {
hjone373dc22016-01-22 14:04:27 -0800172 NSParameterAssert(nativeDataChannel);
173 if (self = [super init]) {
Yura Yaroshevichc75b35a2018-06-27 17:09:14 +0300174 _factory = factory;
tkchin8b9ca952016-03-31 12:08:03 -0700175 _nativeDataChannel = nativeDataChannel;
hjone373dc22016-01-22 14:04:27 -0800176 _observer.reset(new webrtc::DataChannelDelegateAdapter(self));
skvlad630d9ba2016-05-06 16:10:44 -0700177 _nativeDataChannel->RegisterObserver(_observer.get());
hjone373dc22016-01-22 14:04:27 -0800178 }
179 return self;
180}
181
182+ (webrtc::DataChannelInterface::DataState)
183 nativeDataChannelStateForState:(RTCDataChannelState)state {
184 switch (state) {
185 case RTCDataChannelStateConnecting:
186 return webrtc::DataChannelInterface::DataState::kConnecting;
187 case RTCDataChannelStateOpen:
188 return webrtc::DataChannelInterface::DataState::kOpen;
189 case RTCDataChannelStateClosing:
190 return webrtc::DataChannelInterface::DataState::kClosing;
191 case RTCDataChannelStateClosed:
192 return webrtc::DataChannelInterface::DataState::kClosed;
193 }
194}
195
196+ (RTCDataChannelState)dataChannelStateForNativeState:
197 (webrtc::DataChannelInterface::DataState)nativeState {
198 switch (nativeState) {
199 case webrtc::DataChannelInterface::DataState::kConnecting:
200 return RTCDataChannelStateConnecting;
201 case webrtc::DataChannelInterface::DataState::kOpen:
202 return RTCDataChannelStateOpen;
203 case webrtc::DataChannelInterface::DataState::kClosing:
204 return RTCDataChannelStateClosing;
205 case webrtc::DataChannelInterface::DataState::kClosed:
206 return RTCDataChannelStateClosed;
207 }
208}
209
210+ (NSString *)stringForState:(RTCDataChannelState)state {
211 switch (state) {
212 case RTCDataChannelStateConnecting:
213 return @"Connecting";
214 case RTCDataChannelStateOpen:
215 return @"Open";
216 case RTCDataChannelStateClosing:
217 return @"Closing";
218 case RTCDataChannelStateClosed:
219 return @"Closed";
220 }
221}
222
223@end