summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoel Fischer <joeljfischer@gmail.com>2020-01-07 14:46:49 -0500
committerGitHub <noreply@github.com>2020-01-07 14:46:49 -0500
commit84b6518d18a0472022917b1a077974f1af70649a (patch)
tree579082d1c0a760481a566386b14075980d660322
parent086250fcd7cf75ab21e6e1ec1af644b15af88363 (diff)
parent256f03aebd1d12331c7456b2d950ac561894bb86 (diff)
downloadsdl_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.m24
-rw-r--r--SmartDeviceLinkTests/ProxySpecs/SDLSecondaryTransportManagerSpec.m72
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;