summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorasanoaozora <fifitaneki@hotmail.com>2016-10-02 00:07:48 +0200
committerasanoaozora <fifitaneki@hotmail.com>2016-10-02 00:07:48 +0200
commit3e116799398eda2f61c64059b34cbb01c505a1e4 (patch)
treec04577f36a3af41cf210a0317b8c5a585875cbf9
parent91a5f1c511c21533fc4ae2314ece462e42a155e9 (diff)
downloadpoi-service-3e116799398eda2f61c64059b34cbb01c505a1e4.tar.gz
some updates of fidl and plugin fix
-rw-r--r--api/franca/navigation/navigationcore/Guidance.fidl86
-rw-r--r--api/franca/navigation/navigationcore/LocationInput.fidl44
-rw-r--r--api/franca/navigation/navigationcore/NavigationCoreTypes.fidl10
-rw-r--r--api/navigation-core/genivi-navigationcore-guidance.xml2
-rw-r--r--src/navigation/navigation-core/enhancedposition-client-plugin/genivi_positioning_enhancedposition.cxx1
-rw-r--r--src/navigation/navigation-core/guidance-server-plugin/genivi_navigationcore_guidance.cxx3
-rw-r--r--test/navigation/location.xml32
-rw-r--r--test/navigation/locations.xml42
-rwxr-xr-xtest/navigation/test-address-input-capi.py408
-rwxr-xr-xtest/navigation/test-address-input.py395
10 files changed, 937 insertions, 86 deletions
diff --git a/api/franca/navigation/navigationcore/Guidance.fidl b/api/franca/navigation/navigationcore/Guidance.fidl
index 4e760e2..7c10ea0 100644
--- a/api/franca/navigation/navigationcore/Guidance.fidl
+++ b/api/franca/navigation/navigationcore/Guidance.fidl
@@ -38,13 +38,13 @@ interface Guidance {
LANE_INFO_BITMASK_LEFTUTURN = 256
}
- enumeration PromptMode extends BasicEnum { //Base 0x0040
+ enumeration PromptMode extends BasicEnum {
DISABLED_PROMPT = 65
AUTOMATIC_PROMPT = 66
MANUAL_PROMPT = 67
}
- enumeration ManeuverPhase extends BasicEnum { //Base 0x0050
+ enumeration ManeuverPhase extends BasicEnum {
CRUISE = 80
MANEUVER_APPEARED = 81
PRE_ADVICE = 82
@@ -52,12 +52,12 @@ interface Guidance {
PASSED = 84
}
- enumeration GuidanceStatus extends BasicEnum { //Base 0x0060
+ enumeration GuidanceStatus extends BasicEnum {
ACTIVE = 96
INACTIVE = 97
}
- enumeration ManeuverType extends BasicEnum { //Base 0x0070
+ enumeration ManeuverType extends BasicEnum {
STRAIGHT_ON = 112
CROSSROAD = 113
ROUNDABOUT = 114
@@ -70,7 +70,7 @@ interface Guidance {
BIFURCATION = 121
}
- enumeration ManeuverDirection extends BasicEnum { //Base 0x0080
+ enumeration ManeuverDirection extends BasicEnum {
STRAIGHT_ON = 127
LEFT = 128
SLIGHT_LEFT = 129
@@ -82,31 +82,31 @@ interface Guidance {
UTURN_LEFT = 135
}
- enumeration CalculationMode extends BasicEnum { //Base 0x0090
+ enumeration CalculationMode extends BasicEnum {
ALL_MANUAL = 144
ALL_AUTOMATIC = 145
TRAFFIC_MANUAL = 146
OFF_ROUTE_MANUAL = 147
}
- enumeration RoadProperty extends BasicEnum { //Base 0x0100
+ enumeration RoadProperty extends BasicEnum {
UNDEFINED = 256
TOLL_ROADS = 257
}
- enumeration RouteChangedCause extends BasicEnum { //Base 0x0210
+ enumeration RouteChangedCause extends BasicEnum {
TRAFFIC = 528
OFF_ROUTE = 529
MANUAL = 530
}
- enumeration ManeuverDirectionType extends BasicEnum { //Base 0x0240
+ enumeration ManeuverDirectionType extends BasicEnum {
DIRECTION = 576
EXIT_NUMBER = 577
ROAD_FORM = 578
LANE_INFO = 579
}
- enumeration LaneDivider extends BasicEnum { //Base 0x0250
+ enumeration LaneDivider extends BasicEnum {
DIVIDER_UNDEFINED = 592
DIVIDER_INTERRUPTEDLONG = 593
DIVIDER_INTERRUPTEDSHORT = 594
@@ -116,20 +116,26 @@ interface Guidance {
DIVIDER_INTERRUPTEDSOLID = 598
}
- enumeration ManeuverDataAttribute extends BasicEnum { //Base 0x260
- LENGTH = 608
- DIRECTION = 609
- EXIT_NUMBER = 610
- ROAD_FORM = 611
- LANE_INFO = 612
- LATITUDE = 613
- LONGITUDE = 614
- ALTITUDE = 615
+ enumeration RoadForm extends BasicEnum {
+ ROAD_REGULAR = 561
+ ROAD_HIGHWAY_MOTORWAY = 562
+ ROAD_FERRY = 563
+ }
+
+ enumeration ManeuverDataAttribute extends BasicEnum {
+ LENGTH = 608 //value of type UInt16, when maneuver=ROUNDABOUT, expresses the length of the route segment between the entry to and the exit from the roundabout
+ DIRECTION = 576 //value of type ManeuverDirection
+ EXIT_NUMBER = 577 //when maneuver=ROUNDABOUT, value of type UInt16 that expresses the roundabout exit number, when maneuver=HIGHWAY_EXIT, value of type String that expresses the highway exit number
+ ROAD_FORM = 578 //value of type RoadForm
+ LANE_INFO = 579 //value of type LaneInfo[]
+ COORDINATE = 613 //value of type Coordinate3D
}
union ManeuverDataValue {
ManeuverDirection enumValue
+ UInt16 uint16Value
String stringValue
+ RoadForm roadFormValue
LaneInfo[] laneInfoValue
Coordinate3D coordinate3DValue
}
@@ -138,22 +144,22 @@ interface Guidance {
ManeuverDataAttribute to ManeuverDataValue
}
- struct LaneInfo {
- UInt32 laneIndex
- ByteBuffer laneDirections
- LaneType directionToFollow
- LaneDivider divider
+ struct LaneInfo { //Note: To describe the divider on the left side of the left-most lane, use the following entry in LANE_INFO: (laneIndex=0xffffffff,laneDirections=0x00000000,directionToFollow=0x00000000,divider=type)
+ UInt32 laneIndex //number of the individual lane. Counting starts from zero, beginning at the left-most lane in the direction of travel (independent of the driving side)
+ ByteBuffer laneDirections //bitfield where each bit corresponds to a certain direction. A 1-bit indicates that the corresponding part of the lane arrow is drawn in the lane information on the street (see the lane info bitmasks)
+ LaneType directionToFollow //bitfield where each bit corresponds to a certain direction. A 1-bit indicates that the corresponding part of the lane arrow matches the direction of the corresponding maneuver (see the lane info bitmasks). At most one bit of this bitmask will be set.
+ LaneDivider divider //indicates the type of divider between the given lane and the next one to the right, in the direction of travel
}
struct WaypointStruct {
- UInt32 waypointOffset
- UInt32 travelTime
- Int32 direction
- Side side
- Int16 timeZone
- Int16 daylightSavingTime
- Boolean isDestination
- UInt16 number
+ UInt32 waypointOffset //the offset of the way point in meters from the beginning of the route
+ UInt32 travelTime //time to reach the way point in seconds
+ Int32 direction //direction of the way point in degree relatively to the North. Range [0:360]
+ Side side
+ Int16 timeZone //time zone of the way point. It is expressed as the time difference from the UTC in minutes
+ Int16 daylightSavingTime //daylight saving time of the way point. It is expressed as the time difference from the UTC in minutes
+ Boolean isDestination //if TRUE the way point is the destination
+ UInt16 number //number of the next waypoint (related to the waypoint list, first way point index is 0)
}
<**
@@ -190,6 +196,7 @@ interface Guidance {
<**
@description : startGuidance = This method starts the guidance for a given route
+ The guidanceStatus will change to ACTIVE
**>
method startGuidance {
in {
@@ -208,6 +215,7 @@ interface Guidance {
<**
@description : stopGuidance = This method stops the guidance
+ The guidanceStatus will change to INACTIVE
**>
method stopGuidance {
in {
@@ -235,6 +243,10 @@ interface Guidance {
**>
String voice
}
+ error {
+ OK
+ GUIDANCE_ERROR_VOICENOTALLOWED //the voice generation is inactive
+ }
}
<**
@@ -408,6 +420,8 @@ interface Guidance {
<**
@description : guidanceStatus = enum(INVALID,ACTIVE,INACTIVE)
+ ACTIVE means that NavigationCore is providing guidance information
+ INACTIVE means that NavigationCore is not providing guidance information
**>
GuidanceStatus guidanceStatus
@@ -426,6 +440,9 @@ interface Guidance {
<**
@description : mode = enum(INVALID,DISABLED_PROMPT,AUTOMATIC_PROMPT,MANUAL_PROMPT, ... )
+ MANUAL_PROMPT means that a client application can ask the NavigationCore to play the voice prompts
+ AUTOMATIC_PROMPT means that the voice prompts will be requested by NavigationCore automatically
+ DISABLED_PROMPT means that the client application will the voice generator component directly to play the messages (bypassing the NavigationCore)
**>
PromptMode promptMode
}
@@ -443,6 +460,9 @@ interface Guidance {
<**
@description : mode = enum(INVALID,DISABLED_PROMPT,AUTOMATIC_PROMPT,MANUAL_PROMPT, ... )
+ MANUAL_PROMPT means that a client application can ask the NavigationCore to play the voice prompts
+ AUTOMATIC_PROMPT means that the voice prompts will be requested by NavigationCore automatically
+ DISABLED_PROMPT means that the client application will the voice generator component directly to play the messages (bypassing the NavigationCore)
**>
PromptMode promptMode
}
@@ -462,6 +482,8 @@ interface Guidance {
<**
@description : guidanceStatus = enum(INVALID,ACTIVE,INACTIVE)
+ ACTIVE means that NavigationCore is providing guidance information
+ INACTIVE means that NavigationCore is not providing guidance information
**>
GuidanceStatus guidanceStatus
diff --git a/api/franca/navigation/navigationcore/LocationInput.fidl b/api/franca/navigation/navigationcore/LocationInput.fidl
index 1b57845..aff985a 100644
--- a/api/franca/navigation/navigationcore/LocationInput.fidl
+++ b/api/franca/navigation/navigationcore/LocationInput.fidl
@@ -20,31 +20,13 @@ interface LocationInput {
minor 0
}
- enumeration AddressAttribute extends GeoLocalizedEnum { //Base 0x00a0
- COUNTRY = 166
- STATE = 167
- CITY = 168
- ZIPCODE = 169
- STREET = 170
- HOUSENUMBER = 171
- CROSSING = 172
- DISTRICT = 173
- PHONENUMBER = 174
- POINAME = 175
- TOWNCENTER = 176
- LOCATION_INPUT = 177
- FULL_ADDRESS = 178
- COUNTRYCODE = 179
- HOUSENAME = 180
- POSTAL_CODE = 181
- }
enumeration SearchStatus extends BasicEnum { //Base 0x00c0
SEARCHING = 193
FINISHED = 194
}
- enumeration ValidationType extends BasicEnum { //Base 0x00d0
+ enumeration ValidationType extends BasicEnum {
OK = 208
UNKNOWN = 209
AMBIGUOUS = 210
@@ -53,6 +35,26 @@ interface LocationInput {
array AddressAttributeList of AddressAttribute
+ enumeration AddressAttribute extends GeoLocalizedEnum {
+ COUNTRY = 166 //value of type String, that identifies the country name
+ COUNTRYCODE = 179 //value of type String, ISO 3166‐1 alpha 3 country code (upper case)
+ STATE = 167
+ CITY = 168 //value of type String, that identifies the city name
+ ZIPCODE = 169
+ STREET = 170 //value of type String, that identifies the street name
+ ROAD_NUMBER = 182 //value of type String, that identifies the road number
+ HOUSENUMBER = 171 //value of type String, that identifies the house number
+ HOUSENAME = 180 //value of type String, that identifies the house name
+ CROSSING = 172 //value of type String, that identifies the crossing
+ DISTRICT = 173 //value of type String, that identifies the district name
+ PHONENUMBER = 174 //value of type String, that identifies a phone number
+ POINAME = 175 //value of type String, that identifies a POI name
+ TOWNCENTER = 176
+ LOCATION_INPUT = 177
+ FULL_ADDRESS = 178
+ POSTAL_CODE = 181
+ }
+
union AddressValue {
Int32 intValue
Double doubleValue
@@ -178,6 +180,7 @@ interface LocationInput {
<**
@description : spell = This method sends the next spell input for the current session
+ Note: when a spell is started the entries of the search are removed
**>
method spell {
in {
@@ -206,6 +209,7 @@ interface LocationInput {
<**
@description : search = This method sends the search input for the current session
+ Note: when a search is started the entries of the spell input are removed
**>
method search {
in {
@@ -262,6 +266,7 @@ interface LocationInput {
<**
@description : selectEntry = This method triggers selection of a result list entry by index
+ Note: the update of the input content will be notified in signal ContentUpdated
**>
method selectEntry {
in {
@@ -326,6 +331,7 @@ interface LocationInput {
<**
@description : reverseGeocode = This method transforms a geocoordinate into an address
+ Note: the update of the input content will be notified in signal ContentUpdated
**>
method reverseGeocode {
in {
diff --git a/api/franca/navigation/navigationcore/NavigationCoreTypes.fidl b/api/franca/navigation/navigationcore/NavigationCoreTypes.fidl
index ee411bd..61499ab 100644
--- a/api/franca/navigation/navigationcore/NavigationCoreTypes.fidl
+++ b/api/franca/navigation/navigationcore/NavigationCoreTypes.fidl
@@ -14,14 +14,14 @@ typeCollection NavigationCoreTypes {
minor 0
}
- enumeration TimeStampedEnum extends BasicEnum { //Base 0x0010
+ enumeration TimeStampedEnum extends BasicEnum {
TIMESTAMP = 16
}
- enumeration GeoLocalizedEnum extends TimeStampedEnum { //Base 0x00a0
- LATITUDE = 160
- LONGITUDE = 161
- ALTITUDE = 162
+ enumeration GeoLocalizedEnum extends TimeStampedEnum {
+ LATITUDE = 160 //value of type Double, that expresses the latitude in format %3.6f. Range[-90:+90]. Example: 48.70901
+ LONGITUDE = 161 //value of type Double, that expresses the longitude in format %3.6f. Range[-180:+180]. Example: 9.167898
+ ALTITUDE = 162 //value of type Int32, that expresses the altitude in meters
}
}
diff --git a/api/navigation-core/genivi-navigationcore-guidance.xml b/api/navigation-core/genivi-navigationcore-guidance.xml
index 3d18cb2..9fdb6c7 100644
--- a/api/navigation-core/genivi-navigationcore-guidance.xml
+++ b/api/navigation-core/genivi-navigationcore-guidance.xml
@@ -67,6 +67,8 @@
<line>kind of voice (to be defined)</line>
</doc>
</arg>
+ <arg name="error" type="i" direction="out">
+ </arg>
<error name="org.genivi.navigationcore.Guidance.Error.VoiceNotAllowed">
<doc>
<line>This error is generated if the voice generation is inactive </line>
diff --git a/src/navigation/navigation-core/enhancedposition-client-plugin/genivi_positioning_enhancedposition.cxx b/src/navigation/navigation-core/enhancedposition-client-plugin/genivi_positioning_enhancedposition.cxx
index 24d45da..1275ff7 100644
--- a/src/navigation/navigation-core/enhancedposition-client-plugin/genivi_positioning_enhancedposition.cxx
+++ b/src/navigation/navigation-core/enhancedposition-client-plugin/genivi_positioning_enhancedposition.cxx
@@ -116,7 +116,6 @@ class EnhancedPositionClientProxy
position_found=true;
}
if (position_found && !mp_priv->cb_pending) {
- printf("B %ld\n",changedValues);
event_add_timeout(0, 0, mp_priv->cb);
mp_priv->cb_pending=1;
}
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
index 42cb7d3..ac341eb 100644
--- a/src/navigation/navigation-core/guidance-server-plugin/genivi_navigationcore_guidance.cxx
+++ b/src/navigation/navigation-core/guidance-server-plugin/genivi_navigationcore_guidance.cxx
@@ -251,8 +251,9 @@ class GuidanceServerStub : public GuidanceStubDefault
* 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){
+ Guidance::setVoiceGuidanceError _error = Guidance::setVoiceGuidanceError::OK;
mp_guidance->SetVoiceGuidance(_activate,_voice);
- _reply();
+ _reply(_error);
}
/**
diff --git a/test/navigation/location.xml b/test/navigation/location.xml
index 3b9f50d..6baddc7 100644
--- a/test/navigation/location.xml
+++ b/test/navigation/location.xml
@@ -1,34 +1,10 @@
<location-set area="Switzerland extract">
<location>
-<latitude>47.367264</latitude>
-<longitude>8.550330</longitude>
+<latitude>47.415637</latitude>
+<longitude>8.614971</longitude>
<country>Switzerland</country>
<city>Zürich</city>
-<street>Schanzengasse</street>
-<number>11</number>
-</location>
-<location>
-<latitude>46.948108</latitude>
-<longitude>7.444643</longitude>
-<country>Switzerland</country>
-<city>Bern</city>
-<street>Marktgasse</street>
-<number>46</number>
-</location>
-<location>
-<latitude>46.206659</latitude>
-<longitude>6.1410842</longitude>
-<country>Switzerland</country>
-<city>Genève</city>
-<street>Rue Vallin</street>
-<number>11</number>
-</location>
-<location>
-<latitude>46.990585</latitude>
-<longitude>6.928453</longitude>
-<country>Switzerland</country>
-<city>Neuchâtel</city>
-<street>Place des Halles</street>
-<number>8</number>
+<street>In Lampitzäckern</street>
+<number>24</number>
</location>
</location-set>
diff --git a/test/navigation/locations.xml b/test/navigation/locations.xml
new file mode 100644
index 0000000..d86e5fc
--- /dev/null
+++ b/test/navigation/locations.xml
@@ -0,0 +1,42 @@
+<location-set area="Switzerland extract">
+<location>
+<latitude>47.367264</latitude>
+<longitude>8.550330</longitude>
+<country>Switzerland</country>
+<city>Zürich</city>
+<street>Schanzengasse</street>
+<number>11</number>
+</location>
+<location>
+<latitude>46.948108</latitude>
+<longitude>7.444643</longitude>
+<country>Switzerland</country>
+<city>Bern</city>
+<street>Marktgasse</street>
+<number>46</number>
+</location>
+<location>
+<latitude>46.206659</latitude>
+<longitude>6.1410842</longitude>
+<country>Switzerland</country>
+<city>Genève</city>
+<street>Rue Vallin</street>
+<number>11</number>
+</location>
+<location>
+<latitude>46.990585</latitude>
+<longitude>6.928453</longitude>
+<country>Switzerland</country>
+<city>Neuchâtel</city>
+<street>Place des Halles</street>
+<number>8</number>
+</location>
+<location>
+<latitude>47.415637</latitude>
+<longitude>8.614971</longitude>
+<country>Switzerland</country>
+<city>Zürich</city>
+<street>In Lampitzäckern</street>
+<number>24</number>
+</location>
+</location-set>
diff --git a/test/navigation/test-address-input-capi.py b/test/navigation/test-address-input-capi.py
new file mode 100755
index 0000000..0eccc2e
--- /dev/null
+++ b/test/navigation/test-address-input-capi.py
@@ -0,0 +1,408 @@
+#!/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-address-input-capi.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
+
+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))
+
+
+# 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)')
+ exit()
+ else:
+ print ('TEST FAILED (non-guidable address)')
+ exit()
+ address_index = current_address_index + 1
+ if address_index < len(COUNTRY_STRING):
+ startSearch(address_index)
+ else:
+ print('END OF THE TEST')
+ exit()
+
+
+# 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))
+
+ if current_selection_criterion == COUNTRY:
+ change_selection_criterion(CITY)
+ target_search_string = CITY_STRING[current_address_index]
+ elif current_selection_criterion == CITY:
+ change_selection_criterion(STREET)
+ target_search_string = STREET_STRING[current_address_index]
+ elif current_selection_criterion == STREET:
+ change_selection_criterion(HOUSE_NUMBER)
+ target_search_string = HOUSE_NUMBER_STRING[current_address_index]
+ elif current_selection_criterion == HOUSE_NUMBER:
+ target_search_string = ''
+
+ entered_search_string = ''
+
+ if target_search_string == '':
+ evaluate_address(address, guidable)
+ else:
+ full_string_search(handle, target_search_string)
+
+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)')
+ exit()
+ 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(content_updated_handler,
+ dbus_interface='org.genivi.navigation.navigationcore.LocationInput',
+ signal_name='contentUpdated')
+
+
+# Timeout
+def timeout():
+ print('Timeout Expired')
+ print ('\nTEST FAILED\n')
+ exit()
+
+# Exit
+def exit():
+ error=location_input_interface.deleteLocationInput(dbus.UInt32(session_handle),dbus.UInt32(location_input_handle))
+ print('Delete location input: '+str(int(error)))
+ error=session_interface.deleteSession(dbus.UInt32(session_handle))
+ print('Delete session: '+str(int(error)))
+ 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 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)
+ full_string_search(location_input_handle, target_search_string)
+
+
+session = bus.get_object('org.genivi.navigation.navigationcore.Session_Session', '/Session')
+session_interface = dbus.Interface(session, dbus_interface='org.genivi.navigation.navigationcore.Session')
+
+# Get SessionHandle
+ret = session_interface.createSession(dbus.String('test location input'))
+session_handle=ret[1]
+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
+ret = location_input_interface.createLocationInput(dbus.UInt32(session_handle))
+location_input_handle = ret[1]
+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()
diff --git a/test/navigation/test-address-input.py b/test/navigation/test-address-input.py
new file mode 100755
index 0000000..32ece96
--- /dev/null
+++ b/test/navigation/test-address-input.py
@@ -0,0 +1,395 @@
+#!/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-address-input.py
+*
+* @brief This simple test shows how the address 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
+
+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.UInt16(current_selection_criterion))
+
+
+# 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))
+
+ if current_selection_criterion == COUNTRY:
+ change_selection_criterion(CITY)
+ target_search_string = CITY_STRING[current_address_index]
+ elif current_selection_criterion == CITY:
+ change_selection_criterion(STREET)
+ target_search_string = STREET_STRING[current_address_index]
+ elif current_selection_criterion == STREET:
+ change_selection_criterion(HOUSE_NUMBER)
+ target_search_string = HOUSE_NUMBER_STRING[current_address_index]
+ elif current_selection_criterion == HOUSE_NUMBER:
+ target_search_string = ''
+ entered_search_string = ''
+ if target_search_string == '':
+ evaluate_address(address, guidable)
+ else:
+ full_string_search(handle, target_search_string)
+
+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.navigationcore.LocationInput',
+ signal_name='SearchStatus')
+
+bus.add_signal_receiver(search_result_list_handler,
+ dbus_interface='org.genivi.navigationcore.LocationInput',
+ signal_name='SearchResultList')
+
+bus.add_signal_receiver(content_updated_handler,
+ dbus_interface='org.genivi.navigationcore.LocationInput',
+ signal_name='ContentUpdated')
+
+
+# Timeout
+def timeout():
+ print 'Timeout Expired'
+ print '\nTEST FAILED\n'
+ loop.quit()
+
+def startSearch(address_index):
+ global found_exact_match
+ global available_characters
+ global target_search_string
+ global current_address_index
+ current_address_index = address_index
+ entered_search_string = ''
+ found_exact_match = 0
+ available_characters = ''
+ target_search_string = COUNTRY_STRING[current_address_index]
+
+ change_selection_criterion(COUNTRY)
+ 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
+ret = session_interface.CreateSession(dbus.String('test location input'))
+session_handle=ret[1]
+print 'Session handle = ' + str(session_handle)
+
+location_input_obj = bus.get_object('org.genivi.navigationcore.LocationInput', '/org/genivi/navigationcore')
+location_input_interface = dbus.Interface(location_input_obj, dbus_interface='org.genivi.navigationcore.LocationInput')
+
+# Get LocationInputHandle
+ret = location_input_interface.CreateLocationInput(dbus.UInt32(session_handle))
+location_input_handle = ret[1]
+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 = ''
+
+startSearch(0)
+
+# Main loop
+gobject.timeout_add(10000, timeout)
+loop = gobject.MainLoop()
+loop.run()