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 |