Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Security manager set for secondary protocol #1482

Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion SmartDeviceLink/SDLProxy.m
Expand Up @@ -535,7 +535,7 @@ - (void)handleRegisterAppInterfaceResponse:(SDLRPCResponse *)response {
if (self.protocol.securityManager && [self.protocol.securityManager respondsToSelector:@selector(setAppId:)]) {
self.protocol.securityManager.appId = self.appId;
}

joeljfischer marked this conversation as resolved.
Show resolved Hide resolved
joeljfischer marked this conversation as resolved.
Show resolved Hide resolved
justingluck93 marked this conversation as resolved.
Show resolved Hide resolved
if ([SDLGlobals sharedGlobals].protocolVersion.major >= 4) {
[self sendMobileHMIState];
// Send SDL updates to application state
Expand Down
16 changes: 15 additions & 1 deletion SmartDeviceLink/SDLSecondaryTransportManager.m
Expand Up @@ -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"
Expand Down Expand Up @@ -94,6 +95,8 @@ @interface SDLSecondaryTransportManager ()
@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

Expand All @@ -119,6 +122,8 @@ - (instancetype)initWithStreamingProtocolDelegate:(id<SDLStreamingProtocolDelega
@(SDLServiceTypeVideo):@(SDLTransportClassInvalid)} mutableCopy];
_tcpPort = TCPPortUnspecified;

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appDidBecomeReady) name:SDLDidBecomeReady object:nil];

return self;
}

Expand Down Expand Up @@ -224,7 +229,7 @@ - (void)didEnterStateStarted {
}

- (void)didEnterStateConfigured {
if ((self.secondaryTransportType == SDLSecondaryTransportTypeTCP && [self sdl_isTCPReady])
if ((self.secondaryTransportType == SDLSecondaryTransportTypeTCP && [self sdl_isTCPReady] && self.isAppReady)
|| self.secondaryTransportType == SDLSecondaryTransportTypeIAP) {
[self.stateMachine transitionToState:SDLSecondaryTransportStateConnecting];
}
Expand Down Expand Up @@ -507,6 +512,7 @@ - (BOOL)sdl_startTCPSecondaryTransport {
transport.delegate = protocol;
protocol.transport = transport;
[protocol.protocolDelegateTable addObject:self];
protocol.securityManager = self.primaryProtocol.securityManager;

self.secondaryProtocol = protocol;
self.secondaryTransport = transport;
Expand All @@ -529,6 +535,7 @@ - (BOOL)sdl_startIAPSecondaryTransport {
transport.delegate = protocol;
protocol.transport = transport;
[protocol.protocolDelegateTable addObject:self];
protocol.securityManager = self.primaryProtocol.securityManager;

self.secondaryProtocol = protocol;
self.secondaryTransport = transport;
Expand Down Expand Up @@ -705,6 +712,13 @@ - (SDLSecondaryTransportType)sdl_getTransportTypeFromProtocol:(SDLProtocol *)pro
}
}

- (void)appDidBecomeReady {
self.appReady = YES;
if ([self.stateMachine.currentState isEqualToString:SDLSecondaryTransportStateConfigured]) {
[self.stateMachine transitionToState:SDLSecondaryTransportStateConnecting];
}
joeljfischer marked this conversation as resolved.
Show resolved Hide resolved
}

@end

NS_ASSUME_NONNULL_END
67 changes: 60 additions & 7 deletions SmartDeviceLinkTests/ProxySpecs/SDLSecondaryTransportManagerSpec.m
Expand Up @@ -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;
Expand All @@ -45,13 +47,15 @@ @interface SDLSecondaryTransportManager ()

// 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;
@property (strong, nonatomic, nonnull) NSArray<SDLTransportClassBox *> *transportsForVideoService;
@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

Expand Down Expand Up @@ -409,6 +413,7 @@ + (void)swapConnectionMethods {

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", ^{
Expand Down Expand Up @@ -491,44 +496,67 @@ + (void)swapConnectionMethods {
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", ^{
it(@"should transition to Connecting state but before RAIR is sent", ^{
joeljfischer marked this conversation as resolved.
Show resolved Hide resolved
// 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));
expect(manager.secondaryProtocol.securityManager).to(beNil());

OCMVerifyAll(testStreamingProtocolDelegate);
});

it(@"should transition to Connecting state after RAIR is sent", ^{
joeljfischer marked this conversation as resolved.
Show resolved Hide resolved
testPrimaryProtocol.securityManager = OCMClassMock([SDLFakeSecurityManager class]);

dispatch_sync(testStateMachineQueue, ^{
[manager.stateMachine setToState:SDLSecondaryTransportStateConfigured fromOldState:nil callEnterTransition:NO];
});

// 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];

expect(manager.stateMachine.currentState).to(equal(SDLSecondaryTransportStateConnecting));
expect(manager.secondaryProtocol.securityManager).to(equal(testPrimaryProtocol.securityManager));

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];
});

manager.secondaryTransportType = SDLTransportSelectionTCP;
manager.ipAddress = nil;
manager.tcpPort = TCPPortUnspecified;

dispatch_sync(testStateMachineQueue, ^{
[manager.stateMachine transitionToState:SDLSecondaryTransportStateConfigured];
});
});

describe(@"and Transport Event Update is not received", ^{
it(@"should stay in Configured state", ^{

joeljfischer marked this conversation as resolved.
Show resolved Hide resolved
dispatch_sync(testStateMachineQueue, ^{
[manager.stateMachine transitionToState:SDLSecondaryTransportStateConfigured];
joeljfischer marked this conversation as resolved.
Show resolved Hide resolved
});

expect(manager.stateMachine.currentState).to(equal(SDLSecondaryTransportStateConfigured));

OCMVerifyAll(testStreamingProtocolDelegate);
});
});
Expand All @@ -552,11 +580,34 @@ + (void)swapConnectionMethods {
testTransportEventUpdateMessage = [[SDLV2ProtocolMessage alloc] initWithHeader:testTransportEventUpdateHeader andPayload:testTransportEventUpdatePayload.data];
});

it(@"should transition to Connecting state", ^{
it(@"should transition to Connecting state but before RAIR is sent", ^{
joeljfischer marked this conversation as resolved.
Show resolved Hide resolved
dispatch_sync(testStateMachineQueue, ^{
[manager.stateMachine transitionToState:SDLSecondaryTransportStateConfigured];
});

[testPrimaryProtocol handleBytesFromTransport:testTransportEventUpdateMessage.data];
[NSThread sleepForTimeInterval:0.1];

expect(manager.stateMachine.currentState).to(equal(SDLSecondaryTransportStateConnecting));
expect(manager.secondaryProtocol.securityManager).to(beNil());
OCMVerifyAll(testStreamingProtocolDelegate);
});

it(@"should transition to Connecting state after RAIR is sent", ^{
joeljfischer marked this conversation as resolved.
Show resolved Hide resolved
testPrimaryProtocol.securityManager = OCMClassMock([SDLFakeSecurityManager class]);
[testPrimaryProtocol handleBytesFromTransport:testTransportEventUpdateMessage.data];
[NSThread sleepForTimeInterval:0.1];

dispatch_sync(testStateMachineQueue, ^{
[manager.stateMachine setToState:SDLSecondaryTransportStateConfigured fromOldState:nil callEnterTransition:NO];
});

// 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];

expect(manager.stateMachine.currentState).to(equal(SDLSecondaryTransportStateConnecting));
expect(manager.secondaryProtocol.securityManager).to(equal(testPrimaryProtocol.securityManager));

OCMVerifyAll(testStreamingProtocolDelegate);
});
});
Expand Down Expand Up @@ -585,7 +636,6 @@ + (void)swapConnectionMethods {
});
});


describe(@"In Connecting state", ^{
__block SDLProtocol *secondaryProtocol = nil;
__block id testSecondaryProtocolMock = nil;
Expand Down Expand Up @@ -700,6 +750,7 @@ + (void)swapConnectionMethods {
manager.secondaryTransportType = SDLTransportSelectionTCP;
manager.ipAddress = @"192.168.1.1";
manager.tcpPort = 12345;
manager.appReady = YES;
joeljfischer marked this conversation as resolved.
Show resolved Hide resolved

testTransportEventUpdateHeader = [SDLProtocolHeader headerForVersion:5];
testTransportEventUpdateHeader.frameType = SDLFrameTypeControl;
Expand Down Expand Up @@ -816,6 +867,7 @@ + (void)swapConnectionMethods {
manager.secondaryTransportType = SDLTransportSelectionTCP;
manager.ipAddress = @"192.168.1.1";
manager.tcpPort = 12345;
manager.appReady = YES;

testTransportEventUpdateHeader = [SDLProtocolHeader headerForVersion:5];
testTransportEventUpdateHeader.frameType = SDLFrameTypeControl;
Expand Down Expand Up @@ -974,6 +1026,7 @@ + (void)swapConnectionMethods {
manager.secondaryTransportType = SDLTransportSelectionTCP;
manager.ipAddress = @"192.168.1.1";
manager.tcpPort = 12345;
manager.appReady = YES;

testTransportEventUpdateHeader = [SDLProtocolHeader headerForVersion:5];
testTransportEventUpdateHeader.frameType = SDLFrameTypeControl;
Expand Down