Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / third_party / libjingle / source / talk / app / webrtc / objc / RTCDataChannel.mm
1 /*
2  * libjingle
3  * Copyright 2014, Google Inc.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  *  1. Redistributions of source code must retain the above copyright notice,
9  *     this list of conditions and the following disclaimer.
10  *  2. Redistributions in binary form must reproduce the above copyright notice,
11  *     this list of conditions and the following disclaimer in the documentation
12  *     and/or other materials provided with the distribution.
13  *  3. The name of the author may not be used to endorse or promote products
14  *     derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19  * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27
28 #if !defined(__has_feature) || !__has_feature(objc_arc)
29 #error "This file requires ARC support."
30 #endif
31
32 #import "RTCDataChannel+Internal.h"
33
34 #include "talk/app/webrtc/datachannelinterface.h"
35
36 namespace webrtc {
37
38 class RTCDataChannelObserver : public DataChannelObserver {
39  public:
40   RTCDataChannelObserver(RTCDataChannel* channel) { _channel = channel; }
41
42   virtual void OnStateChange() OVERRIDE {
43     [_channel.delegate channelDidChangeState:_channel];
44   }
45
46   virtual void OnMessage(const DataBuffer& buffer) OVERRIDE {
47     if (!_channel.delegate) {
48       return;
49     }
50     RTCDataBuffer* dataBuffer =
51         [[RTCDataBuffer alloc] initWithDataBuffer:buffer];
52     [_channel.delegate channel:_channel didReceiveMessageWithBuffer:dataBuffer];
53   }
54
55  private:
56   __weak RTCDataChannel* _channel;
57 };
58 }
59
60 // TODO(tkchin): move to shared location
61 NSString* NSStringFromStdString(const std::string& stdString) {
62   // std::string may contain null termination character so we construct
63   // using length.
64   return [[NSString alloc] initWithBytes:stdString.data()
65                                   length:stdString.length()
66                                 encoding:NSUTF8StringEncoding];
67 }
68
69 std::string StdStringFromNSString(NSString* nsString) {
70   NSData* charData = [nsString dataUsingEncoding:NSUTF8StringEncoding];
71   return std::string(reinterpret_cast<const char*>([charData bytes]),
72                      [charData length]);
73 }
74
75 @implementation RTCDataChannelInit {
76   webrtc::DataChannelInit _dataChannelInit;
77 }
78
79 - (BOOL)isOrdered {
80   return _dataChannelInit.ordered;
81 }
82
83 - (void)setIsOrdered:(BOOL)isOrdered {
84   _dataChannelInit.ordered = isOrdered;
85 }
86
87 - (NSInteger)maxRetransmitTime {
88   return _dataChannelInit.maxRetransmitTime;
89 }
90
91 - (void)setMaxRetransmitTime:(NSInteger)maxRetransmitTime {
92   _dataChannelInit.maxRetransmitTime = maxRetransmitTime;
93 }
94
95 - (NSInteger)maxRetransmits {
96   return _dataChannelInit.maxRetransmits;
97 }
98
99 - (void)setMaxRetransmits:(NSInteger)maxRetransmits {
100   _dataChannelInit.maxRetransmits = maxRetransmits;
101 }
102
103 - (NSString*)protocol {
104   return NSStringFromStdString(_dataChannelInit.protocol);
105 }
106
107 - (void)setProtocol:(NSString*)protocol {
108   _dataChannelInit.protocol = StdStringFromNSString(protocol);
109 }
110
111 - (BOOL)isNegotiated {
112   return _dataChannelInit.negotiated;
113 }
114
115 - (void)setIsNegotiated:(BOOL)isNegotiated {
116   _dataChannelInit.negotiated = isNegotiated;
117 }
118
119 - (NSInteger)streamId {
120   return _dataChannelInit.id;
121 }
122
123 - (void)setStreamId:(NSInteger)streamId {
124   _dataChannelInit.id = streamId;
125 }
126
127 @end
128
129 @implementation RTCDataChannelInit (Internal)
130
131 - (const webrtc::DataChannelInit*)dataChannelInit {
132   return &_dataChannelInit;
133 }
134
135 @end
136
137 @implementation RTCDataBuffer {
138   talk_base::scoped_ptr<webrtc::DataBuffer> _dataBuffer;
139 }
140
141 - (instancetype)initWithData:(NSData*)data isBinary:(BOOL)isBinary {
142   NSAssert(data, @"data cannot be nil");
143   if (self = [super init]) {
144     talk_base::Buffer buffer([data bytes], [data length]);
145     _dataBuffer.reset(new webrtc::DataBuffer(buffer, isBinary));
146   }
147   return self;
148 }
149
150 - (NSData*)data {
151   return [NSData dataWithBytes:_dataBuffer->data.data()
152                         length:_dataBuffer->data.length()];
153 }
154
155 - (BOOL)isBinary {
156   return _dataBuffer->binary;
157 }
158
159 @end
160
161 @implementation RTCDataBuffer (Internal)
162
163 - (instancetype)initWithDataBuffer:(const webrtc::DataBuffer&)buffer {
164   if (self = [super init]) {
165     _dataBuffer.reset(new webrtc::DataBuffer(buffer));
166   }
167   return self;
168 }
169
170 - (const webrtc::DataBuffer*)dataBuffer {
171   return _dataBuffer.get();
172 }
173
174 @end
175
176 @implementation RTCDataChannel {
177   talk_base::scoped_refptr<webrtc::DataChannelInterface> _dataChannel;
178   talk_base::scoped_ptr<webrtc::RTCDataChannelObserver> _observer;
179   BOOL _isObserverRegistered;
180 }
181
182 - (NSString*)label {
183   return NSStringFromStdString(_dataChannel->label());
184 }
185
186 - (BOOL)isReliable {
187   return _dataChannel->reliable();
188 }
189
190 - (BOOL)isOrdered {
191   return _dataChannel->ordered();
192 }
193
194 - (NSUInteger)maxRetransmitTimeMs {
195   return _dataChannel->maxRetransmitTime();
196 }
197
198 - (NSUInteger)maxRetransmits {
199   return _dataChannel->maxRetransmits();
200 }
201
202 - (NSString*)protocol {
203   return NSStringFromStdString(_dataChannel->protocol());
204 }
205
206 - (BOOL)isNegotiated {
207   return _dataChannel->negotiated();
208 }
209
210 - (NSInteger)streamId {
211   return _dataChannel->id();
212 }
213
214 - (RTCDataChannelState)state {
215   switch (_dataChannel->state()) {
216     case webrtc::DataChannelInterface::DataState::kConnecting:
217       return kRTCDataChannelStateConnecting;
218     case webrtc::DataChannelInterface::DataState::kOpen:
219       return kRTCDataChannelStateOpen;
220     case webrtc::DataChannelInterface::DataState::kClosing:
221       return kRTCDataChannelStateClosing;
222     case webrtc::DataChannelInterface::DataState::kClosed:
223       return kRTCDataChannelStateClosed;
224   }
225 }
226
227 - (NSUInteger)bufferedAmount {
228   return _dataChannel->buffered_amount();
229 }
230
231 - (void)setDelegate:(id<RTCDataChannelDelegate>)delegate {
232   if (_delegate == delegate) {
233     return;
234   }
235   if (_isObserverRegistered) {
236     _dataChannel->UnregisterObserver();
237     _isObserverRegistered = NO;
238   }
239   _delegate = delegate;
240   if (_delegate) {
241     _dataChannel->RegisterObserver(_observer.get());
242     _isObserverRegistered = YES;
243   }
244 }
245
246 - (void)close {
247   _dataChannel->Close();
248 }
249
250 - (BOOL)sendData:(RTCDataBuffer*)data {
251   return _dataChannel->Send(*data.dataBuffer);
252 }
253
254 @end
255
256 @implementation RTCDataChannel (Internal)
257
258 - (instancetype)initWithDataChannel:
259                     (talk_base::scoped_refptr<webrtc::DataChannelInterface>)
260                 dataChannel {
261   NSAssert(dataChannel != NULL, @"dataChannel cannot be NULL");
262   if (self = [super init]) {
263     _dataChannel = dataChannel;
264     _observer.reset(new webrtc::RTCDataChannelObserver(self));
265   }
266   return self;
267 }
268
269 - (talk_base::scoped_refptr<webrtc::DataChannelInterface>)dataChannel {
270   return _dataChannel;
271 }
272
273 @end