-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathwifi.js
143 lines (130 loc) · 4.68 KB
/
wifi.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
var run = require('./run.js');
var platform = require('./platform.js');
exports.getStatus = getStatus;
exports.getConnectedNetwork = getConnectedNetwork;
exports.scan = scan;
exports.startAP = startAP;
exports.stopAP = stopAP;
exports.defineNetwork = defineNetwork;
exports.getKnownNetworks = getKnownNetworks;
/*
* Determine whether we have a wifi connection with the `wpa_cli
* status` command. This function returns a Promise that resolves to a
* string. On my Rasberry Pi, the string is "DISCONNECTED" or
* "INACTIVE" when there is no connection and is "COMPLETED" when
* there is a connection. There are other possible string values when
* a connection is being established
*/
function getStatus() {
return run(platform.getStatus);
}
/*
* Determine the ssid of the wifi network we are connected to.
* This function returns a Promise that resolves to a string.
* The string will be empty if not connected.
*/
function getConnectedNetwork() {
return run(platform.getConnectedNetwork);
}
/*
* Scan for available wifi networks using `iwlist wlan0 scan`.
* Returns a Promise that resolves to an array of strings. Each string
* is the ssid of a wifi network. They are sorted by signal strength from
* strongest to weakest. On a Raspberry Pi, a scan seems to require root
* privileges.
*
* On a Raspberry Pi 3, this function works when the device is in AP mode.
* The Intel Edison, however, cannot scan while in AP mode: iwlist fails
* with an error. iwlist sometimes also fails with an error when the
* hardware is busy, so this function will try multiple times if you
* pass a number. If all attempts fail, the promise is resolved to
* an empty array.
*/
function scan(numAttempts) {
numAttempts = numAttempts || 1;
return new Promise(function(resolve, reject) {
var attempts = 0;
function tryScan() {
attempts++;
_scan()
.then(out => { resolve(out.length ? out.split('\n') : []);})
.catch(err => {
console.error('Scan attempt', attempts, 'failed:', err.message||err);
if (attempts >= numAttempts) {
console.error('Giving up. No scan results available.');
resolve([]);
return;
}
else {
console.error('Will try again in 3 seconds.');
setTimeout(tryScan, 3000);
}
});
}
tryScan();
});
function _scan() {
return run(platform.scan)
}
}
/*
* Enable an access point that users can connect to to configure the device.
*
* This command runs different commands on Raspbery Pi Rasbian and Edison Yocto.
*
* It requires that hostapd and udhcpd are installed on the system but not
* enabled, so that they do not automatically run when the device boots up.
* It also requires that hostapd and udhcpd have appropriate config files
* that define the ssid for the wifi network to be created, for example.
* Also, the udhcpd config file should be set up to work with 10.0.0.1 as
* the IP address of the device.
*
* XXX
* It would probably be better if the IP address, SSID and password were
* options to this function rather than being hardcoded in system config
* files. (Each device ought to be able to add a random number to its
* SSID, for example, so that when you've got multiple devices they don't
* all try to create the same network).
*
* This function returns a Promise that resolves when the necessary
* commands have been run. This does not necessarily mean that the AP
* will be functional, however. The setup process might take a few
* seconds to complete before the user will be able to see and connect
* to the network.
*/
function startAP() {
return run(platform.startAP);
}
/*
* Like startAP(), but take the access point down, using platform-dependent
* commands.
*
* Returns a promise that resolves when the commands have been run. At
* this point, the AP should be in the process of stopping but may not
* yet be completely down.
*/
function stopAP() {
return run(platform.stopAP);
}
/*
* This function uses wpa_cli to add the specified network ssid and password
* to the wpa_supplicant.conf file. This assumes that wpa_supplicant is
* configured to run automatically at boot time and is configured to work
* with wpa_cli.
*
* If the system is not connected to a wifi network, calling this
* command with a valid ssid and password should cause it to connect.
*/
function defineNetwork(ssid, password) {
return run(password ? platform.defineNetwork : platform.defineOpenNetwork, {
SSID: ssid,
PSK: password
});
}
/*
* Return a Promise that resolves to an array of known wifi network names
*/
function getKnownNetworks() {
return run(platform.getKnownNetworks)
.then(out => out.length ? out.split('\n') : []);
}