blob: 4a79cefdb4989878630f23aa5e1999b2ff34a1ff [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
Artem Titov63ee39d2022-05-13 14:46:42 +000013#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:
Mirko Bonadeia81e9c82020-05-04 16:14:32 +020021 DataChannelDelegateAdapter(RTC_OBJC_TYPE(RTCDataChannel) * channel) { channel_ = channel; }
hjone373dc22016-01-22 14:04:27 -080022
23 void OnStateChange() override {
24 [channel_.delegate dataChannelDidChangeState:channel_];
25 }
26
27 void OnMessage(const DataBuffer& buffer) override {
Mirko Bonadeia81e9c82020-05-04 16:14:32 +020028 RTC_OBJC_TYPE(RTCDataBuffer) *data_buffer =
29 [[RTC_OBJC_TYPE(RTCDataBuffer) alloc] initWithNativeBuffer:buffer];
hjone373dc22016-01-22 14:04:27 -080030 [channel_.delegate dataChannel:channel_
31 didReceiveMessageWithBuffer:data_buffer];
32 }
33
34 void OnBufferedAmountChange(uint64_t previousAmount) override {
Mirko Bonadeia81e9c82020-05-04 16:14:32 +020035 id<RTC_OBJC_TYPE(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:
Mirko Bonadeia81e9c82020-05-04 16:14:32 +020043 __weak RTC_OBJC_TYPE(RTCDataChannel) * channel_;
hjone373dc22016-01-22 14:04:27 -080044};
45}
46
Mirko Bonadeia81e9c82020-05-04 16:14:32 +020047@implementation RTC_OBJC_TYPE (RTCDataBuffer) {
kwibergbfefb032016-05-01 14:53:46 -070048 std::unique_ptr<webrtc::DataBuffer> _dataBuffer;
hjone373dc22016-01-22 14:04:27 -080049}
50
51- (instancetype)initWithData:(NSData *)data isBinary:(BOOL)isBinary {
52 NSParameterAssert(data);
53 if (self = [super init]) {
jbaucheec21bd2016-03-20 06:15:43 -070054 rtc::CopyOnWriteBuffer buffer(
55 reinterpret_cast<const uint8_t*>(data.bytes), data.length);
hjone373dc22016-01-22 14:04:27 -080056 _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
Mirko Bonadeia81e9c82020-05-04 16:14:32 +020085@implementation RTC_OBJC_TYPE (RTCDataChannel) {
86 RTC_OBJC_TYPE(RTCPeerConnectionFactory) * _factory;
tkchin8b9ca952016-03-31 12:08:03 -070087 rtc::scoped_refptr<webrtc::DataChannelInterface> _nativeDataChannel;
kwibergbfefb032016-05-01 14:53:46 -070088 std::unique_ptr<webrtc::DataChannelDelegateAdapter> _observer;
hjone373dc22016-01-22 14:04:27 -080089 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.
skvlad630d9ba2016-05-06 16:10:44 -070097 _nativeDataChannel->UnregisterObserver();
hjone373dc22016-01-22 14:04:27 -080098}
99
100- (NSString *)label {
Artem Titov63ee39d2022-05-13 14:46:42 +0000101 return [NSString stringForStdString:_nativeDataChannel->label()];
tkchin8b9ca952016-03-31 12:08:03 -0700102}
103
104- (BOOL)isReliable {
105 return _nativeDataChannel->reliable();
hjone373dc22016-01-22 14:04:27 -0800106}
107
108- (BOOL)isOrdered {
tkchin8b9ca952016-03-31 12:08:03 -0700109 return _nativeDataChannel->ordered();
110}
111
112- (NSUInteger)maxRetransmitTime {
113 return self.maxPacketLifeTime;
hjone373dc22016-01-22 14:04:27 -0800114}
115
116- (uint16_t)maxPacketLifeTime {
tkchin8b9ca952016-03-31 12:08:03 -0700117 return _nativeDataChannel->maxRetransmitTime();
hjone373dc22016-01-22 14:04:27 -0800118}
119
120- (uint16_t)maxRetransmits {
tkchin8b9ca952016-03-31 12:08:03 -0700121 return _nativeDataChannel->maxRetransmits();
hjone373dc22016-01-22 14:04:27 -0800122}
123
124- (NSString *)protocol {
Artem Titov63ee39d2022-05-13 14:46:42 +0000125 return [NSString stringForStdString:_nativeDataChannel->protocol()];
hjone373dc22016-01-22 14:04:27 -0800126}
127
128- (BOOL)isNegotiated {
tkchin8b9ca952016-03-31 12:08:03 -0700129 return _nativeDataChannel->negotiated();
130}
131
132- (NSInteger)streamId {
133 return self.channelId;
hjone373dc22016-01-22 14:04:27 -0800134}
135
hjona2f77982016-03-04 07:09:09 -0800136- (int)channelId {
tkchin8b9ca952016-03-31 12:08:03 -0700137 return _nativeDataChannel->id();
hjone373dc22016-01-22 14:04:27 -0800138}
139
140- (RTCDataChannelState)readyState {
141 return [[self class] dataChannelStateForNativeState:
tkchin8b9ca952016-03-31 12:08:03 -0700142 _nativeDataChannel->state()];
hjone373dc22016-01-22 14:04:27 -0800143}
144
145- (uint64_t)bufferedAmount {
tkchin8b9ca952016-03-31 12:08:03 -0700146 return _nativeDataChannel->buffered_amount();
hjone373dc22016-01-22 14:04:27 -0800147}
148
hjone373dc22016-01-22 14:04:27 -0800149- (void)close {
tkchin8b9ca952016-03-31 12:08:03 -0700150 _nativeDataChannel->Close();
hjone373dc22016-01-22 14:04:27 -0800151}
152
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200153- (BOOL)sendData:(RTC_OBJC_TYPE(RTCDataBuffer) *)data {
tkchin8b9ca952016-03-31 12:08:03 -0700154 return _nativeDataChannel->Send(*data.nativeDataBuffer);
hjone373dc22016-01-22 14:04:27 -0800155}
156
157- (NSString *)description {
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200158 return [NSString stringWithFormat:@"RTC_OBJC_TYPE(RTCDataChannel):\n%ld\n%@\n%@",
hjona2f77982016-03-04 07:09:09 -0800159 (long)self.channelId,
hjone373dc22016-01-22 14:04:27 -0800160 self.label,
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200161 [[self class] stringForState:self.readyState]];
hjone373dc22016-01-22 14:04:27 -0800162}
163
164#pragma mark - Private
165
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200166- (instancetype)initWithFactory:(RTC_OBJC_TYPE(RTCPeerConnectionFactory) *)factory
Yura Yaroshevichc75b35a2018-06-27 17:09:14 +0300167 nativeDataChannel:
168 (rtc::scoped_refptr<webrtc::DataChannelInterface>)nativeDataChannel {
hjone373dc22016-01-22 14:04:27 -0800169 NSParameterAssert(nativeDataChannel);
170 if (self = [super init]) {
Yura Yaroshevichc75b35a2018-06-27 17:09:14 +0300171 _factory = factory;
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