~phablet-team/aethercast/fix-for-microsoft-dongle

« back to all changes in this revision

Viewing changes to src/w11tng/p2pdevicestub.cpp

  • Committer: Tarmac
  • Author(s): Simon Fels
  • Date: 2016-03-04 14:14:09 UTC
  • mfrom: (119.4.12 ac-networking-fixes)
  • Revision ID: tarmac-20160304141409-xe8khdgb43nha1fn
Multiple changes for Networking support:

* Add a DisconnectAll dbus method to allow the UI to easily disconnect
  any connected device. Just for the purpose of a demo.
* Return proper errors when scanning fails.
* Enable miracast mode for the WiFi driver if available.
* Set GO intent by default to 7. Should be higher if we're a sink.
* Print frequencies consider for GO negotiation
* Several minor fixes
* Enable unit tests again.

Approved by PS Jenkins bot, Thomas Voß.

Show diffs side-by-side

added added

removed removed

Lines of Context:
25
25
 
26
26
namespace w11tng {
27
27
 
 
28
std::string P2PDeviceStub::StatusToString(Status status) {
 
29
    switch (status) {
 
30
    case Status::kSucccesAcceptedByUser:
 
31
    case Status::kSuccess:
 
32
        return "Success";
 
33
    case Status::kInformationIsCurrentlyUnavailable:
 
34
        return "Information is currently unavailable";
 
35
    case Status::kIncompatibleParameters:
 
36
        return "Incompatible parameters";
 
37
    case Status::kLimitReached:
 
38
        return "Limit reached";
 
39
    case Status::kInvalidParameter:
 
40
        return "Invalid parameter";
 
41
    case Status::kUnableToAccommodateRequest:
 
42
        return "Unable to accommodate request";
 
43
    case Status::kProtcolErrorOrDisruptiveBehavior:
 
44
        return "Protocol error or disruptive behavior";
 
45
    case Status::kNoCommonChannel:
 
46
        return "No common channels";
 
47
    case Status::kUnknownP2PGroup:
 
48
        return "Unknown P2P group";
 
49
    case Status::kBothGOIntent15:
 
50
        return "Both P2P devices indicated an intent of 15 in group owner negotiation";
 
51
    case Status::kIncompatibleProvisioningMethod:
 
52
        return "Incompatible provisioning method";
 
53
    case Status::kRejectByUser:
 
54
        return "Rejected by user";
 
55
    default:
 
56
        break;
 
57
    }
 
58
 
 
59
    return "Failed: unknown error";
 
60
}
 
61
 
 
62
std::string P2PDeviceStub::PropertyToString(Property property) {
 
63
    switch (property) {
 
64
    case Property::kPeerObject:
 
65
        return "peer_object";
 
66
    case Property::kStatus:
 
67
        return "status";
 
68
    case Property::kFrequency:
 
69
        return "frequency";
 
70
    case Property::kFrequencyList:
 
71
        return "frequency_list";
 
72
    case Property::kWpsMethod:
 
73
        return "wps_method";
 
74
    default:
 
75
        break;
 
76
    }
 
77
    return "unknown";
 
78
}
 
79
 
 
80
P2PDeviceStub::WpsMethod P2PDeviceStub::WpsMethodFromString(const std::string &wps_method) {
 
81
    if (wps_method == "pin")
 
82
        return WpsMethod::kPin;
 
83
    // In all other cases we directly fallback to PBC
 
84
    return WpsMethod::kPbc;
 
85
}
 
86
 
 
87
std::string P2PDeviceStub::WpsMethodToString(WpsMethod wps_method) {
 
88
    switch (wps_method) {
 
89
    case WpsMethod::kPbc:
 
90
        return "pbc";
 
91
    case WpsMethod::kPin:
 
92
        return "pin";
 
93
    default:
 
94
        break;
 
95
    }
 
96
    return "";
 
97
}
 
98
 
28
99
P2PDeviceStub::Ptr P2PDeviceStub::Create(const std::string &object_path, const std::weak_ptr<P2PDeviceStub::Delegate> &delegate) {
29
100
    return std::shared_ptr<P2PDeviceStub>(new P2PDeviceStub(delegate))->FinalizeConstruction(object_path);
30
101
}
110
181
    auto inst = static_cast<mcs::WeakKeepAlive<P2PDeviceStub>*>(user_data)->GetInstance().lock();
111
182
 
112
183
    std::string peer_path;
 
184
    GroupOwnerNegotiationResult result;
113
185
 
114
186
    mcs::DBusHelpers::ParseDictionary(properties, [&](const std::string &name, GVariant *value) {
115
 
        if (name == "peer_object")
116
 
            peer_path = g_variant_get_string(g_variant_get_variant(value), nullptr);
 
187
        if (name == PropertyToString(Property::kStatus)) {
 
188
            const auto v = g_variant_get_variant(value);
 
189
            if (g_variant_is_of_type(v, G_VARIANT_TYPE("i")))
 
190
                result.status = static_cast<Status>(g_variant_get_int32(v));
 
191
        }
 
192
        else if (name == PropertyToString(Property::kPeerObject)) {
 
193
            const auto v = g_variant_get_variant(value);
 
194
            if (g_variant_is_of_type(v, G_VARIANT_TYPE("s")))
 
195
                peer_path = g_variant_get_string(v, nullptr);
 
196
        }
 
197
        else if (name == PropertyToString(Property::kFrequency)) {
 
198
            const auto v = g_variant_get_variant(value);
 
199
            if (g_variant_is_of_type(v, G_VARIANT_TYPE("i")))
 
200
                result.oper_freq = g_variant_get_int32(v);
 
201
        }
 
202
        else if (name == PropertyToString(Property::kFrequencyList)) {
 
203
            const auto v = g_variant_get_variant(value);
 
204
            for (int n = 0; n < g_variant_n_children(v); n++) {
 
205
                Frequency freq = 0;
 
206
                g_variant_get_child(v, n, "i", &freq);
 
207
                result.frequencies.insert(freq);
 
208
            }
 
209
        }
 
210
        else if (name == PropertyToString(Property::kWpsMethod)) {
 
211
            const auto v = g_variant_get_variant(value);
 
212
            if (g_variant_is_of_type(v, G_VARIANT_TYPE("s")))
 
213
                result.wps_method = WpsMethodFromString(g_variant_get_string(v, nullptr));
 
214
        }
117
215
    });
118
216
 
119
217
    if (peer_path.length() == 0)
120
218
        return;
121
219
 
122
220
    if (auto sp = inst->delegate_.lock())
123
 
        sp->OnGroupOwnerNegotiationSuccess(peer_path);
 
221
        sp->OnGroupOwnerNegotiationSuccess(peer_path, result);
124
222
}
125
223
 
126
224
void P2PDeviceStub::OnGONegotiationFailure(WpaSupplicantInterfaceP2PDevice *device, GVariant *properties, gpointer user_data) {
129
227
    auto inst = static_cast<mcs::WeakKeepAlive<P2PDeviceStub>*>(user_data)->GetInstance().lock();
130
228
 
131
229
    std::string peer_path;
132
 
    int status = 0;
 
230
    GroupOwnerNegotiationResult result;
133
231
 
134
232
    mcs::DBusHelpers::ParseDictionary(properties, [&](const std::string &name, GVariant *value) {
135
233
        if (name == "peer_object")
136
234
            peer_path = g_variant_get_string(g_variant_get_variant(value), nullptr);
137
235
        else if (name == "status")
138
 
            status = g_variant_get_int32(g_variant_get_variant(value));
 
236
            result.status = static_cast<Status>(g_variant_get_int32(g_variant_get_variant(value)));
139
237
    });
140
238
 
141
239
    if (peer_path.length() == 0)
142
240
        return;
143
241
 
144
242
    if (auto sp = inst->delegate_.lock())
145
 
        sp->OnGroupOwnerNegotiationFailure(peer_path);
 
243
        sp->OnGroupOwnerNegotiationFailure(peer_path, result);
146
244
}
147
245
 
148
246
void P2PDeviceStub::OnGroupStarted(WpaSupplicantInterfaceP2PDevice *device, GVariant *properties, gpointer user_data) {
215
313
 
216
314
void P2PDeviceStub::StartFindTimeout() {
217
315
    scan_timeout_source_ = g_timeout_add_seconds(scan_timeout_.count(), [](gpointer user_data) {
218
 
        auto inst = static_cast<mcs::SharedKeepAlive<P2PDeviceStub>*>(user_data)->ShouldDie();
219
 
 
220
 
        inst->StopFindTimeout();
 
316
        auto inst = static_cast<mcs::WeakKeepAlive<P2PDeviceStub>*>(user_data)->GetInstance().lock();
 
317
 
 
318
        if (not inst)
 
319
            return FALSE;
 
320
 
 
321
        inst->scan_timeout_source_ = 0;
 
322
        inst->StopFind();
 
323
 
 
324
        if (auto sp = inst->delegate_.lock())
 
325
            sp->OnP2PDeviceChanged();
221
326
 
222
327
        return FALSE;
223
 
    }, new mcs::SharedKeepAlive<P2PDeviceStub>{shared_from_this()});
 
328
    }, new mcs::WeakKeepAlive<P2PDeviceStub>{shared_from_this()});
224
329
}
225
330
 
226
331
void P2PDeviceStub::StopFindTimeout() {
227
332
    if (scan_timeout_source_ == 0)
228
333
        return;
229
334
 
 
335
    g_source_remove(scan_timeout_source_);
230
336
    scan_timeout_source_ = 0;
231
337
    scan_timeout_ = std::chrono::seconds{0};
232
 
    StopFind();
233
338
 
234
339
    if (auto sp = delegate_.lock())
235
340
        sp->OnP2PDeviceChanged();
290
395
            g_error_free(error);
291
396
            return;
292
397
        }
293
 
 
294
398
    }, new mcs::SharedKeepAlive<P2PDeviceStub>{shared_from_this()});
295
399
 
296
400
    StopFindTimeout();
297
401
}
298
402
 
299
 
bool P2PDeviceStub::Connect(const std::string &path) {
 
403
bool P2PDeviceStub::Connect(const std::string &path, const std::int32_t intent) {
300
404
    MCS_DEBUG("");
301
405
 
302
406
    if (!proxy_ || path.length() == 0)
306
410
 
307
411
    auto builder = g_variant_builder_new(G_VARIANT_TYPE_ARRAY);
308
412
 
 
413
    MCS_DEBUG("Using GO intent %d", intent);
 
414
 
309
415
    g_variant_builder_add(builder, "{sv}", "peer", g_variant_new_object_path(path.c_str()));
310
416
    // We support only WPS PBC for now
311
 
    g_variant_builder_add(builder, "{sv}", "wps_method", g_variant_new_string("pbc"));
 
417
    g_variant_builder_add(builder, "{sv}", "wps_method", g_variant_new_string(WpsMethodToString(WpsMethod::kPbc).c_str()));
 
418
    g_variant_builder_add(builder, "{sv}", "go_intent", g_variant_new_int32(intent));
312
419
 
313
420
    auto arguments = g_variant_builder_end(builder);
314
421