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 "RTCLogging.h"
14
15#import "ARDUtilities.h"
16#import "RTCICECandidate+JSON.h"
17#import "RTCSessionDescription+JSON.h"
18
19static NSString const *kARDSignalingMessageTypeKey = @"type";
20
21@implementation ARDSignalingMessage
22
23@synthesize type = _type;
24
25- (instancetype)initWithType:(ARDSignalingMessageType)type {
26  if (self = [super init]) {
27    _type = type;
28  }
29  return self;
30}
31
32- (NSString *)description {
33  return [[NSString alloc] initWithData:[self JSONData]
34                               encoding:NSUTF8StringEncoding];
35}
36
37+ (ARDSignalingMessage *)messageFromJSONString:(NSString *)jsonString {
38  NSDictionary *values = [NSDictionary dictionaryWithJSONString:jsonString];
39  if (!values) {
40    RTCLogError(@"Error parsing signaling message JSON.");
41    return nil;
42  }
43
44  NSString *typeString = values[kARDSignalingMessageTypeKey];
45  ARDSignalingMessage *message = nil;
46  if ([typeString isEqualToString:@"candidate"]) {
47    RTCICECandidate *candidate =
48        [RTCICECandidate candidateFromJSONDictionary:values];
49    message = [[ARDICECandidateMessage alloc] initWithCandidate:candidate];
50  } else if ([typeString isEqualToString:@"offer"] ||
51             [typeString isEqualToString:@"answer"]) {
52    RTCSessionDescription *description =
53        [RTCSessionDescription descriptionFromJSONDictionary:values];
54    message =
55        [[ARDSessionDescriptionMessage alloc] initWithDescription:description];
56  } else if ([typeString isEqualToString:@"bye"]) {
57    message = [[ARDByeMessage alloc] init];
58  } else {
59    RTCLogError(@"Unexpected type: %@", typeString);
60  }
61  return message;
62}
63
64- (NSData *)JSONData {
65  return nil;
66}
67
68@end
69
70@implementation ARDICECandidateMessage
71
72@synthesize candidate = _candidate;
73
74- (instancetype)initWithCandidate:(RTCICECandidate *)candidate {
75  if (self = [super initWithType:kARDSignalingMessageTypeCandidate]) {
76    _candidate = candidate;
77  }
78  return self;
79}
80
81- (NSData *)JSONData {
82  return [_candidate JSONData];
83}
84
85@end
86
87@implementation ARDSessionDescriptionMessage
88
89@synthesize sessionDescription = _sessionDescription;
90
91- (instancetype)initWithDescription:(RTCSessionDescription *)description {
92  ARDSignalingMessageType type = kARDSignalingMessageTypeOffer;
93  NSString *typeString = description.type;
94  if ([typeString isEqualToString:@"offer"]) {
95    type = kARDSignalingMessageTypeOffer;
96  } else if ([typeString isEqualToString:@"answer"]) {
97    type = kARDSignalingMessageTypeAnswer;
98  } else {
99    NSAssert(NO, @"Unexpected type: %@", typeString);
100  }
101  if (self = [super initWithType:type]) {
102    _sessionDescription = description;
103  }
104  return self;
105}
106
107- (NSData *)JSONData {
108  return [_sessionDescription JSONData];
109}
110
111@end
112
113@implementation ARDByeMessage
114
115- (instancetype)init {
116  return [super initWithType:kARDSignalingMessageTypeBye];
117}
118
119- (NSData *)JSONData {
120  NSDictionary *message = @{
121    @"type": @"bye"
122  };
123  return [NSJSONSerialization dataWithJSONObject:message
124                                         options:NSJSONWritingPrettyPrinted
125                                           error:NULL];
126}
127
128@end
129