Skip to content
Draft
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,7 @@ function someHandleCredsFunction ({ ssid, password }) {
}
```



### Contributions
@Redaphid and @Loqwai helped debug significant issues/errors with this package, related to improperly advertising data and flags inside the repository: https://github.com/loqwai/juniper-gardens-twig-debug. Thank you both!
6 changes: 3 additions & 3 deletions improv-wifi-mod/bleservices/improv.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@
"type": "Uint8Array",
"maxBytes": 20,
"permissions": "write",
"properties": "write"
"properties": "write,writeNoResponse"
},
"RPC_RESULT": {
"uuid": "00467768-6228-2272-4663-277478268004",
"type": "Uint8Array",
"type": "Uint8",
"maxBytes": 20,
"permissions": "read",
"properties": "notify"
Expand All @@ -40,4 +40,4 @@
}
}
}
}
}
65 changes: 37 additions & 28 deletions improv-wifi-mod/improv-wifi-mod.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import BLEExports from './consts';
const StateCodes = BLEExports.StateCodes;
const ErrorCodes = BLEExports.ErrorCodes;
const Commands = BLEExports.Commands;

// FYI class definition for BLEServer can be found @ <moddable-project-dir>/modules/network/ble/bleserver.js
export default class ImprovWifi extends BLEServer {
deviceName;
ssid;
Expand All @@ -23,53 +25,47 @@ export default class ImprovWifi extends BLEServer {
this.onCredentialsRecieved = onCredentialsRecieved;
}
startImprov() {
trace("Starting Improv\n");
let advertisingData = {
flags: GAP.ADFlag.LE_GENERAL_DISCOVERABLE_MODE,
completeUUID128List: [uuid `00467768-6228-2272-4663-277478268000`],
completeName: this.deviceName,
shortName: this.deviceName,
serviceDataUUID128: [uuid `00467768-6228-2272-4663-277478268000`],
completeUUID128List: [
uuid `00467768-6228-2272-4663-277478268000`,
uuid `00467768-6228-2272-4663-277478268001`,
uuid `00467768-6228-2272-4663-277478268002`,
uuid `00467768-6228-2272-4663-277478268003`,
uuid `00467768-6228-2272-4663-277478268004`,
uuid `00467768-6228-2272-4663-277478268005`
],
solicitationUUID128List: [
uuid `00467768-6228-2272-4663-277478268000`,
uuid `00467768-6228-2272-4663-277478268001`,
uuid `00467768-6228-2272-4663-277478268002`,
uuid `00467768-6228-2272-4663-277478268003`,
uuid `00467768-6228-2272-4663-277478268004`,
uuid `00467768-6228-2272-4663-277478268005`
]
};
this.startAdvertising({ advertisingData });
}
onDisconnected() {
trace("Disconnected\n");
this.state = StateCodes.STATE_AUTHORIZED;
this.error = ErrorCodes.ERROR_NONE;
this.errorCharacteristic = null;
this.stateCharacteristic = null;
this.startImprov();
}
onReady() {
trace("Ready\n");
this.startImprov();
}
onCharacteristicRead(characteristic) {
if (characteristic.name === "STATE") {
return this.state;
}
if (characteristic.name === "ERROR") {
return this.error;
trace(`Read: ${JSON.stringify(characteristic)}\n`);
switch(characteristic.name){
case "ERROR":
return this.error;
case "STATE":
case "RPC_RESULT":
return this.state;
default:
trace(`I have no idea what ${characteristic.name} is supposed to be`);
return this.error
}
}
onConnected() {
trace("Connected\n");
this.state = StateCodes.STATE_AUTHORIZED;
this.error = ErrorCodes.ERROR_NONE;
}
onCharacteristicNotifyDisabled(characteristic) {
trace('onCharacteristicNotifyDisabled\n');
switch (characteristic.name) {
case 'STATE':
this.stateCharacteristic = null;
Expand All @@ -89,6 +85,7 @@ export default class ImprovWifi extends BLEServer {
}
}
onCharacteristicNotifyEnabled(characteristic) {
trace(`onCharacteristicNotifyEnabled: characteristic: ${characteristic.name} \n`);
this.notify = characteristic;
switch (characteristic.name) {
case 'STATE':
Expand All @@ -114,11 +111,13 @@ export default class ImprovWifi extends BLEServer {
}
}
onCharacteristicWritten(characteristic, value) {
trace(`Written: ${characteristic.name}, in state ${characteristic.state}, with value ${value}, value[0] is ${value?.[0]}, which is a type ${typeof value?.[0]} \n`);
// this is where we go and update state again if necessary
switch (characteristic.name) {
case "RPC_COMMAND":
this.ssid = value;
if (value[0] === Commands.WIFI_SETTINGS) {
trace("Handling wifi settings\n");
this.state = StateCodes.STATE_PROVISIONING;
this.notifyState();
this.handleInboundWifiSettings(value);
Expand All @@ -135,6 +134,7 @@ export default class ImprovWifi extends BLEServer {
}
}
handleInboundWifiSettings(data) {
trace("Handling inbound wifi settings\n");
const ssid_length = data[2];
const ssid_start = 3;
const ssid_end = ssid_start + ssid_length;
Expand All @@ -144,33 +144,42 @@ export default class ImprovWifi extends BLEServer {
const ssid = this.buildValue(data, ssid_start, ssid_end);
const password = this.buildValue(data, pass_start, pass_end);
let result = this.onCredentialsRecieved({ ssid, password });
trace(`Result of onCredentialsRecieved is ${result}\n`);
if (!result) {
this.state = StateCodes.STATE_AUTHORIZED;
this.notifyState();
}
else {
this.state = StateCodes.STATE_PROVISIONED;
this.notifyState();
trace("Credentials weren't authorized :( \n");
this.state = StateCodes.ERROR_UNKNOWN;
this.error = ErrorCodes.ERROR_NOT_AUTHORIZED;
this.notifyError();
return;

}
trace("Credentials were authorized :) \n");
this.state = StateCodes.STATE_PROVISIONED;
this.notifyState();
}
buildValue(data, start, end) {
trace(`Building value from ${start} to ${end}\n`);
let str = '';
for (var i = start; i < end; i++) {
str += String.fromCharCode(data[i]);
}
return str;
}
notifyState() {
trace(`Notifying state: ${this.state}\n`);
if (!this.stateCharacteristic)
return;
this.notifyValue(this.stateCharacteristic, this.state);
}
notifyError() {
trace(`Notifying this characteristic: ${this.errorCharacteristic?.name} this error: ${this.error}\n`);
if (!this.errorCharacteristic)
return;

this.notifyValue(this.errorCharacteristic, this.error);
}
couldNotConnect() {
trace("Could not connect\n");
this.error = ErrorCodes.ERROR_UNABLE_TO_CONNECT;
this.notifyError();
}
Expand Down
30 changes: 4 additions & 26 deletions improv-wifi-mod/manifest.json
Original file line number Diff line number Diff line change
@@ -1,40 +1,18 @@
{
"build": {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This might be needed to support custom board configurations

"SDKCONFIGPATH": "./sdkconfig",
"PARTITIONS_FILE": "./partitions.csv"
},
"include": [
"$(MODDABLE)/examples/manifest_base.json",
"$(MODDABLE)/examples/manifest_net.json",
"$(MODDABLE)/modules/network/ble/manifest_server.json"
],
"preload": [
"improv-wifi-mod",
"improv-wifi-mod",
"btutils",
"gap",
"gap",
"./bleservices/*"
],
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this is where custom pin redefinitions should go

"platforms": {
"esp32": {
"defines": {
"i2c": {
"sda_pin": 21,
"scl_pin": 22
},
},
"modules": {
"*": [
"$(MODULES)/drivers/neopixel/esp32/*"
]
}
},
"...": {
"error": "platform unsupported"
}
},
],
"modules": {
"*": [
"./*"
]
}
}
}
39 changes: 13 additions & 26 deletions src/improv-wifi-mod.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import BLEServer from "bleserver";
import GAP from 'gap'
import {uuid} from "btutils";
import { uuid } from "btutils";
import BLEExports from './consts'

const StateCodes = BLEExports.StateCodes
Expand Down Expand Up @@ -29,26 +29,10 @@ export default class ImprovWifi extends BLEServer {
startImprov() {
let advertisingData = {
flags: GAP.ADFlag.LE_GENERAL_DISCOVERABLE_MODE,
completeUUID128List: [uuid `00467768-6228-2272-4663-277478268000`],
completeName: this.deviceName,
shortName:this.deviceName,
serviceDataUUID128: [uuid`00467768-6228-2272-4663-277478268000`],
completeUUID128List: [
uuid`00467768-6228-2272-4663-277478268000`,
uuid`00467768-6228-2272-4663-277478268001`,
uuid`00467768-6228-2272-4663-277478268002`,
uuid`00467768-6228-2272-4663-277478268003`,
uuid`00467768-6228-2272-4663-277478268004`,
uuid`00467768-6228-2272-4663-277478268005`
],
solicitationUUID128List: [
uuid`00467768-6228-2272-4663-277478268000`,
uuid`00467768-6228-2272-4663-277478268001`,
uuid`00467768-6228-2272-4663-277478268002`,
uuid`00467768-6228-2272-4663-277478268003`,
uuid`00467768-6228-2272-4663-277478268004`,
uuid`00467768-6228-2272-4663-277478268005`
]
}
shortName: this.deviceName,
};
this.startAdvertising({ advertisingData });
}

Expand All @@ -65,13 +49,16 @@ export default class ImprovWifi extends BLEServer {
}

onCharacteristicRead(characteristic: Characteristic) {
if(characteristic.name === "STATE") {
return this.state
}

if(characteristic.name === "ERROR") {
switch(characteristic.name){
case "ERROR":
return this.error;
case "STATE":
case "RPC_RESULT":
return this.state;
default:
trace(`I have no idea what ${characteristic.name} is supposed to be`)
return this.error
}
}
}

onConnected() {
Expand Down
4 changes: 2 additions & 2 deletions src/improv.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@
"type": "Uint8Array",
"maxBytes": 20,
"permissions": "write",
"properties": "write"
"properties": "write,writeNoResponse"
},
"RPC_RESULT": {
"uuid": "00467768-6228-2272-4663-277478268004",
"type": "Uint8Array",
"type": "Uint8",
"maxBytes": 20,
"permissions": "read",
"properties": "notify"
Expand Down