~phablet-team/aethercast/trunk

« back to all changes in this revision

Viewing changes to src/w11tng/networkmanager.cpp

  • Committer: Bileto Bot
  • Author(s): Simon Fels
  • Date: 2016-08-08 08:58:20 UTC
  • mfrom: (148.1.17 trunk)
  • Revision ID: ci-train-bot@canonical.com-20160808085820-dabmzye9h1v7w5vm
Add URfkill support to manage kill switches on selected devices

Some devices don't use the rfkill provided from the kernel to managed the kill state of WiFi. They are using a libhardware_legacy from Android through libhybris to manage the WiFi power state. We have to use urfkill in those cases rather than relying on the rfkill provided from the kernel.

Fixes LP #1579676

This fixes in addition also problems with reporting the correct device state when it updates.

Approved by: Alfonso Sanchez-Beato, Konrad Zapałowicz

Show diffs side-by-side

added added

removed removed

Lines of Context:
24
24
#include <ac/keep_alive.h>
25
25
#include <ac/networkutils.h>
26
26
 
27
 
#include "networkmanager.h"
28
 
#include "informationelement.h"
 
27
#include "w11tng/networkmanager.h"
 
28
#include "w11tng/informationelement.h"
 
29
#include "w11tng/kernelrfkillmanager.h"
 
30
#include "w11tng/urfkillmanager.h"
29
31
 
30
32
namespace {
31
33
// We take two minutes as timeout here which corresponds to what wpa
51
53
        return sp;
52
54
    }
53
55
 
54
 
    rfkill_manager_ = RfkillManager::Create();
55
 
    rfkill_manager_->SetDelegate(sp);
 
56
    // We first check if urfkilld is running or not. If its not we fall back
 
57
    // to just use the plain rfkill interface the kernel offers.
 
58
    AC_DEBUG("Checking if URfkill is available ..");
 
59
    urfkill_watch_ = g_bus_watch_name(G_BUS_TYPE_SYSTEM,
 
60
          URfkillManager::kBusName,
 
61
          G_BUS_NAME_WATCHER_FLAGS_NONE,
 
62
          &NetworkManager::OnURfkillAvailable,
 
63
          &NetworkManager::OnURfkillNotAvailable,
 
64
          new ac::WeakKeepAlive<NetworkManager>(shared_from_this()),
 
65
          [](gpointer data) { delete static_cast<ac::WeakKeepAlive<NetworkManager>*>(data); });
56
66
 
57
67
    return sp;
58
68
}
60
70
NetworkManager::NetworkManager() :
61
71
    firmware_loader_("", this),
62
72
    dedicated_p2p_interface_(ac::Utils::GetEnvValue("AETHERCAST_DEDICATED_P2P_INTERFACE")),
63
 
    session_available_(true) {
 
73
    session_available_(true),
 
74
    urfkill_watch_(0) {
64
75
}
65
76
 
66
77
NetworkManager::~NetworkManager() {
92
103
}
93
104
 
94
105
void NetworkManager::Initialize(bool firmware_loading) {
95
 
    AC_DEBUG("");
96
 
 
97
106
    if (firmware_loading && ac::Utils::GetEnvValue("AETHERCAST_NEED_FIRMWARE") == "1") {
98
107
        auto interface_name = ac::Utils::GetEnvValue("AETHERCAST_DEDICATED_P2P_INTERFACE");
99
 
        if (interface_name.length() == 0)
 
108
        if (interface_name.empty())
100
109
            interface_name = "p2p0";
101
110
 
 
111
        AC_DEBUG("Firmware loading for interface '%s' requested", interface_name);
 
112
 
102
113
        firmware_loader_.SetInterfaceName(interface_name);
103
114
        if (firmware_loader_.IsNeeded()) {
104
115
            AC_DEBUG("Loading WiFi firmware for interface %s", interface_name);
116
127
 
117
128
    manager_ = ManagerStub::Create();
118
129
    manager_->SetDelegate(sp);
 
130
 
 
131
    AC_DEBUG("Successfully initialized");
119
132
}
120
133
 
121
134
void NetworkManager::Release() {
173
186
}
174
187
 
175
188
bool NetworkManager::Setup() {
176
 
    AC_DEBUG("");
177
 
 
178
 
    if (rfkill_manager_->IsBlocked(RfkillManager::Type::kWLAN)) {
179
 
        AC_ERROR("Can't setup network manager as WLAN is disabled");
 
189
    if (!Ready())
180
190
        return false;
181
 
    }
182
191
 
183
192
    g_bus_watch_name_on_connection(connection_.get(),
184
193
                                   kBusName,
191
200
    return true;
192
201
}
193
202
 
 
203
void NetworkManager::OnURfkillAvailable(GDBusConnection*, const gchar*, const gchar*, gpointer user_data) {
 
204
    auto inst = static_cast<ac::WeakKeepAlive<NetworkManager>*>(user_data)->GetInstance().lock();
 
205
    if (!inst)
 
206
        return;
 
207
 
 
208
    AC_DEBUG("URfkill is available");
 
209
 
 
210
    inst->rfkill_manager_ = URfkillManager::Create();
 
211
    inst->FinishRfkillInitialization();
 
212
}
 
213
 
 
214
void NetworkManager::OnURfkillNotAvailable(GDBusConnection*, const gchar*, gpointer user_data) {
 
215
    auto inst = static_cast<ac::WeakKeepAlive<NetworkManager>*>(user_data)->GetInstance().lock();
 
216
    if (!inst)
 
217
        return;
 
218
 
 
219
    AC_DEBUG("URfkill is not available, falling back to kernel rfkill manager");
 
220
 
 
221
    inst->rfkill_manager_ = KernelRfkillManager::Create();
 
222
    inst->FinishRfkillInitialization();
 
223
}
 
224
 
 
225
void NetworkManager::FinishRfkillInitialization() {
 
226
    g_source_remove(urfkill_watch_);
 
227
    urfkill_watch_ = 0;
 
228
 
 
229
    rfkill_manager_->SetDelegate(shared_from_this());
 
230
}
 
231
 
194
232
void NetworkManager::Scan(const std::chrono::seconds &timeout) {
195
233
    if (!p2p_device_)
196
234
        return;
211
249
 
212
250
    connect_timeout_ = g_timeout_add_seconds(kConnectTimeout.count(), [](gpointer user_data) {
213
251
        auto inst = static_cast<ac::SharedKeepAlive<NetworkManager>*>(user_data)->ShouldDie();
214
 
        if (not inst)
215
 
            return FALSE;
216
 
 
217
 
        AC_WARNING("Reached a timeout while trying to connect with remote %s", inst->current_device_->Address());
 
252
        if (!inst)
 
253
            return FALSE;
 
254
 
 
255
        if (!inst->current_device_) {
 
256
            AC_WARNING("Reached a timeout while trying to connect with remote but"
 
257
                       "no current device");
 
258
            return FALSE;
 
259
        }
 
260
 
 
261
        AC_WARNING("Reached a timeout while trying to connect with remote %s",
 
262
                   inst->current_device_->Address());
218
263
 
219
264
        inst->connect_timeout_ = 0;
220
265
 
340
385
    if (!FindDevice(device->Address()))
341
386
        return false;
342
387
 
343
 
    // This will trigger the GroupFinished signal where we will release
344
 
    // all parts in order.
345
 
    current_group_device_->Disconnect();
 
388
    if (current_group_device_) {
 
389
        // This will trigger the GroupFinished signal where we will release
 
390
        // all parts in order.
 
391
        current_group_device_->Disconnect();
 
392
    }
346
393
 
347
394
    return true;
348
395
}
379
426
}
380
427
 
381
428
bool NetworkManager::Ready() const {
 
429
    if (!rfkill_manager_)
 
430
        return false;
 
431
 
382
432
    return !rfkill_manager_->IsBlocked(RfkillManager::Type::kWLAN);
383
433
}
384
434