1/* 2 * Copyright 2014 The WebRTC Project Authors. All rights reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11#import "ARDSignalingMessage.h" 12 13#import "sdk/objc/base/RTCLogging.h" 14 15#import "ARDUtilities.h" 16#import "RTCIceCandidate+JSON.h" 17#import "RTCSessionDescription+JSON.h" 18 19static NSString * const kARDSignalingMessageTypeKey = @"type"; 20static NSString * const kARDTypeValueRemoveCandidates = @"remove-candidates"; 21 22@implementation ARDSignalingMessage 23 24@synthesize type = _type; 25 26- (instancetype)initWithType:(ARDSignalingMessageType)type { 27 if (self = [super init]) { 28 _type = type; 29 } 30 return self; 31} 32 33- (NSString *)description { 34 return [[NSString alloc] initWithData:[self JSONData] 35 encoding:NSUTF8StringEncoding]; 36} 37 38+ (ARDSignalingMessage *)messageFromJSONString:(NSString *)jsonString { 39 NSDictionary *values = [NSDictionary dictionaryWithJSONString:jsonString]; 40 if (!values) { 41 RTCLogError(@"Error parsing signaling message JSON."); 42 return nil; 43 } 44 45 NSString *typeString = values[kARDSignalingMessageTypeKey]; 46 ARDSignalingMessage *message = nil; 47 if ([typeString isEqualToString:@"candidate"]) { 48 RTC_OBJC_TYPE(RTCIceCandidate) *candidate = 49 [RTC_OBJC_TYPE(RTCIceCandidate) candidateFromJSONDictionary:values]; 50 message = [[ARDICECandidateMessage alloc] initWithCandidate:candidate]; 51 } else if ([typeString isEqualToString:kARDTypeValueRemoveCandidates]) { 52 RTCLogInfo(@"Received remove-candidates message"); 53 NSArray<RTC_OBJC_TYPE(RTCIceCandidate) *> *candidates = 54 [RTC_OBJC_TYPE(RTCIceCandidate) candidatesFromJSONDictionary:values]; 55 message = [[ARDICECandidateRemovalMessage alloc] 56 initWithRemovedCandidates:candidates]; 57 } else if ([typeString isEqualToString:@"offer"] || 58 [typeString isEqualToString:@"answer"]) { 59 RTC_OBJC_TYPE(RTCSessionDescription) *description = 60 [RTC_OBJC_TYPE(RTCSessionDescription) descriptionFromJSONDictionary:values]; 61 message = 62 [[ARDSessionDescriptionMessage alloc] initWithDescription:description]; 63 } else if ([typeString isEqualToString:@"bye"]) { 64 message = [[ARDByeMessage alloc] init]; 65 } else { 66 RTCLogError(@"Unexpected type: %@", typeString); 67 } 68 return message; 69} 70 71- (NSData *)JSONData { 72 return nil; 73} 74 75@end 76 77@implementation ARDICECandidateMessage 78 79@synthesize candidate = _candidate; 80 81- (instancetype)initWithCandidate:(RTC_OBJC_TYPE(RTCIceCandidate) *)candidate { 82 if (self = [super initWithType:kARDSignalingMessageTypeCandidate]) { 83 _candidate = candidate; 84 } 85 return self; 86} 87 88- (NSData *)JSONData { 89 return [_candidate JSONData]; 90} 91 92@end 93 94@implementation ARDICECandidateRemovalMessage 95 96@synthesize candidates = _candidates; 97 98- (instancetype)initWithRemovedCandidates:(NSArray<RTC_OBJC_TYPE(RTCIceCandidate) *> *)candidates { 99 NSParameterAssert(candidates.count); 100 if (self = [super initWithType:kARDSignalingMessageTypeCandidateRemoval]) { 101 _candidates = candidates; 102 } 103 return self; 104} 105 106- (NSData *)JSONData { 107 return [RTC_OBJC_TYPE(RTCIceCandidate) JSONDataForIceCandidates:_candidates 108 withType:kARDTypeValueRemoveCandidates]; 109} 110 111@end 112 113@implementation ARDSessionDescriptionMessage 114 115@synthesize sessionDescription = _sessionDescription; 116 117- (instancetype)initWithDescription:(RTC_OBJC_TYPE(RTCSessionDescription) *)description { 118 ARDSignalingMessageType messageType = kARDSignalingMessageTypeOffer; 119 RTCSdpType sdpType = description.type; 120 switch (sdpType) { 121 case RTCSdpTypeOffer: 122 messageType = kARDSignalingMessageTypeOffer; 123 break; 124 case RTCSdpTypeAnswer: 125 messageType = kARDSignalingMessageTypeAnswer; 126 break; 127 case RTCSdpTypePrAnswer: 128 case RTCSdpTypeRollback: 129 NSAssert( 130 NO, @"Unexpected type: %@", [RTC_OBJC_TYPE(RTCSessionDescription) stringForType:sdpType]); 131 break; 132 } 133 if (self = [super initWithType:messageType]) { 134 _sessionDescription = description; 135 } 136 return self; 137} 138 139- (NSData *)JSONData { 140 return [_sessionDescription JSONData]; 141} 142 143@end 144 145@implementation ARDByeMessage 146 147- (instancetype)init { 148 return [super initWithType:kARDSignalingMessageTypeBye]; 149} 150 151- (NSData *)JSONData { 152 NSDictionary *message = @{ 153 @"type": @"bye" 154 }; 155 return [NSJSONSerialization dataWithJSONObject:message 156 options:NSJSONWritingPrettyPrinted 157 error:NULL]; 158} 159 160@end 161