92 |
93 |
94 |
--------------------------------------------------------------------------------
/src/ble.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: base
3 | title: Improv via BLE
4 | description: All the implementation details necessary to make your own client and service implementation.
5 | ---
6 |
7 | This is the description of the Improv Wi-Fi protocol using Bluetooth Low Energy.
8 |
9 | The protocol has two actors: the Improv service running on the gadget and the Improv client.
10 |
11 | The Improv service will broadcast its presence via Bluetooth LE and receives Wi-Fi credentials from the client.
12 |
13 | The Improv client detects the service via Bluetooth LE and will offer the user to send Wi-Fi credentials.
14 |
15 | ## Improv Service
16 |
17 | The Improv service runs on a gadget that needs to connect to the internet but has no credentials or is unable to establish a connection.
18 |
19 | The Improv service can optionally require physical authorization to allow pairing, like pressing a button. It is up to the gadget to decide if and what interaction to pick. A gadget that does not require authorization should start in the "authorized" state.
20 |
21 | If an Improv service has been authorized by a user interaction, the authorization should be automatically revoked after a timeout. This timeout is up to the gadget but we suggest 1 minute.
22 |
23 | A user is able to send Wi-Fi credentials to an authorized service. The gadget will attempt to connect to the specified wireless network. If the connection is successful, the state changes to "provisioned", the gadget can optionally return a URL to the client to finish onboarding and the Improv service is stopped.
24 |
25 | If the gadget is unable to connect an error is returned. If the gadget required authorization, the authorization reset timeout should start over.
26 |
27 | 
28 |
29 | The client is able to send an `identify` command to the Improv service if it is in the states "Require Authorization" and "Authorized". When received, and enabled, the gadget will identify itself, like playing a sound or flashing a light. It is up to the gadget to decide if and what interaction to pick.
30 |
31 | ## Revision history
32 |
33 | - 1.0 - Initial release
34 | - 2.0 - Added Service Data `4677`
35 |
36 | ## GATT Services
37 |
38 | ### Characteristic: Capabilities
39 |
40 | Characteristic UUID: `00467768-6228-2272-4663-277478268005`
41 |
42 | This characteristic has binary encoded byte(s) of the device’s capabilities.
43 |
44 | | Bit (LSB) | Capability |
45 | | --------- | ---------------------------------------------- |
46 | | `0` | 1 if the device supports the identify command. |
47 |
48 | ### Characteristic: Current State
49 |
50 | Characteristic UUID: `00467768-6228-2272-4663-277478268001`
51 |
52 | This characteristic will hold the current status of the provisioning service and will write and notify any listening clients for instant feedback.
53 |
54 | | Value | State | Purpose |
55 | | ------ | ---------------------- | ------------------------------------------------ |
56 | | `0x01` | Authorization Required | Awaiting authorization via physical interaction. |
57 | | `0x02` | Authorized | Ready to accept credentials. |
58 | | `0x03` | Provisioning | Credentials received, attempt to connect. |
59 | | `0x04` | Provisioned | Connection successful. |
60 |
61 | ### Characteristic: Error state
62 |
63 | Characteristic UUID: `00467768-6228-2272-4663-277478268002`
64 |
65 | This characteristic will hold the current error of the provisioning service and will write and notify any listening clients for instant feedback.
66 |
67 | | Value | State | Purpose |
68 | | ------ | ------------------- | --------------------------------------------------------------------------------------- |
69 | | `0x00` | No error | This shows there is no current error state. |
70 | | `0x01` | Invalid RPC packet | RPC packet was malformed/invalid. |
71 | | `0x02` | Unknown RPC command | The command sent is unknown. |
72 | | `0x03` | Unable to connect | The credentials have been received and an attempt to connect to the network has failed. |
73 | | `0x04` | Not Authorized | Credentials were sent via RPC but the Improv service is not authorized. |
74 | | `0xFF` | Unknown Error |
75 |
76 | ### Characteristic: RPC Command
77 |
78 | Characteristic UUID: `00467768-6228-2272-4663-277478268003`
79 |
80 | This characteristic is where the client can write data to call the RPC service.
81 |
82 | Note: if the combined payload is over 20 bytes, it will require multiple BLE packets to transfer the data. Make sure that your code deals with this.
83 |
84 | | Byte | Description |
85 | | ----- | ----------------------------------------------------- |
86 | | 1 | Command (see below) |
87 | | 2 | Data length |
88 | | 3...X | Data |
89 | | X + 3 | Checksum - A simple sum checksum keeping only the LSB |
90 |
91 | #### RPC Command: Send Wi-Fi settings
92 |
93 | Submit Wi-Fi credentials to the Improv Service to attempt to connect to.
94 |
95 | Requires the Improv service to be authorized.
96 |
97 | Command ID: `0x01`
98 |
99 | | Byte | Description |
100 | | ---- | --------------- |
101 | | 01 | command |
102 | | xx | data length |
103 | | yy | ssid length |
104 | | | ssid bytes |
105 | | zz | password length |
106 | | | password bytes |
107 | | CS | checksum |
108 |
109 | Example: SSID = MyWirelessAP, Password = mysecurepassword
110 |
111 | ```
112 | 01 1E 0C {MyWirelessAP} 10 {mysecurepassword} CS
113 | ```
114 |
115 | This command will generate an RPC result. The first entry in the list is an URL to redirect the user to. If there is no URL, omit the entry or add an empty string.
116 |
117 | #### RPC Command: Identify
118 |
119 | What a device actually does when an identify command is received is up to that specific device, but the user should be able to visually or audibly identify the device.
120 |
121 | Command ID: `0x02`
122 |
123 | Does not require the Improv service to be authorized.
124 |
125 | Should only be sent if the capability characteristic indicates that identify is supported.
126 |
127 | | Byte | Description |
128 | | ---- | ---------------------- |
129 | | 02 | command |
130 | | 00 | 0 data bytes / no data |
131 | | CS | checksum |
132 |
133 | This command has no RPC result.
134 |
135 | ### Characteristic: RPC Result
136 |
137 | Characteristic UUID: `00467768-6228-2272-4663-277478268004`
138 |
139 | This characteristic is where the client can read results from the RPC service if it has a result. Results are returned as a list of strings. An empty list is allowed.
140 |
141 | | Byte | Description |
142 | | --------- | ----------------------------------------------------- |
143 | | 1 | Command (see below) |
144 | | 2 | Data length |
145 | | 3 | Length of string 1 |
146 | | 4...X | String 1 |
147 | | X | Length of string 2 |
148 | | X...Y | String 2 |
149 | | ... | etc |
150 | | last byte | Checksum - A simple sum checksum keeping only the LSB |
151 |
152 | ## Bluetooth LE Advertisement
153 |
154 | The device MUST advertise the Service UUID.
155 |
156 | Service UUID: `00467768-6228-2272-4663-277478268000`
157 |
158 | With version 2.0 of the specification:
159 |
160 | - The Service Data and Service UUID MUST be advertised periodically and when the state changes.
161 | - The Service Data and Service UUID MUST be in the same advertisement.
162 | - The Service Data and Service UUID MUST NOT be in the scan response or require active scans.
163 | - If the device cannot fit all of its advertising data in 31 bytes, it should cycle between advertising data.
164 |
165 | ### Service Data format
166 |
167 | Service Data UUID: `4677` (`00004677-0000-1000-8000-00805f9b34fb`)
168 |
169 | | Byte | Description |
170 | | --------- | ----------------------------------------------------- |
171 | | 1 | Current state |
172 | | 2 | Capabilities |
173 | | 3 | 0 (RESERVED) |
174 | | 4 | 0 (RESERVED) |
175 | | 5 | 0 (RESERVED) |
176 | | 6 | 0 (RESERVED) |
177 |
--------------------------------------------------------------------------------
/src/code.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: base
3 | title: Code
4 | description: SDKs and code samples for Improv Wi-Fi clients and services.
5 | ---
6 |
7 | This page contains software development kits (SDK) and code samples to help you get started using Improv Wi-Fi in your projects.
8 |
9 | ## Creating client applications to configure devices
10 |
11 | These examples will help you create clients that can provision devices via Improv.
12 |
13 | ### Bluetooth LE SDK for JavaScript
14 |
15 | The Bluetooth LE SDK for JavaScript contains everything you need to offer Improv provisioning using Bluetooth LE on your website. Simply get started by adding the following HTML snippet:
16 |
17 | ```js
18 |
22 |
23 |
24 | ```
25 |
26 | The result will look like this:
27 |
28 | >
29 |
30 | See [the GitHub repository](https://github.com/improv-wifi/sdk-js) for the documentation, source code, customization examples and how to use it with JavaScript package managers.
31 |
32 | ### Serial SDK for JavaScript
33 |
34 | The Serial SDK for JavaScript contains everything you need to offer Improv provisioning using Serial on your website. See [the GitHub repository](https://github.com/improv-wifi/sdk-serial-js) for the documentation, source code, customization examples and how to use it with JavaScript package managers.
35 |
36 | ### Bluetooth LE SDK for Android
37 |
38 | The Android SDK contains all state management, constants and other helpers required to provision devices via Improv.
39 |
40 | See [the GitHub repository](https://github.com/improv-wifi/sdk-android) for the documentation, source code and demo application.
41 |
42 | ## Creating firmware hosting the Improv service
43 |
44 | ### SDK for C++
45 |
46 | The C++ SDK contains constants and utility functions to parse the packets and help with implementing the Improv service on your device. If you need an example of using the SDK for C++, check this example [here](https://jnthas.github.io/improv-wifi-demo/).
47 |
48 | See [the GitHub repository](https://github.com/improv-wifi/sdk-cpp) for the documentation and source code.
49 |
--------------------------------------------------------------------------------
/src/index.html:
--------------------------------------------------------------------------------
1 | ---
2 | layout: base
3 | description: Free and open standard with ready-made SDKs that offer a great user experience to configure Wi-Fi on devices.
4 | ---
5 |
6 |
10 |
11 |
12 | Improv Wi-Fi is an open standard for connecting devices to Wi-Fi using Bluetooth LE or Serial
13 |
14 |
15 |
16 | Improv is a free and open standard with ready-made SDKs that offer a great
17 | user experience to configure Wi-Fi on devices:
18 |
19 |
20 |
Power on device
21 |
22 | Client application uses Improv to send the Wi-Fi credentials to the device
23 |
24 |
The device connects to Wi-Fi network and returns a URL
25 |
User visits URL to continue setting up the device
26 |
27 |
28 | Improv protocol can be used over Bluetooth Low Energy or via the serial port.
29 | Both protocols can also be used from a browser.
30 |
31 |
32 |
Improv via BLE
33 |
34 |
35 | Your browser is not supported. To try it out, visit this page with Google
36 | Chrome or Microsoft Edge
37 | (but not on your iOS device).
39 |
40 |
41 |
Improv via Serial
42 |
43 |
44 | Your browser is not supported. To try it out, visit this page with Google
45 | Chrome or Microsoft Edge
46 | (but not on your iOS device).
48 |
49 |
50 |
51 |
52 |
53 | Need a device that runs Improv?
54 | Install this example
55 | on an ESP32.
56 |
57 |
Configuring a device to connect to your Wi-Fi network is a pain.
124 |
125 |
126 | A lot of devices require to be connected to the network to be controlled or
127 | receive data. The majority of these devices use Wi-Fi to establish a
128 | connection with a local application or the cloud.
129 |
130 |
131 |
132 | The most common approach is Soft Enabled Access Point. The device starts its
133 | own Wi-Fi access point, the user connects to it with their phone/computer and
134 | then interacts directly with the device via an app or a website served from
135 | the device.
136 |
137 |
138 |
139 | It’s easy for something to go wrong. The user submits incorrect Wi-Fi
140 | credentials or the phone loses access to the access point. In such cases it is
141 | difficult to recover. Phones also have a bad time dealing with access points
142 | that don’t provide internet access.
143 |
144 |
145 |
Scope & Constraints
146 |
147 | The goal of the Improv standard is to get the device connected to the Wi-Fi
148 | via Bluetooth Low Energy (BLE) or Serial (USB/UART). It is not the goal to
149 | offer a way for devices to share data or control. The standard should work
150 | without requiring the device to contain a screen.
151 |
152 |
153 |
More Reading
154 |
155 |
156 |
157 | Read the Bluetooth LE or
158 | serial documentation to see how it works
159 |
162 |
163 |
177 |
--------------------------------------------------------------------------------
/src/serial.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: base
3 | title: Improv via Serial
4 | description:
5 | ---
6 |
7 | This is the description of the Improv Wi-Fi protocol using a serial port.
8 |
9 | The device needs to be connected to the computer via a USB/UART serial port.
10 |
11 | The protocol has two actors: the Improv service running on the gadget and the Improv client.
12 |
13 | The Improv service will receive Wi-Fi credentials from the client via the serial connection.
14 |
15 | The Improv client asks for the current state and sends the Wi-Fi credentials.
16 |
17 | ## Packet format
18 |
19 | All packets are sent in the following format:
20 |
21 | | Byte | Purpose |
22 | | ------ | ------------------------------- |
23 | | 1-6 | Header will equal `IMPROV` |
24 | | 7 | Version CURRENT VERSION = `1` |
25 | | 8 | Type (see below) |
26 | | 9 | Length |
27 | | 10...X | Data |
28 | | X + 10 | Checksum |
29 |
30 | The packet types are:
31 |
32 | | Type | Description | Direction
33 | | ---- | ----------- | --------
34 | | `0x01 ` | Current state | Device to Client
35 | | `0x02 ` | Error state | Device to Client
36 | | `0x03 ` | RPC Command | Client to Device
37 | | `0x04 ` | RPC Result | Device to Client
38 |
39 | ## Packet: Current State
40 |
41 | Type: `0x01`
42 | Direction: Device to Client
43 |
44 | The data of this packet is a single byte and contains the current status of the provisioning service. It is to be written to any listening clients for instant feedback.
45 |
46 | | Byte | Description |
47 | | ---- | ---------------- |
48 | | 1 | current state |
49 |
50 | The current state can be the following values:
51 |
52 | | Value | State | Purpose |
53 | | ------ | ---------------------- | ------------------------------------------------ |
54 | | `0x02` | Ready (Authorized) | Ready to accept credentials. |
55 | | `0x03` | Provisioning | Credentials received, attempt to connect. |
56 | | `0x04` | Provisioned | Connection successful. |
57 |
58 |
59 | ## Packet: Error state
60 |
61 | Type: `0x02`
62 | Direction: Device to client
63 |
64 | The data of this packet is a single byte and contains the current status of the provisioning service. Whenever it changes the device needs to sent it to any listening clients for instant feedback.
65 |
66 | | Byte | Description |
67 | | ---- | ---------------- |
68 | | 1 | error state |
69 |
70 | Error state can be the following values:
71 |
72 | | Value | State | Purpose |
73 | | ------ | ------------------- | --------------------------------------------------------------------------------------- |
74 | | `0x00` | No error | This shows there is no current error state. |
75 | | `0x01` | Invalid RPC packet | RPC packet was malformed/invalid. |
76 | | `0x02` | Unknown RPC command | The command sent is unknown. |
77 | | `0x03` | Unable to connect | The credentials have been received and an attempt to connect to the network has failed. |
78 | | `0xFF` | Unknown Error | |
79 |
80 | ## Packet: RPC Command
81 |
82 | Type: `0x03`
83 | Direction: Client to device
84 |
85 | This packet type is used for the client to send commands to the device. When an RPC command is sent, the device should sent an update to the client to set the error state to 0 (no error). The response will either be an RPC result packet or an error state update.
86 |
87 | | Byte | Description |
88 | | ----- | ----------------------------------------------------- |
89 | | 1 | Command (see below) |
90 | | 2 | Data length |
91 | | 3...X | Data |
92 |
93 | ### RPC Command: Send Wi-Fi settings
94 |
95 | Submit Wi-Fi credentials to the Improv Service to attempt to connect to.
96 |
97 | Type: `0x03`
98 | Command ID: `0x01`
99 |
100 | | Byte | Description |
101 | | ----- | ---------------- |
102 | | 1 | command (`0x01`) |
103 | | 2 | data length |
104 | | 3 | ssid length |
105 | | 4...X | ssid bytes |
106 | | X | password length |
107 | | X...Y | password bytes |
108 |
109 | Example: SSID = MyWirelessAP, Password = mysecurepassword
110 |
111 | ```
112 | 01 1E 0C {MyWirelessAP} 10 {mysecurepassword}
113 | ```
114 |
115 | This command will generate an RPC result. The first entry in the list is an URL to redirect the user to. If there is no URL, omit the entry or add an empty string.
116 |
117 | ### RPC Command: Request current state
118 |
119 | Sends a request for the device to send the current state of improv to the client.
120 |
121 | Type: `0x03`
122 | Command ID: `0x02`
123 |
124 | | Byte | Description |
125 | | ---- | ---------------- |
126 | | 1 | command (`0x02`) |
127 | | 2 | data length (`0`)|
128 |
129 | This command will trigger at least one packet, the `Current State` (see above) and if already provisioned, the same response you would get if device provisioning was successful (see below).
130 |
131 | ### RPC Command: Request device information
132 |
133 | Sends a request for the device to send information about itself.
134 |
135 | Type: `0x03`
136 | Command ID: `0x03`
137 |
138 | | Byte | Description |
139 | | ---- | ---------------- |
140 | | 1 | command (`0x03`) |
141 | | 2 | data length (`0`)|
142 |
143 | This command will trigger one packet, the `Device Information` formatted as a RPC result. This result will contain at least 4 strings.
144 |
145 | Order of strings: Firmware name, firmware version, hardware chip/variant, device name.
146 |
147 | Example: `ESPHome`, `2021.11.0`, `ESP32-C3`, `Temperature Monitor`.
148 |
149 | ### RPC Command: Request scanned Wi-Fi networks
150 |
151 | Sends a request for the device to send the Wi-Fi networks it sees.
152 |
153 | Type: `0x03`
154 | Command ID: `0x04`
155 |
156 | | Byte | Description |
157 | | ---- | ---------------- |
158 | | 1 | command (`0x04`) |
159 | | 2 | data length (`0`)|
160 |
161 | This command will trigger at least one RPC Response. Each response will contain at least 3 strings.
162 |
163 | Order of strings: Wi-Fi SSID, RSSI, Auth required.
164 |
165 | Example: `MyWirelessNetwork`, `-60`, `YES`.
166 |
167 | The final response (or the first if no networks are found) will have 0 strings in the body.
168 |
169 | ## Packet: RPC Result
170 |
171 | Type: `0x04`
172 | Direction: Device to client
173 |
174 | This packet type contains the response to an RPC command. Results are returned as a list of strings. An empty list is allowed.
175 |
176 | | Byte | Description |
177 | | --------- | ----------------------------------------------------- |
178 | | 1 | Command being responded to (see above) |
179 | | 2 | Data length |
180 | | 3 | Length of string 1 |
181 | | 4...X | String 1 |
182 | | X | Length of string 2 |
183 | | X...Y | String 2 |
184 | | ... | etc |
185 |
--------------------------------------------------------------------------------