diff options
author | Joel Fischer <joeljfischer@gmail.com> | 2020-01-07 14:46:49 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-01-07 14:46:49 -0500 |
commit | 84b6518d18a0472022917b1a077974f1af70649a (patch) | |
tree | 579082d1c0a760481a566386b14075980d660322 | |
parent | 086250fcd7cf75ab21e6e1ec1af644b15af88363 (diff) | |
parent | 256f03aebd1d12331c7456b2d950ac561894bb86 (diff) | |
download | sdl_ios-84b6518d18a0472022917b1a077974f1af70649a.tar.gz |
Merge pull request #1482 from smartdevicelink/bugfix/issue-1476-SecurityManager-Set-For-SecondaryProtocol
Security manager set for secondary protocol
-rw-r--r-- | SmartDeviceLink/SDLSecondaryTransportManager.m | 24 | ||||
-rw-r--r-- | SmartDeviceLinkTests/ProxySpecs/SDLSecondaryTransportManagerSpec.m | 72 |
2 files changed, 81 insertions, 15 deletions
diff --git a/SmartDeviceLink/SDLSecondaryTransportManager.m b/SmartDeviceLink/SDLSecondaryTransportManager.m index a8c6d6a11..860abcbaf 100644 --- a/SmartDeviceLink/SDLSecondaryTransportManager.m +++ b/SmartDeviceLink/SDLSecondaryTransportManager.m @@ -18,6 +18,7 @@ #import "SDLLogMacros.h" #import "SDLProtocol.h" #import "SDLProtocolHeader.h" +#import "SDLNotificationConstants.h" #import "SDLSecondaryTransportPrimaryProtocolHandler.h" #import "SDLStateMachine.h" #import "SDLTCPTransport.h" @@ -94,6 +95,8 @@ static const int TCPPortUnspecified = -1; @property (strong, nonatomic, nullable) NSString *ipAddress; // TCP port number of SDL Core. If the information isn't available then TCPPortUnspecified is stored. @property (assign, nonatomic) int tcpPort; +// App is ready to set security manager to secondary protocol +@property (assign, nonatomic, getter=isAppReady) BOOL appReady; @end @@ -119,6 +122,8 @@ static const int TCPPortUnspecified = -1; @(SDLServiceTypeVideo):@(SDLTransportClassInvalid)} mutableCopy]; _tcpPort = TCPPortUnspecified; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appDidBecomeReady) name:SDLDidBecomeReady object:nil]; + return self; } @@ -224,8 +229,8 @@ static const int TCPPortUnspecified = -1; } - (void)didEnterStateConfigured { - if ((self.secondaryTransportType == SDLSecondaryTransportTypeTCP && [self sdl_isTCPReady]) - || self.secondaryTransportType == SDLSecondaryTransportTypeIAP) { + if ((self.secondaryTransportType == SDLSecondaryTransportTypeTCP && [self sdl_isTCPReady] && self.isAppReady) + || (self.secondaryTransportType == SDLSecondaryTransportTypeIAP && self.isAppReady)) { [self.stateMachine transitionToState:SDLSecondaryTransportStateConnecting]; } } @@ -277,6 +282,7 @@ static const int TCPPortUnspecified = -1; } - (void)didEnterStateReconnecting { + self.appReady = NO; __weak typeof(self) weakSelf = self; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(RetryConnectionDelay * NSEC_PER_SEC)), _stateMachineQueue, ^{ if ([weakSelf.stateMachine isCurrentState:SDLSecondaryTransportStateReconnecting]) { @@ -366,7 +372,7 @@ static const int TCPPortUnspecified = -1; return; } - if ([self.stateMachine isCurrentState:SDLSecondaryTransportStateConfigured] && [self sdl_isTCPReady]) { + if ([self.stateMachine isCurrentState:SDLSecondaryTransportStateConfigured] && [self sdl_isTCPReady] && self.isAppReady) { [self.stateMachine transitionToState:SDLSecondaryTransportStateConnecting]; } else if ([self sdl_isTransportOpened]) { // Disconnect current transport. If the IP address is available then we will reconnect immediately. @@ -507,6 +513,7 @@ static const int TCPPortUnspecified = -1; transport.delegate = protocol; protocol.transport = transport; [protocol.protocolDelegateTable addObject:self]; + protocol.securityManager = self.primaryProtocol.securityManager; self.secondaryProtocol = protocol; self.secondaryTransport = transport; @@ -529,6 +536,7 @@ static const int TCPPortUnspecified = -1; transport.delegate = protocol; protocol.transport = transport; [protocol.protocolDelegateTable addObject:self]; + protocol.securityManager = self.primaryProtocol.securityManager; self.secondaryProtocol = protocol; self.secondaryTransport = transport; @@ -648,7 +656,7 @@ static const int TCPPortUnspecified = -1; } } else if (notification.name == UIApplicationDidBecomeActiveNotification) { if (([self.stateMachine isCurrentState:SDLSecondaryTransportStateConfigured]) - && self.secondaryTransportType == SDLSecondaryTransportTypeTCP && [self sdl_isTCPReady]) { + && self.secondaryTransportType == SDLSecondaryTransportTypeTCP && [self sdl_isTCPReady] && self.isAppReady) { SDLLogD(@"Resuming TCP transport since the app becomes foreground"); [self.stateMachine transitionToState:SDLSecondaryTransportStateConnecting]; } @@ -705,6 +713,14 @@ static const int TCPPortUnspecified = -1; } } +- (void)appDidBecomeReady { + self.appReady = YES; + if (([self.stateMachine.currentState isEqualToString:SDLSecondaryTransportStateConfigured] && self.tcpPort != SDLControlFrameInt32NotFound && self.ipAddress != nil) + || self.secondaryTransportType == SDLSecondaryTransportTypeIAP) { + [self.stateMachine transitionToState:SDLSecondaryTransportStateConnecting]; + } +} + @end NS_ASSUME_NONNULL_END diff --git a/SmartDeviceLinkTests/ProxySpecs/SDLSecondaryTransportManagerSpec.m b/SmartDeviceLinkTests/ProxySpecs/SDLSecondaryTransportManagerSpec.m index acc14b3c5..d520a367e 100644 --- a/SmartDeviceLinkTests/ProxySpecs/SDLSecondaryTransportManagerSpec.m +++ b/SmartDeviceLinkTests/ProxySpecs/SDLSecondaryTransportManagerSpec.m @@ -14,11 +14,13 @@ #import "SDLControlFramePayloadRPCStartServiceAck.h" #import "SDLControlFramePayloadTransportEventUpdate.h" #import "SDLIAPTransport.h" +#import "SDLNotificationConstants.h" #import "SDLProtocol.h" #import "SDLSecondaryTransportManager.h" #import "SDLStateMachine.h" #import "SDLTCPTransport.h" #import "SDLV2ProtocolMessage.h" +#import "SDLFakeSecurityManager.h" /* copied from SDLSecondaryTransportManager.m */ typedef NSNumber SDLServiceTypeBox; @@ -45,6 +47,7 @@ static const int TCPPortUnspecified = -1; // we need to reach to private properties for the tests @property (assign, nonatomic) SDLSecondaryTransportType secondaryTransportType; +@property (nullable, strong, nonatomic) SDLProtocol *primaryProtocol; @property (nullable, strong, nonatomic) id<SDLTransportType> secondaryTransport; @property (nullable, strong, nonatomic) SDLProtocol *secondaryProtocol; @property (strong, nonatomic, nonnull) NSArray<SDLTransportClassBox *> *transportsForAudioService; @@ -52,6 +55,7 @@ static const int TCPPortUnspecified = -1; @property (strong, nonatomic) NSMutableDictionary<SDLServiceTypeBox *, SDLTransportClassBox *> *streamingServiceTransportMap; @property (strong, nonatomic, nullable) NSString *ipAddress; @property (assign, nonatomic) int tcpPort; +@property (assign, nonatomic, getter=isAppReady) BOOL appReady; @end @@ -409,6 +413,7 @@ describe(@"the secondary transport manager ", ^{ testStartServiceACKPayload = [[SDLControlFramePayloadRPCStartServiceAck alloc] initWithHashId:testHashId mtu:testMtu authToken:nil protocolVersion:testProtocolVersion secondaryTransports:testSecondaryTransports audioServiceTransports:testAudioServiceTransports videoServiceTransports:testVideoServiceTransports]; testStartServiceACKMessage = [[SDLV2ProtocolMessage alloc] initWithHeader:testStartServiceACKHeader andPayload:testStartServiceACKPayload.data]; + manager.appReady = YES; }); it(@"should configure its properties and immediately transition to Connecting state", ^{ @@ -483,7 +488,6 @@ describe(@"the secondary transport manager ", ^{ }); }); - describe(@"In Configured state", ^{ describe(@"if secondary transport is iAP", ^{ beforeEach(^{ @@ -491,28 +495,51 @@ describe(@"the secondary transport manager ", ^{ testPrimaryProtocol = [[SDLProtocol alloc] init]; testPrimaryTransport = [[SDLTCPTransport alloc] init]; testPrimaryProtocol.transport = testPrimaryTransport; + dispatch_sync(testStateMachineQueue, ^{ [manager startWithPrimaryProtocol:testPrimaryProtocol]; }); manager.secondaryTransportType = SDLTransportSelectionIAP; - }); - it(@"should transition to Connecting state", ^{ - // setToState cannot be used here, as the method will set the state after calling didEnterStateConfigured dispatch_sync(testStateMachineQueue, ^{ [manager.stateMachine transitionToState:SDLSecondaryTransportStateConfigured]; }); + }); - expect(manager.stateMachine.currentState).to(equal(SDLSecondaryTransportStateConnecting)); - OCMVerifyAll(testStreamingProtocolDelegate); + context(@"before the security manager is set by register app interface response", ^{ + it(@"should stay in state Configured", ^{ + expect(manager.stateMachine.currentState).to(equal(SDLSecondaryTransportStateConfigured)); + expect(manager.secondaryProtocol.securityManager).to(beNil()); + expect(manager.isAppReady).to(equal(NO)); + + OCMVerifyAll(testStreamingProtocolDelegate); + }); + }); + + context(@"after the security manager is set by register app interface response", ^{ + beforeEach(^{ + testPrimaryProtocol.securityManager = OCMClassMock([SDLFakeSecurityManager class]); + // By the time this notification is recieved the RAIR should have been sent and the security manager should exist if available + [[NSNotificationCenter defaultCenter] postNotificationName:SDLDidBecomeReady object:nil]; + }); + + it(@"should transition to Connecting state", ^{ + expect(manager.stateMachine.currentState).to(equal(SDLSecondaryTransportStateConnecting)); + expect(manager.secondaryProtocol.securityManager).to(equal(testPrimaryProtocol.securityManager)); + expect(manager.isAppReady).to(equal(YES)); + + OCMVerifyAll(testStreamingProtocolDelegate); + }); }); }); + describe(@"if secondary transport is TCP", ^{ beforeEach(^{ testPrimaryProtocol = [[SDLProtocol alloc] init]; testPrimaryTransport = [[SDLIAPTransport alloc] init]; testPrimaryProtocol.transport = testPrimaryTransport; + dispatch_sync(testStateMachineQueue, ^{ [manager startWithPrimaryProtocol:testPrimaryProtocol]; }); @@ -529,6 +556,7 @@ describe(@"the secondary transport manager ", ^{ describe(@"and Transport Event Update is not received", ^{ it(@"should stay in Configured state", ^{ expect(manager.stateMachine.currentState).to(equal(SDLSecondaryTransportStateConfigured)); + OCMVerifyAll(testStreamingProtocolDelegate); }); }); @@ -550,14 +578,33 @@ describe(@"the secondary transport manager ", ^{ testTransportEventUpdatePayload = [[SDLControlFramePayloadTransportEventUpdate alloc] initWithTcpIpAddress:testTcpIpAddress tcpPort:testTcpPort]; testTransportEventUpdateMessage = [[SDLV2ProtocolMessage alloc] initWithHeader:testTransportEventUpdateHeader andPayload:testTransportEventUpdatePayload.data]; - }); - it(@"should transition to Connecting state", ^{ [testPrimaryProtocol handleBytesFromTransport:testTransportEventUpdateMessage.data]; [NSThread sleepForTimeInterval:0.1]; - expect(manager.stateMachine.currentState).to(equal(SDLSecondaryTransportStateConnecting)); - OCMVerifyAll(testStreamingProtocolDelegate); + }); + + context(@"before the security manager is set by register app interface response", ^{ + it(@"should stay in Configured state", ^{ + expect(manager.stateMachine.currentState).to(equal(SDLSecondaryTransportStateConfigured)); + expect(manager.secondaryProtocol.securityManager).to(beNil()); + OCMVerifyAll(testStreamingProtocolDelegate); + }); + }); + + context(@"after the security manager is set by register app interface response", ^{ + beforeEach(^{ + testPrimaryProtocol.securityManager = OCMClassMock([SDLFakeSecurityManager class]); + // By the time this notification is recieved the RAIR should have been sent and the security manager should exist if available + [[NSNotificationCenter defaultCenter] postNotificationName:SDLDidBecomeReady object:nil]; + }); + + it(@"should transition to Connecting", ^{ + expect(manager.stateMachine.currentState).to(equal(SDLSecondaryTransportStateConnecting)); + expect(manager.secondaryProtocol.securityManager).to(equal(testPrimaryProtocol.securityManager)); + + OCMVerifyAll(testStreamingProtocolDelegate); + }); }); }); }); @@ -585,7 +632,6 @@ describe(@"the secondary transport manager ", ^{ }); }); - describe(@"In Connecting state", ^{ __block SDLProtocol *secondaryProtocol = nil; __block id testSecondaryProtocolMock = nil; @@ -685,6 +731,7 @@ describe(@"the secondary transport manager ", ^{ [NSThread sleepForTimeInterval:0.1]; expect(manager.stateMachine.currentState).to(equal(SDLSecondaryTransportStateReconnecting)); + expect(manager.isAppReady).to(equal(NO)); OCMVerifyAll(testStreamingProtocolDelegate); }); }); @@ -729,6 +776,7 @@ describe(@"the secondary transport manager ", ^{ beforeEach(^{ testTcpIpAddress = @"172.16.12.34"; testTcpPort = 12345; + manager.appReady = YES; testTransportEventUpdatePayload = [[SDLControlFramePayloadTransportEventUpdate alloc] initWithTcpIpAddress:testTcpIpAddress tcpPort:testTcpPort]; testTransportEventUpdateMessage = [[SDLV2ProtocolMessage alloc] initWithHeader:testTransportEventUpdateHeader andPayload:testTransportEventUpdatePayload.data]; @@ -816,6 +864,7 @@ describe(@"the secondary transport manager ", ^{ manager.secondaryTransportType = SDLTransportSelectionTCP; manager.ipAddress = @"192.168.1.1"; manager.tcpPort = 12345; + manager.appReady = YES; testTransportEventUpdateHeader = [SDLProtocolHeader headerForVersion:5]; testTransportEventUpdateHeader.frameType = SDLFrameTypeControl; @@ -974,6 +1023,7 @@ describe(@"the secondary transport manager ", ^{ manager.secondaryTransportType = SDLTransportSelectionTCP; manager.ipAddress = @"192.168.1.1"; manager.tcpPort = 12345; + manager.appReady = YES; testTransportEventUpdateHeader = [SDLProtocolHeader headerForVersion:5]; testTransportEventUpdateHeader.frameType = SDLFrameTypeControl; |