summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/navigation/navigation-core/CMakeLists.txt37
-rw-r--r--src/navigation/navigation-core/configuration-server-plugin/genivi_navigationcore_configuration.cxx44
-rw-r--r--src/navigation/navigation-core/locationinput-server-plugin/CMakeLists.txt116
-rw-r--r--src/navigation/navigation-core/locationinput-server-plugin/genivi_navigationcore_locationinput.cxx570
-rw-r--r--src/navigation/navigation-core/navit_genivi_navigationcore_capi.xsl63
-rwxr-xr-xtest/navigation/test-location-input-capi.py485
6 files changed, 1260 insertions, 55 deletions
diff --git a/src/navigation/navigation-core/CMakeLists.txt b/src/navigation/navigation-core/CMakeLists.txt
index c9fad47..65e2e1b 100644
--- a/src/navigation/navigation-core/CMakeLists.txt
+++ b/src/navigation/navigation-core/CMakeLists.txt
@@ -45,15 +45,29 @@ find_program(XSLTPROC xsltproc REQUIRED)
# Generate the config file for navit/navigation-core
if(NOT ${YOCTO_CONFIG})
- execute_process(
- OUTPUT_FILE ${NAVIT_BIN_DIR}/navit_genivi_navigationcore.xml
- COMMAND ${XSLTPROC} ${CMAKE_CURRENT_SOURCE_DIR}/navit_genivi_navigationcore.xsl ${navit_SOURCE_DIR}/navit/navit_shipped.xml
- )
+ if (WITH_PLUGIN_MIGRATION)
+ execute_process(
+ OUTPUT_FILE ${NAVIT_BIN_DIR}/navit_genivi_navigationcore.xml
+ COMMAND ${XSLTPROC} ${CMAKE_CURRENT_SOURCE_DIR}/navit_genivi_navigationcore_capi.xsl ${navit_SOURCE_DIR}/navit/navit_shipped.xml
+ )
+ else()
+ execute_process(
+ OUTPUT_FILE ${NAVIT_BIN_DIR}/navit_genivi_navigationcore.xml
+ COMMAND ${XSLTPROC} ${CMAKE_CURRENT_SOURCE_DIR}/navit_genivi_navigationcore.xsl ${navit_SOURCE_DIR}/navit/navit_shipped.xml
+ )
+ endif()
else()
- execute_process(
- OUTPUT_FILE ${CMAKE_CURRENT_BINARY_DIR}/navit_genivi_navigationcore.xml
- COMMAND ${XSLTPROC} ${CMAKE_CURRENT_SOURCE_DIR}/navit_genivi_navigationcore.xsl ${NAVIT_CMAKE_DIR}/../navit/navit_shipped.xml
- )
+ if (WITH_PLUGIN_MIGRATION)
+ execute_process(
+ OUTPUT_FILE ${CMAKE_CURRENT_BINARY_DIR}/navit_genivi_navigationcore.xml
+ COMMAND ${XSLTPROC} ${CMAKE_CURRENT_SOURCE_DIR}/navit_genivi_navigationcore_capi.xsl ${NAVIT_CMAKE_DIR}/../navit/navit_shipped.xml
+ )
+ else()
+ execute_process(
+ OUTPUT_FILE ${CMAKE_CURRENT_BINARY_DIR}/navit_genivi_navigationcore.xml
+ COMMAND ${XSLTPROC} ${CMAKE_CURRENT_SOURCE_DIR}/navit_genivi_navigationcore.xsl ${NAVIT_CMAKE_DIR}/../navit/navit_shipped.xml
+ )
+ endif()
endif()
add_definitions(-DPLUGIN=1)
@@ -75,12 +89,9 @@ if(${YOCTO_CONFIG})
include_directories(${STAGING_INCDIR}/navit)
endif()
-add_subdirectory(configuration-plugin)
add_subdirectory(guidance-plugin)
-add_subdirectory(locationinput-plugin)
-
add_subdirectory(mapmatchedposition-plugin)
add_subdirectory(routing-plugin)
@@ -92,5 +103,9 @@ add_subdirectory(enhancedposition-plugin)
if (WITH_PLUGIN_MIGRATION)
set(FRANCA_DIR "${API_DIR}/franca")
add_subdirectory(configuration-server-plugin)
+ add_subdirectory(locationinput-server-plugin)
+else()
+ add_subdirectory(configuration-plugin)
+ add_subdirectory(locationinput-plugin)
endif()
diff --git a/src/navigation/navigation-core/configuration-server-plugin/genivi_navigationcore_configuration.cxx b/src/navigation/navigation-core/configuration-server-plugin/genivi_navigationcore_configuration.cxx
index b16a418..88c15de 100644
--- a/src/navigation/navigation-core/configuration-server-plugin/genivi_navigationcore_configuration.cxx
+++ b/src/navigation/navigation-core/configuration-server-plugin/genivi_navigationcore_configuration.cxx
@@ -78,50 +78,6 @@ static const map32_t country_map[] = {
{"JPN","JP"},
};
-static const char *
-map_3_to_2(const map32_t *map, int len, const char *in)
-{
- int i;
- for (i = 0 ; i < len ; i++)
- if (!strcmp(map[i].c3,in))
- return map[i].c2;
- return "";
-}
-
-static const char *
-map_2_to_3(const map32_t *map, int len, const char *in)
-{
- int i;
- for (i = 0 ; i < len ; i++)
- if (!strcmp(map[i].c2,in))
- return map[i].c3;
- return "";
-}
-
-static const char *
-language_3_to_2(const char *in)
-{
- return map_3_to_2(language_map, sizeof(language_map)/sizeof(language_map[0]), in);
-}
-
-static const char *
-language_2_to_3(const char *in)
-{
- return map_2_to_3(language_map, sizeof(language_map)/sizeof(language_map[0]), in);
-}
-
-static const char *
-country_3_to_2(const char *in)
-{
- return map_3_to_2(country_map, sizeof(country_map)/sizeof(country_map[0]), in);
-}
-
-static const char *
-country_2_to_3(const char *in)
-{
- return map_2_to_3(country_map, sizeof(country_map)/sizeof(country_map[0]), in);
-}
-
class NavigationCoreConfigurationServerStub: public ConfigurationStubDefault {
public:
diff --git a/src/navigation/navigation-core/locationinput-server-plugin/CMakeLists.txt b/src/navigation/navigation-core/locationinput-server-plugin/CMakeLists.txt
new file mode 100644
index 0000000..8600ed9
--- /dev/null
+++ b/src/navigation/navigation-core/locationinput-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(locationinput-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 "LocationInput")
+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_locationinput_server ${PRJ_SRCS})
+target_link_libraries(genivi_navigationcore_locationinput_server ${LIBRARIES})
+
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
new file mode 100644
index 0000000..db45729
--- /dev/null
+++ b/src/navigation/navigation-core/locationinput-server-plugin/genivi_navigationcore_locationinput.cxx
@@ -0,0 +1,570 @@
+/**
+* @licence app begin@
+* SPDX-License-Identifier: MPL-2.0
+*
+* \copyright Copyright (C) 2013-2014, PCA Peugeot Citroen
+*
+* \file genivi_navigationcore_locationinput.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 "search.h"
+#include "callback.h"
+#include "event.h"
+#include "coord.h"
+#include "transform.h"
+
+#include <CommonAPI/CommonAPI.hpp>
+#include <CommonTypes.hpp>
+#include <NavigationTypes.hpp>
+#include <NavigationCoreTypes.hpp>
+#include <LocationInputStubDefault.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 LocationInputServerStub;
+
+class LocationInputObj
+{
+ 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;
+ LocationInputServerStub *mp_locationinput;
+ 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);
+ 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();
+};
+
+class LocationInputServerStub : public LocationInputStubDefault {
+
+public:
+ LocationInputServerStub(){
+ m_version.setVersionMajor(3);
+ m_version.setVersionMinor(0);
+ m_version.setVersionMicro(0);
+ m_version.setDate("21-01-2014");
+ }
+
+ ~LocationInputServerStub(){}
+
+ /**
+ * 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: createLocationInput = This method creates a new location input and retrieves a
+ * handle
+ */
+ void createLocationInput(const std::shared_ptr<CommonAPI::ClientId> _client, ::v4::org::genivi::navigation::NavigationTypes::Handle _sessionHandle, createLocationInputReply_t _reply){
+ uint32_t LocationInputHandle;
+ dbg(lvl_debug,"enter\n");
+ LocationInputHandle=1;
+ while (mp_handles[LocationInputHandle]) {
+ LocationInputHandle++;
+ if (LocationInputHandle == 256)
+ throw DBus::ErrorLimitsExceeded("Out of location handles");
+ }
+ mp_handles[LocationInputHandle]=new LocationInputObj(this, LocationInputHandle);
+ _reply(LocationInputHandle);
+ }
+
+ /**
+ * description: deleteLocationInput = This method deletes a location input and its associated
+ * resources
+ */
+ void deleteLocationInput(const std::shared_ptr<CommonAPI::ClientId> _client, ::v4::org::genivi::navigation::NavigationTypes::Handle _sessionHandle, ::v4::org::genivi::navigation::NavigationTypes::LocationHandle _locationInputHandle, deleteLocationInputReply_t _reply){
+ dbg(lvl_debug,"enter\n");
+ LocationInputObj *obj=mp_handles[_locationInputHandle];
+ if (!obj)
+ throw DBus::ErrorInvalidArgs("location handle invalid");
+ delete(obj);
+ mp_handles[_locationInputHandle]=NULL;
+ _reply();
+ }
+
+ /**
+ * description: getSupportedAddressAttributes = This method retrieves the supported address
+ * attributes
+ */
+ void getSupportedAddressAttributes(const std::shared_ptr<CommonAPI::ClientId> _client, getSupportedAddressAttributesReply_t _reply){
+ LocationInput::AddressAttributeList addressAttributes;
+ addressAttributes.resize(5);
+ addressAttributes[0]=LocationInput::AddressAttribute::COUNTRY;
+ addressAttributes[1]=LocationInput::AddressAttribute::CITY;
+ addressAttributes[2]=LocationInput::AddressAttribute::STREET;
+ addressAttributes[3]=LocationInput::AddressAttribute::HOUSENUMBER;
+ addressAttributes[4]=LocationInput::AddressAttribute::FULL_ADDRESS;
+ _reply(addressAttributes);
+ }
+
+ /**
+ * description: setAddress = This method sets the address to start with for the LocationInput
+ * identified by the given handle
+ */
+ void setAddress(const std::shared_ptr<CommonAPI::ClientId> _client, ::v4::org::genivi::navigation::NavigationTypes::Handle _sessionHandle, ::v4::org::genivi::navigation::NavigationTypes::LocationHandle _locationInputHandle, LocationInput::Address _address, setAddressReply_t _reply){
+ dbg(lvl_debug,"enter\n");
+ LocationInputObj *obj=mp_handles[_locationInputHandle];
+ if (!obj)
+ throw DBus::ErrorInvalidArgs("location handle invalid");
+ throw DBus::ErrorNotSupported("Not yet supported");
+ _reply();
+ }
+
+ /**
+ * description: setSelectionCriterion = This method sets the selection criterion for the
+ * current speller, search input and the corresponding result-lists for the
+ * current session
+ */
+ void setSelectionCriterion(const std::shared_ptr<CommonAPI::ClientId> _client, ::v4::org::genivi::navigation::NavigationTypes::Handle _sessionHandle, ::v4::org::genivi::navigation::NavigationTypes::LocationHandle _locationInputHandle, LocationInput::AddressAttribute _selectionCriterion, setSelectionCriterionReply_t _reply){
+ dbg(lvl_debug,"enter\n");
+ LocationInputObj *obj=mp_handles[_locationInputHandle];
+ if (!obj)
+ throw DBus::ErrorInvalidArgs("location handle invalid");
+ obj->SetSelectionCriterion(_sessionHandle, _selectionCriterion);
+ _reply();
+ }
+
+ /**
+ * description: spell = This method sends the next spell input for the current session
+ */
+ void spell(const std::shared_ptr<CommonAPI::ClientId> _client, ::v4::org::genivi::navigation::NavigationTypes::Handle _sessionHandle, ::v4::org::genivi::navigation::NavigationTypes::LocationHandle _locationInputHandle, std::string _inputCharacter, uint16_t _maxWindowSize, spellReply_t _reply){
+ LocationInputObj *obj=mp_handles[_locationInputHandle];
+ if (!obj)
+ throw DBus::ErrorInvalidArgs("location handle invalid");
+ obj->Spell(_sessionHandle, _inputCharacter, _maxWindowSize);
+ _reply();
+ }
+
+ /**
+ * description: search = This method sends the search input for the current session
+ */
+ void search(const std::shared_ptr<CommonAPI::ClientId> _client, ::v4::org::genivi::navigation::NavigationTypes::Handle _sessionHandle, ::v4::org::genivi::navigation::NavigationTypes::LocationHandle _locationInputHandle, std::string _inputString, uint16_t _maxWindowSize, searchReply_t _reply){
+ dbg(lvl_debug,"enter\n");
+ LocationInputObj *obj=mp_handles[_locationInputHandle];
+ if (!obj)
+ throw DBus::ErrorInvalidArgs("location handle invalid");
+ obj->Search(_sessionHandle, _inputString, _maxWindowSize);
+ _reply();
+ }
+
+ /**
+ * description: requestListUpdate = This method sends a request for more list elements for the
+ * current session
+ */
+ void requestListUpdate(const std::shared_ptr<CommonAPI::ClientId> _client, ::v4::org::genivi::navigation::NavigationTypes::Handle _sessionHandle, ::v4::org::genivi::navigation::NavigationTypes::LocationHandle _locationInputHandle, uint16_t _offset, uint16_t _maxWindowSize, requestListUpdateReply_t _reply){
+ LocationInputObj *obj=mp_handles[_locationInputHandle];
+ if (!obj)
+ throw DBus::ErrorInvalidArgs("location handle invalid");
+
+ obj->RequestListUpdate(_sessionHandle, _offset, _maxWindowSize);
+ _reply();
+ }
+
+ /**
+ * description: selectEntry = This method triggers selection of a result list entry by index
+ */
+ void selectEntry(const std::shared_ptr<CommonAPI::ClientId> _client, ::v4::org::genivi::navigation::NavigationTypes::Handle _sessionHandle, ::v4::org::genivi::navigation::NavigationTypes::LocationHandle _locationInputHandle, uint16_t _index, selectEntryReply_t _reply){
+ dbg(lvl_debug,"enter\n");
+ LocationInputObj *obj=mp_handles[_locationInputHandle];
+ if (!obj)
+ throw DBus::ErrorInvalidArgs("location handle invalid");
+ obj->SelectEntry(_sessionHandle, _index);
+ _reply();
+ }
+
+ /**
+ * description: getEntry = This method synchronously gets the address for the given result list
+ * entry
+ */
+ void getEntry(const std::shared_ptr<CommonAPI::ClientId> _client, ::v4::org::genivi::navigation::NavigationTypes::LocationHandle _locationInputHandle, uint16_t _index, getEntryReply_t _reply){
+ LocationInput::Address ret;
+ LocationInputObj *obj=mp_handles[_locationInputHandle];
+ if (!obj)
+ throw DBus::ErrorInvalidArgs("location handle invalid");
+ obj->GetEntry(_index, ret);
+ _reply(ret);
+ }
+
+ /**
+ * description: validateAddress = This method validates an address from different sources than
+ * Navigation
+ */
+ void validateAddress(const std::shared_ptr<CommonAPI::ClientId> _client, ::v4::org::genivi::navigation::NavigationTypes::Handle _sessionHandle, ::v4::org::genivi::navigation::NavigationTypes::LocationHandle _locationInputHandle, LocationInput::Address _inputAddress, validateAddressReply_t _reply){
+ LocationInputObj *obj=mp_handles[_locationInputHandle];
+ if (!obj)
+ throw DBus::ErrorInvalidArgs("location handle invalid");
+ obj->ValidateAddress(_sessionHandle, _inputAddress);
+ _reply();
+ }
+
+ /**
+ * description: reverseGeocode = This method transforms a geocoordinate into an address
+ */
+ void reverseGeocode(const std::shared_ptr<CommonAPI::ClientId> _client, ::v4::org::genivi::navigation::NavigationTypes::Handle _sessionHandle, ::v4::org::genivi::navigation::NavigationTypes::LocationHandle _locationInputHandle, ::v4::org::genivi::navigation::NavigationTypes::Coordinate2D _coordinate, reverseGeocodeReply_t _reply){
+ throw DBus::ErrorNotSupported("Not yet supported");
+ }
+
+private:
+ CommonTypes::Version m_version;
+ std::map<uint32_t, LocationInputObj *> mp_handles;
+
+};
+
+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 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;
+}
+
+void
+LocationInputObj::SetSelectionCriterion(NavigationTypes::Handle SessionHandle, LocationInput::AddressAttribute SelectionCriterion)
+{
+ m_criterion=SelectionCriterion;
+ switch(m_criterion) {
+ case LocationInput::AddressAttribute::COUNTRY:
+ m_search.type=attr_country_name;
+ break;
+ case LocationInput::AddressAttribute::CITY:
+ m_search.type=attr_town_name;
+ break;
+ case LocationInput::AddressAttribute::STREET:
+ m_search.type=attr_street_name;
+ break;
+ case LocationInput::AddressAttribute::HOUSENUMBER:
+ 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;
+ 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);
+
+ 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);
+}
+
+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);
+
+}
+
+void
+LocationInputObj::RequestListUpdate(NavigationTypes::Handle sessionHandle, const uint16_t& offset, uint16_t maxWindowSize)
+{
+ //for the time being, maxWindowSize is not used, the size is set during the Spell or the Search
+ //note that it gets all the results in one shot (to be improved!), per bunch of maxWindowSize data
+ //not really what is specified..
+ //offset is supposed to be n*maxWindowSize in that case
+
+ if (m_windowsize > 0)
+ {
+ int i = offset/m_windowsize;
+ int shift = offset%m_windowsize;
+ uint16_t window=m_data[i].size();
+ mp_locationinput->fireSearchResultListEvent(m_handle, m_count, (offset-shift), window, m_data[i]);
+ }
+}
+
+void
+LocationInputObj::SelectEntry(const NavigationTypes::Handle &SessionHandle, const uint32_t& Index)
+{
+ LocationInput::Address *res=NULL;
+ std::vector<LocationInput::AddressAttribute> next;
+ std::size_t window=0;
+ 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) {
+ case LocationInput::AddressAttribute::COUNTRY:
+ next.push_back(LocationInput::AddressAttribute::COUNTRY);
+ next.push_back(LocationInput::AddressAttribute::CITY);
+ break;
+ case LocationInput::AddressAttribute::CITY:
+ next.push_back(LocationInput::AddressAttribute::COUNTRY);
+ next.push_back(LocationInput::AddressAttribute::CITY);
+ next.push_back(LocationInput::AddressAttribute::STREET);
+ 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;
+ }
+ if (res->find(LocationInput::AddressAttribute::LATITUDE) != res->end())
+ 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;
+ }
+}
+
+void
+LocationInputObj::Idle(void)
+{
+ dbg(lvl_debug,"enter\n");
+ mp_locationinput->fireSearchStatusEvent(m_handle, LocationInput::SearchStatus::SEARCHING);
+ 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))) {
+ LocationInput::Address entry;
+ 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);
+ 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);
+ 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);
+ 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);
+ 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++;
+ }
+
+ // 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
+ 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) {
+ mp_locationinput->fireSpellResultEvent(m_handle, unique, next, false);
+ 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();
+
+}
+
+static void
+LocationInputObj_Idle(LocationInputObj *obj)
+{
+ obj->Idle();
+}
+
+void
+LocationInputObj::GetEntry(uint16_t index, LocationInput::Address &entry)
+{
+}
+
+void
+LocationInputObj::ValidateAddress(NavigationTypes::Handle sessionHandle, const LocationInput::Address &inputAddress)
+{
+}
+
+LocationInputObj::LocationInputObj(LocationInputServerStub *locationinput, uint32_t handle)
+{
+ mp_locationinput=locationinput;
+ 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);
+}
+
+LocationInputObj::~LocationInputObj()
+{
+ IdleStop();
+ callback_destroy(m_callback);
+ g_free(m_search.u.str);
+ search_list_destroy(m_sl);
+}
+
+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 = "LocationInput";
+
+ std::shared_ptr<LocationInputServerStub> myServiceLocationInput = std::make_shared<LocationInputServerStub>();
+
+ bool successfullyRegistered = runtime->registerService(domain, instance, myServiceLocationInput);
+ while (!successfullyRegistered) {
+ std::this_thread::sleep_for(std::chrono::milliseconds(100));
+ successfullyRegistered = runtime->registerService(domain, instance, myServiceLocationInput);
+ }
+}
diff --git a/src/navigation/navigation-core/navit_genivi_navigationcore_capi.xsl b/src/navigation/navigation-core/navit_genivi_navigationcore_capi.xsl
new file mode 100644
index 0000000..74cc2bc
--- /dev/null
+++ b/src/navigation/navigation-core/navit_genivi_navigationcore_capi.xsl
@@ -0,0 +1,63 @@
+<?xml version="1.0"?>
+<!-- ************************************************************************
+* Component Name: Navit POC
+* Author: Martin Schaller <martin.schaller@it-schaller.de>
+*
+* Copyright (C) 2012, GENIVI Alliance, Inc.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License version 2 as
+* published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+************************************************************************ -->
+<xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xi="http://www.w3.org/2001/XInclude">
+ <xsl:template match="/config/plugins/plugin[1]" priority="1" >
+ <xsl:copy><xsl:apply-templates select="@*|node()"/></xsl:copy>
+ <xsl:text>&#x0A; </xsl:text>
+ <plugin path="../../navigation-core/configuration-server-plugin/.libs/libgenivi_navigationcore_configuration_server.so" ondemand="no"/>
+ <xsl:text>&#x0A; </xsl:text>
+ <plugin path="../../navigation-core/locationinput-server-plugin/.libs/libgenivi_navigationcore_locationinput_server.so" ondemand="no"/>
+ <xsl:text>&#x0A; </xsl:text>
+ <plugin path="../../navigation-core/routing-plugin/.libs/libgenivi_navigationcore_routing.so" ondemand="no"/>
+ <xsl:text>&#x0A; </xsl:text>
+ <plugin path="../../navigation-core/session-plugin/.libs/libgenivi_navigationcore_session.so" ondemand="no"/>
+ <xsl:text>&#x0A; </xsl:text>
+ <plugin path="../../navigation-core/guidance-plugin/.libs/libgenivi_navigationcore_guidance.so" ondemand="no"/>
+ <xsl:text>&#x0A; </xsl:text>
+ <plugin path="../../navigation-core/mapmatchedposition-plugin/.libs/libgenivi_navigationcore_mapmatchedposition.so" ondemand="no"/>
+ <xsl:text>&#x0A; </xsl:text>
+ <plugin path="../../navigation-core/enhancedposition-plugin/.libs/libgenivi_positioning_enhancedposition.so" ondemand="no"/>
+ <xsl:text>&#x0A; </xsl:text>
+ <plugin path="../../poi-cam/.libs/libgenivi_poiservice_cam_navit.so" ondemand="no"/>
+ </xsl:template>
+ <xsl:template match="/config/plugins/plugin">
+ <xsl:copy><xsl:apply-templates select="@*|node()"/></xsl:copy>
+ </xsl:template>
+ <xsl:template match="/config/navit">
+ <xsl:copy><xsl:attribute name="flags">3</xsl:attribute><xsl:apply-templates select="@*|node()"/></xsl:copy>
+ </xsl:template>
+ <xsl:template match="/config/navit/graphics">
+ <xsl:copy><xsl:attribute name="enabled">no</xsl:attribute><xsl:apply-templates select="@*|node()"/></xsl:copy>
+ </xsl:template>
+ <xsl:template match="/config/navit/gui">
+ <xsl:copy><xsl:attribute name="enabled">no</xsl:attribute><xsl:apply-templates select="@*[not(name()='enabled')]|node()"/></xsl:copy>
+ </xsl:template>
+ <xsl:template match="/config/navit/vehicle[@name='Local GPS']">
+ <xsl:copy><xsl:attribute name="enabled">no</xsl:attribute><xsl:apply-templates select="@*[not(name()='enabled')]|node()"/></xsl:copy>
+ </xsl:template>
+ <xsl:template match="/config/navit/vehicle[@name='Demo']">
+ <vehicle name="EnhancedPosition" profilename="car" active="yes" source="enhancedposition://"/>
+ <xsl:text>&#x0A; </xsl:text>
+ <xsl:copy><xsl:attribute name="active">no</xsl:attribute><xsl:apply-templates select="@*[not(name()='enabled' or name()='active')]|node()"/></xsl:copy>
+ </xsl:template>
+ <xsl:template match="@*|node()"><xsl:copy><xsl:apply-templates select="@*|node()"/></xsl:copy></xsl:template>
+</xsl:transform>
diff --git a/test/navigation/test-location-input-capi.py b/test/navigation/test-location-input-capi.py
new file mode 100755
index 0000000..5f2f9fc
--- /dev/null
+++ b/test/navigation/test-location-input-capi.py
@@ -0,0 +1,485 @@
+#!/usr/bin/python
+# -*- coding: latin-1 -*-
+
+"""
+**************************************************************************
+* @licence app begin@
+* SPDX-License-Identifier: MPL-2.0
+*
+* @copyright Copyright (C) 2014, Alpine Electronics R&D Europe GmbH
+*
+* @file test-location-input.py
+*
+* @brief This simple test shows how the location input
+* could be easily tested using a python script
+*
+* @author Stephan Wiehr <stephan.wiehr@alpine.de>
+* @author Philippe Colliot <philippe.colliot@mpsa.com>
+*
+* @version 1.1
+*
+* 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/.
+* List of changes:
+* 04-02-2016, Philippe Colliot, Update to the new API ('i' for enumerations and 'yv' for variants), add status handler
+*
+* @licence end@
+**************************************************************************
+"""
+
+import dbus
+import gobject
+import dbus.mainloop.glib
+from xml.dom.minidom import parse
+import xml.dom.minidom
+import argparse
+import sys
+import errno
+#import pdb;pdb.set_trace()
+
+
+# constants as defined in the Navigation API
+LATITUDE = 0x00a0
+LONGITUDE = 0x00a1
+ALTITUDE = 0x00a2
+FULL_ADDRESS = 0x00b2
+COUNTRY = 0x00a6
+STATE = 0x00a7
+CITY = 0x00a8
+ZIPCODE = 0x00a9
+STREET = 0x00aa
+HOUSE_NUMBER = 0x00ab
+CROSSING = 0x00ac
+DISTRICT = 0x00ad
+PHONE_NUMBER = 0x00ae
+POI_NAME = 0x00af
+TOWN_CENTER = 0x00b0
+FINISHED = 0x00c2
+
+# List of addresses
+COUNTRY_STRING = list()
+CITY_STRING = list()
+STREET_STRING = list()
+HOUSE_NUMBER_STRING = list()
+
+# Default size of the list
+WINDOW_SIZE = 20
+
+# Search mode (0 = Spell, 1 = Full string search)
+country_search_mode = 1
+city_search_mode = 0
+street_search_mode = 1 #set to full because of a bug to be fixed in the plug-in
+house_number_search_mode = 1
+
+print '\n--------------------------\n' + \
+ 'LocationInput Test' + \
+ '\n--------------------------\n'
+
+parser = argparse.ArgumentParser(description='Location input Test for navigation PoC and FSA.')
+parser.add_argument('-l','--loc',action='store', dest='locations', help='List of locations in xml format')
+parser.add_argument("-v", "--verbose", action='store_true',help='print the whole log messages')
+args = parser.parse_args()
+
+if args.locations == None:
+ print('location file is missing')
+ sys.exit(1)
+else:
+ try:
+ DOMTree = xml.dom.minidom.parse(args.locations)
+ except OSError as e:
+ if e.errno == errno.ENOENT:
+ print('file not exists')
+ sys.exit(1)
+ location_set = DOMTree.documentElement
+
+print("Area : %s" % location_set.getAttribute("area"))
+
+locations = location_set.getElementsByTagName("location")
+
+for location in location_set.getElementsByTagName("location"):
+ COUNTRY_STRING.append(location.getElementsByTagName("country")[0].childNodes[0].data)
+ CITY_STRING.append(location.getElementsByTagName("city")[0].childNodes[0].data)
+ STREET_STRING.append(location.getElementsByTagName("street")[0].childNodes[0].data)
+ #HOUSE_NUMBER_STRING.append(location.getElementsByTagName("number")[0].childNodes[0].data)
+ HOUSE_NUMBER_STRING.append('') #there's a bug in the navigation core when the house number doesn't exist, so deactivated
+
+if __name__ == '__main__':
+ dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
+
+# connect to session bus
+bus = dbus.SessionBus()
+
+def vprint(text):
+ if args.verbose:
+ print(text)
+
+# Turn selection criteria values to their corresponding string description
+def selection_criterion_to_string(selection_criterion):
+ return_value = ''
+ if selection_criterion == LATITUDE:
+ return_value += 'Latitude'
+ elif selection_criterion == LONGITUDE:
+ return_value += 'Longitude'
+ elif selection_criterion == COUNTRY:
+ return_value += 'Country'
+ elif selection_criterion == STATE:
+ return_value += 'State'
+ elif selection_criterion == CITY:
+ return_value += 'City'
+ elif selection_criterion == TOWN_CENTER:
+ return_value += 'City center'
+ elif selection_criterion == ZIPCODE:
+ return_value += 'ZipCode'
+ elif selection_criterion == STREET:
+ return_value += 'Street'
+ elif selection_criterion == HOUSE_NUMBER:
+ return_value += 'House number'
+ elif selection_criterion == CROSSING:
+ return_value += 'Crossing'
+ elif selection_criterion == FULL_ADDRESS:
+ return_value += 'Full address'
+ else:
+ return_value += str(selection_criterion)
+
+ return return_value
+
+
+# Prepare a dictionary array for pretty printing
+
+def dictionary_array_to_string(dict_array, linefeed, offset=0):
+ return_value = ''
+ i = offset
+ for item in dict_array:
+ return_value += str(i) + '. ' + unicode(dictionary_to_string(item))
+ if i < offset + len(dict_array) - 1:
+ return_value += linefeed
+ i += 1
+
+ return return_value
+
+
+# Prepare a dictionary for pretty printing
+# NB: the value is supposed to be [UInt8, Variant], according to the DBus '(yv)', used by CommonAPI
+def dictionary_to_string(dictionary):
+ return_value = ''
+ i = 0
+ for key in dictionary.keys():
+ value = dictionary[key][1]
+ return_value += selection_criterion_to_string(key) + ' = ' + unicode(value)
+ i += 1
+ if i < len(dictionary):
+ return_value += ', '
+
+ return return_value
+
+
+# Prepare a selection criteria array for pretty printing
+
+def selection_criteria_array_to_string(selection_criterion_array):
+ return_value = ''
+ i = 0
+ for item in selection_criterion_array:
+ return_value += selection_criterion_to_string(item)
+ i += 1
+ if i < len(selection_criterion_array):
+ return_value += ', '
+
+ return return_value
+
+
+def print_current_context():
+ vprint('\tACTIVE CONTEXT: selection criterion = ' + selection_criterion_to_string(current_selection_criterion) + \
+ ', search string = \'' + entered_search_string + '\'')
+
+
+def change_selection_criterion(selection_criterion):
+ global current_selection_criterion
+
+ current_selection_criterion = selection_criterion
+ location_input_interface.setSelectionCriterion(dbus.UInt32(session_handle), dbus.UInt32(location_input_handle),
+ dbus.Int32(current_selection_criterion))
+
+
+# Spell search
+def spell_search(handle, entered_string, search_string, valid_characters, first=0):
+ global entered_search_string
+
+ vprint('-> SpellSearch - entered \'' + entered_string + '\' target \'' + search_string + '\'')
+
+ if unicode(search_string) != unicode(entered_string):
+ found = unicode(search_string).lower().find(unicode(entered_string).lower())
+ if found == 0:
+ is_valid = -1
+ if first == 0:
+ spell_character = search_string[len(entered_string)]
+ is_valid = valid_characters.find(spell_character)
+ else:
+ spell_character=''
+ is_valid = 0
+ if is_valid != -1:
+ entered_search_string = entered_string + spell_character
+ vprint('\nACTION: Spell search, selection criterion = ' + \
+ selection_criterion_to_string(current_selection_criterion) + ', trying \'' + spell_character + \
+ '\'')
+ location_input_interface.spell(dbus.UInt32(session_handle), dbus.UInt32(handle),
+ dbus.String(spell_character), dbus.UInt16(20))
+ else:
+ print 'TEST FAILED (Target character can not be entered)'
+ loop.quit()
+ else:
+ print 'TEST FAILED (Unexpected completion)'
+ loop.quit()
+ else:
+ print 'Full spell match'
+
+
+# Full string search
+def full_string_search(handle, search_string):
+ global entered_search_string
+ global found_exact_match
+
+ entered_search_string = search_string
+ found_exact_match = 1 # Force exact match for full string search
+ vprint('\nACTION: Full string search, selection criterion = ' + \
+ selection_criterion_to_string(current_selection_criterion) + ', trying \'' + search_string + '\'')
+ location_input_interface.search(dbus.UInt32(session_handle), dbus.UInt32(handle), dbus.String(search_string),
+ dbus.UInt16(20))
+
+
+def evaluate_address(address, guidable):
+ test_passed = 0
+ print '\nAddress complete!\nEvaluating...'
+ if COUNTRY_STRING[current_address_index] == '':
+ test_passed = 1
+ elif address[COUNTRY][1] == COUNTRY_STRING[current_address_index]:
+ print 'Country\t\t\t-> ok (' + address[COUNTRY][1] + ')'
+ if CITY_STRING[current_address_index] == '':
+ test_passed = 1
+ elif address[CITY][1] == CITY_STRING[current_address_index]:
+ print 'City\t\t\t-> ok (' + address[CITY][1] + ')'
+ if STREET_STRING[current_address_index] == '':
+ test_passed = 1
+ elif address[STREET][1] == STREET_STRING[current_address_index]:
+ print 'Street\t\t\t-> ok (' + address[STREET][1] + ')'
+ if HOUSE_NUMBER_STRING[current_address_index] == '':
+ test_passed = 1
+ elif address[HOUSE_NUMBER][1] == HOUSE_NUMBER_STRING[current_address_index]:
+ print 'House number\t-> ok (' + address[HOUSE_NUMBER][1] + ')'
+ test_passed = 1
+
+ if guidable == 1:
+ if test_passed == 1:
+ print 'TEST PASSED'
+ else:
+ print 'TEST FAILED (wrong address)'
+ loop.quit()
+ else:
+ print 'TEST FAILED (non-guidable address)'
+ loop.quit()
+ address_index = current_address_index + 1
+ if address_index < len(COUNTRY_STRING):
+ startSearch(address_index)
+ else:
+ print 'END OF THE TEST'
+ loop.quit()
+
+
+# Signal receiver
+
+# Handler for ContentUpdated callback
+
+def search_status_handler(handle,status):
+ vprint('\n::Search status ' + str(int(status)))
+ if status == FINISHED:
+ location_input_interface.requestListUpdate(dbus.UInt32(session_handle), dbus.UInt32(handle),
+ dbus.UInt16(0),
+ dbus.UInt16(WINDOW_SIZE))
+
+
+def content_updated_handler(handle, guidable, available_selection_criteria, address):
+ global target_search_string
+ global entered_search_string
+
+ vprint('\n::ContentUpdated for LocationInputHandle ' + str(int(handle)))
+ print_current_context()
+ vprint('\tGuidable = ' + str(guidable))
+ vprint('\tAvailable selection criteria = ' + selection_criteria_array_to_string(available_selection_criteria))
+ vprint('\tADDRESS: '+dictionary_to_string(address))
+
+ search_mode = -1
+
+ if current_selection_criterion == COUNTRY:
+ change_selection_criterion(CITY)
+ target_search_string = CITY_STRING[current_address_index]
+ search_mode = city_search_mode
+ elif current_selection_criterion == CITY:
+ change_selection_criterion(STREET)
+ target_search_string = STREET_STRING[current_address_index]
+ search_mode = street_search_mode
+ elif current_selection_criterion == STREET:
+ change_selection_criterion(HOUSE_NUMBER)
+ target_search_string = HOUSE_NUMBER_STRING[current_address_index]
+ search_mode = house_number_search_mode
+ elif current_selection_criterion == HOUSE_NUMBER:
+ target_search_string = ''
+
+ entered_search_string = ''
+
+ if target_search_string == '':
+ evaluate_address(address, guidable)
+ elif search_mode == 0:
+ spell_search(handle, entered_search_string, target_search_string, '', 1)
+ elif search_mode == 1:
+ full_string_search(handle, target_search_string)
+ else:
+ print '\nTEST FAILED (Invalid search mode)'
+ loop.quit()
+
+# Handler for SpellResult callback
+def spell_result_handler(handle, unique_string, valid_characters, full_match):
+ global entered_search_string
+ global spell_next_character
+ global found_exact_match
+ global available_characters
+
+ vprint('\n::SpellResult for LocationInputHandle '+str(int(handle)))
+ if unique_string != entered_search_string:
+ vprint('\tAUTOCOMPLETE: \'' + entered_search_string + '\' -> \'' + unique_string + '\'')
+ entered_search_string = unique_string
+ available_characters = valid_characters
+ print_current_context()
+ vprint('\tUnique string = \''+unique_string+'\'')
+ vprint('\tValid Characters = \''+valid_characters+'\'')
+ vprint('\tFull Match = '+str(full_match))
+
+ if len(valid_characters) == 1:
+ if unicode(valid_characters[0]) == u'\x08':
+ print '\nTEST FAILED (Dead end spelling)'
+ loop.quit()
+
+ if unicode(entered_search_string) == unicode(target_search_string):
+ found_exact_match = 1
+
+ spell_next_character = 1
+
+
+# Handler for SearchResultList callback
+
+def search_result_list_handler(handle, total_size, window_offset, window_size, result_list_window):
+ global spell_next_character
+ global found_exact_match
+
+ vprint('\n::SearchResultList for LocationInputHandle ' + str(int(handle)))
+ print_current_context()
+ vprint('\tTotal size = ' + str(int(total_size)) + ', Window offset = ' + str(int(window_offset)) + \
+ ', Window size = ' + str(int(window_size)))
+ vprint('\t' + dictionary_array_to_string(result_list_window, '\n\t', window_offset))
+
+ if found_exact_match == 1:
+ found_exact_match = 0
+ i = 0
+ for address in result_list_window:
+ if unicode(address[current_selection_criterion][1]) == target_search_string:
+ vprint('\nACTION: Found exact match, selecting \''+unicode(address[current_selection_criterion][1]) + \
+ '\' (Session '+str(int(session_handle)) + ' LocationInputHandle ' + str(int(handle))+')')
+ location_input_interface.selectEntry(dbus.UInt32(session_handle), dbus.UInt32(handle), dbus.UInt16(i))
+ break
+ i += 1
+ if i == window_size:
+ vprint('\nACTION: Found exact match, searching in next page (Session '+str(int(session_handle)) +\
+ ' LocationInputHandle ' + str(int(handle))+')')
+ location_input_interface.requestListUpdate(dbus.UInt32(session_handle), dbus.UInt32(handle),
+ dbus.UInt16(window_offset + window_size),
+ dbus.UInt16(window_size))
+ elif total_size == 1:
+ selection_name = result_list_window[0][current_selection_criterion]
+ if selection_name[1] == target_search_string:
+ vprint('\nACTION: Single entry list, selecting \'' + selection_name[1] + \
+ '\' (Session '+str(int(session_handle)) + ' LocationInputHandle ' + str(int(handle))+')')
+ location_input_interface.selectEntry(dbus.UInt32(session_handle), dbus.UInt32(handle), dbus.UInt16(0))
+ else:
+ print '\nTEST FAILED (Unexpected single result list)'
+ loop.quit()
+ elif spell_next_character == 1:
+ spell_next_character = 0
+ spell_search(handle, entered_search_string, target_search_string, available_characters)
+
+
+# add signal receiver
+bus.add_signal_receiver(search_status_handler,
+ dbus_interface='org.genivi.navigation.navigationcore.LocationInput',
+ signal_name='searchStatus')
+
+bus.add_signal_receiver(search_result_list_handler,
+ dbus_interface='org.genivi.navigation.navigationcore.LocationInput',
+ signal_name='searchResultList')
+
+bus.add_signal_receiver(spell_result_handler,
+ dbus_interface='org.genivi.navigation.navigationcore.LocationInput',
+ signal_name='spellResult')
+
+bus.add_signal_receiver(content_updated_handler,
+ dbus_interface='org.genivi.navigation.navigationcore.LocationInput',
+ signal_name='contentUpdated')
+
+
+# Timeout
+def timeout():
+ print 'Timeout Expired'
+ print '\nTEST FAILED\n'
+ loop.quit()
+
+def startSearch(address_index):
+ global entered_search_string
+ global spell_next_character
+ global found_exact_match
+ global available_characters
+ global target_search_string
+ global country_search_mode
+ global current_address_index
+ current_address_index = address_index
+ entered_search_string = ''
+ spell_next_character = 0
+ found_exact_match = 0
+ available_characters = ''
+ target_search_string = COUNTRY_STRING[current_address_index]
+
+ change_selection_criterion(COUNTRY)
+ if country_search_mode == 0:
+ spell_search(location_input_handle, entered_search_string, target_search_string, available_characters, 1)
+ elif country_search_mode == 1:
+ full_string_search(location_input_handle, target_search_string)
+
+
+session = bus.get_object('org.genivi.navigationcore.Session', '/org/genivi/navigationcore')
+session_interface = dbus.Interface(session, dbus_interface='org.genivi.navigationcore.Session')
+
+# Get SessionHandle
+session_handle = session_interface.CreateSession(dbus.String('test location input'))
+print 'Session handle = ' + str(session_handle)
+
+location_input_obj = bus.get_object('org.genivi.navigation.navigationcore.LocationInput_LocationInput', '/LocationInput')
+location_input_interface = dbus.Interface(location_input_obj, dbus_interface='org.genivi.navigation.navigationcore.LocationInput')
+# Get LocationInputHandle
+location_input_handle = location_input_interface.createLocationInput(dbus.UInt32(session_handle))
+print 'LocationInput handle = ' + str(location_input_handle)
+
+attributes = location_input_interface.getSupportedAddressAttributes()
+print 'Initially supported address attributes = ' + selection_criteria_array_to_string(attributes)
+
+# Configuration
+current_address_index = 0
+entered_search_string = ''
+spell_next_character = 0
+found_exact_match = 0
+available_characters = ''
+target_search_string = ''
+current_selection_criterion = 0
+
+startSearch(0)
+
+# Main loop
+gobject.timeout_add(10000, timeout)
+loop = gobject.MainLoop()
+loop.run()