summaryrefslogtreecommitdiff
path: root/SmartDeviceLink/SDLProtocolMessage.m
blob: bfc33c4d732643059f6d47b30bfbab01327f86c7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
//  SDLProtocolMessage.m
//


#import "SDLProtocolMessage.h"
#import "SDLFunctionID.h"
#import "SDLProtocolHeader.h"
#import "SDLRPCPayload.h"
#import "SDLV1ProtocolMessage.h"
#import "SDLV2ProtocolMessage.h"

@interface SDLProtocolMessage ()

@property (strong) NSMutableData *internalBuffer;

@end

@implementation SDLProtocolMessage

// For use in decoding a stream of bytes.
// Pass in bytes representing message (or beginning of message)
// Looks at and parses first byte to determine version.
+ (UInt8)determineVersion:(NSData *)data {
    UInt8 firstByte = ((UInt8 *)data.bytes)[0];
    UInt8 version = firstByte >> 4;
    return version;
}

- (instancetype)init {
    if (self = [super init]) {
    }
    return self;
}

- (NSDictionary *)rpcDictionary {
    [self doesNotRecognizeSelector:_cmd];
    return nil;
}

- (NSUInteger)size {
    return (self.header.size + self.payload.length);
}

- (NSData *)data {
    NSMutableData *dataOut = [NSMutableData dataWithCapacity:[self size]];
    [dataOut appendData:self.header.data];
    [dataOut appendData:self.payload];

    return dataOut;
}

- (NSString *)description {
    // Print the header data.
    NSMutableString *description = [[NSMutableString alloc] init];
    [description appendString:self.header.description];

    // If it's an RPC, provide greater detail
    if (((self.header.serviceType == SDLServiceType_RPC) || (self.header.serviceType == SDLServiceType_BulkData)) && (self.header.frameType == SDLFrameType_Single)) {
        // version of RPC Message determines how we access the info.
        if (self.header.version >= 2) {
            SDLRPCPayload *rpcPayload = [SDLRPCPayload rpcPayloadWithData:self.payload];
            if (rpcPayload) {
                NSString *functionName = [[[SDLFunctionID alloc] init] getFunctionName:rpcPayload.functionID];

                UInt8 rpcType = rpcPayload.rpcType;
                NSArray *rpcTypeNames = @[@"Request", @"Response", @"Notification"];
                NSString *rpcTypeString = nil;
                if (rpcType >= 0 && rpcType < rpcTypeNames.count) {
                    rpcTypeString = rpcTypeNames[rpcType];
                }
                [description appendFormat:@" RPC Info: %@ %@", functionName, rpcTypeString];
            }
        } else {
            // version == 1
            // turn payload (which is JSON string) into dictionary and extract fields of interest.
        }
    } else {
        // Not an RPC, provide generic info.
        [description appendFormat:@" Payload: %lu bytes.", (unsigned long)self.payload.length];
    }

    return description;
}

// Returns a V1 or V2 object
+ (id)messageWithHeader:(SDLProtocolHeader *)header andPayload:(NSData *)payload {
    SDLProtocolMessage *newMessage = nil;

    UInt8 version = header.version;
    if (version == 1) {
        newMessage = [[SDLV1ProtocolMessage alloc] initWithHeader:(SDLProtocolHeader *)header andPayload:(NSData *)payload];
    } else if (version >= 2) {
        newMessage = [[SDLV2ProtocolMessage alloc] initWithHeader:(SDLProtocolHeader *)header andPayload:(NSData *)payload];
    } else {
        @throw [NSException exceptionWithName:NSInternalInconsistencyException reason:@"Attempted to create an SDLMessage, but the version of the header passed was 0" userInfo:nil];
    }

    return newMessage;
}

@end