[Merge] lp:~thomas-voss/location-service/add_controller_and_service_configuration into lp:location-service
Manuel de la Peña
manuel.delapena at canonical.com
Wed Jun 25 15:12:53 UTC 2014
Review: Approve
Looks good and it have been tested IRL. The comments are not blockers.
Diff comments:
> === modified file 'CMakeLists.txt'
> --- CMakeLists.txt 2014-05-05 09:14:35 +0000
> +++ CMakeLists.txt 2014-06-24 16:02:38 +0000
> @@ -2,12 +2,12 @@
>
> project(ubuntu-location-service)
>
> -set(UBUNTU_LOCATION_SERVICE_VERSION_MAJOR 0)
> +set(UBUNTU_LOCATION_SERVICE_VERSION_MAJOR 1)
> set(UBUNTU_LOCATION_SERVICE_VERSION_MINOR 0)
> -set(UBUNTU_LOCATION_SERVICE_VERSION_PATCH 3)
> +set(UBUNTU_LOCATION_SERVICE_VERSION_PATCH 0)
>
> -set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -pedantic -Wextra -fPIC -pthread")
> -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -fno-strict-aliasing -pedantic -Wextra -fPIC -pthread")
> +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -pedantic -Wextra -fPIC")
> +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -fno-strict-aliasing -pedantic -Wextra -fPIC")
>
> set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
>
> @@ -20,12 +20,17 @@
> include(GNUInstallDirs)
>
> find_package(PkgConfig)
> -find_package(Boost 1.49 COMPONENTS system program_options)
> +find_package(Boost COMPONENTS system program_options)
> find_package(GLog)
> find_package(GFlags)
> +find_package(Threads)
> pkg_check_modules(DBUS dbus-1 REQUIRED)
> pkg_check_modules(DBUS_CPP dbus-cpp REQUIRED)
> -
> +pkg_check_modules(JSON_CPP jsoncpp REQUIRED)
> +# TODO(tvoss): Re-enable once net-cpp hits the archive.
Shouldn't the TODO comment be removed?
> +pkg_check_modules(NET_CPP net-cpp)
> +pkg_check_modules(PROCESS_CPP process-cpp REQUIRED)
> +pkg_check_modules(PROPERTIES_CPP properties-cpp REQUIRED)
> #####################################################################
> # Enable code coverage calculation with gcov/gcovr/lcov
> # Usage:
> @@ -43,18 +48,26 @@
>
> option (DISABLE_ERROR_ON_LOCAL_TYPEDEFS_WARNINGS "Disable errors when local typedefs are unused" ON)
> if (DISABLE_ERROR_ON_LOCAL_TYPEDEFS_WARNINGS)
> - SET (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-error=unused-local-typedefs")
> + SET (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-error=unused-local-typedefs")
> endif (DISABLE_ERROR_ON_LOCAL_TYPEDEFS_WARNINGS)
>
> include_directories(
> ${Boost_INCLUDE_DIRS}
> ${DBUS_INCLUDE_DIRS}
> - ${DBUS_CPP_INCLUDE_DIRS}/dbus
> + ${DBUS_CPP_INCLUDE_DIRS}
> + ${JSON_CPP_INCLUDE_DIRS}
> + ${NET_CPP_INCLUDE_DIRS}
> + ${PROPERTIES_CPP_INCLUDE_DIRS}
> + ${PROCESS_CPP_INCLUDE_DIRS}
> ${GLog_INCLUDE_DIR}
> ${GFlags_INCLUDE_DIR}
> - include/location_service
> +
> + ${CMAKE_SOURCE_DIR}/include/location_service
> + ${CMAKE_SOURCE_DIR}/src/location_service
> )
>
> +file(GLOB_RECURSE UBUNTU_LOCATION_SERVICE_PUBLIC_HEADERS ${CMAKE_CURRENT_SOURCE_DIR} *.h)
> +
> add_subdirectory(data)
> add_subdirectory(doc)
> add_subdirectory(examples)
>
> === modified file 'data/CMakeLists.txt'
> --- data/CMakeLists.txt 2013-08-13 19:52:15 +0000
> +++ data/CMakeLists.txt 2014-06-24 16:02:38 +0000
> @@ -19,12 +19,21 @@
> )
>
> configure_file(
> + ubuntu-location-service-connectivity.pc.in ubuntu-location-service-connectivity.pc @ONLY
> +)
> +
> +configure_file(
> ubuntu-location-service.conf.in ubuntu-location-service.conf @ONLY
> )
>
> install(
> FILES ${CMAKE_CURRENT_BINARY_DIR}/ubuntu-location-service.pc
> - DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/pkgconfig
> + DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig
> +)
> +
> +install(
> + FILES ${CMAKE_CURRENT_BINARY_DIR}/ubuntu-location-service-connectivity.pc
> + DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig
> )
>
> install(
>
> === added file 'data/ubuntu-location-service-connectivity.pc.in'
> --- data/ubuntu-location-service-connectivity.pc.in 1970-01-01 00:00:00 +0000
> +++ data/ubuntu-location-service-connectivity.pc.in 2014-06-24 16:02:38 +0000
> @@ -0,0 +1,12 @@
> +prefix=@CMAKE_INSTALL_PREFIX@
> +exec_prefix=${prefix}
> +libdir=${exec_prefix}/lib
> +includedir=${exec_prefix}/include
> +
> +Name: ubuntu-location-service-connectivity
> +Description: A location service aggregating position/velocity/heading
> + updates and exporting them over dbus, wifi and cell id query interfaces.
> +Version: @UBUNTU_LOCATION_SERVICE_VERSION_MAJOR at .@UBUNTU_LOCATION_SERVICE_VERSION_MINOR at .@UBUNTU_LOCATION_SERVICE_VERSION_PATCH@
> +Libs: -L${libdir} -lubuntu-location-service-connectivity
> +Cflags: -I${includedir}/ubuntu-location-service- at UBUNTU_LOCATION_SERVICE_VERSION_MAJOR@
> +Requires: dbus-cpp
>
> === modified file 'data/ubuntu-location-service.pc.in'
> --- data/ubuntu-location-service.pc.in 2013-08-19 05:51:55 +0000
> +++ data/ubuntu-location-service.pc.in 2014-06-24 16:02:38 +0000
> @@ -9,4 +9,4 @@
> Version: @UBUNTU_LOCATION_SERVICE_VERSION_MAJOR at .@UBUNTU_LOCATION_SERVICE_VERSION_MINOR at .@UBUNTU_LOCATION_SERVICE_VERSION_PATCH@
> Libs: -L${libdir} -lubuntu-location-service
> Cflags: -I${includedir}/ubuntu-location-service- at UBUNTU_LOCATION_SERVICE_VERSION_MAJOR@
> -Requires: dbus-cpp
> \ No newline at end of file
> +Requires: dbus-cpp
>
> === modified file 'debian/changelog'
> --- debian/changelog 2014-06-12 10:45:09 +0000
> +++ debian/changelog 2014-06-24 16:02:38 +0000
> @@ -1,3 +1,9 @@
> +location-service (1.0.0) UNRELEASED; urgency=medium
> +
> + * Bump major version.
> +
> + -- Thomas Voß <thomas.voss at canonical.com> Tue, 24 Jun 2014 15:07:04 +0200
> +
> location-service (0.0.3+14.10.20140612-0ubuntu1) utopic; urgency=low
>
> [ Ubuntu daily release ]
>
> === modified file 'debian/control'
> --- debian/control 2014-05-29 09:28:16 +0000
> +++ debian/control 2014-06-24 16:02:38 +0000
> @@ -6,7 +6,6 @@
> Build-Depends: cmake,
> curl,
> libdbus-cpp-dev (>= 3.0.0),
> - dbus-test-runner,
> debhelper (>= 9),
> doxygen,
> geoclue-ubuntu-geoip,
> @@ -15,9 +14,13 @@
> libboost-program-options-dev,
> libboost-system-dev,
> libdbus-1-dev,
> + libdbus-cpp-dev,
> libgoogle-glog-dev,
> libgtest-dev,
> libiw-dev,
> + libjsoncpp-dev,
> + libnet-cpp-dev,
> + libprocess-cpp-dev,
> libubuntu-platform-hardware-api-headers,
> libubuntu-platform-hardware-api-dev,
> libproperties-cpp-dev,
> @@ -28,7 +31,7 @@
> Vcs-Bzr: https://code.launchpad.net/~phablet-team/location-service/trunk
> Vcs-Browser: http://bazaar.launchpad.net/~phablet-team/location-service/trunk/files
>
> -Package: libubuntu-location-service0
> +Package: libubuntu-location-service1
> Section: libs
> Architecture: any
> Multi-Arch: same
> @@ -45,7 +48,7 @@
> Architecture: any
> Multi-Arch: foreign
> Recommends: ubuntu-location-service-doc,
> -Depends: libubuntu-location-service0 (= ${binary:Version}),
> +Depends: libubuntu-location-service1 (= ${binary:Version}),
> ${misc:Depends},
> Suggests: ubuntu-location-service-doc,
> Description: location service aggregating position/velocity/heading
> @@ -54,9 +57,30 @@
> Contains header files required to develop clients talking to the ubuntu
> location service.
>
> +Package: libubuntu-location-service-dbg
> +Section: debug
> +Architecture: any
> +Multi-Arch: foreign
> +Depends: libubuntu-location-service1 (= ${binary:Version}),
> + ${misc:Depends},
> +Description: location service aggregating position/velocity/heading
> + updates and exporting them over dbus.
> + .
> + Contains debug symbols.
> +
> +Package: ubuntu-location-service-tests
> +Architecture: any
> +Depends: ${misc:Depends},
> + ${shlibs:Depends},
> +Description: location service aggregating position/velocity/heading
> + updates and exporting them over dbus.
> + .
> + Contains all test executables
> +
> Package: ubuntu-location-service-bin
> Architecture: any
> -Depends: ${misc:Depends},
> +Depends: libubuntu-location-service1 (= ${binary:Version}),
> + ${misc:Depends},
> ${shlibs:Depends},
> Breaks: ubuntu-location-service-examples (<< 0.0.2),
> Replaces: ubuntu-location-service-examples (<< 0.0.2),
> @@ -68,7 +92,8 @@
> Package: ubuntu-location-service-examples
> Architecture: any
> Multi-Arch: same
> -Depends: ${misc:Depends},
> +Depends: libubuntu-location-service1 (= ${binary:Version}),
> + ${misc:Depends},
> ${shlibs:Depends},
> ubuntu-location-service-doc,
> Description: location service aggregating position/velocity/heading
>
> === modified file 'debian/copyright'
> --- debian/copyright 2013-06-05 16:59:55 +0000
> +++ debian/copyright 2014-06-24 16:02:38 +0000
> @@ -19,6 +19,24 @@
> License version 2 can be found in the file
> `/usr/share/common-licenses/GPL-2'.
>
> +Files: tests/mongoose.*
> +Copyright: 2004-2013 Sergey Lyubka <valenok at gmail.com>
> +Copyright: 2013-2014 Cesanta Software Limited
> +License: GPL-2+
> + This program is free software; you can redistribute it
> + and/or modify it under the terms of the GNU General
> + Public License as published by the Free Software Foundation;
> + either version 2, or (at your option) any later version.
> + .
> + 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.
> + .
> + On Debian systems, the full text of the GNU General Public
> + License version 2 can be found in the file
> + `/usr/share/common-licenses/GPL-2'.
> +
> Files: *
> Copyright: 2013 Canonical Ltd.
> License: LGPL-3
>
> === modified file 'debian/libubuntu-location-service-dev.install'
> --- debian/libubuntu-location-service-dev.install 2013-06-13 13:57:38 +0000
> +++ debian/libubuntu-location-service-dev.install 2014-06-24 16:02:38 +0000
> @@ -1,3 +1,5 @@
> -usr/include/ubuntu-location-service-0
> +usr/include/ubuntu-location-service-1
> usr/lib/*/libubuntu-location-service.so
> -usr/lib/pkgconfig/ubuntu-location-service.pc
> +usr/lib/*/libubuntu-location-service-connectivity.so
> +usr/lib/*/pkgconfig/ubuntu-location-service.pc
> +usr/lib/*/pkgconfig/ubuntu-location-service-connectivity.pc
>
> === renamed file 'debian/libubuntu-location-service0.install' => 'debian/libubuntu-location-service1.install'
> --- debian/libubuntu-location-service0.install 2013-06-13 13:57:38 +0000
> +++ debian/libubuntu-location-service1.install 2014-06-24 16:02:38 +0000
> @@ -1,1 +1,2 @@
> usr/lib/*/libubuntu-location-service.so.*
> +usr/lib/*/libubuntu-location-service-connectivity.so.*
>
> === modified file 'debian/rules'
> --- debian/rules 2014-05-05 09:14:35 +0000
> +++ debian/rules 2014-06-24 16:02:38 +0000
> @@ -19,5 +19,8 @@
> override_dh_install:
> dh_install -Xubuntu-location-service.1 --fail-missing
>
> +override_dh_strip:
> + dh_strip --dbg-package=libubuntu-location-service-dbg
> +
> override_dh_auto_configure:
> dh_auto_configure -- -DCMAKE_INSTALL_LIBEXECDIR=/usr/lib/$(DEB_HOST_MULTIARCH)/ubuntu-location-service
>
> === modified file 'debian/ubuntu-location-service-bin.install'
> --- debian/ubuntu-location-service-bin.install 2013-10-08 14:48:43 +0000
> +++ debian/ubuntu-location-service-bin.install 2014-06-24 16:02:38 +0000
> @@ -1,4 +1,4 @@
> etc/dbus-1/system.d/
> etc/init/*
> usr/bin/ubuntu-location-serviced
> -
> +usr/bin/ubuntu-location-serviced-cli
>
> === modified file 'debian/ubuntu-location-service-examples.install'
> --- debian/ubuntu-location-service-examples.install 2013-10-14 06:11:15 +0000
> +++ debian/ubuntu-location-service-examples.install 2014-06-24 16:02:38 +0000
> @@ -1,2 +1,3 @@
> usr/lib/*/ubuntu-location-service/examples/client
> usr/lib/*/ubuntu-location-service/examples/service
> +usr/share/ubuntu-location-service
>
> === added file 'debian/ubuntu-location-service-tests.install'
> --- debian/ubuntu-location-service-tests.install 1970-01-01 00:00:00 +0000
> +++ debian/ubuntu-location-service-tests.install 2014-06-24 16:02:38 +0000
> @@ -0,0 +1,1 @@
> +usr/bin/uls-tests/*
>
> === modified file 'doc/Doxyfile.in'
> --- doc/Doxyfile.in 2014-02-09 18:52:25 +0000
> +++ doc/Doxyfile.in 2014-06-24 16:02:38 +0000
> @@ -32,13 +32,13 @@
> # This could be handy for archiving the generated documentation or
> # if some version control system is used.
>
> -PROJECT_NUMBER = @UBUNTU_LOCATION_SERVICE_VERSION_MAJOR at .@UBUNTU_LOCATION_SERVICE_VERSION_MINOR at .@UBUNTU_LOCATION_SERVICE_VERSION_PATCH@
> +PROJECT_NUMBER = @LOCATION_SERVICE_VERSION_MAJOR at .@LOCATION_SERVICE_VERSION_MINOR at .@LOCATION_SERVICE_VERSION_PATCH@
>
> # Using the PROJECT_BRIEF tag one can provide an optional one line description
> # for a project that appears at the top of each page and should give viewer
> # a quick idea about the purpose of the project. Keep the description short.
>
> -PROJECT_BRIEF =
> +PROJECT_BRIEF = "An aggregating location service providing positioning and geocoding capabilities to applications."
>
> # With the PROJECT_LOGO tag one can specify an logo or icon that is
> # included in the documentation. The maximum height of the logo should not
> @@ -266,7 +266,7 @@
> # func(std::string) {}). This also makes the inheritance and collaboration
> # diagrams that involve STL classes more complete and accurate.
>
> -BUILTIN_STL_SUPPORT = NO
> +BUILTIN_STL_SUPPORT = YES
>
> # If you use Microsoft's C++/CLI language, you should set this option to YES to
> # enable parsing support.
> @@ -365,7 +365,7 @@
> # Private class members and static file members will be hidden unless
> # the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
>
> -EXTRACT_ALL = NO
> +EXTRACT_ALL = YES
>
> # If the EXTRACT_PRIVATE tag is set to YES all private members of a class
> # will be included in the documentation.
> @@ -380,7 +380,7 @@
> # If the EXTRACT_STATIC tag is set to YES all static members of a file
> # will be included in the documentation.
>
> -EXTRACT_STATIC = NO
> +EXTRACT_STATIC = YES
>
> # If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
> # defined locally in source files will be included in the documentation.
> @@ -423,7 +423,7 @@
> # If set to NO (the default) these declarations will be included in the
> # documentation.
>
> -HIDE_FRIEND_COMPOUNDS = NO
> +HIDE_FRIEND_COMPOUNDS = YES
>
> # If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any
> # documentation blocks found inside the body of a function.
> @@ -668,7 +668,7 @@
> # directories like "/usr/src/myproject". Separate the files or directories
> # with spaces.
>
> -INPUT = @CMAKE_CURRENT_SOURCE_DIR@/../include
> +INPUT = @CMAKE_CURRENT_SOURCE_DIR@ @CMAKE_CURRENT_SOURCE_DIR@/../include
>
> # This tag can be used to specify the character encoding of the source files
> # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
> @@ -728,7 +728,7 @@
> # directories that contain example code fragments that are included (see
> # the \include command).
>
> -EXAMPLE_PATH = @CMAKE_CURRENT_SOURCE_DIR@/../examples
> +EXAMPLE_PATH = @CMAKE_CURRENT_SOURCE_DIR@/../tests
>
> # If the value of the EXAMPLE_PATH tag contains directories, you can use the
> # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
> @@ -791,7 +791,7 @@
> # This can be useful if you have a project on for instance GitHub and want reuse
> # the introduction page also for the doxygen output.
>
> -USE_MDFILE_AS_MAINPAGE =
> +USE_MDFILE_AS_MAINPAGE = @CMAKE_SOURCE_DIR@/README.md
>
> #---------------------------------------------------------------------------
> # configuration options related to source browsing
> @@ -807,7 +807,7 @@
> # Setting the INLINE_SOURCES tag to YES will include the body
> # of functions and classes directly in the documentation.
>
> -INLINE_SOURCES = YES
> +INLINE_SOURCES = NO
>
> # Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
> # doxygen to hide any special comment blocks from generated source code
> @@ -929,7 +929,7 @@
> # robust against future updates. Doxygen will copy the style sheet file to
> # the output directory.
>
> -HTML_EXTRA_STYLESHEET =
> +HTML_EXTRA_STYLESHEET = @CMAKE_CURRENT_SOURCE_DIR@/extra.css
>
> # The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
> # other source files which should be copied to the HTML output directory. Note
> @@ -975,7 +975,7 @@
> # documentation will contain sections that can be hidden and shown after the
> # page has loaded.
>
> -HTML_DYNAMIC_SECTIONS = NO
> +HTML_DYNAMIC_SECTIONS = YES
>
> # With HTML_INDEX_NUM_ENTRIES one can control the preferred number of
> # entries shown in the various tree structured indices initially; the user
> @@ -1145,7 +1145,7 @@
> # navigation tree you can set this option to NO if you already set
> # GENERATE_TREEVIEW to YES.
>
> -DISABLE_INDEX = NO
> +DISABLE_INDEX = YES
>
> # The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
> # structure should be generated to display hierarchical information.
> @@ -1157,7 +1157,7 @@
> # Since the tree basically has the same information as the tab index you
> # could consider to set DISABLE_INDEX to NO when enabling this option.
>
> -GENERATE_TREEVIEW = NO
> +GENERATE_TREEVIEW = YES
>
> # The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values
> # (range [0,1..20]) that doxygen will group on one line in the generated HTML
> @@ -1234,7 +1234,7 @@
> # typically be disabled. For large projects the javascript based search engine
> # can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution.
>
> -SEARCHENGINE = NO
> +SEARCHENGINE = NO
>
> # When the SERVER_BASED_SEARCH tag is enabled the search engine will be
> # implemented using a web server instead of a web client using Javascript.
> @@ -1293,7 +1293,7 @@
> # If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
> # generate Latex output.
>
> -GENERATE_LATEX = NO
> +GENERATE_LATEX = YES
>
> # The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
> # If a relative path is entered the value of OUTPUT_DIRECTORY will be
> @@ -1319,7 +1319,7 @@
> # LaTeX documents. This may be useful for small projects and may help to
> # save some trees in general.
>
> -COMPACT_LATEX = NO
> +COMPACT_LATEX = YES
>
> # The PAPER_TYPE tag can be used to set the paper type that is used
> # by the printer. Possible values are: a4, letter, legal and
> @@ -1377,7 +1377,7 @@
> # Note that which sources are shown also depends on other settings
> # such as SOURCE_BROWSER.
>
> -LATEX_SOURCE_CODE = NO
> +LATEX_SOURCE_CODE = NO
>
> # The LATEX_BIB_STYLE tag can be used to specify the style to use for the
> # bibliography, e.g. plainnat, or ieeetr. The default style is "plain". See
> @@ -1434,7 +1434,7 @@
> # If the GENERATE_MAN tag is set to YES (the default) Doxygen will
> # generate man pages
>
> -GENERATE_MAN = NO
> +GENERATE_MAN = YES
>
> # The MAN_OUTPUT tag is used to specify where the man pages will be put.
> # If a relative path is entered the value of OUTPUT_DIRECTORY will be
>
> === modified file 'examples/CMakeLists.txt'
> --- examples/CMakeLists.txt 2013-05-28 14:20:45 +0000
> +++ examples/CMakeLists.txt 2014-06-24 16:02:38 +0000
> @@ -1,7 +1,5 @@
> add_subdirectory(service)
>
> -
> -
> -
> -
> -
> +install(
> + DIRECTORY standalone
> + DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/${CMAKE_PROJECT_NAME}/examples)
> \ No newline at end of file
>
> === modified file 'examples/service/CMakeLists.txt'
> --- examples/service/CMakeLists.txt 2014-01-31 11:08:33 +0000
> +++ examples/service/CMakeLists.txt 2014-06-24 16:02:38 +0000
> @@ -1,13 +1,8 @@
> -find_package(PkgConfig)
> -find_package(Boost COMPONENTS system)
> -find_package(Threads)
> -
> -pkg_check_modules(DBUS dbus-1)
> -pkg_check_modules(DBUS_CPP dbus-cpp)
> +message(STATUS ${Boost_LIBRARIES})
> include_directories(
> ${Boost_INCLUDE_DIRS}
> ${DBUS_INCLUDE_DIRS}
> - ${DBUS_CPP_INCLUDE_DIRS}/dbus
> + ${DBUS_CPP_INCLUDE_DIRS}
>
> )
>
>
> === modified file 'examples/service/client.cpp'
> --- examples/service/client.cpp 2014-01-31 11:08:33 +0000
> +++ examples/service/client.cpp 2014-06-24 16:02:38 +0000
> @@ -17,7 +17,7 @@
> */
> #include "program_options.h"
>
> -#include "com/ubuntu/location/service/stub.h"
> +#include <com/ubuntu/location/service/stub.h>
>
> #include <core/dbus/resolver.h>
> #include <core/dbus/asio/executor.h>
> @@ -26,6 +26,7 @@
>
> namespace cul = com::ubuntu::location;
> namespace culs = com::ubuntu::location::service;
> +namespace culss = com::ubuntu::location::service::session;
> namespace dbus = core::dbus;
>
> int main(int argc, char** argv)
> @@ -53,34 +54,34 @@
> {"system", dbus::WellKnownBus::system},
> };
>
> - core::dbus::Bus::Ptr bus
> + dbus::Bus::Ptr bus
> {
> - new core::dbus::Bus{lut.at(options.value_for_key<std::string>("bus"))}
> + new dbus::Bus{lut.at(options.value_for_key<std::string>("bus"))}
> };
> - bus->install_executor(core::dbus::asio::make_executor(bus));
> + bus->install_executor(dbus::asio::make_executor(bus));
> std::thread t{[bus](){bus->run();}};
>
> auto location_service =
> - core::dbus::resolve_service_on_bus<culs::Interface, culs::Stub>(bus);
> -
> - auto s1 = location_service->create_session_for_criteria(com::ubuntu::location::Criteria{});
> -
> - s1->install_position_updates_handler(
> - [&](const com::ubuntu::location::Update<com::ubuntu::location::Position>& new_position) {
> + dbus::resolve_service_on_bus<culs::Interface, culs::Stub>(bus);
> +
> + auto s1 = location_service->create_session_for_criteria(cul::Criteria{});
> +
> + s1->updates().position.changed().connect(
> + [&](const cul::Update<cul::Position>& new_position) {
Do we need to use & to camputer anythig in here?
> std::cout << "On position updated: " << new_position << std::endl;
> });
> - s1->install_velocity_updates_handler(
> - [&](const com::ubuntu::location::Update<com::ubuntu::location::Velocity>& new_velocity) {
> + s1->updates().velocity.changed().connect(
> + [&](const cul::Update<cul::Velocity>& new_velocity) {
> std::cout << "On velocity_changed " << new_velocity << std::endl;
> });
> - s1->install_heading_updates_handler(
> - [&](const com::ubuntu::location::Update<com::ubuntu::location::Heading>& new_heading) {
> + s1->updates().heading.changed().connect(
> + [&](const cul::Update<cul::Heading>& new_heading) {
> std::cout << "On heading changed: " << new_heading << std::endl;
> });
>
> - s1->start_position_updates();
> - s1->start_velocity_updates();
> - s1->start_heading_updates();
> + s1->updates().position_status = culss::Interface::Updates::Status::enabled;
> + s1->updates().heading_status = culss::Interface::Updates::Status::enabled;
> + s1->updates().velocity_status = culss::Interface::Updates::Status::enabled;
>
> if (t.joinable())
> t.join();
>
> === modified file 'examples/service/service.cpp'
> --- examples/service/service.cpp 2014-01-31 11:08:33 +0000
> +++ examples/service/service.cpp 2014-06-24 16:02:38 +0000
> @@ -17,10 +17,10 @@
> */
> #include "program_options.h"
>
> -#include "com/ubuntu/location/provider_factory.h"
> +#include <com/ubuntu/location/provider_factory.h>
>
> -#include "com/ubuntu/location/service/default_configuration.h"
> -#include "com/ubuntu/location/service/implementation.h"
> +#include <com/ubuntu/location/service/default_configuration.h>
> +#include <com/ubuntu/location/service/implementation.h>
>
> #include <core/dbus/announcer.h>
> #include <core/dbus/asio/executor.h>
> @@ -31,6 +31,33 @@
> namespace culs = com::ubuntu::location::service;
> namespace dbus = core::dbus;
>
> +namespace
> +{
> +struct NullReporter : public culs::Harvester::Reporter
> +{
> + NullReporter() = default;
> +
> + /** @brief Tell the reporter that it should start operating. */
> + void start() override
> + {
> + }
> +
> + /** @brief Tell the reporter to shut down its operation. */
> + void stop()
> + {
> + }
> +
> + /**
> + * @brief Triggers the reporter to send off the information.
> + */
> + void report(const cul::Update<cul::Position>&,
> + const std::vector<cul::connectivity::WirelessNetwork::Ptr>&,
> + const std::vector<cul::connectivity::RadioCell::Ptr>&)
> + {
> + }
> +};
> +}
> +
> int main(int argc, char** argv)
> {
> cul::ProgramOptions options;
> @@ -119,30 +146,43 @@
> {"system", dbus::WellKnownBus::system},
> };
>
> - dbus::Bus::Ptr bus
> + dbus::Bus::Ptr incoming
> {
> new dbus::Bus{lut.at(options.value_for_key<std::string>("bus"))}
> };
> + incoming->install_executor(dbus::asio::make_executor(incoming));
>
> - bus->install_executor(dbus::asio::make_executor(bus));
> + dbus::Bus::Ptr outgoing
> + {
> + new dbus::Bus{lut.at(options.value_for_key<std::string>("bus"))}
> + };
> + outgoing->install_executor(dbus::asio::make_executor(outgoing));
>
> culs::DefaultConfiguration config;
> -
> - auto location_service =
> - dbus::announce_service_on_bus<
> - culs::Interface,
> - culs::Implementation
> - >(
> - bus,
> - config.the_engine(
> - instantiated_providers,
> - config.the_provider_selection_policy()),
> - config.the_permission_manager());
> -
> - std::thread t{[bus](){bus->run();}};
> -
> - if (t.joinable())
> - t.join();
> +
> + culs::Implementation::Configuration configuration
> + {
> + incoming,
> + outgoing,
> + config.the_engine(instantiated_providers, config.the_provider_selection_policy()),
> + config.the_permission_manager(),
> + culs::Harvester::Configuration
> + {
> + cul::connectivity::platform_default_manager(),
> + std::make_shared<NullReporter>()
> + }
> + };
> +
> + auto location_service = std::make_shared<culs::Implementation>(configuration);
> +
> + std::thread t1{[incoming](){incoming->run();}};
> + std::thread t2{[outgoing](){outgoing->run();}};
> +
> + if (t1.joinable())
> + t1.join();
> +
> + if (t2.joinable())
> + t2.join();
>
> return EXIT_SUCCESS;
> }
>
> === added directory 'examples/standalone'
> === added directory 'examples/standalone/connectivity'
> === added file 'examples/standalone/connectivity/CMakeLists.txt'
> --- examples/standalone/connectivity/CMakeLists.txt 1970-01-01 00:00:00 +0000
> +++ examples/standalone/connectivity/CMakeLists.txt 2014-06-24 16:02:38 +0000
> @@ -0,0 +1,41 @@
> +cmake_minimum_required(VERSION 2.8)
> +
> +project(connectivity)
> +
> +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
> +
> +find_package(PkgConfig)
> +find_package(Threads)
> +
> +pkg_check_modules(
> + DBUS_CPP
> + dbus-cpp REQUIRED)
> +
> +pkg_check_modules(
> + PROCESS_CPP
> + process-cpp REQUIRED)
> +
> +pkg_check_modules(
> + LOCATION_CONNECTIVITY
> + ubuntu-location-service-connectivity REQUIRED)
> +
> +include_directories(
> + ${DBUS_CPP_INCLUDE_DIRS}
> + ${PROCESS_CPP_INCLUDE_DIRS}
> + ${LOCATION_CONNECTIVITY_INCLUDE_DIRS})
> +
> +add_executable(
> + connectivity
> +
> + connectivity.cpp)
> +
> +target_link_libraries(
> + connectivity
> +
> + ${CMAKE_THREAD_LIBS_INIT}
> +
> + ${DBUS_CPP_LDFLAGS}
> + ${PROCESS_CPP_LDFLAGS}
> + ${LOCATION_CONNECTIVITY_LDFLAGS})
> +
> +
>
> === added file 'examples/standalone/connectivity/connectivity.cpp'
> --- examples/standalone/connectivity/connectivity.cpp 1970-01-01 00:00:00 +0000
> +++ examples/standalone/connectivity/connectivity.cpp 2014-06-24 16:02:38 +0000
> @@ -0,0 +1,201 @@
> +#include <com/ubuntu/location/connectivity/manager.h>
> +
> +#include <core/posix/signal.h>
> +
> +#include <cstdlib>
> +
> +#include <thread>
> +
> +namespace location = com::ubuntu::location;
> +
> +namespace
> +{
> +// Just convenience to safe some typing.
> +typedef std::vector<location::connectivity::RadioCell> RadioCells;
> +typedef std::vector<location::connectivity::WirelessNetwork::Ptr> WirelessNetworks;
> +}
> +
> +// This example illustrates the usage of the location-service-specific connectivity API.
> +// The setup for obtaining measurements of wifis and radio cells is as follows:
> +//
> +// (1.) Obtain an instance of location::connectivity::Manager.
> +// (2.) Connect to the changed signals of the wifi and cell properties and react according to your component's requirements.
> +// (3.) Bootstrap your own setup by explicitly getting all visible wifis and connected cells.
> +int main(int argc, char** argv)
> +{
> + // We catch sig-term to exit cleanly.
> + auto trap = core::posix::trap_signals_for_all_subsequent_threads({core::posix::Signal::sig_term});
> + trap->signal_raised().connect([trap](core::posix::Signal)
> + {
> + trap->stop();
> + });
> +
> + // Trying to acquire a default implementation.
> + auto cm = location::connectivity::platform_default_manager();
> +
> + if (not cm)
> + {
> + std::cerr << "Could not get hold of a connectivity::Manager implementation, aborting..." << std::endl;
> + std::exit(1);
> + }
> +
> + // Subscribe to wifi added/removed signals.
> + cm->wireless_network_added().connect([](const location::connectivity::WirelessNetwork::Ptr& wifi)
> + {
> + std::cout << "Visible wireless network was added: " << *wifi << std::endl;
> +
> + // We don't want to keep the object alive
> + std::weak_ptr<location::connectivity::WirelessNetwork> wp
> + {
> + wifi
> + };
> +
> +
> +
> + // Subscribe to signal strength and last_seen updates. Please note that this is not considering
> + // the case of subscribing to already known wifis. We leave this up
> + // to consumers of the api.
> + wifi->last_seen().changed().connect([wp](const std::chrono::system_clock::time_point& tp)
> + {
> + auto sp = wp.lock();
> + if (sp)
> + std::cout << "Signal strength changed for wifi " << sp->ssid().get() << ": " << tp.time_since_epoch().count() << std::endl;
> + });
> +
> + wifi->signal_strength().changed().connect([wp](const location::connectivity::WirelessNetwork::SignalStrength& s)
> + {
> + auto sp = wp.lock();
> + if (sp)
> + std::cout << "Signal strength changed for wifi " << sp->ssid().get() << ": " << s << std::endl;
> + });
> + });
> +
> + cm->wireless_network_removed().connect([](const location::connectivity::WirelessNetwork::Ptr& wifi)
> + {
> + std::cout << "Visible wireless network was removed: " << wifi->ssid().get() << std::endl;
> + });
> +
> + // Iterate over all radio cells that the device is connected with.
> + cm->enumerate_connected_radio_cells([](const location::connectivity::RadioCell::Ptr& cell)
> + {
> + std::cout << *cell << std::endl;
> +
> + std::weak_ptr<location::connectivity::RadioCell> wp{cell};
> +
> + // Subscribe to changes on the cell
> + cell->changed().connect([wp]()
> + {
> + auto sp = wp.lock();
> +
> + if (sp)
> + std::cout << "Something changed on a radio cell: " << *sp << std::endl;
> + });
> + });
> +
> + cm->connected_cell_added().connect([](const location::connectivity::RadioCell::Ptr& cell)
> + {
> + std::cout << *cell << std::endl;
> +
> + // Subscribe to changes on the cell
> + cell->changed().connect([]()
> + {
> + std::cout << "Something changed on a radio cell." << std::endl;
> + });
> + });
> +
> + cm->connected_cell_removed().connect([](const location::connectivity::RadioCell::Ptr& cell)
> + {
> + std::cout << *cell << std::endl;
> + });
> +
> + // Iterate over all networks that are visible right now.
> + cm->enumerate_visible_wireless_networks([](const location::connectivity::WirelessNetwork::Ptr& wifi)
> + {
> + std::cout << *wifi << std::endl;
> +
> + // We don't want to keep the object alive
> + std::weak_ptr<location::connectivity::WirelessNetwork> wp
> + {
> + wifi
> + };
> +
> + // Subscribe to last-seen updates.
> + wifi->last_seen().changed().connect([wp](const std::chrono::system_clock::time_point& tp)
> + {
> + auto sp = wp.lock();
> + if (sp)
> + std::cout << "Last seen changed for wifi " << *sp << std::endl;
> + });
> +
> + // Subscribe to signal strength updates. Please note that this is not considering
> + // the case of subscribing to already known wifis. We leave this up
> + // to consumers of the api.
> + wifi->signal_strength().changed().connect([wp](const location::connectivity::WirelessNetwork::SignalStrength& s)
> + {
> + auto sp = wp.lock();
> + if (sp)
> + std::cout << "Signal strength changed for wifi: " << *sp << std::endl;
> + });
> + });
> +
> + // Subscribe to end-of-scan signals
> + cm->wireless_network_scan_finished().connect([]()
> + {
> + std::cout << "A wireless network scan finished." << std::endl;
> + });
> +
> + // Request a scan for wireless networks.
> + try
> + {
> + cm->request_scan_for_wireless_networks();
> + } catch(const std::runtime_error& e)
> + {
> + std::cerr << e.what() << std::endl;
> + }
> +
> + bool cancelled = false;
> +
> + std::thread t1
> + {
> + [cm, &cancelled]()
> + {
> + while (not cancelled)
> + {
> + cm->enumerate_visible_wireless_networks([](const location::connectivity::WirelessNetwork::Ptr&)
> + {
> + // We do nothing with the actual values and just keep the thread running
> + // to put some load on the infrastructure.
> + });
> + }
> + }
> + };
> +
> + std::thread t2
> + {
> + [cm, &cancelled]()
> + {
> + while (not cancelled)
> + {
> + cm->enumerate_connected_radio_cells([](const location::connectivity::RadioCell::Ptr&)
> + {
> + // We do nothing with the actual values and just keep the thread running
> + // to put some load on the infrastructure.
> + });
> + }
> + }
> + };
> +
> + trap->run();
> +
> + cancelled = true;
> +
> + if (t1.joinable())
> + t1.join();
> +
> + if (t2.joinable())
> + t2.join();
> +
> + return 0;
> +}
> +
> +
>
> === modified file 'include/CMakeLists.txt'
> --- include/CMakeLists.txt 2013-05-28 14:20:45 +0000
> +++ include/CMakeLists.txt 2014-06-24 16:02:38 +0000
> @@ -1,4 +1,4 @@
> install(
> - DIRECTORY location_service/com
> - DESTINATION include/ubuntu-location-service-${UBUNTU_LOCATION_SERVICE_VERSION_MAJOR}
> -)
> \ No newline at end of file
> + DIRECTORY location_service/com
> + DESTINATION include/ubuntu-location-service-${UBUNTU_LOCATION_SERVICE_VERSION_MAJOR}
> +)
>
> === removed file 'include/location_service/com/ubuntu/location/channel.h'
> --- include/location_service/com/ubuntu/location/channel.h 2013-05-28 14:41:06 +0000
> +++ include/location_service/com/ubuntu/location/channel.h 1970-01-01 00:00:00 +0000
> @@ -1,41 +0,0 @@
> -/*
> - * Copyright © 2012-2013 Canonical Ltd.
> - *
> - * This program is free software: you can redistribute it and/or modify it
> - * under the terms of the GNU Lesser General Public License version 3,
> - * 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 Lesser General Public License for more details.
> - *
> - * You should have received a copy of the GNU Lesser General Public License
> - * along with this program. If not, see <http://www.gnu.org/licenses/>.
> - *
> - * Authored by: Thomas Voß <thomas.voss at canonical.com>
> - */
> -#ifndef LOCATION_SERVICE_COM_UBUNTU_LOCATION_CHANNEL_H_
> -#define LOCATION_SERVICE_COM_UBUNTU_LOCATION_CHANNEL_H_
> -
> -#include <boost/signals2.hpp>
> -
> -#include <memory>
> -#include <set>
> -
> -namespace com
> -{
> -namespace ubuntu
> -{
> -namespace location
> -{
> -template<typename T>
> -using Channel = boost::signals2::signal<void(const T&)>;
> -
> -typedef boost::signals2::scoped_connection ScopedChannelConnection;
> -typedef boost::signals2::connection ChannelConnection;
> -}
> -}
> -}
> -
> -#endif // LOCATION_SERVICE_COM_UBUNTU_LOCATION_CHANNEL_H_
>
> === modified file 'include/location_service/com/ubuntu/location/clock.h'
> --- include/location_service/com/ubuntu/location/clock.h 2013-05-28 14:41:06 +0000
> +++ include/location_service/com/ubuntu/location/clock.h 2014-06-24 16:02:38 +0000
> @@ -26,15 +26,41 @@
> {
> namespace location
> {
> +/**
> + * @brief Defines the timebase of the location service.
> + */
> struct Clock
> {
> + /** @brief The underlying clock we are assuming for all time-stamping purposes. */
> + typedef std::chrono::high_resolution_clock Type;
> +
> + /**
> + * @brief Duration type of the location service clock.
> + */
> typedef std::chrono::high_resolution_clock::duration Duration;
> +
> + /**
> + * @brief Timestamp type of the location service clock.
> + */
> typedef std::chrono::high_resolution_clock::time_point Timestamp;
>
> + /**
> + * @brief Samples a timestamp from the clock.
> + * @return The current time.
> + */
> static inline Timestamp now()
> {
> return std::chrono::high_resolution_clock::now();
> }
> +
> + /**
> + * @brief Samples a timestamp from the clock.
> + * @return The minimum point in time representable by this clock.
> + */
> + static inline Timestamp beginning_of_time()
> + {
> + return std::chrono::high_resolution_clock::time_point::min();
> + }
> };
> }
> }
>
> === modified file 'include/location_service/com/ubuntu/location/codec.h'
> --- include/location_service/com/ubuntu/location/codec.h 2014-01-31 11:08:33 +0000
> +++ include/location_service/com/ubuntu/location/codec.h 2014-06-24 16:02:38 +0000
> @@ -18,16 +18,16 @@
> #ifndef LOCATION_SERVICE_COM_UBUNTU_LOCATION_CODEC_H_
> #define LOCATION_SERVICE_COM_UBUNTU_LOCATION_CODEC_H_
>
> -#include "com/ubuntu/location/accuracy.h"
> -#include "com/ubuntu/location/criteria.h"
> -#include "com/ubuntu/location/heading.h"
> -#include "com/ubuntu/location/position.h"
> -#include "com/ubuntu/location/update.h"
> -#include "com/ubuntu/location/velocity.h"
> -#include "com/ubuntu/location/units/units.h"
> -#include "com/ubuntu/location/wgs84/altitude.h"
> -#include "com/ubuntu/location/wgs84/latitude.h"
> -#include "com/ubuntu/location/wgs84/longitude.h"
> +#include <com/ubuntu/location/criteria.h>
> +#include <com/ubuntu/location/heading.h>
> +#include <com/ubuntu/location/position.h>
> +#include <com/ubuntu/location/space_vehicle.h>
> +#include <com/ubuntu/location/update.h>
> +#include <com/ubuntu/location/velocity.h>
> +#include <com/ubuntu/location/units/units.h>
> +#include <com/ubuntu/location/wgs84/altitude.h>
> +#include <com/ubuntu/location/wgs84/latitude.h>
> +#include <com/ubuntu/location/wgs84/longitude.h>
>
> #include <core/dbus/codec.h>
>
> @@ -44,6 +44,7 @@
> {
> return ArgumentType::floating_point;
> }
> +
> constexpr static bool is_basic_type()
> {
> return true;
> @@ -62,317 +63,283 @@
> }
>
> template<typename T>
> +struct Codec<com::ubuntu::location::Optional<T>>
> +{
> + static void encode_argument(Message::Writer& writer, const com::ubuntu::location::Optional<T>& in)
> + {
> + bool has_value{in};
> + Codec<bool>::encode_argument(writer, has_value);
> + if (has_value)
> + Codec<typename com::ubuntu::location::Optional<T>::value_type>::encode_argument(writer, *in);
> + }
> +
> + static void decode_argument(Message::Reader& reader, com::ubuntu::location::Optional<T>& in)
> + {
> + bool has_value{false};
> + Codec<bool>::decode_argument(reader, has_value);
> + if (has_value)
> + {
> + typename com::ubuntu::location::Optional<T>::value_type value;
> + Codec<typename com::ubuntu::location::Optional<T>::value_type>::decode_argument(reader, value);
> + in = value;
> + } else
> + {
> + in.reset();
> + }
> + }
> +};
> +
> +template<typename T>
> struct Codec<com::ubuntu::location::units::Quantity<T>>
> {
> - static void encode_argument(core::dbus::Message::Writer& out, const com::ubuntu::location::units::Quantity<T>& in)
> + static void encode_argument(Message::Writer& writer, const com::ubuntu::location::units::Quantity<T>& in)
> {
> - Codec<typename com::ubuntu::location::units::Quantity<T>::value_type>::encode_argument(out, in.value());
> + Codec<typename com::ubuntu::location::units::Quantity<T>::value_type>::encode_argument(writer, in.value());
> }
>
> - static void decode_argument(core::dbus::Message::Reader& out, com::ubuntu::location::units::Quantity<T>& in)
> + static void decode_argument(Message::Reader& reader, com::ubuntu::location::units::Quantity<T>& in)
> {
> typename com::ubuntu::location::units::Quantity<T>::value_type value;
> - Codec<typename com::ubuntu::location::units::Quantity<T>::value_type>::decode_argument(out, value);
> + Codec<typename com::ubuntu::location::units::Quantity<T>::value_type>::decode_argument(reader, value);
> in = com::ubuntu::location::units::Quantity<T>::from_value(value);
> - }
> -};
> -
> -namespace helper
> -{
> -template<typename T, typename U>
> -struct TypeMapper<com::ubuntu::location::wgs84::Coordinate<T,U>>
> -{
> - constexpr static ArgumentType type_value()
> - {
> - return ArgumentType::structure;
> - }
> - constexpr static bool is_basic_type()
> - {
> - return false;
> - }
> - constexpr static bool requires_signature()
> - {
> - return true;
> - }
> -
> - static std::string signature()
> - {
> - static const std::string s =
> - DBUS_STRUCT_BEGIN_CHAR_AS_STRING +
> - TypeMapper<com::ubuntu::location::units::Quantity<U>>::signature() +
> - DBUS_STRUCT_END_CHAR_AS_STRING;
> - return s;
> - }
> -};
> -}
> + }
> +};
>
> template<typename T, typename U>
> struct Codec<com::ubuntu::location::wgs84::Coordinate<T,U>>
> {
> - static void encode_argument(core::dbus::Message::Writer& out, const com::ubuntu::location::wgs84::Coordinate<T, U>& in)
> - {
> - Codec<com::ubuntu::location::units::Quantity<U>>::encode_argument(out, in.value);
> - }
> -
> - static void decode_argument(core::dbus::Message::Reader& out, com::ubuntu::location::wgs84::Coordinate<T, U>& in)
> - {
> - Codec<com::ubuntu::location::units::Quantity<U>>::decode_argument(out, in.value);
> - }
> -};
> -
> -namespace helper
> -{
> -template<>
> -struct TypeMapper<com::ubuntu::location::Position>
> -{
> - constexpr static ArgumentType type_value()
> - {
> - return ArgumentType::structure;
> - }
> - constexpr static bool is_basic_type()
> - {
> - return false;
> - }
> - constexpr static bool requires_signature()
> - {
> - return true;
> - }
> -
> - static std::string signature()
> - {
> - static const std::string s =
> - TypeMapper<uint64_t>::signature() +
> - TypeMapper<com::ubuntu::location::wgs84::Latitude>::signature() +
> - TypeMapper<com::ubuntu::location::wgs84::Longitude>::signature() +
> - TypeMapper<com::ubuntu::location::wgs84::Altitude>::signature();
> - return s;
> - }
> -};
> -}
> + static void encode_argument(Message::Writer& writer, const com::ubuntu::location::wgs84::Coordinate<T, U>& in)
> + {
> + Codec<com::ubuntu::location::units::Quantity<U>>::encode_argument(writer, in.value);
> + }
> +
> + static void decode_argument(Message::Reader& reader, com::ubuntu::location::wgs84::Coordinate<T, U>& in)
> + {
> + Codec<com::ubuntu::location::units::Quantity<U>>::decode_argument(reader, in.value);
> + }
> +};
>
> template<>
> struct Codec<com::ubuntu::location::Position>
> {
> - static void encode_argument(core::dbus::Message::Writer& out, const com::ubuntu::location::Position& in)
> - {
> - Codec<uint64_t>::encode_argument(out, in.flags().to_ulong());
> - if (in.has_latitude())
> - Codec<com::ubuntu::location::wgs84::Latitude>::encode_argument(out, in.latitude());
> - if (in.has_longitude())
> - Codec<com::ubuntu::location::wgs84::Longitude>::encode_argument(out, in.longitude());
> - if (in.has_altitude())
> - Codec<com::ubuntu::location::wgs84::Altitude>::encode_argument(out, in.altitude());
> - }
> -
> - static void decode_argument(core::dbus::Message::Reader& out, com::ubuntu::location::Position& in)
> - {
> - com::ubuntu::location::wgs84::Latitude lat;
> - com::ubuntu::location::wgs84::Longitude lon;
> - com::ubuntu::location::wgs84::Altitude alt;
> - uint64_t flags_on_wire;
> - Codec<uint64_t>::decode_argument(out, flags_on_wire);
> -
> - com::ubuntu::location::Position::Flags flags{flags_on_wire};
> - if (flags.test(com::ubuntu::location::Position::latitude_flag))
> - {
> - Codec<com::ubuntu::location::wgs84::Latitude>::decode_argument(out, lat);
> - in.latitude(lat);
> - }
> - if (flags.test(com::ubuntu::location::Position::latitude_flag))
> - {
> - Codec<com::ubuntu::location::wgs84::Longitude>::decode_argument(out, lon);
> - in.longitude(lon);
> - }
> - if (flags.test(com::ubuntu::location::Position::altitude_flag))
> - {
> - Codec<com::ubuntu::location::wgs84::Altitude>::decode_argument(out, alt);
> - in.altitude(alt);
> - }
> - }
> -};
> -
> -namespace helper
> -{
> -template<>
> -struct TypeMapper<com::ubuntu::location::Velocity>
> -{
> - constexpr static ArgumentType type_value()
> - {
> - return ArgumentType::structure;
> - }
> - constexpr static bool is_basic_type()
> - {
> - return false;
> - }
> - constexpr static bool requires_signature()
> - {
> - return true;
> - }
> -
> - static std::string signature()
> - {
> - static const std::string s =
> - DBUS_STRUCT_BEGIN_CHAR_AS_STRING +
> - TypeMapper<typename com::ubuntu::location::Velocity::Quantity>::signature() +
> - DBUS_STRUCT_END_CHAR_AS_STRING;
> - return s;
> - }
> -};
> -}
> -
> -template<>
> -struct Codec<com::ubuntu::location::Velocity>
> -{
> - static void encode_argument(core::dbus::Message::Writer& out, const com::ubuntu::location::Velocity& in)
> - {
> - Codec<typename com::ubuntu::location::Velocity::Quantity>::encode_argument(out, in.value);
> - }
> -
> - static void decode_argument(core::dbus::Message::Reader& out, com::ubuntu::location::Velocity& in)
> - {
> - Codec<typename com::ubuntu::location::Velocity::Quantity>::decode_argument(out, in.value);
> - }
> -};
> -
> -namespace helper
> -{
> -template<>
> -struct TypeMapper<com::ubuntu::location::Heading>
> -{
> - constexpr static ArgumentType type_value()
> - {
> - return ArgumentType::structure;
> - }
> - constexpr static bool is_basic_type()
> - {
> - return false;
> - }
> - constexpr static bool requires_signature()
> - {
> - return true;
> - }
> -
> - static std::string signature()
> - {
> - static const std::string s =
> - DBUS_STRUCT_BEGIN_CHAR_AS_STRING +
> - TypeMapper<typename com::ubuntu::location::Heading::Quantity>::signature() +
> - DBUS_STRUCT_END_CHAR_AS_STRING;
> - return s;
> - }
> -};
> -}
> -
> -template<>
> -struct Codec<com::ubuntu::location::Heading>
> -{
> - static void encode_argument(core::dbus::Message::Writer& out, const com::ubuntu::location::Heading& in)
> - {
> - Codec<typename com::ubuntu::location::Heading::Quantity>::encode_argument(out, in.value);
> - }
> -
> - static void decode_argument(core::dbus::Message::Reader& out, com::ubuntu::location::Heading& in)
> - {
> - Codec<typename com::ubuntu::location::Heading::Quantity>::decode_argument(out, in.value);
> - }
> -};
> -
> -namespace helper
> -{
> -template<typename T>
> -struct TypeMapper<com::ubuntu::location::Accuracy<T>>
> -{
> - constexpr static ArgumentType type_value()
> - {
> - return ArgumentType::structure;
> - }
> - constexpr static bool is_basic_type()
> - {
> - return false;
> - }
> - constexpr static bool requires_signature()
> - {
> - return true;
> - }
> -
> - static std::string signature()
> - {
> - static const std::string s =
> - DBUS_STRUCT_BEGIN_CHAR_AS_STRING +
> - TypeMapper<T>::signature() +
> - DBUS_STRUCT_END_CHAR_AS_STRING;
> - return s;
> - }
> -};
> -}
> -
> -template<typename T>
> -struct Codec<com::ubuntu::location::Accuracy<T>>
> -{
> - static void encode_argument(core::dbus::Message::Writer& out, const com::ubuntu::location::Accuracy<T>& in)
> - {
> - Codec<T>::encode_argument(out, in.value);
> - }
> -
> - static void decode_argument(core::dbus::Message::Reader& out, com::ubuntu::location::Accuracy<T>& in)
> - {
> - Codec<T>::decode_argument(out, in.value);
> - }
> -};
> -
> -namespace helper
> -{
> -template<>
> -struct TypeMapper<com::ubuntu::location::Criteria>
> -{
> - constexpr static ArgumentType type_value()
> - {
> - return ArgumentType::structure;
> - }
> - constexpr static bool is_basic_type()
> - {
> - return false;
> - }
> - constexpr static bool requires_signature()
> - {
> - return true;
> - }
> -
> - static std::string signature()
> - {
> - static const std::string s =
> - DBUS_STRUCT_BEGIN_CHAR_AS_STRING +
> - helper::TypeMapper<com::ubuntu::location::Accuracy<com::ubuntu::location::wgs84::Latitude>>::signature() +
> - helper::TypeMapper<com::ubuntu::location::Accuracy<com::ubuntu::location::wgs84::Longitude>>::signature() +
> - helper::TypeMapper<com::ubuntu::location::Accuracy<com::ubuntu::location::wgs84::Altitude>>::signature() +
> - helper::TypeMapper<com::ubuntu::location::Accuracy<com::ubuntu::location::Velocity>>::signature() +
> - helper::TypeMapper<com::ubuntu::location::Accuracy<com::ubuntu::location::Heading>>::signature() +
> - DBUS_STRUCT_END_CHAR_AS_STRING;
> - return s;
> - }
> -};
> -}
> + typedef com::ubuntu::location::Position::Accuracy::Horizontal HorizontalAccuracy;
> + typedef com::ubuntu::location::Position::Accuracy::Vertical VerticalAccuracy;
> +
> + static void encode_argument(Message::Writer& writer, const com::ubuntu::location::Position& in)
> + {
> + Codec<com::ubuntu::location::wgs84::Latitude>::encode_argument(writer, in.latitude);
> + Codec<com::ubuntu::location::wgs84::Longitude>::encode_argument(writer, in.longitude);
> + Codec<com::ubuntu::location::Optional<com::ubuntu::location::wgs84::Altitude>>::encode_argument(writer, in.altitude);
> +
> + Codec<com::ubuntu::location::Optional<HorizontalAccuracy>>::encode_argument(writer, in.accuracy.horizontal);
> + Codec<com::ubuntu::location::Optional<VerticalAccuracy>>::encode_argument(writer, in.accuracy.vertical);
> + }
> +
> + static void decode_argument(Message::Reader& reader, com::ubuntu::location::Position& in)
> + {
> + Codec<com::ubuntu::location::wgs84::Latitude>::decode_argument(reader, in.latitude);
> + Codec<com::ubuntu::location::wgs84::Longitude>::decode_argument(reader, in.longitude);
> + Codec<com::ubuntu::location::Optional<com::ubuntu::location::wgs84::Altitude>>::decode_argument(reader, in.altitude);
> +
> + Codec<com::ubuntu::location::Optional<HorizontalAccuracy>>::decode_argument(reader, in.accuracy.horizontal);
> + Codec<com::ubuntu::location::Optional<VerticalAccuracy>>::decode_argument(reader, in.accuracy.vertical);
> + }
> +};
> +
> +
> +namespace helper
> +{
> +template<>
> +struct TypeMapper<com::ubuntu::location::SpaceVehicle::Key>
> +{
> + constexpr static ArgumentType type_value()
> + {
> + return ArgumentType::structure;
> + }
> + constexpr static bool is_basic_type()
> + {
> + return false;
> + }
> + constexpr static bool requires_signature()
> + {
> + return true;
> + }
> +
> + static std::string signature()
> + {
> + static const std::string s =
> + helper::TypeMapper<std::uint32_t>::signature() +
> + helper::TypeMapper<std::uint32_t>::signature();
> + return s;
> + }
> +};
> +template<>
> +struct TypeMapper<com::ubuntu::location::SpaceVehicle>
> +{
> + constexpr static ArgumentType type_value()
> + {
> + return ArgumentType::structure;
> + }
> + constexpr static bool is_basic_type()
> + {
> + return false;
> + }
> + constexpr static bool requires_signature()
> + {
> + return true;
> + }
> +
> + inline static std::string signature()
> + {
> + std::string s =
> + DBUS_STRUCT_BEGIN_CHAR_AS_STRING +
> + helper::TypeMapper<com::ubuntu::location::SpaceVehicle::Key>::signature() +
> + helper::TypeMapper<float>::signature() +
> + helper::TypeMapper<bool>::signature() +
> + helper::TypeMapper<bool>::signature() +
> + helper::TypeMapper<bool>::signature() +
> + helper::TypeMapper<com::ubuntu::location::units::Quantity<com::ubuntu::location::units::PlaneAngle>>::signature() +
> + helper::TypeMapper<com::ubuntu::location::units::Quantity<com::ubuntu::location::units::PlaneAngle>>::signature() +
> + DBUS_STRUCT_END_CHAR_AS_STRING;
> + return s;
> + }
> +};
> +}
> +
> +template<>
> +struct Codec<com::ubuntu::location::SpaceVehicle::Key>
> +{
> + static void encode_argument(Message::Writer& writer, const com::ubuntu::location::SpaceVehicle::Key& in)
> + {
> + writer.push_uint32(static_cast<std::uint32_t>(in.type));
> + writer.push_uint32(in.id);
> + }
> +
> + static void decode_argument(Message::Reader& reader, com::ubuntu::location::SpaceVehicle::Key& in)
> + {
> + in.type = static_cast<com::ubuntu::location::SpaceVehicle::Type>(reader.pop_uint32());
> + in.id = reader.pop_uint32();
> + }
> +};
> +
> +template<>
> +struct Codec<com::ubuntu::location::SpaceVehicle>
> +{
> + inline static void encode_argument(Message::Writer& writer, const com::ubuntu::location::SpaceVehicle& in)
> + {
> + auto sub = writer.open_structure();
> +
> + Codec<com::ubuntu::location::SpaceVehicle::Key>::encode_argument(sub, in.key);
> + sub.push_floating_point(in.snr);
> + sub.push_boolean(in.has_almanac_data);
> + sub.push_boolean(in.has_ephimeris_data);
> + sub.push_boolean(in.used_in_fix);
> + Codec<com::ubuntu::location::units::Quantity<com::ubuntu::location::units::PlaneAngle>>::encode_argument(sub, in.azimuth);
> + Codec<com::ubuntu::location::units::Quantity<com::ubuntu::location::units::PlaneAngle>>::encode_argument(sub, in.elevation);
> +
> + writer.close_structure(std::move(sub));
> + }
> +
> + inline static void decode_argument(Message::Reader& reader, com::ubuntu::location::SpaceVehicle& in)
> + {
> + auto sub = reader.pop_structure();
> +
> + Codec<com::ubuntu::location::SpaceVehicle::Key>::decode_argument(sub, in.key);
> + in.snr = sub.pop_floating_point();
> + in.has_almanac_data = sub.pop_boolean();
> + in.has_ephimeris_data = sub.pop_boolean();
> + in.used_in_fix = sub.pop_boolean();
> + Codec<com::ubuntu::location::units::Quantity<com::ubuntu::location::units::PlaneAngle>>::decode_argument(sub, in.azimuth);
> + Codec<com::ubuntu::location::units::Quantity<com::ubuntu::location::units::PlaneAngle>>::decode_argument(sub, in.elevation);
> + }
> +};
> +
> +namespace helper
> +{
> +template<>
> +struct TypeMapper<std::map<com::ubuntu::location::SpaceVehicle::Key, com::ubuntu::location::SpaceVehicle>>
> +{
> + constexpr static ArgumentType type_value()
> + {
> + return ArgumentType::array;
> + }
> + constexpr static bool is_basic_type()
> + {
> + return false;
> + }
> + constexpr static bool requires_signature()
> + {
> + return true;
> + }
> +
> + static std::string signature()
> + {
> + static const std::string s = DBUS_TYPE_ARRAY_AS_STRING + TypeMapper<com::ubuntu::location::SpaceVehicle>::signature();
> + return s;
> + }
> +};
> +}
> +template<>
> +struct Codec<std::map<com::ubuntu::location::SpaceVehicle::Key, com::ubuntu::location::SpaceVehicle>>
> +{
> + inline static void encode_argument(Message::Writer& writer, const std::map<com::ubuntu::location::SpaceVehicle::Key, com::ubuntu::location::SpaceVehicle>& arg)
> + {
> + types::Signature signature(helper::TypeMapper<com::ubuntu::location::SpaceVehicle>::signature());
> + auto sub = writer.open_array(signature);
> +
> + for(const auto& element : arg)
> + {
> + Codec<com::ubuntu::location::SpaceVehicle>::encode_argument(sub, element.second);
> + }
> +
> + writer.close_array(std::move(sub));
> + }
> +
> + inline static void decode_argument(Message::Reader& reader, std::map<com::ubuntu::location::SpaceVehicle::Key, com::ubuntu::location::SpaceVehicle>& out)
> + {
> + auto sub = reader.pop_array();
> + while (sub.type() != ArgumentType::invalid)
> + {
> + com::ubuntu::location::SpaceVehicle sv;
> + Codec<com::ubuntu::location::SpaceVehicle>::decode_argument(sub, sv);
> + out.insert(std::make_pair(sv.key, sv));
> + }
> + }
> +};
>
> template<>
> struct Codec<com::ubuntu::location::Criteria>
> {
> - static void encode_argument(core::dbus::Message::Writer& out, const com::ubuntu::location::Criteria& in)
> - {
> - Codec<com::ubuntu::location::Accuracy<com::ubuntu::location::wgs84::Latitude>>::encode_argument(out, in.latitude_accuracy);
> - Codec<com::ubuntu::location::Accuracy<com::ubuntu::location::wgs84::Longitude>>::encode_argument(out, in.longitude_accuracy);
> - Codec<com::ubuntu::location::Accuracy<com::ubuntu::location::wgs84::Altitude>>::encode_argument(out, in.altitude_accuracy);
> - Codec<com::ubuntu::location::Accuracy<com::ubuntu::location::Velocity>>::encode_argument(out, in.velocity_accuracy);
> - Codec<com::ubuntu::location::Accuracy<com::ubuntu::location::Heading>>::encode_argument(out, in.heading_accuracy);
> - }
> -
> - static void decode_argument(core::dbus::Message::Reader& out, com::ubuntu::location::Criteria& in)
> - {
> - Codec<com::ubuntu::location::Accuracy<com::ubuntu::location::wgs84::Latitude>>::decode_argument(out, in.latitude_accuracy);
> - Codec<com::ubuntu::location::Accuracy<com::ubuntu::location::wgs84::Longitude>>::decode_argument(out, in.longitude_accuracy);
> - Codec<com::ubuntu::location::Accuracy<com::ubuntu::location::wgs84::Altitude>>::decode_argument(out, in.altitude_accuracy);
> - Codec<com::ubuntu::location::Accuracy<com::ubuntu::location::Velocity>>::decode_argument(out, in.velocity_accuracy);
> - Codec<com::ubuntu::location::Accuracy<com::ubuntu::location::Heading>>::decode_argument(out, in.heading_accuracy);
> - }
> + typedef com::ubuntu::location::units::Quantity<com::ubuntu::location::units::Length> HorizontalAccuracy;
> + typedef com::ubuntu::location::units::Quantity<com::ubuntu::location::units::Length> VerticalAccuracy;
Although I understand the separation of the accuracy, should we do the math and return it as a single value?? Nevertheless I think we should add a comment and speicify what was used to calculate it, I'm assuming CEP68 was used.
> + typedef com::ubuntu::location::units::Quantity<com::ubuntu::location::units::Velocity> VelocityAccuracy;
> + typedef com::ubuntu::location::units::Quantity<com::ubuntu::location::units::PlaneAngle> HeadingAccuracy;
> +
> + static void encode_argument(Message::Writer& writer, const com::ubuntu::location::Criteria& in)
> + {
> + Codec<bool>::encode_argument(writer, in.requires.position);
> + Codec<bool>::encode_argument(writer, in.requires.altitude);
> + Codec<bool>::encode_argument(writer, in.requires.heading);
> + Codec<bool>::encode_argument(writer, in.requires.velocity);
> +
> + Codec<HorizontalAccuracy>::encode_argument(writer, in.accuracy.horizontal);
> + Codec<com::ubuntu::location::Optional<VerticalAccuracy>>::encode_argument(writer, in.accuracy.vertical);
> + Codec<com::ubuntu::location::Optional<VelocityAccuracy>>::encode_argument(writer, in.accuracy.velocity);
> + Codec<com::ubuntu::location::Optional<HeadingAccuracy>>::encode_argument(writer, in.accuracy.heading);
> + }
> +
> + static void decode_argument(Message::Reader& reader, com::ubuntu::location::Criteria& in)
> + {
> + Codec<bool>::decode_argument(reader, in.requires.position);
> + Codec<bool>::decode_argument(reader, in.requires.altitude);
> + Codec<bool>::decode_argument(reader, in.requires.heading);
> + Codec<bool>::decode_argument(reader, in.requires.velocity);
> +
> + Codec<HorizontalAccuracy>::decode_argument(reader, in.accuracy.horizontal);
> + Codec<com::ubuntu::location::Optional<VerticalAccuracy>>::decode_argument(reader, in.accuracy.vertical);
> + Codec<com::ubuntu::location::Optional<VelocityAccuracy>>::decode_argument(reader, in.accuracy.velocity);
> + Codec<com::ubuntu::location::Optional<HeadingAccuracy>>::decode_argument(reader, in.accuracy.heading);
> + }
> };
> namespace helper
> {
> @@ -405,18 +372,16 @@
> template<typename T>
> struct Codec<com::ubuntu::location::Update<T>>
> {
> - static void encode_argument(core::dbus::Message::Writer& out, const com::ubuntu::location::Update<T>& in)
> + static void encode_argument(Message::Writer& writer, const com::ubuntu::location::Update<T>& in)
> {
> - Codec<T>::encode_argument(out, in.value);
> - Codec<int64_t>::encode_argument(out, in.when.time_since_epoch().count());
> + Codec<T>::encode_argument(writer, in.value);
> + Codec<int64_t>::encode_argument(writer, in.when.time_since_epoch().count());
> }
>
> - static void decode_argument(core::dbus::Message::Reader& out, com::ubuntu::location::Update<T>& in)
> + static void decode_argument(Message::Reader& reader, com::ubuntu::location::Update<T>& in)
> {
> - Codec<T>::decode_argument(out, in.value);
> - int64_t value;
> - Codec<int64_t>::decode_argument(out, value);
> - in.when = com::ubuntu::location::Clock::Timestamp(com::ubuntu::location::Clock::Duration(value));
> + Codec<T>::decode_argument(reader, in.value);
> + in.when = com::ubuntu::location::Clock::Timestamp(com::ubuntu::location::Clock::Duration(reader.pop_int64()));
> }
> };
> }
>
> === added directory 'include/location_service/com/ubuntu/location/connectivity'
> === added file 'include/location_service/com/ubuntu/location/connectivity/bounded_integer.h'
> --- include/location_service/com/ubuntu/location/connectivity/bounded_integer.h 1970-01-01 00:00:00 +0000
> +++ include/location_service/com/ubuntu/location/connectivity/bounded_integer.h 2014-06-24 16:02:38 +0000
> @@ -0,0 +1,209 @@
> +/*
> + * Copyright © 2012-2013 Canonical Ltd.
> + *
> + * This program is free software: you can redistribute it and/or modify it
> + * under the terms of the GNU Lesser General Public License version 3,
> + * 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 Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public License
> + * along with this program. If not, see <http://www.gnu.org/licenses/>.
> + *
> + * Authored by: Thomas Voß <thomas.voss at canonical.com>
> + */
> +#ifndef LOCATION_SERVICE_COM_UBUNTU_LOCATION_CONNECTIVITY_BOUNDED_INTEGER_H_
> +#define LOCATION_SERVICE_COM_UBUNTU_LOCATION_CONNECTIVITY_BOUNDED_INTEGER_H_
> +
> +#include <iostream>
> +#include <stdexcept>
> +
> +namespace com
> +{
> +namespace ubuntu
> +{
> +namespace location
> +{
> +namespace connectivity
> +{
> +/**
> + * @brief A helper class to handle bounded integer values, with an optional domain
> + * for tagging domain-specific types.
> + */
> +template<typename Tag, int min, int max, int inv = min-1>
> +class BoundedInteger
> +{
> +public:
> + static_assert(min < max, "min >= max");
> +
> + /**
> + * @brief Returns the invalid value for the specified range
> + */
> + inline static int invalid()
> + {
> + return inv;
> + }
> +
> + /**
> + * @brief Access the minimum value of the integer.
> + */
> + inline static int minimum()
> + {
> + return min;
> + }
> +
> + /**
> + * @brief Access the maximum value of the integer.
> + */
> + inline static int maximum()
> + {
> + return max;
> + }
> +
> + /**
> + * @brief Returns max - min.
> + */
> + inline static int range()
> + {
> + return max - min;
> + }
> +
> + /**
> + * @brief from_percent creates a new instance, mapping to the defined range of valid values.
> + */
> + inline static BoundedInteger<Tag, min, max, inv> from_percent(float percent)
> + {
> + // Capping to [0,1]
> + percent = std::min<float>(1., std::max<float>(0., percent));
> +
> + return BoundedInteger<Tag, min, max, inv>
> + {
> + static_cast<int>(minimum() + percent * range())
> + };
> + }
> +
> + /**
> + * @brief Constructs an invalid instance.
> + */
> + inline BoundedInteger() : value(min-1)
> + {
> + }
> +
> + /**
> + * @brief Constructs an instance from a raw value
> + * @param value The raw value.
> + * @throw std::runtime_error if value is not in [min, max].
> + */
> + inline explicit BoundedInteger(int value) : value(value)
> + {
> + if (value < min || value > max)
> + throw std::runtime_error(
> + std::to_string(value) + " is not in " + "[" +
> + std::to_string(min) + ", " + std::to_string(max) + "]");
> + }
> +
> + /**
> + * @brief Copy c'tor.
> + * @param rhs The instance to copy from.
> + */
> + inline BoundedInteger(const BoundedInteger<Tag, min, max, inv>& rhs) : value(rhs.value)
> + {
> + }
> +
> + /**
> + * @brief Assignment operator.
> + * @param rhs The instance to assign from.
> + * @return A mutable reference to this instance.
> + */
> + inline BoundedInteger<Tag, min, max, inv>& operator=(const BoundedInteger<Tag, min, max, inv>& rhs)
> + {
> + value = rhs.value;
> + return *this;
> + }
> +
> + /**
> + * @brief Equality comparison operator.
> + * @param rhs The instance to compare to.
> + * @return true iff both instances' value are equal.
> + */
> + inline bool operator==(const BoundedInteger<Tag, min, max, inv>& rhs) const
> + {
> + return value == rhs.value;
> + }
> +
> + /**
> + * @brief Implicit casting operator to a raw integer value.
> + * @return The raw integer value.
> + */
> + inline operator int() const
> + {
> + return get();
> + }
> +
> + /**
> + * @brief is_valid checks whether the contained value is in [min, max].
> + * @return true iff the contained integer value is in [min, max].
> + */
> + inline bool is_valid() const
> + {
> + return min <= value && value <= max;
> + }
> +
> + /**
> + * @brief Returns the raw integer value contained in this instance.
> + * @throw std::runtime_error if is_valid() returns false.
> + */
> + inline int get() const
> + {
> + return value;
> + }
> +
> + /**
> + * @brief Assigns a new raw integer value
> + * @param new_value The new value.
> + * @throw std::runtime_error if new_value is not in [min, max].
> + */
> + inline void set(int new_value)
> + {
> + if (new_value < min || new_value > max)
> + throw std::runtime_error(
> + std::to_string(new_value) + " is not in " + "[" +
> + std::to_string(min) + ", " + std::to_string(max) + "]");
> +
> + value = new_value;
> + }
> +
> + /** @brief Resets the instance to an invalid value. */
> + inline void reset()
> + {
> + value = invalid();
> + }
> +
> + /**
> + * @brief operator << pretty prints an instance of BoundedInteger.
> + * @param out The stream to print to.
> + * @param bi The instance to print.
> + * @return The stream that has been printed to.
> + */
> + inline friend std::ostream& operator<<(std::ostream& out, const BoundedInteger<Tag, min, max, inv>& bi)
> + {
> + out << bi.value;
> +
> + if (!bi.is_valid())
> + out << " -> invalid";
> +
> + return out;
> + }
> +
> +private:
> + int value;
> +};
> +}
> +}
> +}
> +}
> +
> +#endif // LOCATION_SERVICE_COM_UBUNTU_LOCATION_CONNECTIVITY_BOUNDED_INTEGER_H_
>
> === added file 'include/location_service/com/ubuntu/location/connectivity/manager.h'
> --- include/location_service/com/ubuntu/location/connectivity/manager.h 1970-01-01 00:00:00 +0000
> +++ include/location_service/com/ubuntu/location/connectivity/manager.h 2014-06-24 16:02:38 +0000
> @@ -0,0 +1,167 @@
> +/*
> + * Copyright © 2012-2013 Canonical Ltd.
Please update the copyright to 2014.
> + *
> + * This program is free software: you can redistribute it and/or modify it
> + * under the terms of the GNU Lesser General Public License version 3,
> + * 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 Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public License
> + * along with this program. If not, see <http://www.gnu.org/licenses/>.
> + *
> + * Authored by: Thomas Voß <thomas.voss at canonical.com>
> + */
> +#ifndef LOCATION_SERVICE_COM_UBUNTU_LOCATION_CONNECTIVITY_MANAGER_H_
> +#define LOCATION_SERVICE_COM_UBUNTU_LOCATION_CONNECTIVITY_MANAGER_H_
> +
> +#include <com/ubuntu/location/connectivity/radio_cell.h>
> +#include <com/ubuntu/location/connectivity/wireless_network.h>
> +
> +#include <core/property.h>
> +
> +#include <memory>
> +#include <string>
> +#include <vector>
> +
> +namespace com
> +{
> +namespace ubuntu
> +{
> +namespace location
> +{
> +namespace connectivity
> +{
> +/** @brief Enumerates all known system connectivity states. */
> +enum class State
> +{
> + /** The state is unknown. */
> + unknown,
> + /** The system is not connected to any network. */
> + none,
> + /** The system is behind a captive portal and cannot reach the full internet. */
> + portal,
> + /**
> + * The system is connected to a network, but does not appear to be able to reach
> + * the full internet.
> + */
> + limited,
> + /** The system is connected to a network, and appears to be able to reach the full internet. */
> + full
> +};
> +
> +/**
> + * @brief The Manager class encapsulates access to network/radio information
> + */
> +class Manager
> +{
> +public:
> + struct Errors
> + {
> + Errors() = delete;
> + /**
> + * @brief The ConnectivityManagementNotSupported struct is thrown if the underlying
> + * platform does not provide support for connectivity mgmt.
> + */
> + struct ConnectivityManagementNotSupported : public std::runtime_error
> + {
> + ConnectivityManagementNotSupported()
> + : std::runtime_error(
> + "Underlying platform does not provide support for connectivity mgmt.")
> + {
> + }
> + };
> + };
> +
> + /** @cond */
> + Manager(const Manager& rhs) = delete;
> + virtual ~Manager() = default;
> +
> + Manager& operator=(const Manager& rhs) = delete;
> + bool operator==(const Manager& rhs) const = delete;
> + /** @endcond */
> +
> + /**
> + * @brief Returns the getable/observable connectivity state of the system.
> + *
> + * Please note that this requires the underlying networking state to
> + * support connectivity state tracking. Right now, e.g. NetworkManager needs
> + * custom entries in /etc/NetworkManager/NetworkManager.conf to enable this
> + * functionality.
> + *
> + */
> + virtual const core::Property<State>& state() const = 0;
> +
> + /**
> + * @brief request_scan_for_wireless_networks schedules a scan for visible wireless networks.
> + * @throws std::runtime_error to indicate issues arising from the underlying networking stack.
> + *
> + * Please note that the implementation is required to operate asynchronously. Results of the scan
> + * are reported via emitting the changed() signal on the visible_wireless_networks() property.
> + *
> + * Please also note that calling this function is usually not required. The underlying
> + * networking stack is updating the list of available wireless networks very frequently.
> + * In addition, the results from scans requested by other system components are reported
> + * to consumers of this API, too.
> + *
> + */
> + virtual void request_scan_for_wireless_networks() = 0;
> +
> + /**
> + * @brief wireless_network_scan_finished is emitted when a scan for wireless networks ends.
> + *
> + * Please note that the signal may also be raised for scans that have been
> + * initiated by other system components.
> + *
> + */
> + virtual const core::Signal<>& wireless_network_scan_finished() const = 0;
> +
> + /**
> + * @brief wireless_network_added is emitted whenever a new wifi becomes visible.
> + */
> + virtual const core::Signal<WirelessNetwork::Ptr>& wireless_network_added() const = 0;
> +
> + /**
> + * @brief wireless_network_removed is emitted whenever a wifi disappears.
> + */
> + virtual const core::Signal<WirelessNetwork::Ptr>& wireless_network_removed() const = 0;
> +
> + /**
> + * @brief Enumerates all wireless networks visible to the device.
> + */
> + virtual void enumerate_visible_wireless_networks(const std::function<void(const WirelessNetwork::Ptr&)>&) const = 0;
> +
> + /**
> + * @brief connected_cell_added is emitted whenever the underlying modem connects to a new cell.
> + */
> + virtual const core::Signal<RadioCell::Ptr>& connected_cell_added() const = 0;
> +
> + /**
> + * @brief connected_cell_removed is emitted whenever the underlying modem disconnects from a cell.
> + */
> + virtual const core::Signal<RadioCell::Ptr>& connected_cell_removed() const = 0;
> +
> + /**
> + * @brief Enumerates all radio cells that the device is connected to.
> + */
> + virtual void enumerate_connected_radio_cells(const std::function<void(const RadioCell::Ptr&)>&) const = 0;
> +
> +protected:
> + Manager() = default;
> +};
> +
> +/**
> + * @brief Provides access to a platform-specific implementation/instance of a connectivity manager.
> + * @throw Manager::Errors::ConnectivityManagementNotSupported.
> + * @return An instance of a connectivity manager.
> + */
> +const std::shared_ptr<Manager>& platform_default_manager();
> +}
> +}
> +}
> +}
> +
> +#endif // LOCATION_SERVICE_COM_UBUNTU_LOCATION_CONNECTIVITY_MANAGER_H_
>
> === added file 'include/location_service/com/ubuntu/location/connectivity/radio_cell.h'
> --- include/location_service/com/ubuntu/location/connectivity/radio_cell.h 1970-01-01 00:00:00 +0000
> +++ include/location_service/com/ubuntu/location/connectivity/radio_cell.h 2014-06-24 16:02:38 +0000
> @@ -0,0 +1,283 @@
> +/*
> + * Copyright © 2012-2013 Canonical Ltd.
> + *
Update the copyright to 2014.
> + * This program is free software: you can redistribute it and/or modify it
> + * under the terms of the GNU Lesser General Public License version 3,
> + * 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 Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public License
> + * along with this program. If not, see <http://www.gnu.org/licenses/>.
> + *
> + * Authored by: Thomas Voß <thomas.voss at canonical.com>
> + */
> +#ifndef LOCATION_SERVICE_COM_UBUNTU_LOCATION_CONNECTIVITY_RADIO_CELL_H_
> +#define LOCATION_SERVICE_COM_UBUNTU_LOCATION_CONNECTIVITY_RADIO_CELL_H_
> +
> +#include <com/ubuntu/location/connectivity/bounded_integer.h>
> +
> +#include <core/signal.h>
> +
> +#include <limits>
> +#include <memory>
> +
> +namespace com
> +{
> +namespace ubuntu
> +{
> +namespace location
> +{
> +namespace connectivity
> +{
> +/** @brief Models a radio cell that one of the modems in the system is connected to. */
> +struct RadioCell
> +{
> + /** @cond */
> + typedef std::shared_ptr<RadioCell> Ptr;
> + /** @endcond */
> +
> + /** @brief Enumerates the known technologies. */
> + enum class Type
> + {
> + unknown,
> + gsm,
> + umts,
> + lte
> + };
> +
> + /** @cond */
> + struct Mcc {};
> + struct Mnc {};
> + struct Lac {};
> + struct Id {};
> + struct Psc {};
> + struct Pid {};
> + struct Rss {};
> + struct Asu {};
> + struct Ta {};
> +
> + template<int min, int max, int invalid = min-1>
> + using MobileCountryCode = BoundedInteger<Mcc, min, max, invalid>;
> + template<int min, int max, int invalid = min-1>
> + using MobileNetworkCode = BoundedInteger<Mnc, min, max, invalid>;
> + template<int min, int max, int invalid = min-1>
> + using LocationAreaCode = BoundedInteger<Lac, min, max, invalid>;
> + template<int min, int max, int invalid = min-1>
> + using TrackingAreaCode = BoundedInteger<Lac, min, max, invalid>;
> + template<int min, int max, int invalid = min-1>
> + using CellId = BoundedInteger<Id, min, max, invalid>;
> + template<int min, int max, int invalid = min-1>
> + using PrimaryScramblingCode = BoundedInteger<Psc, min, max, invalid>;
> + template<int min, int max, int invalid = min-1>
> + using PhysicalId = BoundedInteger<Pid, min, max, invalid>;
> + template<int min, int max, int invalid = min-1>
> + using ReceivedSignalStrength = BoundedInteger<Rss, min, max, invalid>;
> + template<int min, int max, int invalid = min-1>
> + using ArbitraryStrengthUnit = BoundedInteger<Asu, min, max, invalid>;
> + template<int min, int max, int invalid = min-1>
> + using TimingAdvance = BoundedInteger<Ta, min, max, invalid>;
> + /** @endcond */
> +
> + /** @brief Models a GSM radio cell. */
> + struct Gsm
> + {
> + /** 3-digit Mobile Country Code, 0..999, INT_MAX if unknown */
> + typedef MobileCountryCode
> + <
> + 0,
> + 999,
> + std::numeric_limits<int>::max()
> + > MCC;
> + /** 2 or 3-digit Mobile Network Code, 0..999, INT_MAX if unknown */
> + typedef MobileNetworkCode
> + <
> + 0,
> + 999,
> + std::numeric_limits<int>::max()
> + > MNC;
> + /** 16-bit Location Area Code, 0..65535, INT_MAX if unknown */
> + typedef LocationAreaCode
> + <
> + 0,
> + 65535,
> + std::numeric_limits<int>::max()
> + > LAC;
> + /** 16-bit GSM Cell Identity described in TS 27.007, 0..65535, INT_MAX if unknown */
> + typedef CellId
> + <
> + 0,
> + 65535,
> + std::numeric_limits<int>::max()
> + > ID;
> +
> + /** Valid values are (0-31, 99) as defined in TS 27.007 8.5 */
> + typedef ArbitraryStrengthUnit
> + <
> + 0,
> + 31,
> + 99
> + > SignalStrength;
> +
> + MCC mobile_country_code;
> + MNC mobile_network_code;
> + LAC location_area_code;
> + ID id;
> + SignalStrength strength;
> + };
> +
> + /** @brief Models a UMTS radio cell. */
> + struct Umts
> + {
> + /** 3-digit Mobile Country Code, 0..999, INT_MAX if unknown */
> + typedef MobileCountryCode
> + <
> + 0,
> + 999,
> + std::numeric_limits<int>::max()
> + > MCC;
> + /** 2 or 3-digit Mobile Network Code, 0..999, INT_MAX if unknown */
> + typedef MobileNetworkCode
> + <
> + 0,
> + 999,
> + std::numeric_limits<int>::max()
> + > MNC;
> + /** 16-bit Location Area Code, 0..65535, INT_MAX if unknown */
> + typedef LocationAreaCode
> + <
> + 0,
> + 65535,
> + std::numeric_limits<int>::max()
> + > LAC;
> + /** 28-bit UMTS Cell Identity described in TS 25.331, 0..268435455, INT_MAX if unknown */
> + typedef CellId
> + <
> + 0,
> + 268435455,
> + std::numeric_limits<int>::max()
> + > ID;
> + /** Valid values are (0-31, 99) as defined in TS 27.007 8.5 */
> + typedef ArbitraryStrengthUnit
> + <
> + 0,
> + 31,
> + 99
> + > SignalStrength;
> +
> + MCC mobile_country_code;
> + MNC mobile_network_code;
> + LAC location_area_code;
> + ID id;
> + SignalStrength strength;
> + };
> +
> + /** @brief Models an LTE radio cell. */
> + struct Lte
> + {
> + /** 3-digit Mobile Country Code, 0..999, INT_MAX if unknown */
> + typedef MobileCountryCode
> + <
> + 0,
> + 999,
> + std::numeric_limits<int>::max()
> + > MCC;
> + /** 2 or 3-digit Mobile Network Code, 0..999, INT_MAX if unknown */
> + typedef MobileNetworkCode
> + <
> + 0,
> + 999,
> + std::numeric_limits<int>::max()
> + > MNC;
> + /** 16-bit Tracking Area Code, 0..65535, INT_MAX if unknown */
> + typedef TrackingAreaCode
> + <
> + 0,
> + 65535,
> + std::numeric_limits<int>::max()
> + > TAC;
> + /** 28-bit Cell Identity described in TS 25.331, 0..268435455, INT_MAX if unknown */
> + typedef CellId
> + <
> + 0,
> + 268435455,
> + std::numeric_limits<int>::max()
> + > ID;
> + /** Physical cell id, 0..503, INT_MAX if unknown */
> + typedef PhysicalId
> + <
> + 0,
> + 503,
> + std::numeric_limits<int>::max()
> + > PID;
> + /** Valid values are (0-31, 99) as defined in TS 27.007 8.5 */
> + typedef ArbitraryStrengthUnit
> + <
> + 0,
> + 31,
> + 99
> + > SignalStrength;
> +
> + MCC mobile_country_code;
> + MNC mobile_network_code;
> + TAC tracking_area_code;
> + ID id;
> + PID physical_id;
> + SignalStrength strength;
> + };
> +
> + RadioCell() = default;
> + virtual ~RadioCell() = default;
> +
> + RadioCell(const RadioCell& rhs) = delete;
> + RadioCell& operator=(const RadioCell& rhs) = delete;
> +
> + /** @brief Emitted when the cell details change. */
> + virtual const core::Signal<>& changed() const = 0;
> +
> + /** @brief Returns the type of the radio cell. */
> + virtual Type type() const = 0;
> +
> + /** @brief Returns GSM-specific details or throws std::runtime_error if this is not a GSM radiocell. */
> + virtual const Gsm& gsm() const = 0;
> +
> + /** @brief Returns UMTS-specific details or throws std::runtime_error if this is not a UMTS radiocell. */
> + virtual const Umts& umts() const = 0;
> +
> + /** @brief Returns LTE-specific details or throws std::runtime_error if this is not an LTE radiocell. */
> + virtual const Lte& lte() const = 0;
> +};
> +
> +/** @brief Returns true iff lhs equals rhs. */
> +bool operator==(const RadioCell::Gsm& lhs, const RadioCell::Gsm& rhs);
> +
> +/** @brief Pretty-prints the given gsm details to the given output stream. */
> +std::ostream& operator<<(std::ostream& out, const RadioCell::Gsm& gsm);
> +
> +/** @brief Returns true iff lhs equals rhs. */
> +bool operator==(const RadioCell::Umts& lhs, const RadioCell::Umts& rhs);
> +
> +/** @brief Pretty-prints the given umts details to the given output stream. */
> +std::ostream& operator<<(std::ostream& out, const RadioCell::Umts& umts);
> +
> +/** @brief Returns true iff lhs equals rhs. */
> +bool operator==(const RadioCell::Lte& lhs, const RadioCell::Lte& rhs);
> +
> +/** @brief Pretty-prints the given gsm details to the given output stream. */
> +std::ostream& operator<<(std::ostream& out, const RadioCell::Lte& lte);
> +
> +/** @brief Returns true iff lhs equals rhs. */
> +bool operator==(const RadioCell& lhs, const RadioCell& rhs);
> +
> +/** @brief Pretty-prints the given cell to the given output stream. */
> +std::ostream& operator<<(std::ostream& out, const RadioCell& cell);
> +}
> +}
> +}
> +}
> +
> +#endif // LOCATION_SERVICE_COM_UBUNTU_LOCATION_CONNECTIVITY_RADIO_CELL_H_
> +
>
> === added file 'include/location_service/com/ubuntu/location/connectivity/wireless_network.h'
> --- include/location_service/com/ubuntu/location/connectivity/wireless_network.h 1970-01-01 00:00:00 +0000
> +++ include/location_service/com/ubuntu/location/connectivity/wireless_network.h 2014-06-24 16:02:38 +0000
> @@ -0,0 +1,117 @@
> +/*
> + * Copyright © 2012-2013 Canonical Ltd.
> + *
Update the copyright to 2014.
> + * This program is free software: you can redistribute it and/or modify it
> + * under the terms of the GNU Lesser General Public License version 3,
> + * 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 Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public License
> + * along with this program. If not, see <http://www.gnu.org/licenses/>.
> + *
> + * Authored by: Thomas Voß <thomas.voss at canonical.com>
> + */
> +#ifndef LOCATION_SERVICE_COM_UBUNTU_LOCATION_CONNECTIVITY_WIRELESS_NETWORK_H_
> +#define LOCATION_SERVICE_COM_UBUNTU_LOCATION_CONNECTIVITY_WIRELESS_NETWORK_H_
> +
> +#include <com/ubuntu/location/connectivity/bounded_integer.h>
> +
> +#include <core/property.h>
> +
> +#include <iosfwd>
> +#include <string>
> +
> +namespace com
> +{
> +namespace ubuntu
> +{
> +namespace location
> +{
> +namespace connectivity
> +{
> +struct WirelessNetwork
> +{
> + typedef std::shared_ptr<WirelessNetwork> Ptr;
> +
> + /** @brief Enumerates all known operational modes of networks/aps. */
> + enum class Mode
> + {
> + /** Mode is unknown. */
> + unknown = 0,
> + /** Indicates the object is part of an Ad-Hoc 802.11 network without a central coordinating access point. */
> + adhoc = 1,
> + /** The wireless device or access point is in infrastructure mode. */
> + infrastructure = 2
> + };
> +
> + /** @cond */
> + struct Tag
> + {
> + /** @brief Tags a frequency measurement for a wireless network. */
> + struct Frequency {};
> + /** @brief Tags the signal strength of a wireless network. */
> + struct SignalStrength {};
> + };
> + /** @endcond */
> +
> + /** Frequency that an individual AP operates on. */
> + typedef BoundedInteger
> + <
> + Tag::Frequency,
> + 2412,
> + 5825
> + > Frequency;
> +
> + /** Strength of signal for an individual AP. */
> + typedef BoundedInteger
> + <
> + Tag::SignalStrength,
> + 0,
> + 100
> + > SignalStrength;
> +
> + /** @cond */
> + WirelessNetwork() = default;
> + WirelessNetwork(const WirelessNetwork&) = delete;
> + WirelessNetwork(WirelessNetwork&&) = delete;
> +
> + virtual ~WirelessNetwork() = default;
> +
> + WirelessNetwork& operator=(const WirelessNetwork&) = delete;
> + WirelessNetwork& operator=(WirelessNetwork&&) = delete;
> + /** @endcond */
> +
> + /** @brief Timestamp when the network became visible. */
> + virtual const core::Property<std::chrono::system_clock::time_point>& last_seen() const = 0;
> +
> + /** @brief Returns the BSSID of the network */
> + virtual const core::Property<std::string>& bssid() const = 0;
> +
> + /** @brief Returns the SSID of the network. */
> + virtual const core::Property<std::string>& ssid() const = 0;
> +
> + /** @brief Returns the mode of the network. */
> + virtual const core::Property<Mode>& mode() const = 0;
> +
> + /** @brief Returns the frequency that the network/AP operates upon. */
> + virtual const core::Property<Frequency>& frequency() const = 0;
> +
> + /** @brief Returns the signal quality of the network/AP in percent. */
> + virtual const core::Property<SignalStrength>& signal_strength() const = 0;
> +};
> +
> +/** @brief Pretty-prints the given mode to the given output stream. */
> +std::ostream& operator<<(std::ostream& out, WirelessNetwork::Mode mode);
> +
> +/** @brief Pretty-prints the given wireless network to the given output stream. */
> +std::ostream& operator<<(std::ostream& out, const WirelessNetwork& wifi);
> +}
> +}
> +}
> +}
> +
> +#endif // LOCATION_SERVICE_COM_UBUNTU_LOCATION_CONNECTIVITY_WIRELESS_NETWORK_H_
>
> === modified file 'include/location_service/com/ubuntu/location/criteria.h'
> --- include/location_service/com/ubuntu/location/criteria.h 2013-05-28 14:41:06 +0000
> +++ include/location_service/com/ubuntu/location/criteria.h 2014-06-24 16:02:38 +0000
> @@ -18,16 +18,8 @@
> #ifndef LOCATION_SERVICE_COM_UBUNTU_LOCATION_CRITERIA_H_
> #define LOCATION_SERVICE_COM_UBUNTU_LOCATION_CRITERIA_H_
>
> -#include "com/ubuntu/location/accuracy.h"
> -#include "com/ubuntu/location/heading.h"
> -#include "com/ubuntu/location/velocity.h"
> -#include "com/ubuntu/location/wgs84/altitude.h"
> -#include "com/ubuntu/location/wgs84/latitude.h"
> -#include "com/ubuntu/location/wgs84/longitude.h"
> -
> -#include <limits>
> -#include <ostream>
> -#include <stdexcept>
> +#include <com/ubuntu/location/optional.h>
> +#include <com/ubuntu/location/units/units.h>
>
> namespace com
> {
> @@ -35,22 +27,40 @@
> {
> namespace location
> {
> +/**
> + * @brief Summarizes criteria of a client session with respect to functionality
> + * and accuracy for position, velocity and heading measurements.
> + */
> struct Criteria
> {
> - Criteria() : latitude_accuracy(),
> - longitude_accuracy(),
> - altitude_accuracy(),
> - velocity_accuracy(),
> - heading_accuracy()
> - {
> - }
> -
> - Accuracy<wgs84::Latitude> latitude_accuracy;
> - Accuracy<wgs84::Longitude> longitude_accuracy;
> - Accuracy<wgs84::Altitude> altitude_accuracy;
> - Accuracy<Velocity> velocity_accuracy;
> - Accuracy<Heading> heading_accuracy;
> + /**
> + * @brief satisfies checks whether this instance also satisfies another criteria instance.
> + * @param rhs The other criteria instance
> + * @return true iff this instance also satisfies the other instance, else false.
> + */
> + bool satisfies(const Criteria& rhs) const;
> +
> + struct Requires
> + {
> + bool position = true; ///< The client needs position measurements.
> + bool altitude = false; ///< The client needs altitude measurements.
> + bool velocity = false; ///< The client needs velocity measurments.
> + bool heading = false; ///< The client needs heading measurements.
> + } requires = Requires{};
> +
> + struct Accuracy
> + {
> + units::Quantity<units::Length> horizontal = 3000 * units::Meters; ///< The client requires measurements of at least this horizontal accuracy.
> + Optional<units::Quantity<units::Length>> vertical; ///< The client requires measurements of at least this vertical accuracy.
> + Optional<units::Quantity<units::Velocity>> velocity; ///< The client requires measurements of at least this velocity accuracy.
> + Optional<units::Quantity<units::PlaneAngle>> heading; ///< The client requires measurements of at least this heading accuracy.
> + } accuracy = Accuracy{};
> };
> +
> +/**
> + * @brief operator + merges lhs and rhs such that satisfying the new criteria satisfies lhs and rhs.
> + */
> +Criteria operator+(const Criteria& lhs, const Criteria& rhs);
> }
> }
> }
>
> === modified file 'include/location_service/com/ubuntu/location/default_provider_selection_policy.h'
> --- include/location_service/com/ubuntu/location/default_provider_selection_policy.h 2013-05-28 14:41:06 +0000
> +++ include/location_service/com/ubuntu/location/default_provider_selection_policy.h 2014-06-24 16:02:38 +0000
> @@ -18,7 +18,7 @@
> #ifndef LOCATION_SERVICE_COM_UBUNTU_DEFAULT_PROVIDER_SELECTION_POLICY_H_
> #define LOCATION_SERVICE_COM_UBUNTU_DEFAULT_PROVIDER_SELECTION_POLICY_H_
>
> -#include "com/ubuntu/location/provider_selection_policy.h"
> +#include <com/ubuntu/location/provider_selection_policy.h>
>
> namespace com
> {
> @@ -32,21 +32,21 @@
> DefaultProviderSelectionPolicy();
> ~DefaultProviderSelectionPolicy() noexcept;
>
> - ProviderSelection determine_provider_selection_from_set_for_criteria(
> + ProviderSelection determine_provider_selection_for_criteria(
> const Criteria& criteria,
> - const std::set<Provider::Ptr>& providers);
> + const ProviderEnumerator& enumerator);
>
> Provider::Ptr determine_position_updates_provider(
> const Criteria& criteria,
> - const std::set<Provider::Ptr>& providers);
> + const ProviderEnumerator& enumerator);
>
> Provider::Ptr determine_heading_updates_provider(
> const Criteria& criteria,
> - const std::set<Provider::Ptr>& providers);
> + const ProviderEnumerator& enumerator);
>
> Provider::Ptr determine_velocity_updates_provider(
> const Criteria& criteria,
> - const std::set<Provider::Ptr>& providers);
> + const ProviderEnumerator& enumerator);
> };
> }
> }
>
> === modified file 'include/location_service/com/ubuntu/location/engine.h'
> --- include/location_service/com/ubuntu/location/engine.h 2013-05-28 14:41:06 +0000
> +++ include/location_service/com/ubuntu/location/engine.h 2014-06-24 16:02:38 +0000
> @@ -18,10 +18,16 @@
> #ifndef LOCATION_SERVICE_COM_UBUNTU_LOCATION_ENGINE_H_
> #define LOCATION_SERVICE_COM_UBUNTU_LOCATION_ENGINE_H_
>
> -#include "com/ubuntu/location/criteria.h"
> -#include "com/ubuntu/location/provider.h"
> -#include "com/ubuntu/location/provider_selection_policy.h"
> -
> +#include <com/ubuntu/location/provider.h>
> +#include <com/ubuntu/location/provider_enumerator.h>
> +#include <com/ubuntu/location/provider_selection.h>
> +#include <com/ubuntu/location/satellite_based_positioning_state.h>
> +#include <com/ubuntu/location/space_vehicle.h>
> +#include <com/ubuntu/location/wifi_and_cell_reporting_state.h>
> +
> +#include <core/property.h>
> +
> +#include <mutex>
> #include <set>
>
> namespace com
> @@ -30,26 +36,118 @@
> {
> namespace location
> {
> -class Engine
> +struct Criteria;
> +class ProviderSelectionPolicy;
> +/**
> + * @brief The Engine class encapsulates a positioning engine, relying on a set
> + * of providers and reporters to acquire and publish location information.
> + */
> +class Engine : public ProviderEnumerator
> {
> public:
> typedef std::shared_ptr<Engine> Ptr;
>
> - Engine(const std::set<Provider::Ptr>& initial_providers,
> - const ProviderSelectionPolicy::Ptr& provider_selection_policy);
> + /**
> + * @brief The State enum models the current state of the engine
> + */
> + enum class Status
> + {
> + off, ///< The engine is currently offline.
> + on, ///< The engine and providers are powered on but not navigating.
> + active ///< The engine and providers are powered on and navigating.
> + };
> +
> + /**
> + * @brief The Configuration struct summarizes the state of the engine.
> + */
> + struct Configuration
> + {
> + /** Setable/getable/observable property for the satellite based positioning state. */
> + core::Property<SatelliteBasedPositioningState> satellite_based_positioning_state
> + {
> + SatelliteBasedPositioningState::on
> + };
> + /** Setable/getable/observable property for the satellite based positioning state. */
> + core::Property<WifiAndCellIdReportingState> wifi_and_cell_id_reporting_state
> + {
> + WifiAndCellIdReportingState::off
> + };
> + /** Setable/getable/observable property for the overall engine state. */
> + core::Property<Engine::Status> engine_state
> + {
> + Engine::Status::on
> + };
> + };
> +
> + /** @brief Summarizes all updates delivered via the engine. */
> + struct Updates
> + {
> + /** The current best known reference location */
> + core::Property<Update<Position>> reference_location{};
> + /** The current best known velocity estimate. */
> + core::Property<Update<Velocity>> reference_velocity{};
> + /** The current best known heading estimate. */
> + core::Property<Update<Heading>> reference_heading{};
> + /** The current set of visible SpaceVehicles. */
> + core::Property<std::map<SpaceVehicle::Key, SpaceVehicle>> visible_space_vehicles{};
> + };
> +
> + Engine(const std::shared_ptr<ProviderSelectionPolicy>& provider_selection_policy);
> Engine(const Engine&) = delete;
> Engine& operator=(const Engine&) = delete;
> - virtual ~Engine() = default;
> + virtual ~Engine();
>
> + /**
> + * @brief Calculates a set of providers that satisfies the given criteria.
> + * @param [in] criteria The criteria to be satisfied by the returned provider selection.
> + * @return A provider selection that satisfies the given criteria.
> + */
> virtual ProviderSelection determine_provider_selection_for_criteria(const Criteria& criteria);
>
> + /**
> + * @brief Checks if the engine knows about a specific provider.
> + * @return True iff the engine knows about the provider.
> + */
> virtual bool has_provider(const Provider::Ptr& provider) noexcept;
> +
> + /**
> + * @brief Makes a provider known to the engine.
> + * @param provider The new provider.
> + */
> virtual void add_provider(const Provider::Ptr& provider);
> +
> + /**
> + * @brief Removes a provider from the engine.
> + * @param provider The provider to be removed.
> + */
> virtual void remove_provider(const Provider::Ptr& provider) noexcept;
>
> + /**
> + * @brief Iterates all known providers and invokes the provided enumerator for each of them.
> + * @param enumerator The functor to be invoked for each provider.
> + */
> + virtual void for_each_provider(const std::function<void(const Provider::Ptr&)>& enumerator) const noexcept;
> +
> + /** @brief The engine's configuration. */
> + Configuration configuration;
> +
> + /** @brief All updates distributed via the engine. */
> + Updates updates;
> +
> private:
> - std::set<Provider::Ptr> providers;
> - ProviderSelectionPolicy::Ptr provider_selection_policy;
> + struct ProviderConnections
> + {
> + core::ScopedConnection reference_location_updates;
> + core::ScopedConnection reference_velocity_updates;
> + core::ScopedConnection reference_heading_updates;
> + core::ScopedConnection wifi_and_cell_id_reporting_state_updates;
> + core::ScopedConnection space_vehicle_visibility_updates;
> + core::ScopedConnection provider_position_updates;
> + };
> +
> + mutable std::mutex guard;
> + std::map<Provider::Ptr, ProviderConnections> providers;
> + std::shared_ptr<ProviderSelectionPolicy> provider_selection_policy;
> };
> }
> }
>
> === modified file 'include/location_service/com/ubuntu/location/heading.h'
> --- include/location_service/com/ubuntu/location/heading.h 2013-05-28 14:41:06 +0000
> +++ include/location_service/com/ubuntu/location/heading.h 2014-06-24 16:02:38 +0000
> @@ -18,12 +18,7 @@
> #ifndef LOCATION_SERVICE_COM_UBUNTU_LOCATION_HEADING_H_
> #define LOCATION_SERVICE_COM_UBUNTU_LOCATION_HEADING_H_
>
> -#include "com/ubuntu/location/accuracy.h"
> -#include "com/ubuntu/location/units/units.h"
> -
> -#include <limits>
> -#include <ostream>
> -#include <stdexcept>
> +#include <com/ubuntu/location/units/units.h>
>
> namespace com
> {
> @@ -31,74 +26,8 @@
> {
> namespace location
> {
> -struct Heading
> -{
> - typedef units::PlaneAngle Unit;
> - typedef units::Quantity<Unit> Quantity;
> -
> - static const Quantity& min()
> - {
> - static const auto instance = Heading::Quantity::from_value(0.);
> - return instance;
> - }
> - static const Quantity& max()
> - {
> - static const auto instance = Heading::Quantity::from_value(360.);
> - return instance;
> - }
> -
> - Heading(const Quantity& value = Quantity()) : value(value)
> - {
> - if (value < min())
> - throw std::out_of_range("");
> - if (value > max())
> - throw std::out_of_range("");
> - }
> -
> - bool operator==(const Heading& rhs) const
> - {
> - return value == rhs.value;
> - }
> -
> - bool operator!=(const Heading& rhs) const
> - {
> - return value != rhs.value;
> - }
> -
> - Quantity value;
> -};
> -
> -inline std::ostream& operator<<(std::ostream& out, const Heading& heading)
> -{
> - out << "Heading(" << heading.value << ")";
> - return out;
> -}
> -
> -template<>
> -struct AccuracyTraits<Heading>
> -{
> - static AccuracyLevel classify(const Heading& h)
> - {
> - static const auto half = 0.5 * Heading::max();
> - if(h.value > half)
> - return AccuracyLevel::worst;
> -
> - if(h.value < half)
> - return AccuracyLevel::best;
> -
> - return AccuracyLevel::worst;
> - }
> -
> - static Accuracy<Heading> best()
> - {
> - return Accuracy<Heading>{Heading{Heading::min()}};
> - }
> -
> - static Accuracy<Heading> worst()
> - {
> - return Accuracy<Heading>{Heading{Heading::max()}};
> - }
> -};
> +/** Heading is measured in ° deviation from true north. */
> +typedef units::Quantity<units::PlaneAngle> Heading;
> }
> }
> }
>
> === modified file 'include/location_service/com/ubuntu/location/logging.h'
> --- include/location_service/com/ubuntu/location/logging.h 2013-05-28 14:41:06 +0000
> +++ include/location_service/com/ubuntu/location/logging.h 2014-06-24 16:02:38 +0000
> @@ -19,6 +19,7 @@
> #define LOCATION_SERVICE_COM_UBUNTU_LOCATION_LOGGING_H_
>
> #include <glog/logging.h>
> +#include <glog/vlog_is_on.h>
>
> #endif // LOCATION_SERVICE_COM_UBUNTU_LOCATION_LOGGING_H_
>
>
> === added file 'include/location_service/com/ubuntu/location/optional.h'
> --- include/location_service/com/ubuntu/location/optional.h 1970-01-01 00:00:00 +0000
> +++ include/location_service/com/ubuntu/location/optional.h 2014-06-24 16:02:38 +0000
> @@ -0,0 +1,35 @@
> +/*
> + * Copyright © 2012-2013 Canonical Ltd.
> + *
Update the copyright to 2014.
> + * This program is free software: you can redistribute it and/or modify it
> + * under the terms of the GNU Lesser General Public License version 3,
> + * 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 Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public License
> + * along with this program. If not, see <http://www.gnu.org/licenses/>.
> + *
> + * Authored by: Thomas Voß <thomas.voss at canonical.com>
> + */
> +#ifndef LOCATION_SERVICE_COM_UBUNTU_LOCATION_OPTIONAL_H_
> +#define LOCATION_SERVICE_COM_UBUNTU_LOCATION_OPTIONAL_H_
> +
> +#include <boost/optional.hpp>
> +
> +namespace com
> +{
> +namespace ubuntu
> +{
> +namespace location
> +{
> +template<typename T>
> +using Optional = boost::optional<T>;
> +}
> +}
> +}
> +
> +#endif // LOCATION_SERVICE_COM_UBUNTU_LOCATION_OPTIONAL_H_
>
> === modified file 'include/location_service/com/ubuntu/location/position.h'
> --- include/location_service/com/ubuntu/location/position.h 2013-05-28 14:41:06 +0000
> +++ include/location_service/com/ubuntu/location/position.h 2014-06-24 16:02:38 +0000
> @@ -18,9 +18,11 @@
> #ifndef LOCATION_SERVICE_COM_UBUNTU_LOCATION_POSITION_H_
> #define LOCATION_SERVICE_COM_UBUNTU_LOCATION_POSITION_H_
>
> -#include "com/ubuntu/location/wgs84/altitude.h"
> -#include "com/ubuntu/location/wgs84/latitude.h"
> -#include "com/ubuntu/location/wgs84/longitude.h"
> +#include <com/ubuntu/location/wgs84/altitude.h>
> +#include <com/ubuntu/location/wgs84/latitude.h>
> +#include <com/ubuntu/location/wgs84/longitude.h>
> +
> +#include <com/ubuntu/location/optional.h>
>
> #include <bitset>
> #include <ostream>
> @@ -31,54 +33,33 @@
> {
> namespace location
> {
> -class Position
> +/**
> + * @brief The Position struct models a position in the wgs84 coordinate system.
> + */
> +struct Position
> {
> - public:
> - enum Flag
> + struct Accuracy
> {
> - latitude_flag = 0,
> - longitude_flag = 1,
> - altitude_flag = 2
> + typedef units::Quantity<units::Length> Horizontal;
> + typedef units::Quantity<units::Length> Vertical;
> +
> + Optional<Horizontal> horizontal{};
> + Optional<Vertical> vertical{};
> };
>
> - typedef std::bitset<3> Flags;
> -
> - Position();
> - Position(
> - const wgs84::Latitude& latitude,
> - const wgs84::Longitude& longitude);
> - Position(
> - const wgs84::Latitude& latitude,
> - const wgs84::Longitude& longitude,
> - const wgs84::Altitude& altitude);
> + Position() = default;
> + Position(const wgs84::Latitude&, const wgs84::Longitude&);
> + Position(const wgs84::Latitude&, const wgs84::Longitude&, const wgs84::Altitude&);
> + Position(const wgs84::Latitude&, const wgs84::Longitude&, const wgs84::Altitude&, const units::Quantity<units::Length>& hor_acc);
> + Position(const wgs84::Latitude&, const wgs84::Longitude&, const wgs84::Altitude&, const units::Quantity<units::Length>& hor_acc, const units::Quantity<units::Length>& ver_acc);
>
> bool operator==(const Position& rhs) const;
> bool operator!=(const Position& rhs) const;
>
> - const Flags& flags() const;
> -
> - bool has_latitude() const;
> - Position& latitude(const wgs84::Latitude& lat);
> - const wgs84::Latitude& latitude() const;
> -
> - bool has_longitude() const;
> - Position& longitude(const wgs84::Longitude& lon);
> - const wgs84::Longitude& longitude() const;
> -
> - bool has_altitude() const;
> - Position& altitude(const wgs84::Altitude& alt);
> - const wgs84::Altitude& altitude() const;
> -
> - private:
> - template<typename> friend struct Codec;
> -
> - struct
> - {
> - Flags flags;
> - wgs84::Latitude latitude;
> - wgs84::Longitude longitude;
> - wgs84::Altitude altitude;
> - } fields;
> + wgs84::Latitude latitude = wgs84::Latitude{};
> + wgs84::Longitude longitude = wgs84::Longitude{};
> + Optional<wgs84::Altitude> altitude = Optional<wgs84::Altitude>{};
> + Accuracy accuracy{};
> };
>
> std::ostream& operator<<(std::ostream& out, const Position& position);
>
> === modified file 'include/location_service/com/ubuntu/location/provider.h'
> --- include/location_service/com/ubuntu/location/provider.h 2013-05-28 14:41:06 +0000
> +++ include/location_service/com/ubuntu/location/provider.h 2014-06-24 16:02:38 +0000
> @@ -18,12 +18,16 @@
> #ifndef LOCATION_SERVICE_COM_UBUNTU_LOCATION_PROVIDER_H_
> #define LOCATION_SERVICE_COM_UBUNTU_LOCATION_PROVIDER_H_
>
> -#include "com/ubuntu/location/channel.h"
> -#include "com/ubuntu/location/criteria.h"
> -#include "com/ubuntu/location/heading.h"
> -#include "com/ubuntu/location/position.h"
> -#include "com/ubuntu/location/update.h"
> -#include "com/ubuntu/location/velocity.h"
> +#include <com/ubuntu/location/criteria.h>
> +#include <com/ubuntu/location/heading.h>
> +#include <com/ubuntu/location/position.h>
> +#include <com/ubuntu/location/space_vehicle.h>
> +#include <com/ubuntu/location/update.h>
> +#include <com/ubuntu/location/velocity.h>
> +#include <com/ubuntu/location/wifi_and_cell_reporting_state.h>
> +
> +#include <core/property.h>
> +#include <core/signal.h>
>
> #include <atomic>
> #include <bitset>
> @@ -35,97 +39,125 @@
> {
> namespace location
> {
> +/**
> + * @brief The Provider class is the abstract base of all positioning providers.
> + */
> class Provider
> {
> public:
> typedef std::shared_ptr<Provider> Ptr;
>
> - enum class Feature : std::size_t
> - {
> - position,
> - velocity,
> - heading
> - };
> -
> - typedef std::bitset<3> FeatureFlags;
> -
> - enum class Requirement : std::size_t
> - {
> - satellites,
> - cell_network,
> - data_network,
> - monetary_spending
> - };
> -
> - typedef std::bitset<4> RequirementFlags;
> -
> + /**
> + * @brief Enumerates the known features that can be supported by providers.
> + */
> + enum class Features : std::size_t
> + {
> + none = 0, ///< The provider does not support any feature.
> + position = 1 << 0, ///< The provider features position updates.
> + velocity = 1 << 1, ///< The provider features velocity updates.
> + heading = 1 << 2 ///< The provider features heading updates.
> + };
> +
> + /**
> + * @brief Enumerates the requirements of a provider implementation.
> + */
> + enum class Requirements : std::size_t
> + {
> + none = 0, ///< The provider does not require anything.
> + satellites = 1 << 0, ///< The provider requires satellites to be visible.
> + cell_network = 1 << 1, ///< The provider requires a cell-network to work correctly.
> + data_network = 1 << 2, ///< The provider requires a data-network to work correctly.
> + monetary_spending = 1 << 3 ///< Using the provider results in monetary cost.
> + };
> +
> + /**
> + * @brief Facade for controlling the state of position/heading/velocity updates.
> + *
> + * Multiple observers can request state changes for updates. This class ensures
> + * that the specific updates are started and stopped if at least one observer
> + * requests them and stopped when the last observer issues a stop request.
> + */
> class Controller
> {
> public:
> typedef std::shared_ptr<Controller> Ptr;
>
> - template<typename T>
> - class Cache
> - {
> - public:
> - Cache() : d{ T{}, false }
> - {
> - }
> - const T& value() const { return d.value; }
> - void update(const T& new_value) { d.value = new_value; d.is_valid = true; }
> - bool is_valid() const { return d.is_valid; }
> - void invalidate() { d.is_valid = false; }
> -
> - private:
> - struct
> - {
> - T value;
> - bool is_valid;
> - } d;
> - };
> -
> virtual ~Controller() = default;
> Controller(const Controller&) = delete;
> Controller& operator=(const Controller&) = delete;
>
> + /**
> + * @brief Request to start position updates if not already running.
> + */
> virtual void start_position_updates();
> +
> + /**
> + * @brief Request to stop position updates. Only stops the provider when the last observer calls this function.
> + */
> virtual void stop_position_updates();
> +
> + /**
> + * @brief Checks if position updates are currently running.
> + * @return true iff position updates are currently running.
> + */
> bool are_position_updates_running() const;
>
> + /**
> + * @brief Request to start heading updates if not already running.
> + */
> virtual void start_heading_updates();
> +
> + /**
> + * @brief Request to stop heading updates. Only stops the provider when the last observer calls this function.
> + */
> virtual void stop_heading_updates();
> +
> + /**
> + * @brief Checks if position updates are currently running.
> + * @return true iff position updates are currently running.
> + */
> bool are_heading_updates_running() const;
>
> + /**
> + * @brief Request to start velocity updates if not already running.
> + */
> virtual void start_velocity_updates();
> +
> + /**
> + * @brief Request to stop velocity updates. Only stops the provider when the last observer calls this function.
> + */
> virtual void stop_velocity_updates();
> +
> + /**
> + * @brief Checks if velocity updates are currently running.
> + * @return true iff velocity updates are currently running.
> + */
> bool are_velocity_updates_running() const;
>
> - const Cache<Update<Position>>& cached_position_update() const;
> - const Cache<Update<Heading>>& cached_heading_update() const;
> - const Cache<Update<Velocity>>& cached_velocity_update() const;
> -
> protected:
> friend class Provider;
> explicit Controller(Provider& instance);
>
> private:
> - void on_position_updated(const Update<Position>& position);
> - void on_velocity_updated(const Update<Velocity>& velocity);
> - void on_heading_updated(const Update<Heading>& heading);
> -
> Provider& instance;
> std::atomic<int> position_updates_counter;
> std::atomic<int> heading_updates_counter;
> std::atomic<int> velocity_updates_counter;
> - ScopedChannelConnection position_update_connection;
> - ScopedChannelConnection velocity_update_connection;
> - ScopedChannelConnection heading_update_connection;
> - struct
> - {
> - Cache<Update<Position>> position;
> - Cache<Update<Velocity>> velocity;
> - Cache<Update<Heading>> heading;
> - } cached;
> + };
> +
> + /**
> + * @brief Wraps all updates that can be delivered by a provider.
> + */
> + struct Updates
> + {
> + /** Position updates. */
> + core::Signal<Update<Position>> position;
> + /** Heading updates. */
> + core::Signal<Update<Heading>> heading;
> + /** Velocity updates. */
> + core::Signal<Update<Velocity>> velocity;
> + /** Space vehicle visibility updates. */
> + core::Signal<Update<std::set<SpaceVehicle>>> svs;
> };
>
> virtual ~Provider() = default;
> @@ -133,43 +165,114 @@
> Provider(const Provider&) = delete;
> Provider& operator=(const Provider&) = delete;
>
> + /**
> + * @brief Provides non-mutable access to this provider's updates.
> + * @return A non-mutable reference to the updates.
> + */
> + virtual const Updates& updates() const;
> +
> + /**
> + * @brief Access to the controller facade of this provider instance.
> + */
> virtual const Controller::Ptr& state_controller() const;
>
> - virtual ChannelConnection subscribe_to_position_updates(std::function<void(const Update<Position>&)> f);
> - virtual ChannelConnection subscribe_to_heading_updates(std::function<void(const Update<Heading>&)> f);
> - virtual ChannelConnection subscribe_to_velocity_updates(std::function<void(const Update<Velocity>&)> f);
> -
> - virtual bool supports(const Feature& f) const;
> - virtual bool requires(const Requirement& r) const;
> -
> - virtual bool matches_criteria(const Criteria&);
> -
> + /**
> + * @brief Checks if the provider supports a specific feature.
> + * @param f Feature to test for
> + * @return true iff the provider supports the feature.
> + */
> + virtual bool supports(const Features& f) const;
> +
> + /**
> + * @brief Checks if the provider has got a specific requirement.
> + * @param r Requirement to test for.
> + * @return true iff the provider has the specific requirement.
> + */
> + virtual bool requires(const Requirements& r) const;
> +
> + /**
> + * @brief Checks if a provider satisfies a set of accuracy criteria.
> + * @param [in] criteria The criteria to check.
> + * @return true iff the provider satisfies the given criteria.
> + */
> + virtual bool matches_criteria(const Criteria& criteria);
> +
> + /**
> + * @brief Called by the engine whenever the wifi and cell ID reporting state changes.
> + * @param state The new state.
> + */
> + virtual void on_wifi_and_cell_reporting_state_changed(WifiAndCellIdReportingState state);
> +
> + /**
> + * @brief Called by the engine whenever the reference location changed.
> + * @param position The new reference location.
> + */
> + virtual void on_reference_location_updated(const Update<Position>& position);
> +
> + /**
> + * @brief Called by the engine whenever the reference velocity changed.
> + * @param velocity The new reference velocity.
> + */
> + virtual void on_reference_velocity_updated(const Update<Velocity>& velocity);
> +
> + /**
> + * @brief Called by the engine whenever the reference heading changed.
> + * @param heading The new reference heading.
> + */
> + virtual void on_reference_heading_updated(const Update<Heading>& heading);
> +
> protected:
> explicit Provider(
> - const FeatureFlags& feature_flags = FeatureFlags(),
> - const RequirementFlags& requirement_flags = RequirementFlags());
> + const Features& features = Features::none,
> + const Requirements& requirements = Requirements::none);
>
> - void deliver_position_updates(const Update<Position>& update);
> - void deliver_heading_updates(const Update<Heading>& update);
> - void deliver_velocity_updates(const Update<Velocity>& update);
> + virtual Updates& mutable_updates();
>
> + /**
> + * @brief Implementation-specific, empty by default.
> + */
> virtual void start_position_updates();
> +
> + /**
> + * @brief Implementation-specific, empty by default.
> + */
> virtual void stop_position_updates();
>
> + /**
> + * @brief Implementation-specific, empty by default.
> + */
> virtual void start_heading_updates();
> +
> + /**
> + * @brief Implementation-specific, empty by default.
> + */
> virtual void stop_heading_updates();
>
> + /**
> + * @brief Implementation-specific, empty by default.
> + */
> virtual void start_velocity_updates();
> +
> + /**
> + * @brief Implementation-specific, empty by default.
> + */
> virtual void stop_velocity_updates();
>
> private:
> - FeatureFlags feature_flags;
> - RequirementFlags requirement_flags;
> - Channel<Update<Position>> position_updates_channel;
> - Channel<Update<Heading>> heading_updates_channel;
> - Channel<Update<Velocity>> velocity_updates_channel;
> - Controller::Ptr controller;
> + struct
> + {
> + Features features = Features::none;
> + Requirements requirements = Requirements::none;
> + Updates updates;
> + Controller::Ptr controller = Controller::Ptr{};
> + } d;
> };
> +
> +Provider::Features operator|(Provider::Features lhs, Provider::Features rhs);
> +Provider::Features operator&(Provider::Features lhs, Provider::Features rhs);
> +
> +Provider::Requirements operator|(Provider::Requirements lhs, Provider::Requirements rhs);
> +Provider::Requirements operator&(Provider::Requirements lhs, Provider::Requirements rhs);
> }
> }
> }
>
> === added file 'include/location_service/com/ubuntu/location/provider_enumerator.h'
> --- include/location_service/com/ubuntu/location/provider_enumerator.h 1970-01-01 00:00:00 +0000
> +++ include/location_service/com/ubuntu/location/provider_enumerator.h 2014-06-24 16:02:38 +0000
> @@ -0,0 +1,49 @@
> +/*
> + * Copyright © 2012-2013 Canonical Ltd.
> + *
Update the copyright to 2014.
> + * This program is free software: you can redistribute it and/or modify it
> + * under the terms of the GNU Lesser General Public License version 3,
> + * 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 Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public License
> + * along with this program. If not, see <http://www.gnu.org/licenses/>.
> + *
> + * Authored by: Thomas Voß <thomas.voss at canonical.com>
> + */
> +#ifndef LOCATION_SERVICE_COM_UBUNTU_PROVIDER_ENUMERATOR_H_
> +#define LOCATION_SERVICE_COM_UBUNTU_PROVIDER_ENUMERATOR_H_
> +
> +#include <functional>
> +#include <memory>
> +
> +namespace com
> +{
> +namespace ubuntu
> +{
> +namespace location
> +{
> +class Provider;
> +class ProviderEnumerator
> +{
> +public:
> + ProviderEnumerator(const ProviderEnumerator&) = delete;
> + virtual ~ProviderEnumerator() = default;
> +
> + ProviderEnumerator& operator=(const ProviderEnumerator&) = delete;
> + bool operator==(const ProviderEnumerator&) const = delete;
> +
> + virtual void for_each_provider(const std::function<void(const std::shared_ptr<Provider>&)>&) const = 0;
> +
> +protected:
> + ProviderEnumerator() = default;
> +};
> +}
> +}
> +}
> +
> +#endif // LOCATION_SERVICE_COM_UBUNTU_PROVIDER_ENUMERATOR_H_
>
> === modified file 'include/location_service/com/ubuntu/location/provider_factory.h'
> --- include/location_service/com/ubuntu/location/provider_factory.h 2013-05-29 06:04:02 +0000
> +++ include/location_service/com/ubuntu/location/provider_factory.h 2014-06-24 16:02:38 +0000
> @@ -18,8 +18,8 @@
> #ifndef LOCATION_SERVICE_COM_UBUNTU_LOCATION_PROVIDER_FACTORY_H_
> #define LOCATION_SERVICE_COM_UBUNTU_LOCATION_PROVIDER_FACTORY_H_
>
> -#include "com/ubuntu/location/configuration.h"
> -#include "com/ubuntu/location/provider.h"
> +#include <com/ubuntu/location/configuration.h>
> +#include <com/ubuntu/location/provider.h>
>
> #include <functional>
> #include <map>
> @@ -57,7 +57,7 @@
> ProviderFactory& operator=(const ProviderFactory&) = delete;
>
> std::mutex guard;
> - std::map<std::string, Factory> factory_store;
> + std::map<std::string, Factory> factory_store;
> };
> }
> }
>
> === added file 'include/location_service/com/ubuntu/location/provider_selection.h'
> --- include/location_service/com/ubuntu/location/provider_selection.h 1970-01-01 00:00:00 +0000
> +++ include/location_service/com/ubuntu/location/provider_selection.h 2014-06-24 16:02:38 +0000
> @@ -0,0 +1,62 @@
> +/*
> + * Copyright © 2012-2013 Canonical Ltd.
> + *
Update the copyright to 2014.
> + * This program is free software: you can redistribute it and/or modify it
> + * under the terms of the GNU Lesser General Public License version 3,
> + * 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 Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public License
> + * along with this program. If not, see <http://www.gnu.org/licenses/>.
> + *
> + * Authored by: Thomas Voß <thomas.voss at canonical.com>
> + */
> +#ifndef LOCATION_SERVICE_COM_UBUNTU_PROVIDER_SELECTION_H_
> +#define LOCATION_SERVICE_COM_UBUNTU_PROVIDER_SELECTION_H_
> +
> +#include <com/ubuntu/location/provider.h>
> +
> +#include <memory>
> +
> +namespace com
> +{
> +namespace ubuntu
> +{
> +namespace location
> +{
> +struct ProviderSelection
> +{
> + inline Provider::Features to_feature_flags() const
> + {
> + Provider::Features flags = Provider::Features::none;
> +
> + if (position_updates_provider)
> + flags = flags | Provider::Features::position;
> + if (heading_updates_provider)
> + flags = flags | Provider::Features::heading;
> + if(velocity_updates_provider)
> + flags = flags | Provider::Features::velocity;
> +
> + return flags;
> + }
> +
> + std::shared_ptr<Provider> position_updates_provider;
> + std::shared_ptr<Provider> heading_updates_provider;
> + std::shared_ptr<Provider> velocity_updates_provider;
> +};
> +
> +inline bool operator==(const ProviderSelection& lhs, const ProviderSelection& rhs)
> +{
> + return lhs.position_updates_provider == rhs.position_updates_provider &&
> + lhs.heading_updates_provider == rhs.heading_updates_provider &&
> + lhs.velocity_updates_provider == rhs.velocity_updates_provider;
> +}
> +}
> +}
> +}
> +
> +#endif // LOCATION_SERVICE_COM_UBUNTU_PROVIDER_SELECTION_H_
>
> === modified file 'include/location_service/com/ubuntu/location/provider_selection_policy.h'
> --- include/location_service/com/ubuntu/location/provider_selection_policy.h 2013-06-10 11:10:00 +0000
> +++ include/location_service/com/ubuntu/location/provider_selection_policy.h 2014-06-24 16:02:38 +0000
> @@ -18,7 +18,8 @@
> #ifndef LOCATION_SERVICE_COM_UBUNTU_PROVIDER_SELECTION_POLICY_H_
> #define LOCATION_SERVICE_COM_UBUNTU_PROVIDER_SELECTION_POLICY_H_
>
> -#include "com/ubuntu/location/provider.h"
> +#include <com/ubuntu/location/provider_enumerator.h>
> +#include <com/ubuntu/location/provider_selection.h>
>
> #include <memory>
>
> @@ -29,52 +30,25 @@
> namespace location
> {
> struct Criteria;
> -
> -struct ProviderSelection
> -{
> - ProviderSelection(const Provider::Ptr position = Provider::Ptr{},
> - const Provider::Ptr heading = Provider::Ptr{},
> - const Provider::Ptr velocity = Provider::Ptr{}) : position_updates_provider(position),
> - heading_updates_provider(heading),
> - velocity_updates_provider(velocity)
> - {
> - }
> -
> - Provider::FeatureFlags to_feature_flags() const
> - {
> - Provider::FeatureFlags flags;
> - flags.set(static_cast<std::size_t>(Provider::Feature::position), static_cast<bool>(position_updates_provider));
> - flags.set(static_cast<std::size_t>(Provider::Feature::heading), static_cast<bool>(heading_updates_provider));
> - flags.set(static_cast<std::size_t>(Provider::Feature::velocity), static_cast<bool>(velocity_updates_provider));
> -
> - return flags;
> - }
> -
> - Provider::Ptr position_updates_provider;
> - Provider::Ptr heading_updates_provider;
> - Provider::Ptr velocity_updates_provider;
> -};
> -
> -inline bool operator==(const ProviderSelection& lhs, const ProviderSelection& rhs)
> -{
> - return lhs.position_updates_provider == rhs.position_updates_provider &&
> - lhs.heading_updates_provider == rhs.heading_updates_provider &&
> - lhs.velocity_updates_provider == rhs.velocity_updates_provider;
> -}
> +class Engine;
>
> class ProviderSelectionPolicy
> {
> public:
> typedef std::shared_ptr<ProviderSelectionPolicy> Ptr;
>
> + static const Provider::Ptr& null_provider();
> +
> + ProviderSelectionPolicy(const ProviderSelectionPolicy&) = delete;
> + ProviderSelectionPolicy& operator=(const ProviderSelectionPolicy&) = delete;
> virtual ~ProviderSelectionPolicy() = default;
>
> - virtual ProviderSelection determine_provider_selection_from_set_for_criteria(const Criteria& criteria, const std::set<Provider::Ptr>& providers) = 0;
> + virtual ProviderSelection determine_provider_selection_for_criteria(
> + const Criteria& criteria,
> + const ProviderEnumerator& enumerator) = 0;
> +
> protected:
> ProviderSelectionPolicy() = default;
> -private:
> - ProviderSelectionPolicy(const ProviderSelectionPolicy&) = delete;
> - ProviderSelectionPolicy& operator=(const ProviderSelectionPolicy&) = delete;
> };
> }
> }
>
> === modified file 'include/location_service/com/ubuntu/location/providers/geoclue/geoclue.h'
> --- include/location_service/com/ubuntu/location/providers/geoclue/geoclue.h 2014-01-31 11:08:33 +0000
> +++ include/location_service/com/ubuntu/location/providers/geoclue/geoclue.h 2014-06-24 16:02:38 +0000
> @@ -18,10 +18,10 @@
> #ifndef LOCATION_SERVICE_COM_UBUNTU_LOCATION_PROVIDERS_GEOCLUE_GEOCLUE_H_
> #define LOCATION_SERVICE_COM_UBUNTU_LOCATION_PROVIDERS_GEOCLUE_GEOCLUE_H_
>
> -#include "core/dbus/service.h"
> -#include "core/dbus/traits/service.h"
> -#include "core/dbus/types/struct.h"
> -#include "core/dbus/types/stl/tuple.h"
> +#include <core/dbus/service.h>
> +#include <core/dbus/traits/service.h>
> +#include <core/dbus/types/struct.h>
> +#include <core/dbus/types/stl/tuple.h>
>
> #include <string>
>
> @@ -43,13 +43,13 @@
>
> friend std::ostream& operator<<(std::ostream& out, const Status& status)
> {
> - static std::map<Status, std::string> lut =
> - {
> - {Status::error, "error"},
> - {Status::unavailable, "unavailable"},
> - {Status::acquiring, "acquiring"},
> - {Status::available, "available"}
> - };
> + static std::map<Status, std::string> lut =
> + {
> + {Status::error, "error"},
> + {Status::unavailable, "unavailable"},
> + {Status::acquiring, "acquiring"},
> + {Status::available, "available"}
> + };
>
> return out << lut[status];
> }
> @@ -59,7 +59,7 @@
> inline static std::string name()
> {
> return "GetProviderInfo";
> - }
> + }
> typedef Geoclue Interface;
> typedef std::tuple<std::string, std::string> ResultType;
> inline static const std::chrono::milliseconds default_timeout() { return std::chrono::seconds{1}; }
> @@ -70,7 +70,7 @@
> inline static std::string name()
> {
> return "GetStatus";
> - }
> + }
> typedef Geoclue Interface;
> typedef int32_t ResultType;
> inline static const std::chrono::milliseconds default_timeout() { return std::chrono::seconds{1}; }
> @@ -81,7 +81,7 @@
> inline static std::string name()
> {
> return "AddReference";
> - }
> + }
> typedef Geoclue Interface;
> typedef void ResultType;
> inline static const std::chrono::milliseconds default_timeout() { return std::chrono::seconds{1}; }
> @@ -92,7 +92,7 @@
> inline static std::string name()
> {
> return "RemoveReference";
> - }
> + }
> typedef Geoclue Interface;
> typedef void ResultType;
> inline static const std::chrono::milliseconds default_timeout() { return std::chrono::seconds{1}; }
> @@ -105,7 +105,7 @@
> inline static std::string name()
> {
> return "GetAddress";
> - }
> + }
> typedef Address Interface;
> typedef std::tuple<int32_t, std::map<std::string, std::string>, dbus::types::Struct<std::tuple<int32_t, double, double>>> ResultType;
> inline static const std::chrono::milliseconds default_timeout() { return std::chrono::seconds{1}; }
> @@ -127,24 +127,24 @@
>
> struct Position
> {
> - struct Field
> - {
> + struct Field
> + {
> Field() = delete;
>
> static const int none = 0;
> static const int latitude = 1;
> static const int longitude = 2;
> static const int altitude = 3;
> - };
> + };
>
> - typedef std::bitset<4> FieldFlags;
> + typedef std::bitset<4> FieldFlags;
>
> struct GetPosition
> {
> inline static std::string name()
> {
> return "GetPosition";
> - }
> + }
> typedef Position Interface;
> typedef std::tuple<int32_t, int32_t, double, double, double, dbus::types::Struct<std::tuple<int32_t, double, double>>> ResultType;
> inline static const std::chrono::milliseconds default_timeout() { return std::chrono::seconds{1}; }
> @@ -166,24 +166,24 @@
>
> struct Velocity
> {
> - struct Field
> - {
> + struct Field
> + {
> Field() = delete;
>
> static const int none = 0;
> static const int speed = 1;
> static const int direction = 2;
> static const int climb = 3;
> - };
> + };
>
> - typedef std::bitset<4> FieldFlags;
> + typedef std::bitset<4> FieldFlags;
>
> struct GetVelocity
> {
> inline static std::string name()
> {
> return "GetVelocity";
> - }
> + }
> typedef Velocity Interface;
> typedef std::tuple<int32_t, int32_t, double, double, double> ResultType;
> inline static const std::chrono::milliseconds default_timeout() { return std::chrono::seconds{1}; }
>
> === modified file 'include/location_service/com/ubuntu/location/providers/geoclue/provider.h'
> --- include/location_service/com/ubuntu/location/providers/geoclue/provider.h 2013-05-29 06:04:02 +0000
> +++ include/location_service/com/ubuntu/location/providers/geoclue/provider.h 2014-06-24 16:02:38 +0000
> @@ -18,8 +18,8 @@
> #ifndef LOCATION_SERVICE_COM_UBUNTU_LOCATION_PROVIDERS_GEOCLUE_PROVIDER_H_
> #define LOCATION_SERVICE_COM_UBUNTU_LOCATION_PROVIDERS_GEOCLUE_PROVIDER_H_
>
> -#include "com/ubuntu/location/provider.h"
> -#include "com/ubuntu/location/provider_factory.h"
> +#include <com/ubuntu/location/provider.h>
> +#include <com/ubuntu/location/provider_factory.h>
>
> namespace com
> {
> @@ -36,9 +36,6 @@
> public:
> static Provider::Ptr create_instance(const ProviderFactory::Configuration&);
>
> - static const Provider::FeatureFlags& default_feature_flags();
> - static const Provider::RequirementFlags& default_requirement_flags();
> -
> struct Configuration
> {
> static std::string key_name() { return "name"; }
> @@ -46,8 +43,8 @@
> std::string name;
> std::string path;
>
> - Provider::FeatureFlags features;
> - Provider::RequirementFlags requirements;
> + Provider::Features features = Provider::Features::none;
> + Provider::Requirements requirements = Provider::Requirements::none;
> };
>
> Provider(const Configuration& config);
>
> === removed directory 'include/location_service/com/ubuntu/location/providers/gps'
> === modified file 'include/location_service/com/ubuntu/location/providers/skyhook/provider.h'
> --- include/location_service/com/ubuntu/location/providers/skyhook/provider.h 2013-05-29 06:04:02 +0000
> +++ include/location_service/com/ubuntu/location/providers/skyhook/provider.h 2014-06-24 16:02:38 +0000
> @@ -18,8 +18,8 @@
> #ifndef LOCATION_SERVICE_COM_UBUNTU_LOCATION_PROVIDERS_SKYHOOK_PROVIDER_H_
> #define LOCATION_SERVICE_COM_UBUNTU_LOCATION_PROVIDERS_SKYHOOK_PROVIDER_H_
>
> -#include "com/ubuntu/location/provider.h"
> -#include "com/ubuntu/location/provider_factory.h"
> +#include <com/ubuntu/location/provider.h>
> +#include <com/ubuntu/location/provider_factory.h>
>
> #include <memory>
>
>
> === modified file 'include/location_service/com/ubuntu/location/proxy_provider.h'
> --- include/location_service/com/ubuntu/location/proxy_provider.h 2013-05-28 14:41:06 +0000
> +++ include/location_service/com/ubuntu/location/proxy_provider.h 2014-06-24 16:02:38 +0000
> @@ -18,8 +18,8 @@
> #ifndef LOCATION_SERVICE_COM_UBUNTU_LOCATION_PROXY_PROVIDER_H_
> #define LOCATION_SERVICE_COM_UBUNTU_LOCATION_PROXY_PROVIDER_H_
>
> -#include "com/ubuntu/location/provider.h"
> -#include "com/ubuntu/location/provider_selection_policy.h"
> +#include <com/ubuntu/location/provider.h>
> +#include <com/ubuntu/location/provider_selection_policy.h>
>
> #include <bitset>
> #include <memory>
> @@ -38,10 +38,6 @@
> ProxyProvider(const ProviderSelection& selection);
> ~ProxyProvider() noexcept;
>
> - ChannelConnection subscribe_to_position_updates(std::function<void(const Update<Position>&)> f);
> - ChannelConnection subscribe_to_heading_updates(std::function<void(const Update<Heading>&)> f);
> - ChannelConnection subscribe_to_velocity_updates(std::function<void(const Update<Velocity>&)> f);
> -
> virtual void start_position_updates();
> virtual void stop_position_updates();
>
> @@ -52,9 +48,14 @@
> virtual void stop_heading_updates();
>
> private:
> - Provider::Ptr position_updates_provider;
> - Provider::Ptr heading_updates_provider;
> - Provider::Ptr velocity_updates_provider;
> + ProviderSelection providers;
> +
> + struct
> + {
> + core::ScopedConnection position_updates;
> + core::ScopedConnection heading_updates;
> + core::ScopedConnection velocity_updates;
> + } connections;
> };
> }
> }
>
> === added file 'include/location_service/com/ubuntu/location/satellite_based_positioning_state.h'
> --- include/location_service/com/ubuntu/location/satellite_based_positioning_state.h 1970-01-01 00:00:00 +0000
> +++ include/location_service/com/ubuntu/location/satellite_based_positioning_state.h 2014-06-24 16:02:38 +0000
> @@ -0,0 +1,40 @@
> +/*
> + * Copyright © 2012-2013 Canonical Ltd.
> + *
Update the copyright to 2014.
> + * This program is free software: you can redistribute it and/or modify it
> + * under the terms of the GNU Lesser General Public License version 3,
> + * 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 Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public License
> + * along with this program. If not, see <http://www.gnu.org/licenses/>.
> + *
> + * Authored by: Thomas Voß <thomas.voss at canonical.com>
> + */
> +#ifndef LOCATION_SERVICE_COM_UBUNTU_LOCATION_SATELLITE_BASED_POSITIONING_STATE_H_
> +#define LOCATION_SERVICE_COM_UBUNTU_LOCATION_SATELLITE_BASED_POSITIONING_STATE_H_
> +
> +namespace com
> +{
> +namespace ubuntu
> +{
> +namespace location
> +{
> +/**
> + * @brief The SatelliteBasedPositioningState enum describes whether satellite
> + * assisted positioning is enabled or disabled.
> + */
> +enum class SatelliteBasedPositioningState
> +{
> + on, ///< Satellite assisted positioning is on.
> + off ///< Satellite assisted positioning is off.
> +};
> +}
> +}
> +}
> +
> +#endif // LOCATION_SERVICE_COM_UBUNTU_LOCATION_SATELLITE_BASED_POSITIONING_STATE_H_
>
> === modified file 'include/location_service/com/ubuntu/location/service/configuration.h'
> --- include/location_service/com/ubuntu/location/service/configuration.h 2013-05-28 14:41:06 +0000
> +++ include/location_service/com/ubuntu/location/service/configuration.h 2014-06-24 16:02:38 +0000
> @@ -18,11 +18,11 @@
> #ifndef LOCATION_SERVICE_COM_UBUNTU_LOCATION_SERVICE_CONFIGURATION_H_
> #define LOCATION_SERVICE_COM_UBUNTU_LOCATION_SERVICE_CONFIGURATION_H_
>
> -#include "com/ubuntu/location/service/permission_manager.h"
> +#include <com/ubuntu/location/service/permission_manager.h>
>
> -#include "com/ubuntu/location/engine.h"
> -#include "com/ubuntu/location/provider.h"
> -#include "com/ubuntu/location/provider_selection_policy.h"
> +#include <com/ubuntu/location/engine.h>
> +#include <com/ubuntu/location/provider.h>
> +#include <com/ubuntu/location/provider_selection_policy.h>
>
> #include <set>
>
>
> === modified file 'include/location_service/com/ubuntu/location/service/default_configuration.h'
> --- include/location_service/com/ubuntu/location/service/default_configuration.h 2013-05-28 14:41:06 +0000
> +++ include/location_service/com/ubuntu/location/service/default_configuration.h 2014-06-24 16:02:38 +0000
> @@ -18,7 +18,7 @@
> #ifndef LOCATION_SERVICE_COM_UBUNTU_LOCATION_SERVICE_DEFAULT_CONFIGURATION_H_
> #define LOCATION_SERVICE_COM_UBUNTU_LOCATION_SERVICE_DEFAULT_CONFIGURATION_H_
>
> -#include "com/ubuntu/location/service/configuration.h"
> +#include <com/ubuntu/location/service/configuration.h>
>
> #include <set>
>
>
> === modified file 'include/location_service/com/ubuntu/location/service/default_permission_manager.h'
> --- include/location_service/com/ubuntu/location/service/default_permission_manager.h 2013-05-28 14:41:06 +0000
> +++ include/location_service/com/ubuntu/location/service/default_permission_manager.h 2014-06-24 16:02:38 +0000
> @@ -18,7 +18,7 @@
> #ifndef LOCATION_SERVICE_COM_UBUNTU_LOCATION_SERVICE_DEFAULT_PERMISSION_MANAGER_H_
> #define LOCATION_SERVICE_COM_UBUNTU_LOCATION_SERVICE_DEFAULT_PERMISSION_MANAGER_H_
>
> -#include "com/ubuntu/location/service/permission_manager.h"
> +#include <com/ubuntu/location/service/permission_manager.h>
>
> #include <sys/types.h>
> #include <unistd.h>
>
> === modified file 'include/location_service/com/ubuntu/location/service/interface.h'
> --- include/location_service/com/ubuntu/location/service/interface.h 2014-01-31 11:08:33 +0000
> +++ include/location_service/com/ubuntu/location/service/interface.h 2014-06-24 16:02:38 +0000
> @@ -18,7 +18,9 @@
> #ifndef LOCATION_SERVICE_COM_UBUNTU_LOCATION_SERVICE_INTERFACE_H_
> #define LOCATION_SERVICE_COM_UBUNTU_LOCATION_SERVICE_INTERFACE_H_
>
> -#include "com/ubuntu/location/service/session/interface.h"
> +#include <com/ubuntu/location/service/session/interface.h>
> +
> +#include <com/ubuntu/location/space_vehicle.h>
>
> #include <core/dbus/service.h>
> #include <core/dbus/traits/service.h>
> @@ -35,18 +37,31 @@
> {
> namespace location
> {
> -
> struct Criteria;
> -
> namespace service
> {
> +/**
> + * @brief The Interface class models the primary interface to the location service.
> + */
> class Interface
> {
> protected:
> struct Errors
> {
> - struct InsufficientPermissions { inline static std::string name() { return "com.ubuntu.location.Service.Error.InsufficientPermissions"; } };
> - struct CreatingSession { inline static std::string name() { return "com.ubuntu.location.Service.Error.CreatingSession"; } };
> + struct InsufficientPermissions
> + {
> + inline static std::string name()
> + {
> + return "com.ubuntu.location.Service.Error.InsufficientPermissions";
> + }
> + };
> + struct CreatingSession
> + {
> + inline static std::string name()
> + {
> + return "com.ubuntu.location.Service.Error.CreatingSession";
> + }
> + };
> };
>
> struct CreateSessionForCriteria
> @@ -64,7 +79,82 @@
>
> typedef dbus::types::ObjectPath ResultType;
>
> - inline static const std::chrono::milliseconds default_timeout() { return std::chrono::seconds{1}; }
> + inline static const std::chrono::milliseconds default_timeout()
> + {
> + return std::chrono::seconds{1};
> + }
> + };
> +
> + struct Properties
> + {
> + struct DoesSatelliteBasedPositioning
> + {
> + inline static const std::string& name()
> + {
> + static const std::string s
> + {
> + "DoesSatelliteBasedPositioning"
> + };
> + return s;
> + }
> +
> + typedef com::ubuntu::location::service::Interface Interface;
> + typedef bool ValueType;
> + static const bool readable = true;
> + static const bool writable = true;
> + };
> +
> + struct DoesReportCellAndWifiIds
> + {
> + inline static const std::string& name()
> + {
> + static const std::string s
> + {
> + "DoesReportCellAndWifiIds"
> + };
> + return s;
> + }
> +
> + typedef com::ubuntu::location::service::Interface Interface;
> + typedef bool ValueType;
> + static const bool readable = true;
> + static const bool writable = true;
> + };
> +
> + struct IsOnline
> + {
> + inline static const std::string& name()
> + {
> + static const std::string s
> + {
> + "IsOnline"
> + };
> + return s;
> + }
> +
> + typedef com::ubuntu::location::service::Interface Interface;
> + typedef bool ValueType;
> + static const bool readable = true;
> + static const bool writable = true;
> + };
> +
> + struct VisibleSpaceVehicles
> + {
> + inline static const std::string& name()
> + {
> + static const std::string s
> + {
> + "VisibleSpaceVehicles"
> + };
> + return s;
> + }
> +
> + typedef com::ubuntu::location::service::Interface Interface;
> + typedef std::map<com::ubuntu::location::SpaceVehicle::Key, com::ubuntu::location::SpaceVehicle> ValueType;
> +
> + static const bool readable = true;
> + static const bool writable = false;
> + };
> };
>
> Interface() = default;
> @@ -72,6 +162,9 @@
> public:
> typedef std::shared_ptr<Interface> Ptr;
>
> + /**
> + * @brief Queries the path that this object is known under.
> + */
> inline static const std::string& path()
> {
> static const std::string s{"/com/ubuntu/location/Service"};
> @@ -82,6 +175,40 @@
> Interface& operator=(const Interface&) = delete;
> virtual ~Interface() = default;
>
> + /**
> + * @brief Whether the service uses satellite-based positioning.
> + * @return A setable/getable/observable property.
> + */
> + virtual core::Property<bool>& does_satellite_based_positioning() = 0;
> +
> + /**
> + * @brief Whether the overall service and its positioning engine is online or not.
> + * @return A setable/getable/observable property.
> + */
> + virtual core::Property<bool>& is_online() = 0;
> +
> + /**
> + * @brief Whether the engine and its providers/reporters do call home to
> + * report reference locations together with wifi and cell ids.
> + *
> + * We consider this feature privacy sensitive and it defaults to false. The
> + * user has to explicitly opt-in into this feature.
> + *
> + * @return A setable/getable/observable property.
> + */
> + virtual core::Property<bool>& does_report_cell_and_wifi_ids() = 0;
> +
> + /**
> + * @brief All space vehicles currently visible.
> + */
> + virtual core::Property<std::map<SpaceVehicle::Key, SpaceVehicle>>& visible_space_vehicles() = 0;
> +
> + /**
> + * @brief Starts a new session for the given criteria
> + * @throw std::runtime_error in case of errors.
> + * @param criteria The client's requirements in terms of accuraccy and functionality
> + * @return A session instance.
> + */
> virtual session::Interface::Ptr create_session_for_criteria(const Criteria& criteria) = 0;
> };
> }
> @@ -111,6 +238,6 @@
> }
> }
>
> -#include "com/ubuntu/location/codec.h"
> +#include <com/ubuntu/location/codec.h>
>
> #endif // LOCATION_SERVICE_COM_UBUNTU_LOCATION_SERVICE_INTERFACE_H_
>
> === modified file 'include/location_service/com/ubuntu/location/service/permission_manager.h'
> --- include/location_service/com/ubuntu/location/service/permission_manager.h 2013-05-28 14:41:06 +0000
> +++ include/location_service/com/ubuntu/location/service/permission_manager.h 2014-06-24 16:02:38 +0000
> @@ -18,10 +18,7 @@
> #ifndef LOCATION_SERVICE_COM_UBUNTU_LOCATION_SERVICE_PERMISSION_MANAGER_H_
> #define LOCATION_SERVICE_COM_UBUNTU_LOCATION_SERVICE_PERMISSION_MANAGER_H_
>
> -#include "com/ubuntu/location/channel.h"
> -#include "com/ubuntu/location/provider_selection_policy.h"
> -
> -#include <functional>
> +#include <memory>
>
> namespace com
> {
> @@ -29,29 +26,47 @@
> {
> namespace location
> {
> +struct Criteria;
> namespace service
> {
> +/** @brief Credentials of a remote session. */
> struct Credentials
> {
> + /** @brief The process id of the remote peer. */
> pid_t pid;
> + /** @brief The user id the remote peer runs under. */
> uid_t uid;
> };
>
> +/**
> + * @brief The PermissionManager class is an interface to check whether an application
> + * is allowed to access the location services.
> + */
> class PermissionManager
> {
> public:
> + /** Manager pointer type. */
> typedef std::shared_ptr<PermissionManager> Ptr;
>
> + /**
> + * @brief The Result enum summarizes the results of a query for permissions.
> + */
> enum class Result
> {
> - granted,
> - rejected
> + granted, ///< The app is allowed to access the location service.
> + rejected ///< The app is not allowed to access the location service.
> };
>
> virtual ~PermissionManager() = default;
> PermissionManager(const PermissionManager&) = delete;
> PermissionManager& operator=(const PermissionManager&) = delete;
>
> + /**
> + * @brief Checks whether the app with the given credentials is allowed to access the service for the given criteria.
> + * @param criteria The requirements of the remote peer.
> + * @param credentials The credentials identifying the remote peer.
> + * @return Result::granted if the remote peer is allowed to access the location service, Result::rejected otherwise.
> + */
> virtual Result check_permission_for_credentials(
> const Criteria& criteria,
> const Credentials& credentials) = 0;
>
> === modified file 'include/location_service/com/ubuntu/location/service/session/implementation.h'
> --- include/location_service/com/ubuntu/location/service/session/implementation.h 2014-01-31 11:08:33 +0000
> +++ include/location_service/com/ubuntu/location/service/session/implementation.h 2014-06-24 16:02:38 +0000
> @@ -18,9 +18,9 @@
> #ifndef LOCATION_SERVICE_COM_UBUNTU_LOCATION_SERVICE_SESSION_IMPLEMENTATION_H_
> #define LOCATION_SERVICE_COM_UBUNTU_LOCATION_SERVICE_SESSION_IMPLEMENTATION_H_
>
> -#include "com/ubuntu/location/service/session/skeleton.h"
> +#include <com/ubuntu/location/service/session/skeleton.h>
>
> -#include "com/ubuntu/location/provider.h"
> +#include <com/ubuntu/location/provider.h>
>
> #include <memory>
>
> @@ -34,13 +34,10 @@
> {
> namespace session
> {
> -class Implementation : public Skeleton
> +class Implementation : public Interface
> {
> public:
> - Implementation(
> - const core::dbus::Bus::Ptr& bus,
> - const core::dbus::types::ObjectPath& session_path,
> - const Provider::Ptr& provider);
> + Implementation(const Provider::Ptr& provider);
> Implementation(const Implementation&) = delete;
> virtual ~Implementation() noexcept;
> Implementation& operator=(const Implementation&) = delete;
>
> === modified file 'include/location_service/com/ubuntu/location/service/session/interface.h'
> --- include/location_service/com/ubuntu/location/service/session/interface.h 2014-03-05 12:57:39 +0000
> +++ include/location_service/com/ubuntu/location/service/session/interface.h 2014-06-24 16:02:38 +0000
> @@ -18,16 +18,13 @@
> #ifndef LOCATION_SERVICE_COM_UBUNTU_LOCATION_SERVICE_SESSION_INTERFACE_H_
> #define LOCATION_SERVICE_COM_UBUNTU_LOCATION_SERVICE_SESSION_INTERFACE_H_
>
> -#include "com/ubuntu/location/channel.h"
> -#include "com/ubuntu/location/heading.h"
> -#include "com/ubuntu/location/position.h"
> -#include "com/ubuntu/location/provider.h"
> -#include "com/ubuntu/location/update.h"
> -#include "com/ubuntu/location/velocity.h"
> +#include <com/ubuntu/location/heading.h>
> +#include <com/ubuntu/location/position.h>
> +#include <com/ubuntu/location/provider.h>
> +#include <com/ubuntu/location/update.h>
> +#include <com/ubuntu/location/velocity.h>
>
> -#include <core/dbus/codec.h>
> -#include <core/dbus/traits/service.h>
> -#include <core/dbus/types/object_path.h>
> +#include <core/property.h>
>
> namespace com
> {
> @@ -39,176 +36,70 @@
> {
> namespace session
> {
> +/**
> + * @brief Models a session with the location service.
> + */
> class Interface
> {
> public:
> - struct UpdatePosition
> - {
> - typedef com::ubuntu::location::service::session::Interface Interface;
> -
> - inline static const std::string& name()
> - {
> - static const std::string s
> - {
> - "UpdatePosition"
> - };
> - return s;
> - }
> -
> - typedef void ResultType;
> -
> - inline static const std::chrono::milliseconds default_timeout() { return std::chrono::milliseconds{250}; }
> - };
> -
> - struct UpdateVelocity
> - {
> - typedef com::ubuntu::location::service::session::Interface Interface;
> -
> - inline static const std::string& name()
> - {
> - static const std::string s
> - {
> - "UpdateVelocity"
> - };
> - return s;
> - }
> -
> - typedef void ResultType;
> -
> - inline static const std::chrono::milliseconds default_timeout() { return std::chrono::milliseconds{250}; }
> - };
> -
> - struct UpdateHeading
> - {
> - typedef com::ubuntu::location::service::session::Interface Interface;
> -
> - inline static const std::string& name()
> - {
> - static const std::string s
> - {
> - "UpdateHeading"
> - };
> - return s;
> - }
> -
> - typedef void ResultType;
> -
> - inline static const std::chrono::milliseconds default_timeout() { return std::chrono::milliseconds{250}; }
> - };
> -
> - struct StartPositionUpdates
> - {
> - typedef com::ubuntu::location::service::session::Interface Interface;
> -
> - inline static const std::string& name()
> - {
> - static const std::string s
> - {
> - "StartPositionUpdates"
> - };
> - return s;
> - }
> -
> - typedef void ResultType;
> -
> - inline static const std::chrono::milliseconds default_timeout() { return std::chrono::seconds{1}; }
> - };
> -
> - struct StopPositionUpdates
> - {
> - typedef com::ubuntu::location::service::session::Interface Interface;
> -
> - inline static const std::string& name()
> - {
> - static const std::string s
> - {
> - "StopPositionUpdates"
> - };
> - return s;
> - }
> -
> - typedef void ResultType;
> -
> - inline static const std::chrono::milliseconds default_timeout() { return std::chrono::seconds{1}; }
> - };
> -
> - struct StartVelocityUpdates
> - {
> - typedef com::ubuntu::location::service::session::Interface Interface;
> -
> - inline static const std::string& name()
> - {
> - static const std::string s
> - {
> - "StartVelocityUpdates"
> - };
> - return s;
> - }
> -
> - typedef void ResultType;
> -
> - inline static const std::chrono::milliseconds default_timeout() { return std::chrono::seconds{1}; }
> - };
> -
> - struct StopVelocityUpdates
> - {
> - typedef com::ubuntu::location::service::session::Interface Interface;
> -
> - inline static const std::string& name()
> - {
> - static const std::string s
> - {
> - "StopVelocityUpdates"
> - };
> - return s;
> - }
> -
> - typedef void ResultType;
> -
> - inline static const std::chrono::milliseconds default_timeout() { return std::chrono::seconds{1}; }
> - };
> -
> - struct StartHeadingUpdates
> - {
> - typedef com::ubuntu::location::service::session::Interface Interface;
> -
> - inline static const std::string& name()
> - {
> - static const std::string s
> - {
> - "StartHeadingUpdates"
> - };
> - return s;
> - }
> -
> - typedef void ResultType;
> -
> - inline static const std::chrono::milliseconds default_timeout() { return std::chrono::seconds{1}; }
> - };
> -
> - struct StopHeadingUpdates
> - {
> - typedef com::ubuntu::location::service::session::Interface Interface;
> -
> - inline static const std::string& name()
> - {
> - static const std::string s
> - {
> - "StopHeadingUpdates"
> - };
> - return s;
> - }
> -
> - typedef void ResultType;
> -
> - inline static const std::chrono::milliseconds default_timeout() { return std::chrono::seconds{1}; }
> - };
> + struct UpdatePosition;
> + struct UpdateVelocity;
> + struct UpdateHeading;
> +
> + struct StartPositionUpdates;
> + struct StopPositionUpdates;
> +
> + struct StartVelocityUpdates;
> + struct StopVelocityUpdates;
> +
> + struct StartHeadingUpdates;
> + struct StopHeadingUpdates;
>
> struct Errors
> {
> - struct ErrorParsingUpdate { inline static std::string name() { return "com.ubuntu.location.Service.Session.ErrorParsingUpdate"; } };
> - struct ErrorStartingUpdate { inline static std::string name() { return "com.ubuntu.location.Service.Session.ErrorStartingUpdate"; } };
> - struct ErrorStoppingUpdate { inline static std::string name() { return "com.ubuntu.location.Service.Session.ErrorStoppingUpdate"; } };
> + struct ErrorParsingUpdate;
> + struct ErrorStartingUpdate;
> + };
> + /**
> + * @brief Encapsulates updates provided for this session, and the ability to enable/disable updates.
> + */
> + struct Updates
> + {
> + /**
> + * @brief The Status enum models the possible states of updates.
> + */
> + enum class Status
> + {
> + enabled, ///< Updates are enabled and delivered to this session.
> + disabled ///< Updates are disabled and not delivered to this session.
> + };
> +
> + /**
> + * @brief Updates for position measurements.
> + */
> + core::Property<Update<Position>> position{};
> + /**
> + * @brief Status of position updates, mutable.
> + */
> + core::Property<Status> position_status{Status::disabled};
> +
> + /**
> + * @brief Updates for the heading measurements.
> + */
> + core::Property<Update<Heading>> heading{};
> + /**
> + * @brief Status of position updates, mutable.
> + */
> + core::Property<Status> heading_status{Status::disabled};
> +
> + /**
> + * @brief Updates for velocity measurements.
> + */
> + core::Property<Update<Velocity>> velocity{};
> + /**
> + * @brief Status of velocity updates, mutable.
> + */
> + core::Property<Status> velocity_status{Status::disabled};
> };
>
> typedef std::shared_ptr<Interface> Ptr;
> @@ -217,58 +108,23 @@
> virtual ~Interface() noexcept;
> Interface& operator=(const Interface&) = delete;
>
> - virtual const core::dbus::types::ObjectPath& path() const = 0;
> -
> - ChannelConnection install_position_updates_handler(std::function<void(const Update<Position>&)> handler);
> - ChannelConnection install_velocity_updates_handler(std::function<void(const Update<Velocity>&)> handler);
> - ChannelConnection install_heading_updates_handler(std::function<void(const Update<Heading>&)> handler);
> -
> - virtual void start_position_updates() = 0;
> - virtual void stop_position_updates() noexcept = 0;
> - virtual void start_velocity_updates() = 0;
> - virtual void stop_velocity_updates() noexcept = 0;
> - virtual void start_heading_updates() = 0;
> - virtual void stop_heading_updates() noexcept = 0;
> -
> -protected:
> + /**
> + * @brief Provides access to the updates delivered for this session.
> + * @return A mutable reference to updates.
> + */
> + virtual Updates& updates();
> +
> +protected:
> Interface();
>
> - Channel<Update<Position>>& access_position_updates_channel();
> - Channel<Update<Heading>>& access_heading_updates_channel();
> - Channel<Update<Velocity>>& access_velocity_updates_channel();
> -
> private:
> struct Private;
> - std::unique_ptr<Private> d;
> -};
> -}
> -}
> -}
> -}
> -}
> -namespace core
> -{
> -namespace dbus
> -{
> -namespace traits
> -{
> -template<>
> -struct Service<com::ubuntu::location::service::session::Interface>
> -{
> - static const std::string& interface_name()
> - {
> - static const std::string s
> - {
> - "com.ubuntu.location.Service.Session"
> - };
> - return s;
> - }
> -};
> -}
> -}
> -}
> -
> -
> -#include "com/ubuntu/location/codec.h"
> + std::shared_ptr<Private> d;
> +};
> +}
> +}
> +}
> +}
> +}
>
> #endif // LOCATION_SERVICE_COM_UBUNTU_LOCATION_SERVICE_SESSION_INTERFACE_H_
>
> === modified file 'include/location_service/com/ubuntu/location/service/session/skeleton.h'
> --- include/location_service/com/ubuntu/location/service/session/skeleton.h 2014-01-31 11:08:33 +0000
> +++ include/location_service/com/ubuntu/location/service/session/skeleton.h 2014-06-24 16:02:38 +0000
> @@ -18,19 +18,19 @@
> #ifndef LOCATION_SERVICE_COM_UBUNTU_LOCATION_SERVICE_SESSION_SKELETON_H_
> #define LOCATION_SERVICE_COM_UBUNTU_LOCATION_SERVICE_SESSION_SKELETON_H_
>
> -#include "com/ubuntu/location/service/session/interface.h"
> +#include <com/ubuntu/location/service/session/interface.h>
>
> -#include "com/ubuntu/location/channel.h"
> -#include "com/ubuntu/location/heading.h"
> -#include "com/ubuntu/location/position.h"
> -#include "com/ubuntu/location/provider.h"
> -#include "com/ubuntu/location/update.h"
> -#include "com/ubuntu/location/velocity.h"
> +#include <com/ubuntu/location/heading.h>
> +#include <com/ubuntu/location/position.h>
> +#include <com/ubuntu/location/provider.h>
> +#include <com/ubuntu/location/update.h>
> +#include <com/ubuntu/location/velocity.h>
>
> #include <core/dbus/message.h>
> +#include <core/dbus/object.h>
> #include <core/dbus/skeleton.h>
>
> -#include <functional>
> +#include <memory>
>
> namespace com
> {
> @@ -44,19 +44,74 @@
> {
> class Skeleton : public core::dbus::Skeleton<Interface>
> {
> - public:
> - Skeleton(
> - const core::dbus::Bus::Ptr& bus,
> - const core::dbus::types::ObjectPath& session_path);
> - Skeleton(const Skeleton&) = delete;
> +public:
> + // All local, i.e., in-process creation-time properties of the Skeleton.
> + struct Local
> + {
> + // The actual implementation of com::ubuntu::location::service::session::Interface.
> + Interface::Ptr impl;
> + // The bus connection that the object is exposed upon.
> + core::dbus::Bus::Ptr bus;
> + };
> +
> + // We communicate position, heading and velocity updates to the client
> + // via an explicit function call. The reason is simple: We want to know
> + // whether the client is still alive and responding as expected to make sure
> + // that we stop positioning as early as possible.
> + struct Remote
> + {
> + // The remote object corresponding to the client, implementing
> + // com.ubuntu.location.service.session.Interface
> + core::dbus::Object::Ptr object;
> + };
> +
> + struct Configuration
> + {
> + // The object path of the session object, shared between clients and service.
> + core::dbus::types::ObjectPath path;
> + // Local attributes
> + Local local;
> + // Remote attributes
> + Remote remote;
> + };
> +
> + Skeleton(const Configuration& configuration);
> virtual ~Skeleton() noexcept;
> - Skeleton& operator=(const Skeleton&) = delete;
>
> virtual const core::dbus::types::ObjectPath& path() const;
>
> - private:
> - struct Private;
> - std::unique_ptr<Private> d;
> +private:
> + // Handle incoming requests for Start/StopPositionUpdates
> + virtual void on_start_position_updates(const core::dbus::Message::Ptr&);
> + virtual void on_stop_position_updates(const core::dbus::Message::Ptr&);
> + // Handles incoming requests for Start/StopHeadingUpdates
> + virtual void on_start_heading_updates(const core::dbus::Message::Ptr&);
> + virtual void on_stop_heading_updates(const core::dbus::Message::Ptr&);
> + // Handles incoming requests for Start/StopVelocityUpdates
> + virtual void on_start_velocity_updates(const core::dbus::Message::Ptr&);
> + virtual void on_stop_velocity_updates(const core::dbus::Message::Ptr&);
> +
> + // Invoked whenever the actual session impl. for the session reports a position update.
> + virtual void on_position_changed(const Update<Position>& position);
> + // Invoked whenever the actual session impl. reports a heading update.
> + virtual void on_heading_changed(const Update<Heading>& heading);
> + // Invoked whenever the actual session impl. reports a velocity update.
> + virtual void on_velocity_changed(const Update<Velocity>& velocity);
> +
> + // Stores all attributes passed at creation time.
> + Configuration configuration;
> + // The DBus object corresponding to the session.
> + core::dbus::Object::Ptr object;
> + // Scoped connections for automatically disconnecting on destruction
> + struct
> + {
> + // Corresponds to position updates coming in from the actual implementation instance.
> + core::ScopedConnection position_changed;
> + // Corresponds to heading updates coming in from the actual implementation instance.
> + core::ScopedConnection heading_changed;
> + // Corresponds to velocity updates coming in from the actual implementation instance.
> + core::ScopedConnection velocity_changed;
> + } connections;
> };
> }
> }
>
> === modified file 'include/location_service/com/ubuntu/location/service/session/stub.h'
> --- include/location_service/com/ubuntu/location/service/session/stub.h 2014-01-31 11:08:33 +0000
> +++ include/location_service/com/ubuntu/location/service/session/stub.h 2014-06-24 16:02:38 +0000
> @@ -18,14 +18,13 @@
> #ifndef LOCATION_SERVICE_COM_UBUNTU_LOCATION_SERVICE_SESSION_STUB_H_
> #define LOCATION_SERVICE_COM_UBUNTU_LOCATION_SESSION_SESSION_STUB_H_
>
> -#include "com/ubuntu/location/service/session/interface.h"
> +#include <com/ubuntu/location/service/session/interface.h>
>
> -#include "com/ubuntu/location/channel.h"
> -#include "com/ubuntu/location/heading.h"
> -#include "com/ubuntu/location/position.h"
> -#include "com/ubuntu/location/provider.h"
> -#include "com/ubuntu/location/update.h"
> -#include "com/ubuntu/location/velocity.h"
> +#include <com/ubuntu/location/heading.h>
> +#include <com/ubuntu/location/position.h>
> +#include <com/ubuntu/location/provider.h>
> +#include <com/ubuntu/location/update.h>
> +#include <com/ubuntu/location/velocity.h>
>
> #include <core/dbus/stub.h>
>
>
> === modified file 'include/location_service/com/ubuntu/location/service/skeleton.h'
> --- include/location_service/com/ubuntu/location/service/skeleton.h 2014-01-31 11:08:33 +0000
> +++ include/location_service/com/ubuntu/location/service/skeleton.h 2014-06-24 16:02:38 +0000
> @@ -18,10 +18,13 @@
> #ifndef LOCATION_SERVICE_COM_UBUNTU_LOCATION_SERVICE_SKELETON_H_
> #define LOCATION_SERVICE_COM_UBUNTU_LOCATION_SERVICE_SKELETON_H_
>
> -#include "com/ubuntu/location/service/interface.h"
> -#include "com/ubuntu/location/service/permission_manager.h"
> -#include "com/ubuntu/location/service/session/interface.h"
> +#include <com/ubuntu/location/service/interface.h>
> +#include <com/ubuntu/location/service/permission_manager.h>
> +#include <com/ubuntu/location/service/session/interface.h>
>
> +#include <core/dbus/dbus.h>
> +#include <core/dbus/object.h>
> +#include <core/dbus/property.h>
> #include <core/dbus/skeleton.h>
>
> namespace com
> @@ -32,20 +35,111 @@
> {
> namespace service
> {
> -class Skeleton : public core::dbus::Skeleton<com::ubuntu::location::service::Interface>,
> - public std::enable_shared_from_this<Skeleton>
> +class Skeleton
> + : public core::dbus::Skeleton<com::ubuntu::location::service::Interface>,
> + public std::enable_shared_from_this<Skeleton>
> {
> - public:
> +public:
> typedef std::shared_ptr<Skeleton> Ptr;
> -
> - Skeleton(const dbus::Bus::Ptr& connection, const PermissionManager::Ptr& permission_manager);
> - Skeleton(const Skeleton&) = delete;
> - Skeleton& operator=(const Skeleton&) = delete;
> +
> + // Models resolution of an incoming dbus message to the credentials of the message sender.
> + struct CredentialsResolver
> + {
> + typedef std::shared_ptr<CredentialsResolver> Ptr;
> +
> + CredentialsResolver() = default;
> + virtual ~CredentialsResolver() = default;
> +
> + // Resolves the sender of msg to the respective credentials.
> + virtual Credentials resolve_credentials_for_incoming_message(const core::dbus::Message::Ptr& msg) = 0;
> + };
> +
> + // Implements CredentialsResolver by reaching out to the dbus daemon and
> + // invoking:
> + // * GetConnectionUnixProcessID
> + // * GetConnectionUnixUser
> + struct DBusDaemonCredentialsResolver : public CredentialsResolver
> + {
> + // Sets up a new instance for the given bus connection.
> + DBusDaemonCredentialsResolver(const core::dbus::Bus::Ptr& bus);
> +
> + // Resolves the sender of msg to pid, uid by calling out to the dbus daemon.
> + Credentials resolve_credentials_for_incoming_message(const core::dbus::Message::Ptr& msg);
> +
> + // Stub for accessing the dbus daemon.
> + core::dbus::DBus daemon;
> + };
> +
> + // Models the generation of stable and unique object paths for client-specific sessions.
> + // The requirements for the resulting object path are:
> + // * Unique for the entire system over its complete lifetime
> + // * Stable with respect to an app. That is, one app is always assigned the same object path.
> + struct ObjectPathGenerator
> + {
> + typedef std::shared_ptr<ObjectPathGenerator> Ptr;
> +
> + ObjectPathGenerator() = default;
> + virtual ~ObjectPathGenerator() = default;
> +
> + // Calculates an object path from pid and uid. The default implementation
> + // creates the path according to the following steps:
> + // [1.] Query the AppArmor profile name for pid in credentials.
> + // [1.1] If the process is running unconfined, rely on a counter to assemble the session name.
> + // [1.2] If the process is confined, use the AppArmor profile name to generate the path.
> + virtual core::dbus::types::ObjectPath object_path_for_caller_credentials(const Credentials& credentials);
> + };
> +
> + struct Configuration
> + {
> + // DBus connection set up for handling requests to the service.
> + core::dbus::Bus::Ptr incoming;
> + // DBus connection for reaching out to other services in a non-blocking way.
> + core::dbus::Bus::Ptr outgoing;
> + // An implementation of CredentialsResolver for resolving incoming message sender
> + // to Credentials = uid, pid.
> + CredentialsResolver::Ptr credentials_resolver;
> + // An implementation of ObjectPathGenerator for generating session names.
> + ObjectPathGenerator::Ptr object_path_generator;
> + // Permission manager implementation for verifying incoming requests.
> + PermissionManager::Ptr permission_manager;
> + };
> +
> + Skeleton(const Configuration& configuration);
> ~Skeleton() noexcept;
>
> - private:
> - struct Private;
> - std::shared_ptr<Private> d;
> + // From com::ubuntu::location::service::Interface
> + core::Property<bool>& does_satellite_based_positioning();
> + core::Property<bool>& does_report_cell_and_wifi_ids();
> + core::Property<bool>& is_online();
> + core::Property<std::map<SpaceVehicle::Key, SpaceVehicle>>& visible_space_vehicles();
> +
> +private:
> + // Handles incoming message calls for create_session_for_criteria.
> + // Dispatches to the actual implementation, and manages object lifetimes.
> + void handle_create_session_for_criteria(const core::dbus::Message::Ptr& msg);
> +
> + // Tries to register the given session under the given path in the session store.
> + // Returns true iff the session has been added to the store.
> + bool add_to_session_store_for_path(
> + const core::dbus::types::ObjectPath& path,
> + const session::Interface::Ptr& session);
> +
> + // Stores the configuration passed in at creation time.
> + Configuration configuration;
> + // The skeleton object representing com.ubuntu.location.service.Interface on the bus.
> + core::dbus::Object::Ptr object;
> + // DBus properties as exposed on the bus for com.ubuntu.location.service.Interface
> + struct
> + {
> + std::shared_ptr< core::dbus::Property<Interface::Properties::DoesSatelliteBasedPositioning> > does_satellite_based_positioning;
> + std::shared_ptr< core::dbus::Property<Interface::Properties::DoesReportCellAndWifiIds> > does_report_cell_and_wifi_ids;
> + std::shared_ptr< core::dbus::Property<Interface::Properties::IsOnline> > is_online;
> + std::shared_ptr< dbus::Property<Interface::Properties::VisibleSpaceVehicles> > visible_space_vehicles;
> + } properties;
> + // Guards the session store.
> + std::mutex guard;
> + // Keeps track of running sessions, keying them by their unique object path.
> + std::map<dbus::types::ObjectPath, std::shared_ptr<session::Interface>> session_store;
> };
> }
> }
>
> === modified file 'include/location_service/com/ubuntu/location/service/stub.h'
> --- include/location_service/com/ubuntu/location/service/stub.h 2014-01-31 11:08:33 +0000
> +++ include/location_service/com/ubuntu/location/service/stub.h 2014-06-24 16:02:38 +0000
> @@ -18,8 +18,8 @@
> #ifndef LOCATION_SERVICE_COM_UBUNTU_LOCATION_SERVICE_STUB_H_
> #define LOCATION_SERVICE_COM_UBUNTU_LOCATION_SERVICE_STUB_H_
>
> -#include "com/ubuntu/location/service/interface.h"
> -#include "com/ubuntu/location/service/session/interface.h"
> +#include <com/ubuntu/location/service/interface.h>
> +#include <com/ubuntu/location/service/session/interface.h>
>
> #include <core/dbus/stub.h>
>
> @@ -40,6 +40,10 @@
> ~Stub() noexcept;
>
> session::Interface::Ptr create_session_for_criteria(const Criteria& criteria);
> + core::Property<bool>& does_satellite_based_positioning();
> + core::Property<bool>& does_report_cell_and_wifi_ids();
> + core::Property<bool>& is_online();
> + core::Property<std::map<SpaceVehicle::Key, SpaceVehicle>>& visible_space_vehicles();
>
> private:
> struct Private;
>
> === added file 'include/location_service/com/ubuntu/location/space_vehicle.h'
> --- include/location_service/com/ubuntu/location/space_vehicle.h 1970-01-01 00:00:00 +0000
> +++ include/location_service/com/ubuntu/location/space_vehicle.h 2014-06-24 16:02:38 +0000
> @@ -0,0 +1,123 @@
> +/*
> + * Copyright © 2012-2013 Canonical Ltd.
> + *
Update the copyright to 2014.
> + * This program is free software: you can redistribute it and/or modify it
> + * under the terms of the GNU Lesser General Public License version 3,
> + * 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 Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public License
> + * along with this program. If not, see <http://www.gnu.org/licenses/>.
> + *
> + * Authored by: Thomas Voß <thomas.voss at canonical.com>
> + */
> +#ifndef LOCATION_SERVICE_COM_UBUNTU_LOCATION_SPACE_VEHICLE_H_
> +#define LOCATION_SERVICE_COM_UBUNTU_LOCATION_SPACE_VEHICLE_H_
> +
> +#include <com/ubuntu/location/units/units.h>
> +
> +#include <iostream>
> +#include <map>
> +
> +namespace com
> +{
> +namespace ubuntu
> +{
> +namespace location
> +{
> +/** @brief A space-vehicle as visible to providers. */
> +struct SpaceVehicle
> +{
> + /** @brief Numeric Id of an individual SpaceVehicle. */
> + typedef std::uint32_t Id;
> +
> + /** @brief Enumerates all known space-vehicle types. */
> + enum class Type
> + {
> + unknown, ///< Unknown (and thus invalid) type.
> + beidou, ///< People's Republic of China's regional system, currently limited to Asia and the West Pacific
> + galileo, ///< A global system being developed by the European Union and other partner countries, planned to be operational by 2014 (and fully deployed by 2019).
> + glonass, ///< Russia's global navigation system. Fully operational worldwide.
> + gps, ///< Fully operational worldwide.
> + compass, ///< People's Republic of China's global system, planned to be operational by 2020.
> + irnss, ///< India's regional navigation system, planned to be operational by 2014, covering India and Northern Indian Ocean.
> + qzss ///< Japanese regional system covering Asia and Oceania.
> + };
> +
> + /** @brief Uniquely identifies a space vehicle, given its type and its id. */
> + struct Key
> + {
> + Type type = Type::unknown; ///< The positioning system this vehicle belongs to.
> + Id id = 0; ///< Unique id of the space vehicle.
> +
> + inline bool operator==(const SpaceVehicle::Key& rhs) const
> + {
> + return type == rhs.type && id == rhs.id;
> + }
> +
> + inline bool operator<(const SpaceVehicle::Key& rhs) const
> + {
> + if (type != rhs.type)
> + return type < rhs.type;
> +
> + return id < rhs.id;
> + }
> + };
> +
> + inline bool operator==(const SpaceVehicle& rhs) const
> + {
> + return key == rhs.key &&
IS it possible that we have the same key and other data is diff. The key is uniuqe and idenifies an instance. Is that instance a software object instance of a SV instance?
> + has_almanac_data == rhs.has_almanac_data &&
> + has_ephimeris_data == rhs.has_ephimeris_data &&
> + used_in_fix == rhs.used_in_fix &&
> + units::roughly_equals(azimuth, rhs.azimuth) &&
> + units::roughly_equals(elevation, rhs.elevation);
> + }
> +
> + inline bool operator<(const SpaceVehicle& rhs) const
> + {
> + return key < rhs.key;
> + }
> +
> + Key key; ///< Unique key identifying an instance.
AS I asked above is the a software object instance of a SV instance (I suspect in the second case).
> + float snr = -std::numeric_limits<float>::max(); ///< Signal to noise ratio;
> + bool has_almanac_data = false; ///< Almanac data available for this vehicle.
> + bool has_ephimeris_data = false; ///< Ephimeris data is available for this vehicle.
> + bool used_in_fix = false; ///< This vehicle has been used to obtain a fix.
> + units::Quantity<units::PlaneAngle> azimuth; ///< Azimuth of SV.
> + units::Quantity<units::PlaneAngle> elevation; ///< Elevation of SV.
> +};
> +
> +inline std::ostream& operator<<(std::ostream& out, const SpaceVehicle& sv)
> +{
> + static const std::map<SpaceVehicle::Type, std::string> lut =
> + {
> + {SpaceVehicle::Type::unknown, "unknown"},
> + {SpaceVehicle::Type::beidou, "beidou"},
> + {SpaceVehicle::Type::galileo, "galileo"},
> + {SpaceVehicle::Type::glonass, "glonass"},
> + {SpaceVehicle::Type::gps, "gps"},
> + {SpaceVehicle::Type::compass, "compass"},
> + {SpaceVehicle::Type::irnss, "irnss"},
> + {SpaceVehicle::Type::qzss, "qzss" }
I like the use of maps for quick acess, but since we have an enumerator and a string, can't we just use a switch. Nevertheless this is not a huge concern.
> + };
> + return out << "("
> + << "type: " << lut.at(sv.key.type) << ", "
> + << "prn: " << sv.key.id << ", "
> + << "snr: " << sv.snr << ", "
> + << "has_almanac_data: " << sv.has_almanac_data << ", "
> + << "has_ephimeris_data: " << sv.has_ephimeris_data << ", "
> + << "used_in_fix: " << sv.used_in_fix << ", "
> + << "azimuth: " << sv.azimuth << ", "
> + << "elevation: " << sv.elevation
> + << ")";
> +}
> +}
> +}
> +}
> +
> +#endif // LOCATION_SERVICE_COM_UBUNTU_LOCATION_SPACE_VEHICLE_H_
>
> === modified file 'include/location_service/com/ubuntu/location/units/units.h'
> --- include/location_service/com/ubuntu/location/units/units.h 2013-05-28 14:41:06 +0000
> +++ include/location_service/com/ubuntu/location/units/units.h 2014-06-24 16:02:38 +0000
> @@ -57,6 +57,12 @@
> using boost::units::sin;
> using boost::units::cos;
> using boost::units::atan2;
> +
> +template<typename Unit>
> +inline bool roughly_equals(const Quantity<Unit>& lhs, const Quantity<Unit>& rhs)
> +{
> + return std::fabs(lhs.value()-rhs.value()) <= std::numeric_limits<double>::epsilon();
> +}
> }
> }
> }
>
> === modified file 'include/location_service/com/ubuntu/location/update.h'
> --- include/location_service/com/ubuntu/location/update.h 2013-05-29 06:04:02 +0000
> +++ include/location_service/com/ubuntu/location/update.h 2014-06-24 16:02:38 +0000
> @@ -18,7 +18,7 @@
> #ifndef LOCATION_SERVICE_COM_UBUNTU_LOCATION_UPDATE_H_
> #define LOCATION_SERVICE_COM_UBUNTU_LOCATION_UPDATE_H_
>
> -#include "com/ubuntu/location/clock.h"
> +#include <com/ubuntu/location/clock.h>
>
> #include <ostream>
>
> @@ -28,27 +28,56 @@
> {
> namespace location
> {
> +/**
> + * @brief Templated class that wraps a value and timestamp.
> + * @tparam T The contained value.
> + */
> template<typename T>
> struct Update
> {
> - Update(const T& value = T{}, const Clock::Timestamp& when = Clock::Timestamp{}) : value{value}, when{when}
> + /**
> + * @brief Constructs a valid update with the given value and timestamp.
> + * @param [in] value The value delivered with this update.
> + * @param [in] when The timestamp when the value was measured.
> + */
> + inline Update(const T& value = T{},
> + const Clock::Timestamp& when = Clock::now())
> + : value{value}, when{when}
> {
> }
>
> - bool operator==(const Update<T>& rhs) const
> + /**
> + * @brief operator == checks if two updates are equal.
> + * @param [in] rhs The update to check against.
> + * @return true iff this instance equals rhs.
> + */
> + inline bool operator==(const Update<T>& rhs) const
> {
> return value == rhs.value && when == rhs.when;
> }
>
> - bool operator!=(const Update<T>& rhs) const
> + /**
> + * @brief operator != checks if two updates are unequal.
> + * @param [in] rhs The update to check against.
> + * @return true iff this instance does not equal rhs.
> + */
> + inline bool operator!=(const Update<T>& rhs) const
> {
> return !(value == rhs.value && when == rhs.when);
> }
>
> + /** The value delivered with this update. */
> T value;
> - Clock::Timestamp when;
> +
> + /** Time when the updated value was measured. */
> + Clock::Timestamp when = Clock::beginning_of_time();
> };
>
> +/**
> + * @brief Pretty-prints the update to the provided output stream.
> + * @param out The stream to write to.
> + * @param update The value to be printed.
> + */
> template<typename T>
> inline std::ostream& operator<<(std::ostream& out, const Update<T>& update)
> {
>
> === modified file 'include/location_service/com/ubuntu/location/velocity.h'
> --- include/location_service/com/ubuntu/location/velocity.h 2013-05-28 14:41:06 +0000
> +++ include/location_service/com/ubuntu/location/velocity.h 2014-06-24 16:02:38 +0000
> @@ -18,12 +18,7 @@
> #ifndef LOCATION_SERVICE_COM_UBUNTU_LOCATION_VELOCITY_H_
> #define LOCATION_SERVICE_COM_UBUNTU_LOCATION_VELOCITY_H_
>
> -#include "com/ubuntu/location/accuracy.h"
> -#include "com/ubuntu/location/units/units.h"
> -
> -#include <limits>
> -#include <ostream>
> -#include <stdexcept>
> +#include <com/ubuntu/location/units/units.h>
>
> namespace com
> {
> @@ -31,74 +26,8 @@
> {
> namespace location
> {
> -struct Velocity
> -{
> - typedef units::Velocity Unit;
> - typedef units::Quantity<Unit> Quantity;
> -
> - static inline const Quantity& min()
> - {
> - static const Quantity instance = Quantity::from_value(0.);
> - return instance;
> - }
> -
> - static inline const Quantity max()
> - {
> - static const Quantity instance = Quantity::from_value(std::numeric_limits<double>::max());
> - return instance;
> - }
> -
> - Velocity(const Quantity& value = Quantity()) : value(value)
> - {
> - if (value < Velocity::min())
> - throw std::out_of_range("");
> - if (value > Velocity::max())
> - throw std::out_of_range("");
> - }
> -
> - inline bool operator==(const Velocity& rhs) const
> - {
> - return value == rhs.value;
> - }
> -
> - inline bool operator!=(const Velocity& rhs) const
> - {
> - return value != rhs.value;
> - }
> -
> - Quantity value;
> -};
> -
> -inline std::ostream& operator<<(std::ostream& out, const Velocity& velocity)
> -{
> - out << "Velocity(" << velocity.value << ")";
> - return out;
> -}
> -
> -template<>
> -struct AccuracyTraits<Velocity>
> -{
> - static AccuracyLevel classify(const Velocity& h)
> - {
> - if (h.value > (1.f * units::MetersPerSecond))
> - return AccuracyLevel::worst;
> -
> - if (h.value <= (1.f * units::MetersPerSecond))
> - return AccuracyLevel::best;
> -
> - return AccuracyLevel::worst;
> - }
> -
> - static Accuracy<Velocity> best()
> - {
> - return Accuracy<Velocity>{Velocity{Velocity::min()}};
> - }
> -
> - static Accuracy<Velocity> worst()
> - {
> - return Accuracy<Velocity>{Velocity{2*units::MetersPerSecond}};
> - }
> -};
> +/** @brief Velocity is measured in m/s. */
> +typedef units::Quantity<units::Velocity> Velocity;
> }
> }
> }
>
> === modified file 'include/location_service/com/ubuntu/location/wgs84/altitude.h'
> --- include/location_service/com/ubuntu/location/wgs84/altitude.h 2013-05-28 14:41:06 +0000
> +++ include/location_service/com/ubuntu/location/wgs84/altitude.h 2014-06-24 16:02:38 +0000
> @@ -18,8 +18,8 @@
> #ifndef LOCATION_SERVICE_COM_UBUNTU_LOCATION_WGS84_ALTITUDE_H_
> #define LOCATION_SERVICE_COM_UBUNTU_LOCATION_WGS84_ALTITUDE_H_
>
> -#include "com/ubuntu/location/units/units.h"
> -#include "com/ubuntu/location/wgs84/coordinate.h"
> +#include <com/ubuntu/location/units/units.h>
> +#include <com/ubuntu/location/wgs84/coordinate.h>
>
> namespace com
> {
>
> === modified file 'include/location_service/com/ubuntu/location/wgs84/coordinate.h'
> --- include/location_service/com/ubuntu/location/wgs84/coordinate.h 2013-05-28 14:41:06 +0000
> +++ include/location_service/com/ubuntu/location/wgs84/coordinate.h 2014-06-24 16:02:38 +0000
> @@ -18,7 +18,7 @@
> #ifndef LOCATION_SERVICE_COM_UBUNTU_LOCATION_WGS84_COORDINATE_H_
> #define LOCATION_SERVICE_COM_UBUNTU_LOCATION_WGS84_COORDINATE_H_
>
> -#include "com/ubuntu/location/units/units.h"
> +#include <com/ubuntu/location/units/units.h>
>
> #include <ostream>
>
> @@ -39,12 +39,14 @@
> };
>
> template<typename Tag, typename UnitType>
> -struct Coordinate
> +class Coordinate
> {
> +public:
> typedef UnitType Unit;
> typedef units::Quantity<Unit> Quantity;
>
> - explicit Coordinate(const Quantity& value = Quantity()) : value(value)
> + explicit Coordinate(const Quantity& value = Quantity())
> + : value(value)
> {
> CoordinateTraits<Coordinate<Tag,UnitType>>::check_and_throw_if_invalid(value);
> }
>
> === modified file 'include/location_service/com/ubuntu/location/wgs84/latitude.h'
> --- include/location_service/com/ubuntu/location/wgs84/latitude.h 2013-05-28 14:41:06 +0000
> +++ include/location_service/com/ubuntu/location/wgs84/latitude.h 2014-06-24 16:02:38 +0000
> @@ -18,8 +18,8 @@
> #ifndef LOCATION_SERVICE_COM_UBUNTU_LOCATION_WGS84_LATITUDE_H_
> #define LOCATION_SERVICE_COM_UBUNTU_LOCATION_WGS84_LATITUDE_H_
>
> -#include "com/ubuntu/location/units/units.h"
> -#include "com/ubuntu/location/wgs84/coordinate.h"
> +#include <com/ubuntu/location/units/units.h>
> +#include <com/ubuntu/location/wgs84/coordinate.h>
>
> #include <stdexcept>
>
>
> === modified file 'include/location_service/com/ubuntu/location/wgs84/longitude.h'
> --- include/location_service/com/ubuntu/location/wgs84/longitude.h 2013-05-28 14:41:06 +0000
> +++ include/location_service/com/ubuntu/location/wgs84/longitude.h 2014-06-24 16:02:38 +0000
> @@ -18,8 +18,8 @@
> #ifndef LOCATION_SERVICE_COM_UBUNTU_LOCATION_WGS84_LONGITUDE_H_
> #define LOCATION_SERVICE_COM_UBUNTU_LOCATION_WGS84_LONGITUDE_H_
>
> -#include "com/ubuntu/location/units/units.h"
> -#include "com/ubuntu/location/wgs84/coordinate.h"
> +#include <com/ubuntu/location/units/units.h>
> +#include <com/ubuntu/location/wgs84/coordinate.h>
>
> #include <stdexcept>
>
>
> === added file 'include/location_service/com/ubuntu/location/wifi_and_cell_reporting_state.h'
> --- include/location_service/com/ubuntu/location/wifi_and_cell_reporting_state.h 1970-01-01 00:00:00 +0000
> +++ include/location_service/com/ubuntu/location/wifi_and_cell_reporting_state.h 2014-06-24 16:02:38 +0000
> @@ -0,0 +1,36 @@
> +/*
> + * Copyright © 2012-2013 Canonical Ltd.
> + *
> + * This program is free software: you can redistribute it and/or modify it
> + * under the terms of the GNU Lesser General Public License version 3,
> + * 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 Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public License
> + * along with this program. If not, see <http://www.gnu.org/licenses/>.
> + *
> + * Authored by: Thomas Voß <thomas.voss at canonical.com>
> + */
> +#ifndef LOCATION_SERVICE_COM_UBUNTU_LOCATION_WIFI_AND_CELL_REPORTING_STATE_H_
> +#define LOCATION_SERVICE_COM_UBUNTU_LOCATION_WIFI_AND_CELL_REPORTING_STATE_H_
> +
> +namespace com
> +{
> +namespace ubuntu
> +{
> +namespace location
> +{
> +enum class WifiAndCellIdReportingState
> +{
> + on, ///< Wifi and Cell Ids might be reported to online location services.
> + off ///< Wifi and Cell Ids are _not_ reported. This is the default value.
> +};
> +}
> +}
> +}
> +
> +#endif // LOCATION_SERVICE_COM_UBUNTU_LOCATION_WIFI_AND_CELL_REPORTING_STATE_H_
>
> === modified file 'src/location_service/com/ubuntu/location/CMakeLists.txt'
> --- src/location_service/com/ubuntu/location/CMakeLists.txt 2014-01-31 11:08:33 +0000
> +++ src/location_service/com/ubuntu/location/CMakeLists.txt 2014-06-24 16:02:38 +0000
> @@ -1,19 +1,31 @@
> +if (${NET_CPP_FOUND})
> + add_definitions(-DCOM_UBUNTU_LOCATION_SERVICE_HAVE_NET_CPP=1)
> +
> + set(ICHNAEA_REPORTER_SRCS service/ichnaea_reporter.cpp)
> +endif (${NET_CPP_FOUND})
> +
> add_subdirectory(providers)
>
> add_library(
> ubuntu-location-service SHARED
>
> + ${UBUNTU_LOCATION_SERVICE_PUBLIC_HEADERS}
> +
> default_provider_selection_policy.cpp
>
> + criteria.cpp
> engine.cpp
> init_and_shutdown.cpp
> position.cpp
> provider.cpp
> provider_factory.cpp
> proxy_provider.cpp
> + set_name_for_thread.cpp
>
> service/default_configuration.cpp
> service/default_permission_manager.cpp
> + service/harvester.cpp
> +
> service/implementation.cpp
> service/skeleton.cpp
> service/stub.cpp
> @@ -24,12 +36,38 @@
> service/session/stub.cpp
>
> providers/config.cpp
> -)
> +
> + ${ICHNAEA_REPORTER_SRCS}
> +)
> +
> +add_library(
> + ubuntu-location-service-connectivity SHARED
> +
> + set_name_for_thread.cpp
> +
> + connectivity/radio_cell.cpp
> + connectivity/wireless_network.cpp
> + connectivity/ofono_nm_connectivity_manager.cpp
> +)
> +
> +set(symbol_map "${CMAKE_SOURCE_DIR}/symbols.map")
>
> set_target_properties(
> ubuntu-location-service
>
> PROPERTIES
> + LINK_FLAGS "${ldflags} -Wl,--version-script,${symbol_map}"
> + LINK_DEPENDS ${symbol_map}
> + VERSION ${UBUNTU_LOCATION_SERVICE_VERSION_MAJOR}.${UBUNTU_LOCATION_SERVICE_VERSION_MINOR}.${UBUNTU_LOCATION_SERVICE_VERSION_PATCH}
> + SOVERSION ${UBUNTU_LOCATION_SERVICE_VERSION_MAJOR}
> +)
> +
> +set_target_properties(
> + ubuntu-location-service-connectivity
> +
> + PROPERTIES
> + LINK_FLAGS "${ldflags} -Wl,--version-script,${symbol_map}"
> + LINK_DEPENDS ${symbol_map}
> VERSION ${UBUNTU_LOCATION_SERVICE_VERSION_MAJOR}.${UBUNTU_LOCATION_SERVICE_VERSION_MINOR}.${UBUNTU_LOCATION_SERVICE_VERSION_PATCH}
> SOVERSION ${UBUNTU_LOCATION_SERVICE_VERSION_MAJOR}
> )
> @@ -37,13 +75,30 @@
> add_definitions(${ENABLED_PROVIDER_TARGETS_DEFINITIONS})
>
> target_link_libraries(
> + ubuntu-location-service-connectivity
> +
> + ${CMAKE_THREAD_LIBS_INIT}
> + ${Boost_LIBRARIES}
> + ${DBUS_LIBRARIES}
> + ${DBUS_CPP_LDFLAGS}
> + ${PROCESS_CPP_LDFLAGS}
> + ${GLog_LIBRARY}
> + ${GFlags_LIBRARY}
> +)
> +
> +target_link_libraries(
> ubuntu-location-service
>
> + ubuntu-location-service-connectivity
> +
> ${ENABLED_PROVIDER_TARGETS}
>
> + ${CMAKE_THREAD_LIBS_INIT}
> ${Boost_LIBRARIES}
> ${DBUS_LIBRARIES}
> ${DBUS_CPP_LDFLAGS}
> + ${JSON_CPP_LDFLAGS}
> + ${NET_CPP_LDFLAGS}
> ${GLog_LIBRARY}
> ${GFlags_LIBRARY}
> )
> @@ -53,21 +108,59 @@
> DESTINATION ${CMAKE_INSTALL_LIBDIR}
> )
>
> +install(
> + TARGETS ubuntu-location-service-connectivity
> + DESTINATION ${CMAKE_INSTALL_LIBDIR}
> +)
> +
> +add_library(
> + ubuntu-location-service-daemon
> +
> + service/daemon.cpp
> +)
> +
> add_executable(
> ubuntu-location-serviced
>
> - service/main.cpp
> + service/daemon_main.cpp
> +)
> +
> +add_executable(
> + ubuntu-location-serviced-cli
> +
> + service/daemon_cli_main.cpp
> )
>
> target_link_libraries(
> - ubuntu-location-serviced
> + ubuntu-location-service-daemon
>
> ubuntu-location-service
> -
> - ${ENABLED_PROVIDER_TARGETS}
> -
> - ${Boost_LIBRARIES}
> - ${DBUS_LIBRARIES}
> +)
> +
> +target_link_libraries(
> + ubuntu-location-serviced
> +
> + ubuntu-location-service-daemon
> +
> + ${ENABLED_PROVIDER_TARGETS}
> +
> + ${Boost_LIBRARIES}
> + ${DBUS_LIBRARIES}
> + ${DBUS_CPP_LIBRARIES}
> + ${GLog_LIBRARY}
> + ${GFlags_LIBRARY}
> +)
> +
> +target_link_libraries(
> + ubuntu-location-serviced-cli
> +
> + ubuntu-location-service-daemon
> +
> + ${ENABLED_PROVIDER_TARGETS}
> +
> + ${Boost_LIBRARIES}
> + ${DBUS_LIBRARIES}
> + ${DBUS_CPP_LIBRARIES}
> ${GLog_LIBRARY}
> ${GFlags_LIBRARY}
> )
> @@ -77,3 +170,8 @@
> DESTINATION ${CMAKE_INSTALL_BINDIR}
> )
>
> +install(
> + TARGETS ubuntu-location-serviced-cli
> + DESTINATION ${CMAKE_INSTALL_BINDIR}
> +)
> +
>
> === added directory 'src/location_service/com/ubuntu/location/connectivity'
> === added file 'src/location_service/com/ubuntu/location/connectivity/cached_radio_cell.h'
> --- src/location_service/com/ubuntu/location/connectivity/cached_radio_cell.h 1970-01-01 00:00:00 +0000
> +++ src/location_service/com/ubuntu/location/connectivity/cached_radio_cell.h 2014-06-24 16:02:38 +0000
> @@ -0,0 +1,489 @@
> +/*
> + * Copyright © 2012-2014 Canonical Ltd.
> + *
> + * This program is free software: you can redistribute it and/or modify it
> + * under the terms of the GNU Lesser General Public License version 3,
> + * 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 Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public License
> + * along with this program. If not, see <http://www.gnu.org/licenses/>.
> + *
> + * Authored by: Thomas Voß <thomas.voss at canonical.com>
> + */
> +#ifndef CACHED_RADIO_CELL_H_
> +#define CACHED_RADIO_CELL_H_
> +
> +#include <com/ubuntu/location/connectivity/radio_cell.h>
> +
> +#include "ofono.h"
> +
> +namespace
> +{
> +
> +struct CachedRadioCell : public com::ubuntu::location::connectivity::RadioCell
> +{
> + typedef std::shared_ptr<CachedRadioCell> Ptr;
> +
> + static const std::map<std::string, com::ubuntu::location::connectivity::RadioCell::Type>& type_lut()
> + {
> + static const std::map<std::string, com::ubuntu::location::connectivity::RadioCell::Type> lut
> + {
> + {
> + org::Ofono::Manager::Modem::NetworkRegistration::Technology::gsm(),
> + com::ubuntu::location::connectivity::RadioCell::Type::gsm
> + },
> + {
> + org::Ofono::Manager::Modem::NetworkRegistration::Technology::lte(),
> + com::ubuntu::location::connectivity::RadioCell::Type::lte
> + },
> + {
> + org::Ofono::Manager::Modem::NetworkRegistration::Technology::umts(),
> + com::ubuntu::location::connectivity::RadioCell::Type::umts
> + },
> + {
> + org::Ofono::Manager::Modem::NetworkRegistration::Technology::edge(),
> + com::ubuntu::location::connectivity::RadioCell::Type::unknown
> + },
> + {
> + org::Ofono::Manager::Modem::NetworkRegistration::Technology::hspa(),
> + com::ubuntu::location::connectivity::RadioCell::Type::unknown
> + },
> + {std::string(), com::ubuntu::location::connectivity::RadioCell::Type::unknown}
> + };
> +
> + return lut;
> + };
> +
> + CachedRadioCell(const org::Ofono::Manager::Modem& modem)
> + : RadioCell(), radio_type(Type::gsm), modem(modem), detail{Gsm()}
> + {
> + auto technology =
> + modem.network_registration.get<
> + org::Ofono::Manager::Modem::NetworkRegistration::Technology
> + >();
> +
> + auto it = type_lut().find(technology);
> +
> + if (it == type_lut().end()) throw std::runtime_error
> + {
> + "Unknown technology for connected cell: " + technology
> + };
> +
> + if (it->second == com::ubuntu::location::connectivity::RadioCell::Type::unknown) throw std::runtime_error
> + {
> + "Unknown technology for connected cell: " + technology
> + };
> +
> + radio_type = it->second;
> +
> + auto lac =
> + modem.network_registration.get<
> + org::Ofono::Manager::Modem::NetworkRegistration::LocationAreaCode
> + >();
> +
> + int cell_id =
> + modem.network_registration.get<
> + org::Ofono::Manager::Modem::NetworkRegistration::CellId
> + >();
> +
> + auto strength =
> + modem.network_registration.get<
> + org::Ofono::Manager::Modem::NetworkRegistration::Strength
> + >();
> +
> + std::stringstream ssmcc
> + {
> + modem.network_registration.get<
> + org::Ofono::Manager::Modem::NetworkRegistration::MobileCountryCode
> + >()
> + };
> + int mcc{0}; ssmcc >> mcc;
> + std::stringstream ssmnc
> + {
> + modem.network_registration.get<
> + org::Ofono::Manager::Modem::NetworkRegistration::MobileNetworkCode
> + >()
> + };
> + int mnc{0}; ssmnc >> mnc;
> +
> + switch(radio_type)
> + {
> + case com::ubuntu::location::connectivity::RadioCell::Type::gsm:
> + {
> + com::ubuntu::location::connectivity::RadioCell::Gsm gsm
> + {
> + com::ubuntu::location::connectivity::RadioCell::Gsm::MCC{mcc},
> + com::ubuntu::location::connectivity::RadioCell::Gsm::MNC{mnc},
> + com::ubuntu::location::connectivity::RadioCell::Gsm::LAC{lac},
> + com::ubuntu::location::connectivity::RadioCell::Gsm::ID{cell_id},
> + com::ubuntu::location::connectivity::RadioCell::Gsm::SignalStrength::from_percent(strength/100.f)
> + };
> + VLOG(1) << gsm;
> + detail.gsm = gsm;
> + break;
> + }
> + case com::ubuntu::location::connectivity::RadioCell::Type::lte:
> + {
> + com::ubuntu::location::connectivity::RadioCell::Lte lte
> + {
> + com::ubuntu::location::connectivity::RadioCell::Lte::MCC{mcc},
> + com::ubuntu::location::connectivity::RadioCell::Lte::MNC{mnc},
> + com::ubuntu::location::connectivity::RadioCell::Lte::TAC{lac},
> + com::ubuntu::location::connectivity::RadioCell::Lte::ID{cell_id},
> + com::ubuntu::location::connectivity::RadioCell::Lte::PID{},
> + com::ubuntu::location::connectivity::RadioCell::Lte::SignalStrength::from_percent(strength/100.f)
> + };
> + VLOG(1) << lte;
> + detail.lte = lte;
> + break;
> + }
> + case com::ubuntu::location::connectivity::RadioCell::Type::umts:
> + {
> + com::ubuntu::location::connectivity::RadioCell::Umts umts
> + {
> + com::ubuntu::location::connectivity::RadioCell::Umts::MCC{mcc},
> + com::ubuntu::location::connectivity::RadioCell::Umts::MNC{mnc},
> + com::ubuntu::location::connectivity::RadioCell::Umts::LAC{lac},
> + com::ubuntu::location::connectivity::RadioCell::Umts::ID{cell_id},
> + com::ubuntu::location::connectivity::RadioCell::Umts::SignalStrength::from_percent(strength/100.f)
> + };
> + VLOG(1) << umts;
> + detail.umts = umts;
> + break;
> + }
> + default:
> + break;
> + }
> +
> + modem.signals.property_changed->connect([this](const std::tuple<std::string, core::dbus::types::Variant>& tuple)
> + {
> + on_modem_property_changed(tuple);
> + });
> +
> + modem.network_registration.signals.property_changed->connect([this](const std::tuple<std::string, core::dbus::types::Variant>& tuple)
> + {
> + on_network_registration_property_changed(tuple);
> + });
> + }
> +
> + const core::Signal<>& changed() const override
> + {
> + return on_changed;
> + }
> +
> + com::ubuntu::location::connectivity::RadioCell::Type type() const override
> + {
> + return radio_type;
> + }
> +
> + const com::ubuntu::location::connectivity::RadioCell::Gsm& gsm() const override
> + {
> + if (radio_type != com::ubuntu::location::connectivity::RadioCell::Type::gsm)
> + throw std::runtime_error("Bad access to unset network type.");
> +
> + return detail.gsm;
> + }
> +
> + const com::ubuntu::location::connectivity::RadioCell::Umts& umts() const override
> + {
> + if (radio_type != RadioCell::Type::umts)
> + throw std::runtime_error("Bad access to unset network type.");
> +
> + return detail.umts;
> + }
> +
> + const com::ubuntu::location::connectivity::RadioCell::Lte& lte() const override
> + {
> + if (radio_type != RadioCell::Type::lte)
> + throw std::runtime_error("Bad access to unset network type.");
> +
> + return detail.lte;
> + }
> +
> + void on_modem_property_changed(const std::tuple<std::string, core::dbus::types::Variant>& tuple)
> + {
> + VLOG(10) << "Property on modem " << modem.object->path() << " changed: " << std::get<0>(tuple);
> + }
> +
> + void on_network_registration_property_changed(const std::tuple<std::string, core::dbus::types::Variant>& tuple)
> + {
> + VLOG(10) << "Property changed on modem " << modem.object->path() << " for network registration: " << std::get<0>(tuple);
> +
> + const auto& key = std::get<0>(tuple);
> + const auto& variant = std::get<1>(tuple);
> +
> + if (key == org::Ofono::Manager::Modem::NetworkRegistration::Technology::name())
> + {
> + auto value = variant.as<
> + org::Ofono::Manager::Modem::NetworkRegistration::Technology::ValueType
> + >();
> +
> + auto it = type_lut().find(value);
> +
> + if (it == type_lut().end())
> + {
> + LOG(WARNING) << "Unknown technology for connected cell: " << value;
> + return;
> + }
> +
> + if (it->second == com::ubuntu::location::connectivity::RadioCell::Type::unknown)
> + {
> + LOG(WARNING) << "Unknown technology for connected cell: " + value;
> + return;
> + }
> +
> + if (radio_type == it->second)
> + return;
> +
> + switch(radio_type)
> + {
> + case com::ubuntu::location::connectivity::RadioCell::Type::gsm:
> + switch(it->second)
> + {
> + case com::ubuntu::location::connectivity::RadioCell::Type::umts:
> + detail.umts.location_area_code = detail.gsm.location_area_code;
> + detail.umts.mobile_network_code = detail.gsm.mobile_network_code;
> + detail.umts.mobile_country_code = detail.gsm.mobile_country_code;
> + detail.umts.strength.reset();
> + detail.umts.id.reset();
> + break;
> + case com::ubuntu::location::connectivity::RadioCell::Type::lte:
> + detail.lte.tracking_area_code = detail.gsm.location_area_code;
> + detail.lte.mobile_network_code = detail.gsm.mobile_network_code;
> + detail.lte.mobile_country_code = detail.gsm.mobile_country_code;
> + detail.lte.strength.reset();
> + detail.lte.id.reset();
> + break;
> + }
> + break;
> + case com::ubuntu::location::connectivity::RadioCell::Type::umts:
> + switch(it->second)
> + {
> + case com::ubuntu::location::connectivity::RadioCell::Type::gsm:
> + detail.gsm.location_area_code = detail.umts.location_area_code;
> + detail.gsm.mobile_network_code = detail.umts.mobile_network_code;
> + detail.gsm.mobile_country_code = detail.umts.mobile_country_code;
> + detail.gsm.strength.reset();
> + detail.gsm.id.reset();
> + break;
> + case com::ubuntu::location::connectivity::RadioCell::Type::lte:
> + detail.lte.tracking_area_code = detail.umts.location_area_code;
> + detail.lte.mobile_network_code = detail.umts.mobile_network_code;
> + detail.lte.mobile_country_code = detail.umts.mobile_country_code;
> + detail.lte.strength.reset();
> + detail.lte.id.reset();
> + break;
> + }
> + break;
> + case com::ubuntu::location::connectivity::RadioCell::Type::lte:
> + switch(it->second)
> + {
> + case com::ubuntu::location::connectivity::RadioCell::Type::gsm:
> + detail.gsm.location_area_code = detail.lte.tracking_area_code;
> + detail.gsm.mobile_network_code = detail.lte.mobile_network_code;
> + detail.gsm.mobile_country_code = detail.lte.mobile_country_code;
> + detail.gsm.strength.reset();
> + detail.gsm.id.reset();
> + break;
> + case com::ubuntu::location::connectivity::RadioCell::Type::umts:
> + detail.umts.location_area_code = detail.lte.tracking_area_code;
> + detail.umts.mobile_network_code = detail.lte.mobile_network_code;
> + detail.umts.mobile_country_code = detail.lte.mobile_country_code;
> + detail.umts.strength.reset();
> + detail.umts.id.reset();
> + break;
> + }
> + default:
> + break;
> + };
> +
> + radio_type = it->second;
> + on_changed();
> + }
> +
> + if (key == org::Ofono::Manager::Modem::NetworkRegistration::CellId::name())
> + {
> + auto value = variant.as<
> + org::Ofono::Manager::Modem::NetworkRegistration::CellId::ValueType
> + >();
> +
> + switch(radio_type)
> + {
> + case com::ubuntu::location::connectivity::RadioCell::Type::gsm:
> + detail.gsm.id.set(value);
> + VLOG(1) << detail.gsm;
> + break;
> + case com::ubuntu::location::connectivity::RadioCell::Type::umts:
> + detail.umts.id.set(value);
> + VLOG(1) << detail.umts;
> + break;
> + case com::ubuntu::location::connectivity::RadioCell::Type::lte:
> + detail.lte.id.set(value);
> + VLOG(1) << detail.lte;
> + break;
> + default:
> + break;
> + };
> +
> + on_changed();
> + }
> +
> + if (key == org::Ofono::Manager::Modem::NetworkRegistration::LocationAreaCode::name())
> + {
> + auto value = variant.as<
> + org::Ofono::Manager::Modem::NetworkRegistration::LocationAreaCode::ValueType
> + >();
> + switch(radio_type)
> + {
> + case com::ubuntu::location::connectivity::RadioCell::Type::gsm:
> + detail.gsm.location_area_code.set(value);
> + VLOG(1) << detail.gsm;
> + break;
> + case com::ubuntu::location::connectivity::RadioCell::Type::umts:
> + detail.umts.location_area_code.set(value);
> + VLOG(1) << detail.umts;
> + break;
> + case com::ubuntu::location::connectivity::RadioCell::Type::lte:
> + detail.lte.tracking_area_code.set(value);
> + VLOG(1) << detail.lte;
> + break;
> + default:
> + break;
> + };
> +
> + on_changed();
> + }
> +
> + if (key == org::Ofono::Manager::Modem::NetworkRegistration::MobileCountryCode::name())
> + {
> + std::stringstream ss
> + {
> + variant.as<
> + org::Ofono::Manager::Modem::NetworkRegistration::MobileCountryCode::ValueType
> + >()
> + };
> + int value{-1}; ss >> value;
> +
> + switch(radio_type)
> + {
> + case com::ubuntu::location::connectivity::RadioCell::Type::gsm:
> + detail.gsm.mobile_country_code.set(value);
> + VLOG(1) << detail.gsm;
> + break;
> + case com::ubuntu::location::connectivity::RadioCell::Type::umts:
> + detail.umts.mobile_country_code.set(value);
> + VLOG(1) << detail.umts;
> + break;
> + case com::ubuntu::location::connectivity::RadioCell::Type::lte:
> + detail.lte.mobile_country_code.set(value);
> + VLOG(1) << detail.lte;
> + break;
> + default:
> + break;
> + };
> +
> + on_changed();
> + }
> +
> + if (key == org::Ofono::Manager::Modem::NetworkRegistration::MobileNetworkCode::name())
> + {
> + std::stringstream ss
> + {
> + variant.as<
> + org::Ofono::Manager::Modem::NetworkRegistration::MobileNetworkCode::ValueType
> + >()
> + };
> + int value{-1}; ss >> value;
> +
> + switch(radio_type)
> + {
> + case com::ubuntu::location::connectivity::RadioCell::Type::gsm:
> + detail.gsm.mobile_network_code.set(value);
> + VLOG(1) << detail.gsm;
> + break;
> + case com::ubuntu::location::connectivity::RadioCell::Type::umts:
> + detail.umts.mobile_network_code.set(value);
> + VLOG(1) << detail.umts;
> + break;
> + case com::ubuntu::location::connectivity::RadioCell::Type::lte:
> + detail.lte.mobile_network_code.set(value);
> + VLOG(1) << detail.lte;
> + break;
> + default:
> + break;
> + };
> +
> + on_changed();
> + }
> +
> + if (key == org::Ofono::Manager::Modem::NetworkRegistration::Strength::name())
> + {
> + auto value = variant.as<
> + org::Ofono::Manager::Modem::NetworkRegistration::Strength::ValueType
> + >();
> +
> + switch(radio_type)
> + {
> + case com::ubuntu::location::connectivity::RadioCell::Type::gsm:
> + detail.gsm.strength
> + = com::ubuntu::location::connectivity::RadioCell::Gsm::SignalStrength::from_percent(value/100.f);
> + VLOG(1) << detail.gsm;
> + break;
> + case com::ubuntu::location::connectivity::RadioCell::Type::umts:
> + detail.umts.strength
> + = com::ubuntu::location::connectivity::RadioCell::Umts::SignalStrength::from_percent(value/100.f);
> + VLOG(1) << detail.umts;
> + break;
> + case com::ubuntu::location::connectivity::RadioCell::Type::lte:
> + detail.lte.strength
> + = com::ubuntu::location::connectivity::RadioCell::Lte::SignalStrength::from_percent(value/100.f);
> + VLOG(1) << detail.lte;
> + break;
> + default:
> + break;
> + };
> +
> + on_changed();
> + }
> + }
> +
> + /** @cond */
> + core::Signal<> on_changed;
> + Type radio_type;
> + org::Ofono::Manager::Modem modem;
> +
> + struct None {};
> +
> + union Detail
> + {
> + Detail() : none(None{})
> + {
> + }
> +
> + Detail(const com::ubuntu::location::connectivity::RadioCell::Gsm& gsm) : gsm(gsm)
> + {
> + }
> +
> + Detail(const com::ubuntu::location::connectivity::RadioCell::Umts& umts) : umts(umts)
> + {
> + }
> +
> + Detail(const com::ubuntu::location::connectivity::RadioCell::Lte& lte) : lte(lte)
> + {
> + }
> +
> + None none;
> + Gsm gsm;
> + Umts umts;
> + Lte lte;
> + } detail;
> + /** @endcond */
> +};
> +}
> +
> +#endif // CACHED_RADIO_CELL_H_
>
> === added file 'src/location_service/com/ubuntu/location/connectivity/cached_wireless_network.h'
> --- src/location_service/com/ubuntu/location/connectivity/cached_wireless_network.h 1970-01-01 00:00:00 +0000
> +++ src/location_service/com/ubuntu/location/connectivity/cached_wireless_network.h 2014-06-24 16:02:38 +0000
> @@ -0,0 +1,218 @@
> +/*
> + * Copyright © 2012-2014 Canonical Ltd.
> + *
> + * This program is free software: you can redistribute it and/or modify it
> + * under the terms of the GNU Lesser General Public License version 3,
> + * 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 Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public License
> + * along with this program. If not, see <http://www.gnu.org/licenses/>.
> + *
> + * Authored by: Thomas Voß <thomas.voss at canonical.com>
> + */
> +#ifndef CACHED_WIRELESS_NETWORK_H_
> +#define CACHED_WIRELESS_NETWORK_H_
> +
> +#include <com/ubuntu/location/connectivity/wireless_network.h>
> +
> +#include <com/ubuntu/location/logging.h>
> +
> +#include "nm.h"
> +
> +namespace
> +{
> +std::string utf8_ssid_to_string(const org::freedesktop::NetworkManager::AccessPoint::Ssid::ValueType& ssid)
> +{
> + return std::string(ssid.begin(), ssid.end());
> +}
> +
> +com::ubuntu::location::connectivity::WirelessNetwork::Mode
> +wifi_mode_from_ap_mode(org::freedesktop::NetworkManager::AccessPoint::Mode::ValueType value)
> +{
> + com::ubuntu::location::connectivity::WirelessNetwork::Mode mode
> + {
> + com::ubuntu::location::connectivity::WirelessNetwork::Mode::unknown
> + };
> +
> + switch (value)
> + {
> + case org::freedesktop::NetworkManager::AccessPoint::Mode::Value::unknown:
> + mode = com::ubuntu::location::connectivity::WirelessNetwork::Mode::unknown;
> + break;
> + case org::freedesktop::NetworkManager::AccessPoint::Mode::Value::adhoc:
> + mode = com::ubuntu::location::connectivity::WirelessNetwork::Mode::adhoc;
> + break;
> + case org::freedesktop::NetworkManager::AccessPoint::Mode::Value::infra:
> + mode = com::ubuntu::location::connectivity::WirelessNetwork::Mode::infrastructure;
> + break;
> + }
> +
> + return mode;
> +}
> +
> +struct CachedWirelessNetwork : public com::ubuntu::location::connectivity::WirelessNetwork
> +{
> + typedef std::shared_ptr<CachedWirelessNetwork> Ptr;
> +
> + const core::Property<std::chrono::system_clock::time_point>& last_seen() const override
> + {
> + return last_seen_;
> + }
> +
> + const core::Property<std::string>& bssid() const override
> + {
> + return bssid_;
> + }
> +
> + const core::Property<std::string>& ssid() const override
> + {
> + return ssid_;
> + }
> +
> + const core::Property<Mode>& mode() const override
> + {
> + return mode_;
> + }
> +
> + const core::Property<Frequency>& frequency() const override
> + {
> + return frequency_;
> + }
> +
> + const core::Property<SignalStrength>& signal_strength() const override
> + {
> + return signal_strength_;
> + }
> +
> + CachedWirelessNetwork(
> + const org::freedesktop::NetworkManager::Device& device,
> + const org::freedesktop::NetworkManager::AccessPoint& ap)
> + : device_(device),
> + access_point_(ap)
> + {
> + try
> + {
> + last_seen_ = std::chrono::system_clock::time_point
> + {
> + std::chrono::system_clock::duration{access_point_.last_seen->get()}
> + };
> + } catch(const std::exception& e)
> + {
> + LOG(WARNING) << e.what();
> + }
> +
> + bssid_ = access_point_.hw_address->get();
> + ssid_ = utf8_ssid_to_string(access_point_.ssid->get());
> + mode_ = wifi_mode_from_ap_mode(access_point_.mode->get());
> + frequency_ = com::ubuntu::location::connectivity::WirelessNetwork::Frequency
> + {
> + access_point_.frequency->get()
> + };
> + signal_strength_ = com::ubuntu::location::connectivity::WirelessNetwork::SignalStrength
> + {
> + int(access_point_.strength->get())
> + };
> +
> + // Wire up all the connections
> + access_point_.properties_changed->connect([this](const std::map<std::string, core::dbus::types::Variant>& dict)
> + {
> + on_access_point_properties_changed(dict);
> + });
> + }
> +
> + void on_access_point_properties_changed(const std::map<std::string, core::dbus::types::Variant>& dict)
> + {
> + // We route by string
> + static const std::unordered_map<std::string, std::function<void(CachedWirelessNetwork&, const core::dbus::types::Variant&)> > lut
> + {
> + {
> + org::freedesktop::NetworkManager::AccessPoint::HwAddress::name(),
> + [](CachedWirelessNetwork& thiz, const core::dbus::types::Variant& value)
> + {
> + thiz.bssid_ = value.as<org::freedesktop::NetworkManager::AccessPoint::HwAddress::ValueType>();
> + }
> + },
> + {
> + org::freedesktop::NetworkManager::AccessPoint::Ssid::name(),
> + [](CachedWirelessNetwork& thiz, const core::dbus::types::Variant& value)
> + {
> + thiz.ssid_ = utf8_ssid_to_string(value.as<org::freedesktop::NetworkManager::AccessPoint::Ssid::ValueType>());
> + }
> + },
> + {
> + org::freedesktop::NetworkManager::AccessPoint::Strength::name(),
> + [](CachedWirelessNetwork& thiz, const core::dbus::types::Variant& value)
> + {
> + thiz.signal_strength_ = com::ubuntu::location::connectivity::WirelessNetwork::SignalStrength
> + {
> + value.as<org::freedesktop::NetworkManager::AccessPoint::Strength::ValueType>()
> + };
> + }
> + },
> + {
> + org::freedesktop::NetworkManager::AccessPoint::Frequency::name(),
> + [](CachedWirelessNetwork& thiz, const core::dbus::types::Variant& value)
> + {
> + thiz.frequency_ = com::ubuntu::location::connectivity::WirelessNetwork::Frequency
> + {
> + value.as<org::freedesktop::NetworkManager::AccessPoint::Frequency::ValueType>()
> + };
> + }
> + },
> + {
> + org::freedesktop::NetworkManager::AccessPoint::Mode::name(),
> + [](CachedWirelessNetwork& thiz, const core::dbus::types::Variant& value)
> + {
> + thiz.mode_ = wifi_mode_from_ap_mode(value.as<org::freedesktop::NetworkManager::AccessPoint::Mode::ValueType>());
> + }
> + },
> + {
> + org::freedesktop::NetworkManager::AccessPoint::LastSeen::name(),
> + [](CachedWirelessNetwork& thiz, const core::dbus::types::Variant& value)
> + {
> + thiz.last_seen_ = std::chrono::system_clock::time_point
> + {
> + std::chrono::system_clock::duration
> + {
> + value.as<org::freedesktop::NetworkManager::AccessPoint::LastSeen::ValueType>()
> + }
> + };
> + }
> + }
> + };
> +
> + for (const auto& pair : dict)
> + {
> + VLOG(1) << "Properties on access point " << ssid_.get() << " changed: \n"
> + << " " << pair.first;
> +
> + // We do not treat failing property updates as fatal but instead just
> + // log the issue for later analysis.
> + try
> + {
> + if (lut.count(pair.first) > 0) lut.at(pair.first)(*this, pair.second);
> + } catch (const std::exception& e)
> + {
> + LOG(WARNING) << "Exception while updating state for property change: " << pair.first;
> + }
> + }
> + }
> +
> + org::freedesktop::NetworkManager::Device device_;
> + org::freedesktop::NetworkManager::AccessPoint access_point_;
> +
> + core::Property<std::chrono::system_clock::time_point> last_seen_;
> + core::Property<std::string> bssid_;
> + core::Property<std::string> ssid_;
> + core::Property<WirelessNetwork::Mode> mode_;
> + core::Property<WirelessNetwork::Frequency> frequency_;
> + core::Property<WirelessNetwork::SignalStrength> signal_strength_;
> +};
> +}
> +
> +#endif // CACHED_WIRELESS_NETWORK_H_
>
> === added file 'src/location_service/com/ubuntu/location/connectivity/nm.h'
> --- src/location_service/com/ubuntu/location/connectivity/nm.h 1970-01-01 00:00:00 +0000
> +++ src/location_service/com/ubuntu/location/connectivity/nm.h 2014-06-24 16:02:38 +0000
> @@ -0,0 +1,519 @@
> +/*
> + * Copyright © 2012-2013 Canonical Ltd.
> + *
> + * This program is free software: you can redistribute it and/or modify it
> + * under the terms of the GNU Lesser General Public License version 3,
> + * 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 Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public License
> + * along with this program. If not, see <http://www.gnu.org/licenses/>.
> + *
> + * Authored by: Thomas Voß <thomas.voss at canonical.com>
> + */
> +#ifndef LOCATION_SERVICE_COM_UBUNTU_LOCATION_CONNECTIVITY_NM_H
> +#define LOCATION_SERVICE_COM_UBUNTU_LOCATION_CONNECTIVITY_NM_H
> +
> +#include <core/dbus/bus.h>
> +#include <core/dbus/object.h>
> +#include <core/dbus/property.h>
> +#include <core/dbus/service.h>
> +#include <core/dbus/types/object_path.h>
> +#include <core/dbus/types/struct.h>
> +#include <core/dbus/types/stl/map.h>
> +#include <core/dbus/types/stl/string.h>
> +#include <core/dbus/types/stl/tuple.h>
> +#include <core/dbus/types/stl/vector.h>
> +
> +namespace org
> +{
> +namespace freedesktop
> +{
> +struct NetworkManager
> +{
> + typedef std::shared_ptr<NetworkManager> Ptr;
> +
> + struct AccessPoint
> + {
> + static const std::string& name()
> + {
> + static const std::string s{"org.freedesktop.NetworkManager.AccessPoint"};
> + return s;
> + }
> +
> + struct Frequency
> + {
> + static const std::string& name()
> + {
> + static const std::string s{"Frequency"};
> + return s;
> + }
> +
> + typedef AccessPoint Interface;
> + typedef std::uint32_t ValueType;
> + static const bool readable = true;
> + static const bool writable = false;
> + };
> +
> + struct LastSeen
> + {
> + static const std::string& name()
> + {
> + static const std::string s{"LastSeen"};
> + return s;
> + }
> +
> + typedef AccessPoint Interface;
> + typedef std::int32_t ValueType;
> + static const bool readable = true;
> + static const bool writable = false;
> + };
> +
> + struct Mode
> + {
> + enum Value
> + {
> + unknown = 0,
> + adhoc = 1,
> + infra = 2,
> + ap = 3
> + };
> +
> + static const std::string& name()
> + {
> + static const std::string s{"Mode"};
> + return s;
> + }
> +
> + typedef AccessPoint Interface;
> + typedef std::uint32_t ValueType;
> + static const bool readable = true;
> + static const bool writable = false;
> + };
> +
> + struct HwAddress
> + {
> + static const std::string& name()
> + {
> + static const std::string s{"HwAddress"};
> + return s;
> + }
> +
> + typedef AccessPoint Interface;
> + typedef std::string ValueType;
> + static const bool readable = true;
> + static const bool writable = false;
> + };
> +
> + struct Ssid
> + {
> + static const std::string& name()
> + {
> + static const std::string s{"Ssid"};
> + return s;
> + }
> +
> + typedef AccessPoint Interface;
> + typedef std::vector<std::int8_t> ValueType;
> + static const bool readable = true;
> + static const bool writable = false;
> + };
> +
> + struct Strength
> + {
> + static const std::string& name()
> + {
> + static const std::string s{"Strength"};
> + return s;
> + }
> +
> + typedef AccessPoint Interface;
> + typedef std::int8_t ValueType;
> + static const bool readable = true;
> + static const bool writable = false;
> + };
> +
> + struct PropertiesChanged
> + {
> + inline static std::string name()
> + {
> + return "PropertiesChanged";
> + }
> +
> + typedef AccessPoint Interface;
> +
> + typedef std::map<std::string, core::dbus::types::Variant> ArgumentType;
> + };
> +
> + AccessPoint(const std::shared_ptr<core::dbus::Object>& object)
> + : object(object),
> + frequency(object->get_property<Frequency>()),
> + last_seen(object->get_property<LastSeen>()),
> + mode(object->get_property<Mode>()),
> + hw_address(object->get_property<HwAddress>()),
> + ssid(object->get_property<Ssid>()),
> + strength(object->get_property<Strength>()),
> + properties_changed(object->get_signal<PropertiesChanged>())
> + {
> + }
> +
> + std::shared_ptr<core::dbus::Object> object;
> + std::shared_ptr<core::dbus::Property<Frequency>> frequency;
> + std::shared_ptr<core::dbus::Property<LastSeen>> last_seen;
> + std::shared_ptr<core::dbus::Property<Mode>> mode;
> + std::shared_ptr<core::dbus::Property<HwAddress>> hw_address;
> + std::shared_ptr<core::dbus::Property<Ssid>> ssid;
> + std::shared_ptr<core::dbus::Property<Strength>> strength;
> + std::shared_ptr<core::dbus::Signal<PropertiesChanged, PropertiesChanged::ArgumentType>> properties_changed;
> + };
> +
> + struct Device
> + {
> + static const std::string& name()
> + {
> + static const std::string s{"org.freedesktop.NetworkManager.Device"};
> + return s;
> + }
> +
> + enum class Type
> + {
> + unknown = 0,
> + ethernet = 1,
> + wifi = 2,
> + unused_1 = 3,
> + unused_2 = 4,
> + bluetooth = 5,
> + olpc_mesh = 6,
> + wimax = 7,
> + modem = 8,
> + infiniband = 9,
> + bond = 10,
> + vlan = 11,
> + adsl = 12,
> + bridge = 13
> + };
> +
> + struct Wireless
> + {
> + static const std::string& name()
> + {
> + static const std::string s{"org.freedesktop.NetworkManager.Device.Wireless"};
> + return s;
> + }
> +
> + struct GetAccessPoints
> + {
> + static const std::string& name()
> + {
> + static const std::string s{"GetAccessPoints"};
> + return s;
> + }
> +
> + typedef Wireless Interface;
> +
> + static std::chrono::milliseconds default_timeout()
> + {
> + return std::chrono::seconds{1};
> + }
> + };
> +
> + struct RequestScan
> + {
> + static const std::string& name()
> + {
> + static const std::string s{"RequestScan"};
> + return s;
> + }
> +
> + typedef Wireless Interface;
> +
> + static std::chrono::milliseconds default_timeout()
> + {
> + return std::chrono::seconds{1};
> + }
> + };
> +
> + struct Signals
> + {
> + struct ScanDone
> + {
> + inline static std::string name()
> + {
> + return "ScanDone";
> + }
> +
> + typedef Wireless Interface;
> + typedef void ArgumentType;
> + };
> +
> + struct AccessPointAdded
> + {
> + inline static std::string name()
> + {
> + return "AccessPointAdded";
> + }
> +
> + typedef Wireless Interface;
> +
> + typedef core::dbus::types::ObjectPath ArgumentType;
> + };
> +
> + struct AccessPointRemoved
> + {
> + inline static std::string name()
> + {
> + return "AccessPointRemoved";
> + }
> +
> + typedef Wireless Interface;
> +
> + typedef core::dbus::types::ObjectPath ArgumentType;
> + };
> + };
> + };
> +
> + struct DeviceType
> + {
> + static const std::string& name()
> + {
> + static const std::string s{"DeviceType"};
> + return s;
> + }
> +
> + typedef Device Interface;
> + typedef std::uint32_t ValueType;
> + static const bool readable = true;
> + static const bool writable = false;
> + };
> +
> + Device(const std::shared_ptr<core::dbus::Service>& service,
> + const std::shared_ptr<core::dbus::Object>& object)
> + : service(service),
> + object(object),
> + device_type(object->get_property<DeviceType>()),
> + signals
> + {
> + object->get_signal<Wireless::Signals::ScanDone>(),
> + object->get_signal<Wireless::Signals::AccessPointAdded>(),
> + object->get_signal<Wireless::Signals::AccessPointRemoved>()
> + }
> + {
> + }
> +
> + Type type() const
> + {
> + return static_cast<Type>(device_type->get());
> + }
> +
> + void for_each_access_point(const std::function<void(const core::dbus::types::ObjectPath&)>& f) const
> + {
> + typedef std::vector<core::dbus::types::ObjectPath> ResultType;
> + auto result = object->transact_method<Wireless::GetAccessPoints, ResultType>();
> +
> + if (result.is_error())
> + throw std::runtime_error(result.error().print());
> +
> + for (const auto& path : result.value())
> + f(path);
> + }
> +
> + std::vector<AccessPoint> get_access_points() const
> + {
> + typedef std::vector<core::dbus::types::ObjectPath> ResultType;
> + auto result = object->invoke_method_synchronously<Wireless::GetAccessPoints, ResultType>();
> +
> + if (result.is_error())
> + throw std::runtime_error(result.error().print());
> +
> + std::vector<AccessPoint> aps;
> +
> + for (const auto& path : result.value())
> + aps.push_back(AccessPoint(service->object_for_path(path)));
> +
> + return aps;
> + }
> +
> + void request_scan() const
> + {
> + static const std::map<std::string, core::dbus::types::Variant> dictionary;
> + auto result = object->invoke_method_asynchronously<Wireless::RequestScan, void>(dictionary);
> + }
> +
> + std::shared_ptr<core::dbus::Service> service;
> + std::shared_ptr<core::dbus::Object> object;
> + std::shared_ptr<core::dbus::Property<DeviceType>> device_type;
> + struct
> + {
> + core::dbus::Signal<Wireless::Signals::ScanDone, Wireless::Signals::ScanDone::ArgumentType>::Ptr scan_done;
> + core::dbus::Signal<Wireless::Signals::AccessPointAdded, Wireless::Signals::AccessPointAdded::ArgumentType>::Ptr ap_added;
> + core::dbus::Signal<Wireless::Signals::AccessPointRemoved, Wireless::Signals::AccessPointRemoved::ArgumentType>::Ptr ap_removed;
> + } signals;
> + };
> +
> + static const std::string& name()
> + {
> + static const std::string s{"org.freedesktop.NetworkManager"};
> + return s;
> + }
> +
> + struct GetDevices
> + {
> + static const std::string& name()
> + {
> + static const std::string s{"GetDevices"};
> + return s;
> + }
> +
> + typedef NetworkManager Interface;
> +
> + static std::chrono::milliseconds default_timeout()
> + {
> + return std::chrono::seconds{1};
> + }
> + };
> +
> + struct Properties
> + {
> + struct Connectivity
> + {
> + enum Values
> + {
> + unknown = 0,
> + none = 1,
> + portal = 2,
> + limited = 3,
> + full = 4
> + };
> +
> + static const std::string& name()
> + {
> + static const std::string s{"Connectivity"};
> + return s;
> + }
> +
> + typedef NetworkManager Interface;
> + typedef std::uint32_t ValueType;
> + static const bool readable = true;
> + static const bool writable = false;
> + };
> + };
> +
> + struct Signals
> + {
> + struct DeviceAdded
> + {
> + inline static std::string name()
> + {
> + return "DeviceAdded";
> + }
> +
> + typedef NetworkManager Interface;
> +
> + typedef core::dbus::types::ObjectPath ArgumentType;
> + };
> +
> + struct DeviceRemoved
> + {
> + inline static std::string name()
> + {
> + return "DeviceRemoved";
> + }
> +
> + typedef NetworkManager Interface;
> +
> + typedef core::dbus::types::ObjectPath ArgumentType;
> + };
> +
> + struct PropertiesChanged
> + {
> + inline static std::string name()
> + {
> + return "PropertiesChanged";
> + }
> +
> + typedef NetworkManager Interface;
> +
> + typedef std::map<std::string, core::dbus::types::Variant> ArgumentType;
> + };
> + };
> +
> + NetworkManager(const core::dbus::Bus::Ptr& bus)
> + : service(core::dbus::Service::use_service<NetworkManager>(bus)),
> + object(service->object_for_path(core::dbus::types::ObjectPath("/org/freedesktop/NetworkManager"))),
> + properties
> + {
> + object->get_property<Properties::Connectivity>()
> + },
> + signals
> + {
> + object->get_signal<Signals::DeviceAdded>(),
> + object->get_signal<Signals::DeviceRemoved>(),
> + object->get_signal<Signals::PropertiesChanged>()
> + }
> + {
> + }
> +
> + void for_each_device(const std::function<void(const core::dbus::types::ObjectPath&)>& f)
> + {
> + auto result =
> + object->transact_method<
> + NetworkManager::GetDevices,
> + std::vector<core::dbus::types::ObjectPath>
> + >();
> +
> + if (result.is_error())
> + throw std::runtime_error(result.error().print());
> +
> + for (const auto& path : result.value())
> + f(path);
> + }
> +
> + Device device_for_path(const core::dbus::types::ObjectPath& path)
> + {
> + return Device(service, service->object_for_path(path));
> + }
> +
> + std::vector<Device> get_devices()
> + {
> + auto result =
> + object->invoke_method_synchronously<
> + NetworkManager::GetDevices,
> + std::vector<core::dbus::types::ObjectPath>>();
> +
> + if (result.is_error())
> + throw std::runtime_error(result.error().print());
> +
> + std::vector<Device> devices;
> + for (const auto& path : result.value())
> + {
> + devices.emplace_back(
> + Device(
> + service,
> + service->object_for_path(path)));
> + }
> +
> + return devices;
> + }
> +
> + std::shared_ptr<core::dbus::Service> service;
> + std::shared_ptr<core::dbus::Object> object;
> +
> + struct
> + {
> + std::shared_ptr<core::dbus::Property<Properties::Connectivity> > connectivity;
> + } properties;
> + struct
> + {
> + core::dbus::Signal<Signals::DeviceAdded, Signals::DeviceAdded::ArgumentType>::Ptr device_added;
> + core::dbus::Signal<Signals::DeviceRemoved, Signals::DeviceRemoved::ArgumentType>::Ptr device_removed;
> + core::dbus::Signal<Signals::PropertiesChanged, Signals::PropertiesChanged::ArgumentType>::Ptr properties_changed;
> + } signals;
> +};
> +}
> +}
> +
> +#endif // LOCATION_SERVICE_COM_UBUNTU_LOCATION_CONNECTIVITY_NM_H
>
> === added file 'src/location_service/com/ubuntu/location/connectivity/ofono.h'
> --- src/location_service/com/ubuntu/location/connectivity/ofono.h 1970-01-01 00:00:00 +0000
> +++ src/location_service/com/ubuntu/location/connectivity/ofono.h 2014-06-24 16:02:38 +0000
> @@ -0,0 +1,699 @@
> +/*
> + * Copyright © 2012-2013 Canonical Ltd.
> + *
> + * This program is free software: you can redistribute it and/or modify it
> + * under the terms of the GNU Lesser General Public License version 3,
> + * 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 Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public License
> + * along with this program. If not, see <http://www.gnu.org/licenses/>.
> + *
> + * Authored by: Thomas Voß <thomas.voss at canonical.com>
> + */
> +#ifndef LOCATION_SERVICE_COM_UBUNTU_LOCATION_CONNECTIVITY_OFONO_H
> +#define LOCATION_SERVICE_COM_UBUNTU_LOCATION_CONNECTIVITY_OFONO_H
> +
> +#include <core/dbus/bus.h>
> +#include <core/dbus/object.h>
> +#include <core/dbus/property.h>
> +#include <core/dbus/service.h>
> +#include <core/dbus/types/object_path.h>
> +#include <core/dbus/types/struct.h>
> +#include <core/dbus/types/variant.h>
> +#include <core/dbus/types/stl/map.h>
> +#include <core/dbus/types/stl/string.h>
> +#include <core/dbus/types/stl/tuple.h>
> +#include <core/dbus/types/stl/vector.h>
> +
> +namespace org
> +{
> +struct Ofono
> +{
> +static const std::string& name()
> +{
> + static const std::string s{"org.ofono"};
> + return s;
> +}
> +struct Manager
> +{
> + typedef std::shared_ptr<Manager> Ptr;
> +
> + static const std::string& name()
> + {
> + static const std::string s{"org.ofono.Manager"};
> + return s;
> + }
> +
> + struct GetModems
> + {
> + static const std::string& name()
> + {
> + static const std::string s{"GetModems"};
> + return s;
> + }
> +
> + typedef Manager Interface;
> + typedef std::vector<
> + core::dbus::types::Struct<
> + core::dbus::types::ObjectPath
> + >
> + > ResultType;
> +
> + static std::chrono::milliseconds default_timeout()
> + {
> + return std::chrono::seconds{1};
> + }
> + };
> +
> + struct ModemAdded
> + {
> + static const std::string& name()
> + {
> + static const std::string s{"ModemAdded"};
> + return s;
> + }
> +
> + typedef Manager Interface;
> + typedef std::tuple<core::dbus::types::ObjectPath, std::map<std::string, std::string>> ArgumentType;
> + };
> +
> + struct ModemRemoved
> + {
> + static const std::string& name()
> + {
> + static const std::string s{"ModemRemoved"};
> + return s;
> + }
> +
> + typedef Manager Interface;
> + typedef core::dbus::types::ObjectPath ArgumentType;
> + };
> +
> + struct Modem
> + {
> + static const std::string& name()
> + {
> + static const std::string s{"org.ofono.Modem"};
> + return s;
> + }
> +
> + struct GetProperties
> + {
> + static const std::string& name()
> + {
> + static const std::string s{"GetProperties"};
> + return s;
> + }
> +
> + typedef Modem Interface;
> + typedef std::map<std::string, core::dbus::types::Variant> ValueType;
> +
> + static std::chrono::milliseconds default_timeout()
> + {
> + return std::chrono::seconds{1};
> + }
> + };
> +
> + struct PropertyChanged
> + {
> + inline static std::string name()
> + {
> + return "PropertyChanged";
> + }
> +
> + typedef Modem Interface;
> +
> + typedef std::tuple<std::string, core::dbus::types::Variant> ArgumentType;
> + };
> +
> + struct Properties
> + {
> + struct Powered
> + {
> + static const std::string& name()
> + {
> + static const std::string s{"Powered"};
> + return s;
> + }
> +
> + typedef Modem Interface;
> + typedef bool ValueType;
> + static const bool readable = true;
> + static const bool writable = true;
> + };
> +
> + struct Online
> + {
> + static const std::string& name()
> + {
> + static const std::string s{"Online"};
> + return s;
> + }
> +
> + typedef Modem Interface;
> + typedef bool ValueType;
> + static const bool readable = true;
> + static const bool writable = true;
> + };
> +
> + struct Lockdown
> + {
> + static const std::string& name()
> + {
> + static const std::string s{"Lockdown"};
> + return s;
> + }
> +
> + typedef Modem Interface;
> + typedef bool ValueType;
> + static const bool readable = true;
> + static const bool writable = true;
> + };
> +
> + struct Name
> + {
> + static const std::string& name()
> + {
> + static const std::string s{"Name"};
> + return s;
> + }
> +
> + typedef Modem Interface;
> + typedef std::string ValueType;
> + static const bool readable = true;
> + static const bool writable = false;
> + };
> +
> + struct Manufacturer
> + {
> + static const std::string& name()
> + {
> + static const std::string s{"Manufacturer"};
> + return s;
> + }
> +
> + typedef Modem Interface;
> + typedef std::string ValueType;
> + static const bool readable = true;
> + static const bool writable = false;
> + };
> +
> + struct Model
> + {
> + static const std::string& name()
> + {
> + static const std::string s{"Model"};
> + return s;
> + }
> +
> + typedef Modem Interface;
> + typedef std::string ValueType;
> + static const bool readable = true;
> + static const bool writable = false;
> + };
> +
> + struct Revision
> + {
> + static const std::string& name()
> + {
> + static const std::string s{"Revision"};
> + return s;
> + }
> +
> + typedef Modem Interface;
> + typedef std::string ValueType;
> + static const bool readable = true;
> + static const bool writable = false;
> + };
> +
> + struct Serial
> + {
> + static const std::string& name()
> + {
> + static const std::string s{"Serial"};
> + return s;
> + }
> +
> + typedef Modem Interface;
> + typedef std::string ValueType;
> + static const bool readable = true;
> + static const bool writable = false;
> + };
> +
> + struct Features
> + {
> + static constexpr const char* net{"net"};
> + static constexpr const char* rat{"rat"};
> + static constexpr const char* cbs{"cbs"};
> + static constexpr const char* sms{"sms"};
> + static constexpr const char* sim{"sim"};
> + static constexpr const char* stk{"stk"};
> + static constexpr const char* ussd{"ussd"};
> + static constexpr const char* gprs{"gprs"};
> + static constexpr const char* tty{"tty"};
> + static constexpr const char* gps{"gps"};
> +
> + static const std::string& name()
> + {
> + static const std::string s{"Features"};
> + return s;
> + }
> +
> + typedef Modem Interface;
> + typedef std::vector<std::string> ValueType;
> + static const bool readable = true;
> + static const bool writable = false;
> + };
> +
> + struct Interfaces
> + {
> + static constexpr const char* assisted_satellite_navigation
> + {
> + "org.ofono.AssistedSatelliteNavigation"
> + };
> + static constexpr const char* audio_settings
> + {
> + "org.ofono.AudioSettings"
> + };
> + static constexpr const char* call_barring
> + {
> + "org.ofono.CallBarring"
> + };
> + static constexpr const char* call_forwarding
> + {
> + "org.ofono.CallForwarding"
> + };
> + static constexpr const char* call_meter
> + {
> + "org.ofono.CallMeter"
> + };
> + static constexpr const char* call_settings
> + {
> + "org.ofono.CallSettings"
> + };
> + static constexpr const char* call_volume
> + {
> + "org.ofono.CallVolume"
> + };
> + static constexpr const char* cell_broadcast
> + {
> + "org.ofono.CellBroadcast"
> + };
> + static constexpr const char* hands_free
> + {
> + "org.ofono.Handsfree"
> + };
> + static constexpr const char* location_reporting
> + {
> + "org.ofono.LocationReporting"
> + };
> + static constexpr const char* message_manager
> + {
> + "org.ofono.MessageManager"
> + };
> + static constexpr const char* message_waiting
> + {
> + "org.ofono.MessageWaiting"
> + };
> + static constexpr const char* network_registration
> + {
> + "org.ofono.NetworkRegistration"
> + };
> + static constexpr const char* phonebook
> + {
> + "org.ofono.Phonebook"
> + };
> + static constexpr const char* push_notification
> + {
> + "org.ofono.PushNotification"
> + };
> + static constexpr const char* radio_settings
> + {
> + "org.ofono.RadioSettings"
> + };
> + static constexpr const char* sim_manager
> + {
> + "org.ofono.SimManager"
> + };
> + static constexpr const char* smart_messaging
> + {
> + "org.ofono.SmartMessaging"
> + };
> + static constexpr const char* sim_toolkit
> + {
> + "org.ofono.SimToolkit"
> + };
> + static constexpr const char* supplementary_services
> + {
> + "org.ofono.SupplementaryServices"
> + };
> + static constexpr const char* text_telephony
> + {
> + "org.ofono.TextTelephony"
> + };
> + static constexpr const char* voice_call_manager
> + {
> + "org.ofono.VoiceCallManager"
> + };
> +
> + static const std::string& name()
> + {
> + static const std::string s{"Interfaces"};
> + return s;
> + }
> +
> + typedef Modem Interface;
> + typedef std::vector<std::string> ValueType;
> + static const bool readable = true;
> + static const bool writable = false;
> + };
> +
> + struct Type
> + {
> + static constexpr const char* test{"test"};
> + static constexpr const char* hfp{"hfp"};
> + static constexpr const char* sap{"sap"};
> + static constexpr const char* hardware{"hardware"};
> +
> + static const std::string& name()
> + {
> + static const std::string s{"Type"};
> + return s;
> + }
> +
> + typedef Modem Interface;
> + typedef std::string ValueType;
> + static const bool readable = true;
> + static const bool writable = false;
> + };
> + };
> +
> + struct NetworkRegistration
> + {
> + static const std::string& name()
> + {
> + static const std::string s{"org.ofono.NetworkRegistration"};
> + return s;
> + }
> +
> + struct GetProperties
> + {
> + static const std::string& name()
> + {
> + static const std::string s{"GetProperties"};
> + return s;
> + }
> +
> + typedef NetworkRegistration Interface;
> + typedef std::map<std::string, core::dbus::types::Variant> ValueType;
> +
> + static std::chrono::milliseconds default_timeout()
> + {
> + return std::chrono::seconds{1};
> + }
> + };
> +
> + struct PropertyChanged
> + {
> + inline static std::string name()
> + {
> + return "PropertyChanged";
> + }
> +
> + typedef NetworkRegistration Interface;
> +
> + typedef std::tuple<std::string, core::dbus::types::Variant> ArgumentType;
> + };
> +
> + struct Status
> + {
> + enum class Value
> + {
> + unregistered,
> + registered,
> + searching,
> + denied,
> + unknown,
> + roaming
> + };
> +
> + static constexpr const char* unregistered
> + {
> + "unregistered"
> + };
> + static constexpr const char* registered
> + {
> + "registered"
> + };
> + static constexpr const char* searching
> + {
> + "searching"
> + };
> + static constexpr const char* denied
> + {
> + "denied"
> + };
> + static constexpr const char* unknown
> + {
> + "unknown"
> + };
> + static constexpr const char* roaming
> + {
> + "roaming"
> + };
> +
> + static const char* value_to_string(Value value)
> + {
> + switch (value)
> + {
> + case Value::unregistered: return unregistered;
> + case Value::registered: return registered;
> + case Value::searching: return searching;
> + case Value::denied: return denied;
> + case Value::unknown: return unknown;
> + case Value::roaming: return roaming;
> + }
> +
> + return nullptr;
> + }
> +
> + static const std::string& name()
> + {
> + static const std::string s{"Status"};
> + return s;
> + }
> +
> + typedef NetworkRegistration Interface;
> + typedef std::string ValueType;
> + static const bool readable = true;
> + static const bool writable = false;
> + };
> +
> + struct LocationAreaCode
> + {
> + static const std::string& name()
> + {
> + static const std::string s{"LocationAreaCode"};
> + return s;
> + }
> +
> + typedef NetworkRegistration Interface;
> + typedef std::uint16_t ValueType;
> + static const bool readable = true;
> + static const bool writable = false;
> + };
> +
> + struct CellId
> + {
> + static const std::string& name()
> + {
> + static const std::string s{"CellId"};
> + return s;
> + }
> +
> + typedef NetworkRegistration Interface;
> + typedef std::uint32_t ValueType;
> + static const bool readable = true;
> + static const bool writable = false;
> + };
> +
> + struct MobileCountryCode
> + {
> + static const std::string& name()
> + {
> + static const std::string s{"MobileCountryCode"};
> + return s;
> + }
> +
> + typedef NetworkRegistration Interface;
> + typedef std::string ValueType;
> + static const bool readable = true;
> + static const bool writable = false;
> + };
> +
> + struct MobileNetworkCode
> + {
> + static const std::string& name()
> + {
> + static const std::string s{"MobileNetworkCode"};
> + return s;
> + }
> +
> + typedef NetworkRegistration Interface;
> + typedef std::string ValueType;
> + static const bool readable = true;
> + static const bool writable = false;
> + };
> +
> + struct Technology
> + {
> + static const char* gsm() { return "gsm"; }
> + static const char* edge() { return "edge"; }
> + static const char* umts() { return "umts"; }
> + static const char* hspa() { return "hspa"; }
> + static const char* lte() { return "lte"; }
> +
> + static const std::string& name()
> + {
> + static const std::string s{"Technology"};
> + return s;
> + }
> +
> + typedef NetworkRegistration Interface;
> + typedef std::string ValueType;
> + static const bool readable = true;
> + static const bool writable = false;
> + };
> +
> + struct Strength
> + {
> + static const std::string& name()
> + {
> + static const std::string s{"Strength"};
> + return s;
> + }
> +
> + typedef NetworkRegistration Interface;
> + typedef std::int8_t ValueType;
> + static const bool readable = true;
> + static const bool writable = false;
> + };
> +
> + NetworkRegistration(const std::shared_ptr<core::dbus::Object>& object)
> + : object(object),
> + signals
> + {
> + object->get_signal<PropertyChanged>()
> + }
> + {
> + refresh_properties();
> + }
> +
> + void refresh_properties() const
> + {
> + auto result = object->invoke_method_synchronously<GetProperties, GetProperties::ValueType>();
> + if (result.is_error())
> + throw std::runtime_error(result.error().print());
> +
> + properties = result.value();
> + }
> +
> + template<typename Property>
> + typename Property::ValueType get() const
> + {
> + refresh_properties();
> +
> + auto it = properties.find(Property::name());
> +
> + if (it == properties.end())
> + {
> + LOG(WARNING) << "Could not find property for name " << Property::name();
> + return typename Property::ValueType{};
> + }
> +
> + return it->second.template as<typename Property::ValueType>();
> + }
> +
> + std::shared_ptr<core::dbus::Object> object;
> + mutable GetProperties::ValueType properties;
> +
> + struct
> + {
> + core::dbus::Signal<PropertyChanged, PropertyChanged::ArgumentType>::Ptr property_changed;
> + } signals;
> + };
> +
> + Modem(const std::shared_ptr<core::dbus::Service>& service,
> + const std::shared_ptr<core::dbus::Object>& object)
> + : service(service),
> + object(object),
> + signals
> + {
> + object->get_signal<PropertyChanged>()
> + },
> + network_registration{object}
> + {
> + }
> +
> + std::shared_ptr<core::dbus::Service> service;
> + std::shared_ptr<core::dbus::Object> object;
> +
> + struct
> + {
> + core::dbus::Signal<PropertyChanged, PropertyChanged::ArgumentType>::Ptr property_changed;
> + } signals;
> +
> + NetworkRegistration network_registration;
> + };
> +
> + Manager(const core::dbus::Bus::Ptr& bus)
> + : service(core::dbus::Service::use_service<org::Ofono>(bus)),
> + object(service->object_for_path(core::dbus::types::ObjectPath("/"))),
> + signals
> + {
> + object->get_signal<ModemAdded>(),
> + object->get_signal<ModemRemoved>()
> + }
> + {
> + }
> +
> + Modem modem_for_path(const core::dbus::types::ObjectPath& path) const
> + {
> + return Modem
> + {
> + service,
> + service->object_for_path(path)
> + };
> + }
> +
> + void for_each_modem(const std::function<void(const core::dbus::types::ObjectPath&)>& functor) const
> + {
> + auto result = object->invoke_method_synchronously<GetModems, GetModems::ResultType>();
> +
> + if (result.is_error())
> + throw std::runtime_error(result.error().print());
> +
> + for (const auto& element : result.value())
> + {
> + functor(element.value);
> + }
> + }
> +
> + std::shared_ptr<core::dbus::Service> service;
> + std::shared_ptr<core::dbus::Object> object;
> +
> + struct
> + {
> + std::shared_ptr<core::dbus::Signal<ModemAdded, ModemAdded::ArgumentType>> modem_added;
> + std::shared_ptr<core::dbus::Signal<ModemRemoved, ModemRemoved::ArgumentType>> modem_removed;
> + } signals;
> +};
> +};
> +}
> +
> +#endif // LOCATION_SERVICE_COM_UBUNTU_LOCATION_CONNECTIVITY_OFONO_H
>
> === added file 'src/location_service/com/ubuntu/location/connectivity/ofono_nm_connectivity_manager.cpp'
> --- src/location_service/com/ubuntu/location/connectivity/ofono_nm_connectivity_manager.cpp 1970-01-01 00:00:00 +0000
> +++ src/location_service/com/ubuntu/location/connectivity/ofono_nm_connectivity_manager.cpp 2014-06-24 16:02:38 +0000
> @@ -0,0 +1,404 @@
> +/*
> + * Copyright © 2012-2013 Canonical Ltd.
> + *
> + * This program is free software: you can redistribute it and/or modify it
> + * under the terms of the GNU Lesser General Public License version 3,
> + * 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 Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public License
> + * along with this program. If not, see <http://www.gnu.org/licenses/>.
> + *
> + * Authored by: Thomas Voß <thomas.voss at canonical.com>
> + */
> +
> +#include "ofono_nm_connectivity_manager.h"
> +
> +namespace connectivity = com::ubuntu::location::connectivity;
> +namespace dbus = core::dbus;
> +namespace xdg = org::freedesktop;
> +namespace
> +{
> +connectivity::State from_nm_property(std::uint32_t value)
> +{
> + connectivity::State result{connectivity::State::unknown};
> +
> + switch (value)
> + {
> + case xdg::NetworkManager::Properties::Connectivity::Values::unknown:
> + result = connectivity::State::unknown;
> + break;
> + case xdg::NetworkManager::Properties::Connectivity::Values::none:
> + result = connectivity::State::none;
> + break;
> + case xdg::NetworkManager::Properties::Connectivity::Values::portal:
> + result = connectivity::State::portal;
> + break;
> + case xdg::NetworkManager::Properties::Connectivity::Values::limited:
> + result = connectivity::State::limited;
> + break;
> + case xdg::NetworkManager::Properties::Connectivity::Values::full:
> + result = connectivity::State::full;
> + break;
> + }
> +
> + return result;
> +}
> +}
> +
> +const core::Property<connectivity::State>& impl::OfonoNmConnectivityManager::state() const
> +{
> + return d.state;
> +}
> +
> +void impl::OfonoNmConnectivityManager::request_scan_for_wireless_networks()
> +{
> + std::lock_guard<std::mutex> lg(d.cached.guard);
> +
> + for (const auto& pair : d.cached.wireless_devices)
> + pair.second.request_scan();
> +}
> +
> +const core::Signal<>& impl::OfonoNmConnectivityManager::wireless_network_scan_finished() const
> +{
> + return d.signals.wireless_network_scan_finished;
> +}
> +
> +const core::Signal<connectivity::WirelessNetwork::Ptr>& impl::OfonoNmConnectivityManager::wireless_network_added() const
> +{
> + return d.signals.wireless_network_added;
> +}
> +
> +const core::Signal<connectivity::WirelessNetwork::Ptr>& impl::OfonoNmConnectivityManager::wireless_network_removed() const
> +{
> + return d.signals.wireless_network_removed;
> +}
> +
> +void impl::OfonoNmConnectivityManager::enumerate_visible_wireless_networks(const std::function<void(const connectivity::WirelessNetwork::Ptr&)>& f) const
> +{
> + std::lock_guard<std::mutex> lg(d.cached.guard);
> + for (const auto& wifi : d.cached.wifis)
> + f(wifi.second);
> +}
> +
> +const core::Signal<connectivity::RadioCell::Ptr>& impl::OfonoNmConnectivityManager::connected_cell_added() const
> +{
> + return d.signals.connected_cell_added;
> +}
> +
> +const core::Signal<connectivity::RadioCell::Ptr>& impl::OfonoNmConnectivityManager::connected_cell_removed() const
> +{
> + return d.signals.connected_cell_removed;
> +}
> +
> +void impl::OfonoNmConnectivityManager::enumerate_connected_radio_cells(const std::function<void(const connectivity::RadioCell::Ptr&)>& f) const
> +{
> + std::lock_guard<std::mutex> lg(d.cached.guard);
> + for (const auto& cell : d.cached.cells)
> + f(cell.second);
> +}
> +
> +impl::OfonoNmConnectivityManager::Private::Private()
> +{
> + try
> + {
> + system_bus = std::make_shared<core::dbus::Bus>(core::dbus::WellKnownBus::system);
> + executor = dbus::asio::make_executor(system_bus);
> + system_bus->install_executor(executor);
> +
> + worker = std::move(std::thread
> + {
> + [this]()
> + {
> + system_bus->run();
> + }
> + });
> +
> + setup_network_stack_access();
> + setup_radio_stack_access();
> + }
> + catch (const std::exception& e)
> + {
> + LOG(ERROR) << "Error while setting up access to radio and network stack: " << e.what();
> + }
> +}
> +
> +impl::OfonoNmConnectivityManager::Private::~Private()
> +{
> + if (system_bus)
> + system_bus->stop();
> +
> + if (worker.joinable())
> + worker.join();
> +}
> +
> +void impl::OfonoNmConnectivityManager::Private::setup_radio_stack_access()
> +{
> + modem_manager.reset(new org::Ofono::Manager(system_bus));
> +
> + modem_manager->for_each_modem([this](const core::dbus::types::ObjectPath& path)
> + {
> + try
> + {
> + on_modem_added(path);
> + }
> + catch(const std::runtime_error& e)
> + {
> + LOG(WARNING) << "Exception while creating connected radio cell: " << e.what();
> + }
> + });
> +
> + modem_manager->signals.modem_added->connect([this](const org::Ofono::Manager::ModemAdded::ArgumentType& arg)
> + {
> + try
> + {
> + on_modem_added(std::get<0>(arg));
> + }
> + catch(const std::exception& e)
> + {
> + LOG(WARNING) << "Exception while adding modem: " << e.what();
> + }
> + });
> +
> + modem_manager->signals.modem_removed->connect([this](const core::dbus::types::ObjectPath& path)
> + {
> + try
> + {
> + on_modem_removed(path);
> + }
> + catch(const std::exception& e)
> + {
> + LOG(WARNING) << "Exception while removing modem: " << e.what();
> + }
> + });
> +}
> +
> +void impl::OfonoNmConnectivityManager::Private::on_modem_added(const core::dbus::types::ObjectPath& path)
> +{
> + auto modem = modem_manager->modem_for_path(path);
> +
> + // We first wire up to property changes here.
> + modem.signals.property_changed->connect([this, path](const std::tuple<std::string, core::dbus::types::Variant>& tuple)
> + {
> + const auto& key = std::get<0>(tuple); VLOG(10) << "Property changed for modem: " << key;
> +
> + if (org::Ofono::Manager::Modem::Properties::Interfaces::name() == key)
> + {
> + auto interfaces = std::get<1>(tuple).as<std::vector<std::string> >();
> + if (VLOG_IS_ON(10)) for(const auto& interface : interfaces) VLOG(10) << interface;
> + on_modem_interfaces_changed(path, interfaces);
> + }
> +
> + });
> +
> + // And update our cache of modems and registered cells.
> + auto cell = std::make_shared<CachedRadioCell>(modem);
> + {
> + std::lock_guard<std::mutex> lg(cached.guard);
> + cached.modems.insert(std::make_pair(modem.object->path(), modem));
> + cached.cells.insert(std::make_pair(modem.object->path(), cell));
> + }
> + // Announce the newly added cell to API customers, without the lock
> + // on the cache being held.
> + signals.connected_cell_added(cell);
> +}
> +
> +void impl::OfonoNmConnectivityManager::Private::on_modem_removed(const core::dbus::types::ObjectPath& path)
> +{
> + CachedRadioCell::Ptr cell;
> + {
> + std::lock_guard<std::mutex> lg(cached.guard);
> +
> + // Update modem and cell cache.
> + auto itc = cached.cells.find(path);
> + auto itm = cached.modems.find(path);
> +
> + if (itc != cached.cells.end())
> + {
> + cell = itc->second;
> + cached.cells.erase(itc);
> + }
> +
> + if (itm != cached.modems.end())
> + {
> + cached.modems.erase(path);
> + }
> + }
> + // Inform customers of the registered cell being removed, without
> + // the lock on the cache being held.
> + if (cell) signals.connected_cell_removed(cell);
> +}
> +
> +void impl::OfonoNmConnectivityManager::Private::on_modem_interfaces_changed(
> + const core::dbus::types::ObjectPath& path,
> + const std::vector<std::string>& interfaces)
> +{
> + std::unique_lock<std::mutex> ul(cached.guard);
> +
> + auto itm = cached.modems.find(path);
> + if (itm == cached.modems.end())
> + {
> + LOG(WARNING) << "Could not find a modem for path " << path.as_string();
> + return;
> + }
> +
> + auto itt = cached.cells.find(path);
> + const bool has_cell_for_modem = itt != cached.cells.end();
> +
> + auto it = std::find(
> + interfaces.begin(),
> + interfaces.end(),
> + std::string{org::Ofono::Manager::Modem::Properties::Interfaces::network_registration});
> + const bool modem_has_network_registration = it != interfaces.end();
> +
> + if (has_cell_for_modem and not modem_has_network_registration)
> + {
> + // A network registration was lost and we remove the corresponding
> + // cell instance from the cache.
> + auto cell = itt->second;
> + cached.cells.erase(itt);
> +
> + // Cache is up to date now and we announce the removal of the cell
> + // to API customers, with the lock on the cache not being held.
> + ul.unlock(); signals.connected_cell_removed(cell);
> + } else if (not has_cell_for_modem and modem_has_network_registration)
> + {
> + // A new network registration is coming in and we have to create
> + // a corresponding cell instance.
> + auto cell = std::make_shared<CachedRadioCell>(itm->second);
> + cached.cells.insert(std::make_pair(path,cell));
> + // Cache is up to date now and we announce the new cell to
> + // API customers, with the lock on the cache not being held.
> + ul.unlock(); signals.connected_cell_added(cell);
> + }
> +}
> +
> +void impl::OfonoNmConnectivityManager::Private::setup_network_stack_access()
> +{
> + network_manager.reset(new xdg::NetworkManager(system_bus));
> +
> + network_manager->for_each_device([this](const core::dbus::types::ObjectPath& device_path)
> + {
> + auto device = network_manager->device_for_path(device_path);
> +
> + if (device.type() == xdg::NetworkManager::Device::Type::wifi)
> + {
> + // Make the device known to the cache.
> + cached.wireless_devices.insert(std::make_pair(device_path, device));
> +
> + // Iterate over all currently known wifis
> + device.for_each_access_point([this, device_path](const core::dbus::types::ObjectPath& path)
> + {
> + try
> + {
> + on_access_point_added(path, device_path);
> + }
> + catch (const std::exception& e)
> + {
> + LOG(ERROR) << "Error while creating ap/wifi: " << e.what();
> + }
> + });
> +
> + device.signals.scan_done->connect([this]()
> + {
> + signals.wireless_network_scan_finished();
> + });
> +
> + device.signals.ap_added->connect([this, device_path](const core::dbus::types::ObjectPath& path)
> + {
> + try
> + {
> + on_access_point_added(path, device_path);
> + }
> + catch (const std::exception& e)
> + {
> + LOG(ERROR) << "Error while creating ap/wifi: " << e.what();
> + }
> + });
> +
> + device.signals.ap_removed->connect([this](const core::dbus::types::ObjectPath& path)
> + {
> + try
> + {
> + on_access_point_removed(path);
> + }
> + catch (const std::exception& e)
> + {
> + LOG(ERROR) << "Error while removing ap/wifi: " << e.what();
> + }
> + });
> + }
> + });
> +
> + // Query the initial connectivity state
> + state.set(from_nm_property(network_manager->properties.connectivity->get()));
> +
> + // And we wire up to property changes here
> + network_manager->signals.properties_changed->connect([this](const std::map<std::string, core::dbus::types::Variant>& dict)
> + {
> + for (const auto& pair : dict)
> + {
> + VLOG(1) << "Property has changed: " << std::endl
> + << " " << pair.first;
> +
> + if (xdg::NetworkManager::Properties::Connectivity::name() == pair.first)
> + {
> + state.set(from_nm_property(pair.second.as<xdg::NetworkManager::Properties::Connectivity::ValueType>()));
> + }
> + }
> + });
> +}
> +
> +void impl::OfonoNmConnectivityManager::Private::on_access_point_added(
> + const core::dbus::types::ObjectPath& ap_path,
> + const core::dbus::types::ObjectPath& device_path)
> +{
> + std::unique_lock<std::mutex> ul(cached.guard);
> +
> + // Let's see if we have a device known for the path. We return early
> + // if we do not know about the device.
> + auto itd = cached.wireless_devices.find(device_path);
> + if (itd == cached.wireless_devices.end())
> + return;
> +
> + xdg::NetworkManager::AccessPoint ap
> + {
> + network_manager->service->add_object_for_path(ap_path)
> + };
> +
> + auto wifi = std::make_shared<CachedWirelessNetwork>(itd->second, ap);
> + cached.wifis[ap_path] = wifi;
> +
> + // Let API consumers know that an AP appeared. The lock on the cache is
> + // not held to prevent from deadlocks.
> + ul.unlock(); signals.wireless_network_added(wifi);
> +}
> +
> +void impl::OfonoNmConnectivityManager::Private::on_access_point_removed(const core::dbus::types::ObjectPath& ap_path)
> +{
> + std::unique_lock<std::mutex> ul(cached.guard);
> +
> + // Let's see if we know about the wifi. We return early if not.
> + auto itw = cached.wifis.find(ap_path);
> + if (itw == cached.wifis.end())
> + return;
> +
> + // Update the cache and keep the wifi object alive until API consumers
> + // have been informed of the wifi going away.
> + connectivity::WirelessNetwork::Ptr wifi = itw->second;
> + cached.wifis.erase(itw);
> +
> + // Let API consumers know that an AP disappeared. The lock on the cache is
> + // not held to prevent from deadlocks.
> + ul.unlock(); signals.wireless_network_removed(wifi);
> +}
> +
> +const std::shared_ptr<connectivity::Manager>& connectivity::platform_default_manager()
> +{
> + static const std::shared_ptr<connectivity::Manager> instance{new impl::OfonoNmConnectivityManager{}};
> + return instance;
> +}
>
> === added file 'src/location_service/com/ubuntu/location/connectivity/ofono_nm_connectivity_manager.h'
> --- src/location_service/com/ubuntu/location/connectivity/ofono_nm_connectivity_manager.h 1970-01-01 00:00:00 +0000
> +++ src/location_service/com/ubuntu/location/connectivity/ofono_nm_connectivity_manager.h 2014-06-24 16:02:38 +0000
> @@ -0,0 +1,114 @@
> +/*
> + * Copyright © 2012-2013 Canonical Ltd.
> + *
> + * This program is free software: you can redistribute it and/or modify it
> + * under the terms of the GNU Lesser General Public License version 3,
> + * 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 Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public License
> + * along with this program. If not, see <http://www.gnu.org/licenses/>.
> + *
> + * Authored by: Thomas Voß <thomas.voss at canonical.com>
> + */
> +
> +#ifndef OFONO_NM_CONNECTIVITY_MANAGER_H_
> +#define OFONO_NM_CONNECTIVITY_MANAGER_H_
> +
> +#include <com/ubuntu/location/connectivity/manager.h>
> +
> +#include <com/ubuntu/location/logging.h>
> +
> +#include "cached_radio_cell.h"
> +#include "cached_wireless_network.h"
> +#include "nm.h"
> +#include "ofono.h"
> +
> +#include <core/dbus/bus.h>
> +#include <core/dbus/object.h>
> +#include <core/dbus/property.h>
> +#include <core/dbus/service.h>
> +#include <core/dbus/types/object_path.h>
> +#include <core/dbus/types/struct.h>
> +#include <core/dbus/types/stl/map.h>
> +#include <core/dbus/types/stl/string.h>
> +#include <core/dbus/types/stl/tuple.h>
> +#include <core/dbus/types/stl/vector.h>
> +
> +#include <core/dbus/asio/executor.h>
> +
> +#include "../set_name_for_thread.h"
> +
> +#include <chrono>
> +
> +namespace dbus = core::dbus;
> +
> +namespace impl
> +{
> +struct OfonoNmConnectivityManager : public com::ubuntu::location::connectivity::Manager
> +{
> + const core::Property<com::ubuntu::location::connectivity::State>& state() const override;
> +
> + void request_scan_for_wireless_networks() override;
> +
> + const core::Signal<>& wireless_network_scan_finished() const override;
> + const core::Signal<com::ubuntu::location::connectivity::WirelessNetwork::Ptr>& wireless_network_added() const override;
> + const core::Signal<com::ubuntu::location::connectivity::WirelessNetwork::Ptr>& wireless_network_removed() const override;
> +
> + void enumerate_visible_wireless_networks(const std::function<void(const com::ubuntu::location::connectivity::WirelessNetwork::Ptr&)>& f) const override;
> +
> + const core::Signal<com::ubuntu::location::connectivity::RadioCell::Ptr>& connected_cell_added() const override;
> + const core::Signal<com::ubuntu::location::connectivity::RadioCell::Ptr>& connected_cell_removed() const override;
> +
> + void enumerate_connected_radio_cells(const std::function<void(const com::ubuntu::location::connectivity::RadioCell::Ptr&)>& f) const override;
> +
> + struct Private
> + {
> + Private();
> + ~Private();
> +
> + void setup_radio_stack_access();
> + void on_modem_added(const core::dbus::types::ObjectPath& path);
> + void on_modem_removed(const core::dbus::types::ObjectPath& path);
> + void on_modem_interfaces_changed(const core::dbus::types::ObjectPath& path, const std::vector<std::string>& interfaces);
> +
> + void setup_network_stack_access();
> + void on_access_point_added(const core::dbus::types::ObjectPath& ap_path, const core::dbus::types::ObjectPath& device_path);
> + void on_access_point_removed(const core::dbus::types::ObjectPath& ap_path);
> +
> + core::dbus::Bus::Ptr system_bus;
> + core::dbus::Executor::Ptr executor;
> +
> + std::thread worker;
> +
> + org::freedesktop::NetworkManager::Ptr network_manager;
> + org::Ofono::Manager::Ptr modem_manager;
> +
> + struct
> + {
> + mutable std::mutex guard;
> + std::map<core::dbus::types::ObjectPath, CachedRadioCell::Ptr> cells;
> + std::map<core::dbus::types::ObjectPath, org::Ofono::Manager::Modem> modems;
> + std::map<core::dbus::types::ObjectPath, CachedWirelessNetwork::Ptr> wifis;
> + std::map<core::dbus::types::ObjectPath, org::freedesktop::NetworkManager::Device> wireless_devices;
> + } cached;
> +
> + struct
> + {
> + core::Signal<> wireless_network_scan_finished;
> + core::Signal<com::ubuntu::location::connectivity::RadioCell::Ptr> connected_cell_added;
> + core::Signal<com::ubuntu::location::connectivity::RadioCell::Ptr> connected_cell_removed;
> + core::Signal<com::ubuntu::location::connectivity::WirelessNetwork::Ptr> wireless_network_added;
> + core::Signal<com::ubuntu::location::connectivity::WirelessNetwork::Ptr> wireless_network_removed;
> + } signals;
> +
> + core::Property<com::ubuntu::location::connectivity::State> state;
> + } d;
> +};
> +}
> +
> +#endif // OFONO_NM_CONNECTIVITY_MANAGER_H_
>
> === added file 'src/location_service/com/ubuntu/location/connectivity/radio_cell.cpp'
> --- src/location_service/com/ubuntu/location/connectivity/radio_cell.cpp 1970-01-01 00:00:00 +0000
> +++ src/location_service/com/ubuntu/location/connectivity/radio_cell.cpp 2014-06-24 16:02:38 +0000
> @@ -0,0 +1,118 @@
> +/*
> + * Copyright © 2012-2013 Canonical Ltd.
> + *
> + * This program is free software: you can redistribute it and/or modify it
> + * under the terms of the GNU Lesser General Public License version 3,
> + * 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 Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public License
> + * along with this program. If not, see <http://www.gnu.org/licenses/>.
> + *
> + * Authored by: Thomas Voß <thomas.voss at canonical.com>
> + */
> +
> +#include <com/ubuntu/location/connectivity/radio_cell.h>
> +
> +namespace location = com::ubuntu::location;
> +
> +bool location::connectivity::operator==(const location::connectivity::RadioCell::Gsm& lhs,
> + const location::connectivity::RadioCell::Gsm& rhs)
> +{
> + return lhs.mobile_country_code == rhs.mobile_country_code &&
> + lhs.mobile_network_code == rhs.mobile_network_code &&
> + lhs.location_area_code == rhs.location_area_code &&
> + lhs.id == rhs.id &&
> + lhs.strength == rhs.strength;
> +}
> +
> +std::ostream& location::connectivity::operator<<(std::ostream& out, const location::connectivity::RadioCell::Gsm& gsm)
> +{
> + out << "("
> + << "mcc: " << gsm.mobile_country_code << ", "
> + << "mnc: " << gsm.mobile_network_code << ", "
> + << "lac: " << gsm.location_area_code << ", "
> + << "id: " << gsm.id << ", "
> + << "asu: " << gsm.strength << ")";
> +
> + return out;
> +}
> +
> +bool location::connectivity::operator==(const location::connectivity::RadioCell::Umts& lhs, const location::connectivity::RadioCell::Umts& rhs)
> +{
> + return lhs.mobile_country_code == rhs.mobile_country_code &&
> + lhs.mobile_network_code == rhs.mobile_network_code &&
> + lhs.location_area_code == rhs.location_area_code &&
> + lhs.id == rhs.id &&
> + lhs.strength == rhs.strength;
> +}
> +
> +std::ostream& location::connectivity::operator<<(std::ostream& out, const location::connectivity::RadioCell::Umts& umts)
> +{
> + out << "("
> + << "mcc: " << umts.mobile_country_code << ", "
> + << "mnc: " << umts.mobile_network_code << ", "
> + << "lac: " << umts.location_area_code << ", "
> + << "id: " << umts.id << ", "
> + << "asu: " << umts.strength << ")";
> +
> + return out;
> +}
> +
> +bool location::connectivity::operator==(const location::connectivity::RadioCell::Lte& lhs,
> + const location::connectivity::RadioCell::Lte& rhs)
> +{
> + return lhs.mobile_country_code == rhs.mobile_country_code &&
> + lhs.mobile_network_code == rhs.mobile_network_code &&
> + lhs.tracking_area_code == rhs.tracking_area_code &&
> + lhs.id == rhs.id &&
> + lhs.physical_id == rhs.physical_id &&
> + lhs.strength == rhs.strength;
> +}
> +
> +std::ostream& location::connectivity::operator<<(std::ostream& out, const location::connectivity::RadioCell::Lte& lte)
> +{
> + out << "("
> + << "mcc: " << lte.mobile_country_code << ", "
> + << "mnc: " << lte.mobile_network_code << ", "
> + << "lac: " << lte.tracking_area_code << ", "
> + << "id: " << lte.id << ", "
> + << "id: " << lte.physical_id << ", "
> + << "asu: " << lte.strength << ")";
> +
> + return out;
> +}
> +
> +bool location::connectivity::operator==(const location::connectivity::RadioCell& lhs,
> + const location::connectivity::RadioCell& rhs)
> +{
> + if (lhs.type() != rhs.type())
> + return false;
> +
> + switch(lhs.type())
> + {
> + case location::connectivity::RadioCell::Type::gsm: return lhs.gsm() == rhs.gsm();
> + case location::connectivity::RadioCell::Type::umts: return lhs.umts() == rhs.umts();
> + case location::connectivity::RadioCell::Type::lte: return lhs.lte() == rhs.lte();
> + default: return true;
> + }
> +
> + return false;
> +}
> +
> +std::ostream& location::connectivity::operator<<(std::ostream& out, const location::connectivity::RadioCell& cell)
> +{
> + switch (cell.type())
> + {
> + case location::connectivity::RadioCell::Type::gsm: out << "gsm" << cell.gsm(); break;
> + case location::connectivity::RadioCell::Type::umts: out << "umts" << cell.umts(); break;
> + case location::connectivity::RadioCell::Type::lte: out << "lte" << cell.lte(); break;
> + case location::connectivity::RadioCell::Type::unknown: break;
> + }
> +
> + return out;
> +}
>
> === added file 'src/location_service/com/ubuntu/location/connectivity/wireless_network.cpp'
> --- src/location_service/com/ubuntu/location/connectivity/wireless_network.cpp 1970-01-01 00:00:00 +0000
> +++ src/location_service/com/ubuntu/location/connectivity/wireless_network.cpp 2014-06-24 16:02:38 +0000
> @@ -0,0 +1,47 @@
> +/*
> + * Copyright © 2012-2013 Canonical Ltd.
> + *
> + * This program is free software: you can redistribute it and/or modify it
> + * under the terms of the GNU Lesser General Public License version 3,
> + * 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 Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public License
> + * along with this program. If not, see <http://www.gnu.org/licenses/>.
> + *
> + * Authored by: Thomas Voß <thomas.voss at canonical.com>
> + */
> +
> +#include <com/ubuntu/location/connectivity/wireless_network.h>
> +
> +#include <iostream>
> +
> +namespace location = com::ubuntu::location;
> +
> +std::ostream& location::connectivity::operator<<(std::ostream& out, location::connectivity::WirelessNetwork::Mode mode)
> +{
> + switch (mode)
> + {
> + case location::connectivity::WirelessNetwork::Mode::unknown: out << "Mode::unknown"; break;
> + case location::connectivity::WirelessNetwork::Mode::adhoc: out << "Mode::adhoc"; break;
> + case location::connectivity::WirelessNetwork::Mode::infrastructure: out << "Mode::infrastructure"; break;
> + }
> +
> + return out;
> +}
> +
> +std::ostream& location::connectivity::operator<<(std::ostream& out, const location::connectivity::WirelessNetwork& wifi)
> +{
> + return out << "("
> + << "bssid: " << wifi.bssid().get() << ", "
> + << "ssid: " << wifi.ssid().get() << ", "
> + << "last seen: " << wifi.last_seen().get().time_since_epoch().count() << ", "
> + << "mode: " << wifi.mode().get() << ", "
> + << "frequency: " << wifi.frequency().get() << ", "
> + << "strength: " << wifi.signal_strength().get()
> + << ")";
> +}
>
> === added file 'src/location_service/com/ubuntu/location/criteria.cpp'
> --- src/location_service/com/ubuntu/location/criteria.cpp 1970-01-01 00:00:00 +0000
> +++ src/location_service/com/ubuntu/location/criteria.cpp 2014-06-24 16:02:38 +0000
> @@ -0,0 +1,99 @@
> +/*
> + * Copyright © 2012-2013 Canonical Ltd.
> + *
> + * This program is free software: you can redistribute it and/or modify it
> + * under the terms of the GNU Lesser General Public License version 3,
> + * 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 Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public License
> + * along with this program. If not, see <http://www.gnu.org/licenses/>.
> + *
> + * Authored by: Thomas Voß <thomas.voss at canonical.com>
> + */
> +
> +#include <com/ubuntu/location/criteria.h>
> +
> +bool com::ubuntu::location::Criteria::satisfies(const com::ubuntu::location::Criteria& rhs) const
> +{
> + bool result = false;
> +
> + if (rhs.requires.position)
> + result &= requires.position;
> +
> + if (rhs.requires.altitude)
> + result &= requires.altitude;
> +
> + if (rhs.requires.heading)
> + result &= requires.heading;
> +
> + if (rhs.requires.velocity)
> + result &= requires.velocity;
> +
> + result &= accuracy.horizontal <= rhs.accuracy.horizontal;
> +
> + if (rhs.accuracy.vertical)
> + result &= accuracy.vertical && accuracy.vertical <= rhs.accuracy.vertical;
> +
> + if (rhs.accuracy.heading)
> + result &= accuracy.heading && accuracy.heading <= rhs.accuracy.heading;
> +
> + if (rhs.accuracy.velocity)
> + result &= accuracy.velocity && accuracy.velocity <= rhs.accuracy.velocity;
> +
> + return result;
> +}
> +
> +com::ubuntu::location::Criteria com::ubuntu::location::operator+(
> + const com::ubuntu::location::Criteria& lhs,
> + const com::ubuntu::location::Criteria& rhs)
> +{
> + Criteria result{lhs};
> +
> + result.requires.position |= rhs.requires.position;
> + result.requires.velocity |= rhs.requires.velocity;
> + result.requires.heading |= rhs.requires.heading;
> + result.requires.altitude |= rhs.requires.altitude;
> +
> + if (rhs.accuracy.horizontal < result.accuracy.horizontal)
> + result.accuracy.horizontal = rhs.accuracy.horizontal;
> +
> + if (result.accuracy.vertical)
> + {
> + if (rhs.accuracy.vertical && rhs.accuracy.vertical < result.accuracy.vertical)
> + {
> + result.accuracy.vertical = rhs.accuracy.vertical;
> + }
> + } else
> + {
> + result.accuracy.vertical = rhs.accuracy.vertical;
> + }
> +
> + if (result.accuracy.velocity)
> + {
> + if (rhs.accuracy.velocity && rhs.accuracy.velocity < result.accuracy.velocity)
> + {
> + result.accuracy.velocity = rhs.accuracy.velocity;
> + }
> + } else
> + {
> + result.accuracy.velocity = rhs.accuracy.velocity;
> + }
> +
> + if (result.accuracy.heading)
> + {
> + if (rhs.accuracy.heading && rhs.accuracy.heading < result.accuracy.heading)
> + {
> + result.accuracy.heading = rhs.accuracy.heading;
> + }
> + } else
> + {
> + result.accuracy.heading = rhs.accuracy.heading;
> + }
> +
> + return result;
> +}
>
> === modified file 'src/location_service/com/ubuntu/location/default_permission_manager.cpp'
> --- src/location_service/com/ubuntu/location/default_permission_manager.cpp 2013-05-28 14:41:06 +0000
> +++ src/location_service/com/ubuntu/location/default_permission_manager.cpp 2014-06-24 16:02:38 +0000
> @@ -15,7 +15,7 @@
> *
> * Authored by: Thomas Voß <thomas.voss at canonical.com>
> */
> -#include "com/ubuntu/location/default_permission_manager.h"
> +#include <com/ubuntu/location/default_permission_manager.h>
>
> namespace cul = com::ubuntu::location;
>
>
> === modified file 'src/location_service/com/ubuntu/location/default_provider_selection_policy.cpp'
> --- src/location_service/com/ubuntu/location/default_provider_selection_policy.cpp 2013-06-10 11:10:00 +0000
> +++ src/location_service/com/ubuntu/location/default_provider_selection_policy.cpp 2014-06-24 16:02:38 +0000
> @@ -15,10 +15,30 @@
> *
> * Authored by: Thomas Voß <thomas.voss at canonical.com>
> */
> -#include "com/ubuntu/location/default_provider_selection_policy.h"
> +#include <com/ubuntu/location/default_provider_selection_policy.h>
> +
> +#include <com/ubuntu/location/engine.h>
>
> namespace cul = com::ubuntu::location;
>
> +namespace
> +{
> +struct NullProvider : public cul::Provider
> +{
> + NullProvider() = default;
> +};
> +
> +std::shared_ptr<cul::Provider> null_provider_instance
> +{
> + new NullProvider{}
> +};
> +}
> +
> +const cul::Provider::Ptr& cul::ProviderSelectionPolicy::null_provider()
> +{
> + return null_provider_instance;
> +}
> +
> cul::DefaultProviderSelectionPolicy::DefaultProviderSelectionPolicy()
> {
> }
> @@ -28,15 +48,15 @@
> }
>
> cul::ProviderSelection
> -cul::DefaultProviderSelectionPolicy::determine_provider_selection_from_set_for_criteria(
> +cul::DefaultProviderSelectionPolicy::determine_provider_selection_for_criteria(
> const cul::Criteria& criteria,
> - const std::set<cul::Provider::Ptr>& providers)
> + const cul::ProviderEnumerator& enumerator)
> {
> ProviderSelection selection
> {
> - determine_position_updates_provider(criteria, providers),
> - determine_heading_updates_provider(criteria, providers),
> - determine_velocity_updates_provider(criteria, providers),
> + determine_position_updates_provider(criteria, enumerator),
> + determine_heading_updates_provider(criteria, enumerator),
> + determine_velocity_updates_provider(criteria, enumerator)
> };
>
> return selection;
> @@ -45,7 +65,7 @@
> cul::Provider::Ptr
> cul::DefaultProviderSelectionPolicy::determine_position_updates_provider(
> const cul::Criteria& criteria,
> - const std::set<cul::Provider::Ptr>& providers)
> + const cul::ProviderEnumerator& enumerator)
> {
> auto less =
> [](const Provider::Ptr& lhs, const Provider::Ptr& rhs)
> @@ -55,24 +75,22 @@
> };
>
> std::set<
> - Provider::Ptr,
> + Provider::Ptr,
> std::function<bool(const Provider::Ptr&, const Provider::Ptr&)>> matching_providers(less);
>
> - std::for_each(
> - providers.begin(),
> - providers.end(),
> + enumerator.for_each_provider(
> [&](const Provider::Ptr& provider)
> {
> if (provider->matches_criteria(criteria))
> matching_providers.insert(provider);
> });
>
> - return matching_providers.empty() ? Provider::Ptr {} : *matching_providers.begin();
> + return matching_providers.empty() ? null_provider() : *matching_providers.begin();
> }
>
> cul::Provider::Ptr cul::DefaultProviderSelectionPolicy::determine_heading_updates_provider(
> const cul::Criteria& criteria,
> - const std::set<cul::Provider::Ptr>& providers)
> + const cul::ProviderEnumerator& enumerator)
> {
> auto less =
> [](const Provider::Ptr& lhs, const Provider::Ptr& rhs)
> @@ -84,21 +102,19 @@
> Provider::Ptr,
> std::function<bool(const Provider::Ptr&, const Provider::Ptr&)>> matching_providers(less);
>
> - std::for_each(
> - providers.begin(),
> - providers.end(),
> + enumerator.for_each_provider(
> [&](const Provider::Ptr& provider)
> {
> if (provider->matches_criteria(criteria))
> matching_providers.insert(provider);
> });
>
> - return matching_providers.empty() ? Provider::Ptr {} : *matching_providers.begin();
> + return matching_providers.empty() ? null_provider() : *matching_providers.begin();
> }
>
> cul::Provider::Ptr cul::DefaultProviderSelectionPolicy::determine_velocity_updates_provider(
> const cul::Criteria& criteria,
> - const std::set<cul::Provider::Ptr>& providers)
> + const cul::ProviderEnumerator& enumerator)
> {
> auto less =
> [](const Provider::Ptr& lhs, const Provider::Ptr& rhs)
> @@ -110,15 +126,12 @@
> Provider::Ptr,
> std::function<bool(const Provider::Ptr&, const Provider::Ptr&)>> matching_providers(less);
>
> - std::for_each(
> - providers.begin(),
> - providers.end(),
> + enumerator.for_each_provider(
> [&](const Provider::Ptr& provider)
> {
> if (provider->matches_criteria(criteria))
> matching_providers.insert(provider);
> });
>
> - return matching_providers.empty() ? Provider::Ptr {} :
> - *matching_providers.begin();
> + return matching_providers.empty() ? null_provider() : *matching_providers.begin();
> }
>
> === modified file 'src/location_service/com/ubuntu/location/engine.cpp'
> --- src/location_service/com/ubuntu/location/engine.cpp 2013-06-10 11:10:00 +0000
> +++ src/location_service/com/ubuntu/location/engine.cpp 2014-06-24 16:02:38 +0000
> @@ -15,24 +15,53 @@
> *
> * Authored by: Thomas Voß <thomas.voss at canonical.com>
> */
> -#include "com/ubuntu/location/engine.h"
> +#include <com/ubuntu/location/engine.h>
> +
> +#include <com/ubuntu/location/logging.h>
> +#include <com/ubuntu/location/provider_selection_policy.h>
>
> #include <stdexcept>
>
> namespace cul = com::ubuntu::location;
>
> -cul::Engine::Engine(const std::set<cul::Provider::Ptr>& initial_providers,
> - const cul::ProviderSelectionPolicy::Ptr& provider_selection_policy)
> - : providers(initial_providers),
> - provider_selection_policy(provider_selection_policy)
> +cul::Engine::Engine(const std::shared_ptr<cul::ProviderSelectionPolicy>& provider_selection_policy)
> + : provider_selection_policy(provider_selection_policy)
> {
> if (!provider_selection_policy)
> std::runtime_error("Cannot construct an engine given a null ProviderSelectionPolicy");
> +
> + // Setup behavior in case of configuration changes.
> + configuration.engine_state.changed().connect([this](const Engine::Status& status)
> + {
> + switch (status)
> + {
> + case Engine::Status::off:
> + for_each_provider([](const Provider::Ptr& provider)
> + {
> + provider->state_controller()->stop_position_updates();
> + provider->state_controller()->stop_heading_updates();
> + provider->state_controller()->stop_velocity_updates();
> + });
> + break;
> + default:
> + break;
> + }
> + });
> +}
> +
> +cul::Engine::~Engine()
> +{
> + for_each_provider([](const Provider::Ptr& provider)
> + {
> + provider->state_controller()->stop_position_updates();
> + provider->state_controller()->stop_heading_updates();
> + provider->state_controller()->stop_velocity_updates();
> + });
> }
>
> cul::ProviderSelection cul::Engine::determine_provider_selection_for_criteria(const cul::Criteria& criteria)
> {
> - return provider_selection_policy->determine_provider_selection_from_set_for_criteria(criteria, providers);
> + return provider_selection_policy->determine_provider_selection_for_criteria(criteria, *this);
> }
>
> bool cul::Engine::has_provider(const cul::Provider::Ptr& provider) noexcept
> @@ -45,10 +74,67 @@
> if (!provider)
> throw std::runtime_error("Cannot add null provider");
>
> - providers.insert(provider);
> + // We wire up changes in the engine's configuration to the respective slots
> + // of the provider.
> + auto cp = updates.reference_location.changed().connect([provider](const cul::Update<cul::Position>& pos)
> + {
> + provider->on_reference_location_updated(pos);
> + });
> +
> + auto cv = updates.reference_velocity.changed().connect([provider](const cul::Update<cul::Velocity>& velocity)
> + {
> + provider->on_reference_velocity_updated(velocity);
> + });
> +
> + auto ch = updates.reference_heading.changed().connect([provider](const cul::Update<cul::Heading>& heading)
> + {
> + provider->on_reference_heading_updated(heading);
> + });
> +
> + auto cr = configuration.wifi_and_cell_id_reporting_state.changed().connect([provider](cul::WifiAndCellIdReportingState state)
> + {
> + provider->on_wifi_and_cell_reporting_state_changed(state);
> + });
> +
> + // And do the reverse: Satellite visibility updates are funneled via the engine's configuration.
> + auto cs = provider->updates().svs.connect([this](const cul::Update<std::set<cul::SpaceVehicle>>& src)
> + {
> + updates.visible_space_vehicles.update([src](std::map<cul::SpaceVehicle::Key, cul::SpaceVehicle>& dest)
> + {
> + for(auto& sv : src.value)
> + {
> + dest[sv.key] = sv;
> + }
> +
> + return true;
> + });
> + });
> +
> + // We are a bit dumb and just take any position update as new reference.
> + // We should come up with a better heuristic here.
> + auto cpr = provider->updates().position.connect([this](const cul::Update<cul::Position>& src)
> + {
> + updates.reference_location = src;
> + });
> +
> + std::lock_guard<std::mutex> lg(guard);
> + providers.emplace(provider, std::move(ProviderConnections{cp, ch, cv, cr, cs, cpr}));
> }
>
> void cul::Engine::remove_provider(const cul::Provider::Ptr& provider) noexcept
> {
> - providers.erase(provider);
> + std::lock_guard<std::mutex> lg(guard);
> +
> + auto it = providers.find(provider);
> + if (it != providers.end())
> + {
> + providers.erase(it);
> + }
> +}
> +
> +void cul::Engine::for_each_provider(const std::function<void(const Provider::Ptr&)>& enumerator) const noexcept
> +{
> + std::lock_guard<std::mutex> lg(guard);
> + for (const auto& provider : providers)
> + enumerator(provider.first);
> }
>
> === modified file 'src/location_service/com/ubuntu/location/init_and_shutdown.cpp'
> --- src/location_service/com/ubuntu/location/init_and_shutdown.cpp 2013-05-29 09:21:16 +0000
> +++ src/location_service/com/ubuntu/location/init_and_shutdown.cpp 2014-06-24 16:02:38 +0000
> @@ -1,5 +1,5 @@
> -#include "com/ubuntu/location/init_and_shutdown.h"
> -#include "com/ubuntu/location/logging.h"
> +#include <com/ubuntu/location/init_and_shutdown.h>
> +#include <com/ubuntu/location/logging.h>
>
> #include <gflags/gflags.h>
>
> @@ -25,11 +25,11 @@
>
> void cul::init(int* argc, char*** argv)
> {
> - static const bool remove_parsed_flags = true;
> - google::ParseCommandLineFlags(argc, argv, remove_parsed_flags);
> + static const bool remove_parsed_flags = true;
> + google::ParseCommandLineFlags(argc, argv, remove_parsed_flags);
> }
>
> void cul::shutdown()
> {
> - google::ShutDownCommandLineFlags();
> -}
> \ No newline at end of file
> + google::ShutDownCommandLineFlags();
> +}
>
> === modified file 'src/location_service/com/ubuntu/location/position.cpp'
> --- src/location_service/com/ubuntu/location/position.cpp 2013-05-28 14:41:06 +0000
> +++ src/location_service/com/ubuntu/location/position.cpp 2014-06-24 16:02:38 +0000
> @@ -15,112 +15,98 @@
> *
> * Authored by: Thomas Voß <thomas.voss at canonical.com>
> */
> -#include "com/ubuntu/location/position.h"
> +#include <com/ubuntu/location/position.h>
>
> #include <bitset>
> #include <ostream>
>
> namespace cul = com::ubuntu::location;
>
> -cul::Position::Position() : fields{Flags("000"), wgs84::Latitude{}, wgs84::Longitude{}, wgs84::Altitude{}}
> -{
> -}
> -
> -cul::Position::Position(
> - const cul::wgs84::Latitude& latitude,
> - const cul::wgs84::Longitude& longitude)
> - : fields{Flags("011"), latitude, longitude, wgs84::Altitude{}}
> -{
> -}
> -
> -cul::Position::Position(
> - const cul::wgs84::Latitude& latitude,
> - const cul::wgs84::Longitude& longitude,
> - const cul::wgs84::Altitude& altitude)
> - : fields{Flags{"111"}, latitude, longitude, altitude}
> -{
> +cul::Position::Position(
> + const cul::wgs84::Latitude& latitude,
> + const cul::wgs84::Longitude& longitude)
> + : latitude(latitude),
> + longitude(longitude)
> +{
> +}
> +
> +cul::Position::Position(
> + const cul::wgs84::Latitude& latitude,
> + const cul::wgs84::Longitude& longitude,
> + const cul::wgs84::Altitude& altitude)
> + : latitude(latitude),
> + longitude(longitude),
> + altitude(altitude)
> +{
> +}
> +
> +cul::Position::Position(const cul::wgs84::Latitude& lat,
> + const cul::wgs84::Longitude& lon,
> + const cul::wgs84::Altitude& alt,
> + const cul::units::Quantity<cul::units::Length>& hor_acc)
> + : cul::Position::Position(lat, lon, alt)
> +{
> + accuracy.horizontal = hor_acc;
> +}
> +
> +cul::Position::Position(const cul::wgs84::Latitude& lat,
> + const cul::wgs84::Longitude& lon,
> + const cul::wgs84::Altitude& alt,
> + const cul::units::Quantity<cul::units::Length>& hor_acc,
> + const cul::units::Quantity<cul::units::Length>& ver_acc)
> + : cul::Position::Position(lat, lon, alt, hor_acc)
> +{
> + accuracy.vertical = ver_acc;
> }
>
> bool cul::Position::operator==(const cul::Position& rhs) const
> {
> - return fields.latitude == rhs.fields.latitude && fields.longitude == rhs.fields.longitude && fields.altitude == rhs.fields.altitude;
> + return latitude == rhs.latitude &&
> + longitude == rhs.longitude &&
> + altitude == rhs.altitude &&
> + accuracy.horizontal == rhs.accuracy.horizontal &&
> + accuracy.vertical == rhs.accuracy.vertical;
> }
>
> bool cul::Position::operator!=(const cul::Position& rhs) const
> {
> - return !(fields.latitude == rhs.fields.latitude && fields.longitude == rhs.fields.longitude && fields.altitude == rhs.fields.altitude);
> -}
> -
> -const cul::Position::Flags& cul::Position::flags() const
> -{
> - return fields.flags;
> -}
> -
> -bool cul::Position::has_latitude() const
> -{
> - return fields.flags.test(latitude_flag);
> -}
> -
> -cul::Position& cul::Position::latitude(const cul::wgs84::Latitude& lat)
> -{
> - fields.flags.set(latitude_flag);
> - fields.latitude = lat;
> - return *this;
> -}
> -
> -const cul::wgs84::Latitude& cul::Position::latitude() const
> -{
> - return fields.latitude;
> -}
> -
> -bool cul::Position::has_longitude() const
> -{
> - return fields.flags.test(longitude_flag);
> -}
> -
> -cul::Position& cul::Position::longitude(const cul::wgs84::Longitude& lon)
> -{
> - fields.flags.set(longitude_flag);
> - fields.longitude = lon;
> - return *this;
> -}
> -
> -const cul::wgs84::Longitude& cul::Position::longitude() const
> -{
> - return fields.longitude;
> -}
> -
> -bool cul::Position::has_altitude() const
> -{
> - return fields.flags.test(altitude_flag);
> -}
> -
> -cul::Position& cul::Position::altitude(const cul::wgs84::Altitude& alt)
> -{
> - fields.flags.set(altitude_flag);
> - fields.altitude = alt;
> - return *this;
> -}
> -
> -const cul::wgs84::Altitude& cul::Position::altitude() const
> -{
> - return fields.altitude;
> + return !(*this == rhs);
> }
>
> std::ostream& cul::operator<<(std::ostream& out, const cul::Position& position)
> {
> - out << "Position(" << position.latitude() << ", " << position.longitude() << ", " << position.altitude() << ")";
> + out << "Position("
> + << "lat: " << position.latitude << ", "
> + << "lon: " << position.longitude << ", ";
> + out << "alt: ";
> + if (position.altitude)
> + out << *position.altitude;
> + else
> + out << "n/a";
> + out << ", ";
> + out << "hor.acc.: ";
> + if (position.accuracy.horizontal)
> + out << *position.accuracy.horizontal;
> + else
> + out << "n/a";
> + out << ", ";
> + out << "ver.acc.: ";
> + if (position.accuracy.vertical)
> + out << *position.accuracy.vertical;
> + else
> + out << "n/a";
> + out << ")";
> return out;
> }
>
> cul::units::Quantity<cul::units::Length> cul::haversine_distance(const cul::Position& p1, const cul::Position& p2)
> {
> - static const units::Quantity<units::Length> radius_of_earth {6371 * units::kilo* units::Meters};
> - auto dLat = p2.latitude() - p1.latitude();
> - auto dLon = p2.longitude() - p1.longitude();
> + static const units::Quantity<units::Length> radius_of_earth {6371 * units::kilo * units::Meters};
> + auto dLat = p2.latitude - p1.latitude;
> + auto dLon = p2.longitude - p1.longitude;
> auto a =
> std::pow(units::sin(dLat.value/2.), 2) +
> - std::pow(units::sin(dLon.value/2.), 2) * units::cos(p1.latitude().value) * units::cos(p2.latitude().value);
> + std::pow(units::sin(dLon.value/2.), 2) * units::cos(p1.latitude.value) * units::cos(p2.latitude.value);
>
> auto c = 2. * std::atan2(std::sqrt(a), std::sqrt(1.-a));
> return radius_of_earth * c;
>
> === modified file 'src/location_service/com/ubuntu/location/provider.cpp'
> --- src/location_service/com/ubuntu/location/provider.cpp 2013-06-10 11:10:00 +0000
> +++ src/location_service/com/ubuntu/location/provider.cpp 2014-06-24 16:02:38 +0000
> @@ -15,7 +15,7 @@
> *
> * Authored by: Thomas Voß <thomas.voss at canonical.com>
> */
> -#include "com/ubuntu/location/provider.h"
> +#include <com/ubuntu/location/provider.h>
>
> #include <atomic>
> #include <bitset>
> @@ -86,95 +86,27 @@
> return velocity_updates_counter > 0;
> }
>
> -const cul::Provider::Controller::Cache<cul::Update<cul::Position>>& cul::Provider::Controller::cached_position_update() const
> -{
> - return cached.position;
> -}
> -
> -const cul::Provider::Controller::Cache<cul::Update<cul::Heading>>& cul::Provider::Controller::cached_heading_update() const
> -{
> - return cached.heading;
> -}
> -
> -const cul::Provider::Controller::Cache<cul::Update<cul::Velocity>>& cul::Provider::Controller::cached_velocity_update() const
> -{
> - return cached.velocity;
> -}
> -
> cul::Provider::Controller::Controller(cul::Provider& instance)
> : instance(instance),
> position_updates_counter(0),
> heading_updates_counter(0),
> - velocity_updates_counter(0),
> - cached
> - {
> - Cache<Update<Position>>{},
> - Cache<Update<Velocity>>{},
> - Cache<Update<Heading>>{}
> - }
> -{
> - position_update_connection =
> - instance.subscribe_to_position_updates(
> - std::bind(&Controller::on_position_updated,
> - this,
> - std::placeholders::_1));
> -
> - velocity_update_connection =
> - instance.subscribe_to_velocity_updates(
> - std::bind(&Controller::on_velocity_updated,
> - this,
> - std::placeholders::_1));
> -
> - heading_update_connection =
> - instance.subscribe_to_heading_updates(
> - std::bind(&Controller::on_heading_updated,
> - this,
> - std::placeholders::_1));
> -}
> -
> -void cul::Provider::Controller::on_position_updated(const cul::Update<cul::Position>& position)
> -{
> - cached.position.update(position);
> -}
> -
> -void cul::Provider::Controller::on_velocity_updated(const cul::Update<cul::Velocity>& velocity)
> -{
> - cached.velocity.update(velocity);
> -}
> -
> -void cul::Provider::Controller::on_heading_updated(const cul::Update<cul::Heading>& heading)
> -{
> - cached.heading.update(heading);
> + velocity_updates_counter(0)
> +{
> }
>
> const cul::Provider::Controller::Ptr& cul::Provider::state_controller() const
> {
> - return controller;
> -}
> -
> -cul::ChannelConnection cul::Provider::subscribe_to_position_updates(std::function<void(const cul::Update<cul::Position>&)> f)
> -{
> - return position_updates_channel.connect(f);
> -}
> -
> -cul::ChannelConnection cul::Provider::subscribe_to_heading_updates(std::function<void(const cul::Update<cul::Heading>&)> f)
> -{
> - return heading_updates_channel.connect(f);
> -}
> -
> -cul::ChannelConnection cul::Provider::subscribe_to_velocity_updates(std::function<void(const cul::Update<cul::Velocity>&)> f)
> -{
> - return velocity_updates_channel.connect(f);
> -}
> -
> -bool cul::Provider::supports(const cul::Provider::Feature& f) const
> -{
> - return feature_flags.test(static_cast<std::size_t>(f));
> -}
> -
> -bool cul::Provider::requires(const cul::Provider::Requirement& r) const
> -{
> - return requirement_flags.test(static_cast<std::size_t>(r));
> + return d.controller;
> +}
> +
> +bool cul::Provider::supports(const cul::Provider::Features& f) const
> +{
> + return (d.features & f) != Features::none;
> +}
> +
> +bool cul::Provider::requires(const cul::Provider::Requirements& r) const
> +{
> + return (d.requirements & r) != Requirements::none;
> }
>
> bool cul::Provider::matches_criteria(const cul::Criteria&)
> @@ -182,28 +114,39 @@
> return false;
> }
>
> +const cul::Provider::Updates& cul::Provider::updates() const
> +{
> + return d.updates;
> +}
> +
> cul::Provider::Provider(
> - const cul::Provider::FeatureFlags& feature_flags,
> - const cul::Provider::RequirementFlags& requirement_flags)
> - : feature_flags(feature_flags),
> - requirement_flags(requirement_flags),
> - controller(new Controller(*this))
> -{
> -}
> -
> -void cul::Provider::deliver_position_updates(const cul::Update<cul::Position>& update)
> -{
> - position_updates_channel(update);
> -}
> -
> -void cul::Provider::deliver_heading_updates(const cul::Update<cul::Heading>& update)
> -{
> - heading_updates_channel(update);
> -}
> -
> -void cul::Provider::deliver_velocity_updates(const cul::Update<cul::Velocity>& update)
> -{
> - velocity_updates_channel(update);
> + const cul::Provider::Features& features,
> + const cul::Provider::Requirements& requirements)
> +{
> + d.features = features;
> + d.requirements = requirements;
> + d.controller = std::shared_ptr<Provider::Controller>(new Provider::Controller(*this));
> +}
> +
> +cul::Provider::Updates& cul::Provider::mutable_updates()
> +{
> + return d.updates;
> +}
> +
> +void cul::Provider::on_wifi_and_cell_reporting_state_changed(cul::WifiAndCellIdReportingState)
> +{
> +}
> +
> +void cul::Provider::on_reference_location_updated(const cul::Update<cul::Position>&)
> +{
> +}
> +
> +void cul::Provider::on_reference_velocity_updated(const cul::Update<cul::Velocity>&)
> +{
> +}
> +
> +void cul::Provider::on_reference_heading_updated(const cul::Update<cul::Heading>&)
> +{
> }
>
> void cul::Provider::start_position_updates() {}
> @@ -212,3 +155,23 @@
> void cul::Provider::stop_heading_updates() {}
> void cul::Provider::start_velocity_updates() {}
> void cul::Provider::stop_velocity_updates() {}
> +
> +cul::Provider::Features cul::operator|(cul::Provider::Features lhs, cul::Provider::Features rhs)
> +{
> + return static_cast<cul::Provider::Features>(static_cast<unsigned int>(lhs) | static_cast<unsigned int>(rhs));
> +}
> +
> +cul::Provider::Features cul::operator&(cul::Provider::Features lhs, cul::Provider::Features rhs)
> +{
> + return static_cast<cul::Provider::Features>(static_cast<unsigned int>(lhs) & static_cast<unsigned int>(rhs));
> +}
> +
> +cul::Provider::Requirements cul::operator|(cul::Provider::Requirements lhs, cul::Provider::Requirements rhs)
> +{
> + return static_cast<cul::Provider::Requirements>(static_cast<unsigned int>(lhs) | static_cast<unsigned int>(rhs));
> +}
> +
> +cul::Provider::Requirements cul::operator&(cul::Provider::Requirements lhs, cul::Provider::Requirements rhs)
> +{
> + return static_cast<cul::Provider::Requirements>(static_cast<unsigned int>(lhs) & static_cast<unsigned int>(rhs));
> +}
>
> === modified file 'src/location_service/com/ubuntu/location/provider_factory.cpp'
> --- src/location_service/com/ubuntu/location/provider_factory.cpp 2013-05-28 14:41:06 +0000
> +++ src/location_service/com/ubuntu/location/provider_factory.cpp 2014-06-24 16:02:38 +0000
> @@ -15,8 +15,8 @@
> *
> * Authored by: Thomas Voß <thomas.voss at canonical.com>
> */
> -#include "com/ubuntu/location/provider_factory.h"
> -#include "com/ubuntu/location/provider.h"
> +#include <com/ubuntu/location/provider_factory.h>
> +#include <com/ubuntu/location/provider.h>
>
> #include <functional>
> #include <map>
>
> === modified file 'src/location_service/com/ubuntu/location/providers/dummy/provider.cpp'
> --- src/location_service/com/ubuntu/location/providers/dummy/provider.cpp 2014-02-10 08:31:32 +0000
> +++ src/location_service/com/ubuntu/location/providers/dummy/provider.cpp 2014-06-24 16:02:38 +0000
> @@ -57,28 +57,47 @@
>
> provider_config.update_period = std::chrono::milliseconds
> {
> - config.get(dummy::Configuration::key_update_period(), 500)
> - };
> - provider_config.reference_position.latitude(wgs84::Latitude
> - {
> - config.get(dummy::Configuration::key_reference_position_lat(), 51.) * units::Degrees
> - });
> - provider_config.reference_position.longitude(wgs84::Longitude
> - {
> - config.get(dummy::Configuration::key_reference_position_lon(), 7.) * units::Degrees
> - });
> + config.get(dummy::Configuration::Keys::update_period, 500)
> + };
> + provider_config.reference_position.latitude = location::wgs84::Latitude
> + {
> + config.get(dummy::Configuration::Keys::reference_position_lat, 51.) * location::units::Degrees
> + };
> + provider_config.reference_position.longitude = location::wgs84::Longitude
> + {
> + config.get(dummy::Configuration::Keys::reference_position_lon, 7.) * location::units::Degrees
> + };
> +
> + if (config.count(dummy::Configuration::Keys::reference_position_alt) > 0)
> + provider_config.reference_position.altitude = location::wgs84::Altitude
> + {
> + config.get(dummy::Configuration::Keys::reference_position_alt, 0.) * location::units::Meters
> + };
> +
> + if (config.count(dummy::Configuration::Keys::reference_horizontal_accuracy) > 0)
> + provider_config.reference_position.accuracy.horizontal =
> + config.get(dummy::Configuration::Keys::reference_horizontal_accuracy, 0.) * location::units::Meters;
> +
> + if (config.count(dummy::Configuration::Keys::reference_vertical_accuracy) > 0)
> + provider_config.reference_position.accuracy.vertical =
> + config.get(dummy::Configuration::Keys::reference_vertical_accuracy, 0.) * location::units::Meters;
> +
> + provider_config.reference_velocity = location::Velocity
> + {
> + config.get(dummy::Configuration::Keys::reference_velocity, 9.) * location::units::MetersPerSecond
> + };
> + provider_config.reference_heading = location::Heading
> + {
> + config.get(dummy::Configuration::Keys::reference_heading, 127.) * location::units::Degrees
> + };
>
> return location::Provider::Ptr{new dummy::Provider{provider_config}};
> }
>
> -namespace
> -{
> -location::Provider::FeatureFlags features{"111"};
> -location::Provider::RequirementFlags requirements{"0000"};
> -}
> -
> dummy::Provider::Provider(const dummy::Configuration& config)
> - : location::Provider(features, requirements),
> + : location::Provider(
> + location::Provider::Features::position | location::Provider::Features::velocity | location::Provider::Features::heading,
> + location::Provider::Requirements::none),
> d(new Private{config})
> {
> }
> @@ -86,6 +105,9 @@
> dummy::Provider::~Provider() noexcept
> {
> stop_position_updates();
> +
> + if (d->worker.joinable())
> + d->worker.join();
> }
>
> bool dummy::Provider::matches_criteria(const location::Criteria&)
> @@ -103,26 +125,41 @@
> d->worker = std::move(std::thread([this]()
> {
> d->state.store(Private::State::started);
> - VLOG(1) << "dummy::Provider::start_position_updates: started";
> + VLOG(1) << __PRETTY_FUNCTION__ << ": started";
>
> - location::Update<location::Position> update
> + location::Update<location::Position> position_update
> {
> d->configuration.reference_position,
> location::Clock::now()
> };
>
> - timespec ts {0, d->configuration.update_period.count() * 1000 * 1000};
> + location::Update<location::Heading> heading_update
> + {
> + d->configuration.reference_heading,
> + location::Clock::now()
> + };
> +
> + location::Update<location::Velocity> velocity_update
> + {
> + d->configuration.reference_velocity,
> + location::Clock::now()
> + };
>
> while (!d->stop_requested)
> {
> - update.when = location::Clock::now();
> - deliver_position_updates(update);
> - ::nanosleep(&ts, nullptr);
> + position_update.when = location::Clock::now();
> + heading_update.when = location::Clock::now();
> + velocity_update.when = location::Clock::now();
> +
> + mutable_updates().position(position_update);
> + mutable_updates().heading(heading_update);
> + mutable_updates().velocity(velocity_update);
> +
> + std::this_thread::sleep_for(d->configuration.update_period);
> }
> +
> + d->state.store(Private::State::stopped);
> }));
> -
> - d->state.store(Private::State::stopped);
> - VLOG(1) << "dummy::Provider::start_position_updates: stopped";
> }
>
> void dummy::Provider::stop_position_updates()
> @@ -131,11 +168,11 @@
> return;
>
> d->state.store(Private::State::stopping);
> - VLOG(1) << "dummy::Provider::stop_position_updates: stopping";
> + VLOG(1) << __PRETTY_FUNCTION__ << ": stopping";
> +
> + d->stop_requested = true;
> +
> if (d->worker.joinable())
> - {
> - d->stop_requested = true;
> d->worker.join();
> - }
> }
>
>
> === modified file 'src/location_service/com/ubuntu/location/providers/dummy/provider.h'
> --- src/location_service/com/ubuntu/location/providers/dummy/provider.h 2014-02-09 18:52:25 +0000
> +++ src/location_service/com/ubuntu/location/providers/dummy/provider.h 2014-06-24 16:02:38 +0000
> @@ -31,31 +31,76 @@
> {
> namespace dummy
> {
> -
> +// Summarizes the configuration options known to the dummy provider.
> struct Configuration
> {
> - inline static const char* key_update_period()
> - {
> - return "dummy::UpdatePeriodInMs";
> - }
> -
> - inline static const char* key_reference_position_lat()
> - {
> - return "ReferenceLocationLat";
> - }
> -
> - inline static const char* key_reference_position_lon()
> - {
> - return "ReferenceLocationLon";
> - }
> -
> + // All configuration keys known to the dummy provider.
> + struct Keys
> + {
> + static constexpr const char* update_period
> + {
> + "UpdatePeriodInMs"
> + };
> + static constexpr const char* reference_position_lat
> + {
> + "ReferenceLocationLat"
> + };
> + static constexpr const char* reference_position_lon
> + {
> + "ReferenceLocationLon"
> + };
> + static constexpr const char* reference_position_alt
> + {
> + "ReferenceLocationAlt"
> + };
> + static constexpr const char* reference_horizontal_accuracy
> + {
> + "ReferenceHorizontalAccuracy"
> + };
> + static constexpr const char* reference_vertical_accuracy
> + {
> + "ReferenceVerticalAccuracy"
> + };
> + static constexpr const char* reference_velocity
> + {
> + "ReferenceVelocity"
> + };
> + static constexpr const char* reference_heading
> + {
> + "ReferenceHeading"
> + };
> + };
> +
> + // Updates are delivered every update_period milliseconds.
> std::chrono::milliseconds update_period{500};
>
> + // The reference position that is delivered in every upate cycle.
> Position reference_position
> {
> - wgs84::Latitude{9. * units::Degrees},
> - wgs84::Longitude{53. * units::Degrees},
> - wgs84::Altitude{-2. * units::Meters}
> + wgs84::Latitude
> + {
> + 9. * units::Degrees
> + },
> + wgs84::Longitude
> + {
> + 53. * units::Degrees
> + },
> + wgs84::Altitude
> + {
> + -2. * units::Meters
> + }
> + };
> +
> + // The reference velocity that is delivered in every update cycle.
> + Velocity reference_velocity
> + {
> + 9 * units::MetersPerSecond
> + };
> +
> + // The reference heading that is delivered in every update cycle.
> + Heading reference_heading
> + {
> + 127 * units::Degrees
> };
> };
>
> @@ -64,17 +109,22 @@
> public:
> // For integration with the Provider factory.
> static std::string class_name();
> + // Instantiates a new provider instance, populating the configuration object
> + // from the provided property bundle. Please see dummy::Configuration::Keys
> + // for the list of known options.
> static Provider::Ptr create_instance(const ProviderFactory::Configuration&);
>
> + // Creates a new provider instance from the given configuration.
> Provider(const Configuration& config = Configuration{});
> - Provider(const Provider&) = delete;
> - Provider& operator=(const Provider&) = delete;
> + // Cleans up all resources and stops the updates.
> ~Provider() noexcept;
>
> - // From Provider
> + // Always returns true.
> bool matches_criteria(const Criteria&);
>
> + // Starts up the updater thread and delivers position updates
> void start_position_updates();
> + // Stops the updater thread.
> void stop_position_updates();
>
> private:
>
> === modified file 'src/location_service/com/ubuntu/location/providers/geoclue/CMakeLists.txt'
> --- src/location_service/com/ubuntu/location/providers/geoclue/CMakeLists.txt 2013-05-28 14:20:45 +0000
> +++ src/location_service/com/ubuntu/location/providers/geoclue/CMakeLists.txt 2014-06-24 16:02:38 +0000
> @@ -21,4 +21,4 @@
> -DCOM_UBUNTU_LOCATION_SERVICE_PROVIDERS_GEOCLUE ${ENABLED_PROVIDER_TARGETS_DEFINITIONS}
> PARENT_SCOPE
> )
> -endif (LOCATION_SERVICE_ENABLE_GEOCLUE_PROVIDER)
> \ No newline at end of file
> +endif (LOCATION_SERVICE_ENABLE_GEOCLUE_PROVIDER)
>
> === modified file 'src/location_service/com/ubuntu/location/providers/geoclue/provider.cpp'
> --- src/location_service/com/ubuntu/location/providers/geoclue/provider.cpp 2014-01-31 11:08:33 +0000
> +++ src/location_service/com/ubuntu/location/providers/geoclue/provider.cpp 2014-06-24 16:02:38 +0000
> @@ -15,8 +15,12 @@
> *
> * Authored by: Thomas Voß <thomas.voss at canonical.com>
> */
> -#include "com/ubuntu/location/providers/geoclue/provider.h"
> -#include "com/ubuntu/location/providers/geoclue/geoclue.h"
> +#include <com/ubuntu/location/providers/geoclue/provider.h>
> +
> +#include <com/ubuntu/location/providers/geoclue/geoclue.h>
> +
> +#include <core/dbus/object.h>
> +#include <core/dbus/signal.h>
>
> #include "core/dbus/object.h"
> #include "core/dbus/signal.h"
> @@ -39,6 +43,16 @@
>
> struct culpg::Provider::Private
> {
> + typedef dbus::Signal<
> + org::freedesktop::Geoclue::Position::Signals::PositionChanged,
> + org::freedesktop::Geoclue::Position::Signals::PositionChanged::ArgumentType
> + > PositionChanged;
> +
> + typedef dbus::Signal<
> + org::freedesktop::Geoclue::Velocity::Signals::VelocityChanged,
> + org::freedesktop::Geoclue::Velocity::Signals::VelocityChanged::ArgumentType
> + > VelocityChanged;
> +
> Private(const culpg::Provider::Configuration& config)
> : bus(the_session_bus()),
> service(dbus::Service::use_service(bus, config.name)),
> @@ -64,27 +78,10 @@
> dbus::Bus::Ptr bus;
> dbus::Service::Ptr service;
> dbus::Object::Ptr object;
> - dbus::Signal<
> - org::freedesktop::Geoclue::Position::Signals::PositionChanged,
> - org::freedesktop::Geoclue::Position::Signals::PositionChanged::ArgumentType
> - >::Ptr signal_position_changed;
> - dbus::Signal<
> - org::freedesktop::Geoclue::Velocity::Signals::VelocityChanged,
> - org::freedesktop::Geoclue::Velocity::Signals::VelocityChanged::ArgumentType
> - >::Ptr signal_velocity_changed;
> -
> - typedef typename dbus::Signal<
> - org::freedesktop::Geoclue::Position::Signals::PositionChanged,
> - org::freedesktop::Geoclue::Position::Signals::PositionChanged::ArgumentType
> - >::SubscriptionToken SignalPositionChangedSubscription;
> -
> - typedef typename dbus::Signal<
> - org::freedesktop::Geoclue::Velocity::Signals::VelocityChanged,
> - org::freedesktop::Geoclue::Velocity::Signals::VelocityChanged::ArgumentType
> - >::SubscriptionToken SignalVelocityChangedSubscription;
> -
> - SignalPositionChangedSubscription position_updates_connection;
> - SignalVelocityChangedSubscription velocity_updates_connection;
> + PositionChanged::Ptr signal_position_changed;
> + VelocityChanged::Ptr signal_velocity_changed;
> + PositionChanged::SubscriptionToken position_updates_connection;
> + VelocityChanged::SubscriptionToken velocity_updates_connection;
>
> std::thread worker;
> };
> @@ -97,18 +94,6 @@
> return cul::Provider::Ptr{new culpg::Provider{pConfig}};
> }
>
> -const cul::Provider::FeatureFlags& culpg::Provider::default_feature_flags()
> -{
> - static const cul::Provider::FeatureFlags flags{"001"};
> - return flags;
> -}
> -
> -const cul::Provider::RequirementFlags& culpg::Provider::default_requirement_flags()
> -{
> - static const cul::Provider::RequirementFlags flags{"1010"};
> - return flags;
> -}
> -
> culpg::Provider::Provider(const culpg::Provider::Configuration& config)
> : com::ubuntu::location::Provider(config.features, config.requirements),
> d(new Private(config))
> @@ -118,19 +103,19 @@
> [this](const org::freedesktop::Geoclue::Position::Signals::PositionChanged::ArgumentType& arg)
> {
> org::freedesktop::Geoclue::Position::FieldFlags flags{static_cast<unsigned long>(std::get<0>(arg))};
> - cul::Update<cul::Position> update
> + cul::Position pos
> {
> - {
> - flags.test(org::freedesktop::Geoclue::Position::Field::latitude) ?
> - cul::wgs84::Latitude{std::get<2>(arg)* cul::units::Degrees} : cul::wgs84::Latitude{},
> - flags.test(org::freedesktop::Geoclue::Position::Field::longitude) ?
> - cul::wgs84::Longitude{std::get<3>(arg)* cul::units::Degrees} : cul::wgs84::Longitude{},
> - flags.test(org::freedesktop::Geoclue::Position::Field::altitude) ?
> - cul::wgs84::Altitude{std::get<4>(arg)* cul::units::Meters} : cul::wgs84::Altitude{}
> - },
> - cul::Clock::now()
> + flags.test(org::freedesktop::Geoclue::Position::Field::latitude) ?
> + cul::wgs84::Latitude{std::get<2>(arg)* cul::units::Degrees} : cul::wgs84::Latitude{},
> + flags.test(org::freedesktop::Geoclue::Position::Field::longitude) ?
> + cul::wgs84::Longitude{std::get<3>(arg)* cul::units::Degrees} : cul::wgs84::Longitude{}
> };
> - this->deliver_position_updates(update);
> +
> + if (flags.test(org::freedesktop::Geoclue::Position::Field::altitude))
> + pos.altitude = cul::wgs84::Altitude{std::get<4>(arg)* cul::units::Meters};
> +
> + cul::Update<cul::Position> update(pos);
> + this->mutable_updates().position(update);
> });
>
> d->velocity_updates_connection =
> @@ -147,7 +132,7 @@
> std::get<2>(arg) * cul::units::MetersPerSecond,
> cul::Clock::now()
> };
> - this->deliver_velocity_updates(update);
> + this->mutable_updates().velocity(update);
> }
>
> if (flags.test(org::freedesktop::Geoclue::Velocity::Field::direction))
> @@ -158,7 +143,7 @@
> cul::Clock::now()
> };
>
> - this->deliver_heading_updates(update);
> + this->mutable_updates().heading(update);
> }
> });
>
>
> === modified file 'src/location_service/com/ubuntu/location/providers/gps/CMakeLists.txt'
> --- src/location_service/com/ubuntu/location/providers/gps/CMakeLists.txt 2013-08-13 07:01:25 +0000
> +++ src/location_service/com/ubuntu/location/providers/gps/CMakeLists.txt 2014-06-24 16:02:38 +0000
> @@ -13,7 +13,17 @@
> if (UBUNTU_HARDWARE_GPS_H)
> message(STATUS "Enabling GPS location provider")
>
> - add_library(gps provider.cpp)
> + add_library(
> + gps
> +
> + android_hardware_abstraction_layer.h
> + android_hardware_abstraction_layer.cpp
> +
> + hardware_abstraction_layer.h
> + # hardware_abstraction_layer.cpp
> +
> + provider.h
> + provider.cpp)
>
> target_link_libraries(gps ubuntu_platform_hardware_api.so)
>
> @@ -28,4 +38,4 @@
> PARENT_SCOPE
> )
> endif (UBUNTU_HARDWARE_GPS_H)
> -endif (LOCATION_SERVICE_ENABLE_GPS_PROVIDER)
> \ No newline at end of file
> +endif (LOCATION_SERVICE_ENABLE_GPS_PROVIDER)
>
> === added file 'src/location_service/com/ubuntu/location/providers/gps/android_hardware_abstraction_layer.cpp'
> --- src/location_service/com/ubuntu/location/providers/gps/android_hardware_abstraction_layer.cpp 1970-01-01 00:00:00 +0000
> +++ src/location_service/com/ubuntu/location/providers/gps/android_hardware_abstraction_layer.cpp 2014-06-24 16:02:38 +0000
> @@ -0,0 +1,631 @@
> +/*
> + * Copyright © 2012-2013 Canonical Ltd.
> + *
> + * This program is free software: you can redistribute it and/or modify it
> + * under the terms of the GNU Lesser General Public License version 3,
> + * 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 Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public License
> + * along with this program. If not, see <http://www.gnu.org/licenses/>.
> + *
> + * Authored by: Thomas Voß <thomas.voss at canonical.com>
> + */
> +
> +#include "android_hardware_abstraction_layer.h"
> +
> +#include "net_cpp_gps_xtra_downloader.h"
> +#include "null_gps_xtra_downloader.h"
> +
> +#include <com/ubuntu/location/clock.h>
> +#include <com/ubuntu/location/configuration.h>
> +#include <com/ubuntu/location/logging.h>
> +
> +#include <com/ubuntu/location/connectivity/manager.h>
> +
> +#include <ubuntu/hardware/gps.h>
> +
> +#include <boost/property_tree/ini_parser.hpp>
> +
> +#include <random>
> +
> +namespace gps = com::ubuntu::location::providers::gps;
> +namespace android = com::ubuntu::location::providers::gps::android;
> +
> +namespace location = com::ubuntu::location;
> +
> +namespace
> +{
> +std::shared_ptr<android::GpsXtraDownloader> create_xtra_downloader()
> +{
> +#if defined(COM_UBUNTU_LOCATION_SERVICE_HAVE_NET_CPP)
> + return std::make_shared<android::NetCppGpsXtraDownloader>();
> +#else
> + return std::make_shared<android::NullGpsXtraDownloader>();
> +#endif // COM_UBUNTU_LOCATION_SERVICE_HAVE_NET_CPP
> +}
> +}
> +
> +/** @brief Reads a configuration from a gps.conf file in INI format. */
> +android::GpsXtraDownloader::Configuration android::GpsXtraDownloader::Configuration::from_gps_conf_ini_file(std::istream& in)
> +{
> + android::GpsXtraDownloader::Configuration result;
> +
> + location::Configuration config;
> + boost::property_tree::read_ini(in, config);
> +
> + if (config.count("XTRA_SERVER_1") > 0)
> + result.xtra_hosts.push_back(config.get<std::string>("XTRA_SERVER_1"));
> + if (config.count("XTRA_SERVER_2") > 0)
> + result.xtra_hosts.push_back(config.get<std::string>("XTRA_SERVER_2"));
> + if (config.count("XTRA_SERVER_3") > 0)
> + result.xtra_hosts.push_back(config.get<std::string>("XTRA_SERVER_3"));
> +
> + result.timeout = std::chrono::milliseconds{1500};
> +
> + return result;
> +}
> +
> +android::HardwareAbstractionLayer::SuplAssistant::SuplAssistant(android::HardwareAbstractionLayer& hal) : impl(hal)
> +{
> +}
> +
> +const core::Property<gps::HardwareAbstractionLayer::SuplAssistant::Status>& android::HardwareAbstractionLayer::SuplAssistant::status() const
> +{
> + return impl.status;
> +}
> +
> +core::Property<gps::HardwareAbstractionLayer::SuplAssistant::Status>& android::HardwareAbstractionLayer::SuplAssistant::status()
> +{
> + return impl.status;
> +}
> +
> +const core::Property<gps::HardwareAbstractionLayer::SuplAssistant::IpV4Address>& android::HardwareAbstractionLayer::SuplAssistant::server_ip() const
> +{
> + return impl.server_ip;
> +}
> +
> +core::Property<gps::HardwareAbstractionLayer::SuplAssistant::IpV4Address>& android::HardwareAbstractionLayer::SuplAssistant::server_ip()
> +{
> + return impl.server_ip;
> +}
> +
> +void android::HardwareAbstractionLayer::SuplAssistant::set_server(const std::string& host_name, std::uint16_t port)
> +{
> + // TODO(tvoss): Reenable this once the platform api HAL changes land.
> + u_hardware_gps_agps_set_server_for_type(
> + impl.hal.impl.gps_handle,
> + U_HARDWARE_GPS_AGPS_TYPE_SUPL,
> + host_name.c_str(),
> + port);
> +}
> +
> +void android::HardwareAbstractionLayer::SuplAssistant::notify_data_connection_open_via_apn(const std::string& name)
> +{
> + // TODO(tvoss): Reenable this once the platform api HAL changes land.
> + u_hardware_gps_agps_notify_connection_is_open(
> + impl.hal.impl.gps_handle,
> + name.c_str());
> +}
> +
> +void android::HardwareAbstractionLayer::SuplAssistant::notify_data_connection_closed()
> +{
> + // TODO(tvoss): Reenable this once the platform api HAL changes land.
> + u_hardware_gps_agps_notify_connection_is_closed(
> + impl.hal.impl.gps_handle);
> +}
> +
> +void android::HardwareAbstractionLayer::SuplAssistant::notify_data_connection_not_available()
> +{
> + // TODO(tvoss): Reenable this once the platform api HAL changes land.
> + u_hardware_gps_agps_notify_connection_not_available(
> + impl.hal.impl.gps_handle);
> +}
> +
> +android::HardwareAbstractionLayer::SuplAssistant::Impl::Impl(android::HardwareAbstractionLayer& hal) : hal(hal)
> +{
> +}
> +
> +void android::HardwareAbstractionLayer::on_nmea_update(int64_t timestamp, const char *nmea, int length, void *context)
> +{
> + VLOG(20) << __PRETTY_FUNCTION__ << ": "
> + << "timestamp=" << timestamp << " "
> + << "nmea=" << nmea << " "
> + << "length=" << length << " "
> + << "context=" << context;
> +}
> +
> +void android::HardwareAbstractionLayer::on_xtra_download_request(void* context)
> +{
> + VLOG(1) << __PRETTY_FUNCTION__ << ": "
> + << "context=" << context;
> +
> + auto thiz = static_cast<android::HardwareAbstractionLayer*>(context);
> +
> + auto xtra_gps_data = thiz->impl.gps_xtra_downloader->download_xtra_data(thiz->impl.gps_xtra_configuration);
> + if (not xtra_gps_data.empty())
> + u_hardware_gps_inject_xtra_data(thiz->impl.gps_handle, &xtra_gps_data.front(), xtra_gps_data.size());
> +}
> +
> +void android::HardwareAbstractionLayer::on_gps_ni_notify(UHardwareGpsNiNotification* notification, void* context)
> +{
> + VLOG(1) << __PRETTY_FUNCTION__ << ": "
> + << "notification=" << notification << " "
> + << "context=" << context;
> +}
> +
> +void android::HardwareAbstractionLayer::on_ril_request_set_id(uint32_t flags, void* context)
> +{
> + VLOG(1) << __PRETTY_FUNCTION__ << ": "
> + << "flags=" << flags << " "
> + << "context=" << context;
> +}
> +
> +void android::HardwareAbstractionLayer::on_ril_request_reference_location(uint32_t flags, void* context)
> +{
> + VLOG(1) << __PRETTY_FUNCTION__ << ": "
> + << "flags=" << flags << " "
> + << "context=" << context;
> +}
> +
> +void android::HardwareAbstractionLayer::on_location_update(UHardwareGpsLocation* location, void* context)
> +{
> + VLOG(1) << __PRETTY_FUNCTION__;
> +
> + auto thiz = static_cast<android::HardwareAbstractionLayer*>(context);
> +
> + if (location->flags & U_HARDWARE_GPS_LOCATION_HAS_LAT_LONG)
> + {
> + location::Position pos
> + {
> + location::wgs84::Latitude{location->latitude * location::units::Degrees},
> + location::wgs84::Longitude{location->longitude * location::units::Degrees}
> + };
> +
> + if (location->flags & U_HARDWARE_GPS_LOCATION_HAS_ACCURACY)
> + pos.accuracy.horizontal = location->accuracy * location::units::Meters;
> +
> + if(location->flags & U_HARDWARE_GPS_LOCATION_HAS_ALTITUDE)
> + pos.altitude = location::wgs84::Altitude{location->altitude * location::units::Meters};
> +
> + // The Android HAL does not provide us with accuracy information for
> + // altitude measurements. We just leave out that field.
> +
> + thiz->position_updates()(pos);
> +
> + VLOG(1) << pos;
> + }
> +
> + if (location->flags & U_HARDWARE_GPS_LOCATION_HAS_SPEED)
> + {
> + location::Velocity v{location->speed * location::units::MetersPerSecond};
> + thiz->velocity_updates()(v);
> + VLOG(1) << v;
> + }
> +
> + if (location->flags & U_HARDWARE_GPS_LOCATION_HAS_BEARING)
> + {
> + location::Heading h{location->bearing * location::units::Degrees};
> + thiz->heading_updates()(h);
> + VLOG(1) << h;
> + }
> +}
> +
> +void android::HardwareAbstractionLayer::on_status_update(uint16_t status, void* context)
> +{
> + VLOG(1) << __PRETTY_FUNCTION__ << ": status=" << status << ", context=" << context;
> + auto thiz = static_cast<android::HardwareAbstractionLayer*>(context);
> + thiz->chipset_status() = static_cast<gps::ChipsetStatus>(status);
> +}
> +
> +void android::HardwareAbstractionLayer::on_sv_status_update(UHardwareGpsSvStatus* sv_info, void* context)
> +{
> + VLOG(20) << __PRETTY_FUNCTION__ << ": "
> + << "count: " << sv_info->num_svs << " "
> + << "a: " << sv_info->almanac_mask << " "
> + << "e: " << sv_info->ephemeris_mask << " "
> + << "u: " << sv_info->used_in_fix_mask << " ";
> +
> + auto thiz = static_cast<android::HardwareAbstractionLayer*>(context);
> +
> + std::set<location::SpaceVehicle> svs;
> +
> + for (int i = 0; i < sv_info->num_svs; i++)
> + {
> + location::SpaceVehicle sv;
> +
> + // PRN is in the range of [1, 32], adjusting it to make sure we
> + // can use it for bitfield flag testing operations.
> + int prn = sv_info->sv_list[i].prn - 1;
> + if (prn < 0)
> + continue;
> +
> + auto shift = (1 << prn);
> +
> + sv.key.type = location::SpaceVehicle::Type::gps;
> + sv.key.id = sv_info->sv_list[i].prn;
> + sv.snr = sv_info->sv_list[i].snr;
> + sv.has_almanac_data = sv_info->almanac_mask & shift;
> + sv.has_ephimeris_data = sv_info->ephemeris_mask & shift;
> + sv.used_in_fix = sv_info->used_in_fix_mask & shift;
> + sv.azimuth = sv_info->sv_list[i].elevation * location::units::Degrees;
> + sv.elevation = sv_info->sv_list[i].azimuth * location::units::Degrees;
> +
> + svs.insert(sv);
> + }
> +
> + thiz->space_vehicle_updates()(svs);
> +}
> +
> +void android::HardwareAbstractionLayer::on_set_capabilities(uint32_t capabilities, void* context)
> +{
> + VLOG(1) << __PRETTY_FUNCTION__;
> +
> + auto thiz = static_cast<android::HardwareAbstractionLayer*>(context);
> + thiz->capabilities() = capabilities;
> +}
> +
> +void android::HardwareAbstractionLayer::on_agps_status_update(UHardwareGpsAGpsStatus* status, void* context)
> +{
> + VLOG(1) << __PRETTY_FUNCTION__;
> +
> + if (status->type == U_HARDWARE_GPS_AGPS_TYPE_C2K)
> + {
> + VLOG(1) << "\t We only support SUPL at this point in time.";
> + return;
> + }
> +
> + auto thiz = static_cast<android::HardwareAbstractionLayer*>(context);
> + thiz->impl.supl_assistant.status() = static_cast<gps::HardwareAbstractionLayer::SuplAssistant::Status>(status->status);
> + thiz->impl.supl_assistant.server_ip() = gps::HardwareAbstractionLayer::SuplAssistant::IpV4Address{status->ipaddr};
> +
> + VLOG(1) << int(thiz->impl.supl_assistant.status().get()) << ", "
> + << status->ipaddr << ", "
> + << (int)thiz->impl.supl_assistant.server_ip().get().triplets[0] << "."
> + << (int)thiz->impl.supl_assistant.server_ip().get().triplets[1] << "."
> + << (int)thiz->impl.supl_assistant.server_ip().get().triplets[2] << "."
> + << (int)thiz->impl.supl_assistant.server_ip().get().triplets[3];
> +
> + switch (status->status)
> + {
> + case U_HARDWARE_GPS_REQUEST_AGPS_DATA_CONN:
> + VLOG(1) << "U_HARDWARE_GPS_REQUEST_AGPS_DATA_CONN";
> + break;
> + case U_HARDWARE_GPS_RELEASE_AGPS_DATA_CONN:
> + VLOG(1) << "U_HARDWARE_GPS_RELEASE_AGPS_DATA_CONN";
> + break;
> + case U_HARDWARE_GPS_AGPS_DATA_CONNECTED:
> + VLOG(1) << "U_HARDWARE_GPS_AGPS_DATA_CONNECTED";
> + break;
> + case U_HARDWARE_GPS_AGPS_DATA_CONN_DONE:
> + VLOG(1) << "U_HARDWARE_GPS_AGPS_DATA_CONN_DONE";
> + break;
> + case U_HARDWARE_GPS_AGPS_DATA_CONN_FAILED:
> + VLOG(1) << "U_HARDWARE_GPS_AGPS_DATA_CONN_FAILED";
> + break;
> + }
> +}
> +
> +void android::HardwareAbstractionLayer::on_request_utc_time(void* context)
> +{
> + VLOG(1) << __PRETTY_FUNCTION__;
> +
> + auto thiz = static_cast<android::HardwareAbstractionLayer*>(context);
> +
> + if (thiz->impl.utc_time_request_handler)
> + {
> + thiz->impl.utc_time_request_handler();
> + } else
> + {
> + auto now = location::Clock::now().time_since_epoch();
> + auto thiz = static_cast<android::HardwareAbstractionLayer*>(context);
> +
> + static const int zero_uncertainty = 0;
> +
> + u_hardware_gps_inject_time(
> + thiz->impl.gps_handle,
> + now.count(),
> + now.count(),
> + zero_uncertainty);
> + }
> +}
> +
> +android::HardwareAbstractionLayer::HardwareAbstractionLayer(const android::HardwareAbstractionLayer::Configuration& config)
> + : impl(this, config)
> +{
> +}
> +
> +std::uint32_t android::HardwareAbstractionLayer::capabilities() const
> +{
> + return impl.capabilities;
> +}
> +
> +std::uint32_t& android::HardwareAbstractionLayer::capabilities()
> +{
> + return impl.capabilities;
> +}
> +
> +// From gps::HardwareAbstractionLayer
> +gps::HardwareAbstractionLayer::SuplAssistant& android::HardwareAbstractionLayer::supl_assistant()
> +{
> + return impl.supl_assistant;
> +}
> +
> +const core::Signal<location::Position>& android::HardwareAbstractionLayer::position_updates() const
> +{
> + return impl.position_updates;
> +}
> +
> +core::Signal<location::Position>& android::HardwareAbstractionLayer::position_updates()
> +{
> + return impl.position_updates;
> +}
> +
> +const core::Signal<location::Heading>& android::HardwareAbstractionLayer::heading_updates() const
> +{
> + return impl.heading_updates;
> +}
> +
> +core::Signal<location::Heading>& android::HardwareAbstractionLayer::heading_updates()
> +{
> + return impl.heading_updates;
> +}
> +
> +const core::Signal<location::Velocity>& android::HardwareAbstractionLayer::velocity_updates() const
> +{
> + return impl.velocity_updates;
> +}
> +
> +core::Signal<location::Velocity>& android::HardwareAbstractionLayer::velocity_updates()
> +{
> + return impl.velocity_updates;
> +}
> +
> +const core::Signal<std::set<location::SpaceVehicle> >& android::HardwareAbstractionLayer::space_vehicle_updates() const
> +{
> + return impl.space_vehicle_updates;
> +}
> +
> +core::Signal<std::set<location::SpaceVehicle> >& android::HardwareAbstractionLayer::space_vehicle_updates()
> +{
> + VLOG(10) << __PRETTY_FUNCTION__;
> + return impl.space_vehicle_updates;
> +}
> +
> +void android::HardwareAbstractionLayer::delete_all_aiding_data()
> +{
> + // TODO(tvoss): We should expose this flag in gps.h.
> + static const std::uint16_t delete_all = 0xFFFF;
> + u_hardware_gps_delete_aiding_data(impl.gps_handle, delete_all);
> +}
> +
> +const core::Property<gps::ChipsetStatus>& android::HardwareAbstractionLayer::chipset_status() const
> +{
> + return impl.chipset_status;
> +}
> +
> +core::Property<gps::ChipsetStatus>& android::HardwareAbstractionLayer::chipset_status()
> +{
> + return impl.chipset_status;
> +}
> +
> +bool android::HardwareAbstractionLayer::is_capable_of(gps::AssistanceMode mode) const
> +{
> + bool result = false;
> +
> + switch(mode)
> + {
> + case gps::AssistanceMode::standalone:
> + result = true;
> + break;
> + case gps::AssistanceMode::mobile_station_assisted:
> + result = capabilities() & U_HARDWARE_GPS_CAPABILITY_MSA;
> + break;
> + case gps::AssistanceMode::mobile_station_based:
> + result = capabilities() & U_HARDWARE_GPS_CAPABILITY_MSB;
> + break;
> + }
> +
> + return result;
> +}
> +
> +bool android::HardwareAbstractionLayer::is_capable_of(gps::PositionMode mode) const
> +{
> + bool result = false;
> + switch(mode)
> + {
> + case gps::PositionMode::single_shot:
> + result = capabilities() & U_HARDWARE_GPS_CAPABILITY_SINGLE_SHOT;
> + break;
> + case gps::PositionMode::periodic:
> + result = capabilities() & U_HARDWARE_GPS_CAPABILITY_SCHEDULING;
> + break;
> + }
> +
> + return result;
> +}
> +
> +bool android::HardwareAbstractionLayer::is_capable_of(gps::Capability capability) const
> +{
> + bool result = false;
> +
> + switch(capability)
> + {
> + case gps::Capability::on_demand_time_injection:
> + result = capabilities() & U_HARDWARE_GPS_CAPABILITY_ON_DEMAND_TIME;
> + break;
> + default:
> + break;
> + }
> +
> + return result;
> +}
> +
> +bool android::HardwareAbstractionLayer::start_positioning()
> +{
> + VLOG(1) << __PRETTY_FUNCTION__ << ": " << this << ", " << impl.gps_handle;
> + return u_hardware_gps_start(impl.gps_handle);
> +}
> +
> +bool android::HardwareAbstractionLayer::stop_positioning()
> +{
> + VLOG(1) << __PRETTY_FUNCTION__ << ": " << this << ", " << impl.gps_handle;
> + return u_hardware_gps_stop(impl.gps_handle);
> +}
> +
> +bool android::HardwareAbstractionLayer::set_assistance_mode(gps::AssistanceMode mode)
> +{
> + if (!is_capable_of(mode))
> + return false;
> +
> + impl.assistance_mode = mode;
> + return impl.dispatch_updated_modes_to_driver();
> +}
> +
> +bool android::HardwareAbstractionLayer::set_position_mode(gps::PositionMode mode)
> +{
> + switch(mode)
> + {
> + case gps::PositionMode::single_shot:
> + if (!(capabilities() & U_HARDWARE_GPS_CAPABILITY_SINGLE_SHOT))
> + return false;
> + break;
> + case gps::PositionMode::periodic:
> + if (!(capabilities() & U_HARDWARE_GPS_CAPABILITY_SCHEDULING))
> + return false;
> + break;
> + }
> +
> + impl.position_mode = mode;
> + return impl.dispatch_updated_modes_to_driver();
> +}
> +
> +bool android::HardwareAbstractionLayer::inject_reference_position(const location::Position& position)
> +{
> + // TODO(tvoss): We should expose the int return type of the underyling
> + // Android HAL to capture errors here.
> + UHardwareGpsLocation loc;
> + loc.size = sizeof(loc);
> + loc.flags = U_HARDWARE_GPS_LOCATION_HAS_LAT_LONG;
> + loc.latitude = position.latitude.value.value();
> + loc.longitude = position.longitude.value.value();
> +
> + if (position.accuracy.horizontal)
> + {
> + loc.flags |= U_HARDWARE_GPS_LOCATION_HAS_ACCURACY;
> + loc.accuracy = (*position.accuracy.horizontal).value();
> + }
> +
> + u_hardware_gps_inject_location(impl.gps_handle, loc);
> +
> + return true;
> +}
> +
> +bool android::HardwareAbstractionLayer::inject_reference_time(
> + const std::chrono::microseconds& reference_time,
> + const std::chrono::microseconds& sample_time)
> +{
> + if (!is_capable_of(gps::Capability::on_demand_time_injection))
> + return false;
> +
> + // TODO(tvoss): We should expose the int return type of the underyling
> + // Android HAL to capture errors here.
> + u_hardware_gps_inject_time(impl.gps_handle,
> + reference_time.count(),
> + sample_time.count(),
> + 10);
> + return true;
> +}
> +
> +android::HardwareAbstractionLayer::Impl::Impl(
> + android::HardwareAbstractionLayer* parent,
> + const android::HardwareAbstractionLayer::Configuration& configuration)
> + : capabilities(0),
> + assistance_mode(gps::AssistanceMode::mobile_station_based),
> + position_mode(gps::PositionMode::periodic),
> + supl_assistant(*parent),
> + gps_xtra_configuration(configuration.gps_xtra.configuration),
> + gps_xtra_downloader(configuration.gps_xtra.downloader)
> +{
> + ::memset(&gps_params, 0, sizeof(gps_params));
> +
> + gps_params.location_cb = HardwareAbstractionLayer::on_location_update;
> + gps_params.status_cb = HardwareAbstractionLayer::on_status_update;
> + gps_params.sv_status_cb = HardwareAbstractionLayer::on_sv_status_update;
> + gps_params.set_capabilities_cb = HardwareAbstractionLayer::on_set_capabilities;
> + gps_params.request_utc_time_cb = HardwareAbstractionLayer::on_request_utc_time;
> + gps_params.agps_status_cb = HardwareAbstractionLayer::on_agps_status_update;
> +
> + gps_params.nmea_cb = HardwareAbstractionLayer::on_nmea_update;
> + gps_params.xtra_download_request_cb = HardwareAbstractionLayer::on_xtra_download_request;
> + gps_params.gps_ni_notify_cb = HardwareAbstractionLayer::on_gps_ni_notify;
> + gps_params.request_setid_cb = HardwareAbstractionLayer::on_ril_request_set_id;
> + gps_params.request_refloc_cb = HardwareAbstractionLayer::on_ril_request_reference_location;
> +
> + gps_params.context = parent;
> +
> + gps_handle = u_hardware_gps_new(std::addressof(gps_params));
> +
> + dispatch_updated_modes_to_driver();
> +}
> +
> +bool android::HardwareAbstractionLayer::Impl::dispatch_updated_modes_to_driver()
> +{
> + static const std::map<gps::AssistanceMode, std::uint32_t> assistance_mode_lut =
> + {
> + {gps::AssistanceMode::mobile_station_assisted, U_HARDWARE_GPS_POSITION_MODE_MS_ASSISTED},
> + {gps::AssistanceMode::mobile_station_based, U_HARDWARE_GPS_POSITION_MODE_MS_BASED},
> + {gps::AssistanceMode::standalone, U_HARDWARE_GPS_POSITION_MODE_STANDALONE}
> + };
> +
> + static const std::map<gps::PositionMode, std::uint32_t> position_mode_lut =
> + {
> + {gps::PositionMode::periodic, U_HARDWARE_GPS_POSITION_RECURRENCE_PERIODIC},
> + {gps::PositionMode::single_shot, U_HARDWARE_GPS_POSITION_RECURRENCE_SINGLE}
> + };
> +
> + auto am = assistance_mode_lut.at(assistance_mode);
> + auto pm = position_mode_lut.at(position_mode);
> +
> + static const uint32_t preferred_accuracy_in_meters = 0;
> + static const uint32_t preferred_ttff_in_ms = 0;
> + static const std::chrono::milliseconds min_interval{500};
> +
> + return u_hardware_gps_set_position_mode(
> + gps_handle,
> + am,
> + pm,
> + min_interval.count(),
> + preferred_accuracy_in_meters,
> + preferred_ttff_in_ms);
> +}
> +
> +namespace
> +{
> +std::ifstream etc_gps_conf{"/etc/gps.conf"};
> +}
> +
> +std::shared_ptr<gps::HardwareAbstractionLayer> gps::HardwareAbstractionLayer::create_default_instance()
> +{
> + static android::HardwareAbstractionLayer::Configuration config
> + {
> + {
> + create_xtra_downloader(),
> + android::GpsXtraDownloader::Configuration::from_gps_conf_ini_file(etc_gps_conf)
> + }
> + };
> +
> + static std::shared_ptr<gps::HardwareAbstractionLayer> instance
> + {
> + new android::HardwareAbstractionLayer
> + {
> + config
> + }
> + };
> +
> + return instance;
> +}
>
> === added file 'src/location_service/com/ubuntu/location/providers/gps/android_hardware_abstraction_layer.h'
> --- src/location_service/com/ubuntu/location/providers/gps/android_hardware_abstraction_layer.h 1970-01-01 00:00:00 +0000
> +++ src/location_service/com/ubuntu/location/providers/gps/android_hardware_abstraction_layer.h 2014-06-24 16:02:38 +0000
> @@ -0,0 +1,278 @@
> +/*
> + * Copyright © 2012-2013 Canonical Ltd.
> + *
> + * This program is free software: you can redistribute it and/or modify it
> + * under the terms of the GNU Lesser General Public License version 3,
> + * 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 Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public License
> + * along with this program. If not, see <http://www.gnu.org/licenses/>.
> + *
> + * Authored by: Thomas Voß <thomas.voss at canonical.com>
> + */
> +#ifndef LOCATION_SERVICE_COM_UBUNTU_LOCATION_PROVIDERS_GPS_ANDROID_HARDWARE_ABSTRACTION_LAYER_H_
> +#define LOCATION_SERVICE_COM_UBUNTU_LOCATION_PROVIDERS_GPS_ANDROID_HARDWARE_ABSTRACTION_LAYER_H_
> +
> +#include <com/ubuntu/location/providers/gps/hardware_abstraction_layer.h>
> +
> +#include <ubuntu/hardware/gps.h>
> +
> +namespace com { namespace ubuntu { namespace location { namespace providers { namespace gps
> +{
> +namespace android
> +{
> +
> +/** @brief Models a downloader for GPS xtra data from HTTP sources. */
> +struct GpsXtraDownloader
> +{
> + static constexpr const char* x_wap_profile_key
> + {
> + "x-wap-profile"
> + };
> +
> + static constexpr const char* x_wap_profile_value
> + {
> + "http://www.openmobilealliance.org/tech/profiles/UAPROF/ccppschema-20021212#"
> + };
> +
> + /** @brief Configuration options specific to a GpsXtraDownloader implementation. */
> + struct Configuration
> + {
> + /** @brief Reads a configuration from a gps.conf file in INI format. */
> + static Configuration from_gps_conf_ini_file(std::istream& in);
> +
> + /** @brief Timeout on gps xtra download operations. */
> + std::chrono::milliseconds timeout
> + {
> + 1500
> + };
> +
> + /** Set of hosts serving GPS xtra data. */
> + std::vector<std::string> xtra_hosts
> + {
> + };
> + };
> +
> + GpsXtraDownloader() = default;
> + virtual ~GpsXtraDownloader() = default;
> +
> + /** brief Downloads a GPS xtra data package from one of the servers given in config. */
> + virtual std::vector<char> download_xtra_data(const Configuration& config) = 0;
> +};
> +
> +struct HardwareAbstractionLayer : public gps::HardwareAbstractionLayer
> +{
> + /** @brief Implements gps::HardwareAbstractionLayer::SuplAssistant interface for the android gps HAL. */
> + struct SuplAssistant : public gps::HardwareAbstractionLayer::SuplAssistant
> + {
> + /** @brief Bootstraps access to the Android GPS HAL assistance features. */
> + SuplAssistant(android::HardwareAbstractionLayer& hal);
> + /** @brief Getable/observable access to the status of the assistant instance. */
> + const core::Property<Status>& status() const override;
> + /** @brief Getable/setable/observable access to the status of the assistant instance. */
> + core::Property<Status>& status();
> + /** @brief Getable/observable access to the ip the assistance instance uses. */
> + const core::Property<IpV4Address>& server_ip() const override;
> + /** @brief Getable/setable/observable access to the ip the assistance instance uses. */
> + core::Property<IpV4Address>& server_ip();
> + /** @brief Informs the assistant instance about the SUPL server it should talk to. */
> + void set_server(const std::string& host_name, std::uint16_t port) override;
> + /** @brief Notifies the assistant instance that a data connection is open now. */
> + void notify_data_connection_open_via_apn(const std::string& name) override;
> + /** @brief Notifies the assistant instance the the data connection is closed now. */
> + void notify_data_connection_closed() override;
> + /** @brief Notifies the assistant instance that a data connection is not available right now. */
> + void notify_data_connection_not_available() override;
> +
> + struct Impl
> + {
> + Impl(android::HardwareAbstractionLayer& hal);
> +
> + // The parent HardwareAbstractionLayer instance.
> + android::HardwareAbstractionLayer& hal;
> + // The status of the assisted GPS HAL.
> + core::Property<gps::HardwareAbstractionLayer::SuplAssistant::Status> status;
> + // The SUPL server address as reported by the Android GPS HAL.
> + core::Property<gps::HardwareAbstractionLayer::SuplAssistant::IpV4Address> server_ip;
> + } impl;
> + };
> +
> + /**
> + * @brief Called whenever new NMEA data is available from the chipset.
> + * @param [in] timestamp Indicates the time when the NMEA sentence was generated in the chipset.
> + * @param [in] nmea NMEA sentence.
> + * @param [in] length Length of the NMEA sentence.
> + * @param [in] context The app-specific callback context.
> + */
> + static void on_nmea_update(int64_t timestamp, const char *nmea, int length, void *context);
> +
> + /**
> + * @brief Called whenever the chipset requests GPS xtra data.
> + * @param context The app-specific callback context.
> + */
> + static void on_xtra_download_request(void* context);
> +
> + /**
> + * @brief Called whenever a new network-initiated message is available.
> + * @param [in] notification The notification object.
> + * @param [in] context The app-specific callback context.
> + */
> + static void on_gps_ni_notify(UHardwareGpsNiNotification* notification, void* context);
> +
> + /**
> + * @brief Called by the chipset for RIL-specific ID generation.
> + * @param [in] flags The flags for the request
> + * @param [in] context The app-specific callback context.
> + */
> + static void on_ril_request_set_id(uint32_t flags, void* context);
> +
> + /**
> + * @brief Called whenever the GPS chipsets requires cell information from RIL.
> + * @param [in] flags The flags for the request.
> + * @param [in] context The app-specific callback context.
> + */
> + static void on_ril_request_reference_location(uint32_t flags, void* context);
> +
> + /**
> + * @brief Called whenever the GPS chipsets has got a location update available.
> + * @param [in] location The new location.
> + * @param [in] context The app-specific callback context.
> + */
> + static void on_location_update(UHardwareGpsLocation* location, void* context);
> +
> + /**
> + * @brief Called whenever the GPS chipset status changes.
> + * @param [in] status The new status of the GPS chipset.
> + * @param [in] context The app-specific callback context.
> + */
> + static void on_status_update(uint16_t status, void* context);
> +
> + /**
> + * @brief Called whenever satellite visibility changes.
> + * @param [in] sv_info The new satellite visibility info.
> + * @param [in] context The app-specific callback context.
> + */
> + static void on_sv_status_update(UHardwareGpsSvStatus* sv_info, void* context);
> +
> + /**
> + * @brief Called to report the GPS chipset's capabilities
> + * @param [in] capabilities Bitfield of capability flags.
> + * @param [in] context The app-specific callback context.
> + */
> + static void on_set_capabilities(uint32_t capabilities, void* context);
> +
> + /**
> + * @brief Called to report assisted gps status updates.
> + * @param [in] status The new assisted gps status.
> + * @param [in] context The app-specific callback context.
> + */
> + static void on_agps_status_update(UHardwareGpsAGpsStatus* status, void* context);
> +
> + /**
> + * @brief Called whenever the GPS chipsets requires a reference time.
> + * @param [in] context The app-specific callback context.
> + */
> + static void on_request_utc_time(void* context);
> +
> + struct Configuration
> + {
> + struct
> + {
> + std::shared_ptr<GpsXtraDownloader> downloader;
> + GpsXtraDownloader::Configuration configuration;
> + } gps_xtra;
> + };
> +
> + HardwareAbstractionLayer(const Configuration& configuration);
> +
> + /** @brief Reports the raw android capabilities. */
> + std::uint32_t capabilities() const;
> +
> + /** @brief Reports the raw android capabilities. */
> + std::uint32_t& capabilities();
> +
> + // From gps::HardwareAbstractionLayer
> + gps::HardwareAbstractionLayer::SuplAssistant& supl_assistant() override;
> +
> + const core::Signal<location::Position>& position_updates() const override;
> + core::Signal<location::Position>& position_updates();
> +
> + const core::Signal<location::Heading>& heading_updates() const override;
> + core::Signal<location::Heading>& heading_updates();
> +
> + const core::Signal<location::Velocity>& velocity_updates() const override;
> + core::Signal<location::Velocity>& velocity_updates();
> +
> + const core::Signal<std::set<location::SpaceVehicle> >& space_vehicle_updates() const override;
> + core::Signal<std::set<location::SpaceVehicle> >& space_vehicle_updates();
> +
> + void delete_all_aiding_data() override;
> +
> + const core::Property<gps::ChipsetStatus>& chipset_status() const override;
> + core::Property<gps::ChipsetStatus>& chipset_status();
> +
> + bool is_capable_of(gps::AssistanceMode mode) const override;
> + bool is_capable_of(gps::PositionMode mode) const override;
> + bool is_capable_of(gps::Capability capability) const override;
> +
> + bool start_positioning() override;
> + bool stop_positioning() override;
> +
> + bool set_assistance_mode(gps::AssistanceMode mode) override;
> + bool set_position_mode(gps::PositionMode mode) override;
> +
> + bool inject_reference_position(const location::Position& position) override;
> + bool inject_reference_time(const std::chrono::microseconds& reference_time,
> + const std::chrono::microseconds& sample_time) override;
> + struct Impl
> + {
> + // Bootstraps access to the GPS chipset, wiring up all callbacks.
> + Impl(android::HardwareAbstractionLayer* parent, const android::HardwareAbstractionLayer::Configuration& configuration);
> +
> + // Adjusts the assistance and positioning mode in one go, returning false in case of issues.
> + bool dispatch_updated_modes_to_driver();
> +
> + // The parameter bundle for the hardware GPS instance.
> + UHardwareGpsParams gps_params;
> + // The actual handle to the hardware GPS instance.
> + UHardwareGps gps_handle;
> +
> + // Capabilities bitfield for the hardware GPS instance.
> + std::uint32_t capabilities;
> + // The current assistance mode.
> + gps::AssistanceMode assistance_mode;
> + // The current position mode.
> + gps::PositionMode position_mode;
> +
> + // An implementation of the gps::HardwareAbstractionLayer::SuplAssistant interface.
> + SuplAssistant supl_assistant;
> +
> + // Callback for handling utc time requests.
> + gps::HardwareAbstractionLayer::UtcTimeRequestHandler utc_time_request_handler;
> +
> + // Emitted whenever the set of visible space vehicles changes.
> + core::Signal<std::set<location::SpaceVehicle>> space_vehicle_updates;
> + // Emitted whenever the position as reported by the GPS chipset changes.
> + core::Signal<location::Position> position_updates;
> + // Emitted whenever the heading as reported by the GPS chipset changes.
> + core::Signal<location::Heading> heading_updates;
> + // Emitted whenever the velocity as reported by the GPS chipset changes.
> + core::Signal<location::Velocity> velocity_updates;
> + // Emitted whenever the chipset status changes.
> + core::Property<gps::ChipsetStatus> chipset_status;
> +
> + // GPS Xtra configuration.
> + GpsXtraDownloader::Configuration gps_xtra_configuration;
> + // GPS xtra downloader implementation.
> + std::shared_ptr<GpsXtraDownloader> gps_xtra_downloader;
> + } impl;
> +};
> +}
> +}}}}}
> +
> +#endif // LOCATION_SERVICE_COM_UBUNTU_LOCATION_PROVIDERS_GPS_ANDROID_HARDWARE_ABSTRACTION_LAYER_H_
>
> === added file 'src/location_service/com/ubuntu/location/providers/gps/hardware_abstraction_layer.h'
> --- src/location_service/com/ubuntu/location/providers/gps/hardware_abstraction_layer.h 1970-01-01 00:00:00 +0000
> +++ src/location_service/com/ubuntu/location/providers/gps/hardware_abstraction_layer.h 2014-06-24 16:02:38 +0000
> @@ -0,0 +1,323 @@
> +/*
> + * Copyright © 2012-2013 Canonical Ltd.
> + *
> + * This program is free software: you can redistribute it and/or modify it
> + * under the terms of the GNU Lesser General Public License version 3,
> + * 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 Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public License
> + * along with this program. If not, see <http://www.gnu.org/licenses/>.
> + *
> + * Authored by: Thomas Voß <thomas.voss at canonical.com>
> + */
> +#ifndef LOCATION_SERVICE_COM_UBUNTU_LOCATION_PROVIDERS_GPS_HARDWARE_ABSTRACTION_LAYER_H_
> +#define LOCATION_SERVICE_COM_UBUNTU_LOCATION_PROVIDERS_GPS_HARDWARE_ABSTRACTION_LAYER_H_
> +
> +#include <com/ubuntu/location/heading.h>
> +#include <com/ubuntu/location/position.h>
> +#include <com/ubuntu/location/space_vehicle.h>
> +#include <com/ubuntu/location/velocity.h>
> +
> +#include <core/property.h>
> +
> +#include <chrono>
> +#include <iosfwd>
> +#include <memory>
> +#include <cstdint>
> +
> +namespace com
> +{
> +namespace ubuntu
> +{
> +namespace location
> +{
> +namespace providers
> +{
> +namespace gps
> +{
> +/**
> + * @brief The ChipsetStatus enum summarizes the gps chipset status.
> + */
> +enum class ChipsetStatus
> +{
> + /** Status is unknown. */
> + unknown = 0,
> + /** Chipset has begun navigating. */
> + session_begin = 1,
> + /** Chipset has stopped navigating. */
> + session_end = 2,
> + /** Chipset is powered on. */
> + engine_on = 3,
> + /** Chipset is powered off. */
> + engine_off = 4
> +};
> +
> +/**
> + * @brief The Capabilities enum summarizes chipset capabilities.
> + */
> +enum class Capability
> +{
> + /** The GPS chipset supports on-demand time injection. */
> + on_demand_time_injection
> +};
> +
> +/**
> + * @brief The AssistanceMode enum summarizes the different assisted gps modes that
> + * the provider supports.
> + */
> +enum class AssistanceMode
> +{
> + /** Provider runs on its own without any external assistance. */
> + standalone,
> +
> + /** In MSB mode A-GPS operation, the A-GPS device receives ephemeris,
> + * reference location, reference time and other optional assistance data from the A-GPS server.
> + * With the help of the above data, the A-GPS device receives signals from
> + * the visible satellites and calculates the position.
> + */
> + mobile_station_based,
> +
> + /** In MSA mode A-GPS operation, the A-GPS capable device receives acquisition assistance,
> + * reference time and other optional assistance data from a mobile service provider.
> + * The mobile service provider continuously logs GPS information (mainly the almanac) from
> + * the GPS satellites using a A-GPS server in its system. With the help of the
> + * above data (the data received from the mobile device and the data already present in A-GPS server)
> + * the A-GPS server calculates the position and sends it back to the A-GPS device.
> + */
> + mobile_station_assisted
> +};
> +
> +enum class PositionMode
> +{
> + /** Continually provide position updates. */
> + periodic,
> +
> + /** Obtain a single position estimate. */
> + single_shot
> +};
> +
> +class HardwareAbstractionLayer
> +{
> +public:
> +
> + class SuplAssistant
> + {
> + public:
> + /**
> + * @brief Simple union for reinterpreting an IP address given as a 32bit unsigned integer into the 4 triplets.
> + */
> + union IpV4Address
> + {
> + IpV4Address(std::uint32_t ip = 0) : ip(ip)
> + {
> + }
> +
> + inline bool operator==(const IpV4Address& rhs) const
> + {
> + return ip == rhs.ip;
> + }
> +
> + inline bool operator!=(const IpV4Address& rhs) const
> + {
> + return ip != rhs.ip;
> + }
> +
> + std::uint32_t ip;
> + std::uint8_t triplets[4];
> + };
> +
> + /**
> + * @brief Current status of a SuplAssistant instance.
> + */
> + enum class Status
> + {
> + /** The assistant requires a data connection. */
> + request_data_connection = 1,
> + /** The assistant no longer requires a data connection. */
> + release_data_connection = 2,
> + /** The data connection has been initiated. */
> + data_connection_initiated = 3,
> + /** The data transfer has been successfully completed. */
> + data_connection_completed = 4,
> + /** The data transfer failed. */
> + data_connection_failed = 5
> + };
> +
> + virtual ~SuplAssistant() = default;
> + SuplAssistant(const SuplAssistant&) = delete;
> +
> + SuplAssistant& operator=(const SuplAssistant&) = delete;
> + bool operator==(const SuplAssistant&) = delete;
> +
> + /**
> + * @brief Getable/observable access to the status of the assistant instance.
> + */
> + virtual const core::Property<Status>& status() const = 0;
> +
> + /**
> + * @brief Getable/observable access to the ip the assistance instance uses.
> + */
> + virtual const core::Property<IpV4Address>& server_ip() const = 0;
> +
> + /**
> + * @brief set_server informs the assistant instance about the SUPL server it should talk to.
> + * @param host_name The host name of the SUPL server.
> + * @param port The port of the SUPL server.
> + */
> + virtual void set_server(const std::string& host_name, std::uint16_t port) = 0;
> +
> + /**
> + * @brief Notifies the assistant instance that a data connection is open now.
> + */
> + virtual void notify_data_connection_open_via_apn(const std::string& name) = 0;
> +
> + /**
> + * @brief Notifies the assistant instance the the data connection is closed now.
> + */
> + virtual void notify_data_connection_closed() = 0;
> +
> + /**
> + * @brief Notifies the assistant instance that a data connection is not available right now.
> + */
> + virtual void notify_data_connection_not_available() = 0;
> +
> + protected:
> + SuplAssistant() = default;
> + };
> +
> + /**
> + * @brief UtcTimeRequestHandler handles chipset requests for time synchronization
> + *
> + * An implementation is expected to provide the new reference time in
> + * milliseconds since 01.01.1970 to the chipset via a call to inject reference time.
> + */
> + typedef std::function<void()> UtcTimeRequestHandler;
> +
> + /**
> + * @brief Returns the default instance for accessing the actual HW.
> + */
> + static std::shared_ptr<HardwareAbstractionLayer> create_default_instance();
> +
> + virtual ~HardwareAbstractionLayer() = default;
> +
> + HardwareAbstractionLayer(const HardwareAbstractionLayer&) = delete;
> + HardwareAbstractionLayer& operator=(const HardwareAbstractionLayer&) = delete;
> + bool operator==(const HardwareAbstractionLayer&) const = delete;
> +
> + /**
> + * @brief supl_assistant provides access to the SuplAssistant instance that the HAL is using.
> + * @return A valid instance if the HAL uses assisted GPS or a nullptr if not.
> + */
> + virtual SuplAssistant& supl_assistant() = 0;
> +
> + /**
> + * @brief Signal for delivery of position updates.
> + */
> + virtual const core::Signal<Position>& position_updates() const = 0;
> +
> + /**
> + * @brief Signal for delivery of heading updates.
> + */
> + virtual const core::Signal<Heading>& heading_updates() const = 0;
> +
> + /**
> + * @brief Signal for delivery of velocity updates.
> + */
> + virtual const core::Signal<Velocity>& velocity_updates() const = 0;
> +
> + /**
> + * @brief Signal for delivery of satellite visibility updates.
> + */
> + virtual const core::Signal<std::set<SpaceVehicle>>& space_vehicle_updates() const = 0;
> +
> + /**
> + * @brief Requests the chipset to drop all aiding data, including almanac, ephimeris and ionospheric data.
> + *
> + * Calling this function results in a cold start the next time the positioning is initiated.
> + *
> + */
> + virtual void delete_all_aiding_data() = 0;
> +
> + /**
> + * @brief Observable/getable property modelling the status of the chipset.
> + * @return A non-mutable reference to the property.
> + */
> + virtual const core::Property<ChipsetStatus>& chipset_status() const = 0;
> +
> + /**
> + * @brief Checks whether the chipset and driver support the specified assistance mode.
> + * @param mode The assistance mode to check for.
> + * @return true iff chipset and driver support the specified mode.
> + */
> + virtual bool is_capable_of(AssistanceMode mode) const = 0;
> +
> + /**
> + * @brief Checks whether the chipset and driver support the specified position mode.
> + * @param mode The position mode to check for.
> + * @return true iff chipset and driver support the specified mode.
> + */
> + virtual bool is_capable_of(PositionMode mode) const = 0;
> +
> + /**
> + * @brief Checks whether the chipset and driver support the specified capability.
> + * @param capability The capability to check for.
> + * @return true iff chipset and driver support the specified capability.
> + */
> + virtual bool is_capable_of(Capability capability) const = 0;
> +
> + /**
> + * @brief Starts the actual positioning process of the underlying HW.
> + * @return true iff starting the positioning engine was successful.
> + */
> + virtual bool start_positioning() = 0;
> +
> + /**
> + * @brief Stops the actual positioning process of the underlying HW.
> + * @return true iff stopping the positioning engine was successful.
> + */
> + virtual bool stop_positioning() = 0;
> +
> + /**
> + * @brief Dispatches the requested mode change to the driver/hw.
> + * @param mode The new assistance mode.
> + * @return true iff the mode change was carried out successfully.
> + */
> + virtual bool set_assistance_mode(AssistanceMode mode) = 0;
> +
> + /**
> + * @brief Dispatches the requested mode change to the driver/hw.
> + * @param mode The new position mode.
> + * @return true iff the mode change was carried out successfully.
> + */
> + virtual bool set_position_mode(PositionMode mode) = 0;
> +
> + /**
> + * @brief Injects a reference position to the underlying gps driver/chipset.
> + * @return true iff the injection was successful, false otherwise.
> + */
> + virtual bool inject_reference_position(const Position& position) = 0;
> +
> + /**
> + * @brief Injects a new reference time to the underlying gps driver/chipset.
> + * @param reference_time The new reference time.
> + * @param sample_time When the reference time was sampled.
> + * @return true iff the injection was successful, false otherwise.
> + */
> + virtual bool inject_reference_time(const std::chrono::microseconds& reference_time,
> + const std::chrono::microseconds& sample_time) = 0;
> +
> +protected:
> + HardwareAbstractionLayer() = default;
> +};
> +}
> +}
> +}
> +}
> +}
> +
> +#endif // LOCATION_SERVICE_COM_UBUNTU_LOCATION_PROVIDERS_GPS_HARDWARE_ABSTRACTION_LAYER_H_
>
> === added file 'src/location_service/com/ubuntu/location/providers/gps/net_cpp_gps_xtra_downloader.cpp'
> === added file 'src/location_service/com/ubuntu/location/providers/gps/net_cpp_gps_xtra_downloader.h'
> --- src/location_service/com/ubuntu/location/providers/gps/net_cpp_gps_xtra_downloader.h 1970-01-01 00:00:00 +0000
> +++ src/location_service/com/ubuntu/location/providers/gps/net_cpp_gps_xtra_downloader.h 2014-06-24 16:02:38 +0000
> @@ -0,0 +1,78 @@
> +/*
> + * Copyright © 2012-2013 Canonical Ltd.
> + *
> + * This program is free software: you can redistribute it and/or modify it
> + * under the terms of the GNU Lesser General Public License version 3,
> + * 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 Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public License
> + * along with this program. If not, see <http://www.gnu.org/licenses/>.
> + *
> + * Authored by: Thomas Voß <thomas.voss at canonical.com>
> + */
> +#ifndef LOCATION_SERVICE_COM_UBUNTU_LOCATION_PROVIDERS_NET_CPP_GPS_XTRA_DOWNLOADER_H_
> +#define LOCATION_SERVICE_COM_UBUNTU_LOCATION_PROVIDERS_NET_CPP_GPS_XTRA_DOWNLOADER_H_
> +
> +#include "android_hardware_abstraction_layer.h"
> +
> +#include <core/net/http/client.h>
> +#include <core/net/http/request.h>
> +#include <core/net/http/response.h>
> +
> +namespace com { namespace ubuntu { namespace location { namespace providers { namespace gps { namespace android {
> +struct NetCppGpsXtraDownloader : public GpsXtraDownloader
> +{
> + NetCppGpsXtraDownloader() : http_client{core::net::http::make_client()}
> + {
> + }
> +
> + /** @brief Executes the actual download, throws if no xtra servers are given in the config. */
> + virtual std::vector<char> download_xtra_data(const Configuration& config) override
> + {
> + if (config.xtra_hosts.empty()) throw std::runtime_error
> + {
> + "Missing xtra hosts."
> + };
> +
> + std::uniform_int_distribution<std::size_t> dist{0, config.xtra_hosts.size() - 1};
> +
> + auto host = config.xtra_hosts.at(dist(dre));
> +
> + auto rc = core::net::http::Request::Configuration::from_uri_as_string(host);
> +
> + rc.header.add("Accept", "*/*");
> + rc.header.add("Accept", "application/vnd.wap.mms-message");
> + rc.header.add("Accept", "application/vnd.wap.sic");
> + rc.header.add(x_wap_profile_key, x_wap_profile_value);
> +
> + auto request = http_client->get(rc);
> + request->set_timeout(config.timeout);
> +
> + auto response = request->execute([](const core::net::http::Request::Progress&)
> + {
> + return core::net::http::Request::Progress::Next::continue_operation;
> + });
> +
> + if (response.status != core::net::http::Status::ok)
> + {
> + std::stringstream ss{"Request for xtra data on "};
> + ss << host << " did not succeed: " << response.status;
> + throw std::runtime_error{ss.str()};
> + }
> +
> + return std::vector<char>(response.body.begin(), response.body.end());
> + }
> +
> + // Client instance to talk to xtra servers.
> + std::shared_ptr<core::net::http::Client> http_client;
> + // Random number generator for load balancing purposes.
> + std::default_random_engine dre;
> +};
> +}}}}}}
> +
> +#endif // LOCATION_SERVICE_COM_UBUNTU_LOCATION_PROVIDERS_NET_CPP_GPS_XTRA_DOWNLOADER_H_
>
> === added file 'src/location_service/com/ubuntu/location/providers/gps/null_gps_xtra_downloader.h'
> --- src/location_service/com/ubuntu/location/providers/gps/null_gps_xtra_downloader.h 1970-01-01 00:00:00 +0000
> +++ src/location_service/com/ubuntu/location/providers/gps/null_gps_xtra_downloader.h 2014-06-24 16:02:38 +0000
> @@ -0,0 +1,39 @@
> +/*
> + * Copyright © 2012-2013 Canonical Ltd.
> + *
> + * This program is free software: you can redistribute it and/or modify it
> + * under the terms of the GNU Lesser General Public License version 3,
> + * 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 Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public License
> + * along with this program. If not, see <http://www.gnu.org/licenses/>.
> + *
> + * Authored by: Thomas Voß <thomas.voss at canonical.com>
> + */
> +#ifndef LOCATION_SERVICE_COM_UBUNTU_LOCATION_PROVIDERS_NULL_GPS_XTRA_DOWNLOADER_H_
> +#define LOCATION_SERVICE_COM_UBUNTU_LOCATION_PROVIDERS_NULL_GPS_XTRA_DOWNLOADER_H_
> +
> +#include "android_hardware_abstraction_layer.h"
> +
> +#include <com/ubuntu/location/logging.h>
> +
> +namespace com { namespace ubuntu { namespace location { namespace providers { namespace gps { namespace android {
> +/** @brief Implements a GPS xtra downloader that just logs download attempts. */
> +struct NullGpsXtraDownloader : public android::GpsXtraDownloader
> +{
> + std::vector<char> download_xtra_data(const Configuration& config) override
> + {
> + VLOG(10) << __PRETTY_FUNCTION__ << "\n"
> + << " Nr. xtra hosts: " << config.xtra_hosts.size();
> +
> + return std::vector<char>{};
> + }
> +};
> +}}}}}}
> +
> +#endif // LOCATION_SERVICE_COM_UBUNTU_LOCATION_PROVIDERS_NULL_GPS_XTRA_DOWNLOADER_H_
>
> === modified file 'src/location_service/com/ubuntu/location/providers/gps/provider.cpp'
> --- src/location_service/com/ubuntu/location/providers/gps/provider.cpp 2013-10-17 10:27:43 +0000
> +++ src/location_service/com/ubuntu/location/providers/gps/provider.cpp 2014-06-24 16:02:38 +0000
> @@ -15,129 +15,24 @@
> *
> * Authored by: Thomas Voß <thomas.voss at canonical.com>
> */
> -#include "com/ubuntu/location/providers/gps/provider.h"
> -
> -#include "com/ubuntu/location/logging.h"
> +
> +#include "provider.h"
> +
> +#include "hardware_abstraction_layer.h"
> +
> +#include <com/ubuntu/location/logging.h>
> +#include <com/ubuntu/location/connectivity/manager.h>
>
> #include <ubuntu/hardware/gps.h>
>
> namespace cul = com::ubuntu::location;
> namespace culg = com::ubuntu::location::providers::gps;
>
> -namespace
> -{
> -static const std::map<uint16_t, std::string> status_lut =
> -{
> - {U_HARDWARE_GPS_STATUS_NONE, "U_HARDWARE_GPS_STATUS_NONE"},
> - {U_HARDWARE_GPS_STATUS_SESSION_BEGIN, "U_HARDWARE_GPS_STATUS_SESSION_BEGIN"},
> - {U_HARDWARE_GPS_STATUS_SESSION_END, "U_HARDWARE_GPS_STATUS_SESSION_END"},
> - {U_HARDWARE_GPS_STATUS_ENGINE_ON, "U_HARDWARE_GPS_STATUS_ENGINE_ON"},
> - {U_HARDWARE_GPS_STATUS_ENGINE_OFF, "U_HARDWARE_GPS_STATUS_ENGINE_OFF"}
> -};
> -}
> -
> struct culg::Provider::Private
> {
> -
> -static void on_location_update(UHardwareGpsLocation* location, void* context)
> -{
> - auto thiz = static_cast<culg::Provider*>(context);
> -
> - if (location->flags & U_HARDWARE_GPS_LOCATION_HAS_LAT_LONG)
> - {
> - VLOG(1) << "location->flags & U_HARDWARE_GPS_LOCATION_HAS_LAT_LONG";
> -
> - cul::Position pos;
> - pos.latitude(cul::wgs84::Latitude{location->latitude * cul::units::Degrees});
> - pos.longitude(cul::wgs84::Longitude{location->longitude * cul::units::Degrees});
> - if(location->flags & U_HARDWARE_GPS_LOCATION_HAS_ALTITUDE)
> - pos.altitude(cul::wgs84::Altitude{location->altitude * cul::units::Meters});
> -
> - thiz->deliver_position_updates(cul::Update<cul::Position>{pos, cul::Clock::now()});
> - }
> -
> - if (location->flags & U_HARDWARE_GPS_LOCATION_HAS_SPEED)
> - {
> - VLOG(1) << "location->flags & U_HARDWARE_GPS_LOCATION_HAS_SPEED";
> -
> - cul::Velocity v{location->speed * cul::units::MetersPerSecond};
> - thiz->deliver_velocity_updates(cul::Update<cul::Velocity>{v, cul::Clock::now()});
> - }
> -
> - if (location->flags & U_HARDWARE_GPS_LOCATION_HAS_BEARING)
> - {
> - VLOG(1) << "location->flags & U_HARDWARE_GPS_LOCATION_HAS_BEARING";
> -
> - cul::Heading h{location->bearing * cul::units::Degrees};
> - thiz->deliver_heading_updates(cul::Update<cul::Heading>{h, cul::Clock::now()});
> - }
> -}
> -
> -static void on_status_update(uint16_t status, void* /*context*/)
> -{
> - SYSLOG(INFO) << "Status = " << status_lut.at(status);
> -}
> -
> -static void on_sv_status_update(UHardwareGpsSvStatus* sv_info, void* /*context*/)
> -{
> - SYSLOG_EVERY_N(INFO, 20) << "SV status update: [#svs: " << sv_info->num_svs << "]";
> -}
> -
> -static void on_nmea_update(int64_t /*timestamp*/, const char* /*nmea*/, int /*length*/, void* /*context*/)
> -{
> -}
> -
> -static void on_set_capabilities(uint32_t capabilities, void* /*context*/)
> -{
> - VLOG(1) << __PRETTY_FUNCTION__ << ": " << capabilities;
> -}
> -
> -static void on_request_utc_time(void* /*context*/)
> -{
> - VLOG(1) << __PRETTY_FUNCTION__;
> -}
> -
> -static void on_agps_status_update(UHardwareGpsAGpsStatus* /*status*/, void* /*context*/)
> -{
> - VLOG(1) << __PRETTY_FUNCTION__;
> -}
> -
> -static void on_gps_ni_notification(UHardwareGpsNiNotification* /*notification*/, void* /*context*/)
> -{
> - VLOG(1) << __PRETTY_FUNCTION__;
> -}
> -
> -static void on_agps_ril_request_set_id(uint32_t /*flags*/, void* /*context*/)
> -{
> - VLOG(1) << __PRETTY_FUNCTION__;
> -}
> -
> -static void on_agps_ril_request_ref_lock(uint32_t /*flags*/, void* /*context*/)
> -{
> - VLOG(1) << __PRETTY_FUNCTION__;
> -}
> -
> - static void on_gps_xtra_download_request(void*)
> - {
> - VLOG(1) << __PRETTY_FUNCTION__;
> - }
> -
> - void start()
> - {
> - u_hardware_gps_start(gps_handle);
> - }
> -
> - void stop()
> - {
> - u_hardware_gps_stop(gps_handle);
> - }
> -
> - UHardwareGpsParams gps_params;
> - UHardwareGps gps_handle;
> + std::shared_ptr<HardwareAbstractionLayer> hal;
> };
>
> -
> -
> std::string culg::Provider::class_name()
> {
> return "gps::Provider";
> @@ -145,63 +40,41 @@
>
> cul::Provider::Ptr culg::Provider::create_instance(const cul::ProviderFactory::Configuration&)
> {
> - return cul::Provider::Ptr{new culg::Provider{}};
> -}
> -
> -const cul::Provider::FeatureFlags& culg::Provider::default_feature_flags()
> -{
> - static const cul::Provider::FeatureFlags flags{"001"};
> - return flags;
> -}
> -
> -const cul::Provider::RequirementFlags& culg::Provider::default_requirement_flags()
> -{
> - static const cul::Provider::RequirementFlags flags{"1010"};
> - return flags;
> -}
> -
> -culg::Provider::Provider()
> - : cul::Provider(
> - culg::Provider::default_feature_flags(),
> - culg::Provider::default_requirement_flags()),
> - d(new Private())
> -{
> - d->gps_params.location_cb = culg::Provider::Private::on_location_update;
> - d->gps_params.status_cb = culg::Provider::Private::on_status_update;
> - d->gps_params.sv_status_cb = culg::Provider::Private::on_sv_status_update;
> - d->gps_params.nmea_cb = culg::Provider::Private::on_nmea_update;
> - d->gps_params.set_capabilities_cb = culg::Provider::Private::on_set_capabilities;
> - d->gps_params.request_utc_time_cb = culg::Provider::Private::on_request_utc_time;
> - d->gps_params.xtra_download_request_cb = culg::Provider::Private::on_gps_xtra_download_request;
> -
> - d->gps_params.agps_status_cb = culg::Provider::Private::on_agps_status_update;
> -
> - d->gps_params.gps_ni_notify_cb = culg::Provider::Private::on_gps_ni_notification;
> -
> - d->gps_params.request_setid_cb = culg::Provider::Private::on_agps_ril_request_set_id;
> - d->gps_params.request_refloc_cb = culg::Provider::Private::on_agps_ril_request_ref_lock;
> - d->gps_params.context = this;
> -
> - d->gps_handle = u_hardware_gps_new(std::addressof(d->gps_params));
> -
> - static const std::chrono::milliseconds minimum_interval{500};
> - static const uint32_t preferred_accuracy{0};
> - static const uint32_t preferred_time_to_first_fix{0};
> -
> - u_hardware_gps_set_position_mode(
> - d->gps_handle,
> - U_HARDWARE_GPS_POSITION_MODE_MS_BASED,
> - U_HARDWARE_GPS_POSITION_RECURRENCE_PERIODIC,
> - minimum_interval.count(),
> - preferred_accuracy,
> - preferred_time_to_first_fix
> - );
> + return cul::Provider::Ptr{new culg::Provider{culg::HardwareAbstractionLayer::create_default_instance()}};
> +}
> +
> +culg::Provider::Provider(const std::shared_ptr<HardwareAbstractionLayer>& hal)
> + : cul::Provider(
> + cul::Provider::Features::position | cul::Provider::Features::velocity | cul::Provider::Features::heading,
> + cul::Provider::Requirements::satellites),
> + d(new Private())
> +{
> + d->hal = hal;
> +
> + d->hal->position_updates().connect([this](const location::Position& pos)
> + {
> + mutable_updates().position(Update<Position>(pos));
> + });
> +
> + d->hal->heading_updates().connect([this](const location::Heading& heading)
> + {
> + mutable_updates().heading(Update<Heading>(heading));
> + });
> +
> + d->hal->velocity_updates().connect([this](const location::Velocity& velocity)
> + {
> + mutable_updates().velocity(Update<Velocity>(velocity));
> + });
> +
> + d->hal->space_vehicle_updates().connect([this](const std::set<location::SpaceVehicle>& svs)
> + {
> + mutable_updates().svs(Update<std::set<location::SpaceVehicle>>(svs));
> + });
> }
>
> culg::Provider::~Provider() noexcept
> {
> - d->stop();
> - u_hardware_gps_delete(d->gps_handle);
> + d->hal->stop_positioning();
> }
>
> bool culg::Provider::matches_criteria(const cul::Criteria&)
> @@ -211,30 +84,36 @@
>
> void culg::Provider::start_position_updates()
> {
> - d->start();
> + d->hal->start_positioning();
> }
>
> void culg::Provider::stop_position_updates()
> {
> - d->stop();
> + d->hal->stop_positioning();
> }
>
> void culg::Provider::start_velocity_updates()
> {
> - d->start();
> + d->hal->start_positioning();
> }
>
> void culg::Provider::stop_velocity_updates()
> {
> - d->stop();
> + d->hal->stop_positioning();
> }
>
> void culg::Provider::start_heading_updates()
> {
> - d->start();
> + d->hal->start_positioning();
> }
>
> void culg::Provider::stop_heading_updates()
> {
> - d->stop();
> -}
> + d->hal->stop_positioning();
> +}
> +
> +void culg::Provider::on_reference_location_updated(const cul::Update<cul::Position>& position)
> +{
> + d->hal->inject_reference_position(position.value);
> +}
> +
>
> === renamed file 'include/location_service/com/ubuntu/location/providers/gps/provider.h' => 'src/location_service/com/ubuntu/location/providers/gps/provider.h'
> --- include/location_service/com/ubuntu/location/providers/gps/provider.h 2013-05-28 14:41:06 +0000
> +++ src/location_service/com/ubuntu/location/providers/gps/provider.h 2014-06-24 16:02:38 +0000
> @@ -18,8 +18,10 @@
> #ifndef LOCATION_SERVICE_COM_UBUNTU_LOCATION_PROVIDERS_GPS_PROVIDER_H_
> #define LOCATION_SERVICE_COM_UBUNTU_LOCATION_PROVIDERS_GPS_PROVIDER_H_
>
> -#include "com/ubuntu/location/provider.h"
> -#include "com/ubuntu/location/provider_factory.h"
> +#include <com/ubuntu/location/provider.h>
> +#include <com/ubuntu/location/provider_factory.h>
> +
> +#include "hardware_abstraction_layer.h"
>
> namespace com
> {
> @@ -31,30 +33,31 @@
> {
> namespace gps
> {
> +
> class Provider : public com::ubuntu::location::Provider
> {
> public:
> + // For integration with the Provider factory.
> static std::string class_name();
> static Provider::Ptr create_instance(const ProviderFactory::Configuration&);
>
> - static const Provider::FeatureFlags& default_feature_flags();
> - static const Provider::RequirementFlags& default_requirement_flags();
> -
> - Provider();
> + Provider(const std::shared_ptr<HardwareAbstractionLayer>& hal = HardwareAbstractionLayer::create_default_instance());
> Provider(const Provider&) = delete;
> Provider& operator=(const Provider&) = delete;
> ~Provider() noexcept;
>
> - virtual bool matches_criteria(const Criteria&);
> -
> - virtual void start_position_updates();
> - virtual void stop_position_updates();
> -
> - virtual void start_velocity_updates();
> - virtual void stop_velocity_updates();
> -
> - virtual void start_heading_updates();
> - virtual void stop_heading_updates();
> + bool matches_criteria(const Criteria&);
> +
> + void start_position_updates();
> + void stop_position_updates();
> +
> + void start_velocity_updates();
> + void stop_velocity_updates();
> +
> + void start_heading_updates();
> + void stop_heading_updates();
> +
> + void on_reference_location_updated(const Update<Position>& position);
>
> private:
> struct Private;
>
> === modified file 'src/location_service/com/ubuntu/location/providers/skyhook/provider.cpp'
> --- src/location_service/com/ubuntu/location/providers/skyhook/provider.cpp 2013-05-29 06:04:02 +0000
> +++ src/location_service/com/ubuntu/location/providers/skyhook/provider.cpp 2014-06-24 16:02:38 +0000
> @@ -15,10 +15,10 @@
> *
> * Authored by: Thomas Voß <thomas.voss at canonical.com>
> */
> -#include "com/ubuntu/location/providers/skyhook/provider.h"
> +#include <com/ubuntu/location/providers/skyhook/provider.h>
>
> -#include "com/ubuntu/location/logging.h"
> -#include "com/ubuntu/location/provider_factory.h"
> +#include <com/ubuntu/location/logging.h>
> +#include <com/ubuntu/location/provider_factory.h>
>
> #pragma GCC diagnostic push
> #pragma GCC diagnostic warning "-Wignored-qualifiers"
>
> === modified file 'src/location_service/com/ubuntu/location/proxy_provider.cpp'
> --- src/location_service/com/ubuntu/location/proxy_provider.cpp 2013-06-10 11:10:00 +0000
> +++ src/location_service/com/ubuntu/location/proxy_provider.cpp 2014-06-24 16:02:38 +0000
> @@ -15,18 +15,35 @@
> *
> * Authored by: Thomas Voß <thomas.voss at canonical.com>
> */
> -#include "com/ubuntu/location/proxy_provider.h"
> +#include <com/ubuntu/location/proxy_provider.h>
>
> #include <bitset>
> #include <memory>
>
> +namespace cu = com::ubuntu;
> namespace cul = com::ubuntu::location;
>
> cul::ProxyProvider::ProxyProvider(const cul::ProviderSelection& selection)
> : Provider(selection.to_feature_flags()),
> - position_updates_provider(selection.position_updates_provider),
> - heading_updates_provider(selection.heading_updates_provider),
> - velocity_updates_provider(selection.velocity_updates_provider)
> + providers(selection),
> + connections
> + {
> + providers.position_updates_provider->updates().position.connect(
> + [this](const cul::Update<cul::Position>& u)
> + {
> + mutable_updates().position(u);
> + }),
> + providers.heading_updates_provider->updates().heading.connect(
> + [this](const cul::Update<cul::Heading>& u)
> + {
> + mutable_updates().heading(u);
> + }),
> + providers.velocity_updates_provider->updates().velocity.connect(
> + [this](const cul::Update<cul::Velocity>& u)
> + {
> + mutable_updates().velocity(u);
> + })
> + }
> {
> }
>
> @@ -34,59 +51,32 @@
> {
> }
>
> -cul::ChannelConnection cul::ProxyProvider::subscribe_to_position_updates(std::function<void(const cul::Update<cul::Position>&)> f)
> -{
> - if (position_updates_provider)
> - return position_updates_provider->subscribe_to_position_updates(f);
> - return ChannelConnection {};
> -}
> -
> -cul::ChannelConnection cul::ProxyProvider::subscribe_to_heading_updates(std::function<void(const cul::Update<cul::Heading>&)> f)
> -{
> - if (heading_updates_provider)
> - return heading_updates_provider->subscribe_to_heading_updates(f);
> - return ChannelConnection {};
> -}
> -
> -cul::ChannelConnection cul::ProxyProvider::subscribe_to_velocity_updates(std::function<void(const cul::Update<cul::Velocity>&)> f)
> -{
> - if (velocity_updates_provider)
> - return velocity_updates_provider->subscribe_to_velocity_updates(f);
> - return ChannelConnection {};
> -}
> -
> void cul::ProxyProvider::start_position_updates()
> {
> - if (position_updates_provider)
> - position_updates_provider->state_controller()->start_position_updates();
> + providers.position_updates_provider->state_controller()->start_position_updates();
> }
>
> void cul::ProxyProvider::stop_position_updates()
> {
> - if (position_updates_provider)
> - position_updates_provider->state_controller()->stop_position_updates();
> + providers.position_updates_provider->state_controller()->stop_position_updates();
> }
>
> void cul::ProxyProvider::start_velocity_updates()
> {
> - if (velocity_updates_provider)
> - velocity_updates_provider->state_controller()->start_velocity_updates();
> + providers.velocity_updates_provider->state_controller()->start_velocity_updates();
> }
>
> void cul::ProxyProvider::stop_velocity_updates()
> {
> - if (velocity_updates_provider)
> - velocity_updates_provider->state_controller()->stop_velocity_updates();
> + providers.velocity_updates_provider->state_controller()->stop_velocity_updates();
> }
>
> void cul::ProxyProvider::start_heading_updates()
> {
> - if (heading_updates_provider)
> - heading_updates_provider->state_controller()->start_heading_updates();
> + providers.heading_updates_provider->state_controller()->start_heading_updates();
> }
>
> void cul::ProxyProvider::stop_heading_updates()
> {
> - if (heading_updates_provider)
> - heading_updates_provider->state_controller()->stop_heading_updates();
> + providers.heading_updates_provider->state_controller()->stop_heading_updates();
> }
>
> === added file 'src/location_service/com/ubuntu/location/service/daemon.cpp'
> --- src/location_service/com/ubuntu/location/service/daemon.cpp 1970-01-01 00:00:00 +0000
> +++ src/location_service/com/ubuntu/location/service/daemon.cpp 2014-06-24 16:02:38 +0000
> @@ -0,0 +1,467 @@
> +/*
> + * Copyright © 2012-2013 Canonical Ltd.
> + *
> + * This program is free software: you can redistribute it and/or modify it
> + * under the terms of the GNU Lesser General Public License version 3,
> + * 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 PARTIlocationAR PURPOSE. See the
> + * GNU Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public License
> + * along with this program. If not, see <http://www.gnu.org/licenses/>.
> + *
> + * Authored by: Thomas Voß <thomas.voss at canonical.com>
> + */
> +#include <com/ubuntu/location/provider_factory.h>
> +
> +#include <com/ubuntu/location/service/default_configuration.h>
> +#include <com/ubuntu/location/service/implementation.h>
> +#include <com/ubuntu/location/service/stub.h>
> +
> +#include "program_options.h"
> +#include "daemon.h"
> +
> +#include <core/dbus/announcer.h>
> +#include <core/dbus/resolver.h>
> +#include <core/dbus/asio/executor.h>
> +
> +#include <core/posix/signal.h>
> +
> +#include <system_error>
> +#include <thread>
> +
> +#include <signal.h>
> +#include <sys/signalfd.h>
> +
> +namespace location = com::ubuntu::location;
> +namespace dbus = core::dbus;
> +
> +namespace
> +{
> +struct NullReporter : public location::service::Harvester::Reporter
> +{
> + NullReporter() = default;
> +
> + /** @brief Tell the reporter that it should start operating. */
> + void start()
> + {
> + }
> +
> + /** @brief Tell the reporter to shut down its operation. */
> + void stop()
> + {
> + }
> +
> + /**
> + * @brief Triggers the reporter to send off the information.
> + */
> + void report(const location::Update<location::Position>&,
> + const std::vector<location::connectivity::WirelessNetwork::Ptr>&,
> + const std::vector<location::connectivity::RadioCell::Ptr>&)
> + {
> + }
> +};
> +
> +location::ProgramOptions init_daemon_options()
> +{
> + location::ProgramOptions options;
> +
> + options.add("help", "Produces this help message");
> + options.add("testing", "Enables running the service without providers");
> + options.add_composed<std::vector<std::string>>("provider",
> + "The providers that should be added to the engine");
> +
> + return options;
> +}
> +
> +location::ProgramOptions& mutable_daemon_options()
> +{
> + static location::ProgramOptions options = init_daemon_options();
> + return options;
> +}
> +}
> +
> +location::service::Daemon::Configuration location::service::Daemon::Configuration::from_command_line_args(
> + int argc,
> + char** argv,
> + location::service::Daemon::DBusConnectionFactory factory)
> +{
> + location::service::Daemon::Configuration result;
> +
> + if (!mutable_daemon_options().parse_from_command_line_args(argc, (const char**)argv))
> + throw std::runtime_error{"Could not parse command-line, aborting..."};
> +
> + result.incoming = factory(mutable_daemon_options().bus());
> + result.outgoing= factory(mutable_daemon_options().bus());
> +
> + if (mutable_daemon_options().value_count_for_key("testing") == 0 && mutable_daemon_options().value_count_for_key("provider") == 0)
> + {
> + std::stringstream ss;
> + ss << "A set of providers need to be specified. The following providers are known:" << std::endl;
> + location::ProviderFactory::instance().enumerate(
> + [&ss](const std::string& name, const location::ProviderFactory::Factory&)
> + {
> + ss << "\t" << name << std::endl;
> + });
> + throw std::runtime_error{ss.str()};
> + }
> +
> + if(mutable_daemon_options().value_count_for_key("provider") > 0)
> + {
> + result.providers = mutable_daemon_options().value_for_key<std::vector<std::string>>("provider");
> +
> + for (const std::string& provider : result.providers)
> + {
> + mutable_daemon_options().enumerate_unrecognized_options(
> + [&result, provider](const std::string& s)
> + {
> + std::stringstream in(s);
> + std::string key, value;
> +
> + std::getline(in, key, '=');
> + std::getline(in, value, '=');
> +
> + std::size_t pos = key.find(provider);
> + if (pos == std::string::npos)
> + return;
> + static const std::string option_marker{"--"};
> + static const std::string scope_separator{"::"};
> + key = key.erase(key.find_first_of(option_marker), option_marker.size());
> + key = key.erase(key.find_first_of(provider), provider.size());
> + key = key.erase(key.find_first_of(scope_separator), scope_separator.size());
> +
> + std::cout << "\t" << key << " -> " << value << std::endl;
> +
> + result.provider_options[provider].put(key, value);
> + });
> + }
> + }
> +
> + return result;
> +}
> +
> +void location::service::Daemon::print_help(std::ostream& out)
> +{
> + mutable_daemon_options().print_help(out);
> +}
> +
> +int location::service::Daemon::main(const location::service::Daemon::Configuration& config)
> +{
> + auto trap = core::posix::trap_signals_for_all_subsequent_threads(
> + {
> + core::posix::Signal::sig_term,
> + core::posix::Signal::sig_int
> + });
> +
> + trap->signal_raised().connect([trap](const core::posix::Signal&)
> + {
> + trap->stop();
> + });
> +
> + const location::Configuration empty_provider_configuration;
> +
> + std::set<location::Provider::Ptr> instantiated_providers;
> +
> + for (const std::string& provider : config.providers)
> + {
> + std::cout << "Instantiating and configuring: " << provider << std::endl;
> +
> + try
> + {
> + auto p = location::ProviderFactory::instance().create_provider_for_name_with_config(
> + provider,
> + config.provider_options.count(provider) > 0 ?
> + config.provider_options.at(provider) : empty_provider_configuration);
> +
> + if (p)
> + instantiated_providers.insert(p);
> + else
> + throw std::runtime_error("Problem instantiating provider");
> +
> + } catch(const std::runtime_error& e)
> + {
> + std::cerr << "Exception instantiating provider: " << e.what() << " ... Aborting now." << std::endl;
> + return EXIT_FAILURE;
> + }
> + }
> +
> + config.incoming->install_executor(dbus::asio::make_executor(config.incoming));
> + config.outgoing->install_executor(dbus::asio::make_executor(config.outgoing));
> +
> + location::service::DefaultConfiguration dc;
> + location::service::Implementation::Configuration configuration
> + {
> + config.incoming,
> + config.outgoing,
> + dc.the_engine(instantiated_providers, dc.the_provider_selection_policy()),
> + dc.the_permission_manager(),
> + location::service::Harvester::Configuration
> + {
> + location::connectivity::platform_default_manager(),
> + std::make_shared<NullReporter>()
> + }
> + };
> +
> + location::service::Implementation location_service
> + {
> + configuration
> + };
> +
> + std::thread t1{[&config](){config.incoming->run();}};
> + std::thread t2{[&config](){config.outgoing->run();}};
> +
> + trap->run();
> +
> + config.incoming->stop();
> + config.outgoing->stop();
> +
> + if (t1.joinable())
> + t1.join();
> +
> + if (t2.joinable())
> + t2.join();
> +
> + return EXIT_SUCCESS;
> +}
> +
> +namespace
> +{
> +location::ProgramOptions init_cli_options()
> +{
> + location::ProgramOptions options;
> +
> + options.add("help", "Produces this help message");
> + options.add("property",
> + "Property to set/get from a running service, known properties are:\n"
> + " is_online [get/set]\n"
> + " does_satellite_based_positioning [get/set]\n"
> + " does_report_wifi_and_cell_ids [get/set]\n"
> + " visible_space_vehicles [get]",
> + location::service::Daemon::Cli::Property::unknown);
> + options.add<std::string>("set", "Adjust the value of the property.");
> + options.add("get", "Query the value of the property.");
> +
> + return options;
> +}
> +
> +location::ProgramOptions& mutable_cli_options()
> +{
> + static location::ProgramOptions options = init_cli_options();
> + return options;
> +}
> +}
> +
> +location::service::Daemon::Cli::Configuration location::service::Daemon::Cli::Configuration::from_command_line_args(
> + int argc,
> + char** argv,
> + location::service::Daemon::DBusConnectionFactory factory)
> +{
> + location::service::Daemon::Cli::Configuration result;
> +
> + if (!mutable_cli_options().parse_from_command_line_args(argc, (const char**)argv))
> + {
> + throw std::runtime_error{"Error parsing command line"};
> + }
> +
> + if (mutable_cli_options().value_count_for_key("help") > 0)
> + {
> + throw std::runtime_error{"Error parsing command line"};
> + }
> +
> + if (mutable_cli_options().value_count_for_key("get") > 0 && mutable_cli_options().value_count_for_key("set") > 0)
> + {
> + throw std::logic_error
> + {
> + "Both set and get specified, aborting..."
> + };
> + }
> +
> + result.bus = factory(mutable_cli_options().bus());
> +
> + result.property = mutable_cli_options().value_for_key<location::service::Daemon::Cli::Property>("property");
> +
> + if (mutable_cli_options().value_count_for_key("get") > 0)
> + {
> + result.command = Command::get;
> + }
> + else if (mutable_cli_options().value_count_for_key("set") > 0)
> + {
> + result.command = Command::set;
> + result.new_value = mutable_cli_options().value_for_key<std::string>("set");
> + }
> +
> + return result;
> +}
> +
> +/** @brief Pretty-prints the CLI's help text to the given output stream. */
> +void location::service::Daemon::Cli::print_help(std::ostream& out)
> +{
> + mutable_cli_options().print_help(out);
> +}
> +
> +int location::service::Daemon::Cli::main(const location::service::Daemon::Cli::Configuration& config)
> +{
> + auto location_service =
> + dbus::resolve_service_on_bus<location::service::Interface, location::service::Stub>(config.bus);
> +
> + switch (config.property)
> + {
> + case Property::is_online:
> + switch (config.command)
> + {
> + case Command::get:
> + std::cout << std::boolalpha << "Location service is "
> + << (location_service->is_online() ? "online" : "offline") << std::endl;
> + break;
> + case Command::set:
> + {
> + std::stringstream ss(config.new_value);
> + bool flag = location_service->is_online();
> + ss >> std::boolalpha >> flag;
> +
> + std::cout << "Adjusting is_online property to value: " << config.new_value << " -> ";
> +
> + location_service->is_online() = flag;
> +
> + if (location_service->is_online() != flag)
> + {
> + std::cout << "failed" << std::endl;
> + return EXIT_FAILURE;
> + }
> + std::cout << "succeeded" << std::endl;
> + break;
> + }
> + case Command::unknown: break;
> + }
> + break;
> + case Property::does_report_wifi_and_cell_ids:
> + switch (config.command)
> + {
> + case Command::get:
> + std::cout << std::boolalpha << "Location service "
> + << (location_service->does_report_cell_and_wifi_ids() ? "does" : "does not")
> + << " report cell and wifi ids." << std::endl;
> + break;
> + case Command::set:
> + {
> + std::stringstream ss(config.new_value);
> + bool flag = location_service->does_report_cell_and_wifi_ids();
> + ss >> std::boolalpha >> flag;
> +
> + std::cout << "Adjusting does_report_cell_and_wifi_ids property to value: "
> + << std::boolalpha << flag << " -> ";
> + location_service->does_report_cell_and_wifi_ids() = flag;
> + if (location_service->does_report_cell_and_wifi_ids() != flag)
> + {
> + std::cout << "failed" << std::endl;
> + return EXIT_FAILURE;
> + }
> + std::cout << "succeeded" << std::endl;
> + break;
> + }
> + case Command::unknown: break;
> + }
> + break;
> + case Property::does_satellite_based_positioning:
> + switch (config.command)
> + {
> + case Command::get:
> + std::cout << std::boolalpha << "Location service "
> + << (location_service->does_satellite_based_positioning() ? "does" : "does not")
> + << " satellite based positioning." << std::endl;
> + break;
> + case Command::set:
> + {
> + std::stringstream ss(config.new_value);
> + bool flag = location_service->does_satellite_based_positioning();
> + ss >> std::boolalpha >> flag;
> +
> + std::cout << "Adjusting does_satellite_based_positioning property to value: "
> + << std::boolalpha << flag << " -> ";
> + location_service->does_satellite_based_positioning() = flag;
> + if (location_service->does_satellite_based_positioning() != flag)
> + {
> + std::cout << "failed" << std::endl;
> + return EXIT_FAILURE;
> + }
> + std::cout << "succeeded" << std::endl;
> + break;
> + }
> + case Command::unknown: break;
> + }
> + break;
> + case Property::visible_space_vehicles:
> + {
> + switch (config.command)
> + {
> + case Command::get:
> + {
> + auto svs = location_service->visible_space_vehicles().get();
> + std::cout << "Visible space vehicles:" << std::endl;
> + for (const auto& sv : svs)
> + std::cout << "\t" << sv.second << std::endl;
> + break;
> + }
> + case Command::set:
> + std::cout << "Property visible_space_vehicles is not set-able, aborting now." << std::endl;
> + location::service::Daemon::Cli::print_help(std::cout);
> + return EXIT_FAILURE;
> + case Command::unknown: break;
> + }
> + break;
> + }
> + case Property::unknown:
> + std::cout << "Unknown property, aborting now." << std::endl;
> + location::service::Daemon::Cli::print_help(std::cout);
> + return EXIT_FAILURE;
> + }
> +
> + return EXIT_SUCCESS;
> +}
> +
> +/** @brief Parses a Cli property from the given input stream, throws std::runtime_error. */
> +std::istream& location::service::operator>>(std::istream& in, location::service::Daemon::Cli::Property& property)
> +{
> + static const std::map<std::string, location::service::Daemon::Cli::Property> lut =
> + {
> + {"is_online", location::service::Daemon::Cli::Property::is_online},
> + {"does_satellite_based_positioning", location::service::Daemon::Cli::Property::does_satellite_based_positioning},
> + {"does_report_wifi_and_cell_ids", location::service::Daemon::Cli::Property::does_report_wifi_and_cell_ids},
> + {"visible_space_vehicles", location::service::Daemon::Cli::Property::visible_space_vehicles}
> + };
> +
> + std::string value; in >> value;
> +
> + auto it = lut.find(value);
> +
> + if (it == lut.end()) throw std::runtime_error
> + {
> + "Unknown property specified: " + value
> + };
> +
> + property = it->second;
> + return in;
> +}
> +
> +/** @brief Parses a Cli property from the given input stream, throws std::runtime_error. */
> +std::ostream& location::service::operator<<(std::ostream& out, location::service::Daemon::Cli::Property property)
> +{
> + switch (property)
> + {
> + case location::service::Daemon::Cli::Property::is_online:
> + out << "is_online"; break;
> + case location::service::Daemon::Cli::Property::does_satellite_based_positioning:
> + out << "does_satellite_based_positioning"; break;
> + case location::service::Daemon::Cli::Property::does_report_wifi_and_cell_ids:
> + out << "does_report_wifi_and_cell_ids"; break;
> + case location::service::Daemon::Cli::Property::visible_space_vehicles:
> + out << "visible_space_vehicles"; break;
> + case location::service::Daemon::Cli::Property::unknown:
> + out << "unknown"; break;
> + }
> +
> + return out;
> +}
>
> === added file 'src/location_service/com/ubuntu/location/service/daemon.h'
> --- src/location_service/com/ubuntu/location/service/daemon.h 1970-01-01 00:00:00 +0000
> +++ src/location_service/com/ubuntu/location/service/daemon.h 2014-06-24 16:02:38 +0000
> @@ -0,0 +1,191 @@
> +/*
> + * Copyright © 2012-2013 Canonical Ltd.
> + *
> + * This program is free software: you can redistribute it and/or modify it
> + * under the terms of the GNU Lesser General Public License version 3,
> + * 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 Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public License
> + * along with this program. If not, see <http://www.gnu.org/licenses/>.
> + *
> + * Authored by: Thomas Voß <thomas.voss at canonical.com>
> + */
> +#ifndef LOCATION_SERVICE_COM_UBUNTU_LOCATION_SERVICE_DAEMON_H_
> +#define LOCATION_SERVICE_COM_UBUNTU_LOCATION_SERVICE_DAEMON_H_
> +
> +#include <com/ubuntu/location/configuration.h>
> +
> +#include <core/dbus/bus.h>
> +
> +#include <iosfwd>
> +#include <string>
> +
> +namespace com
> +{
> +namespace ubuntu
> +{
> +namespace location
> +{
> +namespace service
> +{
> +/**
> + * @brief The Daemon struct encapsulates main functions for the location service and its cli.
> + */
> +struct Daemon
> +{
> + /** @brief Function signature for creating DBus connections. */
> + typedef std::function<core::dbus::Bus::Ptr(core::dbus::WellKnownBus)> DBusConnectionFactory;
> +
> + /** @brief Returns the default connection factory. */
> + static DBusConnectionFactory default_dbus_connection_factory()
> + {
> + return [](core::dbus::WellKnownBus bus)
> + {
> + return core::dbus::Bus::Ptr
> + {
> + new core::dbus::Bus(bus)
> + };
> + };
> + }
> +
> + /** @brief Describes the command-line interface to the daemon. */
> + struct Cli
> + {
> + Cli() = delete;
> +
> + /** @brief Enumerates all commands known to the cli. */
> + enum class Command
> + {
> + /** @brief Marks the unknown command. */
> + unknown,
> + /** @brief Request to query a property value of the running service. */
> + get,
> + /** @brief Request to adjust a property value of the running service. */
> + set
> + };
> +
> + /** @brief Enumerates all properties known to the cli. */
> + enum class Property
> + {
> + /** @brief Marks the unknown property. */
> + unknown,
> + /** @brief Indicates whether the positioning engine is online. */
> + is_online,
> + /** @brief Indicates whether the positioning engine uses satellite-based positioning. */
> + does_satellite_based_positioning,
> + /** @brief Indicates whether the positioning engine leverages wifi and cell ids for positioning. */
> + does_report_wifi_and_cell_ids,
> + /** @brief The list of currently visible space-vehicles. */
> + visible_space_vehicles
> + };
> +
> + /** @brief Parameters for an invocation of the CLI. */
> + struct Configuration
> + {
> + /** @brief Parses a configuration from the command line.
> + *
> + * --bus arg (=session) The well-known bus to connect to the service upon
> + * --help Produces this help message
> + * --property arg (=unknown) Property to set/get from a running service, known
> + properties are:
> + is_online [get/set]
> + does_satellite_based_positioning [get/set]
> + does_report_wifi_and_cell_ids [get/set]
> + visible_space_vehicles [get]
> + * --set arg Adjust the value of the property.
> + * --get Query the value of the property.
> + */
> + static Configuration from_command_line_args(
> + int argc,
> + char** argv,
> + DBusConnectionFactory factory = default_dbus_connection_factory());
> +
> + /** @brief The bus to connect to. */
> + core::dbus::Bus::Ptr bus;
> +
> + /** @brief The command to execute against a running daemon. */
> + Command command
> + {
> + Command::unknown
> + };
> +
> + /** @brief If command is get/set/monitor, the property to act upon. */
> + Property property
> + {
> + Property::unknown
> + };
> +
> + /** @brief The new, string-based value for a property. */
> + std::string new_value;
> + };
> +
> + /** @brief Pretty-prints the CLI's help text to the given output stream. */
> + static void print_help(std::ostream& out);
> +
> + /**
> + * @brief main of the command-line interface to the location service.
> + * @return EXIT_SUCCESS or EXIT_FAILURE.
> + */
> + static int main(const Configuration& configuration);
> + };
> +
> + Daemon() = delete;
> +
> + /** @brief Parameters for an invocation of the daemon. */
> + struct Configuration
> + {
> + /** @brief Parses a configuration from the command line.
> + *
> + * --bus arg (=session) The well-known bus to connect to the service upon
> + * --help Produces this help message
> + * --testing Enables executing the service without selected providers
> + * --provider arg The providers that should be added to the engine
> + */
> + static Configuration from_command_line_args(
> + int argc,
> + char** argv,
> + DBusConnectionFactory factory = default_dbus_connection_factory());
> +
> + /** @brief The bus to expose the service upon. */
> + core::dbus::Bus::Ptr incoming;
> +
> + /** @brief The bus to use for querying other services. */
> + core::dbus::Bus::Ptr outgoing;
> +
> + /** @brief Configures the daemon for testing mode. */
> + bool is_testing_enabled
> + {
> + false
> + };
> + /** @brief Providers that have been requested on the command line. */
> + std::vector<std::string> providers;
> + /** @brief Provider-specific options keyed on the provider name. */
> + std::map< std::string, location::Configuration > provider_options;
> + };
> +
> + /** @brief Pretty-prints the CLI's help text to the given output stream. */
> + static void print_help(std::ostream& out);
> +
> + /**
> + * @brief Executes the daemon with the given configuration.
> + * @return EXIT_SUCCESS or EXIT_FAILURE.
> + */
> + static int main(const Configuration& config);
> +};
> +
> +/** @brief Parses a Cli property from the given input stream, throws std::runtime_error. */
> +std::istream& operator>>(std::istream& in, Daemon::Cli::Property& property);
> +
> +/** @brief Pretty-prints a property value */
> +std::ostream& operator<<(std::ostream& out, Daemon::Cli::Property property);
> +}
> +}
> +}
> +}
> +
> +#endif // LOCATION_SERVICE_COM_UBUNTU_LOCATION_SERVICE_DAEMON_H_
>
> === added file 'src/location_service/com/ubuntu/location/service/daemon_cli_main.cpp'
> --- src/location_service/com/ubuntu/location/service/daemon_cli_main.cpp 1970-01-01 00:00:00 +0000
> +++ src/location_service/com/ubuntu/location/service/daemon_cli_main.cpp 2014-06-24 16:02:38 +0000
> @@ -0,0 +1,49 @@
> +/*
> + * Copyright © 2012-2013 Canonical Ltd.
> + *
> + * This program is free software: you can redistribute it and/or modify it
> + * under the terms of the GNU Lesser General Public License version 3,
> + * 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 PARTIlocationAR PURPOSE. See the
> + * GNU Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public License
> + * along with this program. If not, see <http://www.gnu.org/licenses/>.
> + *
> + * Authored by: Thomas Voß <thomas.voss at canonical.com>
> + */
> +
> +#include "daemon.h"
> +
> +#include <iostream>
> +#include <stdexcept>
> +
> +namespace location = com::ubuntu::location;
> +
> +int main(int argc, char** argv)
> +{
> + location::service::Daemon::Cli::Configuration config;
> + try
> + {
> + config = location::service::Daemon::Cli::Configuration::from_command_line_args(argc, argv);
> + } catch(const std::runtime_error& e)
> + {
> + std::cout << "Problem parsing command line: " << e.what() << std::endl;
> + location::service::Daemon::Cli::print_help(std::cout);
> + return EXIT_FAILURE;
> + }
> +
> + try
> + {
> + location::service::Daemon::Cli::main(config);
> + } catch(const std::exception& e)
> + {
> + std::cout << "Problem executing the CLI: " << e.what() << std::endl;
> + return EXIT_FAILURE;
> + }
> +
> + return EXIT_SUCCESS;
> +}
>
> === added file 'src/location_service/com/ubuntu/location/service/daemon_main.cpp'
> --- src/location_service/com/ubuntu/location/service/daemon_main.cpp 1970-01-01 00:00:00 +0000
> +++ src/location_service/com/ubuntu/location/service/daemon_main.cpp 2014-06-24 16:02:38 +0000
> @@ -0,0 +1,46 @@
> +/*
> + * Copyright © 2012-2013 Canonical Ltd.
> + *
> + * This program is free software: you can redistribute it and/or modify it
> + * under the terms of the GNU Lesser General Public License version 3,
> + * 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 PARTIlocationAR PURPOSE. See the
> + * GNU Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public License
> + * along with this program. If not, see <http://www.gnu.org/licenses/>.
> + *
> + * Authored by: Thomas Voß <thomas.voss at canonical.com>
> + */
> +
> +#include "daemon.h"
> +
> +namespace location = com::ubuntu::location;
> +
> +int main(int argc, char** argv)
> +{
> + location::service::Daemon::Configuration config;
> + try
> + {
> + config = location::service::Daemon::Configuration::from_command_line_args(argc, argv);
> + } catch(const std::runtime_error& e)
> + {
> + std::cerr << "Problem parsing command line: " << e.what();
> + location::service::Daemon::print_help(std::cerr);
> + return EXIT_FAILURE;
> + }
> +
> + try
> + {
> + location::service::Daemon::main(config);
> + } catch(const std::exception& e)
> + {
> + std::cout << "Problem executing the daemon: " << e.what() << std::endl;
> + return EXIT_FAILURE;
> + }
> +
> + return EXIT_SUCCESS;
> +}
>
> === modified file 'src/location_service/com/ubuntu/location/service/default_configuration.cpp'
> --- src/location_service/com/ubuntu/location/service/default_configuration.cpp 2013-05-30 10:21:26 +0000
> +++ src/location_service/com/ubuntu/location/service/default_configuration.cpp 2014-06-24 16:02:38 +0000
> @@ -15,10 +15,10 @@
> *
> * Authored by: Thomas Voß <thomas.voss at canonical.com>
> */
> -#include "com/ubuntu/location/service/default_configuration.h"
> -#include "com/ubuntu/location/service/default_permission_manager.h"
> +#include <com/ubuntu/location/service/default_configuration.h>
> +#include <com/ubuntu/location/service/default_permission_manager.h>
>
> -#include "com/ubuntu/location/default_provider_selection_policy.h"
> +#include <com/ubuntu/location/default_provider_selection_policy.h>
>
> namespace cul = com::ubuntu::location;
> namespace culs = com::ubuntu::location::service;
> @@ -35,7 +35,11 @@
> const std::set<cul::Provider::Ptr>& provider_set,
> const cul::ProviderSelectionPolicy::Ptr& provider_selection_policy)
> {
> - return Engine::Ptr {new Engine{provider_set, provider_selection_policy}};
> + auto engine = std::make_shared<cul::Engine>(provider_selection_policy);
> + for (const auto& provider : provider_set)
> + engine->add_provider(provider);
> +
> + return engine;
> }
>
> cul::ProviderSelectionPolicy::Ptr culs::DefaultConfiguration::the_provider_selection_policy()
>
> === modified file 'src/location_service/com/ubuntu/location/service/default_permission_manager.cpp'
> --- src/location_service/com/ubuntu/location/service/default_permission_manager.cpp 2013-05-28 14:41:06 +0000
> +++ src/location_service/com/ubuntu/location/service/default_permission_manager.cpp 2014-06-24 16:02:38 +0000
> @@ -15,7 +15,9 @@
> *
> * Authored by: Thomas Voß <thomas.voss at canonical.com>
> */
> -#include "com/ubuntu/location/service/default_permission_manager.h"
> +#include <com/ubuntu/location/service/default_permission_manager.h>
> +
> +#include <iostream>
>
> namespace cul = com::ubuntu::location;
> namespace culs = com::ubuntu::location::service;
>
> === added file 'src/location_service/com/ubuntu/location/service/harvester.cpp'
> --- src/location_service/com/ubuntu/location/service/harvester.cpp 1970-01-01 00:00:00 +0000
> +++ src/location_service/com/ubuntu/location/service/harvester.cpp 2014-06-24 16:02:38 +0000
> @@ -0,0 +1,79 @@
> +/*
> + * Copyright © 2012-2013 Canonical Ltd.
> + *
> + * This program is free software: you can redistribute it and/or modify it
> + * under the terms of the GNU Lesser General Public License version 3,
> + * 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 Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public License
> + * along with this program. If not, see <http://www.gnu.org/licenses/>.
> + *
> + * Authored by: Thomas Voß <thomas.voss at canonical.com>
> + */
> +
> +#include <com/ubuntu/location/service/harvester.h>
> +
> +#include <com/ubuntu/location/logging.h>
> +
> +namespace location = com::ubuntu::location;
> +
> +location::service::Harvester::Harvester(const location::service::Harvester::Configuration& configuration)
> + : config(configuration),
> + is_running{false}
> +{
> +}
> +
> +location::service::Harvester::~Harvester()
> +{
> + stop();
> +}
> +
> +/** @brief Report updated position to the harvester instance. */
> +void location::service::Harvester::report_position_update(const location::Update<location::Position>& update)
> +{
> + VLOG(10) << "Reference location changed: " << update;
> +
> + if (not is_running.load())
> + return;
> +
> + std::vector<location::connectivity::WirelessNetwork::Ptr> visible_wifis;
> + config.connectivity_manager->enumerate_visible_wireless_networks([&visible_wifis](location::connectivity::WirelessNetwork::Ptr wifi)
> + {
> + VLOG(10) << "Got a visible wifi: " << *wifi << std::endl;
> + visible_wifis.push_back(wifi);
> + });
> +
> + std::vector<location::connectivity::RadioCell::Ptr> connected_cells;
> + config.connectivity_manager->enumerate_connected_radio_cells([&connected_cells](location::connectivity::RadioCell::Ptr cell)
> + {
> + VLOG(10) << "Got a cell: " << *cell << std::endl;
> + connected_cells.push_back(cell);
> + });
> +
> + config.reporter->report(update, visible_wifis, connected_cells);
> +}
> +
> +void location::service::Harvester::start()
> +{
> + if (is_running.load())
> + return;
> +
> + is_running.exchange(true);
> +
> + config.reporter->start();
> +}
> +
> +void location::service::Harvester::stop()
> +{
> + if (not is_running.load())
> + return;
> +
> + is_running.exchange(false);
> +
> + config.reporter->stop();
> +}
>
> === added file 'src/location_service/com/ubuntu/location/service/harvester.h'
> --- src/location_service/com/ubuntu/location/service/harvester.h 1970-01-01 00:00:00 +0000
> +++ src/location_service/com/ubuntu/location/service/harvester.h 2014-06-24 16:02:38 +0000
> @@ -0,0 +1,97 @@
> +/*
> + * Copyright © 2012-2013 Canonical Ltd.
> + *
> + * This program is free software: you can redistribute it and/or modify it
> + * under the terms of the GNU Lesser General Public License version 3,
> + * 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 Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public License
> + * along with this program. If not, see <http://www.gnu.org/licenses/>.
> + *
> + * Authored by: Thomas Voß <thomas.voss at canonical.com>
> + */
> +#ifndef LOCATION_SERVICE_COM_UBUNTU_LOCATION_SERVICE_HARVESTER_H_
> +#define LOCATION_SERVICE_COM_UBUNTU_LOCATION_SERVICE_HARVESTER_H_
> +
> +#include <com/ubuntu/location/engine.h>
> +#include <com/ubuntu/location/update.h>
> +#include <com/ubuntu/location/connectivity/manager.h>
> +
> +namespace com
> +{
> +namespace ubuntu
> +{
> +namespace location
> +{
> +namespace service
> +{
> +/** @brief Models a wifi- and cell-id harvester for crowd-sourcing purposes. */
> +class Harvester
> +{
> +public:
> +
> + /** @brief Models a reporter of position updates, augmented with wifi and cell ids. */
> + struct Reporter
> + {
> + /** @cond */
> + typedef std::shared_ptr<Reporter> Ptr;
> +
> + Reporter() = default;
> + virtual ~Reporter() = default;
> + /** @endcond */
> +
> + /** @brief Tell the reporter that it should start operating. */
> + virtual void start() = 0;
> +
> + /** @brief Tell the reporter to shut down its operation. */
> + virtual void stop() = 0;
> +
> + /**
> + * @brief Triggers the reporter to send off the information.
> + */
> + virtual void report(const Update<Position>& update,
> + const std::vector<connectivity::WirelessNetwork::Ptr>& wifis,
> + const std::vector<connectivity::RadioCell::Ptr>& cells) = 0;
> + };
> +
> + /** @brief Configuration encapsulates all creation time options of class Harvester */
> + struct Configuration
> + {
> + /** The connectivity manager that the harvester should use. */
> + std::shared_ptr<connectivity::Manager> connectivity_manager;
> + /** The reporter implementation */
> + std::shared_ptr<Reporter> reporter;
> + };
> +
> + /** @brief Creates a new instance and wires up to system components for receiving
> + * location updates, and wifi and cell id measurements.
> + */
> + Harvester(const Configuration& configuration);
> +
> + /** @brief Stops the data collection and frees all resources held by the instance. */
> + virtual ~Harvester();
> +
> + /** @brief Report updated position to the harvester instance. */
> + virtual void report_position_update(const Update<Position>& update);
> +
> + /** @brief Starts the harvester instance and its data collection. */
> + virtual void start();
> +
> + /** @brief Stops the harvester instance and its data collection. */
> + virtual void stop();
> +
> +private:
> + Configuration config;
> + std::atomic<bool> is_running;
> +};
> +}
> +}
> +}
> +}
> +
> +#endif // LOCATION_SERVICE_COM_UBUNTU_LOCATION_SERVICE_HARVESTER_H_
>
> === added file 'src/location_service/com/ubuntu/location/service/ichnaea_reporter.cpp'
> --- src/location_service/com/ubuntu/location/service/ichnaea_reporter.cpp 1970-01-01 00:00:00 +0000
> +++ src/location_service/com/ubuntu/location/service/ichnaea_reporter.cpp 2014-06-24 16:02:38 +0000
> @@ -0,0 +1,226 @@
> +/*
> + * Copyright © 2012-2013 Canonical Ltd.
> + *
> + * This program is free software: you can redistribute it and/or modify it
> + * under the terms of the GNU Lesser General Public License version 3,
> + * 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 Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public License
> + * along with this program. If not, see <http://www.gnu.org/licenses/>.
> + *
> + * Authored by: Thomas Voß <thomas.voss at canonical.com>
> + */
> +
> +#include <com/ubuntu/location/service/ichnaea_reporter.h>
> +
> +#include <com/ubuntu/location/logging.h>
> +
> +#include <core/net/http/client.h>
> +#include <core/net/http/content_type.h>
> +#include <core/net/http/request.h>
> +#include <core/net/http/response.h>
> +#include <core/net/http/status.h>
> +
> +#include <json/json.h>
> +
> +#include <thread>
> +
> +namespace json = Json;
> +namespace location = com::ubuntu::location;
> +
> +location::service::ichnaea::Reporter::Reporter(
> + const location::service::ichnaea::Reporter::Configuration& configuration)
> + : http_client(core::net::http::make_client())
> +{
> + auto uri = configuration.uri +
> + ichnaea::submit::resource +
> + configuration.key;
> +
> + submit_request_config = core::net::http::Request::Configuration::from_uri_as_string(uri);
> + submit_request_config.ssl.verify_host = false;
> + submit_request_config.ssl.verify_peer = false;
> +
> + if (not configuration.nick_name.empty())
> + submit_request_config.header.add(Reporter::nick_name_header, configuration.nick_name);
> +}
> +
> +location::service::ichnaea::Reporter::~Reporter()
> +{
> + stop();
> +}
> +
> +void location::service::ichnaea::Reporter::start()
> +{
> + http_client_worker = std::move(
> + std::thread
> + {
> + [this]()
> + {
> + http_client->run();
> + }
> + });
> +}
> +
> +void location::service::ichnaea::Reporter::stop()
> +{
> + http_client->stop();
> +
> + if (http_client_worker.joinable())
> + http_client_worker.join();
> +}
> +
> +void location::service::ichnaea::Reporter::report(
> + const location::Update<location::Position>& update,
> + const std::vector<location::connectivity::WirelessNetwork::Ptr>& wifis,
> + const std::vector<location::connectivity::RadioCell::Ptr>& cells)
> +{
> + json::Value submit;
> + json::Value item;
> +
> + item[Json::radio] = "gsm"; // We currently only support gsm radio types.
> + item[Json::lat] = update.value.latitude.value.value();
> + item[Json::lon] = update.value.longitude.value.value();
> +
> + if (update.value.accuracy.horizontal)
> + item[Json::accuracy] = (*update.value.accuracy.horizontal).value();
> + if (update.value.altitude)
> + item[Json::altitude] = (*update.value.altitude).value.value();
> + if (update.value.accuracy.vertical)
> + item[Json::altitude_accuracy] = (*update.value.accuracy.vertical).value();
> +
> + if (!wifis.empty())
> + ichnaea::Reporter::convert_wifis_to_json(wifis, item[Json::wifi]);
> +
> + if (!cells.empty())
> + ichnaea::Reporter::convert_cells_to_json(cells, item[Json::cell]);
> +
> + submit[Json::items].append(item);
> +
> + json::FastWriter writer;
> +
> + VLOG(10) << "Submitting: " << writer.write(submit);
> +
> + auto request = http_client->post(
> + submit_request_config,
> + writer.write(submit),
> + core::net::http::ContentType::json);
> +
> + request->async_execute(
> + core::net::http::Request::Handler()
> + .on_response([](const core::net::http::Response& response)
> + {
> + if (response.status != ichnaea::submit::success)
> + LOG(ERROR) << "Error submitting to ichnaea: " << response.body;
> + else
> + LOG(INFO) << "Succesfully submitted to ichnaea.";
> + })
> + .on_error([](const core::net::Error& e)
> + {
> + LOG(ERROR) << "Networking error while submitting to ichnaea: " << e.what();
> + }));
> +}
> +
> +void location::service::ichnaea::Reporter::convert_wifis_to_json(
> + const std::vector<location::connectivity::WirelessNetwork::Ptr>& wifis,
> + json::Value& destination)
> +{
> + for (const auto& wifi : wifis)
> + {
> + // We do not harvest any Wifi marked with '_nomap'.
> + if (wifi->ssid().get().find("_nomap") != std::string::npos)
> + continue;
> +
> + json::Value w;
> + w[Json::Wifi::key] = wifi->bssid().get();
> +
> + if (wifi->frequency().get().is_valid())
> + w[Json::Wifi::frequency] = static_cast<int>(wifi->frequency().get());
> +
> + // We have a relative signal strength percentage in the wifi record.
> + // TODO(tvoss): Check how that could be translated to RSSI.
> + //wifi[Json::Wifi::signal] = -50;
> +
> + destination.append(w);
> + }
> +}
> +
> +void location::service::ichnaea::Reporter::convert_cells_to_json(
> + const std::vector<location::connectivity::RadioCell::Ptr>& cells,
> + json::Value& destination)
> +{
> + for (const auto& cell : cells)
> + {
> + json::Value c;
> +
> + switch (cell->type())
> + {
> + case connectivity::RadioCell::Type::gsm:
> + {
> + c[Json::Cell::radio] = "gsm";
> +
> + const auto& details = cell->gsm();
> +
> + if (details.mobile_country_code.is_valid())
> + c[Json::Cell::mcc] = details.mobile_country_code.get();
> + if (details.mobile_network_code.is_valid())
> + c[Json::Cell::mnc] = details.mobile_network_code.get();
> + if (details.location_area_code.is_valid())
> + c[Json::Cell::lac] = details.location_area_code.get();
> + if (details.id.is_valid())
> + c[Json::Cell::cid] = details.id.get();
> + if (details.strength.is_valid())
> + c[Json::Cell::asu] = details.strength.get();
> +
> + break;
> + }
> + case connectivity::RadioCell::Type::umts:
> + {
> + c[Json::Cell::radio] = "umts";
> +
> + const auto& details = cell->umts();
> +
> + if (details.mobile_country_code.is_valid())
> + c[Json::Cell::mcc] = details.mobile_country_code.get();
> + if (details.mobile_network_code.is_valid())
> + c[Json::Cell::mnc] = details.mobile_network_code.get();
> + if (details.location_area_code.is_valid())
> + c[Json::Cell::lac] = details.location_area_code.get();
> + if (details.id.is_valid())
> + c[Json::Cell::cid] = details.id.get();
> + if (details.strength.is_valid())
> + c[Json::Cell::asu] = details.strength.get();
> +
> + break;
> + }
> + case connectivity::RadioCell::Type::lte:
> + {
> + c[Json::Cell::radio] = "lte";
> +
> + const auto& details = cell->lte();
> +
> + if (details.mobile_country_code.is_valid())
> + c[Json::Cell::mcc] = details.mobile_country_code.get();
> + if (details.mobile_network_code.is_valid())
> + c[Json::Cell::mnc] = details.mobile_network_code.get();
> + if (details.tracking_area_code.is_valid())
> + c[Json::Cell::lac] = details.tracking_area_code.get();
> + if (details.id.is_valid())
> + c[Json::Cell::cid] = details.id.get();
> + if (details.physical_id.is_valid())
> + c[Json::Cell::psc] = details.physical_id.get();
> + if (details.strength.is_valid())
> + c[Json::Cell::asu] = details.strength.get();
> + break;
> + }
> + default:
> + break;
> + }
> +
> + destination.append(c);
> + }
> +}
>
> === added file 'src/location_service/com/ubuntu/location/service/ichnaea_reporter.h'
> --- src/location_service/com/ubuntu/location/service/ichnaea_reporter.h 1970-01-01 00:00:00 +0000
> +++ src/location_service/com/ubuntu/location/service/ichnaea_reporter.h 2014-06-24 16:02:38 +0000
> @@ -0,0 +1,155 @@
> +/*
> + * Copyright © 2012-2013 Canonical Ltd.
> + *
> + * This program is free software: you can redistribute it and/or modify it
> + * under the terms of the GNU Lesser General Public License version 3,
> + * 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 Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public License
> + * along with this program. If not, see <http://www.gnu.org/licenses/>.
> + *
> + * Authored by: Thomas Voß <thomas.voss at canonical.com>
> + */
> +#ifndef LOCATION_SERVICE_COM_UBUNTU_LOCATION_SERVICE_ICHNAEA_REPORTER_H_
> +#define LOCATION_SERVICE_COM_UBUNTU_LOCATION_SERVICE_ICHNAEA_REPORTER_H_
> +
> +#include <com/ubuntu/location/service/harvester.h>
> +
> +#include <core/net/http/client.h>
> +#include <core/net/http/content_type.h>
> +#include <core/net/http/request.h>
> +#include <core/net/http/response.h>
> +#include <core/net/http/status.h>
> +
> +#include <json/json.h>
> +
> +#include <thread>
> +
> +namespace json = Json;
> +
> +namespace com{namespace ubuntu{namespace location{namespace service
> +{
> +/**
> + * @brief All types and functions that are used to communicate with instances
> + * of the Mozilla location service go here. Please see for further details:
> + *
> + * - https://mozilla-ichnaea.readthedocs.org/en/latest/api/index.html#submit
> + * - https://github.com/mozilla/MozStumbler
> + */
> +namespace ichnaea
> +{
> +namespace submit
> +{
> +/** @brief Resource path for wifi- and cell-id submissions. */
> +constexpr const char* resource
> +{
> + "/v1/submit?key="
> +};
> +/** @brief Http code marking errors for Mozilla location service instances. */
> +const core::net::http::Status error
> +{
> + core::net::http::Status::bad_request
> +};
> +/** @brief Http code marking a successful submission request to Mozilla location service instances. */
> +const core::net::http::Status success
> +{
> + core::net::http::Status::no_content
> +};
> +}
> +
> +struct Reporter : public Harvester::Reporter
> +{
> + /** @brief Submissions can be tagged with a nick-name for tracking on leaderboards. */
> + static constexpr const char* nick_name_header{"X-Nickname"};
> +
> + /** @brief The JSON-dialect of the Mozilla location service is described here. */
> + struct Json
> + {
> + static constexpr const char* radio{"radio"};
> + static constexpr const char* lat{"lat"};
> + static constexpr const char* lon{"lon"};
> + static constexpr const char* accuracy{"accuracy"};
> + static constexpr const char* altitude{"altitude"};
> + static constexpr const char* altitude_accuracy{"altitude_accuracy"};
> +
> + static constexpr const char* items{"items"};
> +
> + static constexpr const char* cell{"cell"};
> + static constexpr const char* wifi{"wifi"};
> +
> + struct Cell
> + {
> + static constexpr const char* radio{"radio"};
> + static constexpr const char* mcc{"mcc"};
> + static constexpr const char* mnc{"mnc"};
> + static constexpr const char* lac{"lac"};
> + static constexpr const char* cid{"cid"};
> + static constexpr const char* psc{"psc"};
> + static constexpr const char* asu{"asu"};
> + };
> +
> + struct Wifi
> + {
> + static constexpr const char* channel{"channel"};
> + static constexpr const char* frequency{"frequency"};
> + static constexpr const char* key{"key"};
> + static constexpr const char* signal{"signal"};
> + };
> + };
> +
> + /** Creation-time options for the ICHNAEA reporter */
> + struct Configuration
> + {
> + /** Uri of the ICHNAEA instance we want to submit to. */
> + std::string uri;
> + /** API key for the submission */
> + std::string key;
> + /** Nickname for the submission */
> + std::string nick_name;
> + };
> +
> + /** @brief Constructs a new instance with the given parameters. */
> + Reporter(const Configuration& configuration);
> + /** @brief Stops the reporter instance and frees all related resources. */
> + ~Reporter();
> +
> + /** @brief Starts the reporter and prepares for submission. */
> + void start() override;
> + /** @brief Stops the reporter. */
> + void stop() override;
> +
> + /**
> + * @brief Announced a position update, together with visible wifis and cells to the reporter.
> + * @throws std::runtime_error if wifis and cells are empty.
> + */
> + void report(
> + const Update<Position>& update,
> + const std::vector<connectivity::WirelessNetwork::Ptr>& wifis,
> + const std::vector<connectivity::RadioCell::Ptr>& cells) override;
> +
> + /** @brief Encodes a collection of wifis into the Mozilla loation service JSON dialect. */
> + static void convert_wifis_to_json(
> + const std::vector<connectivity::WirelessNetwork::Ptr>& wifis,
> + json::Value& destination);
> +
> + /** @brief Encodes a collection of radio cells into the Mozilla loation service JSON dialect. */
> + static void convert_cells_to_json(
> + const std::vector<connectivity::RadioCell::Ptr>& cells,
> + json::Value& destination);
> +
> + /** @brief The http request configuration for submissions to the mozilla location service. */
> + core::net::http::Request::Configuration submit_request_config;
> + /** @brief The http client instance used to talk to Mozilla location service instances. */
> + std::shared_ptr<core::net::http::Client> http_client;
> + /** @brief Worker thread for dispatching the http client instance. */
> + std::thread http_client_worker;
> +};
> +}
> +}}}}
> +
> +#endif // LOCATION_SERVICE_COM_UBUNTU_LOCATION_SERVICE_ICHNAEA_REPORTER_H_
>
> === modified file 'src/location_service/com/ubuntu/location/service/implementation.cpp'
> --- src/location_service/com/ubuntu/location/service/implementation.cpp 2014-01-31 11:08:33 +0000
> +++ src/location_service/com/ubuntu/location/service/implementation.cpp 2014-06-24 16:02:38 +0000
> @@ -1,10 +1,31 @@
> -#include "com/ubuntu/location/service/implementation.h"
> -
> -#include "com/ubuntu/location/service/session/implementation.h"
> -
> -#include "com/ubuntu/location/criteria.h"
> -#include "com/ubuntu/location/engine.h"
> -#include "com/ubuntu/location/proxy_provider.h"
> +/*
> + * Copyright © 2012-2013 Canonical Ltd.
> + *
> + * This program is free software: you can redistribute it and/or modify it
> + * under the terms of the GNU Lesser General Public License version 3,
> + * 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 Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public License
> + * along with this program. If not, see <http://www.gnu.org/licenses/>.
> + *
> + * Authored by: Thomas Voß <thomas.voss at canonical.com>
> + */
> +#include <com/ubuntu/location/service/implementation.h>
> +
> +#include <com/ubuntu/location/connectivity/manager.h>
> +#include <com/ubuntu/location/service/harvester.h>
> +
> +#include <com/ubuntu/location/service/session/implementation.h>
> +
> +#include <com/ubuntu/location/criteria.h>
> +#include <com/ubuntu/location/engine.h>
> +#include <com/ubuntu/location/logging.h>
> +#include <com/ubuntu/location/proxy_provider.h>
>
> #include <core/dbus/bus.h>
> #include <core/dbus/service.h>
> @@ -20,49 +41,110 @@
>
> namespace dbus = core::dbus;
>
> -struct culs::Implementation::Private
> -{
> - dbus::types::ObjectPath make_session_path()
> - {
> - static std::size_t counter{0};
> - std::stringstream ss; ss << "/sessions/" << counter;
> - counter++;
> -
> - return dbus::types::ObjectPath{ss.str()};
> - }
> -
> - dbus::Bus::Ptr bus;
> - cul::Engine::Ptr engine;
> - culs::PermissionManager::Ptr permission_manager;
> -};
> -
> -culs::Implementation::Implementation(
> - const dbus::Bus::Ptr& bus,
> - const cul::Engine::Ptr& engine,
> - const culs::PermissionManager::Ptr& permission_manager)
> - : Skeleton(bus, permission_manager),
> - d{new Private{bus, engine, permission_manager}}
> -{
> - if (!bus)
> - throw std::runtime_error("Cannot create service for null bus.");
> - if (!engine)
> +culs::Implementation::Implementation(const culs::Implementation::Configuration& config)
> + : Skeleton
> + {
> + Skeleton::Configuration
> + {
> + config.incoming,
> + config.outgoing,
> + culs::Skeleton::CredentialsResolver::Ptr
> + {
> + new culs::Skeleton::DBusDaemonCredentialsResolver
> + {
> + config.outgoing
> + }
> + },
> + culs::Skeleton::ObjectPathGenerator::Ptr
> + {
> + new culs::Skeleton::ObjectPathGenerator{}
> + },
> + config.permission_manager
> + }
> + },
> + configuration(config),
> + harvester(config.harvester),
> + connections
> + {
> + is_online().changed().connect(
> + [this](bool value)
> + {
> + configuration.engine->configuration.engine_state
> + = value ?
> + Engine::Status::on :
> + Engine::Status::off;
> + }),
> + does_report_cell_and_wifi_ids().changed().connect(
> + [this](bool value)
> + {
> + configuration.engine->configuration.wifi_and_cell_id_reporting_state
> + = value ?
> + cul::WifiAndCellIdReportingState::on :
> + cul::WifiAndCellIdReportingState::off;
> + }),
> + does_satellite_based_positioning().changed().connect(
> + [this](bool value)
> + {
> + configuration.engine->configuration.satellite_based_positioning_state
> + = value ?
> + cul::SatelliteBasedPositioningState::on :
> + cul::SatelliteBasedPositioningState::off;
> + }),
> + configuration.engine->configuration.engine_state.changed().connect(
> + [this](Engine::Status status)
> + {
> + is_online() =
> + status == Engine::Status::on ||
> + status == Engine::Status::active;
> + }),
> + configuration.engine->configuration.satellite_based_positioning_state.changed().connect(
> + [this](cul::SatelliteBasedPositioningState state)
> + {
> + does_satellite_based_positioning() =
> + state == cul::SatelliteBasedPositioningState::on;
> + }),
> + configuration.engine->updates.visible_space_vehicles.changed().connect(
> + [this](const std::map<cul::SpaceVehicle::Key, cul::SpaceVehicle>&svs)
> + {
> + visible_space_vehicles() = svs;
> + }),
> + configuration.engine->updates.reference_location.changed().connect(
> + [this](const cul::Update<cul::Position>& update)
> + {
> + harvester.report_position_update(update);
> + })
> + }
> +{
> + if (!configuration.incoming)
> + throw std::runtime_error("Cannot create service for null bus.");
> + if (!configuration.outgoing)
> + throw std::runtime_error("Cannot create service for null bus.");
> + if (!configuration.engine)
> throw std::runtime_error("Cannot create service for null engine.");
> - if (!permission_manager)
> + if (!configuration.permission_manager)
> throw std::runtime_error("Cannot create service for null permission manager.");
> -}
> -
> -culs::Implementation::~Implementation() noexcept
> -{
> +
> + is_online() =
> + configuration.engine->configuration.engine_state == Engine::Status::on ||
> + configuration.engine->configuration.engine_state == Engine::Status::active;
> + does_report_cell_and_wifi_ids() =
> + configuration.engine->configuration.wifi_and_cell_id_reporting_state ==
> + cul::WifiAndCellIdReportingState::on;
> + does_satellite_based_positioning() =
> + configuration.engine->configuration.satellite_based_positioning_state ==
> + cul::SatelliteBasedPositioningState::on;
> +
> + harvester.start();
> }
>
> culs::session::Interface::Ptr culs::Implementation::create_session_for_criteria(const cul::Criteria& criteria)
> {
> auto provider_selection
> - = d->engine->determine_provider_selection_for_criteria(criteria);
> + = configuration.engine->determine_provider_selection_for_criteria(criteria);
> auto proxy_provider = ProxyProvider::Ptr
> - {
> - new ProxyProvider{provider_selection}
> - };
> -
> - return session::Interface::Ptr{new session::Implementation(d->bus, d->make_session_path(), proxy_provider)};
> + {
> + new ProxyProvider{provider_selection}
> + };
> +
> + return session::Interface::Ptr{new culs::session::Implementation(proxy_provider)};
> }
>
> === renamed file 'include/location_service/com/ubuntu/location/service/implementation.h' => 'src/location_service/com/ubuntu/location/service/implementation.h'
> --- include/location_service/com/ubuntu/location/service/implementation.h 2014-01-31 11:08:33 +0000
> +++ src/location_service/com/ubuntu/location/service/implementation.h 2014-06-24 16:02:38 +0000
> @@ -18,8 +18,10 @@
> #ifndef LOCATION_SERVICE_COM_UBUNTU_LOCATION_SERVICE_IMPLEMENTATION_H_
> #define LOCATION_SERVICE_COM_UBUNTU_LOCATION_SERVICE_IMPLEMENTATION_H_
>
> -#include "com/ubuntu/location/engine.h"
> -#include "com/ubuntu/location/service/skeleton.h"
> +#include <com/ubuntu/location/engine.h>
> +#include <com/ubuntu/location/connectivity/manager.h>
> +#include <com/ubuntu/location/service/harvester.h>
> +#include <com/ubuntu/location/service/skeleton.h>
>
> #include <memory>
>
> @@ -35,22 +37,47 @@
> {
> class Implementation : public Skeleton
> {
> - public:
> +public:
> typedef std::shared_ptr<Implementation> Ptr;
>
> - Implementation(
> - const core::dbus::Bus::Ptr& bus,
> - const Engine::Ptr& engine,
> - const PermissionManager::Ptr& permission_manager);
> - Implementation(const Implementation&) = delete;
> - virtual ~Implementation() noexcept;
> - Implementation& operator=(const Implementation&) = delete;
> -
> - virtual session::Interface::Ptr create_session_for_criteria(const Criteria& criteria);
> + // Summarizes configuration options for the implementation.
> + struct Configuration
> + {
> + // The bus connection to expose the service upon.
> + core::dbus::Bus::Ptr incoming;
> + // The bus connection for querying other services.
> + core::dbus::Bus::Ptr outgoing;
> + // The positioning Engine that the service should use.
> + Engine::Ptr engine;
> + // The permission manager that the service should use.
> + PermissionManager::Ptr permission_manager;
> + // All harvesting specific options.
> + Harvester::Configuration harvester;
> + };
> +
> + // Creates a new instance of the service with the given configuration.
> + // Throws std::runtime_error in case of issues.
> + Implementation(const Configuration& configuration);
> +
> + // Creates a new session for the given criteria.
> + session::Interface::Ptr create_session_for_criteria(const Criteria& criteria);
>
> private:
> - struct Private;
> - std::unique_ptr<Private> d;
> + // The service configuration.
> + Configuration configuration;
> + // The harvester instance.
> + Harvester harvester;
> + // All event connections are automatically cut on destruction.
> + struct
> + {
> + core::ScopedConnection is_online;
> + core::ScopedConnection does_report_cell_and_wifi_ids;
> + core::ScopedConnection does_satellite_based_positioning;
> + core::ScopedConnection engine_state;
> + core::ScopedConnection satellite_based_positioning_state;
> + core::ScopedConnection visible_space_vehicles;
> + core::ScopedConnection reference_position;
> + } connections;
> };
> }
> }
>
> === removed file 'src/location_service/com/ubuntu/location/service/main.cpp'
> --- src/location_service/com/ubuntu/location/service/main.cpp 2014-01-31 11:08:33 +0000
> +++ src/location_service/com/ubuntu/location/service/main.cpp 1970-01-01 00:00:00 +0000
> @@ -1,148 +0,0 @@
> -/*
> - * Copyright © 2012-2013 Canonical Ltd.
> - *
> - * This program is free software: you can redistribute it and/or modify it
> - * under the terms of the GNU Lesser General Public License version 3,
> - * 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 Lesser General Public License for more details.
> - *
> - * You should have received a copy of the GNU Lesser General Public License
> - * along with this program. If not, see <http://www.gnu.org/licenses/>.
> - *
> - * Authored by: Thomas Voß <thomas.voss at canonical.com>
> - */
> -#include "program_options.h"
> -
> -#include "com/ubuntu/location/provider_factory.h"
> -
> -#include "com/ubuntu/location/service/default_configuration.h"
> -#include "com/ubuntu/location/service/implementation.h"
> -
> -#include <core/dbus/announcer.h>
> -#include <core/dbus/asio/executor.h>
> -
> -#include <thread>
> -
> -namespace cul = com::ubuntu::location;
> -namespace culs = com::ubuntu::location::service;
> -namespace dbus = core::dbus;
> -
> -int main(int argc, char** argv)
> -{
> - cul::ProgramOptions options;
> -
> - options.add("help", "Produces this help message");
> - options.add(
> - "bus",
> - "The well-known bus to announce the service upon",
> - std::string{"session"});
> - options.add_composed<std::vector<std::string>>(
> - "provider",
> - "The providers that should be added to the engine");
> -
> - if (!options.parse_from_command_line_args(argc, argv))
> - return EXIT_FAILURE;
> -
> - if (options.value_count_for_key("help") > 0)
> - {
> - options.print_help(std::cout);
> - return EXIT_SUCCESS;
> - }
> -
> - if (options.value_count_for_key("provider") == 0)
> - {
> - std::cout << "A set of providers need to be specified. The following providers are known:" << std::endl;
> - cul::ProviderFactory::instance().enumerate(
> - [](const std::string& name, const cul::ProviderFactory::Factory&)
> - {
> - std::cout << "\t" << name << std::endl;
> - });
> - return EXIT_FAILURE;
> - }
> -
> - auto selected_providers = options.value_for_key<std::vector<std::string>>("provider");
> -
> - std::map<std::string, cul::ProviderFactory::Configuration> config_lut;
> - std::set<cul::Provider::Ptr> instantiated_providers;
> -
> - for (const std::string& provider : selected_providers)
> - {
> - std::cout << "Instantiating and configuring: " << provider << std::endl;
> - options.enumerate_unrecognized_options(
> - [&config_lut, provider](const std::string& s)
> - {
> - std::stringstream in(s);
> - std::string key, value;
> -
> - std::getline(in, key, '=');
> - std::getline(in, value, '=');
> -
> - std::size_t pos = key.find(provider);
> - if (pos == std::string::npos)
> - return;
> - static const std::string option_marker{"--"};
> - static const std::string scope_separator{"::"};
> - key = key.erase(key.find_first_of(option_marker), option_marker.size());
> - key = key.erase(key.find_first_of(provider), provider.size());
> - key = key.erase(key.find_first_of(scope_separator), scope_separator.size());
> -
> - std::cout << "\t" << key << " -> " << value << std::endl;
> -
> - config_lut[provider].put(key, value);
> - });
> -
> - try
> - {
> - auto p = cul::ProviderFactory::instance().create_provider_for_name_with_config(
> - provider,
> - config_lut[provider]);
> -
> - if (p)
> - instantiated_providers.insert(p);
> - else
> - throw std::runtime_error("Problem instantiating provider");
> -
> - } catch(const std::runtime_error& e)
> - {
> - std::cerr << "Exception instantiating provider: " << e.what() << " ... Aborting now." << std::endl;
> - return EXIT_FAILURE;
> - }
> - }
> -
> - static const std::map<std::string, dbus::WellKnownBus> lut =
> - {
> - {"session", dbus::WellKnownBus::session},
> - {"system", dbus::WellKnownBus::system},
> - };
> -
> - dbus::Bus::Ptr bus
> - {
> - new dbus::Bus{lut.at(options.value_for_key<std::string>("bus"))}
> - };
> -
> - bus->install_executor(dbus::asio::make_executor(bus));
> -
> - culs::DefaultConfiguration config;
> -
> - auto location_service =
> - dbus::announce_service_on_bus<
> - culs::Interface,
> - culs::Implementation
> - >(
> - bus,
> - config.the_engine(
> - instantiated_providers,
> - config.the_provider_selection_policy()),
> - config.the_permission_manager());
> -
> - std::thread t{[bus](){bus->run();}};
> -
> - if (t.joinable())
> - t.join();
> -
> - return EXIT_SUCCESS;
> -}
>
> === modified file 'src/location_service/com/ubuntu/location/service/program_options.h'
> --- src/location_service/com/ubuntu/location/service/program_options.h 2013-10-08 14:48:43 +0000
> +++ src/location_service/com/ubuntu/location/service/program_options.h 2014-06-24 16:02:38 +0000
> @@ -19,6 +19,8 @@
> #include <boost/program_options/options_description.hpp>
> #include <boost/program_options/variables_map.hpp>
>
> +#include <core/dbus/well_known_bus.h>
> +
> #include <functional>
> #include <iostream>
>
> @@ -28,8 +30,21 @@
>
> struct ProgramOptions
> {
> + struct Errors
> + {
> + struct OptionNotSet {};
> + };
> +
> + struct Options
> + {
> + static const char* bus() { return "bus"; }
> + };
> +
> ProgramOptions(bool do_allow_unregistered = true) : allow_unregistered(do_allow_unregistered)
> {
> + add(Options::bus(),
> + "The well-known bus to connect to the service upon",
> + std::string{"session"});
> }
>
> ProgramOptions& add(const char* name, const char* desc)
> @@ -65,7 +80,7 @@
> return *this;
> }
>
> - bool parse_from_command_line_args(int argc, char** argv)
> + bool parse_from_command_line_args(int argc, char const** argv)
> {
> try
> {
> @@ -86,12 +101,51 @@
> return true;
> }
>
> + bool parse_from_environment()
> + {
> + try
> + {
> + auto parsed = boost::program_options::parse_environment(od, env_prefix);
> + boost::program_options::store(parsed, vm);
> + vm.notify();
> + } catch(const std::runtime_error& e)
> + {
> + std::cerr << e.what() << std::endl;
> + return false;
> + }
> +
> + return true;
> + }
> +
> + ProgramOptions& environment_prefix(const std::string& prefix)
> + {
> + env_prefix = prefix;
> + return *this;
> + }
> +
> + core::dbus::WellKnownBus bus()
> + {
> + static const std::map<std::string, core::dbus::WellKnownBus> lut =
> + {
> + {"session", core::dbus::WellKnownBus::session},
> + {"system", core::dbus::WellKnownBus::system},
> + };
> +
> + return lut.at(value_for_key<std::string>(Options::bus()));
> + }
> +
> template<typename T>
> T value_for_key(const std::string& key)
> {
> return vm[key].as<T>();
> }
>
> + template<typename T>
> + T value_for_key(const std::string& key) const
> + {
> + return vm[key].as<T>();
> + }
> +
> std::size_t value_count_for_key(const std::string& key)
> {
> return vm.count(key);
> @@ -103,12 +157,19 @@
> enumerator(s);
> }
>
> + void print(std::ostream& out) const
> + {
> + for (const auto& pair : vm)
> + out << pair.first << ": " << (pair.second.defaulted() ? "default" : "set") << std::endl;
> + }
> +
> void print_help(std::ostream& out)
> {
> out << od;
> }
>
> bool allow_unregistered;
> + std::string env_prefix;
> boost::program_options::options_description od;
> boost::program_options::variables_map vm;
> std::vector<std::string> unrecognized;
>
> === modified file 'src/location_service/com/ubuntu/location/service/session/implementation.cpp'
> --- src/location_service/com/ubuntu/location/service/session/implementation.cpp 2014-02-09 18:52:25 +0000
> +++ src/location_service/com/ubuntu/location/service/session/implementation.cpp 2014-06-24 16:02:38 +0000
> @@ -1,8 +1,10 @@
> -#include "com/ubuntu/location/service/session/implementation.h"
> +#include <com/ubuntu/location/service/session/implementation.h>
> +#include <com/ubuntu/location/logging.h>
>
> #include <functional>
> #include <memory>
>
> +namespace cu = com::ubuntu;
> namespace cul = com::ubuntu::location;
> namespace culs = com::ubuntu::location::service;
> namespace culss = com::ubuntu::location::service::session;
> @@ -11,73 +13,117 @@
>
> struct culss::Implementation::Private
> {
> - Private(const Provider::Ptr& provider) : provider(provider)
> + Provider::Ptr provider;
> + struct
> {
> - }
> + core::ScopedConnection position_updates;
> + core::ScopedConnection velocity_updates;
> + core::ScopedConnection heading_updates;
>
> - Provider::Ptr provider;
> - ScopedChannelConnection position_updates_connection;
> - ScopedChannelConnection velocity_updates_connection;
> - ScopedChannelConnection heading_updates_connection;
> + core::ScopedConnection position_status_updates;
> + core::ScopedConnection heading_status_updates;
> + core::ScopedConnection velocity_status_updates;
> + } connections;
> };
>
> -culss::Implementation::Implementation(
> - const dbus::Bus::Ptr& bus,
> - const dbus::types::ObjectPath& session_path,
> - const cul::Provider::Ptr& provider)
> - : Skeleton(bus, session_path),
> - d(new Private{provider})
> +culss::Implementation::Implementation(const cul::Provider::Ptr& provider)
> + : Interface(),
> + d(new Private
> + {
> + provider,
> + {
> + provider->updates().position.connect(
> + [this](const Update<Position>& update)
> + {
> + updates().position = update;
> + }),
> + provider->updates().heading.connect(
> + [this](const Update<Heading>& update)
> + {
> + updates().heading = update;
> + }),
> + provider->updates().velocity.connect(
> + [this](const Update<Velocity>& update)
> + {
> + updates().velocity = update;
> + }),
> + updates().position_status.changed().connect(
> + [this](const Interface::Updates::Status& status)
> + {
> + switch(status)
> + {
> + case Interface::Updates::Status::enabled:
> + start_position_updates(); break;
> + case Interface::Updates::Status::disabled:
> + stop_position_updates(); break;
> + }
> + }),
> + updates().velocity_status.changed().connect(
> + [this](const Interface::Updates::Status& status)
> + {
> + switch(status)
> + {
> + case Interface::Updates::Status::enabled:
> + start_velocity_updates(); break;
> + case Interface::Updates::Status::disabled:
> + stop_velocity_updates(); break;
> + }
> + }),
> + updates().heading_status.changed().connect(
> + [this](const Interface::Updates::Status& status)
> + {
> + switch(status)
> + {
> + case Interface::Updates::Status::enabled:
> + start_heading_updates(); break;
> + case Interface::Updates::Status::disabled:
> + stop_heading_updates(); break;
> + }
> + })
> + }
> + })
> {
> - if (!provider)
> - throw std::runtime_error("Cannot create implementation for null provider.");
> -
> - d->position_updates_connection =
> - provider->subscribe_to_position_updates([this](const Update<Position>& update)
> - {
> - access_position_updates_channel()(update);
> - });
> - d->heading_updates_connection =
> - provider->subscribe_to_heading_updates([this](const Update<Heading>& update)
> - {
> - access_heading_updates_channel()(update);
> - });
> - d->velocity_updates_connection =
> - provider->subscribe_to_velocity_updates([this](const Update<Velocity>& update)
> - {
> - access_velocity_updates_channel()(update);
> - });
> }
>
> culss::Implementation::~Implementation() noexcept
> {
> + stop_position_updates();
> + stop_heading_updates();
> + stop_velocity_updates();
> }
>
> void culss::Implementation::start_position_updates()
> {
> + VLOG(10) << __PRETTY_FUNCTION__;
> d->provider->state_controller()->start_position_updates();
> }
>
> void culss::Implementation::stop_position_updates() noexcept
> {
> + VLOG(10) << __PRETTY_FUNCTION__;
> d->provider->state_controller()->stop_position_updates();
> }
>
> void culss::Implementation::start_velocity_updates()
> {
> + VLOG(10) << __PRETTY_FUNCTION__;
> d->provider->state_controller()->start_velocity_updates();
> }
>
> void culss::Implementation::stop_velocity_updates() noexcept
> {
> + VLOG(10) << __PRETTY_FUNCTION__;
> d->provider->state_controller()->stop_velocity_updates();
> }
>
> void culss::Implementation::start_heading_updates()
> {
> + VLOG(10) << __PRETTY_FUNCTION__;
> d->provider->state_controller()->start_heading_updates();
> }
>
> void culss::Implementation::stop_heading_updates() noexcept
> {
> + VLOG(10) << __PRETTY_FUNCTION__;
> d->provider->state_controller()->stop_heading_updates();
> }
>
> === modified file 'src/location_service/com/ubuntu/location/service/session/interface.cpp'
> --- src/location_service/com/ubuntu/location/service/session/interface.cpp 2014-01-31 11:08:33 +0000
> +++ src/location_service/com/ubuntu/location/service/session/interface.cpp 2014-06-24 16:02:38 +0000
> @@ -15,7 +15,7 @@
> *
> * Authored by: Thomas Voß <thomas.voss at canonical.com>
> */
> -#include "com/ubuntu/location/service/session/interface.h"
> +#include <com/ubuntu/location/service/session/interface.h>
>
> #include <core/dbus/codec.h>
> #include <core/dbus/service.h>
> @@ -30,9 +30,7 @@
>
> struct culss::Interface::Private
> {
> - cul::Channel<cul::Update<cul::Position>> position_updates_channel;
> - cul::Channel<cul::Update<cul::Heading>> heading_updates_channel;
> - cul::Channel<cul::Update<cul::Velocity>> velocity_updates_channel;
> + culss::Interface::Updates updates;
> };
>
> culss::Interface::Interface() : d{new Private{}}
> @@ -43,32 +41,7 @@
> {
> }
>
> -cul::ChannelConnection culss::Interface::install_position_updates_handler(std::function<void(const cul::Update<cul::Position>&)> handler)
> -{
> - return d->position_updates_channel.connect(handler);
> -}
> -
> -cul::ChannelConnection culss::Interface::install_velocity_updates_handler(std::function<void(const cul::Update<cul::Velocity>&)> handler)
> -{
> - return d->velocity_updates_channel.connect(handler);
> -}
> -
> -cul::ChannelConnection culss::Interface::install_heading_updates_handler(std::function<void(const cul::Update<cul::Heading>&)> handler)
> -{
> - return d->heading_updates_channel.connect(handler);
> -}
> -
> -cul::Channel<cul::Update<cul::Position>>& culss::Interface::access_position_updates_channel()
> -{
> - return d->position_updates_channel;
> -}
> -
> -cul::Channel<cul::Update<cul::Heading>>& culss::Interface::access_heading_updates_channel()
> -{
> - return d->heading_updates_channel;
> -}
> -
> -cul::Channel<cul::Update<cul::Velocity>>& culss::Interface::access_velocity_updates_channel()
> -{
> - return d->velocity_updates_channel;
> +culss::Interface::Updates& culss::Interface::updates()
> +{
> + return d->updates;
> }
>
> === added file 'src/location_service/com/ubuntu/location/service/session/interface_p.h'
> --- src/location_service/com/ubuntu/location/service/session/interface_p.h 1970-01-01 00:00:00 +0000
> +++ src/location_service/com/ubuntu/location/service/session/interface_p.h 2014-06-24 16:02:38 +0000
> @@ -0,0 +1,228 @@
> +/*
> + * Copyright © 2012-2013 Canonical Ltd.
> + *
> + * This program is free software: you can redistribute it and/or modify it
> + * under the terms of the GNU Lesser General Public License version 3,
> + * 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 Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public License
> + * along with this program. If not, see <http://www.gnu.org/licenses/>.
> + *
> + * Authored by: Thomas Voß <thomas.voss at canonical.com>
> + */
> +#ifndef LOCATION_SERVICE_COM_UBUNTU_LOCATION_SERVICE_SESSION_INTERFACE_P_H_
> +#define LOCATION_SERVICE_COM_UBUNTU_LOCATION_SERVICE_SESSION_INTERFACE_P_H_
> +
> +#include <com/ubuntu/location/service/session/interface.h>
> +
> +#include <core/dbus/codec.h>
> +#include <core/dbus/traits/service.h>
> +
> +struct com::ubuntu::location::service::session::Interface::UpdatePosition
> +{
> + typedef com::ubuntu::location::service::session::Interface Interface;
> +
> + inline static const std::string& name()
> + {
> + static const std::string s
> + {
> + "UpdatePosition"
> + };
> + return s;
> + }
> +
> + typedef void ResultType;
> +
> + inline static const std::chrono::milliseconds default_timeout() { return std::chrono::seconds{1}; }
> +};
> +
> +struct com::ubuntu::location::service::session::Interface::UpdateVelocity
> +{
> + typedef com::ubuntu::location::service::session::Interface Interface;
> +
> + inline static const std::string& name()
> + {
> + static const std::string s
> + {
> + "UpdateVelocity"
> + };
> + return s;
> + }
> +
> + typedef void ResultType;
> +
> + inline static const std::chrono::milliseconds default_timeout() { return std::chrono::seconds{1}; }
> +};
> +
> +struct com::ubuntu::location::service::session::Interface::UpdateHeading
> +{
> + typedef com::ubuntu::location::service::session::Interface Interface;
> +
> + inline static const std::string& name()
> + {
> + static const std::string s
> + {
> + "UpdateHeading"
> + };
> + return s;
> + }
> +
> + typedef void ResultType;
> +
> + inline static const std::chrono::milliseconds default_timeout() { return std::chrono::seconds{1}; }
> +};
> +
> +struct com::ubuntu::location::service::session::Interface::StartPositionUpdates
> +{
> + typedef com::ubuntu::location::service::session::Interface Interface;
> +
> + inline static const std::string& name()
> + {
> + static const std::string s
> + {
> + "StartPositionUpdates"
> + };
> + return s;
> + }
> +
> + typedef void ResultType;
> +
> + inline static const std::chrono::milliseconds default_timeout() { return std::chrono::seconds{5}; }
> +};
> +
> +struct com::ubuntu::location::service::session::Interface::StopPositionUpdates
> +{
> + typedef com::ubuntu::location::service::session::Interface Interface;
> +
> + inline static const std::string& name()
> + {
> + static const std::string s
> + {
> + "StopPositionUpdates"
> + };
> + return s;
> + }
> +
> + typedef void ResultType;
> +
> + inline static const std::chrono::milliseconds default_timeout() { return std::chrono::seconds{5}; }
> +};
> +
> +struct com::ubuntu::location::service::session::Interface::StartVelocityUpdates
> +{
> + typedef com::ubuntu::location::service::session::Interface Interface;
> +
> + inline static const std::string& name()
> + {
> + static const std::string s
> + {
> + "StartVelocityUpdates"
> + };
> + return s;
> + }
> +
> + typedef void ResultType;
> +
> + inline static const std::chrono::milliseconds default_timeout() { return std::chrono::seconds{5}; }
> +};
> +
> +struct com::ubuntu::location::service::session::Interface::StopVelocityUpdates
> +{
> + typedef com::ubuntu::location::service::session::Interface Interface;
> +
> + inline static const std::string& name()
> + {
> + static const std::string s
> + {
> + "StopVelocityUpdates"
> + };
> + return s;
> + }
> +
> + typedef void ResultType;
> +
> + inline static const std::chrono::milliseconds default_timeout() { return std::chrono::seconds{5}; }
> +};
> +
> +struct com::ubuntu::location::service::session::Interface::StartHeadingUpdates
> +{
> + typedef com::ubuntu::location::service::session::Interface Interface;
> +
> + inline static const std::string& name()
> + {
> + static const std::string s
> + {
> + "StartHeadingUpdates"
> + };
> + return s;
> + }
> +
> + typedef void ResultType;
> +
> + inline static const std::chrono::milliseconds default_timeout() { return std::chrono::seconds{5}; }
> +};
> +
> +struct com::ubuntu::location::service::session::Interface::StopHeadingUpdates
> +{
> + typedef com::ubuntu::location::service::session::Interface Interface;
> +
> + inline static const std::string& name()
> + {
> + static const std::string s
> + {
> + "StopHeadingUpdates"
> + };
> + return s;
> + }
> +
> + typedef void ResultType;
> +
> + inline static const std::chrono::milliseconds default_timeout() { return std::chrono::seconds{5}; }
> +};
> +
> +struct com::ubuntu::location::service::session::Interface::Errors::ErrorParsingUpdate
> +{
> + inline static std::string name()
> + {
> + return "com.ubuntu.location.Service.Session.ErrorParsingUpdate";
> + }
> +};
> +
> +struct com::ubuntu::location::service::session::Interface::Errors::ErrorStartingUpdate
> +{
> + inline static std::string name()
> + {
> + return "com.ubuntu.location.Service.Session.ErrorStartingUpdate";
> + }
> +};
> +
> +namespace core
> +{
> +namespace dbus
> +{
> +namespace traits
> +{
> +template<>
> +struct Service<com::ubuntu::location::service::session::Interface>
> +{
> + static const std::string& interface_name()
> + {
> + static const std::string s
> + {
> + "com.ubuntu.location.Service.Session"
> + };
> + return s;
> + }
> +};
> +}
> +}
> +}
> +
> +#include <com/ubuntu/location/codec.h>
> +
> +#endif // LOCATION_SERVICE_COM_UBUNTU_LOCATION_SERVICE_SESSION_INTERFACE_P_H_
>
> === modified file 'src/location_service/com/ubuntu/location/service/session/skeleton.cpp'
> --- src/location_service/com/ubuntu/location/service/session/skeleton.cpp 2014-03-05 12:57:39 +0000
> +++ src/location_service/com/ubuntu/location/service/session/skeleton.cpp 2014-06-24 16:02:38 +0000
> @@ -15,7 +15,11 @@
> *
> * Authored by: Thomas Voß <thomas.voss at canonical.com>
> */
> -#include "com/ubuntu/location/service/session/skeleton.h"
> +#include <com/ubuntu/location/service/session/skeleton.h>
> +
> +#include <com/ubuntu/location/logging.h>
> +
> +#include "interface_p.h"
>
> #include <core/dbus/message.h>
> #include <core/dbus/object.h>
> @@ -29,172 +33,302 @@
>
> namespace dbus = core::dbus;
>
> -struct culss::Skeleton::Private
> -{
> - void handle_start_position_updates(const core::dbus::Message::Ptr& msg);
> - void handle_stop_position_updates(const core::dbus::Message::Ptr& msg);
> -
> - void handle_start_velocity_updates(const core::dbus::Message::Ptr& msg);
> - void handle_stop_velocity_updates(const core::dbus::Message::Ptr& msg);
> -
> - void handle_start_heading_updates(const core::dbus::Message::Ptr& msg);
> - void handle_stop_heading_updates(const core::dbus::Message::Ptr& msg);
> -
> - Skeleton* parent;
> - dbus::Bus::Ptr bus;
> - dbus::types::ObjectPath session_path;
> - dbus::Object::Ptr object;
> -};
> -
> -culss::Skeleton::Skeleton(
> - const dbus::Bus::Ptr& bus,
> - const dbus::types::ObjectPath& session_path)
> - : dbus::Skeleton<Interface>{bus},
> - d(new Private
> - {
> - this,
> - bus,
> - session_path,
> - access_service()->add_object_for_path(session_path)
> - })
> -{
> - d->object->install_method_handler<Interface::StartPositionUpdates>(
> - std::bind(&Skeleton::Private::handle_start_position_updates,
> - std::ref(d),
> - std::placeholders::_1));
> - d->object->install_method_handler<Interface::StopPositionUpdates>(
> - std::bind(&Skeleton::Private::handle_stop_position_updates,
> - std::ref(d),
> - std::placeholders::_1));
> - d->object->install_method_handler<Interface::StartVelocityUpdates>(
> - std::bind(&Skeleton::Private::handle_start_velocity_updates,
> - std::ref(d),
> - std::placeholders::_1));
> - d->object->install_method_handler<Interface::StopVelocityUpdates>(
> - std::bind(&Skeleton::Private::handle_stop_velocity_updates,
> - std::ref(d),
> - std::placeholders::_1));
> - d->object->install_method_handler<Interface::StartHeadingUpdates>(
> - std::bind(&Skeleton::Private::handle_start_heading_updates,
> - std::ref(d),
> - std::placeholders::_1));
> - d->object->install_method_handler<Interface::StopHeadingUpdates>(
> - std::bind(&Skeleton::Private::handle_stop_heading_updates,
> - std::ref(d),
> - std::placeholders::_1));
> +namespace
> +{
> +dbus::Message::Ptr the_empty_reply()
> +{
> + return dbus::Message::Ptr{};
> +}
> +}
> +
> +culss::Skeleton::Skeleton(const culss::Skeleton::Configuration& config)
> + : dbus::Skeleton<Interface>{config.local.bus},
> + configuration(config),
> + object(access_service()->add_object_for_path(configuration.path)),
> + connections
> + {
> + configuration.local.impl->updates().position.changed().connect(
> + [this](const cul::Update<cul::Position>& position)
> + {
> + on_position_changed(position);
> + }),
> + configuration.local.impl->updates().heading.changed().connect(
> + [this](const cul::Update<cul::Heading>& heading)
> + {
> + on_heading_changed(heading);
> + }),
> + configuration.local.impl->updates().velocity.changed().connect(
> + [this](const cul::Update<cul::Velocity>& velocity)
> + {
> + on_velocity_changed(velocity);
> + })
> + }
> +{
> + object->install_method_handler<Interface::StartPositionUpdates>([this](const dbus::Message::Ptr& msg)
> + {
> + on_start_position_updates(msg);
> + });
> +
> + object->install_method_handler<Interface::StopPositionUpdates>([this](const dbus::Message::Ptr& msg)
> + {
> + on_stop_position_updates(msg);
> + });
> +
> + object->install_method_handler<Interface::StartVelocityUpdates>([this](const dbus::Message::Ptr& msg)
> + {
> + on_start_velocity_updates(msg);
> + });
> +
> + object->install_method_handler<Interface::StopVelocityUpdates>([this](const dbus::Message::Ptr& msg)
> + {
> + on_stop_velocity_updates(msg);
> + });
> +
> + object->install_method_handler<Interface::StartHeadingUpdates>([this](const dbus::Message::Ptr& msg)
> + {
> + on_start_heading_updates(msg);
> + });
> +
> + object->install_method_handler<Interface::StopHeadingUpdates>([this](const dbus::Message::Ptr& msg)
> + {
> + on_stop_heading_updates(msg);
> + });
> }
>
> culss::Skeleton::~Skeleton() noexcept
> {
> - d->object->uninstall_method_handler<Interface::StartPositionUpdates>();
> - d->object->uninstall_method_handler<Interface::StopPositionUpdates>();
> - d->object->uninstall_method_handler<Interface::StartVelocityUpdates>();
> - d->object->uninstall_method_handler<Interface::StopVelocityUpdates>();
> - d->object->uninstall_method_handler<Interface::StartHeadingUpdates>();
> - d->object->uninstall_method_handler<Interface::StopHeadingUpdates>();
> + object->uninstall_method_handler<Interface::StartPositionUpdates>();
> + object->uninstall_method_handler<Interface::StopPositionUpdates>();
> + object->uninstall_method_handler<Interface::StartVelocityUpdates>();
> + object->uninstall_method_handler<Interface::StopVelocityUpdates>();
> + object->uninstall_method_handler<Interface::StartHeadingUpdates>();
> + object->uninstall_method_handler<Interface::StopHeadingUpdates>();
> +}
> +
> +void culss::Skeleton::on_start_position_updates(const core::dbus::Message::Ptr& msg)
> +{
> + VLOG(10) << "MethodHandler for Interface::StartPositionUpdates";
> +
> + auto reply = the_empty_reply();
> +
> + try
> + {
> + configuration.local.impl->updates().position_status = culss::Interface::Updates::Status::enabled;
> + reply = dbus::Message::make_method_return(msg);
> + } catch(const std::runtime_error& e)
> + {
> + // We only provide a generic error message to avoid leaking
> + // any sort of private data to unprivileged clients.
> + reply = core::dbus::Message::make_error(
> + msg,
> + Interface::Errors::ErrorStartingUpdate::name(),
> + "Could not enable position updates");
> + LOG(ERROR) << e.what();
> + }
> +
> + try
> + {
> + configuration.local.bus->send(reply);
> + } catch(const std::exception& e)
> + {
> + LOG(ERROR) << e.what();
> + }
> +}
> +
> +void culss::Skeleton::on_stop_position_updates(const core::dbus::Message::Ptr& msg)
> +{
> + VLOG(10) << "MethodHandler for Interface::StopPositionUpdates";
> + auto reply = the_empty_reply();
> +
> + try
> + {
> + configuration.local.impl->updates().position_status = culss::Interface::Updates::Status::disabled;
> + reply = dbus::Message::make_method_return(msg);
> + } catch(const std::runtime_error& e)
> + {
> + // We only provide a generic error message to avoid leaking
> + // any sort of private data to unprivileged clients.
> + reply = core::dbus::Message::make_error(
> + msg,
> + Interface::Errors::ErrorStartingUpdate::name(),
> + "Could not disable position updates");
> + LOG(ERROR) << e.what();
> + }
> +
> + try
> + {
> + configuration.local.bus->send(reply);
> + } catch(const std::exception& e)
> + {
> + LOG(ERROR) << e.what();
> + }
> +}
> +
> +void culss::Skeleton::on_start_heading_updates(const core::dbus::Message::Ptr& msg)
> +{
> + VLOG(10) << "MethodHandler for Interface::StartHeadingUpdates";
> + auto reply = the_empty_reply();
> +
> + try
> + {
> + configuration.local.impl->updates().position_status = culss::Interface::Updates::Status::enabled;
> + reply = dbus::Message::make_method_return(msg);
> + } catch(const std::runtime_error& e)
> + {
> + // We only provide a generic error message to avoid leaking
> + // any sort of private data to unprivileged clients.
> + reply = core::dbus::Message::make_error(
> + msg,
> + Interface::Errors::ErrorStartingUpdate::name(),
> + "Could not enable position updates");
> + LOG(ERROR) << e.what();
> + }
> +
> + try
> + {
> + configuration.local.bus->send(reply);
> + } catch(const std::exception& e)
> + {
> + LOG(ERROR) << e.what();
> + }
> +}
> +
> +void culss::Skeleton::on_stop_heading_updates(const core::dbus::Message::Ptr& msg)
> +{
> + VLOG(10) << "MethodHandler for Interface::StopHeadingUpdates";
> + auto reply = the_empty_reply();
> + try
> + {
> + configuration.local.impl->updates().heading_status = culss::Interface::Updates::Status::disabled;
> + reply = dbus::Message::make_method_return(msg);
> + } catch(const std::runtime_error& e)
> + {
> + // We only provide a generic error message to avoid leaking
> + // any sort of private data to unprivileged clients.
> + reply = core::dbus::Message::make_error(
> + msg,
> + Interface::Errors::ErrorStartingUpdate::name(),
> + "Could not enable position updates");
> + LOG(ERROR) << e.what();
> + }
> +
> + try
> + {
> + configuration.local.bus->send(reply);
> + } catch(const std::exception& e)
> + {
> + LOG(ERROR) << e.what();
> + }
> +}
> +
> +void culss::Skeleton::on_start_velocity_updates(const core::dbus::Message::Ptr& msg)
> +{
> + VLOG(10) << "MethodHandler for Interface::StartVelocityUpdates";
> + auto reply = the_empty_reply();
> + try
> + {
> + configuration.local.impl->updates().velocity_status = culss::Interface::Updates::Status::enabled;
> + reply = dbus::Message::make_method_return(msg);
> + } catch(const std::runtime_error& e)
> + {
> + // We only provide a generic error message to avoid leaking
> + // any sort of private data to unprivileged clients.
> + reply = core::dbus::Message::make_error(
> + msg,
> + Interface::Errors::ErrorStartingUpdate::name(),
> + "Could not enable position updates");
> + LOG(ERROR) << e.what();
> + }
> +
> + try
> + {
> + configuration.local.bus->send(reply);
> + } catch(const std::exception& e)
> + {
> + LOG(ERROR) << e.what();
> + }
> +}
> +
> +void culss::Skeleton::on_stop_velocity_updates(const core::dbus::Message::Ptr& msg)
> +{
> + VLOG(10) << "MethodHandler for Interface::StopVelocityUpdates";
> + auto reply = the_empty_reply();
> + try
> + {
> + configuration.local.impl->updates().velocity_status = culss::Interface::Updates::Status::disabled;
> + reply = dbus::Message::make_method_return(msg);
> + } catch(const std::runtime_error& e)
> + {
> + // We only provide a generic error message to avoid leaking
> + // any sort of private data to unprivileged clients.
> + reply = core::dbus::Message::make_error(
> + msg,
> + Interface::Errors::ErrorStartingUpdate::name(),
> + "Could not enable position updates");
> + LOG(ERROR) << e.what();
> + }
> +
> + try
> + {
> + configuration.local.bus->send(reply);
> + } catch(const std::exception& e)
> + {
> + LOG(ERROR) << e.what();
> + }
> +}
> +
> +// Invoked whenever the actual session impl. for the session reports a position update.
> +void culss::Skeleton::on_position_changed(const cul::Update<cul::Position>& position)
> +{
> + VLOG(10) << __PRETTY_FUNCTION__;
> + try
> + {
> + configuration.remote.object->invoke_method_synchronously<culs::session::Interface::UpdatePosition, void>(position);
> + } catch(const std::exception&)
> + {
> + // We consider the session to be dead once we hit an exception here.
> + // We thus remove it from the central and end its lifetime.
> + // on_session_died();
> + } catch(...)
> + {
> + }
> +}
> +
> +// Invoked whenever the actual session impl. reports a heading update.
> +void culss::Skeleton::on_heading_changed(const cul::Update<cul::Heading>& heading)
> +{
> + VLOG(10) << __PRETTY_FUNCTION__;
> + try
> + {
> + configuration.remote.object->invoke_method_synchronously<culs::session::Interface::UpdateHeading, void>(heading);
> + } catch(const std::exception&)
> + {
> + // We consider the session to be dead once we hit an exception here.
> + // We thus remove it from the central and end its lifetime.
> + //on_session_died();
> + } catch(...)
> + {
> + }
> +}
> +
> +// Invoked whenever the actual session impl. reports a velocity update.
> +void culss::Skeleton::on_velocity_changed(const cul::Update<cul::Velocity>& velocity)
> +{
> + VLOG(10) << __PRETTY_FUNCTION__;
> + try
> + {
> + configuration.remote.object->invoke_method_synchronously<culs::session::Interface::UpdateVelocity, void>(velocity);
> + } catch(const std::exception&)
> + {
> + // We consider the session to be dead once we hit an exception here.
> + // We thus remove it from the central and end its lifetime.
> + // on_session_died();
> + } catch(...)
> + {
> + }
> }
>
> const dbus::types::ObjectPath& culss::Skeleton::path() const
> {
> - return d->session_path;
> -}
> -
> -void culss::Skeleton::Private::handle_start_position_updates(const core::dbus::Message::Ptr& msg)
> -{
> - try
> - {
> - parent->start_position_updates();
> - auto reply = dbus::Message::make_method_return(msg);
> - bus->send(reply);
> - } catch(const std::runtime_error& e)
> - {
> - auto error = core::dbus::Message::make_error(
> - msg,
> - Interface::Errors::ErrorStartingUpdate::name(),
> - e.what());
> -
> - bus->send(error);
> - }
> -}
> -
> -void culss::Skeleton::Private::handle_stop_position_updates(const core::dbus::Message::Ptr& msg)
> -{
> - try
> - {
> - parent->stop_position_updates();
> - auto reply = core::dbus::Message::make_method_return(msg);
> - bus->send(reply);
> - } catch(const std::runtime_error& e)
> - {
> - auto error = core::dbus::Message::make_error(
> - msg,
> - Interface::Errors::ErrorStoppingUpdate::name(),
> - e.what());
> -
> - bus->send(error);
> - }
> -}
> -
> -void culss::Skeleton::Private::handle_start_velocity_updates(const core::dbus::Message::Ptr& msg)
> -{
> - try
> - {
> - parent->start_velocity_updates();
> - auto reply = core::dbus::Message::make_method_return(msg);
> - bus->send(reply);
> - } catch(const std::runtime_error& e)
> - {
> - auto error = core::dbus::Message::make_error(msg, Interface::Errors::ErrorStartingUpdate::name(), e.what());
> - bus->send(error);
> - }
> -}
> -
> -void culss::Skeleton::Private::handle_stop_velocity_updates(const core::dbus::Message::Ptr& msg)
> -{
> - try
> - {
> - parent->stop_velocity_updates();
> - auto reply = core::dbus::Message::make_method_return(msg);
> - bus->send(reply);
> - } catch(const std::runtime_error& e)
> - {
> - auto error = core::dbus::Message::make_error(
> - msg,
> - Interface::Errors::ErrorStoppingUpdate::name(),
> - e.what());
> -
> - bus->send(error);
> - }
> -}
> -
> -void culss::Skeleton::Private::handle_start_heading_updates(const core::dbus::Message::Ptr& msg)
> -{
> - try
> - {
> - parent->start_heading_updates();
> - auto reply = core::dbus::Message::make_method_return(msg);
> - bus->send(reply);
> - } catch(const std::runtime_error& e)
> - {
> - auto error = core::dbus::Message::make_error(msg, Interface::Errors::ErrorStartingUpdate::name(), e.what());
> - bus->send(error);
> - }
> -}
> -
> -void culss::Skeleton::Private::handle_stop_heading_updates(const core::dbus::Message::Ptr& msg)
> -{
> - try
> - {
> - parent->stop_heading_updates();
> - auto reply = core::dbus::Message::make_method_return(msg);
> - bus->send(reply);
> - } catch(const std::runtime_error& e)
> - {
> - auto error = core::dbus::Message::make_error(
> - msg,
> - Interface::Errors::ErrorStoppingUpdate::name(),
> - e.what());
> -
> - bus->send(error);
> - }
> + return configuration.path;
> }
>
> === modified file 'src/location_service/com/ubuntu/location/service/session/stub.cpp'
> --- src/location_service/com/ubuntu/location/service/session/stub.cpp 2014-03-05 12:57:39 +0000
> +++ src/location_service/com/ubuntu/location/service/session/stub.cpp 2014-06-24 16:02:38 +0000
> @@ -16,9 +16,11 @@
> * Authored by: Thomas Voß <thomas.voss at canonical.com>
> */
>
> -#include "com/ubuntu/location/service/session/stub.h"
> -
> -#include "com/ubuntu/location/logging.h"
> +#include <com/ubuntu/location/service/session/stub.h>
> +
> +#include "interface_p.h"
> +
> +#include <com/ubuntu/location/logging.h>
>
> #include <core/dbus/stub.h>
>
> @@ -32,21 +34,65 @@
>
> struct culss::Stub::Private
> {
> - void update_heading(const core::dbus::Message::Ptr& msg);
> - void update_position(const core::dbus::Message::Ptr& msg);
> - void update_velocity(const core::dbus::Message::Ptr& msg);
> + Private(Stub* parent,
> + const dbus::types::ObjectPath& path,
> + const dbus::Object::Ptr& object,
> + const core::Connection& position,
> + const core::Connection& velocity,
> + const core::Connection& heading)
> + : parent(parent),
> + session_path(path),
> + object(object),
> + position(position),
> + velocity(velocity),
> + heading(heading)
> + {
> + }
> +
> + void update_heading(const dbus::Message::Ptr& msg);
> + void update_position(const dbus::Message::Ptr& msg);
> + void update_velocity(const dbus::Message::Ptr& msg);
>
> Stub* parent;
> dbus::types::ObjectPath session_path;
> dbus::Object::Ptr object;
> + core::ScopedConnection position;
> + core::ScopedConnection velocity;
> + core::ScopedConnection heading;
> +
> };
>
> culss::Stub::Stub(const dbus::Bus::Ptr& bus,
> const dbus::types::ObjectPath& session_path)
> : dbus::Stub<culss::Interface>(bus),
> - d(new Private{this,
> - session_path,
> - access_service()->add_object_for_path(session_path)})
> + d(new Private(this,
> + session_path,
> + access_service()->add_object_for_path(session_path),
> + updates().position_status.changed().connect([this](const Interface::Updates::Status& status)
> + {
> + switch(status)
> + {
> + case Interface::Updates::Status::enabled: start_position_updates(); break;
> + case Interface::Updates::Status::disabled: stop_position_updates(); break;
> + }
> + }),
> + updates().velocity_status.changed().connect([this](const Interface::Updates::Status& status)
> + {
> + switch(status)
> + {
> + case Interface::Updates::Status::enabled: start_velocity_updates(); break;
> + case Interface::Updates::Status::disabled: stop_velocity_updates(); break;
> + }
> + }),
> + updates().heading_status.changed().connect([this](const Interface::Updates::Status& status)
> + {
> + switch(status)
> + {
> + case Interface::Updates::Status::enabled: start_heading_updates(); break;
> + case Interface::Updates::Status::disabled: stop_heading_updates(); break;
> + }
> + })
> + ))
> {
> d->object->install_method_handler<culss::Interface::UpdatePosition>(
> std::bind(&Stub::Private::update_position,
> @@ -62,7 +108,18 @@
> std::placeholders::_1));
> }
>
> -culss::Stub::~Stub() noexcept {}
> +culss::Stub::~Stub() noexcept
> +{
> + VLOG(10) << __PRETTY_FUNCTION__;
> +
> + //stop_position_updates();
> + //stop_heading_updates();
> + //stop_velocity_updates();
> +
> + d->object->uninstall_method_handler<culss::Interface::UpdatePosition>();
> + d->object->uninstall_method_handler<culss::Interface::UpdateHeading>();
> + d->object->uninstall_method_handler<culss::Interface::UpdateVelocity>();
> +}
>
> const dbus::types::ObjectPath& culss::Stub::path() const
> {
> @@ -71,19 +128,30 @@
>
> void culss::Stub::start_position_updates()
> {
> + VLOG(10) << __PRETTY_FUNCTION__;
> +
> auto result = d->object->transact_method<Interface::StartPositionUpdates,void>();
>
> if (result.is_error())
> - throw std::runtime_error(result.error().print());
> + {
> + std::stringstream ss; ss << __PRETTY_FUNCTION__ << ": " << result.error().print();
> + throw std::runtime_error(ss.str());
> + }
> }
>
> void culss::Stub::stop_position_updates() noexcept
> {
> - try {
> - auto result = d->object->transact_method<Interface::StopPositionUpdates,void>();
> + VLOG(10) << __PRETTY_FUNCTION__;
> +
> + try
> + {
> + auto result = d->object->invoke_method_synchronously<Interface::StopPositionUpdates,void>();
>
> if (result.is_error())
> - LOG(WARNING) << result.error();
> + {
> + std::stringstream ss; ss << __PRETTY_FUNCTION__ << ": " << result.error().print();
> + throw std::runtime_error(ss.str());
> + }
> } catch(const std::runtime_error& e)
> {
> LOG(WARNING) << e.what();
> @@ -92,19 +160,29 @@
>
> void culss::Stub::start_velocity_updates()
> {
> + VLOG(10) << __PRETTY_FUNCTION__;
> +
> auto result = d->object->transact_method<Interface::StartVelocityUpdates,void>();
>
> if (result.is_error())
> - throw std::runtime_error(result.error().print());
> + {
> + std::stringstream ss; ss << __PRETTY_FUNCTION__ << ": " << result.error().print();
> + throw std::runtime_error(ss.str());
> + }
> }
>
> void culss::Stub::stop_velocity_updates() noexcept
> {
> + VLOG(10) << __PRETTY_FUNCTION__;
> +
> try {
> auto result = d->object->transact_method<Interface::StopVelocityUpdates,void>();
>
> if (result.is_error())
> - LOG(WARNING) << result.error();
> + {
> + std::stringstream ss; ss << __PRETTY_FUNCTION__ << ": " << result.error().print();
> + throw std::runtime_error(ss.str());
> + }
> } catch(const std::runtime_error& e)
> {
> LOG(WARNING) << e.what();
> @@ -113,60 +191,88 @@
>
> void culss::Stub::start_heading_updates()
> {
> + VLOG(10) << __PRETTY_FUNCTION__;
> +
> auto result = d->object->transact_method<Interface::StartHeadingUpdates,void>();
>
> if (result.is_error())
> - throw std::runtime_error(result.error().print());
> + {
> + std::stringstream ss; ss << __PRETTY_FUNCTION__ << ": " << result.error().print();
> + throw std::runtime_error(ss.str());
> + }
> }
>
> void culss::Stub::stop_heading_updates() noexcept
> {
> + VLOG(10) << __PRETTY_FUNCTION__;
> +
> try {
> auto result = d->object->transact_method<Interface::StopHeadingUpdates,void>();
>
> if (result.is_error())
> - LOG(WARNING) << result.error();
> + {
> + std::stringstream ss; ss << __PRETTY_FUNCTION__ << ": " << result.error().print();
> + throw std::runtime_error(ss.str());
> + }
> } catch(const std::runtime_error& e)
> {
> LOG(WARNING) << e.what();
> }
> }
>
> -void culss::Stub::Private::update_heading(const core::dbus::Message::Ptr& incoming)
> +void culss::Stub::Private::update_heading(const dbus::Message::Ptr& incoming)
> {
> + VLOG(10) << __PRETTY_FUNCTION__;
> +
> try
> {
> Update<Heading> update; incoming->reader() >> update;
> - parent->access_heading_updates_channel()(update);
> + parent->updates().heading = update;
> parent->access_bus()->send(dbus::Message::make_method_return(incoming));
> } catch(const std::runtime_error& e)
> {
> - parent->access_bus()->send(dbus::Message::make_error(incoming, Interface::Errors::ErrorParsingUpdate::name(), e.what()));
> + parent->access_bus()->send(
> + dbus::Message::make_error(
> + incoming,
> + Interface::Errors::ErrorParsingUpdate::name(),
> + e.what()));
> }
> }
>
> -void culss::Stub::Private::update_position(const core::dbus::Message::Ptr& incoming)
> +void culss::Stub::Private::update_position(const dbus::Message::Ptr& incoming)
> {
> + VLOG(10) << __PRETTY_FUNCTION__;
> +
> try
> {
> Update<Position> update; incoming->reader() >> update;
> - parent->access_position_updates_channel()(update);
> + parent->updates().position = update;
> parent->access_bus()->send(dbus::Message::make_method_return(incoming));
> } catch(const std::runtime_error& e)
> {
> - parent->access_bus()->send(dbus::Message::make_error(incoming, Interface::Errors::ErrorParsingUpdate::name(), e.what()));
> + parent->access_bus()->send(
> + dbus::Message::make_error(
> + incoming,
> + Interface::Errors::ErrorParsingUpdate::name(),
> + e.what()));
> }
> }
>
> -void culss::Stub::Private::update_velocity(const core::dbus::Message::Ptr& incoming)
> +void culss::Stub::Private::update_velocity(const dbus::Message::Ptr& incoming)
> {
> + VLOG(10) << __PRETTY_FUNCTION__;
> +
> try
> {
> Update<Velocity> update; incoming->reader() >> update;
> - parent->access_velocity_updates_channel()(update);
> + parent->updates().velocity = update;
> parent->access_bus()->send(dbus::Message::make_method_return(incoming));
> } catch(const std::runtime_error& e)
> {
> - parent->access_bus()->send(dbus::Message::make_error(incoming, Interface::Errors::ErrorParsingUpdate::name(), e.what()));
> + parent->access_bus()->send(
> + dbus::Message::make_error(
> + incoming,
> + Interface::Errors::ErrorParsingUpdate::name(),
> + e.what()));
> }
> }
>
> === modified file 'src/location_service/com/ubuntu/location/service/skeleton.cpp'
> --- src/location_service/com/ubuntu/location/service/skeleton.cpp 2014-03-05 13:09:17 +0000
> +++ src/location_service/com/ubuntu/location/service/skeleton.cpp 2014-06-24 16:02:38 +0000
> @@ -15,13 +15,11 @@
> *
> * Authored by: Thomas Voß <thomas.voss at canonical.com>
> */
> -#include "com/ubuntu/location/service/skeleton.h"
> -
> -#include "com/ubuntu/location/logging.h"
> -
> -#include <core/dbus/dbus.h>
> -#include <core/dbus/object.h>
> -#include <core/dbus/skeleton.h>
> +#include <com/ubuntu/location/service/skeleton.h>
> +#include <com/ubuntu/location/service/session/skeleton.h>
> +
> +#include <com/ubuntu/location/logging.h>
> +
> #include <core/dbus/types/object_path.h>
>
> namespace cul = com::ubuntu::location;
> @@ -32,220 +30,169 @@
>
> namespace
> {
> -
> -template<typename SessionType>
> -struct SessionStore
> -{
> - typedef std::shared_ptr<SessionStore> Ptr;
> -
> - SessionStore() = default;
> - SessionStore(const SessionStore&) = delete;
> - SessionStore& operator=(const SessionStore&) = delete;
> - virtual ~SessionStore() = default;
> -
> - virtual void remove_session(const std::shared_ptr<SessionType>& session) = 0;
> -};
> -
> -struct SessionWrapper : public std::enable_shared_from_this<SessionWrapper>
> -{
> - typedef std::shared_ptr<SessionWrapper> Ptr;
> -
> - SessionWrapper(const SessionStore<SessionWrapper>::Ptr& session_store,
> - const culss::Interface::Ptr& session,
> - core::dbus::Service::Ptr service,
> - core::dbus::Object::Ptr object)
> - : session_store(session_store),
> - session{session},
> - remote(service, object)
> - {
> - session->install_position_updates_handler(std::bind(&SessionWrapper::on_position_update, this, std::placeholders::_1));
> - session->install_velocity_updates_handler(std::bind(&SessionWrapper::on_velocity_update, this, std::placeholders::_1));
> - session->install_heading_updates_handler(std::bind(&SessionWrapper::on_heading_update, this, std::placeholders::_1));
> - }
> -
> - const core::dbus::types::ObjectPath& path() const
> - {
> - return session->path();
> - }
> -
> - void on_session_died() noexcept
> - {
> - std::cout << __PRETTY_FUNCTION__ << std::endl;
> - VLOG(1) << "Session died, removing from store and stopping all updates.";
> -
> - auto thiz = shared_from_this();
> - try
> - {
> - session_store->remove_session(thiz);
> - session->stop_position_updates();
> - session->stop_heading_updates();
> - session->stop_velocity_updates();
> - } catch(const std::runtime_error& e)
> - {
> - LOG(ERROR) << "Error while stopping updates for died session: " << e.what();
> - }
> - }
> -
> - void on_position_update(const cul::Update<cul::Position>& position)
> - {
> - try
> - {
> - auto result = remote.session->transact_method<culs::session::Interface::UpdatePosition, void>(position);
> - if (result.is_error())
> - {
> - LOG(ERROR) << result.error().print();
> - on_session_died();
> - }
> - } catch(const std::runtime_error& e)
> - {
> - // We consider the session to be dead once we hit an exception here.
> - // We thus remove it from the central and end its lifetime.
> - on_session_died();
> - }
> - }
> -
> - void on_velocity_update(const cul::Update<cul::Velocity>& velocity)
> - {
> - try
> - {
> - auto result = remote.session->transact_method<culs::session::Interface::UpdateVelocity, void>(velocity);
> - if (result.is_error())
> - {
> - LOG(ERROR) << result.error().print();
> - on_session_died();
> - }
> - } catch(const std::runtime_error& e)
> - {
> - // We consider the session to be dead once we hit an exception here.
> - // We thus remove it from the central and end its lifetime.
> - on_session_died();
> - }
> - }
> -
> - void on_heading_update(const cul::Update<cul::Heading>& heading)
> - {
> - try
> - {
> - auto result = remote.session->transact_method<culs::session::Interface::UpdateHeading, void>(heading);
> - if (result.is_error())
> - {
> - LOG(ERROR) << result.error().print();
> - on_session_died();
> - }
> - } catch(const std::runtime_error& e)
> - {
> - // We consider the session to be dead once we hit an exception here.
> - // We thus remove it from the central and end its lifetime.
> - on_session_died();
> - }
> - }
> -
> - SessionStore<SessionWrapper>::Ptr session_store;
> - culs::session::Interface::Ptr session;
> - struct Remote
> - {
> - explicit Remote(const dbus::Service::Ptr& service,
> - const dbus::Object::Ptr& session)
> - : service(service),
> - session(session)
> - {
> - }
> -
> - dbus::Service::Ptr service;
> - dbus::Object::Ptr session;
> - } remote;
> -};
> -}
> -
> -struct culs::Skeleton::Private : public SessionStore<SessionWrapper>, std::enable_shared_from_this<culs::Skeleton::Private>
> -{
> - Private(Skeleton* parent, const dbus::Bus::Ptr& connection, const culs::PermissionManager::Ptr& permission_manager)
> - : parent(parent),
> - permission_manager(permission_manager),
> - daemon(connection),
> - object(parent->access_service()->add_object_for_path(culs::Interface::path()))
> - {
> - object->install_method_handler<culs::Interface::CreateSessionForCriteria>(
> - std::bind(&culs::Skeleton::Private::handle_create_session_for_criteria, this, std::placeholders::_1));
> - }
> -
> - ~Private() noexcept {}
> -
> - void handle_create_session_for_criteria(const core::dbus::Message::Ptr& in);
> - void remove_session(const std::shared_ptr<SessionWrapper>& session);
> -
> - Skeleton* parent;
> - PermissionManager::Ptr permission_manager;
> - dbus::DBus daemon;
> - dbus::Object::Ptr object;
> - std::mutex guard;
> - std::map<dbus::types::ObjectPath, std::shared_ptr<SessionWrapper>> session_store;
> -};
> -
> -culs::Skeleton::Skeleton(const dbus::Bus::Ptr& connection, const culs::PermissionManager::Ptr& permission_manager)
> - : dbus::Skeleton<culs::Interface>(connection), d{new Private{this, connection, permission_manager}}
> -{
> +dbus::Message::Ptr the_empty_reply()
> +{
> + return dbus::Message::Ptr{};
> +}
> +}
> +
> +culs::Skeleton::DBusDaemonCredentialsResolver::DBusDaemonCredentialsResolver(const dbus::Bus::Ptr& bus)
> + : daemon(bus)
> +{
> +}
> +
> +culs::Credentials
> +culs::Skeleton::DBusDaemonCredentialsResolver::resolve_credentials_for_incoming_message(const dbus::Message::Ptr& msg)
> +{
> + return culs::Credentials
> + {
> + daemon.get_connection_unix_process_id(msg->sender()),
> + daemon.get_connection_unix_user(msg->sender())
> + };
> +}
> +
> +core::dbus::types::ObjectPath culs::Skeleton::ObjectPathGenerator::object_path_for_caller_credentials(const culs::Credentials&)
> +{
> + static std::uint32_t index{0};
> + std::stringstream ss; ss << "/sessions/" << index++;
> +
> + return core::dbus::types::ObjectPath{ss.str()};
> +}
> +
> +
> +culs::Skeleton::Skeleton(const culs::Skeleton::Configuration& configuration)
> + : dbus::Skeleton<culs::Interface>(configuration.incoming),
> + configuration(configuration),
> + object(access_service()->add_object_for_path(culs::Interface::path())),
> + properties
> + {
> + object->get_property<culs::Interface::Properties::DoesSatelliteBasedPositioning>(),
> + object->get_property<culs::Interface::Properties::DoesReportCellAndWifiIds>(),
> + object->get_property<culs::Interface::Properties::IsOnline>(),
> + object->get_property<culs::Interface::Properties::VisibleSpaceVehicles>()
> + }
> +{
> + object->install_method_handler<culs::Interface::CreateSessionForCriteria>([this](const dbus::Message::Ptr& msg)
> + {
> + handle_create_session_for_criteria(msg);
> + });
> }
>
> culs::Skeleton::~Skeleton() noexcept
> {
> + object->uninstall_method_handler<culs::Interface::CreateSessionForCriteria>();
> }
>
> -void culs::Skeleton::Private::handle_create_session_for_criteria(const core::dbus::Message::Ptr& in)
> +void culs::Skeleton::handle_create_session_for_criteria(const dbus::Message::Ptr& in)
> {
> + VLOG(1) << __PRETTY_FUNCTION__;
> +
> auto sender = in->sender();
> + auto reply = the_empty_reply();
>
> try
> {
> - Criteria criteria;
> - in->reader() >> criteria;
> -
> - Credentials credentials
> - {
> - static_cast<pid_t>(daemon.get_connection_unix_process_id(sender)),
> - static_cast<uid_t>(daemon.get_connection_unix_user(sender))
> - };
> -
> - if (PermissionManager::Result::rejected == permission_manager->check_permission_for_credentials(criteria, credentials))
> - throw std::runtime_error("Client lacks permissions to access the service with the given criteria");
> -
> - auto session = parent->create_session_for_criteria(criteria);
> -
> - auto service = dbus::Service::use_service(parent->access_bus(), in->sender());
> - auto object = service->object_for_path(session->path());
> -
> + Criteria criteria;
> + in->reader() >> criteria;
> +
> + auto credentials =
> + configuration.credentials_resolver->resolve_credentials_for_incoming_message(in);
> +
> + auto result =
> + configuration.permission_manager->check_permission_for_credentials(criteria, credentials);
> +
> + if (PermissionManager::Result::rejected == result) throw std::runtime_error
> + {
> + "Client lacks permissions to access the service with the given criteria"
> + };
> +
> + auto path =
> + configuration.object_path_generator->object_path_for_caller_credentials(credentials);
> +
> + auto stub =
> + dbus::Service::use_service(configuration.outgoing, sender);
> +
> + culss::Skeleton::Configuration config
> + {
> + path,
> + culss::Skeleton::Local
> + {
> + create_session_for_criteria(criteria),
> + configuration.incoming
> + },
> + culss::Skeleton::Remote
> + {
> + stub->object_for_path(path)
> + }
> + };
> +
> + culss::Interface::Ptr session
> + {
> + new culss::Skeleton{config}
> + };
> +
> + if (not add_to_session_store_for_path(path, session))
> + {
> + reply = dbus::Message::make_error(
> + in,
> + culs::Interface::Errors::CreatingSession::name(),
> + "Refused to create second session for same process");
> + } else
> + {
> + reply = dbus::Message::make_method_return(in);
> + reply->writer() << path;
> + }
> +
> + } catch(const std::exception& e)
> {
> - std::lock_guard<std::mutex> lg(guard);
> -
> - auto wrapper = SessionWrapper::Ptr{new SessionWrapper{shared_from_this(), session, service, object}};
> -
> - bool inserted = false;
> - std::tie(std::ignore, inserted) = session_store.insert(std::make_pair(session->path(), wrapper));
> -
> - auto reply = dbus::Message::make_method_return(in);
> - reply->writer() << session->path();
> - parent->access_bus()->send(reply);
> -
> - if (!inserted)
> - throw std::runtime_error("Could not insert duplicate session into store.");
> + // We only send a very generic error message to the client to avoid
> + // leaking any sort of internal error handling details to untrusted
> + // apps.
> + reply = dbus::Message::make_error(
> + in,
> + culs::Interface::Errors::CreatingSession::name(),
> + "Error creating session");
> + // We log the error for debugging purposes.
> + LOG(ERROR) << "Error creating session: " << e.what();
> }
>
> - } catch(const std::runtime_error& e)
> - {
> - parent->access_bus()->send(
> - dbus::Message::make_error(
> - in,
> - culs::Interface::Errors::CreatingSession::name(),
> - e.what()));
> -
> - LOG(ERROR) << "Error creating session: " << e.what();
> + // We are done processing the request and try to send out the result to the client.
> + try
> + {
> + configuration.incoming->send(reply);
> + } catch(const std::exception& e)
> + {
> + // We log the error for debugging purposes.
> + LOG(ERROR) << "Error sending reply to session creation request: " << e.what();
> }
> }
>
> -void culs::Skeleton::Private::remove_session(const SessionWrapper::Ptr& session)
> +bool culs::Skeleton::add_to_session_store_for_path(
> + const core::dbus::types::ObjectPath& path,
> + const culss::Interface::Ptr& session)
> {
> std::lock_guard<std::mutex> lg(guard);
> - session_store.erase(session->path());
> -
> - VLOG(1) << "# of session in session store: " << session_store.size() << std::endl;
> + bool inserted = false;
> + std::tie(std::ignore, inserted) = session_store.insert(std::make_pair(path, session));
> + return inserted;
> +}
> +
> +core::Property<bool>& culs::Skeleton::does_satellite_based_positioning()
> +{
> + return *properties.does_satellite_based_positioning;
> +}
> +
> +core::Property<bool>& culs::Skeleton::does_report_cell_and_wifi_ids()
> +{
> + return *properties.does_report_cell_and_wifi_ids;
> +}
> +
> +core::Property<bool>& culs::Skeleton::is_online()
> +{
> + return *properties.is_online;
> +}
> +
> +core::Property<std::map<cul::SpaceVehicle::Key, cul::SpaceVehicle>>& culs::Skeleton::visible_space_vehicles()
> +{
> + return *properties.visible_space_vehicles;
> }
>
> === modified file 'src/location_service/com/ubuntu/location/service/stub.cpp'
> --- src/location_service/com/ubuntu/location/service/stub.cpp 2014-03-05 12:57:39 +0000
> +++ src/location_service/com/ubuntu/location/service/stub.cpp 2014-06-24 16:02:38 +0000
> @@ -15,10 +15,12 @@
> *
> * Authored by: Thomas Voß <thomas.voss at canonical.com>
> */
> -#include "com/ubuntu/location/service/stub.h"
> -#include "com/ubuntu/location/service/session/stub.h"
> -
> -#include "com/ubuntu/location/logging.h"
> +#include <com/ubuntu/location/service/stub.h>
> +#include <com/ubuntu/location/service/session/stub.h>
> +
> +#include <com/ubuntu/location/logging.h>
> +
> +#include <core/dbus/property.h>
>
> namespace cul = com::ubuntu::location;
> namespace culs = com::ubuntu::location::service;
> @@ -28,8 +30,23 @@
>
> struct culs::Stub::Private
> {
> - core::dbus::Bus::Ptr bus;
> - core::dbus::Object::Ptr object;
> + Private(const dbus::Bus::Ptr& connection,
> + const dbus::Object::Ptr& object)
> + : bus(connection),
> + object(object),
> + does_satellite_based_positioning(object->get_property<culs::Interface::Properties::DoesSatelliteBasedPositioning>()),
> + does_report_cell_and_wifi_ids(object->get_property<culs::Interface::Properties::DoesReportCellAndWifiIds>()),
> + is_online(object->get_property<culs::Interface::Properties::IsOnline>()),
> + visible_space_vehicles(object->get_property<culs::Interface::Properties::VisibleSpaceVehicles>())
> + {
> + }
> +
> + dbus::Bus::Ptr bus;
> + dbus::Object::Ptr object;
> + std::shared_ptr<dbus::Property<culs::Interface::Properties::DoesSatelliteBasedPositioning>> does_satellite_based_positioning;
> + std::shared_ptr<dbus::Property<culs::Interface::Properties::DoesReportCellAndWifiIds>> does_report_cell_and_wifi_ids;
> + std::shared_ptr<dbus::Property<culs::Interface::Properties::IsOnline>> is_online;
> + std::shared_ptr<dbus::Property<culs::Interface::Properties::VisibleSpaceVehicles>> visible_space_vehicles;
> };
>
> culs::Stub::Stub(const dbus::Bus::Ptr& connection) : dbus::Stub<culs::Interface>(connection),
> @@ -44,12 +61,35 @@
> culss::Interface::Ptr culs::Stub::create_session_for_criteria(const cul::Criteria& criteria)
> {
> auto op = d->object->transact_method<
> - culs::Interface::CreateSessionForCriteria,
> - culs::Interface::CreateSessionForCriteria::ResultType
> - >(criteria);
> + culs::Interface::CreateSessionForCriteria,
> + culs::Interface::CreateSessionForCriteria::ResultType
> + >(criteria);
>
> if (op.is_error())
> - throw std::runtime_error(op.error().print());
> + {
> + std::stringstream ss; ss << __PRETTY_FUNCTION__ << ": " << op.error().print();
> + throw std::runtime_error(ss.str());
> + }
>
> return culss::Interface::Ptr(new culss::Stub{d->bus, op.value()});
> }
> +
> +core::Property<bool>& culs::Stub::does_satellite_based_positioning()
> +{
> + return *d->does_satellite_based_positioning;
> +}
> +
> +core::Property<bool>& culs::Stub::does_report_cell_and_wifi_ids()
> +{
> + return *d->does_report_cell_and_wifi_ids;
> +}
> +
> +core::Property<bool>& culs::Stub::is_online()
> +{
> + return *d->is_online;
> +}
> +
> +core::Property<std::map<cul::SpaceVehicle::Key, cul::SpaceVehicle>>& culs::Stub::visible_space_vehicles()
> +{
> + return *d->visible_space_vehicles;
> +}
>
> === added file 'src/location_service/com/ubuntu/location/set_name_for_thread.cpp'
> --- src/location_service/com/ubuntu/location/set_name_for_thread.cpp 1970-01-01 00:00:00 +0000
> +++ src/location_service/com/ubuntu/location/set_name_for_thread.cpp 2014-06-24 16:02:38 +0000
> @@ -0,0 +1,24 @@
> +/*
> + * Copyright © 2012-2013 Canonical Ltd.
> + *
> + * This program is free software: you can redistribute it and/or modify it
> + * under the terms of the GNU Lesser General Public License version 3,
> + * 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 Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public License
> + * along with this program. If not, see <http://www.gnu.org/licenses/>.
> + *
> + * Authored by: Thomas Voß <thomas.voss at canonical.com>
> + */
> +
> +#include "set_name_for_thread.h"
> +
> +void com::ubuntu::location::set_name_for_thread(std::thread& t, const char* name)
> +{
> + pthread_setname_np(t.native_handle(), name);
> +}
>
> === added file 'src/location_service/com/ubuntu/location/set_name_for_thread.h'
> --- src/location_service/com/ubuntu/location/set_name_for_thread.h 1970-01-01 00:00:00 +0000
> +++ src/location_service/com/ubuntu/location/set_name_for_thread.h 2014-06-24 16:02:38 +0000
> @@ -0,0 +1,34 @@
> +/*
> + * Copyright © 2012-2013 Canonical Ltd.
> + *
> + * This program is free software: you can redistribute it and/or modify it
> + * under the terms of the GNU Lesser General Public License version 3,
> + * 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 Lesser G
--
https://code.launchpad.net/~thomas-voss/location-service/add_controller_and_service_configuration/+merge/204490
Your team Ubuntu Phablet Team is subscribed to branch lp:location-service.
More information about the Ubuntu-reviews
mailing list