1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 #include "WifiHotspotUtils.h"
11 #include <cutils/properties.h>
14 #include "mozilla/Assertions.h"
16 #include "nsPrintfCString.h"
18 static void* sWifiHotspotUtilsLib
;
19 static PRCallOnceType sInitWifiHotspotUtilsLib
;
20 // Socket pair used to exit from a blocking read.
21 static struct wpa_ctrl
* ctrl_conn
;
22 static const char *ctrl_iface_dir
= "/data/misc/wifi/hostapd";
23 static char *ctrl_ifname
= nullptr;
25 DEFINE_DLFUNC(wpa_ctrl_open
, struct wpa_ctrl
*, const char*)
26 DEFINE_DLFUNC(wpa_ctrl_close
, void, struct wpa_ctrl
*)
27 DEFINE_DLFUNC(wpa_ctrl_attach
, int32_t, struct wpa_ctrl
*)
28 DEFINE_DLFUNC(wpa_ctrl_detach
, int32_t, struct wpa_ctrl
*)
29 DEFINE_DLFUNC(wpa_ctrl_request
, int32_t, struct wpa_ctrl
*,
30 const char*, size_t cmd_len
, char *reply
,
31 size_t *reply_len
, void (*msg_cb
)(char *msg
, size_t len
))
35 InitWifiHotspotUtilsLib()
37 sWifiHotspotUtilsLib
= dlopen("/system/lib/libwpa_client.so", RTLD_LAZY
);
38 // We might fail to open the hardware lib. That's OK.
43 GetWifiHotspotLibHandle()
45 PR_CallOnce(&sInitWifiHotspotUtilsLib
, InitWifiHotspotUtilsLib
);
46 return sWifiHotspotUtilsLib
;
50 WifiHotspotUtils::openConnection(const char *ifname
)
56 USE_DLFUNC(wpa_ctrl_open
)
57 ctrl_conn
= wpa_ctrl_open(nsPrintfCString("%s/%s", ctrl_iface_dir
, ifname
).get());
62 WifiHotspotUtils::sendCommand(struct wpa_ctrl
*ctrl
, const char *cmd
,
63 char *reply
, size_t *reply_len
)
68 NS_WARNING(nsPrintfCString("Not connected to hostapd - \"%s\" command dropped.\n", cmd
).get());
72 USE_DLFUNC(wpa_ctrl_request
)
73 ret
= wpa_ctrl_request(ctrl
, cmd
, strlen(cmd
), reply
, reply_len
, nullptr);
75 NS_WARNING(nsPrintfCString("'%s' command timed out.\n", cmd
).get());
77 } else if (ret
< 0 || strncmp(reply
, "FAIL", 4) == 0) {
81 // Make the reply printable.
82 reply
[*reply_len
] = '\0';
83 if (strncmp(cmd
, "STA-FIRST", 9) == 0 ||
84 strncmp(cmd
, "STA-NEXT", 8) == 0) {
87 while (*pos
&& *pos
!= '\n')
98 WifiHotspotUtils::GetSharedLibrary()
100 void* wpaClientLib
= GetWifiHotspotLibHandle();
102 NS_WARNING("No /system/lib/libwpa_client.so");
107 int32_t WifiHotspotUtils::do_wifi_connect_to_hostapd()
111 DIR *dir
= opendir(ctrl_iface_dir
);
113 while ((dent
= readdir(dir
))) {
114 if (strcmp(dent
->d_name
, ".") == 0 ||
115 strcmp(dent
->d_name
, "..") == 0) {
118 ctrl_ifname
= strdup(dent
->d_name
);
124 ctrl_conn
= openConnection(ctrl_ifname
);
126 NS_WARNING(nsPrintfCString("Unable to open connection to hostapd on \"%s\": %s",
127 ctrl_ifname
, strerror(errno
)).get());
131 USE_DLFUNC(wpa_ctrl_attach
)
132 if (wpa_ctrl_attach(ctrl_conn
) != 0) {
133 USE_DLFUNC(wpa_ctrl_close
)
134 wpa_ctrl_close(ctrl_conn
);
142 int32_t WifiHotspotUtils::do_wifi_close_hostapd_connection()
145 NS_WARNING("Invalid ctrl_conn.");
149 USE_DLFUNC(wpa_ctrl_detach
)
150 if (wpa_ctrl_detach(ctrl_conn
) < 0) {
151 NS_WARNING("Failed to detach wpa_ctrl.");
154 USE_DLFUNC(wpa_ctrl_close
)
155 wpa_ctrl_close(ctrl_conn
);
160 int32_t WifiHotspotUtils::do_wifi_hostapd_command(const char *command
,
164 return sendCommand(ctrl_conn
, command
, reply
, reply_len
);
167 int32_t WifiHotspotUtils::do_wifi_hostapd_get_stations()
169 char addr
[32], cmd
[64];
171 size_t addrLen
= sizeof(addr
);
173 if (sendCommand(ctrl_conn
, "STA-FIRST", addr
, &addrLen
)) {
178 sprintf(cmd
, "STA-NEXT %s", addr
);
179 while (sendCommand(ctrl_conn
, cmd
, addr
, &addrLen
) == 0) {
181 sprintf(cmd
, "STA-NEXT %s", addr
);