| OLD | NEW |
| (Empty) |
| 1 /* | |
| 2 * libjingle | |
| 3 * Copyright 2013 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 "RTCPeerConnection+Internal.h" | |
| 33 | |
| 34 #import "RTCDataChannel+Internal.h" | |
| 35 #import "RTCEnumConverter.h" | |
| 36 #import "RTCICECandidate+Internal.h" | |
| 37 #import "RTCICEServer+Internal.h" | |
| 38 #import "RTCMediaConstraints+Internal.h" | |
| 39 #import "RTCMediaStream+Internal.h" | |
| 40 #import "RTCMediaStreamTrack+Internal.h" | |
| 41 #import "RTCPeerConnectionObserver.h" | |
| 42 #import "RTCSessionDescription+Internal.h" | |
| 43 #import "RTCSessionDescription.h" | |
| 44 #import "RTCSessionDescriptionDelegate.h" | |
| 45 #import "RTCStatsDelegate.h" | |
| 46 #import "RTCStatsReport+Internal.h" | |
| 47 | |
| 48 #include <memory> | |
| 49 | |
| 50 #include "webrtc/api/jsep.h" | |
| 51 | |
| 52 NSString* const kRTCSessionDescriptionDelegateErrorDomain = @"RTCSDPError"; | |
| 53 int const kRTCSessionDescriptionDelegateErrorCode = -1; | |
| 54 | |
| 55 namespace webrtc { | |
| 56 | |
| 57 class RTCCreateSessionDescriptionObserver | |
| 58 : public CreateSessionDescriptionObserver { | |
| 59 public: | |
| 60 RTCCreateSessionDescriptionObserver( | |
| 61 id<RTCSessionDescriptionDelegate> delegate, | |
| 62 RTCPeerConnection* peerConnection) { | |
| 63 _delegate = delegate; | |
| 64 _peerConnection = peerConnection; | |
| 65 } | |
| 66 | |
| 67 void OnSuccess(SessionDescriptionInterface* desc) override { | |
| 68 RTCSessionDescription* session = | |
| 69 [[RTCSessionDescription alloc] initWithSessionDescription:desc]; | |
| 70 [_delegate peerConnection:_peerConnection | |
| 71 didCreateSessionDescription:session | |
| 72 error:nil]; | |
| 73 delete desc; | |
| 74 } | |
| 75 | |
| 76 void OnFailure(const std::string& error) override { | |
| 77 NSString* str = @(error.c_str()); | |
| 78 NSError* err = | |
| 79 [NSError errorWithDomain:kRTCSessionDescriptionDelegateErrorDomain | |
| 80 code:kRTCSessionDescriptionDelegateErrorCode | |
| 81 userInfo:@{@"error" : str}]; | |
| 82 [_delegate peerConnection:_peerConnection | |
| 83 didCreateSessionDescription:nil | |
| 84 error:err]; | |
| 85 } | |
| 86 | |
| 87 private: | |
| 88 id<RTCSessionDescriptionDelegate> _delegate; | |
| 89 RTCPeerConnection* _peerConnection; | |
| 90 }; | |
| 91 | |
| 92 class RTCSetSessionDescriptionObserver : public SetSessionDescriptionObserver { | |
| 93 public: | |
| 94 RTCSetSessionDescriptionObserver(id<RTCSessionDescriptionDelegate> delegate, | |
| 95 RTCPeerConnection* peerConnection) { | |
| 96 _delegate = delegate; | |
| 97 _peerConnection = peerConnection; | |
| 98 } | |
| 99 | |
| 100 void OnSuccess() override { | |
| 101 [_delegate peerConnection:_peerConnection | |
| 102 didSetSessionDescriptionWithError:nil]; | |
| 103 } | |
| 104 | |
| 105 void OnFailure(const std::string& error) override { | |
| 106 NSString* str = @(error.c_str()); | |
| 107 NSError* err = | |
| 108 [NSError errorWithDomain:kRTCSessionDescriptionDelegateErrorDomain | |
| 109 code:kRTCSessionDescriptionDelegateErrorCode | |
| 110 userInfo:@{@"error" : str}]; | |
| 111 [_delegate peerConnection:_peerConnection | |
| 112 didSetSessionDescriptionWithError:err]; | |
| 113 } | |
| 114 | |
| 115 private: | |
| 116 id<RTCSessionDescriptionDelegate> _delegate; | |
| 117 RTCPeerConnection* _peerConnection; | |
| 118 }; | |
| 119 | |
| 120 class RTCStatsObserver : public StatsObserver { | |
| 121 public: | |
| 122 RTCStatsObserver(id<RTCStatsDelegate> delegate, | |
| 123 RTCPeerConnection* peerConnection) { | |
| 124 _delegate = delegate; | |
| 125 _peerConnection = peerConnection; | |
| 126 } | |
| 127 | |
| 128 void OnComplete(const StatsReports& reports) override { | |
| 129 NSMutableArray* stats = [NSMutableArray arrayWithCapacity:reports.size()]; | |
| 130 for (const auto* report : reports) { | |
| 131 RTCStatsReport* statsReport = | |
| 132 [[RTCStatsReport alloc] initWithStatsReport:*report]; | |
| 133 [stats addObject:statsReport]; | |
| 134 } | |
| 135 [_delegate peerConnection:_peerConnection didGetStats:stats]; | |
| 136 } | |
| 137 | |
| 138 private: | |
| 139 id<RTCStatsDelegate> _delegate; | |
| 140 RTCPeerConnection* _peerConnection; | |
| 141 }; | |
| 142 } | |
| 143 | |
| 144 @implementation RTCPeerConnection { | |
| 145 NSMutableArray* _localStreams; | |
| 146 std::unique_ptr<webrtc::RTCPeerConnectionObserver> _observer; | |
| 147 rtc::scoped_refptr<webrtc::PeerConnectionInterface> _peerConnection; | |
| 148 } | |
| 149 | |
| 150 - (BOOL)addICECandidate:(RTCICECandidate*)candidate { | |
| 151 std::unique_ptr<const webrtc::IceCandidateInterface> iceCandidate( | |
| 152 candidate.candidate); | |
| 153 return self.peerConnection->AddIceCandidate(iceCandidate.get()); | |
| 154 } | |
| 155 | |
| 156 - (BOOL)addStream:(RTCMediaStream*)stream { | |
| 157 BOOL ret = self.peerConnection->AddStream(stream.mediaStream); | |
| 158 if (!ret) { | |
| 159 return NO; | |
| 160 } | |
| 161 [_localStreams addObject:stream]; | |
| 162 return YES; | |
| 163 } | |
| 164 | |
| 165 - (RTCDataChannel*)createDataChannelWithLabel:(NSString*)label | |
| 166 config:(RTCDataChannelInit*)config { | |
| 167 std::string labelString([label UTF8String]); | |
| 168 rtc::scoped_refptr<webrtc::DataChannelInterface> dataChannel = | |
| 169 self.peerConnection->CreateDataChannel(labelString, | |
| 170 config.dataChannelInit); | |
| 171 return [[RTCDataChannel alloc] initWithDataChannel:dataChannel]; | |
| 172 } | |
| 173 | |
| 174 - (void)createAnswerWithDelegate:(id<RTCSessionDescriptionDelegate>)delegate | |
| 175 constraints:(RTCMediaConstraints*)constraints { | |
| 176 rtc::scoped_refptr<webrtc::RTCCreateSessionDescriptionObserver> | |
| 177 observer(new rtc::RefCountedObject< | |
| 178 webrtc::RTCCreateSessionDescriptionObserver>(delegate, self)); | |
| 179 self.peerConnection->CreateAnswer(observer, constraints.constraints); | |
| 180 } | |
| 181 | |
| 182 - (void)createOfferWithDelegate:(id<RTCSessionDescriptionDelegate>)delegate | |
| 183 constraints:(RTCMediaConstraints*)constraints { | |
| 184 rtc::scoped_refptr<webrtc::RTCCreateSessionDescriptionObserver> | |
| 185 observer(new rtc::RefCountedObject< | |
| 186 webrtc::RTCCreateSessionDescriptionObserver>(delegate, self)); | |
| 187 self.peerConnection->CreateOffer(observer, constraints.constraints); | |
| 188 } | |
| 189 | |
| 190 - (void)removeStream:(RTCMediaStream*)stream { | |
| 191 self.peerConnection->RemoveStream(stream.mediaStream); | |
| 192 [_localStreams removeObject:stream]; | |
| 193 } | |
| 194 | |
| 195 - (void)setLocalDescriptionWithDelegate: | |
| 196 (id<RTCSessionDescriptionDelegate>)delegate | |
| 197 sessionDescription:(RTCSessionDescription*)sdp { | |
| 198 rtc::scoped_refptr<webrtc::RTCSetSessionDescriptionObserver> observer( | |
| 199 new rtc::RefCountedObject<webrtc::RTCSetSessionDescriptionObserver>( | |
| 200 delegate, self)); | |
| 201 self.peerConnection->SetLocalDescription(observer, sdp.sessionDescription); | |
| 202 } | |
| 203 | |
| 204 - (void)setRemoteDescriptionWithDelegate: | |
| 205 (id<RTCSessionDescriptionDelegate>)delegate | |
| 206 sessionDescription:(RTCSessionDescription*)sdp { | |
| 207 rtc::scoped_refptr<webrtc::RTCSetSessionDescriptionObserver> observer( | |
| 208 new rtc::RefCountedObject<webrtc::RTCSetSessionDescriptionObserver>( | |
| 209 delegate, self)); | |
| 210 self.peerConnection->SetRemoteDescription(observer, sdp.sessionDescription); | |
| 211 } | |
| 212 | |
| 213 - (BOOL)setConfiguration:(RTCConfiguration *)configuration { | |
| 214 std::unique_ptr<webrtc::PeerConnectionInterface::RTCConfiguration> config( | |
| 215 [configuration createNativeConfiguration]); | |
| 216 if (!config) { | |
| 217 return NO; | |
| 218 } | |
| 219 return self.peerConnection->SetConfiguration(*config); | |
| 220 } | |
| 221 | |
| 222 - (RTCSessionDescription*)localDescription { | |
| 223 const webrtc::SessionDescriptionInterface* sdi = | |
| 224 self.peerConnection->local_description(); | |
| 225 return sdi ? [[RTCSessionDescription alloc] initWithSessionDescription:sdi] | |
| 226 : nil; | |
| 227 } | |
| 228 | |
| 229 - (NSArray*)localStreams { | |
| 230 return [_localStreams copy]; | |
| 231 } | |
| 232 | |
| 233 - (RTCSessionDescription*)remoteDescription { | |
| 234 const webrtc::SessionDescriptionInterface* sdi = | |
| 235 self.peerConnection->remote_description(); | |
| 236 return sdi ? [[RTCSessionDescription alloc] initWithSessionDescription:sdi] | |
| 237 : nil; | |
| 238 } | |
| 239 | |
| 240 - (RTCICEConnectionState)iceConnectionState { | |
| 241 return [RTCEnumConverter | |
| 242 convertIceConnectionStateToObjC:self.peerConnection | |
| 243 ->ice_connection_state()]; | |
| 244 } | |
| 245 | |
| 246 - (RTCICEGatheringState)iceGatheringState { | |
| 247 return [RTCEnumConverter | |
| 248 convertIceGatheringStateToObjC:self.peerConnection | |
| 249 ->ice_gathering_state()]; | |
| 250 } | |
| 251 | |
| 252 - (RTCSignalingState)signalingState { | |
| 253 return [RTCEnumConverter | |
| 254 convertSignalingStateToObjC:self.peerConnection->signaling_state()]; | |
| 255 } | |
| 256 | |
| 257 - (void)close { | |
| 258 self.peerConnection->Close(); | |
| 259 } | |
| 260 | |
| 261 - (BOOL)getStatsWithDelegate:(id<RTCStatsDelegate>)delegate | |
| 262 mediaStreamTrack:(RTCMediaStreamTrack*)mediaStreamTrack | |
| 263 statsOutputLevel:(RTCStatsOutputLevel)statsOutputLevel { | |
| 264 rtc::scoped_refptr<webrtc::RTCStatsObserver> observer( | |
| 265 new rtc::RefCountedObject<webrtc::RTCStatsObserver>(delegate, | |
| 266 self)); | |
| 267 webrtc::PeerConnectionInterface::StatsOutputLevel nativeOutputLevel = | |
| 268 [RTCEnumConverter convertStatsOutputLevelToNative:statsOutputLevel]; | |
| 269 return self.peerConnection->GetStats( | |
| 270 observer, mediaStreamTrack.mediaTrack, nativeOutputLevel); | |
| 271 } | |
| 272 | |
| 273 @end | |
| 274 | |
| 275 @implementation RTCPeerConnection (Internal) | |
| 276 | |
| 277 - (instancetype)initWithFactory:(webrtc::PeerConnectionFactoryInterface*)factory | |
| 278 iceServers:(const webrtc::PeerConnectionInterface::IceServers&)iceServers | |
| 279 constraints:(const webrtc::MediaConstraintsInterface*)constraints { | |
| 280 NSParameterAssert(factory != nullptr); | |
| 281 if (self = [super init]) { | |
| 282 webrtc::PeerConnectionInterface::RTCConfiguration config; | |
| 283 config.servers = iceServers; | |
| 284 _observer.reset(new webrtc::RTCPeerConnectionObserver(self)); | |
| 285 _peerConnection = factory->CreatePeerConnection( | |
| 286 config, constraints, nullptr, nullptr, _observer.get()); | |
| 287 _localStreams = [[NSMutableArray alloc] init]; | |
| 288 } | |
| 289 return self; | |
| 290 } | |
| 291 | |
| 292 - (instancetype)initWithFactory:(webrtc::PeerConnectionFactoryInterface *)factor
y | |
| 293 config:(const webrtc::PeerConnectionInterface::RTCConfi
guration &)config | |
| 294 constraints:(const webrtc::MediaConstraintsInterface *)const
raints | |
| 295 delegate:(id<RTCPeerConnectionDelegate>)delegate { | |
| 296 NSParameterAssert(factory); | |
| 297 if (self = [super init]) { | |
| 298 _observer.reset(new webrtc::RTCPeerConnectionObserver(self)); | |
| 299 _peerConnection = | |
| 300 factory->CreatePeerConnection(config, constraints, nullptr, nullptr, _ob
server.get()); | |
| 301 _localStreams = [[NSMutableArray alloc] init]; | |
| 302 _delegate = delegate; | |
| 303 } | |
| 304 return self; | |
| 305 } | |
| 306 | |
| 307 - (rtc::scoped_refptr<webrtc::PeerConnectionInterface>)peerConnection { | |
| 308 return _peerConnection; | |
| 309 } | |
| 310 | |
| 311 @end | |
| OLD | NEW |