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

Proposed by Thomas Voß
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
Ubuntu Phablet Team 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.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
230. By Thomas Voß

Log individual imsi/msisdn callback invocations.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
231. By Thomas Voß

Extend runtime test cases to cover agps use cases.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
232. By Thomas Voß

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

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)

Unmerged revisions

232. By Thomas Voß

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

231. By Thomas Voß

Extend runtime test cases to cover agps use cases.

230. By Thomas Voß

Log individual imsi/msisdn callback invocations.

229. By Thomas Voß

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