blob: 267b90bb0dcd0aa39771f6722ca29be01efb469b [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
45 struct wpa_ssid *ssid = wpa_config_add_network(wpa_s->conf);
46 if (!ssid) {
47 return android::binder::Status::fromServiceSpecificError(
48 ERROR_GENERIC, "wpa_supplicant couldn't add this network.");
49 }
50
51 // This sequence of steps after network addition is following what is
52 // currently being done in |ctrl_iface.c| & |dbus_new_handlers|.
53 // Notify the control interfaces about the network addition.
54 wpas_notify_network_added(wpa_s, ssid);
55 // Set the new network to be disabled.
56 ssid->disabled = 1;
57 // Set defaults for the new network.
58 wpa_config_set_network_defaults(ssid);
59
60 BinderManager *binder_manager = BinderManager::getInstance();
61 if (!binder_manager ||
62 binder_manager->getNetworkBinderObjectByIfnameAndNetworkId(
63 wpa_s->ifname, ssid->id, network_object_out)) {
64 return android::binder::Status::fromServiceSpecificError(
65 ERROR_GENERIC,
66 "wpa_supplicant encountered a binder error.");
67 }
Roshan Piusd6e37512016-07-07 13:20:46 -070068 return android::binder::Status::ok();
69}
70
71android::binder::Status Iface::RemoveNetwork(int network_id)
72{
Roshan Piusd3854452016-07-07 16:46:41 -070073 struct wpa_supplicant *wpa_s = retrieveIfacePtr();
74 if (!wpa_s) {
75 return android::binder::Status::fromServiceSpecificError(
76 ERROR_IFACE_INVALID,
77 "wpa_supplicant does not control this interface.");
78 }
79
80 struct wpa_ssid *ssid = wpa_config_get_network(wpa_s->conf, network_id);
81 if (!ssid) {
82 return android::binder::Status::fromServiceSpecificError(
83 ERROR_NETWORK_UNKNOWN,
84 "wpa_supplicant does not control this network.");
85 }
86 if (wpa_config_remove_network(wpa_s->conf, network_id)) {
87 return android::binder::Status::fromServiceSpecificError(
88 ERROR_GENERIC,
89 "wpa_supplicant couldn't remove this network.");
90 }
91 return android::binder::Status::ok();
92}
93
94android::binder::Status Iface::GetNetwork(
95 int network_id,
96 android::sp<fi::w1::wpa_supplicant::INetwork> *network_object_out)
97{
98 struct wpa_supplicant *wpa_s = retrieveIfacePtr();
99 if (!wpa_s) {
100 return android::binder::Status::fromServiceSpecificError(
101 ERROR_IFACE_INVALID,
102 "wpa_supplicant does not control this interface.");
103 }
104
105 struct wpa_ssid *ssid = wpa_config_get_network(wpa_s->conf, network_id);
106 if (!ssid) {
107 return android::binder::Status::fromServiceSpecificError(
108 ERROR_NETWORK_UNKNOWN,
109 "wpa_supplicant does not control this network.");
110 }
111
112 BinderManager *binder_manager = BinderManager::getInstance();
113 if (!binder_manager ||
114 binder_manager->getNetworkBinderObjectByIfnameAndNetworkId(
115 wpa_s->ifname, ssid->id, network_object_out)) {
116 return android::binder::Status::fromServiceSpecificError(
117 ERROR_GENERIC,
118 "wpa_supplicant encountered a binder error.");
119 }
Roshan Piusd6e37512016-07-07 13:20:46 -0700120 return android::binder::Status::ok();
121}
122
Roshan Pius54e763a2016-07-06 15:41:53 -0700123/**
124 * Retrieve the underlying |wpa_supplicant| struct pointer for
125 * this iface.
126 * If the underlying iface is removed, then all RPC method calls
127 * on this object will return failure.
128 */
129wpa_supplicant *Iface::retrieveIfacePtr()
130{
131 return wpa_supplicant_get_iface(
132 (struct wpa_global *)wpa_global_, ifname_.c_str());
133}
134
135} // namespace wpa_supplicant_binder