bbaa6092151db2257ec6ee7202c67ea561de93f7
[AGL/documentation.git] / docs / 3_Developer_Guides / 2_Creating_a_New_Service.md
1 ---
2 title: Creating a New Service
3 ---
4
5 This tutorial provides instructions on **Creating a New Service** from scratch.
6
7 ### 1. Create new project development directory
8
9    ```sh
10    $ cd ~/agl-app
11    $ mkdir newservice/
12    $ cd newservice/
13    ```
14
15 ### 2. Source the SDK environment setup
16
17   ```sh
18   $ source ~/agl-app/agl-sdk/environment-setup-corei7-64-agl-linux
19   ```
20
21 ### 3. Copy initial CMAKE configuration templates
22
23   ```sh
24   $ mkdir -p conf.d/cmake
25   $ cp ${OECORE_NATIVE_SYSROOT}/usr/share/doc/CMakeAfbTemplates/samples.d/config.cmake.sample conf.d/cmake/config.cmake
26   $ cp ${OECORE_NATIVE_SYSROOT}/usr/share/doc/CMakeAfbTemplates/samples.d/CMakeLists.txt.sample CMakeLists.txt
27   ```
28
29 ### 4. Edit CMAKE configuration template
30
31   ```sh
32   $ vim ~/agl-app/newservice/conf.d/cmake/config.cmake
33
34     ###########################################################################
35     # Copyright 2020 # INSERT YEAR
36     #
37     # author: John Doe <john.doe@example.com> # INSERT AUTHOR DETAILS
38     #
39     # Licensed under the Apache License, Version 2.0 (the "License");
40     # you may not use this file except in compliance with the License.
41     # You may obtain a copy of the License at
42     #
43     #     http://www.apache.org/licenses/LICENSE-2.0
44     #
45     # Unless required by applicable law or agreed to in writing, software
46     # distributed under the License is distributed on an "AS IS" BASIS,
47     # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
48     # See the License for the specific language governing permissions and
49     # limitations under the License.
50     ###########################################################################
51
52     # Project Info
53     # ------------------
54     set(PROJECT_NAME hellocount)    # INSERT NEW PROJECT NAME
55     set(API_NAME hellocount)    #INSERT NEW API NAME
56     set(PROJECT_PRETTY_NAME "Example")
57     set(PROJECT_DESCRIPTION "AGL hellocount application example")   # INSERT CONCISE PROJECT DESCRIPTION
58     set(PROJECT_URL "https://gerrit.automotivelinux.org/gerrit/apps/cmake-apps-module")
59     set(PROJECT_ICON "icon.png")
60     set(PROJECT_AUTHOR "John Doe")    # INSERT AUTHOR NAME
61     set(PROJECT_AUTHOR_MAIL "john.doe@example.com")   # INSERT AUTHOR EMAIL
62     set(PROJECT_LICENSE "APL2.0")
63     set(PROJECT_LANGUAGES "C")
64     set(PROJECT_VERSION "1.0.0")    # INSERT PROJECT VERSION
65
66     # Which directories inspect to find CMakeLists.txt target files
67     # set(PROJECT_SRC_DIR_PATTERN "*")
68
69     # Where are stored the project configuration files
70     # relative to the root project directory
71     set(PROJECT_CMAKE_CONF_DIR "conf.d")
72
73     # Compilation Mode (DEBUG, RELEASE, COVERAGE or PROFILING)
74     # ----------------------------------
75     set(BUILD_TYPE "RELEASE") # SELECT BUILD TYPE
76     #set(USE_EFENCE 1)
77
78     # Kernel selection if needed. You can choose between a
79     # mandatory version to impose a minimal version.
80     # Or check Kernel minimal version and just print a Warning
81     # about missing features and define a preprocessor variable
82     # to be used as preprocessor condition in code to disable
83     # incompatibles features. Preprocessor define is named
84     # KERNEL_MINIMAL_VERSION_OK.
85     #
86     # NOTE*** FOR NOW IT CHECKS KERNEL Yocto environment and
87     # Yocto SDK Kernel version.
88     # -----------------------------------------------
89     #set (kernel_mandatory_version 4.8)
90     #set (kernel_minimal_version 4.8)
91
92     # Compiler selection if needed. Impose a minimal version.
93     # -----------------------------------------------
94     set (gcc_minimal_version 4.9)
95
96     # PKG_CONFIG required packages
97     # -----------------------------
98     set (PKG_REQUIRED_LIST
99       json-c
100       afb-daemon
101     )
102
103     # You can also consider to include libsystemd
104     # -----------------------------------
105     #list (APPEND PKG_REQUIRED_LIST libsystemd>=222)
106
107     # Prefix path where will be installed the files
108     # Default: /usr/local (need root permission to write in)
109     # ------------------------------------------------------
110     #set(INSTALL_PREFIX /opt/AGL CACHE PATH "INSTALL PREFIX PATH")
111
112     # Customize link option
113     # -----------------------------
114     #list(APPEND link_libraries -an-option)
115
116     # Compilation options definition
117     # Use CMake generator expressions to specify only for a specific language
118     # Values are prefilled with default options that is currently used.
119     # Either separate options with ";", or each options must be quoted separately
120     # DO NOT PUT ALL OPTION QUOTED AT ONCE , COMPILATION COULD FAILED !
121     # ----------------------------------------------------------------------------
122     #set(COMPILE_OPTIONS
123     # -Wall
124     # -Wextra
125     # -Wconversion
126     # -Wno-unused-parameter
127     # -Wno-sign-compare
128     # -Wno-sign-conversion
129     # -Werror=maybe-uninitialized
130     # -Werror=implicit-function-declaration
131     # -ffunction-sections
132     # -fdata-sections
133     # -fPIC
134     # CACHE STRING "Compilation flags")
135     #set(C_COMPILE_OPTIONS "" CACHE STRING "Compilation flags for C language.")
136     #set(CXX_COMPILE_OPTIONS "" CACHE STRING "Compilation flags for C++ language.")
137     #set(PROFILING_COMPILE_OPTIONS
138     # -g
139     # -O0
140     # -pg
141     # -Wp,-U_FORTIFY_SOURCE
142     # CACHE STRING "Compilation flags for PROFILING build type.")
143     #set(DEBUG_COMPILE_OPTIONS
144     # -g
145     # -ggdb
146     # CACHE STRING "Compilation flags for DEBUG build type.")
147     #set(COVERAGE_COMPILE_OPTIONS
148     # -g
149     # -O0
150     # --coverage
151     # CACHE STRING "Compilation flags for COVERAGE build type.")
152     #set(RELEASE_COMPILE_OPTIONS
153     # -O2
154     # -pipe
155     # -D_FORTIFY_SOURCE=2
156     # -fstack-protector-strong
157     # -Wformat -Wformat-security
158     # -Werror=format-security
159     # -feliminate-unused-debug-types
160     # -Wl,-O1
161     # -Wl,--hash-style=gnu
162     # -Wl,--as-needed
163     # -fstack-protector-strong
164     # -Wl,-z,relro,-z,now
165     # CACHE STRING "Compilation flags for RELEASE build type.")
166
167     # Location for config.xml.in template file.
168     #
169     # If you keep them commented then it will build with a default minimal widget
170     # template which is very simple and it is highly probable that it will not suit
171     # to your app.
172     # -----------------------------------------
173     #set(WIDGET_ICON "conf.d/wgt/${PROJECT_ICON}" CACHE PATH "Path to the widget icon")
174     set(WIDGET_CONFIG_TEMPLATE "${CMAKE_CURRENT_SOURCE_DIR}/conf.d/wgt/config.xml.in" CACHE PATH "Path to widget config file template (config.xml.in)")   # UNCOMMENT WIDGET_CONFIG_TEMPLATE
175     #set(TEST_WIDGET_CONFIG_TEMPLATE "${CMAKE_CURRENT_SOURCE_DIR}/conf.d/wgt/test-config.xml.in" CACHE PATH "Path to the test widget config file template (test-config.xml.in)")
176
177     # Mandatory widget Mimetype specification of the main unit
178     # --------------------------------------------------------------------------
179     # Choose between :
180     #- text/html : HTML application,
181     #   content.src designates the home page of the application
182     #
183     #- application/vnd.agl.native : AGL compatible native,
184     #   content.src designates the relative path of the binary.
185     #
186     # - application/vnd.agl.service: AGL service, content.src is not used.
187     #
188     #- ***application/x-executable***: Native application,
189     #   content.src designates the relative path of the binary.
190     #   For such application, only security setup is made.
191     #
192     set(WIDGET_TYPE application/vnd.agl.service)    # UNCOMMENT WIDGET_TYPE
193
194     # Mandatory Widget entry point file of the main unit
195     # --------------------------------------------------------------
196     # This is the file that will be executed, loaded,
197     # at launch time by the application framework.
198     #
199     set(WIDGET_ENTRY_POINT lib/libhellocount.so)    # UNCOMMENT WIDGET_ENTRY_POINT
200
201     # Optional dependencies order
202     # ---------------------------
203     #set(EXTRA_DEPENDENCIES_ORDER)
204
205     # Optional Extra global include path
206     # -----------------------------------
207     #set(EXTRA_INCLUDE_DIRS)
208
209     # Optional extra libraries
210     # -------------------------
211     #set(EXTRA_LINK_LIBRARIES)
212
213     # Optional force binding Linking flag
214     # ------------------------------------
215     # set(BINDINGS_LINK_FLAG LinkOptions )
216
217     # Optional force package prefix generation, like widget
218     # -----------------------------------------------------
219     # set(PKG_PREFIX DestinationPath)
220
221     # Optional Application Framework security token
222     # and port use for remote debugging.
223     #------------------------------------------------------------
224     #set(AFB_TOKEN   ""     CACHE PATH "Default binder security token")   # COMMENT AFB_TOKEN
225     #set(AFB_REMPORT "1234" CACHE PATH "Default binder listening port")   # COMMENT AFB_REMPORT
226
227     # Print a helper message when every thing is finished
228     # ----------------------------------------------------
229     set(CLOSING_MESSAGE "Typical binding launch: cd ${CMAKE_BINARY_DIR}/package \\&\\& afb-daemon --port=${AFB_REMPORT} --workdir=. --ldpaths=lib --roothttp=htdocs  --token=\"${AFB_TOKEN}\" --tracereq=common --verbose")
230     set(PACKAGE_MESSAGE "Install widget file using in the target : afm-util install ${PROJECT_NAME}.wgt")
231
232     # Optional schema validator about now only XML, LUA and JSON
233     # are supported
234     #------------------------------------------------------------
235     #set(LUA_CHECKER "luac" "-p" CACHE STRING "LUA compiler")
236     #set(XML_CHECKER "xmllint" CACHE STRING "XML linter")
237     #set(JSON_CHECKER "json_verify" CACHE STRING "JSON linter")
238
239     include(CMakeAfbTemplates)
240   ```
241
242 ### 5. Copy WGT configuration template
243
244   ```sh
245   $ mkdir -p conf.d/wgt
246   $ cp ${OECORE_NATIVE_SYSROOT}/usr/share/doc/CMakeAfbTemplates/samples.d/config.xml.in.sample conf.d/wgt/config.xml.in
247   ```
248
249 ### 6. Run CMAKE and Generate autobuild
250
251   ```sh
252   $ mkdir build/
253   $ cd build/
254   $ cmake ..
255   $ make autobuild
256   ```
257
258 ### 7. Create service directory
259
260   ```sh
261   $ cd ..
262   $ mkdir service/
263   $ cd service/
264   ```
265   This `service` directory holds the C code & CMakeLists.txt ;
266
267   - Add `hellocount-service.c` file which contains the functional C code :
268
269     ```sh
270     $ vim hellocount-service.c
271
272       /*
273        * Copyright 2020 The Linux Foundation # INSERT YEAR & ORG
274        *
275        * Licensed under the Apache License, Version 2.0 (the "License");
276        * you may not use this file except in compliance with the License.
277        * You may obtain a copy of the License at
278        *
279        *   http://www.apache.org/licenses/LICENSE-2.0
280        *
281        * Unless required by applicable law or agreed to in writing, software
282        * distributed under the License is distributed on an "AS IS" BASIS,
283        * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
284        * See the License for the specific language governing permissions and
285        * limitations under the License.
286        */
287
288       #define _GNU_SOURCE
289       #include <stdio.h>
290       #include <string.h>
291       #include <json-c/json.h>
292
293       #define AFB_BINDING_VERSION 3
294       #include <afb/afb-binding.h>
295
296       static void pingSample(afb_req_t request)
297       {
298         static int pingcount = 0;
299
300         afb_req_success_f(request, json_object_new_int(pingcount), "Ping count = %d", pingcount);
301
302         AFB_API_NOTICE(afbBindingV3root, "Verbosity macro at level notice invoked at ping invocation count = %d", pingcount);
303
304         pingcount++;
305       }
306
307       static void count(afb_req_t request)
308       {
309         static int counter = 0;
310
311         afb_req_success_f(request, json_object_new_int(counter), "Counter = %d", counter);
312
313         AFB_API_NOTICE(afbBindingV3root, "Verbosity macro at level notice invoked at count invocation count = %d", counter);
314
315         counter++;
316       }
317
318
319
320       static const afb_verb_t verbs[] =
321       {
322         /*Without security*/
323         {.verb = "ping", .session = AFB_SESSION_NONE, .callback = pingSample, .auth = NULL},
324         {.verb = "count", .session = AFB_SESSION_NONE, .callback = count, .auth = NULL},
325         {NULL}
326       };
327
328       const afb_binding_t afbBindingExport =
329       {
330         .api = "count",
331         .specification = "HelloCount API",
332         .verbs = verbs,
333         .preinit = NULL,
334         .init = NULL,
335         .onevent = NULL,
336         .userdata = NULL,
337         .provide_class = NULL,
338         .require_class = NULL,
339         .require_api = NULL,
340         .noconcurrency = 0
341       };
342     ```
343
344 - Add `CMakeLists.txt` file :
345
346     ```sh
347     $ vim CMakeLists.txt
348
349       ###########################################################################
350       # Copyright 2020 The Linux Foundation # INSERT YEAR & ORG
351       #
352       # Licensed under the Apache License, Version 2.0 (the "License");
353       # you may not use this file except in compliance with the License.
354       # You may obtain a copy of the License at
355       #
356       #     http://www.apache.org/licenses/LICENSE-2.0
357       #
358       # Unless required by applicable law or agreed to in writing, software
359       # distributed under the License is distributed on an "AS IS" BASIS,
360       # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
361       # See the License for the specific language governing permissions and
362       # limitations under the License.
363       ###########################################################################
364
365       # Add target to project dependency list
366       PROJECT_TARGET_ADD(hellocount)
367           # Define project Targets
368           ADD_LIBRARY(${TARGET_NAME} MODULE hellocount-service.c)
369
370           # Binder exposes a unique public entry point
371           SET_TARGET_PROPERTIES(${TARGET_NAME} PROPERTIES
372           PREFIX "afb-"
373           LABELS "BINDING"
374           OUTPUT_NAME ${TARGET_NAME}
375           )
376     ```
377
378 ### 8. Build and Package `wgt` using autobuild
379
380   ```sh
381   $ cd ..
382
383   $ ./autobuild/agl/autobuild build
384
385     make[1]: Entering directory '/home/boron/agl-app/newservice/build'
386     make[2]: Entering directory '/home/boron/agl-app/newservice/build'
387     make[3]: Entering directory '/home/boron/agl-app/newservice/build'
388     make[3]: Leaving directory '/home/boron/agl-app/newservice/build'
389     [100%] Built target autobuild
390     make[2]: Leaving directory '/home/boron/agl-app/newservice/build'
391     make[1]: Leaving directory '/home/boron/agl-app/newservice/build'
392
393   $ ./autobuild/agl/autobuild package
394
395     make[1]: Entering directory '/home/boron/agl-app/newservice/build'
396     make[2]: Entering directory '/home/boron/agl-app/newservice/build'
397     make[3]: Entering directory '/home/boron/agl-app/newservice/build'
398     make[3]: Leaving directory '/home/boron/agl-app/newservice/build'
399     [100%] Built target autobuild
400     make[2]: Leaving directory '/home/boron/agl-app/newservice/build'
401     make[1]: Leaving directory '/home/boron/agl-app/newservice/build'
402     make[1]: Entering directory '/home/boron/agl-app/newservice/build'
403     make[2]: Entering directory '/home/boron/agl-app/newservice/build'
404     make[3]: Entering directory '/home/boron/agl-app/newservice/build'
405     make[4]: Entering directory '/home/boron/agl-app/newservice/build'
406     Scanning dependencies of target prepare_package
407     make[4]: Leaving directory '/home/boron/agl-app/newservice/build'
408     make[4]: Entering directory '/home/boron/agl-app/newservice/build'
409     [  6%] Generating package
410     [ 12%] Generating package/bin
411     [ 18%] Generating package/etc
412     [ 25%] Generating package/lib
413     [ 31%] Generating package/htdocs
414     [ 37%] Generating package/var
415     make[4]: Leaving directory '/home/boron/agl-app/newservice/build'
416     [ 37%] Built target prepare_package
417     make[4]: Entering directory '/home/boron/agl-app/newservice/build'
418     Scanning dependencies of target prepare_package_test
419     make[4]: Leaving directory '/home/boron/agl-app/newservice/build'
420     make[4]: Entering directory '/home/boron/agl-app/newservice/build'
421     [ 43%] Generating package-test
422     [ 50%] Generating package-test/bin
423     [ 56%] Generating package-test/etc
424     [ 62%] Generating package-test/lib
425     [ 68%] Generating package-test/htdocs
426     [ 75%] Generating package-test/var
427     make[4]: Leaving directory '/home/boron/agl-app/newservice/build'
428     [ 75%] Built target prepare_package_test
429     make[4]: Entering directory '/home/boron/agl-app/newservice/build'
430     Scanning dependencies of target populate
431     make[4]: Leaving directory '/home/boron/agl-app/newservice/build'
432     [ 75%] Built target populate
433     make[4]: Entering directory '/home/boron/agl-app/newservice/build'
434     Scanning dependencies of target widget_files
435     make[4]: Leaving directory '/home/boron/agl-app/newservice/build'
436     make[4]: Entering directory '/home/boron/agl-app/newservice/build'
437     [ 81%] Generating package/icon.png
438     [ 87%] Generating package/config.xml
439     make[4]: Leaving directory '/home/boron/agl-app/newservice/build'
440     [ 93%] Built target widget_files
441     make[4]: Entering directory '/home/boron/agl-app/newservice/build'
442     Scanning dependencies of target widget
443     make[4]: Leaving directory '/home/boron/agl-app/newservice/build'
444     make[4]: Entering directory '/home/boron/agl-app/newservice/build'
445     [100%] Generating hellocount.wgt
446     NOTICE: -- PACKING widget hellocount.wgt from directory /home/boron/agl-app/newservice/build/package
447     ++ Install widget file using in the target : afm-util install hellocount.wgt
448     make[4]: Leaving directory '/home/boron/agl-app/newservice/build'
449     [100%] Built target widget
450     make[3]: Leaving directory '/home/boron/agl-app/newservice/build'
451     make[2]: Leaving directory '/home/boron/agl-app/newservice/build'
452     make[1]: Leaving directory '/home/boron/agl-app/newservice/build'
453   ```
454
455   - The `hellocount.wgt` file is packaged and available at `~/agl-app/newservice/build`.
456
457 ### 9. Install the service
458
459   - Local System :
460     ```sh
461     # Copy hellocount.wgt to remote AGL system
462     $ scp ~/agl-app/newservice/build/hellocount.wgt root@<ip-address>:/home/0/
463     ```
464
465   - Remote AGL System :
466     ```sh
467     # Install using the service using afm-util
468     $ afm-util install ./hellocount.wgt
469     # Reboot the system
470     $ reboot -f
471     ```