| OLD | NEW |
| 1 /* | 1 /* |
| 2 * libjingle | 2 * libjingle |
| 3 * Copyright 2014 Google Inc. | 3 * Copyright 2014 Google Inc. |
| 4 * | 4 * |
| 5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
| 6 * modification, are permitted provided that the following conditions are met: | 6 * modification, are permitted provided that the following conditions are met: |
| 7 * | 7 * |
| 8 * 1. Redistributions of source code must retain the above copyright notice, | 8 * 1. Redistributions of source code must retain the above copyright notice, |
| 9 * this list of conditions and the following disclaimer. | 9 * this list of conditions and the following disclaimer. |
| 10 * 2. Redistributions in binary form must reproduce the above copyright notice, | 10 * 2. Redistributions in binary form must reproduce the above copyright notice, |
| (...skipping 12 matching lines...) Expand all Loading... |
| 23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR | 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 | 24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF |
| 25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 26 */ | 26 */ |
| 27 | 27 |
| 28 #import "ARDAppClient+Internal.h" | 28 #import "ARDAppClient+Internal.h" |
| 29 | 29 |
| 30 #if defined(WEBRTC_IOS) | 30 #if defined(WEBRTC_IOS) |
| 31 #import "RTCAVFoundationVideoSource.h" | 31 #import "RTCAVFoundationVideoSource.h" |
| 32 #endif | 32 #endif |
| 33 #import "RTCFileLogger.h" |
| 33 #import "RTCICEServer.h" | 34 #import "RTCICEServer.h" |
| 34 #import "RTCMediaConstraints.h" | 35 #import "RTCMediaConstraints.h" |
| 35 #import "RTCMediaStream.h" | 36 #import "RTCMediaStream.h" |
| 36 #import "RTCPair.h" | 37 #import "RTCPair.h" |
| 37 #import "RTCPeerConnectionInterface.h" | 38 #import "RTCPeerConnectionInterface.h" |
| 38 #import "RTCVideoCapturer.h" | 39 #import "RTCVideoCapturer.h" |
| 39 #import "RTCAVFoundationVideoSource.h" | 40 #import "RTCAVFoundationVideoSource.h" |
| 40 | 41 |
| 41 #import "ARDAppEngineClient.h" | 42 #import "ARDAppEngineClient.h" |
| 42 #import "ARDCEODTURNClient.h" | 43 #import "ARDCEODTURNClient.h" |
| 43 #import "ARDJoinResponse.h" | 44 #import "ARDJoinResponse.h" |
| 45 #import "ARDLogging.h" |
| 44 #import "ARDMessageResponse.h" | 46 #import "ARDMessageResponse.h" |
| 45 #import "ARDSDPUtils.h" | 47 #import "ARDSDPUtils.h" |
| 46 #import "ARDSignalingMessage.h" | 48 #import "ARDSignalingMessage.h" |
| 47 #import "ARDUtilities.h" | 49 #import "ARDUtilities.h" |
| 48 #import "ARDWebSocketChannel.h" | 50 #import "ARDWebSocketChannel.h" |
| 49 #import "RTCICECandidate+JSON.h" | 51 #import "RTCICECandidate+JSON.h" |
| 50 #import "RTCSessionDescription+JSON.h" | 52 #import "RTCSessionDescription+JSON.h" |
| 51 | 53 |
| 52 | 54 |
| 53 static NSString * const kARDDefaultSTUNServerUrl = | 55 static NSString * const kARDDefaultSTUNServerUrl = |
| 54 @"stun:stun.l.google.com:19302"; | 56 @"stun:stun.l.google.com:19302"; |
| 55 // TODO(tkchin): figure out a better username for CEOD statistics. | 57 // TODO(tkchin): figure out a better username for CEOD statistics. |
| 56 static NSString * const kARDTurnRequestUrl = | 58 static NSString * const kARDTurnRequestUrl = |
| 57 @"https://computeengineondemand.appspot.com" | 59 @"https://computeengineondemand.appspot.com" |
| 58 @"/turn?username=iapprtc&key=4080218913"; | 60 @"/turn?username=iapprtc&key=4080218913"; |
| 59 | 61 |
| 60 static NSString * const kARDAppClientErrorDomain = @"ARDAppClient"; | 62 static NSString * const kARDAppClientErrorDomain = @"ARDAppClient"; |
| 61 static NSInteger const kARDAppClientErrorUnknown = -1; | 63 static NSInteger const kARDAppClientErrorUnknown = -1; |
| 62 static NSInteger const kARDAppClientErrorRoomFull = -2; | 64 static NSInteger const kARDAppClientErrorRoomFull = -2; |
| 63 static NSInteger const kARDAppClientErrorCreateSDP = -3; | 65 static NSInteger const kARDAppClientErrorCreateSDP = -3; |
| 64 static NSInteger const kARDAppClientErrorSetSDP = -4; | 66 static NSInteger const kARDAppClientErrorSetSDP = -4; |
| 65 static NSInteger const kARDAppClientErrorInvalidClient = -5; | 67 static NSInteger const kARDAppClientErrorInvalidClient = -5; |
| 66 static NSInteger const kARDAppClientErrorInvalidRoom = -6; | 68 static NSInteger const kARDAppClientErrorInvalidRoom = -6; |
| 67 | 69 |
| 68 @implementation ARDAppClient | 70 @implementation ARDAppClient { |
| 71 RTCFileLogger *_fileLogger; |
| 72 } |
| 69 | 73 |
| 70 @synthesize delegate = _delegate; | 74 @synthesize delegate = _delegate; |
| 71 @synthesize state = _state; | 75 @synthesize state = _state; |
| 72 @synthesize roomServerClient = _roomServerClient; | 76 @synthesize roomServerClient = _roomServerClient; |
| 73 @synthesize channel = _channel; | 77 @synthesize channel = _channel; |
| 74 @synthesize turnClient = _turnClient; | 78 @synthesize turnClient = _turnClient; |
| 75 @synthesize peerConnection = _peerConnection; | 79 @synthesize peerConnection = _peerConnection; |
| 76 @synthesize factory = _factory; | 80 @synthesize factory = _factory; |
| 77 @synthesize messageQueue = _messageQueue; | 81 @synthesize messageQueue = _messageQueue; |
| 78 @synthesize isTurnComplete = _isTurnComplete; | 82 @synthesize isTurnComplete = _isTurnComplete; |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 124 _delegate = delegate; | 128 _delegate = delegate; |
| 125 [self configure]; | 129 [self configure]; |
| 126 } | 130 } |
| 127 return self; | 131 return self; |
| 128 } | 132 } |
| 129 | 133 |
| 130 - (void)configure { | 134 - (void)configure { |
| 131 _factory = [[RTCPeerConnectionFactory alloc] init]; | 135 _factory = [[RTCPeerConnectionFactory alloc] init]; |
| 132 _messageQueue = [NSMutableArray array]; | 136 _messageQueue = [NSMutableArray array]; |
| 133 _iceServers = [NSMutableArray arrayWithObject:[self defaultSTUNServer]]; | 137 _iceServers = [NSMutableArray arrayWithObject:[self defaultSTUNServer]]; |
| 138 _fileLogger = [[RTCFileLogger alloc] init]; |
| 139 [_fileLogger start]; |
| 134 } | 140 } |
| 135 | 141 |
| 136 - (void)dealloc { | 142 - (void)dealloc { |
| 137 [self disconnect]; | 143 [self disconnect]; |
| 138 } | 144 } |
| 139 | 145 |
| 140 - (void)setState:(ARDAppClientState)state { | 146 - (void)setState:(ARDAppClientState)state { |
| 141 if (_state == state) { | 147 if (_state == state) { |
| 142 return; | 148 return; |
| 143 } | 149 } |
| 144 _state = state; | 150 _state = state; |
| 145 [_delegate appClient:self didChangeState:_state]; | 151 [_delegate appClient:self didChangeState:_state]; |
| 146 } | 152 } |
| 147 | 153 |
| 148 - (void)connectToRoomWithId:(NSString *)roomId | 154 - (void)connectToRoomWithId:(NSString *)roomId |
| 149 options:(NSDictionary *)options { | 155 options:(NSDictionary *)options { |
| 150 NSParameterAssert(roomId.length); | 156 NSParameterAssert(roomId.length); |
| 151 NSParameterAssert(_state == kARDAppClientStateDisconnected); | 157 NSParameterAssert(_state == kARDAppClientStateDisconnected); |
| 152 self.state = kARDAppClientStateConnecting; | 158 self.state = kARDAppClientStateConnecting; |
| 153 | 159 |
| 154 // Request TURN. | 160 // Request TURN. |
| 155 __weak ARDAppClient *weakSelf = self; | 161 __weak ARDAppClient *weakSelf = self; |
| 156 [_turnClient requestServersWithCompletionHandler:^(NSArray *turnServers, | 162 [_turnClient requestServersWithCompletionHandler:^(NSArray *turnServers, |
| 157 NSError *error) { | 163 NSError *error) { |
| 158 if (error) { | 164 if (error) { |
| 159 NSLog(@"Error retrieving TURN servers: %@", error); | 165 ARDLog("Error retrieving TURN servers: %@", error.localizedDescription); |
| 160 } | 166 } |
| 161 ARDAppClient *strongSelf = weakSelf; | 167 ARDAppClient *strongSelf = weakSelf; |
| 162 [strongSelf.iceServers addObjectsFromArray:turnServers]; | 168 [strongSelf.iceServers addObjectsFromArray:turnServers]; |
| 163 strongSelf.isTurnComplete = YES; | 169 strongSelf.isTurnComplete = YES; |
| 164 [strongSelf startSignalingIfReady]; | 170 [strongSelf startSignalingIfReady]; |
| 165 }]; | 171 }]; |
| 166 | 172 |
| 167 // Join room on room server. | 173 // Join room on room server. |
| 168 [_roomServerClient joinRoomWithRoomId:roomId | 174 [_roomServerClient joinRoomWithRoomId:roomId |
| 169 completionHandler:^(ARDJoinResponse *response, NSError *error) { | 175 completionHandler:^(ARDJoinResponse *response, NSError *error) { |
| 170 ARDAppClient *strongSelf = weakSelf; | 176 ARDAppClient *strongSelf = weakSelf; |
| 171 if (error) { | 177 if (error) { |
| 172 [strongSelf.delegate appClient:strongSelf didError:error]; | 178 [strongSelf.delegate appClient:strongSelf didError:error]; |
| 173 return; | 179 return; |
| 174 } | 180 } |
| 175 NSError *joinError = | 181 NSError *joinError = |
| 176 [[strongSelf class] errorForJoinResultType:response.result]; | 182 [[strongSelf class] errorForJoinResultType:response.result]; |
| 177 if (joinError) { | 183 if (joinError) { |
| 178 NSLog(@"Failed to join room:%@ on room server.", roomId); | 184 ARDLog(@"Failed to join room:%@ on room server.", roomId); |
| 179 [strongSelf disconnect]; | 185 [strongSelf disconnect]; |
| 180 [strongSelf.delegate appClient:strongSelf didError:joinError]; | 186 [strongSelf.delegate appClient:strongSelf didError:joinError]; |
| 181 return; | 187 return; |
| 182 } | 188 } |
| 183 NSLog(@"Joined room:%@ on room server.", roomId); | 189 ARDLog(@"Joined room:%@ on room server.", roomId); |
| 184 strongSelf.roomId = response.roomId; | 190 strongSelf.roomId = response.roomId; |
| 185 strongSelf.clientId = response.clientId; | 191 strongSelf.clientId = response.clientId; |
| 186 strongSelf.isInitiator = response.isInitiator; | 192 strongSelf.isInitiator = response.isInitiator; |
| 187 for (ARDSignalingMessage *message in response.messages) { | 193 for (ARDSignalingMessage *message in response.messages) { |
| 188 if (message.type == kARDSignalingMessageTypeOffer || | 194 if (message.type == kARDSignalingMessageTypeOffer || |
| 189 message.type == kARDSignalingMessageTypeAnswer) { | 195 message.type == kARDSignalingMessageTypeAnswer) { |
| 190 strongSelf.hasReceivedSdp = YES; | 196 strongSelf.hasReceivedSdp = YES; |
| 191 [strongSelf.messageQueue insertObject:message atIndex:0]; | 197 [strongSelf.messageQueue insertObject:message atIndex:0]; |
| 192 } else { | 198 } else { |
| 193 [strongSelf.messageQueue addObject:message]; | 199 [strongSelf.messageQueue addObject:message]; |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 265 break; | 271 break; |
| 266 } | 272 } |
| 267 } | 273 } |
| 268 | 274 |
| 269 #pragma mark - RTCPeerConnectionDelegate | 275 #pragma mark - RTCPeerConnectionDelegate |
| 270 // Callbacks for this delegate occur on non-main thread and need to be | 276 // Callbacks for this delegate occur on non-main thread and need to be |
| 271 // dispatched back to main queue as needed. | 277 // dispatched back to main queue as needed. |
| 272 | 278 |
| 273 - (void)peerConnection:(RTCPeerConnection *)peerConnection | 279 - (void)peerConnection:(RTCPeerConnection *)peerConnection |
| 274 signalingStateChanged:(RTCSignalingState)stateChanged { | 280 signalingStateChanged:(RTCSignalingState)stateChanged { |
| 275 NSLog(@"Signaling state changed: %d", stateChanged); | 281 ARDLog(@"Signaling state changed: %d", stateChanged); |
| 276 } | 282 } |
| 277 | 283 |
| 278 - (void)peerConnection:(RTCPeerConnection *)peerConnection | 284 - (void)peerConnection:(RTCPeerConnection *)peerConnection |
| 279 addedStream:(RTCMediaStream *)stream { | 285 addedStream:(RTCMediaStream *)stream { |
| 280 dispatch_async(dispatch_get_main_queue(), ^{ | 286 dispatch_async(dispatch_get_main_queue(), ^{ |
| 281 NSLog(@"Received %lu video tracks and %lu audio tracks", | 287 ARDLog(@"Received %lu video tracks and %lu audio tracks", |
| 282 (unsigned long)stream.videoTracks.count, | 288 (unsigned long)stream.videoTracks.count, |
| 283 (unsigned long)stream.audioTracks.count); | 289 (unsigned long)stream.audioTracks.count); |
| 284 if (stream.videoTracks.count) { | 290 if (stream.videoTracks.count) { |
| 285 RTCVideoTrack *videoTrack = stream.videoTracks[0]; | 291 RTCVideoTrack *videoTrack = stream.videoTracks[0]; |
| 286 [_delegate appClient:self didReceiveRemoteVideoTrack:videoTrack]; | 292 [_delegate appClient:self didReceiveRemoteVideoTrack:videoTrack]; |
| 287 } | 293 } |
| 288 }); | 294 }); |
| 289 } | 295 } |
| 290 | 296 |
| 291 - (void)peerConnection:(RTCPeerConnection *)peerConnection | 297 - (void)peerConnection:(RTCPeerConnection *)peerConnection |
| 292 removedStream:(RTCMediaStream *)stream { | 298 removedStream:(RTCMediaStream *)stream { |
| 293 NSLog(@"Stream was removed."); | 299 ARDLog(@"Stream was removed."); |
| 294 } | 300 } |
| 295 | 301 |
| 296 - (void)peerConnectionOnRenegotiationNeeded: | 302 - (void)peerConnectionOnRenegotiationNeeded: |
| 297 (RTCPeerConnection *)peerConnection { | 303 (RTCPeerConnection *)peerConnection { |
| 298 NSLog(@"WARNING: Renegotiation needed but unimplemented."); | 304 ARDLog(@"WARNING: Renegotiation needed but unimplemented."); |
| 299 } | 305 } |
| 300 | 306 |
| 301 - (void)peerConnection:(RTCPeerConnection *)peerConnection | 307 - (void)peerConnection:(RTCPeerConnection *)peerConnection |
| 302 iceConnectionChanged:(RTCICEConnectionState)newState { | 308 iceConnectionChanged:(RTCICEConnectionState)newState { |
| 303 NSLog(@"ICE state changed: %d", newState); | 309 ARDLog(@"ICE state changed: %d", newState); |
| 304 dispatch_async(dispatch_get_main_queue(), ^{ | 310 dispatch_async(dispatch_get_main_queue(), ^{ |
| 305 [_delegate appClient:self didChangeConnectionState:newState]; | 311 [_delegate appClient:self didChangeConnectionState:newState]; |
| 306 }); | 312 }); |
| 307 } | 313 } |
| 308 | 314 |
| 309 - (void)peerConnection:(RTCPeerConnection *)peerConnection | 315 - (void)peerConnection:(RTCPeerConnection *)peerConnection |
| 310 iceGatheringChanged:(RTCICEGatheringState)newState { | 316 iceGatheringChanged:(RTCICEGatheringState)newState { |
| 311 NSLog(@"ICE gathering state changed: %d", newState); | 317 ARDLog(@"ICE gathering state changed: %d", newState); |
| 312 } | 318 } |
| 313 | 319 |
| 314 - (void)peerConnection:(RTCPeerConnection *)peerConnection | 320 - (void)peerConnection:(RTCPeerConnection *)peerConnection |
| 315 gotICECandidate:(RTCICECandidate *)candidate { | 321 gotICECandidate:(RTCICECandidate *)candidate { |
| 316 dispatch_async(dispatch_get_main_queue(), ^{ | 322 dispatch_async(dispatch_get_main_queue(), ^{ |
| 317 ARDICECandidateMessage *message = | 323 ARDICECandidateMessage *message = |
| 318 [[ARDICECandidateMessage alloc] initWithCandidate:candidate]; | 324 [[ARDICECandidateMessage alloc] initWithCandidate:candidate]; |
| 319 [self sendSignalingMessage:message]; | 325 [self sendSignalingMessage:message]; |
| 320 }); | 326 }); |
| 321 } | 327 } |
| 322 | 328 |
| 323 - (void)peerConnection:(RTCPeerConnection*)peerConnection | 329 - (void)peerConnection:(RTCPeerConnection*)peerConnection |
| 324 didOpenDataChannel:(RTCDataChannel*)dataChannel { | 330 didOpenDataChannel:(RTCDataChannel*)dataChannel { |
| 325 } | 331 } |
| 326 | 332 |
| 327 #pragma mark - RTCSessionDescriptionDelegate | 333 #pragma mark - RTCSessionDescriptionDelegate |
| 328 // Callbacks for this delegate occur on non-main thread and need to be | 334 // Callbacks for this delegate occur on non-main thread and need to be |
| 329 // dispatched back to main queue as needed. | 335 // dispatched back to main queue as needed. |
| 330 | 336 |
| 331 - (void)peerConnection:(RTCPeerConnection *)peerConnection | 337 - (void)peerConnection:(RTCPeerConnection *)peerConnection |
| 332 didCreateSessionDescription:(RTCSessionDescription *)sdp | 338 didCreateSessionDescription:(RTCSessionDescription *)sdp |
| 333 error:(NSError *)error { | 339 error:(NSError *)error { |
| 334 dispatch_async(dispatch_get_main_queue(), ^{ | 340 dispatch_async(dispatch_get_main_queue(), ^{ |
| 335 if (error) { | 341 if (error) { |
| 336 NSLog(@"Failed to create session description. Error: %@", error); | 342 ARDLog(@"Failed to create session description. Error: %@", error); |
| 337 [self disconnect]; | 343 [self disconnect]; |
| 338 NSDictionary *userInfo = @{ | 344 NSDictionary *userInfo = @{ |
| 339 NSLocalizedDescriptionKey: @"Failed to create session description.", | 345 NSLocalizedDescriptionKey: @"Failed to create session description.", |
| 340 }; | 346 }; |
| 341 NSError *sdpError = | 347 NSError *sdpError = |
| 342 [[NSError alloc] initWithDomain:kARDAppClientErrorDomain | 348 [[NSError alloc] initWithDomain:kARDAppClientErrorDomain |
| 343 code:kARDAppClientErrorCreateSDP | 349 code:kARDAppClientErrorCreateSDP |
| 344 userInfo:userInfo]; | 350 userInfo:userInfo]; |
| 345 [_delegate appClient:self didError:sdpError]; | 351 [_delegate appClient:self didError:sdpError]; |
| 346 return; | 352 return; |
| 347 } | 353 } |
| 348 // Prefer H264 if available. | 354 // Prefer H264 if available. |
| 349 RTCSessionDescription *sdpPreferringH264 = | 355 RTCSessionDescription *sdpPreferringH264 = |
| 350 [ARDSDPUtils descriptionForDescription:sdp | 356 [ARDSDPUtils descriptionForDescription:sdp |
| 351 preferredVideoCodec:@"H264"]; | 357 preferredVideoCodec:@"H264"]; |
| 352 [_peerConnection setLocalDescriptionWithDelegate:self | 358 [_peerConnection setLocalDescriptionWithDelegate:self |
| 353 sessionDescription:sdpPreferringH264]; | 359 sessionDescription:sdpPreferringH264]; |
| 354 ARDSessionDescriptionMessage *message = | 360 ARDSessionDescriptionMessage *message = |
| 355 [[ARDSessionDescriptionMessage alloc] | 361 [[ARDSessionDescriptionMessage alloc] |
| 356 initWithDescription:sdpPreferringH264]; | 362 initWithDescription:sdpPreferringH264]; |
| 357 [self sendSignalingMessage:message]; | 363 [self sendSignalingMessage:message]; |
| 358 }); | 364 }); |
| 359 } | 365 } |
| 360 | 366 |
| 361 - (void)peerConnection:(RTCPeerConnection *)peerConnection | 367 - (void)peerConnection:(RTCPeerConnection *)peerConnection |
| 362 didSetSessionDescriptionWithError:(NSError *)error { | 368 didSetSessionDescriptionWithError:(NSError *)error { |
| 363 dispatch_async(dispatch_get_main_queue(), ^{ | 369 dispatch_async(dispatch_get_main_queue(), ^{ |
| 364 if (error) { | 370 if (error) { |
| 365 NSLog(@"Failed to set session description. Error: %@", error); | 371 ARDLog(@"Failed to set session description. Error: %@", error); |
| 366 [self disconnect]; | 372 [self disconnect]; |
| 367 NSDictionary *userInfo = @{ | 373 NSDictionary *userInfo = @{ |
| 368 NSLocalizedDescriptionKey: @"Failed to set session description.", | 374 NSLocalizedDescriptionKey: @"Failed to set session description.", |
| 369 }; | 375 }; |
| 370 NSError *sdpError = | 376 NSError *sdpError = |
| 371 [[NSError alloc] initWithDomain:kARDAppClientErrorDomain | 377 [[NSError alloc] initWithDomain:kARDAppClientErrorDomain |
| 372 code:kARDAppClientErrorSetSDP | 378 code:kARDAppClientErrorSetSDP |
| 373 userInfo:userInfo]; | 379 userInfo:userInfo]; |
| 374 [_delegate appClient:self didError:sdpError]; | 380 [_delegate appClient:self didError:sdpError]; |
| 375 return; | 381 return; |
| (...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 643 code:kARDAppClientErrorInvalidRoom | 649 code:kARDAppClientErrorInvalidRoom |
| 644 userInfo:@{ | 650 userInfo:@{ |
| 645 NSLocalizedDescriptionKey: @"Invalid room.", | 651 NSLocalizedDescriptionKey: @"Invalid room.", |
| 646 }]; | 652 }]; |
| 647 break; | 653 break; |
| 648 } | 654 } |
| 649 return error; | 655 return error; |
| 650 } | 656 } |
| 651 | 657 |
| 652 @end | 658 @end |
| OLD | NEW |