| OLD | NEW |
| (Empty) |
| 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 <memory> | |
| 35 | |
| 36 #include "webrtc/api/datachannelinterface.h" | |
| 37 | |
| 38 namespace webrtc { | |
| 39 | |
| 40 class RTCDataChannelObserver : public DataChannelObserver { | |
| 41 public: | |
| 42 RTCDataChannelObserver(RTCDataChannel* channel) { _channel = channel; } | |
| 43 | |
| 44 void OnStateChange() override { | |
| 45 [_channel.delegate channelDidChangeState:_channel]; | |
| 46 } | |
| 47 | |
| 48 void OnBufferedAmountChange(uint64_t previousAmount) override { | |
| 49 RTCDataChannel* channel = _channel; | |
| 50 id<RTCDataChannelDelegate> delegate = channel.delegate; | |
| 51 if ([delegate | |
| 52 respondsToSelector:@selector(channel:didChangeBufferedAmount:)]) { | |
| 53 [delegate channel:channel didChangeBufferedAmount:previousAmount]; | |
| 54 } | |
| 55 } | |
| 56 | |
| 57 void OnMessage(const DataBuffer& buffer) override { | |
| 58 if (!_channel.delegate) { | |
| 59 return; | |
| 60 } | |
| 61 RTCDataBuffer* dataBuffer = | |
| 62 [[RTCDataBuffer alloc] initWithDataBuffer:buffer]; | |
| 63 [_channel.delegate channel:_channel didReceiveMessageWithBuffer:dataBuffer]; | |
| 64 } | |
| 65 | |
| 66 private: | |
| 67 __weak RTCDataChannel* _channel; | |
| 68 }; | |
| 69 } | |
| 70 | |
| 71 // TODO(henrika): move to shared location. | |
| 72 // See https://code.google.com/p/webrtc/issues/detail?id=4773 for details. | |
| 73 NSString* NSStringFromStdString(const std::string& stdString) { | |
| 74 // std::string may contain null termination character so we construct | |
| 75 // using length. | |
| 76 return [[NSString alloc] initWithBytes:stdString.data() | |
| 77 length:stdString.length() | |
| 78 encoding:NSUTF8StringEncoding]; | |
| 79 } | |
| 80 | |
| 81 std::string StdStringFromNSString(NSString* nsString) { | |
| 82 NSData* charData = [nsString dataUsingEncoding:NSUTF8StringEncoding]; | |
| 83 return std::string(reinterpret_cast<const char*>([charData bytes]), | |
| 84 [charData length]); | |
| 85 } | |
| 86 | |
| 87 @implementation RTCDataChannelInit { | |
| 88 webrtc::DataChannelInit _dataChannelInit; | |
| 89 } | |
| 90 | |
| 91 - (BOOL)isOrdered { | |
| 92 return _dataChannelInit.ordered; | |
| 93 } | |
| 94 | |
| 95 - (void)setIsOrdered:(BOOL)isOrdered { | |
| 96 _dataChannelInit.ordered = isOrdered; | |
| 97 } | |
| 98 | |
| 99 - (NSInteger)maxRetransmitTime { | |
| 100 return _dataChannelInit.maxRetransmitTime; | |
| 101 } | |
| 102 | |
| 103 - (void)setMaxRetransmitTime:(NSInteger)maxRetransmitTime { | |
| 104 _dataChannelInit.maxRetransmitTime = maxRetransmitTime; | |
| 105 } | |
| 106 | |
| 107 - (NSInteger)maxRetransmits { | |
| 108 return _dataChannelInit.maxRetransmits; | |
| 109 } | |
| 110 | |
| 111 - (void)setMaxRetransmits:(NSInteger)maxRetransmits { | |
| 112 _dataChannelInit.maxRetransmits = maxRetransmits; | |
| 113 } | |
| 114 | |
| 115 - (NSString*)protocol { | |
| 116 return NSStringFromStdString(_dataChannelInit.protocol); | |
| 117 } | |
| 118 | |
| 119 - (void)setProtocol:(NSString*)protocol { | |
| 120 _dataChannelInit.protocol = StdStringFromNSString(protocol); | |
| 121 } | |
| 122 | |
| 123 - (BOOL)isNegotiated { | |
| 124 return _dataChannelInit.negotiated; | |
| 125 } | |
| 126 | |
| 127 - (void)setIsNegotiated:(BOOL)isNegotiated { | |
| 128 _dataChannelInit.negotiated = isNegotiated; | |
| 129 } | |
| 130 | |
| 131 - (NSInteger)streamId { | |
| 132 return _dataChannelInit.id; | |
| 133 } | |
| 134 | |
| 135 - (void)setStreamId:(NSInteger)streamId { | |
| 136 _dataChannelInit.id = streamId; | |
| 137 } | |
| 138 | |
| 139 @end | |
| 140 | |
| 141 @implementation RTCDataChannelInit (Internal) | |
| 142 | |
| 143 - (const webrtc::DataChannelInit*)dataChannelInit { | |
| 144 return &_dataChannelInit; | |
| 145 } | |
| 146 | |
| 147 @end | |
| 148 | |
| 149 @implementation RTCDataBuffer { | |
| 150 std::unique_ptr<webrtc::DataBuffer> _dataBuffer; | |
| 151 } | |
| 152 | |
| 153 - (instancetype)initWithData:(NSData*)data isBinary:(BOOL)isBinary { | |
| 154 NSAssert(data, @"data cannot be nil"); | |
| 155 if (self = [super init]) { | |
| 156 rtc::CopyOnWriteBuffer buffer( | |
| 157 reinterpret_cast<const uint8_t*>([data bytes]), [data length]); | |
| 158 _dataBuffer.reset(new webrtc::DataBuffer(buffer, isBinary)); | |
| 159 } | |
| 160 return self; | |
| 161 } | |
| 162 | |
| 163 - (NSData*)data { | |
| 164 return [NSData dataWithBytes:_dataBuffer->data.data() | |
| 165 length:_dataBuffer->data.size()]; | |
| 166 } | |
| 167 | |
| 168 - (BOOL)isBinary { | |
| 169 return _dataBuffer->binary; | |
| 170 } | |
| 171 | |
| 172 @end | |
| 173 | |
| 174 @implementation RTCDataBuffer (Internal) | |
| 175 | |
| 176 - (instancetype)initWithDataBuffer:(const webrtc::DataBuffer&)buffer { | |
| 177 if (self = [super init]) { | |
| 178 _dataBuffer.reset(new webrtc::DataBuffer(buffer)); | |
| 179 } | |
| 180 return self; | |
| 181 } | |
| 182 | |
| 183 - (const webrtc::DataBuffer*)dataBuffer { | |
| 184 return _dataBuffer.get(); | |
| 185 } | |
| 186 | |
| 187 @end | |
| 188 | |
| 189 @implementation RTCDataChannel { | |
| 190 rtc::scoped_refptr<webrtc::DataChannelInterface> _dataChannel; | |
| 191 std::unique_ptr<webrtc::RTCDataChannelObserver> _observer; | |
| 192 BOOL _isObserverRegistered; | |
| 193 } | |
| 194 | |
| 195 - (void)dealloc { | |
| 196 // Handles unregistering the observer properly. We need to do this because | |
| 197 // there may still be other references to the underlying data channel. | |
| 198 self.delegate = nil; | |
| 199 } | |
| 200 | |
| 201 - (NSString*)label { | |
| 202 return NSStringFromStdString(_dataChannel->label()); | |
| 203 } | |
| 204 | |
| 205 - (BOOL)isReliable { | |
| 206 return _dataChannel->reliable(); | |
| 207 } | |
| 208 | |
| 209 - (BOOL)isOrdered { | |
| 210 return _dataChannel->ordered(); | |
| 211 } | |
| 212 | |
| 213 - (NSUInteger)maxRetransmitTimeMs { | |
| 214 return _dataChannel->maxRetransmitTime(); | |
| 215 } | |
| 216 | |
| 217 - (NSUInteger)maxRetransmits { | |
| 218 return _dataChannel->maxRetransmits(); | |
| 219 } | |
| 220 | |
| 221 - (NSString*)protocol { | |
| 222 return NSStringFromStdString(_dataChannel->protocol()); | |
| 223 } | |
| 224 | |
| 225 - (BOOL)isNegotiated { | |
| 226 return _dataChannel->negotiated(); | |
| 227 } | |
| 228 | |
| 229 - (NSInteger)streamId { | |
| 230 return _dataChannel->id(); | |
| 231 } | |
| 232 | |
| 233 - (RTCDataChannelState)state { | |
| 234 switch (_dataChannel->state()) { | |
| 235 case webrtc::DataChannelInterface::DataState::kConnecting: | |
| 236 return kRTCDataChannelStateConnecting; | |
| 237 case webrtc::DataChannelInterface::DataState::kOpen: | |
| 238 return kRTCDataChannelStateOpen; | |
| 239 case webrtc::DataChannelInterface::DataState::kClosing: | |
| 240 return kRTCDataChannelStateClosing; | |
| 241 case webrtc::DataChannelInterface::DataState::kClosed: | |
| 242 return kRTCDataChannelStateClosed; | |
| 243 } | |
| 244 } | |
| 245 | |
| 246 - (NSUInteger)bufferedAmount { | |
| 247 return _dataChannel->buffered_amount(); | |
| 248 } | |
| 249 | |
| 250 - (void)setDelegate:(id<RTCDataChannelDelegate>)delegate { | |
| 251 if (_delegate == delegate) { | |
| 252 return; | |
| 253 } | |
| 254 if (_isObserverRegistered) { | |
| 255 _dataChannel->UnregisterObserver(); | |
| 256 _isObserverRegistered = NO; | |
| 257 } | |
| 258 _delegate = delegate; | |
| 259 if (_delegate) { | |
| 260 _dataChannel->RegisterObserver(_observer.get()); | |
| 261 _isObserverRegistered = YES; | |
| 262 } | |
| 263 } | |
| 264 | |
| 265 - (void)close { | |
| 266 _dataChannel->Close(); | |
| 267 } | |
| 268 | |
| 269 - (BOOL)sendData:(RTCDataBuffer*)data { | |
| 270 return _dataChannel->Send(*data.dataBuffer); | |
| 271 } | |
| 272 | |
| 273 @end | |
| 274 | |
| 275 @implementation RTCDataChannel (Internal) | |
| 276 | |
| 277 - (instancetype)initWithDataChannel: | |
| 278 (rtc::scoped_refptr<webrtc::DataChannelInterface>) | |
| 279 dataChannel { | |
| 280 NSAssert(dataChannel != NULL, @"dataChannel cannot be NULL"); | |
| 281 if (self = [super init]) { | |
| 282 _dataChannel = dataChannel; | |
| 283 _observer.reset(new webrtc::RTCDataChannelObserver(self)); | |
| 284 } | |
| 285 return self; | |
| 286 } | |
| 287 | |
| 288 - (rtc::scoped_refptr<webrtc::DataChannelInterface>)dataChannel { | |
| 289 return _dataChannel; | |
| 290 } | |
| 291 | |
| 292 @end | |
| OLD | NEW |