From 7bb7136d09caeb4cddddee8dbb455a0a01087064 Mon Sep 17 00:00:00 2001 From: Peter Harper Date: Fri, 6 Mar 2026 18:45:20 +0000 Subject: [PATCH 01/13] Rework BT Examples The BT Examples use a lot of "clever" cmake stuff which makes them hard to understand. Re-work all the examples to get rid of all cmake magic which should make them easier to understand and maintain. Move pico-examples/pico_w/bt to pico-examples/bluetooth All btstack examples are in the btstack_examples subfolder. --- CMakeLists.txt | 1 + bluetooth/CMakeLists.txt | 19 ++ bluetooth/btstack_examples/CMakeLists.txt | 85 +++++++ .../a2dp_sink_demo/CMakeLists.txt | 25 +++ .../a2dp_sink_demo/btstack_config.h | 1 + .../a2dp_source_demo/CMakeLists.txt | 20 ++ .../a2dp_source_demo/btstack_config.h | 1 + .../ancs_client_demo/CMakeLists.txt | 20 ++ .../ancs_client_demo/btstack_config.h | 1 + .../att_delayed_response/CMakeLists.txt | 21 ++ .../att_delayed_response/btstack_config.h | 1 + .../avrcp_browsing_client/CMakeLists.txt | 17 ++ .../avrcp_browsing_client/btstack_config.h | 1 + .../btstack_examples/btstack_audio_pico.c | 209 ++++++++++++++++++ .../dut_mode_classic/CMakeLists.txt | 17 ++ .../dut_mode_classic/btstack_config.h | 1 + .../gap_dedicated_bonding/CMakeLists.txt | 16 ++ .../gap_dedicated_bonding/btstack_config.h | 1 + .../gap_inquiry/CMakeLists.txt | 17 ++ .../gap_inquiry/btstack_config.h | 1 + .../gap_le_advertisements/CMakeLists.txt | 16 ++ .../gap_le_advertisements/btstack_config.h | 1 + .../gap_link_keys/CMakeLists.txt | 17 ++ .../gap_link_keys/btstack_config.h | 1 + .../gatt_battery_query/CMakeLists.txt | 21 ++ .../gatt_battery_query/btstack_config.h | 1 + .../gatt_browser/CMakeLists.txt | 21 ++ .../gatt_browser/btstack_config.h | 1 + .../gatt_counter/CMakeLists.txt | 21 ++ .../gatt_counter/btstack_config.h | 1 + .../gatt_counter_with_wifi/CMakeLists.txt | 27 +++ .../gatt_counter_with_wifi/btstack_config.h | 1 + .../gatt_counter_with_wifi/lwipopts.h | 1 + .../CMakeLists.txt | 21 ++ .../btstack_config.h | 1 + .../gatt_heart_rate_client/CMakeLists.txt | 16 ++ .../gatt_heart_rate_client/btstack_config.h | 1 + .../gatt_streamer_server/CMakeLists.txt | 21 ++ .../gatt_streamer_server/btstack_config.h | 1 + .../CMakeLists.txt | 27 +++ .../btstack_config.h | 1 + .../gatt_streamer_server_with_wifi/lwipopts.h | 1 + .../hfp_ag_demo/CMakeLists.txt | 27 +++ .../hfp_ag_demo/btstack_config.h | 1 + .../hfp_hf_demo/CMakeLists.txt | 26 +++ .../hfp_hf_demo/btstack_config.h | 1 + .../hid_host_demo/CMakeLists.txt | 17 ++ .../hid_host_demo/btstack_config.h | 1 + .../hid_keyboard_demo/CMakeLists.txt | 17 ++ .../hid_keyboard_demo/btstack_config.h | 1 + .../hid_mouse_demo/CMakeLists.txt | 17 ++ .../hid_mouse_demo/btstack_config.h | 1 + .../hog_boot_host_demo/CMakeLists.txt | 16 ++ .../hog_boot_host_demo/btstack_config.h | 1 + .../hog_host_demo/CMakeLists.txt | 20 ++ .../hog_host_demo/btstack_config.h | 1 + .../hog_keyboard_demo/CMakeLists.txt | 21 ++ .../hog_keyboard_demo/btstack_config.h | 1 + .../hog_mouse_demo/CMakeLists.txt | 21 ++ .../hog_mouse_demo/btstack_config.h | 1 + .../hsp_ag_demo/CMakeLists.txt | 27 +++ .../hsp_ag_demo/btstack_config.h | 1 + .../hsp_hs_demo/CMakeLists.txt | 27 +++ .../hsp_hs_demo/btstack_config.h | 1 + .../CMakeLists.txt | 16 ++ .../btstack_config.h | 1 + .../CMakeLists.txt | 21 ++ .../btstack_config.h | 1 + .../btstack_examples/le_mitm/CMakeLists.txt | 16 ++ .../btstack_examples/le_mitm/btstack_config.h | 1 + .../le_streamer_client/CMakeLists.txt | 17 ++ .../le_streamer_client/btstack_config.h | 1 + .../led_counter/CMakeLists.txt | 16 ++ .../led_counter/btstack_config.h | 1 + bluetooth/btstack_examples/main.c | 82 +++++++ .../mod_player/CMakeLists.txt | 24 ++ .../mod_player/btstack_config.h | 1 + .../nordic_spp_le_counter/CMakeLists.txt | 21 ++ .../nordic_spp_le_counter/btstack_config.h | 1 + .../nordic_spp_le_streamer/CMakeLists.txt | 21 ++ .../nordic_spp_le_streamer/btstack_config.h | 1 + .../pan_lwip_http_server/CMakeLists.txt | 25 +++ .../pan_lwip_http_server/btstack_config.h | 1 + .../pan_lwip_http_server/lwipopts.h | 1 + .../pbap_client_demo/CMakeLists.txt | 17 ++ .../pbap_client_demo/btstack_config.h | 1 + .../sdp_bnep_query/CMakeLists.txt | 17 ++ .../sdp_bnep_query/btstack_config.h | 1 + .../sdp_general_query/CMakeLists.txt | 17 ++ .../sdp_general_query/btstack_config.h | 1 + .../sdp_rfcomm_query/CMakeLists.txt | 17 ++ .../sdp_rfcomm_query/btstack_config.h | 1 + .../sine_player/CMakeLists.txt | 23 ++ .../sine_player/btstack_config.h | 1 + .../sm_pairing_central/CMakeLists.txt | 21 ++ .../sm_pairing_central/btstack_config.h | 1 + .../sm_pairing_peripheral/CMakeLists.txt | 21 ++ .../sm_pairing_peripheral/btstack_config.h | 1 + .../spp_and_gatt_counter/CMakeLists.txt | 22 ++ .../spp_and_gatt_counter/btstack_config.h | 1 + .../spp_and_gatt_streamer/CMakeLists.txt | 21 ++ .../spp_and_gatt_streamer/btstack_config.h | 1 + .../spp_counter/CMakeLists.txt | 17 ++ .../spp_counter/btstack_config.h | 1 + .../spp_flowcontrol/CMakeLists.txt | 17 ++ .../spp_flowcontrol/btstack_config.h | 1 + .../spp_streamer/CMakeLists.txt | 17 ++ .../spp_streamer/btstack_config.h | 1 + .../spp_streamer_client/CMakeLists.txt | 17 ++ .../spp_streamer_client/btstack_config.h | 1 + .../spp_streamer_with_wifi/CMakeLists.txt | 23 ++ .../spp_streamer_with_wifi/btstack_config.h | 1 + .../spp_streamer_with_wifi/lwipopts.h | 1 + .../ublox_spp_le_counter/CMakeLists.txt | 22 ++ .../ublox_spp_le_counter/btstack_config.h | 1 + bluetooth/config/btstack_config_common.h | 89 ++++++++ 116 files changed, 1605 insertions(+) create mode 100644 bluetooth/CMakeLists.txt create mode 100644 bluetooth/btstack_examples/CMakeLists.txt create mode 100644 bluetooth/btstack_examples/a2dp_sink_demo/CMakeLists.txt create mode 100644 bluetooth/btstack_examples/a2dp_sink_demo/btstack_config.h create mode 100644 bluetooth/btstack_examples/a2dp_source_demo/CMakeLists.txt create mode 100644 bluetooth/btstack_examples/a2dp_source_demo/btstack_config.h create mode 100644 bluetooth/btstack_examples/ancs_client_demo/CMakeLists.txt create mode 100644 bluetooth/btstack_examples/ancs_client_demo/btstack_config.h create mode 100644 bluetooth/btstack_examples/att_delayed_response/CMakeLists.txt create mode 100644 bluetooth/btstack_examples/att_delayed_response/btstack_config.h create mode 100644 bluetooth/btstack_examples/avrcp_browsing_client/CMakeLists.txt create mode 100644 bluetooth/btstack_examples/avrcp_browsing_client/btstack_config.h create mode 100644 bluetooth/btstack_examples/btstack_audio_pico.c create mode 100644 bluetooth/btstack_examples/dut_mode_classic/CMakeLists.txt create mode 100644 bluetooth/btstack_examples/dut_mode_classic/btstack_config.h create mode 100644 bluetooth/btstack_examples/gap_dedicated_bonding/CMakeLists.txt create mode 100644 bluetooth/btstack_examples/gap_dedicated_bonding/btstack_config.h create mode 100644 bluetooth/btstack_examples/gap_inquiry/CMakeLists.txt create mode 100644 bluetooth/btstack_examples/gap_inquiry/btstack_config.h create mode 100644 bluetooth/btstack_examples/gap_le_advertisements/CMakeLists.txt create mode 100644 bluetooth/btstack_examples/gap_le_advertisements/btstack_config.h create mode 100644 bluetooth/btstack_examples/gap_link_keys/CMakeLists.txt create mode 100644 bluetooth/btstack_examples/gap_link_keys/btstack_config.h create mode 100644 bluetooth/btstack_examples/gatt_battery_query/CMakeLists.txt create mode 100644 bluetooth/btstack_examples/gatt_battery_query/btstack_config.h create mode 100644 bluetooth/btstack_examples/gatt_browser/CMakeLists.txt create mode 100644 bluetooth/btstack_examples/gatt_browser/btstack_config.h create mode 100644 bluetooth/btstack_examples/gatt_counter/CMakeLists.txt create mode 100644 bluetooth/btstack_examples/gatt_counter/btstack_config.h create mode 100644 bluetooth/btstack_examples/gatt_counter_with_wifi/CMakeLists.txt create mode 100644 bluetooth/btstack_examples/gatt_counter_with_wifi/btstack_config.h create mode 100644 bluetooth/btstack_examples/gatt_counter_with_wifi/lwipopts.h create mode 100644 bluetooth/btstack_examples/gatt_device_information_query/CMakeLists.txt create mode 100644 bluetooth/btstack_examples/gatt_device_information_query/btstack_config.h create mode 100644 bluetooth/btstack_examples/gatt_heart_rate_client/CMakeLists.txt create mode 100644 bluetooth/btstack_examples/gatt_heart_rate_client/btstack_config.h create mode 100644 bluetooth/btstack_examples/gatt_streamer_server/CMakeLists.txt create mode 100644 bluetooth/btstack_examples/gatt_streamer_server/btstack_config.h create mode 100644 bluetooth/btstack_examples/gatt_streamer_server_with_wifi/CMakeLists.txt create mode 100644 bluetooth/btstack_examples/gatt_streamer_server_with_wifi/btstack_config.h create mode 100644 bluetooth/btstack_examples/gatt_streamer_server_with_wifi/lwipopts.h create mode 100644 bluetooth/btstack_examples/hfp_ag_demo/CMakeLists.txt create mode 100644 bluetooth/btstack_examples/hfp_ag_demo/btstack_config.h create mode 100644 bluetooth/btstack_examples/hfp_hf_demo/CMakeLists.txt create mode 100644 bluetooth/btstack_examples/hfp_hf_demo/btstack_config.h create mode 100644 bluetooth/btstack_examples/hid_host_demo/CMakeLists.txt create mode 100644 bluetooth/btstack_examples/hid_host_demo/btstack_config.h create mode 100644 bluetooth/btstack_examples/hid_keyboard_demo/CMakeLists.txt create mode 100644 bluetooth/btstack_examples/hid_keyboard_demo/btstack_config.h create mode 100644 bluetooth/btstack_examples/hid_mouse_demo/CMakeLists.txt create mode 100644 bluetooth/btstack_examples/hid_mouse_demo/btstack_config.h create mode 100644 bluetooth/btstack_examples/hog_boot_host_demo/CMakeLists.txt create mode 100644 bluetooth/btstack_examples/hog_boot_host_demo/btstack_config.h create mode 100644 bluetooth/btstack_examples/hog_host_demo/CMakeLists.txt create mode 100644 bluetooth/btstack_examples/hog_host_demo/btstack_config.h create mode 100644 bluetooth/btstack_examples/hog_keyboard_demo/CMakeLists.txt create mode 100644 bluetooth/btstack_examples/hog_keyboard_demo/btstack_config.h create mode 100644 bluetooth/btstack_examples/hog_mouse_demo/CMakeLists.txt create mode 100644 bluetooth/btstack_examples/hog_mouse_demo/btstack_config.h create mode 100644 bluetooth/btstack_examples/hsp_ag_demo/CMakeLists.txt create mode 100644 bluetooth/btstack_examples/hsp_ag_demo/btstack_config.h create mode 100644 bluetooth/btstack_examples/hsp_hs_demo/CMakeLists.txt create mode 100644 bluetooth/btstack_examples/hsp_hs_demo/btstack_config.h create mode 100644 bluetooth/btstack_examples/le_credit_based_flow_control_mode_client/CMakeLists.txt create mode 100644 bluetooth/btstack_examples/le_credit_based_flow_control_mode_client/btstack_config.h create mode 100644 bluetooth/btstack_examples/le_credit_based_flow_control_mode_server/CMakeLists.txt create mode 100644 bluetooth/btstack_examples/le_credit_based_flow_control_mode_server/btstack_config.h create mode 100644 bluetooth/btstack_examples/le_mitm/CMakeLists.txt create mode 100644 bluetooth/btstack_examples/le_mitm/btstack_config.h create mode 100644 bluetooth/btstack_examples/le_streamer_client/CMakeLists.txt create mode 100644 bluetooth/btstack_examples/le_streamer_client/btstack_config.h create mode 100644 bluetooth/btstack_examples/led_counter/CMakeLists.txt create mode 100644 bluetooth/btstack_examples/led_counter/btstack_config.h create mode 100644 bluetooth/btstack_examples/main.c create mode 100644 bluetooth/btstack_examples/mod_player/CMakeLists.txt create mode 100644 bluetooth/btstack_examples/mod_player/btstack_config.h create mode 100644 bluetooth/btstack_examples/nordic_spp_le_counter/CMakeLists.txt create mode 100644 bluetooth/btstack_examples/nordic_spp_le_counter/btstack_config.h create mode 100644 bluetooth/btstack_examples/nordic_spp_le_streamer/CMakeLists.txt create mode 100644 bluetooth/btstack_examples/nordic_spp_le_streamer/btstack_config.h create mode 100644 bluetooth/btstack_examples/pan_lwip_http_server/CMakeLists.txt create mode 100644 bluetooth/btstack_examples/pan_lwip_http_server/btstack_config.h create mode 100644 bluetooth/btstack_examples/pan_lwip_http_server/lwipopts.h create mode 100644 bluetooth/btstack_examples/pbap_client_demo/CMakeLists.txt create mode 100644 bluetooth/btstack_examples/pbap_client_demo/btstack_config.h create mode 100644 bluetooth/btstack_examples/sdp_bnep_query/CMakeLists.txt create mode 100644 bluetooth/btstack_examples/sdp_bnep_query/btstack_config.h create mode 100644 bluetooth/btstack_examples/sdp_general_query/CMakeLists.txt create mode 100644 bluetooth/btstack_examples/sdp_general_query/btstack_config.h create mode 100644 bluetooth/btstack_examples/sdp_rfcomm_query/CMakeLists.txt create mode 100644 bluetooth/btstack_examples/sdp_rfcomm_query/btstack_config.h create mode 100644 bluetooth/btstack_examples/sine_player/CMakeLists.txt create mode 100644 bluetooth/btstack_examples/sine_player/btstack_config.h create mode 100644 bluetooth/btstack_examples/sm_pairing_central/CMakeLists.txt create mode 100644 bluetooth/btstack_examples/sm_pairing_central/btstack_config.h create mode 100644 bluetooth/btstack_examples/sm_pairing_peripheral/CMakeLists.txt create mode 100644 bluetooth/btstack_examples/sm_pairing_peripheral/btstack_config.h create mode 100644 bluetooth/btstack_examples/spp_and_gatt_counter/CMakeLists.txt create mode 100644 bluetooth/btstack_examples/spp_and_gatt_counter/btstack_config.h create mode 100644 bluetooth/btstack_examples/spp_and_gatt_streamer/CMakeLists.txt create mode 100644 bluetooth/btstack_examples/spp_and_gatt_streamer/btstack_config.h create mode 100644 bluetooth/btstack_examples/spp_counter/CMakeLists.txt create mode 100644 bluetooth/btstack_examples/spp_counter/btstack_config.h create mode 100644 bluetooth/btstack_examples/spp_flowcontrol/CMakeLists.txt create mode 100644 bluetooth/btstack_examples/spp_flowcontrol/btstack_config.h create mode 100644 bluetooth/btstack_examples/spp_streamer/CMakeLists.txt create mode 100644 bluetooth/btstack_examples/spp_streamer/btstack_config.h create mode 100644 bluetooth/btstack_examples/spp_streamer_client/CMakeLists.txt create mode 100644 bluetooth/btstack_examples/spp_streamer_client/btstack_config.h create mode 100644 bluetooth/btstack_examples/spp_streamer_with_wifi/CMakeLists.txt create mode 100644 bluetooth/btstack_examples/spp_streamer_with_wifi/btstack_config.h create mode 100644 bluetooth/btstack_examples/spp_streamer_with_wifi/lwipopts.h create mode 100644 bluetooth/btstack_examples/ublox_spp_le_counter/CMakeLists.txt create mode 100644 bluetooth/btstack_examples/ublox_spp_le_counter/btstack_config.h create mode 100644 bluetooth/config/btstack_config_common.h diff --git a/CMakeLists.txt b/CMakeLists.txt index a76866c0d..37cda9ff1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -95,3 +95,4 @@ add_subdirectory(usb) add_subdirectory(watchdog) add_subdirectory(sha) add_subdirectory(freertos) +add_subdirectory(bluetooth) diff --git a/bluetooth/CMakeLists.txt b/bluetooth/CMakeLists.txt new file mode 100644 index 000000000..bb3401035 --- /dev/null +++ b/bluetooth/CMakeLists.txt @@ -0,0 +1,19 @@ +if (DEFINED ENV{PICO_BTSTACK_PATH} AND (NOT PICO_BTSTACK_PATH)) + set(PICO_BTSTACK_PATH $ENV{PICO_BTSTACK_PATH}) + message("Using PICO_BTSTACK_PATH from environment ('${PICO_BTSTACK_PATH}')") +endif () +set(BTSTACK_TEST_PATH "src/bluetooth.h") +if (NOT PICO_BTSTACK_PATH) + set(PICO_BTSTACK_PATH ${PICO_SDK_PATH}/lib/btstack) + if (PICO_CYW43_SUPPORTED AND NOT EXISTS ${PICO_BTSTACK_PATH}/${BTSTACK_TEST_PATH}) + message(WARNING "btstack submodule has not been initialized; Pico Bluetooth support will be unavailable. + hint: try 'git submodule update --init' from your SDK directory (${PICO_SDK_PATH}).") + endif() +elseif (NOT EXISTS ${PICO_BTSTACK_PATH}/${BTSTACK_TEST_PATH}) + message(WARNING "PICO_BTSTACK_PATH specified but content not present.") +endif() +if (NOT TARGET pico_btstack_base) + message("Skipping Pico Bluetooth examples as support is not available") +else() + add_subdirectory(btstack_examples) +endif() diff --git a/bluetooth/btstack_examples/CMakeLists.txt b/bluetooth/btstack_examples/CMakeLists.txt new file mode 100644 index 000000000..4f97a67b1 --- /dev/null +++ b/bluetooth/btstack_examples/CMakeLists.txt @@ -0,0 +1,85 @@ +if (NOT TARGET pico_btstack_hxcmod_player) + # mod player used by a2dp_source_demo and mod_player and demo song + add_library(pico_btstack_hxcmod_player INTERFACE) + target_sources(pico_btstack_hxcmod_player INTERFACE + ${PICO_SDK_PATH}/lib/btstack/3rd-party/hxcmod-player/hxcmod.c + ${PICO_SDK_PATH}/lib/btstack/3rd-party/hxcmod-player/mods/mod.c + ) + target_include_directories(pico_btstack_hxcmod_player INTERFACE + ${PICO_SDK_PATH}/lib/btstack/3rd-party/hxcmod-player + ${PICO_SDK_PATH}/lib/btstack/3rd-party/hxcmod-player/mods + ) + target_compile_definitions(pico_btstack_hxcmod_player INTERFACE + ENABLE_MODPLAYER=1 + ) +endif() + +add_subdirectory(a2dp_source_demo) +add_subdirectory(gap_inquiry) +add_subdirectory(gap_le_advertisements) +add_subdirectory(gatt_counter) +add_subdirectory(gatt_streamer_server) +add_subdirectory(gatt_heart_rate_client) +add_subdirectory(hid_host_demo) +add_subdirectory(hid_keyboard_demo) +add_subdirectory(hid_mouse_demo) +add_subdirectory(hog_host_demo) +add_subdirectory(hog_keyboard_demo) +add_subdirectory(hog_mouse_demo) +add_subdirectory(le_streamer_client) +add_subdirectory(pbap_client_demo) +add_subdirectory(sm_pairing_central) +add_subdirectory(sm_pairing_peripheral) +add_subdirectory(spp_counter) +add_subdirectory(spp_streamer) +add_subdirectory(spp_streamer_client) +add_subdirectory(spp_streamer_with_wifi) + +# These examples connect to WiFi +# Define WIFI_SSID and WIFI_PASSWORD to enable them +if (WIFI_SSID AND WIFI_PASSWORD) + add_subdirectory(gatt_counter_with_wifi) + add_subdirectory(gatt_streamer_server_with_wifi) +endif() + +# These examples need https://github.com/raspberrypi/pico-extras +# PICO_EXTRAS_PATH should specify its location +if (PICO_EXTRAS_PATH) + add_subdirectory(a2dp_sink_demo) + if (BTSTACK_EXAMPLES_ALL) + add_subdirectory(hfp_hf_demo) + add_subdirectory(hfp_ag_demo) + add_subdirectory(hsp_ag_demo) + add_subdirectory(hsp_hs_demo) + add_subdirectory(mod_player) + add_subdirectory(sine_player) + endif() +endif() + +# Define BTSTACK_EXAMPLES_ALL=1 to enable these examples +if (BTSTACK_EXAMPLES_ALL) + add_subdirectory(ancs_client_demo) + add_subdirectory(att_delayed_response) + add_subdirectory(avrcp_browsing_client) + add_subdirectory(dut_mode_classic) + add_subdirectory(gap_dedicated_bonding) + add_subdirectory(gap_link_keys) + add_subdirectory(gatt_battery_query) + add_subdirectory(gatt_browser) + add_subdirectory(gatt_device_information_query) + add_subdirectory(hog_boot_host_demo) + add_subdirectory(le_credit_based_flow_control_mode_client) + add_subdirectory(le_credit_based_flow_control_mode_server) + add_subdirectory(le_mitm) + add_subdirectory(led_counter) + add_subdirectory(nordic_spp_le_counter) + add_subdirectory(nordic_spp_le_streamer) + add_subdirectory(pan_lwip_http_server) + add_subdirectory(sdp_bnep_query) + add_subdirectory(sdp_general_query) + add_subdirectory(sdp_rfcomm_query) + add_subdirectory(spp_and_gatt_counter) + add_subdirectory(spp_and_gatt_streamer) + add_subdirectory(spp_flowcontrol) + add_subdirectory(ublox_spp_le_counter) +endif() diff --git a/bluetooth/btstack_examples/a2dp_sink_demo/CMakeLists.txt b/bluetooth/btstack_examples/a2dp_sink_demo/CMakeLists.txt new file mode 100644 index 000000000..dd73fab63 --- /dev/null +++ b/bluetooth/btstack_examples/a2dp_sink_demo/CMakeLists.txt @@ -0,0 +1,25 @@ +# See https://bluekitchen-gmbh.com/btstack/#examples/examples/#sec:a2dpsinkdemoExample +add_executable(a2dp_sink_demo + ../main.c + ../btstack_audio_pico.c + ${PICO_BTSTACK_PATH}/example/a2dp_sink_demo.c # note: this source is in pico-sdk/lib/btstack +) +target_link_libraries(a2dp_sink_demo PRIVATE + pico_stdlib + pico_cyw43_arch_none # we don't need lwip support + pico_btstack_cyw43 # enable bt + pico_btstack_ble # ble support + pico_btstack_classic # classic support + pico_btstack_sbc_decoder + pico_audio_i2s +) +target_include_directories(a2dp_sink_demo PRIVATE + . # for btstack config +) +target_compile_definitions(a2dp_sink_demo PRIVATE + USING_I2C=1 + PICO_AUDIO_I2S_DATA_PIN=9 + PICO_AUDIO_I2S_CLOCK_PIN_BASE=10 +) +pico_add_extra_outputs(a2dp_sink_demo) +example_auto_set_url(a2dp_sink_demo) diff --git a/bluetooth/btstack_examples/a2dp_sink_demo/btstack_config.h b/bluetooth/btstack_examples/a2dp_sink_demo/btstack_config.h new file mode 100644 index 000000000..6eafef0a0 --- /dev/null +++ b/bluetooth/btstack_examples/a2dp_sink_demo/btstack_config.h @@ -0,0 +1 @@ +#include "../../config/btstack_config_common.h" diff --git a/bluetooth/btstack_examples/a2dp_source_demo/CMakeLists.txt b/bluetooth/btstack_examples/a2dp_source_demo/CMakeLists.txt new file mode 100644 index 000000000..23c193ba4 --- /dev/null +++ b/bluetooth/btstack_examples/a2dp_source_demo/CMakeLists.txt @@ -0,0 +1,20 @@ +# See https://bluekitchen-gmbh.com/btstack/#examples/examples/#sec:a2dpsourcedemoExample +add_executable(a2dp_source_demo + ../main.c + ${PICO_BTSTACK_PATH}/example/a2dp_source_demo.c # note: this source is in pico-sdk/lib/btstack + ${PICO_BTSTACK_PATH}/src/btstack_audio_generator.c +) +target_link_libraries(a2dp_source_demo PRIVATE + pico_stdlib + pico_cyw43_arch_none # we don't need lwip support + pico_btstack_cyw43 # enable bt + pico_btstack_ble # ble support + pico_btstack_classic # classic support + pico_btstack_hxcmod_player + pico_btstack_sbc_encoder +) +target_include_directories(a2dp_source_demo PRIVATE + . # for btstack config +) +pico_add_extra_outputs(a2dp_source_demo) +example_auto_set_url(a2dp_source_demo) diff --git a/bluetooth/btstack_examples/a2dp_source_demo/btstack_config.h b/bluetooth/btstack_examples/a2dp_source_demo/btstack_config.h new file mode 100644 index 000000000..6eafef0a0 --- /dev/null +++ b/bluetooth/btstack_examples/a2dp_source_demo/btstack_config.h @@ -0,0 +1 @@ +#include "../../config/btstack_config_common.h" diff --git a/bluetooth/btstack_examples/ancs_client_demo/CMakeLists.txt b/bluetooth/btstack_examples/ancs_client_demo/CMakeLists.txt new file mode 100644 index 000000000..f3caa0ed8 --- /dev/null +++ b/bluetooth/btstack_examples/ancs_client_demo/CMakeLists.txt @@ -0,0 +1,20 @@ +add_executable(ancs_client_demo + ../main.c + ${PICO_BTSTACK_PATH}/example/ancs_client_demo.c # note: this source is in pico-sdk/lib/btstack +) +target_link_libraries(ancs_client_demo PRIVATE + pico_stdlib + pico_cyw43_arch_none # we don't need lwip support + pico_btstack_cyw43 # enable bt + pico_btstack_ble # ble support +) +target_include_directories(ancs_client_demo PRIVATE + . # for btstack config +) +# This builds a header file with details of the gatt service described in a gatt file +# note: this source for this is in pico-sdk/lib/btstack +pico_btstack_make_gatt_header(ancs_client_demo PRIVATE + ${PICO_BTSTACK_PATH}/example/ancs_client_demo.gatt +) +pico_add_extra_outputs(ancs_client_demo) +example_auto_set_url(ancs_client_demo) diff --git a/bluetooth/btstack_examples/ancs_client_demo/btstack_config.h b/bluetooth/btstack_examples/ancs_client_demo/btstack_config.h new file mode 100644 index 000000000..6eafef0a0 --- /dev/null +++ b/bluetooth/btstack_examples/ancs_client_demo/btstack_config.h @@ -0,0 +1 @@ +#include "../../config/btstack_config_common.h" diff --git a/bluetooth/btstack_examples/att_delayed_response/CMakeLists.txt b/bluetooth/btstack_examples/att_delayed_response/CMakeLists.txt new file mode 100644 index 000000000..8930fa33d --- /dev/null +++ b/bluetooth/btstack_examples/att_delayed_response/CMakeLists.txt @@ -0,0 +1,21 @@ +# See https://bluekitchen-gmbh.com/btstack/#examples/examples/#sec:attdelayedresponseExample +add_executable(att_delayed_response + ../main.c + ${PICO_BTSTACK_PATH}/example/att_delayed_response.c # note: this source is in pico-sdk/lib/btstack +) +target_link_libraries(att_delayed_response PRIVATE + pico_stdlib + pico_cyw43_arch_none # we don't need lwip support + pico_btstack_cyw43 # enable bt + pico_btstack_ble # ble support +) +target_include_directories(att_delayed_response PRIVATE + . # for btstack config +) +# This builds a header file with details of the gatt service described in a gatt file +# note: this source for this is in pico-sdk/lib/btstack +pico_btstack_make_gatt_header(att_delayed_response PRIVATE + ${PICO_BTSTACK_PATH}/example/att_delayed_response.gatt +) +pico_add_extra_outputs(att_delayed_response) +example_auto_set_url(att_delayed_response) diff --git a/bluetooth/btstack_examples/att_delayed_response/btstack_config.h b/bluetooth/btstack_examples/att_delayed_response/btstack_config.h new file mode 100644 index 000000000..6eafef0a0 --- /dev/null +++ b/bluetooth/btstack_examples/att_delayed_response/btstack_config.h @@ -0,0 +1 @@ +#include "../../config/btstack_config_common.h" diff --git a/bluetooth/btstack_examples/avrcp_browsing_client/CMakeLists.txt b/bluetooth/btstack_examples/avrcp_browsing_client/CMakeLists.txt new file mode 100644 index 000000000..641896fe2 --- /dev/null +++ b/bluetooth/btstack_examples/avrcp_browsing_client/CMakeLists.txt @@ -0,0 +1,17 @@ +# See https://bluekitchen-gmbh.com/btstack/#examples/examples/#sec:avrcpbrowsingclientExample +add_executable(avrcp_browsing_client + ../main.c + ${PICO_BTSTACK_PATH}/example/avrcp_browsing_client.c # note: this source is in pico-sdk/lib/btstack +) +target_link_libraries(avrcp_browsing_client PRIVATE + pico_stdlib + pico_cyw43_arch_none # we don't need lwip support + pico_btstack_cyw43 # enable bt + pico_btstack_ble # ble support + pico_btstack_classic # classic support +) +target_include_directories(avrcp_browsing_client PRIVATE + . # for btstack config +) +pico_add_extra_outputs(avrcp_browsing_client) +example_auto_set_url(avrcp_browsing_client) diff --git a/bluetooth/btstack_examples/avrcp_browsing_client/btstack_config.h b/bluetooth/btstack_examples/avrcp_browsing_client/btstack_config.h new file mode 100644 index 000000000..6eafef0a0 --- /dev/null +++ b/bluetooth/btstack_examples/avrcp_browsing_client/btstack_config.h @@ -0,0 +1 @@ +#include "../../config/btstack_config_common.h" diff --git a/bluetooth/btstack_examples/btstack_audio_pico.c b/bluetooth/btstack_examples/btstack_audio_pico.c new file mode 100644 index 000000000..1afcacec6 --- /dev/null +++ b/bluetooth/btstack_examples/btstack_audio_pico.c @@ -0,0 +1,209 @@ +/* + * Copyright (C) 2022 BlueKitchen GmbH + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holders nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * 4. Any redistribution, use, or modification is done solely for + * personal benefit and not for any commercial purpose or for + * monetary gain. + * + * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BLUEKITCHEN + * GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * Please inquire about commercial licensing options at + * contact@bluekitchen-gmbh.com + * + */ + +#define BTSTACK_FILE__ "btstack_audio_pico.c" + +/* + * btstack_audio_pico.c + * + * Implementation of btstack_audio.h using pico_i2s + * + */ + +#include "btstack_config.h" + +#include "btstack_debug.h" +#include "btstack_audio.h" +#include "btstack_run_loop.h" + +#include +#include + +#include "pico/audio_i2s.h" + +#define DRIVER_POLL_INTERVAL_MS 5 +#define SAMPLES_PER_BUFFER 512 + +// client +static void (*playback_callback)(int16_t * buffer, uint16_t num_samples, const btstack_audio_context_t * timeinfo); + +// timer to fill output ring buffer +static btstack_timer_source_t driver_timer_sink; + + +static bool btstack_audio_pico_sink_active; + +// from pico-playground/audio/sine_wave/sine_wave.c + +static audio_format_t btstack_audio_pico_audio_format; +static audio_buffer_format_t btstack_audio_pico_producer_format; +static audio_buffer_pool_t * btstack_audio_pico_audio_buffer_pool; +static uint8_t btstack_audio_pico_channel_count; + +static audio_buffer_pool_t *init_audio(uint32_t sample_frequency, uint8_t channel_count) { + + // num channels requested by application + btstack_audio_pico_channel_count = channel_count; + + // always use stereo + btstack_audio_pico_audio_format.format = AUDIO_BUFFER_FORMAT_PCM_S16; + btstack_audio_pico_audio_format.sample_freq = sample_frequency; + btstack_audio_pico_audio_format.channel_count = 2; + + btstack_audio_pico_producer_format.format = &btstack_audio_pico_audio_format; + btstack_audio_pico_producer_format.sample_stride = 2 * 2; + + audio_buffer_pool_t * producer_pool = audio_new_producer_pool(&btstack_audio_pico_producer_format, 3, SAMPLES_PER_BUFFER); // todo correct size + + audio_i2s_config_t config; + config.data_pin = PICO_AUDIO_I2S_DATA_PIN; + config.clock_pin_base = PICO_AUDIO_I2S_CLOCK_PIN_BASE; + config.dma_channel = (int8_t) dma_claim_unused_channel(true); + config.pio_sm = 0; + + // audio_i2s_setup claims the channel again https://github.com/raspberrypi/pico-extras/issues/48 + dma_channel_unclaim(config.dma_channel); + const audio_format_t * output_format = audio_i2s_setup(&btstack_audio_pico_audio_format, &config); + if (!output_format) { + panic("PicoAudio: Unable to open audio device.\n"); + } + + bool ok = audio_i2s_connect(producer_pool); + assert(ok); + (void)ok; + + return producer_pool; +} + +static void btstack_audio_pico_sink_fill_buffers(void){ + while (true){ + audio_buffer_t * audio_buffer = take_audio_buffer(btstack_audio_pico_audio_buffer_pool, false); + if (audio_buffer == NULL){ + break; + } + + int16_t * buffer16 = (int16_t *) audio_buffer->buffer->bytes; + (*playback_callback)(buffer16, audio_buffer->max_sample_count, 0); + + // duplicate samples for mono + if (btstack_audio_pico_channel_count == 1){ + int16_t i; + for (i = SAMPLES_PER_BUFFER - 1 ; i >= 0; i--){ + buffer16[2*i ] = buffer16[i]; + buffer16[2*i+1] = buffer16[i]; + } + } + + audio_buffer->sample_count = audio_buffer->max_sample_count; + give_audio_buffer(btstack_audio_pico_audio_buffer_pool, audio_buffer); + } +} + +static void driver_timer_handler_sink(btstack_timer_source_t * ts){ + + // refill + btstack_audio_pico_sink_fill_buffers(); + + // re-set timer + btstack_run_loop_set_timer(ts, DRIVER_POLL_INTERVAL_MS); + btstack_run_loop_add_timer(ts); +} + +static int btstack_audio_pico_sink_init( + uint8_t channels, + uint32_t samplerate, + void (*playback)(int16_t * buffer, uint16_t num_samples, const btstack_audio_context_t * timeinfo) +){ + btstack_assert(playback != NULL); + btstack_assert(channels != 0); + + playback_callback = playback; + + if (!btstack_audio_pico_audio_buffer_pool) { + btstack_audio_pico_audio_buffer_pool = init_audio(samplerate, channels); + } + return 0; +} + +static void btstack_audio_pico_sink_set_volume(uint8_t volume){ + UNUSED(volume); +} + +static void btstack_audio_pico_sink_start_stream(void){ + + // pre-fill HAL buffers + btstack_audio_pico_sink_fill_buffers(); + + // start timer + btstack_run_loop_set_timer_handler(&driver_timer_sink, &driver_timer_handler_sink); + btstack_run_loop_set_timer(&driver_timer_sink, DRIVER_POLL_INTERVAL_MS); + btstack_run_loop_add_timer(&driver_timer_sink); + + // state + btstack_audio_pico_sink_active = true; + + audio_i2s_set_enabled(true); +} + +static void btstack_audio_pico_sink_stop_stream(void){ + + audio_i2s_set_enabled(false); + + // stop timer + btstack_run_loop_remove_timer(&driver_timer_sink); + // state + btstack_audio_pico_sink_active = false; +} + +static void btstack_audio_pico_sink_close(void){ + // stop stream if needed + if (btstack_audio_pico_sink_active){ + btstack_audio_pico_sink_stop_stream(); + } +} + +static const btstack_audio_sink_t btstack_audio_pico_sink = { + .init = &btstack_audio_pico_sink_init, + .set_volume = &btstack_audio_pico_sink_set_volume, + .start_stream = &btstack_audio_pico_sink_start_stream, + .stop_stream = &btstack_audio_pico_sink_stop_stream, + .close = &btstack_audio_pico_sink_close, +}; + +const btstack_audio_sink_t * btstack_audio_pico_sink_get_instance(void){ + return &btstack_audio_pico_sink; +} diff --git a/bluetooth/btstack_examples/dut_mode_classic/CMakeLists.txt b/bluetooth/btstack_examples/dut_mode_classic/CMakeLists.txt new file mode 100644 index 000000000..628df61ea --- /dev/null +++ b/bluetooth/btstack_examples/dut_mode_classic/CMakeLists.txt @@ -0,0 +1,17 @@ +# See https://bluekitchen-gmbh.com/btstack/#examples/examples/#sec:dutmodeclassicExample +add_executable(dut_mode_classic + ../main.c + ${PICO_BTSTACK_PATH}/example/dut_mode_classic.c # note: this source is in pico-sdk/lib/btstack +) +target_link_libraries(dut_mode_classic PRIVATE + pico_stdlib + pico_cyw43_arch_none # we don't need lwip support + pico_btstack_cyw43 # enable bt + pico_btstack_ble # ble support + pico_btstack_classic # classic support +) +target_include_directories(dut_mode_classic PRIVATE + . # for btstack config +) +pico_add_extra_outputs(dut_mode_classic) +example_auto_set_url(dut_mode_classic) diff --git a/bluetooth/btstack_examples/dut_mode_classic/btstack_config.h b/bluetooth/btstack_examples/dut_mode_classic/btstack_config.h new file mode 100644 index 000000000..6eafef0a0 --- /dev/null +++ b/bluetooth/btstack_examples/dut_mode_classic/btstack_config.h @@ -0,0 +1 @@ +#include "../../config/btstack_config_common.h" diff --git a/bluetooth/btstack_examples/gap_dedicated_bonding/CMakeLists.txt b/bluetooth/btstack_examples/gap_dedicated_bonding/CMakeLists.txt new file mode 100644 index 000000000..7fb797fed --- /dev/null +++ b/bluetooth/btstack_examples/gap_dedicated_bonding/CMakeLists.txt @@ -0,0 +1,16 @@ +add_executable(gap_dedicated_bonding + ../main.c + ${PICO_BTSTACK_PATH}/example/gap_dedicated_bonding.c # note: this source is in pico-sdk/lib/btstack +) +target_link_libraries(gap_dedicated_bonding PRIVATE + pico_stdlib + pico_cyw43_arch_none # we don't need lwip support + pico_btstack_cyw43 # enable bt + pico_btstack_ble # ble support + pico_btstack_classic # classic support +) +target_include_directories(gap_dedicated_bonding PRIVATE + . # for btstack config +) +pico_add_extra_outputs(gap_dedicated_bonding) +example_auto_set_url(gap_dedicated_bonding) diff --git a/bluetooth/btstack_examples/gap_dedicated_bonding/btstack_config.h b/bluetooth/btstack_examples/gap_dedicated_bonding/btstack_config.h new file mode 100644 index 000000000..6eafef0a0 --- /dev/null +++ b/bluetooth/btstack_examples/gap_dedicated_bonding/btstack_config.h @@ -0,0 +1 @@ +#include "../../config/btstack_config_common.h" diff --git a/bluetooth/btstack_examples/gap_inquiry/CMakeLists.txt b/bluetooth/btstack_examples/gap_inquiry/CMakeLists.txt new file mode 100644 index 000000000..e03126c0e --- /dev/null +++ b/bluetooth/btstack_examples/gap_inquiry/CMakeLists.txt @@ -0,0 +1,17 @@ +# See https://bluekitchen-gmbh.com/btstack/#examples/examples/#sec:gapinquiryExample +add_executable(gap_inquiry + ../main.c + ${PICO_BTSTACK_PATH}/example/gap_inquiry.c # note: this source is in pico-sdk/lib/btstack +) +target_link_libraries(gap_inquiry PRIVATE + pico_stdlib + pico_cyw43_arch_none # we don't need lwip support + pico_btstack_cyw43 # enable bt + pico_btstack_ble # ble support + pico_btstack_classic # classic support +) +target_include_directories(gap_inquiry PRIVATE + . # for btstack config +) +pico_add_extra_outputs(gap_inquiry) +example_auto_set_url(gap_inquiry) diff --git a/bluetooth/btstack_examples/gap_inquiry/btstack_config.h b/bluetooth/btstack_examples/gap_inquiry/btstack_config.h new file mode 100644 index 000000000..6eafef0a0 --- /dev/null +++ b/bluetooth/btstack_examples/gap_inquiry/btstack_config.h @@ -0,0 +1 @@ +#include "../../config/btstack_config_common.h" diff --git a/bluetooth/btstack_examples/gap_le_advertisements/CMakeLists.txt b/bluetooth/btstack_examples/gap_le_advertisements/CMakeLists.txt new file mode 100644 index 000000000..df3e1525a --- /dev/null +++ b/bluetooth/btstack_examples/gap_le_advertisements/CMakeLists.txt @@ -0,0 +1,16 @@ +# See https://bluekitchen-gmbh.com/btstack/#examples/examples/#sec:gapleadvertisementsExample +add_executable(gap_le_advertisements + ../main.c + ${PICO_BTSTACK_PATH}/example/gap_le_advertisements.c # note: this source is in pico-sdk/lib/btstack +) +target_link_libraries(gap_le_advertisements PRIVATE + pico_stdlib + pico_cyw43_arch_none # we don't need lwip support + pico_btstack_cyw43 # enable bt + pico_btstack_ble # ble support +) +target_include_directories(gap_le_advertisements PRIVATE + . # for btstack config +) +pico_add_extra_outputs(gap_le_advertisements) +example_auto_set_url(gap_le_advertisements) diff --git a/bluetooth/btstack_examples/gap_le_advertisements/btstack_config.h b/bluetooth/btstack_examples/gap_le_advertisements/btstack_config.h new file mode 100644 index 000000000..6eafef0a0 --- /dev/null +++ b/bluetooth/btstack_examples/gap_le_advertisements/btstack_config.h @@ -0,0 +1 @@ +#include "../../config/btstack_config_common.h" diff --git a/bluetooth/btstack_examples/gap_link_keys/CMakeLists.txt b/bluetooth/btstack_examples/gap_link_keys/CMakeLists.txt new file mode 100644 index 000000000..c9d5f9fb3 --- /dev/null +++ b/bluetooth/btstack_examples/gap_link_keys/CMakeLists.txt @@ -0,0 +1,17 @@ +# See https://bluekitchen-gmbh.com/btstack/#examples/examples/#sec:gaplinkkeysExample +add_executable(gap_link_keys + ../main.c + ${PICO_BTSTACK_PATH}/example/gap_link_keys.c # note: this source is in pico-sdk/lib/btstack +) +target_link_libraries(gap_link_keys PRIVATE + pico_stdlib + pico_cyw43_arch_none # we don't need lwip support + pico_btstack_cyw43 # enable bt + pico_btstack_ble # ble support + pico_btstack_classic # classic support +) +target_include_directories(gap_link_keys PRIVATE + . # for btstack config +) +pico_add_extra_outputs(gap_link_keys) +example_auto_set_url(gap_link_keys) diff --git a/bluetooth/btstack_examples/gap_link_keys/btstack_config.h b/bluetooth/btstack_examples/gap_link_keys/btstack_config.h new file mode 100644 index 000000000..6eafef0a0 --- /dev/null +++ b/bluetooth/btstack_examples/gap_link_keys/btstack_config.h @@ -0,0 +1 @@ +#include "../../config/btstack_config_common.h" diff --git a/bluetooth/btstack_examples/gatt_battery_query/CMakeLists.txt b/bluetooth/btstack_examples/gatt_battery_query/CMakeLists.txt new file mode 100644 index 000000000..f291408ef --- /dev/null +++ b/bluetooth/btstack_examples/gatt_battery_query/CMakeLists.txt @@ -0,0 +1,21 @@ +# See https://bluekitchen-gmbh.com/btstack/#examples/examples/#sec:gattbatteryqueryExample +add_executable(gatt_battery_query + ../main.c + ${PICO_BTSTACK_PATH}/example/gatt_battery_query.c # note: this source is in pico-sdk/lib/btstack +) +target_link_libraries(gatt_battery_query PRIVATE + pico_stdlib + pico_cyw43_arch_none # we don't need lwip support + pico_btstack_cyw43 # enable bt + pico_btstack_ble # ble support +) +target_include_directories(gatt_battery_query PRIVATE + . # for btstack config +) +# This builds a header file with details of the gatt service described in a gatt file +# note: this source for this is in pico-sdk/lib/btstack +pico_btstack_make_gatt_header(gatt_battery_query PRIVATE + ${PICO_BTSTACK_PATH}/example/gatt_battery_query.gatt +) +pico_add_extra_outputs(gatt_battery_query) +example_auto_set_url(gatt_battery_query) diff --git a/bluetooth/btstack_examples/gatt_battery_query/btstack_config.h b/bluetooth/btstack_examples/gatt_battery_query/btstack_config.h new file mode 100644 index 000000000..6eafef0a0 --- /dev/null +++ b/bluetooth/btstack_examples/gatt_battery_query/btstack_config.h @@ -0,0 +1 @@ +#include "../../config/btstack_config_common.h" diff --git a/bluetooth/btstack_examples/gatt_browser/CMakeLists.txt b/bluetooth/btstack_examples/gatt_browser/CMakeLists.txt new file mode 100644 index 000000000..1bed6af4b --- /dev/null +++ b/bluetooth/btstack_examples/gatt_browser/CMakeLists.txt @@ -0,0 +1,21 @@ +# See https://bluekitchen-gmbh.com/btstack/#examples/examples/#sec:gattbrowserExample +add_executable(gatt_browser + ../main.c + ${PICO_BTSTACK_PATH}/example/gatt_browser.c # note: this source is in pico-sdk/lib/btstack +) +target_link_libraries(gatt_browser PRIVATE + pico_stdlib + pico_cyw43_arch_none # we don't need lwip support + pico_btstack_cyw43 # enable bt + pico_btstack_ble # ble support +) +target_include_directories(gatt_browser PRIVATE + . # for btstack config +) +# This builds a header file with details of the gatt service described in a gatt file +# note: this source for this is in pico-sdk/lib/btstack +pico_btstack_make_gatt_header(gatt_browser PRIVATE + ${PICO_BTSTACK_PATH}/example/gatt_browser.gatt +) +pico_add_extra_outputs(gatt_browser) +example_auto_set_url(gatt_browser) diff --git a/bluetooth/btstack_examples/gatt_browser/btstack_config.h b/bluetooth/btstack_examples/gatt_browser/btstack_config.h new file mode 100644 index 000000000..6eafef0a0 --- /dev/null +++ b/bluetooth/btstack_examples/gatt_browser/btstack_config.h @@ -0,0 +1 @@ +#include "../../config/btstack_config_common.h" diff --git a/bluetooth/btstack_examples/gatt_counter/CMakeLists.txt b/bluetooth/btstack_examples/gatt_counter/CMakeLists.txt new file mode 100644 index 000000000..3dcda6c2e --- /dev/null +++ b/bluetooth/btstack_examples/gatt_counter/CMakeLists.txt @@ -0,0 +1,21 @@ +# See https://bluekitchen-gmbh.com/btstack/#examples/examples/#sec:gattcounterExample +add_executable(gatt_counter + ../main.c + ${PICO_BTSTACK_PATH}/example/gatt_counter.c # note: this source is in pico-sdk/lib/btstack +) +target_link_libraries(gatt_counter PRIVATE + pico_stdlib + pico_cyw43_arch_none # we don't need lwip support + pico_btstack_cyw43 # enable bt + pico_btstack_ble # ble support +) +target_include_directories(gatt_counter PRIVATE + . # for btstack config +) +# This builds a header file with details of the gatt service described in a gatt file +# note: this source for this is in pico-sdk/lib/btstack +pico_btstack_make_gatt_header(gatt_counter PRIVATE + ${PICO_BTSTACK_PATH}/example/gatt_counter.gatt +) +pico_add_extra_outputs(gatt_counter) +example_auto_set_url(gatt_counter) diff --git a/bluetooth/btstack_examples/gatt_counter/btstack_config.h b/bluetooth/btstack_examples/gatt_counter/btstack_config.h new file mode 100644 index 000000000..6eafef0a0 --- /dev/null +++ b/bluetooth/btstack_examples/gatt_counter/btstack_config.h @@ -0,0 +1 @@ +#include "../../config/btstack_config_common.h" diff --git a/bluetooth/btstack_examples/gatt_counter_with_wifi/CMakeLists.txt b/bluetooth/btstack_examples/gatt_counter_with_wifi/CMakeLists.txt new file mode 100644 index 000000000..7d7ae643d --- /dev/null +++ b/bluetooth/btstack_examples/gatt_counter_with_wifi/CMakeLists.txt @@ -0,0 +1,27 @@ +# See https://bluekitchen-gmbh.com/btstack/#examples/examples/#sec:gattcounterExample +add_executable(gatt_counter_with_wifi + ../main.c + ${PICO_BTSTACK_PATH}/example/gatt_counter.c # note: this source is in pico-sdk/lib/btstack +) +target_link_libraries(gatt_counter_with_wifi PRIVATE + pico_stdlib + pico_cyw43_arch_lwip_threadsafe_background # we want lwip support + pico_btstack_cyw43 # enable bt + pico_btstack_ble # ble support + pico_lwip_iperf +) +target_include_directories(gatt_counter_with_wifi PRIVATE + . # for btstack config and lwipopts.h +) +target_compile_definitions(gatt_counter_with_wifi PRIVATE + WIFI_SSID=\"${WIFI_SSID}\" + WIFI_PASSWORD=\"${WIFI_PASSWORD}\" + USING_IPERF=1 +) +# This builds a header file with details of the gatt service described in a gatt file +# note: this source for this is in pico-sdk/lib/btstack +pico_btstack_make_gatt_header(gatt_counter_with_wifi PRIVATE + ${PICO_BTSTACK_PATH}/example/gatt_counter.gatt +) +pico_add_extra_outputs(gatt_counter_with_wifi) +example_auto_set_url(gatt_counter_with_wifi) diff --git a/bluetooth/btstack_examples/gatt_counter_with_wifi/btstack_config.h b/bluetooth/btstack_examples/gatt_counter_with_wifi/btstack_config.h new file mode 100644 index 000000000..6eafef0a0 --- /dev/null +++ b/bluetooth/btstack_examples/gatt_counter_with_wifi/btstack_config.h @@ -0,0 +1 @@ +#include "../../config/btstack_config_common.h" diff --git a/bluetooth/btstack_examples/gatt_counter_with_wifi/lwipopts.h b/bluetooth/btstack_examples/gatt_counter_with_wifi/lwipopts.h new file mode 100644 index 000000000..8bf98aed8 --- /dev/null +++ b/bluetooth/btstack_examples/gatt_counter_with_wifi/lwipopts.h @@ -0,0 +1 @@ +#include "../../../pico_w/wifi/lwipopts_examples_common.h" diff --git a/bluetooth/btstack_examples/gatt_device_information_query/CMakeLists.txt b/bluetooth/btstack_examples/gatt_device_information_query/CMakeLists.txt new file mode 100644 index 000000000..d4f3edb89 --- /dev/null +++ b/bluetooth/btstack_examples/gatt_device_information_query/CMakeLists.txt @@ -0,0 +1,21 @@ +# See https://bluekitchen-gmbh.com/btstack/#examples/examples/#sec:gattdeviceinformationqueryExample +add_executable(gatt_device_information_query + ../main.c + ${PICO_BTSTACK_PATH}/example/gatt_device_information_query.c # note: this source is in pico-sdk/lib/btstack +) +target_link_libraries(gatt_device_information_query PRIVATE + pico_stdlib + pico_cyw43_arch_none # we don't need lwip support + pico_btstack_cyw43 # enable bt + pico_btstack_ble # ble support +) +target_include_directories(gatt_device_information_query PRIVATE + . # for btstack config +) +# This builds a header file with details of the gatt service described in a gatt file +# note: this source for this is in pico-sdk/lib/btstack +pico_btstack_make_gatt_header(gatt_device_information_query PRIVATE + ${PICO_BTSTACK_PATH}/example/gatt_device_information_query.gatt +) +pico_add_extra_outputs(gatt_device_information_query) +example_auto_set_url(gatt_device_information_query) diff --git a/bluetooth/btstack_examples/gatt_device_information_query/btstack_config.h b/bluetooth/btstack_examples/gatt_device_information_query/btstack_config.h new file mode 100644 index 000000000..6eafef0a0 --- /dev/null +++ b/bluetooth/btstack_examples/gatt_device_information_query/btstack_config.h @@ -0,0 +1 @@ +#include "../../config/btstack_config_common.h" diff --git a/bluetooth/btstack_examples/gatt_heart_rate_client/CMakeLists.txt b/bluetooth/btstack_examples/gatt_heart_rate_client/CMakeLists.txt new file mode 100644 index 000000000..c7170b9e8 --- /dev/null +++ b/bluetooth/btstack_examples/gatt_heart_rate_client/CMakeLists.txt @@ -0,0 +1,16 @@ +# See https://bluekitchen-gmbh.com/btstack/#examples/examples/#sec:gattheartrateclientExample +add_executable(gatt_heart_rate_client + ../main.c + ${PICO_BTSTACK_PATH}/example/gatt_heart_rate_client.c # note: this source is in pico-sdk/lib/btstack +) +target_link_libraries(gatt_heart_rate_client PRIVATE + pico_stdlib + pico_cyw43_arch_none # we don't need lwip support + pico_btstack_cyw43 # enable bt + pico_btstack_ble # ble support +) +target_include_directories(gatt_heart_rate_client PRIVATE + . # for btstack config +) +pico_add_extra_outputs(gatt_heart_rate_client) +example_auto_set_url(gatt_heart_rate_client) diff --git a/bluetooth/btstack_examples/gatt_heart_rate_client/btstack_config.h b/bluetooth/btstack_examples/gatt_heart_rate_client/btstack_config.h new file mode 100644 index 000000000..6eafef0a0 --- /dev/null +++ b/bluetooth/btstack_examples/gatt_heart_rate_client/btstack_config.h @@ -0,0 +1 @@ +#include "../../config/btstack_config_common.h" diff --git a/bluetooth/btstack_examples/gatt_streamer_server/CMakeLists.txt b/bluetooth/btstack_examples/gatt_streamer_server/CMakeLists.txt new file mode 100644 index 000000000..63a3b62f3 --- /dev/null +++ b/bluetooth/btstack_examples/gatt_streamer_server/CMakeLists.txt @@ -0,0 +1,21 @@ +# See https://bluekitchen-gmbh.com/btstack/#examples/examples/#sec:gattstreamerserverExample +add_executable(gatt_streamer_server + ../main.c + ${PICO_BTSTACK_PATH}/example/gatt_streamer_server.c # note: this source is in pico-sdk/lib/btstack +) +target_link_libraries(gatt_streamer_server PRIVATE + pico_stdlib + pico_cyw43_arch_none # we don't need lwip support + pico_btstack_cyw43 # enable bt + pico_btstack_ble # ble support +) +target_include_directories(gatt_streamer_server PRIVATE + . # for btstack config +) +# This builds a header file with details of the gatt service described in a gatt file +# note: this source for this is in pico-sdk/lib/btstack +pico_btstack_make_gatt_header(gatt_streamer_server PRIVATE + ${PICO_BTSTACK_PATH}/example/gatt_streamer_server.gatt +) +pico_add_extra_outputs(gatt_streamer_server) +example_auto_set_url(gatt_streamer_server) diff --git a/bluetooth/btstack_examples/gatt_streamer_server/btstack_config.h b/bluetooth/btstack_examples/gatt_streamer_server/btstack_config.h new file mode 100644 index 000000000..6eafef0a0 --- /dev/null +++ b/bluetooth/btstack_examples/gatt_streamer_server/btstack_config.h @@ -0,0 +1 @@ +#include "../../config/btstack_config_common.h" diff --git a/bluetooth/btstack_examples/gatt_streamer_server_with_wifi/CMakeLists.txt b/bluetooth/btstack_examples/gatt_streamer_server_with_wifi/CMakeLists.txt new file mode 100644 index 000000000..d7931f90b --- /dev/null +++ b/bluetooth/btstack_examples/gatt_streamer_server_with_wifi/CMakeLists.txt @@ -0,0 +1,27 @@ +# See https://bluekitchen-gmbh.com/btstack/#examples/examples/#sec:gattstreamerserverExample +add_executable(gatt_streamer_server_with_wifi + ../main.c + ${PICO_BTSTACK_PATH}/example/gatt_streamer_server.c # note: this source is in pico-sdk/lib/btstack +) +target_link_libraries(gatt_streamer_server_with_wifi PRIVATE + pico_stdlib + pico_cyw43_arch_lwip_threadsafe_background # we want lwip support + pico_btstack_cyw43 # enable bt + pico_btstack_ble # ble support + pico_lwip_iperf +) +target_include_directories(gatt_streamer_server_with_wifi PRIVATE + . # for btstack config and lwipopts.h +) +target_compile_definitions(gatt_streamer_server_with_wifi PRIVATE + WIFI_SSID=\"${WIFI_SSID}\" + WIFI_PASSWORD=\"${WIFI_PASSWORD}\" + USING_IPERF=1 +) +# This builds a header file with details of the gatt service described in a gatt file +# note: this source for this is in pico-sdk/lib/btstack +pico_btstack_make_gatt_header(gatt_streamer_server_with_wifi PRIVATE + ${PICO_BTSTACK_PATH}/example/gatt_streamer_server.gatt +) +pico_add_extra_outputs(gatt_streamer_server_with_wifi) +example_auto_set_url(gatt_streamer_server_with_wifi) diff --git a/bluetooth/btstack_examples/gatt_streamer_server_with_wifi/btstack_config.h b/bluetooth/btstack_examples/gatt_streamer_server_with_wifi/btstack_config.h new file mode 100644 index 000000000..6eafef0a0 --- /dev/null +++ b/bluetooth/btstack_examples/gatt_streamer_server_with_wifi/btstack_config.h @@ -0,0 +1 @@ +#include "../../config/btstack_config_common.h" diff --git a/bluetooth/btstack_examples/gatt_streamer_server_with_wifi/lwipopts.h b/bluetooth/btstack_examples/gatt_streamer_server_with_wifi/lwipopts.h new file mode 100644 index 000000000..8bf98aed8 --- /dev/null +++ b/bluetooth/btstack_examples/gatt_streamer_server_with_wifi/lwipopts.h @@ -0,0 +1 @@ +#include "../../../pico_w/wifi/lwipopts_examples_common.h" diff --git a/bluetooth/btstack_examples/hfp_ag_demo/CMakeLists.txt b/bluetooth/btstack_examples/hfp_ag_demo/CMakeLists.txt new file mode 100644 index 000000000..6b6a83289 --- /dev/null +++ b/bluetooth/btstack_examples/hfp_ag_demo/CMakeLists.txt @@ -0,0 +1,27 @@ +# See https://bluekitchen-gmbh.com/btstack/#examples/examples/#sec:hfpagdemoExample +add_executable(hfp_ag_demo + ../main.c + ../btstack_audio_pico.c + ${PICO_BTSTACK_PATH}/example/hfp_ag_demo.c # note: this source is in pico-sdk/lib/btstack + ${PICO_BTSTACK_PATH}/src/btstack_audio_generator.c + ${PICO_BTSTACK_PATH}/example/sco_demo_util.c +) +target_link_libraries(hfp_ag_demo PRIVATE + pico_stdlib + pico_cyw43_arch_none # we don't need lwip support + pico_btstack_cyw43 # enable bt + pico_btstack_ble # ble support + pico_btstack_classic # classic support + pico_btstack_sbc_decoder + pico_audio_i2s +) +target_include_directories(hfp_ag_demo PRIVATE + . # for btstack config +) +target_compile_definitions(hfp_ag_demo PRIVATE + USING_I2C=1 + PICO_AUDIO_I2S_DATA_PIN=9 + PICO_AUDIO_I2S_CLOCK_PIN_BASE=10 +) +pico_add_extra_outputs(hfp_ag_demo) +example_auto_set_url(hfp_ag_demo) diff --git a/bluetooth/btstack_examples/hfp_ag_demo/btstack_config.h b/bluetooth/btstack_examples/hfp_ag_demo/btstack_config.h new file mode 100644 index 000000000..6eafef0a0 --- /dev/null +++ b/bluetooth/btstack_examples/hfp_ag_demo/btstack_config.h @@ -0,0 +1 @@ +#include "../../config/btstack_config_common.h" diff --git a/bluetooth/btstack_examples/hfp_hf_demo/CMakeLists.txt b/bluetooth/btstack_examples/hfp_hf_demo/CMakeLists.txt new file mode 100644 index 000000000..7db07599d --- /dev/null +++ b/bluetooth/btstack_examples/hfp_hf_demo/CMakeLists.txt @@ -0,0 +1,26 @@ +add_executable(hfp_hf_demo + ../main.c + ../btstack_audio_pico.c + ${PICO_BTSTACK_PATH}/example/hfp_hf_demo.c # note: this source is in pico-sdk/lib/btstack + ${PICO_BTSTACK_PATH}/src/btstack_audio_generator.c + ${PICO_BTSTACK_PATH}/example/sco_demo_util.c +) +target_link_libraries(hfp_hf_demo PRIVATE + pico_stdlib + pico_cyw43_arch_none # we don't need lwip support + pico_btstack_cyw43 # enable bt + pico_btstack_ble # ble support + pico_btstack_classic # classic support + pico_btstack_sbc_decoder + pico_audio_i2s +) +target_include_directories(hfp_hf_demo PRIVATE + . # for btstack config +) +target_compile_definitions(hfp_hf_demo PRIVATE + USING_I2C=1 + PICO_AUDIO_I2S_DATA_PIN=9 + PICO_AUDIO_I2S_CLOCK_PIN_BASE=10 +) +pico_add_extra_outputs(hfp_hf_demo) +example_auto_set_url(hfp_hf_demo) diff --git a/bluetooth/btstack_examples/hfp_hf_demo/btstack_config.h b/bluetooth/btstack_examples/hfp_hf_demo/btstack_config.h new file mode 100644 index 000000000..6eafef0a0 --- /dev/null +++ b/bluetooth/btstack_examples/hfp_hf_demo/btstack_config.h @@ -0,0 +1 @@ +#include "../../config/btstack_config_common.h" diff --git a/bluetooth/btstack_examples/hid_host_demo/CMakeLists.txt b/bluetooth/btstack_examples/hid_host_demo/CMakeLists.txt new file mode 100644 index 000000000..e44026984 --- /dev/null +++ b/bluetooth/btstack_examples/hid_host_demo/CMakeLists.txt @@ -0,0 +1,17 @@ +# See https://bluekitchen-gmbh.com/btstack/#examples/examples/#sec:hidhostdemoExample +add_executable(hid_host_demo + ../main.c + ${PICO_BTSTACK_PATH}/example/hid_host_demo.c # note: this source is in pico-sdk/lib/btstack +) +target_link_libraries(hid_host_demo PRIVATE + pico_stdlib + pico_cyw43_arch_none # we don't need lwip support + pico_btstack_cyw43 # enable bt + pico_btstack_ble # ble support + pico_btstack_classic # classic support +) +target_include_directories(hid_host_demo PRIVATE + . # for btstack config +) +pico_add_extra_outputs(hid_host_demo) +example_auto_set_url(hid_host_demo) diff --git a/bluetooth/btstack_examples/hid_host_demo/btstack_config.h b/bluetooth/btstack_examples/hid_host_demo/btstack_config.h new file mode 100644 index 000000000..6eafef0a0 --- /dev/null +++ b/bluetooth/btstack_examples/hid_host_demo/btstack_config.h @@ -0,0 +1 @@ +#include "../../config/btstack_config_common.h" diff --git a/bluetooth/btstack_examples/hid_keyboard_demo/CMakeLists.txt b/bluetooth/btstack_examples/hid_keyboard_demo/CMakeLists.txt new file mode 100644 index 000000000..585210776 --- /dev/null +++ b/bluetooth/btstack_examples/hid_keyboard_demo/CMakeLists.txt @@ -0,0 +1,17 @@ +# See https://bluekitchen-gmbh.com/btstack/#examples/examples/#sec:hidkeyboarddemoExample +add_executable(hid_keyboard_demo + ../main.c + ${PICO_BTSTACK_PATH}/example/hid_keyboard_demo.c # note: this source is in pico-sdk/lib/btstack +) +target_link_libraries(hid_keyboard_demo PRIVATE + pico_stdlib + pico_cyw43_arch_none # we don't need lwip support + pico_btstack_cyw43 # enable bt + pico_btstack_ble # ble support + pico_btstack_classic # classic support +) +target_include_directories(hid_keyboard_demo PRIVATE + . # for btstack config +) +pico_add_extra_outputs(hid_keyboard_demo) +example_auto_set_url(hid_keyboard_demo) diff --git a/bluetooth/btstack_examples/hid_keyboard_demo/btstack_config.h b/bluetooth/btstack_examples/hid_keyboard_demo/btstack_config.h new file mode 100644 index 000000000..6eafef0a0 --- /dev/null +++ b/bluetooth/btstack_examples/hid_keyboard_demo/btstack_config.h @@ -0,0 +1 @@ +#include "../../config/btstack_config_common.h" diff --git a/bluetooth/btstack_examples/hid_mouse_demo/CMakeLists.txt b/bluetooth/btstack_examples/hid_mouse_demo/CMakeLists.txt new file mode 100644 index 000000000..c5f09d017 --- /dev/null +++ b/bluetooth/btstack_examples/hid_mouse_demo/CMakeLists.txt @@ -0,0 +1,17 @@ +# See https://bluekitchen-gmbh.com/btstack/#examples/examples/#sec:hogmousedemoExample +add_executable(hid_mouse_demo + ../main.c + ${PICO_BTSTACK_PATH}/example/hid_mouse_demo.c # note: this source is in pico-sdk/lib/btstack +) +target_link_libraries(hid_mouse_demo PRIVATE + pico_stdlib + pico_cyw43_arch_none # we don't need lwip support + pico_btstack_cyw43 # enable bt + pico_btstack_ble # ble support + pico_btstack_classic # classic support +) +target_include_directories(hid_mouse_demo PRIVATE + . # for btstack config +) +pico_add_extra_outputs(hid_mouse_demo) +example_auto_set_url(hid_mouse_demo) diff --git a/bluetooth/btstack_examples/hid_mouse_demo/btstack_config.h b/bluetooth/btstack_examples/hid_mouse_demo/btstack_config.h new file mode 100644 index 000000000..6eafef0a0 --- /dev/null +++ b/bluetooth/btstack_examples/hid_mouse_demo/btstack_config.h @@ -0,0 +1 @@ +#include "../../config/btstack_config_common.h" diff --git a/bluetooth/btstack_examples/hog_boot_host_demo/CMakeLists.txt b/bluetooth/btstack_examples/hog_boot_host_demo/CMakeLists.txt new file mode 100644 index 000000000..d04d39063 --- /dev/null +++ b/bluetooth/btstack_examples/hog_boot_host_demo/CMakeLists.txt @@ -0,0 +1,16 @@ +# See https://bluekitchen-gmbh.com/btstack/#examples/examples/#sec:hogboothostdemoExample +add_executable(hog_boot_host_demo + ../main.c + ${PICO_BTSTACK_PATH}/example/hog_boot_host_demo.c # note: this source is in pico-sdk/lib/btstack +) +target_link_libraries(hog_boot_host_demo PRIVATE + pico_stdlib + pico_cyw43_arch_none # we don't need lwip support + pico_btstack_cyw43 # enable bt + pico_btstack_ble # ble support +) +target_include_directories(hog_boot_host_demo PRIVATE + . # for btstack config +) +pico_add_extra_outputs(hog_boot_host_demo) +example_auto_set_url(hog_boot_host_demo) diff --git a/bluetooth/btstack_examples/hog_boot_host_demo/btstack_config.h b/bluetooth/btstack_examples/hog_boot_host_demo/btstack_config.h new file mode 100644 index 000000000..6eafef0a0 --- /dev/null +++ b/bluetooth/btstack_examples/hog_boot_host_demo/btstack_config.h @@ -0,0 +1 @@ +#include "../../config/btstack_config_common.h" diff --git a/bluetooth/btstack_examples/hog_host_demo/CMakeLists.txt b/bluetooth/btstack_examples/hog_host_demo/CMakeLists.txt new file mode 100644 index 000000000..379984982 --- /dev/null +++ b/bluetooth/btstack_examples/hog_host_demo/CMakeLists.txt @@ -0,0 +1,20 @@ +add_executable(hog_host_demo + ../main.c + ${PICO_BTSTACK_PATH}/example/hog_host_demo.c # note: this source is in pico-sdk/lib/btstack +) +target_link_libraries(hog_host_demo PRIVATE + pico_stdlib + pico_cyw43_arch_none # we don't need lwip support + pico_btstack_cyw43 # enable bt + pico_btstack_ble # ble support +) +target_include_directories(hog_host_demo PRIVATE + . # for btstack config +) +# This builds a header file with details of the gatt service described in a gatt file +# note: this source for this is in pico-sdk/lib/btstack +pico_btstack_make_gatt_header(hog_host_demo PRIVATE + ${PICO_BTSTACK_PATH}/example/hog_host_demo.gatt +) +pico_add_extra_outputs(hog_host_demo) +example_auto_set_url(hog_host_demo) diff --git a/bluetooth/btstack_examples/hog_host_demo/btstack_config.h b/bluetooth/btstack_examples/hog_host_demo/btstack_config.h new file mode 100644 index 000000000..6eafef0a0 --- /dev/null +++ b/bluetooth/btstack_examples/hog_host_demo/btstack_config.h @@ -0,0 +1 @@ +#include "../../config/btstack_config_common.h" diff --git a/bluetooth/btstack_examples/hog_keyboard_demo/CMakeLists.txt b/bluetooth/btstack_examples/hog_keyboard_demo/CMakeLists.txt new file mode 100644 index 000000000..3525318de --- /dev/null +++ b/bluetooth/btstack_examples/hog_keyboard_demo/CMakeLists.txt @@ -0,0 +1,21 @@ +# See https://bluekitchen-gmbh.com/btstack/#examples/examples/#sec:hogkeyboarddemoExample +add_executable(hog_keyboard_demo + ../main.c + ${PICO_BTSTACK_PATH}/example/hog_keyboard_demo.c # note: this source is in pico-sdk/lib/btstack +) +target_link_libraries(hog_keyboard_demo PRIVATE + pico_stdlib + pico_cyw43_arch_none # we don't need lwip support + pico_btstack_cyw43 # enable bt + pico_btstack_ble # ble support +) +target_include_directories(hog_keyboard_demo PRIVATE + . # for btstack config +) +# This builds a header file with details of the gatt service described in a gatt file +# note: this source for this is in pico-sdk/lib/btstack +pico_btstack_make_gatt_header(hog_keyboard_demo PRIVATE + ${PICO_BTSTACK_PATH}/example/hog_keyboard_demo.gatt +) +pico_add_extra_outputs(hog_keyboard_demo) +example_auto_set_url(hog_keyboard_demo) diff --git a/bluetooth/btstack_examples/hog_keyboard_demo/btstack_config.h b/bluetooth/btstack_examples/hog_keyboard_demo/btstack_config.h new file mode 100644 index 000000000..6eafef0a0 --- /dev/null +++ b/bluetooth/btstack_examples/hog_keyboard_demo/btstack_config.h @@ -0,0 +1 @@ +#include "../../config/btstack_config_common.h" diff --git a/bluetooth/btstack_examples/hog_mouse_demo/CMakeLists.txt b/bluetooth/btstack_examples/hog_mouse_demo/CMakeLists.txt new file mode 100644 index 000000000..93a6fc9ac --- /dev/null +++ b/bluetooth/btstack_examples/hog_mouse_demo/CMakeLists.txt @@ -0,0 +1,21 @@ +# See https://bluekitchen-gmbh.com/btstack/#examples/examples/#sec:hogmousedemoExample +add_executable(hog_mouse_demo + ../main.c + ${PICO_BTSTACK_PATH}/example/hog_mouse_demo.c # note: this source is in pico-sdk/lib/btstack +) +target_link_libraries(hog_mouse_demo PRIVATE + pico_stdlib + pico_cyw43_arch_none # we don't need lwip support + pico_btstack_cyw43 # enable bt + pico_btstack_ble # ble support +) +target_include_directories(hog_mouse_demo PRIVATE + . # for btstack config +) +# This builds a header file with details of the gatt service described in a gatt file +# note: this source for this is in pico-sdk/lib/btstack +pico_btstack_make_gatt_header(hog_mouse_demo PRIVATE + ${PICO_BTSTACK_PATH}/example/hog_mouse_demo.gatt +) +pico_add_extra_outputs(hog_mouse_demo) +example_auto_set_url(hog_mouse_demo) diff --git a/bluetooth/btstack_examples/hog_mouse_demo/btstack_config.h b/bluetooth/btstack_examples/hog_mouse_demo/btstack_config.h new file mode 100644 index 000000000..6eafef0a0 --- /dev/null +++ b/bluetooth/btstack_examples/hog_mouse_demo/btstack_config.h @@ -0,0 +1 @@ +#include "../../config/btstack_config_common.h" diff --git a/bluetooth/btstack_examples/hsp_ag_demo/CMakeLists.txt b/bluetooth/btstack_examples/hsp_ag_demo/CMakeLists.txt new file mode 100644 index 000000000..eb3a98382 --- /dev/null +++ b/bluetooth/btstack_examples/hsp_ag_demo/CMakeLists.txt @@ -0,0 +1,27 @@ +# See https://bluekitchen-gmbh.com/btstack/#examples/examples/#sec:hspagdemoExample +add_executable(hsp_ag_demo + ../main.c + ../btstack_audio_pico.c + ${PICO_BTSTACK_PATH}/example/hsp_ag_demo.c # note: this source is in pico-sdk/lib/btstack + ${PICO_BTSTACK_PATH}/src/btstack_audio_generator.c + ${PICO_BTSTACK_PATH}/example/sco_demo_util.c +) +target_link_libraries(hsp_ag_demo PRIVATE + pico_stdlib + pico_cyw43_arch_none # we don't need lwip support + pico_btstack_cyw43 # enable bt + pico_btstack_ble # ble support + pico_btstack_classic # classic support + pico_btstack_sbc_decoder + pico_audio_i2s +) +target_include_directories(hsp_ag_demo PRIVATE + . # for btstack config +) +target_compile_definitions(hsp_ag_demo PRIVATE + USING_I2C=1 + PICO_AUDIO_I2S_DATA_PIN=9 + PICO_AUDIO_I2S_CLOCK_PIN_BASE=10 +) +pico_add_extra_outputs(hsp_ag_demo) +example_auto_set_url(hsp_ag_demo) diff --git a/bluetooth/btstack_examples/hsp_ag_demo/btstack_config.h b/bluetooth/btstack_examples/hsp_ag_demo/btstack_config.h new file mode 100644 index 000000000..6eafef0a0 --- /dev/null +++ b/bluetooth/btstack_examples/hsp_ag_demo/btstack_config.h @@ -0,0 +1 @@ +#include "../../config/btstack_config_common.h" diff --git a/bluetooth/btstack_examples/hsp_hs_demo/CMakeLists.txt b/bluetooth/btstack_examples/hsp_hs_demo/CMakeLists.txt new file mode 100644 index 000000000..15441b561 --- /dev/null +++ b/bluetooth/btstack_examples/hsp_hs_demo/CMakeLists.txt @@ -0,0 +1,27 @@ +# See https://bluekitchen-gmbh.com/btstack/#examples/examples/#sec:hsphsdemoExample +add_executable(hsp_hs_demo + ../main.c + ../btstack_audio_pico.c + ${PICO_BTSTACK_PATH}/example/hsp_hs_demo.c # note: this source is in pico-sdk/lib/btstack + ${PICO_BTSTACK_PATH}/src/btstack_audio_generator.c + ${PICO_BTSTACK_PATH}/example/sco_demo_util.c +) +target_link_libraries(hsp_hs_demo PRIVATE + pico_stdlib + pico_cyw43_arch_none # we don't need lwip support + pico_btstack_cyw43 # enable bt + pico_btstack_ble # ble support + pico_btstack_classic # classic support + pico_btstack_sbc_decoder + pico_audio_i2s +) +target_include_directories(hsp_hs_demo PRIVATE + . # for btstack config +) +target_compile_definitions(hsp_hs_demo PRIVATE + USING_I2C=1 + PICO_AUDIO_I2S_DATA_PIN=9 + PICO_AUDIO_I2S_CLOCK_PIN_BASE=10 +) +pico_add_extra_outputs(hsp_hs_demo) +example_auto_set_url(hsp_hs_demo) diff --git a/bluetooth/btstack_examples/hsp_hs_demo/btstack_config.h b/bluetooth/btstack_examples/hsp_hs_demo/btstack_config.h new file mode 100644 index 000000000..6eafef0a0 --- /dev/null +++ b/bluetooth/btstack_examples/hsp_hs_demo/btstack_config.h @@ -0,0 +1 @@ +#include "../../config/btstack_config_common.h" diff --git a/bluetooth/btstack_examples/le_credit_based_flow_control_mode_client/CMakeLists.txt b/bluetooth/btstack_examples/le_credit_based_flow_control_mode_client/CMakeLists.txt new file mode 100644 index 000000000..69db2686e --- /dev/null +++ b/bluetooth/btstack_examples/le_credit_based_flow_control_mode_client/CMakeLists.txt @@ -0,0 +1,16 @@ +# See https://bluekitchen-gmbh.com/btstack/#examples/examples/#sec:lecreditbasedflowcontrolmodeclientExample +add_executable(le_credit_based_flow_control_mode_client + ../main.c + ${PICO_BTSTACK_PATH}/example/le_credit_based_flow_control_mode_client.c # note: this source is in pico-sdk/lib/btstack +) +target_link_libraries(le_credit_based_flow_control_mode_client PRIVATE + pico_stdlib + pico_cyw43_arch_none # we don't need lwip support + pico_btstack_cyw43 # enable bt + pico_btstack_ble # ble support +) +target_include_directories(le_credit_based_flow_control_mode_client PRIVATE + . # for btstack config +) +pico_add_extra_outputs(le_credit_based_flow_control_mode_client) +example_auto_set_url(le_credit_based_flow_control_mode_client) diff --git a/bluetooth/btstack_examples/le_credit_based_flow_control_mode_client/btstack_config.h b/bluetooth/btstack_examples/le_credit_based_flow_control_mode_client/btstack_config.h new file mode 100644 index 000000000..6eafef0a0 --- /dev/null +++ b/bluetooth/btstack_examples/le_credit_based_flow_control_mode_client/btstack_config.h @@ -0,0 +1 @@ +#include "../../config/btstack_config_common.h" diff --git a/bluetooth/btstack_examples/le_credit_based_flow_control_mode_server/CMakeLists.txt b/bluetooth/btstack_examples/le_credit_based_flow_control_mode_server/CMakeLists.txt new file mode 100644 index 000000000..da49f97d6 --- /dev/null +++ b/bluetooth/btstack_examples/le_credit_based_flow_control_mode_server/CMakeLists.txt @@ -0,0 +1,21 @@ +# See https://bluekitchen-gmbh.com/btstack/#examples/examples/#sec:lecreditbasedflowcontrolmodeserverExample +add_executable(le_credit_based_flow_control_mode_server + ../main.c + ${PICO_BTSTACK_PATH}/example/le_credit_based_flow_control_mode_server.c # note: this source is in pico-sdk/lib/btstack +) +target_link_libraries(le_credit_based_flow_control_mode_server PRIVATE + pico_stdlib + pico_cyw43_arch_none # we don't need lwip support + pico_btstack_cyw43 # enable bt + pico_btstack_ble # ble support +) +target_include_directories(le_credit_based_flow_control_mode_server PRIVATE + . # for btstack config +) +# This builds a header file with details of the gatt service described in a gatt file +# note: this source for this is in pico-sdk/lib/btstack +pico_btstack_make_gatt_header(le_credit_based_flow_control_mode_server PRIVATE + ${PICO_BTSTACK_PATH}/example/le_credit_based_flow_control_mode_server.gatt +) +pico_add_extra_outputs(le_credit_based_flow_control_mode_server) +example_auto_set_url(le_credit_based_flow_control_mode_server) diff --git a/bluetooth/btstack_examples/le_credit_based_flow_control_mode_server/btstack_config.h b/bluetooth/btstack_examples/le_credit_based_flow_control_mode_server/btstack_config.h new file mode 100644 index 000000000..6eafef0a0 --- /dev/null +++ b/bluetooth/btstack_examples/le_credit_based_flow_control_mode_server/btstack_config.h @@ -0,0 +1 @@ +#include "../../config/btstack_config_common.h" diff --git a/bluetooth/btstack_examples/le_mitm/CMakeLists.txt b/bluetooth/btstack_examples/le_mitm/CMakeLists.txt new file mode 100644 index 000000000..25363f445 --- /dev/null +++ b/bluetooth/btstack_examples/le_mitm/CMakeLists.txt @@ -0,0 +1,16 @@ +# See https://bluekitchen-gmbh.com/btstack/#examples/examples/#sec:lemitmExample +add_executable(le_mitm + ../main.c + ${PICO_BTSTACK_PATH}/example/le_mitm.c # note: this source is in pico-sdk/lib/btstack +) +target_link_libraries(le_mitm PRIVATE + pico_stdlib + pico_cyw43_arch_none # we don't need lwip support + pico_btstack_cyw43 # enable bt + pico_btstack_ble # ble support +) +target_include_directories(le_mitm PRIVATE + . # for btstack config +) +pico_add_extra_outputs(le_mitm) +example_auto_set_url(le_mitm) diff --git a/bluetooth/btstack_examples/le_mitm/btstack_config.h b/bluetooth/btstack_examples/le_mitm/btstack_config.h new file mode 100644 index 000000000..6eafef0a0 --- /dev/null +++ b/bluetooth/btstack_examples/le_mitm/btstack_config.h @@ -0,0 +1 @@ +#include "../../config/btstack_config_common.h" diff --git a/bluetooth/btstack_examples/le_streamer_client/CMakeLists.txt b/bluetooth/btstack_examples/le_streamer_client/CMakeLists.txt new file mode 100644 index 000000000..0aec25ea1 --- /dev/null +++ b/bluetooth/btstack_examples/le_streamer_client/CMakeLists.txt @@ -0,0 +1,17 @@ +# See https://bluekitchen-gmbh.com/btstack/#examples/examples/#sec:lestreamerclientExample +add_executable(le_streamer_client + ../main.c + ${PICO_BTSTACK_PATH}/example/le_streamer_client.c # note: this source is in pico-sdk/lib/btstack + ${PICO_BTSTACK_PATH}/src/ble/gatt_service_client.c +) +target_link_libraries(le_streamer_client PRIVATE + pico_stdlib + pico_cyw43_arch_none # we don't need lwip support + pico_btstack_cyw43 # enable bt + pico_btstack_ble # ble support +) +target_include_directories(le_streamer_client PRIVATE + . # for btstack config +) +pico_add_extra_outputs(le_streamer_client) +example_auto_set_url(le_streamer_client) diff --git a/bluetooth/btstack_examples/le_streamer_client/btstack_config.h b/bluetooth/btstack_examples/le_streamer_client/btstack_config.h new file mode 100644 index 000000000..6eafef0a0 --- /dev/null +++ b/bluetooth/btstack_examples/le_streamer_client/btstack_config.h @@ -0,0 +1 @@ +#include "../../config/btstack_config_common.h" diff --git a/bluetooth/btstack_examples/led_counter/CMakeLists.txt b/bluetooth/btstack_examples/led_counter/CMakeLists.txt new file mode 100644 index 000000000..c118fb311 --- /dev/null +++ b/bluetooth/btstack_examples/led_counter/CMakeLists.txt @@ -0,0 +1,16 @@ +# See https://bluekitchen-gmbh.com/btstack/#examples/examples/#sec:ledcounterExample +add_executable(led_counter + ../main.c + ${PICO_BTSTACK_PATH}/example/led_counter.c # note: this source is in pico-sdk/lib/btstack +) +target_link_libraries(led_counter PRIVATE + pico_stdlib + pico_cyw43_arch_none # we don't need lwip support + pico_btstack_cyw43 # enable bt + pico_btstack_ble # ble support +) +target_include_directories(led_counter PRIVATE + . # for btstack config +) +pico_add_extra_outputs(led_counter) +example_auto_set_url(led_counter) diff --git a/bluetooth/btstack_examples/led_counter/btstack_config.h b/bluetooth/btstack_examples/led_counter/btstack_config.h new file mode 100644 index 000000000..6eafef0a0 --- /dev/null +++ b/bluetooth/btstack_examples/led_counter/btstack_config.h @@ -0,0 +1 @@ +#include "../../config/btstack_config_common.h" diff --git a/bluetooth/btstack_examples/main.c b/bluetooth/btstack_examples/main.c new file mode 100644 index 000000000..39297dc99 --- /dev/null +++ b/bluetooth/btstack_examples/main.c @@ -0,0 +1,82 @@ +/** + * Copyright (c) 2026 Raspberry Pi (Trading) Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "pico/stdlib.h" +#include "pico/cyw43_arch.h" +#include "btstack.h" + +#if USING_IPERF +#include "lwip/apps/lwiperf.h" +#endif + +// This is implemented isn pico-sdk/lib/btstack/example/.c +int btstack_main(int argc, const char * argv[]); + +#if USING_I2C +// This sets up the audio sink +const btstack_audio_sink_t * btstack_audio_pico_sink_get_instance(void); +#endif + +#if USING_IPERF +// Report IP results +static void iperf_report(void *arg, enum lwiperf_report_type report_type, + const ip_addr_t *local_addr, u16_t local_port, const ip_addr_t *remote_addr, u16_t remote_port, + u32_t bytes_transferred, u32_t ms_duration, u32_t bandwidth_kbitpsec) { + static uint32_t total_iperf_megabytes = 0; + uint32_t mbytes = bytes_transferred / 1024 / 1024; + float mbits = bandwidth_kbitpsec / 1000.0; + total_iperf_megabytes += mbytes; + + printf("Completed iperf transfer of %d MBytes @ %.1f Mbits/sec\n", mbytes, mbits); + printf("Total iperf megabytes since start %d Mbytes\n", total_iperf_megabytes); +} +#endif + +// This is used in some examples to turn the led on and off +void hal_led_toggle(void){ + static int led_state; + led_state = 1 - led_state; + cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, led_state); +} + +int main() { + stdio_init_all(); + + if (cyw43_arch_init() != PICO_OK) { + panic("failed to cyw43"); + } + +#if USING_I2C + btstack_audio_sink_set_instance(btstack_audio_pico_sink_get_instance()); +#endif + + // Setup the example + btstack_main(0, NULL); + +#if defined(WIFI_SSID) && defined(WIFI_PASSWORD) + // Connect to WiFi + cyw43_arch_enable_sta_mode(); + printf("Connecting to Wi-Fi...\n"); + if (cyw43_arch_wifi_connect_timeout_ms(WIFI_SSID, WIFI_PASSWORD, CYW43_AUTH_WPA2_AES_PSK, 30000)) { + panic("failed to connect"); + } else { + printf("Connected.\n"); + } +#endif + +#if USING_IPERF + // Run iperf server + cyw43_arch_lwip_begin(); + printf("\nReady, running iperf server at %s\n", ip4addr_ntoa(netif_ip4_addr(netif_list))); + lwiperf_start_tcp_server_default(&iperf_report, NULL); + cyw43_arch_lwip_end(); +#endif + + btstack_run_loop_execute(); // run until btstack_run_loop_trigger_exit is called + + cyw43_arch_deinit(); + return 0; +} diff --git a/bluetooth/btstack_examples/mod_player/CMakeLists.txt b/bluetooth/btstack_examples/mod_player/CMakeLists.txt new file mode 100644 index 000000000..2030a3bb2 --- /dev/null +++ b/bluetooth/btstack_examples/mod_player/CMakeLists.txt @@ -0,0 +1,24 @@ +# See https://bluekitchen-gmbh.com/btstack/#examples/examples/#sec:modplayerExample +add_executable(mod_player + ../main.c + ../btstack_audio_pico.c + ${PICO_BTSTACK_PATH}/example/mod_player.c # note: this source is in pico-sdk/lib/btstack + ) +target_link_libraries(mod_player PRIVATE + pico_stdlib + pico_cyw43_arch_none # we don't need lwip support + pico_btstack_cyw43 # enable bt + pico_btstack_ble # ble support + pico_btstack_hxcmod_player + pico_audio_i2s +) +target_include_directories(mod_player PRIVATE + . # for btstack config +) +target_compile_definitions(mod_player PRIVATE + USING_I2C=1 + PICO_AUDIO_I2S_DATA_PIN=9 + PICO_AUDIO_I2S_CLOCK_PIN_BASE=10 +) +pico_add_extra_outputs(mod_player) +example_auto_set_url(mod_player) diff --git a/bluetooth/btstack_examples/mod_player/btstack_config.h b/bluetooth/btstack_examples/mod_player/btstack_config.h new file mode 100644 index 000000000..6eafef0a0 --- /dev/null +++ b/bluetooth/btstack_examples/mod_player/btstack_config.h @@ -0,0 +1 @@ +#include "../../config/btstack_config_common.h" diff --git a/bluetooth/btstack_examples/nordic_spp_le_counter/CMakeLists.txt b/bluetooth/btstack_examples/nordic_spp_le_counter/CMakeLists.txt new file mode 100644 index 000000000..eb877bcce --- /dev/null +++ b/bluetooth/btstack_examples/nordic_spp_le_counter/CMakeLists.txt @@ -0,0 +1,21 @@ +# See https://bluekitchen-gmbh.com/btstack/#examples/examples/#sec:nordicspplecounterExample +add_executable(nordic_spp_le_counter + ../main.c + ${PICO_BTSTACK_PATH}/example/nordic_spp_le_counter.c # note: this source is in pico-sdk/lib/btstack +) +target_link_libraries(nordic_spp_le_counter PRIVATE + pico_stdlib + pico_cyw43_arch_none # we don't need lwip support + pico_btstack_cyw43 # enable bt + pico_btstack_ble # ble support +) +target_include_directories(nordic_spp_le_counter PRIVATE + . # for btstack config +) +# This builds a header file with details of the gatt service described in a gatt file +# note: this source for this is in pico-sdk/lib/btstack +pico_btstack_make_gatt_header(nordic_spp_le_counter PRIVATE + ${PICO_BTSTACK_PATH}/example/nordic_spp_le_counter.gatt +) +pico_add_extra_outputs(nordic_spp_le_counter) +example_auto_set_url(nordic_spp_le_counter) diff --git a/bluetooth/btstack_examples/nordic_spp_le_counter/btstack_config.h b/bluetooth/btstack_examples/nordic_spp_le_counter/btstack_config.h new file mode 100644 index 000000000..6eafef0a0 --- /dev/null +++ b/bluetooth/btstack_examples/nordic_spp_le_counter/btstack_config.h @@ -0,0 +1 @@ +#include "../../config/btstack_config_common.h" diff --git a/bluetooth/btstack_examples/nordic_spp_le_streamer/CMakeLists.txt b/bluetooth/btstack_examples/nordic_spp_le_streamer/CMakeLists.txt new file mode 100644 index 000000000..71b12d0f2 --- /dev/null +++ b/bluetooth/btstack_examples/nordic_spp_le_streamer/CMakeLists.txt @@ -0,0 +1,21 @@ +# See https://bluekitchen-gmbh.com/btstack/#examples/examples/#sec:nordicspplestreamerExample +add_executable(nordic_spp_le_streamer + ../main.c + ${PICO_BTSTACK_PATH}/example/nordic_spp_le_streamer.c # note: this source is in pico-sdk/lib/btstack +) +target_link_libraries(nordic_spp_le_streamer PRIVATE + pico_stdlib + pico_cyw43_arch_none # we don't need lwip support + pico_btstack_cyw43 # enable bt + pico_btstack_ble # ble support +) +target_include_directories(nordic_spp_le_streamer PRIVATE + . # for btstack config +) +# This builds a header file with details of the gatt service described in a gatt file +# note: this source for this is in pico-sdk/lib/btstack +pico_btstack_make_gatt_header(nordic_spp_le_streamer PRIVATE + ${PICO_BTSTACK_PATH}/example/nordic_spp_le_streamer.gatt +) +pico_add_extra_outputs(nordic_spp_le_streamer) +example_auto_set_url(nordic_spp_le_streamer) diff --git a/bluetooth/btstack_examples/nordic_spp_le_streamer/btstack_config.h b/bluetooth/btstack_examples/nordic_spp_le_streamer/btstack_config.h new file mode 100644 index 000000000..6eafef0a0 --- /dev/null +++ b/bluetooth/btstack_examples/nordic_spp_le_streamer/btstack_config.h @@ -0,0 +1 @@ +#include "../../config/btstack_config_common.h" diff --git a/bluetooth/btstack_examples/pan_lwip_http_server/CMakeLists.txt b/bluetooth/btstack_examples/pan_lwip_http_server/CMakeLists.txt new file mode 100644 index 000000000..4789aadca --- /dev/null +++ b/bluetooth/btstack_examples/pan_lwip_http_server/CMakeLists.txt @@ -0,0 +1,25 @@ +# See https://bluekitchen-gmbh.com/btstack/#examples/examples/#sec:panlwiphttpserverExample +add_executable(pan_lwip_http_server + ../main.c + ${PICO_BTSTACK_PATH}/example/pan_lwip_http_server.c # note: this source is in pico-sdk/lib/btstack + ${PICO_BTSTACK_PATH}/3rd-party/lwip/dhcp-server/dhserver.c +) +target_link_libraries(pan_lwip_http_server PRIVATE + pico_stdlib + pico_cyw43_arch_threadsafe_background + pico_btstack_cyw43 # enable bt + pico_btstack_ble # ble support + pico_btstack_classic # classic support + pico_btstack_bnep_lwip # btstack lwip + pico_lwip_http + pico_lwip_nosys + ) +target_include_directories(pan_lwip_http_server PRIVATE + . # for btstack config and lwipopts.h + ${PICO_BTSTACK_PATH}/3rd-party/lwip/dhcp-server +) +target_compile_definitions(pan_lwip_http_server PRIVATE + CYW43_LWIP=0 # Stop cyw43 doing lwip stuff +) +pico_add_extra_outputs(pan_lwip_http_server) +example_auto_set_url(pan_lwip_http_server) diff --git a/bluetooth/btstack_examples/pan_lwip_http_server/btstack_config.h b/bluetooth/btstack_examples/pan_lwip_http_server/btstack_config.h new file mode 100644 index 000000000..6eafef0a0 --- /dev/null +++ b/bluetooth/btstack_examples/pan_lwip_http_server/btstack_config.h @@ -0,0 +1 @@ +#include "../../config/btstack_config_common.h" diff --git a/bluetooth/btstack_examples/pan_lwip_http_server/lwipopts.h b/bluetooth/btstack_examples/pan_lwip_http_server/lwipopts.h new file mode 100644 index 000000000..8bf98aed8 --- /dev/null +++ b/bluetooth/btstack_examples/pan_lwip_http_server/lwipopts.h @@ -0,0 +1 @@ +#include "../../../pico_w/wifi/lwipopts_examples_common.h" diff --git a/bluetooth/btstack_examples/pbap_client_demo/CMakeLists.txt b/bluetooth/btstack_examples/pbap_client_demo/CMakeLists.txt new file mode 100644 index 000000000..d46c33ad4 --- /dev/null +++ b/bluetooth/btstack_examples/pbap_client_demo/CMakeLists.txt @@ -0,0 +1,17 @@ +# See https://bluekitchen-gmbh.com/btstack/#examples/examples/#sec:pbapclientdemoExample +add_executable(pbap_client_demo + ../main.c + ${PICO_BTSTACK_PATH}/example/pbap_client_demo.c # note: this source is in pico-sdk/lib/btstack +) +target_link_libraries(pbap_client_demo PRIVATE + pico_stdlib + pico_cyw43_arch_none # we don't need lwip support + pico_btstack_cyw43 # enable bt + pico_btstack_ble # ble support + pico_btstack_classic # classic support +) +target_include_directories(pbap_client_demo PRIVATE + . # for btstack config +) +pico_add_extra_outputs(pbap_client_demo) +example_auto_set_url(pbap_client_demo) diff --git a/bluetooth/btstack_examples/pbap_client_demo/btstack_config.h b/bluetooth/btstack_examples/pbap_client_demo/btstack_config.h new file mode 100644 index 000000000..6eafef0a0 --- /dev/null +++ b/bluetooth/btstack_examples/pbap_client_demo/btstack_config.h @@ -0,0 +1 @@ +#include "../../config/btstack_config_common.h" diff --git a/bluetooth/btstack_examples/sdp_bnep_query/CMakeLists.txt b/bluetooth/btstack_examples/sdp_bnep_query/CMakeLists.txt new file mode 100644 index 000000000..8148cc649 --- /dev/null +++ b/bluetooth/btstack_examples/sdp_bnep_query/CMakeLists.txt @@ -0,0 +1,17 @@ +# See https://bluekitchen-gmbh.com/btstack/#examples/examples/#sec:sdpbnepqueryExample +add_executable(sdp_bnep_query + ../main.c + ${PICO_BTSTACK_PATH}/example/sdp_bnep_query.c # note: this source is in pico-sdk/lib/btstack +) +target_link_libraries(sdp_bnep_query PRIVATE + pico_stdlib + pico_cyw43_arch_none # we don't need lwip support + pico_btstack_cyw43 # enable bt + pico_btstack_ble # ble support + pico_btstack_classic # classic support +) +target_include_directories(sdp_bnep_query PRIVATE + . # for btstack config +) +pico_add_extra_outputs(sdp_bnep_query) +example_auto_set_url(sdp_bnep_query) diff --git a/bluetooth/btstack_examples/sdp_bnep_query/btstack_config.h b/bluetooth/btstack_examples/sdp_bnep_query/btstack_config.h new file mode 100644 index 000000000..6eafef0a0 --- /dev/null +++ b/bluetooth/btstack_examples/sdp_bnep_query/btstack_config.h @@ -0,0 +1 @@ +#include "../../config/btstack_config_common.h" diff --git a/bluetooth/btstack_examples/sdp_general_query/CMakeLists.txt b/bluetooth/btstack_examples/sdp_general_query/CMakeLists.txt new file mode 100644 index 000000000..67207ac96 --- /dev/null +++ b/bluetooth/btstack_examples/sdp_general_query/CMakeLists.txt @@ -0,0 +1,17 @@ +# See https://bluekitchen-gmbh.com/btstack/#examples/examples/#sec:sdpgeneralqueryExample +add_executable(sdp_general_query + ../main.c + ${PICO_BTSTACK_PATH}/example/sdp_general_query.c # note: this source is in pico-sdk/lib/btstack +) +target_link_libraries(sdp_general_query PRIVATE + pico_stdlib + pico_cyw43_arch_none # we don't need lwip support + pico_btstack_cyw43 # enable bt + pico_btstack_ble # ble support + pico_btstack_classic # classic support +) +target_include_directories(sdp_general_query PRIVATE + . # for btstack config +) +pico_add_extra_outputs(sdp_general_query) +example_auto_set_url(sdp_general_query) diff --git a/bluetooth/btstack_examples/sdp_general_query/btstack_config.h b/bluetooth/btstack_examples/sdp_general_query/btstack_config.h new file mode 100644 index 000000000..6eafef0a0 --- /dev/null +++ b/bluetooth/btstack_examples/sdp_general_query/btstack_config.h @@ -0,0 +1 @@ +#include "../../config/btstack_config_common.h" diff --git a/bluetooth/btstack_examples/sdp_rfcomm_query/CMakeLists.txt b/bluetooth/btstack_examples/sdp_rfcomm_query/CMakeLists.txt new file mode 100644 index 000000000..ff0c6e99a --- /dev/null +++ b/bluetooth/btstack_examples/sdp_rfcomm_query/CMakeLists.txt @@ -0,0 +1,17 @@ +# See https://bluekitchen-gmbh.com/btstack/#examples/examples/#sec:sdprfcommqueryExample +add_executable(sdp_rfcomm_query + ../main.c + ${PICO_BTSTACK_PATH}/example/sdp_rfcomm_query.c # note: this source is in pico-sdk/lib/btstack +) +target_link_libraries(sdp_rfcomm_query PRIVATE + pico_stdlib + pico_cyw43_arch_none # we don't need lwip support + pico_btstack_cyw43 # enable bt + pico_btstack_ble # ble support + pico_btstack_classic # classic support +) +target_include_directories(sdp_rfcomm_query PRIVATE + . # for btstack config +) +pico_add_extra_outputs(sdp_rfcomm_query) +example_auto_set_url(sdp_rfcomm_query) diff --git a/bluetooth/btstack_examples/sdp_rfcomm_query/btstack_config.h b/bluetooth/btstack_examples/sdp_rfcomm_query/btstack_config.h new file mode 100644 index 000000000..6eafef0a0 --- /dev/null +++ b/bluetooth/btstack_examples/sdp_rfcomm_query/btstack_config.h @@ -0,0 +1 @@ +#include "../../config/btstack_config_common.h" diff --git a/bluetooth/btstack_examples/sine_player/CMakeLists.txt b/bluetooth/btstack_examples/sine_player/CMakeLists.txt new file mode 100644 index 000000000..c970533ab --- /dev/null +++ b/bluetooth/btstack_examples/sine_player/CMakeLists.txt @@ -0,0 +1,23 @@ +# See https://bluekitchen-gmbh.com/btstack/#examples/examples/#sec:sineplayerExample +add_executable(sine_player + ../main.c + ../btstack_audio_pico.c + ${PICO_BTSTACK_PATH}/example/sine_player.c # note: this source is in pico-sdk/lib/btstack +) +target_link_libraries(sine_player PRIVATE + pico_stdlib + pico_cyw43_arch_none # we don't need lwip support + pico_btstack_cyw43 # enable bt + pico_btstack_ble # ble support + pico_audio_i2s +) +target_include_directories(sine_player PRIVATE + . # for btstack config +) +target_compile_definitions(sine_player PRIVATE + USING_I2C=1 + PICO_AUDIO_I2S_DATA_PIN=9 + PICO_AUDIO_I2S_CLOCK_PIN_BASE=10 +) +pico_add_extra_outputs(sine_player) +example_auto_set_url(sine_player) diff --git a/bluetooth/btstack_examples/sine_player/btstack_config.h b/bluetooth/btstack_examples/sine_player/btstack_config.h new file mode 100644 index 000000000..6eafef0a0 --- /dev/null +++ b/bluetooth/btstack_examples/sine_player/btstack_config.h @@ -0,0 +1 @@ +#include "../../config/btstack_config_common.h" diff --git a/bluetooth/btstack_examples/sm_pairing_central/CMakeLists.txt b/bluetooth/btstack_examples/sm_pairing_central/CMakeLists.txt new file mode 100644 index 000000000..dffcba9ce --- /dev/null +++ b/bluetooth/btstack_examples/sm_pairing_central/CMakeLists.txt @@ -0,0 +1,21 @@ +# See https://bluekitchen-gmbh.com/btstack/#examples/examples/#sec:smpairingcentralExample +add_executable(sm_pairing_central + ../main.c + ${PICO_BTSTACK_PATH}/example/sm_pairing_central.c # note: this source is in pico-sdk/lib/btstack +) +target_link_libraries(sm_pairing_central PRIVATE + pico_stdlib + pico_cyw43_arch_none # we don't need lwip support + pico_btstack_cyw43 # enable bt + pico_btstack_ble # ble support +) +target_include_directories(sm_pairing_central PRIVATE + . # for btstack config +) +# This builds a header file with details of the gatt service described in a gatt file +# note: this source for this is in pico-sdk/lib/btstack +pico_btstack_make_gatt_header(sm_pairing_central PRIVATE + ${PICO_BTSTACK_PATH}/example/sm_pairing_central.gatt +) +pico_add_extra_outputs(sm_pairing_central) +example_auto_set_url(sm_pairing_central) diff --git a/bluetooth/btstack_examples/sm_pairing_central/btstack_config.h b/bluetooth/btstack_examples/sm_pairing_central/btstack_config.h new file mode 100644 index 000000000..6eafef0a0 --- /dev/null +++ b/bluetooth/btstack_examples/sm_pairing_central/btstack_config.h @@ -0,0 +1 @@ +#include "../../config/btstack_config_common.h" diff --git a/bluetooth/btstack_examples/sm_pairing_peripheral/CMakeLists.txt b/bluetooth/btstack_examples/sm_pairing_peripheral/CMakeLists.txt new file mode 100644 index 000000000..f956d744c --- /dev/null +++ b/bluetooth/btstack_examples/sm_pairing_peripheral/CMakeLists.txt @@ -0,0 +1,21 @@ +# See https://bluekitchen-gmbh.com/btstack/#examples/examples/#sec:smpairingperipheralExample +add_executable(sm_pairing_peripheral + ../main.c + ${PICO_BTSTACK_PATH}/example/sm_pairing_peripheral.c # note: this source is in pico-sdk/lib/btstack +) +target_link_libraries(sm_pairing_peripheral PRIVATE + pico_stdlib + pico_cyw43_arch_none # we don't need lwip support + pico_btstack_cyw43 # enable bt + pico_btstack_ble # ble support +) +target_include_directories(sm_pairing_peripheral PRIVATE + . # for btstack config +) +# This builds a header file with details of the gatt service described in a gatt file +# note: this source for this is in pico-sdk/lib/btstack +pico_btstack_make_gatt_header(sm_pairing_peripheral PRIVATE + ${PICO_BTSTACK_PATH}/example/sm_pairing_peripheral.gatt +) +pico_add_extra_outputs(sm_pairing_peripheral) +example_auto_set_url(sm_pairing_peripheral) diff --git a/bluetooth/btstack_examples/sm_pairing_peripheral/btstack_config.h b/bluetooth/btstack_examples/sm_pairing_peripheral/btstack_config.h new file mode 100644 index 000000000..6eafef0a0 --- /dev/null +++ b/bluetooth/btstack_examples/sm_pairing_peripheral/btstack_config.h @@ -0,0 +1 @@ +#include "../../config/btstack_config_common.h" diff --git a/bluetooth/btstack_examples/spp_and_gatt_counter/CMakeLists.txt b/bluetooth/btstack_examples/spp_and_gatt_counter/CMakeLists.txt new file mode 100644 index 000000000..be6a73059 --- /dev/null +++ b/bluetooth/btstack_examples/spp_and_gatt_counter/CMakeLists.txt @@ -0,0 +1,22 @@ +# See https://bluekitchen-gmbh.com/btstack/#examples/examples/#sec:sppandgattcounterExample +add_executable(spp_and_gatt_counter + ../main.c + ${PICO_BTSTACK_PATH}/example/spp_and_gatt_counter.c # note: this source is in pico-sdk/lib/btstack +) +target_link_libraries(spp_and_gatt_counter PRIVATE + pico_stdlib + pico_cyw43_arch_none # we don't need lwip support + pico_btstack_cyw43 # enable bt + pico_btstack_ble # ble support + pico_btstack_classic # classic support +) +target_include_directories(spp_and_gatt_counter PRIVATE + . # for btstack config +) +# This builds a header file with details of the gatt service described in a gatt file +# note: this source for this is in pico-sdk/lib/btstack +pico_btstack_make_gatt_header(spp_and_gatt_counter PRIVATE + ${PICO_BTSTACK_PATH}/example/spp_and_gatt_counter.gatt +) +pico_add_extra_outputs(spp_and_gatt_counter) +example_auto_set_url(spp_and_gatt_counter) diff --git a/bluetooth/btstack_examples/spp_and_gatt_counter/btstack_config.h b/bluetooth/btstack_examples/spp_and_gatt_counter/btstack_config.h new file mode 100644 index 000000000..6eafef0a0 --- /dev/null +++ b/bluetooth/btstack_examples/spp_and_gatt_counter/btstack_config.h @@ -0,0 +1 @@ +#include "../../config/btstack_config_common.h" diff --git a/bluetooth/btstack_examples/spp_and_gatt_streamer/CMakeLists.txt b/bluetooth/btstack_examples/spp_and_gatt_streamer/CMakeLists.txt new file mode 100644 index 000000000..b036c2798 --- /dev/null +++ b/bluetooth/btstack_examples/spp_and_gatt_streamer/CMakeLists.txt @@ -0,0 +1,21 @@ +add_executable(spp_and_gatt_streamer + ../main.c + ${PICO_BTSTACK_PATH}/example/spp_and_gatt_streamer.c # note: this source is in pico-sdk/lib/btstack +) +target_link_libraries(spp_and_gatt_streamer PRIVATE + pico_stdlib + pico_cyw43_arch_none # we don't need lwip support + pico_btstack_cyw43 # enable bt + pico_btstack_ble # ble support + pico_btstack_classic # classic support +) +target_include_directories(spp_and_gatt_streamer PRIVATE + . # for btstack config +) +# This builds a header file with details of the gatt service described in a gatt file +# note: this source for this is in pico-sdk/lib/btstack +pico_btstack_make_gatt_header(spp_and_gatt_streamer PRIVATE + ${PICO_BTSTACK_PATH}/example/spp_and_gatt_streamer.gatt +) +pico_add_extra_outputs(spp_and_gatt_streamer) +example_auto_set_url(spp_and_gatt_streamer) diff --git a/bluetooth/btstack_examples/spp_and_gatt_streamer/btstack_config.h b/bluetooth/btstack_examples/spp_and_gatt_streamer/btstack_config.h new file mode 100644 index 000000000..6eafef0a0 --- /dev/null +++ b/bluetooth/btstack_examples/spp_and_gatt_streamer/btstack_config.h @@ -0,0 +1 @@ +#include "../../config/btstack_config_common.h" diff --git a/bluetooth/btstack_examples/spp_counter/CMakeLists.txt b/bluetooth/btstack_examples/spp_counter/CMakeLists.txt new file mode 100644 index 000000000..51559f428 --- /dev/null +++ b/bluetooth/btstack_examples/spp_counter/CMakeLists.txt @@ -0,0 +1,17 @@ +# See https://bluekitchen-gmbh.com/btstack/#examples/examples/#sec:sppcounterExample +add_executable(spp_counter + ../main.c + ${PICO_BTSTACK_PATH}/example/spp_counter.c # note: this source is in pico-sdk/lib/btstack +) +target_link_libraries(spp_counter PRIVATE + pico_stdlib + pico_cyw43_arch_none # we don't need lwip support + pico_btstack_cyw43 # enable bt + pico_btstack_ble # ble support + pico_btstack_classic # classic support +) +target_include_directories(spp_counter PRIVATE + . # for btstack config +) +pico_add_extra_outputs(spp_counter) +example_auto_set_url(spp_counter) diff --git a/bluetooth/btstack_examples/spp_counter/btstack_config.h b/bluetooth/btstack_examples/spp_counter/btstack_config.h new file mode 100644 index 000000000..6eafef0a0 --- /dev/null +++ b/bluetooth/btstack_examples/spp_counter/btstack_config.h @@ -0,0 +1 @@ +#include "../../config/btstack_config_common.h" diff --git a/bluetooth/btstack_examples/spp_flowcontrol/CMakeLists.txt b/bluetooth/btstack_examples/spp_flowcontrol/CMakeLists.txt new file mode 100644 index 000000000..464662add --- /dev/null +++ b/bluetooth/btstack_examples/spp_flowcontrol/CMakeLists.txt @@ -0,0 +1,17 @@ +# See https://bluekitchen-gmbh.com/btstack/#examples/examples/#sec:sppflowcontrolExample +add_executable(spp_flowcontrol + ../main.c + ${PICO_BTSTACK_PATH}/example/spp_flowcontrol.c # note: this source is in pico-sdk/lib/btstack +) +target_link_libraries(spp_flowcontrol PRIVATE + pico_stdlib + pico_cyw43_arch_none # we don't need lwip support + pico_btstack_cyw43 # enable bt + pico_btstack_ble # ble support + pico_btstack_classic # classic support +) +target_include_directories(spp_flowcontrol PRIVATE + . # for btstack config +) +pico_add_extra_outputs(spp_flowcontrol) +example_auto_set_url(spp_flowcontrol) diff --git a/bluetooth/btstack_examples/spp_flowcontrol/btstack_config.h b/bluetooth/btstack_examples/spp_flowcontrol/btstack_config.h new file mode 100644 index 000000000..6eafef0a0 --- /dev/null +++ b/bluetooth/btstack_examples/spp_flowcontrol/btstack_config.h @@ -0,0 +1 @@ +#include "../../config/btstack_config_common.h" diff --git a/bluetooth/btstack_examples/spp_streamer/CMakeLists.txt b/bluetooth/btstack_examples/spp_streamer/CMakeLists.txt new file mode 100644 index 000000000..91ec757ae --- /dev/null +++ b/bluetooth/btstack_examples/spp_streamer/CMakeLists.txt @@ -0,0 +1,17 @@ +# See https://bluekitchen-gmbh.com/btstack/#examples/examples/#sec:sppstreamerExample +add_executable(spp_streamer + ../main.c + ${PICO_BTSTACK_PATH}/example/spp_streamer.c # note: this source is in pico-sdk/lib/btstack +) +target_link_libraries(spp_streamer PRIVATE + pico_stdlib + pico_cyw43_arch_none # we don't need lwip support + pico_btstack_cyw43 # enable bt + pico_btstack_ble # ble support + pico_btstack_classic # classic support +) +target_include_directories(spp_streamer PRIVATE + . # for btstack config +) +pico_add_extra_outputs(spp_streamer) +example_auto_set_url(spp_streamer) diff --git a/bluetooth/btstack_examples/spp_streamer/btstack_config.h b/bluetooth/btstack_examples/spp_streamer/btstack_config.h new file mode 100644 index 000000000..6eafef0a0 --- /dev/null +++ b/bluetooth/btstack_examples/spp_streamer/btstack_config.h @@ -0,0 +1 @@ +#include "../../config/btstack_config_common.h" diff --git a/bluetooth/btstack_examples/spp_streamer_client/CMakeLists.txt b/bluetooth/btstack_examples/spp_streamer_client/CMakeLists.txt new file mode 100644 index 000000000..d0e12f2a2 --- /dev/null +++ b/bluetooth/btstack_examples/spp_streamer_client/CMakeLists.txt @@ -0,0 +1,17 @@ +# See https://bluekitchen-gmbh.com/btstack/#examples/examples/#sec:sppstreamerclientExample +add_executable(spp_streamer_client + ../main.c + ${PICO_BTSTACK_PATH}/example/spp_streamer_client.c # note: this source is in pico-sdk/lib/btstack +) +target_link_libraries(spp_streamer_client PRIVATE + pico_stdlib + pico_cyw43_arch_none # we don't need lwip support + pico_btstack_cyw43 # enable bt + pico_btstack_ble # ble support + pico_btstack_classic # classic support +) +target_include_directories(spp_streamer_client PRIVATE + . # for btstack config +) +pico_add_extra_outputs(spp_streamer_client) +example_auto_set_url(spp_streamer_client) diff --git a/bluetooth/btstack_examples/spp_streamer_client/btstack_config.h b/bluetooth/btstack_examples/spp_streamer_client/btstack_config.h new file mode 100644 index 000000000..6eafef0a0 --- /dev/null +++ b/bluetooth/btstack_examples/spp_streamer_client/btstack_config.h @@ -0,0 +1 @@ +#include "../../config/btstack_config_common.h" diff --git a/bluetooth/btstack_examples/spp_streamer_with_wifi/CMakeLists.txt b/bluetooth/btstack_examples/spp_streamer_with_wifi/CMakeLists.txt new file mode 100644 index 000000000..0f0ddef5a --- /dev/null +++ b/bluetooth/btstack_examples/spp_streamer_with_wifi/CMakeLists.txt @@ -0,0 +1,23 @@ +# See https://bluekitchen-gmbh.com/btstack/#examples/examples/#sec:sppstreamerExample +add_executable(spp_streamer_with_wifi + ../main.c + ${PICO_BTSTACK_PATH}/example/spp_streamer.c # note: this source is in pico-sdk/lib/btstack +) +target_link_libraries(spp_streamer_with_wifi PRIVATE + pico_stdlib + pico_cyw43_arch_lwip_threadsafe_background # we want lwip support + pico_btstack_cyw43 # enable bt + pico_btstack_ble # ble support + pico_btstack_classic # classic support + pico_lwip_iperf +) +target_include_directories(spp_streamer_with_wifi PRIVATE + . # for btstack config +) +target_compile_definitions(spp_streamer_with_wifi PRIVATE + WIFI_SSID=\"${WIFI_SSID}\" + WIFI_PASSWORD=\"${WIFI_PASSWORD}\" + USING_IPERF=1 +) +pico_add_extra_outputs(spp_streamer_with_wifi) +example_auto_set_url(spp_streamer_with_wifi) diff --git a/bluetooth/btstack_examples/spp_streamer_with_wifi/btstack_config.h b/bluetooth/btstack_examples/spp_streamer_with_wifi/btstack_config.h new file mode 100644 index 000000000..6eafef0a0 --- /dev/null +++ b/bluetooth/btstack_examples/spp_streamer_with_wifi/btstack_config.h @@ -0,0 +1 @@ +#include "../../config/btstack_config_common.h" diff --git a/bluetooth/btstack_examples/spp_streamer_with_wifi/lwipopts.h b/bluetooth/btstack_examples/spp_streamer_with_wifi/lwipopts.h new file mode 100644 index 000000000..8bf98aed8 --- /dev/null +++ b/bluetooth/btstack_examples/spp_streamer_with_wifi/lwipopts.h @@ -0,0 +1 @@ +#include "../../../pico_w/wifi/lwipopts_examples_common.h" diff --git a/bluetooth/btstack_examples/ublox_spp_le_counter/CMakeLists.txt b/bluetooth/btstack_examples/ublox_spp_le_counter/CMakeLists.txt new file mode 100644 index 000000000..70e4b516d --- /dev/null +++ b/bluetooth/btstack_examples/ublox_spp_le_counter/CMakeLists.txt @@ -0,0 +1,22 @@ +# See https://bluekitchen-gmbh.com/btstack/#examples/examples/#sec:ubloxspplecounterExample +add_executable(ublox_spp_le_counter + ../main.c + ${PICO_BTSTACK_PATH}/example/ublox_spp_le_counter.c # note: this source is in pico-sdk/lib/btstack +) +target_link_libraries(ublox_spp_le_counter PRIVATE + pico_stdlib + pico_cyw43_arch_none # we don't need lwip support + pico_btstack_cyw43 # enable bt + pico_btstack_ble # ble support + pico_btstack_classic # classic support +) +target_include_directories(ublox_spp_le_counter PRIVATE + . # for btstack config +) +# This builds a header file with details of the gatt service described in a gatt file +# note: this source for this is in pico-sdk/lib/btstack +pico_btstack_make_gatt_header(ublox_spp_le_counter PRIVATE + ${PICO_BTSTACK_PATH}/example/ublox_spp_le_counter.gatt +) +pico_add_extra_outputs(ublox_spp_le_counter) +example_auto_set_url(ublox_spp_le_counter) diff --git a/bluetooth/btstack_examples/ublox_spp_le_counter/btstack_config.h b/bluetooth/btstack_examples/ublox_spp_le_counter/btstack_config.h new file mode 100644 index 000000000..6eafef0a0 --- /dev/null +++ b/bluetooth/btstack_examples/ublox_spp_le_counter/btstack_config.h @@ -0,0 +1 @@ +#include "../../config/btstack_config_common.h" diff --git a/bluetooth/config/btstack_config_common.h b/bluetooth/config/btstack_config_common.h new file mode 100644 index 000000000..1b969e1bf --- /dev/null +++ b/bluetooth/config/btstack_config_common.h @@ -0,0 +1,89 @@ +#ifndef _PICO_BTSTACK_BTSTACK_CONFIG_H +#define _PICO_BTSTACK_BTSTACK_CONFIG_H + +// BTstack features that can be enabled +#define ENABLE_LOG_INFO +#define ENABLE_LOG_ERROR +#define ENABLE_PRINTF_HEXDUMP +#define ENABLE_SCO_OVER_HCI + +#ifdef ENABLE_BLE +#define ENABLE_GATT_CLIENT_PAIRING +#define ENABLE_L2CAP_LE_CREDIT_BASED_FLOW_CONTROL_MODE +#define ENABLE_LE_CENTRAL +#define ENABLE_LE_DATA_LENGTH_EXTENSION +#define ENABLE_LE_PERIPHERAL +#define ENABLE_LE_PRIVACY_ADDRESS_RESOLUTION +#define ENABLE_LE_SECURE_CONNECTIONS +#endif + +#ifdef ENABLE_CLASSIC +#define ENABLE_L2CAP_ENHANCED_RETRANSMISSION_MODE +#define ENABLE_GOEP_L2CAP +#endif + +#if defined (ENABLE_CLASSIC) && defined(ENABLE_BLE) +#define ENABLE_CROSS_TRANSPORT_KEY_DERIVATION +#endif + +// BTstack configuration. buffers, sizes, ... +#define HCI_OUTGOING_PRE_BUFFER_SIZE 4 +#define HCI_ACL_PAYLOAD_SIZE (1691 + 4) +#define HCI_ACL_CHUNK_SIZE_ALIGNMENT 4 +#define MAX_NR_AVDTP_CONNECTIONS 1 +#define MAX_NR_AVDTP_STREAM_ENDPOINTS 1 +#define MAX_NR_AVRCP_CONNECTIONS 2 +#define MAX_NR_BNEP_CHANNELS 1 +#define MAX_NR_BNEP_SERVICES 1 +#define MAX_NR_BTSTACK_LINK_KEY_DB_MEMORY_ENTRIES 2 +#define MAX_NR_GATT_CLIENTS 1 +#define MAX_NR_HCI_CONNECTIONS 2 +#define MAX_NR_HID_HOST_CONNECTIONS 1 +#define MAX_NR_HIDS_CLIENTS 1 +#define MAX_NR_HFP_CONNECTIONS 1 +#define MAX_NR_L2CAP_CHANNELS 4 +#define MAX_NR_L2CAP_SERVICES 3 +#define MAX_NR_RFCOMM_CHANNELS 1 +#define MAX_NR_RFCOMM_MULTIPLEXERS 1 +#define MAX_NR_RFCOMM_SERVICES 1 +#define MAX_NR_SERVICE_RECORD_ITEMS 4 +#define MAX_NR_SM_LOOKUP_ENTRIES 3 +#define MAX_NR_WHITELIST_ENTRIES 16 +#define MAX_NR_LE_DEVICE_DB_ENTRIES 16 + +// Limit number of ACL/SCO Buffer to use by stack to avoid cyw43 shared bus overrun +#define MAX_NR_CONTROLLER_ACL_BUFFERS 3 +#define MAX_NR_CONTROLLER_SCO_PACKETS 3 + +// Enable and configure HCI Controller to Host Flow Control to avoid cyw43 shared bus overrun +#define ENABLE_HCI_CONTROLLER_TO_HOST_FLOW_CONTROL +#define HCI_HOST_ACL_PACKET_LEN 1024 +#define HCI_HOST_ACL_PACKET_NUM 3 +#define HCI_HOST_SCO_PACKET_LEN 120 +#define HCI_HOST_SCO_PACKET_NUM 3 + +// Link Key DB and LE Device DB using TLV on top of Flash Sector interface +#define NVM_NUM_DEVICE_DB_ENTRIES 16 +#define NVM_NUM_LINK_KEYS 16 + +// We don't give btstack a malloc, so use a fixed-size ATT DB. +#define MAX_ATT_DB_SIZE 512 + +// BTstack HAL configuration +#define HAVE_EMBEDDED_TIME_MS + +// map btstack_assert onto Pico SDK assert() +#define HAVE_ASSERT + +// Some USB dongles take longer to respond to HCI reset (e.g. BCM20702A). +#define HCI_RESET_RESEND_TIMEOUT_MS 1000 + +#define ENABLE_SOFTWARE_AES128 +#define ENABLE_MICRO_ECC_FOR_LE_SECURE_CONNECTIONS + +#define HAVE_BTSTACK_STDIN + +// To get the audio demos working even with HCI dump at 115200, this truncates long ACL packets +//#define HCI_DUMP_STDOUT_MAX_SIZE_ACL 100 + +#endif // _PICO_BTSTACK_BTSTACK_CONFIG_H From 132ae9bf9782b0c09d55a13f4ec183437f8452ef Mon Sep 17 00:00:00 2001 From: Louis31423142 Date: Thu, 10 Jul 2025 11:38:48 +0100 Subject: [PATCH 02/13] Add new Bluetooth examples. --- README.md | 8 +- .../a2dp_sink_demo/CMakeLists.txt | 1 + .../a2dp_source_demo/CMakeLists.txt | 3 + .../ancs_client_demo/CMakeLists.txt | 3 + .../att_delayed_response/CMakeLists.txt | 3 + .../avrcp_browsing_client/CMakeLists.txt | 3 + .../dut_mode_classic/CMakeLists.txt | 3 + .../gap_dedicated_bonding/CMakeLists.txt | 3 + .../gap_inquiry/CMakeLists.txt | 3 + .../gap_le_advertisements/CMakeLists.txt | 3 + .../gap_link_keys/CMakeLists.txt | 3 + .../gatt_battery_query/CMakeLists.txt | 3 + .../gatt_browser/CMakeLists.txt | 3 + .../gatt_counter/CMakeLists.txt | 3 + .../gatt_counter_with_wifi/CMakeLists.txt | 1 + .../CMakeLists.txt | 3 + .../gatt_heart_rate_client/CMakeLists.txt | 3 + .../gatt_streamer_server/CMakeLists.txt | 3 + .../CMakeLists.txt | 1 + .../hfp_ag_demo/CMakeLists.txt | 1 + .../hfp_hf_demo/CMakeLists.txt | 1 + .../hid_host_demo/CMakeLists.txt | 3 + .../hid_keyboard_demo/CMakeLists.txt | 3 + .../hid_mouse_demo/CMakeLists.txt | 3 + .../hog_boot_host_demo/CMakeLists.txt | 3 + .../hog_host_demo/CMakeLists.txt | 3 + .../hog_keyboard_demo/CMakeLists.txt | 3 + .../hog_mouse_demo/CMakeLists.txt | 3 + .../hsp_ag_demo/CMakeLists.txt | 1 + .../hsp_hs_demo/CMakeLists.txt | 1 + .../CMakeLists.txt | 3 + .../CMakeLists.txt | 3 + .../btstack_examples/le_mitm/CMakeLists.txt | 3 + .../le_streamer_client/CMakeLists.txt | 3 + .../led_counter/CMakeLists.txt | 3 + .../mod_player/CMakeLists.txt | 1 + .../nordic_spp_le_counter/CMakeLists.txt | 3 + .../nordic_spp_le_streamer/CMakeLists.txt | 3 + .../pan_lwip_http_server/CMakeLists.txt | 1 + .../pbap_client_demo/CMakeLists.txt | 3 + .../sdp_bnep_query/CMakeLists.txt | 3 + .../sdp_general_query/CMakeLists.txt | 3 + .../sdp_rfcomm_query/CMakeLists.txt | 3 + .../sine_player/CMakeLists.txt | 1 + .../sm_pairing_central/CMakeLists.txt | 3 + .../sm_pairing_peripheral/CMakeLists.txt | 3 + .../spp_and_gatt_counter/CMakeLists.txt | 3 + .../spp_and_gatt_streamer/CMakeLists.txt | 3 + .../spp_counter/CMakeLists.txt | 3 + .../spp_flowcontrol/CMakeLists.txt | 3 + .../spp_streamer/CMakeLists.txt | 3 + .../spp_streamer_client/CMakeLists.txt | 3 + .../spp_streamer_with_wifi/CMakeLists.txt | 1 + .../ublox_spp_le_counter/CMakeLists.txt | 3 + pico_w/bt/standalone/CMakeLists.txt | 8 +- .../bt/standalone/ble_pointer/CMakeLists.txt | 37 ++ pico_w/bt/standalone/ble_pointer/README.md | 7 + .../bt/standalone/ble_pointer/ble_pointer.c | 451 +++++++++++++++++ .../bt/standalone/ble_pointer/ble_pointer.fzz | Bin 0 -> 143681 bytes .../standalone/ble_pointer/ble_pointer.gatt | 48 ++ .../standalone/ble_pointer/ble_pointer_bb.png | Bin 0 -> 245357 bytes .../{client => ble_pointer}/btstack_config.h | 0 .../standalone/ble_pointer/mpu6050_i2c_lib.c | 164 +++++++ .../standalone/ble_pointer/mpu6050_i2c_lib.h | 12 + pico_w/bt/standalone/doorbell/CMakeLists.txt | 42 ++ pico_w/bt/standalone/doorbell/README.md | 5 + .../{server => doorbell}/btstack_config.h | 0 pico_w/bt/standalone/doorbell/client.c | 303 ++++++++++++ pico_w/bt/standalone/doorbell/doorbell.fzz | Bin 0 -> 143627 bytes pico_w/bt/standalone/doorbell/doorbell.gatt | 11 + pico_w/bt/standalone/doorbell/doorbell_bb.png | Bin 0 -> 266510 bytes pico_w/bt/standalone/doorbell/server.c | 178 +++++++ .../secure_temp_sensor/CMakeLists.txt | 42 ++ .../standalone/secure_temp_sensor/README.md | 10 + .../secure_temp_sensor/btstack_config.h | 9 + .../bt/standalone/secure_temp_sensor/client.c | 464 ++++++++++++++++++ .../bt/standalone/secure_temp_sensor/server.c | 372 ++++++++++++++ .../secure_temp_sensor/temp_sensor.gatt | 8 + .../bt/standalone/temp_sensor/CMakeLists.txt | 2 + pico_w/bt/standalone/temp_sensor/README.md | 3 + .../{ => temp_sensor}/client/CMakeLists.txt | 2 +- .../temp_sensor/client/btstack_config.h | 6 + .../{ => temp_sensor}/client/client.c | 0 .../{ => temp_sensor}/server/CMakeLists.txt | 2 +- .../temp_sensor/server/btstack_config.h | 6 + .../{ => temp_sensor}/server/server.c | 0 .../{ => temp_sensor}/server/temp_sensor.gatt | 0 .../wifi_provisioner/CMakeLists.txt | 32 ++ .../bt/standalone/wifi_provisioner/README.md | 3 + .../wifi_provisioner/btstack_config.h | 6 + .../bt/standalone/wifi_provisioner/example.c | 10 + .../{ => wifi_provisioner}/lwipopts.h | 2 +- .../wifi_provisioner/provisioning.gatt | 16 + .../wifi_provisioner/set_credentials.py | 40 ++ .../wifi_provisioner/wifi_prov_lib.c | 455 +++++++++++++++++ .../wifi_provisioner/wifi_prov_lib.h | 18 + pico_w/wifi/CMakeLists.txt | 1 + .../AP_provisioning.c | 355 ++++++++++++++ .../CMakeLists.txt | 25 + .../access_point_wifi_provisioning/README.md | 4 + .../content/index.shtml | 57 +++ .../dhcpserver/LICENSE | 21 + .../dhcpserver/dhcpserver.c | 309 ++++++++++++ .../dhcpserver/dhcpserver.h | 49 ++ .../dnsserver/dnsserver.c | 235 +++++++++ .../dnsserver/dnsserver.h | 20 + .../access_point_wifi_provisioning/lwipopts.h | 101 ++++ 107 files changed, 4089 insertions(+), 7 deletions(-) create mode 100644 pico_w/bt/standalone/ble_pointer/CMakeLists.txt create mode 100644 pico_w/bt/standalone/ble_pointer/README.md create mode 100644 pico_w/bt/standalone/ble_pointer/ble_pointer.c create mode 100644 pico_w/bt/standalone/ble_pointer/ble_pointer.fzz create mode 100644 pico_w/bt/standalone/ble_pointer/ble_pointer.gatt create mode 100644 pico_w/bt/standalone/ble_pointer/ble_pointer_bb.png rename pico_w/bt/standalone/{client => ble_pointer}/btstack_config.h (100%) create mode 100644 pico_w/bt/standalone/ble_pointer/mpu6050_i2c_lib.c create mode 100644 pico_w/bt/standalone/ble_pointer/mpu6050_i2c_lib.h create mode 100644 pico_w/bt/standalone/doorbell/CMakeLists.txt create mode 100644 pico_w/bt/standalone/doorbell/README.md rename pico_w/bt/standalone/{server => doorbell}/btstack_config.h (100%) create mode 100644 pico_w/bt/standalone/doorbell/client.c create mode 100644 pico_w/bt/standalone/doorbell/doorbell.fzz create mode 100644 pico_w/bt/standalone/doorbell/doorbell.gatt create mode 100644 pico_w/bt/standalone/doorbell/doorbell_bb.png create mode 100644 pico_w/bt/standalone/doorbell/server.c create mode 100644 pico_w/bt/standalone/secure_temp_sensor/CMakeLists.txt create mode 100644 pico_w/bt/standalone/secure_temp_sensor/README.md create mode 100644 pico_w/bt/standalone/secure_temp_sensor/btstack_config.h create mode 100644 pico_w/bt/standalone/secure_temp_sensor/client.c create mode 100644 pico_w/bt/standalone/secure_temp_sensor/server.c create mode 100644 pico_w/bt/standalone/secure_temp_sensor/temp_sensor.gatt create mode 100644 pico_w/bt/standalone/temp_sensor/CMakeLists.txt create mode 100644 pico_w/bt/standalone/temp_sensor/README.md rename pico_w/bt/standalone/{ => temp_sensor}/client/CMakeLists.txt (91%) create mode 100644 pico_w/bt/standalone/temp_sensor/client/btstack_config.h rename pico_w/bt/standalone/{ => temp_sensor}/client/client.c (100%) rename pico_w/bt/standalone/{ => temp_sensor}/server/CMakeLists.txt (90%) create mode 100644 pico_w/bt/standalone/temp_sensor/server/btstack_config.h rename pico_w/bt/standalone/{ => temp_sensor}/server/server.c (100%) rename pico_w/bt/standalone/{ => temp_sensor}/server/temp_sensor.gatt (100%) create mode 100644 pico_w/bt/standalone/wifi_provisioner/CMakeLists.txt create mode 100644 pico_w/bt/standalone/wifi_provisioner/README.md create mode 100644 pico_w/bt/standalone/wifi_provisioner/btstack_config.h create mode 100644 pico_w/bt/standalone/wifi_provisioner/example.c rename pico_w/bt/standalone/{ => wifi_provisioner}/lwipopts.h (99%) create mode 100644 pico_w/bt/standalone/wifi_provisioner/provisioning.gatt create mode 100644 pico_w/bt/standalone/wifi_provisioner/set_credentials.py create mode 100644 pico_w/bt/standalone/wifi_provisioner/wifi_prov_lib.c create mode 100644 pico_w/bt/standalone/wifi_provisioner/wifi_prov_lib.h create mode 100644 pico_w/wifi/access_point_wifi_provisioning/AP_provisioning.c create mode 100644 pico_w/wifi/access_point_wifi_provisioning/CMakeLists.txt create mode 100644 pico_w/wifi/access_point_wifi_provisioning/README.md create mode 100644 pico_w/wifi/access_point_wifi_provisioning/content/index.shtml create mode 100644 pico_w/wifi/access_point_wifi_provisioning/dhcpserver/LICENSE create mode 100644 pico_w/wifi/access_point_wifi_provisioning/dhcpserver/dhcpserver.c create mode 100644 pico_w/wifi/access_point_wifi_provisioning/dhcpserver/dhcpserver.h create mode 100644 pico_w/wifi/access_point_wifi_provisioning/dnsserver/dnsserver.c create mode 100644 pico_w/wifi/access_point_wifi_provisioning/dnsserver/dnsserver.h create mode 100644 pico_w/wifi/access_point_wifi_provisioning/lwipopts.h diff --git a/README.md b/README.md index f43a7339a..6d945a599 100644 --- a/README.md +++ b/README.md @@ -195,6 +195,7 @@ These networking examples are only available if Wi-Fi is supported by the board. App|Description ---|--- [picow_access_point](pico_w/wifi/access_point) | Starts a WiFi access point, and fields DHCP requests. +[picow_access_point_wifi_provisioning](pico_w/wifi/access_point_wifi_provisioning) | Starts a WiFi access point, and allows WiFi credentials to be provisioned through a web page. [picow_blink](pico_w/wifi/blink) | Blinks the on-board LED (which is connected via the WiFi chip). [picow_blink_slow_clock](pico_w/wifi/blink) | Blinks the on-board LED (which is connected via the WiFi chip) with a slower system clock to show how to reconfigure communication with the WiFi chip at run time under those circumstances. [picow_blink_fast_clock](pico_w/wifi/blink) | Blinks the on-board LED (which is connected via the WiFi chip) with a faster system clock to show how to reconfigure communication with the WiFi chip at build time under those circumstances. @@ -296,8 +297,11 @@ Some standalone Bluetooth examples (without all the common example build infrast App|Description ---|--- [picow_ble_temp_sensor](pico_w/bt/standalone) | Reads from the on board temperature sensor and sends notifications via BLE. -[picow_ble_temp_sensor_with_wifi](pico_w/bt/standalone) | Same as above but also connects to Wi-Fi and starts an "iperf" server. -[picow_ble_temp_reader](pico_w/bt/standalone) | Connects to one of the above "sensors" and reads the temperature. +[picow_ble_temp_reader](pico_w/bt/standalone) | Connects to the above sensor and reads the temperature. +[picow_ble_pointer](pico_w/bt/standalone/ble_pointer) | Bluetooth HID mouse using mpu6050 to detect angle and move cursor. +[picow_ble_doorbell](pico_w/bt/standalone/doorbell) | Detects button press on transmitter Pico and illuminates LED on reciever Pico. +[picow_ble_secure_temp_sensor](pico_w/bt/standalone/secure_temp_sensor) | Variant of picow_ble_temp_sensor which allows exploration of LE_secure configurations. +[picow_ble_wifi_provisioner](pico_w/bt/standalone/wifi_provisioner) | Allows WiFi credentials to be provisioned over BLE, either using a mobile app or with the included python script. ### PIO diff --git a/bluetooth/btstack_examples/a2dp_sink_demo/CMakeLists.txt b/bluetooth/btstack_examples/a2dp_sink_demo/CMakeLists.txt index dd73fab63..10d98b4e0 100644 --- a/bluetooth/btstack_examples/a2dp_sink_demo/CMakeLists.txt +++ b/bluetooth/btstack_examples/a2dp_sink_demo/CMakeLists.txt @@ -20,6 +20,7 @@ target_compile_definitions(a2dp_sink_demo PRIVATE USING_I2C=1 PICO_AUDIO_I2S_DATA_PIN=9 PICO_AUDIO_I2S_CLOCK_PIN_BASE=10 + #WANT_HCI_DUMP=1 ) pico_add_extra_outputs(a2dp_sink_demo) example_auto_set_url(a2dp_sink_demo) diff --git a/bluetooth/btstack_examples/a2dp_source_demo/CMakeLists.txt b/bluetooth/btstack_examples/a2dp_source_demo/CMakeLists.txt index 23c193ba4..b3f3382b3 100644 --- a/bluetooth/btstack_examples/a2dp_source_demo/CMakeLists.txt +++ b/bluetooth/btstack_examples/a2dp_source_demo/CMakeLists.txt @@ -16,5 +16,8 @@ target_link_libraries(a2dp_source_demo PRIVATE target_include_directories(a2dp_source_demo PRIVATE . # for btstack config ) +target_compile_definitions(a2dp_source_demo PRIVATE + #WANT_HCI_DUMP=1 +) pico_add_extra_outputs(a2dp_source_demo) example_auto_set_url(a2dp_source_demo) diff --git a/bluetooth/btstack_examples/ancs_client_demo/CMakeLists.txt b/bluetooth/btstack_examples/ancs_client_demo/CMakeLists.txt index f3caa0ed8..48f9ba1c1 100644 --- a/bluetooth/btstack_examples/ancs_client_demo/CMakeLists.txt +++ b/bluetooth/btstack_examples/ancs_client_demo/CMakeLists.txt @@ -16,5 +16,8 @@ target_include_directories(ancs_client_demo PRIVATE pico_btstack_make_gatt_header(ancs_client_demo PRIVATE ${PICO_BTSTACK_PATH}/example/ancs_client_demo.gatt ) +target_compile_definitions(ancs_client_demo PRIVATE + #WANT_HCI_DUMP=1 +) pico_add_extra_outputs(ancs_client_demo) example_auto_set_url(ancs_client_demo) diff --git a/bluetooth/btstack_examples/att_delayed_response/CMakeLists.txt b/bluetooth/btstack_examples/att_delayed_response/CMakeLists.txt index 8930fa33d..6b784da2d 100644 --- a/bluetooth/btstack_examples/att_delayed_response/CMakeLists.txt +++ b/bluetooth/btstack_examples/att_delayed_response/CMakeLists.txt @@ -17,5 +17,8 @@ target_include_directories(att_delayed_response PRIVATE pico_btstack_make_gatt_header(att_delayed_response PRIVATE ${PICO_BTSTACK_PATH}/example/att_delayed_response.gatt ) +target_compile_definitions(att_delayed_response PRIVATE + #WANT_HCI_DUMP=1 +) pico_add_extra_outputs(att_delayed_response) example_auto_set_url(att_delayed_response) diff --git a/bluetooth/btstack_examples/avrcp_browsing_client/CMakeLists.txt b/bluetooth/btstack_examples/avrcp_browsing_client/CMakeLists.txt index 641896fe2..528cdf771 100644 --- a/bluetooth/btstack_examples/avrcp_browsing_client/CMakeLists.txt +++ b/bluetooth/btstack_examples/avrcp_browsing_client/CMakeLists.txt @@ -13,5 +13,8 @@ target_link_libraries(avrcp_browsing_client PRIVATE target_include_directories(avrcp_browsing_client PRIVATE . # for btstack config ) +target_compile_definitions(avrcp_browsing_client PRIVATE + #WANT_HCI_DUMP=1 +) pico_add_extra_outputs(avrcp_browsing_client) example_auto_set_url(avrcp_browsing_client) diff --git a/bluetooth/btstack_examples/dut_mode_classic/CMakeLists.txt b/bluetooth/btstack_examples/dut_mode_classic/CMakeLists.txt index 628df61ea..76356c7d1 100644 --- a/bluetooth/btstack_examples/dut_mode_classic/CMakeLists.txt +++ b/bluetooth/btstack_examples/dut_mode_classic/CMakeLists.txt @@ -13,5 +13,8 @@ target_link_libraries(dut_mode_classic PRIVATE target_include_directories(dut_mode_classic PRIVATE . # for btstack config ) +target_compile_definitions(dut_mode_classic PRIVATE + #WANT_HCI_DUMP=1 +) pico_add_extra_outputs(dut_mode_classic) example_auto_set_url(dut_mode_classic) diff --git a/bluetooth/btstack_examples/gap_dedicated_bonding/CMakeLists.txt b/bluetooth/btstack_examples/gap_dedicated_bonding/CMakeLists.txt index 7fb797fed..940e4bd5a 100644 --- a/bluetooth/btstack_examples/gap_dedicated_bonding/CMakeLists.txt +++ b/bluetooth/btstack_examples/gap_dedicated_bonding/CMakeLists.txt @@ -12,5 +12,8 @@ target_link_libraries(gap_dedicated_bonding PRIVATE target_include_directories(gap_dedicated_bonding PRIVATE . # for btstack config ) +target_compile_definitions(gap_dedicated_bonding PRIVATE + #WANT_HCI_DUMP=1 +) pico_add_extra_outputs(gap_dedicated_bonding) example_auto_set_url(gap_dedicated_bonding) diff --git a/bluetooth/btstack_examples/gap_inquiry/CMakeLists.txt b/bluetooth/btstack_examples/gap_inquiry/CMakeLists.txt index e03126c0e..bdc0add90 100644 --- a/bluetooth/btstack_examples/gap_inquiry/CMakeLists.txt +++ b/bluetooth/btstack_examples/gap_inquiry/CMakeLists.txt @@ -13,5 +13,8 @@ target_link_libraries(gap_inquiry PRIVATE target_include_directories(gap_inquiry PRIVATE . # for btstack config ) +target_compile_definitions(gap_inquiry PRIVATE + #WANT_HCI_DUMP=1 +) pico_add_extra_outputs(gap_inquiry) example_auto_set_url(gap_inquiry) diff --git a/bluetooth/btstack_examples/gap_le_advertisements/CMakeLists.txt b/bluetooth/btstack_examples/gap_le_advertisements/CMakeLists.txt index df3e1525a..e524afa77 100644 --- a/bluetooth/btstack_examples/gap_le_advertisements/CMakeLists.txt +++ b/bluetooth/btstack_examples/gap_le_advertisements/CMakeLists.txt @@ -12,5 +12,8 @@ target_link_libraries(gap_le_advertisements PRIVATE target_include_directories(gap_le_advertisements PRIVATE . # for btstack config ) +target_compile_definitions(gap_le_advertisements PRIVATE + #WANT_HCI_DUMP=1 +) pico_add_extra_outputs(gap_le_advertisements) example_auto_set_url(gap_le_advertisements) diff --git a/bluetooth/btstack_examples/gap_link_keys/CMakeLists.txt b/bluetooth/btstack_examples/gap_link_keys/CMakeLists.txt index c9d5f9fb3..f7f57322c 100644 --- a/bluetooth/btstack_examples/gap_link_keys/CMakeLists.txt +++ b/bluetooth/btstack_examples/gap_link_keys/CMakeLists.txt @@ -13,5 +13,8 @@ target_link_libraries(gap_link_keys PRIVATE target_include_directories(gap_link_keys PRIVATE . # for btstack config ) +target_compile_definitions(gap_link_keys PRIVATE + #WANT_HCI_DUMP=1 +) pico_add_extra_outputs(gap_link_keys) example_auto_set_url(gap_link_keys) diff --git a/bluetooth/btstack_examples/gatt_battery_query/CMakeLists.txt b/bluetooth/btstack_examples/gatt_battery_query/CMakeLists.txt index f291408ef..3569f01ed 100644 --- a/bluetooth/btstack_examples/gatt_battery_query/CMakeLists.txt +++ b/bluetooth/btstack_examples/gatt_battery_query/CMakeLists.txt @@ -17,5 +17,8 @@ target_include_directories(gatt_battery_query PRIVATE pico_btstack_make_gatt_header(gatt_battery_query PRIVATE ${PICO_BTSTACK_PATH}/example/gatt_battery_query.gatt ) +target_compile_definitions(gatt_battery_query PRIVATE + #WANT_HCI_DUMP=1 +) pico_add_extra_outputs(gatt_battery_query) example_auto_set_url(gatt_battery_query) diff --git a/bluetooth/btstack_examples/gatt_browser/CMakeLists.txt b/bluetooth/btstack_examples/gatt_browser/CMakeLists.txt index 1bed6af4b..f1ed6fd1f 100644 --- a/bluetooth/btstack_examples/gatt_browser/CMakeLists.txt +++ b/bluetooth/btstack_examples/gatt_browser/CMakeLists.txt @@ -17,5 +17,8 @@ target_include_directories(gatt_browser PRIVATE pico_btstack_make_gatt_header(gatt_browser PRIVATE ${PICO_BTSTACK_PATH}/example/gatt_browser.gatt ) +target_compile_definitions(gatt_browser PRIVATE + #WANT_HCI_DUMP=1 +) pico_add_extra_outputs(gatt_browser) example_auto_set_url(gatt_browser) diff --git a/bluetooth/btstack_examples/gatt_counter/CMakeLists.txt b/bluetooth/btstack_examples/gatt_counter/CMakeLists.txt index 3dcda6c2e..d2b150cc6 100644 --- a/bluetooth/btstack_examples/gatt_counter/CMakeLists.txt +++ b/bluetooth/btstack_examples/gatt_counter/CMakeLists.txt @@ -17,5 +17,8 @@ target_include_directories(gatt_counter PRIVATE pico_btstack_make_gatt_header(gatt_counter PRIVATE ${PICO_BTSTACK_PATH}/example/gatt_counter.gatt ) +target_compile_definitions(gatt_counter PRIVATE + #WANT_HCI_DUMP=1 +) pico_add_extra_outputs(gatt_counter) example_auto_set_url(gatt_counter) diff --git a/bluetooth/btstack_examples/gatt_counter_with_wifi/CMakeLists.txt b/bluetooth/btstack_examples/gatt_counter_with_wifi/CMakeLists.txt index 7d7ae643d..177ee16a5 100644 --- a/bluetooth/btstack_examples/gatt_counter_with_wifi/CMakeLists.txt +++ b/bluetooth/btstack_examples/gatt_counter_with_wifi/CMakeLists.txt @@ -17,6 +17,7 @@ target_compile_definitions(gatt_counter_with_wifi PRIVATE WIFI_SSID=\"${WIFI_SSID}\" WIFI_PASSWORD=\"${WIFI_PASSWORD}\" USING_IPERF=1 + #WANT_HCI_DUMP=1 ) # This builds a header file with details of the gatt service described in a gatt file # note: this source for this is in pico-sdk/lib/btstack diff --git a/bluetooth/btstack_examples/gatt_device_information_query/CMakeLists.txt b/bluetooth/btstack_examples/gatt_device_information_query/CMakeLists.txt index d4f3edb89..cbac743d1 100644 --- a/bluetooth/btstack_examples/gatt_device_information_query/CMakeLists.txt +++ b/bluetooth/btstack_examples/gatt_device_information_query/CMakeLists.txt @@ -17,5 +17,8 @@ target_include_directories(gatt_device_information_query PRIVATE pico_btstack_make_gatt_header(gatt_device_information_query PRIVATE ${PICO_BTSTACK_PATH}/example/gatt_device_information_query.gatt ) +target_compile_definitions(gatt_device_information_query PRIVATE + #WANT_HCI_DUMP=1 +) pico_add_extra_outputs(gatt_device_information_query) example_auto_set_url(gatt_device_information_query) diff --git a/bluetooth/btstack_examples/gatt_heart_rate_client/CMakeLists.txt b/bluetooth/btstack_examples/gatt_heart_rate_client/CMakeLists.txt index c7170b9e8..3c21fda32 100644 --- a/bluetooth/btstack_examples/gatt_heart_rate_client/CMakeLists.txt +++ b/bluetooth/btstack_examples/gatt_heart_rate_client/CMakeLists.txt @@ -12,5 +12,8 @@ target_link_libraries(gatt_heart_rate_client PRIVATE target_include_directories(gatt_heart_rate_client PRIVATE . # for btstack config ) +target_compile_definitions(gatt_heart_rate_client PRIVATE + #WANT_HCI_DUMP=1 +) pico_add_extra_outputs(gatt_heart_rate_client) example_auto_set_url(gatt_heart_rate_client) diff --git a/bluetooth/btstack_examples/gatt_streamer_server/CMakeLists.txt b/bluetooth/btstack_examples/gatt_streamer_server/CMakeLists.txt index 63a3b62f3..60f761768 100644 --- a/bluetooth/btstack_examples/gatt_streamer_server/CMakeLists.txt +++ b/bluetooth/btstack_examples/gatt_streamer_server/CMakeLists.txt @@ -17,5 +17,8 @@ target_include_directories(gatt_streamer_server PRIVATE pico_btstack_make_gatt_header(gatt_streamer_server PRIVATE ${PICO_BTSTACK_PATH}/example/gatt_streamer_server.gatt ) +target_compile_definitions(gatt_streamer_server PRIVATE + #WANT_HCI_DUMP=1 +) pico_add_extra_outputs(gatt_streamer_server) example_auto_set_url(gatt_streamer_server) diff --git a/bluetooth/btstack_examples/gatt_streamer_server_with_wifi/CMakeLists.txt b/bluetooth/btstack_examples/gatt_streamer_server_with_wifi/CMakeLists.txt index d7931f90b..04616845b 100644 --- a/bluetooth/btstack_examples/gatt_streamer_server_with_wifi/CMakeLists.txt +++ b/bluetooth/btstack_examples/gatt_streamer_server_with_wifi/CMakeLists.txt @@ -17,6 +17,7 @@ target_compile_definitions(gatt_streamer_server_with_wifi PRIVATE WIFI_SSID=\"${WIFI_SSID}\" WIFI_PASSWORD=\"${WIFI_PASSWORD}\" USING_IPERF=1 + #WANT_HCI_DUMP=1 ) # This builds a header file with details of the gatt service described in a gatt file # note: this source for this is in pico-sdk/lib/btstack diff --git a/bluetooth/btstack_examples/hfp_ag_demo/CMakeLists.txt b/bluetooth/btstack_examples/hfp_ag_demo/CMakeLists.txt index 6b6a83289..04194ca5f 100644 --- a/bluetooth/btstack_examples/hfp_ag_demo/CMakeLists.txt +++ b/bluetooth/btstack_examples/hfp_ag_demo/CMakeLists.txt @@ -22,6 +22,7 @@ target_compile_definitions(hfp_ag_demo PRIVATE USING_I2C=1 PICO_AUDIO_I2S_DATA_PIN=9 PICO_AUDIO_I2S_CLOCK_PIN_BASE=10 + #WANT_HCI_DUMP=1 ) pico_add_extra_outputs(hfp_ag_demo) example_auto_set_url(hfp_ag_demo) diff --git a/bluetooth/btstack_examples/hfp_hf_demo/CMakeLists.txt b/bluetooth/btstack_examples/hfp_hf_demo/CMakeLists.txt index 7db07599d..51e9c0e03 100644 --- a/bluetooth/btstack_examples/hfp_hf_demo/CMakeLists.txt +++ b/bluetooth/btstack_examples/hfp_hf_demo/CMakeLists.txt @@ -21,6 +21,7 @@ target_compile_definitions(hfp_hf_demo PRIVATE USING_I2C=1 PICO_AUDIO_I2S_DATA_PIN=9 PICO_AUDIO_I2S_CLOCK_PIN_BASE=10 + #WANT_HCI_DUMP=1 ) pico_add_extra_outputs(hfp_hf_demo) example_auto_set_url(hfp_hf_demo) diff --git a/bluetooth/btstack_examples/hid_host_demo/CMakeLists.txt b/bluetooth/btstack_examples/hid_host_demo/CMakeLists.txt index e44026984..c86ad562b 100644 --- a/bluetooth/btstack_examples/hid_host_demo/CMakeLists.txt +++ b/bluetooth/btstack_examples/hid_host_demo/CMakeLists.txt @@ -13,5 +13,8 @@ target_link_libraries(hid_host_demo PRIVATE target_include_directories(hid_host_demo PRIVATE . # for btstack config ) +target_compile_definitions(hid_host_demo PRIVATE + #WANT_HCI_DUMP=1 +) pico_add_extra_outputs(hid_host_demo) example_auto_set_url(hid_host_demo) diff --git a/bluetooth/btstack_examples/hid_keyboard_demo/CMakeLists.txt b/bluetooth/btstack_examples/hid_keyboard_demo/CMakeLists.txt index 585210776..6df11ec39 100644 --- a/bluetooth/btstack_examples/hid_keyboard_demo/CMakeLists.txt +++ b/bluetooth/btstack_examples/hid_keyboard_demo/CMakeLists.txt @@ -13,5 +13,8 @@ target_link_libraries(hid_keyboard_demo PRIVATE target_include_directories(hid_keyboard_demo PRIVATE . # for btstack config ) +target_compile_definitions(hid_keyboard_demo PRIVATE + #WANT_HCI_DUMP=1 +) pico_add_extra_outputs(hid_keyboard_demo) example_auto_set_url(hid_keyboard_demo) diff --git a/bluetooth/btstack_examples/hid_mouse_demo/CMakeLists.txt b/bluetooth/btstack_examples/hid_mouse_demo/CMakeLists.txt index c5f09d017..a8da575ba 100644 --- a/bluetooth/btstack_examples/hid_mouse_demo/CMakeLists.txt +++ b/bluetooth/btstack_examples/hid_mouse_demo/CMakeLists.txt @@ -13,5 +13,8 @@ target_link_libraries(hid_mouse_demo PRIVATE target_include_directories(hid_mouse_demo PRIVATE . # for btstack config ) +target_compile_definitions(hid_mouse_demo PRIVATE + #WANT_HCI_DUMP=1 +) pico_add_extra_outputs(hid_mouse_demo) example_auto_set_url(hid_mouse_demo) diff --git a/bluetooth/btstack_examples/hog_boot_host_demo/CMakeLists.txt b/bluetooth/btstack_examples/hog_boot_host_demo/CMakeLists.txt index d04d39063..7acdf9218 100644 --- a/bluetooth/btstack_examples/hog_boot_host_demo/CMakeLists.txt +++ b/bluetooth/btstack_examples/hog_boot_host_demo/CMakeLists.txt @@ -12,5 +12,8 @@ target_link_libraries(hog_boot_host_demo PRIVATE target_include_directories(hog_boot_host_demo PRIVATE . # for btstack config ) +target_compile_definitions(hog_boot_host_demo PRIVATE + #WANT_HCI_DUMP=1 +) pico_add_extra_outputs(hog_boot_host_demo) example_auto_set_url(hog_boot_host_demo) diff --git a/bluetooth/btstack_examples/hog_host_demo/CMakeLists.txt b/bluetooth/btstack_examples/hog_host_demo/CMakeLists.txt index 379984982..b935fb6f9 100644 --- a/bluetooth/btstack_examples/hog_host_demo/CMakeLists.txt +++ b/bluetooth/btstack_examples/hog_host_demo/CMakeLists.txt @@ -16,5 +16,8 @@ target_include_directories(hog_host_demo PRIVATE pico_btstack_make_gatt_header(hog_host_demo PRIVATE ${PICO_BTSTACK_PATH}/example/hog_host_demo.gatt ) +target_compile_definitions(hog_host_demo PRIVATE + #WANT_HCI_DUMP=1 +) pico_add_extra_outputs(hog_host_demo) example_auto_set_url(hog_host_demo) diff --git a/bluetooth/btstack_examples/hog_keyboard_demo/CMakeLists.txt b/bluetooth/btstack_examples/hog_keyboard_demo/CMakeLists.txt index 3525318de..e00e14beb 100644 --- a/bluetooth/btstack_examples/hog_keyboard_demo/CMakeLists.txt +++ b/bluetooth/btstack_examples/hog_keyboard_demo/CMakeLists.txt @@ -17,5 +17,8 @@ target_include_directories(hog_keyboard_demo PRIVATE pico_btstack_make_gatt_header(hog_keyboard_demo PRIVATE ${PICO_BTSTACK_PATH}/example/hog_keyboard_demo.gatt ) +target_compile_definitions(hog_keyboard_demo PRIVATE + #WANT_HCI_DUMP=1 +) pico_add_extra_outputs(hog_keyboard_demo) example_auto_set_url(hog_keyboard_demo) diff --git a/bluetooth/btstack_examples/hog_mouse_demo/CMakeLists.txt b/bluetooth/btstack_examples/hog_mouse_demo/CMakeLists.txt index 93a6fc9ac..e07aa92ad 100644 --- a/bluetooth/btstack_examples/hog_mouse_demo/CMakeLists.txt +++ b/bluetooth/btstack_examples/hog_mouse_demo/CMakeLists.txt @@ -17,5 +17,8 @@ target_include_directories(hog_mouse_demo PRIVATE pico_btstack_make_gatt_header(hog_mouse_demo PRIVATE ${PICO_BTSTACK_PATH}/example/hog_mouse_demo.gatt ) +target_compile_definitions(hog_mouse_demo PRIVATE + #WANT_HCI_DUMP=1 +) pico_add_extra_outputs(hog_mouse_demo) example_auto_set_url(hog_mouse_demo) diff --git a/bluetooth/btstack_examples/hsp_ag_demo/CMakeLists.txt b/bluetooth/btstack_examples/hsp_ag_demo/CMakeLists.txt index eb3a98382..d02702e0c 100644 --- a/bluetooth/btstack_examples/hsp_ag_demo/CMakeLists.txt +++ b/bluetooth/btstack_examples/hsp_ag_demo/CMakeLists.txt @@ -22,6 +22,7 @@ target_compile_definitions(hsp_ag_demo PRIVATE USING_I2C=1 PICO_AUDIO_I2S_DATA_PIN=9 PICO_AUDIO_I2S_CLOCK_PIN_BASE=10 + #WANT_HCI_DUMP=1 ) pico_add_extra_outputs(hsp_ag_demo) example_auto_set_url(hsp_ag_demo) diff --git a/bluetooth/btstack_examples/hsp_hs_demo/CMakeLists.txt b/bluetooth/btstack_examples/hsp_hs_demo/CMakeLists.txt index 15441b561..0ce15de8f 100644 --- a/bluetooth/btstack_examples/hsp_hs_demo/CMakeLists.txt +++ b/bluetooth/btstack_examples/hsp_hs_demo/CMakeLists.txt @@ -22,6 +22,7 @@ target_compile_definitions(hsp_hs_demo PRIVATE USING_I2C=1 PICO_AUDIO_I2S_DATA_PIN=9 PICO_AUDIO_I2S_CLOCK_PIN_BASE=10 + #WANT_HCI_DUMP=1 ) pico_add_extra_outputs(hsp_hs_demo) example_auto_set_url(hsp_hs_demo) diff --git a/bluetooth/btstack_examples/le_credit_based_flow_control_mode_client/CMakeLists.txt b/bluetooth/btstack_examples/le_credit_based_flow_control_mode_client/CMakeLists.txt index 69db2686e..3067e444c 100644 --- a/bluetooth/btstack_examples/le_credit_based_flow_control_mode_client/CMakeLists.txt +++ b/bluetooth/btstack_examples/le_credit_based_flow_control_mode_client/CMakeLists.txt @@ -12,5 +12,8 @@ target_link_libraries(le_credit_based_flow_control_mode_client PRIVATE target_include_directories(le_credit_based_flow_control_mode_client PRIVATE . # for btstack config ) +target_compile_definitions(le_credit_based_flow_control_mode_client PRIVATE + #WANT_HCI_DUMP=1 +) pico_add_extra_outputs(le_credit_based_flow_control_mode_client) example_auto_set_url(le_credit_based_flow_control_mode_client) diff --git a/bluetooth/btstack_examples/le_credit_based_flow_control_mode_server/CMakeLists.txt b/bluetooth/btstack_examples/le_credit_based_flow_control_mode_server/CMakeLists.txt index da49f97d6..43c5e46c8 100644 --- a/bluetooth/btstack_examples/le_credit_based_flow_control_mode_server/CMakeLists.txt +++ b/bluetooth/btstack_examples/le_credit_based_flow_control_mode_server/CMakeLists.txt @@ -17,5 +17,8 @@ target_include_directories(le_credit_based_flow_control_mode_server PRIVATE pico_btstack_make_gatt_header(le_credit_based_flow_control_mode_server PRIVATE ${PICO_BTSTACK_PATH}/example/le_credit_based_flow_control_mode_server.gatt ) +target_compile_definitions(le_credit_based_flow_control_mode_server PRIVATE + #WANT_HCI_DUMP=1 +) pico_add_extra_outputs(le_credit_based_flow_control_mode_server) example_auto_set_url(le_credit_based_flow_control_mode_server) diff --git a/bluetooth/btstack_examples/le_mitm/CMakeLists.txt b/bluetooth/btstack_examples/le_mitm/CMakeLists.txt index 25363f445..8f31e36ce 100644 --- a/bluetooth/btstack_examples/le_mitm/CMakeLists.txt +++ b/bluetooth/btstack_examples/le_mitm/CMakeLists.txt @@ -12,5 +12,8 @@ target_link_libraries(le_mitm PRIVATE target_include_directories(le_mitm PRIVATE . # for btstack config ) +target_compile_definitions(le_mitm PRIVATE + #WANT_HCI_DUMP=1 +) pico_add_extra_outputs(le_mitm) example_auto_set_url(le_mitm) diff --git a/bluetooth/btstack_examples/le_streamer_client/CMakeLists.txt b/bluetooth/btstack_examples/le_streamer_client/CMakeLists.txt index 0aec25ea1..08758d0bd 100644 --- a/bluetooth/btstack_examples/le_streamer_client/CMakeLists.txt +++ b/bluetooth/btstack_examples/le_streamer_client/CMakeLists.txt @@ -13,5 +13,8 @@ target_link_libraries(le_streamer_client PRIVATE target_include_directories(le_streamer_client PRIVATE . # for btstack config ) +target_compile_definitions(le_streamer_client PRIVATE + #WANT_HCI_DUMP=1 +) pico_add_extra_outputs(le_streamer_client) example_auto_set_url(le_streamer_client) diff --git a/bluetooth/btstack_examples/led_counter/CMakeLists.txt b/bluetooth/btstack_examples/led_counter/CMakeLists.txt index c118fb311..7d575af37 100644 --- a/bluetooth/btstack_examples/led_counter/CMakeLists.txt +++ b/bluetooth/btstack_examples/led_counter/CMakeLists.txt @@ -12,5 +12,8 @@ target_link_libraries(led_counter PRIVATE target_include_directories(led_counter PRIVATE . # for btstack config ) +target_compile_definitions(led_counter PRIVATE + #WANT_HCI_DUMP=1 +) pico_add_extra_outputs(led_counter) example_auto_set_url(led_counter) diff --git a/bluetooth/btstack_examples/mod_player/CMakeLists.txt b/bluetooth/btstack_examples/mod_player/CMakeLists.txt index 2030a3bb2..b0bd0abd4 100644 --- a/bluetooth/btstack_examples/mod_player/CMakeLists.txt +++ b/bluetooth/btstack_examples/mod_player/CMakeLists.txt @@ -19,6 +19,7 @@ target_compile_definitions(mod_player PRIVATE USING_I2C=1 PICO_AUDIO_I2S_DATA_PIN=9 PICO_AUDIO_I2S_CLOCK_PIN_BASE=10 + #WANT_HCI_DUMP=1 ) pico_add_extra_outputs(mod_player) example_auto_set_url(mod_player) diff --git a/bluetooth/btstack_examples/nordic_spp_le_counter/CMakeLists.txt b/bluetooth/btstack_examples/nordic_spp_le_counter/CMakeLists.txt index eb877bcce..4b1b9673f 100644 --- a/bluetooth/btstack_examples/nordic_spp_le_counter/CMakeLists.txt +++ b/bluetooth/btstack_examples/nordic_spp_le_counter/CMakeLists.txt @@ -17,5 +17,8 @@ target_include_directories(nordic_spp_le_counter PRIVATE pico_btstack_make_gatt_header(nordic_spp_le_counter PRIVATE ${PICO_BTSTACK_PATH}/example/nordic_spp_le_counter.gatt ) +target_compile_definitions(nordic_spp_le_counter PRIVATE + #WANT_HCI_DUMP=1 +) pico_add_extra_outputs(nordic_spp_le_counter) example_auto_set_url(nordic_spp_le_counter) diff --git a/bluetooth/btstack_examples/nordic_spp_le_streamer/CMakeLists.txt b/bluetooth/btstack_examples/nordic_spp_le_streamer/CMakeLists.txt index 71b12d0f2..718565c66 100644 --- a/bluetooth/btstack_examples/nordic_spp_le_streamer/CMakeLists.txt +++ b/bluetooth/btstack_examples/nordic_spp_le_streamer/CMakeLists.txt @@ -17,5 +17,8 @@ target_include_directories(nordic_spp_le_streamer PRIVATE pico_btstack_make_gatt_header(nordic_spp_le_streamer PRIVATE ${PICO_BTSTACK_PATH}/example/nordic_spp_le_streamer.gatt ) +target_compile_definitions(nordic_spp_le_streamer PRIVATE + #WANT_HCI_DUMP=1 +) pico_add_extra_outputs(nordic_spp_le_streamer) example_auto_set_url(nordic_spp_le_streamer) diff --git a/bluetooth/btstack_examples/pan_lwip_http_server/CMakeLists.txt b/bluetooth/btstack_examples/pan_lwip_http_server/CMakeLists.txt index 4789aadca..6eb06d339 100644 --- a/bluetooth/btstack_examples/pan_lwip_http_server/CMakeLists.txt +++ b/bluetooth/btstack_examples/pan_lwip_http_server/CMakeLists.txt @@ -20,6 +20,7 @@ target_include_directories(pan_lwip_http_server PRIVATE ) target_compile_definitions(pan_lwip_http_server PRIVATE CYW43_LWIP=0 # Stop cyw43 doing lwip stuff + #WANT_HCI_DUMP=1 ) pico_add_extra_outputs(pan_lwip_http_server) example_auto_set_url(pan_lwip_http_server) diff --git a/bluetooth/btstack_examples/pbap_client_demo/CMakeLists.txt b/bluetooth/btstack_examples/pbap_client_demo/CMakeLists.txt index d46c33ad4..8e73c97cd 100644 --- a/bluetooth/btstack_examples/pbap_client_demo/CMakeLists.txt +++ b/bluetooth/btstack_examples/pbap_client_demo/CMakeLists.txt @@ -13,5 +13,8 @@ target_link_libraries(pbap_client_demo PRIVATE target_include_directories(pbap_client_demo PRIVATE . # for btstack config ) +target_compile_definitions(pbap_client_demo PRIVATE + #WANT_HCI_DUMP=1 +) pico_add_extra_outputs(pbap_client_demo) example_auto_set_url(pbap_client_demo) diff --git a/bluetooth/btstack_examples/sdp_bnep_query/CMakeLists.txt b/bluetooth/btstack_examples/sdp_bnep_query/CMakeLists.txt index 8148cc649..b3c6a8ef9 100644 --- a/bluetooth/btstack_examples/sdp_bnep_query/CMakeLists.txt +++ b/bluetooth/btstack_examples/sdp_bnep_query/CMakeLists.txt @@ -13,5 +13,8 @@ target_link_libraries(sdp_bnep_query PRIVATE target_include_directories(sdp_bnep_query PRIVATE . # for btstack config ) +target_compile_definitions(sdp_bnep_query PRIVATE + #WANT_HCI_DUMP=1 +) pico_add_extra_outputs(sdp_bnep_query) example_auto_set_url(sdp_bnep_query) diff --git a/bluetooth/btstack_examples/sdp_general_query/CMakeLists.txt b/bluetooth/btstack_examples/sdp_general_query/CMakeLists.txt index 67207ac96..2263f0067 100644 --- a/bluetooth/btstack_examples/sdp_general_query/CMakeLists.txt +++ b/bluetooth/btstack_examples/sdp_general_query/CMakeLists.txt @@ -13,5 +13,8 @@ target_link_libraries(sdp_general_query PRIVATE target_include_directories(sdp_general_query PRIVATE . # for btstack config ) +target_compile_definitions(sdp_general_query PRIVATE + #WANT_HCI_DUMP=1 +) pico_add_extra_outputs(sdp_general_query) example_auto_set_url(sdp_general_query) diff --git a/bluetooth/btstack_examples/sdp_rfcomm_query/CMakeLists.txt b/bluetooth/btstack_examples/sdp_rfcomm_query/CMakeLists.txt index ff0c6e99a..2a40f138e 100644 --- a/bluetooth/btstack_examples/sdp_rfcomm_query/CMakeLists.txt +++ b/bluetooth/btstack_examples/sdp_rfcomm_query/CMakeLists.txt @@ -13,5 +13,8 @@ target_link_libraries(sdp_rfcomm_query PRIVATE target_include_directories(sdp_rfcomm_query PRIVATE . # for btstack config ) +target_compile_definitions(sdp_rfcomm_query PRIVATE + #WANT_HCI_DUMP=1 +) pico_add_extra_outputs(sdp_rfcomm_query) example_auto_set_url(sdp_rfcomm_query) diff --git a/bluetooth/btstack_examples/sine_player/CMakeLists.txt b/bluetooth/btstack_examples/sine_player/CMakeLists.txt index c970533ab..79828de8a 100644 --- a/bluetooth/btstack_examples/sine_player/CMakeLists.txt +++ b/bluetooth/btstack_examples/sine_player/CMakeLists.txt @@ -18,6 +18,7 @@ target_compile_definitions(sine_player PRIVATE USING_I2C=1 PICO_AUDIO_I2S_DATA_PIN=9 PICO_AUDIO_I2S_CLOCK_PIN_BASE=10 + #WANT_HCI_DUMP=1 ) pico_add_extra_outputs(sine_player) example_auto_set_url(sine_player) diff --git a/bluetooth/btstack_examples/sm_pairing_central/CMakeLists.txt b/bluetooth/btstack_examples/sm_pairing_central/CMakeLists.txt index dffcba9ce..1067f9341 100644 --- a/bluetooth/btstack_examples/sm_pairing_central/CMakeLists.txt +++ b/bluetooth/btstack_examples/sm_pairing_central/CMakeLists.txt @@ -17,5 +17,8 @@ target_include_directories(sm_pairing_central PRIVATE pico_btstack_make_gatt_header(sm_pairing_central PRIVATE ${PICO_BTSTACK_PATH}/example/sm_pairing_central.gatt ) +target_compile_definitions(sm_pairing_central PRIVATE + #WANT_HCI_DUMP=1 +) pico_add_extra_outputs(sm_pairing_central) example_auto_set_url(sm_pairing_central) diff --git a/bluetooth/btstack_examples/sm_pairing_peripheral/CMakeLists.txt b/bluetooth/btstack_examples/sm_pairing_peripheral/CMakeLists.txt index f956d744c..0313406e1 100644 --- a/bluetooth/btstack_examples/sm_pairing_peripheral/CMakeLists.txt +++ b/bluetooth/btstack_examples/sm_pairing_peripheral/CMakeLists.txt @@ -17,5 +17,8 @@ target_include_directories(sm_pairing_peripheral PRIVATE pico_btstack_make_gatt_header(sm_pairing_peripheral PRIVATE ${PICO_BTSTACK_PATH}/example/sm_pairing_peripheral.gatt ) +target_compile_definitions(sm_pairing_peripheral PRIVATE + #WANT_HCI_DUMP=1 +) pico_add_extra_outputs(sm_pairing_peripheral) example_auto_set_url(sm_pairing_peripheral) diff --git a/bluetooth/btstack_examples/spp_and_gatt_counter/CMakeLists.txt b/bluetooth/btstack_examples/spp_and_gatt_counter/CMakeLists.txt index be6a73059..e2c896d10 100644 --- a/bluetooth/btstack_examples/spp_and_gatt_counter/CMakeLists.txt +++ b/bluetooth/btstack_examples/spp_and_gatt_counter/CMakeLists.txt @@ -18,5 +18,8 @@ target_include_directories(spp_and_gatt_counter PRIVATE pico_btstack_make_gatt_header(spp_and_gatt_counter PRIVATE ${PICO_BTSTACK_PATH}/example/spp_and_gatt_counter.gatt ) +target_compile_definitions(spp_and_gatt_counter PRIVATE + #WANT_HCI_DUMP=1 +) pico_add_extra_outputs(spp_and_gatt_counter) example_auto_set_url(spp_and_gatt_counter) diff --git a/bluetooth/btstack_examples/spp_and_gatt_streamer/CMakeLists.txt b/bluetooth/btstack_examples/spp_and_gatt_streamer/CMakeLists.txt index b036c2798..9722e7939 100644 --- a/bluetooth/btstack_examples/spp_and_gatt_streamer/CMakeLists.txt +++ b/bluetooth/btstack_examples/spp_and_gatt_streamer/CMakeLists.txt @@ -17,5 +17,8 @@ target_include_directories(spp_and_gatt_streamer PRIVATE pico_btstack_make_gatt_header(spp_and_gatt_streamer PRIVATE ${PICO_BTSTACK_PATH}/example/spp_and_gatt_streamer.gatt ) +target_compile_definitions(spp_and_gatt_streamer PRIVATE + #WANT_HCI_DUMP=1 +) pico_add_extra_outputs(spp_and_gatt_streamer) example_auto_set_url(spp_and_gatt_streamer) diff --git a/bluetooth/btstack_examples/spp_counter/CMakeLists.txt b/bluetooth/btstack_examples/spp_counter/CMakeLists.txt index 51559f428..31e5f2924 100644 --- a/bluetooth/btstack_examples/spp_counter/CMakeLists.txt +++ b/bluetooth/btstack_examples/spp_counter/CMakeLists.txt @@ -13,5 +13,8 @@ target_link_libraries(spp_counter PRIVATE target_include_directories(spp_counter PRIVATE . # for btstack config ) +target_compile_definitions(spp_counter PRIVATE + #WANT_HCI_DUMP=1 +) pico_add_extra_outputs(spp_counter) example_auto_set_url(spp_counter) diff --git a/bluetooth/btstack_examples/spp_flowcontrol/CMakeLists.txt b/bluetooth/btstack_examples/spp_flowcontrol/CMakeLists.txt index 464662add..654d95d9b 100644 --- a/bluetooth/btstack_examples/spp_flowcontrol/CMakeLists.txt +++ b/bluetooth/btstack_examples/spp_flowcontrol/CMakeLists.txt @@ -13,5 +13,8 @@ target_link_libraries(spp_flowcontrol PRIVATE target_include_directories(spp_flowcontrol PRIVATE . # for btstack config ) +target_compile_definitions(spp_flowcontrol PRIVATE + #WANT_HCI_DUMP=1 +) pico_add_extra_outputs(spp_flowcontrol) example_auto_set_url(spp_flowcontrol) diff --git a/bluetooth/btstack_examples/spp_streamer/CMakeLists.txt b/bluetooth/btstack_examples/spp_streamer/CMakeLists.txt index 91ec757ae..424a281b3 100644 --- a/bluetooth/btstack_examples/spp_streamer/CMakeLists.txt +++ b/bluetooth/btstack_examples/spp_streamer/CMakeLists.txt @@ -13,5 +13,8 @@ target_link_libraries(spp_streamer PRIVATE target_include_directories(spp_streamer PRIVATE . # for btstack config ) +target_compile_definitions(spp_streamer PRIVATE + #WANT_HCI_DUMP=1 +) pico_add_extra_outputs(spp_streamer) example_auto_set_url(spp_streamer) diff --git a/bluetooth/btstack_examples/spp_streamer_client/CMakeLists.txt b/bluetooth/btstack_examples/spp_streamer_client/CMakeLists.txt index d0e12f2a2..9b8153329 100644 --- a/bluetooth/btstack_examples/spp_streamer_client/CMakeLists.txt +++ b/bluetooth/btstack_examples/spp_streamer_client/CMakeLists.txt @@ -13,5 +13,8 @@ target_link_libraries(spp_streamer_client PRIVATE target_include_directories(spp_streamer_client PRIVATE . # for btstack config ) +target_compile_definitions(spp_streamer_client PRIVATE + #WANT_HCI_DUMP=1 +) pico_add_extra_outputs(spp_streamer_client) example_auto_set_url(spp_streamer_client) diff --git a/bluetooth/btstack_examples/spp_streamer_with_wifi/CMakeLists.txt b/bluetooth/btstack_examples/spp_streamer_with_wifi/CMakeLists.txt index 0f0ddef5a..73a48d9c3 100644 --- a/bluetooth/btstack_examples/spp_streamer_with_wifi/CMakeLists.txt +++ b/bluetooth/btstack_examples/spp_streamer_with_wifi/CMakeLists.txt @@ -18,6 +18,7 @@ target_compile_definitions(spp_streamer_with_wifi PRIVATE WIFI_SSID=\"${WIFI_SSID}\" WIFI_PASSWORD=\"${WIFI_PASSWORD}\" USING_IPERF=1 + #WANT_HCI_DUMP=1 ) pico_add_extra_outputs(spp_streamer_with_wifi) example_auto_set_url(spp_streamer_with_wifi) diff --git a/bluetooth/btstack_examples/ublox_spp_le_counter/CMakeLists.txt b/bluetooth/btstack_examples/ublox_spp_le_counter/CMakeLists.txt index 70e4b516d..5b3cb85ed 100644 --- a/bluetooth/btstack_examples/ublox_spp_le_counter/CMakeLists.txt +++ b/bluetooth/btstack_examples/ublox_spp_le_counter/CMakeLists.txt @@ -18,5 +18,8 @@ target_include_directories(ublox_spp_le_counter PRIVATE pico_btstack_make_gatt_header(ublox_spp_le_counter PRIVATE ${PICO_BTSTACK_PATH}/example/ublox_spp_le_counter.gatt ) +target_compile_definitions(ublox_spp_le_counter PRIVATE + #WANT_HCI_DUMP=1 +) pico_add_extra_outputs(ublox_spp_le_counter) example_auto_set_url(ublox_spp_le_counter) diff --git a/pico_w/bt/standalone/CMakeLists.txt b/pico_w/bt/standalone/CMakeLists.txt index ef03fe482..19eea4404 100644 --- a/pico_w/bt/standalone/CMakeLists.txt +++ b/pico_w/bt/standalone/CMakeLists.txt @@ -1,2 +1,6 @@ -add_subdirectory(client) -add_subdirectory(server) +add_subdirectory(secure_temp_sensor) +add_subdirectory(doorbell) +add_subdirectory(wifi_provisioner) +add_subdirectory(ble_pointer) +add_subdirectory(temp_sensor) + diff --git a/pico_w/bt/standalone/ble_pointer/CMakeLists.txt b/pico_w/bt/standalone/ble_pointer/CMakeLists.txt new file mode 100644 index 000000000..9230bb4da --- /dev/null +++ b/pico_w/bt/standalone/ble_pointer/CMakeLists.txt @@ -0,0 +1,37 @@ +# Add mpu6050 libary +add_library(mpu6050_i2c_lib INTERFACE) +target_sources(mpu6050_i2c_lib INTERFACE + ${CMAKE_CURRENT_LIST_DIR}/mpu6050_i2c_lib.c + ) +target_include_directories(mpu6050_i2c_lib INTERFACE + ${CMAKE_CURRENT_LIST_DIR} + ) +target_link_libraries(mpu6050_i2c_lib INTERFACE + pico_stdlib + hardware_i2c + ) + +# Add executable. Default name is the project name, version 0.1 +add_executable(ble_pointer + ble_pointer.c + ) + +# Add the standard library to the build +target_link_libraries(ble_pointer + pico_stdlib + pico_btstack_ble + pico_btstack_cyw43 + pico_cyw43_arch_none + mpu6050_i2c_lib + ) + +# Add the standard include files to the build +target_include_directories(ble_pointer PRIVATE + ${CMAKE_CURRENT_LIST_DIR} + ${CMAKE_CURRENT_LIST_DIR}/.. + ) + +pico_btstack_make_gatt_header(ble_pointer PRIVATE "${CMAKE_CURRENT_LIST_DIR}/ble_pointer.gatt") + +pico_add_extra_outputs(ble_pointer) + diff --git a/pico_w/bt/standalone/ble_pointer/README.md b/pico_w/bt/standalone/ble_pointer/README.md new file mode 100644 index 000000000..f1c4157e9 --- /dev/null +++ b/pico_w/bt/standalone/ble_pointer/README.md @@ -0,0 +1,7 @@ +### BLE pointer + +This example is based on BTstack's 'hog_mouse_demo' and demonstrates a Bluetooth HID mouse. Cursor position is controlled by mpu6050 angle measurements, allowing you to point at the screen and move the mouse cursor. + +To use this example connect a mpu6050 (which can be found at https://thepihut.com/products/6-dof-sensor-mpu6050) to the pico, with SDA connected to pin 4 and SCL connected to pin 5. Also, connect 2 buttons to pins 15 and 16 for left and right click. + +Once powered, you should be able to pair your computer with 'HID Mouse' and use the pointer. diff --git a/pico_w/bt/standalone/ble_pointer/ble_pointer.c b/pico_w/bt/standalone/ble_pointer/ble_pointer.c new file mode 100644 index 000000000..cdcfc3e20 --- /dev/null +++ b/pico_w/bt/standalone/ble_pointer/ble_pointer.c @@ -0,0 +1,451 @@ +/* + * Copyright (C) 2017 BlueKitchen GmbH + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holders nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * 4. Any redistribution, use, or modification is done solely for + * personal benefit and not for any commercial purpose or for + * monetary gain. + * + * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BLUEKITCHEN + * GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * Please inquire about commercial licensing options at + * contact@bluekitchen-gmbh.com + * + */ + +//#define BTSTACK_FILE__ "hog_mouse_demo.c" + +// ***************************************************************************** +/* EXAMPLE_START(hog_mouse_demo): HID Mouse LE + */ +// ***************************************************************************** + +#include +#include +#include +#include +#include + +#include "ble_pointer.h" + +#include "btstack.h" + +#include "ble/gatt-service/battery_service_server.h" +#include "ble/gatt-service/device_information_service_server.h" +#include "ble/gatt-service/hids_device.h" + +#include "pico/cyw43_arch.h" +#include "pico/btstack_cyw43.h" +#include "pico/stdlib.h" +#include "hardware/i2c.h" + +#include "pico/binary_info.h" + +// for mpu6050 +#include +#include + +#define ALPHA 0.05 // for complimentary filter, big alpha gives faster reponse but more noise + +// FS values are 0, 1, 2, or 3 +// For gyro, correspond to += 250, 500, 1000, 2000 deg/s +// For accel, correspond to += 2, 4, 8, 16g +#define GYRO_FS 0 +#define ACCEL_FS 0 + +// how many readings taken to find gyro offsets +#define OFFSET_NUM 10000 + +//pins for buttons +#define LEFT_BUTTON_GPIO_NUM 15 +#define RIGHT_BUTTON_GPIO_NUM 16 + +float roll; +float pitch; +float yaw; + +float roll_offset; +float pitch_offset; +float yaw_offset; + +// start in top left corner +int abs_x = 0; +int abs_y = 0; + +// from USB HID Specification 1.1, Appendix B.2 +const uint8_t hid_descriptor_mouse_boot_mode[] = { + 0x05, 0x01, // USAGE_PAGE (Generic Desktop) + 0x09, 0x02, // USAGE (Mouse) + 0xa1, 0x01, // COLLECTION (Application) + + 0x85, 0x01, // Report ID 1 + + 0x09, 0x01, // USAGE (Pointer) + + 0xa1, 0x00, // COLLECTION (Physical) + +#if 1 + 0x05, 0x09, // USAGE_PAGE (Button) + 0x19, 0x01, // USAGE_MINIMUM (Button 1) + 0x29, 0x03, // USAGE_MAXIMUM (Button 3) + 0x15, 0x00, // LOGICAL_MINIMUM (0) + 0x25, 0x01, // LOGICAL_MAXIMUM (1) + 0x95, 0x03, // REPORT_COUNT (3) + 0x75, 0x01, // REPORT_SIZE (1) + 0x81, 0x02, // INPUT (Data,Var,Abs) + 0x95, 0x01, // REPORT_COUNT (1) + 0x75, 0x05, // REPORT_SIZE (5) + 0x81, 0x03, // INPUT (Cnst,Var,Abs) +#endif + +#if 1 + 0x05, 0x01, // USAGE_PAGE (Generic Desktop) + 0x09, 0x30, // USAGE (X) + 0x09, 0x31, // USAGE (Y) + 0x15, 0x81, // LOGICAL_MINIMUM (-127) + 0x25, 0x7f, // LOGICAL_MAXIMUM (127) + 0x75, 0x08, // REPORT_SIZE (8) + 0x95, 0x02, // REPORT_COUNT (2) + 0x81, 0x06, // INPUT (Data,Var,Rel) +#endif + + 0xc0, // END_COLLECTION + 0xc0 // END_COLLECTION +}; + +static btstack_packet_callback_registration_t hci_event_callback_registration; +static btstack_packet_callback_registration_t l2cap_event_callback_registration; +static btstack_packet_callback_registration_t sm_event_callback_registration; +static uint8_t battery = 100; +static hci_con_handle_t con_handle = HCI_CON_HANDLE_INVALID; +static uint8_t protocol_mode = 1; + +static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size); + +const uint8_t adv_data[] = { + // Flags general discoverable, BR/EDR not supported + 0x02, BLUETOOTH_DATA_TYPE_FLAGS, 0x06, + // Name + 0x0a, BLUETOOTH_DATA_TYPE_COMPLETE_LOCAL_NAME, 'H', 'I', 'D', ' ', 'M', 'o', 'u', 's', 'e', + // 16-bit Service UUIDs + 0x03, BLUETOOTH_DATA_TYPE_COMPLETE_LIST_OF_16_BIT_SERVICE_CLASS_UUIDS, ORG_BLUETOOTH_SERVICE_HUMAN_INTERFACE_DEVICE & 0xff, ORG_BLUETOOTH_SERVICE_HUMAN_INTERFACE_DEVICE >> 8, + // Appearance HID - Mouse (Category 15, Sub-Category 2) + 0x03, BLUETOOTH_DATA_TYPE_APPEARANCE, 0xC2, 0x03, +}; +const uint8_t adv_data_len = sizeof(adv_data); + +static void hog_mouse_setup(void){ + + // initialize CYW43 driver architecture (will enable BT if/because CYW43_ENABLE_BLUETOOTH == 1) + if (cyw43_arch_init()) { + printf("failed to initialise cyw43_arch\n"); + } + + // setup l2cap + l2cap_init(); + + // setup SM: Display only + sm_init(); + sm_set_io_capabilities(IO_CAPABILITY_NO_INPUT_NO_OUTPUT); + sm_set_authentication_requirements(SM_AUTHREQ_SECURE_CONNECTION | SM_AUTHREQ_BONDING); + + // setup ATT server + att_server_init(profile_data, NULL, NULL); + + // setup battery service + battery_service_server_init(battery); + + // setup device information service + device_information_service_server_init(); + + // setup HID Device service + hids_device_init(0, hid_descriptor_mouse_boot_mode, sizeof(hid_descriptor_mouse_boot_mode)); + + // setup advertisements + uint16_t adv_int_min = 0x0030; + uint16_t adv_int_max = 0x0030; + uint8_t adv_type = 0; + bd_addr_t null_addr; + memset(null_addr, 0, 6); + gap_advertisements_set_params(adv_int_min, adv_int_max, adv_type, 0, null_addr, 0x07, 0x00); + gap_advertisements_set_data(adv_data_len, (uint8_t*) adv_data); + gap_advertisements_enable(1); + + // register for events + hci_event_callback_registration.callback = &packet_handler; + hci_add_event_handler(&hci_event_callback_registration); + + // register for connection parameter updates + l2cap_event_callback_registration.callback = &packet_handler; + l2cap_add_event_handler(&l2cap_event_callback_registration); + + sm_event_callback_registration.callback = &packet_handler; + sm_add_event_handler(&sm_event_callback_registration); + + hids_device_register_packet_handler(packet_handler); +} + +// HID Report sending +static void send_report(uint8_t buttons, int8_t dx, int8_t dy){ + uint8_t report[] = { buttons, (uint8_t) dx, (uint8_t) dy }; + switch (protocol_mode){ + case 0: + hids_device_send_boot_mouse_input_report(con_handle, report, sizeof(report)); + break; + case 1: + hids_device_send_input_report(con_handle, report, sizeof(report)); + break; + default: + break; + } +} + +static int dx; +static int dy; +static uint8_t buttons; + +#define MOUSE_PERIOD_MS 15 +#define SCREEN_WIDTH 1920 +#define SCREEN_HEIGHT 1080 + +static btstack_timer_source_t mousing_timer; +static int mousing_active = 0; + +static void mousing_timer_handler(btstack_timer_source_t * ts){ + + if (con_handle == HCI_CON_HANDLE_INVALID) { + mousing_active = 0; + return; + } + + mpu6050_fusion_output(roll_offset, pitch_offset, yaw_offset, ALPHA, MOUSE_PERIOD_MS, &roll, &pitch, &yaw, GYRO_FS); + + // move proportional to roll/yaw and pitch (if within boundary, otherwise dont move) + // int desired_x = SCREEN_WIDTH/2 + (SCREEN_WIDTH/2) * roll/90; // fully right at 90 degrees, fully left at -90 degrees + int desired_x = SCREEN_WIDTH/2 + (SCREEN_WIDTH/2) * - yaw/45; // alternative x based on yaw rather than roll (prone to drift) + int desired_y = SCREEN_HEIGHT/2 + (SCREEN_HEIGHT/2) * pitch/45; // fully top at 45 degrees, fully bottom at -45 degrees + + dx = desired_x - abs_x; + dy = desired_y - abs_y; + + if (abs_x + dx < 0 || abs_x + dx > SCREEN_WIDTH) { // about to move off side of screen + dx = 0; + } + + if (abs_y + dy < 0 || abs_y + dy > SCREEN_HEIGHT) { // about to move off top/bottom of screen + dy = 0; + } + + abs_x += dx; + abs_y += dy; + + // trigger send + hids_device_request_can_send_now_event(con_handle); + + // set next timer + btstack_run_loop_set_timer(ts, MOUSE_PERIOD_MS); + btstack_run_loop_add_timer(ts); +} + +// IRQ handler for mouse buttons +void button_irq_handler(uint gpio, uint32_t events) { + if (gpio == LEFT_BUTTON_GPIO_NUM) { + printf("left click!\n"); + if (!gpio_get(gpio)) { + buttons = 1; + } else { + buttons = 0; + } + } else if (gpio == RIGHT_BUTTON_GPIO_NUM) { + printf("right click!\n"); + if (!gpio_get(gpio)) { + buttons = 2; + } else { + buttons = 0; + } + } +} + +static void hid_embedded_start_mousing(void){ + if (mousing_active) return; + mousing_active = 1; + + printf("Start mousing..\n"); + + // set one-shot timer + mousing_timer.process = &mousing_timer_handler; + btstack_run_loop_set_timer(&mousing_timer, MOUSE_PERIOD_MS); + btstack_run_loop_add_timer(&mousing_timer); +} + +static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ + UNUSED(channel); + UNUSED(size); + uint16_t conn_interval; + + if (packet_type != HCI_EVENT_PACKET) return; + + switch (hci_event_packet_get_type(packet)) { + case HCI_EVENT_DISCONNECTION_COMPLETE: + con_handle = HCI_CON_HANDLE_INVALID; + printf("Disconnected\n"); + break; + case SM_EVENT_JUST_WORKS_REQUEST: + printf("Just Works requested\n"); + sm_just_works_confirm(sm_event_just_works_request_get_handle(packet)); + break; + case SM_EVENT_NUMERIC_COMPARISON_REQUEST: + printf("Confirming numeric comparison: %"PRIu32"\n", sm_event_numeric_comparison_request_get_passkey(packet)); + sm_numeric_comparison_confirm(sm_event_passkey_display_number_get_handle(packet)); + break; + case SM_EVENT_PASSKEY_DISPLAY_NUMBER: + printf("Display Passkey: %"PRIu32"\n", sm_event_passkey_display_number_get_passkey(packet)); + break; + case L2CAP_EVENT_CONNECTION_PARAMETER_UPDATE_RESPONSE: + printf("L2CAP Connection Parameter Update Complete, response: %x\n", l2cap_event_connection_parameter_update_response_get_result(packet)); + break; + case HCI_EVENT_META_GAP: + switch (hci_event_gap_meta_get_subevent_code(packet)) { + case GAP_SUBEVENT_LE_CONNECTION_COMPLETE: + // print connection parameters (without using float operations) + conn_interval = gap_subevent_le_connection_complete_get_conn_interval(packet); + printf("LE Connection Complete:\n"); + printf("- Connection Interval: %u.%02u ms\n", conn_interval * 125 / 100, 25 * (conn_interval & 3)); + printf("- Connection Latency: %u\n", gap_subevent_le_connection_complete_get_conn_latency(packet)); + break; + default: + break; + } + break; + case HCI_EVENT_LE_META: + switch (hci_event_le_meta_get_subevent_code(packet)) { + case HCI_SUBEVENT_LE_CONNECTION_UPDATE_COMPLETE: + // print connection parameters (without using float operations) + conn_interval = hci_subevent_le_connection_update_complete_get_conn_interval(packet); + printf("LE Connection Update:\n"); + printf("- Connection Interval: %u.%02u ms\n", conn_interval * 125 / 100, 25 * (conn_interval & 3)); + printf("- Connection Latency: %u\n", hci_subevent_le_connection_update_complete_get_conn_latency(packet)); + break; + default: + break; + } + break; + case HCI_EVENT_HIDS_META: + switch (hci_event_hids_meta_get_subevent_code(packet)){ + case HIDS_SUBEVENT_INPUT_REPORT_ENABLE: + con_handle = hids_subevent_input_report_enable_get_con_handle(packet); + printf("Report Characteristic Subscribed %u\n", hids_subevent_input_report_enable_get_enable(packet)); +#ifndef HAVE_BTSTACK_STDIN + hid_embedded_start_mousing(); +#endif + // request connection param update via L2CAP following Apple Bluetooth Design Guidelines + // gap_request_connection_parameter_update(con_handle, 12, 12, 4, 100); // 15 ms, 4, 1s + + // directly update connection params via HCI following Apple Bluetooth Design Guidelines + // gap_update_connection_parameters(con_handle, 12, 12, 4, 100); // 60-75 ms, 4, 1s + + break; + case HIDS_SUBEVENT_BOOT_KEYBOARD_INPUT_REPORT_ENABLE: + con_handle = hids_subevent_boot_keyboard_input_report_enable_get_con_handle(packet); + printf("Boot Keyboard Characteristic Subscribed %u\n", hids_subevent_boot_keyboard_input_report_enable_get_enable(packet)); + break; + case HIDS_SUBEVENT_BOOT_MOUSE_INPUT_REPORT_ENABLE: + con_handle = hids_subevent_boot_mouse_input_report_enable_get_con_handle(packet); + printf("Boot Mouse Characteristic Subscribed %u\n", hids_subevent_boot_mouse_input_report_enable_get_enable(packet)); + break; + case HIDS_SUBEVENT_PROTOCOL_MODE: + protocol_mode = hids_subevent_protocol_mode_get_protocol_mode(packet); + printf("Protocol Mode: %s mode\n", hids_subevent_protocol_mode_get_protocol_mode(packet) ? "Report" : "Boot"); + break; + case HIDS_SUBEVENT_CAN_SEND_NOW: + send_report(buttons, dx, dy); + break; + default: + break; + } + break; + + default: + break; + } +} + +int main(void) { + stdio_init_all(); + +#if !defined(i2c_default) || !defined(PICO_DEFAULT_I2C_SDA_PIN) || !defined(PICO_DEFAULT_I2C_SCL_PIN) + #warning Example requires a board with I2C pins + puts("Default I2C pins were not defined"); + return 1; +#endif + + // Make the I2C pins available to picotool + bi_decl(bi_2pins_with_func(PICO_DEFAULT_I2C_SDA_PIN, PICO_DEFAULT_I2C_SCL_PIN, GPIO_FUNC_I2C)); + + // mouse buttons + gpio_init(LEFT_BUTTON_GPIO_NUM); + gpio_init(RIGHT_BUTTON_GPIO_NUM); + + gpio_set_dir(LEFT_BUTTON_GPIO_NUM, GPIO_IN); + gpio_set_dir(RIGHT_BUTTON_GPIO_NUM, GPIO_IN); + + gpio_pull_up(LEFT_BUTTON_GPIO_NUM); + gpio_pull_up(RIGHT_BUTTON_GPIO_NUM); + + gpio_set_irq_enabled_with_callback(LEFT_BUTTON_GPIO_NUM, GPIO_IRQ_EDGE_FALL | GPIO_IRQ_EDGE_RISE, true, &button_irq_handler); + gpio_set_irq_enabled(RIGHT_BUTTON_GPIO_NUM, GPIO_IRQ_EDGE_FALL | GPIO_IRQ_EDGE_RISE, true); + + // First initialise mpu6050 + // initialise to min full scale(+=250deg/s and +=2g) + mpu6050_initialise(PICO_DEFAULT_I2C_SDA_PIN, PICO_DEFAULT_I2C_SCL_PIN, GYRO_FS, ACCEL_FS); + mpu6050_reset(); + + // get gyro offsets + mpu6050_get_gyro_offset(OFFSET_NUM, &roll_offset, &pitch_offset, &yaw_offset, GYRO_FS); + + // get initial roll and pitch values based on accelerometer + int16_t acceleration[3], gyro[3], temp; + mpu6050_read_raw(acceleration, gyro, &temp); + roll = atan2(acceleration[1] , acceleration[2]) * 57.3; + pitch = atan2((- acceleration[0]) , sqrt(acceleration[1] * acceleration[1] + acceleration[2] * acceleration[2])) * 57.3; + + // assume yaw starts at 0 degrees (no absolute reference) + yaw = 0; + + // now setup BLE + hog_mouse_setup(); + +#ifdef HAVE_BTSTACK_STDIN + btstack_stdin_setup(stdin_process); +#endif + + // turn on! + hci_power_control(HCI_POWER_ON); + + while (true) { + sleep_ms(1000); + } + return 0; +} diff --git a/pico_w/bt/standalone/ble_pointer/ble_pointer.fzz b/pico_w/bt/standalone/ble_pointer/ble_pointer.fzz new file mode 100644 index 0000000000000000000000000000000000000000..347d8a82d484e021abf30357d63278f1d828f684 GIT binary patch literal 143681 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 z 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
    c96VG$!xD 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 literal 0 HcmV?d00001 diff --git a/pico_w/bt/standalone/ble_pointer/ble_pointer.gatt b/pico_w/bt/standalone/ble_pointer/ble_pointer.gatt new file mode 100644 index 000000000..b2459f553 --- /dev/null +++ b/pico_w/bt/standalone/ble_pointer/ble_pointer.gatt @@ -0,0 +1,48 @@ +PRIMARY_SERVICE, GAP_SERVICE +CHARACTERISTIC, GAP_DEVICE_NAME, READ, "HID Mouse" + +PRIMARY_SERVICE, GATT_SERVICE +CHARACTERISTIC, GATT_DATABASE_HASH, READ, + +// add Battery Service +// Battery Service 180F +PRIMARY_SERVICE, ORG_BLUETOOTH_SERVICE_BATTERY_SERVICE +CHARACTERISTIC, ORG_BLUETOOTH_CHARACTERISTIC_BATTERY_LEVEL, DYNAMIC | READ | NOTIFY, + +// add Device ID Service +// Device Information 180A +PRIMARY_SERVICE, ORG_BLUETOOTH_SERVICE_DEVICE_INFORMATION +CHARACTERISTIC, ORG_BLUETOOTH_CHARACTERISTIC_MANUFACTURER_NAME_STRING, DYNAMIC | READ, +CHARACTERISTIC, ORG_BLUETOOTH_CHARACTERISTIC_MODEL_NUMBER_STRING, DYNAMIC | READ, +CHARACTERISTIC, ORG_BLUETOOTH_CHARACTERISTIC_SERIAL_NUMBER_STRING, DYNAMIC | READ, +CHARACTERISTIC, ORG_BLUETOOTH_CHARACTERISTIC_HARDWARE_REVISION_STRING, DYNAMIC | READ, +CHARACTERISTIC, ORG_BLUETOOTH_CHARACTERISTIC_FIRMWARE_REVISION_STRING, DYNAMIC | READ, +CHARACTERISTIC, ORG_BLUETOOTH_CHARACTERISTIC_SOFTWARE_REVISION_STRING, DYNAMIC | READ, +CHARACTERISTIC, ORG_BLUETOOTH_CHARACTERISTIC_SYSTEM_ID, DYNAMIC | READ, +CHARACTERISTIC, ORG_BLUETOOTH_CHARACTERISTIC_IEEE_11073_20601_REGULATORY_CERTIFICATION_DATA_LIST, DYNAMIC | READ, +CHARACTERISTIC, ORG_BLUETOOTH_CHARACTERISTIC_PNP_ID, DYNAMIC | READ, + +// add HID Service +// Human Interface Device 1812 +PRIMARY_SERVICE, ORG_BLUETOOTH_SERVICE_HUMAN_INTERFACE_DEVICE +CHARACTERISTIC, ORG_BLUETOOTH_CHARACTERISTIC_PROTOCOL_MODE, DYNAMIC | READ | WRITE_WITHOUT_RESPONSE, + +CHARACTERISTIC, ORG_BLUETOOTH_CHARACTERISTIC_REPORT, DYNAMIC | READ | WRITE | NOTIFY | ENCRYPTION_KEY_SIZE_16, +// fixed report id = 1, type = Input (1) +REPORT_REFERENCE, READ, 1, 1 + +CHARACTERISTIC, ORG_BLUETOOTH_CHARACTERISTIC_REPORT, DYNAMIC | READ | WRITE | WRITE_WITHOUT_RESPONSE | ENCRYPTION_KEY_SIZE_16, +// fixed report id = 2, type = Output (2) +REPORT_REFERENCE, READ, 2, 2 + +CHARACTERISTIC, ORG_BLUETOOTH_CHARACTERISTIC_REPORT, DYNAMIC | READ | WRITE | ENCRYPTION_KEY_SIZE_16, +// fixed report id = 3, type = Feature (3) +REPORT_REFERENCE, READ, 3, 3 + +CHARACTERISTIC, ORG_BLUETOOTH_CHARACTERISTIC_REPORT_MAP, DYNAMIC | READ, +CHARACTERISTIC, ORG_BLUETOOTH_CHARACTERISTIC_BOOT_KEYBOARD_INPUT_REPORT, DYNAMIC | READ | WRITE | NOTIFY, +CHARACTERISTIC, ORG_BLUETOOTH_CHARACTERISTIC_BOOT_KEYBOARD_OUTPUT_REPORT, DYNAMIC | READ | WRITE | WRITE_WITHOUT_RESPONSE, +CHARACTERISTIC, ORG_BLUETOOTH_CHARACTERISTIC_BOOT_MOUSE_INPUT_REPORT, DYNAMIC | READ | WRITE | NOTIFY, +// bcdHID = 0x101 (v1.0.1), bCountryCode 0, remote wakeable = 0 | normally connectable 2 +CHARACTERISTIC, ORG_BLUETOOTH_CHARACTERISTIC_HID_INFORMATION, READ, 01 01 00 02 +CHARACTERISTIC, ORG_BLUETOOTH_CHARACTERISTIC_HID_CONTROL_POINT, DYNAMIC | WRITE_WITHOUT_RESPONSE, diff --git a/pico_w/bt/standalone/ble_pointer/ble_pointer_bb.png b/pico_w/bt/standalone/ble_pointer/ble_pointer_bb.png new file mode 100644 index 0000000000000000000000000000000000000000..14acd872e15439c34acaf835c2080df1141c9adf GIT binary patch literal 245357 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�i;1-)%8vRU4 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

    6>D_Ua6Oa8QH;2(W)Mmv_i>< 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

    mSeuJ@-o`&CVIZ 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
  1. SSID: %s, Password: %s, Index: %i
  2. ", + ssid_list[i], password_list[i], i); + } + break; + } + case 1: { // ssid + printed = snprintf(pcInsert, iInsertLen, ssid); + break; + } + case 2: { // password + printed = snprintf(pcInsert, iInsertLen, password); + break; + } + default: { // unknown tag + printed = 0; + break; + } + } + return printed; +} \ No newline at end of file diff --git a/pico_w/wifi/access_point_wifi_provisioning/CMakeLists.txt b/pico_w/wifi/access_point_wifi_provisioning/CMakeLists.txt new file mode 100644 index 000000000..c22c25a5d --- /dev/null +++ b/pico_w/wifi/access_point_wifi_provisioning/CMakeLists.txt @@ -0,0 +1,25 @@ +add_executable(AP_provisioning + AP_provisioning.c + dhcpserver/dhcpserver.c + dnsserver/dnsserver.c + ) +target_include_directories(AP_provisioning PRIVATE + ${CMAKE_CURRENT_LIST_DIR} + ${CMAKE_CURRENT_LIST_DIR}/.. # for our common lwipopts + ${PICO_LWIP_CONTRIB_PATH}/apps/httpd + ${CMAKE_CURRENT_LIST_DIR}/dhcpserver + ${CMAKE_CURRENT_LIST_DIR}/dnsserver + ) +target_link_libraries(AP_provisioning PRIVATE + pico_cyw43_arch_lwip_poll + pico_lwip_http + ap_provisioning_content + pico_stdlib + hardware_flash + ) +pico_add_extra_outputs(AP_provisioning) + +pico_add_library(ap_provisioning_content NOFLAG) +pico_set_lwip_httpd_content(ap_provisioning_content INTERFACE + ${CMAKE_CURRENT_LIST_DIR}/content/index.shtml + ) \ No newline at end of file diff --git a/pico_w/wifi/access_point_wifi_provisioning/README.md b/pico_w/wifi/access_point_wifi_provisioning/README.md new file mode 100644 index 000000000..b264909ff --- /dev/null +++ b/pico_w/wifi/access_point_wifi_provisioning/README.md @@ -0,0 +1,4 @@ +### Access point wifi provisioning + +This example demonstrates provisioning wifi credentials using an access point. The pico saves succesful credentials in flash, which it first uses when attempting to join wifi. If this fails, the pico starts an access point which you can connect to and input credentials. The DNS server means that any address you enter when connected to the access point will take you to the provisioning web page. + diff --git a/pico_w/wifi/access_point_wifi_provisioning/content/index.shtml b/pico_w/wifi/access_point_wifi_provisioning/content/index.shtml new file mode 100644 index 000000000..5f552d417 --- /dev/null +++ b/pico_w/wifi/access_point_wifi_provisioning/content/index.shtml @@ -0,0 +1,57 @@ + + + + + + + +

    AP provisioning

    + +

    Enter new credentials, submit, then connect, or select from previously saved.

    + +
    + +
    +

    Current SSID:

    +

    Current password:

    + +
    +
    +
    +
    +
    + +
    + +
    + +
    + +
    + +
    + +
    + +
    +

    List of saved credentials:

    +
    +
    +
    + +
    +
    + + +
    + + + \ No newline at end of file diff --git a/pico_w/wifi/access_point_wifi_provisioning/dhcpserver/LICENSE b/pico_w/wifi/access_point_wifi_provisioning/dhcpserver/LICENSE new file mode 100644 index 000000000..8f9b52cbb --- /dev/null +++ b/pico_w/wifi/access_point_wifi_provisioning/dhcpserver/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2013-2022 Damien P. George + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/pico_w/wifi/access_point_wifi_provisioning/dhcpserver/dhcpserver.c b/pico_w/wifi/access_point_wifi_provisioning/dhcpserver/dhcpserver.c new file mode 100644 index 000000000..2061d047e --- /dev/null +++ b/pico_w/wifi/access_point_wifi_provisioning/dhcpserver/dhcpserver.c @@ -0,0 +1,309 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018-2019 Damien P. George + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +// For DHCP specs see: +// https://www.ietf.org/rfc/rfc2131.txt +// https://tools.ietf.org/html/rfc2132 -- DHCP Options and BOOTP Vendor Extensions + +#include +#include +#include + +#include "cyw43_config.h" +#include "dhcpserver.h" +#include "lwip/udp.h" + +#define DHCPDISCOVER (1) +#define DHCPOFFER (2) +#define DHCPREQUEST (3) +#define DHCPDECLINE (4) +#define DHCPACK (5) +#define DHCPNACK (6) +#define DHCPRELEASE (7) +#define DHCPINFORM (8) + +#define DHCP_OPT_PAD (0) +#define DHCP_OPT_SUBNET_MASK (1) +#define DHCP_OPT_ROUTER (3) +#define DHCP_OPT_DNS (6) +#define DHCP_OPT_HOST_NAME (12) +#define DHCP_OPT_REQUESTED_IP (50) +#define DHCP_OPT_IP_LEASE_TIME (51) +#define DHCP_OPT_MSG_TYPE (53) +#define DHCP_OPT_SERVER_ID (54) +#define DHCP_OPT_PARAM_REQUEST_LIST (55) +#define DHCP_OPT_MAX_MSG_SIZE (57) +#define DHCP_OPT_VENDOR_CLASS_ID (60) +#define DHCP_OPT_CLIENT_ID (61) +#define DHCP_OPT_END (255) + +#define PORT_DHCP_SERVER (67) +#define PORT_DHCP_CLIENT (68) + +#define DEFAULT_LEASE_TIME_S (24 * 60 * 60) // in seconds + +#define MAC_LEN (6) +#define MAKE_IP4(a, b, c, d) ((a) << 24 | (b) << 16 | (c) << 8 | (d)) + +typedef struct { + uint8_t op; // message opcode + uint8_t htype; // hardware address type + uint8_t hlen; // hardware address length + uint8_t hops; + uint32_t xid; // transaction id, chosen by client + uint16_t secs; // client seconds elapsed + uint16_t flags; + uint8_t ciaddr[4]; // client IP address + uint8_t yiaddr[4]; // your IP address + uint8_t siaddr[4]; // next server IP address + uint8_t giaddr[4]; // relay agent IP address + uint8_t chaddr[16]; // client hardware address + uint8_t sname[64]; // server host name + uint8_t file[128]; // boot file name + uint8_t options[312]; // optional parameters, variable, starts with magic +} dhcp_msg_t; + +static int dhcp_socket_new_dgram(struct udp_pcb **udp, void *cb_data, udp_recv_fn cb_udp_recv) { + // family is AF_INET + // type is SOCK_DGRAM + + *udp = udp_new(); + if (*udp == NULL) { + return -ENOMEM; + } + + // Register callback + udp_recv(*udp, cb_udp_recv, (void *)cb_data); + + return 0; // success +} + +static void dhcp_socket_free(struct udp_pcb **udp) { + if (*udp != NULL) { + udp_remove(*udp); + *udp = NULL; + } +} + +static int dhcp_socket_bind(struct udp_pcb **udp, uint16_t port) { + // TODO convert lwIP errors to errno + return udp_bind(*udp, IP_ANY_TYPE, port); +} + +static int dhcp_socket_sendto(struct udp_pcb **udp, struct netif *nif, const void *buf, size_t len, uint32_t ip, uint16_t port) { + if (len > 0xffff) { + len = 0xffff; + } + + struct pbuf *p = pbuf_alloc(PBUF_TRANSPORT, len, PBUF_RAM); + if (p == NULL) { + return -ENOMEM; + } + + memcpy(p->payload, buf, len); + + ip_addr_t dest; + IP4_ADDR(ip_2_ip4(&dest), ip >> 24 & 0xff, ip >> 16 & 0xff, ip >> 8 & 0xff, ip & 0xff); + err_t err; + if (nif != NULL) { + err = udp_sendto_if(*udp, p, &dest, port, nif); + } else { + err = udp_sendto(*udp, p, &dest, port); + } + + pbuf_free(p); + + if (err != ERR_OK) { + return err; + } + + return len; +} + +static uint8_t *opt_find(uint8_t *opt, uint8_t cmd) { + for (int i = 0; i < 308 && opt[i] != DHCP_OPT_END;) { + if (opt[i] == cmd) { + return &opt[i]; + } + i += 2 + opt[i + 1]; + } + return NULL; +} + +static void opt_write_n(uint8_t **opt, uint8_t cmd, size_t n, const void *data) { + uint8_t *o = *opt; + *o++ = cmd; + *o++ = n; + memcpy(o, data, n); + *opt = o + n; +} + +static void opt_write_u8(uint8_t **opt, uint8_t cmd, uint8_t val) { + uint8_t *o = *opt; + *o++ = cmd; + *o++ = 1; + *o++ = val; + *opt = o; +} + +static void opt_write_u32(uint8_t **opt, uint8_t cmd, uint32_t val) { + uint8_t *o = *opt; + *o++ = cmd; + *o++ = 4; + *o++ = val >> 24; + *o++ = val >> 16; + *o++ = val >> 8; + *o++ = val; + *opt = o; +} + +static void dhcp_server_process(void *arg, struct udp_pcb *upcb, struct pbuf *p, const ip_addr_t *src_addr, u16_t src_port) { + dhcp_server_t *d = arg; + (void)upcb; + (void)src_addr; + (void)src_port; + + // This is around 548 bytes + dhcp_msg_t dhcp_msg; + + #define DHCP_MIN_SIZE (240 + 3) + if (p->tot_len < DHCP_MIN_SIZE) { + goto ignore_request; + } + + size_t len = pbuf_copy_partial(p, &dhcp_msg, sizeof(dhcp_msg), 0); + if (len < DHCP_MIN_SIZE) { + goto ignore_request; + } + + dhcp_msg.op = DHCPOFFER; + memcpy(&dhcp_msg.yiaddr, &ip4_addr_get_u32(ip_2_ip4(&d->ip)), 4); + + uint8_t *opt = (uint8_t *)&dhcp_msg.options; + opt += 4; // assume magic cookie: 99, 130, 83, 99 + + uint8_t *msgtype = opt_find(opt, DHCP_OPT_MSG_TYPE); + if (msgtype == NULL) { + // A DHCP package without MSG_TYPE? + goto ignore_request; + } + + switch (msgtype[2]) { + case DHCPDISCOVER: { + int yi = DHCPS_MAX_IP; + for (int i = 0; i < DHCPS_MAX_IP; ++i) { + if (memcmp(d->lease[i].mac, dhcp_msg.chaddr, MAC_LEN) == 0) { + // MAC match, use this IP address + yi = i; + break; + } + if (yi == DHCPS_MAX_IP) { + // Look for a free IP address + if (memcmp(d->lease[i].mac, "\x00\x00\x00\x00\x00\x00", MAC_LEN) == 0) { + // IP available + yi = i; + } + uint32_t expiry = d->lease[i].expiry << 16 | 0xffff; + if ((int32_t)(expiry - cyw43_hal_ticks_ms()) < 0) { + // IP expired, reuse it + memset(d->lease[i].mac, 0, MAC_LEN); + yi = i; + } + } + } + if (yi == DHCPS_MAX_IP) { + // No more IP addresses left + goto ignore_request; + } + dhcp_msg.yiaddr[3] = DHCPS_BASE_IP + yi; + opt_write_u8(&opt, DHCP_OPT_MSG_TYPE, DHCPOFFER); + break; + } + + case DHCPREQUEST: { + uint8_t *o = opt_find(opt, DHCP_OPT_REQUESTED_IP); + if (o == NULL) { + // Should be NACK + goto ignore_request; + } + if (memcmp(o + 2, &ip4_addr_get_u32(ip_2_ip4(&d->ip)), 3) != 0) { + // Should be NACK + goto ignore_request; + } + uint8_t yi = o[5] - DHCPS_BASE_IP; + if (yi >= DHCPS_MAX_IP) { + // Should be NACK + goto ignore_request; + } + if (memcmp(d->lease[yi].mac, dhcp_msg.chaddr, MAC_LEN) == 0) { + // MAC match, ok to use this IP address + } else if (memcmp(d->lease[yi].mac, "\x00\x00\x00\x00\x00\x00", MAC_LEN) == 0) { + // IP unused, ok to use this IP address + memcpy(d->lease[yi].mac, dhcp_msg.chaddr, MAC_LEN); + } else { + // IP already in use + // Should be NACK + goto ignore_request; + } + d->lease[yi].expiry = (cyw43_hal_ticks_ms() + DEFAULT_LEASE_TIME_S * 1000) >> 16; + dhcp_msg.yiaddr[3] = DHCPS_BASE_IP + yi; + opt_write_u8(&opt, DHCP_OPT_MSG_TYPE, DHCPACK); + printf("DHCPS: client connected: MAC=%02x:%02x:%02x:%02x:%02x:%02x IP=%u.%u.%u.%u\n", + dhcp_msg.chaddr[0], dhcp_msg.chaddr[1], dhcp_msg.chaddr[2], dhcp_msg.chaddr[3], dhcp_msg.chaddr[4], dhcp_msg.chaddr[5], + dhcp_msg.yiaddr[0], dhcp_msg.yiaddr[1], dhcp_msg.yiaddr[2], dhcp_msg.yiaddr[3]); + break; + } + + default: + goto ignore_request; + } + + opt_write_n(&opt, DHCP_OPT_SERVER_ID, 4, &ip4_addr_get_u32(ip_2_ip4(&d->ip))); + opt_write_n(&opt, DHCP_OPT_SUBNET_MASK, 4, &ip4_addr_get_u32(ip_2_ip4(&d->nm))); + opt_write_n(&opt, DHCP_OPT_ROUTER, 4, &ip4_addr_get_u32(ip_2_ip4(&d->ip))); // aka gateway; can have multiple addresses + opt_write_n(&opt, DHCP_OPT_DNS, 4, &ip4_addr_get_u32(ip_2_ip4(&d->ip))); // this server is the dns + opt_write_u32(&opt, DHCP_OPT_IP_LEASE_TIME, DEFAULT_LEASE_TIME_S); + *opt++ = DHCP_OPT_END; + struct netif *nif = ip_current_input_netif(); + dhcp_socket_sendto(&d->udp, nif, &dhcp_msg, opt - (uint8_t *)&dhcp_msg, 0xffffffff, PORT_DHCP_CLIENT); + +ignore_request: + pbuf_free(p); +} + +void dhcp_server_init(dhcp_server_t *d, ip_addr_t *ip, ip_addr_t *nm) { + ip_addr_copy(d->ip, *ip); + ip_addr_copy(d->nm, *nm); + memset(d->lease, 0, sizeof(d->lease)); + if (dhcp_socket_new_dgram(&d->udp, d, dhcp_server_process) != 0) { + return; + } + dhcp_socket_bind(&d->udp, PORT_DHCP_SERVER); +} + +void dhcp_server_deinit(dhcp_server_t *d) { + dhcp_socket_free(&d->udp); +} diff --git a/pico_w/wifi/access_point_wifi_provisioning/dhcpserver/dhcpserver.h b/pico_w/wifi/access_point_wifi_provisioning/dhcpserver/dhcpserver.h new file mode 100644 index 000000000..2349d2ea4 --- /dev/null +++ b/pico_w/wifi/access_point_wifi_provisioning/dhcpserver/dhcpserver.h @@ -0,0 +1,49 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018-2019 Damien P. George + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#ifndef MICROPY_INCLUDED_LIB_NETUTILS_DHCPSERVER_H +#define MICROPY_INCLUDED_LIB_NETUTILS_DHCPSERVER_H + +#include "lwip/ip_addr.h" + +#define DHCPS_BASE_IP (16) +#define DHCPS_MAX_IP (8) + +typedef struct _dhcp_server_lease_t { + uint8_t mac[6]; + uint16_t expiry; +} dhcp_server_lease_t; + +typedef struct _dhcp_server_t { + ip_addr_t ip; + ip_addr_t nm; + dhcp_server_lease_t lease[DHCPS_MAX_IP]; + struct udp_pcb *udp; +} dhcp_server_t; + +void dhcp_server_init(dhcp_server_t *d, ip_addr_t *ip, ip_addr_t *nm); +void dhcp_server_deinit(dhcp_server_t *d); + +#endif // MICROPY_INCLUDED_LIB_NETUTILS_DHCPSERVER_H diff --git a/pico_w/wifi/access_point_wifi_provisioning/dnsserver/dnsserver.c b/pico_w/wifi/access_point_wifi_provisioning/dnsserver/dnsserver.c new file mode 100644 index 000000000..029870b56 --- /dev/null +++ b/pico_w/wifi/access_point_wifi_provisioning/dnsserver/dnsserver.c @@ -0,0 +1,235 @@ +/** + * Copyright (c) 2022 Raspberry Pi (Trading) Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include + +#include "dnsserver.h" +#include "lwip/udp.h" + +#define PORT_DNS_SERVER 53 +#define DUMP_DATA 0 + +#define DEBUG_printf(...) +#define ERROR_printf printf + +typedef struct dns_header_t_ { + uint16_t id; + uint16_t flags; + uint16_t question_count; + uint16_t answer_record_count; + uint16_t authority_record_count; + uint16_t additional_record_count; +} dns_header_t; + +#define MAX_DNS_MSG_SIZE 300 + +static int dns_socket_new_dgram(struct udp_pcb **udp, void *cb_data, udp_recv_fn cb_udp_recv) { + *udp = udp_new(); + if (*udp == NULL) { + return -ENOMEM; + } + udp_recv(*udp, cb_udp_recv, (void *)cb_data); + return ERR_OK; +} + +static void dns_socket_free(struct udp_pcb **udp) { + if (*udp != NULL) { + udp_remove(*udp); + *udp = NULL; + } +} + +static int dns_socket_bind(struct udp_pcb **udp, uint32_t ip, uint16_t port) { + ip_addr_t addr; + IP4_ADDR(&addr, ip >> 24 & 0xff, ip >> 16 & 0xff, ip >> 8 & 0xff, ip & 0xff); + err_t err = udp_bind(*udp, &addr, port); + if (err != ERR_OK) { + ERROR_printf("dns failed to bind to port %u: %d", port, err); + assert(false); + } + return err; +} + +#if DUMP_DATA +static void dump_bytes(const uint8_t *bptr, uint32_t len) { + unsigned int i = 0; + + for (i = 0; i < len;) { + if ((i & 0x0f) == 0) { + printf("\n"); + } else if ((i & 0x07) == 0) { + printf(" "); + } + printf("%02x ", bptr[i++]); + } + printf("\n"); +} +#endif + +static int dns_socket_sendto(struct udp_pcb **udp, const void *buf, size_t len, const ip_addr_t *dest, uint16_t port) { + if (len > 0xffff) { + len = 0xffff; + } + + struct pbuf *p = pbuf_alloc(PBUF_TRANSPORT, len, PBUF_RAM); + if (p == NULL) { + ERROR_printf("DNS: Failed to send message out of memory\n"); + return -ENOMEM; + } + + memcpy(p->payload, buf, len); + err_t err = udp_sendto(*udp, p, dest, port); + + pbuf_free(p); + + if (err != ERR_OK) { + ERROR_printf("DNS: Failed to send message %d\n", err); + return err; + } + +#if DUMP_DATA + dump_bytes(buf, len); +#endif + return len; +} + +static void dns_server_process(void *arg, struct udp_pcb *upcb, struct pbuf *p, const ip_addr_t *src_addr, u16_t src_port) { + dns_server_t *d = arg; + DEBUG_printf("dns_server_process %u\n", p->tot_len); + + uint8_t dns_msg[MAX_DNS_MSG_SIZE]; + dns_header_t *dns_hdr = (dns_header_t*)dns_msg; + + size_t msg_len = pbuf_copy_partial(p, dns_msg, sizeof(dns_msg), 0); + if (msg_len < sizeof(dns_header_t)) { + goto ignore_request; + } + +#if DUMP_DATA + dump_bytes(dns_msg, msg_len); +#endif + + uint16_t flags = lwip_ntohs(dns_hdr->flags); + uint16_t question_count = lwip_ntohs(dns_hdr->question_count); + + DEBUG_printf("len %d\n", msg_len); + DEBUG_printf("dns flags 0x%x\n", flags); + DEBUG_printf("dns question count 0x%x\n", question_count); + + // flags from rfc1035 + // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + // |QR| Opcode |AA|TC|RD|RA| Z | RCODE | + // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + + // Check QR indicates a query + if (((flags >> 15) & 0x1) != 0) { + DEBUG_printf("Ignoring non-query\n"); + goto ignore_request; + } + + // Check for standard query + if (((flags >> 11) & 0xf) != 0) { + DEBUG_printf("Ignoring non-standard query\n"); + goto ignore_request; + } + + // Check question count + if (question_count < 1) { + DEBUG_printf("Invalid question count\n"); + goto ignore_request; + } + + // Print the question + DEBUG_printf("question: "); + const uint8_t *question_ptr_start = dns_msg + sizeof(dns_header_t); + const uint8_t *question_ptr_end = dns_msg + msg_len; + const uint8_t *question_ptr = question_ptr_start; + while(question_ptr < question_ptr_end) { + if (*question_ptr == 0) { + question_ptr++; + break; + } else { + if (question_ptr > question_ptr_start) { + DEBUG_printf("."); + } + int label_len = *question_ptr++; + if (label_len > 63) { + DEBUG_printf("Invalid label\n"); + goto ignore_request; + } + DEBUG_printf("%.*s", label_len, question_ptr); + question_ptr += label_len; + } + } + DEBUG_printf("\n"); + + // Check question length + if (question_ptr - question_ptr_start > 255) { + DEBUG_printf("Invalid question length\n"); + goto ignore_request; + } + + // Skip QNAME and QTYPE + question_ptr += 4; + + // Generate answer + uint8_t *answer_ptr = dns_msg + (question_ptr - dns_msg); + *answer_ptr++ = 0xc0; // pointer + *answer_ptr++ = question_ptr_start - dns_msg; // pointer to question + + *answer_ptr++ = 0; + *answer_ptr++ = 1; // host address + + *answer_ptr++ = 0; + *answer_ptr++ = 1; // Internet class + + *answer_ptr++ = 0; + *answer_ptr++ = 0; + *answer_ptr++ = 0; + *answer_ptr++ = 60; // ttl 60s + + *answer_ptr++ = 0; + *answer_ptr++ = 4; // length + memcpy(answer_ptr, &d->ip.addr, 4); // use our address + answer_ptr += 4; + + dns_hdr->flags = lwip_htons( + 0x1 << 15 | // QR = response + 0x1 << 10 | // AA = authoritative + 0x1 << 7); // RA = authenticated + dns_hdr->question_count = lwip_htons(1); + dns_hdr->answer_record_count = lwip_htons(1); + dns_hdr->authority_record_count = 0; + dns_hdr->additional_record_count = 0; + + // Send the reply + DEBUG_printf("Sending %d byte reply to %s:%d\n", answer_ptr - dns_msg, ipaddr_ntoa(src_addr), src_port); + dns_socket_sendto(&d->udp, &dns_msg, answer_ptr - dns_msg, src_addr, src_port); + +ignore_request: + pbuf_free(p); +} + +void dns_server_init(dns_server_t *d, ip_addr_t *ip) { + if (dns_socket_new_dgram(&d->udp, d, dns_server_process) != ERR_OK) { + DEBUG_printf("dns server failed to start\n"); + return; + } + if (dns_socket_bind(&d->udp, 0, PORT_DNS_SERVER) != ERR_OK) { + DEBUG_printf("dns server failed to bind\n"); + return; + } + ip_addr_copy(d->ip, *ip); + DEBUG_printf("dns server listening on port %d\n", PORT_DNS_SERVER); +} + +void dns_server_deinit(dns_server_t *d) { + dns_socket_free(&d->udp); +} diff --git a/pico_w/wifi/access_point_wifi_provisioning/dnsserver/dnsserver.h b/pico_w/wifi/access_point_wifi_provisioning/dnsserver/dnsserver.h new file mode 100644 index 000000000..d23534c03 --- /dev/null +++ b/pico_w/wifi/access_point_wifi_provisioning/dnsserver/dnsserver.h @@ -0,0 +1,20 @@ +/** + * Copyright (c) 2022 Raspberry Pi (Trading) Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _DNSSERVER_H_ +#define _DNSSERVER_H_ + +#include "lwip/ip_addr.h" + +typedef struct dns_server_t_ { + struct udp_pcb *udp; + ip_addr_t ip; +} dns_server_t; + +void dns_server_init(dns_server_t *d, ip_addr_t *ip); +void dns_server_deinit(dns_server_t *d); + +#endif diff --git a/pico_w/wifi/access_point_wifi_provisioning/lwipopts.h b/pico_w/wifi/access_point_wifi_provisioning/lwipopts.h new file mode 100644 index 000000000..98170b8de --- /dev/null +++ b/pico_w/wifi/access_point_wifi_provisioning/lwipopts.h @@ -0,0 +1,101 @@ +#ifndef _LWIPOPTS_H +#define _LWIPOPTS_H + +// Common settings used in most of the pico_w examples +// (see https://www.nongnu.org/lwip/2_1_x/group__lwip__opts.html for details) + +// allow override in some examples +#ifndef NO_SYS +#define NO_SYS 1 +#endif +// allow override in some examples +#ifndef LWIP_SOCKET +#define LWIP_SOCKET 0 +#endif +#if PICO_CYW43_ARCH_POLL +#define MEM_LIBC_MALLOC 1 +#else +// MEM_LIBC_MALLOC is incompatible with non polling versions +#define MEM_LIBC_MALLOC 0 +#endif +#define MEM_ALIGNMENT 4 +#ifndef MEM_SIZE +#define MEM_SIZE 4000 +#endif +#define MEMP_NUM_TCP_SEG 32 +#define MEMP_NUM_ARP_QUEUE 10 +#define PBUF_POOL_SIZE 24 +#define LWIP_ARP 1 +#define LWIP_ETHERNET 1 +#define LWIP_ICMP 1 +#define LWIP_RAW 1 +#define TCP_WND (8 * TCP_MSS) +#define TCP_MSS 1460 +#define TCP_SND_BUF (8 * TCP_MSS) +#define TCP_SND_QUEUELEN ((4 * (TCP_SND_BUF) + (TCP_MSS - 1)) / (TCP_MSS)) +#define LWIP_NETIF_STATUS_CALLBACK 1 +#define LWIP_NETIF_LINK_CALLBACK 1 +#define LWIP_NETIF_HOSTNAME 1 +#define LWIP_NETCONN 0 +#define MEM_STATS 0 +#define SYS_STATS 0 +#define MEMP_STATS 0 +#define LINK_STATS 0 +// #define ETH_PAD_SIZE 2 +#define LWIP_CHKSUM_ALGORITHM 3 +#define LWIP_DHCP 1 +#define LWIP_IPV4 1 +#define LWIP_TCP 1 +#define LWIP_UDP 1 +#define LWIP_DNS 1 +#define LWIP_TCP_KEEPALIVE 1 +#define LWIP_NETIF_TX_SINGLE_PBUF 1 +#define DHCP_DOES_ARP_CHECK 0 +#define LWIP_DHCP_DOES_ACD_CHECK 0 + +#ifndef NDEBUG +#define LWIP_DEBUG 1 +#define LWIP_STATS 1 +#define LWIP_STATS_DISPLAY 1 +#endif + +#define ETHARP_DEBUG LWIP_DBG_OFF +#define NETIF_DEBUG LWIP_DBG_OFF +#define PBUF_DEBUG LWIP_DBG_OFF +#define API_LIB_DEBUG LWIP_DBG_OFF +#define API_MSG_DEBUG LWIP_DBG_OFF +#define SOCKETS_DEBUG LWIP_DBG_OFF +#define ICMP_DEBUG LWIP_DBG_OFF +#define INET_DEBUG LWIP_DBG_OFF +#define IP_DEBUG LWIP_DBG_OFF +#define IP_REASS_DEBUG LWIP_DBG_OFF +#define RAW_DEBUG LWIP_DBG_OFF +#define MEM_DEBUG LWIP_DBG_OFF +#define MEMP_DEBUG LWIP_DBG_OFF +#define SYS_DEBUG LWIP_DBG_OFF +#define TCP_DEBUG LWIP_DBG_OFF +#define TCP_INPUT_DEBUG LWIP_DBG_OFF +#define TCP_OUTPUT_DEBUG LWIP_DBG_OFF +#define TCP_RTO_DEBUG LWIP_DBG_OFF +#define TCP_CWND_DEBUG LWIP_DBG_OFF +#define TCP_WND_DEBUG LWIP_DBG_OFF +#define TCP_FR_DEBUG LWIP_DBG_OFF +#define TCP_QLEN_DEBUG LWIP_DBG_OFF +#define TCP_RST_DEBUG LWIP_DBG_OFF +#define UDP_DEBUG LWIP_DBG_OFF +#define TCPIP_DEBUG LWIP_DBG_OFF +#define PPP_DEBUG LWIP_DBG_OFF +#define SLIP_DEBUG LWIP_DBG_OFF +#define DHCP_DEBUG LWIP_DBG_OFF + +// Enable some httpd features +#define LWIP_HTTPD_CGI 1 +#define LWIP_HTTPD_SSI 1 +#define LWIP_HTTPD_SSI_MULTIPART 1 +#define LWIP_HTTPD_SUPPORT_POST 0 +#define LWIP_HTTPD_SSI_INCLUDE_TAG 0 + +// Generated file containing html data +#define HTTPD_FSDATA_FILE "pico_fsdata.inc" + +#endif \ No newline at end of file From 17fb6d5e76763af48995d9562d36dc9f2e22f29f Mon Sep 17 00:00:00 2001 From: Peter Harper Date: Wed, 11 Mar 2026 10:59:13 +0000 Subject: [PATCH 03/13] Move bt examples to bluetooth folder --- .../ble_pointer/CMakeLists.txt | 0 .../ble_pointer/README.md | 0 .../ble_pointer/ble_pointer.c | 0 .../ble_pointer/ble_pointer.fzz | Bin .../ble_pointer/ble_pointer.gatt | 0 .../ble_pointer/ble_pointer_bb.png | Bin .../ble_pointer/btstack_config.h | 0 .../ble_pointer/mpu6050_i2c_lib.c | 0 .../ble_pointer/mpu6050_i2c_lib.h | 0 .../doorbell/CMakeLists.txt | 0 .../doorbell/README.md | 0 .../doorbell/btstack_config.h | 0 .../doorbell/client.c | 0 .../doorbell/doorbell.fzz | Bin .../doorbell/doorbell.gatt | 0 .../doorbell/doorbell_bb.png | Bin .../doorbell/server.c | 0 .../secure_temp_sensor/CMakeLists.txt | 0 .../secure_temp_sensor/README.md | 0 .../secure_temp_sensor/btstack_config.h | 0 .../secure_temp_sensor/client.c | 0 .../secure_temp_sensor/server.c | 0 .../secure_temp_sensor/temp_sensor.gatt | 0 .../temp_sensor/CMakeLists.txt | 0 .../temp_sensor/README.md | 0 .../temp_sensor/client/CMakeLists.txt | 0 .../temp_sensor/client/btstack_config.h | 0 .../temp_sensor/client/client.c | 0 .../temp_sensor/server/CMakeLists.txt | 0 .../temp_sensor/server/btstack_config.h | 0 .../temp_sensor/server/server.c | 0 .../temp_sensor/server/temp_sensor.gatt | 0 .../wifi_provisioner/CMakeLists.txt | 0 .../wifi_provisioner/README.md | 0 .../wifi_provisioner/btstack_config.h | 0 .../wifi_provisioner/example.c | 0 .../wifi_provisioner/lwipopts.h | 0 .../wifi_provisioner/provisioning.gatt | 0 .../wifi_provisioner/set_credentials.py | 0 .../wifi_provisioner/wifi_prov_lib.c | 0 .../wifi_provisioner/wifi_prov_lib.h | 0 pico_w/bt/standalone/CMakeLists.txt | 6 -- pico_w/bt/standalone/btstack_config_common.h | 58 ------------------ 43 files changed, 64 deletions(-) rename {pico_w/bt/standalone => bluetooth}/ble_pointer/CMakeLists.txt (100%) rename {pico_w/bt/standalone => bluetooth}/ble_pointer/README.md (100%) rename {pico_w/bt/standalone => bluetooth}/ble_pointer/ble_pointer.c (100%) rename {pico_w/bt/standalone => bluetooth}/ble_pointer/ble_pointer.fzz (100%) rename {pico_w/bt/standalone => bluetooth}/ble_pointer/ble_pointer.gatt (100%) rename {pico_w/bt/standalone => bluetooth}/ble_pointer/ble_pointer_bb.png (100%) rename {pico_w/bt/standalone => bluetooth}/ble_pointer/btstack_config.h (100%) rename {pico_w/bt/standalone => bluetooth}/ble_pointer/mpu6050_i2c_lib.c (100%) rename {pico_w/bt/standalone => bluetooth}/ble_pointer/mpu6050_i2c_lib.h (100%) rename {pico_w/bt/standalone => bluetooth}/doorbell/CMakeLists.txt (100%) rename {pico_w/bt/standalone => bluetooth}/doorbell/README.md (100%) rename {pico_w/bt/standalone => bluetooth}/doorbell/btstack_config.h (100%) rename {pico_w/bt/standalone => bluetooth}/doorbell/client.c (100%) rename {pico_w/bt/standalone => bluetooth}/doorbell/doorbell.fzz (100%) rename {pico_w/bt/standalone => bluetooth}/doorbell/doorbell.gatt (100%) rename {pico_w/bt/standalone => bluetooth}/doorbell/doorbell_bb.png (100%) rename {pico_w/bt/standalone => bluetooth}/doorbell/server.c (100%) rename {pico_w/bt/standalone => bluetooth}/secure_temp_sensor/CMakeLists.txt (100%) rename {pico_w/bt/standalone => bluetooth}/secure_temp_sensor/README.md (100%) rename {pico_w/bt/standalone => bluetooth}/secure_temp_sensor/btstack_config.h (100%) rename {pico_w/bt/standalone => bluetooth}/secure_temp_sensor/client.c (100%) rename {pico_w/bt/standalone => bluetooth}/secure_temp_sensor/server.c (100%) rename {pico_w/bt/standalone => bluetooth}/secure_temp_sensor/temp_sensor.gatt (100%) rename {pico_w/bt/standalone => bluetooth}/temp_sensor/CMakeLists.txt (100%) rename {pico_w/bt/standalone => bluetooth}/temp_sensor/README.md (100%) rename {pico_w/bt/standalone => bluetooth}/temp_sensor/client/CMakeLists.txt (100%) rename {pico_w/bt/standalone => bluetooth}/temp_sensor/client/btstack_config.h (100%) rename {pico_w/bt/standalone => bluetooth}/temp_sensor/client/client.c (100%) rename {pico_w/bt/standalone => bluetooth}/temp_sensor/server/CMakeLists.txt (100%) rename {pico_w/bt/standalone => bluetooth}/temp_sensor/server/btstack_config.h (100%) rename {pico_w/bt/standalone => bluetooth}/temp_sensor/server/server.c (100%) rename {pico_w/bt/standalone => bluetooth}/temp_sensor/server/temp_sensor.gatt (100%) rename {pico_w/bt/standalone => bluetooth}/wifi_provisioner/CMakeLists.txt (100%) rename {pico_w/bt/standalone => bluetooth}/wifi_provisioner/README.md (100%) rename {pico_w/bt/standalone => bluetooth}/wifi_provisioner/btstack_config.h (100%) rename {pico_w/bt/standalone => bluetooth}/wifi_provisioner/example.c (100%) rename {pico_w/bt/standalone => bluetooth}/wifi_provisioner/lwipopts.h (100%) rename {pico_w/bt/standalone => bluetooth}/wifi_provisioner/provisioning.gatt (100%) rename {pico_w/bt/standalone => bluetooth}/wifi_provisioner/set_credentials.py (100%) rename {pico_w/bt/standalone => bluetooth}/wifi_provisioner/wifi_prov_lib.c (100%) rename {pico_w/bt/standalone => bluetooth}/wifi_provisioner/wifi_prov_lib.h (100%) delete mode 100644 pico_w/bt/standalone/CMakeLists.txt delete mode 100644 pico_w/bt/standalone/btstack_config_common.h diff --git a/pico_w/bt/standalone/ble_pointer/CMakeLists.txt b/bluetooth/ble_pointer/CMakeLists.txt similarity index 100% rename from pico_w/bt/standalone/ble_pointer/CMakeLists.txt rename to bluetooth/ble_pointer/CMakeLists.txt diff --git a/pico_w/bt/standalone/ble_pointer/README.md b/bluetooth/ble_pointer/README.md similarity index 100% rename from pico_w/bt/standalone/ble_pointer/README.md rename to bluetooth/ble_pointer/README.md diff --git a/pico_w/bt/standalone/ble_pointer/ble_pointer.c b/bluetooth/ble_pointer/ble_pointer.c similarity index 100% rename from pico_w/bt/standalone/ble_pointer/ble_pointer.c rename to bluetooth/ble_pointer/ble_pointer.c diff --git a/pico_w/bt/standalone/ble_pointer/ble_pointer.fzz b/bluetooth/ble_pointer/ble_pointer.fzz similarity index 100% rename from pico_w/bt/standalone/ble_pointer/ble_pointer.fzz rename to bluetooth/ble_pointer/ble_pointer.fzz diff --git a/pico_w/bt/standalone/ble_pointer/ble_pointer.gatt b/bluetooth/ble_pointer/ble_pointer.gatt similarity index 100% rename from pico_w/bt/standalone/ble_pointer/ble_pointer.gatt rename to bluetooth/ble_pointer/ble_pointer.gatt diff --git a/pico_w/bt/standalone/ble_pointer/ble_pointer_bb.png b/bluetooth/ble_pointer/ble_pointer_bb.png similarity index 100% rename from pico_w/bt/standalone/ble_pointer/ble_pointer_bb.png rename to bluetooth/ble_pointer/ble_pointer_bb.png diff --git a/pico_w/bt/standalone/ble_pointer/btstack_config.h b/bluetooth/ble_pointer/btstack_config.h similarity index 100% rename from pico_w/bt/standalone/ble_pointer/btstack_config.h rename to bluetooth/ble_pointer/btstack_config.h diff --git a/pico_w/bt/standalone/ble_pointer/mpu6050_i2c_lib.c b/bluetooth/ble_pointer/mpu6050_i2c_lib.c similarity index 100% rename from pico_w/bt/standalone/ble_pointer/mpu6050_i2c_lib.c rename to bluetooth/ble_pointer/mpu6050_i2c_lib.c diff --git a/pico_w/bt/standalone/ble_pointer/mpu6050_i2c_lib.h b/bluetooth/ble_pointer/mpu6050_i2c_lib.h similarity index 100% rename from pico_w/bt/standalone/ble_pointer/mpu6050_i2c_lib.h rename to bluetooth/ble_pointer/mpu6050_i2c_lib.h diff --git a/pico_w/bt/standalone/doorbell/CMakeLists.txt b/bluetooth/doorbell/CMakeLists.txt similarity index 100% rename from pico_w/bt/standalone/doorbell/CMakeLists.txt rename to bluetooth/doorbell/CMakeLists.txt diff --git a/pico_w/bt/standalone/doorbell/README.md b/bluetooth/doorbell/README.md similarity index 100% rename from pico_w/bt/standalone/doorbell/README.md rename to bluetooth/doorbell/README.md diff --git a/pico_w/bt/standalone/doorbell/btstack_config.h b/bluetooth/doorbell/btstack_config.h similarity index 100% rename from pico_w/bt/standalone/doorbell/btstack_config.h rename to bluetooth/doorbell/btstack_config.h diff --git a/pico_w/bt/standalone/doorbell/client.c b/bluetooth/doorbell/client.c similarity index 100% rename from pico_w/bt/standalone/doorbell/client.c rename to bluetooth/doorbell/client.c diff --git a/pico_w/bt/standalone/doorbell/doorbell.fzz b/bluetooth/doorbell/doorbell.fzz similarity index 100% rename from pico_w/bt/standalone/doorbell/doorbell.fzz rename to bluetooth/doorbell/doorbell.fzz diff --git a/pico_w/bt/standalone/doorbell/doorbell.gatt b/bluetooth/doorbell/doorbell.gatt similarity index 100% rename from pico_w/bt/standalone/doorbell/doorbell.gatt rename to bluetooth/doorbell/doorbell.gatt diff --git a/pico_w/bt/standalone/doorbell/doorbell_bb.png b/bluetooth/doorbell/doorbell_bb.png similarity index 100% rename from pico_w/bt/standalone/doorbell/doorbell_bb.png rename to bluetooth/doorbell/doorbell_bb.png diff --git a/pico_w/bt/standalone/doorbell/server.c b/bluetooth/doorbell/server.c similarity index 100% rename from pico_w/bt/standalone/doorbell/server.c rename to bluetooth/doorbell/server.c diff --git a/pico_w/bt/standalone/secure_temp_sensor/CMakeLists.txt b/bluetooth/secure_temp_sensor/CMakeLists.txt similarity index 100% rename from pico_w/bt/standalone/secure_temp_sensor/CMakeLists.txt rename to bluetooth/secure_temp_sensor/CMakeLists.txt diff --git a/pico_w/bt/standalone/secure_temp_sensor/README.md b/bluetooth/secure_temp_sensor/README.md similarity index 100% rename from pico_w/bt/standalone/secure_temp_sensor/README.md rename to bluetooth/secure_temp_sensor/README.md diff --git a/pico_w/bt/standalone/secure_temp_sensor/btstack_config.h b/bluetooth/secure_temp_sensor/btstack_config.h similarity index 100% rename from pico_w/bt/standalone/secure_temp_sensor/btstack_config.h rename to bluetooth/secure_temp_sensor/btstack_config.h diff --git a/pico_w/bt/standalone/secure_temp_sensor/client.c b/bluetooth/secure_temp_sensor/client.c similarity index 100% rename from pico_w/bt/standalone/secure_temp_sensor/client.c rename to bluetooth/secure_temp_sensor/client.c diff --git a/pico_w/bt/standalone/secure_temp_sensor/server.c b/bluetooth/secure_temp_sensor/server.c similarity index 100% rename from pico_w/bt/standalone/secure_temp_sensor/server.c rename to bluetooth/secure_temp_sensor/server.c diff --git a/pico_w/bt/standalone/secure_temp_sensor/temp_sensor.gatt b/bluetooth/secure_temp_sensor/temp_sensor.gatt similarity index 100% rename from pico_w/bt/standalone/secure_temp_sensor/temp_sensor.gatt rename to bluetooth/secure_temp_sensor/temp_sensor.gatt diff --git a/pico_w/bt/standalone/temp_sensor/CMakeLists.txt b/bluetooth/temp_sensor/CMakeLists.txt similarity index 100% rename from pico_w/bt/standalone/temp_sensor/CMakeLists.txt rename to bluetooth/temp_sensor/CMakeLists.txt diff --git a/pico_w/bt/standalone/temp_sensor/README.md b/bluetooth/temp_sensor/README.md similarity index 100% rename from pico_w/bt/standalone/temp_sensor/README.md rename to bluetooth/temp_sensor/README.md diff --git a/pico_w/bt/standalone/temp_sensor/client/CMakeLists.txt b/bluetooth/temp_sensor/client/CMakeLists.txt similarity index 100% rename from pico_w/bt/standalone/temp_sensor/client/CMakeLists.txt rename to bluetooth/temp_sensor/client/CMakeLists.txt diff --git a/pico_w/bt/standalone/temp_sensor/client/btstack_config.h b/bluetooth/temp_sensor/client/btstack_config.h similarity index 100% rename from pico_w/bt/standalone/temp_sensor/client/btstack_config.h rename to bluetooth/temp_sensor/client/btstack_config.h diff --git a/pico_w/bt/standalone/temp_sensor/client/client.c b/bluetooth/temp_sensor/client/client.c similarity index 100% rename from pico_w/bt/standalone/temp_sensor/client/client.c rename to bluetooth/temp_sensor/client/client.c diff --git a/pico_w/bt/standalone/temp_sensor/server/CMakeLists.txt b/bluetooth/temp_sensor/server/CMakeLists.txt similarity index 100% rename from pico_w/bt/standalone/temp_sensor/server/CMakeLists.txt rename to bluetooth/temp_sensor/server/CMakeLists.txt diff --git a/pico_w/bt/standalone/temp_sensor/server/btstack_config.h b/bluetooth/temp_sensor/server/btstack_config.h similarity index 100% rename from pico_w/bt/standalone/temp_sensor/server/btstack_config.h rename to bluetooth/temp_sensor/server/btstack_config.h diff --git a/pico_w/bt/standalone/temp_sensor/server/server.c b/bluetooth/temp_sensor/server/server.c similarity index 100% rename from pico_w/bt/standalone/temp_sensor/server/server.c rename to bluetooth/temp_sensor/server/server.c diff --git a/pico_w/bt/standalone/temp_sensor/server/temp_sensor.gatt b/bluetooth/temp_sensor/server/temp_sensor.gatt similarity index 100% rename from pico_w/bt/standalone/temp_sensor/server/temp_sensor.gatt rename to bluetooth/temp_sensor/server/temp_sensor.gatt diff --git a/pico_w/bt/standalone/wifi_provisioner/CMakeLists.txt b/bluetooth/wifi_provisioner/CMakeLists.txt similarity index 100% rename from pico_w/bt/standalone/wifi_provisioner/CMakeLists.txt rename to bluetooth/wifi_provisioner/CMakeLists.txt diff --git a/pico_w/bt/standalone/wifi_provisioner/README.md b/bluetooth/wifi_provisioner/README.md similarity index 100% rename from pico_w/bt/standalone/wifi_provisioner/README.md rename to bluetooth/wifi_provisioner/README.md diff --git a/pico_w/bt/standalone/wifi_provisioner/btstack_config.h b/bluetooth/wifi_provisioner/btstack_config.h similarity index 100% rename from pico_w/bt/standalone/wifi_provisioner/btstack_config.h rename to bluetooth/wifi_provisioner/btstack_config.h diff --git a/pico_w/bt/standalone/wifi_provisioner/example.c b/bluetooth/wifi_provisioner/example.c similarity index 100% rename from pico_w/bt/standalone/wifi_provisioner/example.c rename to bluetooth/wifi_provisioner/example.c diff --git a/pico_w/bt/standalone/wifi_provisioner/lwipopts.h b/bluetooth/wifi_provisioner/lwipopts.h similarity index 100% rename from pico_w/bt/standalone/wifi_provisioner/lwipopts.h rename to bluetooth/wifi_provisioner/lwipopts.h diff --git a/pico_w/bt/standalone/wifi_provisioner/provisioning.gatt b/bluetooth/wifi_provisioner/provisioning.gatt similarity index 100% rename from pico_w/bt/standalone/wifi_provisioner/provisioning.gatt rename to bluetooth/wifi_provisioner/provisioning.gatt diff --git a/pico_w/bt/standalone/wifi_provisioner/set_credentials.py b/bluetooth/wifi_provisioner/set_credentials.py similarity index 100% rename from pico_w/bt/standalone/wifi_provisioner/set_credentials.py rename to bluetooth/wifi_provisioner/set_credentials.py diff --git a/pico_w/bt/standalone/wifi_provisioner/wifi_prov_lib.c b/bluetooth/wifi_provisioner/wifi_prov_lib.c similarity index 100% rename from pico_w/bt/standalone/wifi_provisioner/wifi_prov_lib.c rename to bluetooth/wifi_provisioner/wifi_prov_lib.c diff --git a/pico_w/bt/standalone/wifi_provisioner/wifi_prov_lib.h b/bluetooth/wifi_provisioner/wifi_prov_lib.h similarity index 100% rename from pico_w/bt/standalone/wifi_provisioner/wifi_prov_lib.h rename to bluetooth/wifi_provisioner/wifi_prov_lib.h diff --git a/pico_w/bt/standalone/CMakeLists.txt b/pico_w/bt/standalone/CMakeLists.txt deleted file mode 100644 index 19eea4404..000000000 --- a/pico_w/bt/standalone/CMakeLists.txt +++ /dev/null @@ -1,6 +0,0 @@ -add_subdirectory(secure_temp_sensor) -add_subdirectory(doorbell) -add_subdirectory(wifi_provisioner) -add_subdirectory(ble_pointer) -add_subdirectory(temp_sensor) - diff --git a/pico_w/bt/standalone/btstack_config_common.h b/pico_w/bt/standalone/btstack_config_common.h deleted file mode 100644 index 336e547fe..000000000 --- a/pico_w/bt/standalone/btstack_config_common.h +++ /dev/null @@ -1,58 +0,0 @@ -#ifndef _PICO_BTSTACK_CONFIG_COMMON_H -#define _PICO_BTSTACK_CONFIG_COMMON_H - -#ifndef ENABLE_BLE -#error Please link to pico_btstack_ble -#endif - -// BTstack features that can be enabled -#define ENABLE_LE_PERIPHERAL -#define ENABLE_LOG_INFO -#define ENABLE_LOG_ERROR -#define ENABLE_PRINTF_HEXDUMP - -// for the client -#if RUNNING_AS_CLIENT -#define ENABLE_LE_CENTRAL -#define MAX_NR_GATT_CLIENTS 1 -#else -#define MAX_NR_GATT_CLIENTS 0 -#endif - -// BTstack configuration. buffers, sizes, ... -#define HCI_OUTGOING_PRE_BUFFER_SIZE 4 -#define HCI_ACL_PAYLOAD_SIZE (255 + 4) -#define HCI_ACL_CHUNK_SIZE_ALIGNMENT 4 -#define MAX_NR_HCI_CONNECTIONS 1 -#define MAX_NR_SM_LOOKUP_ENTRIES 3 -#define MAX_NR_WHITELIST_ENTRIES 16 -#define MAX_NR_LE_DEVICE_DB_ENTRIES 16 - -// Limit number of ACL/SCO Buffer to use by stack to avoid cyw43 shared bus overrun -#define MAX_NR_CONTROLLER_ACL_BUFFERS 3 -#define MAX_NR_CONTROLLER_SCO_PACKETS 3 - -// Enable and configure HCI Controller to Host Flow Control to avoid cyw43 shared bus overrun -#define ENABLE_HCI_CONTROLLER_TO_HOST_FLOW_CONTROL -#define HCI_HOST_ACL_PACKET_LEN (255+4) -#define HCI_HOST_ACL_PACKET_NUM 3 -#define HCI_HOST_SCO_PACKET_LEN 120 -#define HCI_HOST_SCO_PACKET_NUM 3 - -// Link Key DB and LE Device DB using TLV on top of Flash Sector interface -#define NVM_NUM_DEVICE_DB_ENTRIES 16 -#define NVM_NUM_LINK_KEYS 16 - -// We don't give btstack a malloc, so use a fixed-size ATT DB. -#define MAX_ATT_DB_SIZE 512 - -// BTstack HAL configuration -#define HAVE_EMBEDDED_TIME_MS -// map btstack_assert onto Pico SDK assert() -#define HAVE_ASSERT -// Some USB dongles take longer to respond to HCI reset (e.g. BCM20702A). -#define HCI_RESET_RESEND_TIMEOUT_MS 1000 -#define ENABLE_SOFTWARE_AES128 -#define ENABLE_MICRO_ECC_FOR_LE_SECURE_CONNECTIONS - -#endif // MICROPY_INCLUDED_EXTMOD_BTSTACK_BTSTACK_CONFIG_H From c5b8dd59d5989cea17f02db559f137a22fc329db Mon Sep 17 00:00:00 2001 From: Peter Harper Date: Wed, 11 Mar 2026 11:17:30 +0000 Subject: [PATCH 04/13] Move BT readme --- bluetooth/README.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 bluetooth/README.md diff --git a/bluetooth/README.md b/bluetooth/README.md new file mode 100644 index 000000000..5e39b09d9 --- /dev/null +++ b/bluetooth/README.md @@ -0,0 +1,22 @@ +# Pico Bluetooth Examples + +The source for most of the Bluetooth examples is stored in `pico-sdk/lib/btstack/example`. +There's a standalone example in `pico-examples/pico_w/bt/standalone`. + +## Debugging + +To debug Bluetooth issues you can enable [btstack](https://github.com/bluekitchen/btstack) debug output which also enables packet logging. +Define `WANT_HCI_DUMP=1` in your CMakeLists.txt file. Uncomment this line to enable debug in the btstack examples. + + target_compile_definitions(picow_bt_example_common INTERFACE + #WANT_HCI_DUMP=1 # This enables btstack debug + ) + +## Packet logging + +To view packet logs, save the output from the debug port (e.g. the uart) to a file and afterwards run `pico-sdk/lib/btstack/tool/create_packet_log.py `. +This will generate a file with the same name except for a `pklg` extension. This can be opened in the [Wireshark](https://www.wireshark.org) application to analyze communications activity. + +## Link keys + +By default, the last two sectors of flash are used to store Bluetooth link keys and this relies on the Bluetooth address. Old pre-release versions of the SDK had issues with some devices using a default Bluetooth address. If you experience issues with pairing try Resetting flash memory, see https://www.raspberrypi.com/documentation/microcontrollers/raspberry-pi-pico.html#resetting-flash-memory From c899377cd2d9eb4a893b85c4c2dab5460c7c4574 Mon Sep 17 00:00:00 2001 From: Peter Harper Date: Wed, 11 Mar 2026 11:05:19 +0000 Subject: [PATCH 05/13] Add new BT examples --- bluetooth/CMakeLists.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/bluetooth/CMakeLists.txt b/bluetooth/CMakeLists.txt index bb3401035..eabbfe7e4 100644 --- a/bluetooth/CMakeLists.txt +++ b/bluetooth/CMakeLists.txt @@ -16,4 +16,9 @@ if (NOT TARGET pico_btstack_base) message("Skipping Pico Bluetooth examples as support is not available") else() add_subdirectory(btstack_examples) + add_subdirectory(secure_temp_sensor) + add_subdirectory(doorbell) + add_subdirectory(wifi_provisioner) + add_subdirectory(ble_pointer) + add_subdirectory(temp_sensor) endif() From af0af019c5f330d40ccb3402b5f9c19079d7a6dc Mon Sep 17 00:00:00 2001 From: Peter Harper Date: Wed, 11 Mar 2026 11:05:01 +0000 Subject: [PATCH 06/13] Remove pico_w/bt folder --- pico_w/CMakeLists.txt | 5 - pico_w/bt/CMakeLists.txt | 397 ------------------ pico_w/bt/FreeRTOS_Kernel_import.cmake | 91 ---- pico_w/bt/README.md | 22 - pico_w/bt/a2dp_sink_demo/CMakeLists.txt | 7 - pico_w/bt/a2dp_source_demo/CMakeLists.txt | 1 - pico_w/bt/ancs_client_demo/CMakeLists.txt | 1 - pico_w/bt/att_delayed_response/CMakeLists.txt | 1 - .../bt/avrcp_browsing_client/CMakeLists.txt | 1 - pico_w/bt/btstack_audio_pico.c | 209 --------- pico_w/bt/config/FreeRTOSConfig.h | 156 ------- pico_w/bt/config/btstack_config.h | 89 ---- pico_w/bt/config/lwipopts.h | 21 - pico_w/bt/dut_mode_classic/CMakeLists.txt | 1 - .../bt/gap_dedicated_bonding/CMakeLists.txt | 1 - pico_w/bt/gap_inquiry/CMakeLists.txt | 1 - .../bt/gap_le_advertisements/CMakeLists.txt | 1 - pico_w/bt/gap_link_keys/CMakeLists.txt | 1 - pico_w/bt/gatt_battery_query/CMakeLists.txt | 1 - pico_w/bt/gatt_browser/CMakeLists.txt | 1 - pico_w/bt/gatt_counter/CMakeLists.txt | 1 - .../bt/gatt_counter_with_wifi/CMakeLists.txt | 6 - .../CMakeLists.txt | 1 - .../bt/gatt_heart_rate_client/CMakeLists.txt | 1 - pico_w/bt/gatt_streamer_server/CMakeLists.txt | 1 - .../CMakeLists.txt | 6 - pico_w/bt/hfp_ag_demo/CMakeLists.txt | 1 - pico_w/bt/hfp_hf_demo/CMakeLists.txt | 6 - pico_w/bt/hid_host_demo/CMakeLists.txt | 1 - pico_w/bt/hid_keyboard_demo/CMakeLists.txt | 1 - pico_w/bt/hid_mouse_demo/CMakeLists.txt | 1 - pico_w/bt/hog_boot_host_demo/CMakeLists.txt | 1 - pico_w/bt/hog_host_demo/CMakeLists.txt | 1 - pico_w/bt/hog_keyboard_demo/CMakeLists.txt | 1 - pico_w/bt/hog_mouse_demo/CMakeLists.txt | 1 - pico_w/bt/hsp_ag_demo/CMakeLists.txt | 1 - pico_w/bt/hsp_hs_demo/CMakeLists.txt | 1 - .../CMakeLists.txt | 1 - .../CMakeLists.txt | 1 - pico_w/bt/le_mitm/CMakeLists.txt | 1 - pico_w/bt/le_streamer_client/CMakeLists.txt | 1 - pico_w/bt/led_counter/CMakeLists.txt | 1 - pico_w/bt/mod_player/CMakeLists.txt | 6 - .../bt/nordic_spp_le_counter/CMakeLists.txt | 1 - .../bt/nordic_spp_le_streamer/CMakeLists.txt | 1 - pico_w/bt/pan_lwip_http_server/CMakeLists.txt | 13 - pico_w/bt/pbap_client_demo/CMakeLists.txt | 1 - pico_w/bt/picow_bt_example_background.c | 21 - pico_w/bt/picow_bt_example_common.c | 103 ----- pico_w/bt/picow_bt_example_common.h | 18 - pico_w/bt/picow_bt_example_freertos.c | 109 ----- pico_w/bt/picow_bt_example_poll.c | 21 - pico_w/bt/sdp_bnep_query/CMakeLists.txt | 1 - pico_w/bt/sdp_general_query/CMakeLists.txt | 1 - pico_w/bt/sdp_rfcomm_query/CMakeLists.txt | 1 - pico_w/bt/sine_player/CMakeLists.txt | 6 - pico_w/bt/sm_pairing_central/CMakeLists.txt | 1 - .../bt/sm_pairing_peripheral/CMakeLists.txt | 1 - pico_w/bt/spp_and_gatt_counter/CMakeLists.txt | 1 - .../bt/spp_and_gatt_streamer/CMakeLists.txt | 1 - pico_w/bt/spp_counter/CMakeLists.txt | 1 - pico_w/bt/spp_flowcontrol/CMakeLists.txt | 1 - pico_w/bt/spp_streamer/CMakeLists.txt | 1 - pico_w/bt/spp_streamer_client/CMakeLists.txt | 1 - .../bt/spp_streamer_with_wifi/CMakeLists.txt | 6 - pico_w/bt/ublox_spp_le_counter/CMakeLists.txt | 1 - 66 files changed, 1363 deletions(-) delete mode 100644 pico_w/bt/CMakeLists.txt delete mode 100644 pico_w/bt/FreeRTOS_Kernel_import.cmake delete mode 100644 pico_w/bt/README.md delete mode 100644 pico_w/bt/a2dp_sink_demo/CMakeLists.txt delete mode 100644 pico_w/bt/a2dp_source_demo/CMakeLists.txt delete mode 100644 pico_w/bt/ancs_client_demo/CMakeLists.txt delete mode 100644 pico_w/bt/att_delayed_response/CMakeLists.txt delete mode 100644 pico_w/bt/avrcp_browsing_client/CMakeLists.txt delete mode 100644 pico_w/bt/btstack_audio_pico.c delete mode 100644 pico_w/bt/config/FreeRTOSConfig.h delete mode 100644 pico_w/bt/config/btstack_config.h delete mode 100644 pico_w/bt/config/lwipopts.h delete mode 100644 pico_w/bt/dut_mode_classic/CMakeLists.txt delete mode 100644 pico_w/bt/gap_dedicated_bonding/CMakeLists.txt delete mode 100644 pico_w/bt/gap_inquiry/CMakeLists.txt delete mode 100644 pico_w/bt/gap_le_advertisements/CMakeLists.txt delete mode 100644 pico_w/bt/gap_link_keys/CMakeLists.txt delete mode 100644 pico_w/bt/gatt_battery_query/CMakeLists.txt delete mode 100644 pico_w/bt/gatt_browser/CMakeLists.txt delete mode 100644 pico_w/bt/gatt_counter/CMakeLists.txt delete mode 100644 pico_w/bt/gatt_counter_with_wifi/CMakeLists.txt delete mode 100644 pico_w/bt/gatt_device_information_query/CMakeLists.txt delete mode 100644 pico_w/bt/gatt_heart_rate_client/CMakeLists.txt delete mode 100644 pico_w/bt/gatt_streamer_server/CMakeLists.txt delete mode 100644 pico_w/bt/gatt_streamer_server_with_wifi/CMakeLists.txt delete mode 100644 pico_w/bt/hfp_ag_demo/CMakeLists.txt delete mode 100644 pico_w/bt/hfp_hf_demo/CMakeLists.txt delete mode 100644 pico_w/bt/hid_host_demo/CMakeLists.txt delete mode 100644 pico_w/bt/hid_keyboard_demo/CMakeLists.txt delete mode 100644 pico_w/bt/hid_mouse_demo/CMakeLists.txt delete mode 100644 pico_w/bt/hog_boot_host_demo/CMakeLists.txt delete mode 100644 pico_w/bt/hog_host_demo/CMakeLists.txt delete mode 100644 pico_w/bt/hog_keyboard_demo/CMakeLists.txt delete mode 100644 pico_w/bt/hog_mouse_demo/CMakeLists.txt delete mode 100644 pico_w/bt/hsp_ag_demo/CMakeLists.txt delete mode 100644 pico_w/bt/hsp_hs_demo/CMakeLists.txt delete mode 100644 pico_w/bt/le_credit_based_flow_control_mode_client/CMakeLists.txt delete mode 100644 pico_w/bt/le_credit_based_flow_control_mode_server/CMakeLists.txt delete mode 100644 pico_w/bt/le_mitm/CMakeLists.txt delete mode 100644 pico_w/bt/le_streamer_client/CMakeLists.txt delete mode 100644 pico_w/bt/led_counter/CMakeLists.txt delete mode 100644 pico_w/bt/mod_player/CMakeLists.txt delete mode 100644 pico_w/bt/nordic_spp_le_counter/CMakeLists.txt delete mode 100644 pico_w/bt/nordic_spp_le_streamer/CMakeLists.txt delete mode 100644 pico_w/bt/pan_lwip_http_server/CMakeLists.txt delete mode 100644 pico_w/bt/pbap_client_demo/CMakeLists.txt delete mode 100644 pico_w/bt/picow_bt_example_background.c delete mode 100644 pico_w/bt/picow_bt_example_common.c delete mode 100644 pico_w/bt/picow_bt_example_common.h delete mode 100644 pico_w/bt/picow_bt_example_freertos.c delete mode 100644 pico_w/bt/picow_bt_example_poll.c delete mode 100644 pico_w/bt/sdp_bnep_query/CMakeLists.txt delete mode 100644 pico_w/bt/sdp_general_query/CMakeLists.txt delete mode 100644 pico_w/bt/sdp_rfcomm_query/CMakeLists.txt delete mode 100644 pico_w/bt/sine_player/CMakeLists.txt delete mode 100644 pico_w/bt/sm_pairing_central/CMakeLists.txt delete mode 100644 pico_w/bt/sm_pairing_peripheral/CMakeLists.txt delete mode 100644 pico_w/bt/spp_and_gatt_counter/CMakeLists.txt delete mode 100644 pico_w/bt/spp_and_gatt_streamer/CMakeLists.txt delete mode 100644 pico_w/bt/spp_counter/CMakeLists.txt delete mode 100644 pico_w/bt/spp_flowcontrol/CMakeLists.txt delete mode 100644 pico_w/bt/spp_streamer/CMakeLists.txt delete mode 100644 pico_w/bt/spp_streamer_client/CMakeLists.txt delete mode 100644 pico_w/bt/spp_streamer_with_wifi/CMakeLists.txt delete mode 100644 pico_w/bt/ublox_spp_le_counter/CMakeLists.txt diff --git a/pico_w/CMakeLists.txt b/pico_w/CMakeLists.txt index f66c02e95..69c01349a 100644 --- a/pico_w/CMakeLists.txt +++ b/pico_w/CMakeLists.txt @@ -19,10 +19,5 @@ if (PICO_CYW43_SUPPORTED) # set by PICO_BOARD=pico_w set(WIFI_PASSWORD "${WIFI_PASSWORD}" CACHE INTERNAL "WiFi password for examples") add_subdirectory(wifi) - if (NOT TARGET pico_btstack_base) - message("Skipping Pico W Bluetooth examples as support is not available") - else() - add_subdirectory(bt) - endif() endif() endif() diff --git a/pico_w/bt/CMakeLists.txt b/pico_w/bt/CMakeLists.txt deleted file mode 100644 index 7423f4898..000000000 --- a/pico_w/bt/CMakeLists.txt +++ /dev/null @@ -1,397 +0,0 @@ -add_subdirectory(standalone) - -set(BTSTACK_ROOT ${PICO_SDK_PATH}/lib/btstack) -set(BTSTACK_EXAMPLE_PATH ${BTSTACK_ROOT}/example) -set(BTSTACK_3RD_PARTY_PATH ${BTSTACK_ROOT}/3rd-party) -set(BT_EXAMPLE_COMMON_DIR "${CMAKE_CURRENT_LIST_DIR}") - -add_library(pico_btstack_audio_example INTERFACE) -target_sources(pico_btstack_audio_example INTERFACE - ${PICO_BTSTACK_PATH}/src/btstack_audio.c - ${PICO_BTSTACK_PATH}/src/btstack_audio_generator.c - ) -if (PICO_EXTRAS_PATH) - target_sources(pico_btstack_audio_example INTERFACE - ${CMAKE_CURRENT_LIST_DIR}/btstack_audio_pico.c - ) - target_link_libraries(pico_btstack_audio_example INTERFACE - pico_audio_i2s - ) -endif() - -# mod player used by a2dp_source_demo and mod_player and demo song -add_library(pico_btstack_hxcmod_player INTERFACE) -target_sources(pico_btstack_hxcmod_player INTERFACE - ${BTSTACK_3RD_PARTY_PATH}/hxcmod-player/hxcmod.c - ${BTSTACK_3RD_PARTY_PATH}/hxcmod-player/mods/mod.c - ) -target_include_directories(pico_btstack_hxcmod_player INTERFACE - ${BTSTACK_3RD_PARTY_PATH}/hxcmod-player - ${BTSTACK_3RD_PARTY_PATH}/hxcmod-player/mods - ) -if (PICO_EXTRAS_PATH) - target_compile_definitions(pico_btstack_hxcmod_player INTERFACE - ENABLE_MODPLAYER=1 - ) -endif() -add_library(pico_btstack_sco_demo_util INTERFACE) -target_sources(pico_btstack_sco_demo_util INTERFACE - # sco demo utils - ${BTSTACK_EXAMPLE_PATH}/sco_demo_util.c - ) - -# Adds common stuff for all the examples -add_library(picow_bt_example_common INTERFACE) -target_sources(picow_bt_example_common INTERFACE - ${CMAKE_CURRENT_LIST_DIR}/picow_bt_example_common.c - ) -target_link_libraries(picow_bt_example_common INTERFACE - pico_stdlib - pico_btstack_cyw43 - ) -target_include_directories(picow_bt_example_common INTERFACE - ${BT_EXAMPLE_COMMON_DIR}/config # Use our own config - ${BTSTACK_EXAMPLE_PATH}/ - ) -target_compile_definitions(picow_bt_example_common INTERFACE - PICO_STDIO_USB_CONNECT_WAIT_TIMEOUT_MS=3000 - #WANT_HCI_DUMP=1 # This enables btstack debug - #ENABLE_SEGGER_RTT=1 - ) -target_link_libraries(picow_bt_example_common INTERFACE - pico_btstack_audio_example - ) -if (PICO_EXTRAS_PATH) - target_compile_definitions(picow_bt_example_common INTERFACE - TEST_AUDIO=1 - ) -endif() - -# Adds stuff needed for cyw43 lwip -add_library(picow_bt_example_cyw43_lwip INTERFACE) -target_link_libraries(picow_bt_example_cyw43_lwip INTERFACE - picow_bt_example_common - ) -target_compile_definitions(picow_bt_example_cyw43_lwip INTERFACE - WIFI_SSID=\"${WIFI_SSID}\" - WIFI_PASSWORD=\"${WIFI_PASSWORD}\" - CYW43_LWIP=1 - ) -target_link_libraries(picow_bt_example_cyw43_lwip INTERFACE - pico_lwip_iperf - ) -target_include_directories(picow_bt_example_cyw43_lwip INTERFACE - ${CMAKE_CURRENT_LIST_DIR}/../wifi # for our common lwipopts - ) - -# disables cyw43 lwip -add_library(picow_bt_example_no_cyw43_lwip INTERFACE) -target_link_libraries(picow_bt_example_no_cyw43_lwip INTERFACE - picow_bt_example_common - ) -target_compile_definitions(picow_bt_example_no_cyw43_lwip INTERFACE - CYW43_LWIP=0 - ) - -# variant: no cyw43 lwip | poll -add_library(picow_bt_example_no_cyw43_lwip_poll INTERFACE) -target_sources(picow_bt_example_no_cyw43_lwip_poll INTERFACE - ${BT_EXAMPLE_COMMON_DIR}/picow_bt_example_poll.c - ) -target_link_libraries(picow_bt_example_no_cyw43_lwip_poll INTERFACE - picow_bt_example_no_cyw43_lwip - pico_cyw43_arch_poll - ) - -# variant: cyw43 lwip | poll -add_library(picow_bt_example_cyw43_lwip_poll INTERFACE) -target_sources(picow_bt_example_cyw43_lwip_poll INTERFACE - ${BT_EXAMPLE_COMMON_DIR}/picow_bt_example_poll.c - ) -target_link_libraries(picow_bt_example_cyw43_lwip_poll INTERFACE - picow_bt_example_cyw43_lwip - pico_cyw43_arch_lwip_poll - ) - -# variant: btstack lwip | poll -add_library(picow_bt_example_btstack_lwip_poll INTERFACE) -target_sources(picow_bt_example_btstack_lwip_poll INTERFACE - ${BT_EXAMPLE_COMMON_DIR}/picow_bt_example_poll.c - ) -target_link_libraries(picow_bt_example_btstack_lwip_poll INTERFACE - picow_bt_example_no_cyw43_lwip - pico_cyw43_arch_poll - pico_lwip_nosys - pico_btstack_bnep_lwip - ) -target_include_directories(picow_bt_example_btstack_lwip_poll INTERFACE - ${CMAKE_CURRENT_LIST_DIR}/../wifi # for our common lwipopts - ) - -# variant: no cyw43 lwip | background -add_library(picow_bt_example_no_cyw43_lwip_background INTERFACE) -target_sources(picow_bt_example_no_cyw43_lwip_background INTERFACE - ${BT_EXAMPLE_COMMON_DIR}/picow_bt_example_background.c - ) -target_link_libraries(picow_bt_example_no_cyw43_lwip_background INTERFACE - picow_bt_example_no_cyw43_lwip - pico_cyw43_arch_threadsafe_background - ) - -# variant: cyw43 lwip | background -add_library(picow_bt_example_cyw43_lwip_background INTERFACE) -target_sources(picow_bt_example_cyw43_lwip_background INTERFACE - ${BT_EXAMPLE_COMMON_DIR}/picow_bt_example_background.c - ) -target_link_libraries(picow_bt_example_cyw43_lwip_background INTERFACE - picow_bt_example_cyw43_lwip - pico_cyw43_arch_lwip_threadsafe_background - ) - -# variant: btstack lwip | background -add_library(picow_bt_example_btstack_lwip_background INTERFACE) -target_sources(picow_bt_example_btstack_lwip_background INTERFACE - ${BT_EXAMPLE_COMMON_DIR}/picow_bt_example_background.c - ) -target_link_libraries(picow_bt_example_btstack_lwip_background INTERFACE - picow_bt_example_no_cyw43_lwip - pico_cyw43_arch_threadsafe_background - pico_lwip_nosys - pico_btstack_bnep_lwip - ) -target_include_directories(picow_bt_example_btstack_lwip_background INTERFACE - ${CMAKE_CURRENT_LIST_DIR}/../wifi # for our common lwipopts - ) - -if (FREERTOS_KERNEL_PATH OR DEFINED ENV{FREERTOS_KERNEL_PATH}) -include(FreeRTOS_Kernel_import.cmake) -endif() - -if (TARGET FreeRTOS-Kernel) - # common freertos stuff - add_library(picow_bt_example_common_freertos INTERFACE) - target_sources(picow_bt_example_common_freertos INTERFACE - ${BT_EXAMPLE_COMMON_DIR}/picow_bt_example_freertos.c - ) - target_link_libraries(picow_bt_example_common_freertos INTERFACE - picow_bt_example_common - FreeRTOS-Kernel-Heap4 # FreeRTOS kernel and dynamic heap - ) - target_compile_definitions(picow_bt_example_common_freertos INTERFACE - CYW43_TASK_STACK_SIZE=1024 - NO_SYS=0 - ) - - # variant: no cyw43 lwip | freertos - add_library(picow_bt_example_no_cyw43_lwip_freertos INTERFACE) - target_link_libraries(picow_bt_example_no_cyw43_lwip_freertos INTERFACE - picow_bt_example_common_freertos - picow_bt_example_no_cyw43_lwip - pico_cyw43_arch_sys_freertos - ) - - # variant: cyw43 lwip | freertos - add_library(picow_bt_example_cyw43_lwip_freertos INTERFACE) - target_link_libraries(picow_bt_example_cyw43_lwip_freertos INTERFACE - picow_bt_example_common_freertos - picow_bt_example_cyw43_lwip - pico_cyw43_arch_lwip_sys_freertos - ) - target_compile_definitions(picow_bt_example_cyw43_lwip_freertos INTERFACE - HAVE_LWIP=1 # stops btstack calling lwip_init - ) - - # variant: btstack lwip | freertos - add_library(picow_bt_example_btstack_lwip_freertos INTERFACE) - target_link_libraries(picow_bt_example_btstack_lwip_freertos INTERFACE - picow_bt_example_common_freertos - picow_bt_example_no_cyw43_lwip - pico_cyw43_arch_sys_freertos - pico_btstack_bnep_lwip_sys_freertos - pico_lwip_freertos - ) - target_include_directories(picow_bt_example_btstack_lwip_freertos INTERFACE - ${CMAKE_CURRENT_LIST_DIR}/../wifi # for our common lwipopts - ) - target_compile_definitions(picow_bt_example_btstack_lwip_freertos INTERFACE - HAVE_LWIP=1 # stops btstack calling lwip_init - ) -endif() - -# Common stuff for all examples. Pass the example name -function(picow_bt_example_common NAME) - if (NOT TARGET picow_bt_example_common_${NAME}) - add_library(picow_bt_example_common_${NAME} INTERFACE) - target_sources(picow_bt_example_common_${NAME} INTERFACE - # actual example - ${BTSTACK_EXAMPLE_PATH}/${NAME}.c - ) - if (EXISTS "${BTSTACK_EXAMPLE_PATH}/${NAME}.gatt") - pico_btstack_make_gatt_header(picow_bt_example_common_${NAME} INTERFACE ${BTSTACK_EXAMPLE_PATH}/${NAME}.gatt) - endif() - endif() -endfunction() - -# The type of example to build -if(NOT DEFINED BTSTACK_EXAMPLE_TYPE) - set(BTSTACK_EXAMPLE_TYPE "background") -endif() -if ((NOT BTSTACK_EXAMPLE_TYPE STREQUAL "poll") AND - (NOT BTSTACK_EXAMPLE_TYPE STREQUAL "background") AND - (NOT BTSTACK_EXAMPLE_TYPE STREQUAL "freertos") AND - (NOT BTSTACK_EXAMPLE_TYPE STREQUAL "all")) - message(FATAL_ERROR "Unknown BTSTACK_EXAMPLE_TYPE '${BTSTACK_EXAMPLE_TYPE}'; valid options are 'poll', 'background', 'freertos' or 'all'") -endif() -set(BTSTACK_EXAMPLE_TYPE "${BTSTACK_EXAMPLE_TYPE}" CACHE INTERNAL "BT stack example type (poll|background|freertos|all)") - -# Add an poll example, pass btstack example name, target name, variant lib and extra libs -function(picow_bt_example_poll NAME TARGET_NAME VARIANT_LIB) - if ("${BTSTACK_EXAMPLE_TYPE}" STREQUAL "poll" OR "${BTSTACK_EXAMPLE_TYPE}" STREQUAL "all") - picow_bt_example_common(${NAME}) - add_executable(${TARGET_NAME}_poll) - target_link_libraries(${TARGET_NAME}_poll PRIVATE - picow_bt_example_common_${NAME} - ${VARIANT_LIB} - ${ARGN} # extra libs - ) - pico_add_extra_outputs(${TARGET_NAME}_poll) - example_auto_set_url(${TARGET_NAME}_poll) - endif() -endfunction() - -# Add an background example, pass btstack example name, target name, variant lib and extra libs -function(picow_bt_example_background NAME TARGET_NAME VARIANT_LIB) - if ("${BTSTACK_EXAMPLE_TYPE}" STREQUAL "background" OR "${BTSTACK_EXAMPLE_TYPE}" STREQUAL "all") - picow_bt_example_common(${NAME}) - add_executable(${TARGET_NAME}_background) - target_link_libraries(${TARGET_NAME}_background PRIVATE - picow_bt_example_common_${NAME} - ${VARIANT_LIB} - ${ARGN} # extra libs - ) - pico_add_extra_outputs(${TARGET_NAME}_background) - example_auto_set_url(${TARGET_NAME}_background) - endif() -endfunction() - -# Add a freertos example, pass btstack example name, target name, variant lib and extra libs -function(picow_bt_example_freertos NAME TARGET_NAME VARIANT_LIB) - if ("${BTSTACK_EXAMPLE_TYPE}" STREQUAL "freertos" OR "${BTSTACK_EXAMPLE_TYPE}" STREQUAL "all") - if (TARGET FreeRTOS-Kernel) - picow_bt_example_common(${NAME}) - add_executable(${TARGET_NAME}_freertos) - target_link_libraries(${TARGET_NAME}_freertos PRIVATE - picow_bt_example_common_${NAME} - ${VARIANT_LIB} - ${ARGN} # extra libs - ) - pico_add_extra_outputs(${TARGET_NAME}_freertos) - example_auto_set_url(${TARGET_NAME}_freertos) - endif() - endif() -endfunction() - -# The default name of the bt example target -function(picow_bt_example_target_name NAME RET) - SET(${RET} "picow_bt_example_${NAME}" PARENT_SCOPE) -endfunction() - -# Make a btstack example, NAME should match source file in lib/btstack/example -# Extra parameters indicate extra libraries to link to -function(picow_bt_example NAME) - picow_bt_example_target_name(${NAME} TARGET_NAME) - picow_bt_example_poll(${NAME} ${TARGET_NAME} picow_bt_example_no_cyw43_lwip_poll pico_btstack_ble pico_btstack_classic ${ARGN}) - picow_bt_example_background(${NAME} ${TARGET_NAME} picow_bt_example_no_cyw43_lwip_background pico_btstack_ble pico_btstack_classic ${ARGN}) - picow_bt_example_freertos(${NAME} ${TARGET_NAME} picow_bt_example_no_cyw43_lwip_freertos pico_btstack_ble pico_btstack_classic ${ARGN}) -endfunction() - -# List of examples from btstack -include(${BTSTACK_ROOT}/example/CMakeLists.txt) - -# Full list of bluetooth examples -set(BTSTACK_EXAMPLES - ${EXAMPLES_GENERAL} - ${EXAMPLES_CLASSIC_ONLY} - ${EXAMPLES_LE_ONLY} - ${EXAMPLES_DUAL_MODE} - pan_lwip_http_server -) - -# These examples run wifi and bt at the same time -if (WIFI_SSID AND WIFI_PASSWORD) - list(APPEND BTSTACK_EXAMPLES - gatt_counter_with_wifi - gatt_streamer_server_with_wifi - #spp_streamer_with_wifi - ) -endif() - -# Extra examples that are not that interesting or a bit tricky to run -# They are not built unless BTSTACK_EXAMPLES_ALL=1 -set(BTSTACK_EXAMPLES_ADDITIONAL - ancs_client_demo - att_delayed_response - avrcp_browsing_client - dut_mode_classic - gap_dedicated_bonding - gap_link_keys - le_credit_based_flow_control_mode_client - le_credit_based_flow_control_mode_server - le_mitm - led_counter - sdp_bnep_query - sdp_general_query - spp_flowcontrol - sdp_rfcomm_query - spp_and_gatt_counter - spp_and_gatt_streamer - hfp_ag_demo - hsp_ag_demo - hfp_hf_demo - hsp_hs_demo - mod_player - sine_player - ublox_spp_le_counter - nordic_spp_le_streamer - nordic_spp_le_counter - hog_boot_host_demo - gatt_battery_query - gatt_browser - gatt_device_information_query - le_streamer_client -) - -# These examples will only be built if pico-extras exists -set(BTSTACK_EXAMPLES_NEED_EXTRAS - a2dp_sink_demo - hfp_hf_demo - hfp_ag_demo - hsp_ag_demo - hsp_hs_demo - mod_player - sine_player -) - -# Add examples -set(BTSTACK_EXAMPLE_COUNT 0) -list(REMOVE_DUPLICATES BTSTACK_EXAMPLES) -foreach(NAME ${BTSTACK_EXAMPLES}) - # Ignore if sub folder not found - if (NOT IS_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/${NAME}) - continue() - endif() - # Ignore example if it needs pico-extras and pico-extras could not be found - if (NOT PICO_EXTRAS_PATH AND ${NAME} IN_LIST BTSTACK_EXAMPLES_NEED_EXTRAS) - continue() - endif() - # Ignore less interesting examples if BTSTACK_EXAMPLES_ALL=1 is not set - if (NOT BTSTACK_EXAMPLES_ALL AND ${NAME} IN_LIST BTSTACK_EXAMPLES_ADDITIONAL) - continue() - endif() - # add example - add_subdirectory_exclude_platforms(${NAME}) - MATH(EXPR BTSTACK_EXAMPLE_COUNT "${BTSTACK_EXAMPLE_COUNT}+1") -endforeach() -message("Adding ${BTSTACK_EXAMPLE_COUNT} BTstack examples of type '${BTSTACK_EXAMPLE_TYPE}'") - -suppress_btstack_warnings() diff --git a/pico_w/bt/FreeRTOS_Kernel_import.cmake b/pico_w/bt/FreeRTOS_Kernel_import.cmake deleted file mode 100644 index 15d8e7724..000000000 --- a/pico_w/bt/FreeRTOS_Kernel_import.cmake +++ /dev/null @@ -1,91 +0,0 @@ -# This is a copy of /portable/ThirdParty/GCC/RP2040/FREERTOS_KERNEL_import.cmake - -# This can be dropped into an external project to help locate the FreeRTOS kernel -# It should be include()ed prior to project(). Alternatively this file may -# or the CMakeLists.txt in this directory may be included or added via add_subdirectory -# respectively. - -if (DEFINED ENV{FREERTOS_KERNEL_PATH} AND (NOT FREERTOS_KERNEL_PATH)) - set(FREERTOS_KERNEL_PATH $ENV{FREERTOS_KERNEL_PATH}) - message("Using FREERTOS_KERNEL_PATH from environment ('${FREERTOS_KERNEL_PATH}')") -endif () - -# first pass we look in old tree; second pass we look in new tree -foreach(SEARCH_PASS RANGE 0 1) - if (SEARCH_PASS) - # ports may be moving to submodule in the future - set(FREERTOS_KERNEL_RP2040_RELATIVE_PATH "portable/ThirdParty/Community-Supported-Ports/GCC") - set(FREERTOS_KERNEL_RP2040_BACK_PATH "../../../../..") - else() - set(FREERTOS_KERNEL_RP2040_RELATIVE_PATH "portable/ThirdParty/GCC") - set(FREERTOS_KERNEL_RP2040_BACK_PATH "../../../..") - endif() - - if(PICO_PLATFORM STREQUAL "rp2040") - set(FREERTOS_KERNEL_RP2040_RELATIVE_PATH "${FREERTOS_KERNEL_RP2040_RELATIVE_PATH}/RP2040") - else() - if (PICO_PLATFORM STREQUAL "rp2350-riscv") - set(FREERTOS_KERNEL_RP2040_RELATIVE_PATH "${FREERTOS_KERNEL_RP2040_RELATIVE_PATH}/RP2350_RISC-V") - else() - set(FREERTOS_KERNEL_RP2040_RELATIVE_PATH "${FREERTOS_KERNEL_RP2040_RELATIVE_PATH}/RP2350_ARM_NTZ") - endif() - endif() - - if (NOT FREERTOS_KERNEL_PATH) - # check if we are inside the FreeRTOS kernel tree (i.e. this file has been included directly) - get_filename_component(_ACTUAL_PATH ${CMAKE_CURRENT_LIST_DIR} REALPATH) - get_filename_component(_POSSIBLE_PATH ${CMAKE_CURRENT_LIST_DIR}/${FREERTOS_KERNEL_RP2040_BACK_PATH}/${FREERTOS_KERNEL_RP2040_RELATIVE_PATH} REALPATH) - if (_ACTUAL_PATH STREQUAL _POSSIBLE_PATH) - get_filename_component(FREERTOS_KERNEL_PATH ${CMAKE_CURRENT_LIST_DIR}/${FREERTOS_KERNEL_RP2040_BACK_PATH} REALPATH) - endif() - if (_ACTUAL_PATH STREQUAL _POSSIBLE_PATH) - get_filename_component(FREERTOS_KERNEL_PATH ${CMAKE_CURRENT_LIST_DIR}/${FREERTOS_KERNEL_RP2040_BACK_PATH} REALPATH) - message("Setting FREERTOS_KERNEL_PATH to ${FREERTOS_KERNEL_PATH} based on location of FreeRTOS-Kernel-import.cmake") - break() - elseif (PICO_SDK_PATH AND EXISTS "${PICO_SDK_PATH}/../FreeRTOS-Kernel") - set(FREERTOS_KERNEL_PATH ${PICO_SDK_PATH}/../FreeRTOS-Kernel) - message("Defaulting FREERTOS_KERNEL_PATH as sibling of PICO_SDK_PATH: ${FREERTOS_KERNEL_PATH}") - break() - endif() - endif () - - if (NOT FREERTOS_KERNEL_PATH) - foreach(POSSIBLE_SUFFIX Source FreeRTOS-Kernel FreeRTOS/Source) - # check if FreeRTOS-Kernel exists under directory that included us - set(SEARCH_ROOT ${CMAKE_CURRENT_SOURCE_DIR}) - get_filename_component(_POSSIBLE_PATH ${SEARCH_ROOT}/${POSSIBLE_SUFFIX} REALPATH) - if (EXISTS ${_POSSIBLE_PATH}/${FREERTOS_KERNEL_RP2040_RELATIVE_PATH}/CMakeLists.txt) - get_filename_component(FREERTOS_KERNEL_PATH ${_POSSIBLE_PATH} REALPATH) - message("Setting FREERTOS_KERNEL_PATH to '${FREERTOS_KERNEL_PATH}' found relative to enclosing project") - break() - endif() - endforeach() - if (FREERTOS_KERNEL_PATH) - break() - endif() - endif() - - # user must have specified - if (FREERTOS_KERNEL_PATH) - if (EXISTS "${FREERTOS_KERNEL_PATH}/${FREERTOS_KERNEL_RP2040_RELATIVE_PATH}") - break() - endif() - endif() -endforeach () - -if (NOT FREERTOS_KERNEL_PATH) - message(FATAL_ERROR "FreeRTOS location was not specified. Please set FREERTOS_KERNEL_PATH.") -endif() - -set(FREERTOS_KERNEL_PATH "${FREERTOS_KERNEL_PATH}" CACHE PATH "Path to the FreeRTOS Kernel") - -get_filename_component(FREERTOS_KERNEL_PATH "${FREERTOS_KERNEL_PATH}" REALPATH BASE_DIR "${CMAKE_BINARY_DIR}") -if (NOT EXISTS ${FREERTOS_KERNEL_PATH}) - message(FATAL_ERROR "Directory '${FREERTOS_KERNEL_PATH}' not found") -endif() -if (NOT EXISTS ${FREERTOS_KERNEL_PATH}/${FREERTOS_KERNEL_RP2040_RELATIVE_PATH}/CMakeLists.txt) - message(FATAL_ERROR "Directory '${FREERTOS_KERNEL_PATH}' does not contain a '${PICO_PLATFORM}' port here: ${FREERTOS_KERNEL_RP2040_RELATIVE_PATH}") -endif() -set(FREERTOS_KERNEL_PATH ${FREERTOS_KERNEL_PATH} CACHE PATH "Path to the FreeRTOS_KERNEL" FORCE) - -add_subdirectory(${FREERTOS_KERNEL_PATH}/${FREERTOS_KERNEL_RP2040_RELATIVE_PATH} FREERTOS_KERNEL) diff --git a/pico_w/bt/README.md b/pico_w/bt/README.md deleted file mode 100644 index 5e39b09d9..000000000 --- a/pico_w/bt/README.md +++ /dev/null @@ -1,22 +0,0 @@ -# Pico Bluetooth Examples - -The source for most of the Bluetooth examples is stored in `pico-sdk/lib/btstack/example`. -There's a standalone example in `pico-examples/pico_w/bt/standalone`. - -## Debugging - -To debug Bluetooth issues you can enable [btstack](https://github.com/bluekitchen/btstack) debug output which also enables packet logging. -Define `WANT_HCI_DUMP=1` in your CMakeLists.txt file. Uncomment this line to enable debug in the btstack examples. - - target_compile_definitions(picow_bt_example_common INTERFACE - #WANT_HCI_DUMP=1 # This enables btstack debug - ) - -## Packet logging - -To view packet logs, save the output from the debug port (e.g. the uart) to a file and afterwards run `pico-sdk/lib/btstack/tool/create_packet_log.py `. -This will generate a file with the same name except for a `pklg` extension. This can be opened in the [Wireshark](https://www.wireshark.org) application to analyze communications activity. - -## Link keys - -By default, the last two sectors of flash are used to store Bluetooth link keys and this relies on the Bluetooth address. Old pre-release versions of the SDK had issues with some devices using a default Bluetooth address. If you experience issues with pairing try Resetting flash memory, see https://www.raspberrypi.com/documentation/microcontrollers/raspberry-pi-pico.html#resetting-flash-memory diff --git a/pico_w/bt/a2dp_sink_demo/CMakeLists.txt b/pico_w/bt/a2dp_sink_demo/CMakeLists.txt deleted file mode 100644 index d92d715a2..000000000 --- a/pico_w/bt/a2dp_sink_demo/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -add_library(a2dp_sink_demo_pins INTERFACE) -target_compile_definitions(a2dp_sink_demo_pins INTERFACE - PICO_AUDIO_I2S_DATA_PIN=9 - PICO_AUDIO_I2S_CLOCK_PIN_BASE=10 - ) - -picow_bt_example(a2dp_sink_demo pico_btstack_sbc_decoder a2dp_sink_demo_pins) diff --git a/pico_w/bt/a2dp_source_demo/CMakeLists.txt b/pico_w/bt/a2dp_source_demo/CMakeLists.txt deleted file mode 100644 index f3ff454d6..000000000 --- a/pico_w/bt/a2dp_source_demo/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -picow_bt_example(a2dp_source_demo pico_btstack_hxcmod_player pico_btstack_sbc_encoder) \ No newline at end of file diff --git a/pico_w/bt/ancs_client_demo/CMakeLists.txt b/pico_w/bt/ancs_client_demo/CMakeLists.txt deleted file mode 100644 index 3a0c52f01..000000000 --- a/pico_w/bt/ancs_client_demo/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -picow_bt_example(ancs_client_demo) diff --git a/pico_w/bt/att_delayed_response/CMakeLists.txt b/pico_w/bt/att_delayed_response/CMakeLists.txt deleted file mode 100644 index 441475a9e..000000000 --- a/pico_w/bt/att_delayed_response/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -picow_bt_example(att_delayed_response) diff --git a/pico_w/bt/avrcp_browsing_client/CMakeLists.txt b/pico_w/bt/avrcp_browsing_client/CMakeLists.txt deleted file mode 100644 index f78762eb5..000000000 --- a/pico_w/bt/avrcp_browsing_client/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -picow_bt_example(avrcp_browsing_client) diff --git a/pico_w/bt/btstack_audio_pico.c b/pico_w/bt/btstack_audio_pico.c deleted file mode 100644 index 1afcacec6..000000000 --- a/pico_w/bt/btstack_audio_pico.c +++ /dev/null @@ -1,209 +0,0 @@ -/* - * Copyright (C) 2022 BlueKitchen GmbH - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * 4. Any redistribution, use, or modification is done solely for - * personal benefit and not for any commercial purpose or for - * monetary gain. - * - * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BLUEKITCHEN - * GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF - * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * Please inquire about commercial licensing options at - * contact@bluekitchen-gmbh.com - * - */ - -#define BTSTACK_FILE__ "btstack_audio_pico.c" - -/* - * btstack_audio_pico.c - * - * Implementation of btstack_audio.h using pico_i2s - * - */ - -#include "btstack_config.h" - -#include "btstack_debug.h" -#include "btstack_audio.h" -#include "btstack_run_loop.h" - -#include -#include - -#include "pico/audio_i2s.h" - -#define DRIVER_POLL_INTERVAL_MS 5 -#define SAMPLES_PER_BUFFER 512 - -// client -static void (*playback_callback)(int16_t * buffer, uint16_t num_samples, const btstack_audio_context_t * timeinfo); - -// timer to fill output ring buffer -static btstack_timer_source_t driver_timer_sink; - - -static bool btstack_audio_pico_sink_active; - -// from pico-playground/audio/sine_wave/sine_wave.c - -static audio_format_t btstack_audio_pico_audio_format; -static audio_buffer_format_t btstack_audio_pico_producer_format; -static audio_buffer_pool_t * btstack_audio_pico_audio_buffer_pool; -static uint8_t btstack_audio_pico_channel_count; - -static audio_buffer_pool_t *init_audio(uint32_t sample_frequency, uint8_t channel_count) { - - // num channels requested by application - btstack_audio_pico_channel_count = channel_count; - - // always use stereo - btstack_audio_pico_audio_format.format = AUDIO_BUFFER_FORMAT_PCM_S16; - btstack_audio_pico_audio_format.sample_freq = sample_frequency; - btstack_audio_pico_audio_format.channel_count = 2; - - btstack_audio_pico_producer_format.format = &btstack_audio_pico_audio_format; - btstack_audio_pico_producer_format.sample_stride = 2 * 2; - - audio_buffer_pool_t * producer_pool = audio_new_producer_pool(&btstack_audio_pico_producer_format, 3, SAMPLES_PER_BUFFER); // todo correct size - - audio_i2s_config_t config; - config.data_pin = PICO_AUDIO_I2S_DATA_PIN; - config.clock_pin_base = PICO_AUDIO_I2S_CLOCK_PIN_BASE; - config.dma_channel = (int8_t) dma_claim_unused_channel(true); - config.pio_sm = 0; - - // audio_i2s_setup claims the channel again https://github.com/raspberrypi/pico-extras/issues/48 - dma_channel_unclaim(config.dma_channel); - const audio_format_t * output_format = audio_i2s_setup(&btstack_audio_pico_audio_format, &config); - if (!output_format) { - panic("PicoAudio: Unable to open audio device.\n"); - } - - bool ok = audio_i2s_connect(producer_pool); - assert(ok); - (void)ok; - - return producer_pool; -} - -static void btstack_audio_pico_sink_fill_buffers(void){ - while (true){ - audio_buffer_t * audio_buffer = take_audio_buffer(btstack_audio_pico_audio_buffer_pool, false); - if (audio_buffer == NULL){ - break; - } - - int16_t * buffer16 = (int16_t *) audio_buffer->buffer->bytes; - (*playback_callback)(buffer16, audio_buffer->max_sample_count, 0); - - // duplicate samples for mono - if (btstack_audio_pico_channel_count == 1){ - int16_t i; - for (i = SAMPLES_PER_BUFFER - 1 ; i >= 0; i--){ - buffer16[2*i ] = buffer16[i]; - buffer16[2*i+1] = buffer16[i]; - } - } - - audio_buffer->sample_count = audio_buffer->max_sample_count; - give_audio_buffer(btstack_audio_pico_audio_buffer_pool, audio_buffer); - } -} - -static void driver_timer_handler_sink(btstack_timer_source_t * ts){ - - // refill - btstack_audio_pico_sink_fill_buffers(); - - // re-set timer - btstack_run_loop_set_timer(ts, DRIVER_POLL_INTERVAL_MS); - btstack_run_loop_add_timer(ts); -} - -static int btstack_audio_pico_sink_init( - uint8_t channels, - uint32_t samplerate, - void (*playback)(int16_t * buffer, uint16_t num_samples, const btstack_audio_context_t * timeinfo) -){ - btstack_assert(playback != NULL); - btstack_assert(channels != 0); - - playback_callback = playback; - - if (!btstack_audio_pico_audio_buffer_pool) { - btstack_audio_pico_audio_buffer_pool = init_audio(samplerate, channels); - } - return 0; -} - -static void btstack_audio_pico_sink_set_volume(uint8_t volume){ - UNUSED(volume); -} - -static void btstack_audio_pico_sink_start_stream(void){ - - // pre-fill HAL buffers - btstack_audio_pico_sink_fill_buffers(); - - // start timer - btstack_run_loop_set_timer_handler(&driver_timer_sink, &driver_timer_handler_sink); - btstack_run_loop_set_timer(&driver_timer_sink, DRIVER_POLL_INTERVAL_MS); - btstack_run_loop_add_timer(&driver_timer_sink); - - // state - btstack_audio_pico_sink_active = true; - - audio_i2s_set_enabled(true); -} - -static void btstack_audio_pico_sink_stop_stream(void){ - - audio_i2s_set_enabled(false); - - // stop timer - btstack_run_loop_remove_timer(&driver_timer_sink); - // state - btstack_audio_pico_sink_active = false; -} - -static void btstack_audio_pico_sink_close(void){ - // stop stream if needed - if (btstack_audio_pico_sink_active){ - btstack_audio_pico_sink_stop_stream(); - } -} - -static const btstack_audio_sink_t btstack_audio_pico_sink = { - .init = &btstack_audio_pico_sink_init, - .set_volume = &btstack_audio_pico_sink_set_volume, - .start_stream = &btstack_audio_pico_sink_start_stream, - .stop_stream = &btstack_audio_pico_sink_stop_stream, - .close = &btstack_audio_pico_sink_close, -}; - -const btstack_audio_sink_t * btstack_audio_pico_sink_get_instance(void){ - return &btstack_audio_pico_sink; -} diff --git a/pico_w/bt/config/FreeRTOSConfig.h b/pico_w/bt/config/FreeRTOSConfig.h deleted file mode 100644 index eed9527c5..000000000 --- a/pico_w/bt/config/FreeRTOSConfig.h +++ /dev/null @@ -1,156 +0,0 @@ -/* - * FreeRTOS V202111.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * http://www.FreeRTOS.org - * http://aws.amazon.com/freertos - * - * 1 tab == 4 spaces! - */ - -#ifndef FREERTOS_CONFIG_H -#define FREERTOS_CONFIG_H - -/*----------------------------------------------------------- - * Application specific definitions. - * - * These definitions should be adjusted for your particular hardware and - * application requirements. - * - * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE - * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. - * - * See http://www.freertos.org/a00110.html - *----------------------------------------------------------*/ - -/* Scheduler Related */ -#define configUSE_PREEMPTION 1 -#define configUSE_TICKLESS_IDLE 0 -#define configUSE_IDLE_HOOK 0 -#define configUSE_TICK_HOOK 0 -#define configTICK_RATE_HZ ( ( TickType_t ) 1000 ) -#define configMAX_PRIORITIES 32 -#define configMINIMAL_STACK_SIZE ( configSTACK_DEPTH_TYPE ) 1024 -#define configUSE_16_BIT_TICKS 0 - -#define configIDLE_SHOULD_YIELD 1 - -/* Synchronization Related */ -#define configUSE_MUTEXES 1 -#define configUSE_RECURSIVE_MUTEXES 1 -#define configUSE_APPLICATION_TASK_TAG 0 -#define configUSE_COUNTING_SEMAPHORES 1 -#define configQUEUE_REGISTRY_SIZE 8 -#define configUSE_QUEUE_SETS 1 -#define configUSE_TIME_SLICING 1 -#define configUSE_NEWLIB_REENTRANT 0 -// todo need this for lwip FreeRTOS sys_arch to compile -#define configENABLE_BACKWARD_COMPATIBILITY 1 -#define configNUM_THREAD_LOCAL_STORAGE_POINTERS 5 - -/* System */ -#define configSTACK_DEPTH_TYPE uint32_t -#define configMESSAGE_BUFFER_LENGTH_TYPE size_t - -/* Memory allocation related definitions. */ -#define configSUPPORT_STATIC_ALLOCATION 0 -#define configSUPPORT_DYNAMIC_ALLOCATION 1 -#define configTOTAL_HEAP_SIZE (128*1024) -#define configAPPLICATION_ALLOCATED_HEAP 0 - -/* Hook function related definitions. */ -#define configCHECK_FOR_STACK_OVERFLOW 0 -#define configUSE_MALLOC_FAILED_HOOK 0 -#define configUSE_DAEMON_TASK_STARTUP_HOOK 0 - -/* Run time and task stats gathering related definitions. */ -#define configGENERATE_RUN_TIME_STATS 0 -#define configUSE_TRACE_FACILITY 1 -#define configUSE_STATS_FORMATTING_FUNCTIONS 0 - -/* Co-routine related definitions. */ -#define configUSE_CO_ROUTINES 0 -#define configMAX_CO_ROUTINE_PRIORITIES 1 - -/* Software timer related definitions. */ -#define configUSE_TIMERS 1 -#define configTIMER_TASK_PRIORITY ( configMAX_PRIORITIES - 1 ) -#define configTIMER_QUEUE_LENGTH 10 -#define configTIMER_TASK_STACK_DEPTH 1024 - -/* Interrupt nesting behaviour configuration. */ -/* -#define configKERNEL_INTERRUPT_PRIORITY [dependent of processor] -#define configMAX_SYSCALL_INTERRUPT_PRIORITY [dependent on processor and application] -#define configMAX_API_CALL_INTERRUPT_PRIORITY [dependent on processor and application] -*/ - -#define configNUMBER_OF_CORES 2 -/* SMP (configNUMBER_OF_CORES > 1) only */ -#define configTICK_CORE 0 -#define configRUN_MULTIPLE_PRIORITIES 1 -#if configNUMBER_OF_CORES > 1 -#define configUSE_CORE_AFFINITY 1 -#endif -#define configUSE_PASSIVE_IDLE_HOOK 0 - -/* Armv8-M */ - -/* Not currently supported */ -#define configENABLE_MPU 0 -//#define configSYSTEM_CALL_STACK_SIZE ( configSTACK_DEPTH_TYPE ) 512 -#define configENABLE_FPU 1 -/* Not currently supported */ -#define configENABLE_TRUSTZONE 0 -#define configRUN_FREERTOS_SECURE_ONLY 1 -// see https://www.freertos.org/RTOS-Cortex-M3-M4.html -#define configMAX_SYSCALL_INTERRUPT_PRIORITY 16 - -/* RP2xxx specific */ -#define configSUPPORT_PICO_SYNC_INTEROP 1 -#define configSUPPORT_PICO_TIME_INTEROP 1 - -#include -/* Define to trap errors during development. */ -#define configASSERT(x) assert(x) - -/* Set the following definitions to 1 to include the API function, or zero -to exclude the API function. */ -#define INCLUDE_vTaskPrioritySet 1 -#define INCLUDE_uxTaskPriorityGet 1 -#define INCLUDE_vTaskDelete 1 -#define INCLUDE_vTaskSuspend 1 -#define INCLUDE_vTaskDelayUntil 1 -#define INCLUDE_vTaskDelay 1 -#define INCLUDE_xTaskGetSchedulerState 1 -#define INCLUDE_xTaskGetCurrentTaskHandle 1 -#define INCLUDE_uxTaskGetStackHighWaterMark 1 -#define INCLUDE_xTaskGetIdleTaskHandle 1 -#define INCLUDE_eTaskGetState 1 -#define INCLUDE_xTimerPendFunctionCall 1 -#define INCLUDE_xTaskAbortDelay 1 -#define INCLUDE_xTaskGetHandle 1 -#define INCLUDE_xTaskResumeFromISR 1 -#define INCLUDE_xQueueGetMutexHolder 1 - -/* A header file that defines trace macro can be included here. */ - -#endif /* FREERTOS_CONFIG_H */ - diff --git a/pico_w/bt/config/btstack_config.h b/pico_w/bt/config/btstack_config.h deleted file mode 100644 index 1b969e1bf..000000000 --- a/pico_w/bt/config/btstack_config.h +++ /dev/null @@ -1,89 +0,0 @@ -#ifndef _PICO_BTSTACK_BTSTACK_CONFIG_H -#define _PICO_BTSTACK_BTSTACK_CONFIG_H - -// BTstack features that can be enabled -#define ENABLE_LOG_INFO -#define ENABLE_LOG_ERROR -#define ENABLE_PRINTF_HEXDUMP -#define ENABLE_SCO_OVER_HCI - -#ifdef ENABLE_BLE -#define ENABLE_GATT_CLIENT_PAIRING -#define ENABLE_L2CAP_LE_CREDIT_BASED_FLOW_CONTROL_MODE -#define ENABLE_LE_CENTRAL -#define ENABLE_LE_DATA_LENGTH_EXTENSION -#define ENABLE_LE_PERIPHERAL -#define ENABLE_LE_PRIVACY_ADDRESS_RESOLUTION -#define ENABLE_LE_SECURE_CONNECTIONS -#endif - -#ifdef ENABLE_CLASSIC -#define ENABLE_L2CAP_ENHANCED_RETRANSMISSION_MODE -#define ENABLE_GOEP_L2CAP -#endif - -#if defined (ENABLE_CLASSIC) && defined(ENABLE_BLE) -#define ENABLE_CROSS_TRANSPORT_KEY_DERIVATION -#endif - -// BTstack configuration. buffers, sizes, ... -#define HCI_OUTGOING_PRE_BUFFER_SIZE 4 -#define HCI_ACL_PAYLOAD_SIZE (1691 + 4) -#define HCI_ACL_CHUNK_SIZE_ALIGNMENT 4 -#define MAX_NR_AVDTP_CONNECTIONS 1 -#define MAX_NR_AVDTP_STREAM_ENDPOINTS 1 -#define MAX_NR_AVRCP_CONNECTIONS 2 -#define MAX_NR_BNEP_CHANNELS 1 -#define MAX_NR_BNEP_SERVICES 1 -#define MAX_NR_BTSTACK_LINK_KEY_DB_MEMORY_ENTRIES 2 -#define MAX_NR_GATT_CLIENTS 1 -#define MAX_NR_HCI_CONNECTIONS 2 -#define MAX_NR_HID_HOST_CONNECTIONS 1 -#define MAX_NR_HIDS_CLIENTS 1 -#define MAX_NR_HFP_CONNECTIONS 1 -#define MAX_NR_L2CAP_CHANNELS 4 -#define MAX_NR_L2CAP_SERVICES 3 -#define MAX_NR_RFCOMM_CHANNELS 1 -#define MAX_NR_RFCOMM_MULTIPLEXERS 1 -#define MAX_NR_RFCOMM_SERVICES 1 -#define MAX_NR_SERVICE_RECORD_ITEMS 4 -#define MAX_NR_SM_LOOKUP_ENTRIES 3 -#define MAX_NR_WHITELIST_ENTRIES 16 -#define MAX_NR_LE_DEVICE_DB_ENTRIES 16 - -// Limit number of ACL/SCO Buffer to use by stack to avoid cyw43 shared bus overrun -#define MAX_NR_CONTROLLER_ACL_BUFFERS 3 -#define MAX_NR_CONTROLLER_SCO_PACKETS 3 - -// Enable and configure HCI Controller to Host Flow Control to avoid cyw43 shared bus overrun -#define ENABLE_HCI_CONTROLLER_TO_HOST_FLOW_CONTROL -#define HCI_HOST_ACL_PACKET_LEN 1024 -#define HCI_HOST_ACL_PACKET_NUM 3 -#define HCI_HOST_SCO_PACKET_LEN 120 -#define HCI_HOST_SCO_PACKET_NUM 3 - -// Link Key DB and LE Device DB using TLV on top of Flash Sector interface -#define NVM_NUM_DEVICE_DB_ENTRIES 16 -#define NVM_NUM_LINK_KEYS 16 - -// We don't give btstack a malloc, so use a fixed-size ATT DB. -#define MAX_ATT_DB_SIZE 512 - -// BTstack HAL configuration -#define HAVE_EMBEDDED_TIME_MS - -// map btstack_assert onto Pico SDK assert() -#define HAVE_ASSERT - -// Some USB dongles take longer to respond to HCI reset (e.g. BCM20702A). -#define HCI_RESET_RESEND_TIMEOUT_MS 1000 - -#define ENABLE_SOFTWARE_AES128 -#define ENABLE_MICRO_ECC_FOR_LE_SECURE_CONNECTIONS - -#define HAVE_BTSTACK_STDIN - -// To get the audio demos working even with HCI dump at 115200, this truncates long ACL packets -//#define HCI_DUMP_STDOUT_MAX_SIZE_ACL 100 - -#endif // _PICO_BTSTACK_BTSTACK_CONFIG_H diff --git a/pico_w/bt/config/lwipopts.h b/pico_w/bt/config/lwipopts.h deleted file mode 100644 index b8983d7d9..000000000 --- a/pico_w/bt/config/lwipopts.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef _LWIPOPTS_H -#define _LWIPOPTS_H - -// Generally you would define your own explicit list of lwIP options -// (see https://www.nongnu.org/lwip/2_1_x/group__lwip__opts.html) -// -// This example uses a common include to avoid repetition -#include "lwipopts_examples_common.h" - -#if !NO_SYS -#define TCPIP_THREAD_STACKSIZE 1024 -#define DEFAULT_THREAD_STACKSIZE 1024 -#define DEFAULT_RAW_RECVMBOX_SIZE 8 -#define TCPIP_MBOX_SIZE 8 -#define LWIP_TIMEVAL_PRIVATE 0 - -// not necessary, can be done either way -#define LWIP_TCPIP_CORE_LOCKING_INPUT 1 -#endif - -#endif diff --git a/pico_w/bt/dut_mode_classic/CMakeLists.txt b/pico_w/bt/dut_mode_classic/CMakeLists.txt deleted file mode 100644 index 44bc17fba..000000000 --- a/pico_w/bt/dut_mode_classic/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -picow_bt_example(dut_mode_classic) diff --git a/pico_w/bt/gap_dedicated_bonding/CMakeLists.txt b/pico_w/bt/gap_dedicated_bonding/CMakeLists.txt deleted file mode 100644 index 72daea2c0..000000000 --- a/pico_w/bt/gap_dedicated_bonding/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -picow_bt_example(gap_dedicated_bonding) diff --git a/pico_w/bt/gap_inquiry/CMakeLists.txt b/pico_w/bt/gap_inquiry/CMakeLists.txt deleted file mode 100644 index 383582e87..000000000 --- a/pico_w/bt/gap_inquiry/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -picow_bt_example(gap_inquiry) diff --git a/pico_w/bt/gap_le_advertisements/CMakeLists.txt b/pico_w/bt/gap_le_advertisements/CMakeLists.txt deleted file mode 100644 index 07f609326..000000000 --- a/pico_w/bt/gap_le_advertisements/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -picow_bt_example(gap_le_advertisements) diff --git a/pico_w/bt/gap_link_keys/CMakeLists.txt b/pico_w/bt/gap_link_keys/CMakeLists.txt deleted file mode 100644 index b20dfc6b3..000000000 --- a/pico_w/bt/gap_link_keys/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -picow_bt_example(gap_link_keys) diff --git a/pico_w/bt/gatt_battery_query/CMakeLists.txt b/pico_w/bt/gatt_battery_query/CMakeLists.txt deleted file mode 100644 index f4669eb28..000000000 --- a/pico_w/bt/gatt_battery_query/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -picow_bt_example(gatt_battery_query) diff --git a/pico_w/bt/gatt_browser/CMakeLists.txt b/pico_w/bt/gatt_browser/CMakeLists.txt deleted file mode 100644 index 42971bc6c..000000000 --- a/pico_w/bt/gatt_browser/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -picow_bt_example(gatt_browser) diff --git a/pico_w/bt/gatt_counter/CMakeLists.txt b/pico_w/bt/gatt_counter/CMakeLists.txt deleted file mode 100644 index 287e542e5..000000000 --- a/pico_w/bt/gatt_counter/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -picow_bt_example(gatt_counter) diff --git a/pico_w/bt/gatt_counter_with_wifi/CMakeLists.txt b/pico_w/bt/gatt_counter_with_wifi/CMakeLists.txt deleted file mode 100644 index f8fea0a07..000000000 --- a/pico_w/bt/gatt_counter_with_wifi/CMakeLists.txt +++ /dev/null @@ -1,6 +0,0 @@ -set(NAME gatt_counter) -picow_bt_example_target_name(${NAME}_with_wifi TARGET_NAME) - -picow_bt_example_poll(${NAME} ${TARGET_NAME} picow_bt_example_cyw43_lwip_poll pico_btstack_ble) -picow_bt_example_background(${NAME} ${TARGET_NAME} picow_bt_example_cyw43_lwip_background pico_btstack_ble) -picow_bt_example_freertos(${NAME} ${TARGET_NAME} picow_bt_example_cyw43_lwip_freertos pico_btstack_ble) diff --git a/pico_w/bt/gatt_device_information_query/CMakeLists.txt b/pico_w/bt/gatt_device_information_query/CMakeLists.txt deleted file mode 100644 index 227acc3ee..000000000 --- a/pico_w/bt/gatt_device_information_query/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -picow_bt_example(gatt_device_information_query) diff --git a/pico_w/bt/gatt_heart_rate_client/CMakeLists.txt b/pico_w/bt/gatt_heart_rate_client/CMakeLists.txt deleted file mode 100644 index 5766c548c..000000000 --- a/pico_w/bt/gatt_heart_rate_client/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -picow_bt_example(gatt_heart_rate_client) diff --git a/pico_w/bt/gatt_streamer_server/CMakeLists.txt b/pico_w/bt/gatt_streamer_server/CMakeLists.txt deleted file mode 100644 index 1e5ea1d30..000000000 --- a/pico_w/bt/gatt_streamer_server/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -picow_bt_example(gatt_streamer_server) diff --git a/pico_w/bt/gatt_streamer_server_with_wifi/CMakeLists.txt b/pico_w/bt/gatt_streamer_server_with_wifi/CMakeLists.txt deleted file mode 100644 index 9599e6f72..000000000 --- a/pico_w/bt/gatt_streamer_server_with_wifi/CMakeLists.txt +++ /dev/null @@ -1,6 +0,0 @@ -set(NAME gatt_streamer_server) -picow_bt_example_target_name(${NAME}_with_wifi TARGET_NAME) - -picow_bt_example_poll(${NAME} ${TARGET_NAME} picow_bt_example_cyw43_lwip_poll pico_btstack_ble) -picow_bt_example_background(${NAME} ${TARGET_NAME} picow_bt_example_cyw43_lwip_background pico_btstack_ble) -picow_bt_example_freertos(${NAME} ${TARGET_NAME} picow_bt_example_cyw43_lwip_freertos pico_btstack_ble) diff --git a/pico_w/bt/hfp_ag_demo/CMakeLists.txt b/pico_w/bt/hfp_ag_demo/CMakeLists.txt deleted file mode 100644 index 5a5b60458..000000000 --- a/pico_w/bt/hfp_ag_demo/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -picow_bt_example(hfp_ag_demo pico_btstack_sco_demo_util pico_btstack_sbc_encoder) diff --git a/pico_w/bt/hfp_hf_demo/CMakeLists.txt b/pico_w/bt/hfp_hf_demo/CMakeLists.txt deleted file mode 100644 index 77e52f0af..000000000 --- a/pico_w/bt/hfp_hf_demo/CMakeLists.txt +++ /dev/null @@ -1,6 +0,0 @@ -add_library(hfp_hf_demo_pins INTERFACE) -target_compile_definitions(hfp_hf_demo_pins INTERFACE - PICO_AUDIO_I2S_DATA_PIN=9 - PICO_AUDIO_I2S_CLOCK_PIN_BASE=10 - ) -picow_bt_example(hfp_hf_demo pico_btstack_sco_demo_util pico_btstack_sbc_encoder hfp_hf_demo_pins) diff --git a/pico_w/bt/hid_host_demo/CMakeLists.txt b/pico_w/bt/hid_host_demo/CMakeLists.txt deleted file mode 100644 index 3febdba15..000000000 --- a/pico_w/bt/hid_host_demo/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -picow_bt_example(hid_host_demo) diff --git a/pico_w/bt/hid_keyboard_demo/CMakeLists.txt b/pico_w/bt/hid_keyboard_demo/CMakeLists.txt deleted file mode 100644 index 29a8ac781..000000000 --- a/pico_w/bt/hid_keyboard_demo/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -picow_bt_example(hid_keyboard_demo) diff --git a/pico_w/bt/hid_mouse_demo/CMakeLists.txt b/pico_w/bt/hid_mouse_demo/CMakeLists.txt deleted file mode 100644 index aebb18a9a..000000000 --- a/pico_w/bt/hid_mouse_demo/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -picow_bt_example(hid_mouse_demo) diff --git a/pico_w/bt/hog_boot_host_demo/CMakeLists.txt b/pico_w/bt/hog_boot_host_demo/CMakeLists.txt deleted file mode 100644 index 536649db6..000000000 --- a/pico_w/bt/hog_boot_host_demo/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -picow_bt_example(hog_boot_host_demo) diff --git a/pico_w/bt/hog_host_demo/CMakeLists.txt b/pico_w/bt/hog_host_demo/CMakeLists.txt deleted file mode 100644 index c7ce663ff..000000000 --- a/pico_w/bt/hog_host_demo/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -picow_bt_example(hog_host_demo) diff --git a/pico_w/bt/hog_keyboard_demo/CMakeLists.txt b/pico_w/bt/hog_keyboard_demo/CMakeLists.txt deleted file mode 100644 index 6cae1e28f..000000000 --- a/pico_w/bt/hog_keyboard_demo/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -picow_bt_example(hog_keyboard_demo) diff --git a/pico_w/bt/hog_mouse_demo/CMakeLists.txt b/pico_w/bt/hog_mouse_demo/CMakeLists.txt deleted file mode 100644 index 2e176ef5d..000000000 --- a/pico_w/bt/hog_mouse_demo/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -picow_bt_example(hog_mouse_demo) diff --git a/pico_w/bt/hsp_ag_demo/CMakeLists.txt b/pico_w/bt/hsp_ag_demo/CMakeLists.txt deleted file mode 100644 index 1cdcfe054..000000000 --- a/pico_w/bt/hsp_ag_demo/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -picow_bt_example(hsp_ag_demo pico_btstack_sco_demo_util pico_btstack_sbc_encoder) diff --git a/pico_w/bt/hsp_hs_demo/CMakeLists.txt b/pico_w/bt/hsp_hs_demo/CMakeLists.txt deleted file mode 100644 index 24221c637..000000000 --- a/pico_w/bt/hsp_hs_demo/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -picow_bt_example(hsp_hs_demo pico_btstack_sco_demo_util pico_btstack_sbc_encoder) diff --git a/pico_w/bt/le_credit_based_flow_control_mode_client/CMakeLists.txt b/pico_w/bt/le_credit_based_flow_control_mode_client/CMakeLists.txt deleted file mode 100644 index addcbe082..000000000 --- a/pico_w/bt/le_credit_based_flow_control_mode_client/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -picow_bt_example(le_credit_based_flow_control_mode_client) diff --git a/pico_w/bt/le_credit_based_flow_control_mode_server/CMakeLists.txt b/pico_w/bt/le_credit_based_flow_control_mode_server/CMakeLists.txt deleted file mode 100644 index 60529c970..000000000 --- a/pico_w/bt/le_credit_based_flow_control_mode_server/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -picow_bt_example(le_credit_based_flow_control_mode_server) diff --git a/pico_w/bt/le_mitm/CMakeLists.txt b/pico_w/bt/le_mitm/CMakeLists.txt deleted file mode 100644 index 0fc965fab..000000000 --- a/pico_w/bt/le_mitm/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -picow_bt_example(le_mitm) diff --git a/pico_w/bt/le_streamer_client/CMakeLists.txt b/pico_w/bt/le_streamer_client/CMakeLists.txt deleted file mode 100644 index 256f1dff6..000000000 --- a/pico_w/bt/le_streamer_client/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -picow_bt_example(le_streamer_client) diff --git a/pico_w/bt/led_counter/CMakeLists.txt b/pico_w/bt/led_counter/CMakeLists.txt deleted file mode 100644 index 9351f102f..000000000 --- a/pico_w/bt/led_counter/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -picow_bt_example(led_counter) diff --git a/pico_w/bt/mod_player/CMakeLists.txt b/pico_w/bt/mod_player/CMakeLists.txt deleted file mode 100644 index b27b23bd4..000000000 --- a/pico_w/bt/mod_player/CMakeLists.txt +++ /dev/null @@ -1,6 +0,0 @@ -add_library(mod_player_pins INTERFACE) -target_compile_definitions(mod_player_pins INTERFACE - PICO_AUDIO_I2S_DATA_PIN=9 - PICO_AUDIO_I2S_CLOCK_PIN_BASE=10 - ) -picow_bt_example(mod_player pico_btstack_hxcmod_player mod_player_pins) diff --git a/pico_w/bt/nordic_spp_le_counter/CMakeLists.txt b/pico_w/bt/nordic_spp_le_counter/CMakeLists.txt deleted file mode 100644 index 9bb804fa7..000000000 --- a/pico_w/bt/nordic_spp_le_counter/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -picow_bt_example(nordic_spp_le_counter) diff --git a/pico_w/bt/nordic_spp_le_streamer/CMakeLists.txt b/pico_w/bt/nordic_spp_le_streamer/CMakeLists.txt deleted file mode 100644 index 0d3b48c50..000000000 --- a/pico_w/bt/nordic_spp_le_streamer/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -picow_bt_example(nordic_spp_le_streamer) diff --git a/pico_w/bt/pan_lwip_http_server/CMakeLists.txt b/pico_w/bt/pan_lwip_http_server/CMakeLists.txt deleted file mode 100644 index 82379beb0..000000000 --- a/pico_w/bt/pan_lwip_http_server/CMakeLists.txt +++ /dev/null @@ -1,13 +0,0 @@ -add_library(pan_lwip_dhserver INTERFACE) -target_sources(pan_lwip_dhserver INTERFACE - ${BTSTACK_3RD_PARTY_PATH}/lwip/dhcp-server/dhserver.c -) -target_include_directories(pan_lwip_dhserver INTERFACE - ${BTSTACK_3RD_PARTY_PATH}/lwip/dhcp-server -) - -picow_bt_example_target_name(pan_lwip_http_server TARGET_NAME) - -picow_bt_example_poll(pan_lwip_http_server ${TARGET_NAME} picow_bt_example_btstack_lwip_poll pan_lwip_dhserver pico_lwip_http pico_btstack_classic) -picow_bt_example_background(pan_lwip_http_server ${TARGET_NAME} picow_bt_example_btstack_lwip_background pan_lwip_dhserver pico_lwip_http pico_btstack_classic) -picow_bt_example_freertos(pan_lwip_http_server ${TARGET_NAME} picow_bt_example_btstack_lwip_freertos pan_lwip_dhserver pico_lwip_http pico_btstack_classic) diff --git a/pico_w/bt/pbap_client_demo/CMakeLists.txt b/pico_w/bt/pbap_client_demo/CMakeLists.txt deleted file mode 100644 index 503c52bae..000000000 --- a/pico_w/bt/pbap_client_demo/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -picow_bt_example(pbap_client_demo) diff --git a/pico_w/bt/picow_bt_example_background.c b/pico_w/bt/picow_bt_example_background.c deleted file mode 100644 index 24794d2b1..000000000 --- a/pico_w/bt/picow_bt_example_background.c +++ /dev/null @@ -1,21 +0,0 @@ -/** - * Copyright (c) 2022 Raspberry Pi (Trading) Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include "btstack_run_loop.h" -#include "pico/stdlib.h" -#include "picow_bt_example_common.h" - -int main() { - stdio_init_all(); - - int res = picow_bt_example_init(); - if (res){ - return -1; - } - - picow_bt_example_main(); - btstack_run_loop_execute(); -} diff --git a/pico_w/bt/picow_bt_example_common.c b/pico_w/bt/picow_bt_example_common.c deleted file mode 100644 index 7d93520b1..000000000 --- a/pico_w/bt/picow_bt_example_common.c +++ /dev/null @@ -1,103 +0,0 @@ -/** - * Copyright (c) 2022 Raspberry Pi (Trading) Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#if TEST_AUDIO -#include "btstack_audio.h" -#endif -#include "btstack_event.h" -#include "hal_led.h" -#include "pico/cyw43_arch.h" -#include "pico/stdlib.h" -#include "btstack.h" - -#if defined(WIFI_SSID) && defined(WIFI_PASSWORD) -#define TEST_BTWIFI 1 -#endif - -#if TEST_BTWIFI -#include "lwip/ip4_addr.h" -#include "lwip/apps/lwiperf.h" -#endif - -// Start the btstack example -int btstack_main(int argc, const char * argv[]); - -#if TEST_AUDIO -const btstack_audio_sink_t * btstack_audio_pico_sink_get_instance(void); -#endif - -static btstack_packet_callback_registration_t hci_event_callback_registration; -static int led_state = 0; - -void hal_led_toggle(void){ - led_state = 1 - led_state; - cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, led_state); -} - -static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ - UNUSED(size); - UNUSED(channel); - bd_addr_t local_addr; - if (packet_type != HCI_EVENT_PACKET) return; - switch(hci_event_packet_get_type(packet)){ - case BTSTACK_EVENT_STATE: - if (btstack_event_state_get_state(packet) != HCI_STATE_WORKING) return; - gap_local_bd_addr(local_addr); - printf("BTstack up and running on %s.\n", bd_addr_to_str(local_addr)); - break; - default: - break; - } -} - -#if TEST_BTWIFI -static void iperf_report(void *arg, enum lwiperf_report_type report_type, - const ip_addr_t *local_addr, u16_t local_port, const ip_addr_t *remote_addr, u16_t remote_port, - u32_t bytes_transferred, u32_t ms_duration, u32_t bandwidth_kbitpsec) { - static uint32_t total_iperf_megabytes = 0; - uint32_t mbytes = bytes_transferred / 1024 / 1024; - float mbits = bandwidth_kbitpsec / 1000.0; - total_iperf_megabytes += mbytes; - printf("Completed iperf transfer of %u MBytes @ %.1f Mbits/sec\n", mbytes, mbits); - printf("Total iperf megabytes since start %u Mbytes\n", total_iperf_megabytes); -} -#endif - -int picow_bt_example_init(void) { - // initialize CYW43 driver architecture (will enable BT if/because CYW43_ENABLE_BLUETOOTH == 1) - if (cyw43_arch_init()) { - printf("failed to initialise cyw43_arch\n"); - return -1; - } - - // inform about BTstack state - hci_event_callback_registration.callback = &packet_handler; - hci_add_event_handler(&hci_event_callback_registration); - - // setup i2s audio for sink -#if TEST_AUDIO - btstack_audio_sink_set_instance(btstack_audio_pico_sink_get_instance()); -#endif - return 0; -} - -void picow_bt_example_main(void) { - - btstack_main(0, NULL); - -#if TEST_BTWIFI - uint32_t start_ms = to_ms_since_boot(get_absolute_time()); - cyw43_arch_enable_sta_mode(); - printf("Connecting to WiFi \"%s\"...\n", WIFI_SSID); - if (cyw43_arch_wifi_connect_timeout_ms(WIFI_SSID, WIFI_PASSWORD, CYW43_AUTH_WPA2_AES_PSK, 30000)) { - panic("failed to connect"); - } else { - printf("Connected in %lus.\n", (to_ms_since_boot(get_absolute_time()) - start_ms) / 1000); - } - printf("\nReady, running iperf server at %s\n", ip4addr_ntoa(netif_ip4_addr(netif_list))); - lwiperf_start_tcp_server_default(&iperf_report, NULL); -#endif -} diff --git a/pico_w/bt/picow_bt_example_common.h b/pico_w/bt/picow_bt_example_common.h deleted file mode 100644 index 725322706..000000000 --- a/pico_w/bt/picow_bt_example_common.h +++ /dev/null @@ -1,18 +0,0 @@ -/** - * Copyright (c) 2022 Raspberry Pi (Trading) Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/* - * \brief Initialise BTstack example with cyw43 - * - * \return 0 if ok - */ -int picow_bt_example_init(void); - -/* - * \brief Run the BTstack example - * - */ -void picow_bt_example_main(void); diff --git a/pico_w/bt/picow_bt_example_freertos.c b/pico_w/bt/picow_bt_example_freertos.c deleted file mode 100644 index b3c8b3b15..000000000 --- a/pico_w/bt/picow_bt_example_freertos.c +++ /dev/null @@ -1,109 +0,0 @@ -/** - * Copyright (c) 2022 Raspberry Pi (Trading) Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include -#include "pico/stdlib.h" -#include "FreeRTOS.h" -#include "task.h" - -#include "picow_bt_example_common.h" - -#if HAVE_LWIP -#include "pico/lwip_freertos.h" -#include "pico/cyw43_arch.h" -#endif - -#ifndef RUN_FREERTOS_ON_CORE -#define RUN_FREERTOS_ON_CORE 0 -#endif - -#define TEST_TASK_PRIORITY ( tskIDLE_PRIORITY + 2UL ) -#define BLINK_TASK_PRIORITY ( tskIDLE_PRIORITY + 1UL ) - -#ifdef TEST_BLINK_TASK -void blink_task(__unused void *params) { - printf("blink_task starts\n"); - while (true) { -#if 0 && configNUMBER_OF_CORES > 1 - static int last_core_id; - if (portGET_CORE_ID() != last_core_id) { - last_core_id = portGET_CORE_ID(); - printf("blinking now from core %d\n", last_core_id); - } -#endif - hal_led_toggle(); - vTaskDelay(200); - } -} -#endif - -void main_task(__unused void *params) { - - int res = picow_bt_example_init(); - if (res){ - return; - } - -// If we're using lwip but not via cyw43 (e.g. pan) we have to call this -#if HAVE_LWIP && !CYW43_LWIP - lwip_freertos_init(cyw43_arch_async_context()); -#endif - - picow_bt_example_main(); - -#ifdef TEST_BLINK_TASK - xTaskCreate(blink_task, "BlinkThread", configMINIMAL_STACK_SIZE, NULL, BLINK_TASK_PRIORITY, NULL); -#endif - - while(true) { - vTaskDelay(1000); - } - -#if HAVE_LWIP && !CYW43_LWIP - lwip_freertos_deinit(cyw43_arch_async_context()); -#endif -} - -void vLaunch( void) { - TaskHandle_t task; - xTaskCreate(main_task, "TestMainThread", 1024, NULL, TEST_TASK_PRIORITY, &task); - -#if NO_SYS && configUSE_CORE_AFFINITY && configNUMBER_OF_CORES > 1 - // we must bind the main task to one core (well at least while the init is called) - // (note we only do this in NO_SYS mode, because cyw43_arch_freertos - // takes care of it otherwise) - vTaskCoreAffinitySet(task, 1); -#endif - - /* Start the tasks and timer running. */ - vTaskStartScheduler(); -} - -int main() -{ - stdio_init_all(); - - /* Configure the hardware ready to run the demo. */ - const char *rtos_name; -#if ( configNUMBER_OF_CORES > 1 ) - rtos_name = "FreeRTOS SMP"; -#else - rtos_name = "FreeRTOS"; -#endif - -#if ( configNUMBER_OF_CORES == 2 ) - printf("Starting %s on both cores:\n", rtos_name); - vLaunch(); -#elif ( RUN_FREE_RTOS_ON_CORE == 1 ) - printf("Starting %s on core 1:\n", rtos_name); - multicore_launch_core1(vLaunch); - while (true); -#else - printf("Starting %s on core 0:\n", rtos_name); - vLaunch(); -#endif - return 0; -} diff --git a/pico_w/bt/picow_bt_example_poll.c b/pico_w/bt/picow_bt_example_poll.c deleted file mode 100644 index 24794d2b1..000000000 --- a/pico_w/bt/picow_bt_example_poll.c +++ /dev/null @@ -1,21 +0,0 @@ -/** - * Copyright (c) 2022 Raspberry Pi (Trading) Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include "btstack_run_loop.h" -#include "pico/stdlib.h" -#include "picow_bt_example_common.h" - -int main() { - stdio_init_all(); - - int res = picow_bt_example_init(); - if (res){ - return -1; - } - - picow_bt_example_main(); - btstack_run_loop_execute(); -} diff --git a/pico_w/bt/sdp_bnep_query/CMakeLists.txt b/pico_w/bt/sdp_bnep_query/CMakeLists.txt deleted file mode 100644 index 17cb14f0c..000000000 --- a/pico_w/bt/sdp_bnep_query/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -picow_bt_example(sdp_bnep_query) diff --git a/pico_w/bt/sdp_general_query/CMakeLists.txt b/pico_w/bt/sdp_general_query/CMakeLists.txt deleted file mode 100644 index e095cdedf..000000000 --- a/pico_w/bt/sdp_general_query/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -picow_bt_example(sdp_general_query) diff --git a/pico_w/bt/sdp_rfcomm_query/CMakeLists.txt b/pico_w/bt/sdp_rfcomm_query/CMakeLists.txt deleted file mode 100644 index f558231de..000000000 --- a/pico_w/bt/sdp_rfcomm_query/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -picow_bt_example(sdp_rfcomm_query) diff --git a/pico_w/bt/sine_player/CMakeLists.txt b/pico_w/bt/sine_player/CMakeLists.txt deleted file mode 100644 index 0ccbddef8..000000000 --- a/pico_w/bt/sine_player/CMakeLists.txt +++ /dev/null @@ -1,6 +0,0 @@ -add_library(sine_player_pins INTERFACE) -target_compile_definitions(sine_player_pins INTERFACE - PICO_AUDIO_I2S_DATA_PIN=9 - PICO_AUDIO_I2S_CLOCK_PIN_BASE=10 - ) -picow_bt_example(sine_player sine_player_pins) diff --git a/pico_w/bt/sm_pairing_central/CMakeLists.txt b/pico_w/bt/sm_pairing_central/CMakeLists.txt deleted file mode 100644 index 456096d03..000000000 --- a/pico_w/bt/sm_pairing_central/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -picow_bt_example(sm_pairing_central) diff --git a/pico_w/bt/sm_pairing_peripheral/CMakeLists.txt b/pico_w/bt/sm_pairing_peripheral/CMakeLists.txt deleted file mode 100644 index 66e5a27df..000000000 --- a/pico_w/bt/sm_pairing_peripheral/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -picow_bt_example(sm_pairing_peripheral) diff --git a/pico_w/bt/spp_and_gatt_counter/CMakeLists.txt b/pico_w/bt/spp_and_gatt_counter/CMakeLists.txt deleted file mode 100644 index 7ed8e4a9c..000000000 --- a/pico_w/bt/spp_and_gatt_counter/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -picow_bt_example(spp_and_gatt_counter) diff --git a/pico_w/bt/spp_and_gatt_streamer/CMakeLists.txt b/pico_w/bt/spp_and_gatt_streamer/CMakeLists.txt deleted file mode 100644 index 47afd6a41..000000000 --- a/pico_w/bt/spp_and_gatt_streamer/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -picow_bt_example(spp_and_gatt_streamer) diff --git a/pico_w/bt/spp_counter/CMakeLists.txt b/pico_w/bt/spp_counter/CMakeLists.txt deleted file mode 100644 index 9465d5c39..000000000 --- a/pico_w/bt/spp_counter/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -picow_bt_example(spp_counter) diff --git a/pico_w/bt/spp_flowcontrol/CMakeLists.txt b/pico_w/bt/spp_flowcontrol/CMakeLists.txt deleted file mode 100644 index 75c4b838d..000000000 --- a/pico_w/bt/spp_flowcontrol/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -picow_bt_example(spp_flowcontrol) diff --git a/pico_w/bt/spp_streamer/CMakeLists.txt b/pico_w/bt/spp_streamer/CMakeLists.txt deleted file mode 100644 index f35d40169..000000000 --- a/pico_w/bt/spp_streamer/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -picow_bt_example(spp_streamer) diff --git a/pico_w/bt/spp_streamer_client/CMakeLists.txt b/pico_w/bt/spp_streamer_client/CMakeLists.txt deleted file mode 100644 index b85838859..000000000 --- a/pico_w/bt/spp_streamer_client/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -picow_bt_example(spp_streamer_client) diff --git a/pico_w/bt/spp_streamer_with_wifi/CMakeLists.txt b/pico_w/bt/spp_streamer_with_wifi/CMakeLists.txt deleted file mode 100644 index f30521f5b..000000000 --- a/pico_w/bt/spp_streamer_with_wifi/CMakeLists.txt +++ /dev/null @@ -1,6 +0,0 @@ -set(NAME spp_streamer) -picow_bt_example_target_name(${NAME}_with_wifi TARGET_NAME) - -picow_bt_example_poll(${NAME} ${TARGET_NAME} picow_bt_example_cyw43_lwip_poll pico_btstack_classic) -picow_bt_example_background(${NAME} ${TARGET_NAME} picow_bt_example_cyw43_lwip_background pico_btstack_classic) -picow_bt_example_freertos(${NAME} ${TARGET_NAME} picow_bt_example_cyw43_lwip_freertos pico_btstack_classic) diff --git a/pico_w/bt/ublox_spp_le_counter/CMakeLists.txt b/pico_w/bt/ublox_spp_le_counter/CMakeLists.txt deleted file mode 100644 index 92ef01ca3..000000000 --- a/pico_w/bt/ublox_spp_le_counter/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -picow_bt_example(ublox_spp_le_counter) From 4310de70acdcf8b2056706b9c0f9016e2eb627b2 Mon Sep 17 00:00:00 2001 From: Peter Harper Date: Wed, 11 Mar 2026 11:15:30 +0000 Subject: [PATCH 07/13] Build fixes --- bluetooth/CMakeLists.txt | 3 +++ bluetooth/ble_pointer/ble_pointer.c | 4 ---- bluetooth/ble_pointer/btstack_config.h | 2 +- bluetooth/doorbell/btstack_config.h | 2 +- bluetooth/secure_temp_sensor/btstack_config.h | 2 +- bluetooth/temp_sensor/client/btstack_config.h | 2 +- bluetooth/temp_sensor/server/btstack_config.h | 2 +- bluetooth/wifi_provisioner/CMakeLists.txt | 8 ++++---- bluetooth/wifi_provisioner/btstack_config.h | 2 +- 9 files changed, 13 insertions(+), 14 deletions(-) diff --git a/bluetooth/CMakeLists.txt b/bluetooth/CMakeLists.txt index eabbfe7e4..6a7db8253 100644 --- a/bluetooth/CMakeLists.txt +++ b/bluetooth/CMakeLists.txt @@ -1,3 +1,6 @@ +if (NOT PICO_CYW43_SUPPORTED) + return() +endif() if (DEFINED ENV{PICO_BTSTACK_PATH} AND (NOT PICO_BTSTACK_PATH)) set(PICO_BTSTACK_PATH $ENV{PICO_BTSTACK_PATH}) message("Using PICO_BTSTACK_PATH from environment ('${PICO_BTSTACK_PATH}')") diff --git a/bluetooth/ble_pointer/ble_pointer.c b/bluetooth/ble_pointer/ble_pointer.c index cdcfc3e20..06d02ccc2 100644 --- a/bluetooth/ble_pointer/ble_pointer.c +++ b/bluetooth/ble_pointer/ble_pointer.c @@ -437,10 +437,6 @@ int main(void) { // now setup BLE hog_mouse_setup(); -#ifdef HAVE_BTSTACK_STDIN - btstack_stdin_setup(stdin_process); -#endif - // turn on! hci_power_control(HCI_POWER_ON); diff --git a/bluetooth/ble_pointer/btstack_config.h b/bluetooth/ble_pointer/btstack_config.h index ce1919916..0dd0d82cb 100644 --- a/bluetooth/ble_pointer/btstack_config.h +++ b/bluetooth/ble_pointer/btstack_config.h @@ -1,6 +1,6 @@ #ifndef _PICO_BTSTACK_CONFIG_H #define _PICO_BTSTACK_CONFIG_H -#include "btstack_config_common.h" +#include "../config/btstack_config_common.h" #endif diff --git a/bluetooth/doorbell/btstack_config.h b/bluetooth/doorbell/btstack_config.h index ce1919916..0dd0d82cb 100644 --- a/bluetooth/doorbell/btstack_config.h +++ b/bluetooth/doorbell/btstack_config.h @@ -1,6 +1,6 @@ #ifndef _PICO_BTSTACK_CONFIG_H #define _PICO_BTSTACK_CONFIG_H -#include "btstack_config_common.h" +#include "../config/btstack_config_common.h" #endif diff --git a/bluetooth/secure_temp_sensor/btstack_config.h b/bluetooth/secure_temp_sensor/btstack_config.h index b628edf30..c0f0f01d3 100644 --- a/bluetooth/secure_temp_sensor/btstack_config.h +++ b/bluetooth/secure_temp_sensor/btstack_config.h @@ -1,7 +1,7 @@ #ifndef _PICO_BTSTACK_CONFIG_H #define _PICO_BTSTACK_CONFIG_H -#include "btstack_config_common.h" +#include "../config/btstack_config_common.h" // security #define ENABLE_LE_SECURE_CONNECTIONS diff --git a/bluetooth/temp_sensor/client/btstack_config.h b/bluetooth/temp_sensor/client/btstack_config.h index ce1919916..191387520 100644 --- a/bluetooth/temp_sensor/client/btstack_config.h +++ b/bluetooth/temp_sensor/client/btstack_config.h @@ -1,6 +1,6 @@ #ifndef _PICO_BTSTACK_CONFIG_H #define _PICO_BTSTACK_CONFIG_H -#include "btstack_config_common.h" +#include "../../config/btstack_config_common.h" #endif diff --git a/bluetooth/temp_sensor/server/btstack_config.h b/bluetooth/temp_sensor/server/btstack_config.h index ce1919916..191387520 100644 --- a/bluetooth/temp_sensor/server/btstack_config.h +++ b/bluetooth/temp_sensor/server/btstack_config.h @@ -1,6 +1,6 @@ #ifndef _PICO_BTSTACK_CONFIG_H #define _PICO_BTSTACK_CONFIG_H -#include "btstack_config_common.h" +#include "../../config/btstack_config_common.h" #endif diff --git a/bluetooth/wifi_provisioner/CMakeLists.txt b/bluetooth/wifi_provisioner/CMakeLists.txt index 9a08e7106..e9ea5ea69 100644 --- a/bluetooth/wifi_provisioner/CMakeLists.txt +++ b/bluetooth/wifi_provisioner/CMakeLists.txt @@ -16,17 +16,17 @@ target_link_libraries(wifi_prov_lib INTERFACE pico_btstack_make_gatt_header(wifi_prov_lib INTERFACE "${CMAKE_CURRENT_LIST_DIR}/provisioning.gatt") # Standalone example which uses the provisioning libary to allow credentials to be set over BLE -add_executable(wifi_provisioning_new +add_executable(wifi_provisioner example.c ) -target_link_libraries(wifi_provisioning_new +target_link_libraries(wifi_provisioner pico_stdlib wifi_prov_lib ) -target_include_directories(wifi_provisioning_new PRIVATE +target_include_directories(wifi_provisioner PRIVATE ${CMAKE_CURRENT_LIST_DIR} ${CMAKE_CURRENT_LIST_DIR}/.. # For our common btstack config ) -pico_add_extra_outputs(wifi_provisioning_new) +pico_add_extra_outputs(wifi_provisioner) diff --git a/bluetooth/wifi_provisioner/btstack_config.h b/bluetooth/wifi_provisioner/btstack_config.h index ce1919916..0dd0d82cb 100644 --- a/bluetooth/wifi_provisioner/btstack_config.h +++ b/bluetooth/wifi_provisioner/btstack_config.h @@ -1,6 +1,6 @@ #ifndef _PICO_BTSTACK_CONFIG_H #define _PICO_BTSTACK_CONFIG_H -#include "btstack_config_common.h" +#include "../config/btstack_config_common.h" #endif From 7ce8a14eb9eeffc65f9af6941d931da61d00c193 Mon Sep 17 00:00:00 2001 From: Peter Harper Date: Wed, 11 Mar 2026 14:42:50 +0000 Subject: [PATCH 08/13] Some changes to doorbell example --- bluetooth/doorbell/CMakeLists.txt | 6 ++-- bluetooth/doorbell/client.c | 55 ++++++++++++++++++------------- bluetooth/doorbell/server.c | 42 +++++++++++++++-------- 3 files changed, 64 insertions(+), 39 deletions(-) diff --git a/bluetooth/doorbell/CMakeLists.txt b/bluetooth/doorbell/CMakeLists.txt index 1242efdfb..6fbc8aa21 100644 --- a/bluetooth/doorbell/CMakeLists.txt +++ b/bluetooth/doorbell/CMakeLists.txt @@ -15,9 +15,8 @@ target_include_directories(doorbell_client PRIVATE ${CMAKE_CURRENT_LIST_DIR}/.. # For our common btstack config ) target_compile_definitions(doorbell_client PRIVATE - RUNNING_AS_CLIENT=1 + #WANT_HCI_DUMP=1 ) - pico_add_extra_outputs(doorbell_client) @@ -36,6 +35,9 @@ target_include_directories(doorbell_server PRIVATE ${CMAKE_CURRENT_LIST_DIR} ${CMAKE_CURRENT_LIST_DIR}/.. # For our common btstack config ) +target_compile_definitions(doorbell_server PRIVATE + #WANT_HCI_DUMP=1 +) pico_btstack_make_gatt_header(doorbell_server PRIVATE "${CMAKE_CURRENT_LIST_DIR}/doorbell.gatt") pico_add_extra_outputs(doorbell_server) diff --git a/bluetooth/doorbell/client.c b/bluetooth/doorbell/client.c index 89cece27c..9be502c78 100644 --- a/bluetooth/doorbell/client.c +++ b/bluetooth/doorbell/client.c @@ -9,11 +9,13 @@ #include "pico/cyw43_arch.h" #include "pico/stdlib.h" -#ifndef NDEBG +#ifndef NDEBUG #define DEBUG_LOG(...) printf(__VA_ARGS__) #else #define DEBUG_LOG(...) #endif +#define INFO_LOG printf +#define ERROR_LOG printf #define LED_QUICK_FLASH_DELAY_MS 100 #define LED_SLOW_FLASH_DELAY_MS 1000 @@ -42,8 +44,18 @@ static bool listener_registered; static gatt_client_notification_t notification_listener; static btstack_timer_source_t heartbeat; +static void doorbell_led_worker_fn(async_context_t *context, async_at_time_worker_t *worker) { + int val = (int)worker->user_data; + gpio_put(EXT_LED_GPIO_NUM, (val % 2) == 0); + if (val < 11) { + worker->user_data = (void*)(val + 1); + async_context_add_at_time_worker_in_ms(context, worker, 100); + } +} +static async_at_time_worker_t doorbell_led_worker = { .do_work = doorbell_led_worker_fn }; + static void client_start(void){ - DEBUG_LOG("Start scanning!\n"); + INFO_LOG("Start scanning!\n"); state = TC_W4_SCAN_RESULT; gap_set_scan_parameters(0,0x0030, 0x0030); gap_start_scan(); @@ -84,19 +96,18 @@ static void handle_gatt_client_event(uint8_t packet_type, uint16_t channel, uint switch(hci_event_packet_get_type(packet)) { case GATT_EVENT_SERVICE_QUERY_RESULT: // store service (we expect only one) - DEBUG_LOG("Storing service\n"); gatt_event_service_query_result_get_service(packet, &server_service); break; case GATT_EVENT_QUERY_COMPLETE: att_status = gatt_event_query_complete_get_att_status(packet); if (att_status != ATT_ERROR_SUCCESS){ - printf("SERVICE_QUERY_RESULT, ATT Error 0x%02x.\n", att_status); + ERROR_LOG("SERVICE_QUERY_RESULT, ATT Error 0x%02x.\n", att_status); gap_disconnect(connection_handle); break; } // service query complete, look for characteristic state = TC_W4_CHARACTERISTIC_RESULT; - DEBUG_LOG("Search for binary sensing characteristic.\n"); + INFO_LOG("Search for binary sensing characteristic.\n"); gatt_client_discover_characteristics_for_service_by_uuid16(handle_gatt_client_event, connection_handle, &server_service, ORG_BLUETOOTH_CHARACTERISTIC_DIGITAL_OUTPUT); break; default: @@ -106,13 +117,13 @@ static void handle_gatt_client_event(uint8_t packet_type, uint16_t channel, uint case TC_W4_CHARACTERISTIC_RESULT: switch(hci_event_packet_get_type(packet)) { case GATT_EVENT_CHARACTERISTIC_QUERY_RESULT: - DEBUG_LOG("Storing characteristic\n"); + INFO_LOG("Storing characteristic\n"); gatt_event_characteristic_query_result_get_characteristic(packet, &server_characteristic); break; case GATT_EVENT_QUERY_COMPLETE: att_status = gatt_event_query_complete_get_att_status(packet); if (att_status != ATT_ERROR_SUCCESS){ - printf("CHARACTERISTIC_QUERY_RESULT, ATT Error 0x%02x.\n", att_status); + ERROR_LOG("CHARACTERISTIC_QUERY_RESULT, ATT Error 0x%02x.\n", att_status); gap_disconnect(connection_handle); break; } @@ -120,7 +131,7 @@ static void handle_gatt_client_event(uint8_t packet_type, uint16_t channel, uint listener_registered = true; gatt_client_listen_for_characteristic_value_updates(¬ification_listener, handle_gatt_client_event, connection_handle, &server_characteristic); // enable notifications - DEBUG_LOG("Enable notify on characteristic.\n"); + INFO_LOG("Enable notify on characteristic.\n"); state = TC_W4_ENABLE_NOTIFICATIONS_COMPLETE; gatt_client_write_client_characteristic_configuration(handle_gatt_client_event, connection_handle, &server_characteristic, GATT_CLIENT_CHARACTERISTICS_CONFIGURATION_NOTIFICATION); @@ -132,7 +143,7 @@ static void handle_gatt_client_event(uint8_t packet_type, uint16_t channel, uint case TC_W4_ENABLE_NOTIFICATIONS_COMPLETE: switch(hci_event_packet_get_type(packet)) { case GATT_EVENT_QUERY_COMPLETE: - DEBUG_LOG("Notifications enabled, ATT status 0x%02x\n", gatt_event_query_complete_get_att_status(packet)); + INFO_LOG("Notifications enabled, ATT status 0x%02x\n", gatt_event_query_complete_get_att_status(packet)); if (gatt_event_query_complete_get_att_status(packet) != ATT_ERROR_SUCCESS) break; state = TC_W4_READY; break; @@ -145,28 +156,26 @@ static void handle_gatt_client_event(uint8_t packet_type, uint16_t channel, uint case GATT_EVENT_NOTIFICATION: { uint16_t value_length = gatt_event_notification_get_value_length(packet); const uint8_t *value = gatt_event_notification_get_value(packet); - - DEBUG_LOG("Indication value len %d\n", value_length); if (value_length == 2) { uint state = little_endian_read_16(value, 0); - printf("recieved state %d \n", state); - // flash LED - for (int i = 1; i < 11; i++) { - gpio_put(EXT_LED_GPIO_NUM, i%2); - busy_wait_ms(100); + INFO_LOG("Doorbell state %d \n", state); + if (state) { + // flash LED + doorbell_led_worker.user_data = 0; + async_context_add_at_time_worker_in_ms(cyw43_arch_async_context(), &doorbell_led_worker, 0); } } else { - printf("Unexpected length %d\n", value_length); + ERROR_LOG("Unexpected length %d\n", value_length); } break; } default: - printf("Unknown packet type 0x%02x\n", hci_event_packet_get_type(packet)); + ERROR_LOG("Unknown packet type 0x%02x\n", hci_event_packet_get_type(packet)); break; } break; default: - printf("Unknown state %d\n", state); + ERROR_LOG("Unknown state %d\n", state); break; } } @@ -182,7 +191,7 @@ static void hci_event_handler(uint8_t packet_type, uint16_t channel, uint8_t *pa case BTSTACK_EVENT_STATE: if (btstack_event_state_get_state(packet) == HCI_STATE_WORKING) { gap_local_bd_addr(local_addr); - printf("BTstack up and running on %s.\n", bd_addr_to_str(local_addr)); + DEBUG_LOG("BTstack up and running on %s.\n", bd_addr_to_str(local_addr)); client_start(); } else { state = TC_OFF; @@ -198,7 +207,7 @@ static void hci_event_handler(uint8_t packet_type, uint16_t channel, uint8_t *pa // stop scanning, and connect to the device state = TC_W4_CONNECT; gap_stop_scan(); - printf("Connecting to device with addr %s.\n", bd_addr_to_str(server_addr)); + DEBUG_LOG("Connecting to device with addr %s.\n", bd_addr_to_str(server_addr)); gap_connect(server_addr, server_addr_type); break; case HCI_EVENT_LE_META: @@ -224,7 +233,7 @@ static void hci_event_handler(uint8_t packet_type, uint16_t channel, uint8_t *pa listener_registered = false; gatt_client_stop_listening_for_characteristic_value_updates(¬ification_listener); } - printf("Disconnected %s\n", bd_addr_to_str(server_addr)); + DEBUG_LOG("Disconnected %s\n", bd_addr_to_str(server_addr)); if (state == TC_OFF) break; client_start(); break; @@ -260,7 +269,7 @@ int main() { // initialize CYW43 driver architecture (will enable BT if/because CYW43_ENABLE_BLUETOOTH == 1) if (cyw43_arch_init()) { - printf("failed to initialise cyw43_arch\n"); + ERROR_LOG("failed to initialise cyw43_arch\n"); return -1; } diff --git a/bluetooth/doorbell/server.c b/bluetooth/doorbell/server.c index f06955d29..b762296c1 100644 --- a/bluetooth/doorbell/server.c +++ b/bluetooth/doorbell/server.c @@ -15,12 +15,13 @@ #define HEARTBEAT_PERIOD_MS 1000 #define APP_AD_FLAGS 0x06 - -#define BUTTON_IRQ_DEBOUNCE_MS 500 #define BUTTON_GPIO_NUM 15 -// initialise time for button debouncing -static int last_time = 0; +#ifndef NDEBUG +#define DEBUG_LOG printf +#else +#define DEBUG_LOG(...) +#endif static uint8_t adv_data[] = { // Flags general discoverable @@ -32,9 +33,9 @@ static uint8_t adv_data[] = { static const uint8_t adv_data_len = sizeof(adv_data); -static int le_notification_enabled; -static hci_con_handle_t con_handle; +static bool le_notification_enabled; static uint16_t current_state; +static hci_con_handle_t con_handle; extern uint8_t const profile_data[]; static btstack_timer_source_t heartbeat; @@ -51,7 +52,7 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe case BTSTACK_EVENT_STATE: if (btstack_event_state_get_state(packet) != HCI_STATE_WORKING) return; gap_local_bd_addr(local_addr); - printf("BTstack up and running on %s.\n", bd_addr_to_str(local_addr)); + DEBUG_LOG("BTstack up and running on %s.\n", bd_addr_to_str(local_addr)); // setup advertisements uint16_t adv_int_min = 800; @@ -94,23 +95,36 @@ static int att_write_callback(hci_con_handle_t connection_handle, uint16_t att_h if (att_handle != ATT_CHARACTERISTIC_ORG_BLUETOOTH_CHARACTERISTIC_DIGITAL_OUTPUT_01_CLIENT_CONFIGURATION_HANDLE) return 0; le_notification_enabled = little_endian_read_16(buffer, 0) == GATT_CLIENT_CHARACTERISTICS_CONFIGURATION_NOTIFICATION; con_handle = connection_handle; + DEBUG_LOG("att_write_callback notifications enabled %d\n", le_notification_enabled); if (le_notification_enabled) { att_server_request_can_send_now_event(con_handle); } return 0; } +static void doorbell_notification_fn(__unused void * arg) { + att_server_request_can_send_now_event(con_handle); +} +static btstack_context_callback_registration_t doorbell_notification = { .callback = doorbell_notification_fn }; static void button_irq_handler(uint gpio, uint32_t events) { - // button debounce handling - ignore any additional presses for BUTTON_IRQ_DEBOUNCE_MS after first press - int time_now = to_ms_since_boot(get_absolute_time()); - if ((time_now - last_time) > BUTTON_IRQ_DEBOUNCE_MS && le_notification_enabled) { - last_time = time_now; - att_server_request_can_send_now_event(con_handle); + uint16_t new_state = 0; + if (events & GPIO_IRQ_EDGE_FALL) new_state = 1; + if (events & GPIO_IRQ_EDGE_RISE) new_state = 0; + if (current_state != new_state) { + current_state = new_state; + DEBUG_LOG("button_irq_handler state %u notifications enabled %d\n", current_state, le_notification_enabled); + if (le_notification_enabled) { + // We want to call att_server_request_can_send_now_event, + // but we are in an IRQ and so it's dangerous to call BTStack directly from here. + // So we ask BTstack to callback a function from the "main thread" + // We could also use an async (when pending) worker using async_when_pending_worker_t, + // async_context_add_when_pending_worker and async_context_set_work_pending + btstack_run_loop_execute_on_main_thread(&doorbell_notification); + } } } - static void heartbeat_handler(struct btstack_timer_source *ts) { static uint32_t counter = 0; counter++; @@ -131,7 +145,7 @@ int main() { gpio_init(BUTTON_GPIO_NUM); gpio_set_dir(BUTTON_GPIO_NUM, GPIO_IN); gpio_pull_up(BUTTON_GPIO_NUM); - gpio_set_irq_enabled_with_callback(BUTTON_GPIO_NUM, GPIO_IRQ_EDGE_FALL, true, &button_irq_handler); + gpio_set_irq_enabled_with_callback(BUTTON_GPIO_NUM, GPIO_IRQ_EDGE_FALL|GPIO_IRQ_EDGE_RISE, true, &button_irq_handler); // initialize CYW43 driver architecture (will enable BT if/because CYW43_ENABLE_BLUETOOTH == 1) if (cyw43_arch_init()) { From 572e1d55def5383c7249492c9de90612061b85f5 Mon Sep 17 00:00:00 2001 From: Peter Harper Date: Wed, 11 Mar 2026 14:57:33 +0000 Subject: [PATCH 09/13] Temp sensor example changes --- bluetooth/temp_sensor/CMakeLists.txt | 46 ++++++++++++++++++- bluetooth/temp_sensor/README.md | 7 ++- .../temp_sensor/{client => }/btstack_config.h | 2 +- bluetooth/temp_sensor/{client => }/client.c | 25 +++++----- bluetooth/temp_sensor/client/CMakeLists.txt | 23 ---------- bluetooth/temp_sensor/{server => }/server.c | 0 bluetooth/temp_sensor/server/CMakeLists.txt | 20 -------- bluetooth/temp_sensor/server/btstack_config.h | 6 --- .../temp_sensor/{server => }/temp_sensor.gatt | 0 9 files changed, 64 insertions(+), 65 deletions(-) rename bluetooth/temp_sensor/{client => }/btstack_config.h (59%) rename bluetooth/temp_sensor/{client => }/client.c (92%) delete mode 100644 bluetooth/temp_sensor/client/CMakeLists.txt rename bluetooth/temp_sensor/{server => }/server.c (100%) delete mode 100644 bluetooth/temp_sensor/server/CMakeLists.txt delete mode 100644 bluetooth/temp_sensor/server/btstack_config.h rename bluetooth/temp_sensor/{server => }/temp_sensor.gatt (100%) diff --git a/bluetooth/temp_sensor/CMakeLists.txt b/bluetooth/temp_sensor/CMakeLists.txt index ef03fe482..93b5ebc96 100644 --- a/bluetooth/temp_sensor/CMakeLists.txt +++ b/bluetooth/temp_sensor/CMakeLists.txt @@ -1,2 +1,44 @@ -add_subdirectory(client) -add_subdirectory(server) +# Example that reads from the on board temperature sensor and sends notifications via BLE +# Flashes slowly each second to show it's running +add_executable(temp_server + server.c + ) +target_link_libraries(temp_server + pico_stdlib + pico_btstack_ble + pico_btstack_cyw43 + pico_cyw43_arch_none + hardware_adc + ) +target_include_directories(temp_server PRIVATE + ${CMAKE_CURRENT_LIST_DIR} # For our btstack config + ) +target_compile_definitions(temp_server PRIVATE + #WANT_HCI_DUMP=1 +) +pico_btstack_make_gatt_header(temp_server PRIVATE "${CMAKE_CURRENT_LIST_DIR}/temp_sensor.gatt") + +pico_add_extra_outputs(temp_server) +example_auto_set_url(temp_server) + +# Example that connects to temp_server and reads the temperature +# Flashes once quickly each second when it's running but not connected to another device +# Flashes twice quickly each second when connected to another device and reading it's temperature +add_executable(temp_reader + client.c + ) +target_link_libraries(temp_reader + pico_stdlib + pico_btstack_ble + pico_btstack_cyw43 + pico_cyw43_arch_none + hardware_adc + ) +target_include_directories(temp_reader PRIVATE + ${CMAKE_CURRENT_LIST_DIR} # For our btstack config + ) +target_compile_definitions(temp_reader PRIVATE + #WANT_HCI_DUMP=1 +) +pico_add_extra_outputs(temp_reader) +example_auto_set_url(temp_reader) diff --git a/bluetooth/temp_sensor/README.md b/bluetooth/temp_sensor/README.md index 86a68cf2d..f0d321120 100644 --- a/bluetooth/temp_sensor/README.md +++ b/bluetooth/temp_sensor/README.md @@ -1,3 +1,6 @@ -### Secure temp sensor +### Temp sensor -This example uses BLE to communicate temperature between a pair of pico Ws. It reads temperature by measuring some onboard voltage and applying a conversion factor. \ No newline at end of file +This example uses BLE to communicate temperature between a pair of pico Ws. It reads temperature by measuring some onboard voltage and applying a conversion factor. + +temp_server is a peripheral or server that transmits its temperature to another device +temp_reader is a client that reads a temperature from another device \ No newline at end of file diff --git a/bluetooth/temp_sensor/client/btstack_config.h b/bluetooth/temp_sensor/btstack_config.h similarity index 59% rename from bluetooth/temp_sensor/client/btstack_config.h rename to bluetooth/temp_sensor/btstack_config.h index 191387520..0dd0d82cb 100644 --- a/bluetooth/temp_sensor/client/btstack_config.h +++ b/bluetooth/temp_sensor/btstack_config.h @@ -1,6 +1,6 @@ #ifndef _PICO_BTSTACK_CONFIG_H #define _PICO_BTSTACK_CONFIG_H -#include "../../config/btstack_config_common.h" +#include "../config/btstack_config_common.h" #endif diff --git a/bluetooth/temp_sensor/client/client.c b/bluetooth/temp_sensor/client.c similarity index 92% rename from bluetooth/temp_sensor/client/client.c rename to bluetooth/temp_sensor/client.c index ca515ae3a..bbd9f7816 100644 --- a/bluetooth/temp_sensor/client/client.c +++ b/bluetooth/temp_sensor/client.c @@ -9,11 +9,13 @@ #include "pico/cyw43_arch.h" #include "pico/stdlib.h" -#if 0 +#ifndef NDEBUG #define DEBUG_LOG(...) printf(__VA_ARGS__) #else #define DEBUG_LOG(...) #endif +#define INFO_LOG printf +#define ERROR_LOG printf #define LED_QUICK_FLASH_DELAY_MS 100 #define LED_SLOW_FLASH_DELAY_MS 1000 @@ -88,7 +90,7 @@ static void handle_gatt_client_event(uint8_t packet_type, uint16_t channel, uint case GATT_EVENT_QUERY_COMPLETE: att_status = gatt_event_query_complete_get_att_status(packet); if (att_status != ATT_ERROR_SUCCESS){ - printf("SERVICE_QUERY_RESULT, ATT Error 0x%02x.\n", att_status); + ERROR_LOG("SERVICE_QUERY_RESULT, ATT Error 0x%02x.\n", att_status); gap_disconnect(connection_handle); break; } @@ -110,7 +112,7 @@ static void handle_gatt_client_event(uint8_t packet_type, uint16_t channel, uint case GATT_EVENT_QUERY_COMPLETE: att_status = gatt_event_query_complete_get_att_status(packet); if (att_status != ATT_ERROR_SUCCESS){ - printf("CHARACTERISTIC_QUERY_RESULT, ATT Error 0x%02x.\n", att_status); + ERROR_LOG("CHARACTERISTIC_QUERY_RESULT, ATT Error 0x%02x.\n", att_status); gap_disconnect(connection_handle); break; } @@ -146,19 +148,20 @@ static void handle_gatt_client_event(uint8_t packet_type, uint16_t channel, uint DEBUG_LOG("Indication value len %d\n", value_length); if (value_length == 2) { float temp = little_endian_read_16(value, 0); - printf("read temp %.2f degc\n", temp / 100); + INFO_LOG("Read temp %.2f degc\n", temp / 100); } else { - printf("Unexpected length %d\n", value_length); + ERROR_LOG("Unexpected length %d\n", value_length); } break; } default: - printf("Unknown packet type 0x%02x\n", hci_event_packet_get_type(packet)); + ERROR_LOG("Unknown packet type 0x%02x\n", hci_event_packet_get_type(packet)); break; } break; default: - printf("error\n"); + assert(false); + ERROR_LOG("Unexpected state %d\n", state); break; } } @@ -174,7 +177,7 @@ static void hci_event_handler(uint8_t packet_type, uint16_t channel, uint8_t *pa case BTSTACK_EVENT_STATE: if (btstack_event_state_get_state(packet) == HCI_STATE_WORKING) { gap_local_bd_addr(local_addr); - printf("BTstack up and running on %s.\n", bd_addr_to_str(local_addr)); + DEBUG_LOG("BTstack up and running on %s.\n", bd_addr_to_str(local_addr)); client_start(); } else { state = TC_OFF; @@ -190,7 +193,7 @@ static void hci_event_handler(uint8_t packet_type, uint16_t channel, uint8_t *pa // stop scanning, and connect to the device state = TC_W4_CONNECT; gap_stop_scan(); - printf("Connecting to device with addr %s.\n", bd_addr_to_str(server_addr)); + INFO_LOG("Connecting to device with addr %s.\n", bd_addr_to_str(server_addr)); gap_connect(server_addr, server_addr_type); break; case HCI_EVENT_LE_META: @@ -216,7 +219,7 @@ static void hci_event_handler(uint8_t packet_type, uint16_t channel, uint8_t *pa listener_registered = false; gatt_client_stop_listening_for_characteristic_value_updates(¬ification_listener); } - printf("Disconnected %s\n", bd_addr_to_str(server_addr)); + INFO_LOG("Disconnected %s\n", bd_addr_to_str(server_addr)); if (state == TC_OFF) break; client_start(); break; @@ -248,7 +251,7 @@ int main() { // initialize CYW43 driver architecture (will enable BT if/because CYW43_ENABLE_BLUETOOTH == 1) if (cyw43_arch_init()) { - printf("failed to initialise cyw43_arch\n"); + ERROR_LOG("failed to initialise cyw43_arch\n"); return -1; } diff --git a/bluetooth/temp_sensor/client/CMakeLists.txt b/bluetooth/temp_sensor/client/CMakeLists.txt deleted file mode 100644 index 67ab5d041..000000000 --- a/bluetooth/temp_sensor/client/CMakeLists.txt +++ /dev/null @@ -1,23 +0,0 @@ -# Standalone example that connects to picow_ble_temp_sensor and reads the temperature -# Flahes once quickly each second when it's running but not connected to another device -# Flashes twice quickly each second when connected to another device and reading it's temperature -add_executable(picow_ble_temp_reader - client.c - ) -target_link_libraries(picow_ble_temp_reader - pico_stdlib - pico_btstack_ble - pico_btstack_cyw43 - pico_cyw43_arch_none - hardware_adc - ) -target_include_directories(picow_ble_temp_reader PRIVATE - ${CMAKE_CURRENT_LIST_DIR} - ${CMAKE_CURRENT_LIST_DIR}/../.. # For our common btstack config - ) -target_compile_definitions(picow_ble_temp_reader PRIVATE - RUNNING_AS_CLIENT=1 -) - -pico_add_extra_outputs(picow_ble_temp_reader) -example_auto_set_url(picow_ble_temp_reader) diff --git a/bluetooth/temp_sensor/server/server.c b/bluetooth/temp_sensor/server.c similarity index 100% rename from bluetooth/temp_sensor/server/server.c rename to bluetooth/temp_sensor/server.c diff --git a/bluetooth/temp_sensor/server/CMakeLists.txt b/bluetooth/temp_sensor/server/CMakeLists.txt deleted file mode 100644 index 30cb69c26..000000000 --- a/bluetooth/temp_sensor/server/CMakeLists.txt +++ /dev/null @@ -1,20 +0,0 @@ -# Standalone example that reads from the on board temperature sensor and sends notifications via BLE -# Flashes slowly each second to show it's running -add_executable(picow_ble_temp_sensor - server.c - ) -target_link_libraries(picow_ble_temp_sensor - pico_stdlib - pico_btstack_ble - pico_btstack_cyw43 - pico_cyw43_arch_none - hardware_adc - ) -target_include_directories(picow_ble_temp_sensor PRIVATE - ${CMAKE_CURRENT_LIST_DIR} - ${CMAKE_CURRENT_LIST_DIR}/../.. # For our common btstack config - ) -pico_btstack_make_gatt_header(picow_ble_temp_sensor PRIVATE "${CMAKE_CURRENT_LIST_DIR}/temp_sensor.gatt") - -pico_add_extra_outputs(picow_ble_temp_sensor) -example_auto_set_url(picow_ble_temp_sensor) diff --git a/bluetooth/temp_sensor/server/btstack_config.h b/bluetooth/temp_sensor/server/btstack_config.h deleted file mode 100644 index 191387520..000000000 --- a/bluetooth/temp_sensor/server/btstack_config.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _PICO_BTSTACK_CONFIG_H -#define _PICO_BTSTACK_CONFIG_H - -#include "../../config/btstack_config_common.h" - -#endif diff --git a/bluetooth/temp_sensor/server/temp_sensor.gatt b/bluetooth/temp_sensor/temp_sensor.gatt similarity index 100% rename from bluetooth/temp_sensor/server/temp_sensor.gatt rename to bluetooth/temp_sensor/temp_sensor.gatt From 2461c4c5f6e204ef2a0d6a66d3c9e67225a3daa8 Mon Sep 17 00:00:00 2001 From: Peter Harper Date: Thu, 12 Mar 2026 00:09:46 +0000 Subject: [PATCH 10/13] secure temp sensor fixes --- bluetooth/secure_temp_sensor/CMakeLists.txt | 74 ++++-- bluetooth/secure_temp_sensor/README.md | 28 ++- bluetooth/secure_temp_sensor/btstack_config.h | 3 - bluetooth/secure_temp_sensor/client.c | 215 ++++++++++++------ bluetooth/secure_temp_sensor/server.c | 167 +++++++++----- 5 files changed, 338 insertions(+), 149 deletions(-) diff --git a/bluetooth/secure_temp_sensor/CMakeLists.txt b/bluetooth/secure_temp_sensor/CMakeLists.txt index 5f62c4745..82aa02c53 100644 --- a/bluetooth/secure_temp_sensor/CMakeLists.txt +++ b/bluetooth/secure_temp_sensor/CMakeLists.txt @@ -1,42 +1,74 @@ +# Select a security setting to explore the BLE security +# +# security setting 0: Just works (pairing), no MITM (Man In The Middle) protection +# client and server have no input or output support +# +# security setting 1: Numeric comparison with MITM protection +# client can query yes or no from the user, server has a display only +# server displays passkey +# client displays passkey and user can select Yes or No if they agree the passkey is from the server +# +# security setting 2: +# client has a keyboard and display, server has a display only +# server displays passkey +# client user enters the passkey displayed by the server +# +# security setting 3: +# client has a display only, server has a display and keyboard +# Client displays passkey +# server user enters the passkey displayed by the server +if (NOT DEFINED SECURITY_SETTING) + set(SECURITY_SETTING 1) +endif() + # Standalone example that reads from the on board temperature sensor and sends notifications via BLE # Flashes slowly each second to show it's running -add_executable(secure_temp_sensor +add_executable(secure_temp_server server.c - ) -target_link_libraries(secure_temp_sensor +) +target_link_libraries(secure_temp_server pico_stdlib pico_btstack_ble pico_btstack_cyw43 pico_cyw43_arch_none hardware_adc - ) -target_include_directories(secure_temp_sensor PRIVATE - ${CMAKE_CURRENT_LIST_DIR} - ${CMAKE_CURRENT_LIST_DIR}/.. # For our common btstack config - ) -pico_btstack_make_gatt_header(secure_temp_sensor PRIVATE "${CMAKE_CURRENT_LIST_DIR}/temp_sensor.gatt") - -pico_add_extra_outputs(secure_temp_sensor) +) +target_include_directories(secure_temp_server PRIVATE + ${CMAKE_CURRENT_LIST_DIR} # For our btstack config +) +target_compile_definitions(secure_temp_server PRIVATE + # Wait up to 3s for stdio USB to initialise, to avoid losing any debug on startup + PICO_STDIO_USB_CONNECT_WAIT_TIMEOUT_MS=3000 + SECURITY_SETTING=${SECURITY_SETTING} + #WANT_HCI_DUMP=1 +) +pico_btstack_make_gatt_header(secure_temp_server PRIVATE "${CMAKE_CURRENT_LIST_DIR}/temp_sensor.gatt") +pico_add_extra_outputs(secure_temp_server) +pico_enable_stdio_usb(secure_temp_server 1) +pico_enable_stdio_uart(secure_temp_server 1) -# Standalone example that connects to secure_temp_sensor and reads the temperature +# Standalone example that connects to secure_temp_server and reads the temperature # Flahes once quickly each second when it's running but not connected to another device # Flashes twice quickly each second when connected to another device and reading it's temperature -add_executable(secure_temp_reader +add_executable(secure_temp_client client.c ) -target_link_libraries(secure_temp_reader +target_link_libraries(secure_temp_client pico_stdlib pico_btstack_ble pico_btstack_cyw43 pico_cyw43_arch_none hardware_adc ) -target_include_directories(secure_temp_reader PRIVATE - ${CMAKE_CURRENT_LIST_DIR} - ${CMAKE_CURRENT_LIST_DIR}/.. # For our common btstack config +target_include_directories(secure_temp_client PRIVATE + ${CMAKE_CURRENT_LIST_DIR} # For our btstack config ) -target_compile_definitions(secure_temp_reader PRIVATE - RUNNING_AS_CLIENT=1 +target_compile_definitions(secure_temp_client PRIVATE + # Wait up to 3s for stdio USB to initialise, to avoid losing any debug on startup + PICO_STDIO_USB_CONNECT_WAIT_TIMEOUT_MS=3000 + SECURITY_SETTING=${SECURITY_SETTING} + #WANT_HCI_DUMP=1 ) - -pico_add_extra_outputs(secure_temp_reader) \ No newline at end of file +pico_add_extra_outputs(secure_temp_client) +pico_enable_stdio_usb(secure_temp_client 1) +pico_enable_stdio_uart(secure_temp_client 1) diff --git a/bluetooth/secure_temp_sensor/README.md b/bluetooth/secure_temp_sensor/README.md index a2c13f59c..9fa185202 100644 --- a/bluetooth/secure_temp_sensor/README.md +++ b/bluetooth/secure_temp_sensor/README.md @@ -2,9 +2,27 @@ This example uses BLE to communicate temperature between a pair of pico Ws. This example is a variant of temp sensor, using LE secure to provide a secure connection. -In server.c and client.c there is a variable security_setting which you can change to explore different security options: +secure_temp_server is a peripheral or server that transmits its temperature to another device +secure_temp_client is a client that reads a temperature from another device -Security setting 0: Just works (pairing), no MITM protection -Security setting 1: Numeric comparison -Security setting 2: Peripheral displays passkey, client enters passkey -Security setting 3: Client displays passkey, peripheral enters passkey \ No newline at end of file +In server.c and client.c there is a define SECURITY_SETTING which you can change to explore different security options: + +security setting 0: Just works (pairing), no MITM (Man In The Middle) protection + client and server have no input or output support + +security setting 1: Numeric comparison with MITM protection + client can query yes or no from the user, server has a display only + server displays passkey + client displays passkey and user can select Yes or No if they agree the passkey is from the server + +security setting 2: + client has a keyboard and display, server has a display only + server displays passkey + client user enters the passkey displayed by the server + +security setting 3: + client has a display only, server has a display and keyboard + Client displays passkey + server user enters the passkey displayed by the server + +You will need to use the console with both devices to see the passkeys and answer security prompts. Both stdio over UART and USB are enabled so you can use either. diff --git a/bluetooth/secure_temp_sensor/btstack_config.h b/bluetooth/secure_temp_sensor/btstack_config.h index c0f0f01d3..0dd0d82cb 100644 --- a/bluetooth/secure_temp_sensor/btstack_config.h +++ b/bluetooth/secure_temp_sensor/btstack_config.h @@ -3,7 +3,4 @@ #include "../config/btstack_config_common.h" -// security -#define ENABLE_LE_SECURE_CONNECTIONS - #endif diff --git a/bluetooth/secure_temp_sensor/client.c b/bluetooth/secure_temp_sensor/client.c index 6f328641d..36b331139 100644 --- a/bluetooth/secure_temp_sensor/client.c +++ b/bluetooth/secure_temp_sensor/client.c @@ -11,11 +11,13 @@ #include "inttypes.h" #include "string.h" -#if 0 +#ifndef NDEBUG #define DEBUG_LOG(...) printf(__VA_ARGS__) #else #define DEBUG_LOG(...) #endif +#define INFO_LOG printf +#define ERROR_LOG printf #define LED_QUICK_FLASH_DELAY_MS 100 #define LED_SLOW_FLASH_DELAY_MS 1000 @@ -44,42 +46,51 @@ static gatt_client_notification_t notification_listener; static btstack_timer_source_t heartbeat; // Select a security setting to explore the BLE security -// security setting 0: Just works (pairing), no MITM protection -// security setting 1: Numeric comparison -// security setting 2: Peripheral displays passkey, client enters passkey -// security setting 3: Client displays passkey, peripheral enters passkey -static int security_setting = 1; +// +// security setting 0: Just works (pairing), no MITM (Man In The Middle) protection +// client and server have no input or output support +// +// security setting 1: Numeric comparison with MITM protection +// client can query yes or no from the user, server has a display only +// server generates and displays passkey +// client displays passkey and user can select Yes or No if they agree the passkey is from the server +// +// security setting 2: +// client has a keyboard and display, server has a display only +// server generates and displays passkey +// client user enters the passkey displayed by the server +// +// security setting 3: +// client has a display only, server has a display and keyboard +// Client generates and displays passkey +// server user enters the passkey displayed by the server +#ifndef SECURITY_SETTING +#define SECURITY_SETTING 1 +#endif static void configure_security(int security_setting) { - + DEBUG_LOG("Security setting %u selected.\n", security_setting); sm_set_secure_connections_only_mode(true); - switch (security_setting) { case 0: - printf("Security setting 0 selected. \n"); - sm_set_io_capabilities(IO_CAPABILITY_NO_INPUT_NO_OUTPUT); sm_set_authentication_requirements(SM_AUTHREQ_SECURE_CONNECTION); break; case 1: - printf("Security setting 1 selected. \n"); - sm_set_io_capabilities(IO_CAPABILITY_DISPLAY_YES_NO); sm_set_authentication_requirements(SM_AUTHREQ_SECURE_CONNECTION|SM_AUTHREQ_MITM_PROTECTION); break; case 2: - printf("Security setting 2 selected. \n"); - - sm_set_io_capabilities(IO_CAPABILITY_KEYBOARD_ONLY); + sm_set_io_capabilities(IO_CAPABILITY_KEYBOARD_DISPLAY); sm_set_authentication_requirements(SM_AUTHREQ_SECURE_CONNECTION|SM_AUTHREQ_MITM_PROTECTION); break; case 3: - printf("Security setting 3 selected. \n"); - sm_set_io_capabilities(IO_CAPABILITY_DISPLAY_ONLY); sm_set_authentication_requirements(SM_AUTHREQ_SECURE_CONNECTION|SM_AUTHREQ_MITM_PROTECTION); break; default: + assert(false); + ERROR_LOG("invalid security setting %u", security_setting); break; } } @@ -132,7 +143,7 @@ static void handle_gatt_client_event(uint8_t packet_type, uint16_t channel, uint case GATT_EVENT_QUERY_COMPLETE: att_status = gatt_event_query_complete_get_att_status(packet); if (att_status != ATT_ERROR_SUCCESS){ - printf("SERVICE_QUERY_RESULT, ATT Error 0x%02x.\n", att_status); + ERROR_LOG("SERVICE_QUERY_RESULT, ATT Error 0x%02x.\n", att_status); gap_disconnect(connection_handle); break; } @@ -154,7 +165,7 @@ static void handle_gatt_client_event(uint8_t packet_type, uint16_t channel, uint case GATT_EVENT_QUERY_COMPLETE: att_status = gatt_event_query_complete_get_att_status(packet); if (att_status != ATT_ERROR_SUCCESS){ - printf("CHARACTERISTIC_QUERY_RESULT, ATT Error 0x%02x.\n", att_status); + ERROR_LOG("CHARACTERISTIC_QUERY_RESULT, ATT Error 0x%02x.\n", att_status); gap_disconnect(connection_handle); break; } @@ -187,22 +198,22 @@ static void handle_gatt_client_event(uint8_t packet_type, uint16_t channel, uint case GATT_EVENT_NOTIFICATION: { uint16_t value_length = gatt_event_notification_get_value_length(packet); const uint8_t *value = gatt_event_notification_get_value(packet); - DEBUG_LOG("Indication value len %d\n", value_length); if (value_length == 2) { float temp = little_endian_read_16(value, 0); - printf("read temp %.2f degc\n", temp / 100); + INFO_LOG("read temp %.2f degc\n", temp / 100); } else { - printf("Unexpected length %d\n", value_length); + ERROR_LOG("Unexpected length %d\n", value_length); } break; } default: - printf("Unknown packet type 0x%02x\n", hci_event_packet_get_type(packet)); + ERROR_LOG("Unknown packet type 0x%02x\n", hci_event_packet_get_type(packet)); break; } break; default: - printf("error\n"); + assert(false); + ERROR_LOG("error bad state %u\n", state); break; } } @@ -220,7 +231,7 @@ static void hci_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *p case BTSTACK_EVENT_STATE: if (btstack_event_state_get_state(packet) == HCI_STATE_WORKING) { gap_local_bd_addr(local_addr); - printf("BTstack up and running on %s.\n", bd_addr_to_str(local_addr)); + DEBUG_LOG("BTstack up and running on %s.\n", bd_addr_to_str(local_addr)); client_start(); } else { state = TC_OFF; @@ -236,7 +247,7 @@ static void hci_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *p // stop scanning, and connect to the device state = TC_W4_CONNECT; gap_stop_scan(); - printf("Connecting to device with addr %s.\n", bd_addr_to_str(server_addr)); + DEBUG_LOG("Connecting to device with addr %s.\n", bd_addr_to_str(server_addr)); gap_connect(server_addr, server_addr_type); break; case HCI_EVENT_LE_META: @@ -259,26 +270,27 @@ static void hci_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *p // wait for connection complete if (hci_event_gap_meta_get_subevent_code(packet) != GAP_SUBEVENT_LE_CONNECTION_COMPLETE) break; con_handle = gap_subevent_le_connection_complete_get_connection_handle(packet); - printf("Connection complete\n"); + DEBUG_LOG("Connection complete\n"); sm_request_pairing(con_handle); break; case GATT_EVENT_QUERY_COMPLETE: status = gatt_event_query_complete_get_att_status(packet); switch (status){ case ATT_ERROR_INSUFFICIENT_ENCRYPTION: - printf("GATT Query result: Insufficient Encryption\n"); + ERROR_LOG("GATT Query result: Insufficient Encryption\n"); break; case ATT_ERROR_INSUFFICIENT_AUTHENTICATION: - printf("GATT Query result: Insufficient Authentication\n"); + ERROR_LOG("GATT Query result: Insufficient Authentication\n"); break; case ATT_ERROR_BONDING_INFORMATION_MISSING: - printf("GATT Query result: Bonding Information Missing\n"); + ERROR_LOG("GATT Query result: Bonding Information Missing\n"); break; case ATT_ERROR_SUCCESS: - printf("GATT Query result: OK\n"); + DEBUG_LOG("GATT Query result: OK\n"); break; default: - printf("GATT Query result: 0x%02x\n", gatt_event_query_complete_get_att_status(packet)); + assert(false); + ERROR_LOG("Unexpected GATT Query result: 0x%02x\n", gatt_event_query_complete_get_att_status(packet)); break; } break; @@ -289,7 +301,7 @@ static void hci_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *p listener_registered = false; gatt_client_stop_listening_for_characteristic_value_updates(¬ification_listener); } - printf("Disconnected %s\n", bd_addr_to_str(server_addr)); + DEBUG_LOG("Disconnected %s\n", bd_addr_to_str(server_addr)); if (state == TC_OFF) break; client_start(); break; @@ -298,6 +310,74 @@ static void hci_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *p } } +static uint32_t passkey_result; +static uint8_t passkey_type; +static hci_con_handle_t passkey_handle; + +// Send passkey result to BTStack +static void passkey_done_fn(__unused void * arg) { + switch (passkey_type) { + case SM_EVENT_NUMERIC_COMPARISON_REQUEST: { + if (passkey_result) { + DEBUG_LOG("SM_EVENT_NUMERIC_COMPARISON_REQUEST confirm\n"); + sm_numeric_comparison_confirm(passkey_handle); + } else { + DEBUG_LOG("SM_EVENT_NUMERIC_COMPARISON_REQUEST decline\n"); + sm_bonding_decline(passkey_handle); + } + break; + } + case SM_EVENT_PASSKEY_INPUT_NUMBER: { + DEBUG_LOG("SM_EVENT_PASSKEY_INPUT_NUMBER %u\n", passkey_result); + sm_passkey_input(passkey_handle, passkey_result); + break; + } + default: { + assert(false); // should not happen! + ERROR_LOG("passkey_done_fn: Unexpected passkey type %u\n", passkey_type); + break; + } + } +} +static btstack_context_callback_registration_t passkey_done = { .callback = passkey_done_fn }; + +// Handle a key press +static void passkey_press_callback(__unused void *user_data) { + int key = getchar_timeout_us(0); // get any pending key press but don't wait + switch (passkey_type) { + case SM_EVENT_NUMERIC_COMPARISON_REQUEST: { + if (key == 'y' || key == 'Y') { + passkey_result = 1; + } else { + passkey_result = 0; + } + // We want to call a BTStack function now, + // but we might be in an IRQ and so it's dangerous to call BTStack directly from here. + // So we ask BTstack to callback a function from the "main thread" + // We could also use an async (when pending) worker using async_when_pending_worker_t, + // async_context_add_when_pending_worker and async_context_set_work_pending + btstack_run_loop_execute_on_main_thread(&passkey_done); + break; + } + case SM_EVENT_PASSKEY_INPUT_NUMBER: { + if (key == 13) { + // See above comment + INFO_LOG("\n"); + btstack_run_loop_execute_on_main_thread(&passkey_done); + } else if (key >= '0' && key <= '9') { + INFO_LOG("%c", key); + passkey_result = (passkey_result * 10) + (key - '0'); + } + break; + } + default: { + assert(false); // should not happen! + ERROR_LOG("passkey_callback: Unexpected passkey type %u\n", passkey_type); + break; + } + } +} + static void sm_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ UNUSED(channel); UNUSED(size); @@ -309,75 +389,75 @@ static void sm_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *pa switch (hci_event_packet_get_type(packet)) { case SM_EVENT_JUST_WORKS_REQUEST: - printf("Just works requested\n"); + INFO_LOG("Just works requested\n"); sm_just_works_confirm(sm_event_just_works_request_get_handle(packet)); break; case SM_EVENT_NUMERIC_COMPARISON_REQUEST: - printf("Confirming numeric comparison: %"PRIu32"\n", sm_event_numeric_comparison_request_get_passkey(packet)); - printf("Do the numbers match? (y/n)\n"); - - char result[2]; - scanf(" %c", &result); - if (result[0] == 'y' || result[0] == 'Y') { - sm_numeric_comparison_confirm(sm_event_passkey_display_number_get_handle(packet)); - } else { - sm_bonding_decline(sm_event_passkey_display_number_get_handle(packet)); - } + // Ask the user if the passkey matches the number shown by the server + INFO_LOG("Confirming numeric comparison: %"PRIu32"\n", sm_event_numeric_comparison_request_get_passkey(packet)); + INFO_LOG("Is the server showing this number? (y/n)\n"); + // We want to "wait" for user input but we must not block, + // so use a stdio callback to tell us when characters are available + passkey_type = SM_EVENT_NUMERIC_COMPARISON_REQUEST; + passkey_handle = sm_event_passkey_display_number_get_handle(packet); + stdio_set_chars_available_callback(passkey_press_callback, NULL); break; case SM_EVENT_PASSKEY_DISPLAY_NUMBER: - printf("Display Passkey: %"PRIu32"\n", sm_event_passkey_display_number_get_passkey(packet)); + INFO_LOG("Displaying passkey: %"PRIu32"\n", sm_event_passkey_display_number_get_passkey(packet)); break; case SM_EVENT_PASSKEY_INPUT_NUMBER: - char passkey[7]; - - printf("Passkey Input requested \n"); - scanf("%6[^\n]", passkey); - int to_send = atoi(passkey); // convert passkey to int - - printf("Sending passkey %"PRIu32"\n", to_send); - sm_passkey_input(sm_event_passkey_input_number_get_handle(packet), to_send); + INFO_LOG("Enter the passkey shown by the server:\n"); + // We want to "wait" for user input but we must not block, + // so use a stdio callback to tell us when characters are available + passkey_result = 0; + passkey_type = SM_EVENT_PASSKEY_INPUT_NUMBER; + passkey_handle = sm_event_passkey_input_number_get_handle(packet); + stdio_set_chars_available_callback(passkey_press_callback, NULL); break; case SM_EVENT_PAIRING_STARTED: - printf("Pairing started\n"); + DEBUG_LOG("Pairing started\n"); break; case SM_EVENT_PAIRING_COMPLETE: + stdio_set_chars_available_callback(NULL, NULL); // stop key press notifications switch (sm_event_pairing_complete_get_status(packet)){ case ERROR_CODE_SUCCESS: - printf("Pairing complete, success\n"); + DEBUG_LOG("Pairing complete, success\n"); break; case ERROR_CODE_CONNECTION_TIMEOUT: - printf("Pairing failed, timeout\n"); + ERROR_LOG("Pairing failed, timeout\n"); break; case ERROR_CODE_REMOTE_USER_TERMINATED_CONNECTION: - printf("Pairing failed, disconnected\n"); + ERROR_LOG("Pairing failed, disconnected\n"); break; case ERROR_CODE_AUTHENTICATION_FAILURE: - printf("Pairing failed, authentication failure with reason = %u\n", sm_event_pairing_complete_get_reason(packet)); + ERROR_LOG("Pairing failed, authentication failure with reason = %u\n", sm_event_pairing_complete_get_reason(packet)); break; default: + assert(false); + ERROR_LOG("Unexpected pairing status %d\n", sm_event_pairing_complete_get_status(packet)); break; } break; case SM_EVENT_REENCRYPTION_STARTED: sm_event_reencryption_complete_get_address(packet, addr); - printf("Bonding information exists for addr type %u, identity addr %s -> start re-encryption\n", + DEBUG_LOG("Bonding information exists for addr type %u, identity addr %s -> start re-encryption\n", sm_event_reencryption_started_get_addr_type(packet), bd_addr_to_str(addr)); break; case SM_EVENT_REENCRYPTION_COMPLETE: switch (sm_event_reencryption_complete_get_status(packet)){ case ERROR_CODE_SUCCESS: - printf("Re-encryption complete, success\n"); + DEBUG_LOG("Re-encryption complete, success\n"); break; case ERROR_CODE_CONNECTION_TIMEOUT: - printf("Re-encryption failed, timeout\n"); + ERROR_LOG("Re-encryption failed, timeout\n"); break; case ERROR_CODE_REMOTE_USER_TERMINATED_CONNECTION: - printf("Re-encryption failed, disconnected\n"); + ERROR_LOG("Re-encryption failed, disconnected\n"); break; case ERROR_CODE_PIN_OR_KEY_MISSING: - printf("Re-encryption failed, bonding information missing\n\n"); - printf("Assuming remote lost bonding information\n"); - printf("Deleting local bonding information and start new pairing...\n"); + ERROR_LOG("Re-encryption failed, bonding information missing\n\n"); + ERROR_LOG("Assuming remote lost bonding information\n"); + ERROR_LOG("Deleting local bonding information and start new pairing...\n"); sm_event_reencryption_complete_get_address(packet, addr); addr_type = sm_event_reencryption_started_get_addr_type(packet); gap_delete_bonding(addr_type, addr); @@ -415,13 +495,12 @@ int main() { // initialize CYW43 driver architecture (will enable BT if/because CYW43_ENABLE_BLUETOOTH == 1) if (cyw43_arch_init()) { - printf("failed to initialise cyw43_arch\n"); + ERROR_LOG("failed to initialise cyw43_arch\n"); return -1; } l2cap_init(); sm_init(); - sm_set_io_capabilities(IO_CAPABILITY_NO_INPUT_NO_OUTPUT); // setup empty ATT server - only needed if LE Peripheral does ATT queries on its own, e.g. Android and iOS att_server_init(NULL, NULL, NULL); @@ -435,7 +514,7 @@ int main() { sm_add_event_handler(&sm_event_callback_registration); // apply security configuration settings - configure_security(security_setting); + configure_security(SECURITY_SETTING); // set one-shot btstack timer heartbeat.process = &heartbeat_handler; diff --git a/bluetooth/secure_temp_sensor/server.c b/bluetooth/secure_temp_sensor/server.c index c85d1269f..42e9ac1eb 100644 --- a/bluetooth/secure_temp_sensor/server.c +++ b/bluetooth/secure_temp_sensor/server.c @@ -14,6 +14,14 @@ #include #include +#ifndef NDEBUG +#define DEBUG_LOG(...) printf(__VA_ARGS__) +#else +#define DEBUG_LOG(...) +#endif +#define INFO_LOG printf +#define ERROR_LOG printf + #define HEARTBEAT_PERIOD_MS 1000 #define ADC_CHANNEL_TEMPSENSOR 4 @@ -39,42 +47,51 @@ static btstack_packet_callback_registration_t hci_event_callback_registration; static btstack_packet_callback_registration_t sm_event_callback_registration; // Select a security setting to explore the BLE security -// security setting 0: Just works (pairing), no MITM protection -// security setting 1: Numeric comparison -// security setting 2: Peripheral displays passkey, client enters passkey -// security setting 3: Client displays passkey, peripheral enters passkey -static int security_setting = 1; +// +// security setting 0: Just works (pairing), no MITM (Man In The Middle) protection +// client and server have no input or output support +// +// security setting 1: Numeric comparison with MITM protection +// client can query yes or no from the user, server has a display only +// server generates and displays passkey +// client displays passkey and user can select Yes or No if they agree the passkey is from the server +// +// security setting 2: +// client has a keyboard and display, server has a display only +// server generates and displays passkey +// client user enters the passkey displayed by the server +// +// security setting 3: +// client has a display only, server has a display and keyboard +// Client generates and displays passkey +// server user enters the passkey displayed by the server +#ifndef SECURITY_SETTING +#define SECURITY_SETTING 1 +#endif static void configure_security(int security_setting) { - + DEBUG_LOG("Security setting %u selected.\n", security_setting); sm_set_secure_connections_only_mode(true); - switch (security_setting) { case 0: - printf("Security setting 0 selected. \n"); - sm_set_io_capabilities(IO_CAPABILITY_NO_INPUT_NO_OUTPUT); sm_set_authentication_requirements(SM_AUTHREQ_SECURE_CONNECTION); break; case 1: - printf("Security setting 1 selected. \n"); - sm_set_io_capabilities(IO_CAPABILITY_DISPLAY_YES_NO); sm_set_authentication_requirements(SM_AUTHREQ_SECURE_CONNECTION|SM_AUTHREQ_MITM_PROTECTION); break; case 2: - printf("Security setting 2 selected. \n"); - sm_set_io_capabilities(IO_CAPABILITY_DISPLAY_ONLY); sm_set_authentication_requirements(SM_AUTHREQ_SECURE_CONNECTION|SM_AUTHREQ_MITM_PROTECTION); break; case 3: - printf("Security setting 3 selected. \n"); - sm_set_io_capabilities(IO_CAPABILITY_KEYBOARD_ONLY); sm_set_authentication_requirements(SM_AUTHREQ_SECURE_CONNECTION|SM_AUTHREQ_MITM_PROTECTION); break; default: + assert(false); + ERROR_LOG("invalid security setting %u", security_setting); break; } } @@ -90,7 +107,7 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe case BTSTACK_EVENT_STATE: if (btstack_event_state_get_state(packet) != HCI_STATE_WORKING) return; gap_local_bd_addr(local_addr); - printf("BTstack up and running on %s.\n", bd_addr_to_str(local_addr)); + DEBUG_LOG("BTstack up and running on %s.\n", bd_addr_to_str(local_addr)); // setup advertisements uint16_t adv_int_min = 800; @@ -117,6 +134,50 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe } } +static uint32_t passkey_result; +static uint8_t passkey_type; +static hci_con_handle_t passkey_handle; + +// Send passkey result to BTStack +static void passkey_done_fn(__unused void * arg) { + switch (passkey_type) { + case SM_EVENT_PASSKEY_INPUT_NUMBER: { + DEBUG_LOG("SM_EVENT_PASSKEY_INPUT_NUMBER %u\n", passkey_result); + sm_passkey_input(passkey_handle, passkey_result); + break; + } + default: { + assert(false); // should not happen! + ERROR_LOG("passkey_done_fn: Unexpected passkey type %u\n", passkey_type); + break; + } + } +} +static btstack_context_callback_registration_t passkey_done = { .callback = passkey_done_fn }; + +// Handle a key press +static void passkey_press_callback(__unused void *user_data) { + int key = getchar_timeout_us(0); // get any pending key press but don't wait + switch (passkey_type) { + case SM_EVENT_PASSKEY_INPUT_NUMBER: { + if (key == 13) { + // See above comment + INFO_LOG("\n"); + btstack_run_loop_execute_on_main_thread(&passkey_done); + } else if (key >= '0' && key <= '9') { + INFO_LOG("%c", key); + passkey_result = (passkey_result * 10) + (key - '0'); + } + break; + } + default: { + assert(false); // should not happen! + ERROR_LOG("passkey_callback: Unexpected passkey type %u\n", passkey_type); + break; + } + } +} + static void sm_packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ UNUSED(channel); UNUSED(size); @@ -132,7 +193,7 @@ static void sm_packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *p case HCI_EVENT_META_GAP: switch (hci_event_gap_meta_get_subevent_code(packet)) { case GAP_SUBEVENT_LE_CONNECTION_COMPLETE: - printf("Connection complete\n"); + DEBUG_LOG("Connection complete\n"); con_handle = gap_subevent_le_connection_complete_get_connection_handle(packet); sm_request_pairing(con_handle); break; @@ -141,79 +202,81 @@ static void sm_packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *p } break; case SM_EVENT_JUST_WORKS_REQUEST: - printf("Just Works requested\n"); + INFO_LOG("Just Works requested\n"); sm_just_works_confirm(sm_event_just_works_request_get_handle(packet)); break; case SM_EVENT_NUMERIC_COMPARISON_REQUEST: - printf("Confirming numeric comparison: %"PRIu32"\n", sm_event_numeric_comparison_request_get_passkey(packet)); + // Server always confirms the comparison + INFO_LOG("Confirming numeric comparison: %"PRIu32"\n", sm_event_numeric_comparison_request_get_passkey(packet)); sm_numeric_comparison_confirm(sm_event_passkey_display_number_get_handle(packet)); break; case SM_EVENT_PASSKEY_DISPLAY_NUMBER: - printf("Display Passkey: %"PRIu32"\n", sm_event_passkey_display_number_get_passkey(packet)); + INFO_LOG("Displaying passkey: %"PRIu32"\n", sm_event_passkey_display_number_get_passkey(packet)); break; case SM_EVENT_PASSKEY_INPUT_NUMBER: - char passkey[7]; - - printf("Passkey Input requested \n"); - scanf("%6[^\n]", passkey); - int to_send = atoi(passkey); // convert passkey to int - - printf("Sending passkey %"PRIu32"\n", to_send); - sm_passkey_input(sm_event_passkey_input_number_get_handle(packet), to_send); + INFO_LOG("Enter the passkey shown by the client:\n"); + // We want to "wait" for user input but we must not block, + // so use a stdio callback to tell us when characters are available + passkey_result = 0; + passkey_type = SM_EVENT_PASSKEY_INPUT_NUMBER; + passkey_handle = sm_event_passkey_input_number_get_handle(packet); + stdio_set_chars_available_callback(passkey_press_callback, NULL); break; case SM_EVENT_IDENTITY_CREATED: sm_event_identity_created_get_identity_address(packet, addr); - printf("Identity created: type %u address %s\n", sm_event_identity_created_get_identity_addr_type(packet), bd_addr_to_str(addr)); + DEBUG_LOG("Identity created: type %u address %s\n", sm_event_identity_created_get_identity_addr_type(packet), bd_addr_to_str(addr)); break; case SM_EVENT_IDENTITY_RESOLVING_SUCCEEDED: sm_event_identity_resolving_succeeded_get_identity_address(packet, addr); - printf("Identity resolved: type %u address %s\n", sm_event_identity_resolving_succeeded_get_identity_addr_type(packet), bd_addr_to_str(addr)); + DEBUG_LOG("Identity resolved: type %u address %s\n", sm_event_identity_resolving_succeeded_get_identity_addr_type(packet), bd_addr_to_str(addr)); break; case SM_EVENT_IDENTITY_RESOLVING_FAILED: sm_event_identity_created_get_address(packet, addr); - printf("Identity resolving failed\n"); + DEBUG_LOG("Identity resolving failed\n"); break; case SM_EVENT_PAIRING_STARTED: - printf("Pairing started\n"); + DEBUG_LOG("Pairing started\n"); break; case SM_EVENT_PAIRING_COMPLETE: switch (sm_event_pairing_complete_get_status(packet)){ case ERROR_CODE_SUCCESS: - printf("Pairing complete, success\n"); + DEBUG_LOG("Pairing complete, success\n"); break; case ERROR_CODE_CONNECTION_TIMEOUT: - printf("Pairing failed, timeout\n"); + ERROR_LOG("Pairing failed, timeout\n"); break; case ERROR_CODE_REMOTE_USER_TERMINATED_CONNECTION: - printf("Pairing failed, disconnected\n"); + ERROR_LOG("Pairing failed, disconnected\n"); break; case ERROR_CODE_AUTHENTICATION_FAILURE: - printf("Pairing failed, authentication failure with reason = %u\n", sm_event_pairing_complete_get_reason(packet)); + ERROR_LOG("Pairing failed, authentication failure with reason = %u\n", sm_event_pairing_complete_get_reason(packet)); break; default: + assert(false); + ERROR_LOG("Unexpected pairing status %d\n", sm_event_pairing_complete_get_status(packet)); break; } break; case SM_EVENT_REENCRYPTION_STARTED: sm_event_reencryption_complete_get_address(packet, addr); - printf("Bonding information exists for addr type %u, identity addr %s -> re-encryption started\n", + DEBUG_LOG("Bonding information exists for addr type %u, identity addr %s -> re-encryption started\n", sm_event_reencryption_started_get_addr_type(packet), bd_addr_to_str(addr)); break; case SM_EVENT_REENCRYPTION_COMPLETE: switch (sm_event_reencryption_complete_get_status(packet)){ case ERROR_CODE_SUCCESS: - printf("Re-encryption complete, success\n"); + DEBUG_LOG("Re-encryption complete, success\n"); break; case ERROR_CODE_CONNECTION_TIMEOUT: - printf("Re-encryption failed, timeout\n"); + ERROR_LOG("Re-encryption failed, timeout\n"); break; case ERROR_CODE_REMOTE_USER_TERMINATED_CONNECTION: - printf("Re-encryption failed, disconnected\n"); + ERROR_LOG("Re-encryption failed, disconnected\n"); break; case ERROR_CODE_PIN_OR_KEY_MISSING: - printf("Re-encryption failed, bonding information missing\n\n"); - printf("Assuming remote lost bonding information\n"); - printf("Deleting local bonding information to allow for new pairing...\n"); + ERROR_LOG("Re-encryption failed, bonding information missing\n\n"); + ERROR_LOG("Assuming remote lost bonding information\n"); + ERROR_LOG("Deleting local bonding information to allow for new pairing...\n"); sm_event_reencryption_complete_get_address(packet, addr); addr_type = sm_event_reencryption_started_get_addr_type(packet); gap_delete_bonding(addr_type, addr); @@ -226,19 +289,20 @@ static void sm_packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *p status = gatt_event_query_complete_get_att_status(packet); switch (status){ case ATT_ERROR_INSUFFICIENT_ENCRYPTION: - printf("GATT Query failed, Insufficient Encryption\n"); + ERROR_LOG("GATT Query failed, Insufficient Encryption\n"); break; case ATT_ERROR_INSUFFICIENT_AUTHENTICATION: - printf("GATT Query failed, Insufficient Authentication\n"); + ERROR_LOG("GATT Query failed, Insufficient Authentication\n"); break; case ATT_ERROR_BONDING_INFORMATION_MISSING: - printf("GATT Query failed, Bonding Information Missing\n"); + ERROR_LOG("GATT Query failed, Bonding Information Missing\n"); break; case ATT_ERROR_SUCCESS: - printf("GATT Query successful\n"); + DEBUG_LOG("GATT Query successful\n"); break; default: - printf("GATT Query failed, status 0x%02x\n", gatt_event_query_complete_get_att_status(packet)); + assert(false); + ERROR_LOG("Unexpected GATT Query failed, status 0x%02x\n", gatt_event_query_complete_get_att_status(packet)); break; } break; @@ -247,7 +311,6 @@ static void sm_packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *p } } - static uint16_t att_read_callback(hci_con_handle_t connection_handle, uint16_t att_handle, uint16_t offset, uint8_t * buffer, uint16_t buffer_size) { UNUSED(connection_handle); @@ -287,7 +350,7 @@ static void poll_temp(void) { // Typically, Vbe = 0.706V at 27 degrees C, with a slope of -1.721mV (0.001721) per degree. float deg_c = 27 - (reading - 0.706) / 0.001721; current_temp = deg_c * 100; - printf("Write temp %.2f degc\n", deg_c); + INFO_LOG("Write temp %.2f degc\n", deg_c); } static void heartbeat_handler(struct btstack_timer_source *ts) { @@ -317,7 +380,7 @@ int main() { // initialize CYW43 driver architecture (will enable BT if/because CYW43_ENABLE_BLUETOOTH == 1) if (cyw43_arch_init()) { - printf("failed to initialise cyw43_arch\n"); + ERROR_LOG("failed to initialise cyw43_arch\n"); return -1; } @@ -340,7 +403,7 @@ int main() { sm_add_event_handler(&sm_event_callback_registration); // apply security configuration settings - configure_security(security_setting); + configure_security(SECURITY_SETTING); // register for ATT event att_server_register_packet_handler(packet_handler); From 137b88bda5f46de54ad0859545e582a8676a07ff Mon Sep 17 00:00:00 2001 From: Peter Harper Date: Thu, 12 Mar 2026 12:58:19 +0000 Subject: [PATCH 11/13] Tidy up ble pointer example --- bluetooth/ble_pointer/CMakeLists.txt | 26 ++--- bluetooth/ble_pointer/README.md | 2 +- bluetooth/ble_pointer/ble_pointer.c | 157 ++++++++++++++++----------- 3 files changed, 104 insertions(+), 81 deletions(-) diff --git a/bluetooth/ble_pointer/CMakeLists.txt b/bluetooth/ble_pointer/CMakeLists.txt index 9230bb4da..4eb655bc6 100644 --- a/bluetooth/ble_pointer/CMakeLists.txt +++ b/bluetooth/ble_pointer/CMakeLists.txt @@ -1,37 +1,33 @@ # Add mpu6050 libary add_library(mpu6050_i2c_lib INTERFACE) target_sources(mpu6050_i2c_lib INTERFACE - ${CMAKE_CURRENT_LIST_DIR}/mpu6050_i2c_lib.c - ) + ${CMAKE_CURRENT_LIST_DIR}/mpu6050_i2c_lib.c +) target_include_directories(mpu6050_i2c_lib INTERFACE - ${CMAKE_CURRENT_LIST_DIR} - ) + ${CMAKE_CURRENT_LIST_DIR} +) target_link_libraries(mpu6050_i2c_lib INTERFACE pico_stdlib hardware_i2c - ) +) -# Add executable. Default name is the project name, version 0.1 add_executable(ble_pointer ble_pointer.c - ) - -# Add the standard library to the build +) target_link_libraries(ble_pointer pico_stdlib pico_btstack_ble pico_btstack_cyw43 pico_cyw43_arch_none mpu6050_i2c_lib - ) - -# Add the standard include files to the build +) target_include_directories(ble_pointer PRIVATE ${CMAKE_CURRENT_LIST_DIR} ${CMAKE_CURRENT_LIST_DIR}/.. - ) - +) +target_compile_definitions(ble_pointer PRIVATE + #WANT_HCI_DUMP=1 +) pico_btstack_make_gatt_header(ble_pointer PRIVATE "${CMAKE_CURRENT_LIST_DIR}/ble_pointer.gatt") - pico_add_extra_outputs(ble_pointer) diff --git a/bluetooth/ble_pointer/README.md b/bluetooth/ble_pointer/README.md index f1c4157e9..68a504c87 100644 --- a/bluetooth/ble_pointer/README.md +++ b/bluetooth/ble_pointer/README.md @@ -2,6 +2,6 @@ This example is based on BTstack's 'hog_mouse_demo' and demonstrates a Bluetooth HID mouse. Cursor position is controlled by mpu6050 angle measurements, allowing you to point at the screen and move the mouse cursor. -To use this example connect a mpu6050 (which can be found at https://thepihut.com/products/6-dof-sensor-mpu6050) to the pico, with SDA connected to pin 4 and SCL connected to pin 5. Also, connect 2 buttons to pins 15 and 16 for left and right click. +To use this example connect a mpu6050 (which can be found at https://thepihut.com/products/6-dof-sensor-mpu6050) to the pico, with SDA connected to pin 4 and SCL connected to pin 5. Also, connect 2 buttons to pins 15 and 16 and ground for left and right click. Once powered, you should be able to pair your computer with 'HID Mouse' and use the pointer. diff --git a/bluetooth/ble_pointer/ble_pointer.c b/bluetooth/ble_pointer/ble_pointer.c index 06d02ccc2..775f02f51 100644 --- a/bluetooth/ble_pointer/ble_pointer.c +++ b/bluetooth/ble_pointer/ble_pointer.c @@ -35,13 +35,6 @@ * */ -//#define BTSTACK_FILE__ "hog_mouse_demo.c" - -// ***************************************************************************** -/* EXAMPLE_START(hog_mouse_demo): HID Mouse LE - */ -// ***************************************************************************** - #include #include #include @@ -67,6 +60,18 @@ #include #include +#if !defined(i2c_default) || !defined(PICO_DEFAULT_I2C_SDA_PIN) || !defined(PICO_DEFAULT_I2C_SCL_PIN) +#error Example requires a board with I2C pins +#endif + +#ifndef NDEBUG +#define DEBUG_LOG(...) printf(__VA_ARGS__) +#else +#define DEBUG_LOG(...) +#endif +#define INFO_LOG printf +#define ERROR_LOG printf + #define ALPHA 0.05 // for complimentary filter, big alpha gives faster reponse but more noise // FS values are 0, 1, 2, or 3 @@ -78,21 +83,44 @@ // how many readings taken to find gyro offsets #define OFFSET_NUM 10000 -//pins for buttons +// pins for buttons +#ifndef LEFT_BUTTON_GPIO_NUM #define LEFT_BUTTON_GPIO_NUM 15 +#endif + +#ifndef RIGHT_BUTTON_GPIO_NUM #define RIGHT_BUTTON_GPIO_NUM 16 +#endif + +#ifndef MOUSE_PERIOD_MS +#define MOUSE_PERIOD_MS 15 +#endif + +#ifndef SCREEN_WIDTH +#define SCREEN_WIDTH 1920 +#endif + +#ifndef SCREEN_HEIGHT +#define SCREEN_HEIGHT 1080 +#endif -float roll; -float pitch; -float yaw; +static float roll; +static float pitch; +static float yaw; -float roll_offset; -float pitch_offset; -float yaw_offset; +static float roll_offset; +static float pitch_offset; +static float yaw_offset; // start in top left corner -int abs_x = 0; -int abs_y = 0; +static int abs_x = 0; +static int abs_y = 0; + +static int dx; +static int dy; +static uint8_t buttons; +static btstack_timer_source_t mousing_timer; +static int mouse_active = 0; // from USB HID Specification 1.1, Appendix B.2 const uint8_t hid_descriptor_mouse_boot_mode[] = { @@ -160,7 +188,7 @@ static void hog_mouse_setup(void){ // initialize CYW43 driver architecture (will enable BT if/because CYW43_ENABLE_BLUETOOTH == 1) if (cyw43_arch_init()) { - printf("failed to initialise cyw43_arch\n"); + ERROR_LOG("failed to initialise cyw43_arch\n"); } // setup l2cap @@ -222,21 +250,11 @@ static void send_report(uint8_t buttons, int8_t dx, int8_t dy){ } } -static int dx; -static int dy; -static uint8_t buttons; - -#define MOUSE_PERIOD_MS 15 -#define SCREEN_WIDTH 1920 -#define SCREEN_HEIGHT 1080 - -static btstack_timer_source_t mousing_timer; -static int mousing_active = 0; - static void mousing_timer_handler(btstack_timer_source_t * ts){ if (con_handle == HCI_CON_HANDLE_INVALID) { - mousing_active = 0; + INFO_LOG("Disabling mouse\n"); + mouse_active = 0; return; } @@ -261,7 +279,7 @@ static void mousing_timer_handler(btstack_timer_source_t * ts){ abs_x += dx; abs_y += dy; - // trigger send + // trigger send. We can call this from here because we are in a btstack callback hids_device_request_can_send_now_event(con_handle); // set next timer @@ -269,30 +287,41 @@ static void mousing_timer_handler(btstack_timer_source_t * ts){ btstack_run_loop_add_timer(ts); } +static void button_notification_fn(__unused void * arg) { + hids_device_request_can_send_now_event(con_handle); +} +static btstack_context_callback_registration_t button_notification = { .callback = button_notification_fn }; + // IRQ handler for mouse buttons void button_irq_handler(uint gpio, uint32_t events) { if (gpio == LEFT_BUTTON_GPIO_NUM) { - printf("left click!\n"); + INFO_LOG("Left click!\n"); if (!gpio_get(gpio)) { buttons = 1; } else { buttons = 0; } } else if (gpio == RIGHT_BUTTON_GPIO_NUM) { - printf("right click!\n"); + INFO_LOG("Right click!\n"); if (!gpio_get(gpio)) { buttons = 2; } else { buttons = 0; } } + // We want to call hids_device_request_can_send_now_event, + // but we are in an IRQ and so it's dangerous to call BTStack directly from here. + // So we ask BTstack to callback a function from the "main thread" + // We could also use an async (when pending) worker using async_when_pending_worker_t, + // async_context_add_when_pending_worker and async_context_set_work_pending + btstack_run_loop_execute_on_main_thread(&button_notification); } static void hid_embedded_start_mousing(void){ - if (mousing_active) return; - mousing_active = 1; + if (mouse_active) return; + mouse_active = 1; - printf("Start mousing..\n"); + INFO_LOG("Enabling mouse\n"); // set one-shot timer mousing_timer.process = &mousing_timer_handler; @@ -310,30 +339,30 @@ static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *pack switch (hci_event_packet_get_type(packet)) { case HCI_EVENT_DISCONNECTION_COMPLETE: con_handle = HCI_CON_HANDLE_INVALID; - printf("Disconnected\n"); + INFO_LOG("Disconnected\n"); break; case SM_EVENT_JUST_WORKS_REQUEST: - printf("Just Works requested\n"); + INFO_LOG("Just Works requested\n"); sm_just_works_confirm(sm_event_just_works_request_get_handle(packet)); break; case SM_EVENT_NUMERIC_COMPARISON_REQUEST: - printf("Confirming numeric comparison: %"PRIu32"\n", sm_event_numeric_comparison_request_get_passkey(packet)); + INFO_LOG("Confirming numeric comparison: %"PRIu32"\n", sm_event_numeric_comparison_request_get_passkey(packet)); sm_numeric_comparison_confirm(sm_event_passkey_display_number_get_handle(packet)); break; case SM_EVENT_PASSKEY_DISPLAY_NUMBER: - printf("Display Passkey: %"PRIu32"\n", sm_event_passkey_display_number_get_passkey(packet)); + INFO_LOG("Display Passkey: %"PRIu32"\n", sm_event_passkey_display_number_get_passkey(packet)); break; case L2CAP_EVENT_CONNECTION_PARAMETER_UPDATE_RESPONSE: - printf("L2CAP Connection Parameter Update Complete, response: %x\n", l2cap_event_connection_parameter_update_response_get_result(packet)); + DEBUG_LOG("L2CAP Connection Parameter Update Complete, response: %x\n", l2cap_event_connection_parameter_update_response_get_result(packet)); break; case HCI_EVENT_META_GAP: switch (hci_event_gap_meta_get_subevent_code(packet)) { case GAP_SUBEVENT_LE_CONNECTION_COMPLETE: // print connection parameters (without using float operations) conn_interval = gap_subevent_le_connection_complete_get_conn_interval(packet); - printf("LE Connection Complete:\n"); - printf("- Connection Interval: %u.%02u ms\n", conn_interval * 125 / 100, 25 * (conn_interval & 3)); - printf("- Connection Latency: %u\n", gap_subevent_le_connection_complete_get_conn_latency(packet)); + DEBUG_LOG("LE Connection Complete:\n"); + DEBUG_LOG("- Connection Interval: %u.%02u ms\n", conn_interval * 125 / 100, 25 * (conn_interval & 3)); + DEBUG_LOG("- Connection Latency: %u\n", gap_subevent_le_connection_complete_get_conn_latency(packet)); break; default: break; @@ -344,9 +373,9 @@ static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *pack case HCI_SUBEVENT_LE_CONNECTION_UPDATE_COMPLETE: // print connection parameters (without using float operations) conn_interval = hci_subevent_le_connection_update_complete_get_conn_interval(packet); - printf("LE Connection Update:\n"); - printf("- Connection Interval: %u.%02u ms\n", conn_interval * 125 / 100, 25 * (conn_interval & 3)); - printf("- Connection Latency: %u\n", hci_subevent_le_connection_update_complete_get_conn_latency(packet)); + DEBUG_LOG("LE Connection Update:\n"); + DEBUG_LOG("- Connection Interval: %u.%02u ms\n", conn_interval * 125 / 100, 25 * (conn_interval & 3)); + DEBUG_LOG("- Connection Latency: %u\n", hci_subevent_le_connection_update_complete_get_conn_latency(packet)); break; default: break; @@ -356,28 +385,20 @@ static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *pack switch (hci_event_hids_meta_get_subevent_code(packet)){ case HIDS_SUBEVENT_INPUT_REPORT_ENABLE: con_handle = hids_subevent_input_report_enable_get_con_handle(packet); - printf("Report Characteristic Subscribed %u\n", hids_subevent_input_report_enable_get_enable(packet)); -#ifndef HAVE_BTSTACK_STDIN + DEBUG_LOG("Report Characteristic Subscribed %u\n", hids_subevent_input_report_enable_get_enable(packet)); hid_embedded_start_mousing(); -#endif - // request connection param update via L2CAP following Apple Bluetooth Design Guidelines - // gap_request_connection_parameter_update(con_handle, 12, 12, 4, 100); // 15 ms, 4, 1s - - // directly update connection params via HCI following Apple Bluetooth Design Guidelines - // gap_update_connection_parameters(con_handle, 12, 12, 4, 100); // 60-75 ms, 4, 1s - break; case HIDS_SUBEVENT_BOOT_KEYBOARD_INPUT_REPORT_ENABLE: con_handle = hids_subevent_boot_keyboard_input_report_enable_get_con_handle(packet); - printf("Boot Keyboard Characteristic Subscribed %u\n", hids_subevent_boot_keyboard_input_report_enable_get_enable(packet)); + DEBUG_LOG("Boot Keyboard Characteristic Subscribed %u\n", hids_subevent_boot_keyboard_input_report_enable_get_enable(packet)); break; case HIDS_SUBEVENT_BOOT_MOUSE_INPUT_REPORT_ENABLE: con_handle = hids_subevent_boot_mouse_input_report_enable_get_con_handle(packet); - printf("Boot Mouse Characteristic Subscribed %u\n", hids_subevent_boot_mouse_input_report_enable_get_enable(packet)); + DEBUG_LOG("Boot Mouse Characteristic Subscribed %u\n", hids_subevent_boot_mouse_input_report_enable_get_enable(packet)); break; case HIDS_SUBEVENT_PROTOCOL_MODE: protocol_mode = hids_subevent_protocol_mode_get_protocol_mode(packet); - printf("Protocol Mode: %s mode\n", hids_subevent_protocol_mode_get_protocol_mode(packet) ? "Report" : "Boot"); + DEBUG_LOG("Protocol Mode: %s mode\n", hids_subevent_protocol_mode_get_protocol_mode(packet) ? "Report" : "Boot"); break; case HIDS_SUBEVENT_CAN_SEND_NOW: send_report(buttons, dx, dy); @@ -395,12 +416,6 @@ static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *pack int main(void) { stdio_init_all(); -#if !defined(i2c_default) || !defined(PICO_DEFAULT_I2C_SDA_PIN) || !defined(PICO_DEFAULT_I2C_SCL_PIN) - #warning Example requires a board with I2C pins - puts("Default I2C pins were not defined"); - return 1; -#endif - // Make the I2C pins available to picotool bi_decl(bi_2pins_with_func(PICO_DEFAULT_I2C_SDA_PIN, PICO_DEFAULT_I2C_SCL_PIN, GPIO_FUNC_I2C)); @@ -440,8 +455,20 @@ int main(void) { // turn on! hci_power_control(HCI_POWER_ON); - while (true) { + // btstack_run_loop_execute is only required when using the 'polling' method (e.g. using pico_cyw43_arch_poll library). + // This example uses the 'threadsafe background` method, where BT work is handled in a low priority IRQ, so it + // is fine to call bt_stack_run_loop_execute() but equally you can continue executing user code. + +#if 1 // this is only necessary when using polling (which we aren't, but we're showing it is still safe to call in this case) + btstack_run_loop_execute(); +#else + // this core is free to do it's own stuff except when using 'polling' method (in which case you should use + // btstacK_run_loop_ methods to add work to the run loop. + + // this is a forever loop in place of where user code would go. + while(true) { sleep_ms(1000); } +#endif return 0; } From 816182348c0f0c14d59b057d2773593f39a70001 Mon Sep 17 00:00:00 2001 From: Peter Harper Date: Thu, 12 Mar 2026 17:11:52 +0000 Subject: [PATCH 12/13] Fixes to wifi_provisioner --- bluetooth/wifi_provisioner/CMakeLists.txt | 24 ++- bluetooth/wifi_provisioner/README.md | 77 ++++++++- bluetooth/wifi_provisioner/example.c | 83 ++++++++- bluetooth/wifi_provisioner/lwipopts.h | 77 +-------- bluetooth/wifi_provisioner/wifi_prov_lib.c | 185 ++++++++++++--------- bluetooth/wifi_provisioner/wifi_prov_lib.h | 19 +-- 6 files changed, 278 insertions(+), 187 deletions(-) diff --git a/bluetooth/wifi_provisioner/CMakeLists.txt b/bluetooth/wifi_provisioner/CMakeLists.txt index e9ea5ea69..520460494 100644 --- a/bluetooth/wifi_provisioner/CMakeLists.txt +++ b/bluetooth/wifi_provisioner/CMakeLists.txt @@ -1,32 +1,30 @@ # Add provisioning libary add_library(wifi_prov_lib INTERFACE) target_sources(wifi_prov_lib INTERFACE - ${CMAKE_CURRENT_LIST_DIR}/wifi_prov_lib.c - ) + ${CMAKE_CURRENT_LIST_DIR}/wifi_prov_lib.c +) target_include_directories(wifi_prov_lib INTERFACE - ${CMAKE_CURRENT_LIST_DIR} - ) + ${CMAKE_CURRENT_LIST_DIR} +) target_link_libraries(wifi_prov_lib INTERFACE pico_stdlib pico_btstack_ble pico_btstack_cyw43 - pico_cyw43_arch_lwip_threadsafe_background hardware_flash - ) +) pico_btstack_make_gatt_header(wifi_prov_lib INTERFACE "${CMAKE_CURRENT_LIST_DIR}/provisioning.gatt") -# Standalone example which uses the provisioning libary to allow credentials to be set over BLE +# Example which uses the provisioning libary to allow credentials to be set over BLE add_executable(wifi_provisioner example.c - ) +) target_link_libraries(wifi_provisioner pico_stdlib wifi_prov_lib - ) + pico_lwip_iperf + pico_cyw43_arch_lwip_threadsafe_background +) target_include_directories(wifi_provisioner PRIVATE ${CMAKE_CURRENT_LIST_DIR} - ${CMAKE_CURRENT_LIST_DIR}/.. # For our common btstack config - ) - +) pico_add_extra_outputs(wifi_provisioner) - diff --git a/bluetooth/wifi_provisioner/README.md b/bluetooth/wifi_provisioner/README.md index c65abed94..6aad4f57d 100644 --- a/bluetooth/wifi_provisioner/README.md +++ b/bluetooth/wifi_provisioner/README.md @@ -1,3 +1,78 @@ ### BLE wifi provisioning -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'. +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'. +To run set_credentials.py you have to install the "bleak" python library, e.g... + +``` +python3 -m venv venv +. venv/bin/activate +pip install bleak +``` + +From the on you just need to activate the python virtual environment + +``` +. venv/bin/activate +``` + +It takes 3 parameters, the ssid name, the password and the Bluetooth address of the device running this example, e.g. + +``` +python set_credentials.py "my ssid" "my password" 2C:CF:67:BE:08:05 +submitted ssid: my ssid +submitted password: my password +submitted address: 2C:CF:67:BE:08:05 +Connected: True +Writing SSID... +Writing password... +``` + +The example waits 3s for you to press `W` when it starts to make it wipe any stored ssid and password to help testing. + +On the pico you should something like this... + +``` +Waiting to receive ssid and password via BLE +Identity resolving failed +Connection complete +Pairing started +Just Works requested +Pairing complete, success +Setting SSID +Current saved SSID: "my ssid" +Current saved password length: 0 +Setting password +Current saved SSID: "my ssid" +Current saved password length: 7 +connect status: joining +connect status: no ip +connect status: link up +Succesfully provisioned credentials using wifi_prov_lib! +finished provisioning result=0 + +Ready, running iperf server at 10.3.194.230 +``` + +When connected to the internet the example runs iperf. +Press "D" to disconnect and the pico will reboot. +The next time it connects it should retrieve the ssid and password details from flash. + +``` +Read credentials +Current saved SSID: "my ssid" +BTstack up and running on 2C:CF:67:BE:08:05. +Current saved password length: 7 + +connect status: joining +connect status: no ip +connect status: link up +Connected. +finished provisioning result=0 + +Ready, running iperf server at 10.3.194.230 +``` diff --git a/bluetooth/wifi_provisioner/example.c b/bluetooth/wifi_provisioner/example.c index 90c36a23e..6c08a5de6 100644 --- a/bluetooth/wifi_provisioner/example.c +++ b/bluetooth/wifi_provisioner/example.c @@ -1,10 +1,85 @@ +/** + * Copyright (c) 2026 Raspberry Pi (Trading) Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + #include -#include +#include "pico/stdlib.h" +#include "pico/cyw43_arch.h" +#include "hardware/watchdog.h" +#include "lwip/apps/lwiperf.h" +#include "wifi_prov_lib.h" + +#ifndef PROV_TIMEOUT_MS +#define PROV_TIMEOUT_MS 120000 +#endif + +// Report IP results +static void iperf_report(void *arg, enum lwiperf_report_type report_type, + const ip_addr_t *local_addr, u16_t local_port, const ip_addr_t *remote_addr, u16_t remote_port, + u32_t bytes_transferred, u32_t ms_duration, u32_t bandwidth_kbitpsec) { + static uint32_t total_iperf_megabytes = 0; + uint32_t mbytes = bytes_transferred / 1024 / 1024; + float mbits = bandwidth_kbitpsec / 1000.0; + total_iperf_megabytes += mbytes; + printf("Completed iperf transfer of %d MBytes @ %.1f Mbits/sec\n", mbytes, mbits); + printf("Total iperf megabytes since start %d Mbytes\n", total_iperf_megabytes); +} + +// Note: This is called from an interrupt handler +void key_pressed_func(void *param) { + int key = getchar_timeout_us(0); // get any pending key press but don't wait + if (key == 'd' || key == 'D') { + bool *exit = (bool*)param; + *exit = true; + } +} int main(void) { + stdio_init_all(); + + // This is for testing + printf("Press 'w' in the next 3s to wipe stored ssid and password\n"); + int c = getchar_timeout_us(3000000); + if (c == 'w' || c == 'W') { + printf("Wiping stored ssid and password\n"); + erase_credentials(); + } + + // initialize CYW43 driver architecture (will enable BT because CYW43_ENABLE_BLUETOOTH == 1) + if (cyw43_arch_init()) { + printf("failed to initialise cyw43_arch\n"); + return PICO_ERROR_GENERIC; + } + // if unable to connect with saved ssid and password, waits 120 seconds // for new credentials to be provisioned over BLE - start_ble_wifi_provisioning(120000); - printf("finished provisioning\n"); -} \ No newline at end of file + int rc = start_ble_wifi_provisioning(PROV_TIMEOUT_MS); + printf("finished provisioning result=%d\n", rc); + if (rc != PICO_OK) { + panic("Wifi provisioning failed"); + } + + // Run iperf server + cyw43_arch_lwip_begin(); + printf("\nReady, running iperf server at %s\n", ip4addr_ntoa(netif_ip4_addr(netif_list))); + lwiperf_start_tcp_server_default(&iperf_report, NULL); + cyw43_arch_lwip_end(); + + bool exit = false; + stdio_set_chars_available_callback(key_pressed_func, &exit); + + // Run forever + printf("Press 'd' to disconnect and reboot\n"); + while(!exit) { + cyw43_arch_poll(); + cyw43_arch_wait_for_work_until(at_the_end_of_time); + } + + printf("Rebooting example...\n"); + watchdog_enable(500, true); + sleep_ms(1000); + return 0; +} diff --git a/bluetooth/wifi_provisioner/lwipopts.h b/bluetooth/wifi_provisioner/lwipopts.h index 7ae8d527c..aa8ae03a7 100644 --- a/bluetooth/wifi_provisioner/lwipopts.h +++ b/bluetooth/wifi_provisioner/lwipopts.h @@ -1,76 +1 @@ -#ifndef _LWIPOPTS_H -#define _LWIPOPTS_H - -// see https://www.nongnu.org/lwip/2_1_x/group__lwip__opts.html for details - -#define NO_SYS 1 -#define LWIP_SOCKET 0 -#define MEM_LIBC_MALLOC 0 -#define MEM_ALIGNMENT 4 -#define MEM_SIZE 4000 -#define MEMP_NUM_TCP_SEG 32 -#define MEMP_NUM_ARP_QUEUE 10 -#define PBUF_POOL_SIZE 24 -#define LWIP_ARP 1 -#define LWIP_ETHERNET 1 -#define LWIP_ICMP 1 -#define LWIP_RAW 1 -#define TCP_WND (8 * TCP_MSS) -#define TCP_MSS 1460 -#define TCP_SND_BUF (8 * TCP_MSS) -#define TCP_SND_QUEUELEN ((4 * (TCP_SND_BUF) + (TCP_MSS - 1)) / (TCP_MSS)) -#define LWIP_NETIF_STATUS_CALLBACK 1 -#define LWIP_NETIF_LINK_CALLBACK 1 -#define LWIP_NETIF_HOSTNAME 1 -#define LWIP_NETCONN 0 -#define MEM_STATS 0 -#define SYS_STATS 0 -#define MEMP_STATS 0 -#define LINK_STATS 0 -#define LWIP_CHKSUM_ALGORITHM 3 -#define LWIP_DHCP 1 -#define LWIP_IPV4 1 -#define LWIP_TCP 1 -#define LWIP_UDP 1 -#define LWIP_DNS 1 -#define LWIP_TCP_KEEPALIVE 1 -#define LWIP_NETIF_TX_SINGLE_PBUF 1 -#define DHCP_DOES_ARP_CHECK 0 -#define LWIP_DHCP_DOES_ACD_CHECK 0 - -#ifndef NDEBUG -#define LWIP_DEBUG 1 -#define LWIP_STATS 1 -#define LWIP_STATS_DISPLAY 1 -#endif - -#define ETHARP_DEBUG LWIP_DBG_OFF -#define NETIF_DEBUG LWIP_DBG_OFF -#define PBUF_DEBUG LWIP_DBG_OFF -#define API_LIB_DEBUG LWIP_DBG_OFF -#define API_MSG_DEBUG LWIP_DBG_OFF -#define SOCKETS_DEBUG LWIP_DBG_OFF -#define ICMP_DEBUG LWIP_DBG_OFF -#define INET_DEBUG LWIP_DBG_OFF -#define IP_DEBUG LWIP_DBG_OFF -#define IP_REASS_DEBUG LWIP_DBG_OFF -#define RAW_DEBUG LWIP_DBG_OFF -#define MEM_DEBUG LWIP_DBG_OFF -#define MEMP_DEBUG LWIP_DBG_OFF -#define SYS_DEBUG LWIP_DBG_OFF -#define TCP_DEBUG LWIP_DBG_OFF -#define TCP_INPUT_DEBUG LWIP_DBG_OFF -#define TCP_OUTPUT_DEBUG LWIP_DBG_OFF -#define TCP_RTO_DEBUG LWIP_DBG_OFF -#define TCP_CWND_DEBUG LWIP_DBG_OFF -#define TCP_WND_DEBUG LWIP_DBG_OFF -#define TCP_FR_DEBUG LWIP_DBG_OFF -#define TCP_QLEN_DEBUG LWIP_DBG_OFF -#define TCP_RST_DEBUG LWIP_DBG_OFF -#define UDP_DEBUG LWIP_DBG_OFF -#define TCPIP_DEBUG LWIP_DBG_OFF -#define PPP_DEBUG LWIP_DBG_OFF -#define SLIP_DEBUG LWIP_DBG_OFF -#define DHCP_DEBUG LWIP_DBG_OFF - -#endif /* __LWIPOPTS_H__ */ \ No newline at end of file +#include "../../pico_w/wifi/lwipopts_examples_common.h" diff --git a/bluetooth/wifi_provisioner/wifi_prov_lib.c b/bluetooth/wifi_provisioner/wifi_prov_lib.c index b3d28eb4e..a043d29a1 100644 --- a/bluetooth/wifi_provisioner/wifi_prov_lib.c +++ b/bluetooth/wifi_provisioner/wifi_prov_lib.c @@ -1,10 +1,11 @@ /** - * Copyright (c) 2023 Raspberry Pi (Trading) Ltd. + * Copyright (c) 2026 Raspberry Pi (Trading) Ltd. * * SPDX-License-Identifier: BSD-3-Clause */ #include +#include #include "btstack.h" #include "pico/cyw43_arch.h" #include "pico/btstack_cyw43.h" @@ -15,22 +16,24 @@ #include "pico/flash.h" #include "hardware/flash.h" -#include +#ifndef NDEBUG +#define DEBUG_LOG(...) printf(__VA_ARGS__) +#else +#define DEBUG_LOG(...) +#endif +#define INFO_LOG printf +#define ERROR_LOG printf #define HEARTBEAT_PERIOD_MS 1000 #define APP_AD_FLAGS 0x06 -int le_notification_enabled; -hci_con_handle_t con_handle; - // max lengths of credentials + 1 to ensure null termination -char ssid[33] = ""; -char password[64] = ""; - -bool connection_status = false; - +static char ssid[33] = ""; +static char password[64] = ""; +static bool connection_status = false; +static int le_notification_enabled; +static hci_con_handle_t con_handle; static btstack_timer_source_t heartbeat; - static btstack_packet_callback_registration_t hci_event_callback_registration; static btstack_packet_callback_registration_t sm_event_callback_registration; @@ -41,7 +44,6 @@ static uint8_t adv_data[] = { 0x17, BLUETOOTH_DATA_TYPE_COMPLETE_LOCAL_NAME, 'P', 'i', 'c', 'o', ' ', '0', '0', ':', '0', '0', ':', '0', '0', ':', '0', '0', ':', '0', '0', ':', '0', '0', 0x03, BLUETOOTH_DATA_TYPE_COMPLETE_LIST_OF_16_BIT_SERVICE_CLASS_UUIDS, 0x10, 0xFF, }; - static const uint8_t adv_data_len = sizeof(adv_data); // Define flash offset towards end of flash @@ -50,14 +52,15 @@ static const uint8_t adv_data_len = sizeof(adv_data); #endif #ifndef PICO_FLASH_BANK_STORAGE_OFFSET -#if PICO_RP2350 && PICO_RP2350_A2_SUPPORTED -#define FLASH_TARGET_OFFSET (PICO_FLASH_SIZE_BYTES - FLASH_SECTOR_SIZE - PICO_FLASH_BANK_TOTAL_SIZE) +#if PICO_RP2350 && PICO_RP2350_A2_SUPPORTED +// picotool stores a "marker" in the last block of the last sector +#define FLASH_TARGET_OFFSET (PICO_FLASH_SIZE_BYTES - (2 * FLASH_SECTOR_SIZE) - PICO_FLASH_BANK_TOTAL_SIZE) #else #define FLASH_TARGET_OFFSET (PICO_FLASH_SIZE_BYTES - FLASH_SECTOR_SIZE - PICO_FLASH_BANK_TOTAL_SIZE) #endif #endif -const uint8_t *flash_target_contents = (const uint8_t *) (XIP_BASE + FLASH_TARGET_OFFSET); +static const uint8_t *flash_target_contents = (const uint8_t *) (XIP_BASE + FLASH_TARGET_OFFSET); // This function will be called when it's safe to call flash_range_erase static void call_flash_range_erase(void *param) { @@ -73,7 +76,7 @@ static void call_flash_range_program(void *param) { } // Security Manager Packet Handler -void sm_packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ +static void sm_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size) { UNUSED(channel); UNUSED(size); @@ -88,7 +91,7 @@ void sm_packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, case HCI_EVENT_META_GAP: switch (hci_event_gap_meta_get_subevent_code(packet)) { case GAP_SUBEVENT_LE_CONNECTION_COMPLETE: - printf("Connection complete\n"); + DEBUG_LOG("Connection complete\n"); con_handle = gap_subevent_le_connection_complete_get_connection_handle(packet); UNUSED(con_handle); sm_request_pairing(con_handle); @@ -98,37 +101,37 @@ void sm_packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, } break; case SM_EVENT_JUST_WORKS_REQUEST: - printf("Just Works requested\n"); + DEBUG_LOG("Just Works requested\n"); sm_just_works_confirm(sm_event_just_works_request_get_handle(packet)); break; case SM_EVENT_IDENTITY_CREATED: sm_event_identity_created_get_identity_address(packet, addr); - printf("Identity created: type %u address %s\n", sm_event_identity_created_get_identity_addr_type(packet), bd_addr_to_str(addr)); + DEBUG_LOG("Identity created: type %u address %s\n", sm_event_identity_created_get_identity_addr_type(packet), bd_addr_to_str(addr)); break; case SM_EVENT_IDENTITY_RESOLVING_SUCCEEDED: sm_event_identity_resolving_succeeded_get_identity_address(packet, addr); - printf("Identity resolved: type %u address %s\n", sm_event_identity_resolving_succeeded_get_identity_addr_type(packet), bd_addr_to_str(addr)); + DEBUG_LOG("Identity resolved: type %u address %s\n", sm_event_identity_resolving_succeeded_get_identity_addr_type(packet), bd_addr_to_str(addr)); break; case SM_EVENT_IDENTITY_RESOLVING_FAILED: sm_event_identity_created_get_address(packet, addr); - printf("Identity resolving failed\n"); + ERROR_LOG("Identity resolving failed\n"); break; case SM_EVENT_PAIRING_STARTED: - printf("Pairing started\n"); + DEBUG_LOG("Pairing started\n"); break; case SM_EVENT_PAIRING_COMPLETE: switch (sm_event_pairing_complete_get_status(packet)){ case ERROR_CODE_SUCCESS: - printf("Pairing complete, success\n"); + DEBUG_LOG("Pairing complete, success\n"); break; case ERROR_CODE_CONNECTION_TIMEOUT: - printf("Pairing failed, timeout\n"); + ERROR_LOG("Pairing failed, timeout\n"); break; case ERROR_CODE_REMOTE_USER_TERMINATED_CONNECTION: - printf("Pairing failed, disconnected\n"); + ERROR_LOG("Pairing failed, disconnected\n"); break; case ERROR_CODE_AUTHENTICATION_FAILURE: - printf("Pairing failed, authentication failure with reason = %u\n", sm_event_pairing_complete_get_reason(packet)); + ERROR_LOG("Pairing failed, authentication failure with reason = %u\n", sm_event_pairing_complete_get_reason(packet)); break; default: break; @@ -136,24 +139,24 @@ void sm_packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, break; case SM_EVENT_REENCRYPTION_STARTED: sm_event_reencryption_complete_get_address(packet, addr); - printf("Bonding information exists for addr type %u, identity addr %s -> re-encryption started\n", + DEBUG_LOG("Bonding information exists for addr type %u, identity addr %s -> re-encryption started\n", sm_event_reencryption_started_get_addr_type(packet), bd_addr_to_str(addr)); break; case SM_EVENT_REENCRYPTION_COMPLETE: switch (sm_event_reencryption_complete_get_status(packet)){ case ERROR_CODE_SUCCESS: - printf("Re-encryption complete, success\n"); + DEBUG_LOG("Re-encryption complete, success\n"); break; case ERROR_CODE_CONNECTION_TIMEOUT: - printf("Re-encryption failed, timeout\n"); + ERROR_LOG("Re-encryption failed, timeout\n"); break; case ERROR_CODE_REMOTE_USER_TERMINATED_CONNECTION: - printf("Re-encryption failed, disconnected\n"); + ERROR_LOG("Re-encryption failed, disconnected\n"); break; case ERROR_CODE_PIN_OR_KEY_MISSING: - printf("Re-encryption failed, bonding information missing\n\n"); - printf("Assuming remote lost bonding information\n"); - printf("Deleting local bonding information to allow for new pairing...\n"); + ERROR_LOG("Re-encryption failed, bonding information missing\n\n"); + ERROR_LOG("Assuming remote lost bonding information\n"); + ERROR_LOG("Deleting local bonding information to allow for new pairing...\n"); sm_event_reencryption_complete_get_address(packet, addr); addr_type = sm_event_reencryption_started_get_addr_type(packet); gap_delete_bonding(addr_type, addr); @@ -166,19 +169,19 @@ void sm_packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, status = gatt_event_query_complete_get_att_status(packet); switch (status){ case ATT_ERROR_INSUFFICIENT_ENCRYPTION: - printf("GATT Query failed, Insufficient Encryption\n"); + ERROR_LOG("GATT Query failed, Insufficient Encryption\n"); break; case ATT_ERROR_INSUFFICIENT_AUTHENTICATION: - printf("GATT Query failed, Insufficient Authentication\n"); + ERROR_LOG("GATT Query failed, Insufficient Authentication\n"); break; case ATT_ERROR_BONDING_INFORMATION_MISSING: - printf("GATT Query failed, Bonding Information Missing\n"); + ERROR_LOG("GATT Query failed, Bonding Information Missing\n"); break; case ATT_ERROR_SUCCESS: - printf("GATT Query successful\n"); + DEBUG_LOG("GATT Query successful\n"); break; default: - printf("GATT Query failed, status 0x%02x\n", gatt_event_query_complete_get_att_status(packet)); + ERROR_LOG("GATT Query failed, status 0x%02x\n", gatt_event_query_complete_get_att_status(packet)); break; } break; @@ -187,7 +190,7 @@ void sm_packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, } } -void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size) { +static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size) { UNUSED(size); UNUSED(channel); bd_addr_t local_addr; @@ -198,7 +201,7 @@ void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint case HCI_EVENT_META_GAP: switch (hci_event_gap_meta_get_subevent_code(packet)) { case GAP_SUBEVENT_LE_CONNECTION_COMPLETE: - printf("Connection complete\n"); + DEBUG_LOG("Connection complete\n"); con_handle = gap_subevent_le_connection_complete_get_connection_handle(packet); UNUSED(con_handle); sm_request_pairing(con_handle); @@ -211,7 +214,7 @@ void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint case BTSTACK_EVENT_STATE: if (btstack_event_state_get_state(packet) != HCI_STATE_WORKING) return; gap_local_bd_addr(local_addr); - printf("BTstack up and running on %s.\n", bd_addr_to_str(local_addr)); + INFO_LOG("BTstack up and running on %s.\n", bd_addr_to_str(local_addr)); // setup advertisements uint16_t adv_int_min = 800; @@ -238,7 +241,7 @@ void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint } } -uint16_t att_read_callback(hci_con_handle_t connection_handle, uint16_t att_handle, uint16_t offset, uint8_t * buffer, uint16_t buffer_size) { +static uint16_t att_read_callback(hci_con_handle_t connection_handle, uint16_t att_handle, uint16_t offset, uint8_t * buffer, uint16_t buffer_size) { UNUSED(connection_handle); // SSID read callbaclk @@ -254,7 +257,7 @@ uint16_t att_read_callback(hci_con_handle_t connection_handle, uint16_t att_hand return 0; } -int att_write_callback(hci_con_handle_t connection_handle, uint16_t att_handle, uint16_t transaction_mode, uint16_t offset, uint8_t *buffer, uint16_t buffer_size) { +static int att_write_callback(hci_con_handle_t connection_handle, uint16_t att_handle, uint16_t transaction_mode, uint16_t offset, uint8_t *buffer, uint16_t buffer_size) { UNUSED(transaction_mode); UNUSED(offset); UNUSED(buffer_size); @@ -268,22 +271,24 @@ int att_write_callback(hci_con_handle_t connection_handle, uint16_t att_handle, // First characteristic (SSID) if (att_handle == ATT_CHARACTERISTIC_b1829813_e8ec_4621_b9b5_6c1be43fe223_01_VALUE_HANDLE){ + DEBUG_LOG("Setting SSID\n"); att_server_request_can_send_now_event(con_handle); memset(ssid, 0, sizeof(ssid)); memcpy(ssid, buffer, buffer_size); //This occurs when the client sends a write request to the ssid characteristic (up arrow on nrf scanner) - printf("Current saved SSID: %s\n", ssid); - printf("Current saved password: %s\n", password); + DEBUG_LOG("Current saved SSID: \"%s\"\n", ssid); + DEBUG_LOG("Current saved password length: %u\n", strlen(password)); } // Second characteristic (Password) if (att_handle == ATT_CHARACTERISTIC_410f5077_9e81_4f3b_b888_bf435174fa58_01_VALUE_HANDLE){ + DEBUG_LOG("Setting password\n"); att_server_request_can_send_now_event(con_handle); memset(password, 0, sizeof(password)); memcpy(password, buffer, buffer_size); //This occurs when the client sends a write request to the password characteristic (up arrow on nrf scanner) - printf("Current saved SSID: %s\n", ssid); - printf("Current saved password: %s\n", password); + DEBUG_LOG("Current saved SSID: \"%s\"\n", ssid); + DEBUG_LOG("Current saved password length: %u\n", strlen(password)); } return 0; @@ -303,7 +308,11 @@ static void heartbeat_handler(struct btstack_timer_source *ts) { btstack_run_loop_add_timer(ts); } -void save_credentials(char ssid[], char password[]) { +int erase_credentials(void) { + return flash_safe_execute(call_flash_range_erase, (void*)FLASH_TARGET_OFFSET, UINT32_MAX); +} + +static int save_credentials(char ssid[], char password[]) { // create empty 256 byte list uint8_t flash_data[FLASH_PAGE_SIZE] = {0}; @@ -324,22 +333,25 @@ void save_credentials(char ssid[], char password[]) { } //now erase and then write flash - int rc = flash_safe_execute(call_flash_range_erase, (void*)FLASH_TARGET_OFFSET, UINT32_MAX); - hard_assert(rc == PICO_OK); + int rc = erase_credentials(); + if (rc != PICO_OK) { + return rc; + } uintptr_t params[] = { FLASH_TARGET_OFFSET, (uintptr_t)flash_data}; rc = flash_safe_execute(call_flash_range_program, params, UINT32_MAX); - hard_assert(rc == PICO_OK); + return rc; } -void read_credentials(void) { +static void read_credentials(void) { uint counter = 0; uint ssid_len = 0; // first check if the flash page begins with FF - this indicates the flash has not yet been written to // so must initialise with empty write (otherwise crashes) if (flash_target_contents[0] == 255) { - save_credentials("", ""); + int rc = save_credentials("", ""); + hard_assert(rc == PICO_OK); } //initialise temporary ssid and password as 1 bigger than max to ensure null termination @@ -377,14 +389,7 @@ void read_credentials(void) { // this function carries out the BLE credential provisioning and also wifi connection int start_ble_wifi_provisioning(int ble_timeout_ms) { - stdio_init_all(); - - // initialize CYW43 driver architecture (will enable BT if/because CYW43_ENABLE_BLUETOOTH == 1) - if (cyw43_arch_init()) { - printf("failed to initialise cyw43_arch\n"); - return -1; - } - + absolute_time_t timeout_time = make_timeout_time_ms(ble_timeout_ms); l2cap_init(); sm_init(); @@ -415,41 +420,59 @@ int start_ble_wifi_provisioning(int ble_timeout_ms) { hci_power_control(HCI_POWER_ON); read_credentials(); - printf("Current saved SSID: %s\n", ssid); - printf("Current saved password: %s\n", password); + DEBUG_LOG("Read credentials\n"); + DEBUG_LOG("Current saved SSID: \"%s\"\n", ssid); + DEBUG_LOG("Current saved password length: %u\n", strlen(password)); // first attempt to connect using saved credentials cyw43_arch_enable_sta_mode(); - if (cyw43_arch_wifi_connect_timeout_ms(ssid, password, CYW43_AUTH_WPA2_AES_PSK, 5000)) { - printf("failed to connect with saved credentials \n"); + connection_status = false; + if (ssid[0] && password[0]) { + if (cyw43_arch_wifi_connect_timeout_ms(ssid, password, CYW43_AUTH_WPA2_AES_PSK, us_to_ms(absolute_time_diff_us(get_absolute_time(), timeout_time)))) { + ERROR_LOG("failed to connect with saved credentials\n"); + } else { + DEBUG_LOG("Connected.\n"); + connection_status = true; + } } else { - printf("Connected.\n"); - connection_status = true; + INFO_LOG("Waiting to receive ssid and password via BLE\n"); } // If this fails, wait for user to provision credentials over BLE until timeout // cyw43_arch_wifi_connect_timeout_ms returns -2 for timeout and -7 for incorrect password // wish to keep trying if password incorrect - int result; + int result = PICO_OK; if (connection_status == false) { while (true) { - result = cyw43_arch_wifi_connect_timeout_ms(ssid, password, CYW43_AUTH_WPA2_AES_PSK, ble_timeout_ms); - if (result == -2) { - panic("Timed out - failed provisioning! \n"); - } else if (result == 0) { - connection_status = true; - printf("Succesfully provisioned credentials through BLE! \n"); - // since connected, save credentiald for future use - save_credentials(ssid, password); - break; - } else if (result == -7) { - printf("Incorrect password - retrying \n"); + if (ssid[0] && password[0]) { + result = cyw43_arch_wifi_connect_timeout_ms(ssid, password, CYW43_AUTH_WPA2_AES_PSK, us_to_ms(absolute_time_diff_us(get_absolute_time(), timeout_time))); + if (result == PICO_ERROR_TIMEOUT) { + ERROR_LOG("Timed out - failed provisioning!\n"); + break; + } else if (result == PICO_OK) { + connection_status = true; + DEBUG_LOG("Succesfully provisioned credentials using wifi_prov_lib!\n"); + // since connected, save credentiald for future use + result = save_credentials(ssid, password); + break; + } else if (result == PICO_ERROR_BADAUTH) { + DEBUG_LOG("Incorrect password - retrying\n"); + } else { + DEBUG_LOG("Connection error - failed provisioning!\n"); + break; + } } else { - panic("Connection error - failed provisioning! \n"); + if (absolute_time_diff_us(get_absolute_time(), timeout_time) < 0) { + ERROR_LOG("Timed out - no ssid or password received!\n"); + result = PICO_ERROR_TIMEOUT; + break; + } + cyw43_arch_poll(); + cyw43_arch_wait_for_work_until(make_timeout_time_ms(1000)); } } } // once finished, turn off bluetooth hci_power_control(HCI_POWER_OFF); - return 0; + return result; } diff --git a/bluetooth/wifi_provisioner/wifi_prov_lib.h b/bluetooth/wifi_provisioner/wifi_prov_lib.h index 53bd1f2b0..025634527 100644 --- a/bluetooth/wifi_provisioner/wifi_prov_lib.h +++ b/bluetooth/wifi_provisioner/wifi_prov_lib.h @@ -1,18 +1,13 @@ -#include -#include "btstack.h" +/** + * Copyright (c) 2026 Raspberry Pi (Trading) Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + */ -#ifndef WIFI_PROV_LIB + #ifndef WIFI_PROV_LIB #define WIFI_PROV_LIB -extern int le_notification_enabled; -extern hci_con_handle_t con_handle; -extern uint8_t const profile_data[]; - -void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size); -void sm_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size); -uint16_t att_read_callback(hci_con_handle_t connection_handle, uint16_t att_handle, uint16_t offset, uint8_t * buffer, uint16_t buffer_size); -int att_write_callback(hci_con_handle_t connection_handle, uint16_t att_handle, uint16_t transaction_mode, uint16_t offset, uint8_t *buffer, uint16_t buffer_size); - int start_ble_wifi_provisioning(int ble_timeout_ms); +int erase_credentials(void); #endif \ No newline at end of file From f00389aaa67d6039250bb5b696ec61cb6f3a64fa Mon Sep 17 00:00:00 2001 From: Peter Harper Date: Thu, 12 Mar 2026 00:21:26 +0000 Subject: [PATCH 13/13] README updates --- README.md | 13 +++++++------ bluetooth/README.md | 6 +----- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 6d945a599..049f59cc9 100644 --- a/README.md +++ b/README.md @@ -296,12 +296,13 @@ Some standalone Bluetooth examples (without all the common example build infrast App|Description ---|--- -[picow_ble_temp_sensor](pico_w/bt/standalone) | Reads from the on board temperature sensor and sends notifications via BLE. -[picow_ble_temp_reader](pico_w/bt/standalone) | Connects to the above sensor and reads the temperature. -[picow_ble_pointer](pico_w/bt/standalone/ble_pointer) | Bluetooth HID mouse using mpu6050 to detect angle and move cursor. -[picow_ble_doorbell](pico_w/bt/standalone/doorbell) | Detects button press on transmitter Pico and illuminates LED on reciever Pico. -[picow_ble_secure_temp_sensor](pico_w/bt/standalone/secure_temp_sensor) | Variant of picow_ble_temp_sensor which allows exploration of LE_secure configurations. -[picow_ble_wifi_provisioner](pico_w/bt/standalone/wifi_provisioner) | Allows WiFi credentials to be provisioned over BLE, either using a mobile app or with the included python script. +[ble_pointer](bluetooth/ble_pointer) | Bluetooth HID mouse using mpu6050 to detect angle and move cursor. +[doorbell](bluetooth/doorbell) | Detects button press on transmitter Pico and illuminates LED on reciever Pico. +[temp_server](bluetooth/temp_sensor) | Reads from the on board temperature sensor and sends notifications via BLE. +[temp_client](bluetooth/temp_sensor) | Connects to the above temp_server and reads the temperature. +[secure_temp_server](bluetooth/secure_temp_sensor) | Variant of temp_server which allows exploration of LE_secure configurations. +[secure_temp_client](bluetooth/secure_temp_sensor) | Connects to the above secure_temp_server and reads the temperature. +[wifi_provisioner](bluetooth/wifi_provisioner) | Allows WiFi credentials to be provisioned over BLE, either using a mobile app or with the included python script. ### PIO diff --git a/bluetooth/README.md b/bluetooth/README.md index 5e39b09d9..87229fe36 100644 --- a/bluetooth/README.md +++ b/bluetooth/README.md @@ -6,11 +6,7 @@ There's a standalone example in `pico-examples/pico_w/bt/standalone`. ## Debugging To debug Bluetooth issues you can enable [btstack](https://github.com/bluekitchen/btstack) debug output which also enables packet logging. -Define `WANT_HCI_DUMP=1` in your CMakeLists.txt file. Uncomment this line to enable debug in the btstack examples. - - target_compile_definitions(picow_bt_example_common INTERFACE - #WANT_HCI_DUMP=1 # This enables btstack debug - ) +Define `WANT_HCI_DUMP=1` in your CMakeLists.txt file. ## Packet logging

    Bmy1c%HzBbgUv)>VE=eWg%0MK3e9Z^g=`y5!Bq zrsb0FNzdN9_}lhha|&HsWKNGbp%OFTsh#@BX!q5?*A{>dcLD4n+np@^K9SAC-?n+9(|}ckudd%V-vDxR@KByEbO+% zp_Jvs<@bbT5ktlmlXCDj&~$n6+=Os^T+thEeVu*%;xQoLgGLVzBK)ayu_!8XB|{x| zr3uMF-ys!Qcdarnuu3K+kB(AjxDmN1{}7C2#}^Utq!CLjac!K$^*v1&AF4>cZa-{4 zWPG-5$3C>#cTm3O|FgA48^%_t#iU@#WuRnb5XZ*Inf&fdv1`pfPMFxf0OX0P3RcEg zFu7|MB@;j%=KmRI65(mj@PpUs-@B7P<5!yl9T`(wJAHpL#r%$L+14rUn#E{q(Ly<% zdmx0#2%{X&1snt`O`WRMLXR-XB?3jnY$dPsiZ`{&h5ws$=bfUtW%1p^{I9tf>8>YZ z?12+J=UI#<@7LjlG}&ER4rHqS^#h5x1&i(Gmgc$qN~H=8LsN%c9LX1O#DRIHQe-mTd_#5!I5Sv zqP+a}ZF}q+7ER5bI_97GdYfYMs<_xd~wmfuc4o(h~+)9u{V6RqzVQw#`3Zq zWhJ8(fIk?q&RdxeL3(`D5NiN=pZw?hzhVUt3D&7!OK}g|%J0=A%PbB3Ka#xN@0gQK zda+roxc~(mXR)qv9!L9mWolU%%@b~Bc4my$*w+el>S|f>zZJf`4VPb%fK8Qo5CPZA z)W3lNb>C9}WTbyYzZ};wqZLd?CMDq#qKBti57(i$tzb4UWwEoQj3P*?a_c1%#+gv~ z-Fs2LcFzBk=a*XA3gV_otQpyBb5%p__dic&cJO)|An2rZnWj=$6{~jo`Bl z{P+@q`cIU!5PC75e4B*o`3-vw`Cw~%_>7#QBEsYu$E+(KX{+%0BAz^pllNy)H$SgN zW_N!( zqCPPLdKFz=?@H%Q0FeeLCUaD-miYVogWrNOi#ilxSx*FH1NzEI^88B68A&mbz=Ihd zZDwXBya;b3A}as7Va)QZ#!m)W)X9mB6mxPXRDE8(bxCnI73U>IcpXzsd$?IjdHK%X z-r4Ur8s0!vU}!8NZ-i-Dudga%-L|N(kdlSPLC5pr{Jfip2G5^)R9;gPa3jKt-Warn z&zyR`s$Dt&f~H|VZOM|c+S=OIUB8FVffb%c6o63l3T&4Ujx ze-VaAt;VlB>)6Fypz4~Zc$!1;$%Z3Dp)P(gFoT%^%8!o@0VR$mtqD(!Qz zOMS9Fcz8&fYy0{NxVpN&nkQa{Az@D7BrKUlkxfka^5x~pomqY(Kw$;*kR#4U6}P|o z35*z9lEc(0bqP4m>0@vQe$= zy%%}SW=ajuUlHsBuQ~X4baeF_k74>+MHScF(sG7C1C=)X4>F=bX8I>|R_I+n%vd0v zVPa^;bur)ht29?o)QQxXFB%X+q?A1_ub>^}9XmS*NgZT4Q9_t`G~ zur!>s8Z8tin+_UF9_lI3;l0ic{nd|;G>5*svTLWOr(xHRKd){NX18{Rs@VJ{kD8aZ z4a1yR9@?F5`qCl4YHmK9vnuDQ406A$JDvJ99hI1glI{UUmnl+V`;WSq!^6W!k_qvP z8LT2u?cjaYD)jUwaisovddr>(C2*!H-S`<5Dq(v8Mgv*GOa;lOnW%%&+^ z*JetjoHhYYjdrA31`f`sN=ALTb>%R!vE4(MxDAY&f|;nn>eW@FXMfRP49J81z#b}JaW$zeBZ`bM2ZAeSXoN1b&_L$u%d?HWHJcxw@^`I z*()DkMZ>|U%V4hVIEwmPYL89kakpV}p^gSue>}Q=osjga&`U!T?#I7wH$}ugFGQ45 z#_<3Im@DRXe0fe+Q6K#f$3Amq34*@$=?^(Ym<2I}@~lRYiW$v$O-%t~OT?Nu4qtjA zqlPVB9MqSr^Hm~#G0v^3t|wyiyJUUzc1JST%zMLzf=z9o@agVG;un-1-?`xudezm1 zeULK#*r8ev59_L3u;vu36kmiQF)*xbbjDJ08m_t-^6|SD9-YOXyW}Tta{)}ApHpZ_ zpv;!733rf9bXUIwz6#nM1OdY#aNvCpfD@`}X%)9Qwb-PzyDh`dtgOUBz^3Z@`j?=r ztG65%18o!pwU$e2qk8Yus10-}9z&z+wX#x6?e!-T|q)fv( zT<5{T0T2!sQ&z?T8PzjZFh4)v)D8nP#%FYN(L@s96YY6OfD12HNQ0C91hHbVdVq5T zwK#q>Ei+5WY#E7xqn({N5ETN}06ZrL;1MdMvWuE&GdJkz>$@C7MS*t)eiy@Sd*bI$ z*Y5_VlkfJkDi{+05{?w;ymWMQ$S5lh0Rp0`ib}5jx8BClE!SN{(~OLa=Y7!t{|D3= zK=JYIKY!YFNBsE~{LI_CyU*F#ae!7z&BmtOY!oI?;?7=GTuk@;mJbgPKYsk^2Iq0> z8D;eTJe|S)^ovbiaRi+Y%%y4* zJwT#-{v!yL;E%N?J#dOsKP~Hf%sB@XMt9v`J--tH>m2;+15aOt?W+QnL8i3!z&)X+g)r?G zI|13CEPu`^f7TsagCbzhxN^-3ZavTeFtxe3x{@ZnCnnWMbIc+4 zgkeq>Su&}zX|gf3+Z``!c3Kl|KN%!ZK`JW!-DpPu$h)ovz6Xr~kHEh!UZr>VUTsu0 zub$2>0wQX4%Lb}}+xQz|mgoT-kCkVp;Hu9aOV`yApmM(dU1y>5-F2&`0dBOyN*QbQ zamV3Z6%dvIusdXgQPlepyKo1@F-tccJs;s^@KHQYtCh8O15tR-cwz1>GDj7;$q0Zg z?r%Hltf*-8yK#-xY7u1+Y6HmQI3P%JYjg0c76Mpw{eXzdeHUSuVwCj+4Z*5$SmKGD z2ZZG4QMN9F%@pT@nOUEwhpSrfeAk-i{;#0D>NZTkw)trt_A=?TcmwU;0f3dS!KvH< z9qZvF&c7{EY$iPT^z@q@2LRRajUM2;_R^*p;Hb9&W=Sxafai`ai*B8SnRZK1e)s9C zP!qt6{MBfevUWrfa80H4%_tVAN=aAY>1?A=d2MHXsPVmWR9pdU**EwsdWF-d=)GZk zz+0S52pmB-HR!7y6=1W^o!58j2m=?}*3WB{rP&1F_|scoOhitY z=sC5YAc8MdGOgF<$pXeD0T(dcN5D(g2r9C@ojZ;?vi!5I-JkS-m=F=_Afl?gG9b!OP*v{pNqz#}?!(PF_$GP5=B_j>gu^(vm!y1?el#%%QX|6nBp^I~~CwEI>3h-%v}XXJpj6 zY)Y+gE8krm4FSLLW(e7;;SH4p*J55-843xn>nOg1t#R8{0yxi) zKg{6knWi4OtR}33eT<$>0mK~ZhF)3Pk`G|%VWZdCIIqXr*|UL#AYozZkM4c^OA}() z=DBNo0BE4qA*@{o7P^>BTj@ZXpbdy9)!NL`8CC)FSqJV=^*8Nkon;$fkAin!wY%)N zTJ8HxEzLcIyihGtWi}LN3J~(GdVsvxQ)@PKACN-BU|-dJ5J$=%e6{MUtZfIZh|gt1 zLPIZ+#^z8Gc;9*W#df_69tSZGkH#l~JbEdI1u*d61o3>EUvlb-oh?zu^6p$;eAYQY zY4C1b^*d9Xo1eGckJ8!$p*CG4Kv4_~jDW5-gX+>o z;m2z;#oY0V3*dxuYil_e+s>PoI((byrvCn1Y;mCmH8!_r*xA9il18&3Oz=uy7RTk5 z7ohTZaWh3rs~t{;O8Z-8)9VkB;89+)i|L&2`ykHUljk)*wY;sd* zWD6PrwKXAD7r33dN-SPN>>tt;{^DQr~$QtV~Bw_zSBT(z)DR(5Slxj%T^IKSe zVxmj(znm6I7!HOF`GlyhFuCQWPNu}YaFhJ;{xWRZ-idS>mP6{SQI$Ta_7f#?jm}tS z*EA-I^*OXaAo4YR!OS$BS>k+hawHvf{E~M=Q{1j;(Q_+FmNdxb5sY7PN2lf`fL$~m zp^n=OpED(-d(V`kez*a$CBy(H8dfz5$MEnKO#$yw#EOp4A<{?4Ek&gn)a$KdD8liDb0cu?2y22g_R4(h$i zR;0t{L7ndNYknTFU>Z4ld$aoI;v(vo;XfblW&YhmPyd06>$|d*)$8JNb(eX+d2OS# znW^0Yo#dat@c7iI6aN0SRD3(;Jfr!~a8%r;v7y2G5@q`qr0}3NPPM_%+`eeYKcS*B z|KUSeW$2>^xV$gy!o+j2EOe#x_4N&&n?5=f-@o(I={Yu&7#bSBSh%tF+i`yzF=y-G z5L-@;X#3lq2juz^m3Xm+pm6EjcC7R#)G-1{UTc|CL^;Xybxm8F?~h&b-l~Xv1(Gd> zB!RApc<-E_crk+ybfr%7@9__RAuU}H*~ zu;L*N9T^MZr={NEp~w^n!n`2#zz@S=gX=Xb@MPu~g5zfpDNf6sMRb2lRLXtH%RFXT z{~E7!_7kX+#|sxe^>4Z6IY1%5eT~-74M@?D%jgVThr_<(U!!wPtr4HN-10#ft&INY z3;$kGV&VrkoR|>t2m6aZMQ}WyMKdrGlCG_FneoTlS=YH?z9uL4+BV)M)5^{i^3M4t zBYNtfNCUB#F{e&iRon=L@2QE2`QBO)1)6GV8@y|3e4a(14e|OllA#!ZkN0HhS>9ig z|Ac4|G_;lA=qMI+PAD6Qmu8J{|leC4xQaaF9YIq z5yE+s+D5xg=QWLR2dG6B+{7Hf?RFtHYn{yM3->#alKUWU{U6K_RoM~b_ znHdVeJc!W46R2(4h0*=ADQqPae0*AS@TuUX3ON2e4BGQZTcl*;Po7atswy)Pw`pjC zz8ICib*)bRJSQP*jHL>g@2#>v82Rzzcs9|3h(ALsQ&e7t_vQSr3%b!7Quyfwd)v*I! z%^&e29SU z_9Q5E%-tU98q0i!1Co;P-evInxk@^Ta1Fl*_k~BHRh!JK-%L$Yta~CLee6K~R7B6` zEi#q0t-XYqI0Oi@_Sr5+y(urxKO7@sM-Lg^+UiWX2|wE&lJu7Ojkw%m8|!qVV@Fow z;nY90O9j6hrtUwA8R0*79mu8s*|ud0oB47|ger`4k>j{~TMpSVv)bgwJUHJS?&Z5{ zNrWADcD}_C==e+KRpH^>@A02LH5rMogM#LnV4i!I^!4iv!eTI)^i`O=G=S67?Fa+j zctB8-$q>pyH7Egd?-a7${$!iNuQv2q0{?yUM;NFSb#f=buuG>yQvOAaL;(39s;jb! z3h|EbtIDH_%c{TMd^j{1Cw&`|_Qoz5Gz$2HGkKlJSN*S667+%!M#BplJ@)2v??6D6 z<_e}?^wH7PElXQst(jOre)H%NBB9L-s>cEW?Rn@aI_Y-~Qi^c7S&-Pa*TlW7)+*(8 zn6^b|linRS#*<@8Z|z}6|2vTttt@;)V=fdEW@yCH!C!>95UXQd%Nz}g*HDEI6(xAF zSp0E)fNsw1#ynU+ekvHB#${#u_f?Fv5H}%uDu-FPC2OzO^^`fMDYz`@H?W)QeV_rX zp`~T}7b!+E3u}4seXZAF71b*5dyABxwvskBWtJ12JKdGnTm^Q;GB|iGX{uJ{dX`8(_b-PJ>%zwy7MWb2;~7Mvzk)-;EqS>t909%LXEfkE7Q>5vTAV0Ykz(?v z|BI{r%7HR>fE_&w(dTJ?e$HfMt}LMA*G6o4d1+Ny(9*%+pHo+3Co&i?R|5yJ97`Fx zTx7KWRz-a2^5}Bxf4>R6E0{t0yOE}&!adO3?lQ}DE>@%>#h^uf+)aym*d-zA6ZuGj z4*64v&77f7V_z4QvjVeUYIgF=ms!}(Ji-IBygV3tV*wg4tH`?!8t)RmZ9J)ybi*fT09nKIwZ2`8!wV`H zjghZ><2i$P+6F;6PxspZ@Avsqx5;1NuMPHqBK*tk|l_&NY(_q#tCYPI?Q(exEyQFY(fNOyOa zN_Ps<-5}i|-JQ~%BHbn3NOwqgNOwwufFSuD-tYJ4nelNLn7Q0LXP>>--fOJ^XyNYr zo8tneYN7c`ov@GIe}Bi?vEw7RYHuxaYL4pYgA9!`mh@v8-?kh&w66P_YfTTXnkUTs zzZJVSl!w2kL81qIKR>f=fvO`~%X7{5;q(spaJWd81E_n|agc;{Vdg4t$!6fRX@iu# z63Eh}_ zz_hvb)*gd{ADAwXbZr1|3OHE2B($3o?JnPsu_Sy&d?R!K2m!7bF|4;at zC&11&lXdJOTH7HdHLG5~EpTt4R0;f3c{?{Ua5_ftZo+h>y{LBp#otHhWYsICIwrrkT#J53fnL7HAsEl+ zD>^XVg-L}mnY!s<^47d%m2sN2Z8RQ#Yn{LDx6oqJorgp#!Q6QyP-An={b11X2b(dG zdVlQSRjRTwYmu$0DGWRnQ_n|W%`1r95I__8`}{ZvU>|E{L2G7LFuyVtiqE;*#$l&V zVf$Ey=A{J}rxs$r#QYj!Dcn?DS)x#6=o7oxZ9vR!(drrVc~Q36>i*H)OBu+_s6ye; z-3g0}cq&ymI%0{p^T!hDNf2>%hFlgC;5vp4+E|zlSmGGKPSoK8F{lU*U^07%a(w+w zPH!Cf;Pjzqbc}PB^P9egQU2UVGL}(bt;%eKPUG$G6b$0TBT_siV|T49DtMDoF4&VX zDA@aY-%8fz5nCu}IJiHQRZ3RFUxCvy$6BwPKPSjeNsn-KuKLd1q}+Wx=$2PnZ6dck zz|x(9OMCZliddDFe;;Fvlrke1_<&oMnk-w>6)*0GzYzg5fXw0AXzcipfq^M!?-rSW zUqlLggncgid7Ss74Z0Zt`m=FA-^B5;PEC!3&DDT~F{sBM)Yt`$jq}W#$yr%3_I?j5 z>H4SfAaouVgB=~{;v3J+&E3JQ0_6V!)b_>zJp@J2EC)MskVp}Fr7nHzBGaNA7eiJj zHc0oy0Ad1+%U?|o06zHYVl#rRxRc49`;Gn}w6edB0nt%-)UMIwu)Yu&ri2;DOo7$0 z>74VBsYtJLQ!yIvL^(rvBKl(~`qdBO`f%3Q8Gi5J;MKCV7q}ni|IN#u2d=A*_t%zP zb4f5TFdo12!dOg4u)Cgc#0l79v{(R$5*UJnm*3jDY~Pt57zpWe+qNMt-aQ!4FluD& zNF0Wcx=GJ083~ml-+~MZH{Vip(3W@H_;TB$bu^c#QU97$83Uw%$Mes31ONJ(8uX2) zGj~?cKf6XtoF4TCR#tStMW%Y1j*hN36om+gx)Hj1!dPhmEHr}~?Y(05HPQes9^TGY z7}@+-3VxLy2zKh=hhF!nox!*V7?bz%>A@&OT)EB7i|6>?s6(<4nUr4Ldw-Zu&RZlU zCT_+{l1_imN-*WM0X@B^dSG<#qaAc?WNAsuWwYqt+uNJ^kA;c~3KZaT7GUo+0{+~o zEJh-80?76Mt?Tmkc48tf8zEs~VO0U@U|`PNW#|U*$5%7F{|+IIo{sKfh$@bpnVH$D zQmE|}NOV0?jZrr>Ev!nWmNs&iL#U?*nI*8v=m!z#3G(JskzCJh=j})NqeF*LSw(to zZoJoTy_VqhMe-ToOmO{F1(P6X;DC7CPErkkg%wV!l@pJ^*yQBk?r?%5kT&hw{1;8Y zesR%<_QLXEXr2n-1vMHNVIiOM9j3cOdV_IS0^s&>cztZD6lzHp$l(~=7 zf`gh#=SRlH4<%WDGBnm<5_ma}b~-!^ z>Am!7M;DW33VT1x%H`%-fAiOjA)%cZ>T8%~7B{nVRQ1c`B&yEl#djvU{Y5rNEkN{* zCcmx8{pT|vNc4Z6|IAg(NBsNuiHN%*^9dImDD(Orj+=xr#hXu1FWMovGI_@V3M1;q zt)#}e-M$>;obSCf>i`_QZr{nwUR}(`lTh4Nk5Mdo6h}v%EZzh!eo5}R_q(ugpJMtH z@VJ@IyzO1yRnb;eT8jb9OlTMw#O(C-HL++U5hXbLgzsr|j|4ZCjH!N$RH zymv&xmpzMct`kfgA{;+hdFM|M5&*l)=_Mod_fJ2+I}Po$ghYetf4Iph%+ZIe8+;99 z8(vo$t;c3Kas#sNFX112u^l#KUwA9fvOf2ZK`Cx9n4F$0cC@=K60F{!k&@*gJrSpy zGxj_m_1)e7YT7y0Fu;!isT@d$U2iQdEQFk$*+HvUNngK88UtR8YZ4xqC1^6VPL2WC zyr8A!wKoh>>8bDV(W+5K_@J?2Q4dcc&;}L@_#LqGQo$<9)XqLy=BR6%5Q0YHYeNCl zCv${WAJ1K&0vdT|GE=R=TF-B8*3=l?atQwA|C^DyqvZ^qg2(-g7&II}OFAGj5>YF#ywUM2i3~L@SoASqk zXRpxx3x)`AtBU*k_iyS_zaudKYNbF=)dpnUhgM6ce`{uoVCb3E)RYYj&NCES>g!dx z*Fe2N?6#()h676Y-=M&^vtt7Fl&h^f53$iozhmY*`6`WLkUGCMJj-xO(fX!=J+~-; z0dyOztgWZl*0Pi;A0K_>(m5;_wfQHlRZzSefa@mE*Thm8HTx0rF`Xh&uUIih0(8w0 z5fPPibt`nxPTd}A8nDHMf!ZhN+8Gz&jDa-kom^^enk-xTF@2&saH|Gg8CIiSX!&mb z^goD2Z%5f)Uv*<64mgTqt4`_p!rfcCuI68dgQ7%_7bAJ$zOX9$O>z6BHgx&%7d$cO^ENSF$z z?4;wadj_JY-}#j7K;^4tABF3JFC_t6ydNT%HTmlku91df-%8m0O)pvD z6MOqH znVoFw!q$s`PK zP4oP9%PHB^HOTzZcc5lVB2tdVkjbx&1g2T4my zOS*JXK|jD5ira|5YVDM+9i^uWgk7c~1rTvh{66~}2EgKIhnpaY&cD{=(lnNeI;p^~ zcPjRBZ){&0tLNbu^ywX8fHzWbitVCh$j{~j&2lgt2`86ag&slQ`FM8B6Ghm#aT~s zgPPiPnNo_{@k50HmS6@w?cl?sTdBFErmbB@5W=a;*t8PEJC&UBK!3CRL%|BEsGZ2s?;UUIpTzA3z#3)G@zGA5TDF2D%=1m zxqP&QBfVUs*NyL#xsg< zCp{YXq;@3z$bpge88z`a&%tdcLA3{7j@(4*r`+vAK2y!@#M&C3tj(Jnw&Z7hA#1@( zpDh&*M@kTBC|cJnY%GKThJXwUCHD@CCmT)*dX^j$QY#rus&K@7TH@v9n3DK!JS+;L z-KRMCU&y7U5(dv^Q@N=NkB3cFEdS>ImuLK#ff`9G*>BixGK1Yu5Y%F$pb6x_oT%Ph zigr^En!^yjS9X@`r?8N=URUfP&audS0F<-!WJNBp>jodSYch7~CRw@HVNYGIw^h_nOiSi<{E2M^Cnnk3ur*Xl<)IC<|GiI8CF!-> z@@cEZmI`mj2_y8jtUUQrkq5)#t=`U5Nqv9MlGF76AY|lELg{$)1b9M65@d z|2L}*GwL_FDdxRP_3N#4U|AUpVN9zfP6u-F7QNEwXSTzl)Tjn9x5AP!jxepFhVw)2 zM|WKXa}8T6?+o$e5ZyE<1LJvkR@y+?CYb5cUT(JhsLn&TK zLvL%RdJLUiJho*}_`JrFCPx8vvp#LvH;uSZC1(8=;N+E@x@2CHt|bb@>&ot+F{TsO zR~lCP$B42XjKGwYVZhyF3DsK-=8qs1P{wa>+U8Cs&H z;RzA=>;O6ANgC_{Y5P=mz}xqeeg<~4U|H1T;ev_ZeZz!j&5hJL+ZWwHrxDfpo%(jR z;FCWt08=G1zY!gHX_rz_ipg)nKYWL8WJSIh)S<>M3~PF-<-$sT7=gfsVhPG6Bc90P zxFUXMjz$8ZttxhL_lxb>#M$ABnJz1)yvP7^{@>$c#{v1sGYS@7%6RWDcBar@7ClQ< zxb5mU6zP5NRx!|%r`~WITAth^h}WOwL3-bF82<9PA1E;o4UeNNe>$_!<8;gZD0hzj zIwBeD^N$jzX#%lYxvV9wZ#b4xN(MpmGh{S;F2Yjshq0`wxIC4XVnX<5ueRu@99(ko z>CgfiM9^F3iG`ZHGStFl7zMz`=-S6j*l8g~FeI3L(Br79+n}m;GrP@$irn|}7gOvG zi(V>fvgsE9dhon8muqO>12BX24_Q+EueL1uWRApe!sw6nAQ8-`L70s+|0pN61_bA4 z3l9zP2dXFdOea^3Yo%zpG@}kY1sSWsICo4$@`9w7!1a8L=4-3${2s9gr~D59LP58# z9%RF1WscLvTJzNt-lH_hHx4y=>kp4omY#f~KOv>RkxPH8o*4Wjn{2vh!=+d0F&86d z>G_2QKJdIH)1tEHw!|YvgTEejK~xyMn?-K5o(4P8yo!@;xT>v6GJdK+%7}zY9bM#N zE*bCj?$h=3`O3NHT#-L00ZG1|ypPW2!zl(pBBdh@SJd|Csu;-b`>tn0k%x}(lnwQQ zBW>1n1l;Cq#jEznQsc?I7XNfHs9%l=1THH)5iPY#&tAsh+=jY7cm3NG?=oCT;NFP) zbyd}UthO?3bl#sC0pyljnKvf{1tPPGQK|LbDyhP-=QKkZ=++@(RcQGh+c3eQ=J25; zl_2n@%%L%+>gm3T-GjxWpKxp1tj@8GcyQ2Yf+^9#en^4n7a~i=Ml?P7W(Lj0K-Ow> zF9}kNqlPfD0S@6b7H5qc+ z5!V#I@^2jYE&D%^CxVA%S0=y0uJ0pJ*8Qh7X9>&q#Pg!vjR_cJABUk36<2<43)@Ok zIk7u+7n;GW?aSHowLW;4{GdsMX5H@LiiIIHAhC8e!9E)&XdBect*-<+spPf=6c|D*fsuQd=z^Znf2e_^()>Xj*kI!38I4J#;He*+U%p*#w38;RCWmr=ol`E2ym(#``3B;mc&_Ot zuWvibqUv~lU-o0b0|r{7o|-TVz2J38{Ae*!8BPEA!vGncl1@{J2{aKy5qvO+y5t2hUg_hBFfVqn*6>BuPOmfw0$m zhZ^&DMI-@A?#C+e@)tLk8lOY8&%k4~F?*o4a{?v8inr zy{AO1_e@Ky#pFAVGZOFb%w4I-F8YuD4lWq>2#=96M$gW|P;&)!-To-{8_kcR{YM0J z>wM$eaOaLZ%Q8WB*fOdMMu*5gTXh*<&Bx~|+HMsEgY{fg-lI@*zlHMCy{)m=QdS%L zx70DmN)^r*62cd9ZzNU~rfS&7Mqr>@5*U?B8)oGHwx2E;yWC?_1y;~2r%y1hmRuTl zoOs%hXcU550cD-2b8?)V`$jNdK%mdTf&K+nBpdO=;BL$;f^XY6&Lp6q8673t9<`1Ve%7AME;;r+&@-ty`H$k#MQe$ql#O68mj@1 z^>W$}(o$g^c!DdJnD=Y3%J!p5S!N1A#b{W|Qkkra|KZJ?yB|hj+P!m@uC~lqlQ$oT z>-Ck5{f{JSnp`DZpor0o@e2)1#b8u1%1-=6uxpT!V#z)u^+8qy%)fbMfl$9?fC9@p z+Mb!j*DSo8Uag`;=`!e+=kbpTYQ1NG2tv*w*2qOKo^SNa`X6(S8yAcDsK~_b2goST z5FDN<54zGXW_vuui%)+-7VJV{?`d}uz>DxVsY|q4dJNKzQr=yCAaI{By$I2OzJ5DB zM@dC!laVd^HG|OS$vmczW^{}oS;F_oN0qbKNI37=qE7a`rwZy%I``Wv@AUz2C!J?K z%T@}F0zTnQ95oE;d$>K_bspuwcYDwAK4O7|w!FKkqJ)mYpbHsd>Lv>9t1-*Ne8Y`v z-rW|^UErS3iZs}GCaXzT@j;8`e7Pk#;dh0Aa2S2uyF1q*6WS}Ve!OO4$_O#oxI{0) zOB7N4+-!;=xOPwJ+j(m5+f&c1+lnZtdxN7nPP?f^YR;E&c~0aPYWrT`()Q}tsC|D^ zbtlr>B`lw=j%If(;0!Q$m=(>o{ph%{qN&bGre$U=7rOxH899Huu$(eJksMqmY2@Tj z6#vYke-CGWVR5pjlag#Kb~*?xOM&Fx-pX}h8N36077NS0^Sflx!C1ODaVpWonV zmml6s|ooQir>z}5QwuD?w?0k$PuUNQIvEIdESsii=nJ<5AdFDX1cO) zE>L(M$T}P-ian^^_OM>Tc7H{P)>Ks6MyOeufNcCAbTYk0S3QI}u^UV`BIMmIQ;KKd zOGcx0Kydh4SYeOAo9qX0pC#3l&B*88TPbgKpZQ1+yd?!X+4FlE zMXZ0P6t2$ovrgB-vtzWzqw=g^-Q#~Te*c%lF0>+2Q?&-tlQv;{JAt6|kYeG7AJO{Rhv-8C@GkCqPCKV9-s>EN&3PIAJGdN9qq+lA5MR1% ztDmt2eIK;=UB*A&b&*v2qX$Y>y+A%ctQ}mgJ5JJYNylFvqv`k7(IQ=rm!EZ~WWTT` zt4|C*-|u)FUnp$Us)}rUqa7Bno{hb=7AT07x|8LBOEC1;bBQUt{sF7+FV51-)GF~P z`VM=^Ob8xBHsRMW>+~>7Qr>7k<>+@<&)8W*B2)bEkN(?%hQooh1^DF9u@l-f#vWOO z(Lm8W(}xVT9NHfy7+Xk+#3B-c4fRY!<`iS?i#Jmz;opd))?)?V8W_EU$)llQ{HZyK9TQ5S@0=jF+ojIwGR6-m-db1>%+%_ z|Ig1Q5XOhSyODQV1*2M3WlER3GB6uoQVJA`l|nZw``RuRm_G&xq>#jXJWam|BT^W= zA(|($U|(#_h2Uv@VI0%0M~tg##%r4(7Ks~`K#CBNrUY5b4z9)3w*--zOC|!1mw+&N z;wAr;aM+bUqMuc%prtUJ$Van@I0hY+59&FcTJk2TlI{q}uYY6lT^e|IhU+)I?{27k zw)b$jd@;&zVA~g9trfkc356>S5l* z`|^kDOYF>v$aULEDyvbQL8}zAPV8w<5dAqU1cytLv5LBYT%geqhAT)Re7e~fNDZFU z9#@ib!n9a`NDdjuvwiI6GG9*dDu4dC<&RYB`sZ%*v6I_!a`x&GSq+synM_Ab4Y0hD zO#yD}MZ#YvcYk~LXoUJ1buQ8z^(lVFcc(;txL`g5c!fSoXj+VDTkmJ9wDYO!DD@ZViYBP}2_Q4`I zMnsy;Y#-xM&|8CqtiPc#N2|$Zb&W#EpS+)B8O;_68?kU*CuF&D?Zfq7bxT>Dk~Wcm zZKk(pPo;Dj``W?n&bpbITejyUuk%EjhG5q( z=bbhc#oT;(_)296E@3Lw@4_lIJq5e0U#JLteCb2@d=GSgX;*0cS}dC3OUWenU%t1h z={~;8fB*y^De6Ean(HIctb9F<;ZH5Kle-IcKk%0!x`hsFs=ZKfZ~n!tHDGz8g`~dk z9_WP%M~e`9X-2kT8i9dm|M2w2r_~QdTXmxEx7D?F)1NuF$PaCpnrub_b;fcSh?hMW z$vd`$Z}-1kLJH{IL7owDB9Waxk>rqQB0(Ltl3RV}fR>j@Te}>H4exM}Mi18Y9b|=D zpf!b0fQDlEWhNUZ)jj`~UTIwy>01#CLkn}PM$(-*r{LpV*!GsA^Tj!B)Wurf_@XBl z8Dp87U%~ay4|Wd4{+CreT+-i^%70BAy5!P~SSbpT3nV*T60g&r(?$krSB9#WH*6W# zYHnWrLyr&x|E|p_n6+Gcb@WG+6t{e6qKN8;j2jHnWay;S^${R5uEpmkt=4IdmZ0Jw zjQLb`W+7ToghSj3jV#(%V%x^FAsyKN1|G6LiX)W+g#{Z4xe`wPsAp>J+|+^vpW#V- z)+H_u<%*|%pAsGtG9Y)QMU@Wc+UrZ4GXXN}X#4c6t;PP#p-n;exGrV{v@TPV&fx0- z?yxl(xjXS%iv|cm#7nt|-~`YT4NqN(^cv@oklRUhh^Xcr;IFQ zSlJ9Y&T6QGvS6?-6DL|jKu`bt&J@8*cgc6F6aoT>&6o@e8zxiHyxa4ur;9$Ezd3w> zWf^Ortbl7&HvP_~9sW2ipnu=cqzyUDTBdsG@5~H`idRg{a@?%Yu=0!0pB;OYK#28h z8R6eOZkxXg4K0QarQkCmX>*`xH+H8ArY#(DYcWrEVUcB-B!Y>;&eJ+9<)jL054L~N zM>wd(*rLcRjMS>=lkzO*#4=b+Dk(JGF|>`OyxMIBAZV}@co zh(W(ePQa^!ji_l~u6uO$Y%o|q$Z@pHT(`((7T*O($8iSp2Ut?D9p$n9hJeVAHQ`!t z{5M5-L-HgVFuE^PsPyMPd&X1>B1kD7{i03ETv7;&O9y znLID(lVswWp&{QuLP53t1gdGd>g6P{p6Nw-vxm8}hvew+=-AkEZ_k}WMBXIHgn*Y+ z#@XljwY57iyf(6DVWasstdamI4!|QLU#CUQ(dOFFz~blb_*Jp9Owq4)IU}koOOA61 zG@nAX-Xh?`0@@DvlofS4VY;SI&)hucTM{CMKoZ6b9R5h%sIGF-8r?(CP*VCjiQ#kB zTycOBFBRO~-Oc1Uyys-muuOX3v|zv?FIq4y1a8!r!gNV)mNxZGO>K#z>E-24;HSV; zXOk{iRVt!tQx?rbyOGho|sZZs~6h#zDZGkl_?aM?BI|u zsH_~PO=&@C(5@7(%HCBe|HbvRN1sh5DRMHf@7XFGen0SlL9&YWhElRL0bUFa`3(#7 zdut?gx@QQ>yorwfUU6jHxZI14FVDZZ1gmV($-mN~7c{XzQ0SuKhYBH;N=B&1M0w#n z$L4hNbHOQZISxsUiA+z&*0U;(z+w~Ppf$1iL$mjgsu)}_&(qU-RI$VN`{)mq^zu*L|-4OioP=4H?iKgf<+=^l|WOiS(l0KP2SDiMo=Q@T_Sn zTjN|yA7y8ZxSxeo{w8fdY}kHZ$m=bsX>p9hibAA*<3w&k#y5A?S0ubVo+eq;@gi1x zSqV<8(M;rA;OQ`M)FY@PnWG^<&v`>7p5NYr`#}XQL?Py+*`>`JC45pyx??yzog^bv za&S_72n&k=wt1{XENXfd4TNcPBbj*?F)7iDpGUV(p^c=WvCzx)(19VbE4-R6(*+Op z4GqG@vrG6YWnw8PJeQ1CDcM6YGLtw)RoJ6hc?-wWGc$oTH7q&NhHPnLr6QA6jIJN> zV} zd>SA#vna-Jn+QJic?}J}=v!zaMI0Pz7Idkl^TA`2*9{|DqF~a=b2-#3jOrV;w=R=) z)z`1+)eB{JLa?`}PL;W%UDP79oMd7(Z!il1BYFazfCa+K3MP^$M`A1yNkY{iMgz zJI71^Wuw~oF>H6!*Xo?s= zxjqzC;o#6>+7L3y?)5#~;A&v$lLVy_jc_6dbX&GA0t9M|Y^;NHaZg>OaWp)lWWEq| z`Wq&zBpwF)kW0dAUvl`~{Hb}On_L1|{#a|gda^%Fn;C8T{bAm|!k*5I5dM=}+e<{} zKXYIn^0-p5^90G(LyO-r|7_e2O7^lrpipl1{wdeq{QPNjSHWMXMia3zXuHB!SJ1<0 zMnp_n&*MiXUo46FA4ij%t<M|(pbo#w%K#vqbz#elXp&T zAdk?IO#I+pk5Gd9H!!~F_?P8xGU*RK0iIfJyYV#tir=3dmWWk{32Poslx^rfY`Q9M zdP`1-nSG{QU%A0bPimwc3lx9j@m$oVJg*zX?6lzRGf5$>)ogu-{5`loSH9q9Xm8iW zV8lmUMY=aBVS@vceHV$o=$Fu72kmE;Y}_%_${YWJi;@x9$y(}Rw>HT1ua{cb!)%0d zSC8RmQ9hJHH4+;9K-c>Xqr*=c&9)bxk!5~|6lQeQjiFSr*biYtbW6YI{5E!Xn<&nr zLM^a-Ro>^D#b<%pIl5uPdSWhKy!kheJKtW84qBI#PUraYxR!*+;raX8x#&+7et}Cj z@Ny_19OcB>^!;TIyBMgDyy)9vO!iJ+Ik}8zqIyq(2kPiorD-n=+q1|&zXTk?IC8} z&P=VtZ+V)sj&Sf^KU(~B9jI~Ry2c9xY6sHZK^9<=*em=f*rl;-g)SvuKRm}l42j7b z2c%Wy*b6GSfl;Mz>x`_nf} zs6_(7I2_>LC#hX?)rhw3T^w#}ZT*9_-gDUi%=qZjr|vnm42E*CgCzDdTiOEbn-<-( zTGsybQJt2t&=cz{S*8^4LY~{CQ6R@QwpaT4%xdU*w?>Q4*0s$6&eQS=57%r+XBx2C{sl8gbWRHHFVeUZz}fwB#)i|k3ygo z(59ga!BUQf(uhQ&rA36)cE{~+^lPbt_N@8tMCj|T-*kx&Vf>p|Qw-+-qFKvFZI2rj zrGHyt?8xY{j*=F{i%j#6JlPPk`6?H-&YUv!e$|9#+6AO>6*{rEMS_uJrsE4PM?>@h z#RFraeoS~t2XQgq@tz84i2fxvR0w z?4iq7cMr=?)ChoBjhccKAr{!ZX;}RcO^2gbII{DN~4arJ-yFy8RF2}i`7!_d&@9YDe#+>I9q z_R-P;*QbZw23u^nG@+5e)!>`hHL*}30(dW$$JKWBMy+H$hB;NXkpA>48>&RM>@-qGk2q2mb7ckdxvV&-0O`B1x zH&Y1`-@^uXK+RWUGcVeF`%uWEqI?p60xi6GLx4spLKxVaj&!&8+b!d2hYfBgLKnh{y&xWa6TFy2-Hr(Ol_m`Cvqu%1;={?LqGpWA&F>&FgXcT!PobYUkQ9plNm? zwd#QV;rwpi%?cz1$Y67&cMjZecSTsnCO! zfV)|Z^qw)a*4>P`2Zi>FV^J0HhXT^shnU_DD)Vi>mCkngt<5%X{l5KtT?TwFEGOpdx>a^n;_!C!E)io34iNaEaz^_VZ<+dPN7&tVOx8rt zjh*IEhB`F;kLJC8LWk@OOCy09m1Nt0hQXAuBG1--m3tUNB>yA$EK=yN2=80&#p8`b3i?irH*g{^IfCWAzm@6*@J%+?WLTL?Ng- zteZ^>UUbeVCAU&!P?qRo;FTVhPQ5)=dRtbf9GgBH<2kZ7)Vw-1C}?dZ6c-m)qDunVY7bzwVqjnxEj)|l)vUCD$!>H~QoF%D`6oGNFpjLS&1C z;oNBpfO*10=#rvQ#={F!Q0SZgzFb_KUtJ96N*nvmzvI-ib0w^def@!?o)Bf%);2sc zB4DZyO@_TOv4)khr)4)T#=1X$FNTJe7R+$JF`LMYNWQ?$h%@WZKX)itt6=I4|4vo) zPqvL4&;5r?tXa}yYmQ5q_VMMW;!DG0$JL3EgQiVJKMDjsi-*&VQ?%SETB%Yrcav`v zN{C;85x&jGFH>6`vPbkFIAm*Iz486n2nC{Z(B#%uQcRA~CuJt&-MzR3w@O5;WWn&# zFOo(=KCtPDwy7OQ1jG#V_4v{>=>u~(aVCZ$?^ODB$Tu%)uEvZ~EE%4fxg7gm&g%GZ zv9M#G6#Y=Y71jKy7KDHpZS)B-)v*!1(1J$VSiM2qN6ijCn6IoMemNhHBY($2oFM1{ z-GV1S%{sZ^!mXe4kK9+VbMzZ!!^_OdX)~5ce$C59j%exZrfj)I9g8&j-;YncjhPeu zBnDm3P~swESlv?bi=UjZ0n!+y1vOxN+IPMkTW#>S#KA%0GbH7A3X549*3w%gxPeAt z@LvoDL?HzcX5w;}EIJAbYQ#}{Z^Sm4*v)yhNzMEdQW8I+-%L`R=|-1a$o8 z`H#(0swmyqJ+~VfWIc%jeYN*@Obq`{^=$keP1@PL5%zul>ZYui$|3}C7xM@TGPMx; zso6-VT)2cqW=srVuhEkDu3xcRq{F75@ZZ2snj#L%A1spcj`OfdW$}Ar9?w_)xSW{) zgZvBCrMQ)J_xpPbtB6|DnB| zKbnXe6_6QfTdHLW|13i6hg)xSetA`*K+yoh*Y6ZE!=)46Ep@PGJMns@+@3520X2~o z;?eQ({_oNWEMTa-&HQFgX*b;Z_Uu)@BaUPN>|(6Gj~+SAW0t!g$X0;L$KUe}aDo6+ z1-#kBnO0kG!vSo_gY=)G zIM9u!^iWZ10pL^x2>RRqD1uiLX#%5EdCto3Rs!eH2PML#4>>%DyEpY%z5{`e=9fPw z-Z#l#EgU}l<=~7aRW1nIgk>W#u3f~OUYc8v?(puE!0&;~F*E{%-%h)#v-yL!@R0O) z{Bf6QK{Yqm!Za>ca>In7rawq~S0{6B7q=GC1gqXP-_vUd_~*8s>j%VO_l`zu?6xqY zpbNdf9AD;YNO8_Xp+=|h{dv}`U(Le_ z@$Bwb(J>f_VwOcu;N8;H(3oG?LV(=oKfaZk>54yKd~OBGBMg$$+F6#(yxK}VCdmxB zQ2%bB;E=Et4+K_Zs3ehq{i1hs3-gq;oWIK9n_SHi+PM%Ea4a1Ikk`NX#}s$56-q63 ze&K`NU|lq0=TzdJvMXSm%@mdE=0kVR>f)ED+pKmPjPdQPh3q0-I*CU%>p$K=V5Dmi zmqzYZxU^q;d0!^ukUyfo^A}XWcAl|n*{;?cxfX;Ok*Lkl-|`5S51sEEpD5)pgKcHi z{XsGO$2%@xn!>qt>A~W;%kg1~$nk)?+HgTDAzp82&txK3deL|PYd<<91PEgUii#~z z?s2JhpW>znF=o(TL&+3JP$@mBWO?hFlijagyqY~1rfh>-gzZ48+J|Aqcw$_nP@{{5 ze^?&Z3+^>}o6JL;bdN6QD#)6R-TSw(EKGgZmu+Wr`f}&oBkw-aL&yyg2UZqefu!`M zFIZo6wUfIEtph`s3-0{var#}>-hp3bzwD>;zK>L9TObbSaUL-aI728MHfXl~lYKp& zF)}uom$mzGS5C8iv=)p)l%&_1pu+RQ7Fprsw6T(3T)DW!^rPiZXKTTMRpA7O$)U7l zRyXSj4-Pu*%d7a&tNpiHRK9|ZSZHw>CeCp>aIun=?Fi+Hy6Q#hjq_W#CT$npzeiz= z3q@votEQIe)aGC-`%BCQ&IjF>iOZAI^1l~CCe(QYAEvvfJEk!rege=r>(BmHpl6lh zL=aHG2^~7Xs<5tTsC2?iQ-LI;JEfU%BU(J$^Wi0T_ZxJEyFFkkZaVnm;r(HuUcY(g z(Ez7E$RWQXUOe~f*A`ILaJX~yKANKy6BApc`C^$K+GFTYUQ<708j_w)SfST8PqA>h zGY9~%P(Z|5b~wE8YSN9}ZFM=s1Z(-=>oFkN!K0xKg4KSy>r`Cx8Gitib%xx+f43!u z>i|xxaPb30*NF=?z#JksVDB4mZ&F7Y1S^O)dGUBi7wXC*Dui`SGW{@a-l(~V1E}L-aaJxIxBdLJG-bBG zTw?@9Nkw(qY?1C(?(Oh1DJRF?+=9JY(C_)*dmw)H_3PIuMqNPRa2sImPW<2nRE5AF zQ6JIExzUGL1wyDtf8p$5H%qjRBwUBSeN**fmtPk+2V)Ip@G&{<&-bP-U!q+@P@*R?qdnfppvEYnJZ5M=f5M#n-@me4_ZJs7~UFR%xM zu>Dg!TJGzouFARsD*xWWkwRJE4~U6$<8AU!6f_kz^)KRL;Ky!J9pqhaTGb#xei6fz zS|X+?Ir~AZ2x2P$_Fvbo${7qxQq7(5bkvaN4yxbjwI4jwaK^>aM0Fm8F@`jcJByBI z2_~M7^%KfpG?AjHGSm>19(X*-C6Xq3=3WRu{BB~c*K$dr!{H(|WT}pG&aPJ?xvmDJFL3n5xRXN|+f zagKcUGZY&03P#i$RO@WXLCH$E+3#*K;c+-ieL218iz|mN6^fRR`{FNUN%M}$4_>YE zMxpwP$$a14!f&06xpXv!X<>*dW-b&TR6I{S+vB)HX(|QPBttPPKfVH7!?L(W*Goxw zY#Em4CpcyLt`k~T76B|?gtX?J;}p3OlJwq{m9D|VMkQ7MvC+Y zq|TV*tDpQsX_Ji=v7IuWuCZJ*vvCgA_QX0`(P1H9|6Z|EvnYiWH<&$B;O4q8F`u&X zIDX&&LVMI{f7r==UVYw-dW42n;0I53{ftXy_-1~eR(sA}g+J#D+P|t25q~!O%`qex zmp<09Z7ns>voxGbwF@2~AbVaZR39U`4V1U>F1j^2pO--h1PNc}P&92L&xn#i3)cvL z`z~(hysHB09dN;2c#xPUcML58kK^i34>X6W-KwE$_t}6#-{hX8A;`)GVo9tEN>~YF z>`)A2RU}FHJ*F5JK%BG1w$8@?OYGQ^@JdE4kcg>^AH{-7b!Du=^^KB`X%x<~T0%xd ztixZWl!3UC`bg$L8iX9Q3Ywgzq(tUOlax$L_Cm+XrfB22t~q6qqDSuU8!bWZgZmXtwY4 z9yH<=??;yx_i0nApG<9S*ad&I{pK>*9T^{QU~NpxS;FeeX4ah_;8JYyAs_;w0`(KN zH$7e-i`^ce^*Imi4d3sffQLh)qkTXkuyss)wtke0!+AVMaAO}|`kUP+CO11##b#7e z{&3H${iU@*l9U3j>tJgjKBe#cMktZ!;F2Au9z_G3*O~2E22|pGE*EYxOcyc;afQi2 zXx)tgF0g6;9EiIZYlaE`7TgQUZJ7?(a@1s)9q+Dp z&Qa1N0t6%fJ`nYy0c|*;)WsGBkt%ty=EY&(J{cIw671a0^?#2ZohmVIAMpZw%#WLo z4{Ypgpbf}{Y}!pEKY<{@BS5CMw`XB#Cy@x%mP*yk*_hS=ExP)h4ILi(D>SrFfyx_< zb^?Y`Ws zS=4m50)R0I7tX%%`d3;Hw^K>fJ?i#5Hw7@3(;Bwn>cJ$3`I%K6p_v~Y`c2_Pr&9TV zAyEMJJ`&^8Gyz@57wDCrXru#?o|BtNhiIFi%H14Yb@gyQZc_SfQ=OH-juC|EMInb7 z{e1bZe|@K`!~BYrv%YDwLEd2VsYP*ftJe8K{Okib{G11d>cH-aE9j!nJR3>~yxob{ zx|#O8kt2;5;pop~KaERElaUP|SU4b?Q9PVb@tmC@NCzA8V$A$C+&mj&v7n7K(8@|n zhxhC`2vI;MRi2Pi(b?5~-^#|u#k1r8k@eM4QAKOtba!`ybazR2Bi#+sDc#)-(jC$z zAl(8|B8{Yof^_${xp&?7pKmROwO|f2hcjpI{p{yg`gL&1^So{I!U;PE-xg-K?uWFC z)q*SRQ`6wyEeTC_vBc0$TNRm{2b9TI9#3YC@vm2<|~k@^!Qz3w|eCNCwemL zxrBb=4Xf%e^OhCfK5BWasi`Srcc0K{Lz&W7D>xk~)*fT@k4j$Bqku;gVaVD?=@-dY>?Vq#<)`Z%C$A+ZVXMAl(pOjr4h_DECf+q$RRF=R zuptmq4!7ELLkceml$Aci!5S&%esbMBXn)Kt?1O}=>s`P}huqE|^|!GR$`nJfRsP!; zw!H2XfEQcAvbluqi#mWh9&ol($fRr!ZxerQC$%h-UnI@aijGa&&AoRrrm)t`jG zn>}P;z&6Y8IQ>97&Ek(7;qV0oxnSW;lz#d77i@j*{-Dn-XXDH_e+g_ZVXe2Q`ce4(d6zY(0Dma5TL?e>Mn-R`6g0T@r0x1{t9G2t+ae) zdwb+B`jsr~=C^Q2!};^@cNLy>2nspddx-;wcnAp3C`?8 zy&zyvZo-qG{i+R*k(c;9s4@a4Zbf`Xicp7QBZ=QSbA)YAwrOf^V<%*(Pl zbN1G?ueq9dg6sr()WQ@5HF%;)gew+b>R$Fy3*ui-8-YCD>jF+yM%jQm@x$es^O%?U zb23AAiU^#&%5von(pFp%4?nN20?cOy41Nb*PAY7dFV|GOIFDBD$K&J3%seMx8V9j% z;m(B;;=|bdBw<*+vjc6{V-vad98YO)X5X@ss;cNmzj?zloL;+4aChCq8@Y6UZB4?+ z6gpZpBqY>3HUMC<(k)hA6DWC2?+??vuMeZ+E}PG;?A#$z$^C83qSQ)B@r?lx*TwQ9 zkzzB0rl}H25UAUv1s4I?V-oT$Huj&ufT_XWiGc!r(D6|SYp_fB&bxY*FK4M^KcdNc zc=(OS&ghtF*!&ewoyy40wyo^;e3K$&VMjT8k-1C#m{g@;N;!56pq^rX(=m)329ap0{h zi@D0Q)VhEJk?}?&(poIKU=J(6{n$?Y5u+wzPlr!Vg!25pU4)jp|F&SR35AGr%8p%w zQyt|B^8fWCdBn=yv?!i+Ux`{ebdq=K;N940rZj)y=C`ZWZ;>NC-97>=eQ(jbCkdLla<#;{4NDd6cY54b-x&#|$R!e&hiSu2cFn=AhwvjSv5|LI0z0Hpg z9xv~sJD^A!ILklL*dgr`)qp+7Lj8rX%J zy?v*m{$Qttf{I}^Z>C2r_~ye?xYol%s_@vsia7TeFT%~9eS zI@8Dr#G@n9$I_FVE29pDV>0_VDfx4KK|x&ti)lBLDI7yTANKxqSDq|o?3`OAx_NA5 z3B*z$T%K%h?m3fORkAsLHE&u^L^bIYoSe39Ir<*uJGiGv+`Qt@by+OJgC;DA=1T`+!*s$Js$5i5mfK-Y!D2p7`LbS8)l6LqbBlfEjWeG6YdZ{R}+p z@^O<;rR`O^V)+Ln`&N~|ON4i>M@4fJotz;o5Rx4A`&vvN{mL5NzEcm)+CO(ykzz$WaNkG25_Nug0(<_FQkk;cx))i0u14dNc9J!}mqq?ui4?ltdrwS&V<)3V_nKM0+FL zy8PrSuprx8NG@kEUbWzrM)k@}0tIr`U(Ts)zzhN_?H5fyma%x87|%C1W*R5O(TGUx z`tf0>D}yim+!B~DAwp5gLw`IBU_&%22kKj7+3Bd^11vOHmU{WGi~&}7g6{a)@BxsT zqLEOBjI?EXe*uS9a^F(YP4YK46s-JM$Wa@X0-0E3aXw*h){Js-^Pvi~?lC$?d0{p3 zy9v1^cSl8s2F#3%_wPq4RtWH-Xspb}!|!glPw|xQ{%~}+?84WszQ8YfoBr^KdfH=t z^i!Ovuw`|kaoN;Q)R7U%sW{?w0ywE`cv|ZcFu?z?8PNXIRVM{zamnL(IbXoN!iZbt zg9`_W#n@|4zU!;tB*~=pZh;@T8;@hMIz1nx)z!(`d)m~eL86~0aYY&(?CLGzuDbfW zZA=@((!S5RZ0xD;vI0-+x|Z-3&39guTmPDM{yBu$Uem>piUY-CL4$?gMELRI?S@`1iKPEFv?D3px7$%aMixKm6D=y2(dJ)*MkH0SLLL%C=`?kaR z$CTP34?)g4KA_UPDg<)%^l5GUayqKM(z_Ex5MLCoh8S8gc8>`QxuTvR> zsi7=tf7_dzdy<4>Bok5_$qMSzI~E$4pLu~c4+40{29qHYCr{4usjceau_NZp2A@&L zgC02mIl?hr9bM!yIiK&X@;n*C6@;e#=(ORhJH2+TZU}IMTXhjR|4Qw(@mS#YIz8ZG zV3?-Vl>KsJTt7W^5e83z?1?73fMFxwFz z)X3i@3EX@e808_x%*8sq{6MG#r`yB~GYd)PF7G10OjGf0Y7aOd6JAGcwDpElH3=UfoiW@^OcAcsXh^Z*EELiUXdvA+NU~ z8u)%Ij0Ph-ALK5S*rHc|v(G(LRDRSvZ>Vca(2soCfvU%xS*?x9GAi&pZ~pL;!Y7yc z$K0ZL&D8*1A3^dI8aoTySHObUxjO_{S0Vs2xy)TxSJzjgPa`6(R2mVo3mW-V`d_6b zC5;X%oc@<{vQ?kHtUDtjB6|O88pD{cw*5@KThwj{E^ia6j=4G2YpMe<3Uk_xjfoim zxM?CViiH80H@t=bUg?lzRTZ0WCDk!BBry(p@_h9Ot*Y)M(MnBE4<92BBH7;F7EM5H z*&bP~N=Z%*esz0i(ykRVGRoicR!~67WY#m^hcV+O5=l%yV19i&W4|LFf8YYoYiMU@ z_n*^dv~cbaoCLmpmfOwsM_HMfk+h1L%jMV}S@*NJI>1iwHDbd5{%<8O4>A`gCy5(C zVg=oS$L@B9j`6@m29sk4$S-Tw-b08`^2E zv4NjJvPF|S-XA0#0DGSeBC~C^%!o?b+t*B;)w@87mFLp>NW6uDM^?ggZ2##+{2q#R zh89$A1j6y35OD?gKC5%9HJr+R28EK?*z8xWR&$^~$XBw5zkca}n;%<;<@~{YLlp1p zAaDsEUdIC=9t;__sc-+J@&e|;Fg(g5_A82D9mk}WF*W>bFB^K`b#v%#@9y3{d8~~}hZUESp5r?rI3x$D>S$eB zhIqS)^U2`cvi&d^e$ln@D6elLiagM8GCDn{ghT(GBbgy_sCz;NYXd`VCq!%o2m6M0 zCop@38@Ad}G7|WjSoZRp$ZSesDPpS~mwcGGh3pkOYy^~wN0ZHz+oKS^;_vp9zs~0> z)J-?C*oyR4BA1I0G+8gu$vl1gHq^%vvS7^Ww3InS?4&j#pyE}?qXDWg>-Bpy-?D z+Nd?k;JxNU-iF^(b->qZmZ6{271XrCcu^AvXXlYK08}lIHY?)!^NKpKgL(-xQ$H7u zk2T1C*mCHp!@NjJ^K(GSeJ9%`58I0?>a5kao4{g1y)>aKt3d;GON9Zmoq;LWzh`D} zMwwT~*3Okq#>_Mb*o9(g5^$7BNrO2Tx}7iR{?|+7+3B9pSfR@50aOJTcUF~i^_pfQ z1)FN~i_v_a{S%NAvY2le?d!#-gHHOPOP$3F|KI?H$ky5B=1?!1WEG)8KHToc1O73& zCo&xEbtovkUOopU{pnW|vM}hE4ThK549yES28^4tiP0G~eUlg&X{L!Bd`B4)sgCj?BU80kjeX(<4M4Z_D?8?gw5G7!f_;ud8tw8 zyMddYh)%S*5eIUHqv4}JaZE>1eb72^6q=*tHC{V1%2BWfJtLP+L*mLJFhw#OeZc`n zdR4$bQA`X1I0};Z7IoEdEq<(V50{jZf_b$PzQ6Yca4QflQStD!O@g-CoJu`F6<-rv zUjGi5&$qh*X!UaUatL-BRw^B|YLt5*f2^4pq=*;G`>f3J8VC^+<&PddH*eTZmhKVs zcymJ?Ld~tN#s&vN43CbM#OqjhPS@IAw6dZ=G@`H+)l3Mc-E0pthmn;FvS}5z%f@FlD{w0z#6_ z?#}mKvz-(b7292bj!~!{kT!|yfmVlxj!sZ1?r)u8eyK0Gyv&Bc>7TW8eL>ZIECa+U z0aeiKATAkMVt6=AluGW#1TEIeqS6$|REouAQq$8z{HV0(X!zUJHUZ38W+1ob)gK+4 zC>0gezXMqPmtH2ftK*-bjec5E?36n30qfn7AA}01}Id zkH5sS+t^|V(Bq-X!ob+(W=bx$fb?ZEkMv z8*jhxNeiz&JDWgCR`v#AsYpDG8E}xWI5;@GRN#AE7MKw79I29Vx4qE?>d=e)9Vof0 z&ACfgtd-BwYgAH_Fk_}g7SOdY)%={uFNcztLP?LNzT&`9)Kj}FcSF)IKapO~qS)dg zYvjm4#938Wx{5JKcJ>uyNyf|li)*hGiQf#oof@sK<~r_uA$#;NV|!+v?qQq}2gBCK1vkIwh;d3kC=o@TCFg!e5WbBI=ww4Dd{I;6E zX)ArDLi+9f@W5xWkB@4US-u}UlZ+57QjmzM(*BeLk!vI~`mvVsMm5&d1$6K>EN z=RRGbd%S(@SX5tme-1-!;59&_`g-M6M>W(WKI&i_CuFAa$@hH+fLdkSKW5m1 zMYt$hE0}mP0!=V|U}M&rouJ!El50AhN37n(a4A&z`>aL>tGEWr*F=v|8u_p?+hiKl zeC)9NIa`>?xM$8J$wPE%_n_(>t*ue_;t)6(gsx{GYBo+l&8aYBC;0ar8Ve?5cv$Ln z5_zgKZn)u3_$X9gRz^cZOY2FDFRd>6Dw=M16+(L%f{pX|_&BRQ$KCfxomilwt26{r zT!35d+M6}|x7+QK<3?xy#1bzq;vFCPG0147BU3&-8)we zc=CH3aDMpAL9Cy@$bvsYfI)LRxW|*L;Kxgy3ixbL)I(br6^!e|WJ#92K$!y(!tM?S z%`{e6`d)yyjpv?t3UQEj00C1TLE(50)nu}>fIfsYm_=m zVThP`^UvP6DQoIATYHxp#41SN+~3{4Kd7r5*mkhj}44P5ik?Und!5^A(DB2&Em#h))*XYf1_KK`5^i7bh_&+E*}8vl{Y?iBPm<2Z#k@>qiTX#S#`yRA#03Sm-xs&`4D`OB3B za6K`KQ-xOvL5rd5o8TOAx-fk=HQC{JQFAPJ-G7}4l_GgBDpqt@TOi>Z>&_McY@f?! z7|f7S!X>%(R^_7wcj(EGGeYR;m%i>8FZQ8FVw?_Z6K6wD_ z>)F3|=Zk_brXABRpAsX81h%>7)fjNl=D8|B*;Lg$XQyrw8$77v96Pt z9Hs^hX?f&q8={kXdyM15}M^p9oW)^OMyfwp%IIY7LOyU(!{b=!{FCdE|U1Y zNpQD4b`=|8(igsDBOJXJsWk9NsX1GcY5|Js?w%*VxMEa@UV#ow&=~|0o3rD8V`fEi zB&=+M|7HqCewR#AK7)P>yXOejEBSh(*OP-ja`f4K>}>dCa_*B;`^VY+z-N-oXna;cRsnDHn-)XJ~4;9XX_zFPsmS5+J74dfENHCR;BS-Jbd(5GJIxN zAZGkIK}?4>IM6KdZqnh<9B(Oe+r@{YOac=OAv^cP61!S~USjI`W=vK@iIz|MJ^rIs zXoEn=iLe#NoT3&N;5AS}}ChGE#FQ#hm3ArzoP;9$exXhXP^nMvv>{Z;V)q5&iu zNTw+;_?2pG?J5(a@l4Vk77e+T!)Eqx__J2Fekay2O-R~z22VzED{(&+u6(tQ-1FzV z)G;wL0j}V2m}5j>N2{ z#XwTG$!3B(xoG&?r?j&3TS{QTS3tw-jz#*XKw5PeKI~=Sn%^4SZ26ZuB87vUpz-G8-lm(w(%0O^>OaA>`F|H+qe&x+guhv0I zP%!nJTc|5mnCAvG4&YbHPm-A68e3tfhOW;=0hu1IN z+L}?T-w$1`o;Jie^F+Cudj({~I&LI_JDf97KYvF4=1%(k++5(-AX~5F)x^Ot^^}&{_(-mAq2~Cp_k)HlqGRTf80B*CroT_a;dyY z9;B&{tR04EQVDHaErEl#w_fet&d0zP=t~Vr(9#2FbuTdr^BB&>+bj|GoSvUA+K#fL z(EmOm#+|E8{a_D6I>gSeXLO%LGy^|f*czvCxyv}iK^iOncIje6X2!AKht&c!i@sgvs7nz{iXK(yV6*z8Xb-FMCKJ0hc{set$uw+- zc_#i9h9IaN*sYU|^0QTJuD488gqZC!ZzK3$c=E^>28cgPVzfdGgq4rZnvx9g9Dgq; zokqjHefvgqL!Qg65oG^NhR`v@%Z9GZ)ap}fFEaQ0;U|uxfp-Tz$!5#(d+yjd2pGg@ zs7&4!*ZKg0IXx&RW<*=N{!u7x+6b2mtXrK;#74T{IY=CMjB4hZCLh(ou$?e}D)CU7 z*gh1)ix&}&qt#z9^1y2q2ct+1rg%53QFbg?4IOGj+qiAy;gWod%Cj zP`pX7)8y;x``0EJnFQsIGQLS_J6;JIQ&NCjT1bE-NE`O;%kNLTVOaUwY-v<}f8KUe zn!;l-bK<4kl~B_QcYGDsXfgBh@l3Z8ey!;)=vnj$Liovx?L_dVX|-ja2;lGhL@-&|sVAkdbZkqUqYS$*%yX1%k$>kiOxp7aMqpt)G)H zy)9Y8n;V=DCmo@1Ir-QSWpx4qcyON|Q{mYByL(f@93gtWhn~EjpBpHq$6UJ)p`H)+ zPRuO_;{?;7XAFZHNF37s@4B|e?m%dAZ3#f;%f#60EK(P2Q7VmVFETwfqL)KC!bnpc zDf1A!^KQgYh)H$|2V#iSl!u7_ewxd;+aWA{Km|8RMY7siL-qYP<>{S{ z=rg1s_^_25_NHaHv8*2-?mpYKH`&GO8npb;w78I*aTq1K8T|KR5_Gs3e37*`O>tBU$rzL$3rZec?(F4J4|nFO&w7{TaiAr({ML9Dp@#|V z%3mGFM#uf7!0@}zt0gS~9|}Z+`|hT0YDVwl49G`f_sNF5X`=mfHlq1n4rIO0H~Sb& z1i(%B-@7pgiIWHVK%e3_EF`8win7#|gg3D>jPu8+a0?EYi0gy4sJU_naL71)l@taJ zIZQY|QGCzV9fGYsqDn3{4GyFWub5f#L)d?=#FzKnI20~7L37?#Oi4Z!2k`6DD45>= zbh!O7JN?VRA@!_Jm$S}hJ9JDcc|;Bw`R8v~`@%-Uk0vb5;(lEA#mS39C|1(hzSl)t z;;VyE*4T=m86ATBqqXYLsEiT9)+4iPgMR95>vIL|gw3(_SI3s*U$0=`Si`F6+6zel zaV}oNn9j>SITA7PLO{O)64YY~hLrj+F?m~&MJxHs#mLcZdqBg4PSbzR_H{BS4Apf% za3-SlKu)oJgjtnl&Nng|d&sYs8@$gCSuVdr5ZIJa@=WOtW_G~D8bGEnn z9f8)8eDceeA0ndheQTGNSLDcuST=h+Uqv|tzXzyz4U#Za&=wOFK6qwJr-~VB_3#W! zng6B$Ni=@=Z~NPi@3?4Eg~@DtVV(0uqIG&7NexL328H8@dp5SakA@JzKWCRmEWfj& zyl~-{h3D1vQW5B}GN#G^rfdzOEKT=!$Lzth|HcR1Et+^9Eht6(8qyoyMZ zo*oaqFYMnAR~rk6==^ui`M=30mG*Eql@CSuc9XleRlI+58T5}_lG{UN z1DD!ElIQKCmxP(R4#+rC)Q+3V7j&2=7xQ>}sLh|U+iK`B&YR;FZHiwucZE;C!{hX} zBy}Hf&Nm$JtW~f!^Xc3_@CBk7e@*)2La*Eo>6oP% z^5lHajK6D}FTC;VmWa=9AD(W42a;~`V6X^`tNI()g;TEzqn?9bgfFB1y*L+aB=M=9 z6ngeS=fgPpqzp(-!anv9r|E9fi~PY;fM_VJY_vd+DLAWXdE{dGfJ!lnA2dOPnrOkz z&nhJM|6g;)St%6nZ4sok8#P@M>aF7us>Ow9m-o{Ao>V`S-scu0LPo z(NIi$bZE8=pt|a6seW(Cm1vm+&CmL9@P6K;=gvaymnFl9Qz6ODy=E2#R6_yf*#RNe z6&&UVHq1u50*H1p7h7rFch&#eiYY=uAVQF-`={e@u01iL&vn`z!DLYt4^`KMF)a-xr+xRgN_)Uepfbd0AQURbRWxL>iDFtd6t^i4CC)G2Oa7q%72bva zPtDhQLD;B0Miz&7C>-(rEV(T=?)Zxoh;YWruZv9l%$jy)HoD0$TYK0YB#7G*G`gPJ z&^3dctX4Xao(x2TBXUItv=l^oxS7A3v4mNr!#W7+;upSta_QQjvfJDhf2$JtguAj( z_Rbxf>lOB%LKbAM$0Tl0hy@|0uqW$G%;?Df^`PczE>lHHV-e8 znJF?Z1%q`gR4b_Zy~d}e^!a{;76=G*@}US@gu1y2-MDn3^)fE`)f?0PsEd?fOI~q^ z3q77p7b4y7UI}NehS4x{+E(OPFpa@l7H2q%cXAL%O==5z$a<)F?(ehh@Ti8lnWC?4 zt3Ex2LWD%*5yfQ?W!u3@MHB4pb`T&Iu@Ke&S+05K>oEI=_NdEdP&1{DCgmVEjvrO& z-DL^3mP)UVLx~XjEmg0jng0DTUIxB2=C~#2(<5aIqgBdlCB2`X z@t4?rYNCfcP+!meCtn3|tKHXniE(&;`!|SH--y>QlfAWz?Y$tRI~VLGBa<^=orWA|ZQ8R# zIt&}bj4N$nr;_6!K(xD?dc--0%iMJ*Y5_q`LmYCf**6JK?GWhaMp`m!GTw3 zt{?C75{n>LB$oQ)DwkS{2%*5d*8=`>`3Q?3G8{I?qi-$w&$9_V)(9*ECDtD*LqyS) z{|-{Va(@5*FdAWtk!)*T7dm9!g6tI0ywzpkX?;0TdfQe>9&lzmB3cWQ-#9wAav~Rq z3$AmBdrf3gt(XR~d&9D2h0m-$bO?5Vw~r!HzOQtp%rf3`%I)4bj+Y24OQK_Cj9 zd1|7w8BXfM=vne5#FMag1jx);j=MeO?ZM4&VmH1da|)x2>K=%v;e|b$8^8 zENE`lEzBFN-s=XEcY!NLv`p!WxCjML^w(x)V3nbpSvS#w3Z8)riykr83Fk>OV$47S za%t?F{+uQztQav2y2HLSnvZQY`l3oSSl|_4kEBy+aFAfZ-VFz7B(J5u%;;mFu5uS= zK;U~n2AtSW*LU8+1xFX=(`(Cy%eYBnm}pU$F;eviO!LMg_m3Io3>gYl?>-6GU;?p$ zhMraza1fLz#@IRYRwsYYO~j6($2EmMU| z9I^c&e(4Nfd};pvd4Ug2k1E~U&fcQl>$V1w542(d*roi7L5OhWL|L+5;+%F(bsyVG zoBo(O%aF*MB`72{(ic^h6op|09oaGqE(>MgVx^|SO)IxT5p%=I?=O)iZJC!nnr0gm z55Kr^4-P234KAi)s9pHOk@Aa)h`&L;^Mhuyl1(qaXXW3=XOSOygf_;m&avF5w;FIrbr+xx9MnuHa=}(Bv3jC~&f40-Wbl*C zsWxBYN}?y<-pOCTz-4^;<7KoxzWGVoiinmIEbiNG+j;@p}8+ z;yaLm1OnB;?c6{BMn>@dooc*MC`JFt&CtosuH(g;txkKXh#-k`_TiE8rG{ou`eb>Xp!I z|1d6ZmMB)!^8a(?i-`hfa}))B$-P2pvE)#zM*j}02Gp_60Ui*%J%nV%UvS_2XIyCa zW@jV(JpHDQ;!FyS(cEA;Rok%sh~OPEHX9D#&ax8x;``eNK>`cCp%eA>$0gOHu1~-! zzYgu$8wPpGskW7Gn&I%%xPvAJO|NBL7@bHFK0a)#tFRP4yo7itF-`GJgejFB2Fz*E zKuEFoJB?8s#pGKqgCiP6jM<7DO9ps(f^N#}Dx5>gG-$~fT`kUv9gNv&TFMT73>3&c z3dB-27-~HqO&6L7HgGr5fgNqaE@V3rjB+R`giil!dwR6|gtGDkF*=&2sSE`tBtS3wcCDCY3-$f#_n_b!i#fHu7uKMOZt- zp)fjIs!|`qkVGs^?K-AWNvfEdiEX5~lt9>`E`sxDsF9*bGYe)r+fwfd)0Tk*dEG;60VCRZZM7VJ_(K_~4JK=p5%B(ogug?kyTFuXrK zL4Awikj7qOYt9}+yyIOkMd%Uk7Q&k%I(m8pEL8*hQ&s4r)KF=($dR;6A~iyCB>78% z;dh%DQjH>1dD}4WXb@q=cL?oCdxd6s9UH4iV8dyAd8~no4s9Ye3q|H5*w3)Ab%l0j#Xz732p`P)VZLV*DCM z<$r#wW6Mj(r><;%IYIfXXztTvELB?mv&Eu`Kt@*9tVwr*HI62h%3suEyw;Z6cSN^I z7X?TjKyH`SjNnXT8Ok(BlVFKBjW~qo0XP7pDR~w?jCU?NopISgO&{ z(FtonvTKI_+fW8(9a9H~THF5OY|apq>RPvd6EIlH;O}d}1d%kRnQ25wu3*>T=1+hW z(JacGrB!cKtcD;wGi1v>-HFcBX7Av@%+~UO4mM1j1`9D;sY1ZU%HNw-H)DC^LRgqg zRj*cQ^R_j;IrFvaquT5Z3)yFpdGq$pi=_r;A(w>z?JOF^@|SH^;p?3xSF=WJVBhw$ z?~Va%DkI+r2c`CQz7KV5KlsL8$>l@`Lne8MGP_j8QAPp<@dsZJBiO2~OGx8)-PWXjkUoX91sG9=UKHN^oUz?Fq9-FCX59dTFqDbEQuOoOLC zIxk5XhV`!vRZ%nAC$4!|6MWah4NMvP$^-X@G>!SE1pK2q3)Bf(DPFbdoFv_w-nYxf zyoX*rw7D!hs^z&m*DM1_%BwH*IgXm>E?cHbOS*vCn<@W1$iTZnHkygv}I zrpm8ax$W3s{kyLnfb;a7b$BO7;nD&NSIU{hgQr5#VNakE3n_`wvH7ciCaP=F`lm&s z6?AW@d2D&%;5iI7LLVOre2O(8iML&ArNiP+Uq4<1A*x}_?iIM6l&N+m0@>Rn>c%t_ z9GI8~CEmveIcI4{KB`g7?h&*e(KoqHi0p!xvbL(RS~15wtIZ*E+m=wT;6^NZ80@+J1c$6Fx6BfA00QEoDKBkm*RdPrlh#hYG3IgT5taPExNt%R6 zXKT*&Bsb_iSkh`|2#;kk9KB1~MOK4u-B)f^%^eZ*RTF2O8GJ$53k41HH?2MGG5#1;3L4lCQP> z$*XO>YlqLu(+4v<34H;jrv-QU52i87t4-_ehFCR*UET#zGy6<_!6@GZ=>EqA5JQ2TOTOoj zJB^J*iw&!6!gNxi~1NF#E})GD{O zH0USwiDO_wt^~^Yqjaj~qIh770-niZ9zq>~Knc*uY;cnFgzlY_t!H>Ir%%PGNN+_f^0 zoYSpWs7v~YAsx=Aza7gz_kBK8i~=Ikddov#+pCi!unx1LlwpxkB}zvgDf(Xr(%C^%sw6X`~- z;$oN9OeEO6|4x<*%{frko%r(5-gF;cv6G^Q&}i%t1}UOYX~Qu&Z%N=_bd4i*ZN@^A z!Z+6veLw{fkfVzSX2OI}l&<Y3&&ojDvVCX;8Xu5Q z0l}a6`l17DTXS^>)5skeld)1rg<+9VQLa0~h`0Wtw%kOux=m0C2?^3q4cb}SJ3K@Q zcvh&WsN2BjOm7iT)aQWhIY*7IsfVpC0`S=BzrE#e)o0PJ(~tP_e_Gj>Y5Al^I<@6 z00ug6Im=VAnG-cU$jSWJwpH<|tBaUC;1V-*fC9wqF4pQnM-8cOVJGe~S_5A3HV`9$ zo(Le@>Gt?~LMp}@jf7@^xKV!h-%6RUET!Io<+5__@ zJl@wkLS_n-;)`g@QDQe@&vqQl9QHpPQI>A-6NjDujY=_jmkTNH6d zn8D|%IthZ~w)pFRT|LFF(8f}&uCBU(*N~!0`PB5kjYDq1nofVe&bG;aRVY2Fn$*PJgYwnX4xY6(u#vtz>3fwywZkiDzy|4mJ>K zpr7_suIsAzheoa_{M5P{+?KlW?&XzmL%DK(r@Sx6i3B_7(Z(^Fh zXng#%iR0?lXL1HJZbX9_BFm3$XzrjN+rB_7*B3$Ydj)qUp@Td7gv0Oe$rw=ypT^=I zOupG%8Ae_-V;d|vNawm?DDG4r?Kd4XhdQ#t=CY6r&%Bxcm zZn{Qnb(Pd5nQVM#1-q7qWcB$Qs6e9hsz$);NePn`T3#7S7#J9Qa&8>b&Ca%zNBxXS zfu>mk$M(59+S@$Uv+02fWW%2g=e(IMCKwD2Z#6YYkoY+Dm9d)=jnqP1!V! z2z1HkR6S4Ttf}z7wB~9Lq~2$baa%s3NmeZ@r`{L4e~OaK19Ny(s|Tw&ogO`rSPiHe zqoO5`mQ*HJU*D{X+7?R}gMvLtYuiJ2HA#sNGisu8Fb=<>5zTYZNp+L&tE4SfMrz__ zzuQW4fXF+j^=u?IBme5)JrBVqs|7p{j3^FtW;v)TohlbmEc%ZNU)@&vRnZCIxyt$# zvy3HxS9!A_npgjxhneC9o(ERc90V+Vs2FL@U^(Yvql4uFh1);#d%|uHAEZMucwpG@ zxppLvFTNx&<9kD#6Eer*WT6a2i3f{n?*$**PXM8B|I~wbGb;lEx!5tRf-l$C4|2 zjNzSHQIbevB(QGrAl28N4__>gi~lgrgkPcC!avf~Wg)GqsT-o6Bp2`VCSa9-q?I46 zR?B>Rz(v8kE(W>iTkU;MjvLHJrLsxpR|gB;zfxq+IafFbay2+*W1B=DPbD9ZKlCw~ z*6FptB?+I)ZMbqlW@vE!jco!}XOXX}APJS^d*BqN+vUYV26QdL+8_#Ol9eHZmqP2e ztE&sgkN2J{wMs=(LBmP^kFBqai!yq*rMsnDN@4(|ML=3Y5RjOmYv>k`l#&LKmM-Z5 zhEyqOq(Qn%x=|YBZvW?;d+vw(WqvU8zI(s1b3N->OZ4J<+83$8G(l^m-<6w?U&BNG zl?JxD&yXo?AY(-G?Cs&81%s3y^|aAjhQn`L+06~O7-;O+g;CW+^kRWumVC+sJvs?R zR}Pzw_-y!-RoG`MQ&K3Ke-A(NM#zN|nXUK4UM_4&>5UQ(m>o16VFhZ>{=l!@cX?QE zRP_0mk;U7fb+JCrgT*GQqt+XzAfqn}ZulTMa~O?Dw_~o>n%MJb$!OHXspU*}!L^sc zyO;1^?QKOhAk4{hfB9m6wzfF1-gca0;oZ%F!i^#q9tIjF0;smF-(4*8Z)bpHQEU;% zIc=B9LX0+fO^Dre(@|@5i|+;HjK@~i+qDz}r&8{{thY-tAejJlud?Z|Lrrv1dnHvX zSZlo6^KcetQWkhNDo1QKlrEeA{qG1OqTD2(bIri{mhRo{QWdh*mBuss zX&`WIJv#dPefxySpJn)aaqR<+XiWVqr_Hy;k+|}#q|oA*LK*6{AJ*QF*A`NTaqY-U zT3Ep8KH=7(N(W*r`TZX1TcJYne0+v{`s7K_a^@8w#@(-T@v`PWdJMueCIloH;K9L? zHZE>X`e*e%PN+Fm6%;-~!%`*#%_)I>!XmEJx+Q^&`TfwF2GwVurK4=%w^%+&w7fdVWf zBt*>Xn3;t>eqB!G)IYnJdVj9oUf?phla`vktvv*rbeQJB&(yS&4Bs45&h9^mAXIwL z;~ugYQl#X>T=KtI>|4BR?nnTTX3y`>}GLZv$=ax=hyTl*)iSo`sB zM#38>mhK{`x$6{YA%P!dll*wMjN{M>yL^vY^pYmW=R<&`>Q=SN5Ehj}HM51KsVPcT z>$TmOo6@6K*$`?RN{qbEKLfgpnf{4Mm5R4@CsLEk)PQdXP#fw2i(9F(PA zawK9Rfa*{4)n}@MObl$Vw1-@-gb?F>&{TBl3#;k8l89}Js39nbmooNo{4#LAx=G#I`9(gc={o(FR}6P2K6uYuKC z!ajGy;;y|2C^o%4>H#NONiJ(0aC-&}EkuKYL-DEj27Ou!=R83714o6Of%dSz)*YR2klug& z?~;Q}Xr@4NdFa&CRP)ICiI*}03elys2SSkwu)<5^jOU9u#(%X!11>w6M#19Gg&^;} z9Y%MWg#l|BJWT(|qI+3vk#uff7_h5ufWjaf1V^Vg&YTvF3p* zoKgaWYa_>uIwBwHnRUC6nCtcM*}T95=6(hje6Tw?-K35=Wt?%_LTdH>ib1Sk%Z#qe z?+mB+DN3bf5$eWFPETXcJ@TjMH+=r__7~)fIRf1NyLY--B; z^y9=V4WD((NuABg%EQw$m`KIBYC-UUc_a-s#WQj7HVijEXuGeR0A-Hr$I6NdLU#?H zqk*im%$Oc)dOrt8N6ZIBQHKUmoWE+!1()#gpzxF?)-HNoORFicLd=aAO*o?amhq?{ zo(4w6Z;U}#5d9V*&>hYyxHLGD^PCtSQ`YYv5;r&~4kV=+%lA*;Kh5avjHki&AI_G< z=X;b`n{cDZMxE~3wgzTPjjqoo1K+kNaR-O{&mO|sWlvV6U3yTXfv$pFyDF$ioj?u4 z%F-XC1Z%K;zKC78QMB>P$Iw;xO^)F99AcF4a#5TD`XzX+{On$@V|4bRufONay;Xs$ zNjh;MN|#f`rE~5a^*mG$^$U@1jw8q@!tIS+(6T@I*z-?U8Zr%iE=3*S8R9NfB$z@-iyA0Sj&9Rn-Yd?DNuFeGrHd4YJn9b2qo|!%&>42q#2bB@hS?2m zR6@(;u1Y&BBG0wOl4j#aruIhZhHsdELV$qjADx==Fe`lM>%urTltw&=3TgsNF`N`7 z=1HsFfdZMO@%JAaWGFAk*rdlMtD`fs!M0@ZgiShL$Ch8fNYO)Imj(A@^85w|?BmXg z^b<-HsJVpn6P;?FH_N=kET$jubx!g!v;vu}ocIl7F*voIsQLySQkgr_rQw3~Zr7_5 zzGkgPfxOCwq$wZCO&@3i>&q`pWP-?qJ~jtGkA1h-QE4z)GNK>^-auNS+_X8GTf7{TFRvq2(2oMQlvW;MZ52Nq7^xZv9lF?3UxI)jT9hn6KVU z+wz2WyV55)Tou|s{UFCb9i1GRTeaWTI_xcv*GwLgAo zoK~gf#~BK?>sX<(@uE8w$sO~5^m;6Z5f#Ppa}?B8GWkiT@=R zW_Ei1+owfPJ-Fh%PE?E#I(EVPVCE4_mf_ zXXz1n{EQVdd^`n#u~ssq7`J^G|8+W_edep&=cEd5l~5skx`MAP5IS&(axC3d0xm%p zkM$0xc+;@=H`=Hd1N!FHK26Y>?TH!|DXB?OjKNsq0|I>e^o@;mY9;xHgQ!u=D9?sE z+`6GEP#P?Zh_dP!p%5%xcH8AvD0zV&!n}!I2p>Pu$K>o7m!QXjWGmNMJ2|5{gXdJiNq2 z5t3Qa*JIUh zP0iD}d@ZjpA>LE-6f5sCmodvKKz-3TM`9cCi?Gejh@MtWU97B23&4HiyRLQRk^}uj z)Sj+30!=Hq<(+Fvc=r2*VoQ^nnQ+&3UG}C4woof;boI}$Z>TJl(Vb|jgbk3reu zTLqDIV`DLVr+mT~E2>?39(qPkDs{Q`YL-UBM47=)=S%J=q+3NHMNE|;aR47o29%@K|7 zXoRi+vo|E1J>%m^R?U-7oDDs?QhdjG5x-znTX-n^ zP_7Sz7ScpAKYjYN+MW^ExhkC$-O-ae+&?2+|9w!X?PUVn?(XhsuvTH6-jfuS!gSZb zv?5!ODZWA2uh)@o`=9@&rZx#VQ#*dz2qA49kH_DYP;3yRQLB{(He^qXq(99cvoTGp z5dr?rf<)Ifkm&UE^k$hQuuvhhFC$J?*@*eOB1Yu&<=IiK78IBTw($X`i~G>mg`+~G zySP!ij|P43Lwcgr?kL5ATC38RV6%dg0=I5nRyxZwt{SlbOyTq*>p>Fk9`0^FE(q8Q zrX|xkyy8gIivbZjrG(5U_9hj&s^&BVVG@AQklGbBsFjvSU7nQiL+e0*HrD&W8v?A( z{Ue~G%hvQ6`T5#~yF6(nSG&pTCz*Qm$Zkam{P(nLOf=eu@ScE}I7lx`=4JrDbO?u1P+<6x(Dw3y@B4O<={n*Iw#fFrU-zvF3aGuoQv0+_3SU(` zD|B~U!`t_t(_KM?s^ugy^H*#2{PU>x6Vg6Uql|_DiSA0%gx>aCV&7Yf zgoA#Ipf(SEbU@5{{EEhz5KoyN#|zo}TsJuq6$57>S9nb~3$utT5i>-Y@g_v7`G~0k zFPbfIub#u4&&K zo3r(!n;nW49tZk`!oj6R?}^>^^KG%BK?0s>olf#3LO7_>D1!K=iBx%H@DtCJT?LIh zVdw*N$%xO^IAcN~?4DGWqS{|trgk72ABEI6k<{t!S}zDICk@K`=W=TU**P=mw`GJF z2hL;R!?cFw<(0%$lLqYxw5@snWq?2I+#JTJkj`ln8au#VNDgPW}KnArSu97axqYF?Y& zTZZ)dNu!cG%Gw9?-75|z{A7N1(u#eYqY~H%12rd?B(yCb-}Yi`$|O9>@imAoaFej9(ukIJ1XkpaWK*UKiK zjZFZw&eymEJ-pDW%-VqpCg&vfb6ef)PL@Zf)MP}mcZXxhn1b67^SeBbxkJ)Qu_=@N zI|X{-!sn-yzy@IZ=*j^dML)@&2hO zSr2EXy4Bg(7oJhgwU&J5QPd36H@HQRkj5 z!ctE)QO@h!z970{?-X4Uw#w;GNUg%&fS5nIf|QjuDCcI0=%RydjWQNp-0IOL;Ol3` z-YK)mB+4jp=?h;y)2(e&n5#9dJ5=f^zf-eg=yApgOO~ou&-O5 z#t=VOw^$dCPkyRm*4j?Fr)B*MjQbcw2`_}4e0B$Sa)N2kK>0F}t0d3HPsC!{Mf8>e z2_pDZ74_p*?EeZ8oT-t@Ecy99{##0V{;`5R18s3%$+#xL;gh*)m8`}KT>(->HLc5h zN2{q8+bLBzQY;xr@R_=MQPcMZWpaGvU`ssy5DP4+9!LEoGqWOW&?Lvq=nTpWLUn)Z z*Cbmpzki4d(F zWXY4%LKLGyGVIs&@)ey4Jru_$u3ZYQ>M+$wABf{b=fI=3XtbAahV|3nX*=3J=Y}@l z<^tir3BX~;BwI=KvKDP_9#P5fQC^F8`}5UlS+wERqb^y}2XnR!zD(gkH0avKLQ9_* zlY%h}cZl|NI(x?;=VlBT;mne!a9**XlCli$Xdi#89*D83z|EFN3&a_xubJ8%gcbea2=X)7?7+))MxIr~j=D&!qUVMx9K7E|@&@sZHVF@tJj>(KDHpilNG?ZIb0 z1DUlrEEJZlJ*GjANYRxev0hpK4;SF$V@YaXQFtaqt`)275$%}=Me~=QdtzrV3)cw_nDy{TCXsGbZQPYvs{$kS?n;sekO)nrq z#a;~{TT{v7Hgo{Gap_yd6xmAr9u&mPNfj87cpK<|`W?lZ$0l0K|C3q$&x)Bk+Xw2| z5-=e_FfA+q$Si_681ptbYJM*-oUsGoY|&O zZK`+;8dd=Krcm3Kq{80dw5VTi4}|ZB#60(*W01$mDmtY0WsCv0t{@PaZvzvn*N+84 zUVu*l&2U--bjDZNnNyWR8KP7RzMnC)-C*4{(SV^03_-MnnWV0MCH{-tX{P9wcU#0s za$GSA>%5XU!BEeUG7>_6RXn~r_JXNm&VRkMIJ*O2R#E@ri~#R9Q$7%8*xNI?_ZfR5 zoc7XdJ1-m$s^xz<@%q*3(ci3(XYmrhgBAoo@M3Q8Q)Mq30i9-UqgA_yR9- z-d)>D-0asXz<|N%#geb{q~GPA@mK2x%h$SNM-C!%0PSxrtIqb`q`AFYzV{!yV<5sl zY`rd0WC!q zGgyi6EIyKYvt`LT|HWUJ`RL+_Pa%|t=|QA$t*4t85~pSEvdEi)l` zNYxzOaZCGo8DZvD&3-1WFo9nE+bUkGx5l}SEPVxnomxe6Ji=H{Y*QzKe)sYoHcQWA z4DqG!p0p8v#jK+LaHcV1J_17O= zVSUf8#;4Mor8D@`q~D7D<2wwMt}5M(4kItiDo~%(?@G%D8)2YI2(piEuCH%@z<3zJ zvcOHazcVP0UC^a>KzO;T(e!!$1sXClERDs=zJmBOq*a+y%UNcfcIpdga^n&n|2iRQqLsj@ZxR3Yp+ z<1XjZjNw(cysBdC#jLEyFo=e|&}?L7Ff%hXPTMn)FnJc#w?;;N8%WhCx`QtJ~W8L5D|wkG83Oe4wAR3TNPDG4u_^$7?Ux{z9#ETgPYEn}rQQ$N+^!wcdLL zvL7`OPo1iiQ`Vx8h#W;q94HO@;GYGI?^1k}3ZJ1IMdFCk5JQmt&fk2D2BZ?>FTPFM zb&Gz#QUj|3gy~04n0aYNDZB_csRJV*-8P^Oe7Pz5JrWQV$qDR|X&o~9!IllUZ~3-g zJ) z2Iu7uMMXu;BYV5M$3UKsJn0FzxYsvfi%y`5XQMMSpDw)p{UwdPRx!o0hS7AviT!S3 z^fL{P1~LKmHa2bG5v+U?Xnzu~lr)&W3&<0ZRK{L;x!(a=We$o!&L1RPhcV+|dVX7U zY6ewc-c^*A;sW0ue$HZ8B(XgRzAn5O0lX-Yqu*D*w=8bX4=~}fs%K`^%ONkBN=p0q zPwIeN?EXwOtMlE6`9&6hjZIAAz>T-&I`iw-;XL!)=j4PN64{p-fuXwd&4?s+>Ok_v z6~ObWf!|&5&(LHf*cu;$S||)(L{sqtdzWXYQ^FNV^``A;|K1Mf^w`fr)qe-)BeZUM zCT<460`_>nc7)RK1yE#cJ3pAmR}mQ2Epsbco&axoC1d&4s=@sYpZ$D;qeiJV2pJye zH#pF=p2Rx0*$q`O*SKw{{O4X_f3yZ(Ox4hf>~PS$=+wn|BHqC8IFidiETPM)ww!yUCA{aw zarybU*u-0!hmz6%3RyLvr>5dz`j}ItZC2oP+UnBwEXKr0Dh*ySdyNw2RAV9GmV>kg|q*ypnt$w1>EYL{64d@(6$BNZp|6;-6Pva|z(dw-TOue)brvvi>3S zXTOp{8wrQ9X6{r@v>S<#OZZ&nCxwu+SCYYh?IAe2dCrh6_gR#DPBdRh^h+Hg`_A#W zeCH6%2Y}X29*eE^)9))t+OV5s+w&hmc{lkE@5Qx2JaPxQy3;$_G?i38ApPX4iMc|l zRXrcw#Dj}pBvXYwqV2F+s(Hba?8VLe!^W7I~!-uay3Qh<4^goK5^$ChpQHe zQ&YZGwlt~|hNC++bFLk%GB&3-M3>Z?FH$keO>6O*?`+|NQCwYaL+6{9W}5-)qF2Qo z`3FMJz_KqEcT`_;-&A9{YA=a8{Yw#d;V82dt%m6?s0VxtGgh zx+A+Lcie+iehV)b5|C_i=$=w1q@>8s-)8ZcHg9r=Y z)nhut|2s*$rmWOUf(Ssq**ajz$qxAIO+ZL!=Hf!4UqK1FERQ}>Q zs0q;xSk;<=zC}$>-!(c);x5hr81CifRJ^W6OJMnild3tzWkK~gZE>^S*LBNe8MiYR z6|mcBW3d1=@F41Z-;+l7bIj?BYAD2+mzJ3VdJ`USiA_L2VCv;XjTM3lMoa~NvH5hX z@!8~o>vN!<9~6Wd6BE;BBa~lRS!w6bst4#_m%RbEFaBIySh%~pE9!pptgr;2`qx11 z$ByZN24BGd%E4gcD|Y%=wps&rAY9Kh1#I=2mhbp{e0^6>yi5hsG(?B?JKYZQZN-no zK$VwE7p{ZvrqpI&gz?XO4M`};uI4}+fQg-mW$!k#_%Uh(rg zE^%>jkRY_;E{>1puLbSi*RQvu_qNR;-uh+LbOkusC%E#%T?r2 zX4)~LH4)1If^6B(j$tG`^-;6hv!`bHdIRR;2N!vK;U45KG|Q_(wPxRsW_Oz6pbb1_ zKnO)^wi-6MLB-jfn$}S##wsu&y0Ew(H!ox!u<5#pf1*)PU`N0Cqq5-HdskvT2b#yq z_>Bw33ypb0d_`E?%+flATG>c_`EqW@!CQ$ytRh12>W#Cg!d}|eVc=I z56TY?EQUvZ3iqC&tA18Xda)|C`0QDNrxi{ht*cTzIoDV)34sjj%y}!FO&#x%TKbKK z(PT1Qu)J1<{Lw263&qI(>$7{mN3{YYSFOKWj@`rHUuIXIcnKhSo8q;50u9o59}&?E zdOiQjXT#1Q;{sdq#8$V2c|McyA+B7(6aVmsnJ-S(Lv$SN8o3lqj7B%Fzqq;QzV>Sz zyE@l6aL6g-#Zf!lFzlw!SRVe6^Tn3kU#A3=?EZ}A)wiOlR+5v^B@mR2OEi=fr9=uQ zyoFT0&bg>q=~VpUoWEF<6Zpty`!l1CD;JlN3$M;tUS8*Be#J)d>M-r@mH7*id;P%O z$G>t31SdeU^)Eb3Z58(PmmKY9d@?i-(q3XE!WR5Z*%Dt0^!?{!*AX%RD1qecQGtVa zWO|_@Go{*57g30Vnx8v$xwFg3P~iE*{vf=5*PI%w&yvhHLNa(>X==AqvWsy+XJLrq zXVJzuju5uANMgjpFc>-2oK~r}nv{0x_VDP>pIQQAO$tD%5X ztH9&ZHG0P2haC|6eVAgw{7?XMYCqdaRG{&F9cB6Fa)2M&bZh4kht`1NG!4Y05c+=5 z4;z3}tD7~cswWBUv#jCJWr-(=ot&M8)v35VgQOR!)+i;AXX&U@nNadDSIdkG0Z)J= zOkb^!Y_Pig+H3@1Rzz)aBr3~5qVoG|@btQ)Na;49EiEni*B|paKacO^M^c=b3#&{| z)kiP%<55Cl`2UzT!fDx*UiJwnkA{?nprE{{#gA5eHetq(VyaO=rR~5fZOZHn58ZJm zw%QkDmNC~7=`(w3kl|X@ho>`xjY6%pXV2F#2EiXMJ*+`&PEjt5XXHg;*G+%A9&sKu{sB(Q%e(qravcCm78ZQ=6y0kgEJhGSbX>EA~8 z&jg1dnG8Q8 zI$Iy-?_K%)lUc@8x}r06jM-T?@#TkBgKu;9CH^}+H@)tc+KL~Cn=}(lt^as zrdGpHbX!BI@fxU}J*k2W(R$h7rPb{tYWIemzg=MKfEUw;EoomS1N9$ulCDrm2 z^O2mKI?49yJ=aG)CaFew@BM3A%s%F=h;8%)vvkrX$GSnET^zL+e<@zEgaHnpKP^L; zh1n9MSQfLK-U!O8RNX}+$J?C?MhZD~2BF7Mxn-gV(>(7`*QD7mZ~ z8qQ9S)~u=bYY#{2c|6DXzS>Y74jgVtEl<@#;FZr#8vVY=_!YI#|L8gO{@6j~4>z$UyYoC)(SkWC!MRO;t!J@k=i&C? z?>t$O0T#Vq4VTA3?M@!Hx=fSdi=~UmnJ-Y;3*H*;q;HP&e!w4ISUVnG<1sO~)`it) zTI^;GPibk{Jo>WXh`*AEDtCI?c>eh!m#eD2Wc1UQzAsWothfXT=oB8pX}SSaw9-K^#__2cKS`nWp$<`hTocQ~cw+t%R9+26_}PwPTUh!4EiDRj%rYLdKp#_46(AM>Y} z>$6{P_e-&z8I*VL_s?0dR_eUbzezQhF}PvjZgLnP#;s@&=c&4@9KA97>(Aj-GB}sK zfVn-$-g_Nq=BD(YCi3s&4*LmcCb5cny5(;&mQ!l>`{VSkDwM**@ljsth+Pug<3Ri1{Y#EcqwdB0k$vT(zHJo_S^?u(9gg`EGtbFH z{ffUT)nt+Hb0?vNP?QEdCv1WHM|!5{rk?~H?rua7V~xP@O{)~)vrH0lrV|~zuab3u ztl<&V;nwNwDJMlJ?ye2=S2iX>yHgm@3$wDzxh-TO`|!{- z#jBp`SSNE0m(6KCtF!k$Na>fXbZ2fsyxYIz|JuY;_)|xBi^*|QeI=4k*$SX}$Ugu~ z)W&R*9?%Kods3pp6m%h!>o%#51+h8wr)3a_t()KeKXfn5TKPgpXMQv-_v0#fP;w14 zr6>nY3p|VgRH~5;DmpfPCadM=k~1{qd|z+sOGLc|!b)y9SEOSnai zVN8@YHtCeH$^JCMZg?b^5VI7=>6ZzXePV;^rzDBV zvF$#+W^81(N`uAYwqO_w>++k5!9d*#!;eXpA@+I9n}gM@v903%u$>JlSpA@?;vLo# z5y>Z{(&fbzb!m#k)!n->Z&~^{s=<%<4cA-<^KG;s5$9(%ufv2{b7a!ht=+3>jNVRH zwd<~5Jn&9aXC26IK?Ayth)UizzTip@%I)K~flhO$W+};*f}z{7vA+380!T=usi=+Q z+vY|xBPD^flv>6kNiq2`g@R|Jm~$HG-H!>Hmu_65+J24;`N&G|eNzeM{@JHI? zX;1LuMMYq#)QGQVDLw2o&ks5n#Qi}-XG^b2kQn9o-xCYRY=F`LB{i+ttPZD%sFBI^ zi5**cyu#@7$>6;JZKiid7RHUO4QVc>ut;{aa!uD6B_orqo4gq2 zI#$7gEYy&!$gE?9TMevf6!V+f*$s?HQK@UH=G%pURU{NSlQx6<>Ib^V3@e_h42joz zK|uS(hdb+-vKM1vB1HC*Ur`;qc<@w}6TH^f1G?Yl+$k$hr3Vl;M!dQ_4IwLH!MVL& z*E`P1{#%6pc!I&i6ct-(}re&5;bT^$)W z<+YP$MibeLZ!YPL{cfAsVZY039~ZCX$E0R6pBzz*tPifHs?=ENS(&OmQlP2g&sri=H*z1=95k871ho`xlEt)4cZxr7Hu1*6z}=N{Dabc}2)`Vv7j@Zhi%dW?z4@|g3Db-c zr3~&mlDZ+xp7SLDPu@K@q_a`-?F01`N`=%|=96}+qqRuMktEAIvt4{Kn5G8JRO-=c z8`2nYIiPtU$_Ceov{sgqn@_S}dy|L#jb@N-l}_mFkcLLKJQVMBZEvG7&Rl2zaf zua(!4zQy<}NLVOdVC-HX3Vd(7;(jK}rDwkQhUs*LmH-3Bl%j=h{f3|14RcELP>#kh zyp>3m9;|h9RPe*gA9bECgbN_C{2BZ{S;4$?^u>%MKMqhpm!atQn$L9wKg87ns#e^}xn93j$lr_u)DGfGbg{C3qSxq9cW(dx{I z>pYIl65u2nqU}4o!7)h|9{!ATNUFw0Bow0#>ucsBGcJwp^k!b{M0}xb@W3P{4OeIX zoP@g>Q=LadY*!I+Mux968OFauqA&M4&8gr2;Sggm0;^z9P*@35x_FmaCY)p{eZ|cK z6%sUA|5Qi;T_e%Md}qkU(>=%xhNv8FrzYM!w;~xgCkTmHim|e$f+C@?v`{X_uqfu; zjwo7)%hSd-q!1u@nZ<;HF9d}0eelz>7ISIv_U!Q=_k?InwuftmDGr*34vb-@=OG(J zh+j)+Q|ZRQNrq}lguum_D!;#~-nNr+#~pOfLG7 z6<(>XI~P@Ld~1TG!n>Ursr)P5to(1F1550NjeqdySy~75Ss0tWfm6`$lcP5u_`Q$T zcME?bBQF`P@Vt+wCQVkmd%q7neHXCKDAjVyjbN!sN89tdnX7Wye4OgxY(YBBZxW~@ z&qRyHQc*JEOp8nUF(yL;;MEQb9%cL)ysn| z=d~`@w52TBsE=B{Zl`$^)F(cD;QgszkXtbJ-@Fnfz0+3NHtzPlW4lf96pKk zwV=LRVBjm3_4EC8^1qGk2$`3 zVXLw1=BI?YDwlSRg?~k?hBkfrc4eUX`%h`N*{yM2N1|``D*boC0Q}!ymL3SdWz1>{ z;t_cIVgFs!o7?jRwZUZ{lZgdymrZ=bL>?EfZQS9L3_+8%_8$t{@_)=+uEi?{;9d^L zI9r#oJN!tA)5sFYQJ04wN8=Wj{YA2y#Y-A7ZBPGc(C;vL+?QPrAfKu8lkG{a`xipdmj(1zHh&l-VyVPEUHRWf5P!dMUkUi~ zKU{#7fOht^ZVD@!KLP9H>f}ffS;pr3)sYo4O}&V`Czr>fuKE7Rh_m+adyL{wqH^gS z!*a{*ktqy@x-RHUet!ftVW{aHhjRD0&-AaK_D-YOUtX@?6NX1f{m~>pXS!naF_O$& zFaN9K=XMg%$(PT^q_*0&dX!h3HsG`39|%mUb+l7bi(HORQpb#turu^!vP!>GJO}d{ zYT7t@Z^odT%nYUx#PG^FXx?o3mBL{?wIjC}!)Q~#LbzfK@84=NZR*kB zjXb|GF%_M|hd!Wg`MVcI{F^on4WCC9CD1C7@c-$p{*p1wfgH;M#y4m87!`tYr4!7I zC!Mn03cPiwKqb)Uh|Jh`Js^0>AXmGLl=#L}`H?(t-3FBI;-p;kFJs*>TA^$xv?MH}(REsSzLh$d!6-k%fu*lyh!~4X)w6S4Bpf;xL)<;Z{s?EK9mCk)g5bSW0T1a(hx%)9oB)IjO4}Lg%gUVL@G;(vja6!9 zyRM|0-}DVrgDhb#5xcC3V?hu=!e`4HV^&5d4EpO>)GUWR%7K*yGg*0(_y@Kvb6 zf9qoQSHx0H_lMF`GBbX90`}derypSysw2xCq2Dq-(tvCG6%j7sQd3tFDuSXBj3N9M zpK8-drszu`8(isqvrA3PHomzwM$n&qLc>ojsNa_Gg4yB;d{<4W$EZq6aLM}8_+6c@ z@i_@aNZ2B^XYjFAqg#~}rJxA+QO*rlrT_7(Z`qBM6{Nlsw@piwHSUtws6Je+l?fy(w>krn|T_L%H1v15|EaC<}VgAZH{y=oV{pOZoGg^nbm+Jj{cQat{YGOZsTjj%Q? zmUWu;FlM1p_QC59y=l=g!8<_G9eAzvF`51952YV~BTeHz1f;GJ2?W$yQ!@C*QBZ)( zv~^oMPF(JtNe&pOPR~FDLk}?NR4?|Q8*AI3qomG;_I~hVN}PU|Ja7K>TVIr<&+8#X z>m5HiI5l^2E-ED4xMP3IS-QsxCbBh}YMTFk4g1T_AN6cKu{KV+LyH^P<~ zcP9oJ`@zr(??xLGIqX;eD$gC73Tp{(4e1_P?!VIDEH4bK-->ts&t)BK%l}$+Hs9%a zW&kN*@J+uw(jHBx`b{3#66at3uk5T3>heU{J*TnDo3!RQ@Qqg-xiTws;l^u}b0QT3 zlc7J_Uqf52-Z?!F5vfJTEl@+TSEW)z!6yE$4Q?!uQIEI-TitYh_=Z{JNb`ULTT2$| zO*}*%DEG?m`@iB_DvdENB#D<75oX#<_7Uq{3k4SSSs*EIw_hU-hG31Mvu`9OyFnd8-0 z)3V}}U|jzN2ZN1bO;s8Uhb#g!2+nbLSPRn7#@#JBY-O}7U!BQ#_#+(VHAez` z1IX(Zeip>$+7*5aV0wXpt%c_b*1 z{McuhMVa!9aiET1KAw(i#>tW;G?9pjm8V7+qUu(noF@2?CbZSwN8Zf7*? zPCoj+g6W#P;qUOqgnQC8ve+?rzTM{=ptYF|`l$bfP}i8g%!8U+({Olh_`}2ZI^G7@ z1HXiO{p1UJrT3&^Qi(4f2OqXT&?CGZU22EvrBRg!S80oyo zABN`tx*N?=H|6>jG-ca;?|=Tiqhw6(zk>_^13UcpzqDqjiXDwF`EEOF?`e+I1A<`p z0two*D7nR4@((moz`XIxsyDT^Aw_BdAAyRJQ*cFbShgGM>4pwW+blAE)k{N91D0VcKM4?kpFgdS~A% z7{(^Qr9*wVBW(maYfeptXXi+bGDciXy&nSuxLI_kVFfD0}+_b`o3efrgFv=SwPRMHg|K4#;Pg?VsbaYQ36NQ5m=fwFLV^=F) z`J1k~ySq5kfB*}9O@{pd@)Bf+vi4NlL(>%vIcOY_6p=PGo}-9i?urfhyDtpMXwSTN zviJ&}LYF7X_Qkmb{=Rp^L&PH{A0n^qZ(+y}htG)ipDmG0y}mI)!4v7ONR|8@n~0(= z65&y1_MM`a@m;kUVhc|sv$9z7e)|jUk8AZ#C_lYVX%ON_<(2dQv$py#eEc8y>0cO= zWXSvvE&soG=>O-h`n22f+umvjetJ=R4Fuq45#mnVeUAyK!>;CPP^3X*3E>DrP#CaY zwfK7|!sq5=k?msw^k8PTDUlukY(=t@sq$4FjhL{)X2k&Yyrx<57u%E`fVX0+=*r_$ zs-oHYs)i(Y_pWaye_Vv^*Q&Kx$eAl6R1`G<&f~~gPWlfu1G1xK7tR~g@yR*0SB;X+ z{|n*b)>j!;$C^>g7ia>BQIN@bB^oM=TA_ z0oa>2X{W$dsck;l86K~M0kWgb5J0|5$XKP24Dc^#V-@Rwf2J8%3h>Dh7NH&D7B-GO zeJDecIYZKElRn(NIvuMs9DY^(a0=f$C7HLwO07_9!@OWgYOp5{oX<{F+t^rNsri01aWQkNpX)#@iBlL;ldR&phGay@vjjmQQzW{= zOuJ`30Q(H<%KL;s5UW-LW-dsBT7-ea&5d8`iV)q;Kw6AVE^w{?w~?3#->695foF{o zA_IU?u1@W~kw4fsKvD?A?;Fm7x!%J?GQOO3kVSWs;DvJ6%HDyy%SQq|AMiRODiy2q z$2fr=DqPo;M`TyZxV_?JZWte*--xA}B_5|^^)Ww_h`b(i!GNWJu)H2C47?x8=)z5^ zmnm@4SVg-0X!vX3U?ny!Sn78spwC0Dt7Fvqjx$*WC?{Um-qHZd zZ>9H?b1U(qvqWeeZ_4dLb-l&6n;uUq>hR9h-Sv&VaFxQ~KFc{u9&)^gw6Rw1vjcl% z(G-#L{nujgO3WaFlLhe1aBx5N+3uY+4o=Oq?f-|Z_kf1G>)wV_q-u#UYDgo>=q&^( zLK31gMmJh?B3iVB=z>HIA_*c1Gs@^jFQbhT(R&a*2%<-Pd!Fa}zu)`4>s`yb@64~9 zUpr@?efGZgb=k(@ktq?8JPq_8<%e#-hZIVBH1eH+>Lk$UWH$vf;c&SwhwQ+v9Nk>n z0qNs3_0U8C(8$W@-no8(708g*JS($l#aXC5RFo@PM~ zp%dO5Yj=CK%dOlXZ_z}0>&QmBcl5J#6DBV0NBsGZb@g}83-xR02B!VsJeqLi5&cmu zSv@4RU|j&`5z!M&OH3h{;9#|;fD@)^r^WinOY9$sN0F3o7xoszg~VhmW@YooaYFJ9 z_peOLpR}f9+K8N=UytW0fdKYS(h-O(?)}WDC z8k6qU&v2UJTm+EIY|Uq`doRfvi{oXE=j-PLM0nrTJDBtX+U;b$p}=w7 zBpu}^U8~zy-#qvsKNoW3h0Z3g46oYCgu_Et!!wL>u70OI+9U6D{U|}-b#<_}ueB=d zYXrKG09R^zs@_I3J&8GaLeEcJ_mlx0rGN`_dK~MPkYXXHMtz~2nw5@K4<(&C zn*&7!fSXEgju5oFIjw^g!1n21fEsLiH|ej8%3qPXEN7#D}8^R;zbp3n^k-TC2`H zJGPj?ul^Ii($Ow2S#ibd%9FeA181`kE#fY&kM(*szIEk%d}z^McICu!H*73mv%}c3 zt8BQL@`w`Xd8G&vdK(uCg~kkC`qL+he^$D?Z$U}F$j{NK)?Vx4bX@uk<++SSdRH~V zM|B<-T=|*}de!0f^#a=aVh@?#Tl*Vw0)V(Pva8n1#K-7rGJW!Udw)Y765gu$v#G&) ze~{&k;bY}y5#pjEXPOH*^v{=SVf0M36BT03JE@!l&RLRbC2?8IDh}2 zu`^}<2a z?5sUS^ID3L4KQrHS(DmO}{kgC_q zMRF-S;X+qF`1Wsuko55|*zI&y-O-PUUN%kO+}Hkx#Pt96a89{TIlLX+f|8hy( zjID0u`G$MPZgZLEA?(L+{B4pFpX2WQv!&{2q~kznrEzgf9EKU zP!8?S-4LSrxP0;&Ha7MBJKPQ9pc7fj>}uU}QN#A{4wpA}O$&!8nic)hBGuToLiQ)O z_fK5Eue>l7>-uNchx{O&loZD*BTRN%dvUa^b?f^F;`kke)_M*iVPciB9p?T3^Q#6p z`nI;HMD>1m*E0{lKXzN={~TIJmkrbPj1RY%gl#t%8dE%)B2_nnRtt~=fPmDyy&jd* z8d3~|s2r>HD*Z97*Wf{6P8rjS?1$NiHJvZzIg}X(pznrz1x@QjZK~hD<;qL#^XA;v z%@Co)txHPr|771^yYTIU^VJmjPTAvs%J7cgF8O(%WO;M;Sgggd;0r5LbCKf$INRa} zui7ILOy9@FV>aC|I$soQE!dUbpr_ZbB^%Fko4IXyU=+UGv9-Tb^lA0&m7~*ZW=2NG zWzqdMAK#Y=>R)kx^d@j^H;N8tjI`-fSCu;#DW3hP{*R$B);pheyO`zcXLfD1z4fB= zmd9qzSICEDGpKjq!kbu7*D+Ek9QN^7j_uwE^{(8zTy#shyhrWM7*$ocn`#su+5F4$ z;7z!~RRTS-t0d8a|LbgbLH<$APhPd5a?~VI2L)WU>~XYuSK8+I$`0LUQS*8Dg=CY8nOX{UKTYg()fw&KhpqoT}weN!9s z#hfF&*I&HzxXU?m>@y3ts_G&c|8K?!E#s=`R;|B)^Zsx!%i7_`n ze(hm8NQXZd2y{GF@v`Dsjo9N6b{%s!SJ#hud3g^KMZVHE@@A4&@N+)giKOoCZhzpk zq2XiI^)X2%;q6%^UV$zGG;=oS*z)o+v(X+uYRj;iV4WG z^t2S}@#E_j6&4D}%V*+${ktE8>u{JK&oU0ueOREvj*iN@m!8l2`0MP{JWcLNxO zqc}%+rXRVt?7bG`s~FJKNOP#%DRlbqjFpMPZ+*h=m~MU0ljR$|m|{~@n!t3ydAJIY zWda^#eqrIL@B?Rfj_fWXKyv%$alTXTh>SND>QE|smaJc zk{HSNvaa@~ly3Izyqdgb01g8mD6A9!AAM)Lr~F1cVieqC@b6bYnP>I8W3kw>C(|ck zi~|=Y@We&FfB!y)P(sqz)2oA;y2*`Q@Bjm4y|+HXk=zTcfMn@eC?V<_8#m<`l-?sx z@*s6kuxy3pEDS18Vo*#>NO0cYa@aZW1Mn~uA~IgQcu@go&njLmhioReEg_Ei-&R1C zq)xcIj@3NpD0P}pymSs6ruy+JZ!)2$Yt?DXc;5Q)3J+S?*U9-8n3+OKN=mMvN`g2! zNGtrPFz}Y~9;@Rq0Ca9L&~-ojdN<|6hvwhEoui7MANmy)6~$E=?<|JjyTYkQNl97u zbWU}p+#Lkv)AN-W_~z#3o@}p-vDqE|I{+q90hXm-@9`sRlfQl;fgcql9>4>^Lo;QD zxekR&3sVh1w(`wdtn#LL-1=owffVW*oqvZ_!@q<5NmuCz*E2)Wcs4sLtCK)#CPgMA z`r&*d+|{O7e|(G=0H7L}I7_`pYHEOHFS^3V5_vZVwb9Q&6QW!I^*=(=(&1<%NL&Ux z`AoAalm}UhosCq~(o95UH68BONB@3awOix-)SXJH{20RF0y@FpxVTS0<|t*oWy7zE z!UxyrfU+LY`uFlV-+};EnegQg3ahg`O38t;#$(Y`4Il|W-)G?P+9u(|f~)DQq$sQa zi8zEL7uQ^Og`S7Du*e-`s+Te&QREVvI}MZ-o%Wx-9VIR$7xKR2mKvveqH19#Ux&zR zDSN2|qFLRKA3qS-zR0Yw6Rr`pN_a7g5`GBL5o>E}q4+(rwN>HIB`r1`jlfF@DALab zv$XsnDO_FMogJfpRM>{dtXA*&@kh_Ic`$^cXWr&q%qQ2683D`3Zz*5qgptVBEQLR} z@eZhfw6vlT;e#yznQ9ATNs$Xlr{>!h=nx^pmHiWEl7oi{M5z2?VqpmwnC!?WjJyNs1pY~~|FBs@uYuNsFFi0jl8J+deOquA(f{r8ghgg+vfkz7fF^4qT>m3?c4*(t-jH2y z-R|mg{Re!vb(0^+r%2wq@<2sj0Qu!iCCr`J&(Sah#|ndz$P=;4@-nA4v62f7wbd%TSH zSzZOs{&NX_9t^oiKAyPZ8F@8n>SCV=pbr%m6N@vaUKtBIwQBV8sp#y6ULBeuk;5k{ zb;VESuqAfBw8YOX++kAvbeJdGwTJa(<TH-{3=>>`)b5p&~m%?}k}$V_*p z-t=4}GEU;XZ=8v@5NTcVFNzb`tYn!R=jo7sI!hG-SnStInVz!NiRMP0b9eRngB|3> z5^Pn2Hdf!w6}3V6Sv{}`cD|E(>9!<2mzg980}z3aD^z;tJ;!#PSy)^=zDK789HdIr zvO-4psN7Y(1T#hdjn(&a`CQkpKgEfY^n+`X1}~&zUvqv)nEqQaCnZ=4hQ7>uTY%iG z&IWG?=RMstT1zdFcZUwbc2MZ@MeV~l0;|p_eCNmLYUdN<8`rO27nYHE1vJMDc<%72 zVgi3fh_)Q%bZz;zQX!NfM>6!B4I!2~=t%YNZg)N<6SXrjGuMHDY6SY^OaH{&zuv|P z#8)CW4*xytBrU^yLZ${@|M?Kfnka?){F%#`poE`4&oXz5+p0LaWE!|F6_79M)C*~| zFlQO%D%BeonU-tAE?ocpapBGz0Xe=xi2Cd~vcRs|q_CSHl+%e0hD0UeuZX$cX@_S^afe)4brn6~>*BnuC${ zn?HP;;>CB!%m`b;t%Zt*7Cw zH-tG|CYEUahuILQE2s12_J4`WYz>+NKcU!t`5SDrM%=tag6jgE91tO1=}(gnabE1@ zp&?6JVf)Uq=jof7b4xd-#E)@^P6$B3E0A%&e)wTS#wz6EduK3(;QH9 zetxO-`iI7iu3IKCIwVhkkkQKR97z-~nqoVIV(uq@<~3xtN1vt_j6Xm0{rhjbM$k<5 z;7`wgO4oON&MFM~DpE$nU3vq>hsfMcvE6|4uR&oMI79&{M=01IL$G@TRp%3+gTB%a zSBVC`+I}3Ceo3N$M4)}fNujyuHOqd9apI=%+$egQBe$@J>uklI_t%ZcB-p)~Fs8_XxHs3wMa0My)=CJQ(g45nrH4H1BMA-avG=0c3L^Y(Oq);NNsN&a!U(EN3nV+ z&2!3~7^3sq6vEEYkp`aRXFk2VXg>R>#L^wHC^flqjYetrUrhAg^yG6KMUTFBRzY$W zZX#W8u}r=i7#(E;YJnj0=BOF2$ToYf+LUr*vt!N59geco{KWK~PqiVXj$`#u^_rL> z##{LI$nzqu1R8_g-hKRO0l)Um$>ot!(JmJGq%+aD)*}?6QZ?2h0-=^I=KP8oJD*;- zE%o!mh+|`Fmx(B}l0B!?+bBY35G%)+e);de*r^*nlR=ENH2H9A0m6&^4+^*vg2ZMQ z!hft2bG%oEUVhF_2Dozs~(%us-$3M8j6>1rae})sv^=Y>pgZB%(?JX)) zk64RtBaJSQE>C#P8c>Bi5ntU)PE937vPzPTh`KL5qB!Egg81!#VGE+2RY!po14iHzkq zgHp%I-Yl&LuAJoA^ic){w|gwZ`NnYGUN$31xpJeVOw}vGwE9I9b3X;AAHtS=cN})?hraVFLV2msw!%%)yLO?+Q0HZ3ivFBrKR(4 z+@dWvq$$7a5BfUE>EDLOX)bmJ9zWtK!~W{4qDyOBzd9exQ@ZOjh$BFcP4jR5(rx=< z@e$?Knc~H?*L`&Mbx>YSD$v*0cm5G_>ITlYUCtPLTnSG;>Cfxr;{JZrufw{3$!Jzq zRwkY3S#*cL)w`P>G%~QD!N5)5*!Hd3<$sCV#7N|5=U~ zcdrh)Rwrz1Vl36%GIrJny|lE%)bnZvt@`0YUgf&dP=cnBkx4WJl<6@2-MSQFDa7QNa}RA`&`{+q<4VOA`3`Z58v9ffla(d2zUDWwIwdz-= z*NuAHUiQR%qt08XN7F^unGvF`>~C&qisPFLkg!0LBK+Cj+?f%4-ukd}ZUh|mZ|jdJ z?htGzd!qlY| z7dq1bKzAs=e`ns))3ZYq^wZdS2X^~B%r{?6A(RPK_H%40@7^`uI^4LGC_6`H3(>gJ zZ&j$1`XJ6yg&D*hjT)bG?5&nR=R;ckWIQO?icY~_4vcq#rLyNtyl&h3jql2W7+BrB zGk343TD+I;DjgX~y+Sz&zL0=nnflhdRln_u!BVFWrZ8oDtc=zPKHnu3%vJtfCy{AR z%39BdWGw!CuSp=AK$C+-UCXZBI$FOMKnNaDPk6S$1t!0^VD9hy{af|lzP&a@@x}*y z`7sWpxh7MQlH=Uooly5`PDMi#UcU#k$8R7}A^ehhzV-Nd@Wm6@;8fMeeXX)kXl5#J1YrS-GG;n&QK$eh+Pa!xpzgQ=x`2Z(BGXm zS3^5_Gndw9NIPSze!5%lKK%RhMS;)HuFq}ZJ7*NAt>1J`TF#OfRypZMCP51YErH+2=TI@kpWcZ%{wptrs9zZx`# zdoeHGpghdyxX=^(Ks_r4M}Bpo<>uDZMVInt73|U(5GfbW7FTD}%BP(}xKg4uWMA-h z)_V+uv?lR10-LbkuI0VqtJZ6hSIbu9;c!&NahG^iA(Hn-YOOg+YMxuHk8? zo$dttmqe?)#fD$~Jd}hJxa@?qSEA?|d{ok|)HNnQT>m{jr2BmxC>6~4hhcb1Ny(|_ zQqDGU_;35XHBIe|+vQ(t8|-;LCLTsze8YEX1yhG^=E5iaNkPc zBfZ@NzKYa`)w#B~!pB|pOTW{H=I&ZQt)wW7BdK#SA)i;j+RcQMrwqgIrqvD=J_e_~ z3>k7kM8Oi}elymm|NCQQw4wgpf<{l!0R8(rZ~`E@{IvAFr8OymGsj9mU<$Z!HB|( z;dJ{p5SGEsRegxPcE&@OaYazz7{$?erJ&x~yX=pjimnD2^ieT12%X+L5E2uw8yclb zz~mQHzUqr-uy&I!vX{FJe%wAKb}B4-6@-~EL9CjFqA0t z=sXD4;jWP5DQuZ@A8%3n`YYN=(ev#JQZv!mTv3d%r5Yn~wsbdS`|HmX_0G zwyVzUD&Ga)%9WrXzWHoC#F5rou0}hfzOP|4=;QZ|quaE!=Xp6U)k1vYK%Lftd0hiKEpv#&_7vZ$s^N`D|2n$urOn>S?r@4%rqNZU)#Zd_ z>!SI6Y*E6vs;~eMWAW3^9IDPVV>l~(_a&m_yy$lgE_~{-xr4*O(y4e#3Osur-jX#; z{N8dIu%i&4<{DS&YujTPmq6l2fmi~m_~IidlAOa#^%oXw{~9l{BvX^e_=Hdz4hZ}Z z3?nTcUw;__wAodT z;zmJo7EGVhbAL@}qV2IW<0K&}IanuU;}T8$%B_)$bp*cyX=ASi&N~DUiqLYZJKk_i z-&8@L^^QRq^{o#FQkvS?$R+Tr=AUj)`r9x&X0on0)8?IFt1~^fG|O3LdPkF0k$h;% z0rPil!WHb7DgYEQl<6=dK0IW|L?4Q6t65IeFa_7aN0lDA`4kuBEGdY(bnZvKzI@Kk z&}bKL0eso+q5g6QBmO#sVRDuJRw_4X(R!ga+mgZ2O_A|K7!9P~OZjPCaI?2X1v+%C zU|svMDpR)ECB)lPMULB|{I7tI$n(r!H_t0*z$*Wa!BbXL4%XRDgs_wU*YDN}eE}l7 zQ2!l28lU?U?c+1Qz5k?{@XlPSlExS}`y~Y*BWdj8y6Yo1+F?E<>+a){C&QPj3c*GC z&Wz4sbV)oLIShV%n^Xv&0Az4Y3rF&;3_=W2Fl$LZ>Mdk%ZSCJoc+DN?+W8mpn7)#e zrTvjx&blh(5H@3CTOnk5Kvx3eJDS|n$G$Qp?%%+-VKyk&ZYle<9fnol?rY|y66!lh z+J(AM-)qfeAMQ!H3{X~>o0%Q^-24b#>QtL^p=mu!1e+Z@EClYFpm>Ije4i1yq=-NSctIF zfMw!07FYPQj&Q99HjTdGJNC7CYfbu{fH-X( zER}lqVHFYN&__D>>|JFHhEc4v=*6XnxV&65H_H<+89F#h0=5Wv>YNYd{u<|b5=*p2 z&Lmi3ibq5xkHrM`Sv4FGiH2#^E!u}vidP?>VB^3@r_uoF3FYF6uW3!Trp1fTKw?ud z{ydAshD-X%8We+mPC|qJnOtpIK?phIeW!#veT`3cQf2MRiK>|-y!MZQTSj>UPtnT$ zoW{r;r4)0UmPLn0Ou?-SnphFPGR899%}VDRRK-eFnIHh3eFe)$0!5Ze*Q|;_JX3I1 z7{Etv5PClmFgU`}VvG5kP3AoNr3-E;LMXp>N~>Z=d|Y4wmr+omv~ubNh}S!|nsdgB z|2LAY4o%oz%=47##PGy~6XwmBxEfq$7nJ&DL5c6mk%XAH=Tdf_Ag3Y+TLD+(M-sW)Rj(!VCw9A%$J=U z3DUp}Q;3C$d5^VNSzdXUo#u&$F$z!SvowEDhBVASay9EKI!n#>F5W2!+oiwBEapL4ExtU+s^F`n=Av{O4~5%r^AM^x$*IB zT^ry^gQVEIz>^$Cndl(wB}xZ3x8iv=Ies^y*%{`%TfqQP$!?l#YYXQlDCHo2HcVw; z>9NDI+5KxVq?vacV3WFebM6|LnB+awy$o{E+P-pz1_l>6CCu<>9TX48y3HwruVfSf z{aNwGkUG=+slX8zoKoz&Haui9bWmAqQ`7Q6ck86OmNrrEC@PE+te#qi>1Upt`I4>b zxwY$4KEXka^?yGzP@tcs?Si&3AuLkR0YiJ^lsRO!SY{A>_%~l~bPF%d9qoHzYDC`F zhX8;T%5vAIdRT9l07}xaw1slNbTubiWl~*g_vr`#QQ+&fNGPG;* z#Bdt;>TFhb*!J5?8D&w0uld={kM-joDl6fMz?f1Zib!l=whXTaV7Nq|}mp zVq38TD$D&(CYmN*-kA;L+oNcA7YnlN(ONlaqTNXm4YmV?N||jcgLL%;Uy)J?Q8T6D z{`xty`8zw12zNp2qey(SlzMgQuM=}sb*|rMZJP@ z(d|+?ilZ5=f$^tkJ#CJ7(vN)Yh)3)Sj<0tN@dpX+yOh5xyiW6hF& zcJy7eDIEG(IzRbQq;6G-kS&L%qtIwP`xeW{jzjSkAsnLm-r44Q_3#j|Na_~|iB@;0HZPNKg$+rMk9{TWPv+)JjE0zyu&?RL#ixDI4 z=!eRh>h^JFYc@|8oNv6&zgChHp|7oN%-Bvc~uE*Sx7UKH1XH51^v~gZ&Hj&+sj+=+Ve&aB zgSEQ%mreuG@YSp#Le~an!Ih9+^#r^G;wQm}G4u2DKV(il-adzD`)*qdB6$oSSb>J< zhG0x_0r{B6=yJm-(53-E0!M;zUPy=4^ebI{JmwV>mP?!Zr2K5s*B{233w{}zS-@`G z^lY+i<+7m)gwMrUREQhBw&MB*MYQy_ygi$m30K;7oj>2x#AVw90pVNxMo zXcvmHcoF&lNJL=Po>h-W34};&RGf=D)%^(dAvL#W!KJH$rp>?K)lLO@{hc@-tVW;A zTcX)yJ}xdkk=70az^NNz^=PvN5l$61bB09`u2+68FbelsA7V5Aghg7m?H7^g8HM0c=tGX{90^?g6sw0Z*;C0duQ$wK3x1N z5p*pVr@NX%s2Wa3$&(>m%^#v^HxAjWahihO#Z8Lh33aC2`dj>Q@x`|IZh$Ek(HqPc zw4~ZG1-ik?*d~Ww+zn+IUqs17~AizolwQphny+JSP!*qyo|< z5@mv{J{~KF6)P{RI?H8B_L18nZ|~d0-w#E*hz^|~74Yi+H497ud$-Hl^f87@}dicH^@ zGKtRov+d>ku(VoxW7~EwSflz+<7>=YLiMZgG@_YCpX4huIJ1yPIIbiMV9IK0(LBOM zL-qyB@+rjsvP`DTZhhZSeNt{n-qt4x!r)`8N>}wZo9q>f6DL*^X9QkZ=tR*rznpd} z?bT$t`qft#Rludswdg3DNpCJYJ)YD;b>&T{Rl@r%%?8czwD}Ts>7ae<$o5YPu z0TWxaQuUvr0boZL+y6d7JCJK+;IU+pmDeVdi!fR0&%stK=V^K`VB9=B2FBP2zHaH4 zIvR~#eE2GS64EiE`hu+=XP3BMp`7{0x z%%9>pmoE{i6^6>s#(RMl4C(R7Gst2rMP|)~(l^*$Op((>^?K5s$bx+4L4uoI-x9~O zpXaH(L#V?p7Y1d)e!v`1Jqs4Q?ilAYR5D`ghx;{AQ{xl$3SlDCMS@L37IVDXi?#m8 zMG}UiPc5we9G%3qO1sX#M(SmiI6W}0^4)jWODonqMazEgL!la@vey_;ZdwGPvIKdQ zoxI0D`LAH=aV8Ci9MU}N;-$05Nlv`ofWQzlO}wLR3-gvS*v>=NC6LO*|%iJ^G@pf-%lJzcJkrMd$k=y=CCWVGCP+wwxbQ zHn8&^i?2~Wpe&hslEwLkf75NkcROD9{nxNGeUtc?m$LE%ZE?KWGI!LBU;WD?F|&&PjzB76${_{ zZVhGQ)VTv8ouqS-!^RoObV^k9QqlZxyOSYE-NXh0zPRuJxw*W zfa<>;T0xMXBRwv$Rk;M9SPe|xu*U=0g!d2qUuC*efex56z)a`YGaIuR8qi29ChR~r zpSOUvZC|#|jEq&ra^KQC5mJR%;~J}uWS2L_raX~)y*rCfxB4t{AcBw}+81*(uHaMG zMlQP38b%k$X1xcIeoI3IKT-OYDy&2MedFIVo6`}E>w z>4e`+`w{!(W)`Joo#^5x(~8W>P7_S)RDBi>`5sI_N{jV6=+7~zbDDA^ zst+4y{OeA}L2B*gNDFg43*{@!>Ufn--UQzKR5&Y?7&yz^Fpez-xX;glIk(*y)kjJ8 zsf{pX(VKe^T)8@s+T$ijsl-W_K8)zvK)?OKcra8M?jX%)c>rgkBtEofS+ z>X?w{ian2q+!0yzFp9%H6uoSC(`BHO)bneJg)gO}4NV@<`|sVEu^J{2#RCer^q)=8 z6}q<$B*t*I)t``wq@acn+NJ#}*YX|%j&42$^&LhtySdw$pfgGootkz@% z&6kG=_usfd3c6@~g4eun+Cy!1!$ND9uZ&zPwTFMhkpIuQsPS4w>HH zlqKjjlzCJr;2sF4S5$%787$OE+T59remO>5 zbQI(?xi$Fjczb7Oc&FC+82hM;H0F9EelH+I0GN=77<)Cj-A`#axyKw^_9Iu#PaHcc z0~GK14y6l@P})#C;@QamS9^AtDLDhmP5?O zqZ5c@9utw()pFej#kO=!2Oj@}1?c1byI*ry@d{X7S*;++{@Zc*r8x*ietH;@&YgFM3 z>6UIpcIlWqD>*VZRH3Lm@tO=6ChI+dyhj9@Rl>ejS+MF_%B7xAK`1K$;OGy?+oUh+ zOFE8*{^!CB`}$}AayLSZ1JI6HZ856)8lOEPIIxy4U^Hv2mNLp^?eeqjH;2`R2i!?xDo4gBYgVl7$L`i6(Y!A?!p z2T{Ux0aX~4XzX3SW`+!eR5nl7ox{CRhY&q=8J6IY`r%d9J00 z7MnNIRPIbgP~$&ULlF_E;Rb@7WoVS-AY?QD^XRtBIn|%-wPxN?b4)#H&b}!mBy?%m z&$s8ZiYG|^w#6pM8=jU8V*k1EYz!IbpPG787!F{$=>+x;vS9Ylz8BPLE=5e=fSK-* zUS8qb(=Xpgu`BdL7YR8(5sImPTf&KY{=CNeU9}|%LFUh9T8oTpUMHX#s&UIG`)J4e zCMF+3iycNJ{e9&4I3(lixT!WBLV;Z z`JKnYTL!SeYkcpX<|6CX+lwhzQ^>J^e0XZI`aBqJX5}0~&i>E8xd190iiViA*t?lu zu2Wn6Bi-P|v)_k0t(z-l$H|b6lY>W%mNR=L4Y7u0{GP0kIKGD?iwOgeCJwHU-K5Wf z7TjJK{ESv@B%*?MxGV*JNlz z8ZNhWc=vndHx(*25dc%O28L!(J;5V~5oqcF2T6~w-bh{jfp2D)Z*#n4H%4b?YWlIg z0F5jIS!4kAJh`^~aBP{=a<}4O-o+gQJOBQ|>*oyUNeF|X%{ErJzRdd1@s{+()c-U_ zo?T`3<})4)(gp9H9Yx#@$&qjJ`r&`d87wNik32JcXt@O)^Fs$p^l*LkdRL%_tFj#* zlDE^)O2CNFI6%q!Ws*(e$6k`7EwKOziVxKV&x80%_y%HGHjJ1qUJN3d-O<(6edZQj zR9AFubJS51hr+(vq>dg<$Z=4qpZD05>>JqG@f=E|Q^pFyNOv-vIPxO2@6E5;#>RU?iTQW4 zyP4j5ymyiY8ZJ=jRzQiJ=Px7>2+3`>(WT}tE_AA23bO^p9}9d9o6PB4_o~_%UMs$0 zXJ(e}!~O~`DRtV`SLM;87nXXBX82$*@wL-y+k;$!?|NZTeEMiO!`&?>kL7~WD&q025roR;hQ$s!2q%^y#`dqF49^2dVv-KM?d{uzOu&Y}eg8gpF=Fl+5WIC%$Dv^o zew&nZhnqeo^~`m{Sk*7$yDk-D;fGPRU`~Lq*}lvPorB6pVp|{|1z~6$2B%+5h8IKC zUf4aT=t>@*JApDVAcs$=!qUFC$%E3Pm{=g>xMMSCk!SeH62HXwzcO9sPoCg0h~_6u z?CgqH-rN>r(J^dwx<LN0CQE_f-9&B}odEn@C-1f(#3I)jIwCzfkZ-`=Gt_ z?yvJZ$E&Ir@$0)X@Wc9xSjLE*k^9A_rY75h606dFnOI#)JIHiE?JYpc(~X8C=q2Mk zPKm_Ccg;a%WOAE+ik`uiB|Z39^^?xr1&WG_>PSR4$N>*KsG2fFD0BzXRpG=J#9`zq zKr|GI(6V5jQKp7rl1MsHF_ugIR!5tkz~@7%J;-W5YP|-EdrB-W$@+^%ZV?Vv4|Yyp zpyU1i2?BF3Tb{i891^EVr@^mmcVAnHo}V#cd`l!HbA~v28jD6|=f0b;tuB%|mv~e8 z!4-)V&V#Z_X1$=hcY4}tXV~QvEXB9wWyx!9pA45X~@IMM`==9WY276(>^h60H^z8U9D^w0hY;ANB%tKb+vi!3zz zT3lvdBADiQ6W7%`OaF2FYrr`awiC-Xi>xLXOwFE0DZPl+eyO2 z>#T#mUr8?YqG98Ap+jv|Q|W;PqoTKw{GV z#h>KNIjpy{4c8`sYK|K6Jus^F(Hp2jrk=-g1?!jG%8h$%ia6^S5S*j@*e{pY=$6`V z&sk4-WR3zu#$GTpGOY`%kyGE1BHoGYyOQ>;KU5I9|Cb&f-oO2eAzo)Szx#bfm7Z0$ zo2t}6&A7+ehC6_FB0@}jA3%?HWK&j~RD9h()!?#ei2!3^q;RSV27rfhqq-eNN$rlU z)IOB!!Z6UD|0;RXI*?PvN-{Q+m^hyPzNo6#Cqv9jP?_?g{{6AcC@n^L<{#bG;D^r1pEmv%}(T~>%XUET5`nkRhNR!Av)S`MF-&C~hv231$ z_7X&jtZ%~WyOk@nS2FL=yhsV)yhfXtlIJ5AeK+kRACFgIK_KmhB4`t3j?Q&h3r=P} z6WydPL`V9(od{)09+K=WXn&P<9x3Vz6yi_|u|6c%Vc~$|4*d1+xjUcn2Jx`E`j4{H z6@whXsOh#Y5j zD5|G4b%Tc7$LjC!k+@9+5|y8@KFZLG@A_(m7-`?i4A$X|hs7AH6*+pE+6j@X`4EW| zYMPLSBDuWJRqbY=i)m3f6nv|_uSgfhvOuEfrz%ITgf|EI3WgriKC;BuxOZyFjYF^X1_OzE@br$tCbi3V~09jTw}B!%_iw!krgV%g6H zpw56qL}cNtwi;}4;8SR3^~P1FHQI`u&m<1GnDWSGu&5+VJb+pY{^tC3V@E|QEWSMy zBZ{`-D#)x3tmo|7NPny?YG!>>c~~;=TKEt$<3p7a&PsL;i-&B|jVJ^6>UK}Xv9EsC z^h=5|8FBA7tYjq}DU|0o6qP(Z_$3pPgmLcA#};ujgOb1*+h;2t&-qh=0yV=_O9dXc zm}`?{gAh0wGe30%ARImPk6M4^C z0$V_H2}DDms@vvSTQb9#xhZj4lDSwFkmd`a<6|`$-X&>v__`E}ak-DeINwTsV7kV}K%$e;z z&LEVtvLfLE>Cu_$z&XW2Uzh>Sm|JYO3I`scW^S}06NHRKuLgHm>5P*a3B~A+l?};o zOFY`NSYPGY^YcrykIzgzv%&`okGPnD!(@iHR$>oAHx;!1V*N8}{jTpTOo`>uQEW5KdiD>n` zXQgV08v#QTbT_R%`_<(JA!q4SQ@wtAl;wmFZ?KYY1~bk}n10x}Ut4W6E;CH1g5>iJP~*3Q z7j+WbrAGDn4XgY>CSE+;BsgKxsVIvxz8OQpMfy3GCWqCkJYWt{^KT_hXN)wZC`Uj9kPta3r%x70FON=x-^UM+qOjCYAmu?$awAH+sMiJ>? z&@PT`)m~;rlE4LLiAm9&COt@a-KAwKh_N@<_U~8xMV0Wjiyd?`s}(miDf$6hs3! zty*a4S8r2Nu&na105TOCJO`cNC_u)thp`~fl2%uOFo9J+H7qJcVl7KY&QqOqD+~oO)=I?;XBRKzkVggqJG}dRb*S+ES~5T#6ArgQw8gb>c6K&DKmQ|dF!_4aUyJfzSqu8>C`ay1 zJ!60R^eNiV5a$i4#(VH=p_%=O=aF@~#U*sZq|*S7y$gLNUPnzJk+RNIeY^Jk^o{n8 zj-+~#9>%T>kXwx9>EaeOZ+XH7kR6evM`Lz+3Gj+~WqDpq-?$e05QdJ{Fu(z_x1dCu zB^+YtR)y`h`Mvc zrK*L9O|szS;Nqs>BcOT%W#n$r@*NgBP2Z>>t$I66{VNGva*&l**#<@u7zWUzm)+$G;E{$ZXcV!Pam1 z7P<;#whHbkX0Y14a3U%eT-GS( z8#pQam+Qf>?1DJg=Uov#@;}qmA3UW}&ZM)lva+a9K%PqIXOd1;g(b7KBe{n_B37mP zo$7Uc0|S+?G-H_h8{6Ao*`Er5X@DvF;_-P)hO;MN`Q65~)o)gAC;%sl(aZDW0C~|d zZC5v-(52A*VZaQEr2doPv)cbIiof!q>neM6N)x%{gmaa%4_S4A&+!E0O?pQq0euDW z;?G+U!T>2)0(#BUFjf$gfAddwX5v9RK;EtNuq+|d62Tg_KmtC zNxh8#N}*;*itJUxrZKMjC!Mj+0s#ISrVgx3kK8%K9I5Ny9Niz!H?cV6I?#@Z;32BjB9y zGy48rYd#&)knCp#Uq$PQ-s^_RZ;juzS`eSa7b*<(jtGg0W@HKRK2W=Y5`@X>3jJA| zy(EZps}Pl{z|uDZ>8L=nQ#An@+YxI^1}SP z%i|}GoznBsCAs8$gu+Yj0{!cY4u5c&(O}{RnVedG&cC)q*-ZpGnn(oIG!E-Wa-a;H z8q|>2(GKMoUz?C-t{F0033k0QGR1aRJZvH1%QyLc-RI+d=}b!WSkX^AjX#<{Y-`zW zL}$~cE!{hIVJtkGz@{1|Xx36NpyweKe$sO&ygo|sD`DF7ioU*gm!y^G0aTn0RUBD& z{q%!uI$_#5cf4emWcDsMO<1yzPWQQwa~;H};;TV1MYYd-Y4?3XX4^c9yLqi}a|Rkb z@!E19^RaieShv%c1WP~b3l1F&nSH%sA&GV?al0NQhR84^W^B!~0uQXYR-;YDQ29%W z#%^|?P62bdTG{)*hH~fRm=!i{DJL*j#%ouDklgkRtd?h6U;maK4z3rpEiNfYHvgzC zT4a&!rL{hPTwJFA*5!i*AC6Zi(Bay4iAUOSljbHh?S=Pi{j#LK!T~db?56_>62+C8 zY}?9zTcsXPa$T2x#1@T;fNHZzn+LYGacve<6{=V1=^KcceO^FLg%E@rW|L;W?O_IO zb#86&#9BfZcPfsYYo%du)5Ht}e zRl0YN8bUGk)BA3y^Gp(DyUESH%dcwBk!~DAN4x)K{?e&bkSmSVivB+Zt6M97F>w!y& zVI0j6uuqc2elsbw*Sa3xTkturCs!G|QDldYm1JNVJWinvT~JQ-xgo%2Mp0rZbvKsS z4rNyw_w}Z^A5vjMjRG-(-qVP!h*Dj_!j^#wEmcery7c&hA4C_uD4+1_u5r~Q?t7ii zZllyKMMv+1>Q8tI{&1||ga!Mt?N^Q@#=S_XB_$eLb{JEl%a3UokkI;c*rucQuBdyH ze_!-~vOEuC;nwxsZ1J(MUBr`%B1|_`!-{M%ZBCpCNRJ5IP&JLsqbgRD22`Tv(EjlB z@1ruZ%kx|>=u9J?M1*JKn03t`yi32mmRlpHU+d{m`)k9)^Vc0QlVi~+9Fr$0Zuh`K zB=0Nzku9n3JPOgtSK8#lTaoZx*$QOJ4Bsb|c*(6a&m1Tte$ild3Y#;%HJ0tV(KdD? z3T&+AZryIkx*_vN1OHFCdG4OQTs^3_r*4-z* zV?l(#b7V_SJ%wa`U)DY0F>&5}!=SsYI*)s=V-5cZyp!?NY_WyBe)P3_uBAMB4Ij;} z-twZl5lu${J1_e1wjT24(K|`c%@6jse?Y3~+P%o%Ryu{W6o_54`#UK&6>({CDw3)7 zsm7qg5)<6?Oj~RT9s0kL|Ml9|?LsEyyyE!lTHt6a>9b!9Ir{i)$_}s5P#{;fS-F?v zaQI&*+NTaQ=Nr0RD^3g}1>$(YS3GV5P&Wz~kZ{pq_Ax;8SySO51YP+*WHn7UCO4t< zb$Iw7D670CBBO8rRXgQ8*GV_p*$tR$_yj2gmEL;&9zYzE&H^m)n{jAwl9FQSVqFaQ(?D`y*S0B<2SHkM5{PrG5w|F5^t zpPgZmA(;J7fsGz^Vz|P3O0gO^xe8SZ&hWhp7!;zrI<%wUfpChq!!2yb*D=?Gh|mO32!X z41uVO*|-%ocA(G)Vr-C+ios6!Y&`&FA-KQXu@K*5{we^KWrlD=(fjN8pyBdZ1=$E` zqmSZc4ZK-^E`N(<0;tw{iU)=23QvbE2G5O$$r4l&r@LR)RX)`vF{y2FRnnOtdrXxL z^<4)wh;aJ6aSnVo%eAIIM|(?Fvs<2{ucFIG#Xp}ME+6QsagoJI667J!Yl z3T3I!2p5gI=^Nqqp~u9RlS!s_hE4RkG^;nU^h>y5V|kIJIP9gXQURUc!v#>udt=8q zuLSkhg^A)jI*!9RS3Z3zeo?7Sve2x!E<=X0>|=^(KtC0HxIo7b=5>GNah=XPjRZB$ zr-$1%KmII_)4Gx&A9!69I1(^_VwIbJI&u3r4Z#yM`R*`+4Gx??JCkmF+G>JvyE-bZ z4f%4Zn5+BakL%FwUPmhxmVA#|vhvm0cc>pIY>a8u>Bw+#GDS@T)}i_8qlt_#j{o|i zzfR{z5cthBuhMoP zEgpby$e+E**4=dbD_D`FaA@9u-k3du-`0>5RfT#IXo4KA)kQhTO>k~y2f@?QE=^bD z`ah1}fugGCA4fVxA82kNqYv|&lM@s1Oh)X&2&WNWUQw?$ah>#*wBis5aNzv|dzmT? z8hJ56n!F-NN*=FvuEFi;7#JGC*u1$IEb$wu+`~ZFd+*+3vgdX{Fae zM7QS3g`TYv+H@jX!Tk=&WM{s4wN*LKHRJmoCUvUhNennN(#jRq(0G5ZEUa`6X%2s0-u)VT*NuOA$OL7}?fK(G$-5NtGI z`0D5-{#g@5?_-Maki5`9@r+vlHS6u~&+15UHQd;%`)h;+)%CTyzp@}f1trXLIuhb` zMxUf#$FmG!3Mc}|4aNW10-M*`KEEY01is@x4}hKKJ+v!@hw}qTol{NQEfvfoxj)*v z)|Xo@fQ-zYd-sUM9e;2iNemQ!n9lykO5aWSA_aONkY6n}Ydkkvr{TmFO}PY2=P*n! zXYs>SsX%xg42WuoI_fT|N{Jr<_0BR-{G}UcB0#bfL}qORl7f25SwWH|rM3Z+SEhsE#VGSq$~ zc?c2$h`Q0G&`9KkX2cW$zx+P**M!z--qGlR&irkYwiuf4A214{tjN6UD%Y{H$LsR? z8>*(MH=mt*6b$kTw+fT8sT#rk=K;je=?T9h2brs0^ra4^mP2#fR^u4CzXv`4ybpBq z!+?jToFdoYPA{%w0o*9p7HWb+JQjJJ+~BoTP_eG|n@%k-M}ZG_Aj5$w>*f4>nGkmT zg3*HfEla|*4-m>$UiV3d^Ju+LQ;L?a5<#&>u#{kIV5wtoj6-eSV0KkN{?&u`# zQR*t!9j#Ww)7QOI!Ex$tw;z0$OND^B5KUbdU^nTt#E;ilp(Tq<&>t%q)5cl|Yu8JG zFbX&?!}>`M`J0|9wctYW^Oh;=XPsztVR+gqvIFJvsA#Uxv{!2cj(z{Rb)>T%{dqVl zuNd)x83p`HjUOjjBFby@&V$Fk=w_8eX`@OP#izhuKzV;H=t$VE0-_}k%?{7y`3Z_5 zE8T3tDOMn{XD4H(rp!EoBg~9Gdtm2o+vCN#uuFo!I%+$T$I##O3ZC%+u!fwGEEHku zd;X8QDTIkK=GI0hCk4&(HkzNl3wPW2)tp@S#K}nzPNrS8l99YzrwNB7CVjNFo)j5Y zzFK!h+<=hL0v@W7Y>wcGw_x_3gi-D)B?0tG0PI#>wLF(K<7;iPc$FM$wtRHWhuZFR zIg>5Z9RNT5#wX!M@Acsg1bpIDdvFeRUL)bSL(Rs}Y-BP%-95K-e6ST7SgxWwZM&0giGMw<+V}z zC8z*o9a=A@&)C}Lqcg`}Rt(!$6#`f5iN=DLfEQ5MO3|ZlYnzxz_X?|ZT4y) zPwg76_|^2C<~D+O;eS1E47)Gc2#6ZMjB6%0>GtCSQ7eG- zLL6H+vPQ4a)ZT(H$(3HFC+iwbya*wC96GMJw4aHocn2p;)&9(D`WKPZET4_Yvuwz|;{jF@I*Bk6;>lmTGCH(+q*+FvPVs3LRnB(p8a; z=1-zn#PGK@aTy6r`<0FoOH}OBMdU?xBGJ+T7;s5CwA|<<6<}3B`Fw94@=GHL@q^Uz z*`ow1WJ=LR;aY=#vRj9L{bCy#j41uDjZ|K5D0|U(sB1BQJ>E?`BEHSyOA8O;<`b>M zpkfl$0g2=ph^5kXM7xP*J2^83`^X9+M@x51G66WP~eZRR4 zwstCxDbs4=HIs3MdEmxEE%;I0m@ZR5MSb;C>e8*(MGuk>b*-w7NEOooJl8CRtAJ1J zhHgAUr4*a}NBt40gLumCd5E@;Z?p^y#Ia)R#UDSHDN2A8hN4`;!`!8k?Opl2B76iK zQX#)oM)+gK|yOrt&koWvOHzz=+a|BBt!>W8I**U=Nt z^xjO_y5npxI?Fu1zOM&cl2cOTuZ(3UK?r8*smYT;146A)<5c_HH_cBC$DgKj%zo>H zw*NMjwy0g)QM?61ALw3QW2Re!4f@I3pd{4%(9Fm^)fRGznY9@~5Jw@mYP3W}ZRAxY z=%WB#`mqNe0m5n@<(p>DY2_dK@Q&ptK^ih9gb;!PGtX`UTw?$9%T1E<6SSU~AUAK6 z<)RU!dtQtt(T%LQySlnJ=n0$V<1&>aAXg7Ag^)wKQbT#!v3gfp3!LNA-V;sz`j(%# zYgnBh9BE9$V9|lGmNnR$v!GRK(Jb8tEung9*LZ!0%JQmO`jCukzdv=imk(Zj_qagU zs1^k2m+w^P>}tZ^W_jMA9dln?b2y>PDi%B7L#x0>!9x5%c%TDtWj|jZyO~tpAIGCp zK^fm@MTZ2X7Gmb@E$vcom_*$juq3M&=aXj!sWDcDPU9z*ja5E*`c~sZLqTdnT2_G~ ztVXp1d^%2cc8zzPGdgX%%7!dqHb4~r_of*0yWttg!G6X6zM|q9wVDkQI2I5X9~+|} zYbk0K8aI%5+51NDac@o=EK6$#2Wl+j#%*q1XS~!{_p_)vxp980t^C;&{qngRV+*dC zSy}Si_2By~0tK}$97>GaoiKKk0ELkJPZGVZm16* zM?h{@0MyFc5J_q|jufo4q@jpWyZO#x71_lIGa*{4E+5@32p$O*@MQxj3F0{v*a7>V z55szPcDxO%*-u>>P`9c2s`x-twwpR2%*>Ta$`$*)(p^V54vMzBjt@#e?vG9P6ZsH; z#_)3f(8Yn9894_rEyWyT-$Y>%y}xBj-!VMb-wXyA^O)Qo-$^nni>rdSFwTC-n?m6SiGWy?<$^&AbnesSDL6> z_D;z~_MESi^768`K4)nVzN+8cLu#}xeo`4s&4(}@H1I4S3z@GrtNY7QmX=<89Y`in ze;oAd8|mBjn&o&4oI&6CIRDY}flVI$c<)g?bDh--f<9_ujW9iLM1Z++YcAfT#{qzb z_4`_FQZ0}m02Pi7%N|SsbFflSl+C`_fXa zXQaIT%s5C11_KR6WfC-ROUP6U`0ng{$AiBCp`JlYl0T3CyP)8K-ehmPEfl#INfr&z z5e$O(=4Zjr6Z4P~1>5{tPrBIEqnh5tcJ(=!$SR$k-R-gb^k9`??X=dM4*)>!uo7SN z)dQ9sdag%1ZFuPS5t>PLVQuiUU>riF?m5t70P&NRUlaZYSaN;T@-=`77#NfI;9v`i zu)r$OI?U*@x|}*VtcDtQyplTj#6m94c-p11*lkI->yLWRADHAzkz^5}8NjE2u#=-o z`rgr>Pb=kP$t{c54cDGe*FPPV$VwLe^d0arLkb-M%hC^dvT4!2Ou8jGjr}ESl36~= zMM)u@d=IFGzJ7b=-#qpUpBvm)QHq5HCl)venYQPf6&k|fN?C4PmzOM+eL=Uf>ax#S z)LXJXhQ{vhhh2Q&AkF2mEa)!8Rkc97^7m5X@^)E%!RMtsM{Ji>MOH!0)o}*# z_s<4-My_7!RC|=Qwy2{P9+~ggs~hWDuHkM(^L)bd2@vAEezU5T8&CRu$nDLt^?$;l z>*rfLcW(q@I2}ZXHkQiL_n*pR=Ysnh$>a=WdmowRJt$W3&;1pI>>|tZJ=!&El0XuN zjeQ+F7W!W2Ul*P&9#rCoqZ5-0$HymGd)~6vV#Y84_J8(3cQ$R^*7y2KspFUxaPwS& z$~MlI2c|~e^-ZNVgwF2Pp-uEivxh6)t87bvG8ZoUB%O6n52%uuk9LHr*Mk57KhUZ9 zn31~hvN2_~`$`P8TsFq|o|F7u0-izlTn9WINw4jX;eZB+!(-h;E~zDyL^9qy-O@nY zP&J?Cjc4W+wXaKVY8ht209zW1O|kL9{C@FMhloXV7Ji?83V7(5ZG!U zz5&5R%h~~U$2f%C(P$6c4$l10lb9vrp+=xBst;~phIS8g{SR~V@fsj!h%V9YhD-VE zI}h?-1inn|(fC?>jF%Vks}L#t%+PHq&ssDTPJNG11O3xzCcM}<91n{+6TbT)^heOU zS2e?+ufr|#xG?kx3cASf^Y_z%tLFJ;7psWuN`NOqI3}JlCk(Vy_yFtw z_auK9Px*jAr94t{hAyV&1`iJGhv^N{h2U$o(aE*tPLr4XE*J3zX_{QCrGRK;(c%uM z^>I6L(^EELztA%I?N8+oul=aJ95_Z&wJK;s+Iret%ok7Z{OUGO8Zu?E#LndPJ0pL1 z(sMrbYhlM?XvUzG{HKD8OODkSjfO+#Hb(VHw|9~I-|1d?an;_yi<#n1$XlN#s%Ar4 znAO|ih_|SRD1DMFY8Y+nG+%NPP3>60U^1F;30H%xezj^Sfe!}Y!&R2%0BV8wxgyZh zgh;jg^6Yz@T7Uh@%qNQPvO3dIA~J-R6-}r+&h7+RHT;ERdt+aNKCWeoBEpAVe@?u}sD;mdLg=*hNxHA@i3CW=LztHM?=8Ra6`ihO zeDD=yXg?o2fy2)zu5B@p~l)Il*jT}ga4hJnf3*~U+S>|;PhC0P>5qmX>wqzZ=Z6XS!ZyC%qN?y#C65_%#yyF}b+}!{}a#A zLLvi*oCgI3t>e{YFVRf`)AOG%2$Ph2FJ8Lz3(^oYS4C=p-6`|;c&p^RhylW};<5NO zH&auBzgzw%kG6M=(%-p4PYxO^w_eYwV-i~AO0yR|l zvaC4HXJ>c!pW9-~?MGi-G4?psXFZ@k1UuXYw87ljSv@Y?3-Y!Xp8)KeuI_NK2vX1N zD&&8b>Q2!1mJb2HCy>zJh1Ul5gK$9@Vywcc^@8AMmd8o`+)KZj!}bS@`~st+moCdc zUmkfmpYG2zQY`9YkoL-&-8nWqes{^~454(f~i|JYH$4r;Uy zDQ|(tX9qqO71f>4*PZMXDbCA6OfGdl!T%s32x`_4&8Nlb)#<<2R?S<@pJkj9I^rm($Xi z@XE6g^BTvmjH0V1!xo?u2Os09P9mt}6;r!rp}i?*2YPKJvs|RvTCpQ) zcq#s%{rJ}FVPo%t&pY&uLU{fg%+ny?s7>KBBStg$Zouz+Q?)d5CQYC+%({v5-g9Jx zl&O3gs}aW5*Zky%3}j)tTx5gHXn#QGz~$WM#vuhXC!5*`i&_y=y;^kv%yu-m=+7R9 z#UHW<#&SJEJv&d@_!Eef^`PlYx)*=^m=e-IJf(0bTdh5ER7BC306HM<-l-Q&CYL4M z7PSvPT?uP`<-JyO1(tXdfiw#;Z}d_*joq$bsRx85+o$!R{*V>$mM?C>xx-2}xqi&4 zjvon;XkUD$^YEQ-l@Gw*LF`o#Z^=5QWv?Mrd|%Ids`*Ps+<4Oc#%J9B@1K!6e}DN} zNV$iLdAd`secp=vI*d<6f)QJ=x*js`$=BIsR`{#aXlNx!j{L>&yp~&J*(x%{wO7=? zU>zz^m|_i{K2BY^knc;YEbR|Q0{{gxk0{IXTtLK~t~Mu_CLqbPHvE{UYTl z7GRGdkqtt+xR>r6aNYxU`1O)9((klEr#edZTXrJY>_7|;C}2DtA8Fm$rGLMBfU~O$}o1Q`yl<4m-%3{DlA&*d^*0&{cP{H^{ z`^IH+Mc=RZ9Kg>$_)rLa{8r~s5--lTy)6m|x#f4_Q^^2sJv^hf|5gVH@e@-ks~k>H zG(+#|goyz`3G@o{`3RDc);NRu63nkPzG65nXZBe)@=aw`(f|VMeND|cxh{@2G9rSN zDe4+!$k$K}FY}LO^l#@q!y_XhXrpbpAyecU6>YUKsx;#Hn0>@>=YF@f7gLIRqkdTmMKK@uT2EZd`i<)Vh!eCrW zeK>59m+Iqj0}I5aw_R3H@**+>6_Qf|uoR$2K<9NdPbeW&E-T@R!+$f3S2~8nt0i<~ zz$|_o9 z4Gwccr!?^FsxaV(>3fScNrCmbdXYh!`Uky0xeib4LvugJOAdV>bJAmV z1+tYpRCLa1*v+e}z~t4@_dy8McG?Tp;3*FF;^+lNoD%Y*CAsr8B;w}u9aU1C><4-q zIGwXezaJhOBRxST{A zzD=v%Klh`vcDuN9+l?29O68Rle5@HIKad}XuV81+3-N!GYRfP#DfqrmkKnm)S*kx? z>!^#GNIGn?eW&A4;&%&$YGa5fE}yTkOZMpHR_&=VyxDhb1vDPjN0a27$te`_L1sT) zD%HX=lAt-L;zdJV)sBErfYR{`2<`zma=JTP)B0lIVp;?dt)ac00!`RizK+mW`VYJ= zF!H|S=wx&dN4qFt=uv6Eh9lN3t-SRMbUzsi3}Td!)>d%lT1fT0&G#pe;ZA(1c3zE0 zmHBU%N>Q91Y*%jngUFSzWnQl02&BydgHrM0)9~M02A4Yx^!z0nL>7%5#Z{$LamL)AM#Vncne(CZ!J38=e7JzJnJ z)nxku8g%NAL{s8bHjdaG-K1`yowsx16aYwIK*QUjCQfG>qtY@bfH%e1C9N(C-?;=LN5zOy(lFqJNLy19{_vB zSrY+?>RxRm9L?=|mo;OU8xPdCDjgTa{KHM^RiFRJI75KYz$nRe?(A2^Bk&X@GCM5& z0iu=ylY*@Y-{c@Y=XefCk+a^FeYIeV+Et63T;*mYFI5^o+#~9P6L`{IN%HQuBQw8i z`tic{N}K9$2WN$ zP2th=RGi956pgcAAvEPI$tX4k%LZO>@lYtC1Y%SVOtLl4R~mN5(b6|-PIr9W)x0c! zV+;`AI0tQ~I6R)#N7hNj8$f?EE|o!e;5n>9t?%d<9eyHH3vZp20nTC& zWuc+tJ@zjaKo}fw;MfeSfY1YQ5h8XkvT}W2HV93Y6)fI7IDVjIea5i_`FJ+Cw9D#s zGxAiU5FFSUTQi_sDT0rl{&tWV6dG$+76Lh(2!NF*cZ>87yO@Dk(&oLYFMthwU<2*B zn_kz4QM#;QtDmizH$_;UJg)={l-8#Yo}3T4n9;*<__lV4tjjcM0bSxmjAs_aS>^y- z3wX^)Z?S1(@mOG(P#yV{rUy41nb4kbW*l}!Is4PCbO8C_?_));;|S;;!81 zLH!2rQ9hGbo$DOiH%k!>9*yC&0(z)k0_ke)8-3Z&H`HRP?K&3%3sM12~fR)6nyuTY$l02pQ z6|2vODv7e%@w}mbH{D4by-5d{VW2s&7V$X(y-2X)p`VXSdILZHyiAf*-pWbSLihAt7dt2y&)c+6JRt$kJ6xhVHAQJ`bVpwOI zd4&H=Ueo82P<@H}_6I=3-V;axdi~4sDS}2JsyOO=xa=4=e-2{Gz+;;a8h6Ykh;9eW zF9^7RjQjRO{e_;0yQe_vALjM(kK*t4Kujqf{T&<3?$=7S={d6O4oL!fCyXgzdEoz4 zVR)6Z*5+ri71nHB4hg%kGFBjU{TuiVCzBgqR*T_jVdv(9H+6e?F z0#U(`;Y{lo6@0qWPGcpb8f6j51kdw5T3V6=MH?tQ394c*~Y01gDW5{^;#L|Mz;_L%#)QjLZ_4OvV}@kynbO(`ho%QHrUMzdl^ z342{$+OV_0*VL=-%GFGyWjNEbrLC=hy)EJZeDfZVHcnE*hb~RWS6$>1(^DED+Yg~^ zL`BN!iqmmDvqCbG#3_TJ>g=aM7Zz(^hDCgN%IFa(FP_qDC=${)W#(FFpm?@|I#XLD zL^F@wb`1usv%B-l(pLS_77YJ~80GMYa8rlp63cM}k113H1(2>Dv=0+5IP`G?-2y@6M_a9I&B_|(^*-F8h8Ez3xn%xaSJy1=KJ$s7m$(ovh}ktLgHIk z*nN&z@D&g^tBX4k)GVM^a8ouCp_c%6lNAqwh1iR$jp>YD5g`R4NYciZa z+tA-!LQMFYmX1-u#~lSI3!rg*Iiv zS9f6DaGN-Po7ZN*r5;koQ;>R$ks8-pE-jtM8Lr?>u14jurC%j=pg49%1JA2BmfiV{o9`Y z4_~O?8;XY=fRaO16;=9KcLL|ipF0O%pa9w@-S^qbFFWK#eWMiE=n9b;1i2kLxL(ft zBbnI8(qOvI$uP1>`{E`E)C-iuVE#Psf%NGt}R|FIYced*FP2 zEspV)gzk@LS*t`*gCq%K5p3{Z%qP1WZ+v3{f(Nb6EV=i4n4jHw4K_C_lpO>_g8LUf zY_yR0w-UV26PdtUO=-pf30-x$pPo#P)PXuzIvQ+onv;ln%9hJaZTs5$j%|9QL2+d= zlgzfYS^>}1ULLlTP~i8Km??0yX3yNV!ylQ!N}ztk>ZZ{KY4CL#@X^GnaFFzpcsW{p zTgZQc>wET^-OJI?TdDV%xn+lKsoBQ&BtKjenDd-|*WGU_C%wLSz_irNQtgyeYTyg}s2=uW4?}Qwl_@@;Im(zW!u6cXarZ>|8>(eJP^- zi6BgjnG${Ayk)%Y(Hj?!ER%^>&K2$*CW2iCLcf@dj2Tw6Nxq!=L|!|q(k z$R|3Hcm?)L{PKVFkS(FhxYoPPF?iHIXw;(0XYX6Q^cXUl7#NDB=#a!QweTo&D=+#X zUh|8}F<-WP?g+?}6TZnrY;1EO9e=u3g2@z?k|FhHA*g6Q10tY;4WX|HBB!BEecZ`^ z{G{%>2-HY?Jxh3J;Ilb)wAi$d4IYYwf&<)Gt>y)n4Db5WQcHeJQ#)Q};z?gFoF+^Q zW+4_zQFE3|J=>!k6QCf|%{X?qbLv!Hf5_RIn#5#?Zp?i6b%QhZyg&uR)tVaMAk36` z-i_@csvb{UlaP#j-E42A`!^&L7?~kM`g{50&yG{S4FnXXF+p<7+{Nd!McvefSKmSG3V*ITEBC4^JDtR0+s=EY|G8W&te)*?Ol&Xta;?e+CstGdGXWqXDl*~iT` zRs8D)grw?+bO{$6M{Wk%K&X~Yf}Bu8P~pyP&Xg{)+k93x_;iI2i!f|Z zmr>!)i^he3qROO}%x9!LvbicWJ24E^4T8r&o52;l9|!>Pp*L$V0rgLE5qn63l`$j z2lgN&eL5&O=xvt;fnlv+_LKV41Yg#B)%{*EL@7n9vG@AU{(VzP)&u&9^moNmYGf7w zZO}h z4c?RyF#hx+vb+1$S^B9YI<*H68|=lw@nC}is`B#co!N?>o;#JNO_G%$U^dzwe{k@I zUHOyi1{-u?>r&vTy%KnT00#vQD?fXhyr?$z!B0=9JiH@kDpC()#B1D480@oJtOgE; zRQz4;jb@~&a#6e850lHf%|Uk#=FRDPmUjYIBqQb78C#kK>lB_me}3oJ>qL`)oLqRW z_1ba(Q0!%B8k_d_XQ`XIx_L?m9EJg=h*GNvQabAWHDuKFT=j9K) zSa5_PWWW;2#{Ql~oKPcxUHM?-{dm+CQQ9;K&9k;J!f_@tFc~kvak61f>uT_dlf(LPufAnseTD$Y&!(yu?)LZ3 zy!X5d{Q$;zaUKjHji8ZAWD1c&gIT~6D{Z+o*UH{%58<1ROe|dW(o)h}>1SWxfn{ul zv?m25WHv6IQHebH7!l?{a1Ro82`nGhAf;09yGXq2vQ*Ye@NYvRL zLm7W2$h@wUw&XV*vnO>PP{Fi5||R|@a$EPtzyC$ zD8rLfH@+MyFE448CXWbVA?|!n_35(<#Mj@vQr}FYMy`UI07Y_|5^QjgGuGZ0=x>ZQ<#1JOq| zwotRX1*%-*m-EojP{*FnHy?|M{+X@%l?_v*E7g^{W6FY+6?ivMJ&uv*q&+5n{#0E? zu6{qoXa+H zcorOFtBf8DT|Ik2$aU(ph_O@sDtG475XG!wL_x8B0T?N8uz3&o_e9lGB?M93tB&E9 z$lyr)jmL#83eND}Pq;W+Tc;{xmRX1i4yrH3S??Y}x(B?JcXC6)iTC~lHEM{6!+e9h z7H3NfxA@$&LW`~9YI~}oh*g;4(~KbQ&^V#gdkBoK#j~58OfSJb>cB4T`5^+#)G$ zepR^YC@Lmq=HkP+;lY?XKHhm1+a$9r4bw@`@QsIPXj{m6_Fqq3-QDVQir*(Dntaf@ z4(=9$4|VLJW%K$4cj)`RmSeVfmD%~yZn_J!;jf0tS>oTBXJCO%^u6ruBu%!V)@XdrL?9$9WiS#% zvd5d*3=95|+;gxU^;G^;x11#OZWT3XJ61`3y0H=k0}IG@@; zsBQeRjv5Y23%sy(RzfP-@&pXD862YXEGQwaao}(A>;{Zzi;@ydcYDQZ{WmvdhSt3( zz?Oa+Le()e&u`Udk#iY}U*O_jPn3X!UK8Nq9vf_Kk@*XG95e;8xs39SlSxO-^McbB zJ3UP+<Q-{f)TW1!uy_zG@hn_TDhc-%UF><-qOsOxKh5uulhD|K-GB3n zKpG6@+07$1N)lE|66#~-o~^UbVq7`T5Ku8}5rhAEpE4&m2h2N+wV8N|Fx+uH-ebz; zCXC}YpW*#WDe|H-l(POpZ*u0WRJtW3yZq!}w}LR!9dZ_uhS~Zc%^1~~--W53_aA#p z7qD|t*{m&p_{2g24yLt@1Ald92h8~TOhsA-rkrMYq?6WVFfo>4)?i`zey=o-d?nuD z-?HJOCx#_-hbq7a+l9o5v=&3_L4;2#$ejrW^^SP#OYYEvJqVt)wSw1@3M1=E(kP=; zo6b)GMSko_U$Jlt9J05|Neayp{T(w_}{cM;1Z@L>`LsF z|LCuOe{+|}^~ry_&Hujq|CtV2s(8Nc_sV@)Sllv1{&T zE?%Asi&)G7u!4eys6xm6>Ov(($e@Giu4)D!i(E0fEPnvXJG_9u-)=Vze4LSKfxX`{%c7N3DJ|YUac9?1~NTx?ry}*Y5H@IS&FBCS4X;$L1Ey+ z*sW7gIlvs6nfO=Fsd{Gb1I3@9Xaha89OikaN!JPJMaAe+3(F;xg|Cu%rV+iU@~^Y9 zYnx84d@rWgDz4NzwY;WRGwobxN4N1uL?ui;DAeJc`$LHGEx1aVd}@<;1p%gxvjDe_ z4XI)wzRwvOWYgx})?74d04F1+s9a8yWfudQFpeUf3)LQJJxA(og$9Sc_br&MMCh7F zgz{@_3!1llCJK@KDP1V1A_JTF(2Lh_5bF6y1#DRCN^ranype)EM5#WFuO?eRWlX40 zjroAi0p#+Od-cVQ3=BYaiz@d@mgTQ410x#RHfld4Q~(KfFrraJ4|Dt9N@B8g1rj$oI!8gua!P@F<1Z`0+0-~hxreYqX?`OmVh-B?bk6CD*|v&=kOp22G`D z!dL+d;?r$a%1TbGE%shSv*SJhQlY%q_(}}>c@SPAXI6;`K=9>!F9f|CZ%S5WfJ$&f zPsxwsrNxK|3q!8{h8_T=#?1@}drqzuwFgJvCxjA7tFoe+s#J;!SsFS95Q6ustK%uS z&)z^Kv6x}G?F|$QbU80M@o(dwSXhYugK+~TFOWA6Ga8OT^*yzYGlJwiUHqYivGtI=`KQ{L?^SB*lwYZ|gm z7CyNglv%A^ogC=VfVAjnzE5>iA#za zfN3hThBwVVNV{ilPrs%<#IzWX>M)u>j45MH) z7fOI8NS9;D4wwf$Z=LBz53UPd|6&1DF3dlX6SP~vc5oNKld7Dr*#Qb_tWcf%gFd?N z(XX!-B0wxi{;o<+XyguXm@b1%?nNo=-6*3$+q|}f4nJ~5jo}THyrYgS zh{UTw2bTZ(Ih-t6q@-$B!XK}aC$MP559ZSRBPwm?qsCV_Ar`9^p=8eY$B+tr6Yw04 zVX7|Uya~l31mG&bB90fIj|Yjms(p@YSALYW1oau%UeIh_$<|R_5lGa;W>~)csHf_b z`IUQM^_52G#apri`Psw4US;gcpz+#|!3&IB34s-2T%h!5Id6R7y+wj9GkspRd#*hH zclwUB?DL{>k{Pu7K|-8>wC0A97W4^XBQD2T~1(@{9Py^rzfh=5pnaY6>P1qC^`1LGUDy+T)cv5pI z5`Ne#0RIJ*DO#aqIP9l|)vHn<03rIBqP08P14uFsV3n;c7m5nqoO)ce2!W1;FUUe~^_Feiso#{jIC#?rTJ)qN;#v}FL} z(Fok*q> z{PsdHfQSKU{}UNJ`Q<+QD|iV0OHkL+E<;m9*Y@g0uaA#iv%7lJg%IYUY&sc(gkuxb z1ff3C#5LDw8h{uK0D`S+oyN;-E~9`@JyMr9s9Dvo9K-(ZmN!kh?=BrcK$ZC`du*Dj zb>dgA!Tt@*|9U{}qnKmy1%!Z;ZM7V8ML;JDFMkij6u^cyuI-s`&2=G4EJ8BL25rF= z%h~5prUVgy2>b=$c90XBcA)qXW!BNix&lR*nxMWkwZAb9js?^@#LrtVZ*TOFW{F+7 zuBz$ zNL2D39v=3Nj~iVn04@Pzy8p>da50o&=R1qPkb)tsnHF3;e6b3=h7H7@9UL5BmCFOR zSH}PZ5;c}au;zHO!CRH=Ucin*ff!eJcacB;gSq$qYAS8phG!g^85>wY1r#hGT@a-R ziWQWq^cW>b6+%%^A|T+11*wkoA}U~zj)4TEt4K$Y-bAEJ6KT@nJGS@p+-tq-egA-O zt@*)$osjH(mGe5zqx@6VM=f8S8E6zM+&>BfHV7?`8yoWn32E#jMr_i#wHWCdkI!-{ z6AuNnX<+WkkdDHISuaa7!Wcyy%TdmazA}WM~fO~)sWJ+A_0cV%uKF7o?^}!d1 zPHg-!`0`md%wfLDv%^ZNCCl!jsswA@w~#b4|OA2 zb4f*Fj8x8j6lT_D#|1W^i+FXMG(EVI}UAl3L58X{|sAeu`fkRA*hN>h2NLCfF?1rqa!u3GEDI4F}1{^?-GhWY7_78yj7jYr1uWe1_sN zXJNUyrLplod`Q1FNpGg_l|T1H{tk2lArX30Q&X4mfi*gtzkErfe%!DCkh+|#rIyv&CAZl;{x@Nr%@xe@`g^`1VPf_*dwCwC{@Pe@{%x<(I z9M1?>qd1oHxapCfEoQkaKLHeqWA9-k)}5OD#q`fa^|1XVdmkNnH?@g6s#B)`20bAZ zQn6{xuyF2ud}eK7HkzWuPW5MzTG^)Wokjd0%d^L^+~ypQEdD6=Gq`f)Wzu~SHS#mJ zi8Wu`XN**cRo(epjMv&ib@GUgLI5NxvwsoF1ZgsssduM1j_Q5FQHL98X&dD3oX;3u zSsq*YF>q`p!i5HXmop5!oZ9I(Y&*;NZ~M)3-hSqSU?Nrv%f|5SSgOG=)G>tr;hQ6Q z_8kgGe!TgEt;kS)hnA-1fw4}wLv18HB_gggryDx^=`UJWAA7^j~s=h+TmI!syZ>HAjAg z3Cf;arr+s`G_aTm&Cfv1vnwOH$P9YrGTHB0W3)dEpTu+5W&E|TnP7fbG$L7u z@E!_7Nf7?ziTEshX?x&5*L3rNV}A%uC7GOl7BV}C8*T6b#^;pdUs&m2YAEkNgfwqo)D~7 z(0*dxBhM~bI2+q7I*NJ#QCZ%qe2GW-UXpMQG3hLH_eqX`Y?FAD`%IF4&L(yb0OlYb zT?rRV5=h$WqmR#*)P&UIXhtZQw(}3M;4=EPWSg;`Epg0HmPkEgWaKZ84a<3u9>!_d ztpzVH*q0@@u+xQq>cf1ZO0p;=LFVw`3n2y!zr)3ju~nZ z`V}lxDkVjRsYWP1eqB>51vfb7$q#Z)?M^a1Qajj*_tia;W&uOdBKYXpZ1sXSGR&zi zQGOf$*?x7nF7Q!_*fP5aSKB{T>vj(}RS@cK<@W$}9aKYIS5Itx`#5Z!fqp}jM_<$SXK;_^|a zp5CaE_l9L_$a6qiiF${<|~HW zP~$(h$Kl(j7$3VdgW=2?C0)FnSc!D4fP*(WxJ@hxWFCfr<*&aY+=beKtNlc(5$aqW zT=@o$QRm_l;tZ1;er5W~+>s-*J+IJ<1yQ z1yxA(_z=EVgy|Sm%Flj4k!av2$#OtEE5G!8*}3Rh+~NZz91`Rbnh2{XWg0VAnr#ie zGp5N4-e14hFK0BtTkf>^}17C#%)v_Ed3vgCF>1ZHKNZRUA| zvtaz$=kx*}7mSGrQc#%`M&bk0P3kpIHvdLAbD>RVQvg>%jmO6mKQ#98nx}TZ4(*&K zc4FOx^VGjsG?9|X6v9C4z?r4N9O|2g%df%-^G1yrO^=mAIIdNztj9&xFb6L(TWgoe z@{!9-*l8?gT`*qCTYd8^E`s*6`khC?+>zgi0Ut4TUV=%CsGWhGMUq8}(wV;%ZUQKK zyd+CO`$)_jR?f;ViLy#cAJ>0oUfM%>A|-M&tPuy8$+}ucm&~oHaHi|0$Em0nZi$uO zbpAVEJbbAvzs6gxihqF|Nk+yD*MEBhGv8@uaBs0ir4oR}slxldCRxN8_c*oIY*?sL2UJ&x*cz@p1miT6`5?bPP zjDZBbMf>9Vg!={s-Pe%o`Jk0Pwc_8zFS>M;zE-EPjn3&6!VF$E*1VlCH4`j46tZx8 z?`TpO$_Mh;6!rb``KvpcMEj?wv;zgWEyDy#XsS zFk$`Y=}xwPd;WtnYXiN2NmUJe--2^OQfzu1DaZMa%J`VX^2K1sHMnC)`R;vpSBECj zx4D672mm?f$8oT$eH9z#Uy%SLA6$1%)LP_2PU9^4b)k)$SD&ceFM|mn7*rAHyF<-7 z(Jnoi8_4Fp3(h(tUfpBQzR3HX-Xpl}aPYjAaGykj)%}yZOO)CBn8E#@sc!N|kEXsZ zKLN(qP?Knu4Xj!n9v6>{eed<=l9~8~qw{AUg}P-G`L$Ki zeOZX<>R|e0e@tS)Hu77Y=ob%w9tFU?ZNtd?X(YzUAfrHm!8)I^9#WQV#6AgaPVUt1 zZUd1#%TBYHeqs5biWe7ce!6o|i>gY<)cuN@0-M=pjvi`zY^}zKDfPnP2{vUZZFmNN zkH7$ed&6!Vl;girR?FZalM){VvMl+HKF)ULTf$-4Mq62%fDJBO3$_w6n3VbxG5KFjf7Zyf zX~)AnD$}UKJaF8L!oOAWnsyx)DYhB2LH`YO{g9He+j$+7Ymb6?@`Bw+s?agM8N9J| zN6$scypu5-uk&lfbyUQZc>!zyip$n>Nal=zn6_Hd?vx;_G}Z#xkidP7-dV|LIk%{bSi6*Ek7gr`$$LH_&#d ztut$`uGT2=R7QFM9ac~4N?lOZ9u* z0=VBNi>os^k?E^z{WSJWRi7hQwOugnT~h6yp+g@9w>9w1eerHhIDD=U@d{rD1XPp2 zps&-p?sXD}=C?K8u_RhENkl?spn^9MUdY;8h<^?ky^7zy_vGQnIeTk9N5kxSRds)k zZ4zX?AJ?gF35Lnp+1YPAWN2_vQBnWkGEq=az*dvUNDeljd$+_Y`>yqo!<>!@_@SGT zoS3LOZuPj;ELhohE0;!mLkoHU5sIp))GGHu*L4sdfh47>m#ptLL$4VS%M*TM%6N|V z-<5+6zfbECxQ(P&mrvX=kc~JaqKCEjhovkDx25;8KD?3J$qjB7Tc;jtN4>z8+H7fZ1Wnd zV0of~nP9Nk8X6kvX_^%|6CH@h=+mzL;nJz}rbfSFHD5V3mf@bq2_!dhdr28GFv)#n z>Q;|zcxE+49{nqU`7nVe6||#Od6tsj(pXz#b}Fc3XmQ?*EZOERs`=4Z@`GOHl7V${ zCZB|iF-}<$7qfzwxRGY#G~8s}q~n@4ySc>_F4AUUZDEGv*Dq$@3O>uAF=raQ0?g^aBI^Dc?-ko;K}M+D)1`9d*TiZMuq{i!(V)$!&Tb(y+(|7x={!d z$A=1mps7+5LH;x{E9v&;u5vnz7&1~ zsw92oDzhiaXN51b^%A21o9j8-gjyZyxuawpijX!eCBU9)AchlJ!Ugqnx2-Z;!(DEs zj^surZU}R$M_-uANmSHNqdx*-WR2+t;(L+p72Z-udL^YhCZ|bIJYrZ93*L zXS-8}Q?vf1*OzR=bSURF@!66Nebh+?#xddJyHnJEQ$uN&50_YYeV3?p;v@k`a9%%?TvnTgX5@)?=OE2p8@0ls28b zjF+Tg9C(Z63dj8eYmQBQI;C+Y-XM842Z(&vuvd#+7ove0yGoQu~X2ZT|pTBy5ES!0JAgjdtHNIQEB^jPmLb}_Zr4rs0MoNbi zaI|U$P@s!k%xm(5?a^QcR$vE{OQnN1n)HShJLj}6q{3bPg(brQrqrQFP9R;Zr}hkg zqeWO<^cocW#ufD(pdJtgJr5q85qW1?Pbl-A#Ja6|Zaa&pFywZO}8kjfE zF3;0ikaLG4d&uXKk;%DNxcfftNn2BODx#oh`-{){c(#$+^&CesaRA^|N_;sra|91r zaEmgG=w8DFUo7BJL$#OMhdy&8_BeF9&opWb;{!<~HUb#Np~Ud!j;)jMH9n~5XrZ8} zI37Lbc7`ZE)h0_@$(=A6Cf>BS7}jV9uj@s?0_3y%OoxW}@O0Prjy!d~iuU&Qs@@w( z-u^%sgBx>u0u*nw(qGUIor#W4&RzQ1Zqr}vNLI@cr8}ICD~YKve}@5~&NrTGTC(=D zW0eF~r#jV*L{$>cbnH|6e4}17*DZmW5c{MlNk93Ayn;zyAcNZl#xRERoz^##{HcC3Bs&2hsPEpd}lCVy0&qe>x50<)5II4)Y z6fbFt3Yl^SZ5scx&JlwL8RhNs|02_^3 zF$GJq3pcEUc_jeGQL~uZ+18tYO)9$CorV14}9dZ8UyPVoMwSr*P^L$n_P1-d@xT%Xe_N6P_|;x*8?>*BC{R3Y154q3kClhhr2mmWh<6ruA zrusKVWXr!Sq#zY8PE_R+JqQo@Y#;nXM1qE-wf?`o?b@?;14)9*tqV3KgT;Z{%R;p8 zpDV0ns5`c{6B*_R6ub2L+U~1{fc`yjBod!4jvxKhVH|KP?-1W!iY9B*ivuA3KT= z{7LV#0y>vber+Snat_|t)#l_KN=R~~bvXC<rTlco2SvFny)cZ~F3PE!6BpGY*Y>A}D+mzU?t4}!HLLKkvUDQY|0SI~k z-Mp@@uEhc0trG9x@vRVx0^YioTJ!YJHLxk{7vvhjxb`|aBXvLeRH*PTBq!EiN8X1;8 zO!A0y)CV7$e?Wk#t*!V9dYe__=)N6HE_Qj^Y!_DC^#)ienxs0cXAH;W2 zCO;j}Z`c1!LHYKpbIT&^oM5f3F&@z)->8~sO3aiGQF1-N=EUU-spy~)CQ2oo_i+5} zE$;8Pw8f0TK+7%Q^_3@`!FA8K!ygetBj2foDBCd;gFyf{2fOf-H)R-zllBe~GbGwrb2hf19NQPp zSuT!TIcDZlLpF;e*_8Njv4OP41~~oTuL(v?>|hw$8s5Aq7bQ1J_%ckbL-9B)Kbdc`_9A0_z z=C@Jqlr6CFbqLYiABK=7DSY?qUhhY)Fa=)tNb;w?G!P`1TzHS6Bv6G8VAva|4|lBY zV-k~h=9+M-6qR|)#1c+zTr2$`mH=0REFOI-VI^HL;%th{4_Fl)yczMWQS?ffHhJ&{ z&)&Uz5##tp^Sl~JJtpXwgIxtLJQ+q+d2dGhsKH`XP=x@1Z}56xRBFWHXtV-P>V}h( zh*DhN`V~jAdm=fxCMx8|qsfUv=0>JN=^_(y?4C_|QR>}M8gufA(e?W+3 zGONs`-}a0PFF$oY5->hKzG$>h#R^;jxbMWJfxomKP_qTA;q%z@{sp>9vUbm_CmeCL z!UV%$a*ocui8lTl)Z$31P+I@zU7x&JW*c6k{@ozy1)Wt;X;`O z#vr&J_RnvT5Qm*#{d;$Eh!KboSXgE1r8gsL5rOU7y+TINvLRC9M+vsWHTg>h$p#0G z9X^b;*)uCED=<%$MRcV^a%{AkU@&X=x$A-$!GXhP29*uAN5Wrj#p`3;)SHO;)dM;% zzV#GZblvtksRX06B-$&(0O^Ql&UnS54Fn-e5=*pIUn`l9=0u~3@?m_ZVmU=nZXlVA zGhE*Y4>IDVBTi#mxE>f}Ye>)gcEt?w^*8Asn})uBH&`sRX%w{x6ZYB8&woZVggCxy z0=oq3ittL(dWmP8I$Q9GhnLE%Y;8<%Abm{3C_)Z&ppxG8ZA-Qzw7l;9-L6(4nKsVO z+rjn0Sn*+y)$`0#QL76tA620y=43`En5IFOGp}W?F6dJkGrdlQ%&HX)%NHTcaLlDQ z+-kDRxu+(`A75{+NgK42Ji60eW>lG68rQr(py$w7)4@8gzRk-1rePEbnXts>lgXPl zi-vs4e10-Ll#idsF6?P|bDYJmfYlAPk;x7u(F*M~M}6haCT~n#C+b&vHcw6PaGF!9 z&08=3{NLg)#U}949yhV*jo%!ERf)jdej^=rue+^t&sESKvHBUqCvm)eRd`OCg@8(% zK9%7?mv6{?_>KIjZqi7$ZvWl`b!j@j)2hjZWdBP)qQyQP2y}Wd;LDYf$xL)y*f|o4h8DZcxF&yvBBo zEZVGGwY*A=rhHES{V< zyKDYnwg{HR@a0We4N7d5$pw!}T#1rRp>gl@B9GKXJ!ww1(7RPZR%zAu=kR^htiQ#} z-{aV0gFL^0V$f8Q&%QXLe)U9BZ4psP2#~M0G%~@6j5I6ckw_&TU@AI=2GdK}tRqKM@&%n@P4J1s9&w?Yo`epqE*+d;N z{-oN#u`cS=X&=5kDj3jFALhm!3)~Y_l0!QsaShE;z$fD*f5`46x= zr(22s8{$Ti^mm{e+%o#pXHnVUXGeFC8GO+hgfj1!=5>%czGXwzl)MQm9O7BZcZtS|=eRwCm8k$Z0h! zz}SCIb$>c5A>&Z)a7pv~LESC9th)ag9&v%GGy)bi?z;$kAKS;~ScAj-O*-lyO~UGP zw{AUC!Pi-Szj}ZPti0Ze@yr&D$g`mp;XsNttFmeKzIaFC;f9|KmvG zrqlbRzdu;46T{#!RgyicZj@1O%GjPHqnIP)v&Z>qQGB3_KM$|URKau|al_VC3y*Tujrw5uF!V7k#Mj?-%1gx>&B7LFWB;2%Zz*@;MoN6JEIS}l4?AWcsOOJj=E@>r(h1M-3e{qm+ zW~N#0Xj+JtUdX$2P9jHAyeWys$k>`{)8S>fmpwg{V>m)lJYYi|_45-=hS7Bk+qi}^ z6=S#Km_wU*Rj8XR3KbD7{{PTTxQACjVE%uJ4q`a|e)H(8Zogd)T;(?!e5J2w2$sl6<}ho??##Cg8ooFKSv@=~$Ez7P(jL7_1K z#x$~udy!wjslB6toyOAv#dERxHDh75+bx<$Zu+#^%Dy;uNX;gTW4ME#hi-A>Kk9>F z9xult#b&0DyOmyb^TlCmsY!u5!jT13r3GaBW1B|C!j7DYShp1Om}Vp)5w}pB6N_bO z;>fd={q450rOfcyUF*Y^=uEm zx~>M+_{;ja7gjJ9Biz`Wk35ak5HJT-HE2b;3i?0dX9Zs(tp$T%rC_Zrk=<@|5L$#Y z(h=g;VaPLY9!^yiGBv-&?M)~Ml3oyuY&hNXO!hI4@SW2%y*n_M58~$oD**Ai?f9Uf z87QtG9@q*Ff7qkq?w?64gTr|^dms&RH+gyjx(k(e4v58FO|S%SRnQvMlJ#~pol+0* zceMek?`9iZ=a_Rz#@khfHBHBXq@IVLEAwgIi*2l@@6;SDd+0Bi0fo5@h^l~ z!0f+qZeBpOvR!`-%tDcUd+U`%QGP=UXtYStPR>GaO3yZ(Ix6kj{k&;E2(QE?KlZ6^ z?jDy1vDt)-eCzJaM(XbVgiu?<%nV^jh`T@vH3F1jmkC8+?1KLuzDwE9`)1#EH0tWPpJ-L=m7X!?W|v z*or5!_>3eTvC!Lv(n$Hydc^d%@^Z?Q?AbqX0yAQH=Ku&uR?yZ4+2k zIA7-ET*$^&vzK%20q-xakkfb}W?BtS{@{NaZE>)AVMJyDdv6 z%ARcYgdjoGgt9J=NwtvX#$IPsQA_-&Rm_Ht%xAJ=hG8kVw$LbnhirK1vImRkfp+yk6k-B_LJ+z%%^egn%bcGo z81-S#4tCyHdL!Q1FvN(sKM=8OxV_5rF%6%(nAOnVe?4ah#Gr`1rpqAf`ht4R1225x z!37);CzS+-{^DvMg6!+WA)dzR>*OuUgEz=wXiPQI=~)SesiFB|pM)h?_p_+&Rc8qW zL0<3syIb>mjnrM;pz?^&pll)IMbKP1ok$}8n%mGy2z^7zm`oQEL70vHwiiiulB~ST zX;}t)`9-)f%eHx&_bUHR9wjbmji(vj4-9RJvr4X&u1ix1IK@(w5AHs1b1SjK{k)jO zQQDyDdytgEs;mS2&kLJ}hiaFz8MD{|s3S=R81)Su`?WdWIy~v$OJi|*L;6OD6|&xF z+Zx903-3FbwTY%0_#*Mmfs5)k(ia0x70|4`H{^UxZp3(aGnpU1`Z`M~rBR#7Qu!Iv zcDm0NvXkc(`&|zF1L@tZ!P>gWsnk*^AN(>vm+1%~j|PtYRo`=pb^o7MoTh{&6VPW1 z4f5$R*%WV-U8^>?rGdbhtUm;-1kx z*>4}S6twt)eT;GJMQ-PI9v)Aiw}FD{1f#b9J{P-JE&8M(#NiI~2c&`N8T`j<*J#=| zC%8%InVTmLUI-Vz1bmbr@}BrhcqN)p6zmh5IH2#!0tXjZi=K5w*7Sj`yAbvmr z&;^4BzzqU*Qk|%Up)lu3d^p(Vnq;=V0)-TmYZg_4ZfYUS`HqN}m6bIhK6Qg$m3{UA z%W`Zsa1^00*5xN4xx$DiU;N-r-j`;f_?xWdZ#G(H1ii2OeSgEppWZ5sBU5F;Q3{}CpDkJs|r z!R*AQb6M)Cs7hwyxem(8{>tB_QrAKch5)!yq7jydN*Dn!q7rj_=oAv72v=7g{GQ0m z#qZaC+39%f`On#4%w!TEjGZNfT;bqBT>~f@5}PWK5JtvbB6y#KLIAlWghBvO9&fxR zIwGl{?9&O)V{mCq@V+P>@V?p&b={}-R^X+|Eio~>30M1=^MB)agn*!pWy585DwX44 zgr6xxC)HrjuaRO_I`4prU!Y(*pVPFd$&RE^LbY2W7JnAtGYoPx&|IO@CU-dfY21= zI0~8>N=N9quhu-A`hUs|7^e4QL)$!~>fBHNCM7Tb5G0^Ike=k^aQ|0PV8-PGr@ zfd#*9%c~eF?rmnbOI^glD?dP{?CU&7T$y1}wH@EeC^JvN#=CCk3E=l2B+1i8wquJ& z=>Yiu9tNi9PdarJC8NeTR&3-ouSFon8BCE~8{hPQh+;r;6EE4A1mgBKW4Ak?(d~t% z0KD<~cul`h+pxA+AH2018LiGzIL&j7>LjBI2|pPnpo-{d0m5M&(g8GnfX@QL6D@qi z!}t_q4m5=LHL?%y{6|@Uj)%!xPd1H}ep;TskbBSg>)0l6YYDO(zN%DNi0C1 zFpT0cGX4(e`2?aokbkK;?$-ST-H*%0>E=zMv*}c?fEn}g>Ctt#sJ@;c3QM{8L2lr( zWmODcZf0sgkXLtX1CbT~`FhO()lfj%1mRz`{I6BN>)$n|FEEGZRO+WOIt7meM)pD}?=#w+uNZuslfnZ%-sV1V;KZlOs=$Sqm{%$DTe zK8849B2EQYU?H6;oGFN;5+Uca_;V3g3q7IE`KIi(#KD+Ibe}t~IvjoT3lYE` zaU~n#pR4Y}7a@D_{ja>>zv6)rw6Crq&qoT37lU88aK$Qc@Cbgi7fYK1j)MZEpiWn&R$x81+i(YKD z+A{ON8eJApx^A$tixGj4N*u)S}x6%M;E6;L-|&8bdbpMDb=o?R>vnkvE!s!*$Y|1^N3O z4-?`eg57P_jKn8j6dvC)Aj3ty!Rdyk_V`FBjhHdv;NL>*w1mOJH8Oe;5Ie${8#Cfg?vQ=}PSF z`j3Wyf~WrUE$F>wNa@H!Gc3}xrtwSmOJ#tDruY%5z?HRMV(wvk_u?24Y7)QGPL>y% znfqu`7Jj|Xy15`?UDD%lWU~685BV5)4X+&gDkG^&MJqEa+dJDvX#_)IrKmu06i`&UA5)!9OIg7A?_q z%m{{dB?(HUN|IKmvAetbL@Do8;g>NGbp>IqIQ((g^=C2uwndC)Z(E1_%0kh~u)Ji? z!mF1r&s?zDl0);V#)>uY&3Ujsg}d`q(#fcDmahbD>`OG0gle#|JB;{$J;swPL_+3S zq=5Tc4)I%EA%9ZaD+tYgy+?B;^iCVI?M6xwf)kkWX`kch_W($pK56p~*;H~bu#$)$ zt$GOBd^xj7YZCI%SS>#DqVCa>dzS;eL4Z$+s!HN+L9SZ-3LTCTN%-Bs%AR3W{w~JPmZ~gkl zY#U2g>FjagHj9>bIEl}?=`b>6cF14bHM$U!wBgZC#dvY1_ocj+cccbJR9NBDYG?4y zfBnUEy9#m3UzhEEOu|ihSdKkkLwTn=^{C<>J4(mq5lpOdVR3T~?f28CPTlRv-|RgN z9e}8rpaQ+iyuMk8dkp$#ywSsQtciVCIS)=-VYtG5@T5h^C0$UmYseyjs2(!)ya;&kfG}qJxYlIMNgX{S}+q; z*yotR}G07G)QmPA{n)SL4#G55CLJC=3SCPvh9Nk*pYp zJj_N}%M|3AN1C>Bzh?Mw+58wsJ3pRZmlhCKSo)8{Cy^$PrwUG$ht6bnkV=C(aOily z*bc!T1^VCmTzf$8I)~cE&*dbcp4H`}P1Fr6@sDA7 zQIiji?x7F;VGKPL-n7u{=BLl))Qz{?IuDd)v_J4Jg%%`TW9d+b&yJ+esXpwC3CFev zS!B2L3rH$1JW0ua@?LGm;~R5BkW>DM8(-4TGSVV*a?#vf#b`|S z$=aoB8DEUGOa+tqsga=>`G+(!r=tV?JgkJ8^uBqO=D+KD6(`HQ_)w-4b@JC2@1^ax zti9h0{e;L|TEojbzE1noE88m;Fqnx{dGKQiJo6(X1FzgB0Su6Q3o0%o$~Nf%;LMueYREf9N9PKWi-NfXzO1o(0wH zu|AxM>hBAcj_SJ{wl2p19Cn#7uO8LkW_H-SvA*6c_lLljg>y2YmtXS#1fc-f2%)=@ zT+G-~6>f+n`H-wE+5Xs(Beul*op5|**)H(u(1#oCFCC6wQhpYuq+NRPiWyg1>D7Zu zp&f&EelD7p;%1a2R(Cfm219_By=553+W=E~-~ma+r62gWcD8i8k#UV`3b+~f+94>5 zGDYNAt3k^6Fsa2G=O_)vh&W9_N@^E0=TX;=F{7GiWwytkJjM)a##e1{<)FRvR6i6N zZ!L|4GA=HzEddt!rkY$f=H>#Tq0u61qNh$R?SC)+y!&cl`f83hH=x0j`;)Lkzb_~;&NKW9m_`Fv4>{F&zR z@`s6|^>z}gh3w?z<%KEfazis=^|F53Y~b9x=yAJY>OHOPQ_py~DYs<2_LA)S)vL61 z|7@>N=TdiKdpRx_?Qk@_qEg-Xud9oCse`igwB}*W*BcZS6)j5rxZ_0@_w_g$X3 z8TMHWEW%so^mKDom}FVO!MMCUMUkaf$;o2hjmEXiK=@9mk#1zxRSbERl5nteSmy~+ zfORK_zl)5VT$#lCgozA*CVQ!oi!co+-DzuBl2Je4&j5nKpZ)Obp>)C>hJ=>{@z^Y0 ztwaviYsP-#!Y8zP6&?!<3uTE@CiywX>Dk%M4!rw#ss_iU`{}vuwOZnu_1!;jVGQNT zk1}JTNf$0$(5{L>L1Em)Hrtz{* z5LQ4e0a_Cit_4^P`;DF*y+wP+&^a33{o<;gfx$ldRZdP$fzMzaN`3dv8W(7?Pcff% zQDpR2M+9A?+&TVcs*UFHFZZM7mKG9O^HEG?l|663?V59zyaxLE%1hDF#E^(@&N_J0 zU0+|nfwrYWUB<%aK+|l_*U{dP$B#{XLc+qXM6NySlwZ2-DsZ`as?PuvAN2#S6bhyK z&h@Y=!R!6i-U^A?L1E+Xb$Z+K7a4zMcGzcQ^%bH@ebN$7&Nnq0`8w|WA|pe(i)7$Z zl6$stc)Aj$MckjwDk>`7?0+UrRDSs2e>i+}a_&Wb{*f+H^K~iZ8nLD;#|;cZtw#?l zy7cw-hBr-BS5$brJeel-w0hGk#e{@}ERR)x{7B=h5=|#<+fAqlOgC_Fl93OO0teLH#dL3=yAT!;^hVi6yn-2$9+4;9<}mSC{O@)=Toj$ z=N*57H#lvqtc1TCiRR?w#3STTv42-VeZG!0W`?#h`%5qZAxw(M0PtN&% zHf|S}{DVmNe{C1;=GiRjI^Yrvg7<23)w^Z0-gwytu@YjV5M7i5PX&v~4 zp_LUAt!SlJR;Akc>bj7jiAjt|6DGxH&&wxHoX~sQ^l`@M#ECmSq@Kx)>mP>?HBFCr z(d<*s?@T8E#!*8+D1HhQnmsN2@b&mO(*67QwHYIqW{vdpdW8+NwY3`-ZZ0Y}1$8{2 znI5(~B@kdOAmlxMDl;u@fB#R!>cNPEXF5Dua&Kem$8pm+H>LVj(X=m@l1LEZ`^?F~ z#0pfk&6#$lCF%kOyEb0iAyz9}U0yCF@n@ucb|*E`l6tD=WNy+OADrzE4|%DKo8m#8 z1+DPi60v+{f$iw@c?*|WN=2m&v7+2RGdi_Fh_QC<+Su>U)yq5*+MYSPV4+m*NWC)S zeAruGM`uq+NJzkZjCQ_Ag4mbwq|{U=&MMVs>B-3lH(Y96>WH#R(N8uw>=W{R=~Y_V z#~b%k>&Mg-?W_iz0w0GBxx8HZq?)3aWs<9DXz`gptcq)9kytOXGTTQ3ZsqGe3)3=n zL7*hVwB$vv#phCtdk{)>>o`W=NBS&D?cG~^=&96&B`HP4i(4frM?{`^mD)KvI%*8e zRt)i$%2roZ`9=zs*^3JmG1jeHXR*9E7qpo;QN+gXNlZ#otGJ?PZJju{cq2n84g;Q; zJAzBE@JnhFSKgSU5Z=yLD`<{V__T;);6v25neGO2R#(2uWH-f%Z!G&!M?U0F8)r_E zUb=8Em}qMHThm@UGxU01(>?If!Sk44%79buDf$$SB*MoSRD~^zc=qumG{HKOWVQ@3(O1>X#!q zC^St=r75gF<_72rdqG#s_`D2S@O|s^k{$ia2BY0`Y?Rj~Mo&Yi016(Eh^D+=$8Kb%WL+O20VO2o4QLM1ZTbh)doVjC% zQ_iJI5+1w%Tsozo&GGBoQCbyo2(G_Oub-K~3nc#fBgM4U=;f#F1bH^zcOM?CXj7>_ zZy&@6{@hjaQbSX#0yLv!FR=d!k6FTmM1xV6%AYimJNZ!&ug<5W6UYAmt&jQ)L{@%J zu(tJQ5Q)mKpB<%{b-*Ja^bZcDXXl=}^mCWt^g==b{47x_ZE|6$lBjTv^c+@}W-hWH zK|i^Sp|fgJ)t`Mz$q}J6JK}Up_whgizCZV|NQyqetpcEW9Zg~-j&1BG68{y z{Lo~Q$1LKiFMKJvL?Q{}WaHe%F_if83LusENfje)?Z=DlMN3g}g)s{8h+@soZ-4pX z#c8mdLzyHnqM3vF+H#oLt+`G%b@Pj$i%*6#_<*v#F4{ZNPgme?!j6Nle{si#U6h*Z zoSPmSFHeNUPj-!)DG=aXUE6slrIh5PBx(OljYCbdio@OhgDpn4R2v@<*|6ec3IOAu ze#WUfVE%zM_zw`H4xoNO z+xd{@s~(e4;S75m@Xz4rdLjB&8PBoE6cUaoGXDJZi*F5C=V0Q1i#kbKS6+h#t~*{j zxIM~4$(G9oBBc0rj(Wo{+WqMYR~tHL?RN3wdtdhS8JMljh3+QG{vKoD)`!>Uu(lqK zf8PGe5Z1P~ej3lD%u3hK!B#*7;-TXW zfB6=E2|x+Ue-QU+OHrpJTrd3JSJu>o5qY+i-7Tk05h@Rb?PG9K&!%{Ku5tlpq9=v;ZlK5pGMDkix%6!PD9y2aZ&T^bxFXmu)?<`YuI;Pi$ z=3yVy50CSGe0+Lu7A-`>bgOo1#=BQWDHKV=SRvuc7l^-BzU>?_0G4Npg(y1BRcr9==|Vt(qV7hroD{PnqlJ$7eolJf#92*FY6oJd)hTZ42_MST>?#e zqTmp*0wT>=gAHe5of0BY{8FLY1qg<`&ZZ42j^zu3#@uX!d3yfZNIO+tE3 zSisWx5JPZuFG0}|*bKu8i?V>7m3eN_Sur&OLC_(p;+IS&6CV@F4xAn}|Ety93`A?R{p`Yng7%^o3Pq)_k~*4=+4$>qhAof${ag83GJTxT zr8p~&t=Zc`{K=npPn5aum6J0>e^>;TFpo6)lAq<}LwXbMdwH}U=mV%>2_)1TI);Wq z#04o%Nzd{~B^gm+9VCdkLg0~7p(n4|>|s?ccI=ojMiw0k?u@Kw?W3W%?-ekEvJ$Ne z2nbM6qOh^CW#Eet$cKhq{E8)EheO=J`3E%vzC6aF;^M(joK;+d+L`6$W=H1MiTUt&a0ZMU%k%T&Cp83%6^k%VR z^R5~87lz7D%(+dx`GcdJ@GH{o zy0OPj{?<=hixdEu=RM#Wq7XnI;>CgDF?z<8@XFd-@3^q!;exr;2OQ3+&P?CXu!{J3 zmDe{0LZc7sra&Wfue7SHEGa1|5JgY|>CW-vd@jA4T>2xf>=;guCn^I@H*;51SL;#cV#^%!I&`$PWAfYf)Z$>PW|`vbg6gfl zZF|o#`OVx`Rh5-Ge7={Zgn>B%QR<$bz%>tZ+O_*m` zup(s{IOMzlRtp+Ha7c(q`g_$w1~gh$pHi7`i2d*`KmL0k@W%b<=!4m-CE=*f#>^W8WfsGFg(nGTm<|RX;qao-YPOjKo63$j=iGArMX+%);j5I}=8YLLDInm0cDbY`So%GrZ^u45l$#S4??s_A;-V;2=2vu2p~ z(aS_7Bv`h^IL@sZzybjyyh_3xvQ(|tnXZ$PkDj0T<;!m-oCPBdQ;1f8G>{m;2$gn$ zJ8^!7L8#dP-(u5Mk0-}w&No;L(xDt{T9SS8azh1r;M`=wJaRKKvWrm&OIrG#%-~X_YQ0R^y$1>Kv+E~acGk9=O2O5_$L+s z>sy8w^Y3`wur9uFjDqDv8l!EqP43TP(%s(~@;T4V4ypR+M@PgQNwM zSodPp$7hd4s2yqod{=3D_=CD}Cjzdj^s>6j%g>UxwN2$eVa5dIPswWZ7L1q!?WNFe z|M5*%LGgoF2;=nopW}6A^aa-)^T(-smOfc`?W>i2a#mc(9tV-M*6z?U^_G|Ppl58*J!;w0>wH+`^Xj`N>N!isapx``Yg~dLzMXGN z^jY40k%sa+Xgi2+@Yunk;Hv!2+nP*%trs?PWT@$ zFpGimBA{IJb$wZ0ozMjaXw0ywzR1{@Ypvn5khW~d%t_mKKtymKfc-yBvj#-=SE$lA@LF8cIgE% za+cIL0mI#{>@(?C)6$xL>>RyiJN5=kB$v zM6cw98b5+{<$E=r#i2tGd5yR30$Bo<2HjhGm)lj?&M5@d(!oza_`u-BzA?I!^dN|tad@lKS$MUKd!W#zHOq! z`T%al*gle#pYb}n+>mSDLoIwltBHNJqwg(?e>aj{2Hb4X$F$q-lKKjM4@FN_SxpC! zO%<&9_Q!{JOuJ8}{o!mq+Wufh&$uy3fww2F6+EVLzi&ve`t%p?SEFyr-&;ne(oKc_ zjl!hEX}#C)+~r@q8Ec^!xsB$Q{(w1iH+taTG#B;44c4aWb(0?Yr3n$^qEYk!s-A#8 z4N{O%n|4Y4$=IqSw3?q^b*gHdIU{Ba*mqVP{)+cE2;4pn)+$H={t4#7>k|ixI*X4g zKdZ9Iv)5#*i3%_5bw0}3(C0stn!Ld|%bqxB09`oTZTmKRV&Hy+eOPs=3VV^%+)w38 z$~SYrOTCuA;W_`{%1^S`^Lp;*`ob5jIDFyTxhJI7B{zIG|3KH|`496Cyvy!QN76qo zoBzX=Z#Bs#kK`qf-v;g|5-VrS|3ON(eZ6y0;&I6z)_L<5&p*1d`+xJ1x;|7^vgGCu zBK7^r1QtbG@&%%FS<#aB_#eJb*ja`7qqMJlN1A`|dei^ydHa8RqcY1?^IyWs3g88P zmG($*2YA}5s;beiUg?9=dbLSJrBazNPjkdmTXBN`$)>|L>N6VpgTDTh1lGvv`NMdB zhH)H}N!c>DpkFg+ zP)t(JpN|6cl3%+v3eGrzl|5g~{rqwTa2Evh+AW+E!Hm;%8M(2sF+1?fxsjm4Z2D{n zCs>>v78VQ$e#FUX{dg|enQbshla`J~T@?tKSjx+nx*3u0Ak9-6OhWYoQe!m$C7SF^ zcp90_z=t@VJsmAsB=IspNL5CYRw#_s^N4aAfIBR#3`~mh+zc~2caBB)$Fjd9 zaV0nB71cAaLZCqmaH1LB*D0<^B{oUDm-1t0*}Dtf(4(W|qq&k}tb9q7G_>GlIsQOK~j*I@`=UP|xREnwnmNW3?FKmt=PMKc{TtUma3mjFqN>0YLZ2#H0)T z`xu-K&}lejYZ_T8DXxy=WXT<|aqu#nOWAoEsI4%;{@Aq`6ciA1!<9LgP{u;cdh_w~7=*yN2hFyi94>-`1Ne%smtz|q`H?<6@b2xAm-?j;Ab zHVAjxj*)=O$(f9koFfFc0tIbNQ`2_Lf#95^W@cKuySuZdN76DfVnOTbUF?lQQE!ID z8xtb~Ryh=x^ZZ*4sfSWhKkhR(`G;*&kBuZIrsSe9PEb_S&>-L3e=if9EQkkcgNrTb z3{=!Qu0vj}$#Zwb#`~~<k66jTe4s_Xr%pFS0Sy18*zn#7c@2dDeVLt3cYWVzZ zsED%9y!no&HPG7|1sbUw(0I#jP+4Fn(lRsSYHDhhj^=vnszYI0)6${=lo7oaba=(%e9=a+B>L zb_oUne7pGxiYmg2Ac4hOr>GbQ@#g_lF}pr>9zqMnSX^$ySn>kmZye*F?{&f5W?!Bh zi(isQc*H;bKnU>&Cf>v(1+@_odk6-RlY}ZZ7DTsRg5y_6X6`_(uEJkZ3r8)2>8Y)& zD+dw36>by}d-FhREJ$QRxL!0IhQ`TpQCS}~>m*0!7$NrY{TvY%249MQ5c<%>}R+L$rg2qilAnYWA&0PIwq$W=gyb;_z?xn{fyjV4r~Px5A5$%1VHK zN;rXc;1+HC^doEh+XVr`vzMo%JUM(UG#=+1F`fYhq#gVXT#CGQu8k1W)le+niFsU> z`>(?V(}^l|U*p2x3I_*sgS}AP!K{*6unC8@RAIKZIydI~XJvR^zjm$bgH9U*Ca>FS zR|omjH!J`&S8}57-`7BWczdQER~*fl3shr#Ja}@mkNx2YAGg|BqF3WoF^3~z-2mc%3C6|3%PUjpw|v>MF0_wgAf>m&-6}ZCWKn3JeqYk<3xtjySbDH^ z)hzt^qo)k?^*gM~dl{g=`ug0LF8&5eu>2u{Qv|IRm*oq=amD_7ZNtotjqR*FNWMoLBaoN7rYa@}KV z>+7BQ)5{lsLxVWC0ku*`yY@(Lh=1ssaXD=P9giC_w2(~Zl)?Kz%qzX@{{1(}m}M~`lX(bi*h zl}>owiH&s&QeXSGKczV7!ND+*(;DxFNLMnAoH*+p$Fc-b6S_<5II`dJL>9XImodD#Z61XZeBT2_{h zVb5occ?|7k3qptJObK>|vL_~j^k`jSBF+gf&HpQ-ammS)UkRv zh-6J`f4!*N7rg@p)ZC{|YVsLe)jEH+!`S9li@BRmipPgI+6`8++#aA*PpE0!hQy6S1%uKHA(VU=cSgzmDLCITT)^w57H4^ zqd1^rpze^pWw74wD0#CUVp#%9b-4#WNYi_R6yv;c=rytrx8ovt(w@494=IlX_0wdxa4=R8;VL2)!jV?iwW3{=htFW=j4KsWExDe%bYMDZ3mXob!?!K%g2yi z401|ac7U$`&`CX?j$gZtFhpbl#~emgZca`a{G7JqALx$j_;6%H#LE(K2n{c$i8f)( zjw$32ok^(Tk`!5gG+uGWOA+Y@gKWIY&&dbUD5=drs0s@Pgx;i=WEJSOm zh|{=*y5J9{q*U|q<3=OWWb{C8nP0wKC>(+N78j*}RpbWbNf2-9E~vg5 z#%9z{u&szi3E%Jt!RRQWN(GP!V=}=4%?~CVWy)p&YoXmaf_9BE-Z+{~cmN_Tm`o3P z=Cvq4wn>VEdo-_~q@!aAO8NK6H`+0C%V}dqT7BCQLl)qajCdTNtQ&I%OlUPKU|J}n znu+b1g}uFIjYZF7SFg4}jgjG5m8iFwx#JYcu(hS-KI3xclP6JxPuec}OfaD{*s^1X zjY($9R^6hqSZ=4MpVhNx&j`5y@jPOWWy%k4KK({Jg%8sGyj1Z;q6Kg1f?S`GwrumI z;r$B5m+qniGu7NVg30mlDP#G5cG_6^P{^y3ngpsIw12v%d|-8dhkTngc#gi==S}9Z z9_h((BbmFW_jJfLmu%pTXc;O-qE_j?)QLn_e#gd073!a*xi_6JYA+xuY8>6%Qiaa} zg&HQBi4;(5gWIx=K3hmsBgCcycWKoK*q+Sy(>ac($ZnV{BucK*7ENGAz)eaJ@x2a* zYCYCG`Eny@e*(UKzhYh3E0@falr0aZj=|J0J39qgr|&s>Aiv(GxVStDhQ@&SM-2aj z0z)2ru)An100kifLkktKpS_S<4#PfIL|bkT!B7-ntNXux_URj-%Fx!h^xR3`lQ;ord%-PvjuZI&f&Iz=>O@^wA;#T2m=3 zEZjvRtqv4)j+mj4N3OC!4i!=J^Ygp!QH!Fni^{LQVct=|`;6cL@m(8%G?J&%Zmh3!Aw)rK)I zM4(R$kRjrjb=}ql7f2*FxZbI1Xv9L1FGg>R%4=H?F?mhU%x^>l^0NJ8VFzsk0i$C` zOFC`qtE)Fr3rFKH?t1S*MMcFO%<7cJ9aUvDA-1_}rogtxOF#BZ{Y_wrPrfV;eUU7Zf*KugWh(uV<<;qAul;EK&3I{_%iWm%r8H}p- z(|bk&Trt#3FhD-}vs958K;_>*%u|6^6y7225CsB;r9de;c=gaYThQe|#ht=pnP$Iu dL2jO+2fiQkS+v@ +#include "btstack.h" +#include "pico/cyw43_arch.h" +#include "pico/btstack_cyw43.h" +#include "pico/stdlib.h" +#include "doorbell.h" // generated by pico_btstack_make_gatt_header in CMakeLists.txt +#include "hardware/gpio.h" + + +#define HEARTBEAT_PERIOD_MS 1000 +#define APP_AD_FLAGS 0x06 + +#define BUTTON_IRQ_DEBOUNCE_MS 500 +#define BUTTON_GPIO_NUM 15 + +// initialise time for button debouncing +static int last_time = 0; + +static uint8_t adv_data[] = { + // Flags general discoverable + 0x02, BLUETOOTH_DATA_TYPE_FLAGS, APP_AD_FLAGS, + // Name + 0x17, BLUETOOTH_DATA_TYPE_COMPLETE_LOCAL_NAME, 'P', 'i', 'c', 'o', ' ', '0', '0', ':', '0', '0', ':', '0', '0', ':', '0', '0', ':', '0', '0', ':', '0', '0', + 0x03, BLUETOOTH_DATA_TYPE_COMPLETE_LIST_OF_16_BIT_SERVICE_CLASS_UUIDS, 0x3b, 0x18, +}; + +static const uint8_t adv_data_len = sizeof(adv_data); + +static int le_notification_enabled; +static hci_con_handle_t con_handle; +static uint16_t current_state; +extern uint8_t const profile_data[]; + +static btstack_timer_source_t heartbeat; +static btstack_packet_callback_registration_t hci_event_callback_registration; + +static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size) { + UNUSED(size); + UNUSED(channel); + bd_addr_t local_addr; + if (packet_type != HCI_EVENT_PACKET) return; + + uint8_t event_type = hci_event_packet_get_type(packet); + switch(event_type){ + case BTSTACK_EVENT_STATE: + if (btstack_event_state_get_state(packet) != HCI_STATE_WORKING) return; + gap_local_bd_addr(local_addr); + printf("BTstack up and running on %s.\n", bd_addr_to_str(local_addr)); + + // setup advertisements + uint16_t adv_int_min = 800; + uint16_t adv_int_max = 800; + uint8_t adv_type = 0; + bd_addr_t null_addr; + memset(null_addr, 0, 6); + gap_advertisements_set_params(adv_int_min, adv_int_max, adv_type, 0, null_addr, 0x07, 0x00); + assert(adv_data_len <= 31); // ble limitation + gap_advertisements_set_data(adv_data_len, (uint8_t*) adv_data); + gap_advertisements_enable(1); + + + break; + case HCI_EVENT_DISCONNECTION_COMPLETE: + le_notification_enabled = 0; + break; + case ATT_EVENT_CAN_SEND_NOW: + att_server_notify(con_handle, ATT_CHARACTERISTIC_ORG_BLUETOOTH_CHARACTERISTIC_DIGITAL_OUTPUT_01_VALUE_HANDLE, (uint8_t*)¤t_state, sizeof(current_state)); + break; + default: + break; + } +} + +static uint16_t att_read_callback(hci_con_handle_t connection_handle, uint16_t att_handle, uint16_t offset, uint8_t * buffer, uint16_t buffer_size) { + UNUSED(connection_handle); + + if (att_handle == ATT_CHARACTERISTIC_ORG_BLUETOOTH_CHARACTERISTIC_DIGITAL_OUTPUT_01_VALUE_HANDLE){ + return att_read_callback_handle_blob((const uint8_t *)¤t_state, sizeof(current_state), offset, buffer, buffer_size); + } + return 0; +} + +static int att_write_callback(hci_con_handle_t connection_handle, uint16_t att_handle, uint16_t transaction_mode, uint16_t offset, uint8_t *buffer, uint16_t buffer_size) { + UNUSED(transaction_mode); + UNUSED(offset); + UNUSED(buffer_size); + + if (att_handle != ATT_CHARACTERISTIC_ORG_BLUETOOTH_CHARACTERISTIC_DIGITAL_OUTPUT_01_CLIENT_CONFIGURATION_HANDLE) return 0; + le_notification_enabled = little_endian_read_16(buffer, 0) == GATT_CLIENT_CHARACTERISTICS_CONFIGURATION_NOTIFICATION; + con_handle = connection_handle; + if (le_notification_enabled) { + att_server_request_can_send_now_event(con_handle); + } + return 0; +} + + +static void button_irq_handler(uint gpio, uint32_t events) { + // button debounce handling - ignore any additional presses for BUTTON_IRQ_DEBOUNCE_MS after first press + int time_now = to_ms_since_boot(get_absolute_time()); + if ((time_now - last_time) > BUTTON_IRQ_DEBOUNCE_MS && le_notification_enabled) { + last_time = time_now; + att_server_request_can_send_now_event(con_handle); + } +} + + +static void heartbeat_handler(struct btstack_timer_source *ts) { + static uint32_t counter = 0; + counter++; + + // Invert the led + static int led_on = true; + led_on = !led_on; + cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, led_on); + + // Restart timer + btstack_run_loop_set_timer(ts, HEARTBEAT_PERIOD_MS); + btstack_run_loop_add_timer(ts); +} + +int main() { + stdio_init_all(); + + gpio_init(BUTTON_GPIO_NUM); + gpio_set_dir(BUTTON_GPIO_NUM, GPIO_IN); + gpio_pull_up(BUTTON_GPIO_NUM); + gpio_set_irq_enabled_with_callback(BUTTON_GPIO_NUM, GPIO_IRQ_EDGE_FALL, true, &button_irq_handler); + + // initialize CYW43 driver architecture (will enable BT if/because CYW43_ENABLE_BLUETOOTH == 1) + if (cyw43_arch_init()) { + printf("failed to initialise cyw43_arch\n"); + return -1; + } + + l2cap_init(); + sm_init(); + + att_server_init(profile_data, att_read_callback, att_write_callback); + + // inform about BTstack state + hci_event_callback_registration.callback = &packet_handler; + hci_add_event_handler(&hci_event_callback_registration); + + // register for ATT event + att_server_register_packet_handler(packet_handler); + + // set one-shot btstack timer + heartbeat.process = &heartbeat_handler; + btstack_run_loop_set_timer(&heartbeat, HEARTBEAT_PERIOD_MS); + btstack_run_loop_add_timer(&heartbeat); + + // turn on bluetooth! + hci_power_control(HCI_POWER_ON); + + // btstack_run_loop_execute is only required when using the 'polling' method (e.g. using pico_cyw43_arch_poll library). + // This example uses the 'threadsafe background` method, where BT work is handled in a low priority IRQ, so it + // is fine to call bt_stack_run_loop_execute() but equally you can continue executing user code. + +#if 0 // btstack_run_loop_execute() is not required, so lets not use it + btstack_run_loop_execute(); +#else + // this core is free to do it's own stuff except when using 'polling' method (in which case you should use + // btstacK_run_loop_ methods to add work to the run loop. + + // this is a forever loop in place of where user code would go. + while(true) { + sleep_ms(1000); + } +#endif + return 0; +} diff --git a/pico_w/bt/standalone/secure_temp_sensor/CMakeLists.txt b/pico_w/bt/standalone/secure_temp_sensor/CMakeLists.txt new file mode 100644 index 000000000..5f62c4745 --- /dev/null +++ b/pico_w/bt/standalone/secure_temp_sensor/CMakeLists.txt @@ -0,0 +1,42 @@ +# Standalone example that reads from the on board temperature sensor and sends notifications via BLE +# Flashes slowly each second to show it's running +add_executable(secure_temp_sensor + server.c + ) +target_link_libraries(secure_temp_sensor + pico_stdlib + pico_btstack_ble + pico_btstack_cyw43 + pico_cyw43_arch_none + hardware_adc + ) +target_include_directories(secure_temp_sensor PRIVATE + ${CMAKE_CURRENT_LIST_DIR} + ${CMAKE_CURRENT_LIST_DIR}/.. # For our common btstack config + ) +pico_btstack_make_gatt_header(secure_temp_sensor PRIVATE "${CMAKE_CURRENT_LIST_DIR}/temp_sensor.gatt") + +pico_add_extra_outputs(secure_temp_sensor) + +# Standalone example that connects to secure_temp_sensor and reads the temperature +# Flahes once quickly each second when it's running but not connected to another device +# Flashes twice quickly each second when connected to another device and reading it's temperature +add_executable(secure_temp_reader + client.c + ) +target_link_libraries(secure_temp_reader + pico_stdlib + pico_btstack_ble + pico_btstack_cyw43 + pico_cyw43_arch_none + hardware_adc + ) +target_include_directories(secure_temp_reader PRIVATE + ${CMAKE_CURRENT_LIST_DIR} + ${CMAKE_CURRENT_LIST_DIR}/.. # For our common btstack config + ) +target_compile_definitions(secure_temp_reader PRIVATE + RUNNING_AS_CLIENT=1 +) + +pico_add_extra_outputs(secure_temp_reader) \ No newline at end of file diff --git a/pico_w/bt/standalone/secure_temp_sensor/README.md b/pico_w/bt/standalone/secure_temp_sensor/README.md new file mode 100644 index 000000000..a2c13f59c --- /dev/null +++ b/pico_w/bt/standalone/secure_temp_sensor/README.md @@ -0,0 +1,10 @@ +### Secure temp sensor + +This example uses BLE to communicate temperature between a pair of pico Ws. This example is a variant of temp sensor, using LE secure to provide a secure connection. + +In server.c and client.c there is a variable security_setting which you can change to explore different security options: + +Security setting 0: Just works (pairing), no MITM protection +Security setting 1: Numeric comparison +Security setting 2: Peripheral displays passkey, client enters passkey +Security setting 3: Client displays passkey, peripheral enters passkey \ No newline at end of file diff --git a/pico_w/bt/standalone/secure_temp_sensor/btstack_config.h b/pico_w/bt/standalone/secure_temp_sensor/btstack_config.h new file mode 100644 index 000000000..b628edf30 --- /dev/null +++ b/pico_w/bt/standalone/secure_temp_sensor/btstack_config.h @@ -0,0 +1,9 @@ +#ifndef _PICO_BTSTACK_CONFIG_H +#define _PICO_BTSTACK_CONFIG_H + +#include "btstack_config_common.h" + +// security +#define ENABLE_LE_SECURE_CONNECTIONS + +#endif diff --git a/pico_w/bt/standalone/secure_temp_sensor/client.c b/pico_w/bt/standalone/secure_temp_sensor/client.c new file mode 100644 index 000000000..6f328641d --- /dev/null +++ b/pico_w/bt/standalone/secure_temp_sensor/client.c @@ -0,0 +1,464 @@ +/** + * Copyright (c) 2023 Raspberry Pi (Trading) Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include "btstack.h" +#include "pico/cyw43_arch.h" +#include "pico/stdlib.h" +#include "inttypes.h" +#include "string.h" + +#if 0 +#define DEBUG_LOG(...) printf(__VA_ARGS__) +#else +#define DEBUG_LOG(...) +#endif + +#define LED_QUICK_FLASH_DELAY_MS 100 +#define LED_SLOW_FLASH_DELAY_MS 1000 + +typedef enum { + TC_OFF, + TC_IDLE, + TC_W4_SCAN_RESULT, + TC_W4_CONNECT, + TC_W4_SERVICE_RESULT, + TC_W4_CHARACTERISTIC_RESULT, + TC_W4_ENABLE_NOTIFICATIONS_COMPLETE, + TC_W4_READY +} gc_state_t; + +static btstack_packet_callback_registration_t hci_event_callback_registration; +static btstack_packet_callback_registration_t sm_event_callback_registration; +static gc_state_t state = TC_OFF; +static bd_addr_t server_addr; +static bd_addr_type_t server_addr_type; +static hci_con_handle_t connection_handle; +static gatt_client_service_t server_service; +static gatt_client_characteristic_t server_characteristic; +static bool listener_registered; +static gatt_client_notification_t notification_listener; +static btstack_timer_source_t heartbeat; + +// Select a security setting to explore the BLE security +// security setting 0: Just works (pairing), no MITM protection +// security setting 1: Numeric comparison +// security setting 2: Peripheral displays passkey, client enters passkey +// security setting 3: Client displays passkey, peripheral enters passkey +static int security_setting = 1; + +static void configure_security(int security_setting) { + + sm_set_secure_connections_only_mode(true); + + switch (security_setting) { + case 0: + printf("Security setting 0 selected. \n"); + + sm_set_io_capabilities(IO_CAPABILITY_NO_INPUT_NO_OUTPUT); + sm_set_authentication_requirements(SM_AUTHREQ_SECURE_CONNECTION); + break; + case 1: + printf("Security setting 1 selected. \n"); + + sm_set_io_capabilities(IO_CAPABILITY_DISPLAY_YES_NO); + sm_set_authentication_requirements(SM_AUTHREQ_SECURE_CONNECTION|SM_AUTHREQ_MITM_PROTECTION); + break; + case 2: + printf("Security setting 2 selected. \n"); + + sm_set_io_capabilities(IO_CAPABILITY_KEYBOARD_ONLY); + sm_set_authentication_requirements(SM_AUTHREQ_SECURE_CONNECTION|SM_AUTHREQ_MITM_PROTECTION); + break; + case 3: + printf("Security setting 3 selected. \n"); + + sm_set_io_capabilities(IO_CAPABILITY_DISPLAY_ONLY); + sm_set_authentication_requirements(SM_AUTHREQ_SECURE_CONNECTION|SM_AUTHREQ_MITM_PROTECTION); + break; + default: + break; + } +} + +static void client_start(void){ + DEBUG_LOG("Start scanning!\n"); + state = TC_W4_SCAN_RESULT; + gap_set_scan_parameters(0,0x0030, 0x0030); + gap_start_scan(); +} + +static bool advertisement_report_contains_service(uint16_t service, uint8_t *advertisement_report){ + // get advertisement from report event + const uint8_t * adv_data = gap_event_advertising_report_get_data(advertisement_report); + uint8_t adv_len = gap_event_advertising_report_get_data_length(advertisement_report); + + // iterate over advertisement data + ad_context_t context; + for (ad_iterator_init(&context, adv_len, adv_data) ; ad_iterator_has_more(&context) ; ad_iterator_next(&context)){ + uint8_t data_type = ad_iterator_get_data_type(&context); + uint8_t data_size = ad_iterator_get_data_len(&context); + const uint8_t * data = ad_iterator_get_data(&context); + switch (data_type){ + case BLUETOOTH_DATA_TYPE_COMPLETE_LIST_OF_16_BIT_SERVICE_CLASS_UUIDS: + for (int i = 0; i < data_size; i += 2) { + uint16_t type = little_endian_read_16(data, i); + if (type == service) return true; + } + default: + break; + } + } + return false; +} + +static void handle_gatt_client_event(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size) { + UNUSED(packet_type); + UNUSED(channel); + UNUSED(size); + + uint8_t att_status; + switch(state){ + case TC_W4_SERVICE_RESULT: + switch(hci_event_packet_get_type(packet)) { + case GATT_EVENT_SERVICE_QUERY_RESULT: + // store service (we expect only one) + DEBUG_LOG("Storing service\n"); + gatt_event_service_query_result_get_service(packet, &server_service); + break; + case GATT_EVENT_QUERY_COMPLETE: + att_status = gatt_event_query_complete_get_att_status(packet); + if (att_status != ATT_ERROR_SUCCESS){ + printf("SERVICE_QUERY_RESULT, ATT Error 0x%02x.\n", att_status); + gap_disconnect(connection_handle); + break; + } + // service query complete, look for characteristic + state = TC_W4_CHARACTERISTIC_RESULT; + DEBUG_LOG("Search for env sensing characteristic.\n"); + gatt_client_discover_characteristics_for_service_by_uuid16(handle_gatt_client_event, connection_handle, &server_service, ORG_BLUETOOTH_CHARACTERISTIC_TEMPERATURE); + break; + default: + break; + } + break; + case TC_W4_CHARACTERISTIC_RESULT: + switch(hci_event_packet_get_type(packet)) { + case GATT_EVENT_CHARACTERISTIC_QUERY_RESULT: + DEBUG_LOG("Storing characteristic\n"); + gatt_event_characteristic_query_result_get_characteristic(packet, &server_characteristic); + break; + case GATT_EVENT_QUERY_COMPLETE: + att_status = gatt_event_query_complete_get_att_status(packet); + if (att_status != ATT_ERROR_SUCCESS){ + printf("CHARACTERISTIC_QUERY_RESULT, ATT Error 0x%02x.\n", att_status); + gap_disconnect(connection_handle); + break; + } + // register handler for notifications + listener_registered = true; + gatt_client_listen_for_characteristic_value_updates(¬ification_listener, handle_gatt_client_event, connection_handle, &server_characteristic); + // enable notifications + DEBUG_LOG("Enable notify on characteristic.\n"); + state = TC_W4_ENABLE_NOTIFICATIONS_COMPLETE; + gatt_client_write_client_characteristic_configuration(handle_gatt_client_event, connection_handle, + &server_characteristic, GATT_CLIENT_CHARACTERISTICS_CONFIGURATION_NOTIFICATION); + break; + default: + break; + } + break; + case TC_W4_ENABLE_NOTIFICATIONS_COMPLETE: + switch(hci_event_packet_get_type(packet)) { + case GATT_EVENT_QUERY_COMPLETE: + DEBUG_LOG("Notifications enabled, ATT status 0x%02x\n", gatt_event_query_complete_get_att_status(packet)); + if (gatt_event_query_complete_get_att_status(packet) != ATT_ERROR_SUCCESS) break; + state = TC_W4_READY; + break; + default: + break; + } + break; + case TC_W4_READY: + switch(hci_event_packet_get_type(packet)) { + case GATT_EVENT_NOTIFICATION: { + uint16_t value_length = gatt_event_notification_get_value_length(packet); + const uint8_t *value = gatt_event_notification_get_value(packet); + DEBUG_LOG("Indication value len %d\n", value_length); + if (value_length == 2) { + float temp = little_endian_read_16(value, 0); + printf("read temp %.2f degc\n", temp / 100); + } else { + printf("Unexpected length %d\n", value_length); + } + break; + } + default: + printf("Unknown packet type 0x%02x\n", hci_event_packet_get_type(packet)); + break; + } + break; + default: + printf("error\n"); + break; + } +} + +static void hci_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size) { + UNUSED(size); + UNUSED(channel); + bd_addr_t local_addr; + if (packet_type != HCI_EVENT_PACKET) return; + hci_con_handle_t con_handle; + uint8_t status; + + uint8_t event_type = hci_event_packet_get_type(packet); + switch(event_type){ + case BTSTACK_EVENT_STATE: + if (btstack_event_state_get_state(packet) == HCI_STATE_WORKING) { + gap_local_bd_addr(local_addr); + printf("BTstack up and running on %s.\n", bd_addr_to_str(local_addr)); + client_start(); + } else { + state = TC_OFF; + } + break; + case GAP_EVENT_ADVERTISING_REPORT: + if (state != TC_W4_SCAN_RESULT) return; + // check name in advertisement + if (!advertisement_report_contains_service(ORG_BLUETOOTH_SERVICE_ENVIRONMENTAL_SENSING, packet)) return; + // store address and type + gap_event_advertising_report_get_address(packet, server_addr); + server_addr_type = gap_event_advertising_report_get_address_type(packet); + // stop scanning, and connect to the device + state = TC_W4_CONNECT; + gap_stop_scan(); + printf("Connecting to device with addr %s.\n", bd_addr_to_str(server_addr)); + gap_connect(server_addr, server_addr_type); + break; + case HCI_EVENT_LE_META: + // wait for connection complete + switch (hci_event_le_meta_get_subevent_code(packet)) { + case HCI_SUBEVENT_LE_CONNECTION_COMPLETE: + if (state != TC_W4_CONNECT) return; + connection_handle = hci_subevent_le_connection_complete_get_connection_handle(packet); + // initialize gatt client context with handle, and add it to the list of active clients + // query primary services + DEBUG_LOG("Search for env sensing service.\n"); + state = TC_W4_SERVICE_RESULT; + gatt_client_discover_primary_services_by_uuid16(handle_gatt_client_event, connection_handle, ORG_BLUETOOTH_SERVICE_ENVIRONMENTAL_SENSING); + break; + default: + break; + } + break; + case HCI_EVENT_META_GAP: + // wait for connection complete + if (hci_event_gap_meta_get_subevent_code(packet) != GAP_SUBEVENT_LE_CONNECTION_COMPLETE) break; + con_handle = gap_subevent_le_connection_complete_get_connection_handle(packet); + printf("Connection complete\n"); + sm_request_pairing(con_handle); + break; + case GATT_EVENT_QUERY_COMPLETE: + status = gatt_event_query_complete_get_att_status(packet); + switch (status){ + case ATT_ERROR_INSUFFICIENT_ENCRYPTION: + printf("GATT Query result: Insufficient Encryption\n"); + break; + case ATT_ERROR_INSUFFICIENT_AUTHENTICATION: + printf("GATT Query result: Insufficient Authentication\n"); + break; + case ATT_ERROR_BONDING_INFORMATION_MISSING: + printf("GATT Query result: Bonding Information Missing\n"); + break; + case ATT_ERROR_SUCCESS: + printf("GATT Query result: OK\n"); + break; + default: + printf("GATT Query result: 0x%02x\n", gatt_event_query_complete_get_att_status(packet)); + break; + } + break; + case HCI_EVENT_DISCONNECTION_COMPLETE: + // unregister listener + connection_handle = HCI_CON_HANDLE_INVALID; + if (listener_registered){ + listener_registered = false; + gatt_client_stop_listening_for_characteristic_value_updates(¬ification_listener); + } + printf("Disconnected %s\n", bd_addr_to_str(server_addr)); + if (state == TC_OFF) break; + client_start(); + break; + default: + break; + } +} + +static void sm_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ + UNUSED(channel); + UNUSED(size); + + if (packet_type != HCI_EVENT_PACKET) return; + + bd_addr_t addr; + bd_addr_type_t addr_type; + + switch (hci_event_packet_get_type(packet)) { + case SM_EVENT_JUST_WORKS_REQUEST: + printf("Just works requested\n"); + sm_just_works_confirm(sm_event_just_works_request_get_handle(packet)); + break; + case SM_EVENT_NUMERIC_COMPARISON_REQUEST: + printf("Confirming numeric comparison: %"PRIu32"\n", sm_event_numeric_comparison_request_get_passkey(packet)); + printf("Do the numbers match? (y/n)\n"); + + char result[2]; + scanf(" %c", &result); + if (result[0] == 'y' || result[0] == 'Y') { + sm_numeric_comparison_confirm(sm_event_passkey_display_number_get_handle(packet)); + } else { + sm_bonding_decline(sm_event_passkey_display_number_get_handle(packet)); + } + break; + case SM_EVENT_PASSKEY_DISPLAY_NUMBER: + printf("Display Passkey: %"PRIu32"\n", sm_event_passkey_display_number_get_passkey(packet)); + break; + case SM_EVENT_PASSKEY_INPUT_NUMBER: + char passkey[7]; + + printf("Passkey Input requested \n"); + scanf("%6[^\n]", passkey); + int to_send = atoi(passkey); // convert passkey to int + + printf("Sending passkey %"PRIu32"\n", to_send); + sm_passkey_input(sm_event_passkey_input_number_get_handle(packet), to_send); + break; + case SM_EVENT_PAIRING_STARTED: + printf("Pairing started\n"); + break; + case SM_EVENT_PAIRING_COMPLETE: + switch (sm_event_pairing_complete_get_status(packet)){ + case ERROR_CODE_SUCCESS: + printf("Pairing complete, success\n"); + break; + case ERROR_CODE_CONNECTION_TIMEOUT: + printf("Pairing failed, timeout\n"); + break; + case ERROR_CODE_REMOTE_USER_TERMINATED_CONNECTION: + printf("Pairing failed, disconnected\n"); + break; + case ERROR_CODE_AUTHENTICATION_FAILURE: + printf("Pairing failed, authentication failure with reason = %u\n", sm_event_pairing_complete_get_reason(packet)); + break; + default: + break; + } + break; + case SM_EVENT_REENCRYPTION_STARTED: + sm_event_reencryption_complete_get_address(packet, addr); + printf("Bonding information exists for addr type %u, identity addr %s -> start re-encryption\n", + sm_event_reencryption_started_get_addr_type(packet), bd_addr_to_str(addr)); + break; + case SM_EVENT_REENCRYPTION_COMPLETE: + switch (sm_event_reencryption_complete_get_status(packet)){ + case ERROR_CODE_SUCCESS: + printf("Re-encryption complete, success\n"); + break; + case ERROR_CODE_CONNECTION_TIMEOUT: + printf("Re-encryption failed, timeout\n"); + break; + case ERROR_CODE_REMOTE_USER_TERMINATED_CONNECTION: + printf("Re-encryption failed, disconnected\n"); + break; + case ERROR_CODE_PIN_OR_KEY_MISSING: + printf("Re-encryption failed, bonding information missing\n\n"); + printf("Assuming remote lost bonding information\n"); + printf("Deleting local bonding information and start new pairing...\n"); + sm_event_reencryption_complete_get_address(packet, addr); + addr_type = sm_event_reencryption_started_get_addr_type(packet); + gap_delete_bonding(addr_type, addr); + sm_request_pairing(sm_event_reencryption_complete_get_handle(packet)); + break; + default: + break; + } + break; + default: + break; + } +} + +static void heartbeat_handler(struct btstack_timer_source *ts) { + // Invert the led + static bool quick_flash; + static bool led_on = true; + + led_on = !led_on; + cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, led_on); + if (listener_registered && led_on) { + quick_flash = !quick_flash; + } else if (!listener_registered) { + quick_flash = false; + } + + // Restart timer + btstack_run_loop_set_timer(ts, (led_on || quick_flash) ? LED_QUICK_FLASH_DELAY_MS : LED_SLOW_FLASH_DELAY_MS); + btstack_run_loop_add_timer(ts); +} + +int main() { + stdio_init_all(); + + // initialize CYW43 driver architecture (will enable BT if/because CYW43_ENABLE_BLUETOOTH == 1) + if (cyw43_arch_init()) { + printf("failed to initialise cyw43_arch\n"); + return -1; + } + + l2cap_init(); + sm_init(); + sm_set_io_capabilities(IO_CAPABILITY_NO_INPUT_NO_OUTPUT); + + // setup empty ATT server - only needed if LE Peripheral does ATT queries on its own, e.g. Android and iOS + att_server_init(NULL, NULL, NULL); + + gatt_client_init(); + + hci_event_callback_registration.callback = &hci_packet_handler; + hci_add_event_handler(&hci_event_callback_registration); + + sm_event_callback_registration.callback = &sm_packet_handler; + sm_add_event_handler(&sm_event_callback_registration); + + // apply security configuration settings + configure_security(security_setting); + + // set one-shot btstack timer + heartbeat.process = &heartbeat_handler; + btstack_run_loop_set_timer(&heartbeat, LED_SLOW_FLASH_DELAY_MS); + btstack_run_loop_add_timer(&heartbeat); + + // turn on! + hci_power_control(HCI_POWER_ON); + + // btstack_run_loop_execute is only required when using the 'polling' method (e.g. using pico_cyw43_arch_poll library). + // This example uses the 'threadsafe background` method, where BT work is handled in a low priority IRQ, so it + // is fine to call bt_stack_run_loop_execute() but equally you can continue executing user code. + +#if 1 // this is only necessary when using polling (which we aren't, but we're showing it is still safe to call in this case) + btstack_run_loop_execute(); +#else + // this core is free to do it's own stuff except when using 'polling' method (in which case you should use + // btstacK_run_loop_ methods to add work to the run loop. + + // this is a forever loop in place of where user code would go. + while(true) { + sleep_ms(1000); + } +#endif + return 0; +} \ No newline at end of file diff --git a/pico_w/bt/standalone/secure_temp_sensor/server.c b/pico_w/bt/standalone/secure_temp_sensor/server.c new file mode 100644 index 000000000..c85d1269f --- /dev/null +++ b/pico_w/bt/standalone/secure_temp_sensor/server.c @@ -0,0 +1,372 @@ +/** + * Copyright (c) 2023 Raspberry Pi (Trading) Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include "btstack.h" +#include "pico/cyw43_arch.h" +#include "pico/btstack_cyw43.h" +#include "hardware/adc.h" +#include "pico/stdlib.h" +#include "temp_sensor.h" +#include +#include + +#define HEARTBEAT_PERIOD_MS 1000 +#define ADC_CHANNEL_TEMPSENSOR 4 + +#define APP_AD_FLAGS 0x06 +static uint8_t adv_data[] = { + // Flags general discoverable + 0x02, BLUETOOTH_DATA_TYPE_FLAGS, APP_AD_FLAGS, + // Name + 0x17, BLUETOOTH_DATA_TYPE_COMPLETE_LOCAL_NAME, 'P', 'i', 'c', 'o', ' ', '0', '0', ':', '0', '0', ':', '0', '0', ':', '0', '0', ':', '0', '0', ':', '0', '0', + 0x03, BLUETOOTH_DATA_TYPE_COMPLETE_LIST_OF_16_BIT_SERVICE_CLASS_UUIDS, 0x1a, 0x18, +}; +static const uint8_t adv_data_len = sizeof(adv_data); + +int le_notification_enabled; +static hci_con_handle_t con_handle; +static uint16_t current_temp; + +extern uint8_t const profile_data[]; +static void poll_temp(void); + +static btstack_timer_source_t heartbeat; +static btstack_packet_callback_registration_t hci_event_callback_registration; +static btstack_packet_callback_registration_t sm_event_callback_registration; + +// Select a security setting to explore the BLE security +// security setting 0: Just works (pairing), no MITM protection +// security setting 1: Numeric comparison +// security setting 2: Peripheral displays passkey, client enters passkey +// security setting 3: Client displays passkey, peripheral enters passkey +static int security_setting = 1; + +static void configure_security(int security_setting) { + + sm_set_secure_connections_only_mode(true); + + switch (security_setting) { + case 0: + printf("Security setting 0 selected. \n"); + + sm_set_io_capabilities(IO_CAPABILITY_NO_INPUT_NO_OUTPUT); + sm_set_authentication_requirements(SM_AUTHREQ_SECURE_CONNECTION); + break; + case 1: + printf("Security setting 1 selected. \n"); + + sm_set_io_capabilities(IO_CAPABILITY_DISPLAY_YES_NO); + sm_set_authentication_requirements(SM_AUTHREQ_SECURE_CONNECTION|SM_AUTHREQ_MITM_PROTECTION); + break; + case 2: + printf("Security setting 2 selected. \n"); + + sm_set_io_capabilities(IO_CAPABILITY_DISPLAY_ONLY); + sm_set_authentication_requirements(SM_AUTHREQ_SECURE_CONNECTION|SM_AUTHREQ_MITM_PROTECTION); + break; + case 3: + printf("Security setting 3 selected. \n"); + + sm_set_io_capabilities(IO_CAPABILITY_KEYBOARD_ONLY); + sm_set_authentication_requirements(SM_AUTHREQ_SECURE_CONNECTION|SM_AUTHREQ_MITM_PROTECTION); + break; + default: + break; + } +} + +static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size) { + UNUSED(size); + UNUSED(channel); + bd_addr_t local_addr; + if (packet_type != HCI_EVENT_PACKET) return; + + uint8_t event_type = hci_event_packet_get_type(packet); + switch(event_type){ + case BTSTACK_EVENT_STATE: + if (btstack_event_state_get_state(packet) != HCI_STATE_WORKING) return; + gap_local_bd_addr(local_addr); + printf("BTstack up and running on %s.\n", bd_addr_to_str(local_addr)); + + // setup advertisements + uint16_t adv_int_min = 800; + uint16_t adv_int_max = 800; + uint8_t adv_type = 0; + bd_addr_t null_addr; + memset(null_addr, 0, 6); + gap_advertisements_set_params(adv_int_min, adv_int_max, adv_type, 0, null_addr, 0x07, 0x00); + assert(adv_data_len <= 31); // ble limitation + gap_advertisements_set_data(adv_data_len, (uint8_t*) adv_data); + gap_advertisements_enable(1); + + poll_temp(); + + break; + case HCI_EVENT_DISCONNECTION_COMPLETE: + le_notification_enabled = 0; + break; + case ATT_EVENT_CAN_SEND_NOW: + att_server_notify(con_handle, ATT_CHARACTERISTIC_ORG_BLUETOOTH_CHARACTERISTIC_TEMPERATURE_01_VALUE_HANDLE, (uint8_t*)¤t_temp, sizeof(current_temp)); + break; + default: + break; + } +} + +static void sm_packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ + UNUSED(channel); + UNUSED(size); + + if (packet_type != HCI_EVENT_PACKET) return; + + hci_con_handle_t con_handle; + bd_addr_t addr; + bd_addr_type_t addr_type; + uint8_t status; + + switch (hci_event_packet_get_type(packet)) { + case HCI_EVENT_META_GAP: + switch (hci_event_gap_meta_get_subevent_code(packet)) { + case GAP_SUBEVENT_LE_CONNECTION_COMPLETE: + printf("Connection complete\n"); + con_handle = gap_subevent_le_connection_complete_get_connection_handle(packet); + sm_request_pairing(con_handle); + break; + default: + break; + } + break; + case SM_EVENT_JUST_WORKS_REQUEST: + printf("Just Works requested\n"); + sm_just_works_confirm(sm_event_just_works_request_get_handle(packet)); + break; + case SM_EVENT_NUMERIC_COMPARISON_REQUEST: + printf("Confirming numeric comparison: %"PRIu32"\n", sm_event_numeric_comparison_request_get_passkey(packet)); + sm_numeric_comparison_confirm(sm_event_passkey_display_number_get_handle(packet)); + break; + case SM_EVENT_PASSKEY_DISPLAY_NUMBER: + printf("Display Passkey: %"PRIu32"\n", sm_event_passkey_display_number_get_passkey(packet)); + break; + case SM_EVENT_PASSKEY_INPUT_NUMBER: + char passkey[7]; + + printf("Passkey Input requested \n"); + scanf("%6[^\n]", passkey); + int to_send = atoi(passkey); // convert passkey to int + + printf("Sending passkey %"PRIu32"\n", to_send); + sm_passkey_input(sm_event_passkey_input_number_get_handle(packet), to_send); + break; + case SM_EVENT_IDENTITY_CREATED: + sm_event_identity_created_get_identity_address(packet, addr); + printf("Identity created: type %u address %s\n", sm_event_identity_created_get_identity_addr_type(packet), bd_addr_to_str(addr)); + break; + case SM_EVENT_IDENTITY_RESOLVING_SUCCEEDED: + sm_event_identity_resolving_succeeded_get_identity_address(packet, addr); + printf("Identity resolved: type %u address %s\n", sm_event_identity_resolving_succeeded_get_identity_addr_type(packet), bd_addr_to_str(addr)); + break; + case SM_EVENT_IDENTITY_RESOLVING_FAILED: + sm_event_identity_created_get_address(packet, addr); + printf("Identity resolving failed\n"); + break; + case SM_EVENT_PAIRING_STARTED: + printf("Pairing started\n"); + break; + case SM_EVENT_PAIRING_COMPLETE: + switch (sm_event_pairing_complete_get_status(packet)){ + case ERROR_CODE_SUCCESS: + printf("Pairing complete, success\n"); + break; + case ERROR_CODE_CONNECTION_TIMEOUT: + printf("Pairing failed, timeout\n"); + break; + case ERROR_CODE_REMOTE_USER_TERMINATED_CONNECTION: + printf("Pairing failed, disconnected\n"); + break; + case ERROR_CODE_AUTHENTICATION_FAILURE: + printf("Pairing failed, authentication failure with reason = %u\n", sm_event_pairing_complete_get_reason(packet)); + break; + default: + break; + } + break; + case SM_EVENT_REENCRYPTION_STARTED: + sm_event_reencryption_complete_get_address(packet, addr); + printf("Bonding information exists for addr type %u, identity addr %s -> re-encryption started\n", + sm_event_reencryption_started_get_addr_type(packet), bd_addr_to_str(addr)); + break; + case SM_EVENT_REENCRYPTION_COMPLETE: + switch (sm_event_reencryption_complete_get_status(packet)){ + case ERROR_CODE_SUCCESS: + printf("Re-encryption complete, success\n"); + break; + case ERROR_CODE_CONNECTION_TIMEOUT: + printf("Re-encryption failed, timeout\n"); + break; + case ERROR_CODE_REMOTE_USER_TERMINATED_CONNECTION: + printf("Re-encryption failed, disconnected\n"); + break; + case ERROR_CODE_PIN_OR_KEY_MISSING: + printf("Re-encryption failed, bonding information missing\n\n"); + printf("Assuming remote lost bonding information\n"); + printf("Deleting local bonding information to allow for new pairing...\n"); + sm_event_reencryption_complete_get_address(packet, addr); + addr_type = sm_event_reencryption_started_get_addr_type(packet); + gap_delete_bonding(addr_type, addr); + break; + default: + break; + } + break; + case GATT_EVENT_QUERY_COMPLETE: + status = gatt_event_query_complete_get_att_status(packet); + switch (status){ + case ATT_ERROR_INSUFFICIENT_ENCRYPTION: + printf("GATT Query failed, Insufficient Encryption\n"); + break; + case ATT_ERROR_INSUFFICIENT_AUTHENTICATION: + printf("GATT Query failed, Insufficient Authentication\n"); + break; + case ATT_ERROR_BONDING_INFORMATION_MISSING: + printf("GATT Query failed, Bonding Information Missing\n"); + break; + case ATT_ERROR_SUCCESS: + printf("GATT Query successful\n"); + break; + default: + printf("GATT Query failed, status 0x%02x\n", gatt_event_query_complete_get_att_status(packet)); + break; + } + break; + default: + break; + } +} + + +static uint16_t att_read_callback(hci_con_handle_t connection_handle, uint16_t att_handle, uint16_t offset, uint8_t * buffer, uint16_t buffer_size) { + UNUSED(connection_handle); + + if (att_handle == ATT_CHARACTERISTIC_ORG_BLUETOOTH_CHARACTERISTIC_TEMPERATURE_01_VALUE_HANDLE){ + return att_read_callback_handle_blob((const uint8_t *)¤t_temp, sizeof(current_temp), offset, buffer, buffer_size); + } + return 0; +} + +static int att_write_callback(hci_con_handle_t connection_handle, uint16_t att_handle, uint16_t transaction_mode, uint16_t offset, uint8_t *buffer, uint16_t buffer_size) { + UNUSED(transaction_mode); + UNUSED(offset); + UNUSED(buffer_size); + + if (att_handle != ATT_CHARACTERISTIC_ORG_BLUETOOTH_CHARACTERISTIC_TEMPERATURE_01_CLIENT_CONFIGURATION_HANDLE) return 0; + le_notification_enabled = little_endian_read_16(buffer, 0) == GATT_CLIENT_CHARACTERISTICS_CONFIGURATION_NOTIFICATION; + con_handle = connection_handle; + if (le_notification_enabled) { + att_server_request_can_send_now_event(con_handle); + } + return 0; +} + +static void poll_temp(void) { + adc_select_input(ADC_CHANNEL_TEMPSENSOR); + uint32_t raw32 = adc_read(); + const uint32_t bits = 12; + + // Scale raw reading to 16 bit value using a Taylor expansion (for 8 <= bits <= 16) + uint16_t raw16 = raw32 << (16 - bits) | raw32 >> (2 * bits - 16); + + // ref https://github.com/raspberrypi/pico-micropython-examples/blob/master/adc/temperature.py + const float conversion_factor = 3.3 / (65535); + float reading = raw16 * conversion_factor; + + // The temperature sensor measures the Vbe voltage of a biased bipolar diode, connected to the fifth ADC channel + // Typically, Vbe = 0.706V at 27 degrees C, with a slope of -1.721mV (0.001721) per degree. + float deg_c = 27 - (reading - 0.706) / 0.001721; + current_temp = deg_c * 100; + printf("Write temp %.2f degc\n", deg_c); + } + +static void heartbeat_handler(struct btstack_timer_source *ts) { + static uint32_t counter = 0; + counter++; + + // Update the temp every 10s + if (counter % 10 == 0) { + poll_temp(); + if (le_notification_enabled) { + att_server_request_can_send_now_event(con_handle); + } + } + + // Invert the led + static int led_on = true; + led_on = !led_on; + cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, led_on); + + // Restart timer + btstack_run_loop_set_timer(ts, HEARTBEAT_PERIOD_MS); + btstack_run_loop_add_timer(ts); +} + +int main() { + stdio_init_all(); + + // initialize CYW43 driver architecture (will enable BT if/because CYW43_ENABLE_BLUETOOTH == 1) + if (cyw43_arch_init()) { + printf("failed to initialise cyw43_arch\n"); + return -1; + } + + // Initialise adc for the temp sensor + adc_init(); + adc_select_input(ADC_CHANNEL_TEMPSENSOR); + adc_set_temp_sensor_enabled(true); + + l2cap_init(); + sm_init(); + + att_server_init(profile_data, att_read_callback, att_write_callback); + + // inform about BTstack state + hci_event_callback_registration.callback = &packet_handler; + hci_add_event_handler(&hci_event_callback_registration); + + // sm packet handler + sm_event_callback_registration.callback = &sm_packet_handler; + sm_add_event_handler(&sm_event_callback_registration); + + // apply security configuration settings + configure_security(security_setting); + + // register for ATT event + att_server_register_packet_handler(packet_handler); + + // set one-shot btstack timer + heartbeat.process = &heartbeat_handler; + btstack_run_loop_set_timer(&heartbeat, HEARTBEAT_PERIOD_MS); + btstack_run_loop_add_timer(&heartbeat); + + // turn on bluetooth! + hci_power_control(HCI_POWER_ON); + + // btstack_run_loop_execute is only required when using the 'polling' method (e.g. using pico_cyw43_arch_poll library). + // This example uses the 'threadsafe background` method, where BT work is handled in a low priority IRQ, so it + // is fine to call bt_stack_run_loop_execute() but equally you can continue executing user code. + +#if 0 // btstack_run_loop_execute() is not required, so lets not use it + btstack_run_loop_execute(); +#else + // this core is free to do it's own stuff except when using 'polling' method (in which case you should use + // btstacK_run_loop_ methods to add work to the run loop. + + // this is a forever loop in place of where user code would go. + while(true) { + sleep_ms(1000); + } +#endif + return 0; +} diff --git a/pico_w/bt/standalone/secure_temp_sensor/temp_sensor.gatt b/pico_w/bt/standalone/secure_temp_sensor/temp_sensor.gatt new file mode 100644 index 000000000..e0219483e --- /dev/null +++ b/pico_w/bt/standalone/secure_temp_sensor/temp_sensor.gatt @@ -0,0 +1,8 @@ +PRIMARY_SERVICE, GAP_SERVICE +CHARACTERISTIC, GAP_DEVICE_NAME, READ, "secure_picow_temp" + +PRIMARY_SERVICE, GATT_SERVICE +CHARACTERISTIC, GATT_DATABASE_HASH, READ, + +PRIMARY_SERVICE, ORG_BLUETOOTH_SERVICE_ENVIRONMENTAL_SENSING +CHARACTERISTIC, ORG_BLUETOOTH_CHARACTERISTIC_TEMPERATURE, READ | NOTIFY | INDICATE | DYNAMIC | ENCRYPTION_KEY_SIZE_16, diff --git a/pico_w/bt/standalone/temp_sensor/CMakeLists.txt b/pico_w/bt/standalone/temp_sensor/CMakeLists.txt new file mode 100644 index 000000000..ef03fe482 --- /dev/null +++ b/pico_w/bt/standalone/temp_sensor/CMakeLists.txt @@ -0,0 +1,2 @@ +add_subdirectory(client) +add_subdirectory(server) diff --git a/pico_w/bt/standalone/temp_sensor/README.md b/pico_w/bt/standalone/temp_sensor/README.md new file mode 100644 index 000000000..86a68cf2d --- /dev/null +++ b/pico_w/bt/standalone/temp_sensor/README.md @@ -0,0 +1,3 @@ +### Secure temp sensor + +This example uses BLE to communicate temperature between a pair of pico Ws. It reads temperature by measuring some onboard voltage and applying a conversion factor. \ No newline at end of file diff --git a/pico_w/bt/standalone/client/CMakeLists.txt b/pico_w/bt/standalone/temp_sensor/client/CMakeLists.txt similarity index 91% rename from pico_w/bt/standalone/client/CMakeLists.txt rename to pico_w/bt/standalone/temp_sensor/client/CMakeLists.txt index 808d2fdf9..67ab5d041 100644 --- a/pico_w/bt/standalone/client/CMakeLists.txt +++ b/pico_w/bt/standalone/temp_sensor/client/CMakeLists.txt @@ -13,7 +13,7 @@ target_link_libraries(picow_ble_temp_reader ) target_include_directories(picow_ble_temp_reader PRIVATE ${CMAKE_CURRENT_LIST_DIR} - ${CMAKE_CURRENT_LIST_DIR}/.. # For our common btstack config + ${CMAKE_CURRENT_LIST_DIR}/../.. # For our common btstack config ) target_compile_definitions(picow_ble_temp_reader PRIVATE RUNNING_AS_CLIENT=1 diff --git a/pico_w/bt/standalone/temp_sensor/client/btstack_config.h b/pico_w/bt/standalone/temp_sensor/client/btstack_config.h new file mode 100644 index 000000000..ce1919916 --- /dev/null +++ b/pico_w/bt/standalone/temp_sensor/client/btstack_config.h @@ -0,0 +1,6 @@ +#ifndef _PICO_BTSTACK_CONFIG_H +#define _PICO_BTSTACK_CONFIG_H + +#include "btstack_config_common.h" + +#endif diff --git a/pico_w/bt/standalone/client/client.c b/pico_w/bt/standalone/temp_sensor/client/client.c similarity index 100% rename from pico_w/bt/standalone/client/client.c rename to pico_w/bt/standalone/temp_sensor/client/client.c diff --git a/pico_w/bt/standalone/server/CMakeLists.txt b/pico_w/bt/standalone/temp_sensor/server/CMakeLists.txt similarity index 90% rename from pico_w/bt/standalone/server/CMakeLists.txt rename to pico_w/bt/standalone/temp_sensor/server/CMakeLists.txt index b18ac013a..30cb69c26 100644 --- a/pico_w/bt/standalone/server/CMakeLists.txt +++ b/pico_w/bt/standalone/temp_sensor/server/CMakeLists.txt @@ -12,7 +12,7 @@ target_link_libraries(picow_ble_temp_sensor ) target_include_directories(picow_ble_temp_sensor PRIVATE ${CMAKE_CURRENT_LIST_DIR} - ${CMAKE_CURRENT_LIST_DIR}/.. # For our common btstack config + ${CMAKE_CURRENT_LIST_DIR}/../.. # For our common btstack config ) pico_btstack_make_gatt_header(picow_ble_temp_sensor PRIVATE "${CMAKE_CURRENT_LIST_DIR}/temp_sensor.gatt") diff --git a/pico_w/bt/standalone/temp_sensor/server/btstack_config.h b/pico_w/bt/standalone/temp_sensor/server/btstack_config.h new file mode 100644 index 000000000..ce1919916 --- /dev/null +++ b/pico_w/bt/standalone/temp_sensor/server/btstack_config.h @@ -0,0 +1,6 @@ +#ifndef _PICO_BTSTACK_CONFIG_H +#define _PICO_BTSTACK_CONFIG_H + +#include "btstack_config_common.h" + +#endif diff --git a/pico_w/bt/standalone/server/server.c b/pico_w/bt/standalone/temp_sensor/server/server.c similarity index 100% rename from pico_w/bt/standalone/server/server.c rename to pico_w/bt/standalone/temp_sensor/server/server.c diff --git a/pico_w/bt/standalone/server/temp_sensor.gatt b/pico_w/bt/standalone/temp_sensor/server/temp_sensor.gatt similarity index 100% rename from pico_w/bt/standalone/server/temp_sensor.gatt rename to pico_w/bt/standalone/temp_sensor/server/temp_sensor.gatt diff --git a/pico_w/bt/standalone/wifi_provisioner/CMakeLists.txt b/pico_w/bt/standalone/wifi_provisioner/CMakeLists.txt new file mode 100644 index 000000000..9a08e7106 --- /dev/null +++ b/pico_w/bt/standalone/wifi_provisioner/CMakeLists.txt @@ -0,0 +1,32 @@ +# Add provisioning libary +add_library(wifi_prov_lib INTERFACE) +target_sources(wifi_prov_lib INTERFACE + ${CMAKE_CURRENT_LIST_DIR}/wifi_prov_lib.c + ) +target_include_directories(wifi_prov_lib INTERFACE + ${CMAKE_CURRENT_LIST_DIR} + ) +target_link_libraries(wifi_prov_lib INTERFACE + pico_stdlib + pico_btstack_ble + pico_btstack_cyw43 + pico_cyw43_arch_lwip_threadsafe_background + hardware_flash + ) +pico_btstack_make_gatt_header(wifi_prov_lib INTERFACE "${CMAKE_CURRENT_LIST_DIR}/provisioning.gatt") + +# Standalone example which uses the provisioning libary to allow credentials to be set over BLE +add_executable(wifi_provisioning_new + example.c + ) +target_link_libraries(wifi_provisioning_new + pico_stdlib + wifi_prov_lib + ) +target_include_directories(wifi_provisioning_new PRIVATE + ${CMAKE_CURRENT_LIST_DIR} + ${CMAKE_CURRENT_LIST_DIR}/.. # For our common btstack config + ) + +pico_add_extra_outputs(wifi_provisioning_new) + diff --git a/pico_w/bt/standalone/wifi_provisioner/README.md b/pico_w/bt/standalone/wifi_provisioner/README.md new file mode 100644 index 000000000..c65abed94 --- /dev/null +++ b/pico_w/bt/standalone/wifi_provisioner/README.md @@ -0,0 +1,3 @@ +### BLE wifi provisioning + +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'. diff --git a/pico_w/bt/standalone/wifi_provisioner/btstack_config.h b/pico_w/bt/standalone/wifi_provisioner/btstack_config.h new file mode 100644 index 000000000..ce1919916 --- /dev/null +++ b/pico_w/bt/standalone/wifi_provisioner/btstack_config.h @@ -0,0 +1,6 @@ +#ifndef _PICO_BTSTACK_CONFIG_H +#define _PICO_BTSTACK_CONFIG_H + +#include "btstack_config_common.h" + +#endif diff --git a/pico_w/bt/standalone/wifi_provisioner/example.c b/pico_w/bt/standalone/wifi_provisioner/example.c new file mode 100644 index 000000000..90c36a23e --- /dev/null +++ b/pico_w/bt/standalone/wifi_provisioner/example.c @@ -0,0 +1,10 @@ +#include +#include + + +int main(void) { + // if unable to connect with saved ssid and password, waits 120 seconds + // for new credentials to be provisioned over BLE + start_ble_wifi_provisioning(120000); + printf("finished provisioning\n"); +} \ No newline at end of file diff --git a/pico_w/bt/standalone/lwipopts.h b/pico_w/bt/standalone/wifi_provisioner/lwipopts.h similarity index 99% rename from pico_w/bt/standalone/lwipopts.h rename to pico_w/bt/standalone/wifi_provisioner/lwipopts.h index 32bb24c51..7ae8d527c 100644 --- a/pico_w/bt/standalone/lwipopts.h +++ b/pico_w/bt/standalone/wifi_provisioner/lwipopts.h @@ -73,4 +73,4 @@ #define SLIP_DEBUG LWIP_DBG_OFF #define DHCP_DEBUG LWIP_DBG_OFF -#endif /* __LWIPOPTS_H__ */ +#endif /* __LWIPOPTS_H__ */ \ No newline at end of file diff --git a/pico_w/bt/standalone/wifi_provisioner/provisioning.gatt b/pico_w/bt/standalone/wifi_provisioner/provisioning.gatt new file mode 100644 index 000000000..d298585ad --- /dev/null +++ b/pico_w/bt/standalone/wifi_provisioner/provisioning.gatt @@ -0,0 +1,16 @@ +PRIMARY_SERVICE, GAP_SERVICE +CHARACTERISTIC, GAP_DEVICE_NAME, READ, "pico_wifi_provisioning" + +PRIMARY_SERVICE, GATT_SERVICE +CHARACTERISTIC, GATT_DATABASE_HASH, READ, + +PRIMARY_SERVICE, 6bfacb8f-6b40-49f8-906e-53bd113c5cfb + +// SSID characteristic +CHARACTERISTIC, b1829813-e8ec-4621-b9b5-6c1be43fe223, READ | WRITE | NOTIFY | DYNAMIC, +CHARACTERISTIC_USER_DESCRIPTION, READ, + + +// Password characteristic +CHARACTERISTIC, 410f5077-9e81-4f3b-b888-bf435174fa58, READ | WRITE | NOTIFY | DYNAMIC, +CHARACTERISTIC_USER_DESCRIPTION, READ, \ No newline at end of file diff --git a/pico_w/bt/standalone/wifi_provisioner/set_credentials.py b/pico_w/bt/standalone/wifi_provisioner/set_credentials.py new file mode 100644 index 000000000..d42a8610c --- /dev/null +++ b/pico_w/bt/standalone/wifi_provisioner/set_credentials.py @@ -0,0 +1,40 @@ +import asyncio +import sys +import argparse + +from bleak import BleakClient + +SSID_CHARACTERISTIC = "b1829813-e8ec-4621-b9b5-6c1be43fe223" +PASSWORD_CHARACTERISTIC = "410f5077-9e81-4f3b-b888-bf435174fa58" + +#Add arguments from terminal with python3 set_credentials.py ssid password address +parser=argparse.ArgumentParser(description="ssid, password and address parser") +parser.add_argument("ssid") +parser.add_argument("password") +parser.add_argument("address") +args = parser.parse_args() + +ssid = args.ssid +password = args.password +address = args.address + +print("submitted ssid: ", ssid) +print("submitted password: ", password) +print("submitted address: ", address) + +async def main(ssid, password): + async with BleakClient(address) as client: + print(f"Connected: {client.is_connected}") + + await client.pair() + + print("Writing SSID...") + await client.write_gatt_char(SSID_CHARACTERISTIC, ssid.encode("utf-8"), response=True) + await asyncio.sleep(1.0) + + print("Writing password...") + await client.write_gatt_char(PASSWORD_CHARACTERISTIC, password.encode("utf-8"), response=True) + await asyncio.sleep(1.0) + +if __name__ == "__main__": + asyncio.run(main(ssid, password)) \ No newline at end of file diff --git a/pico_w/bt/standalone/wifi_provisioner/wifi_prov_lib.c b/pico_w/bt/standalone/wifi_provisioner/wifi_prov_lib.c new file mode 100644 index 000000000..b3d28eb4e --- /dev/null +++ b/pico_w/bt/standalone/wifi_provisioner/wifi_prov_lib.c @@ -0,0 +1,455 @@ +/** + * Copyright (c) 2023 Raspberry Pi (Trading) Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include "btstack.h" +#include "pico/cyw43_arch.h" +#include "pico/btstack_cyw43.h" +#include "pico/stdlib.h" +#include "provisioning.h" +#include "wifi_prov_lib.h" +#include "hardware/gpio.h" +#include "pico/flash.h" +#include "hardware/flash.h" + +#include + +#define HEARTBEAT_PERIOD_MS 1000 +#define APP_AD_FLAGS 0x06 + +int le_notification_enabled; +hci_con_handle_t con_handle; + +// max lengths of credentials + 1 to ensure null termination +char ssid[33] = ""; +char password[64] = ""; + +bool connection_status = false; + +static btstack_timer_source_t heartbeat; + +static btstack_packet_callback_registration_t hci_event_callback_registration; +static btstack_packet_callback_registration_t sm_event_callback_registration; + +static uint8_t adv_data[] = { + // Flags general discoverable + 0x02, BLUETOOTH_DATA_TYPE_FLAGS, APP_AD_FLAGS, + // Name + 0x17, BLUETOOTH_DATA_TYPE_COMPLETE_LOCAL_NAME, 'P', 'i', 'c', 'o', ' ', '0', '0', ':', '0', '0', ':', '0', '0', ':', '0', '0', ':', '0', '0', ':', '0', '0', + 0x03, BLUETOOTH_DATA_TYPE_COMPLETE_LIST_OF_16_BIT_SERVICE_CLASS_UUIDS, 0x10, 0xFF, +}; + +static const uint8_t adv_data_len = sizeof(adv_data); + +// Define flash offset towards end of flash +#ifndef PICO_FLASH_BANK_TOTAL_SIZE +#define PICO_FLASH_BANK_TOTAL_SIZE (FLASH_SECTOR_SIZE * 2u) +#endif + +#ifndef PICO_FLASH_BANK_STORAGE_OFFSET +#if PICO_RP2350 && PICO_RP2350_A2_SUPPORTED +#define FLASH_TARGET_OFFSET (PICO_FLASH_SIZE_BYTES - FLASH_SECTOR_SIZE - PICO_FLASH_BANK_TOTAL_SIZE) +#else +#define FLASH_TARGET_OFFSET (PICO_FLASH_SIZE_BYTES - FLASH_SECTOR_SIZE - PICO_FLASH_BANK_TOTAL_SIZE) +#endif +#endif + +const uint8_t *flash_target_contents = (const uint8_t *) (XIP_BASE + FLASH_TARGET_OFFSET); + +// This function will be called when it's safe to call flash_range_erase +static void call_flash_range_erase(void *param) { + uint32_t offset = (uint32_t)param; + flash_range_erase(offset, FLASH_SECTOR_SIZE); +} + +// This function will be called when it's safe to call flash_range_program +static void call_flash_range_program(void *param) { + uint32_t offset = ((uintptr_t*)param)[0]; + const uint8_t *data = (const uint8_t *)((uintptr_t*)param)[1]; + flash_range_program(offset, data, FLASH_PAGE_SIZE); +} + +// Security Manager Packet Handler +void sm_packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ + UNUSED(channel); + UNUSED(size); + + if (packet_type != HCI_EVENT_PACKET) return; + + hci_con_handle_t con_handle; + bd_addr_t addr; + bd_addr_type_t addr_type; + uint8_t status; + + switch (hci_event_packet_get_type(packet)) { + case HCI_EVENT_META_GAP: + switch (hci_event_gap_meta_get_subevent_code(packet)) { + case GAP_SUBEVENT_LE_CONNECTION_COMPLETE: + printf("Connection complete\n"); + con_handle = gap_subevent_le_connection_complete_get_connection_handle(packet); + UNUSED(con_handle); + sm_request_pairing(con_handle); + break; + default: + break; + } + break; + case SM_EVENT_JUST_WORKS_REQUEST: + printf("Just Works requested\n"); + sm_just_works_confirm(sm_event_just_works_request_get_handle(packet)); + break; + case SM_EVENT_IDENTITY_CREATED: + sm_event_identity_created_get_identity_address(packet, addr); + printf("Identity created: type %u address %s\n", sm_event_identity_created_get_identity_addr_type(packet), bd_addr_to_str(addr)); + break; + case SM_EVENT_IDENTITY_RESOLVING_SUCCEEDED: + sm_event_identity_resolving_succeeded_get_identity_address(packet, addr); + printf("Identity resolved: type %u address %s\n", sm_event_identity_resolving_succeeded_get_identity_addr_type(packet), bd_addr_to_str(addr)); + break; + case SM_EVENT_IDENTITY_RESOLVING_FAILED: + sm_event_identity_created_get_address(packet, addr); + printf("Identity resolving failed\n"); + break; + case SM_EVENT_PAIRING_STARTED: + printf("Pairing started\n"); + break; + case SM_EVENT_PAIRING_COMPLETE: + switch (sm_event_pairing_complete_get_status(packet)){ + case ERROR_CODE_SUCCESS: + printf("Pairing complete, success\n"); + break; + case ERROR_CODE_CONNECTION_TIMEOUT: + printf("Pairing failed, timeout\n"); + break; + case ERROR_CODE_REMOTE_USER_TERMINATED_CONNECTION: + printf("Pairing failed, disconnected\n"); + break; + case ERROR_CODE_AUTHENTICATION_FAILURE: + printf("Pairing failed, authentication failure with reason = %u\n", sm_event_pairing_complete_get_reason(packet)); + break; + default: + break; + } + break; + case SM_EVENT_REENCRYPTION_STARTED: + sm_event_reencryption_complete_get_address(packet, addr); + printf("Bonding information exists for addr type %u, identity addr %s -> re-encryption started\n", + sm_event_reencryption_started_get_addr_type(packet), bd_addr_to_str(addr)); + break; + case SM_EVENT_REENCRYPTION_COMPLETE: + switch (sm_event_reencryption_complete_get_status(packet)){ + case ERROR_CODE_SUCCESS: + printf("Re-encryption complete, success\n"); + break; + case ERROR_CODE_CONNECTION_TIMEOUT: + printf("Re-encryption failed, timeout\n"); + break; + case ERROR_CODE_REMOTE_USER_TERMINATED_CONNECTION: + printf("Re-encryption failed, disconnected\n"); + break; + case ERROR_CODE_PIN_OR_KEY_MISSING: + printf("Re-encryption failed, bonding information missing\n\n"); + printf("Assuming remote lost bonding information\n"); + printf("Deleting local bonding information to allow for new pairing...\n"); + sm_event_reencryption_complete_get_address(packet, addr); + addr_type = sm_event_reencryption_started_get_addr_type(packet); + gap_delete_bonding(addr_type, addr); + break; + default: + break; + } + break; + case GATT_EVENT_QUERY_COMPLETE: + status = gatt_event_query_complete_get_att_status(packet); + switch (status){ + case ATT_ERROR_INSUFFICIENT_ENCRYPTION: + printf("GATT Query failed, Insufficient Encryption\n"); + break; + case ATT_ERROR_INSUFFICIENT_AUTHENTICATION: + printf("GATT Query failed, Insufficient Authentication\n"); + break; + case ATT_ERROR_BONDING_INFORMATION_MISSING: + printf("GATT Query failed, Bonding Information Missing\n"); + break; + case ATT_ERROR_SUCCESS: + printf("GATT Query successful\n"); + break; + default: + printf("GATT Query failed, status 0x%02x\n", gatt_event_query_complete_get_att_status(packet)); + break; + } + break; + default: + break; + } +} + +void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size) { + UNUSED(size); + UNUSED(channel); + bd_addr_t local_addr; + if (packet_type != HCI_EVENT_PACKET) return; + + uint8_t event_type = hci_event_packet_get_type(packet); + switch(event_type){ + case HCI_EVENT_META_GAP: + switch (hci_event_gap_meta_get_subevent_code(packet)) { + case GAP_SUBEVENT_LE_CONNECTION_COMPLETE: + printf("Connection complete\n"); + con_handle = gap_subevent_le_connection_complete_get_connection_handle(packet); + UNUSED(con_handle); + sm_request_pairing(con_handle); + break; + default: + break; + } + break; + + case BTSTACK_EVENT_STATE: + if (btstack_event_state_get_state(packet) != HCI_STATE_WORKING) return; + gap_local_bd_addr(local_addr); + printf("BTstack up and running on %s.\n", bd_addr_to_str(local_addr)); + + // setup advertisements + uint16_t adv_int_min = 800; + uint16_t adv_int_max = 800; + uint8_t adv_type = 0; + bd_addr_t null_addr; + memset(null_addr, 0, 6); + gap_advertisements_set_params(adv_int_min, adv_int_max, adv_type, 0, null_addr, 0x07, 0x00); + assert(adv_data_len <= 31); // ble limitation + gap_advertisements_set_data(adv_data_len, (uint8_t*) adv_data); + gap_advertisements_enable(1); + + break; + case HCI_EVENT_DISCONNECTION_COMPLETE: + le_notification_enabled = 0; + break; + case ATT_EVENT_CAN_SEND_NOW: + att_server_notify(con_handle, ATT_CHARACTERISTIC_b1829813_e8ec_4621_b9b5_6c1be43fe223_01_VALUE_HANDLE, (uint8_t*)ssid, sizeof(ssid)); + att_server_notify(con_handle, ATT_CHARACTERISTIC_410f5077_9e81_4f3b_b888_bf435174fa58_01_VALUE_HANDLE, (uint8_t*)password, sizeof(password)); + break; + + default: + break; + } +} + +uint16_t att_read_callback(hci_con_handle_t connection_handle, uint16_t att_handle, uint16_t offset, uint8_t * buffer, uint16_t buffer_size) { + UNUSED(connection_handle); + + // SSID read callbaclk + if (att_handle == ATT_CHARACTERISTIC_b1829813_e8ec_4621_b9b5_6c1be43fe223_01_VALUE_HANDLE){ + return att_read_callback_handle_blob((const uint8_t *)&ssid, sizeof(ssid), offset, buffer, buffer_size); + } + + // Password read callback + if (att_handle == ATT_CHARACTERISTIC_410f5077_9e81_4f3b_b888_bf435174fa58_01_VALUE_HANDLE){ + return att_read_callback_handle_blob((const uint8_t *)&password, sizeof(password), offset, buffer, buffer_size); + } + + return 0; +} + +int att_write_callback(hci_con_handle_t connection_handle, uint16_t att_handle, uint16_t transaction_mode, uint16_t offset, uint8_t *buffer, uint16_t buffer_size) { + UNUSED(transaction_mode); + UNUSED(offset); + UNUSED(buffer_size); + + le_notification_enabled = little_endian_read_16(buffer, 0) == GATT_CLIENT_CHARACTERISTICS_CONFIGURATION_NOTIFICATION; + con_handle = connection_handle; + if (le_notification_enabled) { + att_server_request_can_send_now_event(con_handle); + //This occurs when the client enables notification (the download button on nrf scanner) + } + + // First characteristic (SSID) + if (att_handle == ATT_CHARACTERISTIC_b1829813_e8ec_4621_b9b5_6c1be43fe223_01_VALUE_HANDLE){ + att_server_request_can_send_now_event(con_handle); + memset(ssid, 0, sizeof(ssid)); + memcpy(ssid, buffer, buffer_size); + //This occurs when the client sends a write request to the ssid characteristic (up arrow on nrf scanner) + printf("Current saved SSID: %s\n", ssid); + printf("Current saved password: %s\n", password); + } + + // Second characteristic (Password) + if (att_handle == ATT_CHARACTERISTIC_410f5077_9e81_4f3b_b888_bf435174fa58_01_VALUE_HANDLE){ + att_server_request_can_send_now_event(con_handle); + memset(password, 0, sizeof(password)); + memcpy(password, buffer, buffer_size); + //This occurs when the client sends a write request to the password characteristic (up arrow on nrf scanner) + printf("Current saved SSID: %s\n", ssid); + printf("Current saved password: %s\n", password); + } + + return 0; +} + +static void heartbeat_handler(struct btstack_timer_source *ts) { + static uint32_t counter = 0; + counter++; + + // Invert the led + static int led_on = true; + led_on = !led_on; + cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, led_on); + + // Restart timer + btstack_run_loop_set_timer(ts, HEARTBEAT_PERIOD_MS); + btstack_run_loop_add_timer(ts); +} + +void save_credentials(char ssid[], char password[]) { + // create empty 256 byte list + uint8_t flash_data[FLASH_PAGE_SIZE] = {0}; + + uint ssid_len = strlen(ssid); + uint password_len = strlen(password); + + // no character has ascii value 0, so we can seperate our ssid and password with a single 0 + // first add ssid + for (uint i = 0; i < ssid_len; i++) { + int ascii = (int) ssid[i]; + flash_data[i] = ascii; + } + + //next add password + for (uint i = 0; i < password_len; i++) { + int ascii = (int) password[i]; + flash_data[i + ssid_len + 1] = ascii; + } + + //now erase and then write flash + int rc = flash_safe_execute(call_flash_range_erase, (void*)FLASH_TARGET_OFFSET, UINT32_MAX); + hard_assert(rc == PICO_OK); + + uintptr_t params[] = { FLASH_TARGET_OFFSET, (uintptr_t)flash_data}; + rc = flash_safe_execute(call_flash_range_program, params, UINT32_MAX); + hard_assert(rc == PICO_OK); +} + +void read_credentials(void) { + uint counter = 0; + uint ssid_len = 0; + + // first check if the flash page begins with FF - this indicates the flash has not yet been written to + // so must initialise with empty write (otherwise crashes) + if (flash_target_contents[0] == 255) { + save_credentials("", ""); + } + + //initialise temporary ssid and password as 1 bigger than max to ensure null termination + char t_ssid[33] = {0}; + char t_password[64] = {0}; + + // itterate through the flash and seperate ssid and password + for (uint i = 0; i < FLASH_PAGE_SIZE; i++) { + // when detect first zero, increment counter and continue. update ssid_len so we can index password + if (flash_target_contents[i] == 0 && counter == 0) { + counter++; + ssid_len = i; + continue; + } + // when detect second zero, have extracted both ssid and password so stop + else if (flash_target_contents[i] == 0 && counter == 1) + { + break; + } + // otherwise just write ssid and password + else if (counter == 0) { + t_ssid[i] = (char) flash_target_contents[i]; + } + else if (counter == 1) { + t_password[i - ssid_len - 1] = (char) flash_target_contents[i]; + } + } + // update global ssid and password + memset(ssid, 0, sizeof(ssid)); + memcpy(ssid, t_ssid, sizeof(t_ssid)); + + memset(password, 0, sizeof(password)); + memcpy(password, t_password, sizeof(t_password)); +} + +// this function carries out the BLE credential provisioning and also wifi connection +int start_ble_wifi_provisioning(int ble_timeout_ms) { + stdio_init_all(); + + // initialize CYW43 driver architecture (will enable BT if/because CYW43_ENABLE_BLUETOOTH == 1) + if (cyw43_arch_init()) { + printf("failed to initialise cyw43_arch\n"); + return -1; + } + + l2cap_init(); + sm_init(); + + att_server_init(profile_data, att_read_callback, att_write_callback); + + // inform about BTstack state + hci_event_callback_registration.callback = &packet_handler; + hci_add_event_handler(&hci_event_callback_registration); + + // secure manager register handler + sm_event_callback_registration.callback = &sm_packet_handler; + sm_add_event_handler(&sm_event_callback_registration); + + // configure secure BLE (Just works) (legacy pairing) + gatt_client_set_required_security_level(LEVEL_2); + sm_set_io_capabilities(IO_CAPABILITY_NO_INPUT_NO_OUTPUT); + sm_set_authentication_requirements(0); + + // register for ATT event + att_server_register_packet_handler(packet_handler); + + // set one-shot btstack timer + heartbeat.process = &heartbeat_handler; + btstack_run_loop_set_timer(&heartbeat, HEARTBEAT_PERIOD_MS); + btstack_run_loop_add_timer(&heartbeat); + + // turn on bluetooth! + hci_power_control(HCI_POWER_ON); + + read_credentials(); + printf("Current saved SSID: %s\n", ssid); + printf("Current saved password: %s\n", password); + + // first attempt to connect using saved credentials + cyw43_arch_enable_sta_mode(); + if (cyw43_arch_wifi_connect_timeout_ms(ssid, password, CYW43_AUTH_WPA2_AES_PSK, 5000)) { + printf("failed to connect with saved credentials \n"); + } else { + printf("Connected.\n"); + connection_status = true; + } + + // If this fails, wait for user to provision credentials over BLE until timeout + // cyw43_arch_wifi_connect_timeout_ms returns -2 for timeout and -7 for incorrect password + // wish to keep trying if password incorrect + int result; + if (connection_status == false) { + while (true) { + result = cyw43_arch_wifi_connect_timeout_ms(ssid, password, CYW43_AUTH_WPA2_AES_PSK, ble_timeout_ms); + if (result == -2) { + panic("Timed out - failed provisioning! \n"); + } else if (result == 0) { + connection_status = true; + printf("Succesfully provisioned credentials through BLE! \n"); + // since connected, save credentiald for future use + save_credentials(ssid, password); + break; + } else if (result == -7) { + printf("Incorrect password - retrying \n"); + } else { + panic("Connection error - failed provisioning! \n"); + } + } + } + // once finished, turn off bluetooth + hci_power_control(HCI_POWER_OFF); + return 0; +} diff --git a/pico_w/bt/standalone/wifi_provisioner/wifi_prov_lib.h b/pico_w/bt/standalone/wifi_provisioner/wifi_prov_lib.h new file mode 100644 index 000000000..53bd1f2b0 --- /dev/null +++ b/pico_w/bt/standalone/wifi_provisioner/wifi_prov_lib.h @@ -0,0 +1,18 @@ +#include +#include "btstack.h" + +#ifndef WIFI_PROV_LIB +#define WIFI_PROV_LIB + +extern int le_notification_enabled; +extern hci_con_handle_t con_handle; +extern uint8_t const profile_data[]; + +void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size); +void sm_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size); +uint16_t att_read_callback(hci_con_handle_t connection_handle, uint16_t att_handle, uint16_t offset, uint8_t * buffer, uint16_t buffer_size); +int att_write_callback(hci_con_handle_t connection_handle, uint16_t att_handle, uint16_t transaction_mode, uint16_t offset, uint8_t *buffer, uint16_t buffer_size); + +int start_ble_wifi_provisioning(int ble_timeout_ms); + +#endif \ No newline at end of file diff --git a/pico_w/wifi/CMakeLists.txt b/pico_w/wifi/CMakeLists.txt index b096d2583..36d73f43f 100644 --- a/pico_w/wifi/CMakeLists.txt +++ b/pico_w/wifi/CMakeLists.txt @@ -4,6 +4,7 @@ set(WIFI_PASSWORD "${WIFI_PASSWORD}" CACHE INTERNAL "WiFi password for examples" add_subdirectory_exclude_platforms(blink) add_subdirectory_exclude_platforms(wifi_scan) add_subdirectory_exclude_platforms(access_point) +add_subdirectory_exclude_platforms(access_point_wifi_provisioning) if ("${WIFI_SSID}" STREQUAL "") message("Skipping some Pico W examples as WIFI_SSID is not defined") diff --git a/pico_w/wifi/access_point_wifi_provisioning/AP_provisioning.c b/pico_w/wifi/access_point_wifi_provisioning/AP_provisioning.c new file mode 100644 index 000000000..ec89a383a --- /dev/null +++ b/pico_w/wifi/access_point_wifi_provisioning/AP_provisioning.c @@ -0,0 +1,355 @@ +/** + * Copyright (c) 2022 Raspberry Pi (Trading) Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "pico/cyw43_arch.h" +#include "pico/stdlib.h" + +#include "lwip/ip4_addr.h" +#include "lwip/init.h" +#include "lwip/apps/httpd.h" + +#include "dhcpserver.h" +#include "dnsserver.h" + +#include "pico/flash.h" +#include "hardware/flash.h" // for saving succesful credentials + +static absolute_time_t wifi_connected_time; +static bool led_on = false; + +// max lengths + 1 +static char ssid[33]; +static char password[64]; + +static int num_credentials; + +static bool connection_status = false; + +// how many sectors would you like to reserve +// each sector is 4096 bytes, so can hold 40 pairs of max length credentials +#define DESIRED_FLASH_SECTORS 1 +static char ssid_list[40 * DESIRED_FLASH_SECTORS][33]; +static char password_list[40 * DESIRED_FLASH_SECTORS][64]; + +// Define flash offset towards end of flash +#ifndef PICO_FLASH_BANK_TOTAL_SIZE +#define PICO_FLASH_BANK_TOTAL_SIZE (FLASH_SECTOR_SIZE * 2u) +#endif + +#ifndef PICO_FLASH_BANK_STORAGE_OFFSET +#if PICO_RP2350 && PICO_RP2350_A2_SUPPORTED +#define FLASH_TARGET_OFFSET (PICO_FLASH_SIZE_BYTES - FLASH_SECTOR_SIZE - PICO_FLASH_BANK_TOTAL_SIZE - FLASH_SECTOR_SIZE * DESIRED_FLASH_SECTORS) +#else +#define FLASH_TARGET_OFFSET (PICO_FLASH_SIZE_BYTES - PICO_FLASH_BANK_TOTAL_SIZE - FLASH_SECTOR_SIZE * DESIRED_FLASH_SECTORS) +#endif +#endif + +static const uint8_t *flash_target_contents = (const uint8_t *) (XIP_BASE + FLASH_TARGET_OFFSET); + +// Function prototypes +static void call_flash_range_erase(void *param); +static void call_flash_range_program(void *param); + +static void save_credentials(char ssid[], char password[]); +static void read_credentials(void); + +static void attempt_wifi_connection(void); + +static const char *credential_cgi_handler(int iIndex, int iNumParams, char *pcParam[], char *pcValue[]); +static const char *connect_cgi_handler(int iIndex, int iNumParams, char *pcParam[], char *pcValue[]); +static const char *connect_from_saved_cgi_handler(int iIndex, int iNumParams, char *pcParam[], char *pcValue[]); +static const char *clear_cgi_handler(int iIndex, int iNumParams, char *pcParam[], char *pcValue[]); + +static u16_t ssi_handler(int iIndex, char *pcInsert, int iInsertLen +#if LWIP_HTTPD_SSI_MULTIPART + , uint16_t current_tag_part, uint16_t *next_tag_part +#endif +); + +static tCGI cgi_handlers[] = { + { "/credentials.cgi", credential_cgi_handler }, + { "/connect.cgi", connect_cgi_handler }, + { "/connect_from_saved.cgi", connect_from_saved_cgi_handler}, + {"/clear.cgi", clear_cgi_handler} +}; + +// Be aware of LWIP_HTTPD_MAX_TAG_NAME_LEN +static const char *ssi_tags[] = { + "wifilist", + "ssid", + "password" +}; + +int main() { + stdio_init_all(); + if (cyw43_arch_init()) { + printf("failed to initialise\n"); + return 1; + } + printf("intitialised\n"); + + // for testing, erase memory first + // might need to erase memory first time you use provisioning in case there are garbage values in flash + //int rc = flash_safe_execute(call_flash_range_erase, (void*)FLASH_TARGET_OFFSET, UINT32_MAX); + //hard_assert(rc == PICO_OK); + + // First, try to connect to network using saved credentials + read_credentials(); + + cyw43_arch_enable_sta_mode(); + for (int i = 0; i < num_credentials; i++) { + if (cyw43_arch_wifi_connect_timeout_ms(ssid_list[i], password_list[i], CYW43_AUTH_WPA2_AES_PSK, 5000)) { + printf("failed to connect with saved credentials %i \n", i); + } else { + printf("Connected.\n"); + connection_status = true; + break; + } + } + + // If this fails, enable access point + if (connection_status == false) { + cyw43_arch_disable_sta_mode(); + cyw43_arch_enable_ap_mode("picow_test", "12345678", CYW43_AUTH_WPA2_AES_PSK); + printf("\nReady, running server at %s\n", ip4addr_ntoa(netif_ip4_addr(netif_list))); + + #if LWIP_IPV6 + #define IP(x) ((x).u_addr.ip4) + #else + #define IP(x) (x) + #endif + + ip4_addr_t mask; + ip4_addr_t gw; + IP(gw).addr = PP_HTONL(CYW43_DEFAULT_IP_AP_ADDRESS); + IP(mask).addr = PP_HTONL(CYW43_DEFAULT_IP_MASK); + + #undef IP + dhcp_server_t dhcp_server; + dhcp_server_init(&dhcp_server, &gw, &mask); + + dns_server_t dns_server; + dns_server_init(&dns_server, &gw); + + char hostname[sizeof(CYW43_HOST_NAME) + 4]; + memcpy(&hostname[0], CYW43_HOST_NAME, sizeof(CYW43_HOST_NAME) - 1); + hostname[sizeof(hostname) - 1] = '\0'; + netif_set_hostname(&cyw43_state.netif[CYW43_ITF_STA], hostname); + + // start http server + wifi_connected_time = get_absolute_time(); + + // setup http server + cyw43_arch_lwip_begin(); + httpd_init(); + http_set_cgi_handlers(cgi_handlers, LWIP_ARRAYSIZE(cgi_handlers)); + http_set_ssi_handler(ssi_handler, ssi_tags, LWIP_ARRAYSIZE(ssi_tags)); + cyw43_arch_lwip_end(); + } + + //wait for connection + while(connection_status == false) { + cyw43_arch_poll(); + cyw43_arch_wait_for_work_until(make_timeout_time_ms(1000)); + } + + printf("Finished provisioning credentials. \n"); + cyw43_arch_deinit(); + return 0; +} + +// This function will be called when it's safe to call flash_range_erase +static void call_flash_range_erase(void *param) { + uint32_t offset = (uint32_t)param; + flash_range_erase(offset, FLASH_SECTOR_SIZE * DESIRED_FLASH_SECTORS); +} + +// This function will be called when it's safe to call flash_range_program +static void call_flash_range_program(void *param) { + uint32_t offset = ((uintptr_t*)param)[0]; + const uint8_t *data = (const uint8_t *)((uintptr_t*)param)[1]; + flash_range_program(offset, data, FLASH_SECTOR_SIZE * DESIRED_FLASH_SECTORS); +} + +// Functions for saving and reading credentials from flash +static void save_credentials(char ssid[], char password[]) { + // create empty 256 byte list + uint8_t flash_data[FLASH_SECTOR_SIZE * DESIRED_FLASH_SECTORS] = {0}; + + uint ssid_len = strlen(ssid); + uint password_len = strlen(password); + uint credential_count; + + //first check how many credentials are already saved + if (flash_target_contents[1] != 255) { + credential_count = flash_target_contents[1]; + //incriment this count since we are about to add a credential + credential_count++; + flash_data[1] = credential_count; + } else { + // first (empty) save, so dont want to incriment + credential_count = 0; + } + + //now need to find how far through the flash to start writing, and also add previous stuff to flash data + uint write_start_location = 2; + if (credential_count != 0) { + uint count = 0; + while (count < 2 * credential_count - 2) { + flash_data[write_start_location] = flash_target_contents[write_start_location]; + if (flash_target_contents[write_start_location] == 0) { + count++; + } + write_start_location++; + } + } + + // no character has ascii value 0, so we can seperate our ssid and password with a single 0 + // first add ssid + for (uint i = 0; i < ssid_len; i++) { + int ascii = (int) ssid[i]; + //printf("%i\n", ascii); + flash_data[i + write_start_location] = ascii; + } + + //next add password + for (uint i = 0; i < password_len; i++) { + int ascii = (int) password[i]; + flash_data[i + ssid_len + write_start_location + 1] = ascii; + } + + // must always erase flash before write + int rc = flash_safe_execute(call_flash_range_erase, (void*)FLASH_TARGET_OFFSET, UINT32_MAX); + hard_assert(rc == PICO_OK); + + // write flash + uintptr_t params[] = { FLASH_TARGET_OFFSET, (uintptr_t)flash_data}; + rc = flash_safe_execute(call_flash_range_program, params, UINT32_MAX); + hard_assert(rc == PICO_OK); +} + +static void read_credentials(void) { + uint credential_count; + + // first check if the flash page begins with FF - this indicates the flash has not yet been written to + // so must initialise with empty write + if (flash_target_contents[0] == 255) { + save_credentials("", ""); + } + + //second byte saves credential count (allows 255 sets of credentials, should be enough) + credential_count = flash_target_contents[1]; + num_credentials = credential_count; + //initialise temporary ssid and password as 1 bigger than max to ensure null termination + char t_ssid_list[20][33] = {0}; + char t_password_list[20][64] = {0}; + + uint space_count = 0; + uint start_index = 1; + + for (uint i = 2; i < FLASH_SECTOR_SIZE * DESIRED_FLASH_SECTORS; i++) { + if (space_count >= 2*credential_count) { + break; + } else if (flash_target_contents[i] == 0) { + space_count++; + start_index = i; + printf("\n"); + //printf("space count %i\n", space_count); + } else if (flash_target_contents[i] != 0 && space_count % 2 == 0) { + // there is a char, and even space count. So we are reading a ssid + t_ssid_list[(int) space_count / 2][i - start_index - 1] = flash_target_contents[i]; + //printf("%c", flash_target_contents[i]); + } else if (flash_target_contents[i] != 0 && space_count % 2 == 1) { + // there is a char and odd space count, so reading password + t_password_list[(int) space_count / 2][i - start_index - 1] = flash_target_contents[i]; + //printf("%c", flash_target_contents[i]); + } + } + + // update global ssid and password lists + memset(ssid_list, 0, sizeof(ssid_list)); + memcpy(ssid_list, t_ssid_list, sizeof(t_ssid_list)); + + memset(password_list, 0, sizeof(password_list)); + memcpy(password_list, t_password_list, sizeof(t_password_list)); +} + +static void attempt_wifi_connection(void) { + cyw43_arch_disable_ap_mode(); + cyw43_arch_enable_sta_mode(); + + if (cyw43_arch_wifi_connect_timeout_ms(ssid, password, CYW43_AUTH_WPA2_AES_PSK, 15000)) { + panic("Failed to connect!"); + } else { + printf("Connected.\n"); + connection_status = true; + // success, so save credentials for future use + save_credentials(ssid, password); + } +} + +static const char *credential_cgi_handler(int iIndex, int iNumParams, char *pcParam[], char *pcValue[]) { + printf("credential_cgi_handler called\n"); + strncpy(ssid, pcValue[0], sizeof(ssid) - 1); + strncpy(password, pcValue[1], sizeof(password) - 1); + printf("SSID AND PASSWORD: %s %s \n", ssid, password); + return "/index.shtml"; +} + +static const char *connect_from_saved_cgi_handler(int iIndex, int iNumParams, char *pcParam[], char *pcValue[]) { + printf("load_from_saved_cgi_handler called\n"); + strncpy(ssid, ssid_list[atoi(pcValue[0])], sizeof(ssid) - 1); + strncpy(password, password_list[atoi(pcValue[0])], sizeof(password) - 1); + attempt_wifi_connection(); + return "/index.shtml"; +} + +static const char *connect_cgi_handler(int iIndex, int iNumParams, char *pcParam[], char *pcValue[]) { + printf("connect_cgi_handler called\n"); + attempt_wifi_connection(); + return "/index.shtml"; +} + +static const char *clear_cgi_handler(int iIndex, int iNumParams, char *pcParam[], char *pcValue[]) { + printf("clear_cgi_handler called\n"); + int rc = flash_safe_execute(call_flash_range_erase, (void*)FLASH_TARGET_OFFSET, UINT32_MAX); + hard_assert(rc == PICO_OK); + save_credentials("", ""); + read_credentials(); + return "/index.shtml"; +} + +// Note that the buffer size is limited by LWIP_HTTPD_MAX_TAG_INSERT_LEN, so use LWIP_HTTPD_SSI_MULTIPART to return larger amounts of data +static u16_t ssi_handler(int iIndex, char *pcInsert, int iInsertLen +#if LWIP_HTTPD_SSI_MULTIPART + , uint16_t current_tag_part, uint16_t *next_tag_part +#endif +) { + int printed = 0; + switch (iIndex) { + case 0: { // wifilist + for (int i = 0; i < num_credentials; i++) { + printed += snprintf(pcInsert + printed, iInsertLen - printed, + "

    @qh0!xZT%lAXU|K^JYWDxh^bU5STUG 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%0D`QKZ5%!0*TnhcXZf-fm}^K9?JV_ z#QsMv#1`K9ELk47Pr5w$J663?Pb)9CE1#b$cCqsIrXydjfY;ft8n>HABD=3F*lQ!b zTrGyVfqwKr2 zDIEyRsn4IkeEwV)hr))vw$^?ma4V*XE|jgp*{^vAaQ z)%gj35BgW5__(;nTPrsm{RHfB@GuM5H5*VW2W3IE;JFeP&x5;m>3~s_eUuRd=^4O3 z0iz4<11DurVc&{EHAw}3Pl9Gd7khhqe%)n1KT9weOB)FZS<>XH2=26R-@bit1&3oz2P zuCTBb-QC^k@GhYGTyrwEvB{d6ntFCwd+Ng?(N(LQgMzd^GvM05$XktHu{gHw*PP9C zbDX^xTUpm$>?8lxAHF8IYCj7L3mXFfX>p_*d{em?xB4o=9xw`DzI^%GaY-;<1}cQk zCn(D1IMfvt70rB(I&Erd`W#}eYek4?WFls{R{Up6=A`6M!bWlNUTD(5z#R)#whLK* zLJWvd+`U_mNF>_FGzP4d=KVU8R}4qe<~#W-23t#+1K$203hEuB>K#`~l!pcK>Z-*1 zRQ7MY3*3ZFBc*i{(svcG1(8lqqbkoYSF;^bjjbmZJ?D&?IT>;-es7%^P!F6)1P$7Q z2M?wR6QiNK^srNdjG`jZjD`EXZ%X4ItF#TIuq*EXz@?ac87AtY^4Zy07~s7HysU|d ziC2+#H{RX-vXd;~R48QEL3gknL@(<+J78b{D@J@BL`a`A=Lhrv*@LCaicnx>o^8E6 z<1w?g){_0b{=DJ3_3NX-Hb;J-=8s zeGF#8TFt18jD6rC6Gz9w%{Udm@aOnk9nU0_4f%Y&B`hZT`gg$geBJwX;kG&EPOL;W zERii*aNo{AmSX33FU0;Ojb;Xk3HV24WM-P`=~ZUr99B}=19v`5Yal@%X?LXl4ru{Q zTQd`r$i5=DoDA>5xI_)#WOmxsZJK`1VR_3P1f&{b@)%|GqMO^<;NWst2=?vUXKH3f z`=kkr$!G84=;-KFXw&{(Rn@oka)8#;GVmyS_O@*lCXrWvbNcNs!ml57L|3owheZZT zoY%q%;f_pw@q(P6Zweg`9Ju+)W`~L&jQ(TM@@WG!@C9_{J$uWJ92@h3-L!d*`|_%S zSY~&leEIieNZTIJ!OyQ35WH2zk3Lxz`%h*=7xu}{zN&B(@k?E7?(&*VdVdEC-7K&k zhX4_N?;c_H}94>_0LQyS+zZY_r%W73~7oj z(7x(hU$F~<6!@UUpEvA3v3?ke8ri61bYTC-m=8B4n24J8q{r4>+ za(f%hq1xKoNTA!Yec?8P888EV@HpCB@W_d~_M4a7|Lcp2ynh4vID{p!Z5n?9VW=f& s<6S+7Ben0|ow;-=FETRn=*)MqH(KfCj;6_K$l2-Z8R=#pJ$L>80#tOoi~s-t literal 0 HcmV?d00001 diff --git a/pico_w/bt/standalone/client/btstack_config.h b/pico_w/bt/standalone/ble_pointer/btstack_config.h similarity index 100% rename from pico_w/bt/standalone/client/btstack_config.h rename to pico_w/bt/standalone/ble_pointer/btstack_config.h diff --git a/pico_w/bt/standalone/ble_pointer/mpu6050_i2c_lib.c b/pico_w/bt/standalone/ble_pointer/mpu6050_i2c_lib.c new file mode 100644 index 000000000..cd767454d --- /dev/null +++ b/pico_w/bt/standalone/ble_pointer/mpu6050_i2c_lib.c @@ -0,0 +1,164 @@ +/** + * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include "pico/stdlib.h" +#include "pico/binary_info.h" +#include "hardware/i2c.h" +#include "mpu6050_i2c_lib.h" +#include + +#define RAD_TO_DEG(r) (r) * 57.3 + +// Defualt address +static int addr = 0x68; + +void mpu6050_reset(void) { + // Two byte reset. First byte register, second byte data + // There are a load more options to set up the device in different ways that could be added here + uint8_t buf[] = {0x6B, 0x80}; + i2c_write_blocking(i2c_default, addr, buf, 2, false); + sleep_ms(100); // Allow device to reset and stabilize + + // Clear sleep mode (0x6B register, 0x00 value) + buf[1] = 0x00; // Clear sleep mode by writing 0x00 to the 0x6B register + i2c_write_blocking(i2c_default, addr, buf, 2, false); + sleep_ms(10); // Allow stabilization after waking up +} + +void mpu6050_read_raw(int16_t accel[3], int16_t gyro[3], int16_t *temp) { + // For this particular device, we send the device the register we want to read + // first, then subsequently read from the device. The register is auto incrementing + // so we don't need to keep sending the register we want, just the first. + + uint8_t buffer[6]; + + // Start reading acceleration registers from register 0x3B for 6 bytes + // accel measurments are from 0x3B to 0x40 + uint8_t val = 0x3B; + i2c_write_blocking(i2c_default, addr, &val, 1, true); // true to keep master control of bus + i2c_read_blocking(i2c_default, addr, buffer, 6, false); + + for (int i = 0; i < 3; i++) { + // register 3B contains accel_xout[15:8] + // next register contains accel_xout[7:0] + // so we bit shift 3B contents by 8 and concatinate with contents of resister 3C + // repeat for each pair of registers + accel[i] = (buffer[i * 2] << 8 | buffer[(i * 2) + 1]); + } + + // Now gyro data from reg 0x43 for 6 bytes + // The register is auto incrementing on each read + val = 0x43; + i2c_write_blocking(i2c_default, addr, &val, 1, true); + i2c_read_blocking(i2c_default, addr, buffer, 6, false); // False - finished with bus + + for (int i = 0; i < 3; i++) { + gyro[i] = (buffer[i * 2] << 8 | buffer[(i * 2) + 1]);; + } + + // Now temperature from reg 0x41 for 2 bytes + // The register is auto incrementing on each read + val = 0x41; + i2c_write_blocking(i2c_default, addr, &val, 1, true); + i2c_read_blocking(i2c_default, addr, buffer, 2, false); // False - finished with bus + + *temp = buffer[0] << 8 | buffer[1]; +} + +// FS values are 0, 1, 2, or 3 +// For gyro, correspond to += 250, 500, 1000, 2000 deg/s +// For accel, correspond to += 2, 4, 8, 16g +int mpu6050_initialise(int sda_pin, int scl_pin, int gyro_fs, int accel_fs) { + // Set the i2c pins + i2c_init(i2c_default, 400 * 1000); + gpio_set_function(sda_pin, GPIO_FUNC_I2C); + gpio_set_function(scl_pin, GPIO_FUNC_I2C); + gpio_pull_up(sda_pin); + gpio_pull_up(scl_pin); + + // set full scale ranges for gyro and accel + // register 1B is gyro config - bit 4 and bit 3 are used for full scale select + uint8_t buffer[1]; + const uint8_t gyro_config = 0x1B; + + // first read + i2c_write_blocking(i2c_default, addr, &gyro_config, 1, true); + i2c_read_blocking(i2c_default, addr, buffer, 1, false); + + uint8_t to_write = buffer[0] | ((gyro_fs & 3) << 3); // Set gyro bits + + uint8_t write_buf[2] = {gyro_config, to_write}; + i2c_write_blocking(i2c_default, addr, write_buf, 1, false); + + // register 1C is for accel config + const uint8_t accel_config = 0x1C; + + // first read + i2c_write_blocking(i2c_default, addr, &accel_config, 1, true); + i2c_read_blocking(i2c_default, addr, buffer, 1, false); + + to_write = buffer[0] | ((accel_fs & 3) << 3); // Set accel bits + + write_buf[0] = accel_config; + write_buf[1] = to_write; + i2c_write_blocking(i2c_default, addr, write_buf, 1, false); + + return 0; +} + +// function takes num sensor readings to get gyro offsets +// sets roll_offset, pitch_offset and yaw_offset +void mpu6050_get_gyro_offset(int num, float *roll_offset, float *pitch_offset, float *yaw_offset, int gyro_fs) { + float r_offset = 0; + float p_offset = 0; + float y_offset = 0; + int16_t acceleration[3], gyro[3], temp; + + // can calculate gyro full scale range from the setting using 250 * 2^setting + int range = 250 * pow(2, gyro_fs); + + const float scale_factor = 1 / 32768.0 * range; + for (int i = 0; i < num; i++) { + mpu6050_read_raw(acceleration, gyro, &temp); + r_offset += gyro[0] * scale_factor; + p_offset += gyro[1] * scale_factor; + y_offset += gyro[2] * scale_factor; + } + r_offset /= num; + p_offset /= num; + y_offset /= num; + + printf("roll offset %f\n", r_offset); + printf("pitch offset %f\n", p_offset); + printf("yaw offset is %f\n", y_offset); + + *roll_offset = r_offset; + *pitch_offset = p_offset; + *yaw_offset = y_offset; +} + +// function outputs roll, pitch using sensor fusion +void mpu6050_fusion_output(float roll_offset, float pitch_offset, float yaw_offset, float alpha, int delta_ms, float *roll, float *pitch, float *yaw, int gyro_fs) { + int16_t acceleration[3], gyro[3], temp; + mpu6050_read_raw(acceleration, gyro, &temp); + // calculate pitch and roll from accelerometer output + // this calculation is independent of full scale + float accel_roll = RAD_TO_DEG(atan2(acceleration[1] , acceleration[2])); + float accel_pitch = RAD_TO_DEG(atan2((- acceleration[0]) , hypot(acceleration[1], acceleration[2]))); + + // can calculate gyro full scale range from the setting using 250 * 2^setting + int range = 250 * pow(2, gyro_fs); + float roll_rate = gyro[0] / 32768.0 * range - roll_offset; + float pitch_rate = gyro[1] / 32768.0 * range - pitch_offset; + float yaw_rate = gyro[2] / 32768.0 * range - yaw_offset; + + // calculate pitch and roll using sensor fusion (complimentary filter) + *roll = (1 - alpha) * (*roll + roll_rate * delta_ms/1000) + alpha * accel_roll; + *pitch = (1 - alpha) * (*pitch + pitch_rate * delta_ms/1000) + alpha * accel_pitch; + *yaw = *yaw + yaw_rate * delta_ms/1000; +} diff --git a/pico_w/bt/standalone/ble_pointer/mpu6050_i2c_lib.h b/pico_w/bt/standalone/ble_pointer/mpu6050_i2c_lib.h new file mode 100644 index 000000000..e46ccb716 --- /dev/null +++ b/pico_w/bt/standalone/ble_pointer/mpu6050_i2c_lib.h @@ -0,0 +1,12 @@ +#include + +#ifndef MPU6050_I2C_LIB +#define MPU6050_I2C_LIB + +void mpu6050_reset(void); +void mpu6050_read_raw(int16_t accel[3], int16_t gyro[3], int16_t *temp); +int mpu6050_initialise(int SDA_pin, int SCL_pin, int GYRO_FS, int ACCEL_FS); +void mpu6050_get_gyro_offset(int num, float *roll_offset, float *pitch_offset, float *yaw_offset, int gyro_fs); +void mpu6050_fusion_output(float roll_offset, float pitch_offset, float yaw_offset, float alpha, int delta_ms, float *roll, float *pitch, float *yaw, int gyro_fs); + +#endif \ No newline at end of file diff --git a/pico_w/bt/standalone/doorbell/CMakeLists.txt b/pico_w/bt/standalone/doorbell/CMakeLists.txt new file mode 100644 index 000000000..1242efdfb --- /dev/null +++ b/pico_w/bt/standalone/doorbell/CMakeLists.txt @@ -0,0 +1,42 @@ +# Standalone example that connects to the server Pico and flashes an external LED when the button is pressed +# Flashes the on-board LED once quickly each second when it's running but not connected to another device +# Flashes the on-board LED twice quickly each second when connected to another device +add_executable(doorbell_client + client.c + ) +target_link_libraries(doorbell_client + pico_stdlib + pico_btstack_ble + pico_btstack_cyw43 + pico_cyw43_arch_none + ) +target_include_directories(doorbell_client PRIVATE + ${CMAKE_CURRENT_LIST_DIR} + ${CMAKE_CURRENT_LIST_DIR}/.. # For our common btstack config + ) +target_compile_definitions(doorbell_client PRIVATE + RUNNING_AS_CLIENT=1 +) + +pico_add_extra_outputs(doorbell_client) + + +# Standalone example that connects to the client Pico and detects button inputs +# Flashes slowly each second to show it's running +add_executable(doorbell_server + server.c + ) +target_link_libraries(doorbell_server + pico_stdlib + pico_btstack_ble + pico_btstack_cyw43 + pico_cyw43_arch_none + ) +target_include_directories(doorbell_server PRIVATE + ${CMAKE_CURRENT_LIST_DIR} + ${CMAKE_CURRENT_LIST_DIR}/.. # For our common btstack config + ) +pico_btstack_make_gatt_header(doorbell_server PRIVATE "${CMAKE_CURRENT_LIST_DIR}/doorbell.gatt") + +pico_add_extra_outputs(doorbell_server) + diff --git a/pico_w/bt/standalone/doorbell/README.md b/pico_w/bt/standalone/doorbell/README.md new file mode 100644 index 000000000..72f5c2ec9 --- /dev/null +++ b/pico_w/bt/standalone/doorbell/README.md @@ -0,0 +1,5 @@ +### Doorbell + +This example uses BLE to communicate between 2 Pico Ws. When the button on one Pico is pressed, the LED connected to the second Pico will illuminate. + +To use this example, connect a LED in series with a 330 ohm resistor between pin 15 and ground on the client Pico. On the server Pico, connect a button between pin 15 and ground. \ No newline at end of file diff --git a/pico_w/bt/standalone/server/btstack_config.h b/pico_w/bt/standalone/doorbell/btstack_config.h similarity index 100% rename from pico_w/bt/standalone/server/btstack_config.h rename to pico_w/bt/standalone/doorbell/btstack_config.h diff --git a/pico_w/bt/standalone/doorbell/client.c b/pico_w/bt/standalone/doorbell/client.c new file mode 100644 index 000000000..89cece27c --- /dev/null +++ b/pico_w/bt/standalone/doorbell/client.c @@ -0,0 +1,303 @@ +/** + * Copyright (c) 2023 Raspberry Pi (Trading) Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include "btstack.h" +#include "pico/cyw43_arch.h" +#include "pico/stdlib.h" + +#ifndef NDEBG +#define DEBUG_LOG(...) printf(__VA_ARGS__) +#else +#define DEBUG_LOG(...) +#endif + +#define LED_QUICK_FLASH_DELAY_MS 100 +#define LED_SLOW_FLASH_DELAY_MS 1000 + +#define EXT_LED_GPIO_NUM 15 + +typedef enum { + TC_OFF, + TC_IDLE, + TC_W4_SCAN_RESULT, + TC_W4_CONNECT, + TC_W4_SERVICE_RESULT, + TC_W4_CHARACTERISTIC_RESULT, + TC_W4_ENABLE_NOTIFICATIONS_COMPLETE, + TC_W4_READY +} gc_state_t; + +static btstack_packet_callback_registration_t hci_event_callback_registration; +static gc_state_t state = TC_OFF; +static bd_addr_t server_addr; +static bd_addr_type_t server_addr_type; +static hci_con_handle_t connection_handle; +static gatt_client_service_t server_service; +static gatt_client_characteristic_t server_characteristic; +static bool listener_registered; +static gatt_client_notification_t notification_listener; +static btstack_timer_source_t heartbeat; + +static void client_start(void){ + DEBUG_LOG("Start scanning!\n"); + state = TC_W4_SCAN_RESULT; + gap_set_scan_parameters(0,0x0030, 0x0030); + gap_start_scan(); +} + +static bool advertisement_report_contains_service(uint16_t service, uint8_t *advertisement_report){ + // get advertisement from report event + const uint8_t * adv_data = gap_event_advertising_report_get_data(advertisement_report); + uint8_t adv_len = gap_event_advertising_report_get_data_length(advertisement_report); + + // iterate over advertisement data + ad_context_t context; + for (ad_iterator_init(&context, adv_len, adv_data) ; ad_iterator_has_more(&context) ; ad_iterator_next(&context)){ + uint8_t data_type = ad_iterator_get_data_type(&context); + uint8_t data_size = ad_iterator_get_data_len(&context); + const uint8_t * data = ad_iterator_get_data(&context); + switch (data_type){ + case BLUETOOTH_DATA_TYPE_COMPLETE_LIST_OF_16_BIT_SERVICE_CLASS_UUIDS: + for (int i = 0; i < data_size; i += 2) { + uint16_t type = little_endian_read_16(data, i); + if (type == service) return true; + } + default: + break; + } + } + return false; +} + +static void handle_gatt_client_event(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size) { + UNUSED(packet_type); + UNUSED(channel); + UNUSED(size); + + uint8_t att_status; + switch(state){ + case TC_W4_SERVICE_RESULT: + switch(hci_event_packet_get_type(packet)) { + case GATT_EVENT_SERVICE_QUERY_RESULT: + // store service (we expect only one) + DEBUG_LOG("Storing service\n"); + gatt_event_service_query_result_get_service(packet, &server_service); + break; + case GATT_EVENT_QUERY_COMPLETE: + att_status = gatt_event_query_complete_get_att_status(packet); + if (att_status != ATT_ERROR_SUCCESS){ + printf("SERVICE_QUERY_RESULT, ATT Error 0x%02x.\n", att_status); + gap_disconnect(connection_handle); + break; + } + // service query complete, look for characteristic + state = TC_W4_CHARACTERISTIC_RESULT; + DEBUG_LOG("Search for binary sensing characteristic.\n"); + gatt_client_discover_characteristics_for_service_by_uuid16(handle_gatt_client_event, connection_handle, &server_service, ORG_BLUETOOTH_CHARACTERISTIC_DIGITAL_OUTPUT); + break; + default: + break; + } + break; + case TC_W4_CHARACTERISTIC_RESULT: + switch(hci_event_packet_get_type(packet)) { + case GATT_EVENT_CHARACTERISTIC_QUERY_RESULT: + DEBUG_LOG("Storing characteristic\n"); + gatt_event_characteristic_query_result_get_characteristic(packet, &server_characteristic); + break; + case GATT_EVENT_QUERY_COMPLETE: + att_status = gatt_event_query_complete_get_att_status(packet); + if (att_status != ATT_ERROR_SUCCESS){ + printf("CHARACTERISTIC_QUERY_RESULT, ATT Error 0x%02x.\n", att_status); + gap_disconnect(connection_handle); + break; + } + // register handler for notifications + listener_registered = true; + gatt_client_listen_for_characteristic_value_updates(¬ification_listener, handle_gatt_client_event, connection_handle, &server_characteristic); + // enable notifications + DEBUG_LOG("Enable notify on characteristic.\n"); + state = TC_W4_ENABLE_NOTIFICATIONS_COMPLETE; + gatt_client_write_client_characteristic_configuration(handle_gatt_client_event, connection_handle, + &server_characteristic, GATT_CLIENT_CHARACTERISTICS_CONFIGURATION_NOTIFICATION); + break; + default: + break; + } + break; + case TC_W4_ENABLE_NOTIFICATIONS_COMPLETE: + switch(hci_event_packet_get_type(packet)) { + case GATT_EVENT_QUERY_COMPLETE: + DEBUG_LOG("Notifications enabled, ATT status 0x%02x\n", gatt_event_query_complete_get_att_status(packet)); + if (gatt_event_query_complete_get_att_status(packet) != ATT_ERROR_SUCCESS) break; + state = TC_W4_READY; + break; + default: + break; + } + break; + case TC_W4_READY: + switch(hci_event_packet_get_type(packet)) { + case GATT_EVENT_NOTIFICATION: { + uint16_t value_length = gatt_event_notification_get_value_length(packet); + const uint8_t *value = gatt_event_notification_get_value(packet); + + DEBUG_LOG("Indication value len %d\n", value_length); + if (value_length == 2) { + uint state = little_endian_read_16(value, 0); + printf("recieved state %d \n", state); + // flash LED + for (int i = 1; i < 11; i++) { + gpio_put(EXT_LED_GPIO_NUM, i%2); + busy_wait_ms(100); + } + } else { + printf("Unexpected length %d\n", value_length); + } + break; + } + default: + printf("Unknown packet type 0x%02x\n", hci_event_packet_get_type(packet)); + break; + } + break; + default: + printf("Unknown state %d\n", state); + break; + } +} + +static void hci_event_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size) { + UNUSED(size); + UNUSED(channel); + bd_addr_t local_addr; + if (packet_type != HCI_EVENT_PACKET) return; + + uint8_t event_type = hci_event_packet_get_type(packet); + switch(event_type){ + case BTSTACK_EVENT_STATE: + if (btstack_event_state_get_state(packet) == HCI_STATE_WORKING) { + gap_local_bd_addr(local_addr); + printf("BTstack up and running on %s.\n", bd_addr_to_str(local_addr)); + client_start(); + } else { + state = TC_OFF; + } + break; + case GAP_EVENT_ADVERTISING_REPORT: + if (state != TC_W4_SCAN_RESULT) return; + // check name in advertisement + if (!advertisement_report_contains_service(ORG_BLUETOOTH_SERVICE_BINARY_SENSOR, packet)) return; + // store address and type + gap_event_advertising_report_get_address(packet, server_addr); + server_addr_type = gap_event_advertising_report_get_address_type(packet); + // stop scanning, and connect to the device + state = TC_W4_CONNECT; + gap_stop_scan(); + printf("Connecting to device with addr %s.\n", bd_addr_to_str(server_addr)); + gap_connect(server_addr, server_addr_type); + break; + case HCI_EVENT_LE_META: + // wait for connection complete + switch (hci_event_le_meta_get_subevent_code(packet)) { + case HCI_SUBEVENT_LE_CONNECTION_COMPLETE: + if (state != TC_W4_CONNECT) return; + connection_handle = hci_subevent_le_connection_complete_get_connection_handle(packet); + // initialize gatt client context with handle, and add it to the list of active clients + // query primary services + DEBUG_LOG("Search for binary sensing service.\n"); + state = TC_W4_SERVICE_RESULT; + gatt_client_discover_primary_services_by_uuid16(handle_gatt_client_event, connection_handle, ORG_BLUETOOTH_SERVICE_BINARY_SENSOR); + break; + default: + break; + } + break; + case HCI_EVENT_DISCONNECTION_COMPLETE: + // unregister listener + connection_handle = HCI_CON_HANDLE_INVALID; + if (listener_registered){ + listener_registered = false; + gatt_client_stop_listening_for_characteristic_value_updates(¬ification_listener); + } + printf("Disconnected %s\n", bd_addr_to_str(server_addr)); + if (state == TC_OFF) break; + client_start(); + break; + default: + break; + } +} + +static void heartbeat_handler(struct btstack_timer_source *ts) { + // Invert the led + static bool quick_flash; + static bool led_on = true; + + led_on = !led_on; + cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, led_on); + if (listener_registered && led_on) { + quick_flash = !quick_flash; + } else if (!listener_registered) { + quick_flash = false; + } + + // Restart timer + btstack_run_loop_set_timer(ts, (led_on || quick_flash) ? LED_QUICK_FLASH_DELAY_MS : LED_SLOW_FLASH_DELAY_MS); + btstack_run_loop_add_timer(ts); +} + +int main() { + stdio_init_all(); + + // initialize external LED + gpio_init(EXT_LED_GPIO_NUM); + gpio_set_dir(EXT_LED_GPIO_NUM, GPIO_OUT); + + // initialize CYW43 driver architecture (will enable BT if/because CYW43_ENABLE_BLUETOOTH == 1) + if (cyw43_arch_init()) { + printf("failed to initialise cyw43_arch\n"); + return -1; + } + + l2cap_init(); + sm_init(); + sm_set_io_capabilities(IO_CAPABILITY_NO_INPUT_NO_OUTPUT); + + // setup empty ATT server - only needed if LE Peripheral does ATT queries on its own, e.g. Android and iOS + att_server_init(NULL, NULL, NULL); + + gatt_client_init(); + + hci_event_callback_registration.callback = &hci_event_handler; + hci_add_event_handler(&hci_event_callback_registration); + + // set one-shot btstack timer + heartbeat.process = &heartbeat_handler; + btstack_run_loop_set_timer(&heartbeat, LED_SLOW_FLASH_DELAY_MS); + btstack_run_loop_add_timer(&heartbeat); + + // turn on! + hci_power_control(HCI_POWER_ON); + + // btstack_run_loop_execute is only required when using the 'polling' method (e.g. using pico_cyw43_arch_poll library). + // This example uses the 'threadsafe background` method, where BT work is handled in a low priority IRQ, so it + // is fine to call bt_stack_run_loop_execute() but equally you can continue executing user code. + +#if 1 // this is only necessary when using polling (which we aren't, but we're showing it is still safe to call in this case) + btstack_run_loop_execute(); +#else + // this core is free to do it's own stuff except when using 'polling' method (in which case you should use + // btstacK_run_loop_ methods to add work to the run loop. + + // this is a forever loop in place of where user code would go. + while(true) { + sleep_ms(1000); + } +#endif + return 0; +} diff --git a/pico_w/bt/standalone/doorbell/doorbell.fzz b/pico_w/bt/standalone/doorbell/doorbell.fzz new file mode 100644 index 0000000000000000000000000000000000000000..378241ec8293819c6b1c899ee4c3b34fe1b1d356 GIT binary patch literal 143627 zcmagEWmp_d)Gdm;2ZFo1yK4w;!QI{628ZD88a%kWyOZGV5Zrx$GrZqD_n!0X{+N2I ztGBGZtM=;Zu2GVOgu(;^1A_yT40_Y<``QUvLJS6mHVp}e2pTnYaBwy@v$bV1_deHK zb6%59^t-GvbTlS+Cx#=bKxly<`*PkaxR-IU48OMK@2Z4JL7IsTEv?1)w(#EXzoHIK z0sV6rsD93-c67_H9jg;>GKn?^;OtF z=q~YMYZK_ok(sTJ+%T<`Fk^o%+rzwx=2?!N^R3GJUay6H!eZd8l^<|zz0Az_aIa8vOPh7r@|I+@ zc)q_^?&oBP+Q6*b;*yg$%@o`5)8ZFRBy6Gm5!u8Hv-!xzY*e)0aw+in3i$FA+kLd+ z=2v-fIo&E;Un)df|8C`Vb@?!6e^ey=wAY!g8>0xwK%yRUdStdZC|u)ZzL}eOwmYoN z_gz1iW2RaHv?ywGbmY9V2onP`7(U#IuM5(nH_Zpen*3y2*d32vGqG3h&ZlZtp4R=+ z3|Y6s2QpEZ>XiYhsQy=Fi@v~vZPN|d)0=Bwo)?XVpMuv6uPS%2D@!Md7N|Z)}ZsE>)z;C|Q_3HyD z1EO3U=HJ4*b`CWcVF#}RqwJ4F^q0&I{oEIad^Z(frZT;zR0pG6ANKKNVBy9r3?fzpIe?ahH7y z0tg#2*7V)1bN~bo6YtJU5rapQu}iQ$MbRYaIK0jNGS0B2M~^%#rejW$XrP`jd>r`W zGu_s`e0zj9F?d4(r1tF}iZZNmq$BV7dH#D-X8xFk=eAOt^ewCkzG;cG_L?m6#F#fi zigp_m&A}^B%DTeVEyD^lLKdj{iA-u-w>Ub7N3TiUt7H?*SrG^sF*R9R!pX8oI$z0! z?g*u9+xRt_^Qw`GD+F%%g`8=zk8Zx`XVhY~7!8E|HqEa(e|%NbvO0ePTCich(9A`c zr&8qxGwM2}a9Wl{&FlmS!!pjKFu2@BDj1Z-NO`frX`5gM4760400xZOKialXq!3}5 zwZAy)2?iQ)>Xg2Kn^g5$BGr==)+X8nS7M;4Q%Yobv}(E>s2xamEIa>ZyL8$y#}k)M zn9qo*1Oy(CBH&mXujLFH$5e9M_>meHQ0*V8g)U@U#}6@wrrh9~W(3rhMI&UT>UV6( z7AQfME(*-6Sa8;p1XCVkI8SgI-RqLe8sJqd{fzgi#!{c*bl$;3v=XyVrKp4pVnDa7 z+>#Wt-%-_k&Q%cJHlC6|Q>o@5!?ZRe2mc}}A^xVQTgJN}i%+R(Dp6f*oKgkf79Pi3 z965y7W?fY$Ath$NySISTrb+%tdo`sHR40|Yq`9L_YC&2_VA8mqtytVEM!uy<^}~|F z^f~HrG$Mv9gkk(@letZk+QF<s$IS9YJoiAF0POV!J$sK&p2iVt+8sAYPGWar73i zf(C=M2DiV)l(gB7El6J<9MRg;fujdlU|1Pg%DI^6i(XIt(?Cm?WwCb-&!*`VjTe5$ z#|g?LMxd&%9&KO9V~WX)6vt-UYlsBT-*lgl4;@Iqa zA*bq-my!Y_wf`pquLx2@9dP>d$a6PtC|i2N*IX#^4GtYqk~Sk!iDvE_8~rHcWzza1 z6b4k$2gj>nh(1k7MH`0I2wg7-ool?6zCNEn2h-NuPkj?mL8YLzrdezgoUKJ)Ik`$= zu^5t~jX&3@Ej_*B&GElv70;nj&#iYTBOt z{T=6oRq#oxSYXEvFxO&f5`C^ulIvvVCeY^%KJDPbd7a3^$DPW)hwfWeSf}^wNfiPC z)-%=7YFB$F5u5!F!?Kq9jYzRolBGQ_#Vp;jKx$5hg=7RyR}*x#e5vMzTmJosoVngV z!5%2%IrF_r4r_$pF#p16P3~z##v^iG6&+%WBp|vCAY5mrOTQKWLzPeqOE~DXvr+$< zxkP%S%?`BRQxS(Ftsq<*L{XL|N1O-pv8yDYB%~<@{fZ2!+`8`CQ=x7W{hIPb$zD8d z9n64mMc*eAil>FS-0avwlMmnKl-*+XIpDW57Nu4M-{z40=q4MwN^;5!BtldHd_k_K z>vbR`!?HFDXwfj_&v2t?4fu_8rGEjm|0+h!RlgpZ5+u^HV1HVH19kowy0S(y0=q$1ORO`C3hG{yQ8CTZfX-=?rAltrVi)s!QKcZuOscnt*s>sSI`^K}k__{s zgz&zqNxEeT7MyBj>Z8xF72PhD#L*$iBU0APm%;>hFQ;W7C&5G}zYLT3vP( zg38k2qu)8V#+X0@->3ME2E}5sf83^8v?-C#SXVaU@q+JQk0v5=-c*K-iy(o&!f4`Z zSaWxf8g7BDZBbw!mpsEjj8(yt*1IJbv}#*7q9h=@Y0|>ge*>+y(fX&5Sn$`|y|b+>^Jfk;pSRLH>z$+9G#56Dqd!{<>96aoM>qA0A> zE4C7Nr0qPkt~Gpdd|lvK(lEc}+?*WFBA8+E`czOF z8qZVg)+SvVy4@(nT^^O3W2y+#KcT7Jj$Q#ibB^>zg%zm2%@zzxiio@BiX_TIjyMA( zV`XzfNx&9@_!SybIeu-o%|_iQni}~e$z(Qd8LWGAgl(S!&*3}? z{bFfq7FtTj<^*~;IBX^|ez6R$th!nw83j^ujB*0}ZBR2r=pj4bz}KQH$?GUp%mTR8 zj~+A8c*_$)8HySq+v(kPbSg>m6Yj;j3&p9XL)In6nU^U+W*CgGv-Zd2E|Hx7nfQ~P^l|OFj{)?xZGP(SOiCG|B|7VP;{Q8>c2prCF;9L0=SeE;^$e6#doTvNf z=%u2jF4Yhiuy1k<$qvNC7VA7uBPaifjzSAx}+h z#Sq8>1%av2C<&@4-QiMnv!h?|XpclL#E)7~lMy(sqBolhb4aqq_bD3l3D7`u3OO9+{Q7%S}pazD*~@#4KdW;tvmX*@clL)XOz!qGCu!o@BM zb^w^6pbQi^8KNXG<^WY$iSWZ`OU8Rv4IgKih46)#w>5Nvbf8mw)@*+O8IS%>dXb zZs%<13$+e^JBSAovr{#Eu)gsV%XRyoo;o^mMa*ehXxZLbWnvW5$&-Bbv`(vyW$Ew!?Y@*)m;4Y|F32J-95H}r2kL$)#VeZE-448_L+PqvWI zCV}l8W*ZDTUByf5qaNH>=S~`4Tse&fg7f;ua@w2IUA=_?qyLZ-wnq;|_l{SJaNMLM z%t&w&>Mz{_<6ZAV>X}=6QZhdT0s3o4K3}8C2EB{UCyK`W%jn-M&o>(n9|Ui(gAHz9 zO7NZU^O1!!JASoAo)8V}lJRTh3^MhtV(y{7@w zqb;KIERv!vlJYE~qb9Ak21iLd0gMS*3;(J>ro%5t>{Fu#7%a{ZO2VC@alCa;rlbW(=AmTm~$n{&PJkAi-&L;ce4 zmJ`;ly{rP(uBF<(BY(oBd3r&9Z*!=Pj_?EqS7S&VnTcu1w_>*d20P8B`Ny?VaMT3n z(r?eQzM+Fms~-aM+d&pn4Rl1-j_B3qT3D!@tt@ITm673iodL1pU;8=&9LvZ&4G>V2 zB`%W#!0~iDMo52d_Y0y(LZu}-!I8DbMvJ5NNtzNk!&Q?&DvP(hIQgx2EUO)e$4vEe zqVPj4p>v`LLZyLPVJHnyD++}TYQ>?J(BNsF!D{4e2)IzH7cmqvmqR-yOyyFZXnij^B4!h;kp8m5|Pm2ZuPp=qa~bU9H?Y&Nh3z zMyT{;3wN3(WwM=TVMRu;X676e#4-L&cqolr<*CfTLRs{TNjG#Q&=^&OGm z2@g)43dj6D%HquOA3U?$O&*xWaGP8qVu*eCT1wKS-Zs#1liS9^2&7QhFUtQ&TJNI8 zVEW7~FzMi!cni@)9ouljV8$0RPeD`LO-E>H+g+ucPSPq=rd&qSDp01}O47<#raVg0 z%2TGiOw!6F%>obWd7xEzW$%cbs)W%2lkvk061m##iww*LN#SqX{5~H9xX|AmqeY)V z9LNkLf9oTMMWD5f7yN`rM_NGf2f4oFGa_1w@zJtYoy6u(gkZl zFpazKyWZ3a9kGq0z6N{C_y}IM^E|NXrVhq}kTa^nx3cf&x2c2A+ZW30?U5sV$+E&H zpwyp&hORaPGdF$+EpFF0@50bw**FeiMQ};|(}NOG3O-#EDPo1dh6>~{fwE5r`xQ;v zY5@_!8n)dGPtgx|ku9>c5smkg?Z1{C)P^L72c%VTqKU@!V(E#EKlgG%Agdw&>|JmX8?X5Tjhp{h6>76w zL|PX{_l=B%$)xvy8Cgv=rkCFlE`l4+u__^;H5wcnAD*U%YulO}{J%{giYSgMm zZfuWMfBrVNFY9t5cT%|X_g(mO{CF_5K)#5sk)qbB+Z^|fu+uJfs9q=GuK-bv+hJzb zC)KdIOig}LO-kFL*(cSE>NeDW*0M=8uU4`61_}A6a7t@t+^6ua($p|W_zI5?Mawq! z=MRCu+i$cyYIVF{)vu+4ZJu}}>Ud%P>yC?XpzA8b82{Y%W<&c9rI8fK^GlbpP3S_e zv*M;;xMUA6oRVv_?bEZQ^4`@T%(MC@rO;TDl)zQfU?{;r=$9<=RCbEy{y0|R9gC0f7-T6aPD&K8_e1(@p=CXd8k9h`n3C6+_0zcXA?-+s3LEq*11d5UL4R@Am@H0xbk6r zm-cb0CTwM7PH|<$>Cr~twC9Inrw(+enxSah*$n72D&RiKmamNtW@X;P$6MiCDQdE( znfhwlo|#zpw9r}lJ!$w3^buAys<*_c&0CR^>7!qP48YSiUfRu_jr1Z8NY8t+kQC~e z8abK(+*t=R9p?2S1MAb5+xR<~oMB`eW+Wo;Qj0S1jHy0RtbNJh(*Nr_Rnf zSQ8#lx!NmF_dEQ*NjF|esx<7wQ)b3Sa*oXahCN#wYeD(!+&Y}jn>E=Jh;1YAp#tgT`(><{WhSyV^rdFfJ*x~n=BjGFXBWdxt4#C>JMe3; zl{t0yLa8)60xxf-2F`rLmtA?sMjE~icHPKRuh`{cbr7@(_{9kj7VXFaMiYAOZMr3j z)Ja`#CnDzWoi1lX-y6qD$(iBEV))-`Eez<~AM7T+Tzs=TjKE$w@NJ8RDz3wxKC)6w zNE_r@b$Ie-e~sc3%)%_3jws6xAy;|excF#)(MdqmzaX}L9|S_nUwj*!rf>OpmZtYe z@8bS-qIf=C?+zX@^t9C3Z5N1G9Alx|w(KX*{*me7Q(Li$hy5@uzaDY%waw8+3~nt=NdC5eAE0u6?CC`1 zY+?Krl5M<$m>RzY2Ti6%-o-fHG24lJHYzQz|4&)xAAsM7y-CxEKOgFnQHT;m4|a9Ih^wBvd3%OPBepO9a)%@ePmL^8KHTd`h<}+R7kbCbp(7w0~D>JEMAHq+nL!%nVlY zk@0WN$j(MJhc)M^lLISAbas27GqOF7_qFqsMOGH@ddGU*N4POhd-;^L^Z z=9YO&2=MlFkOsJWzkfb*$lLk=p87PW?paSL)*Q%fz)hdQ)u*6Oz63kWo%(XM{(ECR z2V|MQ8M%*R`TS0tI10uxki&Iq`Ywp@`^K}ZlVmaBOd;LR{okK&<&V0cG(=ZlVx6GQ zD$x^^xkUy$I2l7}MwTFlN@e zb2>TE+58bSIXs;6#zOG0O(-L3mr(NOIoP*o2xj%A)kB)Nh%aM_#Xi{U%S3Zuzz3}nQ zz>f+klQhqnv)Q^TwOc-#vAo^_WI4+N9T+8OWpT9@Zhr96zo;Jd=cJlb7O%f&1bg+f z;lw*p=ke@aoRw7OX5TSxm*QWH5SN16ia2Ba@w0I-)+s*S^G`-0!Mb=M&_V_`>b$6s zj`%xMnc+|S5}XtCeS^A?=Ej)4rA0FqqhlyvJ@~sKe?8`pf+B2h_lNfTkUSh&71_j- zf~R$^5QOvK0Og8e>?1T>jkHPM2VYIF)gS18h(i0qd-I8qC1 zH0W>?QvTjn1PgqTbf-&QU_9c(^v>QUb^@Bf!}Qmf)RC`w0ws7lNWtRuL%+wXer?Ax z(v1+TToEjLTKE6eRZWoe3Ho<1`YQrSQOJkZuW8#R8=|j^S7Jn0b&;Mj>UKN{-u5?l z93|CVv`vkLN>|94Y*fE$TyiP-mloT)7)oHP0k}?d21<;^@K;n^G41x&=W7JA2-jMV zSYk#!4v3*4>bPoI^&3xf23|0)^0;<%IduNivru{> zwva|$r`x>@bkobbVxdErD~Ypzbsp9KT-B{~ug6S&y9`N-k^k0dv(TTIE6~_H)IAF4 zXIQwsB4`y-OA_jOEIgOkaMgU99SQljO0>mjPt-(O7MEK%7ZmXLQ|7?PCT*b!>tC9^q!G2k=meq8&N4D=x_c=v zR{754U9Zz`vnP?i`s;U66>Y3`8~V&UgeFCK+ZYmYoUTo(D6Yg*!*2dMJfY zgPt_wH(L{U&?#NRpf`h86~lErX%S^q7I6(pkTk5%(bM$_ya{|5OaIdy>jJz9T`)_# z$myc3hfM_TreHOhk6N3u%n(s9$NadGERN*Dtu9vK0tRvHfmToWonm=Ucs-nn^Qh%t zwqeFN3z#JJAHL^(rp(dT`K(37(OJZxaI3oiCwb&!F0?{^a-8Go1ZpOgc*01>gq%`r zR0WdXnXg?t-j7N9rRI|pbA4O6vG4CzYsg5YF4LGxe$c>UFuSk4w=3-er&)<*$Zjx- z)1t83-y(j{vozP4PPO8T;&{YT*8DIOFom;P**zSgk0ANmx5?|@2vI1rUnl7ih{s;S z7c5xz&uhdmskWZ!-)z(!9t=J$Gg5FXrvd^4Q|dvo`k60JD)F6*(P|a{*ZBoAzqlyU z?>N8d!isWZ$L%(?59!$A8^w-@Ajjwrs=}j*8SOSe^Y&yZIV~6(n_7?OWpg3`ip@J6 z0gcB^Iu~Vrah71YP_9g$hO33aY0l_gocK!)YDL?^w+*;d&x|-Xgtf4GgWNI{969Y@ ztq0eWntw5dmWX5@#IQaKtQu5clW>2Xhn5HgAEvSOiofF-ARRD56+zoO{2I7}jXAz> z;6IK9S}QsDzW|i}uj72yl<(wz2w-3Y24G-ppyPZ;BWG78B`XsL4Fe-~P7`wzZeDJ7 zGc#@uc2iznR#sj%ULGzEE^bp^4pRe8F3_RB<5aedLt!gkK+k2()y}@JbIF{|kBwoIcw{+RRt!^aJ{uSg^&AOXQTmoF4xnKjr{tOUz zqe=5|{d7X&0k3gk1W79+6SOT^m2kjV&Ny%{3J{C&}+U;)woxJ+aYxQ@wJu(_k2 z?|rCGbt!}IerJk>sp(NZ>;6x;I{!$ohZMC|?X5L8q^QAV1rMqJQNU?h zevFlD&E^n8(Z0wp9tl6Kizi`uo07(vydr*KxZ-Wsry^CH&0~-#62IcV%c!cSym_5v zLQMSuX8`5vI`-GIKgl$d$v3%)U<3KwI4v4}IRv(FCV{&#O0sRrBq;8}bV#e*Gag%@ z@wQ5<+%|Q*=eeJT-T|XdqQs)&bSjH)Van^gXwOw&YUH>*G&7{*z8UDC{>Y;6E1kOk zNK$ru0SjS8Ow7*^QCL%}(5h3yYj4(J?2uwmXgpxzOVjjUEK+sW7O8qwwQ#}uL5qS~ zsRIbIg=D1xUm$;971mh zN1P|eU$mhg2ZA5I6TkwkQxLjac|S-z2nn#z%RiEcjq#$K-+sO}wDGv|<+zEcZyMoH zB7P-E86j}6)~Yo<3}-|i3eR~O`Qz<}0guj@EDsJq8xNzXq1pQT!la!H;sxbgI#14%BZKmB=B%EPojgGBV@ z>h&a1Zd3=A&;-9nmwRIUyZ#0k|3i_mB>haRV*S>gj7?MLomSc{e!~{cBdbBEPXyNciZl}>wY=r_jN;o*g{=jP3!CUN8S`f{YI*unhEy(K5}h~4omhZ`|*KCfnJPv z>~fFQ3@;Y4FUnu8Tepd@W3@!%{=5t8Q!2xc5_=Uo?e?F4xbA*bgw^9;SQo4}0oF_% ze^hW0cG)ggL|9=?tT~l>b1xFj-;$168LfDQ*YAb+(*0tyY={JQHab_CRF!^lo*%`x zby7|7V9+OsU}Jvr{8Q(kz*NKk@5SLYJDUIB$=zUgJI`hQM2`Uqc_U~1ogX*xf1H=_XDh_vRFS@bxgVm(6a>HPu?D72zdwsb%WS zIZ_>EyzQ8MGgLIA)u{RxhiJwP^V9iQvqWSgpzlyO-iH|+d+4B?he?THx|R53rl(1I zj@{&j_GIH=XSd1(e-r5>3Wd1^w>d0Q!yH-z)h5p21=pcIqd9dCyGid)O>7Jg5AF*l zoC|yLb&zta&sytiQ)>t1#Y9@`l>DG~e5X%`*JH2eBi_y8ApYLQ)}f&1=}%4KL^}ZY znh?&Kzj!l9%@%gec4M_}9WpBdnS>S9-GnH>h=^mb@+WuL$`7^grKv6-3v!ca=GYhw z9rz81VJmhKT3;L#63S#MH-94Esj}MI(}jr^<5brg<0wS!l<3Q)8OF974?A|@xfo23 zMjFM+|7O+XR;L^RJJ&Q3ggG9mB^$lU!e>MJJ?a=rKH!*$#NA}t4&@Sor5JW9iF-lw zg~Qe{C`|MRZndKsjza2ANi)bKO3UtqV;9SSW=5%z%Pj|z^`v7c+koRV5_gI@NVyTq zF6^`mm+HlUMSglwWD2)h$pU9OXQ$-mQ@7*SjANJZfZB&_$)97qGSLAn1mpo;j&-$P z#~71N8XS23E^%R^l6ciDRyYd9J0(o=Af-CvIma%A0hD!DWVNy#gu<|$WIX$mc~|&D zM|$;`c^%Gm=&b5MZ%$p(MV4%>0r`bYroQz(nn)e;dwb-^#U5*+nZ?ChZdKIsfN@S0 z(j~ZTU2^#YkPw0UeO-fKF8`^6|AudFbrrQ^No(*br-~6sM2}ql{8PkZs5+qq@Q(BV z-uRn(7K~Wb28e`Lq(>g9NA9!S)OV;cGu1hTX|L2FMR$f5*kDsst~W=SK2WvHSs$+F z!oF@GyOF54Cie%X$)>2k8l9&@Dsz=nFNk*)WWdec&R5jg&E8o$xSc~~=Pz8gEV;bi zr&rUV;sozBsVj2@^GLQbUUIC%=-v$Wzw_CkG%2f3;(EEbNP%)&&SC*Iot;o}_?g=} z<7w$G-ifV2ZV2r8qyz*-scivVtCKNMp0??7qZhsEC$gAJmV>leRg8w%JnFTVQGKjv*!Lhf{TBggG7lr$h(@Ew+7k;2%+q z8A?64y)~7T(biCrlK2n-|x|L{RmJ#Xgui8jhR zprfu(Y?mknd$VZo^wDI)7Rn2LN?8vD|KWZ##GDWQgMccvBY^P5n#(m(rbp z0?!YXvG?M{H`(IXG?_={1=^K~>7GfgRm!3QJzrjryNM65|9dkllzL7;777M76%PR> z1=`HIxLYt8JDVAq8ao&{oBluBT3!9&UC{UJfo(PBUX( zP6IZB|3e34;;hT2hLATA=gI4hzVRkp3o@fL$&_u(R&ga=eMS?8LvsKc?zKwUMO(F{ z*5fw7|*%SHHQ z&r6nL`upKf$7P%_@Veu&=k3Jd{eD0=?%v`36!44+cm>4nMSVP6yn0;rJYNmGZgoF( z2)|z`Ug`rMM@9gGe)$F1PQ1Mn15q_w?=9GXk0WA$=f}>_hbM5!VdUfeEeaC3`+(Q~ z)tFaqE^6!T)FTey%lcM|%{+`Q1bBHmN7NjBEUnQO@_oA6a{%0C3BMgHh6@)Dpn|Z- zXO|pvUky%Rm!bl^d>K}Ee9FBmRPe%g3sHW281y;uuJHRy^CFK3eNC0*}xP!#re388#{ zdfzzSc#XT%r?WK(6Zd?EpnkueVfJe13H|73*#YHY3rJOI^EUOk1)Si2*`B}#>|lRP z06f7z-p+})a$=dE99|w@JwAXJg4t^wfTxS=ji?WZUOwR5tH&1bI?w;<@QoPt5&*nF z754W4?kMhshob`E0FJ_aNr2a^3%iURZk|w}ydmIvcfi0uB*)M5@d&ktH&>xH`D4%V zh2^aV@P2W9-SXk2oyxiJ0sQ!5Xc=tu9^N``xZigPczVx?rto4Y)=nh}Za{h;czFb* z{X#l?*iU@7&oy&Q=-c|t%*WfMX)UnE?=0YB|K}=I{)ee!O5an*)9W&f_}V&1gg6!O zFtvAjQUySh8a3j5#g>1`{;-8pNfsf3Ra z;arKE>8YL#@7KifxM|sB#yz=b8;7=_jzWn=UtyE1axlWbkDo#~RN5nH&Z?Bu_VydO z>Mu6QL7V?H(~=!yQQvv|ndmC6GE!=g$=GF^Tl=+FXC1ah;I790dPxEFGu)Ya{5Ck*-V?xGN;wFSNn++`5Dbb>|5j3Xl+N=R5SQHyYK#{`~(b8=SUHy zBcR=8?k;xARU6e!hIRO_opv+pnQhgUqYUg5bV-@Pbn2c_AS3Kk`&zx7>GFnt&v`m3 zee_ax56)c}jt`E`GwQXw^8kaZSTm@tI>q^VNGIxn>?dHz}GmUwql z2T^?om;pLdMtXuwYoD;(bYPOmCRxL3{b>p4r+e$1qZ_`N{}+IMFq6mv_$E+tf>iSW ziCX7yT5Yx%)#r5u2f+X@4Ph=;p65IxBxz5DlrWViMRU8bw|lW|5Pm~vC;o)5IMOFJ zoM6$aD(sWyUdx_`9|vTG)=9)HfG8>Nh|;G4&F z6v4w%_X;LlK~o48VT;G*G0!zWeRl7xaGC79hUdTTw`+r%ehA@#cQ9kpU$=xD2%aP7 z+8(TD7swAtok%<@o&9q*LPeN1Q_xN=jh?(`L)oP(Z?YeJZhHfpU;2i&ZfkGPDkMZQ zzy-tIgw*um*k;RPPHw_BB=^iujKH5DjX&12v{1pe+aR{z%ooLN3+>r`qNGX^QR$H| zgty|C5gK|osm0rz!lSFdtURy*v+(|+u#d-JJ{00+$?o2n9Js4_v)@grLU4(Je*IRVZBapI zmyR9x%;YG$To;g}{(FoV^(`G!B|Yhy5nIiOVXbx@mZR?|+&Uk|yQKD~LL|G*7i46w z{Oh)FQ9pmSR(0e@thGf&o;f&n+#0Cq?hog5^hRv8OG-U>w644`({hQy>@UQ;Zbz)O zN_~59UvhYf`Wd%e?H4e}bxuanv3A<>HZ&-0yCx)UyymW)xN&aR{8l{peZ6@PMZ+Z_ zabx4YZgXNZNp5|ew}vz+S^H-;Rz z?u#X4&uIKw2kq8&DgOtTgd7N$DM*bq353h_G*8gl`3ph^+}Oo#3(NraNQ`d$;2L5F z)vwU+`rS`4YVc3ZSQ9+blt>Kt@q5HnK;{rAV>@}yWQ2c-C7o37MpAd>PAIhfC#UuE z!0@zgDMM4r23V4Y8V!PNGz-Znhn_k@6BZy+81Hsa|?t^aBxDh-pMUzuScw z9L>fY@a9KdIpLLrKP%B8rD1(Yh6e;>eieYyWaA@b-D~faiFzF`Gw`xQbjg37YO!F+ zoH61k&Ng~h%_XbEU(`QgV1dw2*y#o1)4U}sbw!Nc4T4QQq}+lkq%k3qva^MivgyK= zy2FAc*I72hIUp1mKNU!$tah443_HVUPrDAc%2-6;QM1XFg$q!eKxRQOL>{UyF?-H1 zY8?7cg%PIkx!=9eHjUg=#AbI0CKKr!%Da49#3jLd*e${te_jxNVb5X{(^(<)tW7pc z6VDFj@Dx3ZYhq7-GVEI;zRipuVejt&{``sEMV_;2Ae&`mpm`e#p3~Kg+qsxB1U^eM zCf5%m_8R->LX5d=g|*&eZ7epoKcq1+atp@fjxblwgIn0#i<{5hxjQw*#`*5lXiZu` zvnw@7#V%9Y%nv;eeh7w&rGwiBWl7>8&_`Ra+8>NE3`a# zzGGzM(qEv<#|e0=!Hg_w;NI(V{XV04{__t3#ojgZ6+@+cETsg=$|GPWkG}fwAT)G) z{k&JKb9%K*dZAu{*RWN9df#?uFQO7&(U^2`p6AP`GTn+Qi($lL9926h)w(4n3g=j; zhbPQ@?>*WL)Rw`&SI-zrXh=6f3Xv^ZCi_Jr4@L*~Z_Ig8a42wTIGem^#sZkxWR-ca zA+zHba-?1)+m9M*jvA;?S#HaEpws+6^db=;NzFABG?7ZQ>?kns<0CvYFix9gu%M#c z`HTRAI2vkpU?dp(%6I4b8^kLU0xsgdx|Ze=`ZafNv(~}->6RRXPC)RR|$=GD^F^NeM9 zb`AjP=!kegM`td@j^B@Ea|Fx7u~Q^fr`ppn0GH})*ljN5+$?|Tcs4tDNK z%5va%R)EwS*g#^eo$QE;xdYHtgFqwHEC?uJ0VH0+EE z4C6p|h`e@5VJJ*?vD~JJz;8Rk=lcJAa7;fdFd-}w-jrCO4@lZw7y-UJ zJcQSX3>@d&=ICOoPOCy>#Vte!b@#n^&89DD8^a=Jn172Y{4BX0BCW{AWrxeS)q(LzflOkDeR7qm&&EIT1@*OBqF zn{D&OvAU@%#5XoOt}QCxZyOp{Qd-A=4Z^Cv)pN=>(;JvFBGFk&dE*o0-s&y+@<5@9 z`1NT0!b3{&#o~-xp&(Upqo(R~+&_me%fV#OGXsGW?u?wZ;QAWwc3K)9zJ(RGh{oA; zC=wOvW+{XuV8qA^E|AtC+z@Q52;%MuxQH7mx?aWJ7@iYDy1vO29;wBu>UWR>9^UqA zo*E^#RD=mebLcP343{T#hytv>J!yht`cm=h09kJmI7_Nbu3oZq!&?yVxLUw+=f zzu7-w*Y9&Oc|#P8!_P<0MnRcYTV}1*;8^|=Ye=U_EtfmT+@VQ~5tQI?g$U4vK9vYh zva-8+Zp5J5Wo2xXLc?>xoyU!-kO)#du3Fp265+dV(=`Tu=ci_2Ct&+(CcbgN$<_ho z4p#b35+03M8byMd4X=T=#j_(0$|^1C31zfJExmyRG=w9XGkK&rhOH&Go;4J=eZFCq zyS*m*2?MS60JM~LBBoPQo%#Z|k+NYBdjfFQF<`W(GT2bW_(U{8@d2S*L>hl~+e@