Skip to content

Commit

Permalink
Merge pull request #33 from smartdevicelink/feature/Mobile_HMI_State_…
Browse files Browse the repository at this point in the history
…Notifications

Application Launching (SDL 4.0)
  • Loading branch information
joeljfischer committed Jan 21, 2015
2 parents 9e6c013 + 5cf4cd0 commit d99c952
Show file tree
Hide file tree
Showing 8 changed files with 108 additions and 101 deletions.
3 changes: 2 additions & 1 deletion sdl_ios/SmartDeviceLink/SDLInterfaceProtocol.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
- (void)handleBytesFromTransport:(NSData *)receivedData;
- (void)sendStartSessionWithType:(SDLServiceType)sessionType;
- (void)sendEndSessionWithType:(SDLServiceType)sessionType sessionID:(Byte)sessionID;
- (void)sendRPCRequest:(SDLRPCRequest *)rpcRequest;
- (void)sendRPC:(SDLRPCMessage *)message;
- (void)sendRPCRequest:(SDLRPCRequest *)rpcRequest __deprecated_msg("use sendRPC: instead");

@end
6 changes: 5 additions & 1 deletion sdl_ios/SmartDeviceLink/SDLProtocol.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,18 @@
// Copyright (c) 2014 Ford Motor Company. All rights reserved.

#import "SDLAbstractProtocol.h"
#import <SmartDeviceLink/SDLRPCMessageType.h>


@interface SDLProtocol : SDLAbstractProtocol <SDLProtocolListener>

- (void)sendStartSessionWithType:(SDLServiceType)serviceType;
- (void)sendEndSessionWithType:(SDLServiceType)serviceType sessionID:(Byte)sessionID;
- (void)sendRPCRequest:(SDLRPCRequest *)rpcRequest;
- (void)sendRPC:(SDLRPCMessage *)message;
- (void)handleBytesFromTransport:(NSData *)receivedData;
- (void)sendHeartbeat;

#pragma mark - Deprecated
- (void)sendRPCRequest:(SDLRPCRequest *)rpcRequest __deprecated_msg("use -sendRPC: instead");

@end
86 changes: 51 additions & 35 deletions sdl_ios/SmartDeviceLink/SDLProtocol.m
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
#import "SDLRPCPayload.h"
#import "SDLDebugTool.h"
#import "SDLPrioritizedObjectCollection.h"
#import "SDLRPCNotification.h"
#import "SDLRPCResponse.h"


const NSUInteger MAX_TRANSMISSION_SIZE = 512;
Expand Down Expand Up @@ -82,67 +84,81 @@ - (void)sendEndSessionWithType:(SDLServiceType)serviceType sessionID:(Byte)sessi

}

// SDLRPCRequest in from app -> SDLProtocolMessage out to transport layer.
- (void)sendRPCRequest:(SDLRPCRequest *)rpcRequest {

NSData *jsonData = [[SDLJsonEncoder instance] encodeDictionary:[rpcRequest serializeAsDictionary:self.version]];
- (void)sendRPC:(SDLRPCMessage *)message {
NSParameterAssert(message != nil);
NSData *jsonData = [[SDLJsonEncoder instance] encodeDictionary:[message serializeAsDictionary:self.version]];
NSData* messagePayload = nil;

NSString *logMessage = [NSString stringWithFormat:@"%@", rpcRequest];
NSString *logMessage = [NSString stringWithFormat:@"%@", message];
[SDLDebugTool logInfo:logMessage withType:SDLDebugType_RPC toOutput:SDLDebugOutput_All toGroup:self.debugConsoleGroupName];


if(self.version == 1) {
messagePayload = jsonData;
} else if (self.version == 2) {
// Serialize the RPC data into an NSData
SDLRPCPayload *rpcPayload = [[SDLRPCPayload alloc] init];
rpcPayload.rpcType = 0;
rpcPayload.functionID = [[[[SDLFunctionID alloc] init] getFunctionID:[rpcRequest getFunctionName]] intValue];
rpcPayload.correlationID = [rpcRequest.correlationID intValue];
rpcPayload.jsonData = jsonData;
rpcPayload.binaryData = rpcRequest.bulkData;
messagePayload = rpcPayload.data;

// Build the message payload. Include the binary header if necessary
switch (self.version) {
case 1: {
// No binary header in version 1
messagePayload = jsonData;
} break;
case 2: // Fallthrough
case 3: {
// Build a binary header
// Serialize the RPC data into an NSData
SDLRPCPayload *rpcPayload = [[SDLRPCPayload alloc] init];
rpcPayload.rpcType = type;
rpcPayload.functionID = [[[[SDLFunctionID alloc] init] getFunctionID:[message getFunctionName]] intValue];
rpcPayload.jsonData = jsonData;
rpcPayload.binaryData = message.bulkData;

// If it's a request or a response, we need to pull out the correlation ID, so we'll upcast
if ([message isKindOfClass:SDLRPCRequest.class]) {
rpcPayload.correlationID = [((SDLRPCRequest *)message).correlationID intValue];
} else if ([message isKindOfClass:SDLRPCResponse.class]) {
rpcPayload.correlationID = [((SDLRPCResponse *)message).correlationID intValue];
}

messagePayload = rpcPayload.data;
} break;
default: {
NSAssert(NO, @"sendRPCMessage:withType: must handle additional versions");
} break;
}

//

// Build the protocol level header & message
//
SDLProtocolHeader *header = [SDLProtocolHeader headerForVersion:self.version];
header.frameType = SDLFrameType_Single;
header.serviceType = SDLServiceType_RPC;
header.frameData = SDLFrameData_SingleFrame;
header.sessionID = self.sessionID;
header.bytesInPayload = (UInt32)messagePayload.length;

// V2+ messages need to have message ID property set.
if (self.version >= 2) {
[((SDLV2ProtocolHeader*)header) setMessageID:++_messageID];
}


SDLProtocolMessage *message = [SDLProtocolMessage messageWithHeader:header andPayload:messagePayload];


//

SDLProtocolMessage *protocolMessage = [SDLProtocolMessage messageWithHeader:header andPayload:messagePayload];

// See if the message is small enough to send in one transmission.
// If not, break it up into smaller messages and send.
//
if (message.size < MAX_TRANSMISSION_SIZE)
if (protocolMessage.size < MAX_TRANSMISSION_SIZE)
{
[self logRPCSend:message];
[self sendDataToTransport:message.data withPriority:SDLServiceType_RPC];
[self logRPCSend:protocolMessage];
[self sendDataToTransport:protocolMessage.data withPriority:SDLServiceType_RPC];
}
else
{
NSArray *messages = [SDLProtocolMessageDisassembler disassemble:message withLimit:MAX_TRANSMISSION_SIZE];
NSArray *messages = [SDLProtocolMessageDisassembler disassemble:protocolMessage withLimit:MAX_TRANSMISSION_SIZE];
for (SDLProtocolMessage *smallerMessage in messages) {
[self logRPCSend:smallerMessage];
[self sendDataToTransport:smallerMessage.data withPriority:SDLServiceType_RPC];
}

}
}

// SDLRPCRequest in from app -> SDLProtocolMessage out to transport layer.
- (void)sendRPCRequest:(SDLRPCRequest *)rpcRequest {
[self sendRPC:rpcRequest withType:SDLRPCMessageTypeRequest];
}

- (void)logRPCSend:(SDLProtocolMessage *)message {
Expand Down
4 changes: 3 additions & 1 deletion sdl_ios/SmartDeviceLink/SDLProxy.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@
-(void) dispose;
-(void) addDelegate:(NSObject<SDLProxyListener>*) delegate;

-(void) sendRPCRequest:(SDLRPCMessage*) msg;
-(void) sendRPCRequest:(SDLRPCMessage*) msg __deprecated_msg("use sendRPC: instead");
-(void) sendRPC:(SDLRPCMessage *)message;

-(void) handleRpcMessage:(NSDictionary*) msg;

-(NSString*) getProxyVersion;
Expand Down
39 changes: 37 additions & 2 deletions sdl_ios/SmartDeviceLink/SDLProxy.m
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@ - (id)initWithTransport:(NSObject<SDLTransport> *)theTransport protocol:(NSObjec
[self.transport connect];

[[EAAccessoryManager sharedAccessoryManager] registerForLocalNotifications];

}

return self;
Expand Down Expand Up @@ -101,6 +100,26 @@ -(void) notifyProxyClosed {
}
}

- (void)sendMobileHMIState {
UIApplicationState appState = [UIApplication sharedApplication].applicationState;
SDLOnHMIStatus *HMIStatusRPC = [[SDLOnHMIStatus alloc] init];

switch (appState) {
case UIApplicationStateActive: {
HMIStatusRPC.hmiLevel = [SDLHMILevel HMI_FULL];
} break;
case UIApplicationStateInactive: // Fallthrough
case UIApplicationStateBackground: {
HMIStatusRPC.hmiLevel = [SDLHMILevel HMI_BACKGROUND];
} break;
default:
break;
}

// TODO: This won't work, there are runtime checks to make sure only requests are sent...
[self sendRPCRequest:HMIStatusRPC];
}


#pragma mark - Pseudo properties
- (NSObject<SDLTransport> *)getTransport {
Expand Down Expand Up @@ -140,7 +159,7 @@ -(void)destroyHandshakeTimer {
- (void) onProtocolOpened {
isConnected = YES;
[SDLDebugTool logInfo:@"StartSession (request)" withType:SDLDebugType_RPC toOutput:SDLDebugOutput_All toGroup:self.debugConsoleGroupName];

[self.protocol sendStartSessionWithType:SDLServiceType_RPC];

[self destroyHandshakeTimer];
Expand Down Expand Up @@ -169,6 +188,13 @@ - (void)handleProtocolSessionStarted:(SDLServiceType)sessionType sessionID:(Byte
rpcSessionID = sessionID;
[self invokeMethodOnDelegates:@selector(onProxyOpened) withObject:nil];
}

if (_version >= 4) {
// Send the Mobile HMI state and register handlers for changing state
[self sendMobileHMIState];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(sendMobileHMIState) name:UIApplicationDidBecomeActiveNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(sendMobileHMIState) name:UIApplicationWillResignActiveNotification object:nil];
}
}

- (void) onProtocolMessageReceived:(SDLProtocolMessage*) msgData {
Expand All @@ -183,6 +209,15 @@ - (void) onProtocolMessageReceived:(SDLProtocolMessage*) msgData {


#pragma mark - Message sending and recieving
- (void)sendRPC:(SDLRPCMessage *)message {
@try {
[self.protocol sendRPC:message];
} @catch (NSException *exception) {
NSString *logMessage = [NSString stringWithFormat:@"Proxy: Failed to send RPC message: %@", message.name];
[SDLDebugTool logInfo:logMessage withType:SDLDebugType_Debug toOutput:SDLDebugOutput_All toGroup:self.debugConsoleGroupName];
}
}

-(void) sendRPCRequest:(SDLRPCMessage*) msg {
if ([msg isKindOfClass:SDLRPCRequest.class]) {
[self sendRPCRequestPrivate:(SDLRPCRequest *)msg];
Expand Down
19 changes: 8 additions & 11 deletions sdl_ios/SmartDeviceLink/SDLRPCMessageType.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,12 @@
// Copyright (c) 2014 Ford Motor Company. All rights reserved.

#import <Foundation/Foundation.h>
#import <SmartDeviceLink/SDLEnum.h>

@interface SDLRPCMessageType : SDLEnum {}

+(SDLRPCMessageType*) valueOf:(NSString*) value;
+(NSMutableArray*) values;

+(SDLRPCMessageType*) request;
+(SDLRPCMessageType*) response;
+(SDLRPCMessageType*) notification;

@end
/**
* Enumeration linking message types with function types.
*/
typedef NS_ENUM(Byte, SDLRPCMessageType){
SDLRPCMessageTypeRequest = 0,
SDLRPCMessageTypeResponse,
SDLRPCMessageTypeNotification
};
49 changes: 0 additions & 49 deletions sdl_ios/SmartDeviceLink/SDLRPCMessageType.m
Original file line number Diff line number Diff line change
Expand Up @@ -4,52 +4,3 @@

#import <SmartDeviceLink/SDLRPCMessageType.h>

SDLRPCMessageType* SDLRPCMessageType_request = nil;
SDLRPCMessageType* SDLRPCMessageType_response = nil;
SDLRPCMessageType* SDLRPCMessageType_notification = nil;

NSMutableArray* SDLRPCMessageType_values = nil;
@implementation SDLRPCMessageType

+(SDLRPCMessageType*) valueOf:(NSString*) value {
for (SDLRPCMessageType* item in SDLRPCMessageType.values) {
if ([item.value isEqualToString:value]) {
return item;
}
}
return nil;
}

+(NSMutableArray*) values {
if (SDLRPCMessageType_values == nil) {
SDLRPCMessageType_values = [[NSMutableArray alloc] initWithObjects:
SDLRPCMessageType_request,
SDLRPCMessageType_response,
SDLRPCMessageType_notification,
nil];
}
return SDLRPCMessageType_values;
}

+(SDLRPCMessageType*) request {
if (SDLRPCMessageType_request == nil) {
SDLRPCMessageType_request = [[SDLRPCMessageType alloc] initWithValue:@"request"];
}
return SDLRPCMessageType_request;
}

+(SDLRPCMessageType*) response {
if (SDLRPCMessageType_response == nil) {
SDLRPCMessageType_response = [[SDLRPCMessageType alloc] initWithValue:@"response"];
}
return SDLRPCMessageType_response;
}

+(SDLRPCMessageType*) notification {
if (SDLRPCMessageType_notification == nil) {
SDLRPCMessageType_notification = [[SDLRPCMessageType alloc] initWithValue:@"notification"];
}
return SDLRPCMessageType_notification;
}

@end
3 changes: 2 additions & 1 deletion sdl_ios/SmartDeviceLink/SDLRPCPayload.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@
// Copyright (c) 2014 Ford Motor Company. All rights reserved.

#import <Foundation/Foundation.h>
#import <SmartDeviceLink/SDLRPCMessageType.h>

@interface SDLRPCPayload : NSObject

@property (assign) Byte rpcType;
@property (assign) SDLRPCMessageType rpcType;
@property (assign) UInt32 functionID;
@property (assign) UInt32 correlationID;
@property (strong) NSData *jsonData;
Expand Down

0 comments on commit d99c952

Please sign in to comment.