blob: d5a650266fd1ca8398c1d99b6bce6d43edff0574 [file] [log] [blame]
Dmitry Shmidte4663042016-04-04 10:07:49 -07001/*
2 * binder interface for wpa_supplicant daemon
3 * Copyright (c) 2004-2016, Jouni Malinen <j@w1.fi>
4 * Copyright (c) 2004-2016, Roshan Pius <rpius@google.com>
5 *
6 * This software may be distributed under the terms of the BSD license.
7 * See README for more details.
8 */
9
Roshan Piusd3854452016-07-07 16:46:41 -070010#include "binder_manager.h"
Dmitry Shmidte4663042016-04-04 10:07:49 -070011#include "iface.h"
12
13namespace wpa_supplicant_binder {
14
Roshan Pius54e763a2016-07-06 15:41:53 -070015Iface::Iface(struct wpa_global *wpa_global, const char ifname[])
16 : wpa_global_(wpa_global), ifname_(ifname)
17{
18}
Dmitry Shmidte4663042016-04-04 10:07:49 -070019
Roshan Pius54e763a2016-07-06 15:41:53 -070020android::binder::Status Iface::GetName(std::string *iface_name_out)
21{
22 // We could directly return the name we hold, but let's verify
23 // if the underlying iface still exists.
24 struct wpa_supplicant *wpa_s = retrieveIfacePtr();
25 if (!wpa_s) {
26 return android::binder::Status::fromServiceSpecificError(
Roshan Piusd6e37512016-07-07 13:20:46 -070027 ERROR_IFACE_INVALID,
Roshan Pius54e763a2016-07-06 15:41:53 -070028 "wpa_supplicant does not control this interface.");
29 }
30
31 *iface_name_out = ifname_;
32 return android::binder::Status::ok();
33}
34
Roshan Piusd6e37512016-07-07 13:20:46 -070035android::binder::Status Iface::AddNetwork(
36 android::sp<fi::w1::wpa_supplicant::INetwork> *network_object_out)
37{
Roshan Piusd3854452016-07-07 16:46:41 -070038 struct wpa_supplicant *wpa_s = retrieveIfacePtr();
39 if (!wpa_s) {
40 return android::binder::Status::fromServiceSpecificError(
41 ERROR_IFACE_INVALID,
42 "wpa_supplicant does not control this interface.");
43 }
44
Roshan Piusf745df82016-07-14 16:00:23 -070045 struct wpa_ssid *ssid = wpa_supplicant_add_network(wpa_s);
Roshan Piusd3854452016-07-07 16:46:41 -070046 if (!ssid) {
47 return android::binder::Status::fromServiceSpecificError(
48 ERROR_GENERIC, "wpa_supplicant couldn't add this network.");
49 }
50
Roshan Piusd3854452016-07-07 16:46:41 -070051 BinderManager *binder_manager = BinderManager::getInstance();
52 if (!binder_manager ||
53 binder_manager->getNetworkBinderObjectByIfnameAndNetworkId(
54 wpa_s->ifname, ssid->id, network_object_out)) {
55 return android::binder::Status::fromServiceSpecificError(
56 ERROR_GENERIC,
57 "wpa_supplicant encountered a binder error.");
58 }
Roshan Piusd6e37512016-07-07 13:20:46 -070059 return android::binder::Status::ok();
60}
61
62android::binder::Status Iface::RemoveNetwork(int network_id)
63{
Roshan Piusd3854452016-07-07 16:46:41 -070064 struct wpa_supplicant *wpa_s = retrieveIfacePtr();
65 if (!wpa_s) {
66 return android::binder::Status::fromServiceSpecificError(
67 ERROR_IFACE_INVALID,
68 "wpa_supplicant does not control this interface.");
69 }
70
Roshan Piusf745df82016-07-14 16:00:23 -070071 int result = wpa_supplicant_remove_network(wpa_s, network_id);
72 if (result == -1) {
Roshan Piusd3854452016-07-07 16:46:41 -070073 return android::binder::Status::fromServiceSpecificError(
74 ERROR_NETWORK_UNKNOWN,
75 "wpa_supplicant does not control this network.");
76 }
Roshan Piusf745df82016-07-14 16:00:23 -070077
78 if (result == -2) {
Roshan Piusd3854452016-07-07 16:46:41 -070079 return android::binder::Status::fromServiceSpecificError(
80 ERROR_GENERIC,
81 "wpa_supplicant couldn't remove this network.");
82 }
83 return android::binder::Status::ok();
84}
85
86android::binder::Status Iface::GetNetwork(
87 int network_id,
88 android::sp<fi::w1::wpa_supplicant::INetwork> *network_object_out)
89{
90 struct wpa_supplicant *wpa_s = retrieveIfacePtr();
91 if (!wpa_s) {
92 return android::binder::Status::fromServiceSpecificError(
93 ERROR_IFACE_INVALID,
94 "wpa_supplicant does not control this interface.");
95 }
96
97 struct wpa_ssid *ssid = wpa_config_get_network(wpa_s->conf, network_id);
98 if (!ssid) {
99 return android::binder::Status::fromServiceSpecificError(
100 ERROR_NETWORK_UNKNOWN,
101 "wpa_supplicant does not control this network.");
102 }
103
104 BinderManager *binder_manager = BinderManager::getInstance();
105 if (!binder_manager ||
106 binder_manager->getNetworkBinderObjectByIfnameAndNetworkId(
107 wpa_s->ifname, ssid->id, network_object_out)) {
108 return android::binder::Status::fromServiceSpecificError(
109 ERROR_GENERIC,
110 "wpa_supplicant encountered a binder error.");
111 }
Roshan Piusd6e37512016-07-07 13:20:46 -0700112 return android::binder::Status::ok();
113}
114
Roshan Pius0470cc82016-07-14 16:37:07 -0700115android::binder::Status Iface::RegisterCallback(
116 const android::sp<fi::w1::wpa_supplicant::IIfaceCallback> &callback)
117{
118 struct wpa_supplicant *wpa_s = retrieveIfacePtr();
119 if (!wpa_s) {
120 return android::binder::Status::fromServiceSpecificError(
121 ERROR_IFACE_INVALID,
122 "wpa_supplicant does not control this interface.");
123 }
124 BinderManager *binder_manager = BinderManager::getInstance();
125 if (!binder_manager ||
126 binder_manager->addIfaceCallbackBinderObject(ifname_, callback)) {
127 return android::binder::Status::fromServiceSpecificError(
128 ERROR_GENERIC,
129 "wpa_supplicant encountered a binder error.");
130 }
131 return android::binder::Status::ok();
132}
133
Roshan Pius54e763a2016-07-06 15:41:53 -0700134/**
135 * Retrieve the underlying |wpa_supplicant| struct pointer for
136 * this iface.
137 * If the underlying iface is removed, then all RPC method calls
138 * on this object will return failure.
139 */
140wpa_supplicant *Iface::retrieveIfacePtr()
141{
142 return wpa_supplicant_get_iface(
143 (struct wpa_global *)wpa_global_, ifname_.c_str());
144}
Roshan Pius54e763a2016-07-06 15:41:53 -0700145} // namespace wpa_supplicant_binder