diff --git a/CMakeLists.txt b/CMakeLists.txt index d80fc82..a28be1d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -35,8 +35,7 @@ FetchContent_Declare(ArduinoJson ) FetchContent_MakeAvailable(ArduinoJson) - -add_executable(pico-asha +set(ASHA_SRC src/main.cpp src/runtime_settings.cpp src/asha_audio.cpp @@ -51,6 +50,10 @@ add_executable(pico-asha lib/g722/g722_encode.cc ) +set_source_files_properties(${ASHA_SRC} PROPERTIES COMPILE_OPTIONS "-Wall;-Wextra;-Werror") + +add_executable(pico-asha ${ASHA_SRC}) + target_include_directories(pico-asha PUBLIC src/ lib/) option(ENABLE_BLE_AD_DUMP "Enable dumping of advertisement packet data" OFF) diff --git a/lib/g722/g722_encode.cc b/lib/g722/g722_encode.cc index 817f5c0..5a6ad53 100644 --- a/lib/g722/g722_encode.cc +++ b/lib/g722/g722_encode.cc @@ -164,7 +164,7 @@ static void block4(g722_band_t *band, int d) /*- End of function --------------------------------------------------------*/ g722_encode_state_t *g722_encode_init(g722_encode_state_t *s, - unsigned int rate, int options) + unsigned int rate, [[maybe_unused]] int options) { if (s == NULL) { diff --git a/src/asha_audio.hpp b/src/asha_audio.hpp index b3aff42..097364f 100644 --- a/src/asha_audio.hpp +++ b/src/asha_audio.hpp @@ -3,7 +3,7 @@ #include #include -#include "pico/async_context.h" +#include #include "g722/g722_enc_dec.h" #include "PseudoAtomic/RP2040Atomic.hpp" diff --git a/src/asha_bt.cpp b/src/asha_bt.cpp index 43a66f3..ea10c2f 100644 --- a/src/asha_bt.cpp +++ b/src/asha_bt.cpp @@ -1,12 +1,12 @@ -#include "stdio.h" -#include "pico/cyw43_arch.h" -#include "pico/time.h" -#include "hardware/watchdog.h" +#include +#include +#include +#include -#include "pico/stdio_usb.h" -#include "pico/stdio_uart.h" +#include +#include -#include "etl/string.h" +#include #include @@ -52,7 +52,6 @@ static void handle_stdin_line_worker(async_context_t *context, async_when_pendin static void set_data_length(); static void discover_services(); static void finalise_curr_discovery(); -static bool device_db_empty(); static void delete_paired_devices(); static void delete_paired_device(const bd_addr_t addr); @@ -112,7 +111,6 @@ AdvertisingReport::AdvertisingReport(uint8_t* packet, bool extended) void AdvertisingReport::check_if_ha(uint8_t length, const uint8_t * data) { ad_context_t context; - bd_addr_t address; for (ad_iterator_init(&context, length, data) ; ad_iterator_has_more(&context) ; ad_iterator_next(&context)) { uint8_t data_type = ad_iterator_get_data_type(&context); uint8_t size = ad_iterator_get_data_len(&context); @@ -157,7 +155,8 @@ void ScanResult::reset() services_it = services.end(); } -static void handle_bt_audio_pending_worker(async_context_t *context, async_when_pending_worker_t *worker) +static void handle_bt_audio_pending_worker([[maybe_unused]] async_context_t *context, + [[maybe_unused]] async_when_pending_worker_t *worker) { // No need to do anything if no hearing aids are connected! using enum HA::State; @@ -192,7 +191,8 @@ static void handle_bt_audio_pending_worker(async_context_t *context, async_when_ } } -static void handle_stdin_line_worker(async_context_t *context, async_when_pending_worker_t *worker) +static void handle_stdin_line_worker([[maybe_unused]] async_context_t *context, + [[maybe_unused]] async_when_pending_worker_t *worker) { JsonDocument cmd_doc; JsonDocument resp_doc; @@ -404,7 +404,10 @@ static void discover_services() } } -static void hci_event_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size) +static void hci_event_handler(uint8_t packet_type, + [[maybe_unused]] uint16_t channel, + uint8_t *packet, + [[maybe_unused]] uint16_t size) { ASHA_ASSERT_PACKET_TYPE(HCI_EVENT_PACKET); bd_addr_t local_addr; @@ -433,7 +436,7 @@ static void hci_event_handler(uint8_t packet_type, uint16_t channel, uint8_t *pa /* Every time a GAP advertising report is received, handle it here */ case GAP_EVENT_EXTENDED_ADVERTISING_REPORT: LOG_SCAN("Got extended advertising report."); - // Fallthrough + [[fallthrough]]; case GAP_EVENT_ADVERTISING_REPORT: if (scan_state != ScanState::Scan) return; if (hci_ev_type == GAP_EVENT_EXTENDED_ADVERTISING_REPORT) { @@ -468,7 +471,10 @@ static void hci_event_handler(uint8_t packet_type, uint16_t channel, uint8_t *pa sm_request_pairing(curr_scan.ha.conn_handle); break; } + default: + break; } + break; case HCI_EVENT_LE_META: switch(hci_event_le_meta_get_subevent_code(packet)) { case HCI_SUBEVENT_LE_DATA_LENGTH_CHANGE: @@ -518,7 +524,10 @@ static void hci_event_handler(uint8_t packet_type, uint16_t channel, uint8_t *pa } /* Handler for security manager events */ -static void sm_event_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size) { +static void sm_event_handler (uint8_t packet_type, + [[maybe_unused]] uint16_t channel, + uint8_t *packet, + [[maybe_unused]] uint16_t size) { ASHA_ASSERT_PACKET_TYPE(HCI_EVENT_PACKET); auto ev_type = hci_event_packet_get_type(packet); if (scan_state == ScanState::IdentityResolving) { @@ -643,7 +652,10 @@ static void sm_event_handler (uint8_t packet_type, uint16_t channel, uint8_t *pa } } -static void l2cap_cbm_event_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size) +static void l2cap_cbm_event_handler (uint8_t packet_type, + [[maybe_unused]] uint16_t channel, + uint8_t *packet, + [[maybe_unused]] uint16_t size) { if (packet_type != HCI_EVENT_PACKET) return; switch (hci_event_packet_get_type(packet)) { @@ -672,13 +684,26 @@ static void l2cap_cbm_event_handler (uint8_t packet_type, uint16_t channel, uint LOG_ERROR(msg ": 0x%02x", static_cast(res)); \ scan_state = ScanState::Disconnecting; \ gap_disconnect(curr_scan.ha.conn_handle); \ + return; \ }} +#define GATT_COMPLETE_ASSERT(pkt, msg) { \ + if (gatt_event_query_complete_get_att_status((pkt)) != ATT_ERROR_SUCCESS) { \ + LOG_ERROR("%s: 0x%02x", (msg), static_cast(gatt_event_query_complete_get_att_status((pkt)))); \ + scan_state = ScanState::Disconnecting; \ + gap_disconnect(curr_scan.ha.conn_handle); \ + return; \ + } \ +} + /* Handler for reading GATT service and characteristic values and subscribing to the AudioStatusPoint characteristic notification during the connection process. This function can be read in sequence for the order of events */ -static void scan_gatt_event_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size) +static void scan_gatt_event_handler ([[maybe_unused]] uint8_t packet_type, + [[maybe_unused]] uint16_t channel, + uint8_t *packet, + [[maybe_unused]] uint16_t size) { switch (scan_state) { case ScanState::ServiceDiscovery: @@ -706,6 +731,7 @@ static void scan_gatt_event_handler (uint8_t packet_type, uint16_t channel, uint break; case GATT_EVENT_QUERY_COMPLETE: { + GATT_COMPLETE_ASSERT(packet, "ATT error discovering services"); // Older hearing aids may support MFI but not ASHA if (!curr_scan.service_found || curr_scan.services.empty()) { LOG_INFO("ASHA service not found. Continuing scanning"); @@ -757,6 +783,7 @@ static void scan_gatt_event_handler (uint8_t packet_type, uint16_t channel, uint // characteristic.start_handle, characteristic.value_handle, characteristic.end_handle); break; case GATT_EVENT_QUERY_COMPLETE: + GATT_COMPLETE_ASSERT(packet, "ATT error discovering characteristics"); LOG_INFO("Characteristic discovery complete"); curr_scan.services_it++; if (curr_scan.services_it != curr_scan.services.end()) { @@ -785,14 +812,7 @@ static void scan_gatt_event_handler (uint8_t packet_type, uint16_t channel, uint switch (hci_event_packet_get_type(packet)) { case GATT_EVENT_QUERY_COMPLETE: { - auto att_res = gatt_event_query_complete_get_att_status(packet); - if (att_res != ATT_ERROR_SUCCESS) { - LOG_ERROR("Subscribing to GATT Service changed indication failed: 0x%02x", static_cast(att_res)); - scan_state = ScanState::Disconnecting; - gap_disconnect(curr_scan.ha.conn_handle); - return; - } - + GATT_COMPLETE_ASSERT(packet, "ATT error service changed indication"); LOG_INFO("Subscribed to GATT Service changed indication"); // Start reading the Device name characteristic scan_state = ScanState::ReadDeviceName; @@ -819,6 +839,7 @@ static void scan_gatt_event_handler (uint8_t packet_type, uint16_t channel, uint break; } case GATT_EVENT_QUERY_COMPLETE: + GATT_COMPLETE_ASSERT(packet, "ATT error reading device name"); LOG_INFO("Completed value read of Device Name"); // Start reading the Read Only Properties characteristic scan_state = ScanState::ReadROP; @@ -840,6 +861,7 @@ static void scan_gatt_event_handler (uint8_t packet_type, uint16_t channel, uint //curr_scan.device.read_only_props.dump_values(); break; case GATT_EVENT_QUERY_COMPLETE: + GATT_COMPLETE_ASSERT(packet, "ATT error reading ROP"); LOG_INFO("Completed value read of ReadOnlyProperties"); /* Next get the PSM value */ scan_state = ScanState::ReadPSM; @@ -861,6 +883,7 @@ static void scan_gatt_event_handler (uint8_t packet_type, uint16_t channel, uint LOG_INFO("PSM: %d", static_cast(curr_scan.ha.psm)); break; case GATT_EVENT_QUERY_COMPLETE: + GATT_COMPLETE_ASSERT(packet, "ATT error reading PSM"); LOG_INFO("Completed value read of PSM"); curr_scan.ha.rop.print_values(); scan_state = ScanState::Finalizing; @@ -869,10 +892,15 @@ static void scan_gatt_event_handler (uint8_t packet_type, uint16_t channel, uint } break; } + default: + break; } } -static void connected_gatt_event_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size) +static void connected_gatt_event_handler([[maybe_unused]] uint8_t packet_type, + [[maybe_unused]] uint16_t channel, + uint8_t *packet, + [[maybe_unused]] uint16_t size) { switch (hci_event_packet_get_type(packet)) { case GATT_EVENT_NOTIFICATION: @@ -944,21 +972,6 @@ static void finalise_curr_discovery() } } -static bool device_db_empty() -{ - int addr_type; - bd_addr_t addr; - sm_key_t sm_key; - int max_db = le_device_db_max_count(); - for (int i = 0; i < max_db; ++i) { - le_device_db_info(i, &addr_type, addr, sm_key); - if (addr_type != BD_ADDR_TYPE_UNKNOWN) { - return false; - } - } - return true; -} - static void delete_paired_devices() { LOG_INFO("Removing paired devices"); diff --git a/src/asha_bt.hpp b/src/asha_bt.hpp index 1720df0..668b217 100644 --- a/src/asha_bt.hpp +++ b/src/asha_bt.hpp @@ -1,8 +1,8 @@ #pragma once #include -#include "etl/vector.h" -#include "btstack.h" +#include +#include #include "hearing_aid.hpp" diff --git a/src/asha_led.cpp b/src/asha_led.cpp index 87f5a30..de8231c 100644 --- a/src/asha_led.cpp +++ b/src/asha_led.cpp @@ -1,7 +1,7 @@ #include +#include #include "asha_led.hpp" -#include "pico/cyw43_arch.h" namespace asha { @@ -9,6 +9,7 @@ namespace asha LEDManager::LEDManager() { led_worker.user_data = this; + led_worker.do_work = &LEDManager::handle_led_work; } void LEDManager::set_led(LEDManager::State led_state) @@ -34,9 +35,9 @@ void LEDManager::handle_led_work(async_context_t* ctx, async_at_time_worker_t *w ++p.pos; if (p.pos >= p.len) { p.pos = 0; - async_context_add_at_time_worker_in_ms(this_->led_ctx, &this_->led_worker, p.interval_ms + p.delay_ms); + async_context_add_at_time_worker_in_ms(ctx, worker, p.interval_ms + p.delay_ms); } else { - async_context_add_at_time_worker_in_ms(this_->led_ctx, &this_->led_worker, p.interval_ms); + async_context_add_at_time_worker_in_ms(ctx, worker, p.interval_ms); } } diff --git a/src/asha_led.hpp b/src/asha_led.hpp index 6aea705..1513c64 100644 --- a/src/asha_led.hpp +++ b/src/asha_led.hpp @@ -2,7 +2,7 @@ #include -#include "pico/async_context.h" +#include namespace asha { @@ -39,7 +39,7 @@ class LEDManager void disable_curr_led_pattern(); static void handle_led_work(async_context_t* ctx, async_at_time_worker_t *worker); async_context_t *led_ctx = nullptr; - async_at_time_worker_t led_worker = {.do_work = &LEDManager::handle_led_work}; + async_at_time_worker_t led_worker = {}; Pattern curr_pattern = {}; }; diff --git a/src/asha_logging.cpp b/src/asha_logging.cpp index dee9ed2..dffea67 100644 --- a/src/asha_logging.cpp +++ b/src/asha_logging.cpp @@ -1,11 +1,11 @@ -#include "pico/stdio_usb.h" +#include #include "asha_logging.h" namespace asha { -void handle_logging_pending_worker(async_context_t *context, async_when_pending_worker_t *worker) +void handle_logging_pending_worker([[maybe_unused]] async_context_t *context, [[maybe_unused]] async_when_pending_worker_t *worker) { while(!log_buffer.empty() && stdio_usb_connected()) { printf("%s", log_buffer.front().c_str()); diff --git a/src/asha_logging.h b/src/asha_logging.h index b1ddd51..8f73910 100644 --- a/src/asha_logging.h +++ b/src/asha_logging.h @@ -1,15 +1,15 @@ #pragma once -#include "stdio.h" +#include -#include "etl/circular_buffer.h" -#include "etl/string.h" +#include +#include -#include "pico/time.h" -#include "pico/async_context.h" +#include +#include -#include "hci_dump_embedded_stdout.h" -#include "btstack_debug.h" +#include +#include #include "runtime_settings.hpp" namespace asha @@ -34,12 +34,14 @@ static void asha_log(enum LogLevel level, const char* fmt, Arg...args) } else { etl::string line = {}; int len = snprintf(line.data(), line.capacity(), fmt, log_level_to_str(level), to_ms_since_boot(get_absolute_time()), args...); - line.uninitialized_resize(len <= log_line_len ? len : log_line_len); - log_buffer.push(line); - if (logging_ctx) { - async_context_set_work_pending(logging_ctx, &logging_pending_worker); + if (len >= 0) { + line.uninitialized_resize((size_t)len <= log_line_len ? (size_t)len : log_line_len); + log_buffer.push(line); + if (logging_ctx) { + async_context_set_work_pending(logging_ctx, &logging_pending_worker); + } + //printf(fmt, log_level_to_str(level), to_ms_since_boot(get_absolute_time()), args...); } - //printf(fmt, log_level_to_str(level), to_ms_since_boot(get_absolute_time()), args...); } } diff --git a/src/asha_unique_id.hpp b/src/asha_unique_id.hpp index 1597d63..6c79233 100644 --- a/src/asha_unique_id.hpp +++ b/src/asha_unique_id.hpp @@ -1,6 +1,6 @@ #pragma once -#include "pico/unique_id.h" +#include namespace asha { diff --git a/src/asha_usb_serial.hpp b/src/asha_usb_serial.hpp index b8c1c34..a5629ef 100644 --- a/src/asha_usb_serial.hpp +++ b/src/asha_usb_serial.hpp @@ -1,7 +1,7 @@ #pragma once -#include "etl/string.h" -#include "pico/async_context.h" +#include +#include namespace asha { diff --git a/src/hearing_aid.cpp b/src/hearing_aid.cpp index 94a1f62..4467a73 100644 --- a/src/hearing_aid.cpp +++ b/src/hearing_aid.cpp @@ -75,9 +75,7 @@ void HA::subscribe_to_asp_notification() void HA::create_l2cap_channel() { state = State::L2Connecting; - int cx_attempts = 0; uint8_t res = ERROR_CODE_SUCCESS; - do { LOG_INFO("%s: Connecting to L2CAP", side_str); res = l2cap_cbm_create_channel(l2cap_packet_handler, conn_handle, @@ -89,14 +87,9 @@ void HA::create_l2cap_channel() &cid); if (res != ERROR_CODE_SUCCESS) { LOG_ERROR("%s: Failure creating l2cap channel with error code: 0x%02x", side_str, (unsigned int)res); - ++cx_attempts; - } - } while (res != ERROR_CODE_SUCCESS && cx_attempts < 5); - if (res != ERROR_CODE_SUCCESS) { state = State::GATTDisconnect; gap_disconnect(conn_handle); } - } void HA::on_l2cap_channel_created(uint8_t status) @@ -104,7 +97,7 @@ void HA::on_l2cap_channel_created(uint8_t status) if (status != ERROR_CODE_SUCCESS) { LOG_ERROR("%s: L2CAP CoC failed with status code: 0x%02x", side_str, status); // Try again - create_l2cap_channel(); + //create_l2cap_channel(); return; } LOG_INFO("%s: L2CAP CoC channel created", side_str); @@ -275,7 +268,7 @@ void HA::send_audio_packet() write_volume(); state = State::AudioPacketSending; } - // fallthrough + [[fallthrough]]; case State::AudioPacketSending: if (avail_credits == 0) { LOG_INFO("%s: Available credits: 0, restarting stream", side_str); @@ -286,8 +279,9 @@ void HA::send_audio_packet() zero_credit_count = 0; l2cap_send(cid, audio_packet, sdu_size_bytes); } + default: + break; } - } void HA::on_audio_packet_sent() diff --git a/src/hearing_aid.hpp b/src/hearing_aid.hpp index bc5185f..8b4ae81 100644 --- a/src/hearing_aid.hpp +++ b/src/hearing_aid.hpp @@ -3,10 +3,10 @@ #include #include //#include -#include "etl/vector.h" -#include "etl/string.h" +#include +#include -#include "btstack.h" +#include #include "asha_audio.hpp" namespace asha diff --git a/src/main.cpp b/src/main.cpp index d16a6d8..a7589d2 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,10 +1,10 @@ #include -#include "pico/stdio.h" -#include "pico/multicore.h" -#include "pico/flash.h" +#include +#include +#include // TinyUSB -#include "bsp/board.h" -#include "tusb.h" +#include +#include #include "asha_unique_id.hpp" #include "asha_audio.hpp" diff --git a/src/runtime_settings.hpp b/src/runtime_settings.hpp index 9c5ba02..b8063fa 100644 --- a/src/runtime_settings.hpp +++ b/src/runtime_settings.hpp @@ -2,7 +2,7 @@ #include -#include "btstack_tlv.h" +#include namespace asha { diff --git a/src/tusb_config.h b/src/tusb_config.h index 3e78d2d..68b9a6f 100644 --- a/src/tusb_config.h +++ b/src/tusb_config.h @@ -31,7 +31,7 @@ extern "C" { #endif -#include "pico/stdio_usb.h" +#include #include "usb_descriptors.h" //--------------------------------------------------------------------+ diff --git a/src/usb_audio.cpp b/src/usb_audio.cpp index ef582cc..fb9883e 100644 --- a/src/usb_audio.cpp +++ b/src/usb_audio.cpp @@ -27,10 +27,10 @@ #include #include -#include "tusb.h" -#include "usb_descriptors.h" +#include +#include -#include "pico/time.h" +#include "usb_descriptors.h" #include "asha_audio.hpp" #include "asha_usb_serial.hpp" @@ -76,7 +76,7 @@ static int8_t mute[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX + 1] = {}; // +1 for static int16_t volume[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX + 1] = {}; // +1 for master channel 0 // Buffer for microphone data -static int16_t mic_buf[CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ / 2] = {}; +[[maybe_unused]] static int16_t mic_buf[CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ / 2] = {}; // Buffer for speaker data static int16_t spk_buf[CFG_TUD_AUDIO_FUNC_1_EP_OUT_SW_BUF_SZ / 2] = {}; // Speaker data size received in the last frame @@ -100,7 +100,9 @@ static constexpr uint32_t silence_timeout = 10'000ul; void audio_task(void); void serial_task(void); -void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts) +void tud_cdc_line_state_cb([[maybe_unused]] uint8_t itf, + bool dtr, + [[maybe_unused]] bool rts) { if (dtr) { async_context_set_work_pending(logging_ctx, &logging_pending_worker); @@ -181,10 +183,8 @@ static bool tud_audio_clock_get_request(uint8_t rhport, audio_control_request_t } else if (request->bRequest == AUDIO_CS_REQ_RANGE) { - audio_control_range_4_n_t(N_SAMPLE_RATES) rangef = - { - .wNumSubRanges = tu_htole16(N_SAMPLE_RATES) - }; + audio_control_range_4_n_t(N_SAMPLE_RATES) rangef = {}; + rangef.wNumSubRanges = tu_htole16(N_SAMPLE_RATES); TU_LOG1("Clock get %d freq ranges\n", N_SAMPLE_RATES); for(uint8_t i = 0; i < N_SAMPLE_RATES; i++) { @@ -349,8 +349,8 @@ extern "C" bool tud_audio_set_itf_close_EP_cb(uint8_t rhport, tusb_control_reque { (void)rhport; - uint8_t const itf = tu_u16_low(tu_le16toh(p_request->wIndex)); - uint8_t const alt = tu_u16_low(tu_le16toh(p_request->wValue)); + [[maybe_unused]] uint8_t const itf = tu_u16_low(tu_le16toh(p_request->wIndex)); + [[maybe_unused]] uint8_t const alt = tu_u16_low(tu_le16toh(p_request->wValue)); return true; } @@ -358,7 +358,7 @@ extern "C" bool tud_audio_set_itf_close_EP_cb(uint8_t rhport, tusb_control_reque extern "C" bool tud_audio_set_itf_cb(uint8_t rhport, tusb_control_request_t const * p_request) { (void)rhport; - uint8_t const itf = tu_u16_low(tu_le16toh(p_request->wIndex)); + [[maybe_unused]] uint8_t const itf = tu_u16_low(tu_le16toh(p_request->wIndex)); uint8_t const alt = tu_u16_low(tu_le16toh(p_request->wValue)); TU_LOG2("Set interface %d alt %d\n", itf, alt); diff --git a/src/usb_descriptors.cpp b/src/usb_descriptors.cpp index 581948f..dafa941 100644 --- a/src/usb_descriptors.cpp +++ b/src/usb_descriptors.cpp @@ -24,7 +24,7 @@ * */ -#include "tusb.h" +#include #include "usb_descriptors.h" #include "asha_unique_id.hpp" diff --git a/src/util.cpp b/src/util.cpp index b35eb21..5c6529d 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -1,5 +1,5 @@ -#include "stdio.h" -#include "string.h" +#include +#include #include "util.hpp" diff --git a/src/util.hpp b/src/util.hpp index b1061a2..84a715b 100644 --- a/src/util.hpp +++ b/src/util.hpp @@ -1,6 +1,6 @@ #pragma once -#include "btstack_util.h" +#include namespace asha {