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

[SDL-0293] Enable OEM exclusive apps support #374

Merged
5 changes: 5 additions & 0 deletions lib/js/src/manager/SdlManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,11 @@ class SdlManager extends _SdlManagerBase {
}

this._lifecycleManager = new _LifecycleManager(this._lifecycleConfig, this._lifecycleListener);
if (this._managerListener) {
this._lifecycleManager.setOnSystemInfoReceived(
this._managerListener.onSystemInfoReceived.bind(this._managerListener)
);
}

/* FIXME: setSdlSecurity and related methods/classes do not exist
if (this._sdlSecList.length > 0) {
Expand Down
23 changes: 23 additions & 0 deletions lib/js/src/manager/SdlManagerListener.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ class SdlManagerListener {
this._managerShouldUpdateLifecycle = (language) => {
return null;
};
this._onSystemInfoReceived = null;
}

/**
Expand Down Expand Up @@ -126,6 +127,28 @@ class SdlManagerListener {
}
return null;
}

/**
* Set the onSystemInfoReceived function.
* @param {function} listener - A function to be invoked when the event occurs.
* @returns {SdlManagerListener} - A reference to this instance to allow method chaining.
*/
setOnSystemInfoReceived (listener) {
this._onSystemInfoReceived = listener;
return this;
}

/**
* Safely attempts to invoke the onSystemInfoReceived event.
* @param {SystemInfo} systemInfo - the system info of vehicle that this session is currently active on.
* @returns {Boolean} Return true if this session should continue, false if the session should end
*/
onSystemInfoReceived (systemInfo) {
if (typeof this._onSystemInfoReceived === 'function') {
return !!this._onSystemInfoReceived(systemInfo);
}
return true;
}
}

export { SdlManagerListener };
2 changes: 1 addition & 1 deletion lib/js/src/manager/_SdlManagerBase.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class _SdlManagerBase {
* @class
* @private
* @param {AppConfig} appConfig - An instance of AppConfig describing the application's metadata and desired transport
* @param {ManagerListener} managerListener - An instance of ManagerListener to be used to listen for manager events
* @param {SdlManagerListener} managerListener - An instance of ManagerListener to be used to listen for manager events
*/
constructor (appConfig = null, managerListener = null) {
this._state = -1;
Expand Down
51 changes: 50 additions & 1 deletion lib/js/src/manager/lifecycle/_LifecycleManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ import { _ArrayTools } from '../../util/_ArrayTools.js';
import { SdlMsgVersion } from '../../rpc/structs/SdlMsgVersion.js';
import { FunctionID } from '../../rpc/enums/FunctionID.js';
import { _ServiceType } from '../../protocol/enums/_ServiceType.js';
import { SystemInfo } from '../../util/SystemInfo.js';

/**
* This class should also be marked private and behind the SdlManager API
Expand Down Expand Up @@ -90,6 +91,8 @@ class _LifecycleManager {
this._systemCapabilityManager = new SystemCapabilityManager(this);
this._encryptionLifecycleManager = null;
this._registerAppInterfaceResponse = null;

this._didCheckSystemInfo = false;
}

/**
Expand All @@ -99,14 +102,23 @@ class _LifecycleManager {
*/
_createSessionListener () {
const sessionListener = new _SdlSessionListener();
sessionListener.setOnProtocolSessionStarted((serviceType, sessionID, version, correlationID, hashID, isEncrypted) => {
sessionListener.setOnProtocolSessionStarted((serviceType, sessionID, version, correlationID, hashID, isEncrypted, systemInfo) => {
// Session has been started
if (this._minimumProtocolVersion !== null && this._minimumProtocolVersion.isNewerThan(this.getProtocolVersion()) === 1) {
console.warn(`Disconnecting from head unit, the configured minimum protocol version ${this._minimumProtocolVersion} is greater than the supported protocol version ${this.getProtocolVersion()}`);
this._sdlSession.endService(serviceType, this._sdlSession.getSessionId());
return this._cleanProxy();
}

if (systemInfo && !this._didCheckSystemInfo) {
this._didCheckSystemInfo = true;
if (!this.onSystemInfoReceived(systemInfo)) {
console.warn('Disconnecting from head unit, the system info was not accepted.');
this._sdlSession.endService(serviceType, this._sdlSession.getSessionId());
return this._cleanProxy();
}
}

if (serviceType === _ServiceType.RPC) {
if (this._lifecycleConfig !== null && this._lifecycleConfig !== undefined) {
this.sendRpcResolve(this._createRegisterAppInterface());
Expand Down Expand Up @@ -406,6 +418,28 @@ class _LifecycleManager {
return registerAppInterface;
}

/**
* Set the onSystemInfoReceived function.
* @param {function} listener - A function to be invoked when the event occurs.
* @returns {_LifecycleManager} - A reference to this instance to allow method chaining.
*/
setOnSystemInfoReceived (listener) {
this._onSystemInfoReceived = listener;
return this;
}

/**
* Safely attempts to invoke the onSystemInfoReceived event.
* @param {SystemInfo} systemInfo - the system info of vehicle that this session is currently active on.
* @returns {Boolean} Return true if this session should continue, false if the session should end
*/
onSystemInfoReceived (systemInfo) {
if (typeof this._onSystemInfoReceived === 'function') {
return !!this._onSystemInfoReceived(systemInfo);
}
return true;
}


/* *******************************************************************************************************
********************************** INTERNAL - RPC LISTENERS !! START !! *********************************
Expand Down Expand Up @@ -484,6 +518,21 @@ class _LifecycleManager {
this._cleanProxy();
}

if (!this._didCheckSystemInfo) {
this._didCheckSystemInfo = true;
const vehicleType = registerAppInterfaceResponse.getVehicleType();
const systemSoftwareVersion = registerAppInterfaceResponse.getSystemSoftwareVersion();
let systemInfo = null;
if (vehicleType || systemSoftwareVersion) {
systemInfo = new SystemInfo(vehicleType, systemSoftwareVersion);
}
if (systemInfo && !this.onSystemInfoReceived(systemInfo)) {
console.warn('Disconnecting from head unit, the system info was not accepted.');
this.sendRpcResolve(new UnregisterAppInterface());
this._cleanProxy();
}
}

// parse RAI for system capabilities
this._systemCapabilityManager._parseRaiResponse(registerAppInterfaceResponse);
}
Expand Down
8 changes: 4 additions & 4 deletions lib/js/src/protocol/_SdlProtocolBase.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,10 @@ import { _FrameType } from './enums/_FrameType.js';
import { _MessageFrameAssembler } from './_MessageFrameAssembler.js';
import { _SdlPacket } from './_SdlPacket.js';
import { _ControlFrameTags } from './enums/_ControlFrameTags.js';
import { _BitConverter } from './../util/_BitConverter.js';
import { _BitConverter } from '../util/_BitConverter.js';

Choose a reason for hiding this comment

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

@ymalovanyi @vladmu Do you need unit tests for this? For example, sdl java suite has SdlProtocolTests

Copy link
Contributor

Choose a reason for hiding this comment

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

@santhanamk we don't need the test for this particular line as this is just a shortenest path identical to previous but aligned with the style of other imports.

Choose a reason for hiding this comment

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

@vladmu I meant do you need unit tests overall for the changes made to this file?

Copy link
Contributor

Choose a reason for hiding this comment

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

@santhanamk it is hard to define expectations of such tests in the order of the library and this class as we don't have any tests of previous functionality covered here. We appreciate any help in this case.

Choose a reason for hiding this comment

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

@vladmu Ok no problem. It was an optional request, as these were not existing before.


import { _SdlPacketFactory } from './_SdlPacketFactory.js';
import { RpcCreator } from './../rpc/RpcCreator.js';
import { RpcCreator } from '../rpc/RpcCreator.js';
import { ImageResolution } from '../rpc/structs/ImageResolution.js';
import { VideoStreamingFormat } from '../rpc/structs/VideoStreamingFormat.js';

Expand Down Expand Up @@ -462,7 +462,7 @@ class _SdlProtocolBase {
}

this._sdlProtocolListener.onProtocolSessionStarted(serviceType,
sdlPacket.getSessionID(), this._protocolVersion.getMajor(), '', this._hashID, sdlPacket.getEncryption());
sdlPacket.getSessionID(), this._protocolVersion.getMajor(), '', this._hashID, sdlPacket.getEncryption(), sdlPacket);
}

/**
Expand Down Expand Up @@ -588,6 +588,6 @@ _SdlProtocolBase.V3_V4_MTU_SIZE = 131072;
/**
* Max supported protocol version in this release of the library
*/
_SdlProtocolBase.MAX_PROTOCOL_VERSION = new Version(5, 3, 0);
_SdlProtocolBase.MAX_PROTOCOL_VERSION = new Version(5, 4, 0);

export { _SdlProtocolBase };
13 changes: 7 additions & 6 deletions lib/js/src/protocol/_SdlProtocolListener.js
Original file line number Diff line number Diff line change
Expand Up @@ -112,16 +112,17 @@ class _SdlProtocolListener {

/**
* Safely attempts to invoke the event listener.
* @param {ServiceType} serviceType - A ServiceType enum value.
* @param {_ServiceType} serviceType - A ServiceType enum value.
* @param {Number} sessionId - A session ID.
* @param {Number} version - A numeric version.
* @param {String} correlationId - A correlation ID.
* @param {Number} hashId - A hash ID.
* @param {Boolean} isEncrypted - Whether or not it is encrypted.
* @param {_SdlPacket} sdlPacket - An _SdlPacket.
*/
onProtocolSessionStarted (serviceType, sessionId, version, correlationId, hashId, isEncrypted) {
onProtocolSessionStarted (serviceType, sessionId, version, correlationId, hashId, isEncrypted, sdlPacket) {
if (typeof this._onProtocolSessionStarted === 'function') {
this._onProtocolSessionStarted(serviceType, sessionId, version, correlationId, hashId, isEncrypted);
this._onProtocolSessionStarted(serviceType, sessionId, version, correlationId, hashId, isEncrypted, sdlPacket);
}
}

Expand All @@ -137,7 +138,7 @@ class _SdlProtocolListener {

/**
* Safely attempts to invoke the event listener.
* @param {ServiceType} serviceType - A ServiceType enum value.
* @param {_ServiceType} serviceType - A ServiceType enum value.
* @param {Number} sessionId - A Session ID.
* @param {String} correlationId - A correlation ID.
*/
Expand All @@ -159,7 +160,7 @@ class _SdlProtocolListener {

/**
* Safely attempts to invoke the event listener.
* @param {ServiceType} serviceType - A ServiceType enum value.
* @param {_ServiceType} serviceType - A ServiceType enum value.
* @param {Number} sessionId - A Session ID.
* @param {String} correlationId - A correlation ID.
*/
Expand Down Expand Up @@ -254,4 +255,4 @@ class _SdlProtocolListener {
}
}

export { _SdlProtocolListener };
export { _SdlProtocolListener };
14 changes: 13 additions & 1 deletion lib/js/src/protocol/enums/_ControlFrameTags.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,18 @@ _ControlFrameTags.RPC = Object.freeze({
VIDEO_SERVICE_TRANSPORTS: 'videoServiceTransports',
/** Auth token to be used for log in into services **/
AUTH_TOKEN: 'authToken',
/**
* Vehicle info to describe connected device
*/
MAKE: 'make',
MODEL: 'model',
MODEL_YEAR: 'modelYear',
TRIM: 'trim',
/**
* System specifics for hardware and software versions of connected device
*/
SYSTEM_SOFTWARE_VERSION: 'systemSoftwareVersion',
SYSTEM_HARDWARE_VERSION: 'systemHardwareVersion',
}, StartServiceACKBase, StartServiceProtocolVersion, StartServiceHashId),

StartServiceNAK: NAKBase,
Expand Down Expand Up @@ -128,4 +140,4 @@ _ControlFrameTags.Video = Object.freeze({
EndServiceNAK: NAKBase,
});

export { _ControlFrameTags };
export { _ControlFrameTags };
4 changes: 3 additions & 1 deletion lib/js/src/rpc/messages/RegisterAppInterfaceResponse.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* eslint-disable camelcase */
/*
* Copyright (c) 2020, SmartDeviceLink Consortium, Inc.
* Copyright (c) 2021, SmartDeviceLink Consortium, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
Expand Down Expand Up @@ -334,6 +334,7 @@ class RegisterAppInterfaceResponse extends RpcResponse {
/**
* Set the VehicleType
* @since SmartDeviceLink 2.0.0
* @deprecated in SmartDeviceLink 7.1.0
* @param {VehicleType} type - Specifies the vehicle's type. See VehicleType. - The desired VehicleType.
* @returns {RegisterAppInterfaceResponse} - The class instance for method chaining.
*/
Expand Down Expand Up @@ -414,6 +415,7 @@ class RegisterAppInterfaceResponse extends RpcResponse {
/**
* Set the SystemSoftwareVersion
* @since SmartDeviceLink 3.0.0
* @deprecated in SmartDeviceLink 7.1.0
* @param {String} version - The software version of the system that implements the SmartDeviceLink core. - The desired SystemSoftwareVersion.
* {'string_min_length': 1, 'string_max_length': 100}
* @returns {RegisterAppInterfaceResponse} - The class instance for method chaining.
Expand Down
46 changes: 43 additions & 3 deletions lib/js/src/session/_SdlSession.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ import { _SdlProtocol } from '../protocol/_SdlProtocol.js';
import { _ServiceType } from '../protocol/enums/_ServiceType.js';
import { _ServiceListenerMap } from './_ServiceListenerMap.js';
import { _VideoStreamingParameters } from '../streaming/video/_VideoStreamingParameters.js';
import { _ControlFrameTags } from '../protocol/enums/_ControlFrameTags.js';
import { VehicleType } from '../rpc/structs/VehicleType.js';
import { SystemInfo } from '../util/SystemInfo.js';
import { Version } from '../util/Version.js';


/**
Expand Down Expand Up @@ -84,6 +88,36 @@ class _SdlSession {
return sdlProtocolListener;
}

/**
* Extracts the SystemInfo out of a packet
* @param {_SdlPacket} sdlPacket - should be a StartServiceACK for the RPC service.
* @returns {SystemInfo|null} - an instance of SystemInfo if the information is available, null otherwise.
*/
_extractSystemInfo (sdlPacket) {
const make = sdlPacket.getTag(_ControlFrameTags.RPC.StartServiceACK.MAKE);
const model = sdlPacket.getTag(_ControlFrameTags.RPC.StartServiceACK.MODEL);
const modelYear = sdlPacket.getTag(_ControlFrameTags.RPC.StartServiceACK.MODEL_YEAR);
const trim = sdlPacket.getTag(_ControlFrameTags.RPC.StartServiceACK.TRIM);

const systemHardwareVersion = sdlPacket.getTag(_ControlFrameTags.RPC.StartServiceACK.SYSTEM_HARDWARE_VERSION);
const systemSoftwareVersion = sdlPacket.getTag(_ControlFrameTags.RPC.StartServiceACK.SYSTEM_SOFTWARE_VERSION);

let vehicleType = null;
if (make || model || modelYear || trim) {
vehicleType = new VehicleType({
make,
model,
modelYear,
trim,
});
}
if (!vehicleType && !systemSoftwareVersion && !systemHardwareVersion) {
return null;
}

return new SystemInfo(vehicleType, systemSoftwareVersion, systemHardwareVersion);
}

/**
* Starts up the SDL protocol class. It will kick off the transport manager and underlying transport.
*/
Expand Down Expand Up @@ -118,15 +152,21 @@ class _SdlSession {
* @param {String} correlationId - A correlationID.
* @param {Number} hashId - A hash ID.
* @param {Boolean} isEncrypted - Whether or not it is encrypted.
* @param {_SdlPacket} sdlPacket - An _SdlPacket.
*/
onProtocolSessionStarted (serviceType, sessionId, version, correlationId, hashId, isEncrypted) {
onProtocolSessionStarted (serviceType, sessionId, version, correlationId, hashId, isEncrypted, sdlPacket) {
this._sessionId = sessionId;

if (serviceType === _ServiceType.RPC) {
this._sessionHashId = hashId;
}

this._sdlSessionListener.onProtocolSessionStarted(serviceType, sessionId, version, correlationId, hashId, isEncrypted);
let systemInfo = null;
if (version && (this.getProtocolVersion().isNewerThan(new Version(5, 4, 0)) >= 0)) {
systemInfo = this._extractSystemInfo(sdlPacket);
}

this._sdlSessionListener.onProtocolSessionStarted(serviceType, sessionId, version, correlationId, hashId, isEncrypted, systemInfo);
this._serviceListeners.sendEventServiceStarted(this, serviceType, isEncrypted);
}

Expand Down Expand Up @@ -324,4 +364,4 @@ class _SdlSession {
}
}

export { _SdlSession };
export { _SdlSession };
13 changes: 7 additions & 6 deletions lib/js/src/session/_SdlSessionListener.js
Original file line number Diff line number Diff line change
Expand Up @@ -101,22 +101,23 @@ class _SdlSessionListener {

/**
* Safely attempts to invoke the onProtocolSessionStarted event.
* @param {ServiceType} serviceType - The ServiceType.
* @param {_ServiceType} serviceType - The ServiceType.
* @param {Number} sessionID - represents a byte
* @param {Number} version - represents a byte
* @param {String} correlationID - The correlationID.
* @param {Number} hashID - The hash ID.
* @param {Boolean} isEncrypted - Whether or not it is encrypted.
* @param {SystemInfo} systemInfo - the system info of vehicle that this session is currently active on.
*/
onProtocolSessionStarted (serviceType, sessionID, version, correlationID, hashID, isEncrypted) {
onProtocolSessionStarted (serviceType, sessionID, version, correlationID, hashID, isEncrypted, systemInfo) {
if (typeof this._onProtocolSessionStarted === 'function') {
this._onProtocolSessionStarted(serviceType, sessionID, version, correlationID, hashID, isEncrypted);
this._onProtocolSessionStarted(serviceType, sessionID, version, correlationID, hashID, isEncrypted, systemInfo);
}
}

/**
* Safely attempts to invoke the onProtocolSessionEnded event.
* @param {ServiceType} serviceType - The ServiceType.
* @param {_ServiceType} serviceType - The ServiceType.
* @param {Number} sessionID - represents a byte
* @param {String} correlationID - The correlationID.
*/
Expand All @@ -128,7 +129,7 @@ class _SdlSessionListener {

/**
* Safely attempts to invoke the onProtocolSessionEndedNACKed event.
* @param {ServiceType} serviceType - The ServiceType.
* @param {_ServiceType} serviceType - The ServiceType.
* @param {Number} sessionID - represents a byte
* @param {String} correlationID - The correlationID.
*/
Expand Down Expand Up @@ -179,4 +180,4 @@ class _SdlSessionListener {
}
}

export { _SdlSessionListener };
export { _SdlSessionListener };
Loading