Skip to content

Commit 690fa3c

Browse files
authored
Merge pull request #17 from webos-tools/develop
[Release 3.1.3] Add native_service for apollo, fixbug ares-setup-device device name with "-"
2 parents b5f61f1 + 06ab434 commit 690fa3c

File tree

10 files changed

+330
-9
lines changed

10 files changed

+330
-9
lines changed

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
## 3.1.3 (October 14, 2024)
2+
### ares-generate
3+
* Added "native_service" template for apollo platform.
4+
5+
### ares-setup-device
6+
* Fixed a bug that device name can not be added with "-".
7+
18

29
## 3.1.2 (August 07, 2024)
310
### ares-config

bin/ares-setup-device.js

Lines changed: 52 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
const async = require('async'),
1010
inquirer = require('inquirer'),
1111
nopt = require('nopt'),
12+
abbrev = require("abbrev"),
1213
log = require('npmlog'),
1314
path = require('path'),
1415
Ssdp = require('ssdp-js'),
@@ -66,7 +67,7 @@ const shortHands = {
6667
"R": ["--reset"]
6768
};
6869

69-
const argv = nopt(knownOpts, shortHands, process.argv, 2 /* drop 'node' & 'ares-*.js'*/);
70+
const argv = getArgv();
7071

7172
log.heading = processName;
7273
log.level = argv.level || 'warn';
@@ -186,7 +187,7 @@ function _queryAddRemove(ssdpDevices, next) {
186187
if (ssdpDevice) {
187188
if (ssdpDevice.op === 'modify') return inqChoices;
188189
else return ['add'];
189-
}
190+
}
190191
if (deviceNames.length > 1) return totChoices;
191192
// deveice list has emulator only > unsupported remove option
192193
return inqChoices.concat(dfChoices);
@@ -261,7 +262,7 @@ function _queryDeviceInfo(selDevice, next) {
261262
const deviceName = selDevice.name,
262263
resolver = this.resolver || (this.resolver = new novacom.Resolver()),
263264
defaultDeviceInfo = appdata.getConfig(true).defaultDeviceInfo;
264-
265+
265266
questions = [{
266267
type: "input",
267268
name: "ip",
@@ -379,7 +380,7 @@ function _queryDeviceInfo(selDevice, next) {
379380
username: answers.user,
380381
default: answers.default
381382
};
382-
383+
383384
if (answers.user !== 'prisoner' && ["add", "modify"].includes(mode)) {
384385
if (answers.auth_type && answers.auth_type === "password") {
385386
inDevice.password = answers.password;
@@ -523,3 +524,50 @@ function finish(err, value) {
523524
cliControl.end();
524525
}
525526
}
527+
528+
function getArgv() {
529+
let argv = nopt(knownOpts, shortHands, process.argv, 2 /* drop 'node' & 'ares-*.js'*/);
530+
let mode = checkMode(argv);
531+
return (mode && argv[mode] === 'true') ? reParse(argv, mode) : argv;
532+
}
533+
534+
function checkMode(argv) {
535+
if (argv.add) return 'add';
536+
if (argv.modify) return 'modify';
537+
if (argv.remove) return 'remove';
538+
return (argv.default) ? 'default' : null;
539+
}
540+
541+
function reParse(argv, mode) {
542+
let nameIndex = -1;
543+
let cookedNameIndex = -1;
544+
let abbrevOpts = abbrev(Object.keys(knownOpts))
545+
546+
for (let i = 0; i < argv.argv.original.length; i++) {
547+
if (argv.argv.original[i].match(/^-{2,}$/)) {
548+
nameIndex = i;
549+
break;
550+
}
551+
}
552+
cookedNameIndex = argv.argv.cooked.indexOf('--');
553+
if (cookedNameIndex <= 0 || !argv.argv.cooked[cookedNameIndex - 1].match(/^-/) || abbrevOpts[argv.argv.cooked[cookedNameIndex - 1].replace(/^-+/, "")] != mode) {
554+
return argv;
555+
}
556+
557+
argv[mode] = argv.argv.original[nameIndex];
558+
if (nameIndex != -1 && cookedNameIndex != -1 && nameIndex + 1 < argv.argv.original.length) {
559+
const remainArgv = nopt(knownOpts, shortHands, argv.argv.original, nameIndex + 1);
560+
for (const option in remainArgv) {
561+
if (remainArgv.hasOwnProperty(option)) {
562+
if (!argv.hasOwnProperty(option)) {
563+
argv[option] = remainArgv[option];
564+
} else if (Array.isArray(argv[option])) {
565+
argv[option] = argv[option].concat(remainArgv[option]);
566+
}
567+
}
568+
}
569+
argv.argv.remain = remainArgv.argv.remain;
570+
argv.argv.cooked = argv.argv.cooked.splice(0, cookedNameIndex + 1).concat(remainArgv.argv.cooked);
571+
}
572+
return argv
573+
}

files/conf-base/template-conf/apollo-sdk-templates.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,11 @@
4343
],
4444
"description": "services.json, package.json for JS service"
4545
},
46+
"native_service": {
47+
"type": "nativeservice",
48+
"path": "$cli-root/files/templates/apollo-sdk-templates/native-service",
49+
"description": "native service for Apollo"
50+
},
4651
"icon": {
4752
"type": "icon",
4853
"path": "$cli-root/files/templates/apollo-sdk-templates/icon",
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
# Copyright (c) 2020-2024 LG Electronics, Inc.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
#
15+
# SPDX-License-Identifier: Apache-2.0
16+
17+
cmake_minimum_required(VERSION 2.8.7)
18+
project(nativeService C)
19+
20+
# set link directory
21+
#link_directories(${CMAKE_SOURCE_DIR}/pkg_$ENV{ARCH}/lib)
22+
23+
# ---
24+
# add include files
25+
include_directories(${CMAKE_SOURCE_DIR})
26+
include_directories(${CMAKE_SOURCE_DIR}/src)
27+
include_directories(${CMAKE_SOURCE_DIR}/include)
28+
29+
# ---
30+
# find required packages
31+
include(FindPkgConfig)
32+
33+
pkg_check_modules(GTHREAD2 REQUIRED gthread-2.0)
34+
include_directories(${GTHREAD2_INCLUDE_DIRS})
35+
36+
pkg_check_modules(PBNJSON REQUIRED pbnjson_c)
37+
include_directories(${PBNJSON_INCLUDE_DIRS})
38+
39+
# -- check for glib 2.0
40+
pkg_check_modules(GLIB2 REQUIRED glib-2.0)
41+
include_directories(${GLIB2_INCLUDE_DIRS})
42+
43+
pkg_check_modules(LS2 REQUIRED luna-service2)
44+
include_directories(${LS2_INCLUDE_DIRS})
45+
46+
pkg_check_modules(PMLOG REQUIRED PmLogLib)
47+
include_directories(${PMLOG_INCLUDE_DIRS})
48+
49+
# ---
50+
# create executable file
51+
set(BIN_NAME echo_service)
52+
53+
set(SRC_LIST
54+
${CMAKE_SOURCE_DIR}/src/main.c
55+
)
56+
57+
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/pkg_$ENV{OECORE_TARGET_ARCH}/")
58+
add_executable(${BIN_NAME} ${SRC_LIST})
59+
60+
# ignore shared library
61+
set(CMAKE_EXE_LINKER_FLAGS "-Wl,--allow-shlib-undefined")
62+
set_target_properties(${BIN_NAME} PROPERTIES LINKER_LANGUAGE C)
63+
64+
target_link_libraries (${BIN_NAME}
65+
${GTHREAD2_LDFLAGS}
66+
${PBNJSON_LDFLAGS}
67+
${LS2_LDFLAGS}
68+
${GLIB2_LDFLAGS}
69+
${PMLOG_LDFLAGS}
70+
)
71+
72+
file(COPY ${CMAKE_SOURCE_DIR}/services.json DESTINATION "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}")
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"id": "com.domain.app.service",
3+
"description": "Native echo service",
4+
"engine": "native",
5+
"executable": "echo_service",
6+
"services": [ {
7+
"name": "com.domain.app.service",
8+
"description": "Native echo service"
9+
}]
10+
}
11+
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
// Copyright (c) 2020-2024 LG Electronics, Inc.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
//
15+
// SPDX-License-Identifier: Apache-2.0
16+
17+
#include <stdlib.h>
18+
#include <string.h>
19+
#include <glib.h>
20+
#include <stdio.h>
21+
#include <glib-object.h>
22+
#include <luna-service2/lunaservice.h>
23+
#include <pbnjson.h>
24+
25+
// This service name
26+
#define SERVICE_NAME "SERVICE_ID"
27+
#define BUF_SIZE 64
28+
29+
// Main loop for aliving background service
30+
GMainLoop *gmainLoop;
31+
32+
LSHandle *sh = NULL;
33+
LSMessage *message;
34+
35+
// Declare of each method
36+
// All method format must be : bool function(LSHandle*, LSMessage*, void*)
37+
bool echo(LSHandle *sh, LSMessage *message, void *data);
38+
39+
LSMethod sampleMethods[] = {
40+
{"echo", echo}, // luna://SERVICE_ID/echo
41+
};
42+
43+
44+
/*
45+
* Define luna://SERVICE_ID/echo
46+
* - A method that always returns the same value
47+
*
48+
* +----------------------------+ +--------------------------------+
49+
* | APP_ID | | SERVICE_ID |
50+
* | Foreground Application | | Background Service |
51+
* +----------------------------+ +--------------------------------+
52+
* | |
53+
* | |
54+
* | 1. Request to luna://SERVICE_ID/echo |
55+
* | with parameters { input: "Hello, World!" } |
56+
* | |
57+
* | ---------------------------------------------------------------------> |
58+
* | |
59+
* | |
60+
* | 2. Response to APP_ID |
61+
* | with result '{ "echoMessage" : "Hello, World!" }' |
62+
* | |
63+
* | <--------------------------------------------------------------------- |
64+
* | |
65+
* \|/ \|/
66+
* ' '
67+
*/
68+
bool echo(LSHandle *sh, LSMessage *message, void *data)
69+
{
70+
LSError lserror;
71+
JSchemaInfo schemaInfo;
72+
jvalue_ref parsed = {0}, value = {0};
73+
jvalue_ref jobj = {0}, jreturnValue = {0};
74+
const char *input = NULL;
75+
char buf[BUF_SIZE] = {0, };
76+
77+
LSErrorInit(&lserror);
78+
79+
// Initialize schema
80+
jschema_info_init (&schemaInfo, jschema_all(), NULL, NULL);
81+
82+
// get message from LS2 and parsing to make object
83+
parsed = jdom_parse(j_cstr_to_buffer(LSMessageGetPayload(message)), DOMOPT_NOOPT, &schemaInfo);
84+
85+
if (jis_null(parsed)) {
86+
j_release(&parsed);
87+
return true;
88+
}
89+
90+
// Get value from payload.input
91+
value = jobject_get(parsed, j_cstr_to_buffer("input"));
92+
93+
// JSON Object to string without schema validation check
94+
input = jvalue_tostring_simple(value);
95+
96+
/**
97+
* JSON create test
98+
*/
99+
jobj = jobject_create();
100+
if (jis_null(jobj)) {
101+
j_release(&jobj);
102+
return true;
103+
}
104+
105+
jreturnValue = jboolean_create(TRUE);
106+
jobject_set(jobj, j_cstr_to_buffer("returnValue"), jreturnValue);
107+
jobject_set(jobj, j_cstr_to_buffer("echoMessage"), value);
108+
109+
LSMessageReply(sh, message, jvalue_tostring_simple(jobj), &lserror);
110+
111+
j_release(&parsed);
112+
return true;
113+
}
114+
115+
// Register background service and initialize
116+
int main(int argc, char* argv[])
117+
{
118+
LSError lserror;
119+
LSHandle *handle = NULL;
120+
bool bRetVal = FALSE;
121+
122+
LSErrorInit(&lserror);
123+
124+
// create a GMainLoop
125+
gmainLoop = g_main_loop_new(NULL, FALSE);
126+
127+
bRetVal = LSRegister(SERVICE_NAME, &handle, &lserror);
128+
if (FALSE== bRetVal) {
129+
LSErrorFree( &lserror );
130+
return 0;
131+
}
132+
sh = LSMessageGetConnection(message);
133+
134+
LSRegisterCategory(handle,"/",sampleMethods, NULL, NULL, &lserror);
135+
136+
LSGmainAttach(handle, gmainLoop, &lserror);
137+
138+
// run to check continuously for new events from each of the event sources
139+
g_main_loop_run(gmainLoop);
140+
// Decreases the reference count on a GMainLoop object by one
141+
g_main_loop_unref(gmainLoop);
142+
143+
return 0;
144+
}

lib/base/setup-device.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,10 @@ const async = require('async'),
142142
return next(errHndl.getErrMsg("INVALID_MODE"));
143143
}
144144
if (options[mode].match(/^-/)) {
145-
return next(errHndl.getErrMsg("EMPTY_VALUE", "DEVICE_NAME"));
145+
let indexMode = options.argv.cooked.indexOf("--" + mode);
146+
if (indexMode != -1 && options.argv.cooked.length > indexMode + 2 && !options.argv.cooked[indexMode + 2].match(/^--[a-z]+$/)) {
147+
return next(errHndl.getErrMsg("EMPTY_VALUE", "DEVICE_NAME"));
148+
}
146149
}
147150
const argName = (options.info) ? "info" : mode;
148151
const inDevice = _getParams(options, argName);

0 commit comments

Comments
 (0)