Bumping manifests a=b2g-bump
[gecko.git] / dom / wifi / WifiHotspotUtils.cpp
blobb9e2b8d8e9036bc7aea280c40bc6bcc3ce413795
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"
6 #include <dlfcn.h>
7 #include <errno.h>
8 #include <string.h>
9 #include <dirent.h>
10 #include <stdlib.h>
11 #include <cutils/properties.h>
13 #include "prinit.h"
14 #include "mozilla/Assertions.h"
15 #include "nsDebug.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))
34 static PRStatus
35 InitWifiHotspotUtilsLib()
37 sWifiHotspotUtilsLib = dlopen("/system/lib/libwpa_client.so", RTLD_LAZY);
38 // We might fail to open the hardware lib. That's OK.
39 return PR_SUCCESS;
42 static void*
43 GetWifiHotspotLibHandle()
45 PR_CallOnce(&sInitWifiHotspotUtilsLib, InitWifiHotspotUtilsLib);
46 return sWifiHotspotUtilsLib;
49 struct wpa_ctrl *
50 WifiHotspotUtils::openConnection(const char *ifname)
52 if (!ifname) {
53 return nullptr;
56 USE_DLFUNC(wpa_ctrl_open)
57 ctrl_conn = wpa_ctrl_open(nsPrintfCString("%s/%s", ctrl_iface_dir, ifname).get());
58 return ctrl_conn;
61 int32_t
62 WifiHotspotUtils::sendCommand(struct wpa_ctrl *ctrl, const char *cmd,
63 char *reply, size_t *reply_len)
65 int32_t ret;
67 if (!ctrl_conn) {
68 NS_WARNING(nsPrintfCString("Not connected to hostapd - \"%s\" command dropped.\n", cmd).get());
69 return -1;
72 USE_DLFUNC(wpa_ctrl_request)
73 ret = wpa_ctrl_request(ctrl, cmd, strlen(cmd), reply, reply_len, nullptr);
74 if (ret == -2) {
75 NS_WARNING(nsPrintfCString("'%s' command timed out.\n", cmd).get());
76 return -2;
77 } else if (ret < 0 || strncmp(reply, "FAIL", 4) == 0) {
78 return -1;
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) {
85 char *pos = reply;
87 while (*pos && *pos != '\n')
88 pos++;
89 *pos = '\0';
92 return 0;
96 // static
97 void*
98 WifiHotspotUtils::GetSharedLibrary()
100 void* wpaClientLib = GetWifiHotspotLibHandle();
101 if (!wpaClientLib) {
102 NS_WARNING("No /system/lib/libwpa_client.so");
104 return wpaClientLib;
107 int32_t WifiHotspotUtils::do_wifi_connect_to_hostapd()
109 struct dirent *dent;
111 DIR *dir = opendir(ctrl_iface_dir);
112 if (dir) {
113 while ((dent = readdir(dir))) {
114 if (strcmp(dent->d_name, ".") == 0 ||
115 strcmp(dent->d_name, "..") == 0) {
116 continue;
118 ctrl_ifname = strdup(dent->d_name);
119 break;
121 closedir(dir);
124 ctrl_conn = openConnection(ctrl_ifname);
125 if (!ctrl_conn) {
126 NS_WARNING(nsPrintfCString("Unable to open connection to hostapd on \"%s\": %s",
127 ctrl_ifname, strerror(errno)).get());
128 return -1;
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);
135 ctrl_conn = nullptr;
136 return -1;
139 return 0;
142 int32_t WifiHotspotUtils::do_wifi_close_hostapd_connection()
144 if (!ctrl_conn) {
145 NS_WARNING("Invalid ctrl_conn.");
146 return -1;
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);
156 ctrl_conn = nullptr;
157 return 0;
160 int32_t WifiHotspotUtils::do_wifi_hostapd_command(const char *command,
161 char *reply,
162 size_t *reply_len)
164 return sendCommand(ctrl_conn, command, reply, reply_len);
167 int32_t WifiHotspotUtils::do_wifi_hostapd_get_stations()
169 char addr[32], cmd[64];
170 int stations = 0;
171 size_t addrLen = sizeof(addr);
173 if (sendCommand(ctrl_conn, "STA-FIRST", addr, &addrLen)) {
174 return 0;
176 stations++;
178 sprintf(cmd, "STA-NEXT %s", addr);
179 while (sendCommand(ctrl_conn, cmd, addr, &addrLen) == 0) {
180 stations++;
181 sprintf(cmd, "STA-NEXT %s", addr);
184 return stations;