Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
121 changes: 121 additions & 0 deletions SmartDeviceLink-iOS.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions SmartDeviceLink/SDLDebugTool.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ typedef NS_ENUM(UInt8, SDLDebugType) {
SDLDebugType_Debug = 0,
SDLDebugType_Transport_iAP = 1,
SDLDebugType_Transport_TCP = 2,
SDLDebugType_Transport_USBMUXD = 6,
SDLDebugType_Protocol = 3,
SDLDebugType_RPC = 4,
SDLDebugType_APP = 5
Expand Down
14 changes: 13 additions & 1 deletion SmartDeviceLink/SDLLifecycleConfiguration.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@ typedef NS_OPTIONS(NSUInteger, SDLLogOutput) {
SDLLogOutputSiphon = 1 << 2
};

typedef NS_ENUM(NSInteger, SDLTransportType) {
SDLTransportTypeTCP = 0,
SDLTransportTypeIAP = 1,
SDLTransportTypeUSBMUXD = 2
};


NS_ASSUME_NONNULL_BEGIN

Expand All @@ -38,10 +44,11 @@ NS_ASSUME_NONNULL_BEGIN
*
* @param appName The name of the app.
* @param appId The appId to be used. This should be registered with the radio's manufacturer.
* @param transportType The transport type.
*
* @return The lifecycle configuration
*/
+ (SDLLifecycleConfiguration *)defaultConfigurationWithAppName:(NSString *)appName appId:(NSString *)appId;
+ (SDLLifecycleConfiguration *)defaultConfigurationWithAppName:(NSString *)appName appId:(NSString *)appId transportType:(SDLTransportType)transportType;

/**
* A debug configuration that runs using TCP. Additional functionality should be customized on the properties.
Expand Down Expand Up @@ -135,6 +142,11 @@ NS_ASSUME_NONNULL_BEGIN
*/
@property (assign, nonatomic) SDLLogOutput logFlags;

/**
* The transport type.
*/
@property (assign, nonatomic) SDLTransportType transportType;

@end

NS_ASSUME_NONNULL_END
11 changes: 6 additions & 5 deletions SmartDeviceLink/SDLLifecycleConfiguration.m
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ @implementation SDLLifecycleConfiguration

#pragma mark Lifecycle

- (instancetype)initDefaultConfigurationWithAppName:(NSString *)appName appId:(NSString *)appId {
- (instancetype)initDefaultConfigurationWithAppName:(NSString *)appName appId:(NSString *)appId transportType:(SDLTransportType)transportType {
self = [super init];
if (!self) {
return nil;
Expand All @@ -52,16 +52,17 @@ - (instancetype)initDefaultConfigurationWithAppName:(NSString *)appName appId:(N
_ttsName = nil;
_voiceRecognitionCommandNames = nil;
_logFlags = SDLLogOutputNone;
_transportType = transportType;

return self;
}

+ (SDLLifecycleConfiguration *)defaultConfigurationWithAppName:(NSString *)appName appId:(NSString *)appId {
return [[self alloc] initDefaultConfigurationWithAppName:appName appId:appId];
+ (SDLLifecycleConfiguration *)defaultConfigurationWithAppName:(NSString *)appName appId:(NSString *)appId transportType:(SDLTransportType)transportType {
return [[self alloc] initDefaultConfigurationWithAppName:appName appId:appId transportType:transportType];
}

+ (SDLLifecycleConfiguration *)debugConfigurationWithAppName:(NSString *)appName appId:(NSString *)appId ipAddress:(NSString *)ipAddress port:(UInt16)port {
SDLLifecycleConfiguration *config = [[self alloc] initDefaultConfigurationWithAppName:appName appId:appId];
SDLLifecycleConfiguration *config = [[self alloc] initDefaultConfigurationWithAppName:appName appId:appId transportType:SDLTransportTypeTCP];
config.tcpDebugMode = YES;
config.tcpDebugIPAddress = ipAddress;
config.tcpDebugPort = port;
Expand Down Expand Up @@ -102,7 +103,7 @@ - (void)setAppType:(nullable SDLAppHMIType *)appType {
#pragma mark NSCopying

- (id)copyWithZone:(nullable NSZone *)zone {
SDLLifecycleConfiguration *newConfig = [[self.class allocWithZone:zone] initDefaultConfigurationWithAppName:_appName appId:_appId];
SDLLifecycleConfiguration *newConfig = [[self.class allocWithZone:zone] initDefaultConfigurationWithAppName:_appName appId:_appId transportType:_transportType];
newConfig->_tcpDebugMode = _tcpDebugMode;
newConfig->_tcpDebugIPAddress = _tcpDebugIPAddress;
newConfig->_tcpDebugPort = _tcpDebugPort;
Expand Down
12 changes: 7 additions & 5 deletions SmartDeviceLink/SDLLifecycleManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ @implementation SDLLifecycleManager
#pragma mark Lifecycle

- (instancetype)init {
return [self initWithConfiguration:[SDLConfiguration configurationWithLifecycle:[SDLLifecycleConfiguration defaultConfigurationWithAppName:@"SDL APP" appId:@"001"] lockScreen:[SDLLockScreenConfiguration disabledConfiguration]] delegate:nil];
return [self initWithConfiguration:[SDLConfiguration configurationWithLifecycle:[SDLLifecycleConfiguration defaultConfigurationWithAppName:@"SDL APP" appId:@"001" transportType:SDLTransportTypeTCP] lockScreen:[SDLLockScreenConfiguration disabledConfiguration]] delegate:nil];
}

- (instancetype)initWithConfiguration:(SDLConfiguration *)configuration delegate:(nullable id<SDLManagerDelegate>)delegate {
Expand Down Expand Up @@ -164,10 +164,12 @@ - (void)didEnterStateStarted {
// Start up the internal proxy object
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
if (self.configuration.lifecycleConfig.tcpDebugMode) {
self.proxy = [SDLProxyFactory buildSDLProxyWithListener:self.notificationDispatcher tcpIPAddress:self.configuration.lifecycleConfig.tcpDebugIPAddress tcpPort:[@(self.configuration.lifecycleConfig.tcpDebugPort) stringValue]];
} else {
self.proxy = [SDLProxyFactory buildSDLProxyWithListener:self.notificationDispatcher];
if (self.configuration.lifecycleConfig.transportType == SDLTransportTypeTCP) {
self.proxy = [SDLProxyFactory buildSDLProxyWithTCPListener:self.notificationDispatcher tcpIPAddress:self.configuration.lifecycleConfig.tcpDebugIPAddress tcpPort:[@(self.configuration.lifecycleConfig.tcpDebugPort) stringValue]];
} else if (self.configuration.lifecycleConfig.transportType == SDLTransportTypeIAP) {
self.proxy = [SDLProxyFactory buildSDLProxyWithiAPListener:self.notificationDispatcher];
} else if (self.configuration.lifecycleConfig.transportType == SDLTransportTypeUSBMUXD) {
self.proxy = [SDLProxyFactory buildSDLProxyWithUSBMUXDListener:self.notificationDispatcher];
}
#pragma clang diagnostic pop
}
Expand Down
2 changes: 1 addition & 1 deletion SmartDeviceLink/SDLManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ @implementation SDLManager
#pragma mark Lifecycle

- (instancetype)init {
return [self initWithConfiguration:[SDLConfiguration configurationWithLifecycle:[SDLLifecycleConfiguration defaultConfigurationWithAppName:@"SDL APP" appId:@"001"] lockScreen:[SDLLockScreenConfiguration enabledConfiguration]] delegate:nil];
return [self initWithConfiguration:[SDLConfiguration configurationWithLifecycle:[SDLLifecycleConfiguration defaultConfigurationWithAppName:@"SDL APP" appId:@"001"transportType:SDLTransportTypeTCP] lockScreen:[SDLLockScreenConfiguration enabledConfiguration]] delegate:nil];
}

- (instancetype)initWithConfiguration:(SDLConfiguration *)configuration delegate:(nullable id<SDLManagerDelegate>)delegate {
Expand Down
11 changes: 7 additions & 4 deletions SmartDeviceLink/SDLProxyFactory.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,12 @@ __deprecated_msg("Use SDLManager instead")
@interface SDLProxyFactory : NSObject {
}

+ (SDLProxy *)buildSDLProxyWithListener:(NSObject<SDLProxyListener> *)listener;
+ (SDLProxy *)buildSDLProxyWithiAPListener:(NSObject<SDLProxyListener> *)listener;

+ (SDLProxy *)buildSDLProxyWithTCPListener:(NSObject<SDLProxyListener> *)listener
tcpIPAddress:(NSString *)ipaddress
tcpPort:(NSString *)port;

+ (SDLProxy *)buildSDLProxyWithUSBMUXDListener:(NSObject<SDLProxyListener> *)delegate;

+ (SDLProxy *)buildSDLProxyWithListener:(NSObject<SDLProxyListener> *)listener
tcpIPAddress:(NSString *)ipaddress
tcpPort:(NSString *)port;
@end
17 changes: 13 additions & 4 deletions SmartDeviceLink/SDLProxyFactory.m
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,22 @@
#import "SDLProtocol.h"
#import "SDLProxy.h"
#import "SDLTCPTransport.h"
#import "SDLUSBMUXDTransport.h"


@implementation SDLProxyFactory

+ (SDLProxy *)buildSDLProxyWithListener:(NSObject<SDLProxyListener> *)delegate {
+ (SDLProxy *)buildSDLProxyWithiAPListener:(NSObject<SDLProxyListener> *)delegate {
SDLIAPTransport *transport = [[SDLIAPTransport alloc] init];
SDLProtocol *protocol = [[SDLProtocol alloc] init];
SDLProxy *ret = [[SDLProxy alloc] initWithTransport:transport protocol:protocol delegate:delegate];

return ret;
}

+ (SDLProxy *)buildSDLProxyWithListener:(NSObject<SDLProxyListener> *)delegate
tcpIPAddress:(NSString *)ipaddress
tcpPort:(NSString *)port {
+ (SDLProxy *)buildSDLProxyWithTCPListener:(NSObject<SDLProxyListener> *)delegate
tcpIPAddress:(NSString *)ipaddress
tcpPort:(NSString *)port {
SDLTCPTransport *transport = [[SDLTCPTransport alloc] init];
transport.hostName = ipaddress;
transport.portNumber = port;
Expand All @@ -34,4 +35,12 @@ + (SDLProxy *)buildSDLProxyWithListener:(NSObject<SDLProxyListener> *)delegate
return ret;
}

+ (SDLProxy *)buildSDLProxyWithUSBMUXDListener:(NSObject<SDLProxyListener> *)delegate {
SDLUSBMUXDTransport *transport = [[SDLUSBMUXDTransport alloc] init];
SDLProtocol *protocol = [[SDLProtocol alloc] init];
SDLProxy *ret = [[SDLProxy alloc] initWithTransport:transport protocol:protocol delegate:delegate];

return ret;
}

@end
8 changes: 8 additions & 0 deletions SmartDeviceLink/SDLUSBMUXDTransport.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// SDLUSBMUXDTransport.h
//

#import <SmartDeviceLink/SmartDeviceLink.h>

@interface SDLUSBMUXDTransport : SDLAbstractTransport

@end
167 changes: 167 additions & 0 deletions SmartDeviceLink/SDLUSBMUXDTransport.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
// SDLUSBMUXDTransport.m
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@conner-wu Please add copyright for this new file, if it's copyed from from other open source project, just keep the original copyright, otherwise, please add SDLC copyright, you can reference smartdevicelink

//

#import "SDLUSBMUXDTransport.h"
#import "SDLUSBMUXDChannel.h"
#import "SDLHexUtility.h"

static const int USBMUXDProtocolIPv4PortNumber = 20001;

enum {
SDLUSBMUXDFrameTypeDeviceInfo = 100,
SDLUSBMUXDFrameTypeTextMessage = 101,
SDLUSBMUXDFrameTypePing = 102,
SDLUSBMUXDFrameTypePong = 103,
};

typedef struct _SDLUSBMUXDTextFrame {
uint32_t length;
uint8_t utf8text[0];
} SDLUSBMUXDTextFrame;

@interface SDLUSBMUXDTransport () <SDLUSBMUXDChannelDelegate>
{
SDLUSBMUXDChannel *_channel;
}
@end

@implementation SDLUSBMUXDTransport

- (void)connect {
if (_channel) {
[self disconnect];
}

// Create a new channel that is listening on our IPv4 port
_channel = [SDLUSBMUXDChannel channelWithDelegate:self];
[_channel listenOnPort:USBMUXDProtocolIPv4PortNumber IPv4Address:INADDR_LOOPBACK callback:^(NSError *error) {
if (error) {
[SDLDebugTool logInfo:[NSString stringWithFormat:@"SDLUSBMUXDTransport Failed to listen on 127.0.0.1:%d: %@", USBMUXDProtocolIPv4PortNumber, error] withType:SDLDebugType_Transport_USBMUXD];
} else {
[SDLDebugTool logInfo:[NSString stringWithFormat:@"SDLUSBMUXDTransport Listening on 127.0.0.1:%d", USBMUXDProtocolIPv4PortNumber]];
}
}];
}

- (void)dealloc {
[self destructObjects];
}

- (void)destructObjects {
[SDLDebugTool logInfo:@"SDLUSBMUXDTransport invalidate and dispose"];

if (_channel) {
[_channel close];
_channel.delegate = nil;
_channel = nil;
}
}

- (void)disconnect {
[self dispose];
}

- (void)sendData:(NSData *)dataToSend {
if (_channel) {
NSString *byteStr = [SDLHexUtility getHexString:dataToSend];
[SDLDebugTool logInfo:[NSString stringWithFormat:@"SDLUSBMUXDTransport Sent %lu bytes: %@", (unsigned long)dataToSend.length, byteStr] withType:SDLDebugType_Transport_USBMUXD toOutput:SDLDebugOutput_DeviceConsole];

dispatch_data_t payload = [dataToSend createReferencingDispatchData];
[_channel sendFrameOfType:SDLUSBMUXDFrameTypeTextMessage tag:SDLUSBMUXDFrameNoTag withPayload:payload callback:^(NSError *error) {
if (error) {
[SDLDebugTool logInfo:[NSString stringWithFormat:@"SDLUSBMUXDTransport Failed to send message: %@", error]];
}
}];
} else {
[SDLDebugTool logInfo:@"SDLUSBMUXDTransport Can not send message — not connected"];
}
}

- (void)dispose {
[self destructObjects];
}

#pragma mark - SDLUSBMUXDChannelDelegate

// Invoked to accept an incoming frame on a channel. Reply NO ignore the
// incoming frame. If not implemented by the delegate, all frames are accepted.
- (BOOL)ioFrameChannel:(SDLUSBMUXDChannel*)channel shouldAcceptFrameOfType:(uint32_t)type tag:(uint32_t)tag payloadSize:(uint32_t)payloadSize {
if (channel != _channel) {
// A previous channel that has been canceled but not yet ended. Ignore.
return NO;
} else if (type != SDLUSBMUXDFrameTypeTextMessage && type != SDLUSBMUXDFrameTypePing) {
[SDLDebugTool logInfo:[NSString stringWithFormat:@"SDLUSBMUXDTransport Unexpected frame of type %u", type]];
[channel close];
return NO;
} else {
return YES;
}
}

// Invoked when a new frame has arrived on a channel.
- (void)ioFrameChannel:(SDLUSBMUXDChannel*)channel didReceiveFrameOfType:(uint32_t)type tag:(uint32_t)tag payload:(SDLUSBMUXDData*)payload {
if (type == SDLUSBMUXDFrameTypeTextMessage) {
// Check if Core disconnected from us
if (payload.length <= 0) {
[SDLDebugTool logInfo:@"SDLUSBMUXDTransport Got a data packet with length 0, the connection was terminated on the other side"];
if (self.delegate) {
[self.delegate onTransportDisconnected];
}

return;
}

// Handle the data we received
SDLUSBMUXDTextFrame *textFrame = (SDLUSBMUXDTextFrame*)payload.data;
textFrame->length = ntohl(textFrame->length);
NSString *byteStr = [[NSString alloc] initWithBytes:textFrame->utf8text length:textFrame->length encoding:NSUTF8StringEncoding];

[SDLDebugTool logInfo:[NSString stringWithFormat:@"SDLUSBMUXDTransport Read %d bytes: %@", textFrame->length, byteStr] withType:SDLDebugType_Transport_USBMUXD toOutput:SDLDebugOutput_DeviceConsole];

if (self.delegate) {
[self.delegate onDataReceived:[NSData dataWithBytes:textFrame->utf8text length:textFrame->length]];
}
} else if (type == SDLUSBMUXDFrameTypePing && _channel) {
[_channel sendFrameOfType:SDLUSBMUXDFrameTypePong tag:tag withPayload:nil callback:nil];
}
}

// Invoked when the channel closed. If it closed because of an error, *error* is
// a non-nil NSError object.
- (void)ioFrameChannel:(SDLUSBMUXDChannel*)channel didEndWithError:(NSError*)error {
if (error) {
[SDLDebugTool logInfo:[NSString stringWithFormat:@"SDLUSBMUXDTransport %@ ended with error: %@", channel, error]];
}
if (channel.userInfo) {
[SDLDebugTool logInfo:[NSString stringWithFormat:@"SDLUSBMUXDTransport Disconnected from %@", channel.userInfo]];

if (self.delegate) {
[self disconnect];
[self.delegate onTransportDisconnected];
}
}
}

// For listening channels, this method is invoked when a new connection has been
// accepted.
- (void)ioFrameChannel:(SDLUSBMUXDChannel*)channel didAcceptConnection:(SDLUSBMUXDChannel*)otherChannel fromAddress:(SDLUSBMUXDAddress*)address {
// Cancel any other connection. We are FIFO, so the last connection
// established will cancel any previous connection and "take its place".
if (_channel) {
[_channel cancel];
}

// Weak pointer to current connection. Connection objects live by themselves
// (owned by its parent dispatch queue) until they are closed.
_channel = otherChannel;
_channel.userInfo = address;

[SDLDebugTool logInfo:[NSString stringWithFormat:@"SDLUSBMUXDTransport Connected to %@", address]];

// Send some information about ourselves to the other end
if (self.delegate) {
[self.delegate onTransportConnected];
}
}

@end
Loading