Merge lp:~thomas-voss/location-service/add-manual-example-for-network-based-positioning into lp:location-service/trunk

Proposed by Thomas Voß
Status: Needs review
Proposed branch: lp:~thomas-voss/location-service/add-manual-example-for-network-based-positioning
Merge into: lp:location-service/trunk
Diff against target: 371 lines (+229/-31)
7 files modified
debian/ubuntu-location-service-examples.install (+1/-0)
examples/CMakeLists.txt (+2/-1)
examples/connectivity/CMakeLists.txt (+7/-0)
examples/connectivity/connectivity.cpp (+188/-0)
src/location_service/com/ubuntu/location/service/ichnaea_reporter.cpp (+19/-19)
src/location_service/com/ubuntu/location/service/ichnaea_reporter.h (+7/-6)
tests/ichnaea_reporter_test.cpp (+5/-5)
To merge this branch: bzr merge lp:~thomas-voss/location-service/add-manual-example-for-network-based-positioning
Reviewer Review Type Date Requested Status
PS Jenkins bot continuous-integration Pending
Ubuntu Phablet Team Pending
Review via email: mp+295709@code.launchpad.net

Commit message

Add a standalone example exercising the connectivity subsystem.

Description of the change

Add a standalone example exercising the connectivity subsystem.

To post a comment you must log in.
251. By Thomas Voß

Account for compiler differences.

252. By Thomas Voß

Adjust debian setup to install example.

253. By Thomas Voß

Print out full request body on exit.

254. By Thomas Voß

Adjust to changes in ichnaea json schema.

Unmerged revisions

254. By Thomas Voß

Adjust to changes in ichnaea json schema.

253. By Thomas Voß

Print out full request body on exit.

252. By Thomas Voß

Adjust debian setup to install example.

251. By Thomas Voß

Account for compiler differences.

250. By Thomas Voß

Add a standalone example exercising the connectivity subsystem.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'debian/ubuntu-location-service-examples.install'
2--- debian/ubuntu-location-service-examples.install 2014-05-20 09:45:02 +0000
3+++ debian/ubuntu-location-service-examples.install 2016-05-25 21:01:56 +0000
4@@ -1,3 +1,4 @@
5+usr/lib/*/ubuntu-location-service/examples/connectivity
6 usr/lib/*/ubuntu-location-service/examples/client
7 usr/lib/*/ubuntu-location-service/examples/service
8 usr/share/ubuntu-location-service
9
10=== modified file 'examples/CMakeLists.txt'
11--- examples/CMakeLists.txt 2014-05-20 09:45:02 +0000
12+++ examples/CMakeLists.txt 2016-05-25 21:01:56 +0000
13@@ -1,5 +1,6 @@
14 add_subdirectory(service)
15+add_subdirectory(connectivity)
16
17 install(
18 DIRECTORY standalone
19- DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/${CMAKE_PROJECT_NAME}/examples)
20\ No newline at end of file
21+ DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/${CMAKE_PROJECT_NAME}/examples)
22
23=== added directory 'examples/connectivity'
24=== added file 'examples/connectivity/CMakeLists.txt'
25--- examples/connectivity/CMakeLists.txt 1970-01-01 00:00:00 +0000
26+++ examples/connectivity/CMakeLists.txt 2016-05-25 21:01:56 +0000
27@@ -0,0 +1,7 @@
28+add_executable(connectivity connectivity.cpp)
29+target_link_libraries(connectivity ubuntu-location-service ubuntu-location-service-connectivity)
30+
31+install(
32+ TARGETS connectivity
33+ DESTINATION ${CMAKE_INSTALL_LIBEXECDIR}/examples/
34+)
35
36=== added file 'examples/connectivity/connectivity.cpp'
37--- examples/connectivity/connectivity.cpp 1970-01-01 00:00:00 +0000
38+++ examples/connectivity/connectivity.cpp 2016-05-25 21:01:56 +0000
39@@ -0,0 +1,188 @@
40+/*
41+ * Copyright © 2016 Canonical Ltd.
42+ *
43+ * This program is free software: you can redistribute it and/or modify it
44+ * under the terms of the GNU Lesser General Public License version 3,
45+ * as published by the Free Software Foundation.
46+ *
47+ * This program is distributed in the hope that it will be useful,
48+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
49+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
50+ * GNU Lesser General Public License for more details.
51+ *
52+ * You should have received a copy of the GNU Lesser General Public License
53+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
54+ *
55+ * Authored by: Thomas Voß <thomas.voss@canonical.com>
56+ */
57+
58+#include <com/ubuntu/location/connectivity/manager.h>
59+#include <com/ubuntu/location/service/ichnaea_reporter.h>
60+
61+#include <core/net/http/client.h>
62+#include <core/posix/signal.h>
63+
64+#include <iostream>
65+
66+namespace connectivity = com::ubuntu::location::connectivity;
67+namespace ichnaea = com::ubuntu::location::service::ichnaea;
68+namespace http = core::net::http;
69+
70+namespace com { namespace ubuntu { namespace location { namespace service { namespace ichnaea
71+{
72+class Client
73+{
74+public:
75+ Client()
76+ : client{http::make_client()},
77+ worker{[this]() { client->run(); }},
78+ request_config(http::Request::Configuration::from_uri_as_string("https://location.services.mozilla.com/v1/geolocate?key=test"))
79+ {
80+ request_config.ssl.verify_host = request_config.ssl.verify_peer = false;
81+ }
82+
83+ ~Client()
84+ {
85+ client->stop();
86+ if (worker.joinable()) worker.join();
87+ }
88+
89+ void geolocate(const std::vector<connectivity::WirelessNetwork::Ptr>& wifis, const std::vector<connectivity::RadioCell::Ptr>& cells)
90+ {
91+ json::Object object = json::Object::create_object();
92+
93+ // Explicitly disable fallback methods to make sure that
94+ // we are getting clear errors for the manual example and help with
95+ // tracking down bugs.
96+ json::Object fallbacks = json::Object::create_object();
97+ fallbacks.put_boolean("lacf", false);
98+ fallbacks.put_boolean("ipf", false);
99+
100+ json::Object cell_towers = json::Object::create_array();
101+ json::Object wifi_access_points = json::Object::create_array();
102+
103+ ichnaea::Reporter::convert_cells_to_json(cells, cell_towers);
104+ ichnaea::Reporter::convert_wifis_to_json(wifis, wifi_access_points);
105+
106+ object.put_array("cellTowers", cell_towers);
107+ object.put_array("wifiAccessPoints", wifi_access_points);
108+ object.put_object("fallbacks", fallbacks);
109+
110+ auto request = client->post(request_config, object.to_plain_string(), http::ContentType::json);
111+ auto response = request->execute([](const http::Request::Progress& progress)
112+ {
113+ return http::Request::Progress::Next::continue_operation;
114+ });
115+
116+ auto result = json::Object::parse_from_string(response.body);
117+ auto location = result.get("location");
118+ auto accuracy = result.get("accuracy");
119+
120+ std::cout << "Query for position estimate succeeded: " << std::endl
121+ << " lat: " << location.get("lat").to_double() << std::endl
122+ << " lng: " << location.get("lng").to_double() << std::endl
123+ << " accuracy: " << accuracy.to_double() << std::endl;
124+ }
125+
126+private:
127+ std::shared_ptr<http::Client> client;
128+ std::thread worker;
129+ http::Request::Configuration request_config;
130+};
131+}}}}}
132+
133+// Sampler periodically requests scans for wireless networks.
134+class Sampler
135+{
136+public:
137+ // Sampler initializes a new instance with the given manager instance.
138+ Sampler(const std::shared_ptr<connectivity::Manager>& manager)
139+ : manager{manager},
140+ running{true},
141+ worker{[this]()
142+ {
143+ while (running)
144+ {
145+ Sampler::manager->request_scan_for_wireless_networks();
146+ std::this_thread::sleep_for(std::chrono::seconds{15});
147+ }
148+ }}
149+ {
150+ }
151+
152+ ~Sampler()
153+ {
154+ running = false;
155+ if (worker.joinable()) worker.join();
156+ }
157+
158+private:
159+ std::shared_ptr<connectivity::Manager> manager;
160+ bool running;
161+ std::thread worker;
162+};
163+
164+int main(int, char)
165+{
166+ auto trap = core::posix::trap_signals_for_all_subsequent_threads({core::posix::Signal::sig_term});
167+ trap->signal_raised().connect([trap](core::posix::Signal) { trap->stop(); });
168+
169+ auto client = std::make_shared<ichnaea::Client>();
170+ auto manager = connectivity::platform_default_manager();
171+ auto sampler = std::make_shared<Sampler>(manager);
172+
173+ manager->state().changed().connect([](connectivity::State state)
174+ {
175+ std::cout << "State changed: " << state << std::endl;
176+ });
177+
178+ manager->is_wifi_enabled().changed().connect([](bool b)
179+ {
180+ std::cout << "is_wifi_enabled changed: " << std::boolalpha << b << std::endl;
181+ });
182+
183+ manager->is_wifi_hardware_enabled().changed().connect([](bool b)
184+ {
185+ std::cout << "is_wifi_hardware_enabled changed: " << std::boolalpha << b << std::endl;
186+ });
187+
188+ manager->is_wwan_enabled().changed().connect([](bool b)
189+ {
190+ std::cout << "is_wwan_enabled changed: " << std::boolalpha << b << std::endl;
191+ });
192+
193+ manager->is_wwan_hardware_enabled().changed().connect([](bool b)
194+ {
195+ std::cout << "is_wwan_hardware_enabled changed: " << std::boolalpha << b << std::endl;
196+ });
197+
198+ manager->active_connection_characteristics().changed().connect([](connectivity::Characteristics characteristics)
199+ {
200+ std::cout << "Active connection characteristics changed: " << characteristics << std::endl;
201+ });
202+
203+ std::weak_ptr<connectivity::Manager> wp{manager};
204+ manager->wireless_network_scan_finished().connect([wp, client]()
205+ {
206+ std::cout << "Wireless network scan finished" << std::endl;
207+ if (auto manager = wp.lock())
208+ {
209+ std::vector<connectivity::RadioCell::Ptr> cells;
210+ manager->enumerate_connected_radio_cells([&cells](const connectivity::RadioCell::Ptr& cell)
211+ {
212+ cells.push_back(cell);
213+ });
214+
215+ std::vector<connectivity::WirelessNetwork::Ptr> wifis;
216+ manager->enumerate_visible_wireless_networks([&wifis](const connectivity::WirelessNetwork::Ptr& wifi)
217+ {
218+ wifis.push_back(wifi);
219+ });
220+
221+ client->geolocate(wifis, cells);
222+ }
223+ });
224+
225+ trap->run();
226+ return EXIT_SUCCESS;
227+}
228
229=== modified file 'src/location_service/com/ubuntu/location/service/ichnaea_reporter.cpp'
230--- src/location_service/com/ubuntu/location/service/ichnaea_reporter.cpp 2016-05-24 09:44:01 +0000
231+++ src/location_service/com/ubuntu/location/service/ichnaea_reporter.cpp 2016-05-25 21:01:56 +0000
232@@ -317,7 +317,7 @@
233 continue;
234
235 json::Object w = json::Object::create_object();
236- w.put_string(Json::Wifi::key, wifi->bssid().get());
237+ w.put_string(Json::Wifi::mac_address, wifi->bssid().get());
238
239 if (wifi->frequency().get().is_valid())
240 w.put_int32(Json::Wifi::frequency, static_cast<int>(wifi->frequency().get()));
241@@ -342,60 +342,60 @@
242 {
243 case connectivity::RadioCell::Type::gsm:
244 {
245- c.put_string(Json::Cell::radio, "gsm");
246+ c.put_string(Json::Cell::radio_type, "gsm");
247
248 const auto& details = cell->gsm();
249
250 if (details.mobile_country_code.is_valid())
251- c.put_int32(Json::Cell::mcc, details.mobile_country_code.get());
252+ c.put_int32(Json::Cell::mobile_country_code, details.mobile_country_code.get());
253 if (details.mobile_network_code.is_valid())
254- c.put_int32(Json::Cell::mnc, details.mobile_network_code.get());
255+ c.put_int32(Json::Cell::mobile_network_code, details.mobile_network_code.get());
256 if (details.location_area_code.is_valid())
257- c.put_int32(Json::Cell::lac, details.location_area_code.get());
258+ c.put_int32(Json::Cell::location_area_code, details.location_area_code.get());
259 if (details.id.is_valid())
260- c.put_int32(Json::Cell::cid, details.id.get());
261+ c.put_int32(Json::Cell::cell_id, details.id.get());
262 if (details.strength.is_valid())
263- c.put_int32(Json::Cell::asu, details.strength.get());
264+ c.put_int32(Json::Cell::signal_strength, details.strength.get());
265
266 break;
267 }
268 case connectivity::RadioCell::Type::umts:
269 {
270- c.put_string(Json::Cell::radio, "umts");
271+ c.put_string(Json::Cell::radio_type, "umts");
272
273 const auto& details = cell->umts();
274
275 if (details.mobile_country_code.is_valid())
276- c.put_int32(Json::Cell::mcc, details.mobile_country_code.get());
277+ c.put_int32(Json::Cell::mobile_country_code, details.mobile_country_code.get());
278 if (details.mobile_network_code.is_valid())
279- c.put_int32(Json::Cell::mnc, details.mobile_network_code.get());
280+ c.put_int32(Json::Cell::mobile_network_code, details.mobile_network_code.get());
281 if (details.location_area_code.is_valid())
282- c.put_int32(Json::Cell::lac, details.location_area_code.get());
283+ c.put_int32(Json::Cell::location_area_code, details.location_area_code.get());
284 if (details.id.is_valid())
285- c.put_int32(Json::Cell::cid, details.id.get());
286+ c.put_int32(Json::Cell::cell_id, details.id.get());
287 if (details.strength.is_valid())
288- c.put_int32(Json::Cell::asu, details.strength.get());
289+ c.put_int32(Json::Cell::signal_strength, details.strength.get());
290
291 break;
292 }
293 case connectivity::RadioCell::Type::lte:
294 {
295- c.put_string(Json::Cell::radio, "lte");
296+ c.put_string(Json::Cell::radio_type, "lte");
297
298 const auto& details = cell->lte();
299
300 if (details.mobile_country_code.is_valid())
301- c.put_int32(Json::Cell::mcc, details.mobile_country_code.get());
302+ c.put_int32(Json::Cell::mobile_country_code, details.mobile_country_code.get());
303 if (details.mobile_network_code.is_valid())
304- c.put_int32(Json::Cell::mnc, details.mobile_network_code.get());
305+ c.put_int32(Json::Cell::mobile_network_code, details.mobile_network_code.get());
306 if (details.tracking_area_code.is_valid())
307- c.put_int32(Json::Cell::lac, details.tracking_area_code.get());
308+ c.put_int32(Json::Cell::location_area_code, details.tracking_area_code.get());
309 if (details.id.is_valid())
310- c.put_int32(Json::Cell::cid, details.id.get());
311+ c.put_int32(Json::Cell::cell_id, details.id.get());
312 if (details.physical_id.is_valid())
313 c.put_int32(Json::Cell::psc, details.physical_id.get());
314 if (details.strength.is_valid())
315- c.put_int32(Json::Cell::asu, details.strength.get());
316+ c.put_int32(Json::Cell::signal_strength, details.strength.get());
317 break;
318 }
319 default:
320
321=== modified file 'src/location_service/com/ubuntu/location/service/ichnaea_reporter.h'
322--- src/location_service/com/ubuntu/location/service/ichnaea_reporter.h 2014-07-11 12:56:40 +0000
323+++ src/location_service/com/ubuntu/location/service/ichnaea_reporter.h 2016-05-25 21:01:56 +0000
324@@ -168,19 +168,20 @@
325
326 struct Cell
327 {
328- static constexpr const char* radio{"radio"};
329- static constexpr const char* mcc{"mcc"};
330- static constexpr const char* mnc{"mnc"};
331- static constexpr const char* lac{"lac"};
332- static constexpr const char* cid{"cid"};
333+ static constexpr const char* radio_type{"radio_type"};
334+ static constexpr const char* mobile_country_code{"mobileCountryCode"};
335+ static constexpr const char* mobile_network_code{"mobileNetworkCode"};
336+ static constexpr const char* location_area_code{"locationAreaCode"};
337+ static constexpr const char* cell_id{"cellId"};
338 static constexpr const char* psc{"psc"};
339- static constexpr const char* asu{"asu"};
340+ static constexpr const char* signal_strength{"signalStrength"};
341 };
342
343 struct Wifi
344 {
345 static constexpr const char* channel{"channel"};
346 static constexpr const char* frequency{"frequency"};
347+ static constexpr const char* mac_address{"macAddress"};
348 static constexpr const char* key{"key"};
349 static constexpr const char* signal{"signal"};
350 };
351
352=== modified file 'tests/ichnaea_reporter_test.cpp'
353--- tests/ichnaea_reporter_test.cpp 2016-05-24 09:44:01 +0000
354+++ tests/ichnaea_reporter_test.cpp 2016-05-25 21:01:56 +0000
355@@ -200,11 +200,11 @@
356 EXPECT_EQ(1u, cells.array_size());
357
358 auto cell = cells.get_object_for_index(0);
359- EXPECT_EQ(ref_cell->gsm().mobile_country_code.get(), cell.get(Reporter::Json::Cell::mcc).to_int32());
360- EXPECT_EQ(ref_cell->gsm().mobile_network_code.get(), cell.get(Reporter::Json::Cell::mnc).to_int32());
361- EXPECT_EQ(ref_cell->gsm().location_area_code.get(), cell.get(Reporter::Json::Cell::lac).to_int32());
362- EXPECT_EQ(ref_cell->gsm().id.get(), cell.get(Reporter::Json::Cell::cid).to_int32());
363- EXPECT_EQ(ref_cell->gsm().strength.get(), cell.get(Reporter::Json::Cell::asu).to_int32());
364+ EXPECT_EQ(ref_cell->gsm().mobile_country_code.get(), cell.get(Reporter::Json::Cell::mobile_country_code).to_int32());
365+ EXPECT_EQ(ref_cell->gsm().mobile_network_code.get(), cell.get(Reporter::Json::Cell::mobile_network_code).to_int32());
366+ EXPECT_EQ(ref_cell->gsm().location_area_code.get(), cell.get(Reporter::Json::Cell::location_area_code).to_int32());
367+ EXPECT_EQ(ref_cell->gsm().id.get(), cell.get(Reporter::Json::Cell::cell_id).to_int32());
368+ EXPECT_EQ(ref_cell->gsm().strength.get(), cell.get(Reporter::Json::Cell::signal_strength).to_int32());
369
370 mg_send_status(conn, static_cast<int>(submit::success));
371 return MG_TRUE;

Subscribers

People subscribed via source and target branches