diff options
Diffstat (limited to 'SmartDeviceLink/SDLV1ProtocolHeader.m')
-rw-r--r-- | SmartDeviceLink/SDLV1ProtocolHeader.m | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/SmartDeviceLink/SDLV1ProtocolHeader.m b/SmartDeviceLink/SDLV1ProtocolHeader.m new file mode 100644 index 000000000..61c976c51 --- /dev/null +++ b/SmartDeviceLink/SDLV1ProtocolHeader.m @@ -0,0 +1,84 @@ +// SDLSmartDeviceLinkV1ProtocolHeader.m +// + + +#import "SDLV1ProtocolHeader.h" + +const int V1PROTOCOL_HEADERSIZE = 8; + +@implementation SDLV1ProtocolHeader + +- (instancetype)init { + if (self = [super init]) { + _version = 1; + _size = V1PROTOCOL_HEADERSIZE; + } + return self; +} + +- (NSData *)data { + // Assembles the properties in the binary header format + Byte headerBytes[V1PROTOCOL_HEADERSIZE] = {0}; + + Byte version = (self.version & 0xF) << 4; // first 4 bits + Byte compressed = (self.compressed ? 1 : 0) << 3; // next 1 bit + Byte frameType = (self.frameType & 0x7); // last 3 bits + + headerBytes[0] = version | compressed | frameType; + headerBytes[1] = self.serviceType; + headerBytes[2] = self.frameData; + headerBytes[3] = self.sessionID; + + // Need to write the larger ints as big-endian. + UInt32 *p = (UInt32 *)&headerBytes[4]; + *p = CFSwapInt32HostToBig(self.bytesInPayload); // swap the byte order + + // Now put it all in an NSData object. + NSData *dataOut = [NSData dataWithBytes:headerBytes length:V1PROTOCOL_HEADERSIZE]; + + return dataOut; +} + +- (id)copyWithZone:(NSZone *)zone { + SDLV1ProtocolHeader *newHeader = [[SDLV1ProtocolHeader allocWithZone:zone] init]; + newHeader.compressed = self.compressed; + newHeader.frameType = self.frameType; + newHeader.serviceType = self.serviceType; + newHeader.frameData = self.frameData; + newHeader.bytesInPayload = self.bytesInPayload; + newHeader.sessionID = self.sessionID; + + return newHeader; +} + +- (void)parse:(NSData *)data { + NSParameterAssert(data != nil); + NSAssert(data.length >= _size, @"Error: insufficient data available to parse V1 header."); + + Byte *bytePointer = (Byte *)data.bytes; + Byte firstByte = bytePointer[0]; + self.compressed = ((firstByte & 8) != 0); + self.frameType = (firstByte & 7); + self.serviceType = bytePointer[1]; + self.frameData = bytePointer[2]; + self.sessionID = bytePointer[3]; + + UInt32 *uintPointer = (UInt32 *)data.bytes; + self.bytesInPayload = CFSwapInt32BigToHost(uintPointer[1]); // Data is coming in in big-endian, so swap it. +} + +- (NSString *)description { + NSMutableString *description = [[NSMutableString alloc] init]; + [description appendFormat:@"Version:%i, compressed:%i, frameType:%i, serviceType:%i, frameData:%i, sessionID:%i, dataSize:%i", + self.version, + self.compressed, + self.frameType, + self.serviceType, + self.frameData, + self.sessionID, + (unsigned int)self.bytesInPayload]; + return description; +} + + +@end |