Skip to content

Commit f03db6d

Browse files
committed
Resolve merge conflicts
2 parents cb10518 + 04515a5 commit f03db6d

12 files changed

Lines changed: 455 additions & 457 deletions

File tree

Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
/*
2+
* Copyright (c) 2019, Livio, Inc.
3+
* All rights reserved.
4+
*
5+
* Redistribution and use in source and binary forms, with or without
6+
* modification, are permitted provided that the following conditions are met:
7+
*
8+
* Redistributions of source code must retain the above copyright notice, this
9+
* list of conditions and the following disclaimer.
10+
*
11+
* Redistributions in binary form must reproduce the above copyright notice,
12+
* this list of conditions and the following
13+
* disclaimer in the documentation and/or other materials provided with the
14+
* distribution.
15+
*
16+
* Neither the name of the Livio Inc. nor the names of its contributors
17+
* may be used to endorse or promote products derived from this software
18+
* without specific prior written permission.
19+
*
20+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
24+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30+
* POSSIBILITY OF SUCH DAMAGE.
31+
*/
32+
33+
const fs = require('fs');
34+
const SDL = require('../../../lib/node/dist/index.js');
35+
const CONFIG = require('./config.js');
36+
37+
class AppClient {
38+
constructor (wsClient) {
39+
this._appConfig = new SDL.manager.AppConfig()
40+
.setAppId(CONFIG.appId)
41+
.setAppName(CONFIG.appName)
42+
.setIsMediaApp(false)
43+
.setLanguageDesired(SDL.rpc.enums.Language.EN_US)
44+
.setHmiDisplayLanguageDesired(SDL.rpc.enums.Language.EN_US)
45+
.setAppTypes([
46+
SDL.rpc.enums.AppHMIType.DEFAULT,
47+
])
48+
.setTransportConfig(
49+
new SDL.transport.WebSocketServerConfig(
50+
wsClient,
51+
CONFIG.connectionLostTimeout
52+
)
53+
);
54+
55+
const listener = new SDL.manager.lifecycle.LifecycleListener();
56+
listener.setOnProxyConnected((manager) => {
57+
this._onConnected();
58+
});
59+
listener.setOnProxyClosed((lifecycleManager, info, reason) => {});
60+
listener.setOnServiceStarted((serviceType, sessionId, correlationId) => {});
61+
listener.setOnServiceEnded((serviceType) => {});
62+
listener.setOnError((lifecycleManager, info) => {});
63+
64+
this._manager = new SDL.manager.lifecycle.LifecycleManager(this._appConfig, listener);
65+
66+
const hmiFullListener = new SDL.rpc.RpcListener().setOnRpcMessage(this._onHmiStatusListener.bind(this));
67+
68+
this._manager.addRpcListener(SDL.rpc.enums.FunctionID.OnHMIStatus, hmiFullListener);
69+
}
70+
71+
start () {
72+
this._manager.start();
73+
}
74+
75+
async _onConnected () {
76+
// app starts in the NONE state
77+
const fileBinary = await _fetchImageUnit8Array('./test_icon_1.png');
78+
const fileName = `${this._appConfig.getAppId()}_icon.gif`;
79+
80+
const putFile = new SDL.rpc.messages.PutFile()
81+
.setFileName(fileName)
82+
.setFileType('GRAPHIC_PNG')
83+
.setPersistentFile(true)
84+
.setFileData(fileBinary);
85+
86+
await this._asyncSendRpc(putFile);
87+
88+
const setAppIcon = new SDL.rpc.messages.SetAppIcon()
89+
.setFileName(fileName);
90+
91+
await this._asyncSendRpc(setAppIcon);
92+
}
93+
94+
async _onHmiStatusListener (onHmiStatus) {
95+
const hmiLevel = onHmiStatus.getHmiLevel();
96+
97+
// wait for the FULL state for more functionality
98+
if (hmiLevel === SDL.rpc.enums.HMILevel.HMI_FULL) {
99+
const show = new SDL.rpc.messages.Show();
100+
show.setMainField1('Hello')
101+
.setMainField2('こんにちは')
102+
.setMainField3('你好');
103+
104+
await this._asyncSendRpc(show);
105+
106+
await this._sleep(2000);
107+
108+
const count = 3;
109+
for (let i = 0; i < count; i++) {
110+
const showCountdown = new SDL.rpc.messages.Show();
111+
showCountdown.setMainField1(`Exiting in ${(count - i).toString()}`)
112+
.setMainField2('')
113+
.setMainField3('');
114+
115+
this._asyncSendRpc(showCountdown); // don't wait for a response
116+
117+
await this._sleep();
118+
}
119+
120+
// tear down the app
121+
await this._asyncSendRpc(new SDL.rpc.messages.UnregisterAppInterface());
122+
123+
this._manager.stop();
124+
}
125+
}
126+
127+
async _sleep (timeout = 1000) {
128+
return new Promise((resolve) => {
129+
setTimeout(resolve, timeout);
130+
});
131+
}
132+
133+
// TODO: this should go into some manager class
134+
// abstracts out the work of sending the RPC and attaching listeners to wait for a response
135+
_asyncSendRpc (request, timeout = 5000) {
136+
return new Promise((resolve, reject) => {
137+
const functionId = SDL.rpc.enums.FunctionID.valueForKey(request.getFunctionName()); // this is the number value
138+
let correlationIdRequest;
139+
let listener;
140+
141+
listener = new SDL.rpc.RpcListener().setOnRpcMessage(rpcMessage => {
142+
const correlationIdResponse = rpcMessage.getCorrelationId();
143+
// ensure the correlation ids match
144+
if (correlationIdRequest === correlationIdResponse) {
145+
// remove the listener once the correct response is received
146+
this._manager.removeRpcListener(functionId, listener);
147+
resolve(rpcMessage);
148+
}
149+
});
150+
151+
this._manager.addRpcListener(functionId, listener);
152+
this._manager.sendRpcMessage(request); // the request will get a correlation id after this method
153+
154+
correlationIdRequest = request.getCorrelationId();
155+
156+
setTimeout(() => {
157+
reject(new Error(`Response timeout for ${request.getFunctionName()}`));
158+
}, timeout); // timeout after so long of not getting a response
159+
});
160+
}
161+
}
162+
163+
async function _fetchImageUnit8Array (path) {
164+
const aryBuffer = fs.readFileSync(path, null);
165+
return new Uint8Array(aryBuffer);
166+
}
167+
168+
module.exports = AppClient;

examples/node/hello-sdl/config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,5 @@ module.exports = {
3434
appId: 'hello-node',
3535
appName: 'hello-node',
3636
port: process.env.APP_PORT || 3005,
37+
connectionLostTimeout: !isNaN(parseInt(process.env.CONNECTION_LOST_TIMEOUT)) ? parseInt(process.env.CONNECTION_LOST_TIMEOUT) : 10000,
3738
};

examples/node/hello-sdl/index.js

Lines changed: 14 additions & 132 deletions
Original file line numberDiff line numberDiff line change
@@ -33,135 +33,17 @@
3333
const fs = require('fs');
3434
const SDL = require('../../../lib/node/dist/index.js');
3535
const CONFIG = require('./config.js');
36-
37-
class HelloSdl {
38-
constructor () {
39-
this._appConfig = new SDL.manager.AppConfig()
40-
.setAppId(CONFIG.appId)
41-
.setAppName(CONFIG.appName)
42-
.setIsMediaApp(false)
43-
.setLanguageDesired(SDL.rpc.enums.Language.EN_US)
44-
.setHmiDisplayLanguageDesired(SDL.rpc.enums.Language.EN_US)
45-
.setAppTypes([
46-
SDL.rpc.enums.AppHMIType.DEFAULT,
47-
])
48-
.setTransportConfig(new SDL.transport.WebSocketServerConfig(
49-
CONFIG.port
50-
));
51-
52-
const listener = new SDL.manager.lifecycle.LifecycleListener();
53-
listener.setOnProxyConnected((manager) => {
54-
this._onConnected();
55-
});
56-
listener.setOnProxyClosed((lifecycleManager, info, reason) => {});
57-
listener.setOnServiceStarted((serviceType, sessionId, correlationId) => {});
58-
listener.setOnServiceEnded((serviceType) => {});
59-
listener.setOnError((lifecycleManager, info) => {});
60-
61-
this._manager = new SDL.manager.lifecycle.LifecycleManager(this._appConfig, listener);
62-
63-
const hmiFullListener = new SDL.rpc.RpcListener().setOnRpcMessage(this._onHmiStatusListener.bind(this));
64-
65-
this._manager.addRpcListener(SDL.rpc.enums.FunctionID.OnHMIStatus, hmiFullListener);
66-
}
67-
68-
start () {
69-
this._manager.start();
70-
}
71-
72-
async _onConnected () {
73-
// app starts in the NONE state
74-
const fileBinary = await _fetchImageUnit8Array('./test_icon_1.png');
75-
const fileName = `${this._appConfig.getAppId()}_icon.gif`;
76-
77-
const putFile = new SDL.rpc.messages.PutFile()
78-
.setFileName(fileName)
79-
.setFileType('GRAPHIC_PNG')
80-
.setPersistentFile(true)
81-
.setFileData(fileBinary);
82-
83-
await this._asyncSendRpc(putFile);
84-
85-
const setAppIcon = new SDL.rpc.messages.SetAppIcon()
86-
.setFileName(fileName);
87-
88-
await this._asyncSendRpc(setAppIcon);
89-
}
90-
91-
async _onHmiStatusListener (onHmiStatus) {
92-
const hmiLevel = onHmiStatus.getHmiLevel();
93-
94-
// wait for the FULL state for more functionality
95-
if (hmiLevel === SDL.rpc.enums.HMILevel.HMI_FULL) {
96-
const show = new SDL.rpc.messages.Show();
97-
show.setMainField1('Hello')
98-
.setMainField2('こんにちは')
99-
.setMainField3('你好');
100-
101-
await this._asyncSendRpc(show);
102-
103-
await this._sleep(2000);
104-
105-
const count = 3;
106-
for (let i = 0; i < count; i++) {
107-
const showCountdown = new SDL.rpc.messages.Show();
108-
showCountdown.setMainField1(`Exiting in ${(count - i).toString()}`)
109-
.setMainField2('')
110-
.setMainField3('');
111-
112-
this._asyncSendRpc(showCountdown); // don't wait for a response
113-
114-
await this._sleep();
115-
}
116-
117-
// tear down the app
118-
await this._asyncSendRpc(new SDL.rpc.messages.UnregisterAppInterface());
119-
120-
this._manager.stop();
121-
}
122-
}
123-
124-
async _sleep (timeout = 1000) {
125-
return new Promise((resolve) => {
126-
setTimeout(resolve, timeout);
127-
});
128-
}
129-
130-
// TODO: this should go into some manager class
131-
// abstracts out the work of sending the RPC and attaching listeners to wait for a response
132-
_asyncSendRpc (request, timeout = 5000) {
133-
return new Promise((resolve, reject) => {
134-
const functionId = SDL.rpc.enums.FunctionID.valueForKey(request.getFunctionName()); // this is the number value
135-
let correlationIdRequest;
136-
let listener;
137-
138-
listener = new SDL.rpc.RpcListener().setOnRpcMessage(rpcMessage => {
139-
const correlationIdResponse = rpcMessage.getCorrelationId();
140-
// ensure the correlation ids match
141-
if (correlationIdRequest === correlationIdResponse) {
142-
// remove the listener once the correct response is received
143-
this._manager.removeRpcListener(functionId, listener);
144-
resolve(rpcMessage);
145-
}
146-
});
147-
148-
this._manager.addRpcListener(functionId, listener);
149-
this._manager.sendRpcMessage(request); // the request will get a correlation id after this method
150-
151-
correlationIdRequest = request.getCorrelationId();
152-
153-
setTimeout(() => {
154-
reject(new Error(`Response timeout for ${request.getFunctionName()}`));
155-
}, timeout); // timeout after so long of not getting a response
156-
});
157-
}
158-
}
159-
160-
async function _fetchImageUnit8Array (path) {
161-
const aryBuffer = fs.readFileSync(path, null);
162-
return new Uint8Array(aryBuffer);
163-
}
164-
165-
console.log('start app');
166-
const app = new HelloSdl();
167-
app.start();
36+
const WS = require('ws');
37+
const AppClient = require('./AppClient.js');
38+
39+
// create a WebSocket Server
40+
const appWebSocketServer = new WS.Server({
41+
port: CONFIG.port,
42+
});
43+
console.log(`WebSocket Server listening on port ${CONFIG.port}`);
44+
45+
// Event listener for incoming WebSocket connections
46+
appWebSocketServer.on('connection', (connection) => {
47+
console.log('connection established');
48+
new AppClient(connection).start();
49+
});

lib/js/dist/SDL.js

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/js/src/protocol/MessageFrameDisassembler.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ class MessageFrameDisassembler {
8181
*/
8282
static buildRPC (rpcRequest, sessionId, messageId, mtu, version, isEncrypted, cb) {
8383
const obj = new MessageFrameDisassembler(rpcRequest, sessionId, messageId, mtu, version, isEncrypted, cb);
84-
obj.doRequest();
84+
obj._doRequest();
8585
return obj;
8686
}
8787

@@ -128,8 +128,9 @@ class MessageFrameDisassembler {
128128
/**
129129
* Start the RPC request and use callback to send
130130
* sdl packets of the appropriate size.
131+
* @private
131132
*/
132-
doRequest () {
133+
_doRequest () {
133134
const version = this._version;
134135
const frameInfo = 0;
135136
const frameType = FrameType.SINGLE;

0 commit comments

Comments
 (0)