diff options
author | Joel Fischer <joeljfischer@gmail.com> | 2020-07-22 10:51:52 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-07-22 10:51:52 -0400 |
commit | 2cd82975807f5b710c60fad7b4442578043c741c (patch) | |
tree | 418deab7dfbf170c00baefb82f5c0a24dd8fe550 | |
parent | 905175db124c1c80a7ae9611b98c48d7f9b2a2bd (diff) | |
parent | f667f55b99eeffc2bfa69abd16c7a5eece1baa47 (diff) | |
download | sdl_ios-2cd82975807f5b710c60fad7b4442578043c741c.tar.gz |
Merge pull request #1717 from smartdevicelink/bugfix/issue_1716_register_sec_transports_timer6.7.0-rc.2
The secondary transport manager now only starts a timer when the secondary transport has opened
16 files changed, 463 insertions, 305 deletions
diff --git a/SmartDeviceLink/SDLEncryptionLifecycleManager.m b/SmartDeviceLink/SDLEncryptionLifecycleManager.m index b6dbc73c3..b141080e4 100644 --- a/SmartDeviceLink/SDLEncryptionLifecycleManager.m +++ b/SmartDeviceLink/SDLEncryptionLifecycleManager.m @@ -171,10 +171,10 @@ typedef NSString SDLVehicleMake; SDLLogD(@"Encryption manager stopped"); } -#pragma mark - SDLProtocolListener +#pragma mark - SDLProtocolDelegate #pragma mark Encryption Start Service ACK -- (void)handleProtocolStartServiceACKMessage:(SDLProtocolMessage *)startServiceACK { +- (void)protocol:(SDLProtocol *)protocol didReceiveStartServiceACK:(SDLProtocolMessage *)startServiceACK { switch (startServiceACK.header.serviceType) { case SDLServiceTypeRPC: { [self sdl_handleEncryptionStartServiceACK:startServiceACK]; @@ -197,7 +197,7 @@ typedef NSString SDLVehicleMake; #pragma mark Encryption Start Service NAK -- (void)handleProtocolStartServiceNAKMessage:(SDLProtocolMessage *)startServiceNAK { +- (void)protocol:(SDLProtocol *)protocol didReceiveStartServiceNAK:(SDLProtocolMessage *)startServiceNAK { switch (startServiceNAK.header.serviceType) { case SDLServiceTypeRPC: { [self sdl_handleEncryptionStartServiceNAK:startServiceNAK]; @@ -214,7 +214,7 @@ typedef NSString SDLVehicleMake; #pragma mark Encryption End Service -- (void)handleProtocolEndServiceACKMessage:(SDLProtocolMessage *)endServiceACK { +- (void)protocol:(SDLProtocol *)protocol didReceiveEndServiceACK:(SDLProtocolMessage *)endServiceACK { switch (endServiceACK.header.serviceType) { case SDLServiceTypeRPC: { SDLLogW(@"Encryption RPC service ended with end service ACK"); @@ -225,7 +225,7 @@ typedef NSString SDLVehicleMake; } } -- (void)handleProtocolEndServiceNAKMessage:(SDLProtocolMessage *)endServiceNAK { +- (void)protocol:(SDLProtocol *)protocol didReceiveEndServiceNAK:(SDLProtocolMessage *)endServiceNAK { switch (endServiceNAK.header.serviceType) { case SDLServiceTypeRPC: { SDLLogW(@"Encryption RPC service ended with end service NAK"); diff --git a/SmartDeviceLink/SDLLifecycleProtocolHandler.m b/SmartDeviceLink/SDLLifecycleProtocolHandler.m index d517e89ee..49a789637 100644 --- a/SmartDeviceLink/SDLLifecycleProtocolHandler.m +++ b/SmartDeviceLink/SDLLifecycleProtocolHandler.m @@ -69,7 +69,9 @@ NS_ASSUME_NONNULL_BEGIN #pragma mark - SDLProtocolDelegate /// Called when the transport is opened. We will send the RPC Start Service and wait for the RPC Start Service ACK -- (void)onProtocolOpened { +- (void)protocolDidOpen:(SDLProtocol *)protocol { + if (self.protocol != protocol) { return; } + SDLLogD(@"Transport opened, sending an RPC Start Service, and starting timer for RPC Start Service ACK to be received."); [self.notificationDispatcher postNotificationName:SDLTransportDidConnect infoObject:nil]; @@ -81,25 +83,30 @@ NS_ASSUME_NONNULL_BEGIN __weak typeof(self) weakSelf = self; self.rpcStartServiceTimeoutTimer.elapsedBlock = ^{ SDLLogE(@"Start session timed out after %f seconds, closing the connection.", StartSessionTime); - [weakSelf performSelector:@selector(onProtocolClosed) withObject:nil afterDelay:0.1]; + [weakSelf.protocol stopWithCompletionHandler:^{}]; }; } [self.rpcStartServiceTimeoutTimer start]; } /// Called when the transport is closed. -- (void)onProtocolClosed { +- (void)protocolDidClose:(SDLProtocol *)protocol { + if (self.protocol != protocol) { return; } + SDLLogW(@"Transport disconnected"); [self.notificationDispatcher postNotificationName:SDLTransportDidDisconnect infoObject:nil]; } -- (void)onTransportError:(NSError *)error { - SDLLogW(@"Transport error: %@", error); +- (void)protocol:(SDLProtocol *)protocol transportDidError:(NSError *)error { + if (self.protocol != protocol) { return; } + SDLLogW(@"Transport error: %@", error); [self.notificationDispatcher postNotificationName:SDLTransportConnectError infoObject:error]; } -- (void)handleProtocolStartServiceACKMessage:(SDLProtocolMessage *)startServiceACK { +- (void)protocol:(SDLProtocol *)protocol didReceiveStartServiceACK:(SDLProtocolMessage *)startServiceACK { + if (self.protocol != protocol) { return; } + SDLLogD(@"Start Service (ACK) SessionId: %d for serviceType %d", startServiceACK.header.sessionID, startServiceACK.header.serviceType); if (startServiceACK.header.serviceType == SDLServiceTypeRPC) { @@ -108,7 +115,9 @@ NS_ASSUME_NONNULL_BEGIN } } -- (void)handleProtocolStartServiceNAKMessage:(SDLProtocolMessage *)startServiceNAK { +- (void)protocol:(SDLProtocol *)protocol didReceiveStartServiceNAK:(SDLProtocolMessage *)startServiceNAK { + if (self.protocol != protocol) { return; } + SDLLogD(@"Start Service (NAK): SessionId: %d for serviceType %d", startServiceNAK.header.sessionID, startServiceNAK.header.serviceType); if (startServiceNAK.header.serviceType == SDLServiceTypeRPC) { @@ -117,7 +126,9 @@ NS_ASSUME_NONNULL_BEGIN } } -- (void)handleProtocolEndServiceACKMessage:(SDLProtocolMessage *)endServiceACK { +- (void)protocol:(SDLProtocol *)protocol didReceiveEndServiceACK:(SDLProtocolMessage *)endServiceACK { + if (self.protocol != protocol) { return; } + SDLLogD(@"End Service (ACK): SessionId: %d for serviceType %d", endServiceACK.header.sessionID, endServiceACK.header.serviceType); if (endServiceACK.header.serviceType == SDLServiceTypeRPC) { @@ -126,14 +137,18 @@ NS_ASSUME_NONNULL_BEGIN } } -- (void)handleProtocolEndServiceNAKMessage:(SDLProtocolMessage *)endServiceNAK { +- (void)protocol:(SDLProtocol *)protocol didReceiveEndServiceNAK:(SDLProtocolMessage *)endServiceNAK { + if (self.protocol != protocol) { return; } + if (endServiceNAK.header.serviceType == SDLServiceTypeRPC) { NSError *error = [NSError sdl_lifecycle_unknownRemoteErrorWithDescription:@"RPC Service failed to stop" andReason:nil]; [self.notificationDispatcher postNotificationName:SDLRPCServiceConnectionDidError infoObject:error]; } } -- (void)onProtocolMessageReceived:(SDLProtocolMessage *)msg { +- (void)protocol:(SDLProtocol *)protocol didReceiveMessage:(SDLProtocolMessage *)msg { + if (self.protocol != protocol) { return; } + NSDictionary<NSString *, id> *rpcMessageAsDictionary = [msg rpcDictionary]; SDLRPCMessage *receivedMessage = [[SDLRPCMessage alloc] initWithDictionary:rpcMessageAsDictionary]; NSString *fullName = [self sdl_fullNameForMessage:receivedMessage]; diff --git a/SmartDeviceLink/SDLProtocol.m b/SmartDeviceLink/SDLProtocol.m index 31b5e4ca8..d9d3c03d7 100644 --- a/SmartDeviceLink/SDLProtocol.m +++ b/SmartDeviceLink/SDLProtocol.m @@ -128,8 +128,8 @@ NS_ASSUME_NONNULL_BEGIN listeners = self.protocolDelegateTable.allObjects; } for (id<SDLProtocolDelegate> listener in listeners) { - if ([listener respondsToSelector:@selector(onProtocolOpened)]) { - [listener onProtocolOpened]; + if ([listener respondsToSelector:@selector(protocolDidOpen:)]) { + [listener protocolDidOpen:self]; } } } @@ -141,8 +141,8 @@ NS_ASSUME_NONNULL_BEGIN listeners = self.protocolDelegateTable.allObjects; } for (id<SDLProtocolDelegate> listener in listeners) { - if ([listener respondsToSelector:@selector(onProtocolClosed)]) { - [listener onProtocolClosed]; + if ([listener respondsToSelector:@selector(protocolDidClose:)]) { + [listener protocolDidClose:self]; } } } @@ -154,8 +154,8 @@ NS_ASSUME_NONNULL_BEGIN - (void)onError:(NSError *)error { SDLLogV(@"Transport received an error: %@", error); for (id<SDLProtocolDelegate> listener in self.protocolDelegateTable.allObjects) { - if ([listener respondsToSelector:@selector(onTransportError:)]) { - [listener onTransportError:error]; + if ([listener respondsToSelector:@selector(protocol:transportDidError:)]) { + [listener protocol:self transportDidError:error]; } } } @@ -494,7 +494,7 @@ NS_ASSUME_NONNULL_BEGIN self.receiveBuffer = [[self.receiveBuffer subdataWithRange:NSMakeRange(messageSize, self.receiveBuffer.length - messageSize)] mutableCopy]; // Pass on the message to the message router. - [self.messageRouter handleReceivedMessage:message]; + [self.messageRouter handleReceivedMessage:message protocol:self]; // Call recursively until the buffer is empty or incomplete message is encountered if (self.receiveBuffer.length > 0) { @@ -505,7 +505,7 @@ NS_ASSUME_NONNULL_BEGIN #pragma mark - SDLProtocolDelegate from SDLReceivedProtocolMessageRouter -- (void)handleProtocolStartServiceACKMessage:(SDLProtocolMessage *)startServiceACK { +- (void)protocol:(SDLProtocol *)protocol didReceiveStartServiceACK:(SDLProtocolMessage *)startServiceACK { SDLLogD(@"Received start service ACK: %@", startServiceACK); // V5+ Packet @@ -546,65 +546,65 @@ NS_ASSUME_NONNULL_BEGIN // Pass along to all the listeners NSArray<id<SDLProtocolDelegate>> *listeners = [self sdl_getProtocolListeners]; for (id<SDLProtocolDelegate> listener in listeners) { - if ([listener respondsToSelector:@selector(handleProtocolStartServiceACKMessage:)]) { - [listener handleProtocolStartServiceACKMessage:startServiceACK]; + if ([listener respondsToSelector:@selector(protocol:didReceiveStartServiceACK:)]) { + [listener protocol:protocol didReceiveStartServiceACK:startServiceACK]; } } } -- (void)handleProtocolStartServiceNAKMessage:(SDLProtocolMessage *)startServiceNAK { +- (void)protocol:(SDLProtocol *)protocol didReceiveStartServiceNAK:(SDLProtocolMessage *)startServiceNAK { [self sdl_logControlNAKPayload:startServiceNAK]; NSArray<id<SDLProtocolDelegate>> *listeners = [self sdl_getProtocolListeners]; for (id<SDLProtocolDelegate> listener in listeners) { - if ([listener respondsToSelector:@selector(handleProtocolStartServiceNAKMessage:)]) { - [listener handleProtocolStartServiceNAKMessage:startServiceNAK]; + if ([listener respondsToSelector:@selector(protocol:didReceiveStartServiceNAK:)]) { + [listener protocol:protocol didReceiveStartServiceNAK:startServiceNAK]; } } } -- (void)handleProtocolEndServiceACKMessage:(SDLProtocolMessage *)endServiceACK { +- (void)protocol:(SDLProtocol *)protocol didReceiveEndServiceACK:(SDLProtocolMessage *)endServiceACK { SDLLogD(@"End service ACK: %@", endServiceACK); // Remove the session id [self.serviceHeaders removeObjectForKey:@(endServiceACK.header.serviceType)]; NSArray<id<SDLProtocolDelegate>> *listeners = [self sdl_getProtocolListeners]; for (id<SDLProtocolDelegate> listener in listeners) { - if ([listener respondsToSelector:@selector(handleProtocolEndServiceACKMessage:)]) { - [listener handleProtocolEndServiceACKMessage:endServiceACK]; + if ([listener respondsToSelector:@selector(protocol:didReceiveEndServiceACK:)]) { + [listener protocol:protocol didReceiveEndServiceACK:endServiceACK]; } } } -- (void)handleProtocolEndServiceNAKMessage:(SDLProtocolMessage *)endServiceNAK { +- (void)protocol:(SDLProtocol *)protocol didReceiveEndServiceNAK:(SDLProtocolMessage *)endServiceNAK { [self sdl_logControlNAKPayload:endServiceNAK]; NSArray<id<SDLProtocolDelegate>> *listeners = [self sdl_getProtocolListeners]; for (id<SDLProtocolDelegate> listener in listeners) { - if ([listener respondsToSelector:@selector(handleProtocolEndServiceNAKMessage:)]) { - [listener handleProtocolEndServiceNAKMessage:endServiceNAK]; + if ([listener respondsToSelector:@selector(protocol:didReceiveEndServiceNAK:)]) { + [listener protocol:protocol didReceiveEndServiceNAK:endServiceNAK]; } } } -- (void)handleProtocolRegisterSecondaryTransportACKMessage:(SDLProtocolMessage *)registerSecondaryTransportACK { +- (void)protocol:(SDLProtocol *)protocol didReceiveRegisterSecondaryTransportACK:(SDLProtocolMessage *)registerSecondaryTransportACK { SDLLogD(@"Register Secondary Transport ACK: %@", registerSecondaryTransportACK); NSArray<id<SDLProtocolDelegate>> *listeners = [self sdl_getProtocolListeners]; for (id<SDLProtocolDelegate> listener in listeners) { - if ([listener respondsToSelector:@selector(handleProtocolRegisterSecondaryTransportACKMessage:)]) { - [listener handleProtocolRegisterSecondaryTransportACKMessage:registerSecondaryTransportACK]; + if ([listener respondsToSelector:@selector(protocol:didReceiveRegisterSecondaryTransportACK:)]) { + [listener protocol:protocol didReceiveRegisterSecondaryTransportACK:registerSecondaryTransportACK]; } } } -- (void)handleProtocolRegisterSecondaryTransportNAKMessage:(SDLProtocolMessage *)registerSecondaryTransportNAK { +- (void)protocol:(SDLProtocol *)protocol didReceiveRegisterSecondaryTransportNAK:(SDLProtocolMessage *)registerSecondaryTransportNAK { [self sdl_logControlNAKPayload:registerSecondaryTransportNAK]; NSArray<id<SDLProtocolDelegate>> *listeners = [self sdl_getProtocolListeners]; for (id<SDLProtocolDelegate> listener in listeners) { - if ([listener respondsToSelector:@selector(handleProtocolRegisterSecondaryTransportNAKMessage:)]) { - [listener handleProtocolRegisterSecondaryTransportNAKMessage:registerSecondaryTransportNAK]; + if ([listener respondsToSelector:@selector(protocol:didReceiveRegisterSecondaryTransportNAK:)]) { + [listener protocol:protocol didReceiveRegisterSecondaryTransportNAK:registerSecondaryTransportNAK]; } } } @@ -640,18 +640,18 @@ NS_ASSUME_NONNULL_BEGIN } } -- (void)handleTransportEventUpdateMessage:(SDLProtocolMessage *)transportEventUpdate { +- (void)protocol:(SDLProtocol *)protocol didReceiveTransportEventUpdate:(SDLProtocolMessage *)transportEventUpdate { SDLLogD(@"Received a transport event update: %@", transportEventUpdate); NSArray<id<SDLProtocolDelegate>> *listeners = [self sdl_getProtocolListeners]; for (id<SDLProtocolDelegate> listener in listeners) { - if ([listener respondsToSelector:@selector(handleTransportEventUpdateMessage:)]) { - [listener handleTransportEventUpdateMessage:transportEventUpdate]; + if ([listener respondsToSelector:@selector(protocol:didReceiveTransportEventUpdate:)]) { + [listener protocol:protocol didReceiveTransportEventUpdate:transportEventUpdate]; } } } -- (void)onProtocolMessageReceived:(SDLProtocolMessage *)msg { +- (void)protocol:(SDLProtocol *)protocol didReceiveMessage:(SDLProtocolMessage *)msg { // Control service (but not control frame type) messages are TLS handshake messages if (msg.header.serviceType == SDLServiceTypeControl) { [self sdl_processSecurityMessage:msg]; @@ -662,8 +662,8 @@ NS_ASSUME_NONNULL_BEGIN NSArray<id<SDLProtocolDelegate>> *listeners = [self sdl_getProtocolListeners]; for (id<SDLProtocolDelegate> listener in listeners) { - if ([listener respondsToSelector:@selector(onProtocolMessageReceived:)]) { - [listener onProtocolMessageReceived:msg]; + if ([listener respondsToSelector:@selector(protocol:didReceiveMessage:)]) { + [listener protocol:protocol didReceiveMessage:msg]; } } } diff --git a/SmartDeviceLink/SDLProtocolDelegate.h b/SmartDeviceLink/SDLProtocolDelegate.h index 7b0303333..f3c55902c 100644 --- a/SmartDeviceLink/SDLProtocolDelegate.h +++ b/SmartDeviceLink/SDLProtocolDelegate.h @@ -1,8 +1,9 @@ -// SDLProtocolListener.h +// SDLProtocolDelegate.h // #import "SDLProtocolHeader.h" +@class SDLProtocol; @class SDLProtocolMessage; NS_ASSUME_NONNULL_BEGIN @@ -11,78 +12,86 @@ NS_ASSUME_NONNULL_BEGIN @optional -#pragma mark - v4.7.0 protocol handlers - -/** - * Called when the message is a start service success message. - * - * @param startServiceACK A SDLProtocolMessage object - */ -- (void)handleProtocolStartServiceACKMessage:(SDLProtocolMessage *)startServiceACK; - -/** - * Called when the message is a start service failed message. - * - * @param startServiceNAK A SDLProtocolMessage object - */ -- (void)handleProtocolStartServiceNAKMessage:(SDLProtocolMessage *)startServiceNAK; - -/** - * Called when the message is a end service success message. - * - * @param endServiceACK A SDLProtocolMessage object - */ -- (void)handleProtocolEndServiceACKMessage:(SDLProtocolMessage *)endServiceACK; - -/** - * Called when the message is a end service failed message. - * - * @param endServiceNAK A SDLProtocolMessage object - */ -- (void)handleProtocolEndServiceNAKMessage:(SDLProtocolMessage *)endServiceNAK; -- (void)handleProtocolRegisterSecondaryTransportACKMessage:(SDLProtocolMessage *)registerSecondaryTransportACK; -- (void)handleProtocolRegisterSecondaryTransportNAKMessage:(SDLProtocolMessage *)registerSecondaryTransportNAK; -- (void)handleTransportEventUpdateMessage:(SDLProtocolMessage *)transportEventUpdate; - -#pragma mark - Older protocol handlers - -/** - * Called when the message is a heartbeat message. - * - * @param session Session number - */ + +#pragma mark - Protocol Messages + +/// Called when a protocol frame is received. +/// @param msg A SDLProtocolMessage object +/// @param protocol The transport's protocol +- (void)protocol:(SDLProtocol *)protocol didReceiveMessage:(SDLProtocolMessage *)msg; + +/// Called when the start service frame succeeds. +/// @discussion This frame can be sent on both the primary and secondary transports +/// @param startServiceACK A SDLProtocolMessage object +/// @param protocol The transport's protocol +- (void)protocol:(SDLProtocol *)protocol didReceiveStartServiceACK:(SDLProtocolMessage *)startServiceACK; + +/// Called when the start service frame fails. +/// @discussion This frame can be sent on both the primary and secondary transports +/// @param startServiceNAK A SDLProtocolMessage object +/// @param protocol The transport's protocol +- (void)protocol:(SDLProtocol *)protocol didReceiveStartServiceNAK:(SDLProtocolMessage *)startServiceNAK; + +/// Called when the end service frame succeeds. +/// @discussion This frame can be sent on both the primary and secondary transports +/// @param endServiceACK A SDLProtocolMessage object +/// @param protocol The transport's protocol +- (void)protocol:(SDLProtocol *)protocol didReceiveEndServiceACK:(SDLProtocolMessage *)endServiceACK; + +/// Called when the end service frame fails. +/// @discussion This frame can be sent on both the primary and secondary transports +/// @param endServiceNAK A SDLProtocolMessage object +/// @param protocol The transport's protocol +- (void)protocol:(SDLProtocol *)protocol didReceiveEndServiceNAK:(SDLProtocolMessage *)endServiceNAK; + +#pragma mark Secondary Transport Messages + +/// Called when the secondary transport registration frame succeeds. +/// @discussion This frame is only sent on the secondary transport +/// @param registerSecondaryTransportACK A SDLProtocolMessage object +/// @param protocol The transport's protocol +- (void)protocol:(SDLProtocol *)protocol didReceiveRegisterSecondaryTransportACK:(SDLProtocolMessage *)registerSecondaryTransportACK; + +/// Called when the secondary transport registration frame fails. +/// @discussion This frame is only sent on the secondary transport +/// @param registerSecondaryTransportNAK A SDLProtocolMessage object +/// @param protocol The transport's protocol +- (void)protocol:(SDLProtocol *)protocol didReceiveRegisterSecondaryTransportNAK:(SDLProtocolMessage *)registerSecondaryTransportNAK; + +/// Called when the status or configuration of one or more transports has updated. +/// @discussion This frame is only sent on the primary transport +/// @param transportEventUpdate A SDLProtocolMessage object +/// @param protocol The transport's protocol +- (void)protocol:(SDLProtocol *)protocol didReceiveTransportEventUpdate:(SDLProtocolMessage *)transportEventUpdate; + +#pragma mark - Transport Lifecycle + +/// Called when the transport opens. +/// @param protocol The transport's protocol +- (void)protocolDidOpen:(SDLProtocol *)protocol; + +/// Called when the transport closes. +/// @param protocol The transport's protocol +- (void)protocolDidClose:(SDLProtocol *)protocol; + +/// Called when the transport errors. +/// @discussion Currently only used by TCP transport. +/// @param error The error +/// @param protocol The transport's protocol +- (void)protocol:(SDLProtocol *)protocol transportDidError:(NSError *)error; + +#pragma mark - Deprecated Protocol Messages + +/// A ping packet that is sent to ensure the connection is still active and the service is still valid. +/// @discussion Deprecated - requires protocol major version 3 +/// @param session The session number - (void)handleHeartbeatForSession:(Byte)session; -/** - * Called when the message is a heartbeat success message. - */ +/// Called when the heartbeat frame was recieved successfully. +/// @discussion Deprecated - requires protocol major version 3 - (void)handleHeartbeatACK; -/** - * Called when the message is protocol message. - * - * @param msg A SDLProtocolMessage object - */ -- (void)onProtocolMessageReceived:(SDLProtocolMessage *)msg; - -/** - * Called when the message is a protocol opened message. - */ -- (void)onProtocolOpened; - -/** - * Called when the message is a protocol closed message. - */ -- (void)onProtocolClosed; - -/** - * Called when an error is notified from transport. - * - * Note: currently, this is used only by TCP transport. - * - * @param error The type of the error - */ -- (void)onTransportError:(NSError *)error; + @end diff --git a/SmartDeviceLink/SDLProtocolReceivedMessageRouter.h b/SmartDeviceLink/SDLProtocolReceivedMessageRouter.h index 40f0b7168..d025310a3 100644 --- a/SmartDeviceLink/SDLProtocolReceivedMessageRouter.h +++ b/SmartDeviceLink/SDLProtocolReceivedMessageRouter.h @@ -19,7 +19,7 @@ NS_ASSUME_NONNULL_BEGIN * * @param message A SDLProtocolMessage object */ -- (void)handleReceivedMessage:(SDLProtocolMessage *)message; +- (void)handleReceivedMessage:(SDLProtocolMessage *)message protocol:(SDLProtocol *)protocol; @end diff --git a/SmartDeviceLink/SDLProtocolReceivedMessageRouter.m b/SmartDeviceLink/SDLProtocolReceivedMessageRouter.m index a4bbf71e2..6c51f0079 100644 --- a/SmartDeviceLink/SDLProtocolReceivedMessageRouter.m +++ b/SmartDeviceLink/SDLProtocolReceivedMessageRouter.m @@ -26,60 +26,60 @@ NS_ASSUME_NONNULL_BEGIN return self; } -- (void)handleReceivedMessage:(SDLProtocolMessage *)message { +- (void)handleReceivedMessage:(SDLProtocolMessage *)message protocol:(SDLProtocol *)protocol { SDLFrameType frameType = message.header.frameType; switch (frameType) { case SDLFrameTypeSingle: { - [self sdl_dispatchProtocolMessage:message]; + [self sdl_dispatchProtocolMessage:message protocol:protocol]; } break; case SDLFrameTypeControl: { - [self sdl_dispatchControlMessage:message]; + [self sdl_dispatchControlMessage:message protocol:protocol]; } break; case SDLFrameTypeFirst: // fallthrough case SDLFrameTypeConsecutive: { - [self sdl_dispatchMultiPartMessage:message]; + [self sdl_dispatchMultiPartMessage:message protocol:protocol]; } break; default: break; } } -- (void)sdl_dispatchProtocolMessage:(SDLProtocolMessage *)message { - if ([self.delegate respondsToSelector:@selector(onProtocolMessageReceived:)]) { - [self.delegate onProtocolMessageReceived:message]; +- (void)sdl_dispatchProtocolMessage:(SDLProtocolMessage *)message protocol:(SDLProtocol *)protocol { + if ([self.delegate respondsToSelector:@selector(protocol:didReceiveMessage:)]) { + [self.delegate protocol:protocol didReceiveMessage:message]; } } -- (void)sdl_dispatchControlMessage:(SDLProtocolMessage *)message { +- (void)sdl_dispatchControlMessage:(SDLProtocolMessage *)message protocol:(SDLProtocol *)protocol { switch (message.header.frameData) { case SDLFrameInfoStartServiceACK: { - if ([self.delegate respondsToSelector:@selector(handleProtocolStartServiceACKMessage:)]) { - [self.delegate handleProtocolStartServiceACKMessage:message]; + if ([self.delegate respondsToSelector:@selector(protocol:didReceiveStartServiceACK:)]) { + [self.delegate protocol:protocol didReceiveStartServiceACK:message]; } } break; case SDLFrameInfoStartServiceNACK: { - if ([self.delegate respondsToSelector:@selector(handleProtocolStartServiceNAKMessage:)]) { - [self.delegate handleProtocolStartServiceNAKMessage:message]; + if ([self.delegate respondsToSelector:@selector(protocol:didReceiveStartServiceNAK:)]) { + [self.delegate protocol:protocol didReceiveStartServiceNAK:message]; } } break; case SDLFrameInfoEndServiceACK: { - if ([self.delegate respondsToSelector:@selector(handleProtocolEndServiceACKMessage:)]) { - [self.delegate handleProtocolEndServiceACKMessage:message]; + if ([self.delegate respondsToSelector:@selector(protocol:didReceiveEndServiceACK:)]) { + [self.delegate protocol:protocol didReceiveEndServiceACK:message]; } } break; case SDLFrameInfoEndServiceNACK: { - if ([self.delegate respondsToSelector:@selector(handleProtocolStartServiceNAKMessage:)]) { - [self.delegate handleProtocolEndServiceNAKMessage:message]; + if ([self.delegate respondsToSelector:@selector(protocol:didReceiveEndServiceNAK:)]) { + [self.delegate protocol:protocol didReceiveEndServiceNAK:message]; } } break; case SDLFrameInfoRegisterSecondaryTransportACK: { - if ([self.delegate respondsToSelector:@selector(handleProtocolRegisterSecondaryTransportACKMessage:)]) { - [self.delegate handleProtocolRegisterSecondaryTransportACKMessage:message]; + if ([self.delegate respondsToSelector:@selector(protocol:didReceiveRegisterSecondaryTransportACK:)]) { + [self.delegate protocol:protocol didReceiveRegisterSecondaryTransportACK:message]; } } break; case SDLFrameInfoRegisterSecondaryTransportNACK: { - if ([self.delegate respondsToSelector:@selector(handleProtocolRegisterSecondaryTransportNAKMessage:)]) { - [self.delegate handleProtocolRegisterSecondaryTransportNAKMessage:message]; + if ([self.delegate respondsToSelector:@selector(protocol:didReceiveRegisterSecondaryTransportNAK:)]) { + [self.delegate protocol:protocol didReceiveRegisterSecondaryTransportNAK:message]; } } break; case SDLFrameInfoHeartbeat: { @@ -93,15 +93,15 @@ NS_ASSUME_NONNULL_BEGIN } } break; case SDLFrameInfoTransportEventUpdate: { - if ([self.delegate respondsToSelector:@selector(handleTransportEventUpdateMessage:)]) { - [self.delegate handleTransportEventUpdateMessage:message]; + if ([self.delegate respondsToSelector:@selector(protocol:didReceiveTransportEventUpdate:)]) { + [self.delegate protocol:protocol didReceiveTransportEventUpdate:message]; } } break; default: break; // Other frame data is possible, but we don't care about them } } -- (void)sdl_dispatchMultiPartMessage:(SDLProtocolMessage *)message { +- (void)sdl_dispatchMultiPartMessage:(SDLProtocolMessage *)message protocol:(SDLProtocol *)protocol { // Pass multipart messages to an assembler and call delegate when done. NSNumber *sessionID = [NSNumber numberWithUnsignedChar:message.header.sessionID]; @@ -113,7 +113,7 @@ NS_ASSUME_NONNULL_BEGIN SDLMessageAssemblyCompletionHandler completionHandler = ^void(BOOL done, SDLProtocolMessage *assembledMessage) { if (done) { - [self sdl_dispatchProtocolMessage:assembledMessage]; + [self sdl_dispatchProtocolMessage:assembledMessage protocol:protocol]; } }; [assembler handleMessage:message withCompletionHandler:completionHandler]; diff --git a/SmartDeviceLink/SDLSecondaryTransportManager.m b/SmartDeviceLink/SDLSecondaryTransportManager.m index 2db93c791..f6054494e 100644 --- a/SmartDeviceLink/SDLSecondaryTransportManager.m +++ b/SmartDeviceLink/SDLSecondaryTransportManager.m @@ -401,9 +401,11 @@ struct TransportProtocolUpdated { #pragma mark - Transport management #pragma mark Primary transport -- (void)handleProtocolStartServiceACKMessage:(SDLProtocolMessage *)startServiceACK { - if (startServiceACK.header.serviceType != SDLServiceTypeRPC) { return; } - SDLLogV(@"Received Start Service ACK header of RPC service on primary transport"); + +- (void)protocol:(SDLProtocol *)protocol didReceiveStartServiceACK:(SDLProtocolMessage *)startServiceACK { + if (startServiceACK.header.serviceType != SDLServiceTypeRPC || self.primaryProtocol != protocol) { return; } + + SDLLogV(@"Received Start Service ACK header of RPC service on primary (%@) transport", protocol.transport); // Keep header to acquire Session ID self.primaryRPCHeader = startServiceACK.header; @@ -413,9 +415,11 @@ struct TransportProtocolUpdated { [self sdl_onStartServiceAckReceived:payload]; } -- (void)handleTransportEventUpdateMessage:(SDLProtocolMessage *)transportEventUpdate { +- (void)protocol:(SDLProtocol *)protocol didReceiveTransportEventUpdate:(SDLProtocolMessage *)transportEventUpdate { + if (self.primaryProtocol != protocol) { return; } + SDLControlFramePayloadTransportEventUpdate *payload = [[SDLControlFramePayloadTransportEventUpdate alloc] initWithData:transportEventUpdate.payload]; - SDLLogV(@"Recieved transport event update on primary transport: %@", payload); + SDLLogV(@"Recieved transport event update on primary (%@) transport: %@", protocol.transport, payload); [self sdl_onTransportEventUpdateReceived:payload]; } @@ -536,10 +540,12 @@ struct TransportProtocolUpdated { return YES; } -#pragma mark - SDLProtocolListener Implementation +#pragma mark - SDLProtocolDelegate Implementation // called on transport's thread, notifying that the transport is established -- (void)onProtocolOpened { +- (void)protocolDidOpen:(SDLProtocol *)protocol { + if (self.secondaryProtocol != protocol) { return; } + SDLLogD(@"Secondary transport connected"); self.registerTransportTimer = [[SDLTimer alloc] initWithDuration:RegisterTransportTime repeat:NO]; @@ -566,16 +572,22 @@ struct TransportProtocolUpdated { [self.secondaryProtocol registerSecondaryTransport]; } -/// Called on the transport's thread, notifying that the transport has errored before a connection was established +/// Called on the transport's thread, notifying that the transport has errored before a connection was established. /// @param error The error -- (void)onTransportError:(NSError *)error { +/// @param protocol The protocol +- (void)protocol:(SDLProtocol *)protocol transportDidError:(NSError *)error { + if (self.secondaryProtocol != protocol) { return; } + SDLLogE(@"The secondary transport errored."); [self sdl_transportClosed]; } -// Called on transport's thread, notifying that the transport is disconnected -// (Note: when transport's disconnect method is called, this method will not be called) -- (void)onProtocolClosed { +/// Called on transport's thread, notifying that the transport is disconnected. +/// @discussion When the transport's disconnect method is called, this method will not be called. +/// @param protocol The protocol +- (void)protocolDidClose:(SDLProtocol *)protocol { + if (self.secondaryProtocol != protocol) { return; } + SDLLogE(@"The secondary transport disconnected."); [self sdl_transportClosed]; } @@ -594,9 +606,10 @@ struct TransportProtocolUpdated { } // called from SDLProtocol's _receiveQueue of secondary transport -- (void)handleProtocolRegisterSecondaryTransportACKMessage:(SDLProtocolMessage *)registerSecondaryTransportACK { - SDLLogD(@"Received Register Secondary Transport ACK frame"); +- (void)protocol:(SDLProtocol *)protocol didReceiveRegisterSecondaryTransportACK:(SDLProtocolMessage *)registerSecondaryTransportACK { + if (self.secondaryProtocol != protocol) { return; } + SDLLogD(@"Received Register Secondary Transport ACK on the secondary (%@) transport", protocol.transport); dispatch_async(self.stateMachineQueue, ^{ // secondary transport is now ready [self.stateMachine transitionToState:SDLSecondaryTransportStateRegistered]; @@ -604,9 +617,10 @@ struct TransportProtocolUpdated { } // called from SDLProtocol's _receiveQueue of secondary transport -- (void)handleProtocolRegisterSecondaryTransportNAKMessage:(SDLProtocolMessage *)registerSecondaryTransportNAK { - SDLLogW(@"Received Register Secondary Transport NAK frame"); +- (void)protocol:(SDLProtocol *)protocol didReceiveRegisterSecondaryTransportNAK:(SDLProtocolMessage *)registerSecondaryTransportNAK { + if (self.secondaryProtocol != protocol) { return; } + SDLLogW(@"Received Register Secondary Transport NAK on the secondary (%@) transport", protocol.transport); dispatch_async(self.stateMachineQueue, ^{ if ([self.stateMachine.currentState isEqualToEnum:SDLSecondaryTransportStateRegistered]) { [self sdl_handleTransportUpdateWithPrimaryAvailable:YES secondaryAvailable:NO]; diff --git a/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m b/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m index 554eb89e1..af806d779 100644 --- a/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m +++ b/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m @@ -190,16 +190,16 @@ NS_ASSUME_NONNULL_BEGIN [self.protocol endServiceWithType:SDLServiceTypeAudio]; } -#pragma mark - SDLProtocolListener +#pragma mark - SDLProtocolDelegate #pragma mark Start Service ACK/NAK -- (void)handleProtocolStartServiceACKMessage:(SDLProtocolMessage *)startServiceACK { +- (void)protocol:(SDLProtocol *)protocol didReceiveStartServiceACK:(SDLProtocolMessage *)startServiceACK { if (startServiceACK.header.serviceType != SDLServiceTypeAudio) { return; } self.audioEncrypted = startServiceACK.header.encrypted; SDLControlFramePayloadAudioStartServiceAck *audioAckPayload = [[SDLControlFramePayloadAudioStartServiceAck alloc] initWithData:startServiceACK.payload]; - SDLLogD(@"Request to start audio service ACKed with payload: %@", audioAckPayload); + SDLLogD(@"Request to start audio service ACKed on transport %@, with payload: %@", protocol.transport, audioAckPayload); if (audioAckPayload.mtu != SDLControlFrameInt64NotFound) { [[SDLGlobals sharedGlobals] setDynamicMTUSize:(NSUInteger)audioAckPayload.mtu forServiceType:SDLServiceTypeAudio]; @@ -208,27 +208,28 @@ NS_ASSUME_NONNULL_BEGIN [self.audioStreamStateMachine transitionToState:SDLAudioStreamManagerStateReady]; } -- (void)handleProtocolStartServiceNAKMessage:(SDLProtocolMessage *)startServiceNAK { +- (void)protocol:(SDLProtocol *)protocol didReceiveStartServiceNAK:(SDLProtocolMessage *)startServiceNAK { if (startServiceNAK.header.serviceType != SDLServiceTypeAudio) { return; } - SDLLogE(@"Request to start audio service NAKed"); + + SDLLogE(@"Request to start audio service NAKed on transport %@, with payload: %@", protocol.transport, startServiceNAK.payload); [self.audioStreamStateMachine transitionToState:SDLAudioStreamManagerStateStopped]; } #pragma mark End Service ACK/NAK -- (void)handleProtocolEndServiceACKMessage:(SDLProtocolMessage *)endServiceACK { +- (void)protocol:(SDLProtocol *)protocol didReceiveEndServiceACK:(SDLProtocolMessage *)endServiceACK { if (endServiceACK.header.serviceType != SDLServiceTypeAudio) { return; } - SDLLogD(@"Request to end audio service ACKed"); + SDLLogD(@"Request to end audio service ACKed on transport %@", protocol.transport); [self.audioStreamStateMachine transitionToState:SDLAudioStreamManagerStateStopped]; } -- (void)handleProtocolEndServiceNAKMessage:(SDLProtocolMessage *)endServiceNAK { +- (void)protocol:(SDLProtocol *)protocol didReceiveEndServiceNAK:(SDLProtocolMessage *)endServiceNAK { if (endServiceNAK.header.serviceType != SDLServiceTypeAudio) { return; } SDLControlFramePayloadNak *nakPayload = [[SDLControlFramePayloadNak alloc] initWithData:endServiceNAK.payload]; - SDLLogE(@"Request to end audio service NAKed with playlod: %@", nakPayload); + SDLLogE(@"Request to end audio service NAKed on transport %@, with payload: %@", protocol.transport, nakPayload); /// Core will NAK the audio end service control frame if audio is not streaming or if video is streaming but the HMI does not recognize that audio is streaming. [self.audioStreamStateMachine transitionToState:SDLAudioStreamManagerStateStopped]; diff --git a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m index 6e0b8a0c7..b5f75cf32 100644 --- a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m +++ b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m @@ -509,17 +509,16 @@ typedef void(^SDLVideoCapabilityResponseHandler)(SDLVideoStreamingCapability *_N [self.protocol endServiceWithType:SDLServiceTypeVideo]; } -#pragma mark - SDLProtocolListener +#pragma mark - SDLProtocolDelegate #pragma mark Start Service ACK/NAK -- (void)handleProtocolStartServiceACKMessage:(SDLProtocolMessage *)startServiceACK { +- (void)protocol:(SDLProtocol *)protocol didReceiveStartServiceACK:(SDLProtocolMessage *)startServiceACK { if (startServiceACK.header.serviceType != SDLServiceTypeVideo) { return; } self.videoEncrypted = startServiceACK.header.encrypted; SDLControlFramePayloadVideoStartServiceAck *videoAckPayload = [[SDLControlFramePayloadVideoStartServiceAck alloc] initWithData:startServiceACK.payload]; - SDLLogD(@"Request to start video service ACKed with payload: %@", videoAckPayload); - + SDLLogD(@"Request to start video service ACKed on transport %@, with payload: %@", protocol.transport, videoAckPayload); if (videoAckPayload.mtu != SDLControlFrameInt64NotFound) { [[SDLGlobals sharedGlobals] setDynamicMTUSize:(NSUInteger)videoAckPayload.mtu forServiceType:SDLServiceTypeVideo]; @@ -546,11 +545,11 @@ typedef void(^SDLVideoCapabilityResponseHandler)(SDLVideoStreamingCapability *_N [self.videoStreamStateMachine transitionToState:SDLVideoStreamManagerStateReady]; } -- (void)handleProtocolStartServiceNAKMessage:(SDLProtocolMessage *)startServiceNAK { +- (void)protocol:(SDLProtocol *)protocol didReceiveStartServiceNAK:(SDLProtocolMessage *)startServiceNAK { if (startServiceNAK.header.serviceType != SDLServiceTypeVideo) { return; } SDLControlFramePayloadNak *nakPayload = [[SDLControlFramePayloadNak alloc] initWithData:startServiceNAK.payload]; - SDLLogE(@"Request to start video service NAKed with reason: %@", nakPayload.description); + SDLLogE(@"Request to start video service NAKed on transport %@, with payload: %@", protocol.transport, nakPayload); // If we have no payload rejected params, we don't know what to do to retry, so we'll just stop and maybe cry if (nakPayload.rejectedParams.count == 0) { @@ -574,18 +573,18 @@ typedef void(^SDLVideoCapabilityResponseHandler)(SDLVideoStreamingCapability *_N #pragma mark End Service ACK/NAK -- (void)handleProtocolEndServiceACKMessage:(SDLProtocolMessage *)endServiceACK { +- (void)protocol:(SDLProtocol *)protocol didReceiveEndServiceACK:(SDLProtocolMessage *)endServiceACK { if (endServiceACK.header.serviceType != SDLServiceTypeVideo) { return; } - SDLLogD(@"Request to end video service ACKed"); + SDLLogD(@"Request to end video service ACKed on transport %@", protocol.transport); [self.videoStreamStateMachine transitionToState:SDLVideoStreamManagerStateStopped]; } -- (void)handleProtocolEndServiceNAKMessage:(SDLProtocolMessage *)endServiceNAK { +- (void)protocol:(SDLProtocol *)protocol didReceiveEndServiceNAK:(SDLProtocolMessage *)endServiceNAK { if (endServiceNAK.header.serviceType != SDLServiceTypeVideo) { return; } SDLControlFramePayloadNak *nakPayload = [[SDLControlFramePayloadNak alloc] initWithData:endServiceNAK.payload]; - SDLLogE(@"Request to end video service NAKed with payload: %@", nakPayload); + SDLLogE(@"Request to end video service NAKed on transport %@, with payload: %@", protocol.transport, nakPayload); /// Core will NAK the video end service control frame if video is not streaming or if video is streaming but the HMI does not recognize that video is streaming. [self.videoStreamStateMachine transitionToState:SDLVideoStreamManagerStateStopped]; diff --git a/SmartDeviceLinkTests/DevAPISpecs/SDLLifecycleProtocolHandlerSpec.m b/SmartDeviceLinkTests/DevAPISpecs/SDLLifecycleProtocolHandlerSpec.m index b743a95b5..681ec9cc5 100644 --- a/SmartDeviceLinkTests/DevAPISpecs/SDLLifecycleProtocolHandlerSpec.m +++ b/SmartDeviceLinkTests/DevAPISpecs/SDLLifecycleProtocolHandlerSpec.m @@ -80,7 +80,7 @@ describe(@"SDLLifecycleProtocolHandler tests", ^{ OCMExpect([mockNotificationDispatcher postNotificationName:[OCMArg isEqual:SDLTransportDidConnect] infoObject:[OCMArg isNil]]); OCMExpect([mockProtocol startServiceWithType:0 payload:[OCMArg any]]).ignoringNonObjectArgs(); OCMExpect([(SDLTimer *)mockTimer start]); - [testHandler onProtocolOpened]; + [testHandler protocolDidOpen:mockProtocol]; }); it(@"should set everything up", ^{ @@ -93,7 +93,7 @@ describe(@"SDLLifecycleProtocolHandler tests", ^{ context(@"of the transport closing", ^{ beforeEach(^{ OCMExpect([mockNotificationDispatcher postNotificationName:[OCMArg isEqual:SDLTransportDidDisconnect] infoObject:[OCMArg isNil]]); - [testHandler onProtocolClosed]; + [testHandler protocolDidClose:mockProtocol]; }); it(@"should send a notification", ^{ @@ -104,7 +104,7 @@ describe(@"SDLLifecycleProtocolHandler tests", ^{ context(@"of the transport erroring", ^{ beforeEach(^{ OCMExpect([mockNotificationDispatcher postNotificationName:[OCMArg isEqual:SDLTransportConnectError] infoObject:[OCMArg isNotNil]]); - [testHandler onTransportError:[NSError errorWithDomain:@"test" code:1 userInfo:nil]]; + [testHandler protocol:mockProtocol transportDidError:[NSError errorWithDomain:@"test" code:1 userInfo:nil]]; }); it(@"should send a notification", ^{ @@ -122,7 +122,7 @@ describe(@"SDLLifecycleProtocolHandler tests", ^{ OCMExpect([mockNotificationDispatcher postNotificationName:[OCMArg isEqual:SDLRPCServiceDidConnect] infoObject:[OCMArg isNil]]); OCMExpect([(SDLTimer *)mockTimer cancel]); - [testHandler handleProtocolStartServiceACKMessage:message]; + [testHandler protocol:mockProtocol didReceiveStartServiceACK:message]; }); it(@"should stop the timer and send a notification", ^{ @@ -141,7 +141,7 @@ describe(@"SDLLifecycleProtocolHandler tests", ^{ OCMExpect([mockNotificationDispatcher postNotificationName:[OCMArg isEqual:SDLRPCServiceConnectionDidError] infoObject:[OCMArg isNil]]); OCMExpect([(SDLTimer *)mockTimer cancel]); - [testHandler handleProtocolStartServiceNAKMessage:message]; + [testHandler protocol:mockProtocol didReceiveStartServiceNAK:message]; }); it(@"should stop the timer and send a notification", ^{ @@ -150,6 +150,20 @@ describe(@"SDLLifecycleProtocolHandler tests", ^{ }); }); + context(@"no response from the module to the RPC Start Service", ^{ + beforeEach(^{ + testHandler.rpcStartServiceTimeoutTimer = nil; + }); + + it(@"should send a transport disconnected notification when the timer elapses", ^{ + OCMExpect([mockProtocol stopWithCompletionHandler:[OCMArg any]]); + + [testHandler protocolDidOpen:mockProtocol]; + + OCMVerifyAllWithDelay(mockProtocol, 11.0); + }); + }); + context(@"of an RPC End Service ACK", ^{ beforeEach(^{ SDLProtocolHeader *header = [SDLProtocolHeader headerForVersion:4]; @@ -160,7 +174,7 @@ describe(@"SDLLifecycleProtocolHandler tests", ^{ OCMExpect([mockNotificationDispatcher postNotificationName:[OCMArg isEqual:SDLRPCServiceDidDisconnect] infoObject:[OCMArg isNil]]); OCMExpect([(SDLTimer *)mockTimer cancel]); - [testHandler handleProtocolEndServiceACKMessage:message]; + [testHandler protocol:mockProtocol didReceiveEndServiceACK:message]; }); it(@"should stop the timer and send a notification", ^{ @@ -169,6 +183,23 @@ describe(@"SDLLifecycleProtocolHandler tests", ^{ }); }); + context(@"of an RPC End Service NAK", ^{ + beforeEach(^{ + SDLProtocolHeader *header = [SDLProtocolHeader headerForVersion:4]; + header.serviceType = SDLServiceTypeRPC; + header.frameData = SDLFrameInfoEndServiceNACK; + SDLProtocolMessage *message = [SDLProtocolMessage messageWithHeader:header andPayload:nil]; + + OCMExpect([mockNotificationDispatcher postNotificationName:[OCMArg isEqual:SDLRPCServiceConnectionDidError] infoObject:[OCMArg any]]); + + [testHandler protocol:mockProtocol didReceiveEndServiceNAK:message]; + }); + + it(@"should send a RPC service connection error notification", ^{ + OCMVerifyAll(mockNotificationDispatcher); + }); + }); + context(@"of a protocol message", ^{ beforeEach(^{ SDLShow *showRPC = [[SDLShow alloc] initWithMainField1:@"Test1" mainField2:@"Test2" alignment:SDLTextAlignmentLeft]; @@ -189,7 +220,7 @@ describe(@"SDLLifecycleProtocolHandler tests", ^{ OCMExpect([mockNotificationDispatcher postRPCRequestNotification:[OCMArg isEqual:SDLDidReceiveShowRequest] request:[OCMArg isNotNil]]); - [testHandler onProtocolMessageReceived:testMessage]; + [testHandler protocol:mockProtocol didReceiveMessage:testMessage]; }); it(@"should send the notification", ^{ diff --git a/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingAudioLifecycleManagerSpec.m b/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingAudioLifecycleManagerSpec.m index 96ea3897d..93d5e5829 100644 --- a/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingAudioLifecycleManagerSpec.m +++ b/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingAudioLifecycleManagerSpec.m @@ -311,7 +311,7 @@ describe(@"the streaming audio manager", ^{ testAudioStartServicePayload = [[SDLControlFramePayloadAudioStartServiceAck alloc] initWithMTU:testMTU]; testAudioMessage = [[SDLV2ProtocolMessage alloc] initWithHeader:testAudioHeader andPayload:testAudioStartServicePayload.data]; - [streamingLifecycleManager handleProtocolStartServiceACKMessage:testAudioMessage]; + [streamingLifecycleManager protocol:protocolMock didReceiveStartServiceACK:testAudioMessage]; }); it(@"should have set all the right properties", ^{ @@ -335,7 +335,7 @@ describe(@"the streaming audio manager", ^{ testAudioHeader.serviceType = SDLServiceTypeAudio; testAudioMessage = [[SDLV2ProtocolMessage alloc] initWithHeader:testAudioHeader andPayload:nil]; - [streamingLifecycleManager handleProtocolEndServiceACKMessage:testAudioMessage]; + [streamingLifecycleManager protocol:protocolMock didReceiveEndServiceACK:testAudioMessage]; }); it(@"should have set all the right properties", ^{ @@ -357,7 +357,7 @@ describe(@"the streaming audio manager", ^{ testAudioHeader.serviceType = SDLServiceTypeAudio; testAudioMessage = [[SDLV2ProtocolMessage alloc] initWithHeader:testAudioHeader andPayload:nil]; - [streamingLifecycleManager handleProtocolEndServiceACKMessage:testAudioMessage]; + [streamingLifecycleManager protocol:protocolMock didReceiveEndServiceACK:testAudioMessage]; }); it(@"should have set all the right properties", ^{ @@ -379,7 +379,7 @@ describe(@"the streaming audio manager", ^{ testAudioHeader.serviceType = SDLServiceTypeAudio; testAudioMessage = [[SDLV2ProtocolMessage alloc] initWithHeader:testAudioHeader andPayload:nil]; - [streamingLifecycleManager handleProtocolEndServiceNAKMessage:testAudioMessage]; + [streamingLifecycleManager protocol:protocolMock didReceiveEndServiceNAK:testAudioMessage]; }); it(@"should have set all the right properties", ^{ @@ -464,7 +464,7 @@ describe(@"the streaming audio manager", ^{ testAudioHeader.serviceType = SDLServiceTypeAudio; testAudioMessage = [[SDLV2ProtocolMessage alloc] initWithHeader:testAudioHeader andPayload:nil]; - [streamingLifecycleManager handleProtocolEndServiceACKMessage:testAudioMessage]; + [streamingLifecycleManager protocol:protocolMock didReceiveEndServiceACK:testAudioMessage]; }); it(@"should transistion to the stopped state", ^{ @@ -484,7 +484,7 @@ describe(@"the streaming audio manager", ^{ testAudioHeader.serviceType = SDLServiceTypeAudio; testAudioMessage = [[SDLV2ProtocolMessage alloc] initWithHeader:testAudioHeader andPayload:nil]; - [streamingLifecycleManager handleProtocolEndServiceNAKMessage:testAudioMessage]; + [streamingLifecycleManager protocol:protocolMock didReceiveEndServiceNAK:testAudioMessage]; }); it(@"should transistion to the stopped state", ^{ diff --git a/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingVideoLifecycleManagerSpec.m b/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingVideoLifecycleManagerSpec.m index 6e9fc2136..f138e873d 100644 --- a/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingVideoLifecycleManagerSpec.m +++ b/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingVideoLifecycleManagerSpec.m @@ -552,7 +552,7 @@ describe(@"the streaming video manager", ^{ beforeEach(^{ testVideoStartServicePayload = [[SDLControlFramePayloadVideoStartServiceAck alloc] initWithMTU:testMTU height:testVideoHeight width:testVideoWidth protocol:testVideoProtocol codec:testVideoCodec]; testVideoMessage = [[SDLV2ProtocolMessage alloc] initWithHeader:testVideoHeader andPayload:testVideoStartServicePayload.data]; - [streamingLifecycleManager handleProtocolStartServiceACKMessage:testVideoMessage]; + [streamingLifecycleManager protocol:protocolMock didReceiveStartServiceACK:testVideoMessage]; }); it(@"should have set all the right properties", ^{ @@ -568,7 +568,7 @@ describe(@"the streaming video manager", ^{ beforeEach(^{ testVideoStartServicePayload = [[SDLControlFramePayloadVideoStartServiceAck alloc] initWithMTU:testMTU height:testVideoHeight width:testVideoWidth protocol:nil codec:nil]; testVideoMessage = [[SDLV2ProtocolMessage alloc] initWithHeader:testVideoHeader andPayload:testVideoStartServicePayload.data]; - [streamingLifecycleManager handleProtocolStartServiceACKMessage:testVideoMessage]; + [streamingLifecycleManager protocol:protocolMock didReceiveStartServiceACK:testVideoMessage]; }); it(@"should fall back correctly", ^{ @@ -589,7 +589,7 @@ describe(@"the streaming video manager", ^{ context(@"If no preferred resolutions were set in the data source", ^{ beforeEach(^{ streamingLifecycleManager.dataSource = nil; - [streamingLifecycleManager handleProtocolStartServiceACKMessage:testVideoMessage]; + [streamingLifecycleManager protocol:protocolMock didReceiveStartServiceACK:testVideoMessage]; }); it(@"should not replace the existing screen resolution", ^{ expect(@(CGSizeEqualToSize(streamingLifecycleManager.videoScaleManager.displayViewportResolution, CGSizeZero))).to(beTrue()); @@ -606,7 +606,7 @@ describe(@"the streaming video manager", ^{ streamingLifecycleManager.dataSource = testDataSource; streamingLifecycleManager.preferredResolutions = @[preferredResolutionLow, preferredResolutionHigh]; - [streamingLifecycleManager handleProtocolStartServiceACKMessage:testVideoMessage]; + [streamingLifecycleManager protocol:protocolMock didReceiveStartServiceACK:testVideoMessage]; }); it(@"should set the screen size using the first provided preferred resolution", ^{ CGSize preferredFormat = CGSizeMake(preferredResolutionLow.resolutionWidth.floatValue, preferredResolutionLow.resolutionHeight.floatValue); @@ -648,7 +648,7 @@ describe(@"the streaming video manager", ^{ testVideoStartNakPayload = [[SDLControlFramePayloadNak alloc] initWithRejectedParams:@[[NSString stringWithUTF8String:SDLControlFrameHeightKey], [NSString stringWithUTF8String:SDLControlFrameVideoCodecKey]]]; testVideoMessage = [[SDLV2ProtocolMessage alloc] initWithHeader:testVideoHeader andPayload:testVideoStartNakPayload.data]; - [streamingLifecycleManager handleProtocolStartServiceNAKMessage:testVideoMessage]; + [streamingLifecycleManager protocol:protocolMock didReceiveStartServiceNAK:testVideoMessage]; }); it(@"should have retried with new properties", ^{ @@ -670,7 +670,7 @@ describe(@"the streaming video manager", ^{ testVideoStartNakPayload = [[SDLControlFramePayloadNak alloc] initWithRejectedParams:@[[NSString stringWithUTF8String:SDLControlFrameVideoCodecKey]]]; testVideoMessage = [[SDLV2ProtocolMessage alloc] initWithHeader:testVideoHeader andPayload:testVideoStartNakPayload.data]; - [streamingLifecycleManager handleProtocolStartServiceNAKMessage:testVideoMessage]; + [streamingLifecycleManager protocol:protocolMock didReceiveStartServiceNAK:testVideoMessage]; }); it(@"should have retried with new properties", ^{ @@ -691,7 +691,7 @@ describe(@"the streaming video manager", ^{ testVideoStartNakPayload = [[SDLControlFramePayloadNak alloc] initWithRejectedParams:@[[NSString stringWithUTF8String:SDLControlFrameVideoCodecKey]]]; testVideoMessage = [[SDLV2ProtocolMessage alloc] initWithHeader:testVideoHeader andPayload:testVideoStartNakPayload.data]; - [streamingLifecycleManager handleProtocolStartServiceNAKMessage:testVideoMessage]; + [streamingLifecycleManager protocol:protocolMock didReceiveStartServiceNAK:testVideoMessage]; }); it(@"should end the service", ^{ @@ -706,7 +706,7 @@ describe(@"the streaming video manager", ^{ testVideoStartNakPayload = [[SDLControlFramePayloadNak alloc] initWithRejectedParams:nil]; testVideoMessage = [[SDLV2ProtocolMessage alloc] initWithHeader:testVideoHeader andPayload:testVideoStartNakPayload.data]; - [streamingLifecycleManager handleProtocolStartServiceNAKMessage:testVideoMessage]; + [streamingLifecycleManager protocol:protocolMock didReceiveStartServiceNAK:testVideoMessage]; }); it(@"should end the service", ^{ @@ -729,7 +729,7 @@ describe(@"the streaming video manager", ^{ testVideoHeader.serviceType = SDLServiceTypeVideo; testVideoMessage = [[SDLV2ProtocolMessage alloc] initWithHeader:testVideoHeader andPayload:nil]; - [streamingLifecycleManager handleProtocolEndServiceACKMessage:testVideoMessage]; + [streamingLifecycleManager protocol:protocolMock didReceiveEndServiceACK:testVideoMessage]; }); it(@"should have set all the right properties", ^{ @@ -751,7 +751,7 @@ describe(@"the streaming video manager", ^{ testVideoHeader.serviceType = SDLServiceTypeVideo; testVideoMessage = [[SDLV2ProtocolMessage alloc] initWithHeader:testVideoHeader andPayload:nil]; - [streamingLifecycleManager handleProtocolEndServiceNAKMessage:testVideoMessage]; + [streamingLifecycleManager protocol:protocolMock didReceiveEndServiceNAK:testVideoMessage]; }); it(@"should have set all the right properties", ^{ @@ -837,7 +837,7 @@ describe(@"the streaming video manager", ^{ testVideoHeader.serviceType = SDLServiceTypeVideo; testVideoMessage = [[SDLV2ProtocolMessage alloc] initWithHeader:testVideoHeader andPayload:nil]; - [streamingLifecycleManager handleProtocolEndServiceACKMessage:testVideoMessage]; + [streamingLifecycleManager protocol:protocolMock didReceiveEndServiceACK:testVideoMessage]; }); it(@"should transistion to the stopped state", ^{ @@ -857,7 +857,7 @@ describe(@"the streaming video manager", ^{ testVideoHeader.serviceType = SDLServiceTypeVideo; testVideoMessage = [[SDLV2ProtocolMessage alloc] initWithHeader:testVideoHeader andPayload:nil]; - [streamingLifecycleManager handleProtocolEndServiceNAKMessage:testVideoMessage]; + [streamingLifecycleManager protocol:protocolMock didReceiveEndServiceNAK:testVideoMessage]; }); it(@"should transistion to the stopped state", ^{ diff --git a/SmartDeviceLinkTests/ProtocolSpecs/MessageSpecs/SDLProtocolSpec.m b/SmartDeviceLinkTests/ProtocolSpecs/MessageSpecs/SDLProtocolSpec.m index daf08d146..b4e542012 100644 --- a/SmartDeviceLinkTests/ProtocolSpecs/MessageSpecs/SDLProtocolSpec.m +++ b/SmartDeviceLinkTests/ProtocolSpecs/MessageSpecs/SDLProtocolSpec.m @@ -129,7 +129,7 @@ describe(@"Send EndSession Tests", ^ { SDLV1ProtocolHeader *testHeader = [[SDLV1ProtocolHeader alloc] init]; testHeader.serviceType = SDLServiceTypeRPC; testHeader.sessionID = 0x03; - [testProtocol handleProtocolStartServiceACKMessage:[SDLProtocolMessage messageWithHeader:testHeader andPayload:nil]]; + [testProtocol protocol:testProtocol didReceiveStartServiceACK:[SDLProtocolMessage messageWithHeader:testHeader andPayload:nil]]; [testProtocol endServiceWithType:SDLServiceTypeRPC]; @@ -157,7 +157,7 @@ describe(@"Send EndSession Tests", ^ { SDLV2ProtocolHeader *testHeader = [[SDLV2ProtocolHeader alloc] initWithVersion:2]; testHeader.serviceType = SDLServiceTypeRPC; testHeader.sessionID = 0x61; - [testProtocol handleProtocolStartServiceACKMessage:[SDLProtocolMessage messageWithHeader:testHeader andPayload:nil]]; + [testProtocol protocol:testProtocol didReceiveStartServiceACK:[SDLProtocolMessage messageWithHeader:testHeader andPayload:nil]]; [testProtocol endServiceWithType:SDLServiceTypeRPC]; @@ -188,7 +188,7 @@ describe(@"Send Register Secondary Transport Tests", ^ { refHeader.serviceType = SDLServiceTypeRPC; refHeader.frameData = SDLFrameInfoStartServiceACK; refHeader.sessionID = 0x11; - [testProtocol handleProtocolStartServiceACKMessage:[SDLProtocolMessage messageWithHeader:refHeader andPayload:nil]]; + [testProtocol protocol:testProtocol didReceiveStartServiceACK:[SDLProtocolMessage messageWithHeader:refHeader andPayload:nil]]; // store the header to apply Session ID value to Register Secondary Transport frame [testProtocol storeHeader:refHeader forServiceType:SDLServiceTypeControl]; @@ -233,7 +233,7 @@ describe(@"SendRPCRequest Tests", ^ { SDLV1ProtocolHeader *testHeader = [[SDLV1ProtocolHeader alloc] init]; testHeader.serviceType = SDLServiceTypeRPC; testHeader.sessionID = 0xFF; - [testProtocol handleProtocolStartServiceACKMessage:[SDLProtocolMessage messageWithHeader:testHeader andPayload:nil]]; + [testProtocol protocol:testProtocol didReceiveStartServiceACK:[SDLProtocolMessage messageWithHeader:testHeader andPayload:nil]]; [testProtocol sendRPC:mockRequest]; @@ -279,7 +279,7 @@ describe(@"SendRPCRequest Tests", ^ { SDLV2ProtocolHeader *testHeader = [[SDLV2ProtocolHeader alloc] initWithVersion:2]; testHeader.serviceType = SDLServiceTypeRPC; testHeader.sessionID = 0x01; - [testProtocol handleProtocolStartServiceACKMessage:[SDLProtocolMessage messageWithHeader:testHeader andPayload:nil]]; + [testProtocol protocol:testProtocol didReceiveStartServiceACK:[SDLProtocolMessage messageWithHeader:testHeader andPayload:nil]]; [testProtocol sendRPC:mockRequest]; @@ -430,10 +430,10 @@ describe(@"HandleProtocolSessionStarted tests", ^ { testHeader.bytesInPayload = (UInt32)testData.length; SDLProtocolMessage *ackMessage = [SDLProtocolMessage messageWithHeader:testHeader andPayload:testData]; - OCMExpect([delegateMock handleProtocolStartServiceACKMessage:ackMessage]); + OCMExpect([delegateMock protocol:testProtocol didReceiveStartServiceACK:ackMessage]); [testProtocol.protocolDelegateTable addObject:delegateMock]; - [testProtocol handleProtocolStartServiceACKMessage:ackMessage]; + [testProtocol protocol:testProtocol didReceiveStartServiceACK:ackMessage]; OCMVerifyAllWithDelay(delegateMock, 0.1); @@ -454,10 +454,10 @@ describe(@"HandleProtocolSessionStarted tests", ^ { testHeader.bytesInPayload = (UInt32)testData.length; SDLProtocolMessage *ackMessage = [SDLProtocolMessage messageWithHeader:testHeader andPayload:testData]; - OCMExpect([delegateMock handleProtocolStartServiceACKMessage:ackMessage]); + OCMExpect([delegateMock protocol:testProtocol didReceiveStartServiceACK:ackMessage]); [testProtocol.protocolDelegateTable addObject:delegateMock]; - [testProtocol handleProtocolStartServiceACKMessage:ackMessage]; + [testProtocol protocol:testProtocol didReceiveStartServiceACK:ackMessage]; OCMVerifyAllWithDelay(delegateMock, 0.1); @@ -478,10 +478,10 @@ describe(@"HandleProtocolSessionStarted tests", ^ { testHeader.bytesInPayload = (UInt32)testData.length; SDLProtocolMessage *ackMessage = [SDLProtocolMessage messageWithHeader:testHeader andPayload:testData]; - OCMExpect([delegateMock handleProtocolStartServiceACKMessage:ackMessage]); + OCMExpect([delegateMock protocol:testProtocol didReceiveStartServiceACK:ackMessage]); [testProtocol.protocolDelegateTable addObject:delegateMock]; - [testProtocol handleProtocolStartServiceACKMessage:ackMessage]; + [testProtocol protocol:testProtocol didReceiveStartServiceACK:ackMessage]; OCMVerifyAllWithDelay(delegateMock, 0.1); @@ -504,10 +504,10 @@ describe(@"HandleProtocolSessionStarted tests", ^ { testHeader.bytesInPayload = (UInt32)testData.length; SDLProtocolMessage *ackMessage = [SDLProtocolMessage messageWithHeader:testHeader andPayload:testData]; - OCMExpect([delegateMock handleProtocolStartServiceACKMessage:ackMessage]); + OCMExpect([delegateMock protocol:testProtocol didReceiveStartServiceACK:ackMessage]); [testProtocol.protocolDelegateTable addObject:delegateMock]; - [testProtocol handleProtocolStartServiceACKMessage:ackMessage]; + [testProtocol protocol:testProtocol didReceiveStartServiceACK:ackMessage]; OCMVerifyAllWithDelay(delegateMock, 0.1); @@ -533,10 +533,10 @@ describe(@"HandleProtocolSessionStarted tests", ^ { testHeader.bytesInPayload = (UInt32)testData.length; SDLProtocolMessage *ackMessage = [SDLProtocolMessage messageWithHeader:testHeader andPayload:testData]; - OCMExpect([delegateMock handleProtocolStartServiceACKMessage:ackMessage]); + OCMExpect([delegateMock protocol:testProtocol didReceiveStartServiceACK:ackMessage]); [testProtocol.protocolDelegateTable addObject:delegateMock]; - [testProtocol handleProtocolStartServiceACKMessage:ackMessage]; + [testProtocol protocol:testProtocol didReceiveStartServiceACK:ackMessage]; OCMVerifyAllWithDelay(delegateMock, 0.1); @@ -558,10 +558,10 @@ describe(@"HandleProtocolSessionStarted tests", ^ { testHeader.bytesInPayload = (UInt32)testData.length; SDLProtocolMessage *ackMessage = [SDLProtocolMessage messageWithHeader:testHeader andPayload:testData]; - OCMExpect([delegateMock handleProtocolStartServiceACKMessage:ackMessage]); + OCMExpect([delegateMock protocol:testProtocol didReceiveStartServiceACK:ackMessage]); [testProtocol.protocolDelegateTable addObject:delegateMock]; - [testProtocol handleProtocolStartServiceACKMessage:ackMessage]; + [testProtocol protocol:testProtocol didReceiveStartServiceACK:ackMessage]; // Should keep their default values expect([SDLGlobals sharedGlobals].protocolVersion.stringVersion).to(equal(@"1.0.0")); @@ -593,10 +593,10 @@ describe(@"HandleProtocolRegisterSecondaryTransport Tests", ^{ testHeader.bytesInPayload = 0; SDLProtocolMessage *ackMessage = [SDLProtocolMessage messageWithHeader:testHeader andPayload:nil]; - OCMExpect([delegateMock handleProtocolRegisterSecondaryTransportACKMessage:ackMessage]); + OCMExpect([delegateMock protocol:testProtocol didReceiveRegisterSecondaryTransportACK:ackMessage]); [testProtocol.protocolDelegateTable addObject:delegateMock]; - [testProtocol handleProtocolRegisterSecondaryTransportACKMessage:ackMessage]; + [testProtocol protocol:testProtocol didReceiveRegisterSecondaryTransportACK:ackMessage]; OCMVerifyAllWithDelay(delegateMock, 0.1); }); @@ -615,10 +615,10 @@ describe(@"HandleProtocolRegisterSecondaryTransport Tests", ^{ NSData *payloadData = payload.data; SDLProtocolMessage *nakMessage = [SDLProtocolMessage messageWithHeader:testHeader andPayload:payloadData]; - OCMExpect([delegateMock handleProtocolRegisterSecondaryTransportNAKMessage:nakMessage]); + OCMExpect([delegateMock protocol:testProtocol didReceiveRegisterSecondaryTransportNAK:nakMessage]); [testProtocol.protocolDelegateTable addObject:delegateMock]; - [testProtocol handleProtocolRegisterSecondaryTransportNAKMessage:nakMessage]; + [testProtocol protocol:testProtocol didReceiveRegisterSecondaryTransportNAK:nakMessage]; OCMVerifyAllWithDelay(delegateMock, 0.1); }); @@ -660,10 +660,10 @@ describe(@"OnProtocolMessageReceived Tests", ^ { testMessage.header = testHeader; id delegateMock = OCMProtocolMock(@protocol(SDLProtocolDelegate)); - OCMExpect([delegateMock onProtocolMessageReceived:[OCMArg any]]); + OCMExpect([delegateMock protocol:testProtocol didReceiveMessage:[OCMArg any]]); [testProtocol.protocolDelegateTable addObject:delegateMock]; - [testProtocol onProtocolMessageReceived:testMessage]; + [testProtocol protocol:testProtocol didReceiveMessage:testMessage]; }); it(@"Should pass information along to delegate", ^ { @@ -681,7 +681,7 @@ describe(@"OnProtocolOpened Tests", ^ { testProtocol = [[SDLProtocol alloc] initWithTransport:transportMock encryptionManager:nil]; id delegateMock = OCMProtocolMock(@protocol(SDLProtocolDelegate)); - OCMExpect([delegateMock onProtocolOpened]); + OCMExpect([delegateMock protocolDidOpen:testProtocol]); [testProtocol.protocolDelegateTable addObject:delegateMock]; [testProtocol onTransportConnected]; @@ -702,7 +702,7 @@ describe(@"OnProtocolClosed Tests", ^ { testProtocol = [[SDLProtocol alloc] initWithTransport:transportMock encryptionManager:nil]; delegateMock = OCMProtocolMock(@protocol(SDLProtocolDelegate)); - OCMExpect([delegateMock onProtocolClosed]); + OCMExpect([delegateMock protocolDidClose:testProtocol]); [testProtocol.protocolDelegateTable addObject:delegateMock]; [testProtocol onTransportDisconnected]; diff --git a/SmartDeviceLinkTests/ProtocolSpecs/SDLProtocolReceivedMessageRouterSpec.m b/SmartDeviceLinkTests/ProtocolSpecs/SDLProtocolReceivedMessageRouterSpec.m index 0d6d44727..c1e9f6f1e 100644 --- a/SmartDeviceLinkTests/ProtocolSpecs/SDLProtocolReceivedMessageRouterSpec.m +++ b/SmartDeviceLinkTests/ProtocolSpecs/SDLProtocolReceivedMessageRouterSpec.m @@ -9,106 +9,187 @@ #import <Nimble/Nimble.h> #import <OCMock/OCMock.h> +#import "SDLProtocol.h" #import "SDLProtocolReceivedMessageRouter.h" +#import "SDLRPCParameterNames.h" #import "SDLV2ProtocolHeader.h" #import "SDLV2ProtocolMessage.h" -#import "SDLRPCParameterNames.h" QuickSpecBegin(SDLProtocolReceivedMessageRouterSpec) -describe(@"HandleReceivedMessage Tests", ^ { - context(@"When handling control message", ^ { - it(@"Should route message correctly", ^ { - id delegateMock = OCMProtocolMock(@protocol(SDLProtocolDelegate)); - - SDLV2ProtocolMessage *testMessage = [[SDLV2ProtocolMessage alloc] init]; - SDLV2ProtocolHeader *testHeader = [[SDLV2ProtocolHeader alloc] init]; - +describe(@"Handle received message tests", ^{ + __block SDLProtocolReceivedMessageRouter *router = nil; + __block id delegateMock = nil; + __block SDLProtocol *mockProtocol = nil; + + beforeEach(^{ + router = [[SDLProtocolReceivedMessageRouter alloc] init]; + delegateMock = OCMProtocolMock(@protocol(SDLProtocolDelegate)); + router.delegate = delegateMock; + mockProtocol = OCMStrictClassMock([SDLProtocol class]); + }); + + context(@"When handling a control message", ^{ + __block SDLV2ProtocolMessage *testMessage = nil; + __block SDLV2ProtocolHeader *testHeader = nil; + + beforeEach(^{ + testHeader = [[SDLV2ProtocolHeader alloc] init]; testHeader.frameType = SDLFrameTypeControl; testHeader.serviceType = SDLServiceTypeRPC; - testHeader.frameData = SDLFrameInfoStartServiceACK; testHeader.sessionID = 0x93; testHeader.bytesInPayload = 0; + + testMessage = [[SDLV2ProtocolMessage alloc] init]; + testMessage.payload = [NSData data]; + testMessage.header = testHeader; + }); + + it(@"Should route a start service ACK message correctly", ^{ + testHeader.frameData = SDLFrameInfoStartServiceACK; + testMessage.header = testHeader; + + [router handleReceivedMessage:testMessage protocol:mockProtocol]; + OCMVerify([delegateMock protocol:mockProtocol didReceiveStartServiceACK:testMessage]); + }); + + it(@"Should route a start service NAK message correctly", ^{ + testHeader.frameData = SDLFrameInfoStartServiceNACK; testMessage.header = testHeader; - testMessage.payload = [NSData data]; - SDLProtocolReceivedMessageRouter* router = [[SDLProtocolReceivedMessageRouter alloc] init]; - router.delegate = delegateMock; - [router handleReceivedMessage:testMessage]; + [router handleReceivedMessage:testMessage protocol:mockProtocol]; - OCMVerify([delegateMock handleProtocolStartServiceACKMessage:testMessage]); + OCMVerify([delegateMock protocol:mockProtocol didReceiveStartServiceNAK:testMessage]); }); - }); - - context(@"When handling single frame message", ^ { - it(@"Should route message correctly", ^ { - id delegateMock = OCMProtocolMock(@protocol(SDLProtocolDelegate)); + + it(@"Should route an end service ACK message correctly", ^{ + testHeader.frameData = SDLFrameInfoEndServiceACK; + testMessage.header = testHeader; + + [router handleReceivedMessage:testMessage protocol:mockProtocol]; + + OCMVerify([delegateMock protocol:mockProtocol didReceiveEndServiceACK:testMessage]); + }); + + it(@"Should route an end service NAK message correctly", ^{ + testHeader.frameData = SDLFrameInfoEndServiceNACK; + testMessage.header = testHeader; + + [router handleReceivedMessage:testMessage protocol:mockProtocol]; + + OCMVerify([delegateMock protocol:mockProtocol didReceiveEndServiceNAK:testMessage]); + }); + + it(@"Should route register secondary transport ACK message correctly", ^{ + testHeader.frameData = SDLFrameInfoRegisterSecondaryTransportACK; + testMessage.header = testHeader; + + [router handleReceivedMessage:testMessage protocol:mockProtocol]; + + OCMVerify([delegateMock protocol:mockProtocol didReceiveRegisterSecondaryTransportACK:testMessage]); + }); + + it(@"Should route register secondary transport NAK message correctly", ^{ + testHeader.frameData = SDLFrameInfoRegisterSecondaryTransportNACK; + testMessage.header = testHeader; + + [router handleReceivedMessage:testMessage protocol:mockProtocol]; + + OCMVerify([delegateMock protocol:mockProtocol didReceiveRegisterSecondaryTransportNAK:testMessage]); + }); + + it(@"Should route a transport event update message correctly", ^{ + testHeader.frameData = SDLFrameInfoTransportEventUpdate; + testMessage.header = testHeader; + + [router handleReceivedMessage:testMessage protocol:mockProtocol]; + + OCMVerify([delegateMock protocol:mockProtocol didReceiveTransportEventUpdate:testMessage]); + }); + + it(@"Should route a heartbeat message correctly", ^{ + testHeader.frameData = SDLFrameInfoHeartbeat; + testMessage.header = testHeader; + + [router handleReceivedMessage:testMessage protocol:mockProtocol]; + + OCMVerify([delegateMock handleHeartbeatForSession:testHeader.sessionID]); + }); + + it(@"Should route a heartbeat ACK message correctly", ^{ + testHeader.frameData = SDLFrameInfoHeartbeatACK; + testMessage.header = testHeader; - SDLV2ProtocolMessage* testMessage = [[SDLV2ProtocolMessage alloc] init]; - SDLV2ProtocolHeader* testHeader = [[SDLV2ProtocolHeader alloc] init]; + [router handleReceivedMessage:testMessage protocol:mockProtocol]; + OCMVerify([delegateMock handleHeartbeatACK]); + }); + }); + + context(@"When handling a single frame message", ^{ + __block SDLV2ProtocolMessage *testMessage = nil; + __block SDLV2ProtocolHeader *testHeader = nil; + + beforeEach(^{ + testHeader = [[SDLV2ProtocolHeader alloc] init]; testHeader.frameType = SDLFrameTypeSingle; testHeader.serviceType = SDLServiceTypeRPC; - testHeader.frameData = SDLFrameInfoSingleFrame; testHeader.sessionID = 0x07; testHeader.bytesInPayload = 0; - - testMessage.header = testHeader; - + + testMessage = [[SDLV2ProtocolMessage alloc] init]; testMessage.payload = [NSData data]; - + testMessage.header = testHeader; + }); + + it(@"Should route the message correctly", ^{ __block BOOL verified = NO; - [[[[delegateMock stub] andDo: ^(NSInvocation* invocation) { + [OCMStub([delegateMock protocol:mockProtocol didReceiveMessage:testMessage]) andDo:^(NSInvocation *invocation) { verified = YES; - - __unsafe_unretained SDLProtocolMessage* message; - - [invocation getArgument:&message atIndex:2]; - - SDLV2ProtocolMessage* messageReceived = (SDLV2ProtocolMessage *)message; - + __unsafe_unretained SDLProtocolMessage *message; + [invocation getArgument:&message atIndex:3]; + SDLV2ProtocolMessage *messageReceived = (SDLV2ProtocolMessage *)message; + expect(messageReceived).to(beIdenticalTo(testMessage)); - }] ignoringNonObjectArgs] onProtocolMessageReceived:[OCMArg any]]; - - SDLProtocolReceivedMessageRouter* router = [[SDLProtocolReceivedMessageRouter alloc] init]; - router.delegate = delegateMock; - - [router handleReceivedMessage:testMessage]; + }]; + + [router handleReceivedMessage:testMessage protocol:mockProtocol]; - expect(@(verified)).to(beTruthy()); + expect(verified).toEventually(beTrue()); }); }); - context(@"When handling multi-frame message", ^ { - it(@"Should route message correctly", ^ { - //Allocate 2000 bytes and use it as test data + context(@"When handling a multi-frame message", ^{ + __block SDLV2ProtocolMessage *testMessage = nil; + __block SDLV2ProtocolHeader *testHeader = nil; + + beforeEach(^{ + testMessage = [[SDLV2ProtocolMessage alloc] init]; + testHeader = [[SDLV2ProtocolHeader alloc] init]; + }); + + it(@"Should route the message correctly", ^{ + // Allocate 2000 bytes and use it as test data const NSUInteger dataLength = 2000; char dummyBytes[dataLength]; const char testPayloadHeader[12] = {0x20, 0x55, 0x64, 0x73, 0x12, 0x34, 0x43, 0x21, (dataLength >> 24) & 0xFF, (dataLength >> 16) & 0xFF, (dataLength >> 8) & 0xFF, dataLength & 0xFF}; - - NSMutableData* payloadData = [NSMutableData dataWithBytes:testPayloadHeader length:12]; + NSMutableData *payloadData = [NSMutableData dataWithBytes:testPayloadHeader length:12]; [payloadData appendBytes:dummyBytes length:dataLength]; - - SDLV2ProtocolMessage* testMessage = [[SDLV2ProtocolMessage alloc] init]; - SDLV2ProtocolHeader* testHeader = [[SDLV2ProtocolHeader alloc] init]; - - //First frame + + // First frame testHeader.frameType = SDLFrameTypeFirst; testHeader.serviceType = SDLServiceTypeBulkData; testHeader.frameData = 1; testHeader.sessionID = 0x33; testHeader.bytesInPayload = 8; - testMessage.header = testHeader; const char firstPayload[8] = {(payloadData.length >> 24) & 0xFF, (payloadData.length >> 16) & 0xFF, (payloadData.length >> 8) & 0xFF, payloadData.length & 0xFF, 0x00, 0x00, 0x00, ceil(payloadData.length / 500.0)}; testMessage.payload = [NSData dataWithBytes:firstPayload length:8]; - SDLProtocolReceivedMessageRouter* router = [[SDLProtocolReceivedMessageRouter alloc] init]; - - [router handleReceivedMessage:testMessage]; + [router handleReceivedMessage:testMessage protocol:mockProtocol]; testMessage.header.frameType = SDLFrameTypeConsecutive; testMessage.header.bytesInPayload = 500; @@ -116,29 +197,27 @@ describe(@"HandleReceivedMessage Tests", ^ { NSUInteger frameNumber = 1; NSUInteger offset = 0; while ((offset + 500) < payloadData.length) { - //Consectutive frames + // Consectutive frames testMessage.header.frameData = frameNumber; testMessage.payload = [payloadData subdataWithRange:NSMakeRange(offset, 500)]; - [router handleReceivedMessage:testMessage]; + [router handleReceivedMessage:testMessage protocol:mockProtocol]; frameNumber++; offset += 500; } - //Final frame + // Final frame testMessage.header.frameData = 0; testMessage.payload = [payloadData subdataWithRange:NSMakeRange(offset, payloadData.length - offset)]; - - id delegateMock = OCMProtocolMock(@protocol(SDLProtocolDelegate)); - + __block BOOL verified = NO; - [[[delegateMock stub] andDo:^(NSInvocation* invocation) { + [OCMStub([delegateMock protocol:mockProtocol didReceiveMessage:[OCMArg any]]) andDo:^(NSInvocation *invocation) { verified = YES; - //Without the __unsafe_unretained, a double release will occur. More information: https://github.com/erikdoe/ocmock/issues/123 - __unsafe_unretained SDLProtocolMessage* message; - [invocation getArgument:&message atIndex:2]; - SDLProtocolMessage* assembledMessage = message; + // Without the __unsafe_unretained, a double release will occur. More information: https://github.com/erikdoe/ocmock/issues/123 + __unsafe_unretained SDLProtocolMessage *message; + [invocation getArgument:&message atIndex:3]; + SDLProtocolMessage *assembledMessage = message; expect(assembledMessage.payload).to(equal(payloadData)); expect(@(assembledMessage.header.frameType)).to(equal(@(SDLFrameTypeSingle))); @@ -146,12 +225,11 @@ describe(@"HandleReceivedMessage Tests", ^ { expect(@(assembledMessage.header.frameData)).to(equal(@(SDLFrameInfoSingleFrame))); expect(@(assembledMessage.header.sessionID)).to(equal(@0x33)); expect(@(assembledMessage.header.bytesInPayload)).to(equal(@(payloadData.length))); - }] onProtocolMessageReceived:[OCMArg any]]; - - router.delegate = delegateMock; - [router handleReceivedMessage:testMessage]; + }]; + + [router handleReceivedMessage:testMessage protocol:mockProtocol]; - expect(@(verified)).to(beTruthy()); + expect(verified).toEventually(beTrue()); }); }); }); diff --git a/SmartDeviceLinkTests/ProxySpecs/SDLSecondaryTransportManagerSpec.m b/SmartDeviceLinkTests/ProxySpecs/SDLSecondaryTransportManagerSpec.m index a60e9a549..b7279a352 100644 --- a/SmartDeviceLinkTests/ProxySpecs/SDLSecondaryTransportManagerSpec.m +++ b/SmartDeviceLinkTests/ProxySpecs/SDLSecondaryTransportManagerSpec.m @@ -14,18 +14,18 @@ #import "SDLControlFramePayloadRegisterSecondaryTransportNak.h" #import "SDLControlFramePayloadRPCStartServiceAck.h" #import "SDLControlFramePayloadTransportEventUpdate.h" +#import "SDLFakeSecurityManager.h" #import "SDLHMILevel.h" #import "SDLIAPTransport.h" #import "SDLNotificationConstants.h" -#import "SDLRPCNotificationNotification.h" +#import "SDLOnHMIStatus.h" #import "SDLProtocol.h" +#import "SDLRPCNotificationNotification.h" #import "SDLSecondaryTransportManager.h" #import "SDLStateMachine.h" #import "SDLTCPTransport.h" +#import "SDLTimer.h" #import "SDLV2ProtocolMessage.h" -#import "SDLFakeSecurityManager.h" -#import "SDLHMILevel.h" -#import "SDLOnHMIStatus.h" /* copied from SDLSecondaryTransportManager.m */ typedef NSNumber SDLServiceTypeBox; @@ -65,6 +65,7 @@ static const int TCPPortUnspecified = -1; @property (strong, nonatomic, nullable) SDLHMILevel currentHMILevel; @property (assign, nonatomic) UIApplicationState currentApplicationState; @property (strong, nonatomic) SDLBackgroundTaskManager *backgroundTaskManager; +@property (strong, nonatomic, nullable) SDLTimer *registerTransportTimer; - (nullable BOOL (^)(void))sdl_backgroundTaskEndedHandler; @@ -211,6 +212,14 @@ describe(@"the secondary transport manager ", ^{ }); }); + it(@"should ignore the primary transport being opened before the secondary transport is established", ^{ + manager.secondaryProtocol = nil; + + [testPrimaryProtocol onTransportConnected]; + + expect(manager.registerTransportTimer).to(beNil()); + }); + describe(@"when received Start Service ACK on primary transport", ^{ __block SDLProtocolHeader *testStartServiceACKHeader = nil; __block SDLProtocolMessage *testStartServiceACKMessage = nil; @@ -644,6 +653,8 @@ describe(@"the secondary transport manager ", ^{ [testSecondaryProtocolMock onTransportConnected]; OCMVerifyAllWithDelay(testSecondaryProtocolMock, 0.5); + + expect(manager.registerTransportTimer).toNot(beNil()); }); describe(@"and Register Secondary Transport ACK is received", ^{ diff --git a/SmartDeviceLinkTests/SDLEncryptionLifecycleManagerSpec.m b/SmartDeviceLinkTests/SDLEncryptionLifecycleManagerSpec.m index 6bbc5b3e3..15295118b 100644 --- a/SmartDeviceLinkTests/SDLEncryptionLifecycleManagerSpec.m +++ b/SmartDeviceLinkTests/SDLEncryptionLifecycleManagerSpec.m @@ -91,7 +91,7 @@ describe(@"the encryption lifecycle manager", ^{ testRPCHeader.serviceType = SDLServiceTypeRPC; testRPCMessage = [[SDLV2ProtocolMessage alloc] initWithHeader:testRPCHeader andPayload:nil]; - [encryptionLifecycleManager handleProtocolStartServiceACKMessage:testRPCMessage]; + [encryptionLifecycleManager protocol:protocolMock didReceiveStartServiceACK:testRPCMessage]; }); it(@"should have set all the right properties", ^{ @@ -114,7 +114,7 @@ describe(@"the encryption lifecycle manager", ^{ testRPCHeader.serviceType = SDLServiceTypeRPC; testRPCMessage = [[SDLV2ProtocolMessage alloc] initWithHeader:testRPCHeader andPayload:nil]; - [encryptionLifecycleManager handleProtocolEndServiceACKMessage:testRPCMessage]; + [encryptionLifecycleManager protocol:protocolMock didReceiveEndServiceACK:testRPCMessage]; }); it(@"should have set all the right properties", ^{ @@ -136,7 +136,7 @@ describe(@"the encryption lifecycle manager", ^{ testRPCHeader.serviceType = SDLServiceTypeRPC; testRPCMessage = [[SDLV2ProtocolMessage alloc] initWithHeader:testRPCHeader andPayload:nil]; - [encryptionLifecycleManager handleProtocolEndServiceACKMessage:testRPCMessage]; + [encryptionLifecycleManager protocol:protocolMock didReceiveEndServiceACK:testRPCMessage]; }); it(@"should have set all the right properties", ^{ @@ -158,7 +158,7 @@ describe(@"the encryption lifecycle manager", ^{ testRPCHeader.serviceType = SDLServiceTypeRPC; testRPCMessage = [[SDLV2ProtocolMessage alloc] initWithHeader:testRPCHeader andPayload:nil]; - [encryptionLifecycleManager handleProtocolEndServiceNAKMessage:testRPCMessage]; + [encryptionLifecycleManager protocol:protocolMock didReceiveEndServiceNAK:testRPCMessage]; }); it(@"should have set all the right properties", ^{ |