~thomas-voss/location-service/fix-1347887

« back to all changes in this revision

Viewing changes to examples/standalone/connectivity/connectivity.cpp

This MP consolidates multiple related changes together, with the goal of:

(1.) Make the service instance accessible via a cli. Useful for testing scenarios.
(2.) To cut down time-to-first-fix (ttff) by:
  (2.1) Leveraging SUPL and other supplementary data downloaded over ordinary data connections.
  (2.2) Enabling network-based positioning providers to acquire fast position estimates.

In more detail:

* Added tests for daemon and cli.
* Unified daemon and cli header and implementation files.
* Add a command-line interface to the service.
* Split up provider selection policy to rely on an interface ProviderEnumerator to ease in testing.
* Trimmed down on types.
* Removed connectivity API draft to prepare for simpler approach.
* Refactored includes.
* Added a configuration option to handle cell and wifi ID reporting.
* Add a mock for a connectivity API exposed to providers and reporters.
* Add units for connectivity api.
* Refactor cell class into namespace radio. Fixes: 1226204, 1248973, 1281817

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include <com/ubuntu/location/connectivity/manager.h>
 
2
 
 
3
#include <core/posix/signal.h>
 
4
 
 
5
#include <cstdlib>
 
6
 
 
7
#include <thread>
 
8
 
 
9
namespace location = com::ubuntu::location;
 
10
 
 
11
namespace
 
12
{
 
13
// Just convenience to safe some typing.
 
14
typedef std::vector<location::connectivity::RadioCell> RadioCells;
 
15
typedef std::vector<location::connectivity::WirelessNetwork::Ptr> WirelessNetworks;
 
16
}
 
17
 
 
18
// This example illustrates the usage of the location-service-specific connectivity API.
 
19
// The setup for obtaining measurements of wifis and radio cells is as follows:
 
20
//
 
21
//   (1.) Obtain an instance of location::connectivity::Manager.
 
22
//   (2.) Connect to the changed signals of the wifi and cell properties and react according to your component's requirements.
 
23
//   (3.) Bootstrap your own setup by explicitly getting all visible wifis and connected cells.
 
24
int main(int argc, char** argv)
 
25
{
 
26
    // We catch sig-term to exit cleanly.
 
27
    auto trap = core::posix::trap_signals_for_all_subsequent_threads({core::posix::Signal::sig_term});
 
28
    trap->signal_raised().connect([trap](core::posix::Signal)
 
29
                                  {
 
30
                                      trap->stop();
 
31
                                  });
 
32
 
 
33
    // Trying to acquire a default implementation.
 
34
    auto cm = location::connectivity::platform_default_manager();
 
35
 
 
36
    if (not cm)
 
37
    {
 
38
        std::cerr << "Could not get hold of a connectivity::Manager implementation, aborting..." << std::endl;
 
39
        std::exit(1);
 
40
    }
 
41
 
 
42
    // Subscribe to wifi added/removed signals.
 
43
    cm->wireless_network_added().connect([](const location::connectivity::WirelessNetwork::Ptr& wifi)
 
44
    {
 
45
        std::cout << "Visible wireless network was added: " << *wifi << std::endl;
 
46
 
 
47
        // We don't want to keep the object alive
 
48
        std::weak_ptr<location::connectivity::WirelessNetwork> wp
 
49
        {
 
50
            wifi
 
51
        };
 
52
 
 
53
 
 
54
 
 
55
        // Subscribe to signal strength and last_seen updates. Please note that this is not considering
 
56
        // the case of subscribing to already known wifis. We leave this up
 
57
        // to consumers of the api.
 
58
        wifi->last_seen().changed().connect([wp](const std::chrono::system_clock::time_point& tp)
 
59
        {
 
60
            auto sp = wp.lock();
 
61
            if (sp)
 
62
                std::cout << "Signal strength changed for wifi " << sp->ssid().get() << ": " << tp.time_since_epoch().count() << std::endl;
 
63
        });
 
64
 
 
65
        wifi->signal_strength().changed().connect([wp](const location::connectivity::WirelessNetwork::SignalStrength& s)
 
66
        {
 
67
            auto sp = wp.lock();
 
68
            if (sp)
 
69
                std::cout << "Signal strength changed for wifi " << sp->ssid().get() << ": " << s << std::endl;
 
70
        });
 
71
    });
 
72
 
 
73
    cm->wireless_network_removed().connect([](const location::connectivity::WirelessNetwork::Ptr& wifi)
 
74
    {
 
75
        std::cout << "Visible wireless network was removed: " << wifi->ssid().get() << std::endl;
 
76
    });
 
77
 
 
78
    // Iterate over all radio cells that the device is connected with.
 
79
    cm->enumerate_connected_radio_cells([](const location::connectivity::RadioCell::Ptr& cell)
 
80
    {
 
81
        std::cout << *cell << std::endl;
 
82
 
 
83
        std::weak_ptr<location::connectivity::RadioCell> wp{cell};
 
84
 
 
85
        // Subscribe to changes on the cell
 
86
        cell->changed().connect([wp]()
 
87
        {
 
88
            auto sp = wp.lock();
 
89
 
 
90
            if (sp)
 
91
                std::cout << "Something changed on a radio cell: " << *sp << std::endl;
 
92
        });
 
93
    });
 
94
 
 
95
    cm->connected_cell_added().connect([](const location::connectivity::RadioCell::Ptr& cell)
 
96
    {
 
97
        std::cout << *cell << std::endl;
 
98
 
 
99
        // Subscribe to changes on the cell
 
100
        cell->changed().connect([]()
 
101
        {
 
102
            std::cout << "Something changed on a radio cell." << std::endl;
 
103
        });
 
104
    });
 
105
 
 
106
    cm->connected_cell_removed().connect([](const location::connectivity::RadioCell::Ptr& cell)
 
107
    {
 
108
        std::cout << *cell << std::endl;
 
109
    });
 
110
 
 
111
    // Iterate over all networks that are visible right now.
 
112
    cm->enumerate_visible_wireless_networks([](const location::connectivity::WirelessNetwork::Ptr& wifi)
 
113
    {
 
114
        std::cout << *wifi << std::endl;
 
115
 
 
116
        // We don't want to keep the object alive
 
117
        std::weak_ptr<location::connectivity::WirelessNetwork> wp
 
118
        {
 
119
            wifi
 
120
        };
 
121
 
 
122
        // Subscribe to last-seen updates.
 
123
        wifi->last_seen().changed().connect([wp](const std::chrono::system_clock::time_point& tp)
 
124
        {
 
125
            auto sp = wp.lock();
 
126
            if (sp)
 
127
                std::cout << "Last seen changed for wifi " << *sp << std::endl;
 
128
        });
 
129
 
 
130
        // Subscribe to signal strength updates. Please note that this is not considering
 
131
        // the case of subscribing to already known wifis. We leave this up
 
132
        // to consumers of the api.
 
133
        wifi->signal_strength().changed().connect([wp](const location::connectivity::WirelessNetwork::SignalStrength& s)
 
134
        {
 
135
            auto sp = wp.lock();
 
136
            if (sp)
 
137
                std::cout << "Signal strength changed for wifi: " << *sp << std::endl;
 
138
        });
 
139
    });
 
140
    
 
141
    // Subscribe to end-of-scan signals
 
142
    cm->wireless_network_scan_finished().connect([]()
 
143
    {
 
144
        std::cout << "A wireless network scan finished." << std::endl;
 
145
    });
 
146
 
 
147
    // Request a scan for wireless networks.
 
148
    try
 
149
    {
 
150
        cm->request_scan_for_wireless_networks();
 
151
    } catch(const std::runtime_error& e)
 
152
    {
 
153
        std::cerr << e.what() << std::endl;
 
154
    }
 
155
 
 
156
    bool cancelled = false;
 
157
 
 
158
    std::thread t1
 
159
    {
 
160
        [cm, &cancelled]()
 
161
        {
 
162
            while (not cancelled)
 
163
            {
 
164
                cm->enumerate_visible_wireless_networks([](const location::connectivity::WirelessNetwork::Ptr&)
 
165
                {
 
166
                    // We do nothing with the actual values and just keep the thread running
 
167
                    // to put some load on the infrastructure.
 
168
                });
 
169
            }
 
170
        }
 
171
    };
 
172
 
 
173
    std::thread t2
 
174
    {
 
175
        [cm, &cancelled]()
 
176
        {
 
177
            while (not cancelled)
 
178
            {
 
179
                cm->enumerate_connected_radio_cells([](const location::connectivity::RadioCell::Ptr&)
 
180
                {
 
181
                    // We do nothing with the actual values and just keep the thread running
 
182
                    // to put some load on the infrastructure.
 
183
                });
 
184
            }
 
185
        }
 
186
    };
 
187
 
 
188
    trap->run();
 
189
 
 
190
    cancelled = true;
 
191
 
 
192
    if (t1.joinable())
 
193
        t1.join();
 
194
 
 
195
    if (t2.joinable())
 
196
        t2.join();
 
197
 
 
198
    return 0;
 
199
}    
 
200
 
 
201