diff options
Diffstat (limited to 'src')
11 files changed, 3007 insertions, 177 deletions
diff --git a/src/navigation/navigation-core/CMakeLists.txt b/src/navigation/navigation-core/CMakeLists.txt index 65e2e1b..819f89b 100644 --- a/src/navigation/navigation-core/CMakeLists.txt +++ b/src/navigation/navigation-core/CMakeLists.txt @@ -90,22 +90,22 @@ if(${YOCTO_CONFIG}) endif() -add_subdirectory(guidance-plugin) - -add_subdirectory(mapmatchedposition-plugin) - -add_subdirectory(routing-plugin) - -add_subdirectory(session-plugin) - add_subdirectory(enhancedposition-plugin) if (WITH_PLUGIN_MIGRATION) set(FRANCA_DIR "${API_DIR}/franca") add_subdirectory(configuration-server-plugin) add_subdirectory(locationinput-server-plugin) + add_subdirectory(guidance-server-plugin) + add_subdirectory(mapmatchedposition-server-plugin) + add_subdirectory(routing-server-plugin) + add_subdirectory(session-server-plugin) else() add_subdirectory(configuration-plugin) add_subdirectory(locationinput-plugin) + add_subdirectory(guidance-plugin) + add_subdirectory(mapmatchedposition-plugin) + add_subdirectory(routing-plugin) + add_subdirectory(session-plugin) endif() diff --git a/src/navigation/navigation-core/guidance-server-plugin/CMakeLists.txt b/src/navigation/navigation-core/guidance-server-plugin/CMakeLists.txt new file mode 100644 index 0000000..78773ac --- /dev/null +++ b/src/navigation/navigation-core/guidance-server-plugin/CMakeLists.txt @@ -0,0 +1,116 @@ +########################################################################### +# @licence app begin@ +# SPDX-License-Identifier: MPL-2.0 +# +# Component Name: configuration-server-plugin +# +# Author: Philippe Colliot +# +# Copyright (C) 2015, PCA Peugeot Citroën +# +# License: +# This Source Code Form is subject to the terms of the +# Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with +# this file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# @licence end@ +########################################################################### +project(guidance-server-plugin) +cmake_minimum_required(VERSION 2.8) + +message(STATUS ${PROJECT_NAME}) + +set(CMAKE_VERBOSE_MAKEFILE on) +set(CMAKE_CXX_FLAGS "-Wall -std=c++0x") + + + +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/lib) +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/bin) + + +# DBus Path +if(DBUS_LIB_PATH) + message(STATUS "DBUS_LIB_PATH = " ${DBUS_LIB_PATH}) + set(DBUS_INCLUDE_DIRS ${DBUS_LIB_PATH}/include/dbus-1.0 ${DBUS_LIB_PATH}/lib/dbus-1.0/include) + set(DBUS_LIBDIR ${DBUS_LIB_PATH}/lib) + set(DBUS_LIBRARIES ${DBUS_LIB_PATH}/lib/libdbus-1.so) +else() + message(FATAL_ERROR "Please specify the path to your patched DBus library using -DDBUS_LIB_PATH=yourPath") +endif() + +# Packages +find_package(CommonAPI 3.1.5 REQUIRED) +find_package(CommonAPI-DBus 3.1.5 REQUIRED) + + +#pkg_check_modules(DBUS "dbus-1 >= 1.8.4") // #to be fixed, it doesn't work so the paths are set manually (see above) +pkg_check_modules(COMMONAPI "CommonAPI >= 3.1.5") +pkg_check_modules(COMMONAPI_DBUS "CommonAPI-DBus >= 3.1.5") +pkg_check_modules(GOBJECT gobject-2.0) +pkg_check_modules(GLIB REQUIRED glib-2.0) +pkg_check_modules(DBUS_CPP_GLIB dbus-c++-glib-1) + + +# Add the Franca files (that will generate the CommonAPI stuff) +set(COMMONAPI_GEN_DIR "${CMAKE_CURRENT_BINARY_DIR}/src-gen") +add_subdirectory(${FRANCA_DIR}/navigation/navigationcore "${CMAKE_CURRENT_BINARY_DIR}/franca") + +# Path to the generated files +set(API_VERSION_MAJOR 4) +set(API_VERSION "v${API_VERSION_MAJOR}") +set(PRJ_SRC_GEN_ROOT_PATH ${COMMONAPI_GEN_DIR}/${API_VERSION}/org/genivi) #files shared by all the APIs +set(PRJ_SRC_GEN_NAVIGATION_PATH ${PRJ_SRC_GEN_ROOT_PATH}/navigation) #files shared by the navigation APIs +set(PRJ_SRC_GEN_NAVIGATIONCORE_PATH ${PRJ_SRC_GEN_NAVIGATION_PATH}/navigationcore) #files shared by the navigationcore APIs + +# Source Files +set(FRANCA_FILE "Guidance") +FILE(GLOB PRJ_LOCAL_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/*.cxx) +FILE(GLOB PRJ_STUB_GEN_SRCS + ${PRJ_SRC_GEN_ROOT_PATH}/*DBusStub*.cpp ${PRJ_SRC_GEN_ROOT_PATH}/*Types.cpp ${PRJ_SRC_GEN_ROOT_PATH}/*DBusDeployment.cpp ${PRJ_SRC_GEN_ROOT_PATH}/*StubDefault.cpp + ${PRJ_SRC_GEN_NAVIGATION_PATH}/*DBusStub*.cpp ${PRJ_SRC_GEN_NAVIGATION_PATH}/*Types.cpp ${PRJ_SRC_GEN_NAVIGATION_PATH}/*DBusDeployment.cpp ${PRJ_SRC_GEN_NAVIGATION_PATH}/*StubDefault.cpp + ${PRJ_SRC_GEN_NAVIGATIONCORE_PATH}/${FRANCA_FILE}DBusStub*.cpp ${PRJ_SRC_GEN_NAVIGATIONCORE_PATH}/${FRANCA_FILE}Types.cpp ${PRJ_SRC_GEN_NAVIGATIONCORE_PATH}/${FRANCA_FILE}DBusDeployment.cpp ${PRJ_SRC_GEN_NAVIGATIONCORE_PATH}/${FRANCA_FILE}StubDefault.cpp + ) +FILE(GLOB PRJ_STUB_IMPL_SRCS + ${PRJ_SRC_GEN_ROOT_PATH}/*Stub*.cpp + ${PRJ_SRC_GEN_NAVIGATION_PATH}/*Stub*.cpp + ${PRJ_SRC_GEN_NAVIGATIONCORE_PATH}/${FRANCA_FILE}Stub*.cpp + ) + +set(PRJ_SRCS ${PRJ_LOCAL_SRCS} ${PRJ_STUB_GEN_SRCS} ${PRJ_STUB_IMPL_SRCS}) + +include_directories( + ${COMMONAPI_GEN_DIR} + ${PRJ_SRC_GEN_ROOT_PATH} + ${PRJ_SRC_GEN_NAVIGATION_PATH} + ${PRJ_SRC_GEN_NAVIGATIONCORE_PATH} + ${DBUS_INCLUDE_DIRS} + ${COMMONAPI_INCLUDE_DIRS} + ${COMMONAPI_DBUS_INCLUDE_DIRS} + ${GOBJECT_INCLUDE_DIRS} + ${GLIB_INCLUDE_DIRS} + ${DBUS_CPP_GLIB_INCLUDE_DIRS} +) + +link_directories( + ${DBUS_LIBDIR} + ${COMMONAPI_LIBDIR} + ${COMMONAPI_DBUS_LIBDIR} + ${GOBJECT_LIBRARY_DIRS} + ${GLIB_LIBRARY_DIRS} + ${DBUS_CPP_GLIB_DIRS} +) + +set(LIBRARIES + ${DBUS_LIBRARIES} + ${COMMONAPI_LIBRARIES} + ${COMMONAPI_DBUS_LIBRARIES} + ${GOBJECT_LIBRARIES} + ${GLIB_LIBRARIES} + ${DBUS_CPP_GLIB_LIBRARIES} +) + +# Build service +module_add_library(genivi_navigationcore_guidance_server ${PRJ_SRCS}) +target_link_libraries(genivi_navigationcore_guidance_server ${LIBRARIES}) + diff --git a/src/navigation/navigation-core/guidance-server-plugin/genivi_navigationcore_guidance.cxx b/src/navigation/navigation-core/guidance-server-plugin/genivi_navigationcore_guidance.cxx new file mode 100644 index 0000000..45e563e --- /dev/null +++ b/src/navigation/navigation-core/guidance-server-plugin/genivi_navigationcore_guidance.cxx @@ -0,0 +1,846 @@ +/** +* @licence app begin@ +* SPDX-License-Identifier: MPL-2.0 +* +* \copyright Copyright (C) 2013-2014, PCA Peugeot Citroen +* +* \file genivi_navigationcore_guidance.cxx +* +* \brief This file is part of the Navit POC. +* +* \author Martin Schaller <martin.schaller@it-schaller.de> +* \author Philippe Colliot <philippe.colliot@mpsa.com> +* +* \version 1.0 +* +* This Source Code Form is subject to the terms of the +* Mozilla Public License (MPL), v. 2.0. +* If a copy of the MPL was not distributed with this file, +* You can obtain one at http://mozilla.org/MPL/2.0/. +* +* For further information see http://www.genivi.org/. +* +* List of changes: +* +* <date>, <name>, <description of change> +* +* @licence end@ +*/ +#include <dbus-c++/glib-integration.h> + +#if (SPEECH_ENABLED) +#include "genivi-speechservice-constants.h" +#include "genivi-speechservice-speechoutput_proxy.h" +#endif + +#include "config.h" +#define USE_PLUGINS 1 +#include "debug.h" +#include "plugin.h" +#include "item.h" +#include "config_.h" +#include "navit.h" +#include "callback.h" +#include "navigation.h" +#include "map.h" +#include "transform.h" +#include "track.h" +#include "vehicle.h" +#include "route.h" + +#include <CommonAPI/CommonAPI.hpp> +#include <CommonTypes.hpp> +#include <NavigationTypes.hpp> +#include <NavigationCoreTypes.hpp> +#include <GuidanceStubDefault.hpp> + +#if (!DEBUG_ENABLED) +#undef dbg +#define dbg(level,...) ; +#endif + +using namespace v4::org::genivi::navigation::navigationcore; +using namespace v4::org::genivi::navigation; +using namespace v4::org::genivi; + +#if (SPEECH_ENABLED) +class SpeechOutput +: public org::genivi::hmi::speechservice::SpeechOutput_proxy, + public DBus::ObjectProxy +{ + public: + SpeechOutput(DBus::Connection &connection) + : DBus::ObjectProxy(connection, + "/org/genivi/hmi/speechservice/SpeechOutput", + "org.genivi.hmi.speechservice.SpeechOutput") + { + } + + void notifyConnectionStatus(const uint32_t& connectionStatus) + { + + } + + void notifyMarkerReached(const uint32_t& chunkID, const std::string& marker) + { + + } + + void notifyQueueStatus(const uint32_t& queueStatus) + { + + } + + void notifyTTSStatus(const uint32_t& ttsStatus) + { + + } +}; +#endif + +class GuidanceServerStub; + +class GuidanceObj +{ + public: + struct callback *m_guidance_callback; + struct attr m_route, m_vehicleprofile, m_tracking_callback; + uint32_t m_session,m_route_handle; + GuidanceServerStub *m_guidance; +#if (SPEECH_ENABLED) + SpeechOutput *m_speechoutput; +#endif + bool m_paused; + bool m_voice_guidance; + Guidance::PromptMode m_prompt_mode; + std::string m_kind_of_voice; + struct item *get_item(struct map_rect *mr); + struct map_rect *get_map_rect(void); + void SetSimulationMode(uint32_t SessionHandle, bool Activate); + void GetSimulationMode(bool& SimulationMode); + void SetSimulationSpeed(uint32_t sessionHandle); + void PauseGuidance(uint32_t sessionHandle); + void ResumeGuidance(uint32_t sessionHandle); + void SetVoiceGuidance(const bool& activate, const std::string& voice); + void SetVoiceGuidanceSettings(const Guidance::PromptMode &promptMode); + Guidance::PromptMode GetVoiceGuidanceSettings(); + void PlayVoiceManeuver(); + void GetGuidanceStatus(Guidance::GuidanceStatus &guidanceStatus, NavigationTypes::Handle &routeHandle); + void GetDestinationInformation(uint32_t& offset, uint32_t& TravelTime, int32_t& Direction, int16_t& TimeZone); + void GetManeuver(struct item *item, uint32_t& offsetOfManeuver, Guidance::ManeuverType &maneuverType, std::string& roadNameAfterManeuver, Guidance::ManeuverData &maneuverData); + void GetManeuversList(const uint16_t& requestedNumberOfManeuvers, const uint32_t& maneuverOffset, uint16_t& numberOfManeuvers, std::vector<Guidance::Maneuver> &maneuversList); + void GetGuidanceDetails(bool& voiceGuidance, bool& vehicleOnTheRoad, bool& isDestinationReached, Guidance::ManeuverPhase &maneuver); + GuidanceObj(class GuidanceServerStub *guidance, uint32_t SessionHandle, uint32_t RouteHandle); + ~GuidanceObj(); +}; + +void GuidanceObj_Callback(GuidanceObj *obj); +static class GuidanceObj *mp_guidance; +static struct attr vehicle_speed={attr_speed,(char *)40}; + +static struct navit * +get_navit(void) +{ + struct attr navit; + if (!config_get_attr(config, attr_navit, &navit, NULL)) + return NULL; + return navit.u.navit; +} + +static struct navigation * +get_navigation(void) +{ + struct navit *navit=get_navit(); + struct attr navigation; + if (!navit) + return NULL; + if (!navit_get_attr(navit, attr_navigation, &navigation, NULL)) + return NULL; + return navigation.u.navigation; +} + +static struct tracking * +get_tracking(void) +{ + struct navit *navit=get_navit(); + struct attr tracking; + if (!navit) + return NULL; + if (!navit_get_attr(navit, attr_trackingo, &tracking, NULL)) + return NULL; + return tracking.u.tracking; +} + +static struct vehicle * +get_vehicle(const char *source_prefix) +{ + struct navit *navit=get_navit(); + struct attr vehicle; + struct vehicle *ret=NULL; + if (!source_prefix) { + if (navit_get_attr(navit, attr_vehicle, &vehicle, NULL)) + ret=vehicle.u.vehicle; + } else { + struct attr_iter *iter=navit_attr_iter_new(); + while (navit_get_attr(navit, attr_vehicle, &vehicle, iter)) { + struct attr source; + if (vehicle.u.vehicle && vehicle_get_attr(vehicle.u.vehicle, attr_source, &source, NULL) && + !strncmp(source.u.str, source_prefix, strlen(source_prefix))) { + ret=vehicle.u.vehicle; + break; + } + } + navit_attr_iter_destroy(iter); + } + return ret; +} + +class GuidanceServerStub : public GuidanceStubDefault +{ + public: + GuidanceServerStub() + { + m_version.setVersionMajor(3); + m_version.setVersionMinor(0); + m_version.setVersionMicro(0); + m_version.setDate("21-01-2014"); + } + + ~GuidanceServerStub() { + delete mp_guidance; + } + + /** + * description: getVersion = This method returns the API version implemented by the server + * application + */ + void getVersion(const std::shared_ptr<CommonAPI::ClientId> _client, getVersionReply_t _reply) { + _reply(m_version); + } + + /** + * description: startGuidance = This method starts the guidance for a given route + */ + void startGuidance(const std::shared_ptr<CommonAPI::ClientId> _client, ::v4::org::genivi::navigation::NavigationTypes::Handle _sessionHandle, ::v4::org::genivi::navigation::NavigationTypes::Handle _routeHandle, startGuidanceReply_t _reply){ + dbg(lvl_debug,"enter\n"); + if (mp_guidance) { + dbg(lvl_debug,"guidance already active\n"); + throw DBus::ErrorFailed("guidance already active"); + } + mp_guidance=new GuidanceObj(this, _sessionHandle, _routeHandle); + _reply(); + } + + /** + * description: stopGuidance = This method stops the guidance + */ + void stopGuidance(const std::shared_ptr<CommonAPI::ClientId> _client, ::v4::org::genivi::navigation::NavigationTypes::Handle _sessionHandle, stopGuidanceReply_t _reply){ + dbg(lvl_debug,"enter\n"); + if (!mp_guidance) { + dbg(lvl_debug,"no guidance active\n"); + throw DBus::ErrorFailed("no guidance active"); + } + delete(mp_guidance); + mp_guidance=NULL; + _reply(); + } + + /** + * description: setVoiceGuidance = This method switch on/off the voice guidance + */ + void setVoiceGuidance(const std::shared_ptr<CommonAPI::ClientId> _client, bool _activate, std::string _voice, setVoiceGuidanceReply_t _reply){ + mp_guidance->SetVoiceGuidance(_activate,_voice); + _reply(); + } + + /** + * description: getGuidanceDetails = This method retrieves guidance information + */ + void getGuidanceDetails(const std::shared_ptr<CommonAPI::ClientId> _client, getGuidanceDetailsReply_t _reply){ + if (!mp_guidance) { + dbg(lvl_debug,"no guidance active\n"); + throw DBus::ErrorFailed("no guidance active"); + } + + bool _voiceGuidance; + bool _vehicleOnTheRoad; + bool _isDestinationReached; + Guidance::ManeuverPhase _maneuver; + mp_guidance->GetGuidanceDetails(_voiceGuidance, _vehicleOnTheRoad, _isDestinationReached, _maneuver); + + _reply(_voiceGuidance,_vehicleOnTheRoad,_isDestinationReached,_maneuver); + } + + /** + * description: playVoiceManeuver = This method plays or repeats the last voice guidance + */ + void playVoiceManeuver(const std::shared_ptr<CommonAPI::ClientId> _client, playVoiceManeuverReply_t _reply){ + if (!mp_guidance) { + dbg(lvl_debug,"no guidance active\n"); + throw DBus::ErrorFailed("no guidance active"); + } + + mp_guidance->PlayVoiceManeuver(); + _reply(); + } + + /** + * description: getWaypointInformation = This method retrieves the information on the remaining + * way points of the route. A point can be the final destination as well as a + * stage defined by the user. The returned waypoints are ordered by their + * 'number'. + */ + void getWaypointInformation(const std::shared_ptr<CommonAPI::ClientId> _client, uint16_t _requestedNumberOfWaypoints, getWaypointInformationReply_t _reply){ + throw DBus::ErrorNotSupported("Not yet supported"); + } + + /** + * description: This method retrieves the information on the final destination + */ + void getDestinationInformation(const std::shared_ptr<CommonAPI::ClientId> _client, getDestinationInformationReply_t _reply){ + dbg(lvl_debug,"enter\n"); + if (!mp_guidance) { + dbg(lvl_debug,"no guidance active\n"); + throw DBus::ErrorFailed("no guidance active"); + } + + uint32_t _offset; + uint32_t _travelTime; + int32_t _direction; + Guidance::Side _side = Guidance::Side::NOT_AVAILABLE; + int16_t _timeZone; + int16_t _daylightSavingTime = 0; + mp_guidance->GetDestinationInformation(_offset, _travelTime, _direction, _timeZone); + _reply(_offset, _travelTime, _direction, _side, _timeZone, _daylightSavingTime); + } + + /** + * description: getManeuversList = This method retrieves the list of next maneuvers + */ + void getManeuversList(const std::shared_ptr<CommonAPI::ClientId> _client, uint16_t _requestedNumberOfManeuvers, uint32_t _maneuverOffset, getManeuversListReply_t _reply){ + if (!mp_guidance) { + dbg(lvl_debug,"no guidance active\n"); + throw DBus::ErrorFailed("no guidance active"); + } + + uint16_t _numberOfManeuvers; + std::vector<Guidance::Maneuver> _maneuversList; + mp_guidance->GetManeuversList(_requestedNumberOfManeuvers, _maneuverOffset, _numberOfManeuvers, _maneuversList); + _reply(_numberOfManeuvers,_maneuversList); + } + + /** + * description: setRouteCalculationMode = This method configures the way the navigation + * application wants the navigation core to behave of reroute trigger + */ + void setRouteCalculationMode(const std::shared_ptr<CommonAPI::ClientId> _client, ::v4::org::genivi::navigation::NavigationTypes::Handle _sessionHandle, Guidance::CalculationMode _routeCalculationMode, setRouteCalculationModeReply_t _reply){ + throw DBus::ErrorNotSupported("Not yet supported"); + } + + /** + * description: skipNextManeuver = This method allows to jump behind the current maneuver + */ + void skipNextManeuver(const std::shared_ptr<CommonAPI::ClientId> _client, ::v4::org::genivi::navigation::NavigationTypes::Handle _sessionHandle, skipNextManeuverReply_t _reply){ + throw DBus::ErrorNotSupported("Not yet supported"); + } + + /** + * description: getGuidanceStatus = This method retrieves the guidance status + */ + void getGuidanceStatus(const std::shared_ptr<CommonAPI::ClientId> _client, getGuidanceStatusReply_t _reply){ + Guidance::GuidanceStatus _guidanceStatus; + NavigationTypes::Handle _routeHandle; + if (mp_guidance) { + mp_guidance->GetGuidanceStatus(_guidanceStatus, _routeHandle); + } else { + _guidanceStatus=Guidance::GuidanceStatus::INACTIVE; + _routeHandle=0; + } + _reply(_guidanceStatus,_routeHandle); + } + + /** + * description: setVoiceGuidanceSettings = This method sets the voice guidance settings + */ + void setVoiceGuidanceSettings(const std::shared_ptr<CommonAPI::ClientId> _client, Guidance::PromptMode _promptMode, setVoiceGuidanceSettingsReply_t _reply){ + mp_guidance->SetVoiceGuidanceSettings(_promptMode); + _reply(); + } + + /** + * description: getVoiceGuidanceSettings = This method returns the used voice guidance settings + */ + void getVoiceGuidanceSettings(const std::shared_ptr<CommonAPI::ClientId> _client, getVoiceGuidanceSettingsReply_t _reply){ + _reply(mp_guidance->GetVoiceGuidanceSettings()); + } + +private: + CommonTypes::Version m_version; +}; + +void +GuidanceObj::GetDestinationInformation(uint32_t& Distance, uint32_t& TravelTime, int32_t& Direction, int16_t &TimeZone) +{ + struct coord c[2]; + int idx=0; + struct attr destination_time, destination_length; + struct map_rect *mr=get_map_rect(); + struct item *item; + if (!mr) + throw DBus::ErrorFailed("internal error:failed to get map rect"); + while (item=map_rect_get_item(mr)) { + if (item_coord_get(item, &c[idx], 1)) { + if (!idx) { + if (!item_attr_get(item, attr_destination_time, &destination_time)) + destination_time.u.num=-1; + if (!item_attr_get(item, attr_destination_length, &destination_length)) + destination_length.u.num=-1; + idx=1; + } + } + } + if (!idx) + throw DBus::ErrorFailed("internal error:navigation has only one coordinate"); + if (destination_time.u.num == -1 || destination_length.u.num == -1) { + dbg(lvl_debug,"time %d length %d\n",(int) destination_time.u.num, (int) destination_length.u.num); + throw DBus::ErrorFailed("internal error:failed to get time or length"); + } + Distance=destination_length.u.num; + TravelTime=destination_time.u.num/10; + Direction=transform_get_angle_delta(&c[0], &c[1], 0); + TimeZone=0; +} + +void +GuidanceObj::GetManeuver(struct item *item, uint32_t& offsetOfManeuver, Guidance::ManeuverType& maneuverType, std::string& roadNameAfterManeuver, Guidance::ManeuverData& maneuverData) +{ + struct attr length, street_name; + Guidance::ManeuverDataAttribute maneuverDataAttribute; + Guidance::ManeuverDataValue maneuverDataValue; + + if (item_attr_get(item, attr_length, &length)) { + offsetOfManeuver=length.u.num; + } + if (item_attr_get(item, attr_street_name, &street_name)) { + roadNameAfterManeuver=std::string(street_name.u.str); + } + + maneuverDataAttribute = Guidance::ManeuverDataAttribute::DIRECTION; + switch (item->type) { + case type_nav_straight: + maneuverType=Guidance::ManeuverType::CROSSROAD; + maneuverDataValue = Guidance::ManeuverDirection::STRAIGHT_ON; + break; + case type_nav_turnaround: + maneuverType=Guidance::ManeuverType::CROSSROAD; + maneuverDataValue = Guidance::ManeuverDirection::UTURN_LEFT; + break; + case type_nav_right_1: + maneuverType=Guidance::ManeuverType::CROSSROAD; + maneuverDataValue = Guidance::ManeuverDirection::SLIGHT_RIGHT; + break; + case type_nav_right_2: + maneuverType=Guidance::ManeuverType::CROSSROAD; + maneuverDataValue = Guidance::ManeuverDirection::RIGHT; + break; + case type_nav_right_3: + maneuverType=Guidance::ManeuverType::CROSSROAD; + maneuverDataValue = Guidance::ManeuverDirection::HARD_RIGHT; + break; + case type_nav_left_1: + maneuverType=Guidance::ManeuverType::CROSSROAD; + maneuverDataValue = Guidance::ManeuverDirection::SLIGHT_LEFT; + break; + case type_nav_left_2: + maneuverType=Guidance::ManeuverType::CROSSROAD; + maneuverDataValue = Guidance::ManeuverDirection::LEFT; + break; + case type_nav_left_3: + maneuverType=Guidance::ManeuverType::CROSSROAD; + maneuverDataValue = Guidance::ManeuverDirection::HARD_LEFT; + break; + // FIXME: Are ManeuverDirection values right here? + case type_nav_roundabout_r1: + maneuverType=Guidance::ManeuverType::ROUNDABOUT; + maneuverDataValue = Guidance::ManeuverDirection::HARD_RIGHT; + break; + case type_nav_roundabout_r2: + maneuverType=Guidance::ManeuverType::ROUNDABOUT; + maneuverDataValue = Guidance::ManeuverDirection::RIGHT; + break; + case type_nav_roundabout_r3: + maneuverType=Guidance::ManeuverType::ROUNDABOUT; + maneuverDataValue = Guidance::ManeuverDirection::SLIGHT_RIGHT; + break; + case type_nav_roundabout_r4: + maneuverType=Guidance::ManeuverType::ROUNDABOUT; + maneuverDataValue = Guidance::ManeuverDirection::STRAIGHT_ON; + break; + case type_nav_roundabout_r5: + maneuverType=Guidance::ManeuverType::ROUNDABOUT; + maneuverDataValue = Guidance::ManeuverDirection::SLIGHT_LEFT; + break; + case type_nav_roundabout_r6: + maneuverType=Guidance::ManeuverType::ROUNDABOUT; + maneuverDataValue = Guidance::ManeuverDirection::LEFT; + break; + case type_nav_roundabout_r7: + maneuverType=Guidance::ManeuverType::ROUNDABOUT; + maneuverDataValue = Guidance::ManeuverDirection::HARD_LEFT; + break; + case type_nav_roundabout_r8: + maneuverType=Guidance::ManeuverType::ROUNDABOUT; + maneuverDataValue = Guidance::ManeuverDirection::UTURN_LEFT; + break; + // FIXME: Distinguish between clockwise and counterclockwise roundabout? + case type_nav_roundabout_l1: + maneuverType=Guidance::ManeuverType::ROUNDABOUT; + maneuverDataValue = Guidance::ManeuverDirection::HARD_LEFT; + break; + case type_nav_roundabout_l2: + maneuverType=Guidance::ManeuverType::ROUNDABOUT; + maneuverDataValue = Guidance::ManeuverDirection::LEFT; + break; + case type_nav_roundabout_l3: + maneuverType=Guidance::ManeuverType::ROUNDABOUT; + maneuverDataValue = Guidance::ManeuverDirection::SLIGHT_LEFT; + break; + case type_nav_roundabout_l4: + maneuverType=Guidance::ManeuverType::ROUNDABOUT; + maneuverDataValue = Guidance::ManeuverDirection::STRAIGHT_ON; + break; + case type_nav_roundabout_l5: + maneuverType=Guidance::ManeuverType::ROUNDABOUT; + maneuverDataValue = Guidance::ManeuverDirection::SLIGHT_RIGHT; + break; + case type_nav_roundabout_l6: + maneuverType=Guidance::ManeuverType::ROUNDABOUT; + maneuverDataValue = Guidance::ManeuverDirection::RIGHT; + break; + case type_nav_roundabout_l7: + maneuverType=Guidance::ManeuverType::ROUNDABOUT; + maneuverDataValue = Guidance::ManeuverDirection::HARD_RIGHT; + break; + case type_nav_roundabout_l8: + maneuverType=Guidance::ManeuverType::ROUNDABOUT; + maneuverDataValue = Guidance::ManeuverDirection::UTURN_RIGHT; + break; + case type_nav_destination: + maneuverType=Guidance::ManeuverType::DESTINATION; + maneuverDataValue = Guidance::ManeuverDirection::STRAIGHT_ON; + break; + default: + dbg(lvl_error,"Unable to convert type %s\n",item_to_name(item->type)); + maneuverType=Guidance::ManeuverType::INVALID; + maneuverDataAttribute = Guidance::ManeuverDataAttribute::INVALID; + maneuverDataValue = Guidance::ManeuverDirection::INVALID; + } + maneuverData[maneuverDataAttribute] = maneuverDataValue; +} + + +void +GuidanceObj::GetGuidanceDetails(bool& voiceGuidance, bool& vehicleOnTheRoad, bool& isDestinationReached, Guidance::ManeuverPhase& maneuver) +{ + struct map_rect *mr=get_map_rect(); + struct item *item; + item=get_item(mr); + struct attr level; + + voiceGuidance = m_voice_guidance; + vehicleOnTheRoad = true; //by default, no off-road managed + isDestinationReached = false; //to be done + if (item && item_attr_get(item, attr_level, &level)) { + dbg(lvl_debug,"level=%d\n",(int) level.u.num); + switch(level.u.num) { + case 3: + maneuver=Guidance::ManeuverPhase::CRUISE; + break; + case 2: + maneuver=Guidance::ManeuverPhase::MANEUVER_APPEARED; + break; + case 1: + maneuver=Guidance::ManeuverPhase::PRE_ADVICE; + break; + case 0: + maneuver=Guidance::ManeuverPhase::ADVICE; + break; + default: + maneuver=Guidance::ManeuverPhase::INVALID; + } + } else { + dbg(lvl_debug,"failed to get level item=%p\n",item); + } + +} + +void +GuidanceObj::GetManeuversList(const uint16_t& requestedNumberOfManeuvers, const uint32_t& maneuverOffset, uint16_t& numberOfManeuvers, std::vector<Guidance::Maneuver>& maneuversList) +{ + struct map_rect *mr=get_map_rect(); + struct item *item; + uint16_t maneuverIndex; + Guidance::ManeuverData::iterator it; + + numberOfManeuvers = 0; + maneuverIndex = 0; + while (item=get_item(mr)) { //scan the list of maneuvers of the route + if (maneuverIndex >= maneuverOffset && maneuverIndex < maneuverOffset+requestedNumberOfManeuvers) { + Guidance::Maneuver maneuver; + std::vector<Guidance::ManeuverItem> items; + Guidance::ManeuverItem sub_maneuver; + Guidance::ManeuverData maneuverData; + maneuver.setRoadNumberAfterManeuver(""); //roadNumberAfterManeuver not managed yet + maneuver.setRoadPropertyAfterManeuver(Guidance::RoadProperty::INVALID); //roadPropertyAfterManeuver not managed yet + maneuver.setDrivingSide(Guidance::Side::RIGHT); //drivingSide not managed yet + maneuver.setOffsetOfNextManeuver(0); //offsetOfNextManeuver not managed yet + //get infos about maneuver: sub_maneuver._1: DistanceToManeuver, sub_maneuver._4: Maneuver, maneuver._2: RoadAfterManeuver + //maneuver_data is a map of attribute and value (e.g. DIRECTION STRAIGHT_ON ) + uint32_t offsetOfManeuver; + Guidance::ManeuverType maneuverType; + std::string roadNameAfterManeuver; + GetManeuver(item, offsetOfManeuver, maneuverType, roadNameAfterManeuver, maneuverData); + maneuver.setRoadNameAfterManeuver(roadNameAfterManeuver); + sub_maneuver.setOffsetOfManeuver(offsetOfManeuver); + sub_maneuver.setManeuver(maneuverType); + sub_maneuver.setManeuverData(maneuverData); + items.push_back(sub_maneuver); + maneuver.setItems(items); + if (maneuversList.size()) + maneuversList.back().setOffsetOfNextManeuver(offsetOfManeuver); //offsetOfNextManeuver of the last record is the offsetOfManeuver of this one + maneuversList.push_back(maneuver); + numberOfManeuvers++; + } + maneuverIndex++; + } + map_rect_destroy(mr); +} + +void +GuidanceObj::SetSimulationSpeed(uint32_t sessionHandle) +{ + struct vehicle *vehicle=get_vehicle("demo:"); + if (vehicle && !m_paused) + vehicle_set_attr(vehicle, &vehicle_speed); +} + +void +GuidanceObj::PauseGuidance(uint32_t sessionHandle) +{ + struct vehicle *vehicle=get_vehicle("demo:"); + if (vehicle) { + struct attr vehicle_speed0={attr_speed,(char *)0}; + vehicle_set_attr(vehicle, &vehicle_speed0); + } + m_paused=true; +} + +void +GuidanceObj::ResumeGuidance(uint32_t sessionHandle) +{ + struct vehicle *vehicle=get_vehicle("demo:"); + GuidanceObj_Callback(this); + if (vehicle) + { + vehicle_set_attr(vehicle, &vehicle_speed); + } + m_paused=false; +} + +void GuidanceObj::SetVoiceGuidance(const bool& activate, const std::string& voice) +{ + m_voice_guidance = activate; + m_kind_of_voice.clear(); + m_kind_of_voice.append(voice); +} + +void GuidanceObj::PlayVoiceManeuver() +{ + message *messages; + messages = navit_get_messages(get_navit()); +#if (SPEECH_ENABLED) + m_speechoutput->openPrompter(GENIVI_SPEECHSERVICE_CT_NAVIGATION,GENIVI_SPEECHSERVICE_PPT_NAVIGATION); + m_speechoutput->addTextChunk(messages); + m_speechoutput->closePrompter(); +#endif +} + +void GuidanceObj::SetVoiceGuidanceSettings(const Guidance::PromptMode& promptMode) +{ + m_prompt_mode = promptMode; +} + +Guidance::PromptMode GuidanceObj::GetVoiceGuidanceSettings() +{ + return m_prompt_mode; +} + +void +GuidanceObj::GetGuidanceStatus(Guidance::GuidanceStatus &guidanceStatus, NavigationTypes::Handle& routeHandle) +{ + if (m_paused) + guidanceStatus = Guidance::GuidanceStatus::INACTIVE; + else + guidanceStatus = Guidance::GuidanceStatus::ACTIVE; + routeHandle=m_route_handle; +} + + +void +GuidanceObj_Callback(GuidanceObj *obj) +{ + struct attr level; + struct map_rect *mr; + struct item *item; + dbg(lvl_debug,"enter\n"); + if (obj->m_paused) + return; + mr=obj->get_map_rect(); + if (!mr) { + dbg(lvl_debug,"failed to get map rect\n"); + return; + } + item=obj->get_item(mr); + if (item && item_attr_get(item, attr_level, &level)) { + Guidance::ManeuverPhase maneuver; + dbg(lvl_debug,"level=%d\n",(int) level.u.num); + switch(level.u.num) { + case 3: + maneuver=Guidance::ManeuverPhase::CRUISE; + break; + case 2: + maneuver=Guidance::ManeuverPhase::MANEUVER_APPEARED; + break; + case 1: + maneuver=Guidance::ManeuverPhase::PRE_ADVICE; + break; + case 0: + maneuver=Guidance::ManeuverPhase::ADVICE; + break; + default: + maneuver=Guidance::ManeuverPhase::INVALID; + } + obj->m_guidance->fireManeuverChangedEvent(maneuver); + } else { + dbg(lvl_debug,"failed to get level item=%p\n",item); + } +} + + +void +GuidanceObj_TrackingCallback(GuidanceObj *obj) +{ + dbg(lvl_debug,"enter\n"); + struct attr attr; + route_set_position_from_tracking(obj->m_route.u.route, get_tracking(), projection_mg); + if (!obj->m_paused) + obj->m_guidance->firePositionOnRouteChangedEvent(0); //to do return the current offset on the route in meters from the beginning of the route + + int destreached=route_destination_reached(obj->m_route.u.route); + if (destreached) + obj->m_guidance->fireWaypointReachedEvent(destreached == 2); + if (destreached == 2) + route_set_destination(obj->m_route.u.route, NULL, 0); +} + +struct item * +GuidanceObj::get_item(struct map_rect *mr) +{ + struct item *ret; + while (mr && (ret = map_rect_get_item(mr))) { + if (ret->type != type_nav_position && ret->type != type_nav_none) + break; + } + return ret; +} + +struct map_rect * +GuidanceObj::get_map_rect(void) +{ + struct map *map=navigation_get_map(get_navigation()); + if (!map) + return NULL; + return map_rect_new(map, NULL); +} + +GuidanceObj::GuidanceObj(GuidanceServerStub *guidance, uint32_t SessionHandle, uint32_t RouteHandle) +{ + m_guidance=guidance; + m_session=SessionHandle; + m_route_handle=RouteHandle; + m_guidance_callback=callback_new_1(reinterpret_cast<void (*)(void)>(GuidanceObj_Callback), this); + m_paused=false; + m_voice_guidance=false; + m_kind_of_voice="DEFAULT"; + m_prompt_mode=Guidance::PromptMode::MANUAL_PROMPT; + m_tracking_callback.type=attr_callback; + m_tracking_callback.u.callback=NULL; + struct attr id={attr_id}; + id.u.num=RouteHandle; + struct attr *in[]={&id, NULL}; + struct attr **ret=NULL; + struct attr callback_list; + struct navit *navit=get_navit(); + +#if (SPEECH_ENABLED) + m_speechoutput=new SpeechOutput(*conn); +#endif + if (navit_get_attr(navit, attr_callback_list, &callback_list, NULL)) { + callback_list_call_attr_4(callback_list.u.callback_list, attr_command, "navit_genivi_get_route", in, &ret, NULL); + if (ret && ret[0] && ret[1] && ret[0]->type == attr_route && ret[1]->type == attr_vehicleprofile) { + struct tracking *tracking=get_tracking(); + m_route=*ret[0]; + m_vehicleprofile=*ret[1]; + m_tracking_callback.u.callback=callback_new_attr_1(reinterpret_cast<void (*)(void)>(GuidanceObj_TrackingCallback), attr_position_coord_geo, this); + tracking_add_attr(tracking, &m_tracking_callback); + struct vehicle *demo=get_vehicle("demo:"); + if (demo) { + vehicle_set_attr(demo, &m_route); + vehicle_set_attr(demo, &vehicle_speed); + } + navigation_set_route(get_navigation(), m_route.u.route); + tracking_set_route(get_tracking(), m_route.u.route); + navigation_register_callback(get_navigation(), attr_navigation_speech, m_guidance_callback); + GuidanceObj_Callback(this); + } + g_free(ret); + } + m_guidance->fireGuidanceStatusChangedEvent(Guidance::GuidanceStatus::ACTIVE, RouteHandle); +} + +GuidanceObj::~GuidanceObj() +{ + if (m_tracking_callback.u.callback) { + struct tracking *tracking=get_tracking(); + if (tracking) + tracking_remove_attr(tracking, &m_tracking_callback); + callback_destroy(m_tracking_callback.u.callback); + } + if (m_guidance_callback) { + navigation_unregister_callback(get_navigation(), attr_navigation_speech, m_guidance_callback); + callback_destroy(m_guidance_callback); + } + m_guidance->fireGuidanceStatusChangedEvent(Guidance::GuidanceStatus::INACTIVE, 0); +#if (SPEECH_ENABLED) + delete(m_speechoutput); +#endif + +} + +void +plugin_init(void) +{ + // Common API data init + std::shared_ptr < CommonAPI::Runtime > runtime = CommonAPI::Runtime::get(); + + const std::string &domain = "local"; + const std::string &instance = "Guidance"; + + std::shared_ptr<GuidanceServerStub> myServiceGuidance = std::make_shared<GuidanceServerStub>(); + + bool successfullyRegistered = runtime->registerService(domain, instance, myServiceGuidance); + while (!successfullyRegistered) { + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + successfullyRegistered = runtime->registerService(domain, instance, myServiceGuidance); + } +} diff --git a/src/navigation/navigation-core/locationinput-server-plugin/genivi_navigationcore_locationinput.cxx b/src/navigation/navigation-core/locationinput-server-plugin/genivi_navigationcore_locationinput.cxx index db45729..e42a3c9 100644 --- a/src/navigation/navigation-core/locationinput-server-plugin/genivi_navigationcore_locationinput.cxx +++ b/src/navigation/navigation-core/locationinput-server-plugin/genivi_navigationcore_locationinput.cxx @@ -20,7 +20,7 @@ * For further information see http://www.genivi.org/. * * List of changes: -* +* * <date>, <name>, <description of change> * * @licence end@ @@ -58,34 +58,34 @@ class LocationInputServerStub; class LocationInputObj { - public: - struct search_list *m_sl; + public: + struct search_list *m_sl; NavigationTypes::Handle m_handle; NavigationTypes::Handle m_session; LocationInput::AddressAttribute m_criterion; - uint32_t m_windowsize; - struct attr m_search; + uint32_t m_windowsize; + struct attr m_search; LocationInputServerStub *mp_locationinput; - struct callback *m_callback; - struct event_idle *m_event; - bool m_spell; - bool m_spell_backspace; + struct callback *m_callback; + struct event_idle *m_event; + bool m_spell; + bool m_spell_backspace; std::vector< std::vector< LocationInput::Address > > m_data; int m_chunk; int m_count; void SetSelectionCriterion(NavigationTypes::Handle SessionHandle, LocationInput::AddressAttribute SelectionCriterion); void Search(NavigationTypes::Handle SessionHandle, const std::string& InputString, uint32_t MaxWindowSize); void SelectEntry(const NavigationTypes::Handle& SessionHandle, const uint32_t& Index); - struct navit *get_navit(void); - struct mapset *get_mapset(struct navit *navit); - void IdleStop(void); - void Idle(void); + struct navit *get_navit(void); + struct mapset *get_mapset(struct navit *navit); + void IdleStop(void); + void Idle(void); void Spell(NavigationTypes::Handle SessionHandle, const std::string& InputCharacter, uint32_t MaxWindowSize); void RequestListUpdate(NavigationTypes::Handle sessionHandle, const uint16_t& offset, uint16_t maxWindowSize); void GetEntry(uint16_t index, LocationInput::Address &entry); void ValidateAddress(NavigationTypes::Handle sessionHandle, const LocationInput::Address &inputAddress); LocationInputObj(LocationInputServerStub *locationinput, uint32_t handle); - ~LocationInputObj(); + ~LocationInputObj(); }; class LocationInputServerStub : public LocationInputStubDefault { @@ -270,107 +270,107 @@ private: struct navit * LocationInputObj::get_navit(void) { - struct attr navit; - if (!config_get_attr(config, attr_navit, &navit, NULL)) - return NULL; - return navit.u.navit; + struct attr navit; + if (!config_get_attr(config, attr_navit, &navit, NULL)) + return NULL; + return navit.u.navit; } struct mapset * LocationInputObj::get_mapset(struct navit *navit) { - struct attr mapset; - if (!navit_get_attr(navit, attr_mapset, &mapset, NULL)) - return NULL; - return mapset.u.mapset; + struct attr mapset; + if (!navit_get_attr(navit, attr_mapset, &mapset, NULL)) + return NULL; + return mapset.u.mapset; } void LocationInputObj::SetSelectionCriterion(NavigationTypes::Handle SessionHandle, LocationInput::AddressAttribute SelectionCriterion) { - m_criterion=SelectionCriterion; - switch(m_criterion) { + m_criterion=SelectionCriterion; + switch(m_criterion) { case LocationInput::AddressAttribute::COUNTRY: - m_search.type=attr_country_name; - break; + m_search.type=attr_country_name; + break; case LocationInput::AddressAttribute::CITY: - m_search.type=attr_town_name; - break; + m_search.type=attr_town_name; + break; case LocationInput::AddressAttribute::STREET: - m_search.type=attr_street_name; - break; + m_search.type=attr_street_name; + break; case LocationInput::AddressAttribute::HOUSENUMBER: - m_search.type=attr_house_number; - break; + m_search.type=attr_house_number; + break; case LocationInput::AddressAttribute::FULL_ADDRESS: - m_search.type=attr_address; - break; - default: - throw DBus::ErrorInvalidArgs("Invalid selection criterion"); - } - g_free(m_search.u.str); - m_search.u.str=NULL; + m_search.type=attr_address; + break; + default: + throw DBus::ErrorInvalidArgs("Invalid selection criterion"); + } + g_free(m_search.u.str); + m_search.u.str=NULL; mp_locationinput->fireCurrentSelectionCriterionEvent(m_handle, m_criterion); } void LocationInputObj::Search(NavigationTypes::Handle SessionHandle, const std::string& InputString, uint32_t MaxWindowSize) { - IdleStop(); - g_free(m_search.u.str); + IdleStop(); + g_free(m_search.u.str); - m_session=SessionHandle; - m_search.u.str=g_strdup(InputString.c_str()); - m_windowsize=MaxWindowSize; - m_spell=false; + m_session=SessionHandle; + m_search.u.str=g_strdup(InputString.c_str()); + m_windowsize=MaxWindowSize; + m_spell=false; - search_list_search(m_sl, &m_search, 0); - m_event=event_add_idle(0, m_callback); + search_list_search(m_sl, &m_search, 0); + m_event=event_add_idle(0, m_callback); } void LocationInputObj::Spell(NavigationTypes::Handle SessionHandle, const std::string& InputCharacter, uint32_t MaxWindowSize) { - IdleStop(); - - m_spell=true; - m_spell_backspace=false; - m_session=SessionHandle; - char *newstr; - const char *input=InputCharacter.c_str(); - int len=strlen(input)+1; - dbg(lvl_debug,"input '%s' (%d)\n",input,strlen(input)); - if (m_search.u.str && strlen(m_search.u.str)) { - const char *i=input; - char c; - newstr=g_strdup(m_search.u.str); - dbg(lvl_debug,"string %s\n",newstr); - while ((c=*i++)) { - dbg(lvl_debug,"char '%c'\n",c); - if (c == '\b') { - m_spell_backspace=true; - *g_utf8_prev_char(newstr+strlen(newstr))='\0'; - } else { - int len=strlen(newstr); - newstr=g_renew(char,newstr,len+2); - newstr[len]=c; - newstr[len+1]='\0'; - } - dbg(lvl_debug,"string now %s\n",newstr); - } - } else { - if (strcmp(input,"\b")) - newstr=g_strdup(input); - else - newstr=NULL; - } - g_free(m_search.u.str); - dbg(lvl_debug,"search string '%s' (%d)\n",newstr,strlen(newstr)); - m_search.u.str=newstr; - m_windowsize=MaxWindowSize; - - search_list_search(m_sl, &m_search, 1); - dbg(lvl_debug,"backspace %d\n",m_spell_backspace); - m_event=event_add_idle(0, m_callback); + IdleStop(); + + m_spell=true; + m_spell_backspace=false; + m_session=SessionHandle; + char *newstr; + const char *input=InputCharacter.c_str(); + int len=strlen(input)+1; + dbg(lvl_debug,"input '%s' (%d)\n",input,strlen(input)); + if (m_search.u.str && strlen(m_search.u.str)) { + const char *i=input; + char c; + newstr=g_strdup(m_search.u.str); + dbg(lvl_debug,"string %s\n",newstr); + while ((c=*i++)) { + dbg(lvl_debug,"char '%c'\n",c); + if (c == '\b') { + m_spell_backspace=true; + *g_utf8_prev_char(newstr+strlen(newstr))='\0'; + } else { + int len=strlen(newstr); + newstr=g_renew(char,newstr,len+2); + newstr[len]=c; + newstr[len+1]='\0'; + } + dbg(lvl_debug,"string now %s\n",newstr); + } + } else { + if (strcmp(input,"\b")) + newstr=g_strdup(input); + else + newstr=NULL; + } + g_free(m_search.u.str); + dbg(lvl_debug,"search string '%s' (%d)\n",newstr,strlen(newstr)); + m_search.u.str=newstr; + m_windowsize=MaxWindowSize; + + search_list_search(m_sl, &m_search, 1); + dbg(lvl_debug,"backspace %d\n",m_spell_backspace); + m_event=event_add_idle(0, m_callback); } @@ -397,127 +397,127 @@ LocationInputObj::SelectEntry(const NavigationTypes::Handle &SessionHandle, cons LocationInput::Address *res=NULL; std::vector<LocationInput::AddressAttribute> next; std::size_t window=0; - bool guidable=false; + bool guidable=false; for (std::size_t i = 0 ; i < m_data.size() ; i++) { - if (Index >= window && Index < window+m_data[i].size()) { - res=&m_data[i][Index-window]; - break; - } - window+=m_data[i].size(); - } - if (!res) - throw DBus::ErrorInvalidArgs("Invalid index"); - search_list_select(m_sl, m_search.type, Index+1, 1); - switch(m_criterion) { + if (Index >= window && Index < window+m_data[i].size()) { + res=&m_data[i][Index-window]; + break; + } + window+=m_data[i].size(); + } + if (!res) + throw DBus::ErrorInvalidArgs("Invalid index"); + search_list_select(m_sl, m_search.type, Index+1, 1); + switch(m_criterion) { case LocationInput::AddressAttribute::COUNTRY: next.push_back(LocationInput::AddressAttribute::COUNTRY); next.push_back(LocationInput::AddressAttribute::CITY); - break; + break; case LocationInput::AddressAttribute::CITY: next.push_back(LocationInput::AddressAttribute::COUNTRY); next.push_back(LocationInput::AddressAttribute::CITY); next.push_back(LocationInput::AddressAttribute::STREET); - break; + break; case LocationInput::AddressAttribute::STREET: case LocationInput::AddressAttribute::HOUSENUMBER: next.push_back(LocationInput::AddressAttribute::COUNTRY); next.push_back(LocationInput::AddressAttribute::CITY); next.push_back(LocationInput::AddressAttribute::STREET); next.push_back(LocationInput::AddressAttribute::HOUSENUMBER); - break; - } + break; + } if (res->find(LocationInput::AddressAttribute::LATITUDE) != res->end()) - guidable=true; + guidable=true; mp_locationinput->fireContentUpdatedEvent(m_handle, guidable, next, *res); } void LocationInputObj::IdleStop(void) { - if (m_event) { - event_remove_idle(m_event); - m_event=NULL; - } + if (m_event) { + event_remove_idle(m_event); + m_event=NULL; + } } void LocationInputObj::Idle(void) { - dbg(lvl_debug,"enter\n"); + dbg(lvl_debug,"enter\n"); mp_locationinput->fireSearchStatusEvent(m_handle, LocationInput::SearchStatus::SEARCHING); - struct search_list_result *res; - int chunk=0; + struct search_list_result *res; + int chunk=0; uint16_t count=0; - m_data.resize(0); - m_data.resize(1); - while ((res=search_list_get_result(m_sl))) { + m_data.resize(0); + m_data.resize(1); + while ((res=search_list_get_result(m_sl))) { LocationInput::Address entry; - if (res->country && res->country->name) { - dbg(lvl_debug,"country %s\n",res->country->name); + if (res->country && res->country->name) { + dbg(lvl_debug,"country %s\n",res->country->name); entry[LocationInput::AddressAttribute::COUNTRY] = std::string(res->country->name); - } - if (res->town && res->town->common.town_name) { - dbg(lvl_debug,"town %s\n",res->town->common.town_name); + } + if (res->town && res->town->common.town_name) { + dbg(lvl_debug,"town %s\n",res->town->common.town_name); entry[LocationInput::AddressAttribute::CITY] = std::string(res->town->common.town_name); - } - if (res->street && res->street->name) { - dbg(lvl_debug,"street %s\n",res->street->name); + } + if (res->street && res->street->name) { + dbg(lvl_debug,"street %s\n",res->street->name); entry[LocationInput::AddressAttribute::STREET] = std::string(res->street->name); - } - if (res->house_number && res->house_number->house_number) { - dbg(lvl_debug,"house number %s\n",res->house_number->house_number); + } + if (res->house_number && res->house_number->house_number) { + dbg(lvl_debug,"house number %s\n",res->house_number->house_number); entry[LocationInput::AddressAttribute::HOUSENUMBER] = std::string(res->house_number->house_number); - } - if (res->c) { - struct coord_geo g; - struct coord c; - c.x=res->c->x; - c.y=res->c->y; - transform_to_geo(res->c->pro, &c, &g); + } + if (res->c) { + struct coord_geo g; + struct coord c; + c.x=res->c->x; + c.y=res->c->y; + transform_to_geo(res->c->pro, &c, &g); entry[LocationInput::AddressAttribute::LATITUDE] = g.lat; entry[LocationInput::AddressAttribute::LONGITUDE] = g.lng; - } - m_data[chunk].push_back(entry); - if (m_data[chunk].size() >= m_windowsize) { - chunk++; - m_data.resize(chunk+1); - } - count++; - } + } + m_data[chunk].push_back(entry); + if (m_data[chunk].size() >= m_windowsize) { + chunk++; + m_data.resize(chunk+1); + } + count++; + } // the search_list_get_unique has been removed from the svn in the r5549, so navit needs to be patched for upper versions if (m_spell) { - char *unique; - if (m_spell_backspace) - unique=g_strdup(m_search.u.str); - else + char *unique; + if (m_spell_backspace) + unique=g_strdup(m_search.u.str); + else unique=search_list_get_unique(m_sl, NULL); - m_spell_backspace=false; - if (unique) { - g_free(m_search.u.str); - m_search.u.str=unique; - char *next=search_list_get_unique(m_sl, unique); - if (next) { + m_spell_backspace=false; + if (unique) { + g_free(m_search.u.str); + m_search.u.str=unique; + char *next=search_list_get_unique(m_sl, unique); + if (next) { mp_locationinput->fireSpellResultEvent(m_handle, unique, next, false); - g_free(next); - } + g_free(next); + } } else mp_locationinput->fireSpellResultEvent(m_handle, "", "\b", false); - } + } m_count = count; //amount of data m_chunk = chunk; //amount of lists of data mp_locationinput->fireSearchStatusEvent(m_handle, LocationInput::SearchStatus::FINISHED); - IdleStop(); + IdleStop(); } static void LocationInputObj_Idle(LocationInputObj *obj) { - obj->Idle(); + obj->Idle(); } void @@ -533,22 +533,22 @@ LocationInputObj::ValidateAddress(NavigationTypes::Handle sessionHandle, const L LocationInputObj::LocationInputObj(LocationInputServerStub *locationinput, uint32_t handle) { mp_locationinput=locationinput; - m_handle=handle; - m_sl=search_list_new(get_mapset(get_navit())); + m_handle=handle; + m_sl=search_list_new(get_mapset(get_navit())); m_count=0; m_chunk=0; - m_search.type=attr_none; - m_search.u.str=NULL; - m_event=NULL; - m_callback=callback_new_1(reinterpret_cast<void (*)(void)>(LocationInputObj_Idle), this); + m_search.type=attr_none; + m_search.u.str=NULL; + m_event=NULL; + m_callback=callback_new_1(reinterpret_cast<void (*)(void)>(LocationInputObj_Idle), this); } LocationInputObj::~LocationInputObj() { - IdleStop(); - callback_destroy(m_callback); - g_free(m_search.u.str); - search_list_destroy(m_sl); + IdleStop(); + callback_destroy(m_callback); + g_free(m_search.u.str); + search_list_destroy(m_sl); } void diff --git a/src/navigation/navigation-core/mapmatchedposition-server-plugin/CMakeLists.txt b/src/navigation/navigation-core/mapmatchedposition-server-plugin/CMakeLists.txt new file mode 100644 index 0000000..43df6dd --- /dev/null +++ b/src/navigation/navigation-core/mapmatchedposition-server-plugin/CMakeLists.txt @@ -0,0 +1,116 @@ +########################################################################### +# @licence app begin@ +# SPDX-License-Identifier: MPL-2.0 +# +# Component Name: mapmatchedposition-server-plugin +# +# Author: Philippe Colliot +# +# Copyright (C) 2015, PCA Peugeot Citroën +# +# License: +# This Source Code Form is subject to the terms of the +# Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with +# this file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# @licence end@ +########################################################################### +project(mapmatchedposition-server-plugin) +cmake_minimum_required(VERSION 2.8) + +message(STATUS ${PROJECT_NAME}) + +set(CMAKE_VERBOSE_MAKEFILE on) +set(CMAKE_CXX_FLAGS "-Wall -std=c++0x") + + + +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/lib) +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/bin) + + +# DBus Path +if(DBUS_LIB_PATH) + message(STATUS "DBUS_LIB_PATH = " ${DBUS_LIB_PATH}) + set(DBUS_INCLUDE_DIRS ${DBUS_LIB_PATH}/include/dbus-1.0 ${DBUS_LIB_PATH}/lib/dbus-1.0/include) + set(DBUS_LIBDIR ${DBUS_LIB_PATH}/lib) + set(DBUS_LIBRARIES ${DBUS_LIB_PATH}/lib/libdbus-1.so) +else() + message(FATAL_ERROR "Please specify the path to your patched DBus library using -DDBUS_LIB_PATH=yourPath") +endif() + +# Packages +find_package(CommonAPI 3.1.5 REQUIRED) +find_package(CommonAPI-DBus 3.1.5 REQUIRED) + + +#pkg_check_modules(DBUS "dbus-1 >= 1.8.4") // #to be fixed, it doesn't work so the paths are set manually (see above) +pkg_check_modules(COMMONAPI "CommonAPI >= 3.1.5") +pkg_check_modules(COMMONAPI_DBUS "CommonAPI-DBus >= 3.1.5") +pkg_check_modules(GOBJECT gobject-2.0) +pkg_check_modules(GLIB REQUIRED glib-2.0) +pkg_check_modules(DBUS_CPP_GLIB dbus-c++-glib-1) + + +# Add the Franca files (that will generate the CommonAPI stuff) +set(COMMONAPI_GEN_DIR "${CMAKE_CURRENT_BINARY_DIR}/src-gen") +add_subdirectory(${FRANCA_DIR}/navigation/navigationcore "${CMAKE_CURRENT_BINARY_DIR}/franca") + +# Path to the generated files +set(API_VERSION_MAJOR 4) +set(API_VERSION "v${API_VERSION_MAJOR}") +set(PRJ_SRC_GEN_ROOT_PATH ${COMMONAPI_GEN_DIR}/${API_VERSION}/org/genivi) #files shared by all the APIs +set(PRJ_SRC_GEN_NAVIGATION_PATH ${PRJ_SRC_GEN_ROOT_PATH}/navigation) #files shared by the navigation APIs +set(PRJ_SRC_GEN_NAVIGATIONCORE_PATH ${PRJ_SRC_GEN_NAVIGATION_PATH}/navigationcore) #files shared by the navigationcore APIs + +# Source Files +set(FRANCA_FILE "MapMatchedPosition") +FILE(GLOB PRJ_LOCAL_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/*.cxx) +FILE(GLOB PRJ_STUB_GEN_SRCS + ${PRJ_SRC_GEN_ROOT_PATH}/*DBusStub*.cpp ${PRJ_SRC_GEN_ROOT_PATH}/*Types.cpp ${PRJ_SRC_GEN_ROOT_PATH}/*DBusDeployment.cpp ${PRJ_SRC_GEN_ROOT_PATH}/*StubDefault.cpp + ${PRJ_SRC_GEN_NAVIGATION_PATH}/*DBusStub*.cpp ${PRJ_SRC_GEN_NAVIGATION_PATH}/*Types.cpp ${PRJ_SRC_GEN_NAVIGATION_PATH}/*DBusDeployment.cpp ${PRJ_SRC_GEN_NAVIGATION_PATH}/*StubDefault.cpp + ${PRJ_SRC_GEN_NAVIGATIONCORE_PATH}/${FRANCA_FILE}DBusStub*.cpp ${PRJ_SRC_GEN_NAVIGATIONCORE_PATH}/${FRANCA_FILE}Types.cpp ${PRJ_SRC_GEN_NAVIGATIONCORE_PATH}/${FRANCA_FILE}DBusDeployment.cpp ${PRJ_SRC_GEN_NAVIGATIONCORE_PATH}/${FRANCA_FILE}StubDefault.cpp + ) +FILE(GLOB PRJ_STUB_IMPL_SRCS + ${PRJ_SRC_GEN_ROOT_PATH}/*Stub*.cpp + ${PRJ_SRC_GEN_NAVIGATION_PATH}/*Stub*.cpp + ${PRJ_SRC_GEN_NAVIGATIONCORE_PATH}/${FRANCA_FILE}Stub*.cpp + ) + +set(PRJ_SRCS ${PRJ_LOCAL_SRCS} ${PRJ_STUB_GEN_SRCS} ${PRJ_STUB_IMPL_SRCS}) + +include_directories( + ${COMMONAPI_GEN_DIR} + ${PRJ_SRC_GEN_ROOT_PATH} + ${PRJ_SRC_GEN_NAVIGATION_PATH} + ${PRJ_SRC_GEN_NAVIGATIONCORE_PATH} + ${DBUS_INCLUDE_DIRS} + ${COMMONAPI_INCLUDE_DIRS} + ${COMMONAPI_DBUS_INCLUDE_DIRS} + ${GOBJECT_INCLUDE_DIRS} + ${GLIB_INCLUDE_DIRS} + ${DBUS_CPP_GLIB_INCLUDE_DIRS} +) + +link_directories( + ${DBUS_LIBDIR} + ${COMMONAPI_LIBDIR} + ${COMMONAPI_DBUS_LIBDIR} + ${GOBJECT_LIBRARY_DIRS} + ${GLIB_LIBRARY_DIRS} + ${DBUS_CPP_GLIB_DIRS} +) + +set(LIBRARIES + ${DBUS_LIBRARIES} + ${COMMONAPI_LIBRARIES} + ${COMMONAPI_DBUS_LIBRARIES} + ${GOBJECT_LIBRARIES} + ${GLIB_LIBRARIES} + ${DBUS_CPP_GLIB_LIBRARIES} +) + +# Build service +module_add_library(genivi_navigationcore_mapmatchedposition_server ${PRJ_SRCS}) +target_link_libraries(genivi_navigationcore_mapmatchedposition_server ${LIBRARIES}) + diff --git a/src/navigation/navigation-core/mapmatchedposition-server-plugin/genivi_navigationcore_mapmatchedposition.cxx b/src/navigation/navigation-core/mapmatchedposition-server-plugin/genivi_navigationcore_mapmatchedposition.cxx new file mode 100644 index 0000000..40b6984 --- /dev/null +++ b/src/navigation/navigation-core/mapmatchedposition-server-plugin/genivi_navigationcore_mapmatchedposition.cxx @@ -0,0 +1,391 @@ +/** +* @licence app begin@ +* SPDX-License-Identifier: MPL-2.0 +* +* \copyright Copyright (C) 2013-2014, PCA Peugeot Citroen +* +* \file genivi_navigationcore_mapmatchedposition.cxx +* +* \brief This file is part of the Navit POC. +* +* \author Martin Schaller <martin.schaller@it-schaller.de> +* +* \version 1.0 +* +* This Source Code Form is subject to the terms of the +* Mozilla Public License (MPL), v. 2.0. +* If a copy of the MPL was not distributed with this file, +* You can obtain one at http://mozilla.org/MPL/2.0/. +* +* For further information see http://www.genivi.org/. +* +* List of changes: +* +* <date>, <name>, <description of change> +* +* @licence end@ +*/ +#include <dbus-c++/glib-integration.h> +#include "config.h" +#define USE_PLUGINS 1 +#include "debug.h" +#include "plugin.h" +#include "item.h" +#include "config_.h" +#include "navit.h" +#include "callback.h" +#include "navigation.h" +#include "map.h" +#include "transform.h" +#include "track.h" +#include "vehicle.h" +#include "route.h" +#include "config_.h" +#include <CommonAPI/CommonAPI.hpp> +#include <CommonTypes.hpp> +#include <NavigationTypes.hpp> +#include <NavigationCoreTypes.hpp> +#include <MapMatchedPositionStubDefault.hpp> + +#if (!DEBUG_ENABLED) +#undef dbg +#define dbg(level,...) ; +#endif + +using namespace v4::org::genivi::navigation::navigationcore; +using namespace v4::org::genivi::navigation; +using namespace v4::org::genivi; + +static struct attr config_cb,navit_cb,tracking_cb; +static struct tracking *tracking; +static struct item last_item; +static char *mp_street_name; +static struct attr vehicle_speed={attr_speed,(char *)40}; + +static struct navit * +get_navit(void) +{ + struct attr navit; + if (!config_get_attr(config, attr_navit, &navit, NULL)) + return NULL; + return navit.u.navit; +} + +static struct vehicle * +get_vehicle(const char *source_prefix) +{ + struct navit *navit=get_navit(); + struct attr vehicle; + struct vehicle *ret=NULL; + if (!source_prefix) { + if (navit_get_attr(navit, attr_vehicle, &vehicle, NULL)) + ret=vehicle.u.vehicle; + } else { + struct attr_iter *iter=navit_attr_iter_new(); + while (navit_get_attr(navit, attr_vehicle, &vehicle, iter)) { + struct attr source; + if (vehicle.u.vehicle && vehicle_get_attr(vehicle.u.vehicle, attr_source, &source, NULL) && + !strncmp(source.u.str, source_prefix, strlen(source_prefix))) { + ret=vehicle.u.vehicle; + break; + } + } + navit_attr_iter_destroy(iter); + } + return ret; +} + +class MapMatchedPositionServerStub : public MapMatchedPositionStubDefault +{ + public: + MapMatchedPositionServerStub() + { + m_version.setVersionMajor(3); + m_version.setVersionMinor(0); + m_version.setVersionMicro(0); + m_version.setDate("21-01-2014"); + + m_simulationMode = MapMatchedPosition::SimulationStatus::SIMULATION_STATUS_NO_SIMULATION; + } + + ~MapMatchedPositionServerStub(){} + + /** + * description: getVersion = This method returns the API version implemented by the server + * application + */ + void getVersion(const std::shared_ptr<CommonAPI::ClientId> _client, getVersionReply_t _reply) { + _reply(m_version); + } + + /** + * description: setSimulationMode = This method activates or deactivates the simulation mode + */ + void setSimulationMode(const std::shared_ptr<CommonAPI::ClientId> _client, ::v4::org::genivi::navigation::NavigationTypes::Handle _sessionHandle, bool _activate, setSimulationModeReply_t _reply){ + dbg(lvl_debug,"enter Activate=%d\n",_activate); + MapMatchedPosition::SimulationStatus newSimulationMode; + struct attr vehicle; + vehicle.type=attr_vehicle; + vehicle.u.vehicle=get_vehicle(_activate ? "demo:":"enhancedposition:"); + if (vehicle.u.vehicle) { + newSimulationMode = _activate ? MapMatchedPosition::SimulationStatus::SIMULATION_STATUS_FIXED_POSITION : MapMatchedPosition::SimulationStatus::SIMULATION_STATUS_NO_SIMULATION; + if (newSimulationMode != m_simulationMode) { + m_simulationMode=newSimulationMode; + fireSimulationStatusChangedEvent(m_simulationMode); + } + demo_update(false); + struct navit *navit=get_navit(); + navit_set_attr(navit, &vehicle); + } else { + dbg(lvl_debug,"Failed to get vehicle\n"); + } + + _reply(); + } + + /** + * description: getSimulationStatus = This method retrieves the simulation status + */ + void getSimulationStatus(const std::shared_ptr<CommonAPI::ClientId> _client, getSimulationStatusReply_t _reply){ + _reply(m_simulationMode); + } + + /** + * description: AddSimulationStatusListener = Add this node as a listener to Simulation Status + * changes. + */ + void addSimulationStatusListener(const std::shared_ptr<CommonAPI::ClientId> _client, addSimulationStatusListenerReply_t _reply){ + throw DBus::ErrorNotSupported("Not yet supported"); + } + + /** + * description: RemoveSimulationStatusListener = Remove this node as a listener to Simulation + * Status changes. + */ + void removeSimulationStatusListener(const std::shared_ptr<CommonAPI::ClientId> _client, removeSimulationStatusListenerReply_t _reply){ + throw DBus::ErrorNotSupported("Not yet supported"); + } + + /** + * description: setSimulationSpeed = This method sets the speed factor for the simulation mode + */ + void setSimulationSpeed(const std::shared_ptr<CommonAPI::ClientId> _client, ::v4::org::genivi::navigation::NavigationTypes::Handle _sessionHandle, uint8_t _speedFactor, setSimulationSpeedReply_t _reply){ + int speed=_speedFactor*40/4; + if (vehicle_speed.u.num != speed) { + vehicle_speed.u.num=speed; + fireSimulationSpeedChangedEvent(_speedFactor); + if (m_simulationMode == MapMatchedPosition::SimulationStatus::SIMULATION_STATUS_RUNNING) { + demo_update(true); + } + } + _reply(); + } + + /** + * description: getSimulationSpeed = returns the speed factor for the simulation mode + */ + void getSimulationSpeed(const std::shared_ptr<CommonAPI::ClientId> _client, getSimulationSpeedReply_t _reply){ + _reply(vehicle_speed.u.num*4/40); + } + + /** + * description: AddSimulationSpeedListener = Add this node as a listener to simulation speed + * factor changes. + */ + void addSimulationSpeedListener(const std::shared_ptr<CommonAPI::ClientId> _client, addSimulationSpeedListenerReply_t _reply){ + throw DBus::ErrorNotSupported("Not yet supported"); + } + + /** + * description: RemoveSimulationSpeedListener = Remove this node as a listener to simulation + * speed factor changes. + */ + void removeSimulationSpeedListener(const std::shared_ptr<CommonAPI::ClientId> _client, removeSimulationSpeedListenerReply_t _reply){ + throw DBus::ErrorNotSupported("Not yet supported"); + } + + /** + * description: startSimulation = This method starts, or resumes, a Follow Active Route + * simulation + */ + void startSimulation(const std::shared_ptr<CommonAPI::ClientId> _client, ::v4::org::genivi::navigation::NavigationTypes::Handle _sessionHandle, startSimulationReply_t _reply){ + if (m_simulationMode == MapMatchedPosition::SimulationStatus::SIMULATION_STATUS_PAUSED || m_simulationMode == MapMatchedPosition::SimulationStatus::SIMULATION_STATUS_FIXED_POSITION ) { + m_simulationMode=MapMatchedPosition::SimulationStatus::SIMULATION_STATUS_RUNNING; + fireSimulationStatusChangedEvent(m_simulationMode); + demo_update(true); + } + _reply(); + } + + /** + * description: pauseSimulation = This method freezes the current location + */ + void pauseSimulation(const std::shared_ptr<CommonAPI::ClientId> _client, ::v4::org::genivi::navigation::NavigationTypes::Handle _sessionHandle, pauseSimulationReply_t _reply){ + if (m_simulationMode == MapMatchedPosition::SimulationStatus::SIMULATION_STATUS_RUNNING) { + m_simulationMode=MapMatchedPosition::SimulationStatus::SIMULATION_STATUS_PAUSED; + fireSimulationStatusChangedEvent(m_simulationMode); + demo_update(false); + } + _reply(); + } + + /** + * description: getPosition = This method returns the current position + */ + void getPosition(const std::shared_ptr<CommonAPI::ClientId> _client, std::vector<MapMatchedPosition::PositionItemKey> _valuesToReturn, getPositionReply_t _reply){ + dbg(lvl_debug,"enter\n"); + MapMatchedPosition::PositionItemDict map; + struct attr attr; + for (std::size_t i = 0 ; i < _valuesToReturn.size() ; i++) { + switch (_valuesToReturn[i]) { + case MapMatchedPosition::PositionItemKey::LATITUDE: + if (tracking_get_attr(tracking, attr_position_coord_geo, &attr, NULL)) + map[MapMatchedPosition::PositionItemKey::LATITUDE]=attr.u.coord_geo->lat; + break; + case MapMatchedPosition::PositionItemKey::LONGITUDE: + if (tracking_get_attr(tracking, attr_position_coord_geo, &attr, NULL)) + map[MapMatchedPosition::PositionItemKey::LONGITUDE]=attr.u.coord_geo->lng; + break; + case MapMatchedPosition::PositionItemKey::SPEED: + if (tracking_get_attr(tracking, attr_position_speed, &attr, NULL)) + map[MapMatchedPosition::PositionItemKey::SPEED]=*attr.u.numd; + break; + case MapMatchedPosition::PositionItemKey::HEADING: + if (tracking_get_attr(tracking, attr_position_direction, &attr, NULL)) + map[MapMatchedPosition::PositionItemKey::HEADING]=*attr.u.numd; + break; + } + } + _reply(map); + } + + /** + * description: setPosition = This method sets the position to a specific location + */ + void setPosition(const std::shared_ptr<CommonAPI::ClientId> _client, ::v4::org::genivi::navigation::NavigationTypes::Handle _sessionHandle, MapMatchedPosition::PositionItemDict _position, setPositionReply_t _reply){ + throw DBus::ErrorNotSupported("Not yet supported"); + } + + /** + * description: getAddress = This method returns the current address + */ + void getAddress(const std::shared_ptr<CommonAPI::ClientId> _client, std::vector<MapMatchedPosition::AddressItemKey> _valuesToReturn, getAddressReply_t _reply){ + MapMatchedPosition::AddressItemDict ret; + std::vector< MapMatchedPosition::AddressItemKey >::const_iterator it; + for (it = _valuesToReturn.begin(); it < _valuesToReturn.end(); it++) { + if (*it == MapMatchedPosition::AddressItemKey::STREET && mp_street_name) { + ret[*it]= std::string(mp_street_name); + } + } + _reply(ret); + } + + /** + * description: positionOnSegment = This method returns the vehicle position on a route segment + */ + void getPositionOnSegment(const std::shared_ptr<CommonAPI::ClientId> _client, std::vector<MapMatchedPosition::PositionOnSegmentKey> _valuesToReturn, getPositionOnSegmentReply_t _reply){ + throw DBus::ErrorNotSupported("Not yet supported"); + } + + /** + * description: getStatus = This method returns the current status + */ + void getStatus(const std::shared_ptr<CommonAPI::ClientId> _client, std::vector<MapMatchedPosition::PositionStatus> _valuesToReturn, getStatusReply_t _reply){ + throw DBus::ErrorNotSupported("Not yet supported"); + } + +private: + CommonTypes::Version m_version; + MapMatchedPosition::SimulationStatus m_simulationMode; + + void + demo_update(bool start) + { + struct attr vehicle_null_speed={attr_speed,(char *)0}; + struct vehicle *vehicle=get_vehicle("demo:"); + vehicle_set_attr(vehicle, start?&vehicle_speed:&vehicle_null_speed); + } + +}; + +static std::shared_ptr<MapMatchedPositionServerStub> myServiceMapMatchedPosition; + +static void +tracking_attr_position_coord_geo(void) +{ + struct attr position_coord_geo, current_item; + dbg(lvl_debug,"enter\n"); + if (tracking_get_attr(tracking, attr_position_coord_geo, &position_coord_geo, NULL)) { + std::vector< MapMatchedPosition::PositionItemKey >changes; + changes.push_back(MapMatchedPosition::PositionItemKey::LATITUDE); + changes.push_back(MapMatchedPosition::PositionItemKey::LONGITUDE); + changes.push_back(MapMatchedPosition::PositionItemKey::SPEED); + changes.push_back(MapMatchedPosition::PositionItemKey::HEADING); + myServiceMapMatchedPosition->firePositionUpdateEvent(changes); + } + if (tracking_get_attr(tracking, attr_current_item, ¤t_item, NULL) && current_item.u.item) { + if (!item_is_equal(last_item, *current_item.u.item)) { + last_item=*current_item.u.item; + char *new_street_name=NULL; + struct map_rect *mr=map_rect_new(last_item.map, NULL); + struct item *item; + if (mr && (item = map_rect_get_item_byid(mr, last_item.id_hi, last_item.id_lo))) { + struct attr label; + if (item_attr_get(item, attr_label, &label)) + new_street_name=label.u.str; + } + if (g_strcmp0(new_street_name, mp_street_name)) { + g_free(mp_street_name); + mp_street_name=g_strdup(new_street_name); + std::vector< MapMatchedPosition::AddressItemKey >changes; + changes.push_back(MapMatchedPosition::AddressItemKey::STREET); + myServiceMapMatchedPosition->fireAddressUpdateEvent(changes); + } + if (mr) + map_rect_destroy(mr); + } + } +} + +static void +navit_attr_navit(struct navit *navit) +{ + struct attr tracking_attr; + if (navit_get_attr(navit, attr_trackingo, &tracking_attr, NULL)) { + tracking=tracking_attr.u.tracking; + tracking_cb.type=attr_callback; + tracking_cb.u.callback=callback_new_attr_0(callback_cast(tracking_attr_position_coord_geo), attr_position_coord_geo); + tracking_add_attr(tracking, &tracking_cb); + } +} + +static void +config_attr_navit(struct navit *navit, int add) +{ + if (!tracking && !navit_cb.u.callback && add) { + navit_cb.type=attr_callback; + navit_cb.u.callback=callback_new_attr_0(callback_cast(navit_attr_navit), attr_navit); + navit_add_attr(navit, &navit_cb); + } +} + +void +plugin_init(void) +{ + // Common API data init + std::shared_ptr < CommonAPI::Runtime > runtime = CommonAPI::Runtime::get(); + + const std::string &domain = "local"; + const std::string &instance = "MapMatchedPosition"; + + myServiceMapMatchedPosition = std::make_shared<MapMatchedPositionServerStub>(); + + bool successfullyRegistered = runtime->registerService(domain, instance, myServiceMapMatchedPosition); + while (!successfullyRegistered) { + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + successfullyRegistered = runtime->registerService(domain, instance, myServiceMapMatchedPosition); + } + config_cb.type=attr_callback; + config_cb.u.callback=callback_new_attr_0(callback_cast(config_attr_navit), attr_navit); + config_add_attr(config, &config_cb); +} diff --git a/src/navigation/navigation-core/navit_genivi_navigationcore_capi.xsl b/src/navigation/navigation-core/navit_genivi_navigationcore_capi.xsl index 74cc2bc..68cd29d 100644 --- a/src/navigation/navigation-core/navit_genivi_navigationcore_capi.xsl +++ b/src/navigation/navigation-core/navit_genivi_navigationcore_capi.xsl @@ -27,13 +27,13 @@ <xsl:text>
 </xsl:text> <plugin path="../../navigation-core/locationinput-server-plugin/.libs/libgenivi_navigationcore_locationinput_server.so" ondemand="no"/> <xsl:text>
 </xsl:text> - <plugin path="../../navigation-core/routing-plugin/.libs/libgenivi_navigationcore_routing.so" ondemand="no"/> + <plugin path="../../navigation-core/routing-server-plugin/.libs/libgenivi_navigationcore_routing_server.so" ondemand="no"/> <xsl:text>
 </xsl:text> - <plugin path="../../navigation-core/session-plugin/.libs/libgenivi_navigationcore_session.so" ondemand="no"/> + <plugin path="../../navigation-core/session-server-plugin/.libs/libgenivi_navigationcore_session_server.so" ondemand="no"/> <xsl:text>
 </xsl:text> - <plugin path="../../navigation-core/guidance-plugin/.libs/libgenivi_navigationcore_guidance.so" ondemand="no"/> + <plugin path="../../navigation-core/guidance-server-plugin/.libs/libgenivi_navigationcore_guidance_server.so" ondemand="no"/> <xsl:text>
 </xsl:text> - <plugin path="../../navigation-core/mapmatchedposition-plugin/.libs/libgenivi_navigationcore_mapmatchedposition.so" ondemand="no"/> + <plugin path="../../navigation-core/mapmatchedposition-server-plugin/.libs/libgenivi_navigationcore_mapmatchedposition_server.so" ondemand="no"/> <xsl:text>
 </xsl:text> <plugin path="../../navigation-core/enhancedposition-plugin/.libs/libgenivi_positioning_enhancedposition.so" ondemand="no"/> <xsl:text>
 </xsl:text> diff --git a/src/navigation/navigation-core/routing-server-plugin/CMakeLists.txt b/src/navigation/navigation-core/routing-server-plugin/CMakeLists.txt new file mode 100644 index 0000000..de78caf --- /dev/null +++ b/src/navigation/navigation-core/routing-server-plugin/CMakeLists.txt @@ -0,0 +1,116 @@ +########################################################################### +# @licence app begin@ +# SPDX-License-Identifier: MPL-2.0 +# +# Component Name: mapmatchedposition-server-plugin +# +# Author: Philippe Colliot +# +# Copyright (C) 2015, PCA Peugeot Citroën +# +# License: +# This Source Code Form is subject to the terms of the +# Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with +# this file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# @licence end@ +########################################################################### +project(routing-server-plugin) +cmake_minimum_required(VERSION 2.8) + +message(STATUS ${PROJECT_NAME}) + +set(CMAKE_VERBOSE_MAKEFILE on) +set(CMAKE_CXX_FLAGS "-Wall -std=c++0x") + + + +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/lib) +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/bin) + + +# DBus Path +if(DBUS_LIB_PATH) + message(STATUS "DBUS_LIB_PATH = " ${DBUS_LIB_PATH}) + set(DBUS_INCLUDE_DIRS ${DBUS_LIB_PATH}/include/dbus-1.0 ${DBUS_LIB_PATH}/lib/dbus-1.0/include) + set(DBUS_LIBDIR ${DBUS_LIB_PATH}/lib) + set(DBUS_LIBRARIES ${DBUS_LIB_PATH}/lib/libdbus-1.so) +else() + message(FATAL_ERROR "Please specify the path to your patched DBus library using -DDBUS_LIB_PATH=yourPath") +endif() + +# Packages +find_package(CommonAPI 3.1.5 REQUIRED) +find_package(CommonAPI-DBus 3.1.5 REQUIRED) + + +#pkg_check_modules(DBUS "dbus-1 >= 1.8.4") // #to be fixed, it doesn't work so the paths are set manually (see above) +pkg_check_modules(COMMONAPI "CommonAPI >= 3.1.5") +pkg_check_modules(COMMONAPI_DBUS "CommonAPI-DBus >= 3.1.5") +pkg_check_modules(GOBJECT gobject-2.0) +pkg_check_modules(GLIB REQUIRED glib-2.0) +pkg_check_modules(DBUS_CPP_GLIB dbus-c++-glib-1) + + +# Add the Franca files (that will generate the CommonAPI stuff) +set(COMMONAPI_GEN_DIR "${CMAKE_CURRENT_BINARY_DIR}/src-gen") +add_subdirectory(${FRANCA_DIR}/navigation/navigationcore "${CMAKE_CURRENT_BINARY_DIR}/franca") + +# Path to the generated files +set(API_VERSION_MAJOR 4) +set(API_VERSION "v${API_VERSION_MAJOR}") +set(PRJ_SRC_GEN_ROOT_PATH ${COMMONAPI_GEN_DIR}/${API_VERSION}/org/genivi) #files shared by all the APIs +set(PRJ_SRC_GEN_NAVIGATION_PATH ${PRJ_SRC_GEN_ROOT_PATH}/navigation) #files shared by the navigation APIs +set(PRJ_SRC_GEN_NAVIGATIONCORE_PATH ${PRJ_SRC_GEN_NAVIGATION_PATH}/navigationcore) #files shared by the navigationcore APIs + +# Source Files +set(FRANCA_FILE "Routing") +FILE(GLOB PRJ_LOCAL_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/*.cxx) +FILE(GLOB PRJ_STUB_GEN_SRCS + ${PRJ_SRC_GEN_ROOT_PATH}/*DBusStub*.cpp ${PRJ_SRC_GEN_ROOT_PATH}/*Types.cpp ${PRJ_SRC_GEN_ROOT_PATH}/*DBusDeployment.cpp ${PRJ_SRC_GEN_ROOT_PATH}/*StubDefault.cpp + ${PRJ_SRC_GEN_NAVIGATION_PATH}/*DBusStub*.cpp ${PRJ_SRC_GEN_NAVIGATION_PATH}/*Types.cpp ${PRJ_SRC_GEN_NAVIGATION_PATH}/*DBusDeployment.cpp ${PRJ_SRC_GEN_NAVIGATION_PATH}/*StubDefault.cpp + ${PRJ_SRC_GEN_NAVIGATIONCORE_PATH}/${FRANCA_FILE}DBusStub*.cpp ${PRJ_SRC_GEN_NAVIGATIONCORE_PATH}/${FRANCA_FILE}Types.cpp ${PRJ_SRC_GEN_NAVIGATIONCORE_PATH}/${FRANCA_FILE}DBusDeployment.cpp ${PRJ_SRC_GEN_NAVIGATIONCORE_PATH}/${FRANCA_FILE}StubDefault.cpp + ) +FILE(GLOB PRJ_STUB_IMPL_SRCS + ${PRJ_SRC_GEN_ROOT_PATH}/*Stub*.cpp + ${PRJ_SRC_GEN_NAVIGATION_PATH}/*Stub*.cpp + ${PRJ_SRC_GEN_NAVIGATIONCORE_PATH}/${FRANCA_FILE}Stub*.cpp + ) + +set(PRJ_SRCS ${PRJ_LOCAL_SRCS} ${PRJ_STUB_GEN_SRCS} ${PRJ_STUB_IMPL_SRCS}) + +include_directories( + ${COMMONAPI_GEN_DIR} + ${PRJ_SRC_GEN_ROOT_PATH} + ${PRJ_SRC_GEN_NAVIGATION_PATH} + ${PRJ_SRC_GEN_NAVIGATIONCORE_PATH} + ${DBUS_INCLUDE_DIRS} + ${COMMONAPI_INCLUDE_DIRS} + ${COMMONAPI_DBUS_INCLUDE_DIRS} + ${GOBJECT_INCLUDE_DIRS} + ${GLIB_INCLUDE_DIRS} + ${DBUS_CPP_GLIB_INCLUDE_DIRS} +) + +link_directories( + ${DBUS_LIBDIR} + ${COMMONAPI_LIBDIR} + ${COMMONAPI_DBUS_LIBDIR} + ${GOBJECT_LIBRARY_DIRS} + ${GLIB_LIBRARY_DIRS} + ${DBUS_CPP_GLIB_DIRS} +) + +set(LIBRARIES + ${DBUS_LIBRARIES} + ${COMMONAPI_LIBRARIES} + ${COMMONAPI_DBUS_LIBRARIES} + ${GOBJECT_LIBRARIES} + ${GLIB_LIBRARIES} + ${DBUS_CPP_GLIB_LIBRARIES} +) + +# Build service +module_add_library(genivi_navigationcore_routing_server ${PRJ_SRCS}) +target_link_libraries(genivi_navigationcore_routing_server ${LIBRARIES}) + diff --git a/src/navigation/navigation-core/routing-server-plugin/genivi_navigationcore_routing.cxx b/src/navigation/navigation-core/routing-server-plugin/genivi_navigationcore_routing.cxx new file mode 100644 index 0000000..8bdaaea --- /dev/null +++ b/src/navigation/navigation-core/routing-server-plugin/genivi_navigationcore_routing.cxx @@ -0,0 +1,976 @@ +/** +* @licence app begin@ +* SPDX-License-Identifier: MPL-2.0 +* +* \copyright Copyright (C) 2013-2014, PCA Peugeot Citroen +* +* \file genivi_navigationcore_routing.cxx +* +* \brief This file is part of the Navit POC. +* +* \author Martin Schaller <martin.schaller@it-schaller.de> +* \author Philippe Colliot <philippe.colliot@mpsa.com> +* +* \version 1.0 +* +* This Source Code Form is subject to the terms of the +* Mozilla Public License (MPL), v. 2.0. +* If a copy of the MPL was not distributed with this file, +* You can obtain one at http://mozilla.org/MPL/2.0/. +* +* For further information see http://www.genivi.org/. +* +* List of changes: +* +* <date>, <name>, <description of change> +* +* @licence end@ +*/ +#include <dbus-c++/glib-integration.h> +#include "config.h" +#define USE_PLUGINS 1 +#include "debug.h" +#include "plugin.h" +#include "item.h" +#include "coord.h" +#include "config_.h" +#include "navit.h" +#include "route.h" +#include "transform.h" +#include "command.h" +#include "callback.h" +#include "vehicle.h" +#include "xmlconfig.h" +#include "vehicleprofile.h" +#include "roadprofile.h" +#include "map.h" +#include "event.h" + +#include <CommonAPI/CommonAPI.hpp> +#include <CommonTypes.hpp> +#include <NavigationTypes.hpp> +#include <NavigationCoreTypes.hpp> +#include <RoutingStubDefault.hpp> + +#if (!DEBUG_ENABLED) +#undef dbg +#define dbg(level,...) ; +#endif + +using namespace v4::org::genivi::navigation::navigationcore; +using namespace v4::org::genivi::navigation; +using namespace v4::org::genivi; + +struct vehicleprofile_settings { + int flags_forward_mask,flags_reverse_mask; + int ferry_weight; + int highway_city_weight; + int highway_land_weight; +}; + +class RoutingServerStub; + +class RoutingObj +{ +public: + RoutingObj(RoutingServerStub *routing, uint32_t session, uint32_t handle); + ~RoutingObj(); + void map_to_pcoord(Routing::WayPoint map, struct pcoord *pc); + void SetCostModel(uint32_t SessionHandle, Routing::CostModel CostModel); + void GetCostModel(Routing::CostModel &CostModel); + void SetWaypoints(uint32_t SessionHandle, bool StartFromCurrentPosition, std::vector< Routing::WayPoint > Waypoints); + void GetWaypoints(bool& StartFromCurrentPosition, std::vector<Routing::WayPoint> &Waypoints); + void CalculateRoute(uint32_t SessionHandle); + void GetRouteSegments(int16_t detailLevel , const std::vector< Routing::RouteSegmentType >& valuesToReturn, const uint32_t& numberOfSegments, const uint32_t& offset, uint32_t& totalNumberOfSegments, std::vector<Routing::RouteSegment>& RouteSegments); + void GetRouteOverview(uint32_t routeHandle , Routing::RouteOverview &routeOverview); + void GetRouteBoundingBox(NavigationTypes::Rectangle &boundingBox); + void CancelRouteCalculation(uint32_t sessionHandle); + bool RoutePreference(Routing::PreferenceMode preferenceMode,Routing::RoutePreferenceSource preferenceSource); + void SetRoutePreferences(uint32_t sessionHandle, const std::string& country, const std::vector< Routing::RoutePreference >& routePreferencesList); + void GetRoutePreferences(const std::string& country, std::vector< Routing::RoutePreference >& roadPreferenceList); + + uint32_t m_handle; + RoutingServerStub *mp_routing; + int m_route_status; + struct attr m_route,m_vehicleprofile; + +private: + struct search_list *m_sl; + uint32_t m_session; + Routing::CostModel m_costmodel; + std::vector< Routing::RoutePreference > m_route_preferences_list[2]; + std::vector< Routing::WayPoint > m_waypoints; + bool m_startfromcurrentposition; + int m_vehicleprofile_idx; + struct vehicleprofile_settings m_vehicleprofile_settings[2]; + struct callback *m_callback; + struct navit *get_navit(void); + struct mapset *get_mapset(struct navit *navit); + struct route *get_route(struct navit *navit); + struct vehicle *get_vehicle(struct navit *navit); + struct tracking *get_tracking(void); +}; + +static std::map<uint32_t, RoutingObj *> mp_handles; + +static bool commands_registered; + +static void +navit_genivi_get_route(struct navit *nav, char *function, struct attr **in, struct attr ***out, int *valid) +{ + if (!out || !in || !in[0]) + return; + if (!ATTR_IS_INT(in[0]->type)) + return; + RoutingObj *obj=mp_handles[in[0]->u.num]; + if (!obj) + return; + *out=attr_generic_add_attr(*out, &obj->m_route); + *out=attr_generic_add_attr(*out, &obj->m_vehicleprofile); +} + +static struct command_table commands[] = { + {"navit_genivi_get_route",command_cast(navit_genivi_get_route)}, +}; + +class RoutingServerStub : public RoutingStubDefault +{ + public: + +#define MAX_ROUTE_HANDLES 256 + + RoutingServerStub() + { + m_version.setVersionMajor(3); + m_version.setVersionMinor(0); + m_version.setVersionMicro(0); + m_version.setDate("21-01-2014"); + } + + /** + * description: This method returns the API version implemented by the server application + */ + void getVersion(const std::shared_ptr<CommonAPI::ClientId> _client, getVersionReply_t _reply) { + _reply(m_version); + } + + /** + * description: This method creates a route + */ + void createRoute(const std::shared_ptr<CommonAPI::ClientId> _client, ::v4::org::genivi::navigation::NavigationTypes::Handle _sessionHandle, createRouteReply_t _reply){ + dbg(lvl_debug,"enter\n"); + NavigationTypes::Handle routeHandle=1; + while (mp_handles[routeHandle]) { + routeHandle++; + if (routeHandle == MAX_ROUTE_HANDLES) + throw DBus::ErrorLimitsExceeded("Out of route handles"); + } + mp_handles[routeHandle]=new RoutingObj(this, _sessionHandle, routeHandle); + _reply(routeHandle); + } + + /** + * description: This method deletes a route and its associated resources + */ + void deleteRoute(const std::shared_ptr<CommonAPI::ClientId> _client, ::v4::org::genivi::navigation::NavigationTypes::Handle _sessionHandle, ::v4::org::genivi::navigation::NavigationTypes::Handle _routeHandle, deleteRouteReply_t _reply){ + RoutingObj *obj=mp_handles[_routeHandle]; + if (!obj) + throw DBus::ErrorInvalidArgs("Route handle invalid"); + delete(obj); + mp_handles[_routeHandle]=NULL; + fireRouteDeletedEvent(_routeHandle); + _reply(); + } + + /** + * description: This method sets the cost model + */ + void setCostModel(const std::shared_ptr<CommonAPI::ClientId> _client, ::v4::org::genivi::navigation::NavigationTypes::Handle _sessionHandle, ::v4::org::genivi::navigation::NavigationTypes::Handle _routeHandle, Routing::CostModel _costModel, setCostModelReply_t _reply){ + RoutingObj *obj=mp_handles[_routeHandle]; + if (!obj) + throw DBus::ErrorInvalidArgs("Route handle invalid"); + obj->SetCostModel(_sessionHandle, _costModel); + _reply(); + } + + /** + * description: This method retrieves the selected cost model + */ + void getCostModel(const std::shared_ptr<CommonAPI::ClientId> _client, ::v4::org::genivi::navigation::NavigationTypes::Handle _routeHandle, getCostModelReply_t _reply){ + Routing::CostModel costModel; + dbg(lvl_debug,"enter\n"); + RoutingObj *obj=mp_handles[_routeHandle]; + if (!obj) + throw DBus::ErrorInvalidArgs("Route handle invalid"); + obj->GetCostModel(costModel); + _reply(costModel); + } + + /** + * description: This method retrieves a list of supported cost models + */ + void getSupportedCostModels(const std::shared_ptr<CommonAPI::ClientId> _client, getSupportedCostModelsReply_t _reply){ + std::vector< Routing::CostModel > costModels; + costModels.resize(2); + costModels[0]=Routing::CostModel::FASTEST; + costModels[1]=Routing::CostModel::SHORTEST; + _reply(costModels); + } + + /** + * description: This method sets a list of route preferences + */ + void setRoutePreferences(const std::shared_ptr<CommonAPI::ClientId> _client, ::v4::org::genivi::navigation::NavigationTypes::Handle _sessionHandle, ::v4::org::genivi::navigation::NavigationTypes::Handle _routeHandle, std::string _countryCode, std::vector<Routing::RoutePreference> _roadPreferenceList, std::vector<Routing::ConditionPreference> _conditionPreferenceList, setRoutePreferencesReply_t _reply){ + RoutingObj *obj=mp_handles[_routeHandle]; + if (!obj) + throw DBus::ErrorInvalidArgs("Route handle invalid"); + obj->SetRoutePreferences(_sessionHandle, _countryCode, _roadPreferenceList); + _reply(); + } + + /** + * description: This method retrieves a list of selected route preferences + */ + void getRoutePreferences(const std::shared_ptr<CommonAPI::ClientId> _client, ::v4::org::genivi::navigation::NavigationTypes::Handle _routeHandle, std::string _countryCode, getRoutePreferencesReply_t _reply){ + Routing::RoutePreference routePreference; + std::vector<Routing::RoutePreference> _roadPreferenceList; + Routing::ConditionPreference conditionPreference; + std::vector<Routing::ConditionPreference> _conditionPreferenceList; + + RoutingObj *obj=mp_handles[_routeHandle]; + if (!obj) + throw DBus::ErrorInvalidArgs("Route handle invalid"); + obj->GetRoutePreferences(_countryCode, _roadPreferenceList); + if (_roadPreferenceList.size() == 0) + { //add a default value (bug in qml to be fixed) + routePreference.setMode(Routing::PreferenceMode::INVALID); + routePreference.setSource(Routing::RoutePreferenceSource::INVALID); + _roadPreferenceList.push_back(routePreference); + } + conditionPreference.setMode(Routing::PreferenceMode::USE); + conditionPreference.setSource(Routing::ConditionPreferenceSource::TRAFFIC_REALTIME); + _conditionPreferenceList.push_back(conditionPreference); //by default + _reply(_roadPreferenceList,_conditionPreferenceList); + } + + /** + * description: This method retrieves a list of supported route preferences + */ + void getSupportedRoutePreferences(const std::shared_ptr<CommonAPI::ClientId> _client, getSupportedRoutePreferencesReply_t _reply){ + Routing::RoutePreference routePreference; + std::vector<Routing::RoutePreference> _routePreferencesList; + Routing::ConditionPreference conditionPreference; + std::vector<Routing::ConditionPreference> _conditionPreferenceList; + routePreference.setMode(Routing::PreferenceMode::AVOID); + routePreference.setSource(Routing::RoutePreferenceSource::HIGHWAYS_MOTORWAYS); + _routePreferencesList.push_back(routePreference); + routePreference.setMode(Routing::PreferenceMode::AVOID); + routePreference.setSource(Routing::RoutePreferenceSource::TOLL_ROADS); + _routePreferencesList.push_back(routePreference); + routePreference.setMode(Routing::PreferenceMode::AVOID); + routePreference.setSource(Routing::RoutePreferenceSource::FERRY); + _routePreferencesList.push_back(routePreference); + conditionPreference.setMode(Routing::PreferenceMode::USE); + conditionPreference.setSource(Routing::ConditionPreferenceSource::TRAFFIC_REALTIME); + _conditionPreferenceList.push_back(conditionPreference); + _reply(_routePreferencesList,_conditionPreferenceList); + } + + /** + * description: This method sets the time schedule for the route to be calculated + */ + void setRouteSchedule(const std::shared_ptr<CommonAPI::ClientId> _client, ::v4::org::genivi::navigation::NavigationTypes::Handle _sessionHandle, ::v4::org::genivi::navigation::NavigationTypes::Handle _routeHandle, Routing::RouteSchedule _routeSchedule, setRouteScheduleReply_t _reply){ + throw DBus::ErrorNotSupported("Not yet supported"); + _reply(); + } + + /** + * description: This method gets the time schedule for the route to be calculated + */ + void getRouteSchedule(const std::shared_ptr<CommonAPI::ClientId> _client, ::v4::org::genivi::navigation::NavigationTypes::Handle _routeHandle, std::vector<Routing::Schedule> _valuesToReturn, getRouteScheduleReply_t _reply){ + throw DBus::ErrorNotSupported("Not yet supported"); + } + + /** + * description: This method sets a list of means of transportation that must be considered when + * calculating a route + */ + void setTransportationMeans(const std::shared_ptr<CommonAPI::ClientId> _client, ::v4::org::genivi::navigation::NavigationTypes::Handle _sessionHandle, ::v4::org::genivi::navigation::NavigationTypes::Handle _routeHandle, std::vector<Routing::TransportationMeans> _transportationMeansList, setTransportationMeansReply_t _reply){ + throw DBus::ErrorNotSupported("Not yet supported"); + _reply(); + } + + /** + * description: getTransportationMeans = This method retrieves the selected means of + * transportation + */ + void getTransportationMeans(const std::shared_ptr<CommonAPI::ClientId> _client, ::v4::org::genivi::navigation::NavigationTypes::Handle _routeHandle, getTransportationMeansReply_t _reply){ + throw DBus::ErrorNotSupported("Not yet supported"); + } + + /** + * description: getSupportedTransportationMeans = This method retrieves a list of supported + * means of transportation + */ + void getSupportedTransportationMeans(const std::shared_ptr<CommonAPI::ClientId> _client, getSupportedTransportationMeansReply_t _reply){ + throw DBus::ErrorNotSupported("Not yet supported"); + } + + /** + * description: setExcludedAreas = This method sets the areas to be excluded when calculating a + * route + */ + void setExcludedAreas(const std::shared_ptr<CommonAPI::ClientId> _client, ::v4::org::genivi::navigation::NavigationTypes::Handle _sessionHandle, ::v4::org::genivi::navigation::NavigationTypes::Handle _routeHandle, std::vector< ::v4::org::genivi::navigation::NavigationTypes::Polygon> _excludedAreas, setExcludedAreasReply_t _reply){ + throw DBus::ErrorNotSupported("Not yet supported"); + _reply(); + } + + /** + * description: getExcludedAreas = This method retrieves the areas to be excluded when + * calculating a route + */ + void getExcludedAreas(const std::shared_ptr<CommonAPI::ClientId> _client, ::v4::org::genivi::navigation::NavigationTypes::Handle _routeHandle, getExcludedAreasReply_t _reply){ + throw DBus::ErrorNotSupported("Not yet supported"); + } + + /** + * description: setWaypoints = This method sets a list of waypoints + */ + void setWaypoints(const std::shared_ptr<CommonAPI::ClientId> _client, ::v4::org::genivi::navigation::NavigationTypes::Handle _sessionHandle, ::v4::org::genivi::navigation::NavigationTypes::Handle _routeHandle, bool _startFromCurrentPosition, std::vector<Routing::WayPoint> _waypointsList, setWaypointsReply_t _reply){ + dbg(lvl_debug,"enter\n"); + RoutingObj *obj=mp_handles[_routeHandle]; + if (!obj) + throw DBus::ErrorInvalidArgs("Route handle invalid"); + obj->SetWaypoints(_sessionHandle, _startFromCurrentPosition, _waypointsList); + _reply(); + } + + /** + * description: getWaypoints = This method retrieves a list of waypoints + */ + void getWaypoints(const std::shared_ptr<CommonAPI::ClientId> _client, ::v4::org::genivi::navigation::NavigationTypes::Handle _routeHandle, getWaypointsReply_t _reply){ + dbg(lvl_debug,"enter\n"); + bool _startFromCurrentPosition; + std::vector<Routing::WayPoint> _waypointsList; + RoutingObj *obj=mp_handles[_routeHandle]; + if (!obj) + throw DBus::ErrorInvalidArgs("Route handle invalid"); + obj->GetWaypoints(_startFromCurrentPosition, _waypointsList); + _reply(_startFromCurrentPosition,_waypointsList); + } + + /** + * description: calculateRoute = This method starts a route calculation + */ + void calculateRoute(const std::shared_ptr<CommonAPI::ClientId> _client, ::v4::org::genivi::navigation::NavigationTypes::Handle _sessionHandle, ::v4::org::genivi::navigation::NavigationTypes::Handle _routeHandle, calculateRouteReply_t _reply){ + dbg(lvl_debug,"enter\n"); + RoutingObj *obj=mp_handles[_routeHandle]; + if (!obj) + throw DBus::ErrorInvalidArgs("Route handle invalid"); + obj->CalculateRoute(_sessionHandle); + _reply(); + } + + /** + * description: cancelRouteCalculation = This method cancels a route calculation + */ + void cancelRouteCalculation(const std::shared_ptr<CommonAPI::ClientId> _client, ::v4::org::genivi::navigation::NavigationTypes::Handle _sessionHandle, ::v4::org::genivi::navigation::NavigationTypes::Handle _routeHandle, cancelRouteCalculationReply_t _reply){ + RoutingObj *obj=mp_handles[_routeHandle]; + if (!obj) + throw DBus::ErrorInvalidArgs("Route handle invalid"); + obj->CancelRouteCalculation(_sessionHandle); + fireRouteCalculationCancelledEvent(_routeHandle); + _reply(); + } + + /** + * description: calculateRoutes = This method allows a client to calculate alternative routes + * that differs from a list of already calculated routes + */ + void calculateRoutes(const std::shared_ptr<CommonAPI::ClientId> _client, ::v4::org::genivi::navigation::NavigationTypes::Handle _sessionHandle, std::vector< ::v4::org::genivi::navigation::NavigationTypes::Handle> _calculatedRoutesList, calculateRoutesReply_t _reply){ + throw DBus::ErrorNotSupported("Not yet supported"); + } + + /** + * description: getRouteSegments = This method retrieves a list of segments for a given route + * starting from the one closest to the current position to the one closest to + * the destination + */ + void getRouteSegments(const std::shared_ptr<CommonAPI::ClientId> _client, ::v4::org::genivi::navigation::NavigationTypes::Handle _routeHandle, int16_t _detailLevel, std::vector<Routing::RouteSegmentType> _valuesToReturn, uint32_t _numberOfSegments, uint32_t _offset, getRouteSegmentsReply_t _reply){ + dbg(lvl_debug,"enter\n"); + uint32_t _totalNumberOfSegments; + std::vector<Routing::RouteSegment> _routeSegments; + RoutingObj *obj=mp_handles[_routeHandle]; + if (!obj) + throw DBus::ErrorInvalidArgs("Route handle invalid"); + obj->GetRouteSegments(_detailLevel,_valuesToReturn, _numberOfSegments, _offset, _totalNumberOfSegments, _routeSegments); + _reply(_totalNumberOfSegments,_routeSegments); + } + + /** + * description: getRouteOverview = This method retrieves general information about a given route + */ + void getRouteOverview(const std::shared_ptr<CommonAPI::ClientId> _client, ::v4::org::genivi::navigation::NavigationTypes::Handle _routeHandle, std::vector<Routing::RouteOverviewType> _valuesToReturn, getRouteOverviewReply_t _reply){ + Routing::RouteOverview _routeOverview; + RoutingObj *obj=mp_handles[_routeHandle]; + if (!obj) + throw DBus::ErrorInvalidArgs("Route handle invalid"); + obj->GetRouteOverview(_routeHandle, _routeOverview); + _reply(_routeOverview); + + } + + /** + * description: getRouteBoundingBox = This method retrieves the bounding box containing a + * calculated route + */ + void getRouteBoundingBox(const std::shared_ptr<CommonAPI::ClientId> _client, ::v4::org::genivi::navigation::NavigationTypes::Handle _routeHandle, getRouteBoundingBoxReply_t _reply){ + NavigationTypes::Rectangle _boundingBox; + RoutingObj *obj=mp_handles[_routeHandle]; + if (!obj) + throw DBus::ErrorInvalidArgs("Route handle invalid"); + obj->GetRouteBoundingBox(_boundingBox); + _reply(_boundingBox); + + } + + /** + * description: getAllRoutes = This method retrieves the handles of all created routes + */ + void getAllRoutes(const std::shared_ptr<CommonAPI::ClientId> _client, getAllRoutesReply_t _reply){ + std::vector< NavigationTypes::Handle >_routesList; + std::map<uint32_t, RoutingObj *>::const_iterator itr; + + for(itr = mp_handles.begin(); itr != mp_handles.end(); itr++) + _routesList.push_back((*itr).first); + _reply(_routesList); + } + + /** + * description: setBlockedRouteStretches = This method sets blocked streches on a given route + */ + void setBlockedRouteStretches(const std::shared_ptr<CommonAPI::ClientId> _client, ::v4::org::genivi::navigation::NavigationTypes::Handle _sessionHandle, ::v4::org::genivi::navigation::NavigationTypes::Handle _routeHandle, std::vector<Routing::BlockedRouteElement> _blockParameters, setBlockedRouteStretchesReply_t _reply){ + throw DBus::ErrorNotSupported("Not yet supported"); + _reply(); + } + + /** + * description: getBlockedRouteStretches = This method retrieves all blocked streches on a + * given route + */ + void getBlockedRouteStretches(const std::shared_ptr<CommonAPI::ClientId> _client, ::v4::org::genivi::navigation::NavigationTypes::Handle _routeHandle, getBlockedRouteStretchesReply_t _reply){ + throw DBus::ErrorNotSupported("Not yet supported"); + } + +private: + CommonTypes::Version m_version; + std::map<NavigationTypes::Handle, RoutingObj *> mp_handles; + +}; + +struct navit * +RoutingObj::get_navit(void) +{ + struct attr navit,callback_list; + if (!config_get_attr(config, attr_navit, &navit, NULL)) + return NULL; + + if (!commands_registered && navit_get_attr(navit.u.navit, attr_callback_list, &callback_list, NULL)) { + command_add_table(callback_list.u.callback_list, commands, sizeof(commands)/sizeof(struct command_table), navit.u.navit); + commands_registered=true; + } + + return navit.u.navit; +} + +struct mapset * +RoutingObj::get_mapset(struct navit *navit) +{ + struct attr mapset; + if (!navit_get_attr(navit, attr_mapset, &mapset, NULL)) + return NULL; + return mapset.u.mapset; +} + +struct route * +RoutingObj::get_route(struct navit *navit) +{ + struct attr route; + if (!navit_get_attr(navit, attr_route, &route, NULL)) + return NULL; + return route.u.route; +} + +struct vehicle * +RoutingObj::get_vehicle(struct navit *navit) +{ + struct attr vehicle; + if (!navit_get_attr(navit, attr_vehicle, &vehicle, NULL)) + return NULL; + return vehicle.u.vehicle; +} + +struct tracking * +RoutingObj::get_tracking(void) +{ + struct navit *navit=get_navit(); + struct attr tracking; + if (!navit) + return NULL; + if (!navit_get_attr(navit, attr_trackingo, &tracking, NULL)) + return NULL; + return tracking.u.tracking; +} + +void +RoutingObj_Callback(struct RoutingObj *obj) +{ + struct attr route_status; + if (!route_get_attr(obj->m_route.u.route, attr_route_status, &route_status, NULL)) { + dbg(lvl_debug,"failed to get route status\n"); + return; + } + if (route_status.u.num == route_status_destination_set) { + obj->mp_routing->fireRouteCalculationProgressUpdateEvent(obj->m_handle, Routing::CalculationStatus::CALCULATION_OK, 5); + obj->m_route_status=route_status.u.num; + } + if (route_status.u.num == route_status_building_graph) { + obj->m_route_status=route_status.u.num; + } + if (route_status.u.num == route_status_building_path && obj->m_route_status == route_status_building_graph) { + obj->mp_routing->fireRouteCalculationProgressUpdateEvent(obj->m_handle, Routing::CalculationStatus::CALCULATION_OK, 50); + obj->m_route_status=route_status.u.num; + } + if (route_status.u.num == route_status_path_done_new || + (obj->m_route_status==route_status_destination_set && route_status.u.num == route_status_path_done_incremental)) { + if (route_status.u.num == route_status_path_done_new) + obj->mp_routing->fireRouteCalculationProgressUpdateEvent(obj->m_handle, Routing::CalculationStatus::CALCULATION_OK, 100); + obj->m_route_status=route_status.u.num; + dbg(lvl_debug,"callback routing ok\n"); + Routing::UnfullfilledRoutePreference unfulfilled_preferences; + //tbd complete the unfulfilled_preferences + obj->mp_routing->fireRouteCalculationSuccessfulEvent(obj->m_handle, unfulfilled_preferences); + } + if (route_status.u.num == route_status_not_found) { + obj->m_route_status=route_status.u.num; + dbg(lvl_debug,"callback routing failed\n"); + Routing::UnfullfilledRoutePreference unfulfilled_preferences; + //tbd complete the unfulfilled_preferences + obj->mp_routing->fireRouteCalculationFailedEvent(obj->m_handle, Routing::CalculationError::UNREACHABLE_DESTINATION, unfulfilled_preferences); + } +} + +RoutingObj::RoutingObj(RoutingServerStub *routing, uint32_t session, uint32_t handle) +{ + struct attr callback; + + mp_routing=routing; + m_session=session; + m_handle=handle; + m_route.type=attr_route; + m_route.u.route=route_new(NULL, NULL); + m_vehicleprofile.type=attr_vehicleprofile; + m_vehicleprofile.u.vehicleprofile=NULL; + m_callback=callback_new_attr_1(reinterpret_cast<void (*)(void)>(RoutingObj_Callback), attr_route_status, this); + memset(m_vehicleprofile_settings, 0, sizeof(m_vehicleprofile_settings)); + SetCostModel(handle, Routing::CostModel::FASTEST); + callback.type=attr_callback; + callback.u.callback=m_callback; + route_add_attr(m_route.u.route, &callback); + route_set_mapset(m_route.u.route, get_mapset(get_navit())); +} + +RoutingObj::~RoutingObj() +{ + struct attr callback; + + callback.type=attr_callback; + callback.u.callback=m_callback; + route_remove_attr(m_route.u.route, &callback); + callback_destroy(m_callback); + route_destroy(m_route.u.route); +} + +void +RoutingObj::SetCostModel(uint32_t SessionHandle, Routing::CostModel CostModel) +{ + const char *vehicleprofile_name; + switch (CostModel) { + case Routing::CostModel::FASTEST: + vehicleprofile_name="car"; + m_vehicleprofile_idx=0; + break; + case Routing::CostModel::SHORTEST: + vehicleprofile_name="car_shortest"; + m_vehicleprofile_idx=1; + break; + default: + throw DBus::ErrorInvalidArgs("Invalid cost model"); + } + m_costmodel=CostModel; + m_vehicleprofile.u.vehicleprofile=NULL; + GList *vehicleprofiles=navit_get_vehicleprofiles(get_navit()); + + while (vehicleprofiles) { + struct attr name; + if (vehicleprofile_get_attr((struct vehicleprofile *)vehicleprofiles->data, attr_name, &name, NULL)) { + if ((!strcmp(name.u.str,vehicleprofile_name))) { + m_vehicleprofile.u.vehicleprofile=(struct vehicleprofile *)vehicleprofiles->data; + break; + } + } + vehicleprofiles=g_list_next(vehicleprofiles); + } + if (!m_vehicleprofile.u.vehicleprofile) + throw DBus::ErrorFailed("internal error:no vehicleprofile found"); +} + +void +RoutingObj::GetCostModel(Routing::CostModel &CostModel) +{ + CostModel=m_costmodel; +} + +void +RoutingObj::SetWaypoints(uint32_t SessionHandle, bool StartFromCurrentPosition, std::vector<Routing::WayPoint> Waypoints) +{ + if (StartFromCurrentPosition) { + if (Waypoints.size() != 1) + throw DBus::ErrorFailed("StartFromCurrentPosition is set, but Waypoint size is not 1"); + } else { + if (Waypoints.size() != 2) + throw DBus::ErrorFailed("StartFromCurrentPosition is not set, but Waypoint size is not 2"); + } + for (size_t i=0 ; i < Waypoints.size(); i++) { + if (Waypoints[i].find(Routing::WaypointElementType::LATITUDE) == Waypoints[i].end()) + throw DBus::ErrorInvalidArgs("Waypoint doesn't contain Latitude"); + if (Waypoints[i].find(Routing::WaypointElementType::LONGITUDE) == Waypoints[i].end()) + throw DBus::ErrorInvalidArgs("Waypoint doesn't contain Longitude"); + } + m_startfromcurrentposition=StartFromCurrentPosition; + m_waypoints=Waypoints; + +} + +void +RoutingObj::GetWaypoints(bool& StartFromCurrentPosition, std::vector< Routing::WayPoint >& Waypoints) +{ + StartFromCurrentPosition=m_startfromcurrentposition; + Waypoints=m_waypoints; +} + +void +RoutingObj::map_to_pcoord(Routing::WayPoint map, struct pcoord *pc) +{ + struct coord_geo g; + struct coord c; + g.lat=(map[Routing::WaypointElementType::LATITUDE]).get<double>(); + g.lng=(map[Routing::WaypointElementType::LONGITUDE]).get<double>(); + transform_from_geo(projection_mg, &g, &c); + pc->pro=projection_mg; + pc->x=c.x; + pc->y=c.y; + dbg(lvl_debug,"lat %f lon %f is 0x%x,0x%x\n",g.lat,g.lng,pc->x,pc->y); + +} + +void +RoutingObj::CalculateRoute(uint32_t SessionHandle) +{ + struct pcoord pc; + + if (!m_waypoints.size()) + throw DBus::ErrorFailed("no waipoints set"); + route_set_profile(m_route.u.route,m_vehicleprofile.u.vehicleprofile); + if (!m_startfromcurrentposition) { + route_set_destination(m_route.u.route, NULL, 0); + map_to_pcoord(m_waypoints[0], &pc); + route_set_position(m_route.u.route, &pc); + map_to_pcoord(m_waypoints[1], &pc); + } else { + struct tracking *tracking=get_tracking(); + if (tracking) + route_set_position_from_tracking(m_route.u.route, tracking, projection_mg); + map_to_pcoord(m_waypoints[0], &pc); + } + m_route_status = route_status_destination_set; + route_set_destination(m_route.u.route, &pc, 1); +} + +static bool +vector_contains(const std::vector< Routing::RouteSegmentType >& vector, Routing::RouteSegmentType val) +{ + size_t i; + for (i = 0 ; i < vector.size() ; i++) { + if (vector[i] == val) + return true; + } + return false; +} + +static void +get_map(struct coord *c, struct item *item, int is_end, const std::vector< Routing::RouteSegmentType >& valuesToReturn, Routing::RouteSegment &map) +{ + Routing::RouteSegmentType lat_key=is_end?Routing::RouteSegmentType::END_LATITUDE:Routing::RouteSegmentType::START_LATITUDE; + Routing::RouteSegmentType lon_key=is_end?Routing::RouteSegmentType::END_LONGITUDE:Routing::RouteSegmentType::START_LONGITUDE; + if (vector_contains(valuesToReturn, lat_key) || vector_contains(valuesToReturn, lon_key)) { + struct coord_geo g; + transform_to_geo(projection_mg, c, &g); + if (vector_contains(valuesToReturn, lat_key)) + map[lat_key]=(double)g.lat; + if (vector_contains(valuesToReturn, lon_key)) + map[lon_key]=g.lng; + } + if (item && (vector_contains(valuesToReturn, Routing::RouteSegmentType::DISTANCE) || vector_contains(valuesToReturn, Routing::RouteSegmentType::TIME) || vector_contains(valuesToReturn, Routing::RouteSegmentType::SPEED))) { + struct attr length, time, speed; + if (item_attr_get(item, attr_length, &length) && vector_contains(valuesToReturn, Routing::RouteSegmentType::DISTANCE)) { + map[Routing::RouteSegmentType::DISTANCE]=(double)length.u.num; + } + if (item_attr_get(item, attr_time, &time) && vector_contains(valuesToReturn, Routing::RouteSegmentType::TIME)) { + map[Routing::RouteSegmentType::TIME]=(uint32_t)((time.u.num+5)/10); + } + if (item_attr_get(item, attr_speed, &speed) && vector_contains(valuesToReturn, Routing::RouteSegmentType::SPEED)) { + map[Routing::RouteSegmentType::SPEED]=(uint32_t)speed.u.num; + } + } + if (item && vector_contains(valuesToReturn, Routing::RouteSegmentType::ROAD_NAME)) { + struct attr street_item; + if (item_attr_get(item, attr_street_item, &street_item)) { + struct map_rect *mr=map_rect_new(street_item.u.item->map, NULL); + struct item *item2=map_rect_get_item_byid(mr, street_item.u.item->id_hi, street_item.u.item->id_lo); + struct attr label; + if (item2 && item_attr_get(item2, attr_label, &label)) + map[Routing::RouteSegmentType::ROAD_NAME]=std::string(label.u.str); + map_rect_destroy(mr); + } + } +} + +void RoutingObj::GetRouteSegments(int16_t detailLevel , const std::vector< Routing::RouteSegmentType >& valuesToReturn, const uint32_t& numberOfSegments, const uint32_t& offset, uint32_t& totalNumberOfSegments, std::vector<Routing::RouteSegment>& RouteSegments) +{ + struct map *m=route_get_map(m_route.u.route); + if (!m) + throw DBus::ErrorFailed("internal error:failed to get route map"); + struct map_rect *mr=map_rect_new(m, NULL); + if (!mr) + throw DBus::ErrorFailed("internal error:failed to create route map rect"); + struct item *item; + struct coord c[128],last; + int count,i; + int pos; + bool intermediate=vector_contains(valuesToReturn, Routing::RouteSegmentType::INTERMEDIATE_POINTS); + totalNumberOfSegments=0; + while ((item=map_rect_get_item(mr))) { + if (item->type == type_street_route) { + pos=0; + if (totalNumberOfSegments >= offset && totalNumberOfSegments < offset+numberOfSegments) { + std::vector<DBus::Struct<uint16_t, double, double, double> >intermediate_points; + do { + count=item_coord_get(item, c, 128); + for (i = 0 ; i < count ; i++) { + switch (pos) { + case 0: /* last not valid */ + pos++; + break; + case 1: /* last is start coordinates */ + { + Routing::RouteSegment map; + get_map(&last, item, 0, valuesToReturn, map); + RouteSegments.push_back(map); + pos++; + } + break; + case 2: /* last is intermediate coordinates */ + if (intermediate) { + struct coord_geo g; + transform_to_geo(projection_mg, &last, &g); + DBus::Struct<uint16_t, double, double, double> point; + point._1=0; + point._2=g.lat; + point._3=g.lng; + point._4=0; + intermediate_points.push_back(point); + } + } + last=c[i]; + } + } while (count == 128); +#if 0 + if (intermediate_points.size()) { + DBus::Variant variant; + DBus::MessageIter iter=variant.writer(); + iter << intermediate_points; + RouteSegments.back()[GENIVI_NAVIGATIONCORE_INTERMEDIATE_POINTS]=variant; + } +#endif + } + totalNumberOfSegments++; + } + } + if (pos == 2) /* last is final coordinates */ + get_map(&last, NULL, 1, valuesToReturn, RouteSegments.back()); + map_rect_destroy(mr); +} + +void +RoutingObj::GetRouteOverview(uint32_t routeHandle , Routing::RouteOverview &routeOverview) +{ + struct attr destination_length, destination_time; + if (!route_get_attr(m_route.u.route,attr_destination_length, &destination_length, NULL)) + throw DBus::ErrorFailed("internal error:failed to get attribute destination_length"); + if (!route_get_attr(m_route.u.route,attr_destination_time, &destination_time, NULL)) + throw DBus::ErrorFailed("internal error:failed to get attribute destination_time"); + + routeOverview[Routing::RouteOverviewType::TOTAL_DISTANCE] = (uint32_t)destination_length.u.num; + routeOverview[Routing::RouteOverviewType::TOTAL_TIME] = (uint32_t)(destination_time.u.num/10); +} + +void +RoutingObj::GetRouteBoundingBox(NavigationTypes::Rectangle &boundingBox) +{ + struct coord_rect r; + struct coord_geo g; + bool first=true; + struct map *m=route_get_map(m_route.u.route); + struct item *item; + NavigationTypes::Coordinate2D value; + if (!m) + throw DBus::ErrorFailed("internal error:failed to get route map"); + struct map_rect *mr=map_rect_new(m, NULL); + if (!mr) + throw DBus::ErrorFailed("internal error:failed to create route map rect"); + while ((item=map_rect_get_item(mr))) { + struct coord c[128]; + int count,i; + do { + count=item_coord_get(item, c, 128); + for (i = 0 ; i < count ; i++) { + if (first) { + first=0; + r.lu=c[i]; + r.rl=c[i]; + } else + coord_rect_extend(&r, &c[i]); + } + } while (count == 128); + } + map_rect_destroy(mr); + if (first) + throw DBus::ErrorFailed("no route available"); + dbg(lvl_debug,"bounding box 0x%x,0x%x-0x%x,0x%x\n",r.lu.x,r.lu.y,r.rl.x,r.rl.y); + transform_to_geo(projection_mg, &r.lu, &g); + value.setLatitude(g.lat); + value.setLongitude(g.lng); + boundingBox.setTopLeft(value); + dbg(lvl_debug,"%f,%f\n",g.lat,g.lng); + transform_to_geo(projection_mg, &r.rl, &g); + value.setLatitude(g.lat); + value.setLongitude(g.lng); + boundingBox.setBottomRight(value); + dbg(lvl_debug,"-%f,%f\n",g.lat,g.lng); +} + +void +RoutingObj::CancelRouteCalculation(uint32_t sessionHandle) +{ + route_set_destination(m_route.u.route, NULL, 0); +} + +bool +RoutingObj::RoutePreference(Routing::PreferenceMode preferenceMode,Routing::RoutePreferenceSource preferenceSource) +{ + size_t index; + + for (index=0;index<m_route_preferences_list[m_vehicleprofile_idx].size();index++) + { + if (((m_route_preferences_list[m_vehicleprofile_idx].at(index)).getSource() == preferenceSource) && ((m_route_preferences_list[m_vehicleprofile_idx].at(index)).getMode() == preferenceMode)) + return true; + } + + return false; +} + +void +RoutingObj::SetRoutePreferences(uint32_t sessionHandle, const std::string& country, const std::vector< Routing::RoutePreference >& routePreferencesList) +{ + int idx; + struct attr flags_forward_mask,flags_reverse_mask,roadprofile,item_types,route_weight; + m_route_preferences_list[m_vehicleprofile_idx]=routePreferencesList; + struct vehicleprofile_settings *s=&m_vehicleprofile_settings[m_vehicleprofile_idx]; + + if (!s->flags_forward_mask) { + vehicleprofile_get_attr(m_vehicleprofile.u.vehicleprofile, attr_flags_forward_mask, &flags_forward_mask, NULL); + vehicleprofile_get_attr(m_vehicleprofile.u.vehicleprofile, attr_flags_reverse_mask, &flags_reverse_mask, NULL); + s->flags_forward_mask=flags_forward_mask.u.num; + s->flags_reverse_mask=flags_reverse_mask.u.num; + } + flags_forward_mask.type=attr_flags_forward_mask; + flags_reverse_mask.type=attr_flags_reverse_mask; + if (RoutePreference(Routing::PreferenceMode::AVOID, Routing::RoutePreferenceSource::TOLL_ROADS)) { + flags_forward_mask.u.num=s->flags_forward_mask | AF_TOLL; + flags_reverse_mask.u.num=s->flags_reverse_mask | AF_TOLL; + } else { + flags_forward_mask.u.num=s->flags_forward_mask; + flags_reverse_mask.u.num=s->flags_reverse_mask; + } + vehicleprofile_set_attr(m_vehicleprofile.u.vehicleprofile, &flags_forward_mask); + vehicleprofile_set_attr(m_vehicleprofile.u.vehicleprofile, &flags_reverse_mask); + struct attr_iter *iter=vehicleprofile_attr_iter_new(); + while (vehicleprofile_get_attr(m_vehicleprofile.u.vehicleprofile, attr_roadprofile, &roadprofile, iter)) { + if (roadprofile_get_attr(roadprofile.u.roadprofile, attr_item_types, &item_types, NULL)) { + int *par=NULL; + bool active=false; + switch (item_types.u.item_types[0]) { + case type_ferry: + par=&s->ferry_weight; + active=RoutePreference(Routing::PreferenceMode::AVOID, Routing::RoutePreferenceSource::FERRY); + break; + case type_highway_city: + par=&s->highway_city_weight; + active=RoutePreference(Routing::PreferenceMode::AVOID, Routing::RoutePreferenceSource::HIGHWAYS_MOTORWAYS); + break; + case type_highway_land: + par=&s->highway_land_weight; + active=RoutePreference(Routing::PreferenceMode::AVOID, Routing::RoutePreferenceSource::HIGHWAYS_MOTORWAYS); + break; + } + if (par) { + if (!*par) { + roadprofile_get_attr(roadprofile.u.roadprofile, attr_route_weight, &route_weight, NULL); + *par=route_weight.u.num; + } + route_weight.type=attr_route_weight; + route_weight.u.num=active?0:*par; + roadprofile_set_attr(roadprofile.u.roadprofile, &route_weight); + } + } + } + vehicleprofile_attr_iter_destroy(iter); + +} + +void +RoutingObj::GetRoutePreferences(const std::string& country, std::vector< Routing::RoutePreference >& roadPreferenceList) +{ + roadPreferenceList=m_route_preferences_list[m_vehicleprofile_idx]; +} + +static std::shared_ptr<RoutingServerStub> myServiceRouting; + +void +plugin_init(void) +{ + // Common API data init + std::shared_ptr < CommonAPI::Runtime > runtime = CommonAPI::Runtime::get(); + + const std::string &domain = "local"; + const std::string &instance = "Routing"; + + myServiceRouting = std::make_shared<RoutingServerStub>(); + + bool successfullyRegistered = runtime->registerService(domain, instance, myServiceRouting); + while (!successfullyRegistered) { + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + successfullyRegistered = runtime->registerService(domain, instance, myServiceRouting); + } +} diff --git a/src/navigation/navigation-core/session-server-plugin/CMakeLists.txt b/src/navigation/navigation-core/session-server-plugin/CMakeLists.txt new file mode 100644 index 0000000..bb56781 --- /dev/null +++ b/src/navigation/navigation-core/session-server-plugin/CMakeLists.txt @@ -0,0 +1,116 @@ +########################################################################### +# @licence app begin@ +# SPDX-License-Identifier: MPL-2.0 +# +# Component Name: mapmatchedposition-server-plugin +# +# Author: Philippe Colliot +# +# Copyright (C) 2015, PCA Peugeot Citroën +# +# License: +# This Source Code Form is subject to the terms of the +# Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with +# this file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# @licence end@ +########################################################################### +project(session-server-plugin) +cmake_minimum_required(VERSION 2.8) + +message(STATUS ${PROJECT_NAME}) + +set(CMAKE_VERBOSE_MAKEFILE on) +set(CMAKE_CXX_FLAGS "-Wall -std=c++0x") + + + +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/lib) +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/bin) + + +# DBus Path +if(DBUS_LIB_PATH) + message(STATUS "DBUS_LIB_PATH = " ${DBUS_LIB_PATH}) + set(DBUS_INCLUDE_DIRS ${DBUS_LIB_PATH}/include/dbus-1.0 ${DBUS_LIB_PATH}/lib/dbus-1.0/include) + set(DBUS_LIBDIR ${DBUS_LIB_PATH}/lib) + set(DBUS_LIBRARIES ${DBUS_LIB_PATH}/lib/libdbus-1.so) +else() + message(FATAL_ERROR "Please specify the path to your patched DBus library using -DDBUS_LIB_PATH=yourPath") +endif() + +# Packages +find_package(CommonAPI 3.1.5 REQUIRED) +find_package(CommonAPI-DBus 3.1.5 REQUIRED) + + +#pkg_check_modules(DBUS "dbus-1 >= 1.8.4") // #to be fixed, it doesn't work so the paths are set manually (see above) +pkg_check_modules(COMMONAPI "CommonAPI >= 3.1.5") +pkg_check_modules(COMMONAPI_DBUS "CommonAPI-DBus >= 3.1.5") +pkg_check_modules(GOBJECT gobject-2.0) +pkg_check_modules(GLIB REQUIRED glib-2.0) +pkg_check_modules(DBUS_CPP_GLIB dbus-c++-glib-1) + + +# Add the Franca files (that will generate the CommonAPI stuff) +set(COMMONAPI_GEN_DIR "${CMAKE_CURRENT_BINARY_DIR}/src-gen") +add_subdirectory(${FRANCA_DIR}/navigation/navigationcore "${CMAKE_CURRENT_BINARY_DIR}/franca") + +# Path to the generated files +set(API_VERSION_MAJOR 4) +set(API_VERSION "v${API_VERSION_MAJOR}") +set(PRJ_SRC_GEN_ROOT_PATH ${COMMONAPI_GEN_DIR}/${API_VERSION}/org/genivi) #files shared by all the APIs +set(PRJ_SRC_GEN_NAVIGATION_PATH ${PRJ_SRC_GEN_ROOT_PATH}/navigation) #files shared by the navigation APIs +set(PRJ_SRC_GEN_NAVIGATIONCORE_PATH ${PRJ_SRC_GEN_NAVIGATION_PATH}/navigationcore) #files shared by the navigationcore APIs + +# Source Files +set(FRANCA_FILE "NavigationCoreSession") +FILE(GLOB PRJ_LOCAL_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/*.cxx) +FILE(GLOB PRJ_STUB_GEN_SRCS + ${PRJ_SRC_GEN_ROOT_PATH}/*DBusStub*.cpp ${PRJ_SRC_GEN_ROOT_PATH}/*Types.cpp ${PRJ_SRC_GEN_ROOT_PATH}/*DBusDeployment.cpp ${PRJ_SRC_GEN_ROOT_PATH}/*StubDefault.cpp + ${PRJ_SRC_GEN_NAVIGATION_PATH}/*DBusStub*.cpp ${PRJ_SRC_GEN_NAVIGATION_PATH}/*Types.cpp ${PRJ_SRC_GEN_NAVIGATION_PATH}/*DBusDeployment.cpp ${PRJ_SRC_GEN_NAVIGATION_PATH}/*StubDefault.cpp + ${PRJ_SRC_GEN_NAVIGATIONCORE_PATH}/${FRANCA_FILE}DBusStub*.cpp ${PRJ_SRC_GEN_NAVIGATIONCORE_PATH}/${FRANCA_FILE}Types.cpp ${PRJ_SRC_GEN_NAVIGATIONCORE_PATH}/${FRANCA_FILE}DBusDeployment.cpp ${PRJ_SRC_GEN_NAVIGATIONCORE_PATH}/${FRANCA_FILE}StubDefault.cpp + ) +FILE(GLOB PRJ_STUB_IMPL_SRCS + ${PRJ_SRC_GEN_ROOT_PATH}/*Stub*.cpp + ${PRJ_SRC_GEN_NAVIGATION_PATH}/*Stub*.cpp + ${PRJ_SRC_GEN_NAVIGATIONCORE_PATH}/${FRANCA_FILE}Stub*.cpp + ) + +set(PRJ_SRCS ${PRJ_LOCAL_SRCS} ${PRJ_STUB_GEN_SRCS} ${PRJ_STUB_IMPL_SRCS}) + +include_directories( + ${COMMONAPI_GEN_DIR} + ${PRJ_SRC_GEN_ROOT_PATH} + ${PRJ_SRC_GEN_NAVIGATION_PATH} + ${PRJ_SRC_GEN_NAVIGATIONCORE_PATH} + ${DBUS_INCLUDE_DIRS} + ${COMMONAPI_INCLUDE_DIRS} + ${COMMONAPI_DBUS_INCLUDE_DIRS} + ${GOBJECT_INCLUDE_DIRS} + ${GLIB_INCLUDE_DIRS} + ${DBUS_CPP_GLIB_INCLUDE_DIRS} +) + +link_directories( + ${DBUS_LIBDIR} + ${COMMONAPI_LIBDIR} + ${COMMONAPI_DBUS_LIBDIR} + ${GOBJECT_LIBRARY_DIRS} + ${GLIB_LIBRARY_DIRS} + ${DBUS_CPP_GLIB_DIRS} +) + +set(LIBRARIES + ${DBUS_LIBRARIES} + ${COMMONAPI_LIBRARIES} + ${COMMONAPI_DBUS_LIBRARIES} + ${GOBJECT_LIBRARIES} + ${GLIB_LIBRARIES} + ${DBUS_CPP_GLIB_LIBRARIES} +) + +# Build service +module_add_library(genivi_navigationcore_session_server ${PRJ_SRCS}) +target_link_libraries(genivi_navigationcore_session_server ${LIBRARIES}) + diff --git a/src/navigation/navigation-core/session-server-plugin/genivi_navigationcore_session.cxx b/src/navigation/navigation-core/session-server-plugin/genivi_navigationcore_session.cxx new file mode 100644 index 0000000..880b030 --- /dev/null +++ b/src/navigation/navigation-core/session-server-plugin/genivi_navigationcore_session.cxx @@ -0,0 +1,153 @@ +/** +* @licence app begin@ +* SPDX-License-Identifier: MPL-2.0 +* +* \copyright Copyright (C) 2013-2014, PCA Peugeot Citroen +* +* \file genivi_navigationcore_session.cxx +* +* \brief This file is part of the Navit POC. +* +* \author Martin Schaller <martin.schaller@it-schaller.de> +* +* \version 1.0 +* +* This Source Code Form is subject to the terms of the +* Mozilla Public License (MPL), v. 2.0. +* If a copy of the MPL was not distributed with this file, +* You can obtain one at http://mozilla.org/MPL/2.0/. +* +* For further information see http://www.genivi.org/. +* +* List of changes: +* +* <date>, <name>, <description of change> +* +* @licence end@ +*/ +#include <dbus-c++/glib-integration.h> +#include "config.h" +#define USE_PLUGINS 1 +#include "debug.h" +#include "plugin.h" +#include "event.h" + +#include <CommonAPI/CommonAPI.hpp> +#include <CommonTypes.hpp> +#include <NavigationTypes.hpp> +#include <NavigationCoreTypes.hpp> +#include <SessionStubDefault.hpp> + +#if (!DEBUG_ENABLED) +#undef dbg +#define dbg(level,...) ; +#endif + +using namespace v4::org::genivi::navigation::navigationcore; +using namespace v4::org::genivi::navigation; +using namespace v4::org::genivi; + +class SessionServerStub : public SessionStubDefault +{ + public: + +#define MAX_SESSION_HANDLES 256 + + SessionServerStub() + { + m_version.setVersionMajor(3); + m_version.setVersionMinor(0); + m_version.setVersionMicro(0); + m_version.setDate("21-01-2014"); + } + + ~SessionServerStub(){} + + /** + * description: getVersion = This method returns the API version implemented by the server + * application + */ + void getVersion(const std::shared_ptr<CommonAPI::ClientId> _client, getVersionReply_t _reply) { + _reply(m_version); + } + + /** + * description: createSession = This method creates a new session and retrieves a handle . + */ + void createSession(const std::shared_ptr<CommonAPI::ClientId> _client, std::string _clientApp, createSessionReply_t _reply){ + dbg(lvl_debug,"enter\n"); + NavigationTypes::Handle _sessionHandle=1; + while (mp_handles[_sessionHandle]) { + _sessionHandle++; + if (_sessionHandle == MAX_SESSION_HANDLES) + throw DBus::Error("org.genivi.navigationcore.Session.Error.NoMoreSessionHandles","Out of session handles"); + } + mp_handles[_sessionHandle]=new std::string(_clientApp); + _reply(_sessionHandle); + } + + /** + * description: deleteSession = This method deletes a session and its associated resources . + */ + void deleteSession(const std::shared_ptr<CommonAPI::ClientId> _client, ::v4::org::genivi::navigation::NavigationTypes::Handle _sessionHandle, deleteSessionReply_t _reply){ + dbg(lvl_debug,"enter\n"); + if (!mp_handles[_sessionHandle]) + throw DBus::Error("org.genivi.navigationcore.Session.Error.NotAvailableSessionHandle","Session handle invalid"); + delete(mp_handles[_sessionHandle]); + mp_handles[_sessionHandle]=NULL; + fireSessionDeletedEvent(_sessionHandle); + _reply(); + } + + /** + * description: This method returns whether a given session handle is available or not (for + * example because it was deleted) . + */ + void getSessionStatus(const std::shared_ptr<CommonAPI::ClientId> _client, ::v4::org::genivi::navigation::NavigationTypes::Handle _sessionHandle, getSessionStatusReply_t _reply){ + if (mp_handles[_sessionHandle]) + _reply(NavigationTypes::SessionStatus::AVAILABLE); + else + _reply(NavigationTypes::SessionStatus::AVAILABLE); + } + + /** + * description: This method returns a list of all available sessions . + */ + void getAllSessions(const std::shared_ptr<CommonAPI::ClientId> _client, getAllSessionsReply_t _reply){ + std::vector< NavigationTypes::Session > _sessionsList; + std::map<NavigationTypes::Handle, std::string *>::const_iterator it; + for(it = mp_handles.begin(); it != mp_handles.end(); it++) { + NavigationTypes::Session session; + if (it->second) { + session.setSessionHandle(it->first); + session.setClientApp(*it->second); + _sessionsList.push_back(session); + } + + } + _reply(_sessionsList); + } + +private: + CommonTypes::Version m_version; + std::map<NavigationTypes::Handle, std::string *> mp_handles; + +}; + +void +plugin_init(void) +{ + // Common API data init + std::shared_ptr < CommonAPI::Runtime > runtime = CommonAPI::Runtime::get(); + + const std::string &domain = "local"; + const std::string &instance = "Session"; + + std::shared_ptr<SessionServerStub> myServiceSession = std::make_shared<SessionServerStub>(); + + bool successfullyRegistered = runtime->registerService(domain, instance, myServiceSession); + while (!successfullyRegistered) { + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + successfullyRegistered = runtime->registerService(domain, instance, myServiceSession); + } +} |