Merge lp:~thomas-voss/location-service/generalize-glue-code-for-agps-operation into lp:location-service/trunk

Proposed by Thomas Voß on 2016-03-10
Status: Needs review
Proposed branch: lp:~thomas-voss/location-service/generalize-glue-code-for-agps-operation
Merge into: lp:location-service/trunk
Prerequisite: lp:~thomas-voss/location-service/enable-dual-landing
Diff against target: 5020 lines (+4045/-151) (has conflicts)
52 files modified
3rd-party/boost/core/scoped_enum.hpp (+192/-0)
3rd-party/boost/endian/arithmetic.hpp (+413/-0)
3rd-party/boost/endian/buffers.hpp (+515/-0)
3rd-party/boost/endian/conversion.hpp (+487/-0)
3rd-party/boost/endian/detail/config.hpp (+62/-0)
3rd-party/boost/endian/detail/cover_operators.hpp (+142/-0)
3rd-party/boost/endian/detail/disable_warnings.hpp (+33/-0)
3rd-party/boost/endian/detail/disable_warnings_pop.hpp (+12/-0)
3rd-party/boost/endian/detail/intrinsic.hpp (+64/-0)
3rd-party/boost/endian/detail/lightweight_test.hpp (+223/-0)
3rd-party/boost/endian/endian.hpp (+19/-0)
3rd-party/boost/endian/std_pair.hpp (+38/-0)
CMakeLists.txt (+3/-0)
debian/changelog (+23/-0)
debian/source/format (+1/-1)
examples/service/service.cpp (+14/-15)
include/location_service/com/ubuntu/location/connectivity/manager.h (+21/-0)
include/location_service/com/ubuntu/location/provider_factory.h (+3/-0)
po/ubuntu-location-service.pot (+7/-11)
src/location_service/com/ubuntu/location/CMakeLists.txt (+8/-0)
src/location_service/com/ubuntu/location/connectivity/ofono.h (+115/-1)
src/location_service/com/ubuntu/location/connectivity/ofono_nm_connectivity_manager.cpp (+30/-2)
src/location_service/com/ubuntu/location/connectivity/ofono_nm_connectivity_manager.h (+5/-1)
src/location_service/com/ubuntu/location/provider_factory.cpp (+14/-0)
src/location_service/com/ubuntu/location/providers/config.cpp (+7/-0)
src/location_service/com/ubuntu/location/providers/dummy/CMakeLists.txt (+3/-1)
src/location_service/com/ubuntu/location/providers/dummy/delayed_provider.cpp (+42/-0)
src/location_service/com/ubuntu/location/providers/dummy/delayed_provider.h (+62/-0)
src/location_service/com/ubuntu/location/providers/gps/CMakeLists.txt (+13/-10)
src/location_service/com/ubuntu/location/providers/gps/android_hardware_abstraction_layer.cpp (+122/-30)
src/location_service/com/ubuntu/location/providers/gps/android_hardware_abstraction_layer.h (+34/-5)
src/location_service/com/ubuntu/location/providers/gps/hardware_abstraction_layer.cpp (+30/-0)
src/location_service/com/ubuntu/location/providers/gps/hardware_abstraction_layer.h (+35/-4)
src/location_service/com/ubuntu/location/providers/gps/sntp_client.cpp (+210/-0)
src/location_service/com/ubuntu/location/providers/gps/sntp_client.h (+210/-0)
src/location_service/com/ubuntu/location/providers/gps/sntp_reference_time_source.cpp (+57/-0)
src/location_service/com/ubuntu/location/providers/gps/sntp_reference_time_source.h (+51/-0)
src/location_service/com/ubuntu/location/providers/remote/provider.cpp (+23/-0)
src/location_service/com/ubuntu/location/service/daemon.cpp (+16/-19)
src/location_service/com/ubuntu/location/service/implementation.cpp (+6/-4)
src/location_service/com/ubuntu/location/service/provider_daemon.cpp (+1/-1)
src/location_service/com/ubuntu/location/service/runtime.h (+1/-1)
src/location_service/com/ubuntu/location/service/runtime_tests.cpp (+125/-29)
src/location_service/com/ubuntu/location/service/trust_store_permission_manager.cpp (+1/-1)
src/location_service/com/ubuntu/location/time_since_boot.cpp (+140/-0)
src/location_service/com/ubuntu/location/time_since_boot.h (+35/-0)
tests/CMakeLists.txt (+2/-0)
tests/delayed_service_test.cpp (+193/-0)
tests/gps_provider_test.cpp (+42/-8)
tests/mock_event_receiver.h (+35/-0)
tests/remote_providerd_test.cpp (+1/-7)
tests/sntp_client_test.cpp (+104/-0)
Text conflict in debian/changelog
To merge this branch: bzr merge lp:~thomas-voss/location-service/generalize-glue-code-for-agps-operation
Reviewer Review Type Date Requested Status
PS Jenkins bot continuous-integration Needs Fixing on 2016-03-17
Ubuntu Phablet Team 2016-03-10 Pending
Review via email: mp+288705@code.launchpad.net

This proposal supersedes a proposal from 2016-03-10.

Commit message

This is the first MP in a series to generalize AGPS behavior. Here, we wire up
incoming RIL-specific requests and respond to them by reaching out to our Ofono-based telephony stack.

Description of the change

This is the first MP in a series to generalize AGPS behavior. Here, we wire up
incoming RIL-specific requests and respond to them by reaching out to our Ofono-based telephony stack.

To post a comment you must log in.
230. By Thomas Voß on 2016-03-11

Log individual imsi/msisdn callback invocations.

231. By Thomas Voß on 2016-03-15

Extend runtime test cases to cover agps use cases.

232. By Thomas Voß on 2016-03-17

Clean up event connections after each trial.
Adjust terminal output.

Unmerged revisions

232. By Thomas Voß on 2016-03-17

Clean up event connections after each trial.
Adjust terminal output.

231. By Thomas Voß on 2016-03-15

Extend runtime test cases to cover agps use cases.

230. By Thomas Voß on 2016-03-11

Log individual imsi/msisdn callback invocations.

229. By Thomas Voß on 2016-03-10

Wire up ril request callbacks.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added directory '3rd-party'
2=== added directory '3rd-party/boost'
3=== added directory '3rd-party/boost/core'
4=== added file '3rd-party/boost/core/scoped_enum.hpp'
5--- 3rd-party/boost/core/scoped_enum.hpp 1970-01-01 00:00:00 +0000
6+++ 3rd-party/boost/core/scoped_enum.hpp 2016-03-17 09:08:50 +0000
7@@ -0,0 +1,192 @@
8+// scoped_enum.hpp ---------------------------------------------------------//
9+
10+// Copyright Beman Dawes, 2009
11+// Copyright (C) 2011-2012 Vicente J. Botet Escriba
12+// Copyright (C) 2012 Anthony Williams
13+
14+// Distributed under the Boost Software License, Version 1.0.
15+// See http://www.boost.org/LICENSE_1_0.txt
16+
17+#ifndef BOOST_CORE_SCOPED_ENUM_HPP
18+#define BOOST_CORE_SCOPED_ENUM_HPP
19+
20+#include <boost/config.hpp>
21+
22+#ifdef BOOST_HAS_PRAGMA_ONCE
23+#pragma once
24+#endif
25+
26+namespace boost
27+{
28+
29+#ifdef BOOST_NO_CXX11_SCOPED_ENUMS
30+
31+ /**
32+ * Meta-function to get the native enum type associated to an enum class or its emulation.
33+ */
34+ template <typename EnumType>
35+ struct native_type
36+ {
37+ /**
38+ * The member typedef type names the native enum type associated to the scoped enum,
39+ * which is it self if the compiler supports scoped enums or EnumType::enum_type if it is an emulated scoped enum.
40+ */
41+ typedef typename EnumType::enum_type type;
42+ };
43+
44+ /**
45+ * Casts a scoped enum to its underlying type.
46+ *
47+ * This function is useful when working with scoped enum classes, which doens't implicitly convert to the underlying type.
48+ * @param v A scoped enum.
49+ * @returns The underlying type.
50+ * @throws No-throws.
51+ */
52+ template <typename UnderlyingType, typename EnumType>
53+ UnderlyingType underlying_cast(EnumType v)
54+ {
55+ return v.get_underlying_value_();
56+ }
57+
58+ /**
59+ * Casts a scoped enum to its native enum type.
60+ *
61+ * This function is useful to make programs portable when the scoped enum emulation can not be use where native enums can.
62+ *
63+ * EnumType the scoped enum type
64+ *
65+ * @param v A scoped enum.
66+ * @returns The native enum value.
67+ * @throws No-throws.
68+ */
69+ template <typename EnumType>
70+ inline
71+ typename EnumType::enum_type native_value(EnumType e)
72+ {
73+ return e.get_native_value_();
74+ }
75+
76+#else // BOOST_NO_CXX11_SCOPED_ENUMS
77+
78+ template <typename EnumType>
79+ struct native_type
80+ {
81+ typedef EnumType type;
82+ };
83+
84+ template <typename UnderlyingType, typename EnumType>
85+ UnderlyingType underlying_cast(EnumType v)
86+ {
87+ return static_cast<UnderlyingType>(v);
88+ }
89+
90+ template <typename EnumType>
91+ inline
92+ EnumType native_value(EnumType e)
93+ {
94+ return e;
95+ }
96+
97+#endif // BOOST_NO_CXX11_SCOPED_ENUMS
98+}
99+
100+
101+#ifdef BOOST_NO_CXX11_SCOPED_ENUMS
102+
103+#ifndef BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS
104+
105+#define BOOST_SCOPED_ENUM_UT_DECLARE_CONVERSION_OPERATOR \
106+ explicit operator underlying_type() const BOOST_NOEXCEPT { return get_underlying_value_(); }
107+
108+#else
109+
110+#define BOOST_SCOPED_ENUM_UT_DECLARE_CONVERSION_OPERATOR
111+
112+#endif
113+
114+/**
115+ * Start a declaration of a scoped enum.
116+ *
117+ * @param EnumType The new scoped enum.
118+ * @param UnderlyingType The underlying type.
119+ */
120+#define BOOST_SCOPED_ENUM_UT_DECLARE_BEGIN(EnumType, UnderlyingType) \
121+ struct EnumType { \
122+ typedef void is_boost_scoped_enum_tag; \
123+ typedef UnderlyingType underlying_type; \
124+ EnumType() BOOST_NOEXCEPT {} \
125+ explicit EnumType(underlying_type v) BOOST_NOEXCEPT : v_(v) {} \
126+ underlying_type get_underlying_value_() const BOOST_NOEXCEPT { return v_; } \
127+ BOOST_SCOPED_ENUM_UT_DECLARE_CONVERSION_OPERATOR \
128+ private: \
129+ underlying_type v_; \
130+ typedef EnumType self_type; \
131+ public: \
132+ enum enum_type
133+
134+#define BOOST_SCOPED_ENUM_DECLARE_END2() \
135+ enum_type get_native_value_() const BOOST_NOEXCEPT { return enum_type(v_); } \
136+ friend bool operator ==(self_type lhs, self_type rhs) BOOST_NOEXCEPT { return enum_type(lhs.v_)==enum_type(rhs.v_); } \
137+ friend bool operator ==(self_type lhs, enum_type rhs) BOOST_NOEXCEPT { return enum_type(lhs.v_)==rhs; } \
138+ friend bool operator ==(enum_type lhs, self_type rhs) BOOST_NOEXCEPT { return lhs==enum_type(rhs.v_); } \
139+ friend bool operator !=(self_type lhs, self_type rhs) BOOST_NOEXCEPT { return enum_type(lhs.v_)!=enum_type(rhs.v_); } \
140+ friend bool operator !=(self_type lhs, enum_type rhs) BOOST_NOEXCEPT { return enum_type(lhs.v_)!=rhs; } \
141+ friend bool operator !=(enum_type lhs, self_type rhs) BOOST_NOEXCEPT { return lhs!=enum_type(rhs.v_); } \
142+ friend bool operator <(self_type lhs, self_type rhs) BOOST_NOEXCEPT { return enum_type(lhs.v_)<enum_type(rhs.v_); } \
143+ friend bool operator <(self_type lhs, enum_type rhs) BOOST_NOEXCEPT { return enum_type(lhs.v_)<rhs; } \
144+ friend bool operator <(enum_type lhs, self_type rhs) BOOST_NOEXCEPT { return lhs<enum_type(rhs.v_); } \
145+ friend bool operator <=(self_type lhs, self_type rhs) BOOST_NOEXCEPT { return enum_type(lhs.v_)<=enum_type(rhs.v_); } \
146+ friend bool operator <=(self_type lhs, enum_type rhs) BOOST_NOEXCEPT { return enum_type(lhs.v_)<=rhs; } \
147+ friend bool operator <=(enum_type lhs, self_type rhs) BOOST_NOEXCEPT { return lhs<=enum_type(rhs.v_); } \
148+ friend bool operator >(self_type lhs, self_type rhs) BOOST_NOEXCEPT { return enum_type(lhs.v_)>enum_type(rhs.v_); } \
149+ friend bool operator >(self_type lhs, enum_type rhs) BOOST_NOEXCEPT { return enum_type(lhs.v_)>rhs; } \
150+ friend bool operator >(enum_type lhs, self_type rhs) BOOST_NOEXCEPT { return lhs>enum_type(rhs.v_); } \
151+ friend bool operator >=(self_type lhs, self_type rhs) BOOST_NOEXCEPT { return enum_type(lhs.v_)>=enum_type(rhs.v_); } \
152+ friend bool operator >=(self_type lhs, enum_type rhs) BOOST_NOEXCEPT { return enum_type(lhs.v_)>=rhs; } \
153+ friend bool operator >=(enum_type lhs, self_type rhs) BOOST_NOEXCEPT { return lhs>=enum_type(rhs.v_); } \
154+ };
155+
156+#define BOOST_SCOPED_ENUM_DECLARE_END(EnumType) \
157+ ; \
158+ EnumType(enum_type v) BOOST_NOEXCEPT : v_(v) {} \
159+ BOOST_SCOPED_ENUM_DECLARE_END2()
160+
161+/**
162+ * Starts a declaration of a scoped enum with the default int underlying type.
163+ *
164+ * @param EnumType The new scoped enum.
165+ */
166+#define BOOST_SCOPED_ENUM_DECLARE_BEGIN(EnumType) \
167+ BOOST_SCOPED_ENUM_UT_DECLARE_BEGIN(EnumType,int)
168+
169+/**
170+ * Name of the native enum type.
171+ *
172+ * @param EnumType The new scoped enum.
173+ */
174+#define BOOST_SCOPED_ENUM_NATIVE(EnumType) EnumType::enum_type
175+/**
176+ * Forward declares an scoped enum.
177+ *
178+ * @param EnumType The scoped enum.
179+ */
180+#define BOOST_SCOPED_ENUM_FORWARD_DECLARE(EnumType) struct EnumType
181+
182+#else // BOOST_NO_CXX11_SCOPED_ENUMS
183+
184+#define BOOST_SCOPED_ENUM_UT_DECLARE_BEGIN(EnumType,UnderlyingType) enum class EnumType : UnderlyingType
185+#define BOOST_SCOPED_ENUM_DECLARE_BEGIN(EnumType) enum class EnumType
186+#define BOOST_SCOPED_ENUM_DECLARE_END2()
187+#define BOOST_SCOPED_ENUM_DECLARE_END(EnumType) ;
188+
189+#define BOOST_SCOPED_ENUM_NATIVE(EnumType) EnumType
190+#define BOOST_SCOPED_ENUM_FORWARD_DECLARE(EnumType) enum class EnumType
191+
192+#endif // BOOST_NO_CXX11_SCOPED_ENUMS
193+
194+// Deprecated macros
195+#define BOOST_SCOPED_ENUM_START(name) BOOST_SCOPED_ENUM_DECLARE_BEGIN(name)
196+#define BOOST_SCOPED_ENUM_END BOOST_SCOPED_ENUM_DECLARE_END2()
197+#define BOOST_SCOPED_ENUM(name) BOOST_SCOPED_ENUM_NATIVE(name)
198+
199+#endif // BOOST_CORE_SCOPED_ENUM_HPP
200
201=== added directory '3rd-party/boost/endian'
202=== added file '3rd-party/boost/endian/arithmetic.hpp'
203--- 3rd-party/boost/endian/arithmetic.hpp 1970-01-01 00:00:00 +0000
204+++ 3rd-party/boost/endian/arithmetic.hpp 2016-03-17 09:08:50 +0000
205@@ -0,0 +1,413 @@
206+// boost/endian/arithmetic.hpp -------------------------------------------------------//
207+
208+// (C) Copyright Darin Adler 2000
209+// (C) Copyright Beman Dawes 2006, 2009, 2014
210+
211+// Distributed under the Boost Software License, Version 1.0.
212+// See http://www.boost.org/LICENSE_1_0.txt
213+
214+// See library home page at http://www.boost.org/libs/endian
215+
216+//--------------------------------------------------------------------------------------//
217+
218+// Original design developed by Darin Adler based on classes developed by Mark
219+// Borgerding. Four original class templates were combined into a single endian
220+// class template by Beman Dawes, who also added the unrolled_byte_loops sign
221+// partial specialization to correctly extend the sign when cover integer size
222+// differs from endian representation size.
223+
224+// TODO: When a compiler supporting constexpr becomes available, try possible uses.
225+
226+#ifndef BOOST_ENDIAN_ARITHMETIC_HPP
227+#define BOOST_ENDIAN_ARITHMETIC_HPP
228+
229+#if defined(_MSC_VER)
230+# pragma warning(push)
231+# pragma warning(disable:4365) // conversion ... signed/unsigned mismatch
232+#endif
233+
234+#ifdef BOOST_ENDIAN_LOG
235+# include <iostream>
236+#endif
237+
238+#if defined(__BORLANDC__) || defined( __CODEGEARC__)
239+# pragma pack(push, 1)
240+#endif
241+
242+#include <boost/config.hpp>
243+#include <boost/predef/detail/endian_compat.h>
244+#include <boost/endian/conversion.hpp>
245+#include <boost/endian/buffers.hpp>
246+#define BOOST_ENDIAN_MINIMAL_COVER_OPERATORS
247+#include <boost/endian/detail/cover_operators.hpp>
248+#undef BOOST_ENDIAN_MINIMAL_COVER_OPERATORS
249+#include <boost/type_traits/is_signed.hpp>
250+#include <boost/cstdint.hpp>
251+#include <boost/static_assert.hpp>
252+#include <boost/core/scoped_enum.hpp>
253+#include <iosfwd>
254+#include <climits>
255+
256+# if CHAR_BIT != 8
257+# error Platforms with CHAR_BIT != 8 are not supported
258+# endif
259+
260+# ifdef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS
261+# define BOOST_ENDIAN_DEFAULT_CONSTRUCT {} // C++03
262+# else
263+# define BOOST_ENDIAN_DEFAULT_CONSTRUCT = default; // C++0x
264+# endif
265+
266+# if defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) && defined(BOOST_ENDIAN_FORCE_PODNESS)
267+# define BOOST_ENDIAN_NO_CTORS
268+# endif
269+
270+# ifndef BOOST_ENDIAN_EXPLICIT_CTORS
271+# define BOOST_ENDIAN_EXPLICIT_OPT
272+# else
273+# define BOOST_ENDIAN_EXPLICIT_OPT explicit
274+# endif
275+
276+//---------------------------------- synopsis ----------------------------------------//
277+
278+namespace boost
279+{
280+namespace endian
281+{
282+
283+ template <BOOST_SCOPED_ENUM(order) Order, class T, std::size_t n_bits,
284+ BOOST_SCOPED_ENUM(align) A = align::no>
285+ class endian_arithmetic;
286+
287+ // big endian signed integer aligned types
288+ typedef endian_arithmetic<order::big, int8_t, 8, align::yes> big_int8_at;
289+ typedef endian_arithmetic<order::big, int16_t, 16, align::yes> big_int16_at;
290+ typedef endian_arithmetic<order::big, int32_t, 32, align::yes> big_int32_at;
291+ typedef endian_arithmetic<order::big, int64_t, 64, align::yes> big_int64_at;
292+
293+ // big endian unsigned integer aligned types
294+ typedef endian_arithmetic<order::big, uint8_t, 8, align::yes> big_uint8_at;
295+ typedef endian_arithmetic<order::big, uint16_t, 16, align::yes> big_uint16_at;
296+ typedef endian_arithmetic<order::big, uint32_t, 32, align::yes> big_uint32_at;
297+ typedef endian_arithmetic<order::big, uint64_t, 64, align::yes> big_uint64_at;
298+
299+ // little endian signed integer aligned types
300+ typedef endian_arithmetic<order::little, int8_t, 8, align::yes> little_int8_at;
301+ typedef endian_arithmetic<order::little, int16_t, 16, align::yes> little_int16_at;
302+ typedef endian_arithmetic<order::little, int32_t, 32, align::yes> little_int32_at;
303+ typedef endian_arithmetic<order::little, int64_t, 64, align::yes> little_int64_at;
304+
305+ // little endian unsigned integer aligned types
306+ typedef endian_arithmetic<order::little, uint8_t, 8, align::yes> little_uint8_at;
307+ typedef endian_arithmetic<order::little, uint16_t, 16, align::yes> little_uint16_at;
308+ typedef endian_arithmetic<order::little, uint32_t, 32, align::yes> little_uint32_at;
309+ typedef endian_arithmetic<order::little, uint64_t, 64, align::yes> little_uint64_at;
310+
311+ // aligned native endian typedefs are not provided because
312+ // <cstdint> types are superior for this use case
313+
314+ // big endian signed integer unaligned types
315+ typedef endian_arithmetic<order::big, int_least8_t, 8> big_int8_t;
316+ typedef endian_arithmetic<order::big, int_least16_t, 16> big_int16_t;
317+ typedef endian_arithmetic<order::big, int_least32_t, 24> big_int24_t;
318+ typedef endian_arithmetic<order::big, int_least32_t, 32> big_int32_t;
319+ typedef endian_arithmetic<order::big, int_least64_t, 40> big_int40_t;
320+ typedef endian_arithmetic<order::big, int_least64_t, 48> big_int48_t;
321+ typedef endian_arithmetic<order::big, int_least64_t, 56> big_int56_t;
322+ typedef endian_arithmetic<order::big, int_least64_t, 64> big_int64_t;
323+
324+ // big endian unsigned integer unaligned types
325+ typedef endian_arithmetic<order::big, uint_least8_t, 8> big_uint8_t;
326+ typedef endian_arithmetic<order::big, uint_least16_t, 16> big_uint16_t;
327+ typedef endian_arithmetic<order::big, uint_least32_t, 24> big_uint24_t;
328+ typedef endian_arithmetic<order::big, uint_least32_t, 32> big_uint32_t;
329+ typedef endian_arithmetic<order::big, uint_least64_t, 40> big_uint40_t;
330+ typedef endian_arithmetic<order::big, uint_least64_t, 48> big_uint48_t;
331+ typedef endian_arithmetic<order::big, uint_least64_t, 56> big_uint56_t;
332+ typedef endian_arithmetic<order::big, uint_least64_t, 64> big_uint64_t;
333+
334+ // little endian signed integer unaligned types
335+ typedef endian_arithmetic<order::little, int_least8_t, 8> little_int8_t;
336+ typedef endian_arithmetic<order::little, int_least16_t, 16> little_int16_t;
337+ typedef endian_arithmetic<order::little, int_least32_t, 24> little_int24_t;
338+ typedef endian_arithmetic<order::little, int_least32_t, 32> little_int32_t;
339+ typedef endian_arithmetic<order::little, int_least64_t, 40> little_int40_t;
340+ typedef endian_arithmetic<order::little, int_least64_t, 48> little_int48_t;
341+ typedef endian_arithmetic<order::little, int_least64_t, 56> little_int56_t;
342+ typedef endian_arithmetic<order::little, int_least64_t, 64> little_int64_t;
343+
344+ // little endian unsigned integer unaligned types
345+ typedef endian_arithmetic<order::little, uint_least8_t, 8> little_uint8_t;
346+ typedef endian_arithmetic<order::little, uint_least16_t, 16> little_uint16_t;
347+ typedef endian_arithmetic<order::little, uint_least32_t, 24> little_uint24_t;
348+ typedef endian_arithmetic<order::little, uint_least32_t, 32> little_uint32_t;
349+ typedef endian_arithmetic<order::little, uint_least64_t, 40> little_uint40_t;
350+ typedef endian_arithmetic<order::little, uint_least64_t, 48> little_uint48_t;
351+ typedef endian_arithmetic<order::little, uint_least64_t, 56> little_uint56_t;
352+ typedef endian_arithmetic<order::little, uint_least64_t, 64> little_uint64_t;
353+
354+# ifdef BOOST_BIG_ENDIAN
355+ // native endian signed integer unaligned types
356+ typedef big_int8_t native_int8_t;
357+ typedef big_int16_t native_int16_t;
358+ typedef big_int24_t native_int24_t;
359+ typedef big_int32_t native_int32_t;
360+ typedef big_int40_t native_int40_t;
361+ typedef big_int48_t native_int48_t;
362+ typedef big_int56_t native_int56_t;
363+ typedef big_int64_t native_int64_t;
364+
365+ // native endian unsigned integer unaligned types
366+ typedef big_uint8_t native_uint8_t;
367+ typedef big_uint16_t native_uint16_t;
368+ typedef big_uint24_t native_uint24_t;
369+ typedef big_uint32_t native_uint32_t;
370+ typedef big_uint40_t native_uint40_t;
371+ typedef big_uint48_t native_uint48_t;
372+ typedef big_uint56_t native_uint56_t;
373+ typedef big_uint64_t native_uint64_t;
374+# else
375+ // native endian signed integer unaligned types
376+ typedef little_int8_t native_int8_t;
377+ typedef little_int16_t native_int16_t;
378+ typedef little_int24_t native_int24_t;
379+ typedef little_int32_t native_int32_t;
380+ typedef little_int40_t native_int40_t;
381+ typedef little_int48_t native_int48_t;
382+ typedef little_int56_t native_int56_t;
383+ typedef little_int64_t native_int64_t;
384+
385+ // native endian unsigned integer unaligned types
386+ typedef little_uint8_t native_uint8_t;
387+ typedef little_uint16_t native_uint16_t;
388+ typedef little_uint24_t native_uint24_t;
389+ typedef little_uint32_t native_uint32_t;
390+ typedef little_uint40_t native_uint40_t;
391+ typedef little_uint48_t native_uint48_t;
392+ typedef little_uint56_t native_uint56_t;
393+ typedef little_uint64_t native_uint64_t;
394+# endif
395+
396+# ifdef BOOST_ENDIAN_DEPRECATED_NAMES
397+
398+ typedef order endianness;
399+ typedef align alignment;
400+
401+# ifndef BOOST_NO_CXX11_TEMPLATE_ALIASES
402+ template <BOOST_SCOPED_ENUM(order) Order, class T, std::size_t n_bits,
403+ BOOST_SCOPED_ENUM(align) Align = align::no>
404+ using endian = endian_arithmetic<Order, T, n_bits, Align>;
405+# endif
406+
407+ // unaligned big endian signed integer types
408+ typedef endian_arithmetic< order::big, int_least8_t, 8 > big8_t;
409+ typedef endian_arithmetic< order::big, int_least16_t, 16 > big16_t;
410+ typedef endian_arithmetic< order::big, int_least32_t, 24 > big24_t;
411+ typedef endian_arithmetic< order::big, int_least32_t, 32 > big32_t;
412+ typedef endian_arithmetic< order::big, int_least64_t, 40 > big40_t;
413+ typedef endian_arithmetic< order::big, int_least64_t, 48 > big48_t;
414+ typedef endian_arithmetic< order::big, int_least64_t, 56 > big56_t;
415+ typedef endian_arithmetic< order::big, int_least64_t, 64 > big64_t;
416+
417+ // unaligned big endian_arithmetic unsigned integer types
418+ typedef endian_arithmetic< order::big, uint_least8_t, 8 > ubig8_t;
419+ typedef endian_arithmetic< order::big, uint_least16_t, 16 > ubig16_t;
420+ typedef endian_arithmetic< order::big, uint_least32_t, 24 > ubig24_t;
421+ typedef endian_arithmetic< order::big, uint_least32_t, 32 > ubig32_t;
422+ typedef endian_arithmetic< order::big, uint_least64_t, 40 > ubig40_t;
423+ typedef endian_arithmetic< order::big, uint_least64_t, 48 > ubig48_t;
424+ typedef endian_arithmetic< order::big, uint_least64_t, 56 > ubig56_t;
425+ typedef endian_arithmetic< order::big, uint_least64_t, 64 > ubig64_t;
426+
427+ // unaligned little endian_arithmetic signed integer types
428+ typedef endian_arithmetic< order::little, int_least8_t, 8 > little8_t;
429+ typedef endian_arithmetic< order::little, int_least16_t, 16 > little16_t;
430+ typedef endian_arithmetic< order::little, int_least32_t, 24 > little24_t;
431+ typedef endian_arithmetic< order::little, int_least32_t, 32 > little32_t;
432+ typedef endian_arithmetic< order::little, int_least64_t, 40 > little40_t;
433+ typedef endian_arithmetic< order::little, int_least64_t, 48 > little48_t;
434+ typedef endian_arithmetic< order::little, int_least64_t, 56 > little56_t;
435+ typedef endian_arithmetic< order::little, int_least64_t, 64 > little64_t;
436+
437+ // unaligned little endian_arithmetic unsigned integer types
438+ typedef endian_arithmetic< order::little, uint_least8_t, 8 > ulittle8_t;
439+ typedef endian_arithmetic< order::little, uint_least16_t, 16 > ulittle16_t;
440+ typedef endian_arithmetic< order::little, uint_least32_t, 24 > ulittle24_t;
441+ typedef endian_arithmetic< order::little, uint_least32_t, 32 > ulittle32_t;
442+ typedef endian_arithmetic< order::little, uint_least64_t, 40 > ulittle40_t;
443+ typedef endian_arithmetic< order::little, uint_least64_t, 48 > ulittle48_t;
444+ typedef endian_arithmetic< order::little, uint_least64_t, 56 > ulittle56_t;
445+ typedef endian_arithmetic< order::little, uint_least64_t, 64 > ulittle64_t;
446+
447+ // unaligned native endian_arithmetic signed integer types
448+ typedef endian_arithmetic< order::native, int_least8_t, 8 > native8_t;
449+ typedef endian_arithmetic< order::native, int_least16_t, 16 > native16_t;
450+ typedef endian_arithmetic< order::native, int_least32_t, 24 > native24_t;
451+ typedef endian_arithmetic< order::native, int_least32_t, 32 > native32_t;
452+ typedef endian_arithmetic< order::native, int_least64_t, 40 > native40_t;
453+ typedef endian_arithmetic< order::native, int_least64_t, 48 > native48_t;
454+ typedef endian_arithmetic< order::native, int_least64_t, 56 > native56_t;
455+ typedef endian_arithmetic< order::native, int_least64_t, 64 > native64_t;
456+
457+ // unaligned native endian_arithmetic unsigned integer types
458+ typedef endian_arithmetic< order::native, uint_least8_t, 8 > unative8_t;
459+ typedef endian_arithmetic< order::native, uint_least16_t, 16 > unative16_t;
460+ typedef endian_arithmetic< order::native, uint_least32_t, 24 > unative24_t;
461+ typedef endian_arithmetic< order::native, uint_least32_t, 32 > unative32_t;
462+ typedef endian_arithmetic< order::native, uint_least64_t, 40 > unative40_t;
463+ typedef endian_arithmetic< order::native, uint_least64_t, 48 > unative48_t;
464+ typedef endian_arithmetic< order::native, uint_least64_t, 56 > unative56_t;
465+ typedef endian_arithmetic< order::native, uint_least64_t, 64 > unative64_t;
466+
467+ // aligned native endian_arithmetic typedefs are not provided because
468+ // <cstdint> types are superior for this use case
469+
470+ typedef endian_arithmetic< order::big, int16_t, 16, align::yes > aligned_big16_t;
471+ typedef endian_arithmetic< order::big, uint16_t, 16, align::yes > aligned_ubig16_t;
472+ typedef endian_arithmetic< order::little, int16_t, 16, align::yes > aligned_little16_t;
473+ typedef endian_arithmetic< order::little, uint16_t, 16, align::yes > aligned_ulittle16_t;
474+
475+ typedef endian_arithmetic< order::big, int32_t, 32, align::yes > aligned_big32_t;
476+ typedef endian_arithmetic< order::big, uint32_t, 32, align::yes > aligned_ubig32_t;
477+ typedef endian_arithmetic< order::little, int32_t, 32, align::yes > aligned_little32_t;
478+ typedef endian_arithmetic< order::little, uint32_t, 32, align::yes > aligned_ulittle32_t;
479+
480+ typedef endian_arithmetic< order::big, int64_t, 64, align::yes > aligned_big64_t;
481+ typedef endian_arithmetic< order::big, uint64_t, 64, align::yes > aligned_ubig64_t;
482+ typedef endian_arithmetic< order::little, int64_t, 64, align::yes > aligned_little64_t;
483+ typedef endian_arithmetic< order::little, uint64_t, 64, align::yes > aligned_ulittle64_t;
484+
485+# endif
486+
487+//---------------------------------- end synopsis ------------------------------------//
488+
489+// endian class template specializations ---------------------------------------------//
490+
491+ // Specializations that represent unaligned bytes.
492+ // Taking an integer type as a parameter provides a nice way to pass both
493+ // the size and signness of the desired integer and get the appropriate
494+ // corresponding integer type for the interface.
495+
496+ // unaligned integer big endian specialization
497+ template <typename T, std::size_t n_bits>
498+ class endian_arithmetic< order::big, T, n_bits, align::no >
499+ : public endian_buffer< order::big, T, n_bits, align::no >,
500+ cover_operators<endian_arithmetic<order::big, T, n_bits>, T>
501+ {
502+ BOOST_STATIC_ASSERT( (n_bits/8)*8 == n_bits );
503+ public:
504+ typedef T value_type;
505+# ifndef BOOST_ENDIAN_NO_CTORS
506+ endian_arithmetic() BOOST_ENDIAN_DEFAULT_CONSTRUCT
507+ BOOST_ENDIAN_EXPLICIT_OPT endian_arithmetic(T val) BOOST_NOEXCEPT
508+ {
509+# ifdef BOOST_ENDIAN_LOG
510+ if ( endian_log )
511+ std::cout << "big, unaligned, " << n_bits << "-bits, construct(" << val << ")\n";
512+# endif
513+ detail::store_big_endian<T, n_bits/8>(this->m_value, val);
514+ }
515+# endif
516+ endian_arithmetic& operator=(T val) BOOST_NOEXCEPT
517+ { detail::store_big_endian<T, n_bits/8>(this->m_value, val); return *this; }
518+ operator value_type() const BOOST_NOEXCEPT { return this->value(); }
519+ };
520+
521+ // unaligned little endian specialization
522+ template <typename T, std::size_t n_bits>
523+ class endian_arithmetic< order::little, T, n_bits, align::no >
524+ : public endian_buffer< order::little, T, n_bits, align::no >,
525+ cover_operators< endian_arithmetic< order::little, T, n_bits >, T >
526+ {
527+ BOOST_STATIC_ASSERT( (n_bits/8)*8 == n_bits );
528+ public:
529+ typedef T value_type;
530+# ifndef BOOST_ENDIAN_NO_CTORS
531+ endian_arithmetic() BOOST_ENDIAN_DEFAULT_CONSTRUCT
532+ BOOST_ENDIAN_EXPLICIT_OPT endian_arithmetic(T val) BOOST_NOEXCEPT
533+ {
534+# ifdef BOOST_ENDIAN_LOG
535+ if ( endian_log )
536+ std::cout << "little, unaligned, " << n_bits << "-bits, construct(" << val << ")\n";
537+# endif
538+ detail::store_little_endian<T, n_bits/8>(this->m_value, val);
539+ }
540+# endif
541+ endian_arithmetic& operator=(T val) BOOST_NOEXCEPT
542+ { detail::store_little_endian<T, n_bits/8>(this->m_value, val); return *this; }
543+ operator value_type() const BOOST_NOEXCEPT { return this->value(); }
544+ };
545+
546+ // align::yes specializations; only n_bits == 16/32/64 supported
547+
548+ // aligned big endian specialization
549+ template <typename T, std::size_t n_bits>
550+ class endian_arithmetic<order::big, T, n_bits, align::yes>
551+ : public endian_buffer< order::big, T, n_bits, align::yes >,
552+ cover_operators<endian_arithmetic<order::big, T, n_bits, align::yes>, T>
553+ {
554+ BOOST_STATIC_ASSERT( (n_bits/8)*8 == n_bits );
555+ BOOST_STATIC_ASSERT( sizeof(T) == n_bits/8 );
556+ public:
557+ typedef T value_type;
558+# ifndef BOOST_ENDIAN_NO_CTORS
559+ endian_arithmetic() BOOST_ENDIAN_DEFAULT_CONSTRUCT
560+ BOOST_ENDIAN_EXPLICIT_OPT endian_arithmetic(T val) BOOST_NOEXCEPT
561+ {
562+# ifdef BOOST_ENDIAN_LOG
563+ if ( endian_log )
564+ std::cout << "big, aligned, " << n_bits << "-bits, construct(" << val << ")\n";
565+# endif
566+ this->m_value = ::boost::endian::native_to_big(val);
567+ }
568+
569+# endif
570+ endian_arithmetic& operator=(T val) BOOST_NOEXCEPT
571+ {
572+ this->m_value = ::boost::endian::native_to_big(val);
573+ return *this;
574+ }
575+ operator value_type() const BOOST_NOEXCEPT { return this->value(); }
576+ };
577+
578+ // aligned little endian specialization
579+ template <typename T, std::size_t n_bits>
580+ class endian_arithmetic<order::little, T, n_bits, align::yes>
581+ : public endian_buffer< order::little, T, n_bits, align::yes >,
582+ cover_operators<endian_arithmetic<order::little, T, n_bits, align::yes>, T>
583+ {
584+ BOOST_STATIC_ASSERT( (n_bits/8)*8 == n_bits );
585+ BOOST_STATIC_ASSERT( sizeof(T) == n_bits/8 );
586+ public:
587+ typedef T value_type;
588+# ifndef BOOST_ENDIAN_NO_CTORS
589+ endian_arithmetic() BOOST_ENDIAN_DEFAULT_CONSTRUCT
590+ BOOST_ENDIAN_EXPLICIT_OPT endian_arithmetic(T val) BOOST_NOEXCEPT
591+ {
592+# ifdef BOOST_ENDIAN_LOG
593+ if ( endian_log )
594+ std::cout << "little, aligned, " << n_bits << "-bits, construct(" << val << ")\n";
595+# endif
596+ this->m_value = ::boost::endian::native_to_little(val);
597+ }
598+# endif
599+ endian_arithmetic& operator=(T val) BOOST_NOEXCEPT
600+ {
601+ this->m_value = ::boost::endian::native_to_little(val);
602+ return *this;
603+ }
604+ operator value_type() const BOOST_NOEXCEPT { return this->value(); }
605+ };
606+
607+} // namespace endian
608+} // namespace boost
609+
610+#if defined(__BORLANDC__) || defined( __CODEGEARC__)
611+# pragma pack(pop)
612+#endif
613+
614+#if defined(_MSC_VER)
615+# pragma warning(pop)
616+#endif
617+
618+#endif // BOOST_ENDIAN_ARITHMETIC_HPP
619
620=== added file '3rd-party/boost/endian/buffers.hpp'
621--- 3rd-party/boost/endian/buffers.hpp 1970-01-01 00:00:00 +0000
622+++ 3rd-party/boost/endian/buffers.hpp 2016-03-17 09:08:50 +0000
623@@ -0,0 +1,515 @@
624+// boost/endian/buffers.hpp ----------------------------------------------------------//
625+
626+// (C) Copyright Darin Adler 2000
627+// (C) Copyright Beman Dawes 2006, 2009, 2014
628+
629+// Distributed under the Boost Software License, Version 1.0.
630+// See http://www.boost.org/LICENSE_1_0.txt
631+
632+// See library home page at http://www.boost.org/libs/endian
633+
634+//--------------------------------------------------------------------------------------//
635+
636+// Original design developed by Darin Adler based on classes developed by Mark
637+// Borgerding. Four original class templates were combined into a single endian
638+// class template by Beman Dawes, who also added the unrolled_byte_loops sign
639+// partial specialization to correctly extend the sign when cover integer size
640+// differs from endian representation size.
641+
642+// TODO: When a compiler supporting constexpr becomes available, try possible uses.
643+
644+#ifndef BOOST_ENDIAN_BUFFERS_HPP
645+#define BOOST_ENDIAN_BUFFERS_HPP
646+
647+#if defined(_MSC_VER)
648+# pragma warning(push)
649+# pragma warning(disable:4365) // conversion ... signed/unsigned mismatch
650+#endif
651+
652+#ifdef BOOST_ENDIAN_LOG
653+# include <iostream>
654+#endif
655+
656+#if defined(__BORLANDC__) || defined( __CODEGEARC__)
657+# pragma pack(push, 1)
658+#endif
659+
660+#include <boost/config.hpp>
661+#include <boost/predef/detail/endian_compat.h>
662+#include <boost/endian/conversion.hpp>
663+#include <boost/type_traits/is_signed.hpp>
664+#include <boost/cstdint.hpp>
665+#include <boost/static_assert.hpp>
666+#include <boost/core/scoped_enum.hpp>
667+#include <iosfwd>
668+#include <climits>
669+
670+# if CHAR_BIT != 8
671+# error Platforms with CHAR_BIT != 8 are not supported
672+# endif
673+
674+# ifdef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS
675+# define BOOST_ENDIAN_DEFAULT_CONSTRUCT {} // C++03
676+# else
677+# define BOOST_ENDIAN_DEFAULT_CONSTRUCT = default; // C++0x
678+# endif
679+
680+# if defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) && defined(BOOST_ENDIAN_FORCE_PODNESS)
681+# define BOOST_ENDIAN_NO_CTORS
682+# endif
683+
684+//---------------------------------- synopsis ----------------------------------------//
685+
686+namespace boost
687+{
688+namespace endian
689+{
690+
691+ BOOST_SCOPED_ENUM_START(align)
692+ {no, yes
693+# ifdef BOOST_ENDIAN_DEPRECATED_NAMES
694+ , unaligned = no, aligned = yes
695+# endif
696+ }; BOOST_SCOPED_ENUM_END
697+
698+ template <BOOST_SCOPED_ENUM(order) Order, class T, std::size_t n_bits,
699+ BOOST_SCOPED_ENUM(align) A = align::no>
700+ class endian_buffer;
701+
702+ // aligned big endian signed integer buffers
703+ typedef endian_buffer<order::big, int8_t, 8, align::yes> big_int8_buf_at;
704+ typedef endian_buffer<order::big, int16_t, 16, align::yes> big_int16_buf_at;
705+ typedef endian_buffer<order::big, int32_t, 32, align::yes> big_int32_buf_at;
706+ typedef endian_buffer<order::big, int64_t, 64, align::yes> big_int64_buf_at;
707+
708+ // aligned big endian unsigned integer buffers
709+ typedef endian_buffer<order::big, uint8_t, 8, align::yes> big_uint8_buf_at;
710+ typedef endian_buffer<order::big, uint16_t, 16, align::yes> big_uint16_buf_at;
711+ typedef endian_buffer<order::big, uint32_t, 32, align::yes> big_uint32_buf_at;
712+ typedef endian_buffer<order::big, uint64_t, 64, align::yes> big_uint64_buf_at;
713+
714+ // aligned little endian signed integer buffers
715+ typedef endian_buffer<order::little, int8_t, 8, align::yes> little_int8_buf_at;
716+ typedef endian_buffer<order::little, int16_t, 16, align::yes> little_int16_buf_at;
717+ typedef endian_buffer<order::little, int32_t, 32, align::yes> little_int32_buf_at;
718+ typedef endian_buffer<order::little, int64_t, 64, align::yes> little_int64_buf_at;
719+
720+ // aligned little endian unsigned integer buffers
721+ typedef endian_buffer<order::little, uint8_t, 8, align::yes> little_uint8_buf_at;
722+ typedef endian_buffer<order::little, uint16_t, 16, align::yes> little_uint16_buf_at;
723+ typedef endian_buffer<order::little, uint32_t, 32, align::yes> little_uint32_buf_at;
724+ typedef endian_buffer<order::little, uint64_t, 64, align::yes> little_uint64_buf_at;
725+
726+ // aligned native endian typedefs are not provided because
727+ // <cstdint> types are superior for this use case
728+
729+ // unaligned big endian signed integer buffers
730+ typedef endian_buffer<order::big, int_least8_t, 8> big_int8_buf_t;
731+ typedef endian_buffer<order::big, int_least16_t, 16> big_int16_buf_t;
732+ typedef endian_buffer<order::big, int_least32_t, 24> big_int24_buf_t;
733+ typedef endian_buffer<order::big, int_least32_t, 32> big_int32_buf_t;
734+ typedef endian_buffer<order::big, int_least64_t, 40> big_int40_buf_t;
735+ typedef endian_buffer<order::big, int_least64_t, 48> big_int48_buf_t;
736+ typedef endian_buffer<order::big, int_least64_t, 56> big_int56_buf_t;
737+ typedef endian_buffer<order::big, int_least64_t, 64> big_int64_buf_t;
738+
739+ // unaligned big endian unsigned integer buffers
740+ typedef endian_buffer<order::big, uint_least8_t, 8> big_uint8_buf_t;
741+ typedef endian_buffer<order::big, uint_least16_t, 16> big_uint16_buf_t;
742+ typedef endian_buffer<order::big, uint_least32_t, 24> big_uint24_buf_t;
743+ typedef endian_buffer<order::big, uint_least32_t, 32> big_uint32_buf_t;
744+ typedef endian_buffer<order::big, uint_least64_t, 40> big_uint40_buf_t;
745+ typedef endian_buffer<order::big, uint_least64_t, 48> big_uint48_buf_t;
746+ typedef endian_buffer<order::big, uint_least64_t, 56> big_uint56_buf_t;
747+ typedef endian_buffer<order::big, uint_least64_t, 64> big_uint64_buf_t;
748+
749+ // unaligned little endian signed integer buffers
750+ typedef endian_buffer<order::little, int_least8_t, 8> little_int8_buf_t;
751+ typedef endian_buffer<order::little, int_least16_t, 16> little_int16_buf_t;
752+ typedef endian_buffer<order::little, int_least32_t, 24> little_int24_buf_t;
753+ typedef endian_buffer<order::little, int_least32_t, 32> little_int32_buf_t;
754+ typedef endian_buffer<order::little, int_least64_t, 40> little_int40_buf_t;
755+ typedef endian_buffer<order::little, int_least64_t, 48> little_int48_buf_t;
756+ typedef endian_buffer<order::little, int_least64_t, 56> little_int56_buf_t;
757+ typedef endian_buffer<order::little, int_least64_t, 64> little_int64_buf_t;
758+
759+ // unaligned little endian unsigned integer buffers
760+ typedef endian_buffer<order::little, uint_least8_t, 8> little_uint8_buf_t;
761+ typedef endian_buffer<order::little, uint_least16_t, 16> little_uint16_buf_t;
762+ typedef endian_buffer<order::little, uint_least32_t, 24> little_uint24_buf_t;
763+ typedef endian_buffer<order::little, uint_least32_t, 32> little_uint32_buf_t;
764+ typedef endian_buffer<order::little, uint_least64_t, 40> little_uint40_buf_t;
765+ typedef endian_buffer<order::little, uint_least64_t, 48> little_uint48_buf_t;
766+ typedef endian_buffer<order::little, uint_least64_t, 56> little_uint56_buf_t;
767+ typedef endian_buffer<order::little, uint_least64_t, 64> little_uint64_buf_t;
768+
769+# ifdef BOOST_BIG_ENDIAN
770+ // unaligned native endian signed integer buffers
771+ typedef big_int8_buf_t native_int8_buf_t;
772+ typedef big_int16_buf_t native_int16_buf_t;
773+ typedef big_int24_buf_t native_int24_buf_t;
774+ typedef big_int32_buf_t native_int32_buf_t;
775+ typedef big_int40_buf_t native_int40_buf_t;
776+ typedef big_int48_buf_t native_int48_buf_t;
777+ typedef big_int56_buf_t native_int56_buf_t;
778+ typedef big_int64_buf_t native_int64_buf_t;
779+
780+ // unaligned native endian unsigned integer buffers
781+ typedef big_uint8_buf_t native_uint8_buf_t;
782+ typedef big_uint16_buf_t native_uint16_buf_t;
783+ typedef big_uint24_buf_t native_uint24_buf_t;
784+ typedef big_uint32_buf_t native_uint32_buf_t;
785+ typedef big_uint40_buf_t native_uint40_buf_t;
786+ typedef big_uint48_buf_t native_uint48_buf_t;
787+ typedef big_uint56_buf_t native_uint56_buf_t;
788+ typedef big_uint64_buf_t native_uint64_buf_t;
789+# else
790+ // unaligned native endian signed integer buffers
791+ typedef little_int8_buf_t native_int8_buf_t;
792+ typedef little_int16_buf_t native_int16_buf_t;
793+ typedef little_int24_buf_t native_int24_buf_t;
794+ typedef little_int32_buf_t native_int32_buf_t;
795+ typedef little_int40_buf_t native_int40_buf_t;
796+ typedef little_int48_buf_t native_int48_buf_t;
797+ typedef little_int56_buf_t native_int56_buf_t;
798+ typedef little_int64_buf_t native_int64_buf_t;
799+
800+ // unaligned native endian unsigned integer buffers
801+ typedef little_uint8_buf_t native_uint8_buf_t;
802+ typedef little_uint16_buf_t native_uint16_buf_t;
803+ typedef little_uint24_buf_t native_uint24_buf_t;
804+ typedef little_uint32_buf_t native_uint32_buf_t;
805+ typedef little_uint40_buf_t native_uint40_buf_t;
806+ typedef little_uint48_buf_t native_uint48_buf_t;
807+ typedef little_uint56_buf_t native_uint56_buf_t;
808+ typedef little_uint64_buf_t native_uint64_buf_t;
809+# endif
810+
811+ // Stream inserter
812+ template <class charT, class traits, BOOST_SCOPED_ENUM(order) Order, class T,
813+ std::size_t n_bits, BOOST_SCOPED_ENUM(align) A>
814+ std::basic_ostream<charT, traits>&
815+ operator<<(std::basic_ostream<charT, traits>& os,
816+ const endian_buffer<Order, T, n_bits, A>& x)
817+ {
818+ return os << x.value();
819+ }
820+
821+ // Stream extractor
822+ template <class charT, class traits, BOOST_SCOPED_ENUM(order) Order, class T,
823+ std::size_t n_bits, BOOST_SCOPED_ENUM(align) A>
824+ std::basic_istream<charT, traits>&
825+ operator>>(std::basic_istream<charT, traits>& is,
826+ endian_buffer<Order, T, n_bits, A>& x)
827+ {
828+ T i;
829+ if (is >> i)
830+ x = i;
831+ return is;
832+ }
833+
834+//---------------------------------- end synopsis ------------------------------------//
835+
836+ namespace detail
837+ {
838+
839+ // Unrolled loops for loading and storing streams of bytes.
840+
841+ template <typename T, std::size_t n_bytes,
842+ bool sign=boost::is_signed<T>::value >
843+ struct unrolled_byte_loops
844+ {
845+ typedef unrolled_byte_loops<T, n_bytes - 1, sign> next;
846+
847+ static T load_big(const unsigned char* bytes) BOOST_NOEXCEPT
848+ { return static_cast<T>(*(bytes - 1) | (next::load_big(bytes - 1) << 8)); }
849+ static T load_little(const unsigned char* bytes) BOOST_NOEXCEPT
850+ { return static_cast<T>(*bytes | (next::load_little(bytes + 1) << 8)); }
851+
852+ static void store_big(char* bytes, T value) BOOST_NOEXCEPT
853+ {
854+ *(bytes - 1) = static_cast<char>(value);
855+ next::store_big(bytes - 1, static_cast<T>(value >> 8));
856+ }
857+ static void store_little(char* bytes, T value) BOOST_NOEXCEPT
858+ {
859+ *bytes = static_cast<char>(value);
860+ next::store_little(bytes + 1, static_cast<T>(value >> 8));
861+ }
862+ };
863+
864+ template <typename T>
865+ struct unrolled_byte_loops<T, 1, false>
866+ {
867+ static T load_big(const unsigned char* bytes) BOOST_NOEXCEPT
868+ { return *(bytes - 1); }
869+ static T load_little(const unsigned char* bytes) BOOST_NOEXCEPT
870+ { return *bytes; }
871+ static void store_big(char* bytes, T value) BOOST_NOEXCEPT
872+ { *(bytes - 1) = static_cast<char>(value); }
873+ static void store_little(char* bytes, T value) BOOST_NOEXCEPT
874+ { *bytes = static_cast<char>(value); }
875+
876+ };
877+
878+ template <typename T>
879+ struct unrolled_byte_loops<T, 1, true>
880+ {
881+ static T load_big(const unsigned char* bytes) BOOST_NOEXCEPT
882+ { return *reinterpret_cast<const signed char*>(bytes - 1); }
883+ static T load_little(const unsigned char* bytes) BOOST_NOEXCEPT
884+ { return *reinterpret_cast<const signed char*>(bytes); }
885+ static void store_big(char* bytes, T value) BOOST_NOEXCEPT
886+ { *(bytes - 1) = static_cast<char>(value); }
887+ static void store_little(char* bytes, T value) BOOST_NOEXCEPT
888+ { *bytes = static_cast<char>(value); }
889+ };
890+
891+ template <typename T, std::size_t n_bytes>
892+ inline
893+ T load_big_endian(const void* bytes) BOOST_NOEXCEPT
894+ {
895+ return unrolled_byte_loops<T, n_bytes>::load_big
896+ (static_cast<const unsigned char*>(bytes) + n_bytes);
897+ }
898+
899+ template <typename T, std::size_t n_bytes>
900+ inline
901+ T load_little_endian(const void* bytes) BOOST_NOEXCEPT
902+ {
903+# if defined(__x86_64__) || defined(_M_X64) || defined(__i386) || defined(_M_IX86)
904+ // On x86 (which is little endian), unaligned loads are permitted
905+ if (sizeof(T) == n_bytes) // GCC 4.9, VC++ 14.0, and probably others, elide this
906+ // test and generate code only for the applicable return
907+ // case since sizeof(T) and n_bytes are known at compile
908+ // time.
909+ {
910+ return *reinterpret_cast<T const *>(bytes);
911+ }
912+# endif
913+ return unrolled_byte_loops<T, n_bytes>::load_little
914+ (static_cast<const unsigned char*>(bytes));
915+ }
916+
917+ template <typename T, std::size_t n_bytes>
918+ inline
919+ void store_big_endian(void* bytes, T value) BOOST_NOEXCEPT
920+ {
921+ unrolled_byte_loops<T, n_bytes>::store_big
922+ (static_cast<char*>(bytes) + n_bytes, value);
923+ }
924+
925+ template <typename T, std::size_t n_bytes>
926+ inline
927+ void store_little_endian(void* bytes, T value) BOOST_NOEXCEPT
928+ {
929+# if defined(__x86_64__) || defined(_M_X64) || defined(__i386) || defined(_M_IX86)
930+ // On x86 (which is little endian), unaligned stores are permitted
931+ if (sizeof(T) == n_bytes) // GCC 4.9, VC++ 14.0, and probably others, elide this
932+ // test and generate code only for the applicable return
933+ // case since sizeof(T) and n_bytes are known at compile
934+ // time.
935+ {
936+ *reinterpret_cast<T *>(bytes) = value;
937+ return;
938+ }
939+# endif
940+ unrolled_byte_loops<T, n_bytes>::store_little
941+ (static_cast<char*>(bytes), value);
942+ }
943+
944+ } // namespace detail
945+
946+# ifdef BOOST_ENDIAN_LOG
947+ bool endian_log(true);
948+# endif
949+
950+// endian_buffer class template specializations --------------------------------------//
951+
952+ // Specializations that represent unaligned bytes.
953+ // Taking an integer type as a parameter provides a nice way to pass both
954+ // the size and signedness of the desired integer and get the appropriate
955+ // corresponding integer type for the interface.
956+
957+ // Q: Should endian_buffer supply "value_type operator value_type() const noexcept"?
958+ // A: No. The rationale for endian_buffers is to prevent high-cost hidden
959+ // conversions. If an implicit conversion operator is supplied, hidden conversions
960+ // can occur.
961+
962+ // unaligned big endian_buffer specialization
963+ template <typename T, std::size_t n_bits>
964+ class endian_buffer< order::big, T, n_bits, align::no >
965+ {
966+ BOOST_STATIC_ASSERT( (n_bits/8)*8 == n_bits );
967+ public:
968+ typedef T value_type;
969+# ifndef BOOST_ENDIAN_NO_CTORS
970+ endian_buffer() BOOST_ENDIAN_DEFAULT_CONSTRUCT
971+ explicit endian_buffer(T val) BOOST_NOEXCEPT
972+ {
973+# ifdef BOOST_ENDIAN_LOG
974+ if ( endian_log )
975+ std::cout << "big, unaligned, "
976+ << n_bits << "-bits, construct(" << val << ")\n";
977+# endif
978+ detail::store_big_endian<T, n_bits/8>(m_value, val);
979+ }
980+# endif
981+ endian_buffer & operator=(T val) BOOST_NOEXCEPT
982+ {
983+# ifdef BOOST_ENDIAN_LOG
984+ if (endian_log)
985+ std::cout << "big, unaligned, " << n_bits << "-bits, assign(" << val << ")\n";
986+# endif
987+ detail::store_big_endian<T, n_bits/8>(m_value, val);
988+ return *this;
989+ }
990+ value_type value() const BOOST_NOEXCEPT
991+ {
992+# ifdef BOOST_ENDIAN_LOG
993+ if ( endian_log )
994+ std::cout << "big, unaligned, " << n_bits << "-bits, convert("
995+ << detail::load_big_endian<T, n_bits/8>(m_value) << ")\n";
996+# endif
997+ return detail::load_big_endian<T, n_bits/8>(m_value);
998+ }
999+ const char* data() const BOOST_NOEXCEPT { return m_value; }
1000+ protected:
1001+ char m_value[n_bits/8];
1002+ };
1003+
1004+ // unaligned little endian_buffer specialization
1005+ template <typename T, std::size_t n_bits>
1006+ class endian_buffer< order::little, T, n_bits, align::no >
1007+ {
1008+ BOOST_STATIC_ASSERT( (n_bits/8)*8 == n_bits );
1009+ public:
1010+ typedef T value_type;
1011+# ifndef BOOST_ENDIAN_NO_CTORS
1012+ endian_buffer() BOOST_ENDIAN_DEFAULT_CONSTRUCT
1013+ explicit endian_buffer(T val) BOOST_NOEXCEPT
1014+ {
1015+# ifdef BOOST_ENDIAN_LOG
1016+ if ( endian_log )
1017+ std::cout << "little, unaligned, " << n_bits << "-bits, construct("
1018+ << val << ")\n";
1019+# endif
1020+ detail::store_little_endian<T, n_bits/8>(m_value, val);
1021+ }
1022+# endif
1023+ endian_buffer & operator=(T val) BOOST_NOEXCEPT
1024+ { detail::store_little_endian<T, n_bits/8>(m_value, val); return *this; }
1025+ value_type value() const BOOST_NOEXCEPT
1026+ {
1027+# ifdef BOOST_ENDIAN_LOG
1028+ if ( endian_log )
1029+ std::cout << "little, unaligned, " << n_bits << "-bits, convert("
1030+ << detail::load_little_endian<T, n_bits/8>(m_value) << ")\n";
1031+# endif
1032+ return detail::load_little_endian<T, n_bits/8>(m_value);
1033+ }
1034+ const char* data() const BOOST_NOEXCEPT { return m_value; }
1035+ protected:
1036+ char m_value[n_bits/8];
1037+ };
1038+
1039+ // align::yes specializations; only n_bits == 16/32/64 supported
1040+
1041+ // aligned big endian_buffer specialization
1042+ template <typename T, std::size_t n_bits>
1043+ class endian_buffer<order::big, T, n_bits, align::yes>
1044+ {
1045+ BOOST_STATIC_ASSERT( (n_bits/8)*8 == n_bits );
1046+ BOOST_STATIC_ASSERT( sizeof(T) == n_bits/8 );
1047+ public:
1048+ typedef T value_type;
1049+# ifndef BOOST_ENDIAN_NO_CTORS
1050+ endian_buffer() BOOST_ENDIAN_DEFAULT_CONSTRUCT
1051+ explicit endian_buffer(T val) BOOST_NOEXCEPT
1052+ {
1053+# ifdef BOOST_ENDIAN_LOG
1054+ if ( endian_log )
1055+ std::cout << "big, aligned, " << n_bits
1056+ << "-bits, construct(" << val << ")\n";
1057+# endif
1058+ m_value = ::boost::endian::native_to_big(val);
1059+ }
1060+
1061+# endif
1062+ endian_buffer& operator=(T val) BOOST_NOEXCEPT
1063+ {
1064+ m_value = ::boost::endian::native_to_big(val);
1065+ return *this;
1066+ }
1067+ //operator value_type() const BOOST_NOEXCEPT
1068+ //{
1069+ // return ::boost::endian::big_to_native(m_value);
1070+ //}
1071+ value_type value() const BOOST_NOEXCEPT
1072+ {
1073+# ifdef BOOST_ENDIAN_LOG
1074+ if ( endian_log )
1075+ std::cout << "big, aligned, " << n_bits << "-bits, convert("
1076+ << ::boost::endian::big_to_native(m_value) << ")\n";
1077+# endif
1078+ return ::boost::endian::big_to_native(m_value);
1079+ }
1080+ const char* data() const BOOST_NOEXCEPT
1081+ {return reinterpret_cast<const char*>(&m_value);}
1082+ protected:
1083+ T m_value;
1084+ };
1085+
1086+ // aligned little endian_buffer specialization
1087+ template <typename T, std::size_t n_bits>
1088+ class endian_buffer<order::little, T, n_bits, align::yes>
1089+ {
1090+ BOOST_STATIC_ASSERT( (n_bits/8)*8 == n_bits );
1091+ BOOST_STATIC_ASSERT( sizeof(T) == n_bits/8 );
1092+ public:
1093+ typedef T value_type;
1094+# ifndef BOOST_ENDIAN_NO_CTORS
1095+ endian_buffer() BOOST_ENDIAN_DEFAULT_CONSTRUCT
1096+ explicit endian_buffer(T val) BOOST_NOEXCEPT
1097+ {
1098+# ifdef BOOST_ENDIAN_LOG
1099+ if ( endian_log )
1100+ std::cout << "little, aligned, " << n_bits
1101+ << "-bits, construct(" << val << ")\n";
1102+# endif
1103+ m_value = ::boost::endian::native_to_little(val);
1104+ }
1105+
1106+# endif
1107+ endian_buffer& operator=(T val) BOOST_NOEXCEPT
1108+ {
1109+ m_value = ::boost::endian::native_to_little(val);
1110+ return *this;
1111+ }
1112+ value_type value() const BOOST_NOEXCEPT
1113+ {
1114+# ifdef BOOST_ENDIAN_LOG
1115+ if ( endian_log )
1116+ std::cout << "little, aligned, " << n_bits << "-bits, convert("
1117+ << ::boost::endian::little_to_native(m_value) << ")\n";
1118+# endif
1119+ return ::boost::endian::little_to_native(m_value);
1120+ }
1121+ const char* data() const BOOST_NOEXCEPT
1122+ {return reinterpret_cast<const char*>(&m_value);}
1123+ protected:
1124+ T m_value;
1125+ };
1126+
1127+} // namespace endian
1128+} // namespace boost
1129+
1130+#if defined(__BORLANDC__) || defined( __CODEGEARC__)
1131+# pragma pack(pop)
1132+#endif
1133+
1134+#if defined(_MSC_VER)
1135+# pragma warning(pop)
1136+#endif
1137+
1138+#endif // BOOST_ENDIAN_BUFFERS_HPP
1139
1140=== added file '3rd-party/boost/endian/conversion.hpp'
1141--- 3rd-party/boost/endian/conversion.hpp 1970-01-01 00:00:00 +0000
1142+++ 3rd-party/boost/endian/conversion.hpp 2016-03-17 09:08:50 +0000
1143@@ -0,0 +1,487 @@
1144+// boost/endian/conversion.hpp -------------------------------------------------------//
1145+
1146+// Copyright Beman Dawes 2010, 2011, 2014
1147+
1148+// Distributed under the Boost Software License, Version 1.0.
1149+// http://www.boost.org/LICENSE_1_0.txt
1150+
1151+#ifndef BOOST_ENDIAN_CONVERSION_HPP
1152+#define BOOST_ENDIAN_CONVERSION_HPP
1153+
1154+#include <boost/config.hpp>
1155+#include <boost/predef/detail/endian_compat.h>
1156+#include <boost/cstdint.hpp>
1157+#include <boost/endian/detail/intrinsic.hpp>
1158+#include <boost/core/scoped_enum.hpp>
1159+#include <boost/static_assert.hpp>
1160+#include <algorithm>
1161+#include <cstring> // for memcpy
1162+
1163+//------------------------------------- synopsis ---------------------------------------//
1164+
1165+namespace boost
1166+{
1167+namespace endian
1168+{
1169+#ifndef BOOST_ENDIAN_ORDER_ENUM_DEFINED
1170+ BOOST_SCOPED_ENUM_START(order)
1171+ {
1172+ big, little,
1173+# ifdef BOOST_BIG_ENDIAN
1174+ native = big
1175+# else
1176+ native = little
1177+# endif
1178+ }; BOOST_SCOPED_ENUM_END
1179+# define BOOST_ENDIAN_ORDER_ENUM_DEFINED
1180+#endif
1181+
1182+//--------------------------------------------------------------------------------------//
1183+// //
1184+// return-by-value interfaces //
1185+// suggested by Phil Endecott //
1186+// //
1187+// user-defined types (UDTs) //
1188+// //
1189+// All return-by-value conversion function templates are required to be implemented in //
1190+// terms of an unqualified call to "endian_reverse(x)", a function returning the //
1191+// value of x with endianness reversed. This provides a customization point for any //
1192+// UDT that provides a "endian_reverse" free-function meeting the requirements. //
1193+// It must be defined in the same namespace as the UDT itself so that it will be found //
1194+// by argument dependent lookup (ADL). //
1195+// //
1196+//--------------------------------------------------------------------------------------//
1197+
1198+ // customization for exact-length arithmetic types. See doc/conversion.html/#FAQ
1199+ inline int8_t endian_reverse(int8_t x) BOOST_NOEXCEPT;
1200+ inline int16_t endian_reverse(int16_t x) BOOST_NOEXCEPT;
1201+ inline int32_t endian_reverse(int32_t x) BOOST_NOEXCEPT;
1202+ inline int64_t endian_reverse(int64_t x) BOOST_NOEXCEPT;
1203+ inline uint8_t endian_reverse(uint8_t x) BOOST_NOEXCEPT;
1204+ inline uint16_t endian_reverse(uint16_t x) BOOST_NOEXCEPT;
1205+ inline uint32_t endian_reverse(uint32_t x) BOOST_NOEXCEPT;
1206+ inline uint64_t endian_reverse(uint64_t x) BOOST_NOEXCEPT;
1207+
1208+ // reverse byte order unless native endianness is big
1209+ template <class EndianReversible >
1210+ inline EndianReversible big_to_native(EndianReversible x) BOOST_NOEXCEPT;
1211+ // Returns: x if native endian order is big, otherwise endian_reverse(x)
1212+ template <class EndianReversible >
1213+ inline EndianReversible native_to_big(EndianReversible x) BOOST_NOEXCEPT;
1214+ // Returns: x if native endian order is big, otherwise endian_reverse(x)
1215+
1216+ // reverse byte order unless native endianness is little
1217+ template <class EndianReversible >
1218+ inline EndianReversible little_to_native(EndianReversible x) BOOST_NOEXCEPT;
1219+ // Returns: x if native endian order is little, otherwise endian_reverse(x)
1220+ template <class EndianReversible >
1221+ inline EndianReversible native_to_little(EndianReversible x) BOOST_NOEXCEPT;
1222+ // Returns: x if native endian order is little, otherwise endian_reverse(x)
1223+
1224+ // generic conditional reverse byte order
1225+ template <BOOST_SCOPED_ENUM(order) From, BOOST_SCOPED_ENUM(order) To,
1226+ class EndianReversible>
1227+ inline EndianReversible conditional_reverse(EndianReversible from) BOOST_NOEXCEPT;
1228+ // Returns: If From == To have different values, from.
1229+ // Otherwise endian_reverse(from).
1230+ // Remarks: The From == To test, and as a consequence which form the return takes, is
1231+ // is determined at compile time.
1232+
1233+ // runtime conditional reverse byte order
1234+ template <class EndianReversible >
1235+ inline EndianReversible conditional_reverse(EndianReversible from,
1236+ BOOST_SCOPED_ENUM(order) from_order, BOOST_SCOPED_ENUM(order) to_order)
1237+ BOOST_NOEXCEPT;
1238+ // Returns: from_order == to_order ? from : endian_reverse(from).
1239+
1240+ //------------------------------------------------------------------------------------//
1241+
1242+
1243+ // Q: What happended to bswap, htobe, and the other synonym functions based on names
1244+ // popularized by BSD, OS X, and Linux?
1245+ // A: Turned out these may be implemented as macros on some systems. Ditto POSIX names
1246+ // for such functionality. Since macros would cause endless problems with functions
1247+ // of the same names, and these functions are just synonyms anyhow, they have been
1248+ // removed.
1249+
1250+
1251+ //------------------------------------------------------------------------------------//
1252+ // //
1253+ // reverse in place interfaces //
1254+ // //
1255+ // user-defined types (UDTs) //
1256+ // //
1257+ // All reverse in place function templates are required to be implemented in terms //
1258+ // of an unqualified call to "endian_reverse_inplace(x)", a function reversing //
1259+ // the endianness of x, which is a non-const reference. This provides a //
1260+ // customization point for any UDT that provides a "reverse_inplace" free-function //
1261+ // meeting the requirements. The free-function must be declared in the same //
1262+ // namespace as the UDT itself so that it will be found by argument-dependent //
1263+ // lookup (ADL). //
1264+ // //
1265+ //------------------------------------------------------------------------------------//
1266+
1267+ // reverse in place
1268+ template <class EndianReversible>
1269+ inline void endian_reverse_inplace(EndianReversible& x) BOOST_NOEXCEPT;
1270+ // Effects: x = endian_reverse(x)
1271+
1272+ // reverse in place unless native endianness is big
1273+ template <class EndianReversibleInplace>
1274+ inline void big_to_native_inplace(EndianReversibleInplace& x) BOOST_NOEXCEPT;
1275+ // Effects: none if native byte-order is big, otherwise endian_reverse_inplace(x)
1276+ template <class EndianReversibleInplace>
1277+ inline void native_to_big_inplace(EndianReversibleInplace& x) BOOST_NOEXCEPT;
1278+ // Effects: none if native byte-order is big, otherwise endian_reverse_inplace(x)
1279+
1280+ // reverse in place unless native endianness is little
1281+ template <class EndianReversibleInplace>
1282+ inline void little_to_native_inplace(EndianReversibleInplace& x) BOOST_NOEXCEPT;
1283+ // Effects: none if native byte-order is little, otherwise endian_reverse_inplace(x);
1284+ template <class EndianReversibleInplace>
1285+ inline void native_to_little_inplace(EndianReversibleInplace& x) BOOST_NOEXCEPT;
1286+ // Effects: none if native byte-order is little, otherwise endian_reverse_inplace(x);
1287+
1288+ // generic conditional reverse in place
1289+ template <BOOST_SCOPED_ENUM(order) From, BOOST_SCOPED_ENUM(order) To,
1290+ class EndianReversibleInplace>
1291+ inline void conditional_reverse_inplace(EndianReversibleInplace& x) BOOST_NOEXCEPT;
1292+
1293+ // runtime reverse in place
1294+ template <class EndianReversibleInplace>
1295+ inline void conditional_reverse_inplace(EndianReversibleInplace& x,
1296+ BOOST_SCOPED_ENUM(order) from_order, BOOST_SCOPED_ENUM(order) to_order)
1297+ BOOST_NOEXCEPT;
1298+
1299+//----------------------------------- end synopsis -------------------------------------//
1300+
1301+ namespace detail
1302+ {
1303+ // generic reverse function template implementation approach using std::reverse
1304+ // suggested by Mathias Gaunard. Primary motivation for inclusion is to have an
1305+ // independent implementation to test against.
1306+
1307+ template <class T>
1308+ inline T std_endian_reverse(T x) BOOST_NOEXCEPT
1309+ {
1310+ T tmp(x);
1311+ std::reverse(
1312+ reinterpret_cast<unsigned char*>(&tmp),
1313+ reinterpret_cast<unsigned char*>(&tmp) + sizeof(T));
1314+ return tmp;
1315+ }
1316+
1317+ // conditional unaligned reverse copy, patterned after std::reverse_copy
1318+ template <class T>
1319+ inline void big_reverse_copy(T from, char* to) BOOST_NOEXCEPT;
1320+ template <class T>
1321+ inline void big_reverse_copy(const char* from, T& to) BOOST_NOEXCEPT;
1322+ template <class T>
1323+ inline void little_reverse_copy(T from, char* to) BOOST_NOEXCEPT;
1324+ template <class T>
1325+ inline void little_reverse_copy(const char* from, T& to) BOOST_NOEXCEPT;
1326+ } // namespace detail
1327+
1328+//--------------------------------------------------------------------------------------//
1329+// //
1330+// return-by-value implementation //
1331+// //
1332+// -- portable approach suggested by tymofey, with avoidance of undefined behavior //
1333+// as suggested by Giovanni Piero Deretta, with a further refinement suggested //
1334+// by Pyry Jahkola. //
1335+// -- intrinsic approach suggested by reviewers, and by David Stone, who provided //
1336+// his Boost licensed macro implementation (detail/intrinsic.hpp) //
1337+// //
1338+//--------------------------------------------------------------------------------------//
1339+
1340+ inline int8_t endian_reverse(int8_t x) BOOST_NOEXCEPT
1341+ {
1342+ return x;
1343+ }
1344+
1345+ inline int16_t endian_reverse(int16_t x) BOOST_NOEXCEPT
1346+ {
1347+# ifdef BOOST_ENDIAN_NO_INTRINSICS
1348+ return (static_cast<uint16_t>(x) << 8)
1349+ | (static_cast<uint16_t>(x) >> 8);
1350+# else
1351+ return BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_2(static_cast<uint16_t>(x));
1352+# endif
1353+ }
1354+
1355+ inline int32_t endian_reverse(int32_t x) BOOST_NOEXCEPT
1356+ {
1357+# ifdef BOOST_ENDIAN_NO_INTRINSICS
1358+ uint32_t step16;
1359+ step16 = static_cast<uint32_t>(x) << 16 | static_cast<uint32_t>(x) >> 16;
1360+ return
1361+ ((static_cast<uint32_t>(step16) << 8) & 0xff00ff00)
1362+ | ((static_cast<uint32_t>(step16) >> 8) & 0x00ff00ff);
1363+# else
1364+ return BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_4(static_cast<uint32_t>(x));
1365+# endif
1366+ }
1367+
1368+ inline int64_t endian_reverse(int64_t x) BOOST_NOEXCEPT
1369+ {
1370+# ifdef BOOST_ENDIAN_NO_INTRINSICS
1371+ uint64_t step32, step16;
1372+ step32 = static_cast<uint64_t>(x) << 32 | static_cast<uint64_t>(x) >> 32;
1373+ step16 = (step32 & 0x0000FFFF0000FFFFULL) << 16
1374+ | (step32 & 0xFFFF0000FFFF0000ULL) >> 16;
1375+ return static_cast<int64_t>((step16 & 0x00FF00FF00FF00FFULL) << 8
1376+ | (step16 & 0xFF00FF00FF00FF00ULL) >> 8);
1377+# else
1378+ return BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_8(static_cast<uint64_t>(x));
1379+# endif
1380+ }
1381+
1382+ inline uint8_t endian_reverse(uint8_t x) BOOST_NOEXCEPT
1383+ {
1384+ return x;
1385+ }
1386+
1387+ inline uint16_t endian_reverse(uint16_t x) BOOST_NOEXCEPT
1388+ {
1389+# ifdef BOOST_ENDIAN_NO_INTRINSICS
1390+ return (x << 8)
1391+ | (x >> 8);
1392+# else
1393+ return BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_2(x);
1394+# endif
1395+ }
1396+
1397+ inline uint32_t endian_reverse(uint32_t x) BOOST_NOEXCEPT
1398+ {
1399+# ifdef BOOST_ENDIAN_NO_INTRINSICS
1400+ uint32_t step16;
1401+ step16 = x << 16 | x >> 16;
1402+ return
1403+ ((step16 << 8) & 0xff00ff00)
1404+ | ((step16 >> 8) & 0x00ff00ff);
1405+# else
1406+ return BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_4(x);
1407+# endif
1408+ }
1409+
1410+ inline uint64_t endian_reverse(uint64_t x) BOOST_NOEXCEPT
1411+ {
1412+# ifdef BOOST_ENDIAN_NO_INTRINSICS
1413+ uint64_t step32, step16;
1414+ step32 = x << 32 | x >> 32;
1415+ step16 = (step32 & 0x0000FFFF0000FFFFULL) << 16
1416+ | (step32 & 0xFFFF0000FFFF0000ULL) >> 16;
1417+ return (step16 & 0x00FF00FF00FF00FFULL) << 8
1418+ | (step16 & 0xFF00FF00FF00FF00ULL) >> 8;
1419+# else
1420+ return BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_8(x);
1421+# endif
1422+ }
1423+
1424+ template <class EndianReversible >
1425+ inline EndianReversible big_to_native(EndianReversible x) BOOST_NOEXCEPT
1426+ {
1427+# ifdef BOOST_BIG_ENDIAN
1428+ return x;
1429+# else
1430+ return endian_reverse(x);
1431+# endif
1432+ }
1433+
1434+ template <class EndianReversible >
1435+ inline EndianReversible native_to_big(EndianReversible x) BOOST_NOEXCEPT
1436+ {
1437+# ifdef BOOST_BIG_ENDIAN
1438+ return x;
1439+# else
1440+ return endian_reverse(x);
1441+# endif
1442+ }
1443+
1444+ template <class EndianReversible >
1445+ inline EndianReversible little_to_native(EndianReversible x) BOOST_NOEXCEPT
1446+ {
1447+# ifdef BOOST_LITTLE_ENDIAN
1448+ return x;
1449+# else
1450+ return endian_reverse(x);
1451+# endif
1452+ }
1453+
1454+ template <class EndianReversible >
1455+ inline EndianReversible native_to_little(EndianReversible x) BOOST_NOEXCEPT
1456+ {
1457+# ifdef BOOST_LITTLE_ENDIAN
1458+ return x;
1459+# else
1460+ return endian_reverse(x);
1461+# endif
1462+ }
1463+
1464+ namespace detail
1465+ {
1466+ // Primary template and specializations to support endian_reverse().
1467+ // See rationale in endian_reverse() below.
1468+ template <BOOST_SCOPED_ENUM(order) From, BOOST_SCOPED_ENUM(order) To,
1469+ class EndianReversible>
1470+ class value_converter ; // primary template
1471+ template <class T> class value_converter <order::big, order::big, T>
1472+ {public: T operator()(T x) BOOST_NOEXCEPT {return x;}};
1473+ template <class T> class value_converter <order::little, order::little, T>
1474+ {public: T operator()(T x) BOOST_NOEXCEPT {return x;}};
1475+ template <class T> class value_converter <order::big, order::little, T>
1476+ {public: T operator()(T x) BOOST_NOEXCEPT {return endian_reverse(x);}};
1477+ template <class T> class value_converter <order::little, order::big, T>
1478+ {public: T operator()(T x) BOOST_NOEXCEPT {return endian_reverse(x);}};
1479+ }
1480+
1481+ // generic conditional reverse
1482+ template <BOOST_SCOPED_ENUM(order) From, BOOST_SCOPED_ENUM(order) To,
1483+ class EndianReversible>
1484+ inline EndianReversible conditional_reverse(EndianReversible from) BOOST_NOEXCEPT {
1485+ // work around lack of function template partial specialization by instantiating
1486+ // a function object of a class that is partially specialized on the two order
1487+ // template parameters, and then calling its operator().
1488+ detail::value_converter <From, To, EndianReversible> tmp;
1489+ return tmp(from);
1490+ }
1491+
1492+ // runtime conditional reverse
1493+ template <class EndianReversible >
1494+ inline EndianReversible conditional_reverse(EndianReversible from,
1495+ BOOST_SCOPED_ENUM(order) from_order, BOOST_SCOPED_ENUM(order) to_order) BOOST_NOEXCEPT
1496+ {
1497+ return from_order == to_order ? from : endian_reverse(from);
1498+ }
1499+
1500+//--------------------------------------------------------------------------------------//
1501+// reverse-in-place implementation //
1502+//--------------------------------------------------------------------------------------//
1503+
1504+ // reverse in place
1505+ template <class EndianReversible>
1506+ inline void endian_reverse_inplace(EndianReversible& x) BOOST_NOEXCEPT
1507+ {
1508+ x = endian_reverse(x);
1509+ }
1510+
1511+ template <class EndianReversibleInplace>
1512+# ifdef BOOST_BIG_ENDIAN
1513+ inline void big_to_native_inplace(EndianReversibleInplace&) BOOST_NOEXCEPT {}
1514+# else
1515+ inline void big_to_native_inplace(EndianReversibleInplace& x) BOOST_NOEXCEPT
1516+ { endian_reverse_inplace(x); }
1517+# endif
1518+ template <class EndianReversibleInplace>
1519+# ifdef BOOST_BIG_ENDIAN
1520+ inline void native_to_big_inplace(EndianReversibleInplace&) BOOST_NOEXCEPT {}
1521+# else
1522+ inline void native_to_big_inplace(EndianReversibleInplace& x) BOOST_NOEXCEPT
1523+ {
1524+ endian_reverse_inplace(x);
1525+ }
1526+# endif
1527+
1528+ template <class EndianReversibleInplace>
1529+# ifdef BOOST_LITTLE_ENDIAN
1530+ inline void little_to_native_inplace(EndianReversibleInplace&) BOOST_NOEXCEPT {}
1531+# else
1532+ inline void little_to_native_inplace(EndianReversibleInplace& x) BOOST_NOEXCEPT
1533+ { endian_reverse_inplace(x); }
1534+# endif
1535+ template <class EndianReversibleInplace>
1536+# ifdef BOOST_LITTLE_ENDIAN
1537+ inline void native_to_little_inplace(EndianReversibleInplace&) BOOST_NOEXCEPT {}
1538+# else
1539+ inline void native_to_little_inplace(EndianReversibleInplace& x) BOOST_NOEXCEPT
1540+ {
1541+ endian_reverse_inplace(x);
1542+ }
1543+# endif
1544+
1545+ namespace detail
1546+ {
1547+ // Primary template and specializations support generic
1548+ // endian_reverse_inplace().
1549+ // See rationale in endian_reverse_inplace() below.
1550+ template <BOOST_SCOPED_ENUM(order) From, BOOST_SCOPED_ENUM(order) To,
1551+ class EndianReversibleInplace>
1552+ class converter; // primary template
1553+ template <class T> class converter<order::big, order::big, T>
1554+ {public: void operator()(T&) BOOST_NOEXCEPT {/*no effect*/}};
1555+ template <class T> class converter<order::little, order::little, T>
1556+ {public: void operator()(T&) BOOST_NOEXCEPT {/*no effect*/}};
1557+ template <class T> class converter<order::big, order::little, T>
1558+ {public: void operator()(T& x) BOOST_NOEXCEPT { endian_reverse_inplace(x); }};
1559+ template <class T> class converter<order::little, order::big, T>
1560+ {public: void operator()(T& x) BOOST_NOEXCEPT { endian_reverse_inplace(x); }};
1561+ } // namespace detail
1562+
1563+ // generic conditional reverse in place
1564+ template <BOOST_SCOPED_ENUM(order) From, BOOST_SCOPED_ENUM(order) To,
1565+ class EndianReversibleInplace>
1566+ inline void conditional_reverse_inplace(EndianReversibleInplace& x) BOOST_NOEXCEPT
1567+ {
1568+ // work around lack of function template partial specialization by instantiating
1569+ // a function object of a class that is partially specialized on the two order
1570+ // template parameters, and then calling its operator().
1571+ detail::converter<From, To, EndianReversibleInplace> tmp;
1572+ tmp(x); // call operator ()
1573+ }
1574+
1575+ // runtime reverse in place
1576+ template <class EndianReversibleInplace>
1577+ inline void conditional_reverse_inplace(EndianReversibleInplace& x,
1578+ BOOST_SCOPED_ENUM(order) from_order, BOOST_SCOPED_ENUM(order) to_order)
1579+ BOOST_NOEXCEPT
1580+ {
1581+ if (from_order != to_order)
1582+ endian_reverse_inplace(x);
1583+ }
1584+
1585+
1586+ namespace detail
1587+ {
1588+ template <class T>
1589+ inline void big_reverse_copy(T from, char* to) BOOST_NOEXCEPT
1590+ {
1591+# ifdef BOOST_BIG_ENDIAN
1592+ std::memcpy(to, reinterpret_cast<const char*>(&from), sizeof(T));
1593+# else
1594+ std::reverse_copy(reinterpret_cast<const char*>(&from),
1595+ reinterpret_cast<const char*>(&from) + sizeof(T), to);
1596+# endif
1597+ }
1598+ template <class T>
1599+ inline void big_reverse_copy(const char* from, T& to) BOOST_NOEXCEPT
1600+ {
1601+# ifdef BOOST_BIG_ENDIAN
1602+ std::memcpy(reinterpret_cast<char*>(&to), from, sizeof(T));
1603+# else
1604+ std::reverse_copy(from, from + sizeof(T), reinterpret_cast<char*>(&to));
1605+# endif
1606+ }
1607+ template <class T>
1608+ inline void little_reverse_copy(T from, char* to) BOOST_NOEXCEPT
1609+ {
1610+# ifdef BOOST_LITTLE_ENDIAN
1611+ std::memcpy(to, reinterpret_cast<const char*>(&from), sizeof(T));
1612+# else
1613+ std::reverse_copy(reinterpret_cast<const char*>(&from),
1614+ reinterpret_cast<const char*>(&from) + sizeof(T), to);
1615+# endif
1616+ }
1617+ template <class T>
1618+ inline void little_reverse_copy(const char* from, T& to) BOOST_NOEXCEPT
1619+ {
1620+# ifdef BOOST_LITTLE_ENDIAN
1621+ std::memcpy(reinterpret_cast<char*>(&to), from, sizeof(T));
1622+# else
1623+ std::reverse_copy(from, from + sizeof(T), reinterpret_cast<char*>(&to));
1624+# endif
1625+ }
1626+ } // namespace detail
1627+} // namespace endian
1628+} // namespace boost
1629+
1630+#endif // BOOST_ENDIAN_CONVERSION_HPP
1631
1632=== added directory '3rd-party/boost/endian/detail'
1633=== added file '3rd-party/boost/endian/detail/config.hpp'
1634--- 3rd-party/boost/endian/detail/config.hpp 1970-01-01 00:00:00 +0000
1635+++ 3rd-party/boost/endian/detail/config.hpp 2016-03-17 09:08:50 +0000
1636@@ -0,0 +1,62 @@
1637+// boost/endian/detail/config.hpp ----------------------------------------------------//
1638+
1639+// Copyright Beman Dawes 2003, 2010
1640+
1641+// Distributed under the Boost Software License, Version 1.0.
1642+// See http://www.boost.org/LICENSE_1_0.txt
1643+
1644+//--------------------------------------------------------------------------------------//
1645+
1646+#ifndef BOOST_ENDIAN_CONFIG_HPP
1647+#define BOOST_ENDIAN_CONFIG_HPP
1648+
1649+// This header implements separate compilation features as described in
1650+// http://www.boost.org/more/separate_compilation.html
1651+
1652+#include <boost/config.hpp>
1653+#include <boost/system/api_config.hpp> // for BOOST_POSIX_API or BOOST_WINDOWS_API
1654+
1655+// throw an exception ----------------------------------------------------------------//
1656+//
1657+// Exceptions were originally thrown via boost::throw_exception().
1658+// As throw_exception() became more complex, it caused user error reporting
1659+// to be harder to interpret, since the exception reported became much more complex.
1660+// The immediate fix was to throw directly, wrapped in a macro to make any later change
1661+// easier.
1662+
1663+#define BOOST_ENDIAN_THROW(EX) throw EX
1664+
1665+// enable dynamic linking -------------------------------------------------------------//
1666+
1667+#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_ENDIAN_DYN_LINK)
1668+# if defined(BOOST_ENDIAN_SOURCE)
1669+# define BOOST_ENDIAN_DECL BOOST_SYMBOL_EXPORT
1670+# else
1671+# define BOOST_ENDIAN_DECL BOOST_SYMBOL_IMPORT
1672+# endif
1673+#else
1674+# define BOOST_ENDIAN_DECL
1675+#endif
1676+
1677+// enable automatic library variant selection ----------------------------------------//
1678+
1679+#if !defined(BOOST_ENDIAN_SOURCE) && !defined(BOOST_ALL_NO_LIB) \
1680+ && !defined(BOOST_ENDIAN_NO_LIB)
1681+//
1682+// Set the name of our library, this will get undef'ed by auto_link.hpp
1683+// once it's done with it:
1684+//
1685+#define BOOST_LIB_NAME boost_endian
1686+//
1687+// If we're importing code from a dll, then tell auto_link.hpp about it:
1688+//
1689+#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_ENDIAN_DYN_LINK)
1690+# define BOOST_DYN_LINK
1691+#endif
1692+//
1693+// And include the header that does the work:
1694+//
1695+#include <boost/config/auto_link.hpp>
1696+#endif // auto-linking disabled
1697+
1698+#endif // BOOST_ENDIAN_CONFIG_HPP
1699
1700=== added file '3rd-party/boost/endian/detail/cover_operators.hpp'
1701--- 3rd-party/boost/endian/detail/cover_operators.hpp 1970-01-01 00:00:00 +0000
1702+++ 3rd-party/boost/endian/detail/cover_operators.hpp 2016-03-17 09:08:50 +0000
1703@@ -0,0 +1,142 @@
1704+// boost/endian/detail/cover_operators.hpp ----------------------------------//
1705+
1706+// Copyright Darin Adler 2000
1707+// Copyright Beman Dawes 2008
1708+
1709+// Distributed under the Boost Software License, Version 1.0. (See accompanying
1710+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
1711+
1712+#ifndef BOOST_ENDIAN_COVER_OPERATORS_HPP
1713+#define BOOST_ENDIAN_COVER_OPERATORS_HPP
1714+
1715+#if defined(_MSC_VER)
1716+# pragma warning(push)
1717+# pragma warning(disable:4365) // conversion ... signed/unsigned mismatch
1718+#endif
1719+
1720+# ifndef BOOST_ENDIAN_MINIMAL_COVER_OPERATORS
1721+# include <boost/operators.hpp>
1722+# endif
1723+
1724+#include <boost/config.hpp>
1725+#include <iosfwd>
1726+
1727+namespace boost
1728+{
1729+ namespace endian
1730+ {
1731+
1732+//--------------------------------------------------------------------------------------//
1733+
1734+// A class that adds arithmetic operators to an arithmetic cover class
1735+//
1736+// Uses the curiously recurring template pattern (CRTP).
1737+//
1738+// If the class being covered has a non-explicit conversion to an integer type
1739+// then a smaller number of cover operations are needed. Define the macro
1740+// BOOST_ENDIAN_MINIMAL_COVER_OPERATORS to indicate this.
1741+//
1742+// Define BOOST_NO_IO_COVER_OPERATORS if I/O cover operations are not desired.
1743+
1744+//--------------------------------------------------------------------------------------//
1745+
1746+ template <class D, // D is the CRTP derived type, i.e. the cover class
1747+ class ArithmeticT>
1748+ class cover_operators
1749+# ifndef BOOST_ENDIAN_MINIMAL_COVER_OPERATORS
1750+ : boost::operators<D>
1751+# endif
1752+ {
1753+ // The other operations take advantage of the type conversion that's
1754+ // built into unary +.
1755+
1756+ // Unary operations.
1757+ friend ArithmeticT operator+(const D& x) BOOST_NOEXCEPT { return x; }
1758+# ifndef BOOST_ENDIAN_MINIMAL_COVER_OPERATORS
1759+ friend ArithmeticT operator-(const D& x) BOOST_NOEXCEPT { return -+x; }
1760+ friend ArithmeticT operator~(const D& x) BOOST_NOEXCEPT { return ~+x; }
1761+ friend ArithmeticT operator!(const D& x) BOOST_NOEXCEPT { return !+x; }
1762+
1763+ // The basic ordering operations.
1764+ friend bool operator==(const D& x, ArithmeticT y) BOOST_NOEXCEPT { return +x == y; }
1765+ friend bool operator<(const D& x, ArithmeticT y) BOOST_NOEXCEPT { return +x < y; }
1766+# endif
1767+
1768+ // The basic arithmetic operations.
1769+ friend D& operator+=(D& x, ArithmeticT y) BOOST_NOEXCEPT
1770+ { return x = static_cast<ArithmeticT>(+x + y); }
1771+ friend D& operator-=(D& x, ArithmeticT y) BOOST_NOEXCEPT
1772+ { return x = static_cast<ArithmeticT>(+x - y); }
1773+ friend D& operator*=(D& x, ArithmeticT y) BOOST_NOEXCEPT
1774+ { return x = static_cast<ArithmeticT>(+x * y); }
1775+ friend D& operator/=(D& x, ArithmeticT y) BOOST_NOEXCEPT
1776+ { return x = static_cast<ArithmeticT>(+x / y); }
1777+ friend D& operator%=(D& x, ArithmeticT y) BOOST_NOEXCEPT
1778+ { return x = static_cast<ArithmeticT>(+x % y); }
1779+ friend D& operator&=(D& x, ArithmeticT y) BOOST_NOEXCEPT
1780+ { return x = static_cast<ArithmeticT>(+x & y); }
1781+ friend D& operator|=(D& x, ArithmeticT y) BOOST_NOEXCEPT
1782+ { return x = static_cast<ArithmeticT>(+x | y); }
1783+ friend D& operator^=(D& x, ArithmeticT y) BOOST_NOEXCEPT
1784+ { return x = static_cast<ArithmeticT>(+x ^ y); }
1785+ friend D& operator<<=(D& x, ArithmeticT y) BOOST_NOEXCEPT
1786+ { return x = static_cast<ArithmeticT>(+x << y); }
1787+ friend D& operator>>=(D& x, ArithmeticT y) BOOST_NOEXCEPT
1788+ { return x = static_cast<ArithmeticT>(+x >> y); }
1789+
1790+ // A few binary arithmetic operations not covered by operators base class.
1791+ friend ArithmeticT operator<<(const D& x, ArithmeticT y) BOOST_NOEXCEPT
1792+ { return static_cast<ArithmeticT>(+x << y); }
1793+ friend ArithmeticT operator>>(const D& x, ArithmeticT y) BOOST_NOEXCEPT
1794+ { return static_cast<ArithmeticT>(+x >> y); }
1795+
1796+ // Auto-increment and auto-decrement can be defined in terms of the
1797+ // arithmetic operations.
1798+ friend D& operator++(D& x) BOOST_NOEXCEPT { return x += 1; }
1799+ friend D& operator--(D& x) BOOST_NOEXCEPT { return x -= 1; }
1800+
1801+# ifdef BOOST_ENDIAN_MINIMAL_COVER_OPERATORS
1802+ friend D operator++(D& x, int) BOOST_NOEXCEPT
1803+ {
1804+ D tmp(x);
1805+ x += 1;
1806+ return tmp;
1807+ }
1808+ friend D operator--(D& x, int) BOOST_NOEXCEPT
1809+ {
1810+ D tmp(x);
1811+ x -= 1;
1812+ return tmp;
1813+ }
1814+# endif
1815+
1816+# ifndef BOOST_NO_IO_COVER_OPERATORS
1817+
1818+ // Stream inserter
1819+ template <class charT, class traits>
1820+ friend std::basic_ostream<charT, traits>&
1821+ operator<<(std::basic_ostream<charT, traits>& os, const D& x)
1822+ {
1823+ return os << +x;
1824+ }
1825+
1826+ // Stream extractor
1827+ template <class charT, class traits>
1828+ friend std::basic_istream<charT, traits>&
1829+ operator>>(std::basic_istream<charT, traits>& is, D& x)
1830+ {
1831+ ArithmeticT i;
1832+ if (is >> i)
1833+ x = i;
1834+ return is;
1835+ }
1836+# endif
1837+ };
1838+ } // namespace endian
1839+} // namespace boost
1840+
1841+#if defined(_MSC_VER)
1842+# pragma warning(pop)
1843+#endif
1844+
1845+#endif // BOOST_ENDIAN_COVER_OPERATORS_HPP
1846
1847=== added file '3rd-party/boost/endian/detail/disable_warnings.hpp'
1848--- 3rd-party/boost/endian/detail/disable_warnings.hpp 1970-01-01 00:00:00 +0000
1849+++ 3rd-party/boost/endian/detail/disable_warnings.hpp 2016-03-17 09:08:50 +0000
1850@@ -0,0 +1,33 @@
1851+// disable_warnings.hpp --------------------------------------------------------------//
1852+
1853+// Copyright Beman Dawes 2011
1854+
1855+// Distributed under the Boost Software License, Version 1.0.
1856+// See http://www.boost.org/LICENSE_1_0.txt
1857+
1858+//--------------------------------------------------------------------------------------//
1859+
1860+#ifdef _MSC_VER
1861+
1862+#ifndef _SCL_SECURE_NO_WARNINGS
1863+# define _SCL_SECURE_NO_WARNINGS
1864+#endif
1865+
1866+#ifndef _CRT_SECURE_NO_WARNINGS
1867+# define _CRT_SECURE_NO_WARNINGS
1868+#endif
1869+
1870+# pragma warning(push)
1871+
1872+// triggered by boost/detail/lightweight_test.hpp
1873+# pragma warning( disable : 4640 ) // ... construction of local static object is not thread-safe
1874+
1875+// triggered by Microsoft's own headers, so disable
1876+# pragma warning( disable : 4820 ) // padding added after data member
1877+# pragma warning( disable : 4548 ) // expression before comma has no effect
1878+# pragma warning( disable : 4668 ) // ... is not defined as a preprocessor macro
1879+# pragma warning( disable : 4514 ) // ... unreferenced inline function has been removed
1880+# pragma warning( disable : 4710 ) // ... function not inlined
1881+# pragma warning( disable : 4986 ) // ... exception specification does not match previous declaration
1882+# pragma warning( disable : 4711 ) // ... selected for automatic inline expansion
1883+#endif
1884
1885=== added file '3rd-party/boost/endian/detail/disable_warnings_pop.hpp'
1886--- 3rd-party/boost/endian/detail/disable_warnings_pop.hpp 1970-01-01 00:00:00 +0000
1887+++ 3rd-party/boost/endian/detail/disable_warnings_pop.hpp 2016-03-17 09:08:50 +0000
1888@@ -0,0 +1,12 @@
1889+// disable_warnings_pop.hpp ----------------------------------------------------------//
1890+
1891+// Copyright Beman Dawes 2011
1892+
1893+// Distributed under the Boost Software License, Version 1.0.
1894+// See http://www.boost.org/LICENSE_1_0.txt
1895+
1896+//--------------------------------------------------------------------------------------//
1897+
1898+#ifdef _MSC_VER
1899+# pragma warning(push)
1900+#endif
1901
1902=== added file '3rd-party/boost/endian/detail/intrinsic.hpp'
1903--- 3rd-party/boost/endian/detail/intrinsic.hpp 1970-01-01 00:00:00 +0000
1904+++ 3rd-party/boost/endian/detail/intrinsic.hpp 2016-03-17 09:08:50 +0000
1905@@ -0,0 +1,64 @@
1906+// endian/detail/intrinsic.hpp -------------------------------------------------------//
1907+
1908+// Copyright (C) 2012 David Stone
1909+// Copyright Beman Dawes 2013
1910+
1911+// Distributed under the Boost Software License, Version 1.0.
1912+// http://www.boost.org/LICENSE_1_0.txt
1913+
1914+#ifndef BOOST_ENDIAN_INTRINSIC_HPP
1915+#define BOOST_ENDIAN_INTRINSIC_HPP
1916+
1917+// Allow user to force BOOST_ENDIAN_NO_INTRINSICS in case they aren't available for a
1918+// particular platform/compiler combination. Please report such platform/compiler
1919+// combinations to the Boost mailing list.
1920+#ifndef BOOST_ENDIAN_NO_INTRINSICS
1921+
1922+#ifndef __has_builtin // Optional of course
1923+ #define __has_builtin(x) 0 // Compatibility with non-clang compilers
1924+#endif
1925+
1926+// GCC and Clang recent versions provide intrinsic byte swaps via builtins
1927+#if (defined(__clang__) && __has_builtin(__builtin_bswap32) && __has_builtin(__builtin_bswap64)) \
1928+ || (defined(__GNUC__ ) && \
1929+ (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)))
1930+# define BOOST_ENDIAN_INTRINSIC_MSG "__builtin_bswap16, etc."
1931+// prior to 4.8, gcc did not provide __builtin_bswap16 on some platforms so we emulate it
1932+// see http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52624
1933+// Clang has a similar problem, but their feature test macros make it easier to detect
1934+# if (defined(__clang__) && __has_builtin(__builtin_bswap16)) \
1935+ || (defined(__GNUC__) &&(__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)))
1936+# define BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_2(x) __builtin_bswap16(x)
1937+# else
1938+# define BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_2(x) __builtin_bswap32((x) << 16)
1939+# endif
1940+# define BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_4(x) __builtin_bswap32(x)
1941+# define BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_8(x) __builtin_bswap64(x)
1942+
1943+// Linux systems provide the byteswap.h header, with
1944+#elif defined(__linux__)
1945+// don't check for obsolete forms defined(linux) and defined(__linux) on the theory that
1946+// compilers that predefine only these are so old that byteswap.h probably isn't present.
1947+# define BOOST_ENDIAN_INTRINSIC_MSG "byteswap.h bswap_16, etc."
1948+# include <byteswap.h>
1949+# define BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_2(x) bswap_16(x)
1950+# define BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_4(x) bswap_32(x)
1951+# define BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_8(x) bswap_64(x)
1952+
1953+#elif defined(_MSC_VER)
1954+// Microsoft documents these as being compatible since Windows 95 and specificly
1955+// lists runtime library support since Visual Studio 2003 (aka 7.1).
1956+# define BOOST_ENDIAN_INTRINSIC_MSG "cstdlib _byteswap_ushort, etc."
1957+# include <cstdlib>
1958+# define BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_2(x) _byteswap_ushort(x)
1959+# define BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_4(x) _byteswap_ulong(x)
1960+# define BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_8(x) _byteswap_uint64(x)
1961+#else
1962+# define BOOST_ENDIAN_NO_INTRINSICS
1963+# define BOOST_ENDIAN_INTRINSIC_MSG "no byte swap intrinsics"
1964+#endif
1965+
1966+#elif !defined(BOOST_ENDIAN_INTRINSIC_MSG)
1967+# define BOOST_ENDIAN_INTRINSIC_MSG "no byte swap intrinsics"
1968+#endif // BOOST_ENDIAN_NO_INTRINSICS
1969+#endif // BOOST_ENDIAN_INTRINSIC_HPP
1970
1971=== added file '3rd-party/boost/endian/detail/lightweight_test.hpp'
1972--- 3rd-party/boost/endian/detail/lightweight_test.hpp 1970-01-01 00:00:00 +0000
1973+++ 3rd-party/boost/endian/detail/lightweight_test.hpp 2016-03-17 09:08:50 +0000
1974@@ -0,0 +1,223 @@
1975+// boost/endian/detail/lightweight_test.hpp --------------------------------------------//
1976+
1977+#ifndef BOOST_ENDIAN_LIGHTWEIGHT_TEST_HPP
1978+#define BOOST_ENDIAN_LIGHTWEIGHT_TEST_HPP
1979+
1980+// MS compatible compilers support #pragma once
1981+
1982+#if defined(_MSC_VER)
1983+# pragma once
1984+#endif
1985+
1986+//
1987+// Copyright (c) 2002, 2009, 2014 Peter Dimov
1988+// Copyright (2) Beman Dawes 2010, 2011, 2015
1989+// Copyright (3) Ion Gaztanaga 2013
1990+//
1991+// Distributed under the Boost Software License, Version 1.0.
1992+// See http://www.boost.org/LICENSE_1_0.txt
1993+//
1994+
1995+#include <boost/assert.hpp>
1996+#include <boost/current_function.hpp>
1997+#include <boost/core/no_exceptions_support.hpp>
1998+#include <cstring> // for memcmp
1999+#include <iostream>
2000+
2001+// IDE's like Visual Studio perform better if output goes to std::cout or
2002+// some other stream, so allow user to configure output stream:
2003+#ifndef BOOST_LIGHTWEIGHT_TEST_OSTREAM
2004+# define BOOST_LIGHTWEIGHT_TEST_OSTREAM std::cerr
2005+#endif
2006+
2007+namespace boost
2008+{
2009+namespace endian
2010+{
2011+namespace detail
2012+{
2013+
2014+struct report_errors_reminder
2015+{
2016+ bool called_report_errors_function;
2017+
2018+ report_errors_reminder() : called_report_errors_function(false) {}
2019+
2020+ ~report_errors_reminder()
2021+ {
2022+ BOOST_ASSERT(called_report_errors_function); // verify report_errors() was called
2023+ }
2024+};
2025+
2026+inline report_errors_reminder& report_errors_remind()
2027+{
2028+ static report_errors_reminder r;
2029+ return r;
2030+}
2031+
2032+inline int & test_errors()
2033+{
2034+ static int x = 0;
2035+ report_errors_remind();
2036+ return x;
2037+}
2038+
2039+inline void test_failed_impl(char const * expr, char const * file, int line, char const * function)
2040+{
2041+ BOOST_LIGHTWEIGHT_TEST_OSTREAM
2042+ << file << "(" << line << "): test '" << expr << "' failed in function '"
2043+ << function << "'" << std::endl;
2044+ ++test_errors();
2045+}
2046+
2047+inline void error_impl(char const * msg, char const * file, int line, char const * function)
2048+{
2049+ BOOST_LIGHTWEIGHT_TEST_OSTREAM
2050+ << file << "(" << line << "): " << msg << " in function '"
2051+ << function << "'" << std::endl;
2052+ ++test_errors();
2053+}
2054+
2055+inline void throw_failed_impl(char const * excep, char const * file, int line, char const * function)
2056+{
2057+ BOOST_LIGHTWEIGHT_TEST_OSTREAM
2058+ << file << "(" << line << "): Exception '" << excep << "' not thrown in function '"
2059+ << function << "'" << std::endl;
2060+ ++test_errors();
2061+}
2062+
2063+template<class T, class U> inline void test_eq_impl( char const * expr1, char const * expr2,
2064+ char const * file, int line, char const * function, T const & t, U const & u )
2065+{
2066+ if( t == u )
2067+ {
2068+ report_errors_remind();
2069+ }
2070+ else
2071+ {
2072+ BOOST_LIGHTWEIGHT_TEST_OSTREAM
2073+ << file << "(" << line << "): test '" << expr1 << " == " << expr2
2074+ << "' failed in function '" << function << "': "
2075+ << "'" << t << "' != '" << u << "'" << std::endl;
2076+ ++test_errors();
2077+ }
2078+}
2079+
2080+template<class T, class U> inline void test_ne_impl( char const * expr1, char const * expr2,
2081+ char const * file, int line, char const * function, T const & t, U const & u )
2082+{
2083+ if( t != u )
2084+ {
2085+ report_errors_remind();
2086+ }
2087+ else
2088+ {
2089+ BOOST_LIGHTWEIGHT_TEST_OSTREAM
2090+ << file << "(" << line << "): test '" << expr1 << " != " << expr2
2091+ << "' failed in function '" << function << "': "
2092+ << "'" << t << "' == '" << u << "'" << std::endl;
2093+ ++test_errors();
2094+ }
2095+}
2096+
2097+template <class T>
2098+std::string to_hex(const T& x)
2099+{
2100+ const char hex[] = { '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f' };
2101+ std::string tmp;
2102+ const unsigned char* p = reinterpret_cast<const unsigned char*>(&x);
2103+ const unsigned char* e = p + sizeof(T);
2104+
2105+ for (; p < e; ++p)
2106+ {
2107+ tmp += hex[*p >> 4]; // high-order nibble
2108+ tmp += hex[*p & 0x0f]; // low-order nibble
2109+ }
2110+ return tmp;
2111+}
2112+
2113+template<class T, class U> inline bool test_memcmp_eq_impl(char const * expr1,
2114+ char const * expr2, char const * file, int line, char const * function, T const & t,
2115+ U const & u)
2116+{
2117+ BOOST_ASSERT(sizeof(T) == sizeof(U));
2118+ if (sizeof(T) == sizeof(U)
2119+ && std::memcmp(&t, &u, sizeof(T)) == 0)
2120+ {
2121+ report_errors_remind();
2122+ return true;
2123+ }
2124+ else
2125+ {
2126+ BOOST_LIGHTWEIGHT_TEST_OSTREAM
2127+ << file << "(" << line << "): test 'std::memcmp(" << expr1 << ", " << expr2
2128+ << ") == 0' fails in function '" << function << "': "
2129+ << " with values '" << to_hex(t) << "' and '" << to_hex(u) << "'" << std::endl;
2130+ ++test_errors();
2131+ return false;
2132+ }
2133+}
2134+
2135+} // namespace detail
2136+
2137+inline int report_errors()
2138+{
2139+ boost::endian::detail::report_errors_remind().called_report_errors_function = true;
2140+
2141+ int errors = boost::endian::detail::test_errors();
2142+
2143+ if( errors == 0 )
2144+ {
2145+ BOOST_LIGHTWEIGHT_TEST_OSTREAM
2146+ << "No errors detected." << std::endl;
2147+ return 0;
2148+ }
2149+ else
2150+ {
2151+ BOOST_LIGHTWEIGHT_TEST_OSTREAM
2152+ << errors << " error" << (errors == 1? "": "s") << " detected." << std::endl;
2153+ return 1;
2154+ }
2155+}
2156+
2157+} // namespace endian
2158+} // namespace boost
2159+
2160+//////////////////////////////////////////////////////////////////////////////////////////
2161+// TODO: Should all test macros return bool? See BOOST_TEST_MEM_EQ usage in fp_exaustive_test,cpp
2162+//////////////////////////////////////////////////////////////////////////////////////////
2163+
2164+
2165+#define BOOST_TEST(expr) \
2166+ ((expr)? (void)0: ::boost::endian::detail::test_failed_impl(#expr, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION))
2167+
2168+#define BOOST_ERROR(msg) \
2169+ ( ::boost::endian::detail::error_impl(msg, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION) )
2170+
2171+#define BOOST_TEST_EQ(expr1,expr2) \
2172+ ( ::boost::endian::detail::test_eq_impl(#expr1, #expr2, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, expr1, expr2) )
2173+#define BOOST_TEST_NE(expr1,expr2) \
2174+ ( ::boost::endian::detail::test_ne_impl(#expr1, #expr2, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, expr1, expr2) )
2175+
2176+#define BOOST_TEST_MEM_EQ(expr1,expr2) \
2177+ (::boost::endian::detail::test_memcmp_eq_impl(#expr1, #expr2, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, expr1, expr2))
2178+
2179+#ifndef BOOST_NO_EXCEPTIONS
2180+ #define BOOST_TEST_THROWS( EXPR, EXCEP ) \
2181+ try { \
2182+ EXPR; \
2183+ ::boost::detail::throw_failed_impl \
2184+ (#EXCEP, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION); \
2185+ } \
2186+ catch(EXCEP const&) { \
2187+ } \
2188+ catch(...) { \
2189+ ::boost::detail::throw_failed_impl \
2190+ (#EXCEP, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION); \
2191+ } \
2192+ //
2193+#else
2194+ #define BOOST_TEST_THROWS( EXPR, EXCEP )
2195+#endif
2196+
2197+#endif // #ifndef BOOST_ENDIAN_LIGHTWEIGHT_TEST_HPP
2198
2199=== added file '3rd-party/boost/endian/endian.hpp'
2200--- 3rd-party/boost/endian/endian.hpp 1970-01-01 00:00:00 +0000
2201+++ 3rd-party/boost/endian/endian.hpp 2016-03-17 09:08:50 +0000
2202@@ -0,0 +1,19 @@
2203+// boost/endian/endian.hpp -----------------------------------------------------------//
2204+
2205+// Copyright Beman Dawes 2015
2206+
2207+// Distributed under the Boost Software License, Version 1.0.
2208+// See http://www.boost.org/LICENSE_1_0.txt
2209+
2210+// See library home page at http://www.boost.org/libs/endian
2211+
2212+#ifndef BOOST_ENDIAN_ENDIAN_HPP
2213+#define BOOST_ENDIAN_ENDIAN_HPP
2214+
2215+#ifndef BOOST_ENDIAN_DEPRECATED_NAMES
2216+# error "<boost/endian/endian.hpp> is deprecated. Define BOOST_ENDIAN_DEPRECATED_NAMES to use."
2217+#endif
2218+
2219+#include <boost/endian/arithmetic.hpp>
2220+
2221+#endif //BOOST_ENDIAN_ENDIAN_HPP
2222
2223=== added file '3rd-party/boost/endian/std_pair.hpp'
2224--- 3rd-party/boost/endian/std_pair.hpp 1970-01-01 00:00:00 +0000
2225+++ 3rd-party/boost/endian/std_pair.hpp 2016-03-17 09:08:50 +0000
2226@@ -0,0 +1,38 @@
2227+// boost/endian/std_pair.hpp ---------------------------------------------------------//
2228+
2229+// Copyright Beman Dawes 2013
2230+
2231+// Distributed under the Boost Software License, Version 1.0.
2232+// http://www.boost.org/LICENSE_1_0.txt
2233+
2234+//--------------------------------------------------------------------------------------//
2235+
2236+#ifndef BOOST_ENDIAN_STD_PAIR_HPP
2237+#define BOOST_ENDIAN_STD_PAIR_HPP
2238+
2239+#include <boost/endian/conversion.hpp>
2240+#include <utility>
2241+
2242+namespace boost
2243+{
2244+namespace endian
2245+{
2246+ template <class ReversibleValueT, class ReversibleValueU>
2247+ std::pair<ReversibleValueT, ReversibleValueU>
2248+ reverse_value(std::pair<ReversibleValueT, ReversibleValueU> x)
2249+ {
2250+ return std::pair<ReversibleValueT, ReversibleValueU>(reverse_value(x.first),
2251+ reverse_value(x.second));
2252+ }
2253+
2254+ template <class ReversibleT, class ReversibleU>
2255+ void reverse(std::pair<ReversibleT, ReversibleU>& x)
2256+ {
2257+ reverse(x.first);
2258+ reverse(x.second);
2259+ }
2260+
2261+}
2262+}
2263+
2264+#endif // BOOST_ENDIAN_STD_PAIR_HPP
2265
2266=== modified file 'CMakeLists.txt'
2267--- CMakeLists.txt 2016-03-17 09:08:50 +0000
2268+++ CMakeLists.txt 2016-03-17 09:08:50 +0000
2269@@ -34,6 +34,7 @@
2270 pkg_check_modules(PROCESS_CPP process-cpp REQUIRED)
2271 pkg_check_modules(PROPERTIES_CPP properties-cpp REQUIRED)
2272 pkg_check_modules(TRUST_STORE trust-store REQUIRED)
2273+pkg_check_modules(UBUNTU_PLATFORM_HARDWARE_API ubuntu-platform-hardware-api)
2274 #####################################################################
2275 # Enable code coverage calculation with gcov/gcovr/lcov
2276 # Usage:
2277@@ -69,6 +70,8 @@
2278 endif()
2279
2280 include_directories(
2281+ 3rd-party/
2282+
2283 ${Boost_INCLUDE_DIRS}
2284 ${DBUS_INCLUDE_DIRS}
2285 ${DBUS_CPP_INCLUDE_DIRS}
2286
2287=== modified file 'debian/changelog'
2288--- debian/changelog 2016-03-17 09:08:50 +0000
2289+++ debian/changelog 2016-03-17 09:08:50 +0000
2290@@ -38,6 +38,29 @@
2291 -- CI Train Bot <ci-train-bot@canonical.com> Thu, 28 May 2015 11:40:58 +0000
2292
2293 =======
2294+location-service (2.1+15.04.20160106-0ubuntu1) vivid; urgency=medium
2295+
2296+ [ Alberto Mardegan ]
2297+ * Set debian source format to "3.0 (native)"
2298+
2299+ [ Scott Sweeny ]
2300+ * Allow providers to register themselves asynchronously (LP: #1415029)
2301+
2302+ -- Thomas Voß <ci-train-bot@canonical.com> Wed, 06 Jan 2016 16:15:29 +0000
2303+
2304+location-service (2.1+15.04.20151211-0ubuntu1) vivid; urgency=medium
2305+
2306+ * Account for changes in trust-store w.r.t. assembling the description
2307+ of a trust prompt.
2308+
2309+ -- Thomas Voß <ci-train-bot@canonical.com> Fri, 11 Dec 2015 08:57:44 +0000
2310+
2311+location-service (2.1+15.04.20151209-0ubuntu1) vivid; urgency=medium
2312+
2313+ * Fix settings not being applied correctly.
2314+
2315+ -- Thomas Voß <ci-train-bot@canonical.com> Wed, 09 Dec 2015 15:22:22 +0000
2316+
2317 location-service (2.1+15.04.20151202.1-0ubuntu1) vivid; urgency=medium
2318
2319 * Ensure that event connections are cleaned up on destruction. (LP:
2320
2321=== modified file 'debian/source/format'
2322--- debian/source/format 2014-07-30 14:15:06 +0000
2323+++ debian/source/format 2016-03-17 09:08:50 +0000
2324@@ -1,1 +1,1 @@
2325-3.0 (quilt)
2326+3.0 (native)
2327
2328=== modified file 'examples/service/service.cpp'
2329--- examples/service/service.cpp 2014-11-14 11:26:45 +0000
2330+++ examples/service/service.cpp 2016-03-17 09:08:50 +0000
2331@@ -99,7 +99,10 @@
2332 auto selected_providers = options.value_for_key<std::vector<std::string>>("provider");
2333
2334 std::map<std::string, cul::ProviderFactory::Configuration> config_lut;
2335- std::set<cul::Provider::Ptr> instantiated_providers;
2336+
2337+ culs::DefaultConfiguration config;
2338+ auto settings = std::make_shared<cul::BoostPtreeSettings>(options.value_for_key<std::string>("config-file"));
2339+ auto engine = config.the_engine(std::set<cul::Provider::Ptr>{}, config.the_provider_selection_policy(), settings);
2340
2341 for (const std::string& provider : selected_providers)
2342 {
2343@@ -129,15 +132,15 @@
2344
2345 try
2346 {
2347- auto p = cul::ProviderFactory::instance().create_provider_for_name_with_config(
2348- provider,
2349- config_lut[provider]);
2350-
2351- if (p)
2352- instantiated_providers.insert(p);
2353- else
2354- throw std::runtime_error("Problem instantiating provider");
2355-
2356+ auto result = std::async(std::launch::async, [provider, config_lut, engine] {
2357+ return cul::ProviderFactory::instance().create_provider_for_name_with_config(
2358+ provider,
2359+ config_lut.at(provider),
2360+ [engine](cul::Provider::Ptr provider)
2361+ {
2362+ engine->add_provider(provider);
2363+ });
2364+ });
2365 } catch(const std::runtime_error& e)
2366 {
2367 std::cerr << "Exception instantiating provider: " << e.what() << " ... Aborting now." << std::endl;
2368@@ -163,15 +166,11 @@
2369 };
2370 outgoing->install_executor(dbus::asio::make_executor(outgoing));
2371
2372- auto settings = std::make_shared<cul::BoostPtreeSettings>(options.value_for_key<std::string>("config-file"));
2373-
2374- culs::DefaultConfiguration config;
2375-
2376 culs::Implementation::Configuration configuration
2377 {
2378 incoming,
2379 outgoing,
2380- config.the_engine(instantiated_providers, config.the_provider_selection_policy(), settings),
2381+ engine,
2382 config.the_permission_manager(incoming),
2383 culs::Harvester::Configuration
2384 {
2385
2386=== modified file 'include/location_service/com/ubuntu/location/connectivity/manager.h'
2387--- include/location_service/com/ubuntu/location/connectivity/manager.h 2014-07-10 16:44:26 +0000
2388+++ include/location_service/com/ubuntu/location/connectivity/manager.h 2016-03-17 09:08:50 +0000
2389@@ -219,6 +219,27 @@
2390 Manager() = default;
2391 };
2392
2393+/** @brief ExtendedManager extends the Manager interface in an ABI-stable way. */
2394+class ExtendedManager : public Manager
2395+{
2396+public:
2397+ /**
2398+ * @brief ismis requests enumeration of the imsis of all SIMs installed in the device.
2399+ */
2400+ virtual void enumerate_imsis(const std::function<void(const std::string&)>&) const = 0;
2401+
2402+ /**
2403+ * @brief msisdns requests enumeration of all mobile station international subscriber directory numbers
2404+ * of all SIMs installed in the device.
2405+ */
2406+ virtual void enumerate_msisdns(const std::function<void(const std::string&)>&) const = 0;
2407+
2408+protected:
2409+ /** @cond */
2410+ ExtendedManager() = default;
2411+ /** @endcond */
2412+};
2413+
2414 /**
2415 * @brief Provides access to a platform-specific implementation/instance of a connectivity manager.
2416 * @throw Manager::Errors::ConnectivityManagementNotSupported.
2417
2418=== modified file 'include/location_service/com/ubuntu/location/provider_factory.h'
2419--- include/location_service/com/ubuntu/location/provider_factory.h 2014-10-27 21:58:16 +0000
2420+++ include/location_service/com/ubuntu/location/provider_factory.h 2016-03-17 09:08:50 +0000
2421@@ -54,6 +54,9 @@
2422 // --provider=remote::Provider@gps --remote::Provider@gps::name="com.ubuntu.android.gps.Provider" --remote::Provider@gps::path="/com/ubuntu/android/gps/Provider"
2423 Provider::Ptr create_provider_for_name_with_config(const std::string& name, const Configuration& config);
2424
2425+ // Async version of above.
2426+ void create_provider_for_name_with_config(const std::string& name, const Configuration& config, const std::function<void(Provider::Ptr)>& cb);
2427+
2428 void enumerate(const std::function<void(const std::string&, const Factory&)>& enumerator);
2429
2430 private:
2431
2432=== modified file 'po/ubuntu-location-service.pot'
2433--- po/ubuntu-location-service.pot 2014-09-19 09:06:30 +0000
2434+++ po/ubuntu-location-service.pot 2016-03-17 09:08:50 +0000
2435@@ -1,13 +1,14 @@
2436-# Copyright (C) 2014 Canonical Ltd.
2437-# This file is distributed under the same license as the ubuntu-location-service package.
2438-# Thomas Voß <thomas.voss@canonical.com>, 2014.
2439+# SOME DESCRIPTIVE TITLE.
2440+# Copyright (C) YEAR Canonical Ltd.
2441+# This file is distributed under the same license as the PACKAGE package.
2442+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
2443 #
2444 #, fuzzy
2445 msgid ""
2446 msgstr ""
2447 "Project-Id-Version: ubuntu-location-service\n"
2448 "Report-Msgid-Bugs-To: \n"
2449-"POT-Creation-Date: 2014-09-19 01:04+0200\n"
2450+"POT-Creation-Date: 2015-11-27 14:07+0100\n"
2451 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
2452 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
2453 "Language-Team: LANGUAGE <LL@li.org>\n"
2454@@ -16,11 +17,6 @@
2455 "Content-Type: text/plain; charset=CHARSET\n"
2456 "Content-Transfer-Encoding: 8bit\n"
2457
2458-#: /tmp/i18n/src/location_service/com/ubuntu/location/service/trust_store_permission_manager.cpp:170
2459-msgid "An unconfined application wants to access your current location."
2460-msgstr ""
2461-
2462-#: /tmp/i18n/src/location_service/com/ubuntu/location/service/trust_store_permission_manager.cpp:173
2463-#, boost-format
2464-msgid "%1% wants to access your current location."
2465+#: /home/tvoss/ubuntu/scratch/fix-prompt-string/src/location_service/com/ubuntu/location/service/trust_store_permission_manager.cpp:149
2466+msgid "wants to access your current location."
2467 msgstr ""
2468
2469=== modified file 'src/location_service/com/ubuntu/location/CMakeLists.txt'
2470--- src/location_service/com/ubuntu/location/CMakeLists.txt 2016-03-17 09:08:50 +0000
2471+++ src/location_service/com/ubuntu/location/CMakeLists.txt 2016-03-17 09:08:50 +0000
2472@@ -1,3 +1,7 @@
2473+if (UBUNTU_PLATFORM_HARDWARE_API_FOUND)
2474+ add_definitions(-DCOM_UBUNTU_LOCATION_SERVICE_HAVE_UBUNTU_PLATFORM_HARDWARE_API)
2475+endif()
2476+
2477 if (NET_CPP_FOUND)
2478 add_definitions(-DCOM_UBUNTU_LOCATION_SERVICE_HAVE_NET_CPP=1)
2479
2480@@ -10,6 +14,8 @@
2481 service/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/service/config.h @ONLY
2482 )
2483
2484+include_directories(${UBUNTU_PLATFORM_HARDWARE_API_INCLUDE_DIRS})
2485+
2486 add_library(
2487 ubuntu-location-service SHARED
2488
2489@@ -29,6 +35,7 @@
2490 settings.cpp
2491 time_based_update_policy.cpp
2492 set_name_for_thread.cpp
2493+ time_since_boot.cpp
2494 wifi_and_cell_reporting_state.cpp
2495
2496 boost_ptree_settings.cpp
2497@@ -126,6 +133,7 @@
2498 ${LIBAPPARMOR_LDFLAGS}
2499 ${NET_CPP_LDFLAGS}
2500 ${TRUST_STORE_LDFLAGS}
2501+ ${UBUNTU_PLATFORM_HARDWARE_API_LDFLAGS}
2502 ${GLog_LIBRARY}
2503 ${GFlags_LIBRARY}
2504 )
2505
2506=== modified file 'src/location_service/com/ubuntu/location/connectivity/ofono.h'
2507--- src/location_service/com/ubuntu/location/connectivity/ofono.h 2015-01-06 12:35:02 +0000
2508+++ src/location_service/com/ubuntu/location/connectivity/ofono.h 2016-03-17 09:08:50 +0000
2509@@ -640,6 +640,118 @@
2510 } signals;
2511 };
2512
2513+ struct SimManager
2514+ {
2515+ static const std::string& name()
2516+ {
2517+ static const std::string s{"org.ofono.SimManager"};
2518+ return s;
2519+ }
2520+
2521+ struct GetProperties
2522+ {
2523+ static const std::string& name()
2524+ {
2525+ static const std::string s{"GetProperties"};
2526+ return s;
2527+ }
2528+
2529+ typedef SimManager Interface;
2530+ typedef std::map<std::string, core::dbus::types::Variant> ValueType;
2531+
2532+ static std::chrono::milliseconds default_timeout()
2533+ {
2534+ return std::chrono::seconds{1};
2535+ }
2536+ };
2537+
2538+ struct PropertyChanged
2539+ {
2540+ inline static std::string name()
2541+ {
2542+ return "PropertyChanged";
2543+ }
2544+
2545+ typedef SimManager Interface;
2546+
2547+ typedef std::tuple<std::string, core::dbus::types::Variant> ArgumentType;
2548+ };
2549+
2550+ struct Present
2551+ {
2552+ static const std::string& name()
2553+ {
2554+ static const std::string s{"Present"};
2555+ return s;
2556+ }
2557+
2558+ typedef SimManager Interface;
2559+ typedef bool ValueType;
2560+ static const bool readable = true;
2561+ static const bool writable = false;
2562+ };
2563+
2564+ struct SubscriberIdentity
2565+ {
2566+ static const std::string& name()
2567+ {
2568+ static const std::string s{"SubscriberIdentity"};
2569+ return s;
2570+ }
2571+
2572+ typedef SimManager Interface;
2573+ typedef std::string ValueType;
2574+ static const bool readable = true;
2575+ static const bool writable = false;
2576+ };
2577+
2578+ struct SubscriberNumbers
2579+ {
2580+ static const std::string& name()
2581+ {
2582+ static const std::string s{"SubscriberNumbers"};
2583+ return s;
2584+ }
2585+
2586+ typedef SimManager Interface;
2587+ typedef std::vector<std::string> ValueType;
2588+ static const bool readable = true;
2589+ static const bool writable = false;
2590+ };
2591+
2592+ SimManager(const std::shared_ptr<core::dbus::Object>& object)
2593+ : object(object)
2594+ {
2595+ }
2596+
2597+ template<typename Property>
2598+ void async_get(const std::function<void(const typename Property::ValueType& result)>& cb) const
2599+ {
2600+ object->invoke_method_asynchronously_with_callback<GetProperties, GetProperties::ValueType>(
2601+ [cb](const core::dbus::Result<GetProperties::ValueType>& result)
2602+ {
2603+ if (result.is_error())
2604+ {
2605+ LOG(WARNING) << "Failed to query properties: " << result.error().print();
2606+ return;
2607+ }
2608+
2609+ auto properties = result.value();
2610+ auto it = properties.find(Property::name());
2611+
2612+ if (it == properties.end())
2613+ {
2614+ VLOG(1) << "Could not find property for name " << Property::name();
2615+ return;
2616+ }
2617+
2618+ cb(it->second.template as<typename Property::ValueType>());
2619+ });
2620+ }
2621+
2622+ std::shared_ptr<core::dbus::Object> object;
2623+ };
2624+
2625 Modem(const std::shared_ptr<core::dbus::Service>& service,
2626 const std::shared_ptr<core::dbus::Object>& object)
2627 : service(service),
2628@@ -648,7 +760,8 @@
2629 {
2630 object->get_signal<PropertyChanged>()
2631 },
2632- network_registration{object}
2633+ network_registration{object},
2634+ sim_manager{object}
2635 {
2636 }
2637
2638@@ -661,6 +774,7 @@
2639 } signals;
2640
2641 NetworkRegistration network_registration;
2642+ SimManager sim_manager;
2643 };
2644
2645 Manager(const core::dbus::Bus::Ptr& bus)
2646
2647=== modified file 'src/location_service/com/ubuntu/location/connectivity/ofono_nm_connectivity_manager.cpp'
2648--- src/location_service/com/ubuntu/location/connectivity/ofono_nm_connectivity_manager.cpp 2016-03-17 09:08:50 +0000
2649+++ src/location_service/com/ubuntu/location/connectivity/ofono_nm_connectivity_manager.cpp 2016-03-17 09:08:50 +0000
2650@@ -126,6 +126,33 @@
2651 return d.active_connection_characteristics;
2652 }
2653
2654+void connectivity::OfonoNmConnectivityManager::enumerate_imsis(const std::function<void(const std::string&)>& cb) const
2655+{
2656+ std::lock_guard<std::mutex> lg(d.cached.guard);
2657+
2658+ for (const auto& modem : d.cached.modems)
2659+ {
2660+ modem.second.sim_manager.async_get<org::Ofono::Manager::Modem::SimManager::SubscriberIdentity>([cb](const std::string& imsi)
2661+ {
2662+ cb(imsi);
2663+ });
2664+ }
2665+}
2666+
2667+void connectivity::OfonoNmConnectivityManager::enumerate_msisdns(const std::function<void(const std::string&)>& cb) const
2668+{
2669+ std::lock_guard<std::mutex> lg(d.cached.guard);
2670+
2671+ for (const auto& modem : d.cached.modems)
2672+ {
2673+ modem.second.sim_manager.async_get<org::Ofono::Manager::Modem::SimManager::SubscriberNumbers>([cb](const std::vector<std::string>& msisdns)
2674+ {
2675+ for (const auto& nr : msisdns)
2676+ cb(nr);
2677+ });
2678+ }
2679+}
2680+
2681 connectivity::OfonoNmConnectivityManager::Private::Private(const core::dbus::Bus::Ptr& bus)
2682 : bus{bus},
2683 bus_daemon{std::make_shared<core::dbus::DBus>(bus)}
2684@@ -340,11 +367,12 @@
2685 auto itt = cached.cells.find(path);
2686 const bool has_cell_for_modem = itt != cached.cells.end();
2687
2688- auto it = std::find(
2689+ auto itnr = std::find(
2690 interfaces.begin(),
2691 interfaces.end(),
2692 std::string{org::Ofono::Manager::Modem::Properties::Interfaces::network_registration});
2693- const bool modem_has_network_registration = it != interfaces.end();
2694+
2695+ const bool modem_has_network_registration = itnr != interfaces.end();
2696
2697 if (has_cell_for_modem and not modem_has_network_registration)
2698 {
2699
2700=== modified file 'src/location_service/com/ubuntu/location/connectivity/ofono_nm_connectivity_manager.h'
2701--- src/location_service/com/ubuntu/location/connectivity/ofono_nm_connectivity_manager.h 2015-04-27 15:44:40 +0000
2702+++ src/location_service/com/ubuntu/location/connectivity/ofono_nm_connectivity_manager.h 2016-03-17 09:08:50 +0000
2703@@ -52,7 +52,7 @@
2704 namespace dbus = core::dbus;
2705
2706 namespace com { namespace ubuntu { namespace location { namespace connectivity {
2707-struct OfonoNmConnectivityManager : public com::ubuntu::location::connectivity::Manager
2708+struct OfonoNmConnectivityManager : public com::ubuntu::location::connectivity::ExtendedManager
2709 {
2710 // Creates an instance of the manager, resolving services on the given bus.
2711 OfonoNmConnectivityManager(const core::dbus::Bus::Ptr& bus);
2712@@ -82,6 +82,10 @@
2713
2714 const core::Property<com::ubuntu::location::connectivity::Characteristics>& active_connection_characteristics() const;
2715
2716+ void enumerate_imsis(const std::function<void(const std::string&)>&) const override;
2717+
2718+ void enumerate_msisdns(const std::function<void(const std::string&)>&) const override;
2719+
2720 struct Private
2721 {
2722 Private(const core::dbus::Bus::Ptr& bus);
2723
2724=== modified file 'src/location_service/com/ubuntu/location/provider_factory.cpp'
2725--- src/location_service/com/ubuntu/location/provider_factory.cpp 2014-10-27 21:58:16 +0000
2726+++ src/location_service/com/ubuntu/location/provider_factory.cpp 2016-03-17 09:08:50 +0000
2727@@ -52,6 +52,20 @@
2728 return cul::Provider::Ptr{factory_store.at(undecorated_name)(config)};
2729 }
2730
2731+void cul::ProviderFactory::create_provider_for_name_with_config(
2732+ const std::string& name,
2733+ const cul::ProviderFactory::Configuration& config,
2734+ const std::function<void(Provider::Ptr)>& cb)
2735+{
2736+ auto undecorated_name = name.substr(0, name.find("@"));
2737+
2738+ std::lock_guard<std::mutex> lg(guard);
2739+ if (factory_store.count(undecorated_name) == 0)
2740+ return;
2741+
2742+ cb(cul::Provider::Ptr{factory_store.at(undecorated_name)(config)});
2743+}
2744+
2745 void cul::ProviderFactory::enumerate(
2746 const std::function<void(const std::string&, const cul::ProviderFactory::Factory&)>& enumerator)
2747 {
2748
2749=== modified file 'src/location_service/com/ubuntu/location/providers/config.cpp'
2750--- src/location_service/com/ubuntu/location/providers/config.cpp 2014-09-15 08:58:50 +0000
2751+++ src/location_service/com/ubuntu/location/providers/config.cpp 2016-03-17 09:08:50 +0000
2752@@ -19,6 +19,7 @@
2753 #include <com/ubuntu/location/provider_factory.h>
2754
2755 #include "dummy/provider.h"
2756+#include "dummy/delayed_provider.h"
2757
2758 #include <map>
2759
2760@@ -41,6 +42,12 @@
2761 com::ubuntu::location::providers::dummy::Provider::create_instance
2762 };
2763
2764+static FactoryInjector dummy_delayed_injector
2765+{
2766+ "dummy::DelayedProvider",
2767+ com::ubuntu::location::providers::dummy::DelayedProvider::create_instance
2768+};
2769+
2770 #include <com/ubuntu/location/providers/remote/provider.h>
2771 static FactoryInjector remote_injector
2772 {
2773
2774=== modified file 'src/location_service/com/ubuntu/location/providers/dummy/CMakeLists.txt'
2775--- src/location_service/com/ubuntu/location/providers/dummy/CMakeLists.txt 2014-02-07 17:16:49 +0000
2776+++ src/location_service/com/ubuntu/location/providers/dummy/CMakeLists.txt 2016-03-17 09:08:50 +0000
2777@@ -2,7 +2,9 @@
2778 dummy
2779
2780 provider.h
2781- provider.cpp)
2782+ provider.cpp
2783+ delayed_provider.h
2784+ delayed_provider.cpp)
2785
2786 set(
2787 ENABLED_PROVIDER_TARGETS
2788
2789=== added file 'src/location_service/com/ubuntu/location/providers/dummy/delayed_provider.cpp'
2790--- src/location_service/com/ubuntu/location/providers/dummy/delayed_provider.cpp 1970-01-01 00:00:00 +0000
2791+++ src/location_service/com/ubuntu/location/providers/dummy/delayed_provider.cpp 2016-03-17 09:08:50 +0000
2792@@ -0,0 +1,42 @@
2793+/*
2794+ * Copyright © 2015 Canonical Ltd.
2795+ *
2796+ * This program is free software: you can redistribute it and/or modify it
2797+ * under the terms of the GNU Lesser General Public License version 3,
2798+ * as published by the Free Software Foundation.
2799+ *
2800+ * This program is distributed in the hope that it will be useful,
2801+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2802+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2803+ * GNU Lesser General Public License for more details.
2804+ *
2805+ * You should have received a copy of the GNU Lesser General Public License
2806+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2807+ *
2808+ * Authored by: Scott Sweeny <scott.sweeny@canonical.com>
2809+ */
2810+
2811+#include <com/ubuntu/location/logging.h>
2812+
2813+#include <chrono>
2814+#include <thread>
2815+
2816+#include "delayed_provider.h"
2817+
2818+namespace location = com::ubuntu::location;
2819+namespace dummy = com::ubuntu::location::providers::dummy;
2820+
2821+std::string dummy::DelayedProvider::class_name()
2822+{
2823+ return "dummy::DelayedProvider";
2824+}
2825+
2826+location::Provider::Ptr dummy::DelayedProvider::create_instance(const ProviderFactory::Configuration& config)
2827+{
2828+ int delay = config.get(dummy::DelayConfiguration::Keys::delay, 0);
2829+ VLOG(1) << __PRETTY_FUNCTION__ << ": delay for " << delay << "ms";
2830+
2831+ std::this_thread::sleep_for(std::chrono::milliseconds{delay});
2832+
2833+ return dummy::Provider::create_instance(config);
2834+}
2835
2836=== added file 'src/location_service/com/ubuntu/location/providers/dummy/delayed_provider.h'
2837--- src/location_service/com/ubuntu/location/providers/dummy/delayed_provider.h 1970-01-01 00:00:00 +0000
2838+++ src/location_service/com/ubuntu/location/providers/dummy/delayed_provider.h 2016-03-17 09:08:50 +0000
2839@@ -0,0 +1,62 @@
2840+/*
2841+ * Copyright © 2015 Canonical Ltd.
2842+ *
2843+ * This program is free software: you can redistribute it and/or modify it
2844+ * under the terms of the GNU Lesser General Public License version 3,
2845+ * as published by the Free Software Foundation.
2846+ *
2847+ * This program is distributed in the hope that it will be useful,
2848+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2849+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2850+ * GNU Lesser General Public License for more details.
2851+ *
2852+ * You should have received a copy of the GNU Lesser General Public License
2853+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2854+ *
2855+ * Authored by: Scott Sweeny <scott.sweeny@canonical.com>
2856+ */
2857+
2858+#ifndef LOCATION_SERVICE_COM_UBUNTU_LOCATION_PROVIDERS_DUMMY_DELAYED_PROVIDER_H_
2859+#define LOCATION_SERVICE_COM_UBUNTU_LOCATION_PROVIDERS_DUMMY_DELAYED_PROVIDER_H_
2860+
2861+#include "provider.h"
2862+
2863+namespace com
2864+{
2865+namespace ubuntu
2866+{
2867+namespace location
2868+{
2869+namespace providers
2870+{
2871+namespace dummy
2872+{
2873+ struct DelayConfiguration
2874+ {
2875+ struct Keys
2876+ {
2877+ static constexpr const char* delay
2878+ {
2879+ "DelayInMs"
2880+ };
2881+ };
2882+ };
2883+
2884+class DelayedProvider : public Provider
2885+{
2886+ public:
2887+ // For integration with the Provider factory
2888+ static std::string class_name();
2889+ // Waits for "DelayInMs" from the provided property bundle then
2890+ // instantiates a new provider instance, populating the configuration object
2891+ // from the provided property bundle.
2892+ static DelayedProvider::Ptr create_instance(const ProviderFactory::Configuration&);
2893+ // Creates a new provider instance from the given configuration.
2894+ DelayedProvider(const Configuration config = Configuration{});
2895+};
2896+}
2897+}
2898+}
2899+}
2900+}
2901+#endif // LOCATION_SERVICE_COM_UBUNTU_LOCATION_PROVIDERS_DUMMY_DELAYED_PROVIDER_H_
2902
2903=== modified file 'src/location_service/com/ubuntu/location/providers/gps/CMakeLists.txt'
2904--- src/location_service/com/ubuntu/location/providers/gps/CMakeLists.txt 2014-07-28 19:14:58 +0000
2905+++ src/location_service/com/ubuntu/location/providers/gps/CMakeLists.txt 2016-03-17 09:08:50 +0000
2906@@ -4,30 +4,34 @@
2907 ON
2908 )
2909
2910-if (LOCATION_SERVICE_ENABLE_GPS_PROVIDER)
2911- find_file(
2912- UBUNTU_HARDWARE_GPS_H gps.h
2913- NAMES ubuntu/hardware/gps.h
2914- )
2915-
2916- if (UBUNTU_HARDWARE_GPS_H)
2917+if ((LOCATION_SERVICE_ENABLE_GPS_PROVIDER) AND (UBUNTU_PLATFORM_HARDWARE_API_FOUND))
2918 message(STATUS "Enabling GPS location provider")
2919
2920+ include_directories(${UBUNTU_PLATFORM_HARDWARE_API_INCLUDE_DIRS})
2921+
2922 add_library(
2923 gps
2924
2925 gps.conf
2926
2927+ hardware_abstraction_layer.cpp
2928+
2929 android_hardware_abstraction_layer.h
2930 android_hardware_abstraction_layer.cpp
2931
2932+ sntp_reference_time_source.h
2933+ sntp_reference_time_source.cpp
2934+
2935+ sntp_client.h
2936+ sntp_client.cpp
2937+
2938 hardware_abstraction_layer.h
2939 # hardware_abstraction_layer.cpp
2940
2941 provider.h
2942 provider.cpp)
2943
2944- target_link_libraries(gps ubuntu_platform_hardware_api.so)
2945+ target_link_libraries(gps ${UBUNTU_PLATFORM_HARDWARE_API_LDFLAGS})
2946
2947 set(
2948 ENABLED_PROVIDER_TARGETS
2949@@ -41,5 +45,4 @@
2950 )
2951
2952 install(FILES gps.conf DESTINATION /etc/)
2953- endif (UBUNTU_HARDWARE_GPS_H)
2954-endif (LOCATION_SERVICE_ENABLE_GPS_PROVIDER)
2955+endif ()
2956
2957=== modified file 'src/location_service/com/ubuntu/location/providers/gps/android_hardware_abstraction_layer.cpp'
2958--- src/location_service/com/ubuntu/location/providers/gps/android_hardware_abstraction_layer.cpp 2016-03-17 09:08:50 +0000
2959+++ src/location_service/com/ubuntu/location/providers/gps/android_hardware_abstraction_layer.cpp 2016-03-17 09:08:50 +0000
2960@@ -17,6 +17,7 @@
2961 */
2962
2963 #include "android_hardware_abstraction_layer.h"
2964+#include "sntp_reference_time_source.h"
2965
2966 #if defined(COM_UBUNTU_LOCATION_SERVICE_HAVE_NET_CPP)
2967 #include "net_cpp_gps_xtra_downloader.h"
2968@@ -93,6 +94,44 @@
2969 return impl.server_ip;
2970 }
2971
2972+void android::HardwareAbstractionLayer::SuplAssistant::set_set_id(SetIdType type, const std::string& id) const
2973+{
2974+ u_hardware_gps_agps_set_set_id(
2975+ impl.hal.impl.gps_handle,
2976+ static_cast<UHardwareGpsAgpsSetIdType>(type),
2977+ id.c_str());
2978+}
2979+
2980+
2981+void android::HardwareAbstractionLayer::SuplAssistant::inject_radio_cell_information(const location::connectivity::RadioCell& cell) const
2982+{
2983+ UHardwareGpsAGpsRefLocation ref_loc;
2984+ switch (cell.type())
2985+ {
2986+ case location::connectivity::RadioCell::Type::gsm:
2987+ ref_loc.type = U_HARDWARE_GPS_AGPS_REF_LOCATION_TYPE_GSM_CELLID;
2988+ ref_loc.u.cellID.mcc = cell.gsm().mobile_country_code;
2989+ ref_loc.u.cellID.mnc = cell.gsm().mobile_network_code;
2990+ ref_loc.u.cellID.lac = cell.gsm().location_area_code;
2991+ ref_loc.u.cellID.cid = cell.gsm().id;
2992+ break;
2993+ case location::connectivity::RadioCell::Type::umts:
2994+ ref_loc.type = U_HARDWARE_GPS_AGPS_REF_LOCATION_TYPE_UMTS_CELLID;
2995+ ref_loc.u.cellID.mcc = cell.umts().mobile_country_code;
2996+ ref_loc.u.cellID.mnc = cell.umts().mobile_network_code;
2997+ ref_loc.u.cellID.lac = cell.umts().location_area_code;
2998+ ref_loc.u.cellID.cid = cell.umts().id;
2999+ break;
3000+ default:
3001+ return;
3002+ }
3003+
3004+ u_hardware_gps_agps_set_reference_location(
3005+ impl.hal.impl.gps_handle,
3006+ &ref_loc,
3007+ sizeof(ref_loc));
3008+}
3009+
3010 void android::HardwareAbstractionLayer::SuplAssistant::set_server(const std::string& host_name, std::uint16_t port)
3011 {
3012 // TODO(tvoss): Reenable this once the platform api HAL changes land.
3013@@ -169,16 +208,49 @@
3014
3015 void android::HardwareAbstractionLayer::on_ril_request_set_id(uint32_t flags, void* context)
3016 {
3017- VLOG(1) << __PRETTY_FUNCTION__ << ": "
3018- << "flags=" << flags << " "
3019- << "context=" << context;
3020+ VLOG(1) << __PRETTY_FUNCTION__ << ": " << "flags=" << flags << " " << "context=" << context;
3021+
3022+ if (auto thiz = static_cast<android::HardwareAbstractionLayer*>(context))
3023+ {
3024+ switch (flags)
3025+ {
3026+ case U_HARDWARE_GPS_AGPS_REQUEST_SETID_IMSI:
3027+ thiz->impl.connectivity_manager->enumerate_imsis([thiz](const std::string& imsi)
3028+ {
3029+ VLOG(1) << "IMSI received: " << imsi;
3030+ thiz->impl.supl_assistant.set_set_id(SuplAssistant::SetIdType::imsi, imsi);
3031+ });
3032+ break;
3033+ case U_HARDWARE_GPS_AGPS_REQUEST_SETID_MSISDN:
3034+ thiz->impl.connectivity_manager->enumerate_msisdns([thiz](const std::string& msisdn)
3035+ {
3036+ VLOG(1) << "MSISDN received: " << msisdn;
3037+ thiz->impl.supl_assistant.set_set_id(SuplAssistant::SetIdType::msisdn, msisdn);
3038+ });
3039+ break;
3040+ }
3041+ }
3042 }
3043
3044 void android::HardwareAbstractionLayer::on_ril_request_reference_location(uint32_t flags, void* context)
3045 {
3046- VLOG(1) << __PRETTY_FUNCTION__ << ": "
3047- << "flags=" << flags << " "
3048- << "context=" << context;
3049+ VLOG(1) << __PRETTY_FUNCTION__ << ": " << "flags=" << flags << " " << "context=" << context;
3050+
3051+ if (auto thiz = static_cast<android::HardwareAbstractionLayer*>(context))
3052+ {
3053+ switch (flags)
3054+ {
3055+ case U_HARDWARE_GPS_AGPS_REQUEST_REFLOC_CELLID:
3056+ thiz->impl.connectivity_manager->enumerate_connected_radio_cells([thiz](const connectivity::RadioCell::Ptr& cell)
3057+ {
3058+ thiz->impl.supl_assistant.inject_radio_cell_information(*cell);
3059+ });
3060+ break;
3061+ case U_HARDWARE_GPS_AGPS_REQUEST_REFLOC_MAC:
3062+ default:
3063+ break;
3064+ }
3065+ }
3066 }
3067
3068 void android::HardwareAbstractionLayer::on_location_update(UHardwareGpsLocation* location, void* context)
3069@@ -323,23 +395,18 @@
3070 {
3071 VLOG(1) << __PRETTY_FUNCTION__;
3072
3073- auto thiz = static_cast<android::HardwareAbstractionLayer*>(context);
3074-
3075- if (thiz->impl.utc_time_request_handler)
3076- {
3077- thiz->impl.utc_time_request_handler();
3078- } else
3079- {
3080- auto now = location::Clock::now().time_since_epoch();
3081- auto ms_since_epoch = std::chrono::duration_cast<std::chrono::milliseconds>(now);
3082-
3083- static const int zero_uncertainty = 0;
3084-
3085- u_hardware_gps_inject_time(
3086- thiz->impl.gps_handle,
3087- ms_since_epoch.count(),
3088- ms_since_epoch.count(),
3089- zero_uncertainty);
3090+ try
3091+ {
3092+ if (auto thiz = static_cast<android::HardwareAbstractionLayer*>(context))
3093+ thiz->inject_reference_time(thiz->impl.reference_time_source->sample());
3094+ }
3095+ catch (const std::runtime_error& e)
3096+ {
3097+ LOG(WARNING) << "Failed to inject reference time to chipset: " << e.what();
3098+ }
3099+ catch (...)
3100+ {
3101+ LOG(WARNING) << "Failed to inject reference time to chipset.";
3102 }
3103 }
3104
3105@@ -534,19 +601,22 @@
3106 return true;
3107 }
3108
3109-bool android::HardwareAbstractionLayer::inject_reference_time(
3110- const std::chrono::microseconds& reference_time,
3111- const std::chrono::microseconds& sample_time)
3112+bool android::HardwareAbstractionLayer::inject_reference_time(const ReferenceTimeSample& sample)
3113 {
3114 if (!is_capable_of(gps::Capability::on_demand_time_injection))
3115 return false;
3116
3117 // TODO(tvoss): We should expose the int return type of the underyling
3118 // Android HAL to capture errors here.
3119+ //
3120+ // Please see:
3121+ // http://androidxref.com/5.1.1_r6/xref/frameworks/base/core/java/android/net/SntpClient.java#72
3122+ // for the bloody details of relating the system wall clock time to the elapsed realtime since boot
3123+ // including deep sleep.
3124 u_hardware_gps_inject_time(impl.gps_handle,
3125- reference_time.count(),
3126- sample_time.count(),
3127- 10);
3128+ sample.since_epoch.count(),
3129+ sample.since_boot.count(),
3130+ sample.uncertainty.count());
3131 return true;
3132 }
3133
3134@@ -557,6 +627,8 @@
3135 assistance_mode(gps::AssistanceMode::mobile_station_based),
3136 position_mode(gps::PositionMode::periodic),
3137 supl_assistant(*parent),
3138+ connectivity_manager(configuration.connectivity_manager),
3139+ reference_time_source(configuration.reference_time_source),
3140 gps_xtra_configuration(configuration.gps_xtra.configuration),
3141 gps_xtra_downloader(configuration.gps_xtra.downloader)
3142 {
3143@@ -615,6 +687,22 @@
3144
3145 namespace
3146 {
3147+gps::SntpReferenceTimeSource::Configuration sntp_reference_time_source_configuration(std::istream& in)
3148+{
3149+ gps::SntpReferenceTimeSource::Configuration config;
3150+
3151+ try
3152+ {
3153+ config = gps::SntpReferenceTimeSource::Configuration::from_gps_conf_ini_file(in);
3154+ }
3155+ catch (...)
3156+ {
3157+ // Consciously dropping all exceptions here.
3158+ }
3159+
3160+ return config;
3161+}
3162+
3163 android::GpsXtraDownloader::Configuration gps_xtra_downloader_configuration(std::istream& in)
3164 {
3165 android::GpsXtraDownloader::Configuration config;
3166@@ -641,6 +729,8 @@
3167
3168 return config;
3169 }
3170+
3171+
3172 }
3173
3174 std::shared_ptr<gps::HardwareAbstractionLayer> gps::HardwareAbstractionLayer::create_default_instance()
3175@@ -664,7 +754,9 @@
3176 {
3177 create_xtra_downloader(),
3178 gps_xtra_downloader_configuration((in_system_gps_conf ? in_system_gps_conf : in_gps_conf))
3179- }
3180+ },
3181+ std::dynamic_pointer_cast<connectivity::ExtendedManager>(connectivity::platform_default_manager()),
3182+ std::make_shared<gps::SntpReferenceTimeSource>(sntp_reference_time_source_configuration((in_system_gps_conf ? in_system_gps_conf : in_gps_conf)))
3183 };
3184
3185 static std::shared_ptr<gps::HardwareAbstractionLayer> instance
3186
3187=== modified file 'src/location_service/com/ubuntu/location/providers/gps/android_hardware_abstraction_layer.h'
3188--- src/location_service/com/ubuntu/location/providers/gps/android_hardware_abstraction_layer.h 2016-03-17 09:08:50 +0000
3189+++ src/location_service/com/ubuntu/location/providers/gps/android_hardware_abstraction_layer.h 2016-03-17 09:08:50 +0000
3190@@ -19,6 +19,9 @@
3191 #define LOCATION_SERVICE_COM_UBUNTU_LOCATION_PROVIDERS_GPS_ANDROID_HARDWARE_ABSTRACTION_LAYER_H_
3192
3193 #include <com/ubuntu/location/providers/gps/hardware_abstraction_layer.h>
3194+#include <com/ubuntu/location/providers/gps/sntp_client.h>
3195+
3196+#include <com/ubuntu/location/connectivity/manager.h>
3197
3198 #include <ubuntu/hardware/gps.h>
3199
3200@@ -66,7 +69,24 @@
3201 };
3202
3203 struct HardwareAbstractionLayer : public gps::HardwareAbstractionLayer
3204-{
3205+{
3206+ /** @brief A ReferenceTimeSource provides samples of an arbitrary reference time source. */
3207+ class ReferenceTimeSource
3208+ {
3209+ public:
3210+ /** @cond */
3211+ typedef std::shared_ptr<ReferenceTimeSource> Ptr;
3212+
3213+ virtual ~ReferenceTimeSource() = default;
3214+ /** @endcond */
3215+
3216+ /** @brief sample returns a sample of the current ReferenceTimeSource. */
3217+ virtual ReferenceTimeSample sample() = 0;
3218+
3219+ protected:
3220+ ReferenceTimeSource() = default;
3221+ };
3222+
3223 /** @brief Implements gps::HardwareAbstractionLayer::SuplAssistant interface for the android gps HAL. */
3224 struct SuplAssistant : public gps::HardwareAbstractionLayer::SuplAssistant
3225 {
3226@@ -74,6 +94,10 @@
3227 SuplAssistant(android::HardwareAbstractionLayer& hal);
3228 /** @brief Getable/observable access to the status of the assistant instance. */
3229 const core::Property<Status>& status() const override;
3230+ /** @brief Sets mobile subscriber identity. */
3231+ void set_set_id(SetIdType type, const std::string& id) const override;
3232+ /** @brief Injects reference location information. */
3233+ void inject_radio_cell_information(const connectivity::RadioCell& radio_cell) const override;
3234 /** @brief Getable/setable/observable access to the status of the assistant instance. */
3235 core::Property<Status>& status();
3236 /** @brief Getable/observable access to the ip the assistance instance uses. */
3237@@ -186,6 +210,9 @@
3238 std::shared_ptr<GpsXtraDownloader> downloader;
3239 GpsXtraDownloader::Configuration configuration;
3240 } gps_xtra;
3241+
3242+ std::shared_ptr<connectivity::ExtendedManager> connectivity_manager;
3243+ ReferenceTimeSource::Ptr reference_time_source;
3244 };
3245
3246 HardwareAbstractionLayer(const Configuration& configuration);
3247@@ -227,8 +254,8 @@
3248 bool set_position_mode(gps::PositionMode mode) override;
3249
3250 bool inject_reference_position(const location::Position& position) override;
3251- bool inject_reference_time(const std::chrono::microseconds& reference_time,
3252- const std::chrono::microseconds& sample_time) override;
3253+ bool inject_reference_time(const ReferenceTimeSample& sample) override;
3254+
3255 struct Impl
3256 {
3257 // Bootstraps access to the GPS chipset, wiring up all callbacks.
3258@@ -252,8 +279,10 @@
3259 // An implementation of the gps::HardwareAbstractionLayer::SuplAssistant interface.
3260 SuplAssistant supl_assistant;
3261
3262- // Callback for handling utc time requests.
3263- gps::HardwareAbstractionLayer::UtcTimeRequestHandler utc_time_request_handler;
3264+ // An implementation of connectivity::Manager.
3265+ std::shared_ptr<connectivity::ExtendedManager> connectivity_manager;
3266+ // An implementation of ReferenceTimeSource.
3267+ ReferenceTimeSource::Ptr reference_time_source;
3268
3269 // Emitted whenever the set of visible space vehicles changes.
3270 core::Signal<std::set<location::SpaceVehicle>> space_vehicle_updates;
3271
3272=== added file 'src/location_service/com/ubuntu/location/providers/gps/hardware_abstraction_layer.cpp'
3273--- src/location_service/com/ubuntu/location/providers/gps/hardware_abstraction_layer.cpp 1970-01-01 00:00:00 +0000
3274+++ src/location_service/com/ubuntu/location/providers/gps/hardware_abstraction_layer.cpp 2016-03-17 09:08:50 +0000
3275@@ -0,0 +1,30 @@
3276+/*
3277+ * Copyright © 2012-2013 Canonical Ltd.
3278+ *
3279+ * This program is free software: you can redistribute it and/or modify it
3280+ * under the terms of the GNU Lesser General Public License version 3,
3281+ * as published by the Free Software Foundation.
3282+ *
3283+ * This program is distributed in the hope that it will be useful,
3284+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3285+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3286+ * GNU Lesser General Public License for more details.
3287+ *
3288+ * You should have received a copy of the GNU Lesser General Public License
3289+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
3290+ *
3291+ * Authored by: Thomas Voß <thomas.voss@canonical.com>
3292+ */
3293+
3294+#include <com/ubuntu/location/providers/gps/hardware_abstraction_layer.h>
3295+
3296+#include <iostream>
3297+
3298+namespace gps = com::ubuntu::location::providers::gps;
3299+
3300+std::ostream& gps::operator<<(std::ostream& out, const gps::HardwareAbstractionLayer::ReferenceTimeSample& sample)
3301+{
3302+ return out << "[since epoch: " << sample.since_epoch.count() << " [ms], since boot: "
3303+ << sample.since_boot.count() << " [ms], uncertainty: "
3304+ << sample.uncertainty.count() << " [ms]";
3305+}
3306
3307=== modified file 'src/location_service/com/ubuntu/location/providers/gps/hardware_abstraction_layer.h'
3308--- src/location_service/com/ubuntu/location/providers/gps/hardware_abstraction_layer.h 2014-06-06 17:52:59 +0000
3309+++ src/location_service/com/ubuntu/location/providers/gps/hardware_abstraction_layer.h 2016-03-17 09:08:50 +0000
3310@@ -18,11 +18,14 @@
3311 #ifndef LOCATION_SERVICE_COM_UBUNTU_LOCATION_PROVIDERS_GPS_HARDWARE_ABSTRACTION_LAYER_H_
3312 #define LOCATION_SERVICE_COM_UBUNTU_LOCATION_PROVIDERS_GPS_HARDWARE_ABSTRACTION_LAYER_H_
3313
3314+#include <com/ubuntu/location/clock.h>
3315 #include <com/ubuntu/location/heading.h>
3316 #include <com/ubuntu/location/position.h>
3317 #include <com/ubuntu/location/space_vehicle.h>
3318 #include <com/ubuntu/location/velocity.h>
3319
3320+#include <com/ubuntu/location/connectivity/radio_cell.h>
3321+
3322 #include <core/property.h>
3323
3324 #include <chrono>
3325@@ -104,6 +107,13 @@
3326 class HardwareAbstractionLayer
3327 {
3328 public:
3329+ /** @brief ReferenceTimeSample bundles together the local reference. */
3330+ struct ReferenceTimeSample
3331+ {
3332+ std::chrono::milliseconds since_epoch; /**< Reference wall-clock time since the epoch (UTC). */
3333+ std::chrono::milliseconds since_boot; /**< Reference time since boot. */
3334+ std::chrono::milliseconds uncertainty; /**< Uncertainty estimate of the sample. */
3335+ };
3336
3337 class SuplAssistant
3338 {
3339@@ -148,6 +158,16 @@
3340 data_connection_failed = 5
3341 };
3342
3343+ /**
3344+ * @brief The SetIdType enum enumerates all valid types of SetIds.
3345+ */
3346+ enum class SetIdType
3347+ {
3348+ none,
3349+ imsi,
3350+ msisdn
3351+ };
3352+
3353 virtual ~SuplAssistant() = default;
3354 SuplAssistant(const SuplAssistant&) = delete;
3355
3356@@ -165,6 +185,16 @@
3357 virtual const core::Property<IpV4Address>& server_ip() const = 0;
3358
3359 /**
3360+ * @brief Sets mobile subscriber identity.
3361+ */
3362+ virtual void set_set_id(SetIdType type, const std::string& id) const = 0;
3363+
3364+ /**
3365+ * @brief Injects reference location information.
3366+ */
3367+ virtual void inject_radio_cell_information(const connectivity::RadioCell& radio_cell) const = 0;
3368+
3369+ /**
3370 * @brief set_server informs the assistant instance about the SUPL server it should talk to.
3371 * @param host_name The host name of the SUPL server.
3372 * @param port The port of the SUPL server.
3373@@ -304,16 +334,17 @@
3374
3375 /**
3376 * @brief Injects a new reference time to the underlying gps driver/chipset.
3377- * @param reference_time The new reference time.
3378- * @param sample_time When the reference time was sampled.
3379+ * @param sample The reference time sample
3380 * @return true iff the injection was successful, false otherwise.
3381 */
3382- virtual bool inject_reference_time(const std::chrono::microseconds& reference_time,
3383- const std::chrono::microseconds& sample_time) = 0;
3384+ virtual bool inject_reference_time(const ReferenceTimeSample& sample) = 0;
3385
3386 protected:
3387 HardwareAbstractionLayer() = default;
3388 };
3389+
3390+/** @brief operator<< inserts sample into out. */
3391+std::ostream& operator<<(std::ostream& out, const HardwareAbstractionLayer::ReferenceTimeSample& sample);
3392 }
3393 }
3394 }
3395
3396=== added file 'src/location_service/com/ubuntu/location/providers/gps/sntp_client.cpp'
3397--- src/location_service/com/ubuntu/location/providers/gps/sntp_client.cpp 1970-01-01 00:00:00 +0000
3398+++ src/location_service/com/ubuntu/location/providers/gps/sntp_client.cpp 2016-03-17 09:08:50 +0000
3399@@ -0,0 +1,210 @@
3400+/*
3401+ * Copyright © 2012-2013 Canonical Ltd.
3402+ *
3403+ * This program is free software: you can redistribute it and/or modify it
3404+ * under the terms of the GNU Lesser General Public License version 3,
3405+ * as published by the Free Software Foundation.
3406+ *
3407+ * This program is distributed in the hope that it will be useful,
3408+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3409+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3410+ * GNU Lesser General Public License for more details.
3411+ *
3412+ * You should have received a copy of the GNU Lesser General Public License
3413+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
3414+ *
3415+ * Authored by: Thomas Voß <thomas.voss@canonical.com>
3416+ */
3417+
3418+#include <com/ubuntu/location/providers/gps/sntp_client.h>
3419+
3420+#include <com/ubuntu/location/time_since_boot.h>
3421+
3422+#include <boost/asio/ip/udp.hpp>
3423+#include <boost/endian/buffers.hpp>
3424+
3425+#include <bitset>
3426+#include <fstream>
3427+#include <future>
3428+#include <iostream>
3429+#include <thread>
3430+
3431+namespace location = com::ubuntu::location;
3432+namespace gps = location::providers::gps;
3433+namespace ip = boost::asio::ip;
3434+
3435+namespace
3436+{
3437+
3438+template<typename T>
3439+T sync_or_throw(std::future<T>& f)
3440+{
3441+ return f.get();
3442+}
3443+
3444+template<>
3445+void sync_or_throw<>(std::future<void>& f)
3446+{
3447+ f.get();
3448+}
3449+
3450+struct Now
3451+{
3452+ std::chrono::nanoseconds time = std::chrono::duration_cast<std::chrono::milliseconds>(
3453+ std::chrono::system_clock::now().time_since_epoch());
3454+ std::chrono::nanoseconds ticks = location::time_since_boot();
3455+};
3456+}
3457+
3458+const std::chrono::seconds& gps::sntp::offset_1900_to_1970()
3459+{
3460+ static const std::uint64_t secs = ((365ull * 70ull) + 17ull) * 24ull * 60ull * 60ull;
3461+ static const std::chrono::seconds seconds{secs};
3462+ return seconds;
3463+}
3464+
3465+gps::sntp::LeapIndicator gps::sntp::Packet::LeapIndicatorVersionMode::leap_indicator() const
3466+{
3467+ return static_cast<LeapIndicator>((livm.value() >> 6) & 0x3);
3468+}
3469+
3470+gps::sntp::Packet::LeapIndicatorVersionMode& gps::sntp::Packet::LeapIndicatorVersionMode::leap_indicator(LeapIndicator li)
3471+{
3472+ livm = livm.value() | (static_cast<uint8_t>(li) << 6);
3473+ return *this;
3474+}
3475+
3476+std::uint8_t gps::sntp::Packet::LeapIndicatorVersionMode::version() const
3477+{
3478+ return (livm.value() >> 3) & 0x7;
3479+}
3480+
3481+gps::sntp::Packet::LeapIndicatorVersionMode& gps::sntp::Packet::LeapIndicatorVersionMode::version(std::uint8_t version)
3482+{
3483+ livm = livm.value() | (version << 3);
3484+ return *this;
3485+}
3486+
3487+gps::sntp::Mode gps::sntp::Packet::LeapIndicatorVersionMode::mode() const
3488+{
3489+ return static_cast<Mode>(livm.value() & 0x7);
3490+}
3491+
3492+gps::sntp::Packet::LeapIndicatorVersionMode& gps::sntp::Packet::LeapIndicatorVersionMode::mode(Mode m)
3493+{
3494+ livm = static_cast<uint8_t>(m) | livm.value();
3495+ return *this;
3496+}
3497+
3498+gps::sntp::Client::Response gps::sntp::Client::request_time(const std::string& host, const std::chrono::milliseconds& timeout, boost::asio::io_service& ios)
3499+{
3500+ ip::udp::resolver resolver{ios};
3501+ ip::udp::socket socket{ios};
3502+ bool timed_out{false};
3503+
3504+ std::promise<ip::udp::resolver::iterator> promise_resolve;
3505+ auto future_resolve= promise_resolve.get_future();
3506+
3507+ boost::asio::deadline_timer timer{ios};
3508+ timer.expires_from_now(boost::posix_time::milliseconds{timeout.count()});
3509+ timer.async_wait([&timed_out, &resolver, &socket](const boost::system::error_code& ec)
3510+ {
3511+ if (ec)
3512+ return;
3513+
3514+ timed_out = true;
3515+
3516+ resolver.cancel();
3517+ socket.shutdown(ip::udp::socket::shutdown_both);
3518+ socket.close();
3519+ });
3520+
3521+ ip::udp::resolver::query query{ip::udp::v4(), host, "ntp"};
3522+
3523+ resolver.async_resolve(query, [&promise_resolve](const boost::system::error_code& ec, ip::udp::resolver::iterator it)
3524+ {
3525+ if (ec)
3526+ promise_resolve.set_exception(std::make_exception_ptr(boost::system::system_error(ec)));
3527+ else
3528+ promise_resolve.set_value(it);
3529+ });
3530+
3531+ auto it = sync_or_throw(future_resolve);
3532+
3533+ std::promise<void> promise_connect;
3534+ auto future_connect = promise_connect.get_future();
3535+
3536+ socket.async_connect(*it, [&promise_connect](const boost::system::error_code& ec)
3537+ {
3538+ if (ec)
3539+ promise_connect.set_exception(std::make_exception_ptr(boost::system::system_error(ec)));
3540+ else
3541+ promise_connect.set_value();
3542+ });
3543+
3544+ sync_or_throw(future_connect);
3545+
3546+ sntp::Packet packet;
3547+
3548+ Now before;
3549+ {
3550+ packet = request(socket);
3551+ timer.cancel();
3552+
3553+ if (timed_out)
3554+ throw std::runtime_error("Operation timed out.");
3555+ }
3556+ Now after;
3557+
3558+ auto originate = packet.originate.to_milliseconds_since_epoch();
3559+ auto receive = packet.receive.to_milliseconds_since_epoch();
3560+ auto transmit = packet.transmit.to_milliseconds_since_epoch();
3561+
3562+ auto rtt = after.ticks - before.ticks - (transmit - receive);
3563+ auto offset = ((receive - originate) + (transmit - after.time))/2;
3564+
3565+ return
3566+ {
3567+ packet,
3568+ std::chrono::duration_cast<std::chrono::milliseconds>(after.time + offset),
3569+ std::chrono::duration_cast<std::chrono::milliseconds>(after.ticks),
3570+ std::chrono::duration_cast<std::chrono::milliseconds>(rtt)
3571+ };
3572+}
3573+
3574+gps::sntp::Packet gps::sntp::Client::request(boost::asio::ip::udp::socket& socket)
3575+{
3576+ sntp::Packet packet;
3577+ packet.transmit.from_milliseconds_since_epoch(
3578+ std::chrono::duration_cast<std::chrono::milliseconds>(
3579+ std::chrono::system_clock::now().time_since_epoch()));
3580+ packet.livm.mode(sntp::Mode::client).version(sntp::version);
3581+
3582+ std::promise<std::size_t> promise_send;
3583+ auto future_send = promise_send.get_future();
3584+
3585+ socket.async_send(boost::asio::buffer(&packet, sizeof(packet)), [&promise_send](const boost::system::error_code& ec, std::size_t transferred)
3586+ {
3587+ if (ec)
3588+ promise_send.set_exception(std::make_exception_ptr(boost::system::system_error(ec)));
3589+ else
3590+ promise_send.set_value(transferred);
3591+ });
3592+
3593+ sync_or_throw(future_send);
3594+
3595+ std::promise<std::size_t> promise_receive;
3596+ auto future_receive = promise_receive.get_future();
3597+
3598+ socket.async_receive(boost::asio::buffer(&packet, sizeof(packet)), [&promise_receive](const boost::system::error_code& ec, std::size_t transferred)
3599+ {
3600+ if (ec)
3601+ promise_receive.set_exception(std::make_exception_ptr(boost::system::system_error(ec)));
3602+ else
3603+ promise_receive.set_value(transferred);
3604+ });
3605+
3606+ sync_or_throw(future_receive);
3607+
3608+ return packet;
3609+}
3610
3611=== added file 'src/location_service/com/ubuntu/location/providers/gps/sntp_client.h'
3612--- src/location_service/com/ubuntu/location/providers/gps/sntp_client.h 1970-01-01 00:00:00 +0000
3613+++ src/location_service/com/ubuntu/location/providers/gps/sntp_client.h 2016-03-17 09:08:50 +0000
3614@@ -0,0 +1,210 @@
3615+/*
3616+ * Copyright © 2012-2013 Canonical Ltd.
3617+ *
3618+ * This program is free software: you can redistribute it and/or modify it
3619+ * under the terms of the GNU Lesser General Public License version 3,
3620+ * as published by the Free Software Foundation.
3621+ *
3622+ * This program is distributed in the hope that it will be useful,
3623+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3624+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3625+ * GNU Lesser General Public License for more details.
3626+ *
3627+ * You should have received a copy of the GNU Lesser General Public License
3628+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
3629+ *
3630+ * Authored by: Thomas Voß <thomas.voss@canonical.com>
3631+ */
3632+#ifndef LOCATION_SERVICE_COM_UBUNTU_LOCATION_PROVIDERS_GPS_SNTP_CLIENT_H_
3633+#define LOCATION_SERVICE_COM_UBUNTU_LOCATION_PROVIDERS_GPS_SNTP_CLIENT_H_
3634+
3635+#include <com/ubuntu/location/providers/gps/android_hardware_abstraction_layer.h>
3636+
3637+#include <boost/asio.hpp>
3638+#include <boost/endian/buffers.hpp>
3639+
3640+#include <chrono>
3641+#include <string>
3642+
3643+namespace com { namespace ubuntu { namespace location { namespace providers { namespace gps { namespace sntp {
3644+// Please see https://tools.ietf.org/html/rfc4330 for a discussion of sntp
3645+// and for a detailed explanation of the different types and algorithms.
3646+
3647+namespace detail
3648+{
3649+// enum_constant returns a compile-time constant assembled from 4 or at least
3650+// 3 individual characters.
3651+template<std::uint8_t a, std::uint8_t b, std::uint8_t c, std::uint8_t d = 0>
3652+constexpr uint32_t enum_constant()
3653+{
3654+ return (a << 24) | (b << 16) | (c << 8) | d;
3655+}
3656+}
3657+
3658+// offset_1900_to_1970 returns the number of seconds that elapsed between 1900 and 1970.
3659+const std::chrono::seconds& offset_1900_to_1970();
3660+
3661+// LeapIndicator enumerates warnings of an impending
3662+// leap second to be inserted/deleted in the last minute of the current
3663+// day.
3664+enum class LeapIndicator : std::uint8_t
3665+{
3666+ no_warning = 0,
3667+ last_minute_has_61_seconds = 1,
3668+ last_minute_has_59_seconds = 2,
3669+ alarm = 3
3670+};
3671+
3672+// Mode enumerates the different protocol modes.
3673+enum class Mode : std::uint8_t
3674+{
3675+ reserved = 0,
3676+ symmetric_active = 1,
3677+ symmetric_passive = 2,
3678+ client = 3,
3679+ server = 4,
3680+ broadcast = 5,
3681+ reserved_for_control = 6,
3682+ reserved_for_private_use = 7
3683+};
3684+
3685+// ReferenceIdentifier enumerates known references for NTP-servers
3686+// on stratum 0 or 1.
3687+enum class ReferenceIdentifier : std::uint32_t
3688+{
3689+ locl = detail::enum_constant<'L','O','C','L'>(), // uncalibrated local clock
3690+ cesm = detail::enum_constant<'C','E','S','M'>(), // calibrated Cesium clock
3691+ rbdm = detail::enum_constant<'R','B','D','M'>(), // calibrated Rubidium clock
3692+ pps = detail::enum_constant<'P','P','S'>(), // calibrated quartz clock or other pulse-per-second source
3693+ irig = detail::enum_constant<'I','R','I','G'>(), // Inter-Range Instrumentation Group
3694+ acts = detail::enum_constant<'A','C','T','S'>(), // NIST telephone modem service
3695+ usno = detail::enum_constant<'U','S','N','O'>(), // USNO telephone modem service
3696+ ptb = detail::enum_constant<'P','T','B'>(), // PTB (Germany) telephone modem service
3697+ tdf = detail::enum_constant<'T','D','F'>(), // Allouis (France) Radio 164 kHz
3698+ dcf = detail::enum_constant<'D','C','F'>(), // Mainflingen (Germany) Radio 77.5 kHz
3699+ msf = detail::enum_constant<'M','S', 'F'>(), // Rugby (UK) Radio 60 kHz
3700+ wwv = detail::enum_constant<'W','W','V'>(), // Ft. Collins (US) Radio 2.5, 5, 10, 15, 20 MHz
3701+ wwvb = detail::enum_constant<'W','W','V','B'>(), // Boulder (US) Radio 60 kHz
3702+ wwvh = detail::enum_constant<'W','W','V','H'>(), // Kauai Hawaii (US) Radio 2.5, 5, 10, 15 MHz
3703+ chu = detail::enum_constant<'C','H','U'>(), // Ottawa (Canada) Radio 3330, 7335, 14670 kHz
3704+ lorc = detail::enum_constant<'L','O','R','C'>(), // LORAN-C radionavigation system
3705+ omeg = detail::enum_constant<'O','M','E','G'>(), // OMEGA radionavigation system
3706+ gps = detail::enum_constant<'G','P','S'>() // Global Positioning Service
3707+};
3708+
3709+// Timestamp models a fixed-point NTP timestamp relative to 01.01.1900
3710+template<typename Seconds, typename FractionalSeconds = Seconds>
3711+struct Timestamp
3712+{
3713+ // To stay on the safe side, we only allow for the types specified below.
3714+ // With that, we make sure that we only ever use endian-save types.
3715+ static_assert(std::is_same<Seconds, boost::endian::big_int16_buf_t>::value ||
3716+ std::is_same<Seconds, boost::endian::big_uint16_buf_t>::value ||
3717+ std::is_same<Seconds, boost::endian::big_int32_buf_t>::value ||
3718+ std::is_same<Seconds, boost::endian::big_uint32_buf_t>::value,
3719+ "Timestamp<> only supports boost::endian::big_{{u}int{16,32}}_buf_t");
3720+
3721+ // from_milliseconds_since_epoch fills in seconds/fractional_seconds from
3722+ // ms, converting to NTP's reference time.
3723+ void from_milliseconds_since_epoch(const std::chrono::milliseconds& ts)
3724+ {
3725+ using s = std::chrono::seconds;
3726+ using ms = std::chrono::milliseconds;
3727+
3728+ auto secs = std::chrono::duration_cast<s>(ts);
3729+ auto msecs = std::chrono::duration_cast<ms>(ts - secs);
3730+
3731+ secs += offset_1900_to_1970();
3732+
3733+ seconds = secs.count();
3734+ fractional_seconds = msecs.count() * std::numeric_limits<typename FractionalSeconds::value_type>::max() + 1 / 1000;
3735+ }
3736+
3737+ // to_milliseconds_since_epoch returns a unix timestamp calculated from
3738+ // an NTP-timestamp.
3739+ std::chrono::milliseconds to_milliseconds_since_epoch() const
3740+ {
3741+ return std::chrono::seconds{seconds.value()} - offset_1900_to_1970() +
3742+ std::chrono::milliseconds{(fractional_seconds.value() * 1000) / std::numeric_limits<typename FractionalSeconds::value_type>::max()};
3743+ }
3744+
3745+ Seconds seconds;
3746+ FractionalSeconds fractional_seconds;
3747+};
3748+
3749+// Duration is just an alias to an sntp::Timestamp.
3750+template<typename T, typename U>
3751+using Duration = Timestamp<T, U>;
3752+
3753+// Packet models the SNTP wire format.
3754+struct Packet
3755+{
3756+ // LeapIndicatorVersionMode helps in handling the bitfield setup
3757+ // for the first byte of an sntp::Packet in a portable and endianess-safe way.
3758+ struct LeapIndicatorVersionMode
3759+ {
3760+ // leap_indicator extracts the LeapIndicator from the underlying data.
3761+ LeapIndicator leap_indicator() const;
3762+ // leap_indicator sets the value of the leap_indicatorin in the underyling
3763+ // data to li.
3764+ LeapIndicatorVersionMode& leap_indicator(LeapIndicator li);
3765+
3766+ // version extracts the version from the underlying data.
3767+ std::uint8_t version() const;
3768+ // version adjusts the version to version in the underlying data.
3769+ LeapIndicatorVersionMode& version(std::uint8_t version);
3770+
3771+ // mode extracts the mode from the underlying data.
3772+ Mode mode() const;
3773+ // mode adjusts the mode to m in the underlying data.
3774+ LeapIndicatorVersionMode& mode(Mode m);
3775+
3776+ boost::endian::big_uint8_buf_t livm;
3777+ };
3778+
3779+ LeapIndicatorVersionMode livm;
3780+ boost::endian::big_uint8_buf_t stratum;
3781+ boost::endian::big_uint8_buf_t poll_interval;
3782+ boost::endian::big_int8_buf_t precision;
3783+ Duration<boost::endian::big_int16_buf_t, boost::endian::big_uint16_buf_t> root_delay;
3784+ Duration<boost::endian::big_uint16_buf_t, boost::endian::big_uint16_buf_t> root_dispersion;
3785+ boost::endian::big_uint32_buf_t reference_identifier;
3786+ Timestamp<boost::endian::big_uint32_buf_t> reference;
3787+ Timestamp<boost::endian::big_uint32_buf_t> originate;
3788+ Timestamp<boost::endian::big_uint32_buf_t> receive;
3789+ Timestamp<boost::endian::big_uint32_buf_t> transmit;
3790+};
3791+// The SNTP version we are working with.
3792+static constexpr const std::uint8_t version = 3;
3793+
3794+// SntpClient provides access to querying time from an NTP server in
3795+// a unicast scenario.
3796+class Client
3797+{
3798+public:
3799+ // Response is returned in a request for time information.
3800+ struct Response
3801+ {
3802+ // The raw packet that was returned from the request.
3803+ sntp::Packet packet;
3804+ // Time computed from the NTP transaction.
3805+ std::chrono::milliseconds ntp_time;
3806+ // Reference clock value corresponding to the NTP time.
3807+ std::chrono::milliseconds ntp_time_reference;
3808+ // Round-trip time of the last NTP transaction.
3809+ std::chrono::milliseconds round_trip_time;
3810+ };
3811+
3812+ // request_time_with_timeout reaches out to the SNTP server known under host,
3813+ // and tries to determine the current UTC reference time. The operation aborts after
3814+ // timeout milliseconds.
3815+ //
3816+ // std::runtime_error is thrown in case of issues.
3817+ Response request_time(const std::string& host, const std::chrono::milliseconds& timeout, boost::asio::io_service& ios);
3818+ sntp::Packet request(boost::asio::ip::udp::socket& socket);
3819+};
3820+}
3821+}
3822+
3823+}}}}
3824+#endif // LOCATION_SERVICE_COM_UBUNTU_LOCATION_PROVIDERS_GPS_SNTP_CLIENT_H_
3825
3826=== added file 'src/location_service/com/ubuntu/location/providers/gps/sntp_reference_time_source.cpp'
3827--- src/location_service/com/ubuntu/location/providers/gps/sntp_reference_time_source.cpp 1970-01-01 00:00:00 +0000
3828+++ src/location_service/com/ubuntu/location/providers/gps/sntp_reference_time_source.cpp 2016-03-17 09:08:50 +0000
3829@@ -0,0 +1,57 @@
3830+/*
3831+ * Copyright © 2012-2013 Canonical Ltd.
3832+ *
3833+ * This program is free software: you can redistribute it and/or modify it
3834+ * under the terms of the GNU Lesser General Public License version 3,
3835+ * as published by the Free Software Foundation.
3836+ *
3837+ * This program is distributed in the hope that it will be useful,
3838+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3839+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3840+ * GNU Lesser General Public License for more details.
3841+ *
3842+ * You should have received a copy of the GNU Lesser General Public License
3843+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
3844+ *
3845+ * Authored by: Thomas Voß <thomas.voss@canonical.com>
3846+ */
3847+
3848+#include <com/ubuntu/location/providers/gps/sntp_reference_time_source.h>
3849+
3850+#include <com/ubuntu/location/configuration.h>
3851+#include <com/ubuntu/location/service/runtime.h>
3852+
3853+#include <boost/property_tree/ini_parser.hpp>
3854+
3855+#include <future>
3856+
3857+namespace location = com::ubuntu::location;
3858+namespace gps = com::ubuntu::location::providers::gps;
3859+
3860+gps::SntpReferenceTimeSource::Configuration gps::SntpReferenceTimeSource::Configuration::from_gps_conf_ini_file(std::istream& in)
3861+{
3862+ gps::SntpReferenceTimeSource::Configuration result;
3863+
3864+ location::Configuration config;
3865+ boost::property_tree::read_ini(in, config);
3866+
3867+ if (config.count("NTP_SERVER") > 0)
3868+ result.host = config.get<std::string>("NTP_SERVER");
3869+
3870+ return result;
3871+}
3872+gps::SntpReferenceTimeSource::SntpReferenceTimeSource(const Configuration& config)
3873+ : config(config)
3874+{
3875+}
3876+
3877+gps::HardwareAbstractionLayer::ReferenceTimeSample gps::SntpReferenceTimeSource::sample()
3878+{
3879+ auto rt = location::service::Runtime::create();
3880+ rt->start();
3881+
3882+ location::providers::gps::sntp::Client sntp_client;
3883+ auto result = sntp_client.request_time(config.host, config.timeout, rt->service());
3884+
3885+ return {result.ntp_time, result.ntp_time_reference, result.round_trip_time};
3886+}
3887
3888=== added file 'src/location_service/com/ubuntu/location/providers/gps/sntp_reference_time_source.h'
3889--- src/location_service/com/ubuntu/location/providers/gps/sntp_reference_time_source.h 1970-01-01 00:00:00 +0000
3890+++ src/location_service/com/ubuntu/location/providers/gps/sntp_reference_time_source.h 2016-03-17 09:08:50 +0000
3891@@ -0,0 +1,51 @@
3892+/*
3893+ * Copyright © 2016 Canonical Ltd.
3894+ *
3895+ * This program is free software: you can redistribute it and/or modify it
3896+ * under the terms of the GNU Lesser General Public License version 3,
3897+ * as published by the Free Software Foundation.
3898+ *
3899+ * This program is distributed in the hope that it will be useful,
3900+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3901+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3902+ * GNU Lesser General Public License for more details.
3903+ *
3904+ * You should have received a copy of the GNU Lesser General Public License
3905+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
3906+ *
3907+ * Authored by: Thomas Voß <thomas.voss@canonical.com>
3908+ */
3909+#ifndef LOCATION_SERVICE_COM_UBUNTU_LOCATION_PROVIDERS_GPS_SNTP_REFERENCE_TIME_SOURCE_H_
3910+#define LOCATION_SERVICE_COM_UBUNTU_LOCATION_PROVIDERS_GPS_SNTP_REFERENCE_TIME_SOURCE_H_
3911+
3912+#include <com/ubuntu/location/providers/gps/android_hardware_abstraction_layer.h>
3913+
3914+#include <com/ubuntu/location/providers/gps/sntp_client.h>
3915+
3916+namespace com { namespace ubuntu { namespace location { namespace providers { namespace gps {
3917+
3918+class SntpReferenceTimeSource : public android::HardwareAbstractionLayer::ReferenceTimeSource
3919+{
3920+public:
3921+
3922+ /** @brief Configuration summarizes default parameter available to implementations. */
3923+ struct Configuration
3924+ {
3925+ /** @brief Reads a configuration from a gps.conf file in INI format. */
3926+ static Configuration from_gps_conf_ini_file(std::istream& in);
3927+
3928+ std::string host{"pool.ntp.org"}; /**< NTP host. */
3929+ std::chrono::milliseconds timeout{5000}; /**< Timeout when querying the NTP server. */
3930+ };
3931+
3932+ SntpReferenceTimeSource(const Configuration& configuration);
3933+
3934+ gps::HardwareAbstractionLayer::ReferenceTimeSample sample() override;
3935+
3936+private:
3937+ const Configuration config;
3938+};
3939+
3940+}}}}}
3941+
3942+#endif // LOCATION_SERVICE_COM_UBUNTU_LOCATION_PROVIDERS_GPS_SNTP_REFERENCE_TIME_SOURCE_H_
3943
3944=== modified file 'src/location_service/com/ubuntu/location/providers/remote/provider.cpp'
3945--- src/location_service/com/ubuntu/location/providers/remote/provider.cpp 2015-04-14 18:54:00 +0000
3946+++ src/location_service/com/ubuntu/location/providers/remote/provider.cpp 2016-03-17 09:08:50 +0000
3947@@ -23,6 +23,7 @@
3948 #include <com/ubuntu/location/logging.h>
3949
3950 #include <core/dbus/object.h>
3951+#include <core/dbus/service_watcher.h>
3952 #include <core/dbus/signal.h>
3953 #include <core/dbus/asio/executor.h>
3954
3955@@ -191,6 +192,28 @@
3956 auto service = dbus::Service::use_service(bus, name);
3957 auto object = service->object_for_path(path);
3958
3959+ // Check if the service has come up
3960+ if (!bus->has_owner_for_name(name)) {
3961+ // If it hasn't wait for it to come up
3962+ bool valid = false;
3963+ std::mutex guard;
3964+ std::condition_variable cv;
3965+ dbus::DBus daemon(bus);
3966+ dbus::ServiceWatcher::Ptr service_watcher(
3967+ daemon.make_service_watcher(name, dbus::DBus::WatchMode::registration));
3968+
3969+ service_watcher->service_registered().connect([&valid, &guard, &cv]()
3970+ {
3971+ std::unique_lock<std::mutex> ul(guard);
3972+ valid = true;
3973+ cv.notify_all();
3974+ });
3975+
3976+ std::unique_lock<std::mutex> ul(guard);
3977+ if (not cv.wait_for(ul, std::chrono::seconds{30}, [&valid]() { return valid; }))
3978+ throw std::runtime_error("Remote service failed to start");
3979+ }
3980+
3981 return create_instance_with_config(remote::stub::Configuration{object});
3982 }
3983
3984
3985=== modified file 'src/location_service/com/ubuntu/location/service/daemon.cpp'
3986--- src/location_service/com/ubuntu/location/service/daemon.cpp 2016-03-17 09:08:50 +0000
3987+++ src/location_service/com/ubuntu/location/service/daemon.cpp 2016-03-17 09:08:50 +0000
3988@@ -181,28 +181,27 @@
3989 trap->stop();
3990 });
3991
3992- auto runtime = location::service::Runtime::create();
3993-
3994- const location::Configuration empty_provider_configuration;
3995-
3996- std::set<location::Provider::Ptr> instantiated_providers;
3997-
3998+ auto runtime = location::service::Runtime::create(4);
3999+
4000+ location::service::DefaultConfiguration dc;
4001+ auto engine = dc.the_engine(std::set<location::Provider::Ptr>{}, dc.the_provider_selection_policy(), config.settings);
4002 for (const std::string& provider : config.providers)
4003 {
4004 std::cout << "Instantiating and configuring: " << provider << std::endl;
4005
4006 try
4007 {
4008- auto p = location::ProviderFactory::instance().create_provider_for_name_with_config(
4009- provider,
4010- config.provider_options.count(provider) > 0 ?
4011- config.provider_options.at(provider) : empty_provider_configuration);
4012-
4013- if (p)
4014- instantiated_providers.insert(p);
4015- else
4016- throw std::runtime_error("Problem instantiating provider");
4017-
4018+ auto result = std::async(std::launch::async, [provider, config, engine] {
4019+ return location::ProviderFactory::instance().create_provider_for_name_with_config(
4020+ provider,
4021+ config.provider_options.count(provider) > 0 ?
4022+ config.provider_options.at(provider) : location::Configuration {},
4023+ [engine](Provider::Ptr provider)
4024+ {
4025+ engine->add_provider(provider);
4026+ }
4027+ );
4028+ });
4029 } catch(const std::runtime_error& e)
4030 {
4031 std::cerr << "Issue instantiating provider: " << e.what() << std::endl;
4032@@ -214,13 +213,11 @@
4033
4034 runtime->start();
4035
4036- location::service::DefaultConfiguration dc;
4037-
4038 location::service::Implementation::Configuration configuration
4039 {
4040 config.incoming,
4041 config.outgoing,
4042- dc.the_engine(instantiated_providers, dc.the_provider_selection_policy(), config.settings),
4043+ engine,
4044 dc.the_permission_manager(config.outgoing),
4045 location::service::Harvester::Configuration
4046 {
4047
4048=== modified file 'src/location_service/com/ubuntu/location/service/implementation.cpp'
4049--- src/location_service/com/ubuntu/location/service/implementation.cpp 2016-03-17 09:08:50 +0000
4050+++ src/location_service/com/ubuntu/location/service/implementation.cpp 2016-03-17 09:08:50 +0000
4051@@ -156,10 +156,12 @@
4052 std::weak_ptr<session::Interface> session_weak{session_iface};
4053 session_iface->updates().position_status.changed().connect([this, session_weak](const session::Interface::Updates::Status& status)
4054 {
4055- cul::Optional<cul::Update<cul::Position>> last_known_position =
4056- configuration.engine->updates.last_known_location.get();
4057- if (last_known_position &&
4058- status == culs::session::Interface::Updates::Status::enabled)
4059+ cul::Optional<cul::Update<cul::Position>> last_known_position = configuration.engine->updates.last_known_location.get();
4060+ bool has_last_known_position = last_known_position ? true : false;
4061+ bool is_session_enabled = status == culs::session::Interface::Updates::Status::enabled;
4062+ bool is_session_on_or_active = configuration.engine->configuration.engine_state != Engine::Status::off;
4063+
4064+ if (has_last_known_position && is_session_enabled && is_session_on_or_active)
4065 {
4066 // Immediately send the last known position to the client
4067 if (auto session_iface = session_weak.lock())
4068
4069=== modified file 'src/location_service/com/ubuntu/location/service/provider_daemon.cpp'
4070--- src/location_service/com/ubuntu/location/service/provider_daemon.cpp 2016-03-17 09:08:50 +0000
4071+++ src/location_service/com/ubuntu/location/service/provider_daemon.cpp 2016-03-17 09:08:50 +0000
4072@@ -112,7 +112,7 @@
4073 {
4074 std::shared_ptr<location::service::Runtime> runtime()
4075 {
4076- static const auto inst = location::service::Runtime::create(1);
4077+ static const auto inst = location::service::Runtime::create(2);
4078 return inst;
4079 }
4080 }
4081
4082=== modified file 'src/location_service/com/ubuntu/location/service/runtime.h'
4083--- src/location_service/com/ubuntu/location/service/runtime.h 2016-03-17 09:08:50 +0000
4084+++ src/location_service/com/ubuntu/location/service/runtime.h 2016-03-17 09:08:50 +0000
4085@@ -42,7 +42,7 @@
4086 {
4087 public:
4088 // Our default concurrency setup.
4089- static constexpr const std::uint32_t worker_threads = 2;
4090+ static constexpr const std::uint32_t worker_threads = 4;
4091
4092 // create returns a Runtime instance with pool_size worker threads
4093 // executing the underlying service.
4094
4095=== modified file 'src/location_service/com/ubuntu/location/service/runtime_tests.cpp'
4096--- src/location_service/com/ubuntu/location/service/runtime_tests.cpp 2015-01-26 20:15:05 +0000
4097+++ src/location_service/com/ubuntu/location/service/runtime_tests.cpp 2016-03-17 09:08:50 +0000
4098@@ -16,9 +16,12 @@
4099 * Authored by: Thomas Voß <thomas.voss@canonical.com>
4100 */
4101
4102+#include <com/ubuntu/location/service/program_options.h>
4103+#include <com/ubuntu/location/service/runtime.h>
4104 #include <com/ubuntu/location/service/runtime_tests.h>
4105
4106 #include <com/ubuntu/location/clock.h>
4107+#include <com/ubuntu/location/logging.h>
4108 #include <com/ubuntu/location/providers/gps/hardware_abstraction_layer.h>
4109
4110 #include <boost/accumulators/accumulators.hpp>
4111@@ -30,6 +33,7 @@
4112
4113 #include <chrono>
4114 #include <condition_variable>
4115+#include <fstream>
4116 #include <iostream>
4117 #include <mutex>
4118 #include <thread>
4119@@ -39,6 +43,39 @@
4120
4121 namespace
4122 {
4123+namespace options
4124+{
4125+struct ResultFile
4126+{
4127+ static constexpr const char* name{"result-file"};
4128+
4129+ static void add_to_options(location::ProgramOptions& options)
4130+ {
4131+ options.add(name, "statistics are written to this file", std::string("runtime_test_result.txt"));
4132+ }
4133+
4134+ static std::string read_from_options(location::ProgramOptions& options)
4135+ {
4136+ return options.value_for_key<std::string>(name);
4137+ }
4138+};
4139+
4140+struct Trials
4141+{
4142+ static constexpr const char* name{"trials"};
4143+
4144+ static void add_to_options(location::ProgramOptions& options)
4145+ {
4146+ options.add(name, "total number of independent trials", std::uint32_t(3));
4147+ }
4148+
4149+ static std::uint32_t read_from_options(location::ProgramOptions& options)
4150+ {
4151+ return options.value_for_key<std::uint32_t>(name);
4152+ }
4153+};
4154+}
4155+
4156 template<bool expected, typename Exception>
4157 void expect(bool value, const std::string& what)
4158 {
4159@@ -49,6 +86,22 @@
4160 // running service instance and restarting it after the tests have been run.
4161 struct Fixture
4162 {
4163+ // ChipsetStartupMode enumerates all known startup modes.
4164+ enum class ChipsetStartupMode : std::uint32_t
4165+ {
4166+ cold, // Force a cold start, deleting all assistance data.
4167+ warm // Warm start, rely on known assistance data.
4168+ };
4169+
4170+ // Configuration summarizes test case parameters.
4171+ struct Configuration
4172+ {
4173+ std::string name; // Name of the test case.
4174+ gps::AssistanceMode assistance_mode; // Requested assistance mode.
4175+ ChipsetStartupMode startup_mode; // Requested startup mode.
4176+ std::size_t no_trials; // Total number of independent trials.
4177+ };
4178+
4179 Fixture()
4180 {
4181 // We need to make sure that we are running as root. In addition, we will stop
4182@@ -70,8 +123,19 @@
4183 }
4184 };
4185
4186+std::ostream& operator<<(std::ostream& out, Fixture::ChipsetStartupMode mode)
4187+{
4188+ switch (mode)
4189+ {
4190+ case Fixture::ChipsetStartupMode::cold: return out << "cold";
4191+ case Fixture::ChipsetStartupMode::warm: return out << "warm";
4192+ }
4193+
4194+ return out;
4195+}
4196+
4197 #if defined(COM_UBUNTU_LOCATION_SERVICE_PROVIDERS_GPS)
4198-int snr_and_ttff()
4199+int snr_and_ttff(const Fixture::Configuration& config, std::ostream& out)
4200 {
4201 typedef boost::accumulators::accumulator_set<
4202 double,
4203@@ -84,8 +148,6 @@
4204 using boost::accumulators::mean;
4205 using boost::accumulators::variance;
4206
4207- static const unsigned int trials = 3;
4208-
4209 Statistics stats;
4210 auto hal = gps::HardwareAbstractionLayer::create_default_instance();
4211
4212@@ -120,28 +182,37 @@
4213 bool fix_received;
4214 } state;
4215
4216- // We want to run in standalone mode
4217- hal->set_assistance_mode(gps::AssistanceMode::standalone);
4218+ hal->set_assistance_mode(config.assistance_mode);
4219
4220 // We wire up our state to position updates from the hal.
4221- hal->position_updates().connect([&state](const location::Position& pos)
4222+ core::ScopedConnection scp = hal->position_updates().connect([&state](const location::Position& pos)
4223 {
4224 state.on_position_updated(pos);
4225 });
4226
4227 // We report updates to the visible space vehicles here.
4228- hal->space_vehicle_updates().connect([](const std::set<location::SpaceVehicle>& svs)
4229+ core::ScopedConnection svsc = hal->space_vehicle_updates().connect([](const std::set<location::SpaceVehicle>& svs)
4230 {
4231- std::cout << std::scientific;
4232- std::cout << "key snr has_almanac_data has_ephimeris_data used_in_fix azimuth elevation" << std::endl;
4233- for (const auto& sv : svs)
4234- std::cout << sv.key.id << " " << sv.snr << " " << sv.has_almanac_data << " " << sv.has_ephimeris_data << " " << sv.used_in_fix << " " << sv.azimuth.value() << " " << sv.elevation.value() << std::endl;
4235+ if (svs.size() > 0)
4236+ {
4237+ LOG(INFO) << "key snr has_almanac_data has_ephimeris_data used_in_fix azimuth elevation";
4238+ for (const auto& sv : svs)
4239+ LOG(INFO) << sv.key.id << " " << sv.snr << " " << sv.has_almanac_data << " " << sv.has_ephimeris_data << " " << sv.used_in_fix << " " << sv.azimuth.value() << " " << sv.elevation.value();
4240+ }
4241 });
4242
4243- for (unsigned int i = 0; i < trials; i++)
4244+ std::cout << " " << config.name << " [" << config.no_trials << " trials]\t\t|" << std::flush;
4245+
4246+ for (unsigned int i = 0; i < config.no_trials; i++)
4247 {
4248- // We want to force a cold start per trial.
4249- hal->delete_all_aiding_data();
4250+ switch (config.startup_mode)
4251+ {
4252+ case Fixture::ChipsetStartupMode::cold:
4253+ hal->delete_all_aiding_data();
4254+ break;
4255+ default:
4256+ break;
4257+ }
4258
4259 state.reset();
4260 auto start = std::chrono::duration_cast<std::chrono::microseconds>(location::Clock::now().time_since_epoch());
4261@@ -155,31 +226,56 @@
4262 }
4263 auto stop = std::chrono::duration_cast<std::chrono::microseconds>(location::Clock::now().time_since_epoch());
4264
4265- stats((stop - start).count());
4266+ stats((stop - start).count()); std::cout << "·" << std::flush;
4267 }
4268+ std::cout << "|" << std::endl;
4269
4270- std::cout << "Mean time to first fix in [ms]: "
4271- << std::chrono::duration_cast<std::chrono::milliseconds>(
4272- std::chrono::microseconds(
4273- static_cast<std::uint64_t>(mean(stats)))).count()
4274- << std::endl;
4275- std::cout << "Variance in time to first fix in [ms]: "
4276- << std::chrono::duration_cast<std::chrono::milliseconds>(
4277- std::chrono::microseconds(
4278- static_cast<std::uint64_t>(variance(stats)))).count()
4279- << std::endl;
4280+ out << config.name << std::endl
4281+ << " Mean time to first fix in [ms]: "
4282+ << std::chrono::duration_cast<std::chrono::milliseconds>(
4283+ std::chrono::microseconds(
4284+ static_cast<std::uint64_t>(mean(stats)))).count()
4285+ << std::endl
4286+ << " Std. dev in time to first fix in [ms]: "
4287+ << std::chrono::duration_cast<std::chrono::milliseconds>(
4288+ std::chrono::microseconds(
4289+ static_cast<std::uint64_t>(::sqrt(variance(stats))))).count()
4290+ << std::endl;
4291
4292 return 0;
4293 }
4294 #else
4295-int snr_and_ttff() { return 0; }
4296+int snr_and_ttff(const Fixture::Configuration&, std::ostream&) { return 0; }
4297 #endif // COM_UBUNTU_LOCATION_SERVICE_PROVIDERS_GPS
4298 }
4299
4300+#define RUNTIME_TEST(name, assistance_mode, startup_mode, trials, result) \
4301+ {\
4302+ auto rc = snr_and_ttff(Fixture::Configuration{name, assistance_mode, startup_mode, trials}, result); \
4303+ if (rc != 0) return rc; \
4304+ }
4305+
4306 int location::service::execute_runtime_tests()
4307 {
4308 Fixture fixture; // This throws in case of issues.
4309- auto rc = snr_and_ttff(); if (rc != 0) return rc;
4310- // Other runtime tests go here;
4311- return rc;
4312+
4313+ location::ProgramOptions po;
4314+ po.environment_prefix("UBUNTU_LOCATION_SERVICE_RUNTIME_TESTS_");
4315+
4316+ options::ResultFile::add_to_options(po);
4317+ options::Trials::add_to_options(po);
4318+
4319+ po.parse_from_environment();
4320+
4321+ auto trials = options::Trials::read_from_options(po);
4322+ std::ofstream out{options::ResultFile::read_from_options(po)}; // Actual result statistics are stored here.
4323+
4324+ std::cout << "Location service runtime tests:" << std::endl;
4325+
4326+ RUNTIME_TEST("ColdStartWithAssistance", gps::AssistanceMode::mobile_station_based, Fixture::ChipsetStartupMode::cold, trials, out);
4327+ RUNTIME_TEST("WarmStartWithoutAssistance", gps::AssistanceMode::standalone, Fixture::ChipsetStartupMode::warm, trials, out);
4328+ RUNTIME_TEST("WarmStartWithAssistance", gps::AssistanceMode::mobile_station_based, Fixture::ChipsetStartupMode::warm, trials, out);
4329+ RUNTIME_TEST("ColdStartWithoutAssistance", gps::AssistanceMode::standalone, Fixture::ChipsetStartupMode::cold, trials, out);
4330+
4331+ return 0;
4332 }
4333
4334=== modified file 'src/location_service/com/ubuntu/location/service/trust_store_permission_manager.cpp'
4335--- src/location_service/com/ubuntu/location/service/trust_store_permission_manager.cpp 2014-09-19 14:36:51 +0000
4336+++ src/location_service/com/ubuntu/location/service/trust_store_permission_manager.cpp 2016-03-17 09:08:50 +0000
4337@@ -146,7 +146,7 @@
4338 return service::PermissionManager::Result::rejected;
4339 }
4340
4341- std::string description = i18n::tr("%1% wants to access your current location.");
4342+ std::string description = i18n::tr("wants to access your current location.");
4343
4344 core::trust::Agent::RequestParameters params
4345 {
4346
4347=== added file 'src/location_service/com/ubuntu/location/time_since_boot.cpp'
4348--- src/location_service/com/ubuntu/location/time_since_boot.cpp 1970-01-01 00:00:00 +0000
4349+++ src/location_service/com/ubuntu/location/time_since_boot.cpp 2016-03-17 09:08:50 +0000
4350@@ -0,0 +1,140 @@
4351+/*
4352+ * Copyright © 2016 Canonical Ltd.
4353+ *
4354+ * This program is free software: you can redistribute it and/or modify it
4355+ * under the terms of the GNU Lesser General Public License version 3,
4356+ * as published by the Free Software Foundation.
4357+ *
4358+ * This program is distributed in the hope that it will be useful,
4359+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4360+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4361+ * GNU Lesser General Public License for more details.
4362+ *
4363+ * You should have received a copy of the GNU Lesser General Public License
4364+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4365+ *
4366+ * Authored by: Thomas Voß <thomas.voss@canonical.com>
4367+ */
4368+
4369+#include <com/ubuntu/location/time_since_boot.h>
4370+#include <com/ubuntu/location/logging.h>
4371+
4372+#if defined(COM_UBUNTU_LOCATION_SERVICE_HAVE_UBUNTU_PLATFORM_HARDWARE_API)
4373+#include <ubuntu/hardware/alarm.h>
4374+#endif // COM_UBUNTU_LOCATION_SERVICE_HAVE_UBUNTU_PLATFORM_HARDWARE_API
4375+
4376+#include <fstream>
4377+#include <sstream>
4378+#include <stdexcept>
4379+#include <system_error>
4380+
4381+namespace location = com::ubuntu::location;
4382+
4383+namespace
4384+{
4385+bool have_ubuntu_hardware_alarm()
4386+{
4387+#if defined(COM_UBUNTU_LOCATION_SERVICE_HAVE_UBUNTU_PLATFORM_HARDWARE_API)
4388+ return true;
4389+#else
4390+ return false;
4391+#endif // COM_UBUNTU_LOCATION_SERVICE_HAVE_UBUNTU_PLATFORM_HARDWARE_API
4392+}
4393+
4394+std::chrono::nanoseconds from_ubuntu_hardware_alarm()
4395+{
4396+#if defined(COM_UBUNTU_LOCATION_SERVICE_HAVE_UBUNTU_PLATFORM_HARDWARE_API)
4397+ struct Scope
4398+ {
4399+ Scope() : alarm{u_hardware_alarm_create()}
4400+ {
4401+ }
4402+
4403+ ~Scope()
4404+ {
4405+ u_hardware_alarm_unref(alarm);
4406+ }
4407+
4408+ UHardwareAlarm alarm{nullptr};
4409+ };
4410+
4411+ static Scope scope;
4412+
4413+ ::timespec ts;
4414+ if (not scope.alarm)
4415+ throw std::runtime_error{"Failed to access UHardwareAlarm subsystem."};
4416+
4417+ if (U_STATUS_SUCCESS != u_hardware_alarm_get_elapsed_real_time(scope.alarm, &ts))
4418+ throw std::runtime_error{"Failed to query time since boot from UHardwareAlarm."};
4419+
4420+ return std::chrono::seconds{ts.tv_sec} + std::chrono::nanoseconds{ts.tv_nsec};
4421+#else
4422+ throw std::logic_error{"not implemented"};
4423+#endif // COM_UBUNTU_LOCATION_SERVICE_HAVE_UBUNTU_PLATFORM_HARDWARE_API
4424+}
4425+
4426+
4427+std::chrono::nanoseconds from_clock_boottime()
4428+{
4429+ ::timespec ts;
4430+ if (-1 == clock_gettime(CLOCK_BOOTTIME, &ts))
4431+ throw std::system_error(errno, std::system_category());
4432+
4433+ return std::chrono::seconds{ts.tv_sec} + std::chrono::nanoseconds{ts.tv_nsec};
4434+}
4435+
4436+std::chrono::nanoseconds boot_time()
4437+{
4438+ std::ifstream in{"/proc/stat"};
4439+ std::string line;
4440+
4441+ while (std::getline(in, line))
4442+ {
4443+ if (line.empty())
4444+ continue;
4445+
4446+ std::stringstream ss{line};
4447+ std::string name; ss >> name;
4448+
4449+ if (name != "btime")
4450+ continue;
4451+
4452+ std::uint64_t ts; ss >> ts;
4453+ return std::chrono::nanoseconds{std::chrono::seconds{ts}};
4454+ }
4455+
4456+ throw std::runtime_error{"Failed to determine system boot time."};
4457+}
4458+
4459+std::chrono::nanoseconds from_proc_stat()
4460+{
4461+ static const std::chrono::nanoseconds bt{boot_time()};
4462+ return std::chrono::system_clock::now().time_since_epoch() - bt;
4463+}
4464+}
4465+
4466+std::chrono::nanoseconds location::time_since_boot()
4467+{
4468+ if (have_ubuntu_hardware_alarm())
4469+ {
4470+ try
4471+ {
4472+ return from_ubuntu_hardware_alarm();
4473+ }
4474+ catch (const std::exception& e)
4475+ {
4476+ VLOG(1) << e.what();
4477+ }
4478+ }
4479+
4480+ try
4481+ {
4482+ return from_clock_boottime();
4483+ }
4484+ catch (const std::exception& e)
4485+ {
4486+ VLOG(1) << e.what();
4487+ }
4488+
4489+ return from_proc_stat();
4490+}
4491
4492=== added file 'src/location_service/com/ubuntu/location/time_since_boot.h'
4493--- src/location_service/com/ubuntu/location/time_since_boot.h 1970-01-01 00:00:00 +0000
4494+++ src/location_service/com/ubuntu/location/time_since_boot.h 2016-03-17 09:08:50 +0000
4495@@ -0,0 +1,35 @@
4496+/*
4497+ * Copyright © 2016 Canonical Ltd.
4498+ *
4499+ * This program is free software: you can redistribute it and/or modify it
4500+ * under the terms of the GNU Lesser General Public License version 3,
4501+ * as published by the Free Software Foundation.
4502+ *
4503+ * This program is distributed in the hope that it will be useful,
4504+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4505+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4506+ * GNU Lesser General Public License for more details.
4507+ *
4508+ * You should have received a copy of the GNU Lesser General Public License
4509+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4510+ *
4511+ * Authored by: Thomas Voß <thomas.voss@canonical.com>
4512+ */
4513+#ifndef LOCATION_SERVICE_UBUNTU_LOCATION_SERVICE_TIME_SINCE_BOOT_H_
4514+#define LOCATION_SERVICE_UBUNTU_LOCATION_SERVICE_TIME_SINCE_BOOT_H_
4515+
4516+#include <chrono>
4517+
4518+namespace com
4519+{
4520+namespace ubuntu
4521+{
4522+namespace location
4523+{
4524+/** @brief time_since_boot returns the nanoseconds that elapsed since boot. */
4525+std::chrono::nanoseconds time_since_boot();
4526+}
4527+}
4528+}
4529+
4530+#endif // LOCATION_SERVICE_UBUNTU_LOCATION_SERVICE_TIME_SINCE_BOOT_H_
4531
4532=== modified file 'tests/CMakeLists.txt'
4533--- tests/CMakeLists.txt 2016-03-17 09:08:50 +0000
4534+++ tests/CMakeLists.txt 2016-03-17 09:08:50 +0000
4535@@ -98,6 +98,7 @@
4536 if (LOCATION_SERVICE_ENABLE_GPS_PROVIDER)
4537 include_directories(${CMAKE_SOURCE_DIR}/src/location_service)
4538 LOCATION_SERVICE_ADD_TEST(gps_provider_test gps_provider_test.cpp)
4539+ LOCATION_SERVICE_ADD_TEST(sntp_client_test sntp_client_test.cpp)
4540 endif(LOCATION_SERVICE_ENABLE_GPS_PROVIDER)
4541
4542 if (LOCATION_SERVICE_ENABLE_GEOCLUE_PROVIDERS)
4543@@ -125,3 +126,4 @@
4544
4545 LOCATION_SERVICE_ADD_TEST(remote_provider_test remote_provider_test.cpp)
4546 LOCATION_SERVICE_ADD_TEST(espoo_provider_test espoo_provider_test.cpp)
4547+LOCATION_SERVICE_ADD_TEST(delayed_service_test delayed_service_test.cpp)
4548
4549=== added file 'tests/delayed_service_test.cpp'
4550--- tests/delayed_service_test.cpp 1970-01-01 00:00:00 +0000
4551+++ tests/delayed_service_test.cpp 2016-03-17 09:08:50 +0000
4552@@ -0,0 +1,193 @@
4553+/*
4554+ * Copyright © 2014 Canonical Ltd.
4555+ *
4556+ * This program is free software: you can redistribute it and/or modify it
4557+ * under the terms of the GNU Lesser General Public License version 3,
4558+ * as published by the Free Software Foundation.
4559+ *
4560+ * This program is distributed in the hope that it will be useful,
4561+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4562+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4563+ * GNU Lesser General Public License for more details.
4564+ *
4565+ * You should have received a copy of the GNU Lesser General Public License
4566+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4567+ *
4568+ * Authored by: Thomas Voß <thomas.voss@canonical.com>
4569+ * Scott Sweeny <scott.sweeny@canonical.com>
4570+ */
4571+
4572+#include <com/ubuntu/location/service/daemon.h>
4573+#include <com/ubuntu/location/service/provider_daemon.h>
4574+#include <com/ubuntu/location/providers/remote/provider.h>
4575+
4576+#include <com/ubuntu/location/service/stub.h>
4577+
4578+#include <com/ubuntu/location/position.h>
4579+#include <com/ubuntu/location/update.h>
4580+
4581+#include <core/dbus/fixture.h>
4582+
4583+#include <core/dbus/asio/executor.h>
4584+
4585+#include <core/posix/fork.h>
4586+#include <core/posix/signal.h>
4587+#include <core/posix/this_process.h>
4588+
4589+#include "did_finish_successfully.h"
4590+#include "mock_event_receiver.h"
4591+
4592+#include <gmock/gmock.h>
4593+
4594+namespace location = com::ubuntu::location;
4595+namespace remote = com::ubuntu::location::providers::remote;
4596+
4597+namespace
4598+{
4599+struct DelayedServiceTest : public core::dbus::testing::Fixture, public ::testing::WithParamInterface<int>
4600+{
4601+
4602+};
4603+}
4604+
4605+TEST_P(DelayedServiceTest, AClientReceivesUpdatesFromADelayedProvider)
4606+{
4607+ auto oopp = core::posix::fork([this]()
4608+ {
4609+ auto bus = session_bus();
4610+
4611+ // Pass the delay value to the provider
4612+ char delay[50];
4613+ sprintf(delay, "--dummy::DelayedProvider::DelayInMs=%d", GetParam());
4614+
4615+ const char* argv[] =
4616+ {
4617+ "--bus", "session", // 2
4618+ "--service-name", "com.ubuntu.location.providers.Dummy", // 4
4619+ "--service-path", "/com/ubuntu/location/providers/Dummy", // 6
4620+ "--provider", "dummy::DelayedProvider", // 8
4621+ delay // 9
4622+ };
4623+
4624+ auto dbus_connection_factory = [bus](core::dbus::WellKnownBus)
4625+ {
4626+ return bus;
4627+ };
4628+
4629+ return static_cast<core::posix::exit::Status>(
4630+ location::service::ProviderDaemon::main(
4631+ location::service::ProviderDaemon::Configuration::from_command_line_args(
4632+ 9, argv, dbus_connection_factory)));
4633+ }, core::posix::StandardStream::empty);
4634+
4635+ std::this_thread::sleep_for(std::chrono::milliseconds{250});
4636+
4637+ auto service = core::posix::fork([this]()
4638+ {
4639+ core::posix::this_process::env::set_or_throw(
4640+ "TRUST_STORE_PERMISSION_MANAGER_IS_RUNNING_UNDER_TESTING",
4641+ "1");
4642+
4643+ const char* argv[] =
4644+ {
4645+ "--bus", "session", // 2
4646+ "--provider", "remote::Provider", // 4
4647+ "--remote::Provider::bus=session_with_address_from_env", // 5
4648+ "--remote::Provider::name=com.ubuntu.location.providers.Dummy", // 6
4649+ "--remote::Provider::path=/com/ubuntu/location/providers/Dummy" // 7
4650+ };
4651+
4652+ // The daemon instance requires two bus instances.
4653+ auto dbus_connection_factory = [this](core::dbus::WellKnownBus)
4654+ {
4655+ return session_bus();
4656+ };
4657+
4658+ return static_cast<core::posix::exit::Status>(
4659+ location::service::Daemon::main(
4660+ location::service::Daemon::Configuration::from_command_line_args(
4661+ 7, argv, dbus_connection_factory)));
4662+ }, core::posix::StandardStream::empty);
4663+
4664+ // Wait to setup the client until the service is up
4665+ std::this_thread::sleep_for(std::chrono::milliseconds{250 + GetParam()});
4666+
4667+ auto client = core::posix::fork([this]()
4668+ {
4669+ using namespace ::testing;
4670+
4671+ auto trap = core::posix::trap_signals_for_all_subsequent_threads(
4672+ {
4673+ core::posix::Signal::sig_term,
4674+ core::posix::Signal::sig_int
4675+ });
4676+
4677+ trap->signal_raised().connect([trap](const core::posix::Signal&)
4678+ {
4679+ trap->stop();
4680+ });
4681+
4682+ auto bus = session_bus();
4683+ bus->install_executor(core::dbus::asio::make_executor(bus));
4684+
4685+ std::thread worker
4686+ {
4687+ [bus]() { bus->run(); }
4688+ };
4689+
4690+ MockEventReceiver receiver;
4691+ EXPECT_CALL(receiver, position_update_received(_)).Times(AtLeast(1));
4692+ EXPECT_CALL(receiver, heading_update_received(_)).Times(AtLeast(1));
4693+ EXPECT_CALL(receiver, velocity_update_received(_)).Times(AtLeast(1));
4694+
4695+ com::ubuntu::location::service::Stub service{bus};
4696+
4697+ auto session = service.create_session_for_criteria(location::Criteria{});
4698+
4699+ session->updates().position.changed().connect([&receiver](location::Update<location::Position> pos)
4700+ {
4701+ receiver.position_update_received(pos);
4702+ });
4703+
4704+ session->updates().heading.changed().connect([&receiver](location::Update<location::Heading> heading)
4705+ {
4706+ receiver.heading_update_received(heading);
4707+ });
4708+
4709+ session->updates().velocity.changed().connect([&receiver](location::Update<location::Velocity> velocity)
4710+ {
4711+ receiver.velocity_update_received(velocity);
4712+ });
4713+
4714+ session->updates().position_status = location::service::session::Interface::Updates::Status::enabled;
4715+ session->updates().velocity_status = location::service::session::Interface::Updates::Status::enabled;
4716+ session->updates().heading_status = location::service::session::Interface::Updates::Status::enabled;
4717+
4718+ trap->run();
4719+
4720+ bus->stop();
4721+
4722+ if (worker.joinable())
4723+ worker.join();
4724+
4725+ return ::testing::Test::HasFailure() ? core::posix::exit::Status::failure :
4726+ core::posix::exit::Status::success;
4727+ }, core::posix::StandardStream::empty);
4728+
4729+ std::this_thread::sleep_for(std::chrono::milliseconds{4000});
4730+
4731+ std::cout << "Shutting down client" << std::endl;
4732+ client.send_signal_or_throw(core::posix::Signal::sig_term);
4733+ EXPECT_TRUE(did_finish_successfully(client.wait_for(core::posix::wait::Flags::untraced)));
4734+
4735+ std::cout << "Shutting down service" << std::endl;
4736+ service.send_signal_or_throw(core::posix::Signal::sig_term);
4737+ EXPECT_TRUE(did_finish_successfully(service.wait_for(core::posix::wait::Flags::untraced)));
4738+
4739+ std::cout << "Shutting down oopp" << std::endl;
4740+ oopp.send_signal_or_throw(core::posix::Signal::sig_term);
4741+ EXPECT_TRUE(did_finish_successfully(oopp.wait_for(core::posix::wait::Flags::untraced)));
4742+}
4743+
4744+INSTANTIATE_TEST_CASE_P(ServiceDelays, DelayedServiceTest,
4745+ ::testing::Values(0, 250, 500, 1000, 2000, 5000, 10000));
4746
4747=== modified file 'tests/gps_provider_test.cpp'
4748--- tests/gps_provider_test.cpp 2016-03-17 09:08:50 +0000
4749+++ tests/gps_provider_test.cpp 2016-03-17 09:08:50 +0000
4750@@ -81,6 +81,11 @@
4751 MOCK_METHOD1(on_space_vehicles_updated, void(const std::set<location::SpaceVehicle>&));
4752 };
4753
4754+struct MockReferenceTimeSource : public gps::android::HardwareAbstractionLayer::ReferenceTimeSource
4755+{
4756+ MOCK_METHOD0(sample, gps::HardwareAbstractionLayer::ReferenceTimeSample());
4757+};
4758+
4759 struct MockSuplAssistant : public gps::HardwareAbstractionLayer::SuplAssistant
4760 {
4761 MockSuplAssistant()
4762@@ -93,6 +98,8 @@
4763
4764 MOCK_CONST_METHOD0(status, const core::Property<Status>&());
4765 MOCK_CONST_METHOD0(server_ip, const core::Property<IpV4Address>&());
4766+ MOCK_CONST_METHOD2(set_set_id, void(SetIdType, const std::string&));
4767+ MOCK_CONST_METHOD1(inject_radio_cell_information, void(const location::connectivity::RadioCell& radio_cell));
4768 MOCK_METHOD2(set_server, void(const std::string&, std::uint16_t));
4769 MOCK_METHOD1(notify_data_connection_open_via_apn, void(const std::string&));
4770 MOCK_METHOD0(notify_data_connection_closed, void());
4771@@ -133,9 +140,7 @@
4772 MOCK_METHOD1(set_assistance_mode, bool(gps::AssistanceMode));
4773 MOCK_METHOD1(set_position_mode, bool(gps::PositionMode));
4774 MOCK_METHOD1(inject_reference_position, bool(const location::Position&));
4775- MOCK_METHOD2(inject_reference_time,
4776- bool(const std::chrono::microseconds&,
4777- const std::chrono::microseconds&));
4778+ MOCK_METHOD1(inject_reference_time, bool(const location::providers::gps::HardwareAbstractionLayer::ReferenceTimeSample&));
4779
4780 MockSuplAssistant supl_assistant_;
4781 core::Signal<location::Position> position_updates_;
4782@@ -322,24 +327,54 @@
4783 provider.on_reference_location_updated(pos);
4784 }
4785
4786+TEST(GpsProvider, time_requests_query_reference_time_source)
4787+{
4788+ using namespace ::testing;
4789+
4790+ NiceMock<MockHardwareGps> hardwareGps;
4791+
4792+ auto mock_reference_time_source = std::make_shared<MockReferenceTimeSource>();
4793+ EXPECT_CALL(*mock_reference_time_source, sample())
4794+ .Times(1)
4795+ .WillRepeatedly(Return(gps::HardwareAbstractionLayer::ReferenceTimeSample{}));
4796+
4797+ gps::android::HardwareAbstractionLayer::Configuration configuration;
4798+ configuration.reference_time_source = mock_reference_time_source;
4799+ gps::android::HardwareAbstractionLayer hal(configuration);
4800+
4801+ gps::android::HardwareAbstractionLayer::on_request_utc_time(&hal);
4802+}
4803+
4804 TEST(GpsProvider, time_requests_inject_current_time_into_the_hal)
4805 {
4806 using namespace ::testing;
4807
4808+ auto sample_reference_time = []()
4809+ {
4810+ auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(location::Clock::now().time_since_epoch());
4811+ std::cout << duration.count() << std::endl;
4812+ return gps::HardwareAbstractionLayer::ReferenceTimeSample{duration, duration, std::chrono::milliseconds{0}};
4813+ };
4814+
4815 NiceMock<MockHardwareGps> hardwareGps;
4816
4817+ auto mock_reference_time_source = std::make_shared<MockReferenceTimeSource>();
4818+ EXPECT_CALL(*mock_reference_time_source, sample())
4819+ .Times(1)
4820+ .WillRepeatedly(Invoke(sample_reference_time));
4821+
4822 gps::android::HardwareAbstractionLayer::Configuration configuration;
4823+ configuration.reference_time_source = mock_reference_time_source;
4824 gps::android::HardwareAbstractionLayer hal(configuration);
4825- std::shared_ptr<gps::HardwareAbstractionLayer> hal_ptr(&hal, [](gps::HardwareAbstractionLayer*){});
4826+ hal.capabilities() = U_HARDWARE_GPS_CAPABILITY_ON_DEMAND_TIME;
4827
4828- gps::Provider provider(hal_ptr);
4829 int64_t time = 0;
4830 EXPECT_CALL(hardwareGps, inject_time(_, _, 0)).Times(1).WillOnce(SaveArg<0>(&time));
4831
4832 auto t0 = std::chrono::duration_cast<std::chrono::milliseconds>(location::Clock::now().time_since_epoch());
4833-
4834+ //std::this_thread::sleep_for(std::chrono::milliseconds{10});
4835 gps::android::HardwareAbstractionLayer::on_request_utc_time(&hal);
4836-
4837+ //std::this_thread::sleep_for(std::chrono::milliseconds{10});
4838 auto t1 = std::chrono::duration_cast<std::chrono::milliseconds>(location::Clock::now().time_since_epoch());
4839 EXPECT_THAT(time, AllOf(Ge(t0.count()), Le(t1.count())));
4840 }
4841@@ -929,4 +964,3 @@
4842 static_cast<std::uint64_t>(variance(stats)))).count()
4843 << std::endl;
4844 }
4845-
4846
4847=== added file 'tests/mock_event_receiver.h'
4848--- tests/mock_event_receiver.h 1970-01-01 00:00:00 +0000
4849+++ tests/mock_event_receiver.h 2016-03-17 09:08:50 +0000
4850@@ -0,0 +1,35 @@
4851+/*
4852+ * Copyright © 2015 Canonical Ltd.
4853+ *
4854+ * This program is free software: you can redistribute it and/or modify it
4855+ * under the terms of the GNU Lesser General Public License version 3,
4856+ * as published by the Free Software Foundation.
4857+ *
4858+ * This program is distributed in the hope that it will be useful,
4859+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4860+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4861+ * GNU Lesser General Public License for more details.
4862+ *
4863+ * You should have received a copy of the GNU Lesser General Public License
4864+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4865+ *
4866+ * Authored by: Thomas Voß <thomas.voss@canonical.com>
4867+ * Scott Sweeny <scott.sweeny@canonical.com>
4868+ */
4869+#ifndef MOCK_EVENT_RECEIVER_H_
4870+#define MOCK_EVENT_RECEIVER_H_
4871+
4872+#include <com/ubuntu/location/update.h>
4873+
4874+#include <gmock/gmock.h>
4875+
4876+namespace location = com::ubuntu::location;
4877+
4878+struct MockEventReceiver
4879+{
4880+ MOCK_METHOD1(position_update_received, void(const location::Update<location::Position>&));
4881+ MOCK_METHOD1(heading_update_received, void(const location::Update<location::Heading>&));
4882+ MOCK_METHOD1(velocity_update_received, void(const location::Update<location::Velocity>&));
4883+};
4884+
4885+#endif // MOCK_EVENT_RECEIVER_H_
4886
4887=== modified file 'tests/remote_providerd_test.cpp'
4888--- tests/remote_providerd_test.cpp 2014-10-27 21:58:16 +0000
4889+++ tests/remote_providerd_test.cpp 2016-03-17 09:08:50 +0000
4890@@ -31,6 +31,7 @@
4891 #include <core/posix/fork.h>
4892
4893 #include "did_finish_successfully.h"
4894+#include "mock_event_receiver.h"
4895
4896 #include <gmock/gmock.h>
4897
4898@@ -38,13 +39,6 @@
4899
4900 namespace
4901 {
4902-struct MockEventReceiver
4903-{
4904- MOCK_METHOD1(position_update_received, void(const location::Update<location::Position>&));
4905- MOCK_METHOD1(heading_update_received, void(const location::Update<location::Heading>&));
4906- MOCK_METHOD1(velocity_update_received, void(const location::Update<location::Velocity>&));
4907-};
4908-
4909 struct RemoteProviderdTest : public core::dbus::testing::Fixture
4910 {
4911
4912
4913=== added file 'tests/sntp_client_test.cpp'
4914--- tests/sntp_client_test.cpp 1970-01-01 00:00:00 +0000
4915+++ tests/sntp_client_test.cpp 2016-03-17 09:08:50 +0000
4916@@ -0,0 +1,104 @@
4917+/*
4918+ * Copyright © 2016 Canonical Ltd.
4919+ *
4920+ * This program is free software: you can redistribute it and/or modify it
4921+ * under the terms of the GNU Lesser General Public License version 3,
4922+ * as published by the Free Software Foundation.
4923+ *
4924+ * This program is distributed in the hope that it will be useful,
4925+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4926+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4927+ * GNU Lesser General Public License for more details.
4928+ *
4929+ * You should have received a copy of the GNU Lesser General Public License
4930+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4931+ *
4932+ * Authored by: Thomas Voß <thomas.voss@canonical.com>
4933+ */
4934+
4935+#include <com/ubuntu/location/providers/gps/sntp_client.h>
4936+#include <com/ubuntu/location/service/runtime.h>
4937+
4938+#include <future>
4939+
4940+#include <core/posix/this_process.h>
4941+
4942+#include <gtest/gtest.h>
4943+
4944+namespace env = core::posix::this_process::env;
4945+namespace location = com::ubuntu::location;
4946+namespace sntp = location::providers::gps::sntp;
4947+
4948+namespace
4949+{
4950+struct SntpClient : public ::testing::Test
4951+{
4952+ void SetUp()
4953+ {
4954+ rt->start();
4955+ }
4956+
4957+ void TearDown()
4958+ {
4959+ rt->stop();
4960+ }
4961+
4962+ std::shared_ptr<location::service::Runtime> rt = location::service::Runtime::create();
4963+ std::string host = env::get("UBUNTU_LOCATION_SERVICE_NTP_HOST_FOR_TESTING", "ntp.ubuntu.com");
4964+};
4965+}
4966+
4967+TEST_F(SntpClient, packet_has_correct_size)
4968+{
4969+ static_assert(sizeof(sntp::Packet) == 48, "");
4970+}
4971+
4972+#pragma GCC diagnostic push
4973+#pragma GCC diagnostic ignored "-Wmultichar"
4974+TEST(EnumConstant, yields_same_value_as_multibyte_constant)
4975+{
4976+ static_assert(sntp::detail::enum_constant<'L','O','C','L'>() == 'LOCL', "");
4977+}
4978+#pragma GCC diagnostic pop
4979+
4980+TEST_F(SntpClient, succeeds_in_querying_time_from_server)
4981+{
4982+ location::providers::gps::sntp::Client sntp_client;
4983+ try
4984+ {
4985+ sntp_client.request_time(host, std::chrono::milliseconds{5000}, rt->service());
4986+ }
4987+ catch(...)
4988+ {
4989+ }
4990+}
4991+
4992+TEST_F(SntpClient, throws_for_timed_out_operation)
4993+{
4994+ location::providers::gps::sntp::Client sntp_client;
4995+ EXPECT_ANY_THROW(sntp_client.request_time(host, std::chrono::milliseconds{1}, rt->service()));
4996+}
4997+
4998+TEST_F(SntpClient, returns_correct_data_in_packet)
4999+{
5000+ for (unsigned int i = 0; i < 10; i++)
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches