Skip to content

Commit

Permalink
Add particle wifi commands
Browse files Browse the repository at this point in the history
  • Loading branch information
keeramis committed May 20, 2024
1 parent d137755 commit 9726a65
Show file tree
Hide file tree
Showing 5 changed files with 433 additions and 23 deletions.
2 changes: 2 additions & 0 deletions src/cli/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ const variable = require('./variable');
const version = require('./version');
const webhook = require('./webhook');
const whoami = require('./whoami');
const wifi = require('./wifi');
const usb = require('./usb');

/**
Expand Down Expand Up @@ -69,6 +70,7 @@ module.exports = function registerAllCommands(context) {
version(context);
webhook(context);
whoami(context);
wifi(context);
usb(context);
alias(context);
};
105 changes: 105 additions & 0 deletions src/cli/wifi.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
const unindent = require('../lib/unindent');

module.exports = ({ commandProcessor, root }) => {
const wifi = commandProcessor.createCategory(root, 'wifi', 'Configure Wi-Fi credentials to your device(s)');

const portOption = {
'port': {
describe: 'Use this serial port instead of auto-detecting. Useful if there are more than 1 connected device'
}
};

commandProcessor.createCommand(wifi, 'add', 'Adds a WiFi network to your device', {
options: Object.assign({
'file': {
description: 'Take the credentials from a JSON file instead of prompting for them'
}
}, portOption),
handler: (args) => {
const WiFiCommands = require('../cmd/wifi');
return new WiFiCommands().addNetwork(args);
},
examples: {
'$0 $command': 'Prompt for Wi-Fi credentials and send them to a device',
'$0 $command --file credentials.json': 'Read Wi-Fi credentials from credentials.json and send them to a device'
},
epilogue: unindent(`
The JSON file for passing Wi-Fi credentials should look like this:
{
"network": "my_ssid",
"security": "WPA2_AES",
"password": "my_password"
}
The security property can be NONE, WEP, WPA2_AES, WPA2_TKIP, WPA2_AES+TKIP, WPA_AES, WPA_TKIP, WPA_AES+TKIP.
For enterprise Wi-Fi, set security to WPA_802.1x or WPA2_802.1x and provide the eap, username, outer_identity, client_certificate, private_key and root_ca properties.
`)
});

commandProcessor.createCommand(wifi, 'join', 'Joins a wifi network', {
options: Object.assign({
'file': {
description: 'Take the credentials from a JSON file instead of prompting for them'
},
'ssid': {
description: 'The name of the network to join'
},
}, portOption),
handler: (args) => {
const WiFiCommands = require('../cmd/wifi');
if (args.ssid) {
return new WiFiCommands().joinKnownNetwork(args);
}
return new WiFiCommands().joinNetwork(args);
},
examples: {
'$0 $command': 'Prompt for Wi-Fi credentials and send them to a device',
'$0 $command --file credentials.json': 'Read Wi-Fi credentials from credentials.json and send them to a device'
},
epilogue: unindent(`
The JSON file for passing Wi-Fi credentials should look like this:
{
"network": "my_ssid",
"security": "WPA2_AES",
"password": "my_password"
}
The security property can be NONE, WEP, WPA2_AES, WPA2_TKIP, WPA2_AES+TKIP, WPA_AES, WPA_TKIP, WPA_AES+TKIP.
For enterprise Wi-Fi, set security to WPA_802.1x or WPA2_802.1x and provide the eap, username, outer_identity, client_certificate, private_key and root_ca properties.
`)
});

commandProcessor.createCommand(wifi, 'clear', 'Clears the list of wifi credentials on your device', {
handler: () => {
const WiFiCommands = require('../cmd/wifi');
return new WiFiCommands().clearNetworks();
},
examples: {
'$0 $command': 'Clears the list of wifi credentials on your device',
}
});

commandProcessor.createCommand(wifi, 'list', 'Lists the wifi networks on your device', {
handler: () => {
const WiFiCommands = require('../cmd/wifi');
return new WiFiCommands().listNetworks();
},
examples: {
'$0 $command': 'Clears the list of wifi credentials on your device',
}
});

commandProcessor.createCommand(wifi, 'remove', 'Removes a network from the device', {
params: '<ssid>',
handler: (args) => {
const WiFiCommands = require('../cmd/wifi');
return new WiFiCommands().removeNetwork(args.params.ssid);
},
examples: {
'$0 $command ssid': 'Removes network from the device',
}
});

return wifi;
};

7 changes: 6 additions & 1 deletion src/cmd/serial.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ const FlashCommand = require('./flash');
const usbUtils = require('./usb-util');
const { platformForId } = require('../lib/platform');
const { FirmwareModuleDisplayNames } = require('particle-usb');
const WifiControlRequest = require('../lib/wifi-control-request');
const semver = require('semver');

const IDENTIFY_COMMAND_TIMEOUT = 20000;
Expand Down Expand Up @@ -532,6 +531,12 @@ module.exports = class SerialCommand extends CLICommandBase {
throw new VError('The device does not support Wi-Fi');
}

const fwVer = device.firmwareVersion;
if (semver.gte(fwVer, '6.2.0')) {
this.ui.stdout.write(`[Recommendation]${os.EOL}Use the improved Wi-Fi configuration commands for this device-os version (>= 6.2.0).${os.EOL}See 'particle wifi --help' for more details on available commands.${os.EOL}`);
this.ui.stdout.write(`${os.EOL}`);
}

// configure serial
if (file){
return this._configWifiFromFile(deviceFromSerialPort, file);
Expand Down
40 changes: 40 additions & 0 deletions src/cmd/wifi.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
const WifiControlRequest = require('../lib/wifi-control-request');
const CLICommandBase = require('./base');
const spinnerMixin = require('../lib/spinner-mixin');

// add checks that if the device < 6.2.0, then use the old wifi command

module.exports = class WiFiCommands extends CLICommandBase {
constructor() {
super();
spinnerMixin(this);
this.wifiControlRequest = new WifiControlRequest(null, { ui: this.ui, newSpin: this.newSpin, stopSpin: this.stopSpin });
}

addNetwork(args) {
this.wifiControlRequest.file = args.file;
return this.wifiControlRequest.addNetwork();
}

joinNetwork(args) {
this.wifiControlRequest.file = args.file;
return this.wifiControlRequest.joinNetwork();
}

joinKnownNetwork(args) {
this.wifiControlRequest.file = args.file;
return this.wifiControlRequest.joinKnownNetwork({ ssid: args.ssid });
}

clearNetworks() {
return this.wifiControlRequest.clearNetworks();
}

listNetworks() {
return this.wifiControlRequest.listNetworks();
}

removeNetwork(ssid) {
return this.wifiControlRequest.removeNetwork(ssid);
}
}
Loading

0 comments on commit 9726a65

Please sign in to comment.