From 3e94024998c1615bd30306aab7537db22161a9ce Mon Sep 17 00:00:00 2001 From: Matt Ranostay <matt.ranostay@konsulko.com> Date: Sat, 19 Oct 2019 13:45:11 -0700 Subject: [PATCH] binding: navigation: rewrite of navigation binding To remove dependency on DBus the binding needed to be rewritten to output pure JSON output to subscribed consumers. Bug-AGL: SPEC-2880 Change-Id: Ie85dfccd42ca36119116a0fbfb16bf4e96efc184 Signed-off-by: Matt Ranostay <matt.ranostay@konsulko.com> --- CMakeLists.txt | 85 +- README.md | 64 +- autobuild/agl/autobuild | 4 +- autobuild/linux/autobuild | 30 +- binding/CMakeLists.txt | 35 + binding/navigation-api.c | 245 ++++ binding/navigation-api.h | 53 + conf.d/cmake/config.cmake | 167 +++ conf.d/wgt/config.xml.in | 22 + config.xml.in | 19 - include/analyze_request.h | 31 - include/binder_reply.h | 34 - include/genivi/genivi-navicore-constants.h | 199 --- include/genivi/genivi-navigationcore-proxy.h | 1147 ------------------ include/genivi/navicore.h | 140 --- include/genivi_request.h | 37 - libnavi/include/BinderClient.h | 57 - libnavi/include/JsonRequestGenerator.h | 29 - libnavi/include/JsonResponseAnalyzer.h | 25 - libnavi/include/RequestManage.h | 64 - libnavi/include/RequestManageListener.h | 17 - libnavi/include/libnavicore.hpp | 69 -- libnavi/include/traces.h | 38 - libnavi/src/BinderClient.cpp | 315 ----- libnavi/src/JsonRequestGenerator.cpp | 188 --- libnavi/src/JsonResponseAnalyzer.cpp | 254 ---- libnavi/src/RequestManage.cpp | 204 ---- libnavi/src/navicore.cpp | 81 -- libnavi/src/navicorelistener.cpp | 28 - libnaviapi-agl.pc.in | 14 - navigation.png | Bin 38244 -> 0 bytes src/analyze_request.cpp | 296 ----- src/api.cpp | 419 ------- src/binder_reply.cpp | 168 --- src/genivi_request.cpp | 350 ------ src/traces.h | 38 - 36 files changed, 619 insertions(+), 4347 deletions(-) create mode 100644 binding/CMakeLists.txt create mode 100644 binding/navigation-api.c create mode 100644 binding/navigation-api.h create mode 100644 conf.d/cmake/config.cmake create mode 100644 conf.d/wgt/config.xml.in delete mode 100644 config.xml.in delete mode 100644 include/analyze_request.h delete mode 100644 include/binder_reply.h delete mode 100644 include/genivi/genivi-navicore-constants.h delete mode 100644 include/genivi/genivi-navigationcore-proxy.h delete mode 100644 include/genivi/navicore.h delete mode 100644 include/genivi_request.h delete mode 100644 libnavi/include/BinderClient.h delete mode 100644 libnavi/include/JsonRequestGenerator.h delete mode 100644 libnavi/include/JsonResponseAnalyzer.h delete mode 100644 libnavi/include/RequestManage.h delete mode 100644 libnavi/include/RequestManageListener.h delete mode 100644 libnavi/include/libnavicore.hpp delete mode 100644 libnavi/include/traces.h delete mode 100644 libnavi/src/BinderClient.cpp delete mode 100644 libnavi/src/JsonRequestGenerator.cpp delete mode 100644 libnavi/src/JsonResponseAnalyzer.cpp delete mode 100644 libnavi/src/RequestManage.cpp delete mode 100644 libnavi/src/navicore.cpp delete mode 100644 libnavi/src/navicorelistener.cpp delete mode 100644 libnaviapi-agl.pc.in delete mode 100644 navigation.png delete mode 100644 src/analyze_request.cpp delete mode 100644 src/api.cpp delete mode 100644 src/binder_reply.cpp delete mode 100644 src/genivi_request.cpp delete mode 100644 src/traces.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 9bd545b..b485097 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,64 +1,21 @@ -cmake_minimum_required(VERSION 2.8.11) - -INCLUDE(FindPkgConfig) - -set(PROJECT_NAME "agl-service-navigation") -set(PROJECT_PRETTY_NAME "AFM binding for navigation service") -set(PROJECT_DESCRIPTION "Binding for AGL Navigation API") -set(PROJECT_INCLUDEDIR ${CMAKE_INSTALL_PREFIX}/include) -set(PROJECT_LIBDIR ${CMAKE_INSTALL_PREFIX}/lib) -set(PROJECT_API_VERSION 0.1.0) -set(PROJECT_URL "https://wiki.automotivelinux.org/eg-navi") - -# Set a default build type if none was specified -if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) - message(STATUS "Setting build type to 'Release' as none was specified.") - set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build." FORCE) -endif() - -project(navi_binder) - -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -fPIC ") - -set(CMAKE_INCLUDE_CURRENT_DIR ON) - -pkg_check_modules(DBUSCXX REQUIRED dbus-c++-1) -pkg_check_modules(JSON REQUIRED json-c) -pkg_check_modules(AFBWSC REQUIRED libafbwsc) - -include_directories( ${PROJECT_SOURCE_DIR}/libnavi/include ${PROJECT_SOURCE_DIR}/include ${DBUSCXX_INCLUDE_DIRS} ${JSON_INCLUDE_DIRS} ${AFBWSC_INCLUDE_DIRS} ) - -add_library( naviapi-agl SHARED libnavi/src/navicore.cpp libnavi/src/navicorelistener.cpp libnavi/src/BinderClient.cpp libnavi/src/JsonRequestGenerator.cpp libnavi/src/JsonResponseAnalyzer.cpp libnavi/src/RequestManage.cpp ) -target_link_libraries( naviapi-agl ${JSON_LIBRARIES} ${AFBWSC_LIBRARIES} ) -set_target_properties(naviapi-agl PROPERTIES VERSION 0.1.0 SOVERSION 0) - -install(TARGETS naviapi-agl LIBRARY DESTINATION ${PROJECT_LIBDIR}) -install(FILES ${PROJECT_SOURCE_DIR}/libnavi/include/libnavicore.hpp DESTINATION ${PROJECT_INCLUDEDIR}) - -add_library( NaviAPIService SHARED src/api.cpp src/analyze_request.cpp src/binder_reply.cpp src/genivi_request.cpp ) - -target_link_libraries( NaviAPIService ${DBUSCXX_LIBRARIES} ${JSON_LIBRARIES} ${AFBWSC_LIBRARIES} ) - -########################################################################## -# AGL binding -configure_file(config.xml.in config.xml) -set(BINARY_NAME "naviapi.wgt") - -add_custom_command( - OUTPUT ${BINARY_NAME} - DEPENDS NaviAPIService - COMMAND rm -rf package - COMMAND mkdir -p package/root - COMMAND mkdir -p package/root/lib - COMMAND mv config.xml package/root/ - COMMAND cp ${CMAKE_CURRENT_SOURCE_DIR}/navigation.png package/root/icon.png - COMMAND mv libNaviAPIService.so package/root/lib - COMMAND wgtpkg-pack -f -o package/${BINARY_NAME} package/root -) -add_custom_target(widget ALL DEPENDS ${BINARY_NAME}) - -#generate configure file -configure_file(libnaviapi-agl.pc.in libnaviapi-agl.pc @ONLY) -INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/libnaviapi-agl.pc - DESTINATION - ${CMAKE_INSTALL_PREFIX}/lib/pkgconfig) +########################################################################### +# Copyright 2015, 2016, 2017 IoT.bzh +# +# author: Romain Forlot <romain.forlot@iot.bzh> +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +########################################################################### + +CMAKE_MINIMUM_REQUIRED(VERSION 3.3) + +include(${CMAKE_CURRENT_SOURCE_DIR}/conf.d/cmake/config.cmake) diff --git a/README.md b/README.md index 7a27f6d..8c5e3d3 100644 --- a/README.md +++ b/README.md @@ -1,25 +1,59 @@ -AGL Navigation API Binder -=============== +# Navigation Service -Copyright 2017 AISIN AW +## Overview -author: Yoshito Momiyama <i25461_momiyama@aisin-aw.co.jp> +Navigation service keeps track of application data that allows other clients to share location, waypoints, +and state between each other. - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at +## Verbs - http://www.apache.org/licenses/LICENSE-2.0 +| Name | Description | JSON Response | +|---------------------|---------------------------------------------|------------------------------------| +| subscribe | subscribe to an navigation service | *Request:* {"value": "status"} | +| unsubscribe | unsubscribe to an navigation service | *Request:* {"value": "status"} | +| broadcast_status | broadcast status event to other clients | *Request:* {"state": "stop"} | +| broadcast_position | broadcast position event to other clients | See *position Verb* section | +| broadcast_waypoints | broadcast waypoints events to other clients | See *waypoints Verb* section | - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. +### broadcast_position Verb -=============== +Populate same data referenced in *position Event* section for the event -This component is a reference implementation of the AGL Navigation API. +### broadcast_waypoints Verb +Populate same data referenced in *waypoints Event* section for the event +## Events + +| Name | Description | +|----------------|-------------------------------------| +| status | status of the navigation engine | +| position | current route or car position event | +| waypoints | waypoints for routing engine | + +### position Event + +<pre> +{ + "points": [ + { + "latitude": 36.12906, + "longitude": -115.17908 + } + ] +} +</pre> + +### waypoints Event + +<pre> +{ + "points": [ + { + "latitude": 36.12906, + "longitude": -115.17908 + } + ] +} +</pre> diff --git a/autobuild/agl/autobuild b/autobuild/agl/autobuild index a086c89..db00c1a 100755 --- a/autobuild/agl/autobuild +++ b/autobuild/agl/autobuild @@ -59,8 +59,8 @@ package: build @mkdir -p ${BUILD_DIR}/$@/htdocs @mkdir -p ${BUILD_DIR}/$@/var @cmake --build ${BUILD_DIR} ${PACKAGE_ARGS} --target widget - @if [ "${DEST}" != "${BUILD_DIR}/$@" ]; then \ - mkdir -p ${DEST} && cp ${BUILD_DIR}/$@/*.wgt ${DEST}; \ + @if [ "${DEST}" != "${BUILD_DIR}" ]; then \ + mkdir -p ${DEST} && cp ${BUILD_DIR}/*.wgt ${DEST}; \ fi package-test: build diff --git a/autobuild/linux/autobuild b/autobuild/linux/autobuild index 512adda..db00c1a 100755 --- a/autobuild/linux/autobuild +++ b/autobuild/linux/autobuild @@ -16,7 +16,7 @@ THISFILE := $(lastword $(MAKEFILE_LIST)) BUILD_DIR := $(abspath $(dir $(THISFILE))/../../build) -DESTDIR := ${BUILD_DIR} +DEST := ${BUILD_DIR} .PHONY: all clean distclean configure build package help update @@ -33,8 +33,11 @@ help: @echo "- package: output a widget file '*.wgt'" @echo "- install: install in your ${CMAKE_INSTALL_DIR} directory" @echo "" - @echo "Usage: ./autobuild/linux/autobuild package DESTDIR=${HOME}/opt" - @echo "Don't use your build dir as DESTDIR as wgt file is generated at this location" + @echo "Usage: ./autobuild/agl/autobuild package DEST=${HOME}/opt" + @echo "Don't use your build dir as DEST as wgt file is generated at this location" + +update: configure + @cmake --build ${BUILD_DIR} --target autobuild clean: @([ -d ${BUILD_DIR} ] && make -C ${BUILD_DIR} ${CLEAN_ARGS} clean) || echo Nothing to clean @@ -50,9 +53,26 @@ build: configure @cmake --build ${BUILD_DIR} ${BUILD_ARGS} --target all package: build + @mkdir -p ${BUILD_DIR}/$@/bin + @mkdir -p ${BUILD_DIR}/$@/etc + @mkdir -p ${BUILD_DIR}/$@/lib + @mkdir -p ${BUILD_DIR}/$@/htdocs + @mkdir -p ${BUILD_DIR}/$@/var + @cmake --build ${BUILD_DIR} ${PACKAGE_ARGS} --target widget + @if [ "${DEST}" != "${BUILD_DIR}" ]; then \ + mkdir -p ${DEST} && cp ${BUILD_DIR}/*.wgt ${DEST}; \ + fi + +package-test: build + @mkdir -p ${BUILD_DIR}/$@/bin + @mkdir -p ${BUILD_DIR}/$@/etc + @mkdir -p ${BUILD_DIR}/$@/lib + @mkdir -p ${BUILD_DIR}/$@/htdocs + @mkdir -p ${BUILD_DIR}/$@/var @cmake --build ${BUILD_DIR} ${PACKAGE_ARGS} --target widget - @if [ "${DESTDIR}" != "${BUILD_DIR}" ]; then \ - mkdir -p ${DESTDIR} && cp ${BUILD_DIR}/*.wgt ${DESTDIR}; \ + @cmake --build ${BUILD_DIR} ${PACKAGE_ARGS} --target test_widget + @if [ "${DEST}" != "${BUILD_DIR}" ]; then \ + mkdir -p ${DEST} && cp ${BUILD_DIR}/*.wgt ${DEST}; \ fi install: build diff --git a/binding/CMakeLists.txt b/binding/CMakeLists.txt new file mode 100644 index 0000000..9088825 --- /dev/null +++ b/binding/CMakeLists.txt @@ -0,0 +1,35 @@ +########################################################################### +# Copyright 2015, 2016, 2017 IoT.bzh +# +# author: Fulup Ar Foll <fulup@iot.bzh> +# contrib: Romain Forlot <romain.forlot@iot.bzh> +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +########################################################################### + +# Add target to project dependency list +PROJECT_TARGET_ADD(afm-navigation-binding) + + # Define project Targets + add_library(afm-navigation-binding MODULE navigation-api.c) + + # Binder exposes a unique public entry point + SET_TARGET_PROPERTIES(${TARGET_NAME} PROPERTIES + PREFIX "lib" + LABELS "BINDING" + LINK_FLAGS ${BINDINGS_LINK_FLAG} + OUTPUT_NAME ${TARGET_NAME} + ) + + # Library dependencies (include updates automatically) + TARGET_LINK_LIBRARIES(${TARGET_NAME} ${link_libraries}) diff --git a/binding/navigation-api.c b/binding/navigation-api.c new file mode 100644 index 0000000..d9ea285 --- /dev/null +++ b/binding/navigation-api.c @@ -0,0 +1,245 @@ +/* + * Copyright (C) 2019 Konsulko Group + * Author: Matt Ranostay <matt.ranostay@konsulko.com> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define _GNU_SOURCE +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/time.h> +#include <time.h> + +#include <glib.h> +#include <glib/gstdio.h> +#include <gio/gio.h> +#include <json-c/json.h> + +#define AFB_BINDING_VERSION 3 +#include <afb/afb-binding.h> + +#include "navigation-api.h" + +struct navigation_state *navigation_get_userdata(afb_req_t request) { + afb_api_t api = afb_req_get_api(request); + return afb_api_get_userdata(api); +} + +static afb_event_t get_event_from_value(struct navigation_state *ns, + const char *value) +{ + if (!g_strcmp0(value, "status")) + return ns->status_event; + + if (!g_strcmp0(value, "position")) + return ns->position_event; + + if (!g_strcmp0(value, "waypoints")) + return ns->waypoints_event; + + return NULL; +} + +static json_object **get_storage_from_value(struct navigation_state *ns, + const char *value) +{ + if (!g_strcmp0(value, "status")) + return &ns->status_storage; + + if (!g_strcmp0(value, "position")) + return &ns->position_storage; + + if (!g_strcmp0(value, "waypoints")) + return &ns->waypoints_storage; + + return NULL; +} + +static void navigation_subscribe_unsubscribe(afb_req_t request, + gboolean unsub) +{ + struct navigation_state *ns = navigation_get_userdata(request); + json_object *jresp = json_object_new_object(); + const char *value; + afb_event_t event; + int rc; + + value = afb_req_value(request, "value"); + if (!value) { + afb_req_fail_f(request, "failed", "Missing \"value\" event"); + return; + } + + event = get_event_from_value(ns, value); + if (!event) { + afb_req_fail_f(request, "failed", "Bad \"value\" event \"%s\"", + value); + return; + } + + if (!unsub) { + json_object *storage; + rc = afb_req_subscribe(request, event); + + g_rw_lock_reader_lock(&ns->rw_lock); + storage = *get_storage_from_value(ns, value); + if (storage) { + // increment reference counter, and send out cached value + json_object_get(storage); + afb_event_push(event, storage); + } + g_rw_lock_reader_unlock(&ns->rw_lock); + } else { + rc = afb_req_unsubscribe(request, event); + } + if (rc != 0) { + afb_req_fail_f(request, "failed", + "%s error on \"value\" event \"%s\"", + !unsub ? "subscribe" : "unsubscribe", + value); + return; + } + + afb_req_success_f(request, jresp, "Navigation %s to event \"%s\"", + !unsub ? "subscribed" : "unsubscribed", + value); +} + +static void subscribe(afb_req_t request) +{ + navigation_subscribe_unsubscribe(request, FALSE); +} + +static void unsubscribe(afb_req_t request) +{ + navigation_subscribe_unsubscribe(request, TRUE); +} + +static void broadcast(afb_req_t request, const char *name, gboolean cache) +{ + struct navigation_state *ns = navigation_get_userdata(request); + afb_event_t event = get_event_from_value(ns, name); + json_object *jresp = afb_req_json(request); + + if (cache) { + json_object **storage = get_storage_from_value(ns, name); + + g_rw_lock_writer_lock(&ns->rw_lock); + + if (*storage) + json_object_put(*storage); + + // increment reference for storage + json_object_get(jresp); + *storage = jresp; + + g_rw_lock_writer_unlock(&ns->rw_lock); + } + + // increment reference for event + json_object_get(jresp); + afb_event_push(event, jresp); +} + +static void broadcast_status(afb_req_t request) +{ + broadcast(request, "status", TRUE); + + afb_req_success(request, NULL, "Broadcast status send"); +} + +static void broadcast_position(afb_req_t request) +{ + const char *position = afb_req_value(request, "position"); + gboolean cache = FALSE; + + // only send out a car position event on subscribe + if (position && !g_strcmp0(position, "car")) + cache = TRUE; + + broadcast(request, "position", cache); + + afb_req_success(request, NULL, "Broadcast position send"); +} + +static void broadcast_waypoints(afb_req_t request) +{ + broadcast(request, "waypoints", TRUE); + + afb_req_success(request, NULL, "Broadcast waypoints send"); +} + +static int init(afb_api_t api) +{ + struct navigation_state *ns; + + ns = g_try_malloc0(sizeof(*ns)); + if (!ns) { + AFB_ERROR("out of memory allocating navigation state"); + return -ENOMEM; + } + + ns->status_event = afb_daemon_make_event("status"); + ns->position_event = afb_daemon_make_event("position"); + ns->waypoints_event = afb_daemon_make_event("waypoints"); + + if (!afb_event_is_valid(ns->status_event) || + !afb_event_is_valid(ns->position_event) || + !afb_event_is_valid(ns->waypoints_event)) { + AFB_ERROR("Cannot create events"); + return -EINVAL; + } + + afb_api_set_userdata(api, ns); + + g_rw_lock_init(&ns->rw_lock); + + return 0; +} + +static const afb_verb_t binding_verbs[] = { + { + .verb = "subscribe", + .callback = subscribe, + .info = "Subscribe to event" + }, { + .verb = "unsubscribe", + .callback = unsubscribe, + .info = "Unsubscribe to event" + }, { + .verb = "broadcast_status", + .callback = broadcast_status, + .info = "Allows clients to broadcast status events" + }, { + .verb = "broadcast_position", + .callback = broadcast_position, + .info = "Broadcast out position event" + }, { + .verb = "broadcast_waypoints", + .callback = broadcast_waypoints, + .info = "Broadcast out waypoint event" + }, + {} +}; + +/* + * description of the binding for afb-daemon + */ +const afb_binding_t afbBindingV3 = { + .api = "navigation", + .verbs = binding_verbs, + .init = init, +}; diff --git a/binding/navigation-api.h b/binding/navigation-api.h new file mode 100644 index 0000000..457a87d --- /dev/null +++ b/binding/navigation-api.h @@ -0,0 +1,53 @@ +/* + * Copyright 2019 Konsulko Group + * Author: Matt Ranostay <matt.ranostay@konsulko.com> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef NAVIGATION_API_H +#define NAVIGATION_API_H + +#include <stddef.h> + +#define _GNU_SOURCE +#include <glib.h> +#include <stdlib.h> +#include <gio/gio.h> +#include <glib-object.h> + +#include <json-c/json.h> + +#define AFB_BINDING_VERSION 3 +#include <afb/afb-binding.h> + +#include <json-c/json.h> + +struct call_work; + +struct navigation_state { + // events + afb_event_t status_event; + afb_event_t position_event; + afb_event_t waypoints_event; + + // storage + json_object *status_storage; + json_object *position_storage; + json_object *waypoints_storage; + + // locking + GRWLock rw_lock; +}; + +#endif diff --git a/conf.d/cmake/config.cmake b/conf.d/cmake/config.cmake new file mode 100644 index 0000000..e096705 --- /dev/null +++ b/conf.d/cmake/config.cmake @@ -0,0 +1,167 @@ +########################################################################### +# Copyright 2015, 2016, 2017 IoT.bzh +# +# author: Fulup Ar Foll <fulup@iot.bzh> +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +########################################################################### + +# Project Info +# ------------------ +set(PROJECT_NAME agl-service-navigation) +set(PROJECT_VERSION "1.0") +set(PROJECT_PRETTY_NAME "Navigation service for AGL") +set(PROJECT_DESCRIPTION "Navigation reporting proxy for consumers") +set(PROJECT_URL "https://gerrit.automotivelinux.org/gerrit/apps/agl-service-navigation") +set(PROJECT_ICON "icon.png") +set(PROJECT_AUTHOR "Matt Ranostay") +set(PROJECT_AUTHOR_MAIL "matt.ranostay@konsulko.com") +set(PROJECT_LICENSE "APL2.0") +set(PROJECT_LANGUAGES,"C") +set(API_NAME "navigation") + +# Where the project configuration files are stored +set(PROJECT_CMAKE_CONF_DIR "conf.d") + +# Where are stored your external libraries for your project. This is 3rd party library that you don't maintain +# but used and must be built and linked. +# set(PROJECT_LIBDIR "libs") + +# Where are stored data for your application. Pictures, static resources must be placed in that folder. +# set(PROJECT_RESOURCES "data") + +# Which directories inspect to find CMakeLists.txt target files +# set(PROJECT_SRC_DIR_PATTERN "*") + +# Compilation Mode (DEBUG, RELEASE) +# ---------------------------------- +set(BUILD_TYPE "RELEASE") + +# Kernel selection if needed. You can choose between a +# mandatory version to impose a minimal version. +# Or check Kernel minimal version and just print a Warning +# about missing features and define a preprocessor variable +# to be used as preprocessor condition in code to disable +# incompatibles features. Preprocessor define is named +# KERNEL_MINIMAL_VERSION_OK. +# +# NOTE*** FOR NOW IT CHECKS KERNEL Yocto environment and +# Yocto SDK Kernel version. +# ----------------------------------------------- +#set(kernel_mandatory_version 4.8) + +# Compiler selection if needed. Impose a minimal version. +# ----------------------------------------------- +set (gcc_minimal_version 4.9) + +# PKG_CONFIG required packages +# ----------------------------- +set (PKG_REQUIRED_LIST + json-c + libsystemd>=222 + afb-daemon + json-c + glib-2.0 + gio-2.0 + gobject-2.0 + gio-unix-2.0 + zlib +) + +# Static constante definition +# ----------------------------- +add_compile_options(-DPB_FIELD_16BIT) +add_compile_options($<$<COMPILE_LANGUAGE:CXX>:-pthread>) + +# Customize link option +# ----------------------------- +list (APPEND link_libraries -pthread) + +# (BUG!!!) as PKG_CONFIG_PATH does not work [should be an env variable] +# --------------------------------------------------------------------- +set(INSTALL_PREFIX $ENV{HOME}/opt) +set(CMAKE_PREFIX_PATH ${CMAKE_INSTALL_PREFIX}/lib64/pkgconfig ${CMAKE_INSTALL_PREFIX}/lib/pkgconfig) +set(LD_LIBRARY_PATH ${CMAKE_INSTALL_PREFIX}/lib64 ${CMAKE_INSTALL_PREFIX}/lib) + +# Optional location for config.xml.in +# ----------------------------------- +set(WIDGET_CONFIG_TEMPLATE ${CMAKE_CURRENT_SOURCE_DIR}/conf.d/wgt/config.xml.in) + +# Mandatory widget Mimetype specification of the main unit +# -------------------------------------------------------------------------- +# Choose between : +#- text/html : HTML application, +# content.src designates the home page of the application +# +#- application/vnd.agl.native : AGL compatible native, +# content.src designates the relative path of the binary. +# +# - application/vnd.agl.service: AGL service, content.src is not used. +# +#- ***application/x-executable***: Native application, +# content.src designates the relative path of the binary. +# For such application, only security setup is made. +# +set(WIDGET_TYPE application/vnd.agl.service) + +# Mandatory Widget entry point file of the main unit +# -------------------------------------------------------------- +# This is the file that will be executed, loaded, +# at launch time by the application framework. +# +set(WIDGET_ENTRY_POINT lib/libafm-navigation-binding.so) + +# Print a helper message when every thing is finished +# ---------------------------------------------------- +set(CLOSING_MESSAGE "Test with: afb-daemon --rootdir=\$\$(pwd)/package --binding=\$\$(pwd)/package/${WIDGET_ENTRY_POINT} --port=1234 --tracereq=common --token=\"1\" --verbose") +set(PACKAGE_MESSAGE "Install widget file using in the target : afm-util install ${PROJECT_NAME}.wgt") + + + +# Optional dependencies order +# --------------------------- +#set(EXTRA_DEPENDENCIES_ORDER) + +# Optional Extra global include path +# ----------------------------------- +#set(EXTRA_INCLUDE_DIRS) + +# Optional extra libraries +# ------------------------- +#set(EXTRA_LINK_LIBRARIES) + +# Optional force binding installation +# ------------------------------------ +# set(BINDINGS_INSTALL_PREFIX PrefixPath ) + +# Optional force binding Linking flag +# ------------------------------------ +# set(BINDINGS_LINK_FLAG LinkOptions ) + +# Optional force package prefix generation, like widget +# ----------------------------------------------------- +# set(PKG_PREFIX DestinationPath) + +# Optional Application Framework security token +# and port use for remote debugging. +#------------------------------------------------------------ +#set(AFB_TOKEN "" CACHE PATH "Default AFB_TOKEN") +#set(AFB_REMPORT "1234" CACHE PATH "Default AFB_TOKEN") + +# This include is mandatory and MUST happens at the end +# of this file, else you expose you to unexpected behavior +# +# This CMake module could be found at the following url: +# https://gerrit.automotivelinux.org/gerrit/#/admin/projects/src/cmake-apps-module +# ----------------------------------------------------------- +include(CMakeAfbTemplates) diff --git a/conf.d/wgt/config.xml.in b/conf.d/wgt/config.xml.in new file mode 100644 index 0000000..485407e --- /dev/null +++ b/conf.d/wgt/config.xml.in @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<widget xmlns="http://www.w3.org/ns/widgets" id="@PROJECT_NAME@" version="@PROJECT_VERSION@"> + <name>@PROJECT_NAME@</name> + <icon src="@PROJECT_ICON@"/> + <content src="@WIDGET_ENTRY_POINT@" type="@WIDGET_TYPE@"/> + <description>@PROJECT_DESCRIPTION@</description> + <author>@PROJECT_AUTHOR@ <@PROJECT_AUTHOR_MAIL@></author> + <license>@PROJECT_LICENSE@</license> + + <feature name="urn:AGL:widget:required-permission"> + <param name="urn:AGL:permission::public:hidden" value="required" /> + <param name="urn:AGL:permission::public:no-htdocs" value="required" /> + </feature> + + <feature name="urn:AGL:widget:provided-api"> + <param name="navigation" value="ws" /> + </feature> + + <feature name="urn:AGL:widget:required-api"> + <param name="@WIDGET_ENTRY_POINT@" value="local" /> + </feature> +</widget> diff --git a/config.xml.in b/config.xml.in deleted file mode 100644 index 25b9e53..0000000 --- a/config.xml.in +++ /dev/null @@ -1,19 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<widget xmlns="http://www.w3.org/ns/widgets" id="naviapi-binding-service" version="0.1"> - <name>naviapi-binding-service</name> - <icon src="icon.png"/> - <content src="config.xml" type="application/vnd.agl.service"/> - <description>naviapi binding service</description> - <author>AISIN AW</author> - <license>GPL</license> - <feature name="urn:AGL:widget:required-permission"> - <param name="urn:AGL:permission::public:hidden" value="required" /> - <param name="http://tizen.org/privilege/internal/dbus" value="required" /> - </feature> - <feature name="urn:AGL:widget:provided-api"> - <param name="naviapi" value="ws" /> - </feature> - <feature name="urn:AGL:widget:required-api"> - <param name="lib/libNaviAPIService.so" value="local" /> - </feature> -</widget> diff --git a/include/analyze_request.h b/include/analyze_request.h deleted file mode 100644 index f570a1c..0000000 --- a/include/analyze_request.h +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright 2017 AW SOFTWARE CO.,LTD -// Copyright 2017 AISIN AW CO.,LTD - -#pragma once - -#include <stdbool.h> -#include <stdint.h> -#include <vector> - -#include "genivi_request.h" - -/** - * @brief Analyze requests from BinderClient and create arguments to pass to Genivi API. - */ -class AnalyzeRequest -{ -public: - bool CreateParamsGetPosition( const char* req_json_str, std::vector< int32_t >& Params ); - bool CreateParamsCreateRoute( const char* req_json_str, uint32_t& sessionHdl ); - bool CreateParamsPauseSimulation( const char* req_json_str, uint32_t& sessionHdl ); - bool CreateParamsSetSimulationMode( const char* req_json_str, uint32_t& sessionHdl, bool& simuMode ); - bool CreateParamsCancelRouteCalculation( const char* req_json_str, uint32_t& sessionHdl, uint32_t& routeHdl ); - bool CreateParamsSetWaypoints( const char* req_json_str, uint32_t& sessionHdl, uint32_t& routeHdl, - bool& currentPos, std::vector<Waypoint>& waypointsList ); - bool CreateParamsCalculateRoute( const char* req_json_str, uint32_t& sessionHdl, uint32_t& routeHdl ); - -private: - bool JsonObjectGetSessionHdl( const char* req_json_str, uint32_t& sessionHdl); - bool JsonObjectGetSessionHdlRouteHdl( const char* req_json_str, uint32_t& sessionHdl, uint32_t& routeHdl); -}; - diff --git a/include/binder_reply.h b/include/binder_reply.h deleted file mode 100644 index 44e20d0..0000000 --- a/include/binder_reply.h +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright 2017 AW SOFTWARE CO.,LTD -// Copyright 2017 AISIN AW CO.,LTD - -#pragma once - -#include <stdio.h> -#include <stdbool.h> -#include <string> -#include <map> -#include <vector> -#include <json-c/json.h> - -/** - * @brief Response to return to Binder client. - */ -typedef struct APIResponse_ -{ - bool isSuccess; - std::string errMessage; - json_object* json_data; -}APIResponse; - -/** - * @brief Convert information acquired by Genevi API to JSON format. - */ -class BinderReply -{ -public: - APIResponse ReplyNavicoreGetPosition( std::map<int32_t, double>& posList ); - APIResponse ReplyNavicoreGetAllRoutes( std::vector< uint32_t > &allRoutes ); - APIResponse ReplyNavicoreCreateRoute( uint32_t route ); - APIResponse ReplyNavicoreGetAllSessions( std::map<uint32_t, std::string> &allSessions ); -}; - diff --git a/include/genivi/genivi-navicore-constants.h b/include/genivi/genivi-navicore-constants.h deleted file mode 100644 index 4021006..0000000 --- a/include/genivi/genivi-navicore-constants.h +++ /dev/null @@ -1,199 +0,0 @@ -// Copyright 2017 AISIN AW CO.,LTD - -#ifndef GENIVI_NAVICORE_CONSTANTS_H -#define GENIVI_NAVICORE_CONSTANTS_H - -#define NAVICORE_INVALID 0x0000 -#define NAVICORE_DEFAULT 0xfffe -#define NAVICORE_ALL 0xffff -#define NAVICORE_AVAILABLE 0x0001 -#define NAVICORE_NOT_AVAILABLE 0x0002 -#define NAVICORE_TIME_FORMAT 0x0003 -#define NAVICORE_12H 0x0004 -#define NAVICORE_24H 0x0005 -#define NAVICORE_COORDINATES_FORMAT 0x0006 -#define NAVICORE_DEGREES 0x0007 -#define NAVICORE_MINUTES 0x0008 -#define NAVICORE_SECONDS 0x0009 -#define NAVICORE_TIMESTAMP 0x0010 -#define NAVICORE_TIMEZONE_OFFSET 0x0011 -#define NAVICORE_DAYLIGHT_OFFSET 0x0012 -#define NAVICORE_LOCALE 0x0025 -#define NAVICORE_UNITS_OF_MEASUREMENT 0x0030 -#define NAVICORE_LENGTH 0x0031 -#define NAVICORE_METER 0x0032 -#define NAVICORE_MILE 0x0033 -#define NAVICORE_KM 0x0034 -#define NAVICORE_YARD 0x0035 -#define NAVICORE_FOOT 0x0036 -#define NAVICORE_DISABLED_PROMPT 0x0041 -#define NAVICORE_AUTOMATIC_PROMPT 0x0042 -#define NAVICORE_MANUAL_PROMPT 0x0043 -#define NAVICORE_CRUISE 0x0050 -#define NAVICORE_MANEUVER_APPEARED 0x0051 -#define NAVICORE_PRE_ADVICE 0x0052 -#define NAVICORE_ADVICE 0x0053 -#define NAVICORE_PASSED 0x0054 -#define NAVICORE_ACTIVE 0x0060 -#define NAVICORE_INACTIVE 0x0061 -#define NAVICORE_STRAIGHT_ON 0x0070 -#define NAVICORE_CROSSROAD 0x0071 -#define NAVICORE_ROUNDABOUT 0x0072 -#define NAVICORE_HIGHWAY_ENTER 0x0073 -#define NAVICORE_HIGHWAY_EXIT 0x0074 -#define NAVICORE_FOLLOW_SPECIFIC_LANE 0x0075 -#define NAVICORE_DESTINATION 0x0076 -#define NAVICORE_WAYPOINT 0x0077 -#define NAVICORE_TURN 0x0078 -#define NAVICORE_BIFURCATION 0x0079 -#define NAVICORE_LEFT 0x0080 -#define NAVICORE_SLIGHT_LEFT 0x0081 -#define NAVICORE_HARD_LEFT 0x0082 -#define NAVICORE_RIGHT 0x0083 -#define NAVICORE_SLIGHT_RIGHT 0x0084 -#define NAVICORE_HARD_RIGHT 0x0085 -#define NAVICORE_UTURN_RIGHT 0x0086 -#define NAVICORE_UTURN_LEFT 0x0087 -#define NAVICORE_ALL_MANUAL 0x0090 -#define NAVICORE_ALL_AUTOMATIC 0x0091 -#define NAVICORE_TRAFFIC_MANUAL 0x0092 -#define NAVICORE_OFF_ROUTE_MANUAL 0x0093 -#define NAVICORE_LATITUDE 0x00a0 -#define NAVICORE_LONGITUDE 0x00a1 -#define NAVICORE_ALTITUDE 0x00a2 -#define NAVICORE_HEADING 0x00a3 -#define NAVICORE_SPEED 0x00a4 -#define NAVICORE_CLIMB 0x00a5 -#define NAVICORE_COUNTRY 0x00a6 -#define NAVICORE_STATE 0x00a7 -#define NAVICORE_CITY 0x00a8 -#define NAVICORE_ZIPCODE 0x00a9 -#define NAVICORE_STREET 0x00aa -#define NAVICORE_HOUSENUMBER 0x00ab -#define NAVICORE_CROSSING 0x00ac -#define NAVICORE_DISTRICT 0x00ad -#define NAVICORE_PHONENUMBER 0x00ae -#define NAVICORE_POINAME 0x00af -#define NAVICORE_TOWNCENTER 0x00b0 -#define NAVICORE_LOCATION_INPUT 0x00b1 -#define NAVICORE_FULL_ADDRESS 0x00b2 -#define NAVICORE_COUNTRYCODE 0x00b3 -#define NAVICORE_HOUSENAME 0x00b4 -#define NAVICORE_POSTAL_CODE 0x00b5 -#define NAVICORE_NOT_STARTED 0x0c0 -#define NAVICORE_SEARCHING 0x00c1 -#define NAVICORE_FINISHED 0x00c2 -#define NAVICORE_OK 0x00d0 -#define NAVICORE_UNKNOWN 0x00d1 -#define NAVICORE_AMBIGUOUS 0x00d2 -#define NAVICORE_INCONSISTENT 0x00d3 -#define NAVICORE_GNSS_FIX_STATUS 0x00e0 -#define NAVICORE_DR_STATUS 0x00e1 -#define NAVICORE_MM_STATUS 0x00e2 -#define NAVICORE_SIMULATION_MODE 0x00e3 -#define NAVICORE_MATCH_TYPE 0x00f0 -#define NAVICORE_ON_ROAD 0x00f1 -#define NAVICORE_OFF_ROAD 0x00f2 -#define NAVICORE_ON_FERRY 0x00f3 -#define NAVICORE_IN_TUNNEL 0x00f4 -#define NAVICORE_ON_CARPARK 0x00f5 -#define NAVICORE_NO_FIX 0x0100 -#define NAVICORE_TIME_FIX 0x0101 -#define NAVICORE_2D_FIX 0x0102 -#define NAVICORE_3D_FIX 0x0103 -#define NAVICORE_SEGMENT_ID 0x0110 -#define NAVICORE_DIRECTION_ON_SEGMENT 0x0112 -#define NAVICORE_DISTANCE_ON_SEGMENT 0x0113 -#define NAVICORE_INTERMEDIATE_POINTS 0x0120 -#define NAVICORE_WAYPOINT_TYPE 0x0121 -#define NAVICORE_SOFT_POINT 0x0122 -#define NAVICORE_HARD_POINT 0x0123 -#define NAVICORE_CALCULATION_OK 0x0130 -#define NAVICORE_NO_POSITION 0x0131 -#define NAVICORE_UNMATCHED_POSITION 0x0132 -#define NAVICORE_UNREACHABLE_DESTINATION 0x0133 -#define NAVICORE_UNFULFILLED_PREFERENCE_MODE 0x0134 -#define NAVICORE_LINK_ID 0x0140 -#define NAVICORE_START_LATITUDE 0x0141 -#define NAVICORE_END_LATITUDE 0x0142 -#define NAVICORE_START_LONGITUDE 0x0143 -#define NAVICORE_END_LONGITUDE 0x0144 -#define NAVICORE_START_ALTITUDE 0x0145 -#define NAVICORE_END_ALTITUDE 0x0146 -#define NAVICORE_ROAD_NAME 0x0147 -#define NAVICORE_DISTANCE 0x0148 -#define NAVICORE_TIME 0x0149 -#define NAVICORE_MANEUVER 0x014a -#define NAVICORE_INSTRUCTION 0x014b -#define NAVICORE_BORDER_CROSSING 0x014c -#define NAVICORE_ADDITIONAL_INFORMATION 0x014d -#define NAVICORE_ROAD_NUMBER 0x014e -#define NAVICORE_START_OFFSET 0x014f -#define NAVICORE_FASTEST 0x0160 -#define NAVICORE_SHORTEST 0x0161 -#define NAVICORE_ECOLOGICAL 0x0162 -#define NAVICORE_SCENIC 0x0163 -#define NAVICORE_EASY 0x0164 -#define NAVICORE_BALANCED 0x0166 -#define NAVICORE_CHEAPEST 0x0167 -#define NAVICORE_FERRY 0x0170 -#define NAVICORE_TOLL_ROADS 0x0171 -#define NAVICORE_TUNNELS 0x0172 -#define NAVICORE_HIGHWAYS_MOTORWAYS 0x0173 -#define NAVICORE_VEHICLE_SIZE_LIMIT 0x0174 -#define NAVICORE_CRIME_AREAS 0x0175 -#define NAVICORE_BY_CAR 0x0180 -#define NAVICORE_ON_FOOT 0x0181 -#define NAVICORE_LONG_RANGE_TRAINS 0x0182 -#define NAVICORE_PUBLIC_TRANSPORTATION 0x0183 -#define NAVICORE_BY_BICYCLE 0x0184 -#define NAVICORE_BY_TRUCK 0x0185 -#define NAVICORE_BLOCK_NUMBER 0x0186 -#define NAVICORE_UNIT_NUMBER 0x0187 -#define NAVICORE_BEGIN_STREET 0x0188 -#define NAVICORE_ROAD_INTERSECTION 0x0189 -#define NAVICORE_ARRIVAL_TIME 0x018a -#define NAVICORE_ARRIVAL_DATE 0x018b -#define NAVICORE_DEPARTURE_TIME 0x018c -#define NAVICORE_DEPARTURE_DATE 0x018d -#define NAVICORE_TOTAL_TIME 0x018e -#define NAVICORE_TOTAL_DISTANCE 0x018f -#define NAVICORE_PROHIBIT 0x0190 -#define NAVICORE_AVOID 0x0191 -#define NAVICORE_USE 0x0192 -#define NAVICORE_PREFER 0x0193 -#define NAVICORE_IGNORE 0x0194 -#define NAVICORE_TRAFFIC_REALTIME 0x0200 -#define NAVICORE_TRAFFIC 0x0210 -#define NAVICORE_OFF_ROUTE 0x0211 -#define NAVICORE_MANUAL 0x0212 -#define NAVICORE_SIMULATION_STATUS_NO_SIMULATION 0x0220 -#define NAVICORE_SIMULATION_STATUS_RUNNING 0x0221 -#define NAVICORE_SIMULATION_STATUS_PAUSED 0x0222 -#define NAVICORE_SIMULATION_STATUS_FIXED_POSITION 0x0223 -#define NAVICORE_ROAD_FORM_CHANGE 0x0230 -#define NAVICORE_ROAD_REGULAR 0x0231 -#define NAVICORE_ROAD_HIGHWAY_MOTORWAY 0x0232 -#define NAVICORE_ROAD_FERRY 0x0233 -#define NAVICORE_DIRECTION 0x0240 -#define NAVICORE_EXIT_NUMBER 0x0241 -#define NAVICORE_ROAD_FORM 0x0242 -#define NAVICORE_LANE_INFO 0x0243 -#define NAVICORE_LANE_INFO_BITMASK_STRAIGHT 0x0001 -#define NAVICORE_LANE_INFO_BITMASK_SLIGHTRIGHT 0x0002 -#define NAVICORE_LANE_INFO_BITMASK_RIGHT 0x0004 -#define NAVICORE_LANE_INFO_BITMASK_SHARPRIGHT 0x0008 -#define NAVICORE_LANE_INFO_BITMASK_RIGHTUTURN 0x0010 -#define NAVICORE_LANE_INFO_BITMASK_SLIGHTLEFT 0x0020 -#define NAVICORE_LANE_INFO_BITMASK_LEFT 0x0040 -#define NAVICORE_LANE_INFO_BITMASK_SHARPLEFT 0x0080 -#define NAVICORE_LANE_INFO_BITMASK_LEFTUTURN 0x0100 -#define NAVICORE_DIVIDER_UNDEFINED 0x0250 -#define NAVICORE_DIVIDER_INTERRUPTEDLONG 0x0251 -#define NAVICORE_DIVIDER_INTERRUPTEDSHORT 0x0252 -#define NAVICORE_DIVIDER_SOLIDSINGLE 0x0253 -#define NAVICORE_DIVIDER_SOLIDDOUBLE 0x0254 -#define NAVICORE_DIVIDER_SOLIDINTERRUPTED 0x0255 -#define NAVICORE_DIVIDER_INTERRUPTEDSOLID 0x0256 - -#endif diff --git a/include/genivi/genivi-navigationcore-proxy.h b/include/genivi/genivi-navigationcore-proxy.h deleted file mode 100644 index 2322fa0..0000000 --- a/include/genivi/genivi-navigationcore-proxy.h +++ /dev/null @@ -1,1147 +0,0 @@ - -/* - * This file was automatically generated by dbusxx-xml2cpp; DO NOT EDIT! - */ - -#ifndef __dbusxx__genivi_navigationcore_proxy_h__PROXY_MARSHAL_H -#define __dbusxx__genivi_navigationcore_proxy_h__PROXY_MARSHAL_H - -#include <dbus-c++-1/dbus-c++/dbus.h> -#include <cassert> - -namespace org { -namespace genivi { -namespace navigationcore { - -class Session_proxy -: public ::DBus::InterfaceProxy -{ -public: - - Session_proxy() - : ::DBus::InterfaceProxy("org.genivi.navigationcore.Session") - { - connect_signal(Session_proxy, SessionDeleted, _SessionDeleted_stub); - } - -public: - - /* properties exported by this interface */ -public: - - /* methods exported by this interface, - * this functions will invoke the corresponding methods on the remote objects - */ - ::DBus::Struct< uint16_t, uint16_t, uint16_t, std::string > SessionGetVersion() - { - ::DBus::CallMessage call; - call.member("GetVersion"); - ::DBus::Message ret = invoke_method (call); - ::DBus::MessageIter ri = ret.reader(); - - ::DBus::Struct< uint16_t, uint16_t, uint16_t, std::string > argout; - ri >> argout; - return argout; - } - - uint32_t CreateSession(const std::string& client) - { - ::DBus::CallMessage call; - ::DBus::MessageIter wi = call.writer(); - - wi << client; - call.member("CreateSession"); - ::DBus::Message ret = invoke_method (call); - ::DBus::MessageIter ri = ret.reader(); - - uint32_t argout; - ri >> argout; - return argout; - } - - void DeleteSession(const uint32_t& sessionHandle) - { - ::DBus::CallMessage call; - ::DBus::MessageIter wi = call.writer(); - - wi << sessionHandle; - call.member("DeleteSession"); - ::DBus::Message ret = invoke_method (call); - } - - int32_t GetSessionStatus(const uint32_t& sessionHandle) - { - ::DBus::CallMessage call; - ::DBus::MessageIter wi = call.writer(); - - wi << sessionHandle; - call.member("GetSessionStatus"); - ::DBus::Message ret = invoke_method (call); - ::DBus::MessageIter ri = ret.reader(); - - int32_t argout; - ri >> argout; - return argout; - } - - std::vector< ::DBus::Struct< uint32_t, std::string > > GetAllSessions() - { - ::DBus::CallMessage call; - call.member("GetAllSessions"); - ::DBus::Message ret = invoke_method (call); - ::DBus::MessageIter ri = ret.reader(); - - std::vector< ::DBus::Struct< uint32_t, std::string > > argout; - ri >> argout; - return argout; - } - - -public: - - /* signal handlers for this interface - */ - virtual void SessionDeleted(const uint32_t& sessionHandle) = 0; - -private: - - /* unmarshalers (to unpack the DBus message before calling the actual signal handler) - */ - void _SessionDeleted_stub(const ::DBus::SignalMessage &sig) - { - ::DBus::MessageIter ri = sig.reader(); - - uint32_t sessionHandle; - ri >> sessionHandle; - SessionDeleted(sessionHandle); - } -}; - -} } } -namespace org { -namespace genivi { -namespace navigationcore { - -class Routing_proxy -: public ::DBus::InterfaceProxy -{ -public: - - Routing_proxy() - : ::DBus::InterfaceProxy("org.genivi.navigationcore.Routing") - { - connect_signal(Routing_proxy, RouteDeleted, _RouteDeleted_stub); - connect_signal(Routing_proxy, RouteCalculationCancelled, _RouteCalculationCancelled_stub); - connect_signal(Routing_proxy, RouteCalculationSuccessful, _RouteCalculationSuccessful_stub); - connect_signal(Routing_proxy, RouteCalculationFailed, _RouteCalculationFailed_stub); - connect_signal(Routing_proxy, RouteCalculationProgressUpdate, _RouteCalculationProgressUpdate_stub); - connect_signal(Routing_proxy, AlternativeRoutesAvailable, _AlternativeRoutesAvailable_stub); - } - -public: - - /* properties exported by this interface */ -public: - - /* methods exported by this interface, - * this functions will invoke the corresponding methods on the remote objects - */ - ::DBus::Struct< uint16_t, uint16_t, uint16_t, std::string > RoutingGetVersion() - { - ::DBus::CallMessage call; - call.member("GetVersion"); - ::DBus::Message ret = invoke_method (call); - ::DBus::MessageIter ri = ret.reader(); - - ::DBus::Struct< uint16_t, uint16_t, uint16_t, std::string > argout; - ri >> argout; - return argout; - } - - uint32_t CreateRoute(const uint32_t& sessionHandle) - { - ::DBus::CallMessage call; - ::DBus::MessageIter wi = call.writer(); - - wi << sessionHandle; - call.member("CreateRoute"); - ::DBus::Message ret = invoke_method (call); - ::DBus::MessageIter ri = ret.reader(); - - uint32_t argout; - ri >> argout; - return argout; - } - - void DeleteRoute(const uint32_t& sessionHandle, const uint32_t& routeHandle) - { - ::DBus::CallMessage call; - ::DBus::MessageIter wi = call.writer(); - - wi << sessionHandle; - wi << routeHandle; - call.member("DeleteRoute"); - ::DBus::Message ret = invoke_method (call); - } - - void SetCostModel(const uint32_t& sessionHandle, const uint32_t& routeHandle, const int32_t& costModel) - { - ::DBus::CallMessage call; - ::DBus::MessageIter wi = call.writer(); - - wi << sessionHandle; - wi << routeHandle; - wi << costModel; - call.member("SetCostModel"); - ::DBus::Message ret = invoke_method (call); - } - - int32_t GetCostModel(const uint32_t& routeHandle) - { - ::DBus::CallMessage call; - ::DBus::MessageIter wi = call.writer(); - - wi << routeHandle; - call.member("GetCostModel"); - ::DBus::Message ret = invoke_method (call); - ::DBus::MessageIter ri = ret.reader(); - - int32_t argout; - ri >> argout; - return argout; - } - - std::vector< int32_t > GetSupportedCostModels() - { - ::DBus::CallMessage call; - call.member("GetSupportedCostModels"); - ::DBus::Message ret = invoke_method (call); - ::DBus::MessageIter ri = ret.reader(); - - std::vector< int32_t > argout; - ri >> argout; - return argout; - } - - void SetRoutePreferences(const uint32_t& sessionHandle, const uint32_t& routeHandle, const std::string& countryCode, const std::vector< ::DBus::Struct< int32_t, int32_t > >& roadPreferenceList, const std::vector< ::DBus::Struct< int32_t, int32_t > >& conditionPreferenceList) - { - ::DBus::CallMessage call; - ::DBus::MessageIter wi = call.writer(); - - wi << sessionHandle; - wi << routeHandle; - wi << countryCode; - wi << roadPreferenceList; - wi << conditionPreferenceList; - call.member("SetRoutePreferences"); - ::DBus::Message ret = invoke_method (call); - } - - void GetRoutePreferences(const uint32_t& routeHandle, const std::string& countryCode, std::vector< ::DBus::Struct< int32_t, int32_t > >& roadPreferenceList, std::vector< ::DBus::Struct< int32_t, int32_t > >& conditionPreferenceList) - { - ::DBus::CallMessage call; - ::DBus::MessageIter wi = call.writer(); - - wi << routeHandle; - wi << countryCode; - call.member("GetRoutePreferences"); - ::DBus::Message ret = invoke_method (call); - ::DBus::MessageIter ri = ret.reader(); - - ri >> roadPreferenceList; - ri >> conditionPreferenceList; - } - - void GetSupportedRoutePreferences(std::vector< ::DBus::Struct< int32_t, int32_t > >& routePreferencesList, std::vector< ::DBus::Struct< int32_t, int32_t > >& conditionPreferenceList) - { - ::DBus::CallMessage call; - call.member("GetSupportedRoutePreferences"); - ::DBus::Message ret = invoke_method (call); - ::DBus::MessageIter ri = ret.reader(); - - ri >> routePreferencesList; - ri >> conditionPreferenceList; - } - - void SetRouteSchedule(const uint32_t& sessionHandle, const uint32_t& routeHandle, const std::map< int32_t, uint32_t >& routeSchedule) - { - ::DBus::CallMessage call; - ::DBus::MessageIter wi = call.writer(); - - wi << sessionHandle; - wi << routeHandle; - wi << routeSchedule; - call.member("SetRouteSchedule"); - ::DBus::Message ret = invoke_method (call); - } - - std::map< int32_t, uint32_t > GetRouteSchedule(const uint32_t& routeHandle, const std::vector< int32_t >& valuesToReturn) - { - ::DBus::CallMessage call; - ::DBus::MessageIter wi = call.writer(); - - wi << routeHandle; - wi << valuesToReturn; - call.member("GetRouteSchedule"); - ::DBus::Message ret = invoke_method (call); - ::DBus::MessageIter ri = ret.reader(); - - std::map< int32_t, uint32_t > argout; - ri >> argout; - return argout; - } - - void SetTransportationMeans(const uint32_t& sessionHandle, const uint32_t& routeHandle, const std::vector< int32_t >& transportationMeansList) - { - ::DBus::CallMessage call; - ::DBus::MessageIter wi = call.writer(); - - wi << sessionHandle; - wi << routeHandle; - wi << transportationMeansList; - call.member("SetTransportationMeans"); - ::DBus::Message ret = invoke_method (call); - } - - std::vector< int32_t > GetTransportationMeans(const uint32_t& routeHandle) - { - ::DBus::CallMessage call; - ::DBus::MessageIter wi = call.writer(); - - wi << routeHandle; - call.member("GetTransportationMeans"); - ::DBus::Message ret = invoke_method (call); - ::DBus::MessageIter ri = ret.reader(); - - std::vector< int32_t > argout; - ri >> argout; - return argout; - } - - std::vector< int32_t > GetSupportedTransportationMeans() - { - ::DBus::CallMessage call; - call.member("GetSupportedTransportationMeans"); - ::DBus::Message ret = invoke_method (call); - ::DBus::MessageIter ri = ret.reader(); - - std::vector< int32_t > argout; - ri >> argout; - return argout; - } - - void SetExcludedAreas(const uint32_t& sessionHandle, const uint32_t& routeHandle, const std::vector< std::vector< ::DBus::Struct< double, double > > >& excludedAreas) - { - ::DBus::CallMessage call; - ::DBus::MessageIter wi = call.writer(); - - wi << sessionHandle; - wi << routeHandle; - wi << excludedAreas; - call.member("SetExcludedAreas"); - ::DBus::Message ret = invoke_method (call); - } - - std::vector< std::vector< ::DBus::Struct< double, double > > > GetExcludedAreas(const uint32_t& routeHandle) - { - ::DBus::CallMessage call; - ::DBus::MessageIter wi = call.writer(); - - wi << routeHandle; - call.member("GetExcludedAreas"); - ::DBus::Message ret = invoke_method (call); - ::DBus::MessageIter ri = ret.reader(); - - std::vector< std::vector< ::DBus::Struct< double, double > > > argout; - ri >> argout; - return argout; - } - - void SetWaypoints(const uint32_t& sessionHandle, const uint32_t& routeHandle, const bool& startFromCurrentPosition, const std::vector< std::map< int32_t, ::DBus::Struct< uint8_t, ::DBus::Variant > > >& waypointsList) - { - ::DBus::CallMessage call; - ::DBus::MessageIter wi = call.writer(); - - wi << sessionHandle; - wi << routeHandle; - wi << startFromCurrentPosition; - wi << waypointsList; - call.member("SetWaypoints"); - ::DBus::Message ret = invoke_method (call); - } - - void GetWaypoints(const uint32_t& routeHandle, bool& startFromCurrentPosition, std::vector< std::map< int32_t, ::DBus::Struct< uint8_t, ::DBus::Variant > > >& waypointsList) - { - ::DBus::CallMessage call; - ::DBus::MessageIter wi = call.writer(); - - wi << routeHandle; - call.member("GetWaypoints"); - ::DBus::Message ret = invoke_method (call); - ::DBus::MessageIter ri = ret.reader(); - - ri >> startFromCurrentPosition; - ri >> waypointsList; - } - - void CalculateRoute(const uint32_t& sessionHandle, const uint32_t& routeHandle) - { - ::DBus::CallMessage call; - ::DBus::MessageIter wi = call.writer(); - - wi << sessionHandle; - wi << routeHandle; - call.member("CalculateRoute"); - ::DBus::Message ret = invoke_method (call); - } - - void CancelRouteCalculation(const uint32_t& sessionHandle, const uint32_t& routeHandle) - { - ::DBus::CallMessage call; - ::DBus::MessageIter wi = call.writer(); - - wi << sessionHandle; - wi << routeHandle; - call.member("CancelRouteCalculation"); - ::DBus::Message ret = invoke_method (call); - } - - std::vector< uint32_t > CalculateRoutes(const uint32_t& sessionHandle, const std::vector< uint32_t >& calculatedRoutesList) - { - ::DBus::CallMessage call; - ::DBus::MessageIter wi = call.writer(); - - wi << sessionHandle; - wi << calculatedRoutesList; - call.member("CalculateRoutes"); - ::DBus::Message ret = invoke_method (call); - ::DBus::MessageIter ri = ret.reader(); - - std::vector< uint32_t > argout; - ri >> argout; - return argout; - } - - void GetRouteSegments(const uint32_t& routeHandle, const int16_t& detailLevel, const std::vector< int32_t >& valuesToReturn, const uint32_t& numberOfSegments, const uint32_t& offset, uint32_t& totalNumberOfSegments, std::vector< std::map< int32_t, ::DBus::Struct< uint8_t, ::DBus::Variant > > >& routeSegments) - { - ::DBus::CallMessage call; - ::DBus::MessageIter wi = call.writer(); - - wi << routeHandle; - wi << detailLevel; - wi << valuesToReturn; - wi << numberOfSegments; - wi << offset; - call.member("GetRouteSegments"); - ::DBus::Message ret = invoke_method (call); - ::DBus::MessageIter ri = ret.reader(); - - ri >> totalNumberOfSegments; - ri >> routeSegments; - } - - std::map< int32_t, ::DBus::Struct< uint8_t, ::DBus::Variant > > GetRouteOverview(const uint32_t& routeHandle, const std::vector< int32_t >& valuesToReturn) - { - ::DBus::CallMessage call; - ::DBus::MessageIter wi = call.writer(); - - wi << routeHandle; - wi << valuesToReturn; - call.member("GetRouteOverview"); - ::DBus::Message ret = invoke_method (call); - ::DBus::MessageIter ri = ret.reader(); - - std::map< int32_t, ::DBus::Struct< uint8_t, ::DBus::Variant > > argout; - ri >> argout; - return argout; - } - - ::DBus::Struct< ::DBus::Struct< double, double >, ::DBus::Struct< double, double > > GetRouteBoundingBox(const uint32_t& routeHandle) - { - ::DBus::CallMessage call; - ::DBus::MessageIter wi = call.writer(); - - wi << routeHandle; - call.member("GetRouteBoundingBox"); - ::DBus::Message ret = invoke_method (call); - ::DBus::MessageIter ri = ret.reader(); - - ::DBus::Struct< ::DBus::Struct< double, double >, ::DBus::Struct< double, double > > argout; - ri >> argout; - return argout; - } - - std::vector< uint32_t > GetAllRoutes() - { - ::DBus::CallMessage call; - call.member("GetAllRoutes"); - ::DBus::Message ret = invoke_method (call); - ::DBus::MessageIter ri = ret.reader(); - - std::vector< uint32_t > argout; - ri >> argout; - return argout; - } - - void SetBlockedRouteStretches(const uint32_t& sessionHandle, const uint32_t& routeHandle, const std::vector< ::DBus::Struct< uint32_t, uint32_t > >& blockParameters) - { - ::DBus::CallMessage call; - ::DBus::MessageIter wi = call.writer(); - - wi << sessionHandle; - wi << routeHandle; - wi << blockParameters; - call.member("SetBlockedRouteStretches"); - ::DBus::Message ret = invoke_method (call); - } - - std::vector< ::DBus::Struct< uint32_t, uint32_t > > GetBlockedRouteStretches(const uint32_t& routeHandle) - { - ::DBus::CallMessage call; - ::DBus::MessageIter wi = call.writer(); - - wi << routeHandle; - call.member("GetBlockedRouteStretches"); - ::DBus::Message ret = invoke_method (call); - ::DBus::MessageIter ri = ret.reader(); - - std::vector< ::DBus::Struct< uint32_t, uint32_t > > argout; - ri >> argout; - return argout; - } - - -public: - - /* signal handlers for this interface - */ - virtual void RouteDeleted(const uint32_t& routeHandle) = 0; - virtual void RouteCalculationCancelled(const uint32_t& routeHandle) = 0; - virtual void RouteCalculationSuccessful(const uint32_t& routeHandle, const std::map< int32_t, int32_t >& unfullfilledPreferences) = 0; - virtual void RouteCalculationFailed(const uint32_t& routeHandle, const int32_t& errorCode, const std::map< int32_t, int32_t >& unfullfilledPreferences) = 0; - virtual void RouteCalculationProgressUpdate(const uint32_t& routeHandle, const int32_t& status, const uint8_t& percentage) = 0; - virtual void AlternativeRoutesAvailable(const std::vector< uint32_t >& routeHandlesList) = 0; - -private: - - /* unmarshalers (to unpack the DBus message before calling the actual signal handler) - */ - void _RouteDeleted_stub(const ::DBus::SignalMessage &sig) - { - ::DBus::MessageIter ri = sig.reader(); - - uint32_t routeHandle; - ri >> routeHandle; - RouteDeleted(routeHandle); - } - void _RouteCalculationCancelled_stub(const ::DBus::SignalMessage &sig) - { - ::DBus::MessageIter ri = sig.reader(); - - uint32_t routeHandle; - ri >> routeHandle; - RouteCalculationCancelled(routeHandle); - } - void _RouteCalculationSuccessful_stub(const ::DBus::SignalMessage &sig) - { - ::DBus::MessageIter ri = sig.reader(); - - uint32_t routeHandle; - ri >> routeHandle; - std::map< int32_t, int32_t > unfullfilledPreferences; - ri >> unfullfilledPreferences; - RouteCalculationSuccessful(routeHandle, unfullfilledPreferences); - } - void _RouteCalculationFailed_stub(const ::DBus::SignalMessage &sig) - { - ::DBus::MessageIter ri = sig.reader(); - - uint32_t routeHandle; - ri >> routeHandle; - int32_t errorCode; - ri >> errorCode; - std::map< int32_t, int32_t > unfullfilledPreferences; - ri >> unfullfilledPreferences; - RouteCalculationFailed(routeHandle, errorCode, unfullfilledPreferences); - } - void _RouteCalculationProgressUpdate_stub(const ::DBus::SignalMessage &sig) - { - ::DBus::MessageIter ri = sig.reader(); - - uint32_t routeHandle; - ri >> routeHandle; - int32_t status; - ri >> status; - uint8_t percentage; - ri >> percentage; - RouteCalculationProgressUpdate(routeHandle, status, percentage); - } - void _AlternativeRoutesAvailable_stub(const ::DBus::SignalMessage &sig) - { - ::DBus::MessageIter ri = sig.reader(); - - std::vector< uint32_t > routeHandlesList; - ri >> routeHandlesList; - AlternativeRoutesAvailable(routeHandlesList); - } -}; - -} } } -namespace org { -namespace genivi { -namespace navigationcore { - -class MapMatchedPosition_proxy -: public ::DBus::InterfaceProxy -{ -public: - - MapMatchedPosition_proxy() - : ::DBus::InterfaceProxy("org.genivi.navigationcore.MapMatchedPosition") - { - connect_signal(MapMatchedPosition_proxy, SimulationStatusChanged, _SimulationStatusChanged_stub); - connect_signal(MapMatchedPosition_proxy, SimulationSpeedChanged, _SimulationSpeedChanged_stub); - connect_signal(MapMatchedPosition_proxy, PositionUpdate, _PositionUpdate_stub); - connect_signal(MapMatchedPosition_proxy, AddressUpdate, _AddressUpdate_stub); - connect_signal(MapMatchedPosition_proxy, PositionOnSegmentUpdate, _PositionOnSegmentUpdate_stub); - connect_signal(MapMatchedPosition_proxy, StatusUpdate, _StatusUpdate_stub); - connect_signal(MapMatchedPosition_proxy, OffRoadPositionChanged, _OffRoadPositionChanged_stub); - } - -public: - - /* properties exported by this interface */ -public: - - /* methods exported by this interface, - * this functions will invoke the corresponding methods on the remote objects - */ - ::DBus::Struct< uint16_t, uint16_t, uint16_t, std::string > MapMatchedPositionGetVersion() - { - ::DBus::CallMessage call; - call.member("GetVersion"); - ::DBus::Message ret = invoke_method (call); - ::DBus::MessageIter ri = ret.reader(); - - ::DBus::Struct< uint16_t, uint16_t, uint16_t, std::string > argout; - ri >> argout; - return argout; - } - - void SetSimulationMode(const uint32_t& sessionHandle, const bool& activate) - { - ::DBus::CallMessage call; - ::DBus::MessageIter wi = call.writer(); - - wi << sessionHandle; - wi << activate; - call.member("SetSimulationMode"); - ::DBus::Message ret = invoke_method (call); - } - - int32_t GetSimulationStatus() - { - ::DBus::CallMessage call; - call.member("GetSimulationStatus"); - ::DBus::Message ret = invoke_method (call); - ::DBus::MessageIter ri = ret.reader(); - - int32_t argout; - ri >> argout; - return argout; - } - - void AddSimulationStatusListener() - { - ::DBus::CallMessage call; - call.member("AddSimulationStatusListener"); - ::DBus::Message ret = invoke_method (call); - } - - void RemoveSimulationStatusListener() - { - ::DBus::CallMessage call; - call.member("RemoveSimulationStatusListener"); - ::DBus::Message ret = invoke_method (call); - } - - void SetSimulationSpeed(const uint32_t& sessionHandle, const uint8_t& speedFactor) - { - ::DBus::CallMessage call; - ::DBus::MessageIter wi = call.writer(); - - wi << sessionHandle; - wi << speedFactor; - call.member("SetSimulationSpeed"); - ::DBus::Message ret = invoke_method (call); - } - - uint8_t GetSimulationSpeed() - { - ::DBus::CallMessage call; - call.member("GetSimulationSpeed"); - ::DBus::Message ret = invoke_method (call); - ::DBus::MessageIter ri = ret.reader(); - - uint8_t argout; - ri >> argout; - return argout; - } - - void AddSimulationSpeedListener() - { - ::DBus::CallMessage call; - call.member("AddSimulationSpeedListener"); - ::DBus::Message ret = invoke_method (call); - } - - void RemoveSimulationSpeedListener() - { - ::DBus::CallMessage call; - call.member("RemoveSimulationSpeedListener"); - ::DBus::Message ret = invoke_method (call); - } - - void StartSimulation(const uint32_t& sessionHandle) - { - ::DBus::CallMessage call; - ::DBus::MessageIter wi = call.writer(); - - wi << sessionHandle; - call.member("StartSimulation"); - ::DBus::Message ret = invoke_method (call); - } - - void PauseSimulation(const uint32_t& sessionHandle) - { - ::DBus::CallMessage call; - ::DBus::MessageIter wi = call.writer(); - - wi << sessionHandle; - call.member("PauseSimulation"); - ::DBus::Message ret = invoke_method (call); - } - - std::map< int32_t, ::DBus::Struct< uint8_t, ::DBus::Variant > > GetPosition(const std::vector< int32_t >& valuesToReturn) - { - ::DBus::CallMessage call; - ::DBus::MessageIter wi = call.writer(); - - wi << valuesToReturn; - call.member("GetPosition"); - ::DBus::Message ret = invoke_method (call); - ::DBus::MessageIter ri = ret.reader(); - - std::map< int32_t, ::DBus::Struct< uint8_t, ::DBus::Variant > > argout; - ri >> argout; - return argout; - } - - void SetPosition(const uint32_t& sessionHandle, const std::map< int32_t, ::DBus::Struct< uint8_t, ::DBus::Variant > >& position) - { - ::DBus::CallMessage call; - ::DBus::MessageIter wi = call.writer(); - - wi << sessionHandle; - wi << position; - call.member("SetPosition"); - ::DBus::Message ret = invoke_method (call); - } - - std::map< int32_t, ::DBus::Struct< uint8_t, ::DBus::Variant > > GetAddress(const std::vector< int32_t >& valuesToReturn) - { - ::DBus::CallMessage call; - ::DBus::MessageIter wi = call.writer(); - - wi << valuesToReturn; - call.member("GetAddress"); - ::DBus::Message ret = invoke_method (call); - ::DBus::MessageIter ri = ret.reader(); - - std::map< int32_t, ::DBus::Struct< uint8_t, ::DBus::Variant > > argout; - ri >> argout; - return argout; - } - - std::map< int32_t, ::DBus::Struct< uint8_t, ::DBus::Variant > > GetPositionOnSegment(const std::vector< int32_t >& valuesToReturn) - { - ::DBus::CallMessage call; - ::DBus::MessageIter wi = call.writer(); - - wi << valuesToReturn; - call.member("GetPositionOnSegment"); - ::DBus::Message ret = invoke_method (call); - ::DBus::MessageIter ri = ret.reader(); - - std::map< int32_t, ::DBus::Struct< uint8_t, ::DBus::Variant > > argout; - ri >> argout; - return argout; - } - - std::map< int32_t, ::DBus::Struct< uint8_t, ::DBus::Variant > > GetStatus(const std::vector< int32_t >& valuesToReturn) - { - ::DBus::CallMessage call; - ::DBus::MessageIter wi = call.writer(); - - wi << valuesToReturn; - call.member("GetStatus"); - ::DBus::Message ret = invoke_method (call); - ::DBus::MessageIter ri = ret.reader(); - - std::map< int32_t, ::DBus::Struct< uint8_t, ::DBus::Variant > > argout; - ri >> argout; - return argout; - } - - -public: - - /* signal handlers for this interface - */ - virtual void SimulationStatusChanged(const int32_t& simulationStatus) = 0; - virtual void SimulationSpeedChanged(const uint8_t& speedFactor) = 0; - virtual void PositionUpdate(const std::vector< int32_t >& changedValues) = 0; - virtual void AddressUpdate(const std::vector< int32_t >& changedValues) = 0; - virtual void PositionOnSegmentUpdate(const std::vector< int32_t >& changedValues) = 0; - virtual void StatusUpdate(const std::vector< int32_t >& changedValues) = 0; - virtual void OffRoadPositionChanged(const uint32_t& distance, const int32_t& direction) = 0; - -private: - - /* unmarshalers (to unpack the DBus message before calling the actual signal handler) - */ - void _SimulationStatusChanged_stub(const ::DBus::SignalMessage &sig) - { - ::DBus::MessageIter ri = sig.reader(); - - int32_t simulationStatus; - ri >> simulationStatus; - SimulationStatusChanged(simulationStatus); - } - void _SimulationSpeedChanged_stub(const ::DBus::SignalMessage &sig) - { - ::DBus::MessageIter ri = sig.reader(); - - uint8_t speedFactor; - ri >> speedFactor; - SimulationSpeedChanged(speedFactor); - } - void _PositionUpdate_stub(const ::DBus::SignalMessage &sig) - { - ::DBus::MessageIter ri = sig.reader(); - - std::vector< int32_t > changedValues; - ri >> changedValues; - PositionUpdate(changedValues); - } - void _AddressUpdate_stub(const ::DBus::SignalMessage &sig) - { - ::DBus::MessageIter ri = sig.reader(); - - std::vector< int32_t > changedValues; - ri >> changedValues; - AddressUpdate(changedValues); - } - void _PositionOnSegmentUpdate_stub(const ::DBus::SignalMessage &sig) - { - ::DBus::MessageIter ri = sig.reader(); - - std::vector< int32_t > changedValues; - ri >> changedValues; - PositionOnSegmentUpdate(changedValues); - } - void _StatusUpdate_stub(const ::DBus::SignalMessage &sig) - { - ::DBus::MessageIter ri = sig.reader(); - - std::vector< int32_t > changedValues; - ri >> changedValues; - StatusUpdate(changedValues); - } - void _OffRoadPositionChanged_stub(const ::DBus::SignalMessage &sig) - { - ::DBus::MessageIter ri = sig.reader(); - - uint32_t distance; - ri >> distance; - int32_t direction; - ri >> direction; - OffRoadPositionChanged(distance, direction); - } -}; - -} } } -namespace org { -namespace genivi { -namespace navigationcore { - -class Guidance_proxy -: public ::DBus::InterfaceProxy -{ -public: - - Guidance_proxy() - : ::DBus::InterfaceProxy("org.genivi.navigationcore.Guidance") - { - connect_signal(Guidance_proxy, VehicleLeftTheRoadNetwork, _VehicleLeftTheRoadNetwork_stub); - connect_signal(Guidance_proxy, GuidanceStatusChanged, _GuidanceStatusChanged_stub); - connect_signal(Guidance_proxy, WaypointReached, _WaypointReached_stub); - connect_signal(Guidance_proxy, ManeuverChanged, _ManeuverChanged_stub); - connect_signal(Guidance_proxy, PositionOnRouteChanged, _PositionOnRouteChanged_stub); - connect_signal(Guidance_proxy, VehicleLeftTheRoute, _VehicleLeftTheRoute_stub); - connect_signal(Guidance_proxy, PositionToRouteChanged, _PositionToRouteChanged_stub); - connect_signal(Guidance_proxy, ActiveRouteChanged, _ActiveRouteChanged_stub); - } - -public: - - /* properties exported by this interface */ -public: - - /* methods exported by this interface, - * this functions will invoke the corresponding methods on the remote objects - */ - ::DBus::Struct< uint16_t, uint16_t, uint16_t, std::string > GuidanceGetVersion() - { - ::DBus::CallMessage call; - call.member("GetVersion"); - ::DBus::Message ret = invoke_method (call); - ::DBus::MessageIter ri = ret.reader(); - - ::DBus::Struct< uint16_t, uint16_t, uint16_t, std::string > argout; - ri >> argout; - return argout; - } - - void StartGuidance(const uint32_t& sessionHandle, const uint32_t& routeHandle) - { - ::DBus::CallMessage call; - ::DBus::MessageIter wi = call.writer(); - - wi << sessionHandle; - wi << routeHandle; - call.member("StartGuidance"); - ::DBus::Message ret = invoke_method (call); - } - - void StopGuidance(const uint32_t& sessionHandle) - { - ::DBus::CallMessage call; - ::DBus::MessageIter wi = call.writer(); - - wi << sessionHandle; - call.member("StopGuidance"); - ::DBus::Message ret = invoke_method (call); - } - - void SetVoiceGuidance(const bool& activate, const std::string& voice) - { - ::DBus::CallMessage call; - ::DBus::MessageIter wi = call.writer(); - - wi << activate; - wi << voice; - call.member("SetVoiceGuidance"); - ::DBus::Message ret = invoke_method (call); - } - - void GetGuidanceDetails(bool& voiceGuidance, bool& vehicleOnTheRoad, bool& isDestinationReached, int32_t& maneuver) - { - ::DBus::CallMessage call; - call.member("GetGuidanceDetails"); - ::DBus::Message ret = invoke_method (call); - ::DBus::MessageIter ri = ret.reader(); - - ri >> voiceGuidance; - ri >> vehicleOnTheRoad; - ri >> isDestinationReached; - ri >> maneuver; - } - - void PlayVoiceManeuver() - { - ::DBus::CallMessage call; - call.member("PlayVoiceManeuver"); - ::DBus::Message ret = invoke_method (call); - } - - void GetWaypointInformation(const uint16_t& requestedNumberOfWaypoints, uint16_t& numberOfWaypoints, std::vector< ::DBus::Struct< uint32_t, uint32_t, int32_t, int32_t, int16_t, int16_t, bool, uint16_t > >& waypointsList) - { - ::DBus::CallMessage call; - ::DBus::MessageIter wi = call.writer(); - - wi << requestedNumberOfWaypoints; - call.member("GetWaypointInformation"); - ::DBus::Message ret = invoke_method (call); - ::DBus::MessageIter ri = ret.reader(); - - ri >> numberOfWaypoints; - ri >> waypointsList; - } - - void GetDestinationInformation(uint32_t& offset, uint32_t& travelTime, int32_t& direction, int32_t& side, int16_t& timeZone, int16_t& daylightSavingTime) - { - ::DBus::CallMessage call; - call.member("GetDestinationInformation"); - ::DBus::Message ret = invoke_method (call); - ::DBus::MessageIter ri = ret.reader(); - - ri >> offset; - ri >> travelTime; - ri >> direction; - ri >> side; - ri >> timeZone; - ri >> daylightSavingTime; - } - - void GetManeuversList(const uint16_t& requestedNumberOfManeuvers, const uint32_t& maneuverOffset, uint16_t& numberOfManeuvers, std::vector< ::DBus::Struct< std::string, std::string, uint16_t, int32_t, uint32_t, std::vector< ::DBus::Struct< uint32_t, uint32_t, int32_t, int32_t, std::map< int32_t, ::DBus::Struct< uint8_t, ::DBus::Variant > > > > > >& maneuversList) - { - ::DBus::CallMessage call; - ::DBus::MessageIter wi = call.writer(); - - wi << requestedNumberOfManeuvers; - wi << maneuverOffset; - call.member("GetManeuversList"); - ::DBus::Message ret = invoke_method (call); - ::DBus::MessageIter ri = ret.reader(); - - ri >> numberOfManeuvers; - ri >> maneuversList; - } - - void SetRouteCalculationMode(const uint32_t& sessionHandle, const int32_t& routeCalculationMode) - { - ::DBus::CallMessage call; - ::DBus::MessageIter wi = call.writer(); - - wi << sessionHandle; - wi << routeCalculationMode; - call.member("SetRouteCalculationMode"); - ::DBus::Message ret = invoke_method (call); - } - - void SkipNextManeuver(const uint32_t& sessionHandle) - { - ::DBus::CallMessage call; - ::DBus::MessageIter wi = call.writer(); - - wi << sessionHandle; - call.member("SkipNextManeuver"); - ::DBus::Message ret = invoke_method (call); - } - - void GetGuidanceStatus(int32_t& guidanceStatus, uint32_t& routeHandle) - { - ::DBus::CallMessage call; - call.member("GetGuidanceStatus"); - ::DBus::Message ret = invoke_method (call); - ::DBus::MessageIter ri = ret.reader(); - - ri >> guidanceStatus; - ri >> routeHandle; - } - - void SetVoiceGuidanceSettings(const int32_t& promptMode) - { - ::DBus::CallMessage call; - ::DBus::MessageIter wi = call.writer(); - - wi << promptMode; - call.member("SetVoiceGuidanceSettings"); - ::DBus::Message ret = invoke_method (call); - } - - int32_t GetVoiceGuidanceSettings() - { - ::DBus::CallMessage call; - call.member("GetVoiceGuidanceSettings"); - ::DBus::Message ret = invoke_method (call); - ::DBus::MessageIter ri = ret.reader(); - - int32_t argout; - ri >> argout; - return argout; - } - - -public: - - /* signal handlers for this interface - */ - virtual void VehicleLeftTheRoadNetwork() = 0; - virtual void GuidanceStatusChanged(const int32_t& guidanceStatus, const uint32_t& routeHandle) = 0; - virtual void WaypointReached(const bool& isDestination) = 0; - virtual void ManeuverChanged(const int32_t& maneuver) = 0; - virtual void PositionOnRouteChanged(const uint32_t& offsetOnRoute) = 0; - virtual void VehicleLeftTheRoute() = 0; - virtual void PositionToRouteChanged(const uint32_t& distance, const int32_t& direction) = 0; - virtual void ActiveRouteChanged(const int32_t& changeCause) = 0; - -private: - - /* unmarshalers (to unpack the DBus message before calling the actual signal handler) - */ - void _VehicleLeftTheRoadNetwork_stub(const ::DBus::SignalMessage &sig) - { - VehicleLeftTheRoadNetwork(); - } - void _GuidanceStatusChanged_stub(const ::DBus::SignalMessage &sig) - { - ::DBus::MessageIter ri = sig.reader(); - - int32_t guidanceStatus; - ri >> guidanceStatus; - uint32_t routeHandle; - ri >> routeHandle; - GuidanceStatusChanged(guidanceStatus, routeHandle); - } - void _WaypointReached_stub(const ::DBus::SignalMessage &sig) - { - ::DBus::MessageIter ri = sig.reader(); - - bool isDestination; - ri >> isDestination; - WaypointReached(isDestination); - } - void _ManeuverChanged_stub(const ::DBus::SignalMessage &sig) - { - ::DBus::MessageIter ri = sig.reader(); - - int32_t maneuver; - ri >> maneuver; - ManeuverChanged(maneuver); - } - void _PositionOnRouteChanged_stub(const ::DBus::SignalMessage &sig) - { - ::DBus::MessageIter ri = sig.reader(); - - uint32_t offsetOnRoute; - ri >> offsetOnRoute; - PositionOnRouteChanged(offsetOnRoute); - } - void _VehicleLeftTheRoute_stub(const ::DBus::SignalMessage &sig) - { - VehicleLeftTheRoute(); - } - void _PositionToRouteChanged_stub(const ::DBus::SignalMessage &sig) - { - ::DBus::MessageIter ri = sig.reader(); - - uint32_t distance; - ri >> distance; - int32_t direction; - ri >> direction; - PositionToRouteChanged(distance, direction); - } - void _ActiveRouteChanged_stub(const ::DBus::SignalMessage &sig) - { - ::DBus::MessageIter ri = sig.reader(); - - int32_t changeCause; - ri >> changeCause; - ActiveRouteChanged(changeCause); - } -}; - -} } } -#endif //__dbusxx__genivi_navigationcore_proxy_h__PROXY_MARSHAL_H diff --git a/include/genivi/navicore.h b/include/genivi/navicore.h deleted file mode 100644 index a80bc1f..0000000 --- a/include/genivi/navicore.h +++ /dev/null @@ -1,140 +0,0 @@ -// Copyright 2017 AISIN AW CO.,LTD - -#ifndef NAVICORE_H -#define NAVICORE_H - -#include <dbus-c++-1/dbus-c++/dbus.h> -#include "genivi-navigationcore-proxy.h" -#include <stdio.h> - -class Navicore : - public org::genivi::navigationcore::Session_proxy, - public org::genivi::navigationcore::Routing_proxy, - public org::genivi::navigationcore::MapMatchedPosition_proxy, - public org::genivi::navigationcore::Guidance_proxy, - public DBus::IntrospectableProxy, - public DBus::ObjectProxy -{ -public: - Navicore(DBus::Connection &connection, const char *path, const char *name) - : DBus::ObjectProxy(connection, path, name) - { - }; - - // Session - void SessionDeleted(const uint32_t& sessionHandle) - { - printf("NavicoreSession - Session %d deleted\n",sessionHandle); - }; - - // Routing - void RouteDeleted(const uint32_t& routeHandle) - { - // TODO - }; - - void RouteCalculationCancelled(const uint32_t& routeHandle) - { - // TODO - }; - - void RouteCalculationSuccessful(const uint32_t& routeHandle, const std::map< int32_t, int32_t >& unfullfilledPreferences) - { - // TODO - }; - - void RouteCalculationFailed(const uint32_t& routeHandle, const int32_t& errorCode, const std::map< int32_t, int32_t >& unfullfilledPreferences) - { - // TODO - }; - - void RouteCalculationProgressUpdate(const uint32_t& routeHandle, const int32_t& status, const uint8_t& percentage) - { - // TODO - }; - - void AlternativeRoutesAvailable(const std::vector< uint32_t >& routeHandlesList) - { - // TODO - }; - - // MapMatchedPosition - void SimulationStatusChanged(const int32_t& simulationStatus) - { - // TODO - }; - - void SimulationSpeedChanged(const uint8_t& speedFactor) - { - // TODO - }; - - void PositionUpdate(const std::vector< int32_t >& changedValues) - { - // TODO - }; - - void AddressUpdate(const std::vector< int32_t >& changedValues) - { - // TODO - }; - - void PositionOnSegmentUpdate(const std::vector< int32_t >& changedValues) - { - // TODO - }; - - void StatusUpdate(const std::vector< int32_t >& changedValues) - { - // TODO - }; - - void OffRoadPositionChanged(const uint32_t& distance, const int32_t& direction) - { - // TODO - }; - - // Guidance - void VehicleLeftTheRoadNetwork() - { - // TODO - }; - - void GuidanceStatusChanged(const int32_t& guidanceStatus, const uint32_t& routeHandle) - { - // TODO - }; - - void WaypointReached(const bool& isDestination) - { - // TODO - }; - - void ManeuverChanged(const int32_t& maneuver) - { - // TODO - }; - - void PositionOnRouteChanged(const uint32_t& offsetOnRoute) - { - // TODO - }; - - void VehicleLeftTheRoute() - { - // TODO - }; - - void PositionToRouteChanged(const uint32_t& distance, const int32_t& direction) - { - // TODO - }; - - void ActiveRouteChanged(const int32_t& changeCause) - { - // TODO - }; - -}; - -#endif diff --git a/include/genivi_request.h b/include/genivi_request.h deleted file mode 100644 index 75201c7..0000000 --- a/include/genivi_request.h +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright 2017 AW SOFTWARE CO.,LTD -// Copyright 2017 AISIN AW CO.,LTD - -#pragma once - -#include <map> -#include <vector> -#include <stdint.h> - -typedef std::tuple<double, double> Waypoint; - -/** - * @brief Genivi API call. - */ -class GeniviRequest -{ -public: - ~GeniviRequest(); - - std::map< int32_t, double > NavicoreGetPosition( const std::vector< int32_t >& valuesToReturn ); - std::vector< uint32_t > NavicoreGetAllRoutes(); - uint32_t NavicoreCreateRoute( const uint32_t& sessionHandle ); - void NavicorePauseSimulation( const uint32_t& sessionHandle ); - void NavicoreSetSimulationMode( const uint32_t& sessionHandle, const bool& activate ); - void NavicoreCancelRouteCalculation( const uint32_t& sessionHandle, const uint32_t& routeHandle ); - void NavicoreSetWaypoints( const uint32_t& sessionHandle, const uint32_t& routeHandle, - const bool& startFromCurrentPosition, const std::vector<Waypoint>& waypointsList ); - void NavicoreCalculateRoute( const uint32_t& sessionHandle, const uint32_t& routeHandle ); - std::map<uint32_t, std::string> NavicoreGetAllSessions(); - -private: - void* navicore_; - - void CreateDBusSession(); - bool CheckSession(); -}; - diff --git a/libnavi/include/BinderClient.h b/libnavi/include/BinderClient.h deleted file mode 100644 index 70a6558..0000000 --- a/libnavi/include/BinderClient.h +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright 2017 AISIN AW CO.,LTD - -#pragma once - -#include <map> -#include <tuple> -#include <vector> -#include <string> - -#include "libnavicore.hpp" - -#include "RequestManageListener.h" -#include "RequestManage.h" - -#define API_NAME "naviapi" - -/** - * @brief API name - */ -#define VERB_GETPOSITION "navicore_getposition" -#define VERB_GETALLROUTES "navicore_getallroutes" -#define VERB_CREATEROUTE "navicore_createroute" -#define VERB_PAUSESIMULATION "navicore_pausesimulation" -#define VERB_SETSIMULATIONMODE "navicore_setsimulationmode" -#define VERB_CANCELROUTECALCULATION "navicore_cancelroutecalculation" -#define VERB_SETWAYPOINTS "navicore_setwaypoints" -#define VERB_CALCULATEROUTE "navicore_calculateroute" -#define VERB_GETALLSESSIONS "navicore_getallsessions" - -/** - * @brief Binder client class - */ -class BinderClient : public RequestManageListener -{ -public: - BinderClient(); - ~BinderClient(); - - bool ConnectServer(std::string url , naviapi::NavicoreListener* listener); - void NavicoreGetPosition(const std::vector< int32_t >& valuesToReturn); - void NavicoreGetAllRoutes(); - void NavicoreCreateRoute(const uint32_t& sessionHandle); - void NavicorePauseSimulation(const uint32_t& sessionHandle); - void NavicoreSetSimulationMode(const uint32_t& sessionHandle, const bool& activate); - void NavicoreCancelRouteCalculation(const uint32_t& sessionHandle, const uint32_t& routeHandle); - void NavicoreSetWaypoints(const uint32_t& sessionHandle, const uint32_t& routeHandle, const bool& startFromCurrentPosition, const std::vector<naviapi::Waypoint>& waypointsList); - void NavicoreCalculateRoute(const uint32_t& sessionHandle, const uint32_t& routeHandle); - void NavicoreGetAllSessions(); - -private: - void OnReply(struct json_object *reply); - -private: - naviapi::NavicoreListener* navicoreListener; - RequestManage* requestMng; -}; - diff --git a/libnavi/include/JsonRequestGenerator.h b/libnavi/include/JsonRequestGenerator.h deleted file mode 100644 index 7cd6979..0000000 --- a/libnavi/include/JsonRequestGenerator.h +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2017 AW SOFTWARE CO.,LTD -// Copyright 2017 AISIN AW CO.,LTD - -#pragma once - -#include <stdint.h> -#include <string> -#include <vector> - -#include "libnavicore.hpp" - -/** -* @brief Class for generating Json request -*/ -class JsonRequestGenerator -{ -public: - static std::string CreateRequestGetPosition(const std::vector< int32_t >& valuesToReturn); - static std::string CreateRequestGetAllRoutes(); - static std::string CreateRequestCreateRoute(const uint32_t* sessionHandle); - static std::string CreateRequestPauseSimulation(const uint32_t* sessionHandle); - static std::string CreateRequestSetSimulationMode(const uint32_t* sessionHandle, const bool* activate); - static std::string CreateRequestCancelRouteCalculation(const uint32_t* sessionHandle, const uint32_t* routeHandle); - static std::string CreateRequestSetWaypoints(const uint32_t* sessionHandle, const uint32_t* routeHandle, - const bool* startFromCurrentPosition, const std::vector<naviapi::Waypoint>* waypointsList); - static std::string CreateRequestCalculateroute(const uint32_t* sessionHandle, const uint32_t* routeHandle); - static std::string CreateRequestGetAllSessions(); -}; - diff --git a/libnavi/include/JsonResponseAnalyzer.h b/libnavi/include/JsonResponseAnalyzer.h deleted file mode 100644 index 50b2cd2..0000000 --- a/libnavi/include/JsonResponseAnalyzer.h +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2017 AW SOFTWARE CO.,LTD -// Copyright 2017 AISIN AW CO.,LTD - -#pragma once - -#include <json-c/json.h> -#include <stdint.h> -#include <string> -#include <vector> -#include <map> - -#include "libnavicore.hpp" - -/** -* @brief JSON response analysis class -*/ -class JsonResponseAnalyzer -{ -public: - static std::map< int32_t, naviapi::variant > AnalyzeResponseGetPosition( std::string& res_json ); - static std::vector< uint32_t > AnalyzeResponseGetAllRoutes( std::string& res_json ); - static uint32_t AnalyzeResponseCreateRoute( std::string& res_json ); - static std::map<uint32_t, std::string> AnalyzeResponseGetAllSessions( std::string& res_json ); -}; - diff --git a/libnavi/include/RequestManage.h b/libnavi/include/RequestManage.h deleted file mode 100644 index 05ffcdf..0000000 --- a/libnavi/include/RequestManage.h +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright 2017 AISIN AW CO.,LTD - -#pragma once - -#include <stdint.h> -#include <string> -#include <pthread.h> - -extern "C" { - #include <afb/afb-wsj1.h> - #include <afb/afb-ws-client.h> -} - -#include "RequestManageListener.h" - -/** -* @brief Class for request -*/ -class RequestManage -{ -public: - pthread_cond_t cond; - pthread_mutex_t mutex; - - struct afb_wsj1* wsj1; - std::string* requestURL; - struct afb_wsj1_itf wsj1_itf; - -private: - RequestManageListener* listener; - int request_cnt; - uint32_t sessionHandle; - uint32_t routeHandle; - - // Function called from thread - static void* BinderThread(void* param); - - // Callback function - void OnReply(struct afb_wsj1_msg *msg); - void OnHangup(struct afb_wsj1 *wsj1); - void OnCallStatic(const char *api, const char *verb, struct afb_wsj1_msg *msg); - void OnEventStatic(const char *event, struct afb_wsj1_msg *msg); - - static void OnReplyStatic(void *closure, struct afb_wsj1_msg *msg); - static void OnHangupStatic(void *closure, struct afb_wsj1 *wsj1); - static void OnCallStatic(void *closure, const char *api, const char *verb, struct afb_wsj1_msg *msg); - static void OnEventStatic(void *closure, const char *event, struct afb_wsj1_msg *msg); - -// ================================================================================================== -// public -// ================================================================================================== -public: - RequestManage(); - ~RequestManage(); - - bool Connect(const char* api_url, RequestManageListener* listener); - bool IsConnect(); - bool CallBinderAPI(const char *api, const char *verb, const char *object); - void SetSessionHandle(uint32_t session); - uint32_t GetSessionHandle(); - void SetRouteHandle(uint32_t route); - uint32_t GetRouteHandle(); -}; - diff --git a/libnavi/include/RequestManageListener.h b/libnavi/include/RequestManageListener.h deleted file mode 100644 index 3b0c932..0000000 --- a/libnavi/include/RequestManageListener.h +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2017 AISIN AW CO.,LTD - -#pragma once - -#include <json-c/json.h> - -class RequestManageListener -{ -public: - RequestManageListener() { - } - virtual ~RequestManageListener() { - } - - virtual void OnReply(struct json_object *reply) = 0; -}; - diff --git a/libnavi/include/libnavicore.hpp b/libnavi/include/libnavicore.hpp deleted file mode 100644 index 66200d9..0000000 --- a/libnavi/include/libnavicore.hpp +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright 2017 AISIN AW CO.,LTD - -#pragma once - -#include <map> -#include <string> -#include <tuple> -#include <vector> - -#include <stdint.h> - -namespace naviapi { - -static const uint32_t NAVICORE_TIMESTAMP = 0x0010; -static const uint32_t NAVICORE_LATITUDE = 0x00a0; -static const uint32_t NAVICORE_LONGITUDE = 0x00a1; -static const uint32_t NAVICORE_HEADING = 0x00a3; -static const uint32_t NAVICORE_SPEED = 0x00a4; -static const uint32_t NAVICORE_SIMULATION_MODE = 0x00e3; - -typedef union -{ - bool _bool; - int32_t _int32_t; - uint32_t _uint32_t; - double _double; -} variant; - -typedef std::tuple<double, double> Waypoint; - -class NavicoreListener -{ -public: - NavicoreListener(); - virtual ~NavicoreListener(); - - virtual void getAllSessions_reply(const std::map< uint32_t, std::string >& allSessions); - virtual void getPosition_reply(std::map< int32_t, variant > position); - virtual void getAllRoutes_reply(std::vector< uint32_t > allRoutes); - virtual void createRoute_reply(uint32_t routeHandle); -}; // class NavicoreListener - -class Navicore -{ -private: - NavicoreListener* mListener; - -public: - Navicore(); - virtual ~Navicore(); - - bool connect(int argc, char *argv[], NavicoreListener* listener); - void disconnect(); - - void getAllSessions(); - void getPosition(std::vector<int32_t> params); - void getAllRoutes(); - void createRoute(uint32_t session); - - void pauseSimulation(uint32_t session); - void setSimulationMode(uint32_t session, bool activate); - void cancelRouteCalculation(uint32_t session, uint32_t routeHandle); - void setWaypoints(uint32_t session, uint32_t routeHandle, bool flag, std::vector<Waypoint>); - void calculateRoute(uint32_t session, uint32_t routeHandle); - -}; // class Navicore - -}; // namespace naviapi - diff --git a/libnavi/include/traces.h b/libnavi/include/traces.h deleted file mode 100644 index a1f96ec..0000000 --- a/libnavi/include/traces.h +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright 2017 AISIN AW CO.,LTD - -#ifndef __TRACE_H__ -#define __TRACE_H__ - -#include <stdio.h> - -#define BLACK "\033[30m" -#define RED "\033[31m" -#define GREEN "\033[32m" -#define YELLOW "\033[33m" -#define BLUE "\033[34m" -#define PURPLE "\033[35m" -#define DGREEN "\033[6m" -#define WHITE "\033[7m" -#define CYAN "\x1b[36m" -#define NONE "\033[0m" - -#ifdef NDEBUG - -#define TRACE_DEBUG_JSON(fmt, args...) -#define TRACE_DEBUG(fmt, args...) -#define TRACE_INFO(fmt, args...) -#define TRACE_WARN(fmt, args...) -#define TRACE_ERROR(fmt, args...) - -#else - -#define TRACE_DEBUG(fmt, args...) do { fprintf(stderr, "[%s:%d] " CYAN "DEBUG" NONE ": " fmt "\n", __func__, __LINE__, ##args); } while(0) -#define TRACE_INFO(fmt, args...) do { fprintf(stderr, "[%s:%d] " GREEN "INFO" NONE ": " fmt "\n", __func__, __LINE__, ##args); } while(0) -#define TRACE_WARN(fmt, args...) do { fprintf(stderr, "[%s:%d] " YELLOW "WARN" NONE": " fmt "\n", __func__, __LINE__, ##args); } while(0) -#define TRACE_ERROR(fmt, args...) do { fprintf(stderr, "[%s:%d] " RED "ERROR" NONE ": " fmt "\n", __func__, __LINE__, ##args); } while(0) - -#define TRACE_DEBUG_JSON(fmt, args...) - -#endif - -#endif // __TRACE_H__ diff --git a/libnavi/src/BinderClient.cpp b/libnavi/src/BinderClient.cpp deleted file mode 100644 index 1e1e9e9..0000000 --- a/libnavi/src/BinderClient.cpp +++ /dev/null @@ -1,315 +0,0 @@ -// Copyright 2017 AW SOFTWARE CO.,LTD -// Copyright 2017 AISIN AW CO.,LTD - -#include <cstring> - -#include "BinderClient.h" -#include "JsonRequestGenerator.h" -#include "JsonResponseAnalyzer.h" - -#include "traces.h" - -/** - * @brief constructor - */ -BinderClient::BinderClient() : navicoreListener(nullptr) -{ - requestMng = new RequestManage(); -} - -/** - * @brief Destructor - */ -BinderClient::~BinderClient() -{ - delete requestMng; -} - -/** - * @brief Connect with the Binder server - */ -bool BinderClient::ConnectServer(std::string url, naviapi::NavicoreListener* listener) -{ - this->navicoreListener = listener; - - if( !requestMng->Connect(url.c_str(), this)) - { - TRACE_ERROR("cannot connect to binding service.\n"); - return false; - } - - return true; -} - -/** - * @brief Call Genivi's GetPosition via Binder and get the result - */ -void BinderClient::NavicoreGetPosition(const std::vector< int32_t >& valuesToReturn) -{ - // Check if it is connected - if( requestMng->IsConnect() ) - { - // JSON request generation - std::string req_json = JsonRequestGenerator::CreateRequestGetPosition(valuesToReturn); - - // Send request - if( requestMng->CallBinderAPI(API_NAME, VERB_GETPOSITION, req_json.c_str()) ) - { - TRACE_DEBUG("navicore_getposition success.\n"); - } - else - { - TRACE_ERROR("navicore_getposition failed.\n"); - } - } -} - -/** - * @brief Get route handle - */ -void BinderClient::NavicoreGetAllRoutes() -{ - // Check if it is connected - if( requestMng->IsConnect() ) - { - // JSON request generation - std::string req_json = JsonRequestGenerator::CreateRequestGetAllRoutes(); - - // Send request - if( requestMng->CallBinderAPI(API_NAME, VERB_GETALLROUTES, req_json.c_str()) ) - { - TRACE_DEBUG("navicore_getallroutes success.\n"); - } - else - { - TRACE_ERROR("navicore_getallroutes failed.\n"); - } - } -} - -/** - * @brief Generate route handle - */ -void BinderClient::NavicoreCreateRoute(const uint32_t& sessionHandle) -{ - // Check if it is connected - if( requestMng->IsConnect() ) - { - // JSON request generation - uint32_t session = requestMng->GetSessionHandle(); - std::string req_json = JsonRequestGenerator::CreateRequestCreateRoute(&session); - - // Send request - if( requestMng->CallBinderAPI(API_NAME, VERB_CREATEROUTE, req_json.c_str()) ) - { - TRACE_DEBUG("navicore_createroute success.\n"); - } - else - { - TRACE_ERROR("navicore_createroute failed.\n"); - } - } -} - -/** - * @brief Pause demo - */ -void BinderClient::NavicorePauseSimulation(const uint32_t& sessionHandle) -{ - // Check if it is connected - if( requestMng->IsConnect() ) - { - // JSON request generation - uint32_t session = requestMng->GetSessionHandle(); - std::string req_json = JsonRequestGenerator::CreateRequestPauseSimulation(&session); - - // Send request - if( requestMng->CallBinderAPI(API_NAME, VERB_PAUSESIMULATION, req_json.c_str()) ) - { - TRACE_DEBUG("navicore_pausesimulationmode success.\n"); - } - else - { - TRACE_ERROR("navicore_pausesimulationmode failed.\n"); - } - } -} - -/** - * @brief Simulation mode setting - */ -void BinderClient::NavicoreSetSimulationMode(const uint32_t& sessionHandle, const bool& activate) -{ - // Check if it is connected - if( requestMng->IsConnect() ) - { - // JSON request generation - uint32_t session = requestMng->GetSessionHandle(); - std::string req_json = JsonRequestGenerator::CreateRequestSetSimulationMode(&session, &activate); - - // Send request - if( requestMng->CallBinderAPI(API_NAME, VERB_SETSIMULATIONMODE, req_json.c_str()) ) - { - TRACE_DEBUG("navicore_setsimulationmode success.\n"); - } - else - { - TRACE_ERROR("navicore_setsimulationmode failed.\n"); - } - } -} - -/** - * @brief Delete route information - */ -void BinderClient::NavicoreCancelRouteCalculation(const uint32_t& sessionHandle, const uint32_t& routeHandle) -{ - // Check if it is connected - if( requestMng->IsConnect() ) - { - // JSON request generation - uint32_t session = requestMng->GetSessionHandle(); - std::string req_json = JsonRequestGenerator::CreateRequestCancelRouteCalculation(&session, &routeHandle); - - // Send request - if( requestMng->CallBinderAPI(API_NAME, VERB_CANCELROUTECALCULATION, req_json.c_str()) ) - { - TRACE_DEBUG("navicore_cancelroutecalculation success.\n"); - } - else - { - TRACE_ERROR("navicore_cancelroutecalculation failed.\n"); - } - } -} - -/** - * @brief Destination setting - */ -void BinderClient::NavicoreSetWaypoints(const uint32_t& sessionHandle, const uint32_t& routeHandle, const bool& startFromCurrentPosition, const std::vector<naviapi::Waypoint>& waypointsList) -{ - // Check if it is connected - if( requestMng->IsConnect() ) - { - // JSON request generation - uint32_t session = requestMng->GetSessionHandle(); - uint32_t route = requestMng->GetRouteHandle(); - std::string req_json = JsonRequestGenerator::CreateRequestSetWaypoints(&session, &route, - &startFromCurrentPosition, &waypointsList); - - // Send request - if( requestMng->CallBinderAPI(API_NAME, VERB_SETWAYPOINTS, req_json.c_str()) ) - { - TRACE_DEBUG("navicore_setwaypoints success.\n"); - } - else - { - TRACE_ERROR("navicore_setwaypoints failed.\n"); - } - } -} - -/** - * @brief Route calculation processing - */ -void BinderClient::NavicoreCalculateRoute(const uint32_t& sessionHandle, const uint32_t& routeHandle) -{ - // Check if it is connected - if( requestMng->IsConnect() ) - { - // JSON request generation - uint32_t session = requestMng->GetSessionHandle(); - uint32_t route = requestMng->GetRouteHandle(); - std::string req_json = JsonRequestGenerator::CreateRequestCalculateroute(&session, &route); - - // Send request - if( requestMng->CallBinderAPI(API_NAME, VERB_CALCULATEROUTE, req_json.c_str()) ) - { - TRACE_DEBUG("navicore_calculateroute success.\n"); - } - else - { - TRACE_ERROR("navicore_calculateroute failed.\n"); - } - } -} - -/** - * @brief Retrieve session information - * @return Map of session information - */ -void BinderClient::NavicoreGetAllSessions() -{ - // Check if it is connected - if( requestMng->IsConnect() ) - { - // JSON request generation - std::string req_json = JsonRequestGenerator::CreateRequestGetAllSessions(); - - // Send request - if( requestMng->CallBinderAPI(API_NAME, VERB_GETALLSESSIONS, req_json.c_str()) ) - { - TRACE_DEBUG("navicore_getallsessions success.\n"); - } - else - { - TRACE_ERROR("navicore_getallsessions failed.\n"); - } - } -} - -void BinderClient::OnReply(struct json_object* reply) -{ - struct json_object* requestObject = nullptr; - json_object_object_get_ex(reply, "request", &requestObject); - - struct json_object* infoObject = nullptr; - json_object_object_get_ex(requestObject, "info", &infoObject); - - const char* info = json_object_get_string(infoObject); - - char tmpVerb[256]; - strcpy(tmpVerb, info); - - // Create a new JSON response - const char* json_str = json_object_to_json_string_ext(reply, JSON_C_TO_STRING_PRETTY); - std::string response_json = std::string( json_str ); - - if (strcmp(VERB_GETALLSESSIONS, tmpVerb) == 0) - { - std::map<uint32_t, std::string> ret = JsonResponseAnalyzer::AnalyzeResponseGetAllSessions(response_json); - - // keep session handle - requestMng->SetSessionHandle( ret.begin()->first ); - - this->navicoreListener->getAllSessions_reply(ret); - } - else if (strcmp(VERB_GETPOSITION, tmpVerb) == 0) - { - std::map< int32_t, naviapi::variant > ret = JsonResponseAnalyzer::AnalyzeResponseGetPosition(response_json); - - this->navicoreListener->getPosition_reply(ret); - } - else if (strcmp(VERB_GETALLROUTES, tmpVerb) == 0) - { - std::vector< uint32_t > ret = JsonResponseAnalyzer::AnalyzeResponseGetAllRoutes(response_json); - - // route handle - if(ret.size() > 0) - { - requestMng->SetRouteHandle(ret[0]); - } - - this->navicoreListener->getAllRoutes_reply(ret); - } - else if (strcmp(VERB_CREATEROUTE, tmpVerb) == 0) - { - uint32_t ret = JsonResponseAnalyzer::AnalyzeResponseCreateRoute(response_json); - - // keep route handle - requestMng->SetRouteHandle(ret); - - this->navicoreListener->createRoute_reply(ret); - } -} - diff --git a/libnavi/src/JsonRequestGenerator.cpp b/libnavi/src/JsonRequestGenerator.cpp deleted file mode 100644 index 09d68c0..0000000 --- a/libnavi/src/JsonRequestGenerator.cpp +++ /dev/null @@ -1,188 +0,0 @@ -// Copyright 2017 AW SOFTWARE CO.,LTD -// Copyright 2017 AISIN AW CO.,LTD - -#include <json-c/json.h> -#include <traces.h> -#include "JsonRequestGenerator.h" - -/** - * @brief Generate request for navicore_getposition - * @param valuesToReturn Key information you want to obtain - * @return json string - */ -std::string JsonRequestGenerator::CreateRequestGetPosition(const std::vector< int32_t >& valuesToReturn) -{ - std::vector< int32_t >::const_iterator itr; - - struct json_object* request_json = json_object_new_object(); - struct json_object* json_array = json_object_new_array(); - - for (itr = valuesToReturn.begin(); itr != valuesToReturn.end(); itr++) - { - json_object_array_add(json_array, json_object_new_int(*itr)); - } - - json_object_object_add(request_json, "valuesToReturn", json_array); - TRACE_DEBUG("CreateRequestGetPosition request_json:\n%s\n", json_object_to_json_string(request_json)); - - return std::string( json_object_to_json_string( request_json ) ); -} - -/** - * @brief Generate request for navicore_getallroutes - * @return json strin - */ -std::string JsonRequestGenerator::CreateRequestGetAllRoutes() -{ - // Request is empty and OK - struct json_object* request_json = json_object_new_object(); - TRACE_DEBUG("CreateRequestGetAllRoutes request_json:\n%s\n", json_object_to_json_string(request_json)); - - return std::string( json_object_to_json_string( request_json ) ); -} - -/** - * @brief Generate request for navicore_createroute - * @param sessionHandle session handle - * @return json string - */ -std::string JsonRequestGenerator::CreateRequestCreateRoute(const uint32_t* sessionHandle) -{ - struct json_object* request_json = json_object_new_object(); - json_object_object_add(request_json, "sessionHandle", json_object_new_int(*sessionHandle)); - TRACE_DEBUG("CreateRequestCreateRoute request_json:\n%s\n", json_object_to_json_string(request_json)); - - return std::string( json_object_to_json_string( request_json ) ); -} - -/** - * @brief Generate request for navicore_pausesimulation - * @param sessionHandle session handle - * @return json string - */ -std::string JsonRequestGenerator::CreateRequestPauseSimulation(const uint32_t* sessionHandle) -{ - struct json_object* request_json = json_object_new_object(); - // sessionHandle - json_object_object_add(request_json, "sessionHandle", json_object_new_int(*sessionHandle)); - TRACE_DEBUG("CreateRequestPauseSimulation request_json:\n%s\n", json_object_to_json_string(request_json)); - - return std::string( json_object_to_json_string( request_json ) ); -} - -/** - * @brief Generate request for navicore_pausesimulation - * @param sessionHandle session handle - * @param active Simulation state - * @return json string - */ -std::string JsonRequestGenerator::CreateRequestSetSimulationMode(const uint32_t* sessionHandle, const bool* activate) -{ - struct json_object* request_json = json_object_new_object(); - - // "sessionHandle" - json_object_object_add(request_json, "sessionHandle", json_object_new_int(*sessionHandle)); - - // "simulationMode" - json_object_object_add(request_json, "simulationMode", json_object_new_boolean(*activate)); - TRACE_DEBUG("CreateRequestSetSimulationMode request_json:\n%s\n", json_object_to_json_string(request_json)); - - return std::string( json_object_to_json_string( request_json ) ); -} - -/** - * @brief Generate request for navicore_pausesimulation - * @param sessionHandle session handle - * @param routeHandle route handle - * @return json string - */ -std::string JsonRequestGenerator::CreateRequestCancelRouteCalculation(const uint32_t* sessionHandle, const uint32_t* routeHandle) -{ - struct json_object* request_json = json_object_new_object(); - - // "sessionHandle" - json_object_object_add(request_json, "sessionHandle", json_object_new_int(*sessionHandle)); - - // "route" - json_object_object_add(request_json, "route", json_object_new_int(*routeHandle)); - TRACE_DEBUG("CreateRequestCancelRouteCalculation request_json:\n%s\n", json_object_to_json_string(request_json)); - - return std::string( json_object_to_json_string( request_json ) ); -} - -/** - * @brief Generate request for navicore_setwaypoints - * @param sessionHandle session handle - * @param routeHandle route handle - * @return json string - */ -std::string JsonRequestGenerator::CreateRequestSetWaypoints(const uint32_t* sessionHandle, const uint32_t* routeHandle, - const bool* startFromCurrentPosition, const std::vector<naviapi::Waypoint>* waypointsList) -{ - naviapi::Waypoint destWp; - - struct json_object* request_json = json_object_new_object(); - struct json_object* json_array = json_object_new_array(); - - // "sessionHandle" - json_object_object_add(request_json, "sessionHandle", json_object_new_int(*sessionHandle)); - - // "route" - json_object_object_add(request_json, "route", json_object_new_int(*routeHandle)); - - // "startFromCurrentPosition" - json_object_object_add(request_json, "startFromCurrentPosition", json_object_new_boolean(*startFromCurrentPosition)); - - // "latitude", "longitude" - std::vector<naviapi::Waypoint>::const_iterator it; - for (it = waypointsList->begin(); it != waypointsList->end(); ++it) - { - struct json_object* destpoint = json_object_new_object(); - - double latitude = std::get<0>(*it); - json_object_object_add(destpoint, "latitude", json_object_new_double(latitude)); - - double longitude = std::get<1>(*it); - json_object_object_add(destpoint, "longitude", json_object_new_double(longitude)); - - json_object_array_add(json_array, destpoint); - } - - json_object_object_add(request_json, "", json_array); - TRACE_DEBUG("CreateRequestSetWaypoints request_json:\n%s\n", json_object_to_json_string(request_json)); - - return std::string( json_object_to_json_string( request_json ) ); -} - -/** - * @brief Generate request for navicore_calculateroute - * @param sessionHandle session handle - * @param routeHandle route handle - * @return json string - */ -std::string JsonRequestGenerator::CreateRequestCalculateroute(const uint32_t* sessionHandle, const uint32_t* routeHandle) -{ - struct json_object* request_json = json_object_new_object(); - // "sessionHandle" - json_object_object_add(request_json, "sessionHandle", json_object_new_int(*sessionHandle)); - - // "route" - json_object_object_add(request_json, "route", json_object_new_int(*routeHandle)); - TRACE_DEBUG("CreateRequestCalculateroute request_json:\n%s\n", json_object_to_json_string(request_json)); - - return std::string( json_object_to_json_string( request_json ) ); -} - -/** - * @brief Generate request for navicore_getallsessions - * @return json string - */ -std::string JsonRequestGenerator::CreateRequestGetAllSessions() -{ - // Request is empty and OK - struct json_object* request_json = json_object_new_object(); - TRACE_DEBUG("CreateRequestGetAllSessions request_json:\n%s\n", json_object_to_json_string(request_json)); - - return std::string( json_object_to_json_string( request_json ) ); -} - diff --git a/libnavi/src/JsonResponseAnalyzer.cpp b/libnavi/src/JsonResponseAnalyzer.cpp deleted file mode 100644 index b0d943f..0000000 --- a/libnavi/src/JsonResponseAnalyzer.cpp +++ /dev/null @@ -1,254 +0,0 @@ -// Copyright 2017 AW SOFTWARE CO.,LTD -// Copyright 2017 AISIN AW CO.,LTD - -#include <traces.h> - -#include "JsonResponseAnalyzer.h" - -/** - * @brief Response analysis of navicore_getallroutes - * @param res_json JSON string of response - * @return Map information for the key sent in the request - */ -std::map< int32_t, naviapi::variant > JsonResponseAnalyzer::AnalyzeResponseGetPosition( std::string& res_json ) -{ - std::map< int32_t, naviapi::variant > ret; - - TRACE_DEBUG("AnalyzeResponseGetPosition json_obj:\n%s\n", json_object_to_json_string(json_obj)); - - // convert to Json Object - struct json_object *json_obj = json_tokener_parse( res_json.c_str() ); - - // Check key - struct json_object *json_map_ary = NULL; - if( json_object_object_get_ex(json_obj, "response", &json_map_ary) ) - { - // Check if the response is array information - if( json_object_is_type(json_map_ary, json_type_array) ) - { - for (int i = 0; i < json_object_array_length(json_map_ary); ++i) - { - struct json_object* j_elem = json_object_array_get_idx(json_map_ary, i); - - if( json_object_is_type( j_elem, json_type_object) ) - { - // Check key - struct json_object* key = NULL; - struct json_object* value = NULL; - if( json_object_object_get_ex(j_elem, "key", &key) - && json_object_object_get_ex(j_elem, "value", &value) ) - { - if( json_object_is_type(key, json_type_int) ) - { - uint32_t req_key = (uint32_t)json_object_get_int(key); - - switch( req_key ) - { - case naviapi::NAVICORE_LATITUDE: - ret[req_key]._double = json_object_get_double(value); - break; - - case naviapi::NAVICORE_LONGITUDE: - ret[req_key]._double = json_object_get_double(value); - break; - - case naviapi::NAVICORE_TIMESTAMP: - ret[req_key]._uint32_t = (uint32_t)json_object_get_int(value); - break; - - case naviapi::NAVICORE_HEADING: - ret[req_key]._uint32_t = (uint32_t)json_object_get_int(value); - break; - - case naviapi::NAVICORE_SPEED: - ret[req_key]._int32_t = json_object_get_int(value); - break; - - case naviapi::NAVICORE_SIMULATION_MODE: - ret[req_key]._bool = json_object_get_boolean(value); - break; - - default: - TRACE_WARN("unknown key type.\n"); - break; - } - } - } - } - else - { - TRACE_WARN("element type is not object.\n"); - break; - } - } - } - else - { - TRACE_WARN("response type is not array.\n"); - } - } - - json_object_put(json_obj); - return ret; -} - -/** - * @brief Response analysis of navicore_getallroutes - * @param res_json JSON string of response - * @return Route handle array - */ -std::vector< uint32_t > JsonResponseAnalyzer::AnalyzeResponseGetAllRoutes( std::string& res_json ) -{ - std::vector< uint32_t > routeList; - - TRACE_DEBUG("AnalyzeResponseGetAllRoutes json_obj:\n%s\n", json_object_to_json_string(json_obj)); - - // convert to Json Object - struct json_object *json_obj = json_tokener_parse( res_json.c_str() ); - - // Check key - struct json_object *json_route_ary = NULL; - if( json_object_object_get_ex(json_obj, "response", &json_route_ary) ) - { - // Check if the response is array information - if( json_object_is_type(json_route_ary, json_type_array) ) - { - for (int i = 0; i < json_object_array_length(json_route_ary); ++i) - { - struct json_object* j_elem = json_object_array_get_idx(json_route_ary, i); - - // Check that it is an element - struct json_object *json_route_obj = NULL; - if( json_object_object_get_ex(j_elem, "route", &json_route_obj) ) - { - // Check if it is an int value - if( json_object_is_type(json_route_obj, json_type_int) ) - { - uint32_t routeHandle = (uint32_t)json_object_get_int(json_route_obj); - routeList.push_back( routeHandle ); - } - else - { - TRACE_WARN("route value is not integer.\n"); - break; - } - } - else - { - TRACE_WARN("key route is not found.\n"); - break; - } - } - } - else - { - TRACE_WARN("response type is not array.\n"); - } - } - - json_object_put(json_obj); - return routeList; -} - -/** - * @brief Response analysis of navicore_createroute - * @param res_json JSON string of response - * @return Route handle - */ -uint32_t JsonResponseAnalyzer::AnalyzeResponseCreateRoute( std::string& res_json ) -{ - uint32_t routeHandle = 0; - - TRACE_DEBUG("AnalyzeResponseCreateRoute json_obj:\n%s\n", json_object_to_json_string(json_obj)); - - // convert to Json Object - struct json_object *json_obj = json_tokener_parse( res_json.c_str() ); - - // Check key - struct json_object *json_root_obj = NULL; - struct json_object *json_route_obj = NULL; - if( json_object_object_get_ex(json_obj, "response", &json_root_obj) - && json_object_object_get_ex(json_root_obj, "route", &json_route_obj) ) - { - // Check if the response is array information - if( json_object_is_type(json_route_obj, json_type_int) ) - { - // Get route handle - routeHandle = (uint32_t)json_object_get_int(json_route_obj); - } - else - { - TRACE_WARN("response type is not integer.\n"); - } - } - - json_object_put(json_obj); - return routeHandle; -} - -/** - * @brief Response analysis of navicore_getallsessions - * @param res_json JSON string of response - * @return Map of session information - */ -std::map<uint32_t, std::string> JsonResponseAnalyzer::AnalyzeResponseGetAllSessions( std::string& res_json ) -{ - std::map<uint32_t, std::string> session_map; - - TRACE_DEBUG("AnalyzeResponseGetAllSessions json_obj:\n%s\n", json_object_to_json_string(json_obj)); - - // convert to Json Object - struct json_object *json_obj = json_tokener_parse( res_json.c_str() ); - - // Check key - struct json_object *json_map_ary = NULL; - if( json_object_object_get_ex(json_obj, "response", &json_map_ary) ) - { - // Check if the response is array information - if( json_object_is_type(json_map_ary, json_type_array) ) - { - for (int i = 0; i < json_object_array_length(json_map_ary); ++i) - { - struct json_object* j_elem = json_object_array_get_idx(json_map_ary, i); - - if( json_object_is_type( j_elem, json_type_object) ) - { - // Check key - struct json_object* handle = NULL; - struct json_object* client = NULL; - if( json_object_object_get_ex(j_elem, "sessionHandle", &handle) - && json_object_object_get_ex(j_elem, "client", &client) ) - { - if( json_object_is_type(handle, json_type_int) - && json_object_is_type(client, json_type_string) ) - { - uint32_t sessionHandle = (uint32_t)json_object_get_int(handle); - std::string clientName = std::string( json_object_get_string(client) ); - - // add to map - session_map[sessionHandle] = clientName; - } - else - { - TRACE_WARN("invalid response.\n"); - break; - } - } - } - else - { - TRACE_WARN("element type is not object.\n"); - break; - } - } - } - else - { - TRACE_WARN("response type is not array.\n"); - } - } - - json_object_put(json_obj); - return session_map; -} - diff --git a/libnavi/src/RequestManage.cpp b/libnavi/src/RequestManage.cpp deleted file mode 100644 index 7db34e1..0000000 --- a/libnavi/src/RequestManage.cpp +++ /dev/null @@ -1,204 +0,0 @@ -// Copyright 2017 AW SOFTWARE CO.,LTD -// Copyright 2017 AISIN AW CO.,LTD - -#include <string.h> -#include <errno.h> -#include <pthread.h> -#include <time.h> -#include <unistd.h> -#include <systemd/sd-event.h> -#include <json-c/json.h> -#include <traces.h> -#include "RequestManage.h" - -/** - * @brief constructor - */ -RequestManage::RequestManage() : listener(nullptr) -{ - // Callback setting - this->wsj1_itf.on_hangup = RequestManage::OnHangupStatic; - this->wsj1_itf.on_call = RequestManage::OnCallStatic; - this->wsj1_itf.on_event = RequestManage::OnEventStatic; - - pthread_cond_init(&this->cond, nullptr); - pthread_mutex_init(&this->mutex, nullptr); -} - -/** - * @brief Destructor - */ -RequestManage::~RequestManage() -{ -} - -void* RequestManage::BinderThread(void* param) -{ - RequestManage* instance = (RequestManage*) param; - sd_event *loop; - - int rc = sd_event_default(&loop); - if (rc < 0) { - TRACE_ERROR("connection to default event loop failed: %s\n", strerror(-rc)); - return nullptr; - } - - instance->wsj1 = afb_ws_client_connect_wsj1(loop, instance->requestURL->c_str(), &instance->wsj1_itf, nullptr); - if (instance->wsj1 == nullptr) - { - TRACE_ERROR("connection to %s failed: %m\n", api_url); - return nullptr; - } - - // Signal - pthread_mutex_unlock(&instance->mutex); - pthread_cond_signal(&instance->cond); - - while (1) - { - sd_event_run(loop, 1000 * 1000); // 1sec - } - - return nullptr; -} - -/** - * @brief Connect with a service - * @param URL - * @return Success or failure of connection - */ -bool RequestManage::Connect(const char* api_url, RequestManageListener* listener) -{ - this->listener = listener; - this->requestURL = new std::string(api_url); - - pthread_t thread_id; - pthread_create(&thread_id, nullptr, RequestManage::BinderThread, (void*)this); - - // Wait until response comes - pthread_mutex_lock(&this->mutex); - pthread_cond_wait(&this->cond, &this->mutex); - pthread_mutex_unlock(&this->mutex); - - if (this->wsj1 == nullptr) - { - return false; - } - - return true; -} - -/** - * @brief Connection status check with service - * @return Connection status - */ -bool RequestManage::IsConnect(){ - return (this->wsj1 != NULL); -} - -/** - * @brief Call Binder's API - * @param api api - * @param verb method - * @param req_json Json style request - * @return Success or failure of processing - */ -bool RequestManage::CallBinderAPI(const char* api, const char* verb, const char* req_json) -{ - // Send request - int rc = afb_wsj1_call_s(this->wsj1, api, verb, req_json, RequestManage::OnReplyStatic, this); - if (rc < 0) - { - TRACE_ERROR("calling %s/%s(%s) failed: %m\n", api, verb, req_json); - return false; - } - - return true; -} - -/** - * @brief Set session handle - * @param session Session handle - */ -void RequestManage::SetSessionHandle( uint32_t session ) -{ - this->sessionHandle = session; -} - -/** - * @brief Get session handle - * @return Session handle - */ -uint32_t RequestManage::GetSessionHandle() -{ - return this->sessionHandle; -} - -/** - * @brief Set route handle - * @param route Route handle - */ -void RequestManage::SetRouteHandle( uint32_t route ) -{ - this->routeHandle = route; -} - -/** - * @brief Get route handle - * @return Route handle - */ -uint32_t RequestManage::GetRouteHandle() -{ - return this->routeHandle; -} - -void RequestManage::OnReply(struct afb_wsj1_msg *msg) -{ - struct json_object * json = afb_wsj1_msg_object_j(msg); - - this->listener->OnReply(json); -} - -void RequestManage::OnHangup(struct afb_wsj1 *wsj1) -{ -} - -void RequestManage::OnCallStatic(const char *api, const char *verb, struct afb_wsj1_msg *msg) -{ -} - -void RequestManage::OnEventStatic(const char *event, struct afb_wsj1_msg *msg) -{ -} - - -/** - * @brief Answer callback from service - */ -void RequestManage::OnReplyStatic(void *closure, struct afb_wsj1_msg *msg) -{ - RequestManage* instance = (RequestManage *)closure; - instance->OnReply(msg); -} - -/** - * @brief Service hang notification - */ -void RequestManage::OnHangupStatic(void *closure, struct afb_wsj1 *wsj1) -{ - printf("DEBUG:%s:%d (%p,%p)\n", __func__, __LINE__, closure, wsj1); - fflush(stdout); -} - -void RequestManage::OnCallStatic(void *closure, const char *api, const char *verb, struct afb_wsj1_msg *msg) -{ - printf("DEBUG:%s:%d (%p,%s,%s,%p)\n", __func__, __LINE__, closure, api, verb, msg); - fflush(stdout); -} - -void RequestManage::OnEventStatic(void *closure, const char *event, struct afb_wsj1_msg *msg) -{ - printf("DEBUG:%s:%d (%p,%s,%p)\n", __func__, __LINE__, closure, event, msg); - fflush(stdout); -} - diff --git a/libnavi/src/navicore.cpp b/libnavi/src/navicore.cpp deleted file mode 100644 index 5402aa8..0000000 --- a/libnavi/src/navicore.cpp +++ /dev/null @@ -1,81 +0,0 @@ -// Copyright 2017 AISIN AW CO.,LTD - -#include "libnavicore.hpp" -#include "BinderClient.h" - -static BinderClient mBinderClient; - -naviapi::Navicore::Navicore() -{ -} - -naviapi::Navicore::~Navicore() -{ -} - -bool naviapi::Navicore::connect(int argc, char *argv[], NavicoreListener* listener) -{ - this->mListener = listener; - - if (argc != 3) - { - printf("Error: argc != 3 : argc = %d\n", argc); - return false; - } - - char url[1024]; - sprintf(url, "ws://localhost:%d/api?token=%s", atoi(argv[1]), argv[2]); - - return mBinderClient.ConnectServer(url, this->mListener); -} - -void naviapi::Navicore::disconnect() -{ - // TODO -} - -void naviapi::Navicore::getAllSessions() -{ - mBinderClient.NavicoreGetAllSessions(); -} - -void naviapi::Navicore::getPosition(std::vector<int32_t> params) -{ - mBinderClient.NavicoreGetPosition(params); -} - -void naviapi::Navicore::getAllRoutes() -{ - mBinderClient.NavicoreGetAllRoutes(); -} - -void naviapi::Navicore::createRoute(uint32_t session) -{ - mBinderClient.NavicoreCreateRoute(session); -} - -void naviapi::Navicore::pauseSimulation(uint32_t session) -{ - mBinderClient.NavicorePauseSimulation(session); -} - -void naviapi::Navicore::setSimulationMode(uint32_t session, bool activate) -{ - mBinderClient.NavicoreSetSimulationMode(session, activate); -} - -void naviapi::Navicore::cancelRouteCalculation(uint32_t session, uint32_t routeHandle) -{ - mBinderClient.NavicoreCancelRouteCalculation(session, routeHandle); -} - -void naviapi::Navicore::setWaypoints(uint32_t session, uint32_t routeHandle, bool flag, std::vector<Waypoint> waypoints) -{ - mBinderClient.NavicoreSetWaypoints(session, routeHandle, flag, waypoints); -} - -void naviapi::Navicore::calculateRoute(uint32_t session, uint32_t routeHandle) -{ - mBinderClient.NavicoreCalculateRoute(session, routeHandle); -} - diff --git a/libnavi/src/navicorelistener.cpp b/libnavi/src/navicorelistener.cpp deleted file mode 100644 index 2aa2b5d..0000000 --- a/libnavi/src/navicorelistener.cpp +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright 2017 AISIN AW CO.,LTD - -#include "libnavicore.hpp" - -naviapi::NavicoreListener::NavicoreListener() -{ -} - -naviapi::NavicoreListener::~NavicoreListener() -{ -} - -void naviapi::NavicoreListener::getAllSessions_reply(const std::map< uint32_t, std::string >& allSessions) -{ -} - -void naviapi::NavicoreListener::getPosition_reply(std::map< int32_t, variant > position) -{ -} - -void naviapi::NavicoreListener::getAllRoutes_reply(std::vector< uint32_t > allRoutes) -{ -} - -void naviapi::NavicoreListener::createRoute_reply(uint32_t routeHandle) -{ -} - diff --git a/libnaviapi-agl.pc.in b/libnaviapi-agl.pc.in deleted file mode 100644 index b7dcb60..0000000 --- a/libnaviapi-agl.pc.in +++ /dev/null @@ -1,14 +0,0 @@ -prefix=@CMAKE_INSTALL_PREFIX@ -exec_prefix=${prefix} -includedir=@PROJECT_INCLUDEDIR@ -libdir=@PROJECT_LIBDIR@ -binding_install_dir=@binding_install_dir@ - -Name: @PROJECT_PRETTY_NAME@ -Description: @PROJECT_DESCRIPTION@ -Version: @PROJECT_VERSION@ -URL: @PROJECT_URL@ - -Requires: json-c libafbwsc -Cflags: -I${includedir} -Libs: -L${libdir} -lnaviapi-agl diff --git a/navigation.png b/navigation.png deleted file mode 100644 index e7ad085b7f69407205ef04bb1a986c535529a13a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 38244 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 diff --git a/src/analyze_request.cpp b/src/analyze_request.cpp deleted file mode 100644 index 593ed42..0000000 --- a/src/analyze_request.cpp +++ /dev/null @@ -1,296 +0,0 @@ -// Copyright 2017 AW SOFTWARE CO.,LTD -// Copyright 2017 AISIN AW CO.,LTD - -#include "genivi/genivi-navicore-constants.h" -#include "analyze_request.h" -#include <stdio.h> -#include <string.h> -#include <json-c/json.h> -#include <string> - - -/** - * @brief Create arguments to pass to Genivi API GetPosition. - * @param[in] req_json_str JSON request from BinderClient - * @param[out] Params An array of key information you want to obtain - * @return Success or failure of processing - */ -bool AnalyzeRequest::CreateParamsGetPosition( const char* req_json_str, std::vector< int32_t >& Params) -{ - struct json_object *req_json = json_tokener_parse(req_json_str); - struct json_object* jValuesToReturn = NULL; - if( json_object_object_get_ex(req_json, "valuesToReturn", &jValuesToReturn) ) - { - if( json_object_is_type(jValuesToReturn, json_type_array) ) - { - for (int i = 0; i < json_object_array_length(jValuesToReturn); ++i) - { - struct json_object* j_elem = json_object_array_get_idx(jValuesToReturn, i); - - // JSON type acquisition - if( json_object_is_type(j_elem, json_type_int ) ) - { - int32_t req_key = json_object_get_int (j_elem); - - // no supported. - if ((NAVICORE_TIMESTAMP == req_key) || (NAVICORE_SPEED == req_key)) - { - continue; - } - Params.push_back(req_key); - } - else - { - fprintf(stdout, "key is not integer type.\n"); - return false; - } - } - } - else - { - fprintf(stdout, "request is not array type.\n"); - return false; - } - } - else - { - fprintf(stdout, "key valuesToReturn not found.\n"); - return false; - } - - return true; -} - - -/** - * @brief Create arguments to pass to Genivi API CreateRoute - * @param[in] req_json_str JSON request from BinderClient - * @param[out] sessionHdl Session handle - * @return Success or failure of processing - */ -bool AnalyzeRequest::CreateParamsCreateRoute( const char* req_json_str, uint32_t& sessionHdl ) -{ - // Get sessionHandle information - return JsonObjectGetSessionHdl(req_json_str, sessionHdl); -} - - -/** - * @brief Create arguments to pass to Genivi API PauseSimulation - * @param[in] req_json_str JSON request from BinderClient - * @param[out] sessionHdl Session handle - * @return Success or failure of processing - */ -bool AnalyzeRequest::CreateParamsPauseSimulation( const char* req_json_str, uint32_t& sessionHdl ) -{ - // Get sessionHandle information - return JsonObjectGetSessionHdl(req_json_str, sessionHdl); -} - - -/** - * @brief Create arguments to pass to Genivi API CreateRoute - * @param[in] req_json_str JSON request from BinderClient - * @param[out] sessionHdl Session handle - * @param[out] simuMode Simulation mode - * @return Success or failure of processing - */ -bool AnalyzeRequest::CreateParamsSetSimulationMode( const char* req_json_str, uint32_t& sessionHdl, bool& simuMode ) -{ - bool ret = false; - struct json_object *sess = NULL; - struct json_object *simu = NULL; - - struct json_object *req_json = json_tokener_parse(req_json_str); - if ((json_object_object_get_ex(req_json, "sessionHandle", &sess)) && - (json_object_object_get_ex(req_json, "simulationMode", &simu))) - { - if (json_object_is_type(sess, json_type_int) && - json_object_is_type(simu, json_type_boolean)) - { - sessionHdl = json_object_get_int(sess); - simuMode = json_object_get_int(simu); - ret = true; - } - else - { - fprintf(stdout, "key is invalid type.\n"); - } - } - else - { - fprintf(stdout, "key sessionHandle or simulationMode not found.\n"); - } - - return ret; -} - - -/** - * @brief Create arguments to pass to Genivi API CancelRouteCalculation - * @param[in] req_json_str JSON request from BinderClient - * @param[out] sessionHdl Session handle - * @param[out] routeHdl Route handle - * @return Success or failure of processing - */ -bool AnalyzeRequest::CreateParamsCancelRouteCalculation( const char* req_json_str, uint32_t& sessionHdl, uint32_t& routeHdl ) -{ - // Get sessionHandle, RouteHandle - return JsonObjectGetSessionHdlRouteHdl(req_json_str, sessionHdl, routeHdl); -} - - -/** - * @brief Create arguments to pass to Genivi API SetWaypoints - * @param[in] req_json_str JSON request from BinderClient - * @param[out] sessionHdl Session handle - * @param[out] routeHdl Route handle - * @param[out] currentPos Whether or not to draw a route from the position of the vehicle - * @param[out] waypointsList Destination coordinates - * @return Success or failure of processing - */ -bool AnalyzeRequest::CreateParamsSetWaypoints( const char* req_json_str, uint32_t& sessionHdl, uint32_t& routeHdl, - bool& currentPos, std::vector<Waypoint>& waypointsList ) -{ - bool ret = false; - struct json_object *sess = NULL; - struct json_object *rou = NULL; - struct json_object *current = NULL; - struct json_object *wpl = NULL; - - struct json_object *req_json = json_tokener_parse(req_json_str); - if ((json_object_object_get_ex(req_json, "sessionHandle", &sess)) && - (json_object_object_get_ex(req_json, "route", &rou)) && - (json_object_object_get_ex(req_json, "startFromCurrentPosition", ¤t)) && - (json_object_object_get_ex(req_json, "", &wpl))) - { - if (json_object_is_type(sess, json_type_int) && - json_object_is_type(rou, json_type_int) && - json_object_is_type(current, json_type_boolean) && - json_object_is_type(wpl, json_type_array)) - { - sessionHdl = json_object_get_int(sess); - routeHdl = json_object_get_int(rou); - currentPos = json_object_get_boolean(current); - - // Get latitude, longitude - for (int i = 0; i < json_object_array_length(wpl); ++i) - { - struct json_object *array = json_object_array_get_idx(wpl, i); - struct json_object *lati = NULL; - struct json_object *longi = NULL; - - if (json_object_object_get_ex(array, "latitude", &lati) && - json_object_object_get_ex(array, "longitude", &longi)) { - - double latitude = json_object_get_double(lati); - double longitude = json_object_get_double(longi); - Waypoint destWp(latitude, longitude); - waypointsList.push_back(destWp); - ret = true; - } - else - { - fprintf(stdout, "key latitude or longitude not found.\n"); - } - } - } - else - { - fprintf(stdout, "key is invalid type.\n"); - } - } - else - { - fprintf(stdout, "key valuesToReturn not found.\n"); - } - - return ret; -} - - -/** - * @brief Create arguments to pass to Genivi API CalculateRoute - * @param[in] req_json_str JSON request from BinderClient - * @param[out] sessionHdl Session handle - * @param[out] routeHdl Route handle - * @return Success or failure of processing - */ -bool AnalyzeRequest::CreateParamsCalculateRoute( const char* req_json_str, uint32_t& sessionHdl, uint32_t& routeHdl ) -{ - // Get sessionHandle, RouteHandle - return JsonObjectGetSessionHdlRouteHdl(req_json_str, sessionHdl, routeHdl); -} - - -/** - * @brief Get session handle and route handle information from JSON - * @param[in] req_json_str JSON request from BinderClient - * @param[out] Session handle value - * @return Success or failure of processing - */ - -bool AnalyzeRequest::JsonObjectGetSessionHdl( const char* req_json_str, uint32_t& sessionHdl) -{ - bool ret = false; - struct json_object *sess = NULL; - - struct json_object *req_json = json_tokener_parse(req_json_str); - if (json_object_object_get_ex(req_json, "sessionHandle", &sess)) - { - if (json_object_is_type(sess, json_type_int)) - { - sessionHdl = json_object_get_int(sess); - ret = true; - } - else - { - fprintf(stdout, "key is not integer type.\n"); - } - } - else - { - fprintf(stdout, "key sessionHandle not found.\n"); - } - - return ret; -} - - -/** - * @brief Get session handle and route handle information from JSON - * @param[in] req_json_str JSON request from BinderClient - * @param[out] Session handle value - * @param[out] Route handle value - * @return Success or failure of processing - */ - -bool AnalyzeRequest::JsonObjectGetSessionHdlRouteHdl( const char* req_json_str, uint32_t& sessionHdl, uint32_t& routeHdl) -{ - bool ret = false; - struct json_object *sess = NULL; - struct json_object *rou = NULL; - - struct json_object *req_json = json_tokener_parse(req_json_str); - if ((json_object_object_get_ex(req_json, "sessionHandle", &sess)) && - (json_object_object_get_ex(req_json, "route", &rou))) - { - if (json_object_is_type(sess, json_type_int) && - json_object_is_type(rou, json_type_int)) - { - sessionHdl = json_object_get_int(sess); - routeHdl = json_object_get_int(rou); - ret = true; - } - else - { - fprintf(stdout, "key is not integer type.\n"); - } - } - else - { - fprintf(stdout, "key sessionHandle or route not found.\n"); - } - - return ret; -} diff --git a/src/api.cpp b/src/api.cpp deleted file mode 100644 index 8573b47..0000000 --- a/src/api.cpp +++ /dev/null @@ -1,419 +0,0 @@ -// Copyright 2017 AW SOFTWARE CO.,LTD -// Copyright 2017 AISIN AW CO.,LTD - -#include <string.h> - -#include "binder_reply.h" -#include "genivi_request.h" -#include "analyze_request.h" -#include "genivi/genivi-navicore-constants.h" - -#define AFB_BINDING_VERSION 2 - -extern "C" { - #include <afb/afb-binding.h> -} - -/** - * Variable declaration - */ -GeniviRequest* geniviRequest; // Send request to Genivi -BinderReply* binderReply; // Convert Genivi response result to json format -AnalyzeRequest* analyzeRequest; // Analyze BinderClient's request and create arguments to pass to GeniviAPI - -/** - * @brief navicore_getposition request callback - * @param[in] req Request from client - */ -void OnRequestNavicoreGetPosition(afb_req req) -{ - AFB_REQ_NOTICE(req, "--> Start %s()", __func__); - AFB_REQ_DEBUG(req, "request navicore_getposition"); - - // Request of Json format request - json_object* req_json = afb_req_json(req); - const char* req_json_str = json_object_to_json_string(req_json); - AFB_REQ_NOTICE(req, "req_json_str = %s", req_json_str); - - // Request analysis and create arguments to pass to Genivi - std::vector< int32_t > Params; - if( !analyzeRequest->CreateParamsGetPosition( req_json_str, Params )) - { - afb_req_fail(req, "failed", "navicore_getposition Bad Request"); - return; - } - - // GENIVI API call - std::map< int32_t, double > posList = geniviRequest->NavicoreGetPosition( Params ); - - // Convert to json style response - APIResponse response = binderReply->ReplyNavicoreGetPosition( posList ); - - // On success - if(response.isSuccess) - { - AFB_REQ_NOTICE(req, "res_json_str = %s", json_object_to_json_string(response.json_data)); - // Return success to BinderClient - afb_req_success(req, response.json_data, "navicore_getposition"); - } - else - { - AFB_REQ_ERROR(req, "%s - %s:%d", response.errMessage.c_str(), __FILE__, __LINE__); - afb_req_fail(req, "failed", "navicore_getposition Bad Request"); - - // Json object release - json_object_put(response.json_data); - } - - AFB_REQ_NOTICE(req, "<-- End %s()", __func__); -} - - -/** - * @brief navicore_getallroutes request callback - * @param[in] req Request from client - */ -void OnRequestNavicoreGetAllRoutes(afb_req req) -{ - AFB_REQ_NOTICE(req, "--> Start %s()", __func__); - AFB_REQ_DEBUG(req, "request navicore_getallroutes"); - - // No request information in json format - AFB_REQ_NOTICE(req, "req_json_str = none"); - - // GENEVI API call - std::vector< uint32_t > allRoutes = geniviRequest->NavicoreGetAllRoutes(); - - // Convert to json style response - APIResponse response = binderReply->ReplyNavicoreGetAllRoutes( allRoutes ); - - // On success - if(response.isSuccess) - { - AFB_REQ_NOTICE(req, "res_json_str = %s", json_object_to_json_string(response.json_data)); - // Return success to BinderClient - afb_req_success(req, response.json_data, "navicore_getallroutes"); - } - else - { - AFB_REQ_ERROR(req, "%s - %s:%d", response.errMessage.c_str(), __FILE__, __LINE__); - afb_req_fail(req, "failed", "navicore_getallroutes Bad Request"); - - // json object release - json_object_put(response.json_data); - } - - AFB_REQ_NOTICE(req, "<-- End %s()", __func__); -} - - -/** - * @brief navicore_createroute request callback - * @param[in] req Request from client - */ -void OnRequestNavicoreCreateRoute(afb_req req) -{ - AFB_REQ_NOTICE(req, "--> Start %s ", __func__); - AFB_REQ_DEBUG(req, "request navicore_createroute"); - - // Request of json format request - json_object* req_json = afb_req_json(req); - const char* req_json_str = json_object_to_json_string(req_json); - AFB_REQ_NOTICE(req, "req_json_str = %s", req_json_str); - - // Request analysis and create arguments to pass to Genivi - uint32_t sessionHdl = 0; - if( !analyzeRequest->CreateParamsCreateRoute( req_json_str, sessionHdl )) - { - afb_req_fail(req, "failed", "navicore_createroute Bad Request"); - return; - } - - // GENEVI API call - uint32_t routeHdl = geniviRequest->NavicoreCreateRoute( sessionHdl ); - - // Convert to json style response - APIResponse response = binderReply->ReplyNavicoreCreateRoute( routeHdl ); - - // On success - if(response.isSuccess) - { - AFB_REQ_NOTICE(req, "res_json_str = %s", json_object_to_json_string(response.json_data)); - // Return success to BinderClient - afb_req_success(req, response.json_data, "navicore_createroute"); - } - else - { - AFB_REQ_ERROR(req, "%s - %s:%d", response.errMessage.c_str(), __FILE__, __LINE__); - afb_req_fail(req, "failed", "navicore_createroute Bad Request"); - - // json object release - json_object_put(response.json_data); - } - - AFB_REQ_NOTICE(req, "<-- End %s()", __func__); -} - - -/** - * @brief navicore_pausesimulation request callback - * @param[in] req Request from client - */ -void OnRequestNavicorePauseSimulation(afb_req req) -{ - AFB_REQ_NOTICE(req, "--> Start %s()", __func__); - AFB_REQ_DEBUG(req, "request navicore_pausesimulation"); - - // Request of json format request - json_object* req_json = afb_req_json(req); - const char* req_json_str = json_object_to_json_string(req_json); - AFB_REQ_NOTICE(req, "req_json_str = %s", req_json_str); - - // Request analysis and create arguments to pass to Genivi - uint32_t sessionHdl = 0; - if( !analyzeRequest->CreateParamsPauseSimulation( req_json_str, sessionHdl )) - { - afb_req_fail(req, "failed", "navicore_pausesimulation Bad Request"); - return; - } - - // GENEVI API call - geniviRequest->NavicorePauseSimulation( sessionHdl ); - - // No reply unnecessary API for conversion to json format response is unnecessary - AFB_REQ_NOTICE(req, "res_json_str = none"); - - // Return success to BinderClient - afb_req_success(req, NULL, "navicore_pausesimulation"); - - AFB_REQ_NOTICE(req, "<-- End %s()", __func__); -} - - -/** - * @brief navicore_setsimulationmode request callback - * @param[in] req Request from client - */ -void OnRequestNavicoreSetSimulationMode(afb_req req) -{ - AFB_REQ_NOTICE(req, "--> Start %s()", __func__); - AFB_REQ_DEBUG(req, "request navicore_setsimulationmode"); - - // Request of json format request - json_object* req_json = afb_req_json(req); - const char* req_json_str = json_object_to_json_string(req_json); - AFB_REQ_NOTICE(req, "req_json_str = %s", req_json_str); - - // Request analysis and create arguments to pass to Genivi - uint32_t sessionHdl = 0; - bool simuMode = false; - if( !analyzeRequest->CreateParamsSetSimulationMode( req_json_str, sessionHdl, simuMode )) - { - afb_req_fail(req, "failed", "navicore_setsimulationmode Bad Request"); - return; - } - - // GENEVI API call - geniviRequest->NavicoreSetSimulationMode( sessionHdl, simuMode ); - - // No reply unnecessary API for conversion to json format response is unnecessary - AFB_REQ_NOTICE(req, "res_json_str = none"); - - // Return success to BinderClient - afb_req_success(req, NULL, "navicore_setsimulationmode"); - - AFB_REQ_NOTICE(req, "<-- End %s()", __func__); -} - - -/** - * @brief navicore_cancelroutecalculation request callback - * @param[in] req Request from client - */ -void OnRequestNavicoreCancelRouteCalculation(afb_req req) -{ - AFB_REQ_NOTICE(req, "--> Start %s()", __func__); - AFB_REQ_DEBUG(req, "request navicore_cancelroutecalculation"); - - // Request of Json format request - json_object* req_json = afb_req_json(req); - const char* req_json_str = json_object_to_json_string(req_json); - AFB_REQ_NOTICE(req, "req_json_str = %s", req_json_str); - - // Request analysis and create arguments to pass to Genivi - uint32_t sessionHdl = 0; - uint32_t routeHdl = 0; - if( !analyzeRequest->CreateParamsCancelRouteCalculation( req_json_str, sessionHdl, routeHdl )) - { - afb_req_fail(req, "failed", "navicore_cancelroutecalculation Bad Request"); - return; - } - - // GENEVI API call - geniviRequest->NavicoreCancelRouteCalculation( sessionHdl, routeHdl ); - - // No reply unnecessary API for conversion to json format response is unnecessary - AFB_REQ_NOTICE(req, "res_json_str = none"); - - // Return success to BinderClient - afb_req_success(req, NULL, "navicore_cancelroutecalculation"); - - AFB_REQ_NOTICE(req, "<-- End %s()", __func__); -} - - -/** - * @brief navicore_setwaypoints request callback - * @param[in] req Request from client - */ -void OnRequestNavicoreWaypoints(afb_req req) -{ - AFB_REQ_NOTICE(req, "--> Start %s()", __func__); - AFB_REQ_DEBUG(req, "request navicore_setwaypoints"); - - // Request of Json format request - json_object* req_json = afb_req_json(req); - const char* req_json_str = json_object_to_json_string(req_json); - AFB_REQ_NOTICE(req, "req_json_str = %s", req_json_str); - - // Request analysis and create arguments to pass to Genivi - uint32_t sessionHdl = 0; - uint32_t routeHdl = 0; - bool currentPos = false; - std::vector<Waypoint> waypointsList; - if( !analyzeRequest->CreateParamsSetWaypoints( req_json_str, sessionHdl, routeHdl, currentPos, waypointsList )) - { - afb_req_fail(req, "failed", "navicore_setwaypoints Bad Request"); - return; - } - - // GENEVI API call - geniviRequest->NavicoreSetWaypoints( sessionHdl, routeHdl, currentPos, waypointsList ); - - // No reply unnecessary API for conversion to json format response is unnecessary - AFB_REQ_NOTICE(req, "res_json_str = none"); - - // Return success to BinderClient - afb_req_success(req, NULL, "navicore_setwaypoints"); - - AFB_REQ_NOTICE(req, "<-- End %s()", __func__); -} - - -/** - * @brief navicore_calculateroute request callback - * @param[in] req Request from client - */ -void OnRequestNavicoreCalculateRoute(afb_req req) -{ - AFB_REQ_NOTICE(req, "--> Start %s()", __func__); - AFB_REQ_DEBUG(req, "request navicore_calculateroute"); - - // Request of Json format request - json_object* req_json = afb_req_json(req); - const char* req_json_str = json_object_to_json_string(req_json); - AFB_REQ_NOTICE(req, "req_json_str = %s", req_json_str); - - // Request analysis and create arguments to pass to Genivi - uint32_t sessionHdl = 0; - uint32_t routeHdl = 0; - if( !analyzeRequest->CreateParamsCalculateRoute( req_json_str, sessionHdl, routeHdl )) - { - afb_req_fail(req, "failed", "navicore_calculateroute Bad Request"); - return; - } - - // GENEVI API call - geniviRequest->NavicoreCalculateRoute( sessionHdl, routeHdl ); - - // No reply unnecessary API for conversion to json format response is unnecessary - AFB_REQ_NOTICE(req, "res_json_str = none"); - - // Return success to BinderClient - afb_req_success(req, NULL, "navicore_calculateroute"); - - AFB_REQ_NOTICE(req, "<-- End %s()", __func__); -} - - -/** - * @brief navicore_getallsessions request callback - * @param[in] req Request from client - */ -void OnRequestNavicoreGetAllSessions(afb_req req) -{ - AFB_REQ_NOTICE(req, "--> Start %s()", __func__); - AFB_REQ_DEBUG(req, "request navicore_getallsessions"); - - // No request information in Json format - AFB_REQ_NOTICE(req, "req_json_str = none"); - - // GENEVI API call - std::map<uint32_t, std::string> allSessions = geniviRequest->NavicoreGetAllSessions(); - - // Convert to json style response - APIResponse response = binderReply->ReplyNavicoreGetAllSessions( allSessions ); - - // On success - if(response.isSuccess) - { - AFB_REQ_NOTICE(req, "res_json_str = %s", json_object_to_json_string(response.json_data)); - // Return success to BinderClient - afb_req_success(req, response.json_data, "navicore_getallsessions"); - } - else - { - AFB_REQ_ERROR(req, "%s - %s:%d", response.errMessage.c_str(), __FILE__, __LINE__); - afb_req_fail(req, "failed", "navicore_getallsessions Bad Request"); - - // json object release - json_object_put(response.json_data); - } - - AFB_REQ_NOTICE(req, "<-- End %s()", __func__); -} - - -/** - * @brief Callback called at service startup - */ -int Init() -{ - // Create instance - geniviRequest = new GeniviRequest(); - binderReply = new BinderReply(); - analyzeRequest = new AnalyzeRequest(); - - return 0; -} - -/** - * @brief API definition - */ -const afb_verb_v2 verbs[] = -{ - { verb : "navicore_getposition", callback : OnRequestNavicoreGetPosition }, - { verb : "navicore_getallroutes", callback : OnRequestNavicoreGetAllRoutes }, - { verb : "navicore_createroute", callback : OnRequestNavicoreCreateRoute }, - { verb : "navicore_pausesimulation", callback : OnRequestNavicorePauseSimulation }, - { verb : "navicore_setsimulationmode", callback : OnRequestNavicoreSetSimulationMode }, - { verb : "navicore_cancelroutecalculation", callback : OnRequestNavicoreCancelRouteCalculation }, - { verb : "navicore_setwaypoints", callback : OnRequestNavicoreWaypoints }, - { verb : "navicore_calculateroute", callback : OnRequestNavicoreCalculateRoute }, - { verb : "navicore_getallsessions", callback : OnRequestNavicoreGetAllSessions }, - { verb : NULL } -}; - -/** - * @brief Service definition - */ -const afb_binding_v2 afbBindingV2 = -{ - "naviapi", - "", - "", - verbs, - NULL, - Init -}; - diff --git a/src/binder_reply.cpp b/src/binder_reply.cpp deleted file mode 100644 index 172a22a..0000000 --- a/src/binder_reply.cpp +++ /dev/null @@ -1,168 +0,0 @@ -// Copyright 2017 AW SOFTWARE CO.,LTD -// Copyright 2017 AISIN AW CO.,LTD - -#include "binder_reply.h" -#include "genivi/genivi-navicore-constants.h" - -/** - * @brief GeniviAPI GetPosition call - * @param[in] posList Map information on key and value of information acquired from Genivi - * @return Response information - */ -APIResponse BinderReply::ReplyNavicoreGetPosition( std::map<int32_t, double>& posList ) -{ - APIResponse response = {0}; - - // Json information to return as a response - struct json_object* response_json = json_object_new_array(); - std::map<int32_t, double>::iterator it; - - // If the argument map is empty return - if(posList.empty()) - { - response.isSuccess = false; - response.errMessage = "posList is empty"; - response.json_data = response_json; - return response; - } - - // Make the passed Genivi response json format - for (it = posList.begin(); it != posList.end(); it++) - { - struct json_object* obj = json_object_new_object(); - - switch(it->first) - { - case NAVICORE_LATITUDE: - json_object_object_add(obj, "key", json_object_new_int(NAVICORE_LATITUDE)); - json_object_object_add(obj, "value", json_object_new_double(it->second) ); - json_object_array_add(response_json, obj); - break; - - case NAVICORE_LONGITUDE: - json_object_object_add(obj, "key", json_object_new_int(NAVICORE_LONGITUDE)); - json_object_object_add(obj, "value", json_object_new_double(it->second)); - json_object_array_add(response_json, obj); - break; - - case NAVICORE_HEADING: - json_object_object_add(obj, "key", json_object_new_int(NAVICORE_HEADING)); - json_object_object_add(obj, "value", json_object_new_boolean (it->second)); - json_object_array_add(response_json, obj); - break; -#if 0 - // no support - case NAVICORE_TIMESTAMP: - json_object_object_add(obj, "key", json_object_new_int(NAVICORE_TIMESTAMP)); - json_object_object_add(obj, "value", json_object_new_int(it->second)); - json_object_array_add(response_json, obj); - break; - - // no support - case NAVICORE_SPEED: - json_object_object_add(obj, "key", json_object_new_int(NAVICORE_SPEED)); - json_object_object_add(obj, "value", json_object_new_int(it->second)); - json_object_array_add(response_json, obj); - break; -#endif - - case NAVICORE_SIMULATION_MODE: - json_object_object_add(obj, "key", json_object_new_int(NAVICORE_SIMULATION_MODE)); - json_object_object_add(obj, "value", json_object_new_boolean (it->second)); - json_object_array_add(response_json, obj); - break; - - default: - fprintf(stderr, "Unknown key."); - json_object_put(obj); - break; - } - } - - response.json_data = response_json; - response.isSuccess = true; - return response; -} - -/** - * @brief GeniviAPI GetAllRoutes call - * @param[in] allRoutes Route handle information - * @return Response information - */ -APIResponse BinderReply::ReplyNavicoreGetAllRoutes( std::vector< uint32_t > &allRoutes ) -{ - APIResponse response = {0}; - - // Json information to return as a response - struct json_object* response_json = json_object_new_array(); - - if (0 < allRoutes.size()) - { - std::vector< uint32_t >::iterator it; - - for (it = allRoutes.begin(); it != allRoutes.end(); it++) - { - struct json_object* obj = json_object_new_object(); - json_object_object_add(obj, "route", json_object_new_int(*it)); - json_object_array_add(response_json, obj); - } - } - - response.json_data = response_json; - response.isSuccess = true; - return response; -} - -/** - * @brief GeniviAPI CreateRoute call - * @param[in] route Route handle - * @return Response information - */ -APIResponse BinderReply::ReplyNavicoreCreateRoute( uint32_t route ) -{ - APIResponse response; - - // Json information to return as a response - struct json_object* response_json = json_object_new_object(); - json_object_object_add(response_json, "route", json_object_new_int(route)); - - response.json_data = response_json; - response.isSuccess = true; - return response; -} - -/** - * @brief GeniviAPI GetAllSessions call - * @param[in] allSessions Map information on key and value of information acquired from Genivi - * @return Response information - */ -APIResponse BinderReply::ReplyNavicoreGetAllSessions( std::map<uint32_t, std::string> &allSessions ) -{ - APIResponse response = {0}; - - // Json information to return as a response - struct json_object* response_json = json_object_new_array(); - std::map<uint32_t, std::string>::iterator it; - - for (it = allSessions.begin(); it != allSessions.end(); it++) - { - struct json_object* obj = json_object_new_object(); - - if (NAVICORE_INVALID != it->first) - { - json_object_object_add(obj, "sessionHandle", json_object_new_int(it->first)); - json_object_object_add(obj, "client", json_object_new_string(it->second.c_str())); - json_object_array_add(response_json, obj); - } - else - { - fprintf(stderr, "invalid key."); - json_object_put(obj); - } - } - - response.json_data = response_json; - response.isSuccess = true; - return response; -} - diff --git a/src/genivi_request.cpp b/src/genivi_request.cpp deleted file mode 100644 index a485667..0000000 --- a/src/genivi_request.cpp +++ /dev/null @@ -1,350 +0,0 @@ -// Copyright 2017 AW SOFTWARE CO.,LTD -// Copyright 2017 AISIN AW CO.,LTD - -#include "genivi/navicore.h" -#include "genivi/genivi-navicore-constants.h" -#include "genivi_request.h" -#include <stdio.h> -#include <exception> -#include <dbus-c++-1/dbus-c++/dbus.h> - -/** - * @brief Destructor - */ -GeniviRequest::~GeniviRequest() -{ - delete (Navicore*)navicore_; - navicore_ = NULL; -} - -/** - * @brief DBus session creation - */ -void GeniviRequest::CreateDBusSession( ) -{ - try - { - static DBus::BusDispatcher dispatcher; - DBus::default_dispatcher = &dispatcher; - DBus::Connection conn = DBus::Connection::SessionBus(); - - navicore_ = new Navicore(conn, "/org/genivi/navicore", "org.agl.naviapi"); - } - catch(const std::exception& e) - { - fprintf(stderr, "Error:%s\n", e.what()); - } -} - -/** - * @brief Check connection status - * @return Presence / absence of connection - */ -bool GeniviRequest::CheckSession() -{ - if(this->navicore_ == NULL) - { - this->CreateDBusSession(); - } - - try - { - // Get connection status - DBus::Connection conn = ((Navicore*)navicore_)->conn(); - bool isConnect = conn.connected(); - - // If it is not connected, it issues an error - if(!isConnect) - { - fprintf(stderr, "Service has no session.\n"); - } - - return isConnect; - } - catch(const std::exception& e) - { - fprintf(stderr, "Error:%s\n", e.what()); - return false; - } -} - -/** - * @brief Call GeniviAPI GetPosition to get information - * @param[in] valuesToReturn Key arrangement of information acquired from Genivi - * @return Map information on key and value of information acquired from Genivi - */ -std::map< int32_t, double > GeniviRequest::NavicoreGetPosition( const std::vector< int32_t >& valuesToReturn ) -{ - std::map< int32_t, double > ret; - - if( !CheckSession() ) - { - return ret; - } - - try - { - std::map< int32_t, ::DBus::Struct< uint8_t, ::DBus::Variant > >::iterator it; - std::map< int32_t, ::DBus::Struct< uint8_t, ::DBus::Variant > > PosList = - ((Navicore*)navicore_)->GetPosition(valuesToReturn); - for (it = PosList.begin(); it != PosList.end(); it++) - { - if (it->first == NAVICORE_LATITUDE || it->second._1 == NAVICORE_LATITUDE) - { - ret[it->first] = it->second._2.reader().get_double(); - } - else if (it->first == NAVICORE_LONGITUDE || it->second._1 == NAVICORE_LONGITUDE) - { - ret[it->first] = it->second._2.reader().get_double(); - } - else if (it->first == NAVICORE_HEADING || it->second._1 == NAVICORE_HEADING) - { - ret[it->first] = it->second._2.reader().get_uint32(); - } -#if 0 // no supported - else if (it->first == NAVICORE_TIMESTAMP || it->second._1 == NAVICORE_TIMESTAMP) - { - ret[it->first] = it->second._2.reader().get_uint32(); - } - else if (it->first == NAVICORE_SPEED || it->second._1 == NAVICORE_SPEED) - { - ret[it->first] = it->second._2.reader().get_int32(); - } -#endif - else if (it->first == NAVICORE_SIMULATION_MODE || it->second._1 == NAVICORE_SIMULATION_MODE) - { - ret[it->first] = it->second._2.reader().get_bool(); - } - } - } - catch(const std::exception& e) - { - fprintf(stderr, "Error:%s\n", e.what()); - } - - return ret; -} - -/** - * @brief Call GeniviAPI GetPosition to get information - * @return Route handle acquired from Genivi - */ -std::vector< uint32_t > GeniviRequest::NavicoreGetAllRoutes( void ) -{ - if( !CheckSession() ) - { - std::vector< uint32_t > no_route; - return no_route; - } - - std::vector< uint32_t > allRoutes; - try - { - allRoutes = ((Navicore*)navicore_)->GetAllRoutes(); - } - catch(const std::exception& e) - { - fprintf(stderr, "Error:%s\n", e.what()); - } - - return allRoutes; -} - - -/** - * @brief Call GeniviAPI GetPosition to get information - * @param[in] sessionHandle Session handle - * @return Route handle acquired from Genivi - */ -uint32_t GeniviRequest::NavicoreCreateRoute( const uint32_t& sessionHandle ) -{ - if( !CheckSession() ) - { - return 0; - } - - uint32_t routeHandle = 0; - try - { - routeHandle = ((Navicore*)navicore_)->CreateRoute(sessionHandle); - } - catch(const std::exception& e) - { - fprintf(stderr, "Error:%s\n", e.what()); - } - - return routeHandle; -} - -/** - * @brief Call GeniviAPI PauseSimulation - * @param[in] sessionHandle Session handle - */ -void GeniviRequest::NavicorePauseSimulation( const uint32_t& sessionHandle ) -{ - if( !CheckSession() ) - { - return; - } - - try - { - ((Navicore*)navicore_)->PauseSimulation(sessionHandle); - } - catch(const std::exception& e) - { - fprintf(stderr, "Error:%s\n", e.what()); - } -} - - -/** - * @brief Call GeniviAPI SetSimulationMode - * @param[in] sessionHandle Session handle - * @param[in] activate Simulation mode enabled / disabled - */ -void GeniviRequest::NavicoreSetSimulationMode( const uint32_t& sessionHandle, const bool& activate ) -{ - if( !CheckSession() ) - { - return; - } - - try - { - ((Navicore*)navicore_)->SetSimulationMode(sessionHandle, activate); - } - catch(const std::exception& e) - { - fprintf(stderr, "Error:%s\n", e.what()); - } -} - - -/** - * @brief Call GeniviAPI SetSimulationMode - * @param[in] sessionHandle Session handle - * @param[in] routeHandle Route handle - */ -void GeniviRequest::NavicoreCancelRouteCalculation( const uint32_t& sessionHandle, const uint32_t& routeHandle ) -{ - if( !CheckSession() ) - { - return; - } - - try - { - ((Navicore*)navicore_)->CancelRouteCalculation(sessionHandle, routeHandle); - } - catch(const std::exception& e) - { - fprintf(stderr, "Error:%s\n", e.what()); - } -} - -/** - * @brief Call GeniviAPI SetWaypoints - * @param[in] sessionHandle Session handle - * @param[in] routeHandle Route handle - * @param[in] startFromCurrentPosition Whether or not to draw a route from the position of the vehicle - * @param[in] waypointsList Destination coordinates - */ -void GeniviRequest::NavicoreSetWaypoints( const uint32_t& sessionHandle, const uint32_t& routeHandle, - const bool& startFromCurrentPosition, const std::vector<Waypoint>& waypointsList ) -{ - if( !CheckSession() ) - { - return; - } - - std::vector<Waypoint>::const_iterator it; - std::vector< std::map< int32_t, ::DBus::Struct< uint8_t, ::DBus::Variant > > > wpl; - - fprintf(stdout, "session: %d, route: %d, startFromCurrentPosition: %d\n", - sessionHandle, routeHandle, startFromCurrentPosition); - - for (it = waypointsList.begin(); it != waypointsList.end(); it++) - { - std::map< int32_t, ::DBus::Struct< uint8_t, ::DBus::Variant > > Point; - ::DBus::Struct< uint8_t, ::DBus::Variant > VarLat, VarLon; - - VarLat._1 = NAVICORE_LATITUDE; - VarLat._2.writer().append_double(std::get<0>(*it)); - fprintf(stdout, "VarLat._1 : %x, VarLat._2 : %lf\n", VarLat._1, VarLat._2.reader().get_double()); - - VarLon._1 = NAVICORE_LONGITUDE; - VarLon._2.writer().append_double(std::get<1>(*it)); - fprintf(stdout, "VarLon._1 : %x, VarLon._2 : %lf\n", VarLon._1, VarLon._2.reader().get_double()); - - Point[NAVICORE_LATITUDE] = VarLat; - Point[NAVICORE_LONGITUDE] = VarLon; - - wpl.push_back(Point); - } - - try - { - ((Navicore*)navicore_)->SetWaypoints(sessionHandle, routeHandle, startFromCurrentPosition, wpl); - } - catch(const std::exception& e) - { - fprintf(stderr, "Error:%s\n", e.what()); - } -} - -/** - * @brief Call GeniviAPI CalculateRoute - * @param[in] sessionHandle Session handle - * @param[in] routeHandle Route handle - */ -void GeniviRequest::NavicoreCalculateRoute( const uint32_t& sessionHandle, const uint32_t& routeHandle ) -{ - if( !CheckSession() ) - { - return; - } - - try - { - ((Navicore*)navicore_)->CalculateRoute(sessionHandle, routeHandle); - } - catch(const std::exception& e) - { - fprintf(stderr, "Error:%s\n", e.what()); - } -} - - -/** - * @brief Call GeniviAPI CalculateRoute - * @return Map information on key and value of information acquired from Genivi - */ -std::map<uint32_t, std::string> GeniviRequest::NavicoreGetAllSessions() -{ - std::map<uint32_t, std::string> ret; - - if( !CheckSession() ) - { - return ret; - } - - std::vector< ::DBus::Struct< uint32_t, std::string > > ncAllSessions; - std::vector< ::DBus::Struct< uint32_t, std::string > >::iterator it; - - try - { - ncAllSessions = ((Navicore*)navicore_)->GetAllSessions(); - for (it = ncAllSessions.begin(); it != ncAllSessions.end(); it++) - { - ret[it->_1] = it->_2; - } - } - catch(const std::exception& e) - { - fprintf(stderr, "Error:%s\n", e.what()); - } - - return ret; -} - diff --git a/src/traces.h b/src/traces.h deleted file mode 100644 index a1f96ec..0000000 --- a/src/traces.h +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright 2017 AISIN AW CO.,LTD - -#ifndef __TRACE_H__ -#define __TRACE_H__ - -#include <stdio.h> - -#define BLACK "\033[30m" -#define RED "\033[31m" -#define GREEN "\033[32m" -#define YELLOW "\033[33m" -#define BLUE "\033[34m" -#define PURPLE "\033[35m" -#define DGREEN "\033[6m" -#define WHITE "\033[7m" -#define CYAN "\x1b[36m" -#define NONE "\033[0m" - -#ifdef NDEBUG - -#define TRACE_DEBUG_JSON(fmt, args...) -#define TRACE_DEBUG(fmt, args...) -#define TRACE_INFO(fmt, args...) -#define TRACE_WARN(fmt, args...) -#define TRACE_ERROR(fmt, args...) - -#else - -#define TRACE_DEBUG(fmt, args...) do { fprintf(stderr, "[%s:%d] " CYAN "DEBUG" NONE ": " fmt "\n", __func__, __LINE__, ##args); } while(0) -#define TRACE_INFO(fmt, args...) do { fprintf(stderr, "[%s:%d] " GREEN "INFO" NONE ": " fmt "\n", __func__, __LINE__, ##args); } while(0) -#define TRACE_WARN(fmt, args...) do { fprintf(stderr, "[%s:%d] " YELLOW "WARN" NONE": " fmt "\n", __func__, __LINE__, ##args); } while(0) -#define TRACE_ERROR(fmt, args...) do { fprintf(stderr, "[%s:%d] " RED "ERROR" NONE ": " fmt "\n", __func__, __LINE__, ##args); } while(0) - -#define TRACE_DEBUG_JSON(fmt, args...) - -#endif - -#endif // __TRACE_H__ -- GitLab