Skip to content

Commit 8161823

Browse files
committed
Fixes to wifi_provisioner
1 parent 137b88b commit 8161823

6 files changed

Lines changed: 278 additions & 187 deletions

File tree

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,30 @@
11
# Add provisioning libary
22
add_library(wifi_prov_lib INTERFACE)
33
target_sources(wifi_prov_lib INTERFACE
4-
${CMAKE_CURRENT_LIST_DIR}/wifi_prov_lib.c
5-
)
4+
${CMAKE_CURRENT_LIST_DIR}/wifi_prov_lib.c
5+
)
66
target_include_directories(wifi_prov_lib INTERFACE
7-
${CMAKE_CURRENT_LIST_DIR}
8-
)
7+
${CMAKE_CURRENT_LIST_DIR}
8+
)
99
target_link_libraries(wifi_prov_lib INTERFACE
1010
pico_stdlib
1111
pico_btstack_ble
1212
pico_btstack_cyw43
13-
pico_cyw43_arch_lwip_threadsafe_background
1413
hardware_flash
15-
)
14+
)
1615
pico_btstack_make_gatt_header(wifi_prov_lib INTERFACE "${CMAKE_CURRENT_LIST_DIR}/provisioning.gatt")
1716

18-
# Standalone example which uses the provisioning libary to allow credentials to be set over BLE
17+
# Example which uses the provisioning libary to allow credentials to be set over BLE
1918
add_executable(wifi_provisioner
2019
example.c
21-
)
20+
)
2221
target_link_libraries(wifi_provisioner
2322
pico_stdlib
2423
wifi_prov_lib
25-
)
24+
pico_lwip_iperf
25+
pico_cyw43_arch_lwip_threadsafe_background
26+
)
2627
target_include_directories(wifi_provisioner PRIVATE
2728
${CMAKE_CURRENT_LIST_DIR}
28-
${CMAKE_CURRENT_LIST_DIR}/.. # For our common btstack config
29-
)
30-
29+
)
3130
pico_add_extra_outputs(wifi_provisioner)
32-
Lines changed: 76 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,78 @@
11
### BLE wifi provisioning
22

3-
This example demonstrates provisioning wifi credentials using bluetooth low energy. The pico saves the most recent set of succesful credentials in flash for future use. Upon powering, the pico attemps to connect using the saved credentials. If this fails, the pico sets up a GATT server which you can connect to using a mobile BLE scanner app or the attached python script. The GATT server has 2 custom characteritics - one for ssid and one for password. To write to these characteristics you can run 'python3 set_credentials.py ssid password address'.
3+
This example demonstrates provisioning wifi credentials using bluetooth low energy.
4+
The pico saves the most recent set of succesful credentials in flash for future use.
5+
Upon powering, the pico attemps to connect using the saved credentials.
6+
If this fails, the pico sets up a GATT server which you can connect to using a mobile BLE scanner app or the attached python script.
7+
The GATT server has 2 custom characteritics, one for ssid and one for password.
8+
To write to these characteristics you can run 'python3 set_credentials.py ssid password address'.
9+
To run set_credentials.py you have to install the "bleak" python library, e.g...
10+
11+
```
12+
python3 -m venv venv
13+
. venv/bin/activate
14+
pip install bleak
15+
```
16+
17+
From the on you just need to activate the python virtual environment
18+
19+
```
20+
. venv/bin/activate
21+
```
22+
23+
It takes 3 parameters, the ssid name, the password and the Bluetooth address of the device running this example, e.g.
24+
25+
```
26+
python set_credentials.py "my ssid" "my password" 2C:CF:67:BE:08:05
27+
submitted ssid: my ssid
28+
submitted password: my password
29+
submitted address: 2C:CF:67:BE:08:05
30+
Connected: True
31+
Writing SSID...
32+
Writing password...
33+
```
34+
35+
The example waits 3s for you to press `W` when it starts to make it wipe any stored ssid and password to help testing.
36+
37+
On the pico you should something like this...
38+
39+
```
40+
Waiting to receive ssid and password via BLE
41+
Identity resolving failed
42+
Connection complete
43+
Pairing started
44+
Just Works requested
45+
Pairing complete, success
46+
Setting SSID
47+
Current saved SSID: "my ssid"
48+
Current saved password length: 0
49+
Setting password
50+
Current saved SSID: "my ssid"
51+
Current saved password length: 7
52+
connect status: joining
53+
connect status: no ip
54+
connect status: link up
55+
Succesfully provisioned credentials using wifi_prov_lib!
56+
finished provisioning result=0
57+
58+
Ready, running iperf server at 10.3.194.230
59+
```
60+
61+
When connected to the internet the example runs iperf.
62+
Press "D" to disconnect and the pico will reboot.
63+
The next time it connects it should retrieve the ssid and password details from flash.
64+
65+
```
66+
Read credentials
67+
Current saved SSID: "my ssid"
68+
BTstack up and running on 2C:CF:67:BE:08:05.
69+
Current saved password length: 7
70+
71+
connect status: joining
72+
connect status: no ip
73+
connect status: link up
74+
Connected.
75+
finished provisioning result=0
76+
77+
Ready, running iperf server at 10.3.194.230
78+
```
Lines changed: 79 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,85 @@
1+
/**
2+
* Copyright (c) 2026 Raspberry Pi (Trading) Ltd.
3+
*
4+
* SPDX-License-Identifier: BSD-3-Clause
5+
*/
6+
17
#include <stdio.h>
2-
#include <wifi_prov_lib.h>
8+
#include "pico/stdlib.h"
9+
#include "pico/cyw43_arch.h"
10+
#include "hardware/watchdog.h"
11+
#include "lwip/apps/lwiperf.h"
12+
#include "wifi_prov_lib.h"
13+
14+
#ifndef PROV_TIMEOUT_MS
15+
#define PROV_TIMEOUT_MS 120000
16+
#endif
17+
18+
// Report IP results
19+
static void iperf_report(void *arg, enum lwiperf_report_type report_type,
20+
const ip_addr_t *local_addr, u16_t local_port, const ip_addr_t *remote_addr, u16_t remote_port,
21+
u32_t bytes_transferred, u32_t ms_duration, u32_t bandwidth_kbitpsec) {
22+
static uint32_t total_iperf_megabytes = 0;
23+
uint32_t mbytes = bytes_transferred / 1024 / 1024;
24+
float mbits = bandwidth_kbitpsec / 1000.0;
25+
total_iperf_megabytes += mbytes;
326

27+
printf("Completed iperf transfer of %d MBytes @ %.1f Mbits/sec\n", mbytes, mbits);
28+
printf("Total iperf megabytes since start %d Mbytes\n", total_iperf_megabytes);
29+
}
30+
31+
// Note: This is called from an interrupt handler
32+
void key_pressed_func(void *param) {
33+
int key = getchar_timeout_us(0); // get any pending key press but don't wait
34+
if (key == 'd' || key == 'D') {
35+
bool *exit = (bool*)param;
36+
*exit = true;
37+
}
38+
}
439

540
int main(void) {
41+
stdio_init_all();
42+
43+
// This is for testing
44+
printf("Press 'w' in the next 3s to wipe stored ssid and password\n");
45+
int c = getchar_timeout_us(3000000);
46+
if (c == 'w' || c == 'W') {
47+
printf("Wiping stored ssid and password\n");
48+
erase_credentials();
49+
}
50+
51+
// initialize CYW43 driver architecture (will enable BT because CYW43_ENABLE_BLUETOOTH == 1)
52+
if (cyw43_arch_init()) {
53+
printf("failed to initialise cyw43_arch\n");
54+
return PICO_ERROR_GENERIC;
55+
}
56+
657
// if unable to connect with saved ssid and password, waits 120 seconds
758
// for new credentials to be provisioned over BLE
8-
start_ble_wifi_provisioning(120000);
9-
printf("finished provisioning\n");
10-
}
59+
int rc = start_ble_wifi_provisioning(PROV_TIMEOUT_MS);
60+
printf("finished provisioning result=%d\n", rc);
61+
if (rc != PICO_OK) {
62+
panic("Wifi provisioning failed");
63+
}
64+
65+
// Run iperf server
66+
cyw43_arch_lwip_begin();
67+
printf("\nReady, running iperf server at %s\n", ip4addr_ntoa(netif_ip4_addr(netif_list)));
68+
lwiperf_start_tcp_server_default(&iperf_report, NULL);
69+
cyw43_arch_lwip_end();
70+
71+
bool exit = false;
72+
stdio_set_chars_available_callback(key_pressed_func, &exit);
73+
74+
// Run forever
75+
printf("Press 'd' to disconnect and reboot\n");
76+
while(!exit) {
77+
cyw43_arch_poll();
78+
cyw43_arch_wait_for_work_until(at_the_end_of_time);
79+
}
80+
81+
printf("Rebooting example...\n");
82+
watchdog_enable(500, true);
83+
sleep_ms(1000);
84+
return 0;
85+
}
Lines changed: 1 addition & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -1,76 +1 @@
1-
#ifndef _LWIPOPTS_H
2-
#define _LWIPOPTS_H
3-
4-
// see https://www.nongnu.org/lwip/2_1_x/group__lwip__opts.html for details
5-
6-
#define NO_SYS 1
7-
#define LWIP_SOCKET 0
8-
#define MEM_LIBC_MALLOC 0
9-
#define MEM_ALIGNMENT 4
10-
#define MEM_SIZE 4000
11-
#define MEMP_NUM_TCP_SEG 32
12-
#define MEMP_NUM_ARP_QUEUE 10
13-
#define PBUF_POOL_SIZE 24
14-
#define LWIP_ARP 1
15-
#define LWIP_ETHERNET 1
16-
#define LWIP_ICMP 1
17-
#define LWIP_RAW 1
18-
#define TCP_WND (8 * TCP_MSS)
19-
#define TCP_MSS 1460
20-
#define TCP_SND_BUF (8 * TCP_MSS)
21-
#define TCP_SND_QUEUELEN ((4 * (TCP_SND_BUF) + (TCP_MSS - 1)) / (TCP_MSS))
22-
#define LWIP_NETIF_STATUS_CALLBACK 1
23-
#define LWIP_NETIF_LINK_CALLBACK 1
24-
#define LWIP_NETIF_HOSTNAME 1
25-
#define LWIP_NETCONN 0
26-
#define MEM_STATS 0
27-
#define SYS_STATS 0
28-
#define MEMP_STATS 0
29-
#define LINK_STATS 0
30-
#define LWIP_CHKSUM_ALGORITHM 3
31-
#define LWIP_DHCP 1
32-
#define LWIP_IPV4 1
33-
#define LWIP_TCP 1
34-
#define LWIP_UDP 1
35-
#define LWIP_DNS 1
36-
#define LWIP_TCP_KEEPALIVE 1
37-
#define LWIP_NETIF_TX_SINGLE_PBUF 1
38-
#define DHCP_DOES_ARP_CHECK 0
39-
#define LWIP_DHCP_DOES_ACD_CHECK 0
40-
41-
#ifndef NDEBUG
42-
#define LWIP_DEBUG 1
43-
#define LWIP_STATS 1
44-
#define LWIP_STATS_DISPLAY 1
45-
#endif
46-
47-
#define ETHARP_DEBUG LWIP_DBG_OFF
48-
#define NETIF_DEBUG LWIP_DBG_OFF
49-
#define PBUF_DEBUG LWIP_DBG_OFF
50-
#define API_LIB_DEBUG LWIP_DBG_OFF
51-
#define API_MSG_DEBUG LWIP_DBG_OFF
52-
#define SOCKETS_DEBUG LWIP_DBG_OFF
53-
#define ICMP_DEBUG LWIP_DBG_OFF
54-
#define INET_DEBUG LWIP_DBG_OFF
55-
#define IP_DEBUG LWIP_DBG_OFF
56-
#define IP_REASS_DEBUG LWIP_DBG_OFF
57-
#define RAW_DEBUG LWIP_DBG_OFF
58-
#define MEM_DEBUG LWIP_DBG_OFF
59-
#define MEMP_DEBUG LWIP_DBG_OFF
60-
#define SYS_DEBUG LWIP_DBG_OFF
61-
#define TCP_DEBUG LWIP_DBG_OFF
62-
#define TCP_INPUT_DEBUG LWIP_DBG_OFF
63-
#define TCP_OUTPUT_DEBUG LWIP_DBG_OFF
64-
#define TCP_RTO_DEBUG LWIP_DBG_OFF
65-
#define TCP_CWND_DEBUG LWIP_DBG_OFF
66-
#define TCP_WND_DEBUG LWIP_DBG_OFF
67-
#define TCP_FR_DEBUG LWIP_DBG_OFF
68-
#define TCP_QLEN_DEBUG LWIP_DBG_OFF
69-
#define TCP_RST_DEBUG LWIP_DBG_OFF
70-
#define UDP_DEBUG LWIP_DBG_OFF
71-
#define TCPIP_DEBUG LWIP_DBG_OFF
72-
#define PPP_DEBUG LWIP_DBG_OFF
73-
#define SLIP_DEBUG LWIP_DBG_OFF
74-
#define DHCP_DEBUG LWIP_DBG_OFF
75-
76-
#endif /* __LWIPOPTS_H__ */
1+
#include "../../pico_w/wifi/lwipopts_examples_common.h"

0 commit comments

Comments
 (0)