blob: fc07f06f341604bcd0eb212020ddbeb86f756170 [file] [log] [blame]
Roshan Piuscc817562017-12-22 14:45:05 -08001/*
2 * hidl interface for wpa_hostapd daemon
3 * Copyright (c) 2004-2018, Jouni Malinen <j@w1.fi>
4 * Copyright (c) 2004-2018, 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 */
Roshan Pius30b452e2017-12-27 13:36:21 -08009#include <iomanip>
10#include <sstream>
11#include <string>
12#include <vector>
13
14#include <android-base/file.h>
15#include <android-base/stringprintf.h>
Roshan Piuscc817562017-12-22 14:45:05 -080016
17#include "hostapd.h"
18#include "hidl_return_util.h"
19
Roshan Pius30b452e2017-12-27 13:36:21 -080020// The HIDL implementation for hostapd creates a hostapd.conf dynamically for
21// each interface. This file can then be used to hook onto the normal config
22// file parsing logic in hostapd code. Helps us to avoid duplication of code
23// in the HIDL interface.
24// TOOD(b/71872409): Add unit tests for this.
25namespace {
26constexpr char kConfFileNameFmt[] = "/data/vendor/wifi/hostapd/hostapd_%s.conf";
27
28using android::base::RemoveFileIfExists;
29using android::base::StringPrintf;
30using android::base::WriteStringToFile;
31using android::hardware::wifi::hostapd::V1_0::IHostapd;
32
33std::string WriteHostapdConfig(
34 const std::string& interface_name, const std::string& config)
35{
36 const std::string file_path =
37 StringPrintf(kConfFileNameFmt, interface_name.c_str());
38 if (WriteStringToFile(
39 config, file_path, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
40 getuid(), getgid())) {
41 return file_path;
42 }
43 // Diagnose failure
44 int error = errno;
45 wpa_printf(
46 MSG_ERROR, "Cannot write hostapd config to %s, error: %s",
47 file_path.c_str(), strerror(error));
48 struct stat st;
49 int result = stat(file_path.c_str(), &st);
50 if (result == 0) {
51 wpa_printf(
52 MSG_ERROR, "hostapd config file uid: %d, gid: %d, mode: %d",
53 st.st_uid, st.st_gid, st.st_mode);
54 } else {
55 wpa_printf(
56 MSG_ERROR,
57 "Error calling stat() on hostapd config file: %s",
58 strerror(errno));
59 }
60 return "";
61}
62
63std::string CreateHostapdConfig(
64 const IHostapd::IfaceParams& iface_params,
65 const IHostapd::NetworkParams& nw_params)
66{
67 if (nw_params.ssid.size() >
68 static_cast<uint32_t>(
69 IHostapd::ParamSizeLimits::SSID_MAX_LEN_IN_BYTES)) {
70 wpa_printf(
71 MSG_ERROR, "Invalid SSID size: %zu", nw_params.ssid.size());
72 return "";
73 }
74 if (nw_params.pskPassphrase.size() <
75 static_cast<uint32_t>(
76 IHostapd::ParamSizeLimits::
77 WPA2_PSK_PASSPHRASE_MIN_LEN_IN_BYTES) ||
78 nw_params.pskPassphrase.size() >
79 static_cast<uint32_t>(
80 IHostapd::ParamSizeLimits::
81 WPA2_PSK_PASSPHRASE_MAX_LEN_IN_BYTES)) {
82 wpa_printf(
83 MSG_ERROR, "Invalid psk passphrase size: %zu",
84 nw_params.pskPassphrase.size());
85 return "";
86 }
87
88 // SSID string
89 std::stringstream ss;
90 ss << std::hex;
91 ss << std::setfill('0');
92 for (uint8_t b : nw_params.ssid) {
93 ss << std::setw(2) << static_cast<unsigned int>(b);
94 }
95 const std::string ssid_as_string = ss.str();
96
97 // Encryption config string
98 std::string encryption_config_as_string;
99 switch (nw_params.encryptionType) {
100 case IHostapd::EncryptionType::NONE:
101 // no security params
102 break;
103 case IHostapd::EncryptionType::WPA:
104 encryption_config_as_string = StringPrintf(
105 "wpa=3\n"
106 "wpa_pairwise=TKIP CCMP\n"
107 "wpa_passphrase=%s",
108 nw_params.pskPassphrase.c_str());
109 break;
110 case IHostapd::EncryptionType::WPA2:
111 encryption_config_as_string = StringPrintf(
112 "wpa=2\n"
113 "rsn_pairwise=CCMP\n"
114 "wpa_passphrase=%s",
115 nw_params.pskPassphrase.c_str());
116 break;
117 default:
118 wpa_printf(MSG_ERROR, "Unknown encryption type");
119 return "";
120 }
121
122 std::string channel_config_as_string;
123 if (iface_params.channelParams.enableAcs) {
124 channel_config_as_string = StringPrintf(
125 "channel=0\n"
126 "acs_exclude_dfs=%d",
127 iface_params.channelParams.acsShouldExcludeDfs);
128 } else {
129 channel_config_as_string = StringPrintf(
130 "channel=%d", iface_params.channelParams.channel);
131 }
132
133 // Hw Mode String
134 std::string hw_mode_as_string;
135 switch (iface_params.channelParams.band) {
136 case IHostapd::Band::BAND_2_4_GHZ:
137 hw_mode_as_string = "g";
138 break;
139 case IHostapd::Band::BAND_5_GHZ:
140 hw_mode_as_string = "a";
141 break;
142 case IHostapd::Band::BAND_ANY:
143 hw_mode_as_string = "any";
144 break;
145 default:
146 wpa_printf(MSG_ERROR, "Invalid band");
147 return "";
148 }
149
150 return StringPrintf(
151 "interface=%s\n"
152 "driver=nl80211\n"
153 // ssid2 signals to hostapd that the value is not a literal value
154 // for use as a SSID. In this case, we're giving it a hex
155 // std::string and hostapd needs to expect that.
156 "ssid2=%s\n"
157 "%s\n"
158 "ieee80211n=%d\n"
159 "ieee80211ac=%d\n"
160 "hw_mode=%s\n"
161 "ignore_broadcast_ssid=%d\n"
162 "wowlan_triggers=any\n"
163 "%s\n",
164 iface_params.ifaceName.c_str(), ssid_as_string.c_str(),
165 channel_config_as_string.c_str(),
166 iface_params.hwModeParams.enable80211N ? 1 : 0,
167 iface_params.hwModeParams.enable80211AC ? 1 : 0,
168 hw_mode_as_string.c_str(), nw_params.isHidden ? 1 : 0,
169 encryption_config_as_string.c_str());
170}
171} // namespace
172
Roshan Piuscc817562017-12-22 14:45:05 -0800173namespace android {
174namespace hardware {
175namespace wifi {
176namespace hostapd {
177namespace V1_0 {
178namespace implementation {
179using hidl_return_util::call;
180
181Hostapd::Hostapd(struct hapd_interfaces* interfaces) : interfaces_(interfaces)
182{}
183
184Return<void> Hostapd::addAccessPoint(
185 const IfaceParams& iface_params, const NetworkParams& nw_params,
186 addAccessPoint_cb _hidl_cb)
187{
188 return call(
189 this, &Hostapd::addAccessPointInternal, _hidl_cb, iface_params,
190 nw_params);
191}
192
193Return<void> Hostapd::removeAccessPoint(
194 const hidl_string& iface_name, removeAccessPoint_cb _hidl_cb)
195{
196 return call(
197 this, &Hostapd::removeAccessPointInternal, _hidl_cb, iface_name);
198}
199
200HostapdStatus Hostapd::addAccessPointInternal(
201 const IfaceParams& iface_params, const NetworkParams& nw_params)
202{
203 return {HostapdStatusCode::SUCCESS, ""};
204}
205
206HostapdStatus Hostapd::removeAccessPointInternal(const std::string& iface_name)
207{
208 return {HostapdStatusCode::SUCCESS, ""};
209}
210} // namespace implementation
211} // namespace V1_0
212} // namespace hostapd
213} // namespace wifi
214} // namespace hardware
215} // namespace android