summaryrefslogtreecommitdiff
path: root/SmartDeviceLink/SDLProtocolReceivedMessageRouter.m
diff options
context:
space:
mode:
Diffstat (limited to 'SmartDeviceLink/SDLProtocolReceivedMessageRouter.m')
-rw-r--r--SmartDeviceLink/SDLProtocolReceivedMessageRouter.m116
1 files changed, 116 insertions, 0 deletions
diff --git a/SmartDeviceLink/SDLProtocolReceivedMessageRouter.m b/SmartDeviceLink/SDLProtocolReceivedMessageRouter.m
new file mode 100644
index 000000000..5ea7c6e63
--- /dev/null
+++ b/SmartDeviceLink/SDLProtocolReceivedMessageRouter.m
@@ -0,0 +1,116 @@
+// SDLProtocolReceivedMessageRouter.m
+//
+
+// This class gets handed the SDLProtocol messages as they are received and decides what happens to them and where they are sent on to.
+
+#import "SDLProtocolReceivedMessageRouter.h"
+#import "SDLDebugTool.h"
+#import "SDLProtocolMessage.h"
+#import "SDLProtocolMessageAssembler.h"
+
+
+@interface SDLProtocolReceivedMessageRouter ()
+
+@property (assign) BOOL alreadyDestructed;
+@property (strong) NSMutableDictionary *messageAssemblers;
+
+- (void)dispatchProtocolMessage:(SDLProtocolMessage *)message;
+- (void)dispatchControlMessage:(SDLProtocolMessage *)message;
+- (void)dispatchMultiPartMessage:(SDLProtocolMessage *)message;
+
+@end
+
+
+@implementation SDLProtocolReceivedMessageRouter
+
+- (instancetype)init {
+ if (self = [super init]) {
+ _alreadyDestructed = NO;
+ self.messageAssemblers = [NSMutableDictionary dictionaryWithCapacity:2];
+ }
+ return self;
+}
+
+- (void)handleReceivedMessage:(SDLProtocolMessage *)message {
+ SDLFrameType frameType = message.header.frameType;
+
+ switch (frameType) {
+ case SDLFrameType_Single: {
+ [self dispatchProtocolMessage:message];
+ } break;
+ case SDLFrameType_Control: {
+ [self dispatchControlMessage:message];
+ } break;
+ case SDLFrameType_First: // fallthrough
+ case SDLFrameType_Consecutive: {
+ [self dispatchMultiPartMessage:message];
+ } break;
+ default: break;
+ }
+}
+
+- (void)dispatchProtocolMessage:(SDLProtocolMessage *)message {
+ [self.delegate onProtocolMessageReceived:message];
+}
+
+- (void)dispatchControlMessage:(SDLProtocolMessage *)message {
+ switch (message.header.frameData) {
+ case SDLFrameData_StartSessionACK: {
+ [self.delegate handleProtocolStartSessionACK:message.header.serviceType
+ sessionID:message.header.sessionID
+ version:message.header.version];
+
+ } break;
+ case SDLFrameData_StartSessionNACK: {
+ [self.delegate handleProtocolStartSessionNACK:message.header.serviceType];
+ } break;
+ case SDLFrameData_EndSessionACK: {
+ [self.delegate handleProtocolEndSessionACK:message.header.serviceType];
+ } break;
+ case SDLFrameData_EndSessionNACK: {
+ [self.delegate handleProtocolStartSessionNACK:message.header.serviceType];
+ } break;
+ case SDLFrameData_Heartbeat: {
+ [self.delegate handleHeartbeatForSession:message.header.sessionID];
+ } break;
+ case SDLFrameData_HeartbeatACK: {
+ [self.delegate handleHeartbeatACK];
+ } break;
+ default: break;
+ }
+}
+
+- (void)dispatchMultiPartMessage:(SDLProtocolMessage *)message {
+ // Pass multipart messages to an assembler and call delegate when done.
+ NSNumber *sessionID = [NSNumber numberWithUnsignedChar:message.header.sessionID];
+
+ SDLProtocolMessageAssembler *assembler = self.messageAssemblers[sessionID];
+ if (assembler == nil) {
+ assembler = [[SDLProtocolMessageAssembler alloc] initWithSessionID:message.header.sessionID];
+ self.messageAssemblers[sessionID] = assembler;
+ }
+
+ SDLMessageAssemblyCompletionHandler completionHandler = ^void(BOOL done, SDLProtocolMessage *assembledMessage) {
+ if (done) {
+ [self dispatchProtocolMessage:assembledMessage];
+ }
+ };
+ [assembler handleMessage:message withCompletionHandler:completionHandler];
+}
+
+- (void)destructObjects {
+ if (!self.alreadyDestructed) {
+ self.alreadyDestructed = YES;
+ self.delegate = nil;
+ }
+}
+
+- (void)dispose {
+ [self destructObjects];
+}
+
+- (void)dealloc {
+ [self destructObjects];
+}
+
+@end