From 363328db067741cfc940519745054bab8e76ae30 Mon Sep 17 00:00:00 2001 From: Benedek Kupper Date: Wed, 5 Feb 2025 11:56:22 +0100 Subject: [PATCH 01/11] bugfix for cmake versions.c generation --- CMakeLists.txt | 7 +++---- shared/CMakeLists.txt | 3 +++ 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 54a7e43d..20cfe20a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,10 +16,9 @@ if(NOT CONFIG_DEVICE_ID) endif() project(uhk) -add_library(${PROJECT_NAME}) +add_subdirectory(shared) +add_subdirectory(right/src) +add_subdirectory(device/src) target_link_libraries(${PROJECT_NAME} PUBLIC zephyr_interface ) -add_subdirectory(device/src) -add_subdirectory(right/src) -add_subdirectory(shared) diff --git a/shared/CMakeLists.txt b/shared/CMakeLists.txt index 99acfa65..1edf5f80 100644 --- a/shared/CMakeLists.txt +++ b/shared/CMakeLists.txt @@ -1,3 +1,6 @@ +# the library target is created here, so version generation will work without extra steps +add_library(${PROJECT_NAME}) + target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} # this really needs to be changed when time and restructuring permits From a0dfb6def1ae8deea55242542dd107fa38607b6b Mon Sep 17 00:00:00 2001 From: Benedek Kupper Date: Wed, 5 Feb 2025 12:19:01 +0100 Subject: [PATCH 02/11] shell: fix missing commands --- device/src/shell.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/device/src/shell.c b/device/src/shell.c index 82ba77e8..59d59504 100644 --- a/device/src/shell.c +++ b/device/src/shell.c @@ -192,7 +192,7 @@ void InitShell(void) SHELL_CMD_ARG(gamepad, NULL, "switch gamepad on/off", cmd_uhk_gamepad, 1, 1), SHELL_CMD_ARG(passkey, NULL, "send passkey for bluetooth pairing", cmd_uhk_passkey, 2, 0), SHELL_CMD_ARG(btunpair, NULL, "unpair bluetooth devices", cmd_uhk_btunpair, 1, 1), - [10]=SHELL_CMD_ARG(connections, NULL, "list BLE connections", cmd_uhk_connections, 1, 0), + SHELL_CMD_ARG(connections, NULL, "list BLE connections", cmd_uhk_connections, 1, 0), SHELL_SUBCMD_SET_END); SHELL_CMD_REGISTER(uhk, &uhk_cmds, "UHK commands", NULL); From 5800ef321786cffc36052c8cfd63222b43a04317 Mon Sep 17 00:00:00 2001 From: Benedek Kupper Date: Wed, 5 Feb 2025 14:12:47 +0100 Subject: [PATCH 03/11] bt: left uses directed advertising, right advertises HID only --- device/src/bt_advertise.c | 97 ++++++++------------------------------- device/src/bt_advertise.h | 10 +--- device/src/bt_manager.c | 4 +- device/src/bt_pair.c | 2 +- right/src/stubs.c | 3 +- right/src/stubs.h | 3 +- 6 files changed, 27 insertions(+), 92 deletions(-) diff --git a/device/src/bt_advertise.c b/device/src/bt_advertise.c index 853d654f..596f8352 100644 --- a/device/src/bt_advertise.c +++ b/device/src/bt_advertise.c @@ -7,15 +7,14 @@ #include "event_scheduler.h" #include "bt_scan.h" -#undef DEVICE_NAME -#define DEVICE_NAME CONFIG_BT_DEVICE_NAME -#define DEVICE_NAME_LEN (sizeof(DEVICE_NAME) - 1) +#define ADV_DEVICE_NAME CONFIG_BT_DEVICE_NAME +#define ADV_DEVICE_NAME_LEN (sizeof(CONFIG_BT_DEVICE_NAME) - 1) // Advertisement packets #define AD_NUS_DATA \ BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)), \ - BT_DATA(BT_DATA_NAME_COMPLETE, DEVICE_NAME, DEVICE_NAME_LEN), + BT_DATA(BT_DATA_NAME_COMPLETE, ADV_DEVICE_NAME, ADV_DEVICE_NAME_LEN), #define AD_HID_DATA \ BT_DATA_BYTES(BT_DATA_GAP_APPEARANCE, (CONFIG_BT_DEVICE_APPEARANCE >> 0) & 0xff, \ @@ -25,107 +24,51 @@ BT_UUID_16_ENCODE(BT_UUID_BAS_VAL)), static const struct bt_data adNus[] = {AD_NUS_DATA}; - static const struct bt_data adHid[] = {AD_HID_DATA}; -static const struct bt_data adNusHid[] = {AD_NUS_DATA AD_HID_DATA}; - // Scan response packets #define SD_NUS_DATA BT_DATA_BYTES(BT_DATA_UUID128_ALL, BT_UUID_NUS_VAL), -#define SD_HID_DATA BT_DATA(BT_DATA_NAME_COMPLETE, DEVICE_NAME, DEVICE_NAME_LEN), +#define SD_HID_DATA BT_DATA(BT_DATA_NAME_COMPLETE, ADV_DEVICE_NAME, ADV_DEVICE_NAME_LEN), static const struct bt_data sdNus[] = {SD_NUS_DATA}; - static const struct bt_data sdHid[] = {SD_HID_DATA}; -static const struct bt_data sdNusHid[] = {SD_NUS_DATA SD_HID_DATA}; - -static struct bt_le_adv_param advertisementParams[] = BT_LE_ADV_CONN; - -static void setFilters() { - bt_le_filter_accept_list_clear(); +int BtAdvertise_Start(void) +{ + int err = 0; + // directed advertising + static struct bt_le_adv_param adv_param; if (DEVICE_IS_UHK80_RIGHT) { - if (BtConn_UnusedPeripheralConnectionCount() <= 1 && SelectedHostConnectionId != ConnectionId_Invalid) { - bt_le_filter_accept_list_add(&HostConnection(SelectedHostConnectionId)->bleAddress); - advertisementParams->options = BT_LE_ADV_OPT_FILTER_CONN; - } else { - advertisementParams->options = BT_LE_ADV_OPT_NONE; - } - } -} + adv_param = *BT_LE_ADV_CONN_ONE_TIME; -uint8_t BtAdvertise_Start(uint8_t adv_type) -{ - setFilters(); + err = bt_le_adv_start(&adv_param, adHid, ARRAY_SIZE(adHid), sdHid, ARRAY_SIZE(sdHid)); + + } else if (DEVICE_IS_UHK80_LEFT) { + adv_param = *BT_LE_ADV_CONN_DIR_LOW_DUTY(&HostConnection(ConnectionId_NusClientRight)->bleAddress); + // adv_param.options |= BT_LE_ADV_OPT_DIR_ADDR_RPA; + err = bt_le_adv_start(&adv_param, adNus, ARRAY_SIZE(adNus), sdNus, ARRAY_SIZE(sdNus)); - int err; - const char *adv_type_string; - if (adv_type == (ADVERTISE_NUS | ADVERTISE_HID)) { - adv_type_string = "NUS and HID"; - err = bt_le_adv_start( - BT_LE_ADV_CONN, adNusHid, ARRAY_SIZE(adNusHid), sdNusHid, ARRAY_SIZE(sdNusHid)); - } else if (adv_type == ADVERTISE_NUS) { - adv_type_string = "NUS"; - err = bt_le_adv_start(BT_LE_ADV_CONN, adNus, ARRAY_SIZE(adNus), sdNus, ARRAY_SIZE(sdNus)); - } else if (adv_type == ADVERTISE_HID) { - adv_type_string = "HID"; - err = bt_le_adv_start(BT_LE_ADV_CONN, adHid, ARRAY_SIZE(adHid), sdHid, ARRAY_SIZE(sdHid)); } else { - printk("Attempted to start advertising without any type! Ignoring.\n"); return 0; } if (err == 0) { - printk("%s advertising successfully started\n", adv_type_string); + printk("Advertising successfully started\n"); return 0; } else if (err == -EALREADY) { - printk("%s advertising continued\n", adv_type_string); + printk("Advertising continued\n"); return 0; } else { - printk("%s advertising failed to start (err %d), free connections: %d\n", adv_type_string, err, BtConn_UnusedPeripheralConnectionCount()); + printk("Advertising failed to start (err %d), free connections: %d\n", err, BtConn_UnusedPeripheralConnectionCount()); return err; } } -void BtAdvertise_Stop() { +void BtAdvertise_Stop(void) { int err = bt_le_adv_stop(); if (err) { printk("Advertising failed to stop (err %d)\n", err); } } - -static uint8_t connectedHidCount() { - uint8_t connectedHids = 0; - for (uint8_t peerId = PeerIdFirstHost; peerId <= PeerIdLastHost; peerId++) { - if (Peers[peerId].conn && Connections_Type(Peers[peerId].connectionId) == ConnectionType_BtHid) { - connectedHids++; - } - } - return connectedHids; -} - -uint8_t BtAdvertise_Type() { - switch (DEVICE_ID) { - case DeviceId_Uhk80_Left: - return ADVERTISE_NUS; - case DeviceId_Uhk80_Right: - if (BtConn_UnusedPeripheralConnectionCount() > 0) { - if (connectedHidCount() > 0) { - return ADVERTISE_NUS; - } else { - return ADVERTISE_NUS | ADVERTISE_HID; - } - } else { - printk("Current slot count %d, not advertising\n", BtConn_UnusedPeripheralConnectionCount()); - BtConn_ListCurrentConnections(); - return 0; - } - case DeviceId_Uhk_Dongle: - return 0; - default: - printk("unknown device!\n"); - return 0; - } -} diff --git a/device/src/bt_advertise.h b/device/src/bt_advertise.h index 7f67e9e5..ca6aea54 100644 --- a/device/src/bt_advertise.h +++ b/device/src/bt_advertise.h @@ -5,15 +5,9 @@ #include -// Macros: - - #define ADVERTISE_NUS (1 << 0) - #define ADVERTISE_HID (1 << 1) - // Functions: - uint8_t BtAdvertise_Start(uint8_t adv_type); - void BtAdvertise_Stop(); - uint8_t BtAdvertise_Type(); + int BtAdvertise_Start(void); + void BtAdvertise_Stop(void); #endif // __BT_ADVERTISE_H__ diff --git a/device/src/bt_manager.c b/device/src/bt_manager.c index 629de63c..42381ef5 100644 --- a/device/src/bt_manager.c +++ b/device/src/bt_manager.c @@ -52,7 +52,7 @@ void BtManager_StartBt() { } if (DEVICE_IS_UHK80_LEFT || DEVICE_IS_UHK80_RIGHT) { - BtAdvertise_Start(BtAdvertise_Type()); + BtAdvertise_Start(); } if (DEVICE_IS_UHK80_RIGHT || DEVICE_IS_UHK_DONGLE) { @@ -125,7 +125,7 @@ void BtManager_StartScanningAndAdvertising() { } if (leftShouldAdvertise || rightShouldAdvertise) { - err = BtAdvertise_Start(BtAdvertise_Type()); + err = BtAdvertise_Start(); success &= err == 0; } diff --git a/device/src/bt_pair.c b/device/src/bt_pair.c index 7e4298b1..ac2a7ab5 100644 --- a/device/src/bt_pair.c +++ b/device/src/bt_pair.c @@ -66,7 +66,7 @@ void BtPair_PairPeripheral() { pairingAsCentral = false; Settings_Reload(); bt_le_oob_set_sc_flag(true); - BtAdvertise_Start(ADVERTISE_NUS); + BtAdvertise_Start(); printk ("Waiting for central to pair to me.\n"); EventScheduler_Reschedule(k_uptime_get_32() + PAIRING_TIMEOUT, EventSchedulerEvent_EndBtPairing, "Oob pairing timeout."); } diff --git a/right/src/stubs.c b/right/src/stubs.c index cf784537..2da01dda 100644 --- a/right/src/stubs.c +++ b/right/src/stubs.c @@ -23,8 +23,7 @@ ATTRS void BtManager_RestartBt() {}; ATTRS void DongleLeds_Update(void) {}; ATTRS void BtPair_ClearUnknownBonds() {}; - ATTRS uint8_t BtAdvertise_Start(uint8_t adv_type) { return 0; }; - ATTRS uint8_t BtAdvertise_Type() { return 0; }; + ATTRS int BtAdvertise_Start(void) { return 0; }; ATTRS int BtScan_Start(void) { return 0; }; ATTRS void BtManager_StartScanningAndAdvertising() {}; ATTRS void BtConn_UpdateHostConnectionPeerAllocations() {}; diff --git a/right/src/stubs.h b/right/src/stubs.h index e0ef85c0..469ef154 100644 --- a/right/src/stubs.h +++ b/right/src/stubs.h @@ -43,8 +43,7 @@ extern void BtManager_RestartBt(); extern void DongleLeds_Update(void); extern void BtPair_ClearUnknownBonds(); - extern uint8_t BtAdvertise_Start(uint8_t adv_type); - extern uint8_t BtAdvertise_Type(); + extern int BtAdvertise_Start(void); extern int BtScan_Start(void); extern void BtManager_StartScanningAndAdvertising(); extern void BtConn_UpdateHostConnectionPeerAllocations(); From ee1bca1c94b4b8509ed6cf57d0766098331c2088 Mon Sep 17 00:00:00 2001 From: Karel Tucek Date: Wed, 12 Feb 2025 10:05:27 +0100 Subject: [PATCH 04/11] Restore the ble advertising type computation. --- device/src/bt_advertise.c | 115 ++++++++++++++++++++++++++++++------ device/src/bt_advertise.h | 19 +++++- device/src/bt_conn.c | 2 +- device/src/bt_manager.c | 9 ++- device/src/bt_pair.c | 2 +- right/src/host_connection.h | 12 ++-- right/src/stubs.c | 4 +- right/src/stubs.h | 2 - 8 files changed, 130 insertions(+), 35 deletions(-) diff --git a/device/src/bt_advertise.c b/device/src/bt_advertise.c index 596f8352..97a76e64 100644 --- a/device/src/bt_advertise.c +++ b/device/src/bt_advertise.c @@ -4,8 +4,6 @@ #include "bt_conn.h" #include "connections.h" #include "device.h" -#include "event_scheduler.h" -#include "bt_scan.h" #define ADV_DEVICE_NAME CONFIG_BT_DEVICE_NAME #define ADV_DEVICE_NAME_LEN (sizeof(CONFIG_BT_DEVICE_NAME) - 1) @@ -35,33 +33,57 @@ static const struct bt_data adHid[] = {AD_HID_DATA}; static const struct bt_data sdNus[] = {SD_NUS_DATA}; static const struct bt_data sdHid[] = {SD_HID_DATA}; -int BtAdvertise_Start(void) +static const char * advertisingString(uint8_t advType) { + switch (advType) { + case ADVERTISE_NUS: + return "NUS"; + case ADVERTISE_HID: + return "HID"; + case ADVERTISE_NUS | ADVERTISE_HID: + return "HID \"and NUS\""; + case ADVERTISE_DIRECTED_NUS: + return "Directed NUS"; + default: + return "None"; + } +} + +uint8_t BtAdvertise_Start(adv_config_t advConfig) { int err = 0; - // directed advertising - static struct bt_le_adv_param adv_param; - if (DEVICE_IS_UHK80_RIGHT) { - adv_param = *BT_LE_ADV_CONN_ONE_TIME; - - err = bt_le_adv_start(&adv_param, adHid, ARRAY_SIZE(adHid), sdHid, ARRAY_SIZE(sdHid)); - } else if (DEVICE_IS_UHK80_LEFT) { - adv_param = *BT_LE_ADV_CONN_DIR_LOW_DUTY(&HostConnection(ConnectionId_NusClientRight)->bleAddress); - // adv_param.options |= BT_LE_ADV_OPT_DIR_ADDR_RPA; - err = bt_le_adv_start(&adv_param, adNus, ARRAY_SIZE(adNus), sdNus, ARRAY_SIZE(sdNus)); + const char * advTypeString = advertisingString(advConfig.advType); - } else { - return 0; + // Start advertising + static struct bt_le_adv_param advParam; + switch (advConfig.advType) { + case ADVERTISE_HID: + case ADVERTISE_NUS | ADVERTISE_HID: + /* our devices don't check service uuids, so hid advertisement effectively advertises nus too */ + advParam = *BT_LE_ADV_CONN_ONE_TIME; + err = bt_le_adv_start(&advParam, adHid, ARRAY_SIZE(adHid), sdHid, ARRAY_SIZE(sdHid)); + break; + case ADVERTISE_NUS: + advParam = *BT_LE_ADV_CONN_ONE_TIME; + err = bt_le_adv_start(&advParam, adNus, ARRAY_SIZE(adNus), sdNus, ARRAY_SIZE(sdNus)); + break; + case ADVERTISE_DIRECTED_NUS: + advParam = *BT_LE_ADV_CONN_DIR_LOW_DUTY(advConfig.addr); + err = bt_le_adv_start(&advParam, adNus, ARRAY_SIZE(adNus), sdNus, ARRAY_SIZE(sdNus)); + default: + printk("Adv: Attempted to start advertising without any type! Ignoring.\n"); + return 0; } + // Log it if (err == 0) { - printk("Advertising successfully started\n"); + printk("Adv: %s advertising successfully started\n", advTypeString); return 0; } else if (err == -EALREADY) { - printk("Advertising continued\n"); + printk("Adv: %s advertising continued\n", advTypeString); return 0; } else { - printk("Advertising failed to start (err %d), free connections: %d\n", err, BtConn_UnusedPeripheralConnectionCount()); + printk("Adv: %s advertising failed to start (err %d), free connections: %d\n", advTypeString, err, BtConn_UnusedPeripheralConnectionCount()); return err; } } @@ -69,6 +91,61 @@ int BtAdvertise_Start(void) void BtAdvertise_Stop(void) { int err = bt_le_adv_stop(); if (err) { - printk("Advertising failed to stop (err %d)\n", err); + printk("Adv: Advertising failed to stop (err %d)\n", err); } } + +static uint8_t connectedHidCount() { + uint8_t connectedHids = 0; + for (uint8_t peerId = PeerIdFirstHost; peerId <= PeerIdLastHost; peerId++) { + if (Peers[peerId].conn && Connections_Type(Peers[peerId].connectionId) == ConnectionType_BtHid) { + connectedHids++; + } + } + return connectedHids; +} + +#define ADVERTISEMENT(TYPE) ((adv_config_t) { .advType = TYPE }) +#define ADVERTISEMENT_DIRECT_NUS(ADDR) ((adv_config_t) { .advType = ADVERTISE_DIRECTED_NUS, .addr = ADDR }) + +adv_config_t BtAdvertise_Config() { + switch (DEVICE_ID) { + case DeviceId_Uhk80_Left: + return ADVERTISEMENT_DIRECT_NUS(&Peers[PeerIdRight].addr); + + case DeviceId_Uhk80_Right: + if (BtConn_UnusedPeripheralConnectionCount() > 0) { + if (BtConn_UnusedPeripheralConnectionCount() <= 1 && SelectedHostConnectionId != ConnectionId_Invalid) { + /* we need to reserve last peripheral slot for a specific target */ + connection_type_t selectedConnectionType = Connections_Type(SelectedHostConnectionId); + if (selectedConnectionType == ConnectionType_NusDongle) { + return ADVERTISEMENT_DIRECT_NUS(&HostConnection(SelectedHostConnectionId)->bleAddress); + } else if (selectedConnectionType == ConnectionType_BtHid) { + return ADVERTISEMENT(ADVERTISE_HID); + } else { + printk("Adv: Selected connection is neither BLE HID nor NUS. Can't advertise!"); + return ADVERTISEMENT( 0 ); + } + } + else if (connectedHidCount() > 0) { + /** we can't handle multiple HID connections, so don't advertise it when one HID is already connected */ + return ADVERTISEMENT(ADVERTISE_NUS); + } else { + /** we can connect both NUS and HID */ + return ADVERTISEMENT(ADVERTISE_NUS | ADVERTISE_HID); + } + } else { + /** advertising needs a peripheral slot. When it is not free and we try to advertise, it will fail, and our code will try to + * disconnect other devices in order to restore proper function. */ + printk("Adv: Current slot count is zero, not advertising!\n"); + BtConn_ListCurrentConnections(); + return ADVERTISEMENT( 0 ); + } + case DeviceId_Uhk_Dongle: + return ADVERTISEMENT( 0 ); + default: + printk("unknown device!\n"); + return ADVERTISEMENT( 0 ); + } +} + diff --git a/device/src/bt_advertise.h b/device/src/bt_advertise.h index ca6aea54..c058094d 100644 --- a/device/src/bt_advertise.h +++ b/device/src/bt_advertise.h @@ -4,10 +4,27 @@ // Includes: #include + #include + #include "shared/attributes.h" + +// Macros: + + #define ADVERTISE_NUS (1 << 0) + #define ADVERTISE_HID (1 << 1) + #define ADVERTISE_DIRECTED_NUS (1 << 2) + +// Typedefs: + + typedef struct { + uint8_t advType; + bt_addr_le_t* addr; + } ATTR_PACKED adv_config_t; + // Functions: - int BtAdvertise_Start(void); + uint8_t BtAdvertise_Start(adv_config_t advConfig); void BtAdvertise_Stop(void); + adv_config_t BtAdvertise_Config(); #endif // __BT_ADVERTISE_H__ diff --git a/device/src/bt_conn.c b/device/src/bt_conn.c index 1c7cf756..0cd0e8f5 100644 --- a/device/src/bt_conn.c +++ b/device/src/bt_conn.c @@ -695,7 +695,7 @@ uint8_t BtConn_UnusedPeripheralConnectionCount() { return count; } -static void disconnectOldestHost() { +ATTR_UNUSED static void disconnectOldestHost() { uint32_t oldestSwitchover = UINT32_MAX; uint8_t oldestPeerId = PeerIdUnknown; for (uint8_t peerId = PeerIdFirstHost; peerId <= PeerIdLastHost; peerId++) { diff --git a/device/src/bt_manager.c b/device/src/bt_manager.c index 42381ef5..8c5d4f27 100644 --- a/device/src/bt_manager.c +++ b/device/src/bt_manager.c @@ -52,7 +52,7 @@ void BtManager_StartBt() { } if (DEVICE_IS_UHK80_LEFT || DEVICE_IS_UHK80_RIGHT) { - BtAdvertise_Start(); + BtAdvertise_Start(BtAdvertise_Config()); } if (DEVICE_IS_UHK80_RIGHT || DEVICE_IS_UHK_DONGLE) { @@ -124,15 +124,20 @@ void BtManager_StartScanningAndAdvertising() { printk("Starting %s, try %d!\n", label, try); } +#ifdef CONFIG_BT_PERIPHERAL if (leftShouldAdvertise || rightShouldAdvertise) { - err = BtAdvertise_Start(); + err = BtAdvertise_Start(BtAdvertise_Config()); success &= err == 0; } +#endif +#ifdef CONFIG_BT_CENTRAL if (rightShouldScan || dongleShouldScan) { err = BtScan_Start(); success &= err == 0; } +#endif + if (!success && try > 0) { BtConn_DisconnectAll(); diff --git a/device/src/bt_pair.c b/device/src/bt_pair.c index ac2a7ab5..ced0da35 100644 --- a/device/src/bt_pair.c +++ b/device/src/bt_pair.c @@ -66,7 +66,7 @@ void BtPair_PairPeripheral() { pairingAsCentral = false; Settings_Reload(); bt_le_oob_set_sc_flag(true); - BtAdvertise_Start(); + BtAdvertise_Start((adv_config_t) { .advType = ADVERTISE_NUS }); printk ("Waiting for central to pair to me.\n"); EventScheduler_Reschedule(k_uptime_get_32() + PAIRING_TIMEOUT, EventSchedulerEvent_EndBtPairing, "Oob pairing timeout."); } diff --git a/right/src/host_connection.h b/right/src/host_connection.h index f8a358a8..fb7766da 100644 --- a/right/src/host_connection.h +++ b/right/src/host_connection.h @@ -36,12 +36,12 @@ // Typedefs: typedef enum { - HostConnectionType_Empty, - HostConnectionType_UsbHidRight, - HostConnectionType_UsbHidLeft, - HostConnectionType_BtHid, - HostConnectionType_Dongle, - HostConnectionType_NewBtHid, + HostConnectionType_Empty = 0, + HostConnectionType_UsbHidRight = 1, + HostConnectionType_UsbHidLeft = 2, + HostConnectionType_BtHid = 3, + HostConnectionType_Dongle = 4, + HostConnectionType_NewBtHid = 5, HostConnectionType_Count, } host_connection_type_t; diff --git a/right/src/stubs.c b/right/src/stubs.c index 2da01dda..6470e40e 100644 --- a/right/src/stubs.c +++ b/right/src/stubs.c @@ -23,10 +23,8 @@ ATTRS void BtManager_RestartBt() {}; ATTRS void DongleLeds_Update(void) {}; ATTRS void BtPair_ClearUnknownBonds() {}; - ATTRS int BtAdvertise_Start(void) { return 0; }; - ATTRS int BtScan_Start(void) { return 0; }; ATTRS void BtManager_StartScanningAndAdvertising() {}; ATTRS void BtConn_UpdateHostConnectionPeerAllocations() {}; ATTRS void Oled_RequestRedraw() {}; ATTRS void RoundTripTest_Run() {}; - ATTRS void PairingScreen_Feedback(bool success) {}; \ No newline at end of file + ATTRS void PairingScreen_Feedback(bool success) {}; diff --git a/right/src/stubs.h b/right/src/stubs.h index 469ef154..6944e4af 100644 --- a/right/src/stubs.h +++ b/right/src/stubs.h @@ -43,8 +43,6 @@ extern void BtManager_RestartBt(); extern void DongleLeds_Update(void); extern void BtPair_ClearUnknownBonds(); - extern int BtAdvertise_Start(void); - extern int BtScan_Start(void); extern void BtManager_StartScanningAndAdvertising(); extern void BtConn_UpdateHostConnectionPeerAllocations(); extern void Oled_RequestRedraw(); From 4e4e26531de87b9644db5bcb0e33b3f9d434b50f Mon Sep 17 00:00:00 2001 From: Karel Tucek Date: Wed, 12 Feb 2025 12:37:27 +0100 Subject: [PATCH 05/11] Use normal advertising as directed doesn't work. --- device/src/bt_advertise.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/device/src/bt_advertise.c b/device/src/bt_advertise.c index 97a76e64..ba329815 100644 --- a/device/src/bt_advertise.c +++ b/device/src/bt_advertise.c @@ -111,7 +111,9 @@ static uint8_t connectedHidCount() { adv_config_t BtAdvertise_Config() { switch (DEVICE_ID) { case DeviceId_Uhk80_Left: - return ADVERTISEMENT_DIRECT_NUS(&Peers[PeerIdRight].addr); + // TODO: fix direct advertisement? + // return ADVERTISEMENT_DIRECT_NUS(&Peers[PeerIdRight].addr); + return ADVERTISEMENT(ADVERTISE_NUS); case DeviceId_Uhk80_Right: if (BtConn_UnusedPeripheralConnectionCount() > 0) { @@ -119,7 +121,9 @@ adv_config_t BtAdvertise_Config() { /* we need to reserve last peripheral slot for a specific target */ connection_type_t selectedConnectionType = Connections_Type(SelectedHostConnectionId); if (selectedConnectionType == ConnectionType_NusDongle) { - return ADVERTISEMENT_DIRECT_NUS(&HostConnection(SelectedHostConnectionId)->bleAddress); + // TODO: fix direct advertisement? + // return ADVERTISEMENT_DIRECT_NUS(&HostConnection(SelectedHostConnectionId)->bleAddress); + return ADVERTISEMENT(ADVERTISE_NUS); } else if (selectedConnectionType == ConnectionType_BtHid) { return ADVERTISEMENT(ADVERTISE_HID); } else { From 1e05cf338e2c0db16a6f457f6d2914580a80f6a7 Mon Sep 17 00:00:00 2001 From: Karel Tucek Date: Wed, 12 Feb 2025 12:50:41 +0100 Subject: [PATCH 06/11] Aesthetic refactors. --- device/src/bt_advertise.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/device/src/bt_advertise.c b/device/src/bt_advertise.c index ba329815..a9223393 100644 --- a/device/src/bt_advertise.c +++ b/device/src/bt_advertise.c @@ -68,8 +68,13 @@ uint8_t BtAdvertise_Start(adv_config_t advConfig) err = bt_le_adv_start(&advParam, adNus, ARRAY_SIZE(adNus), sdNus, ARRAY_SIZE(sdNus)); break; case ADVERTISE_DIRECTED_NUS: - advParam = *BT_LE_ADV_CONN_DIR_LOW_DUTY(advConfig.addr); + + advParam = *BT_LE_ADV_CONN_ONE_TIME; err = bt_le_adv_start(&advParam, adNus, ARRAY_SIZE(adNus), sdNus, ARRAY_SIZE(sdNus)); + + // TODO: fix and reenable this? + // advParam = *BT_LE_ADV_CONN_DIR_LOW_DUTY(advConfig.addr); + // err = bt_le_adv_start(&advParam, adNus, ARRAY_SIZE(adNus), sdNus, ARRAY_SIZE(sdNus)); default: printk("Adv: Attempted to start advertising without any type! Ignoring.\n"); return 0; @@ -111,9 +116,7 @@ static uint8_t connectedHidCount() { adv_config_t BtAdvertise_Config() { switch (DEVICE_ID) { case DeviceId_Uhk80_Left: - // TODO: fix direct advertisement? - // return ADVERTISEMENT_DIRECT_NUS(&Peers[PeerIdRight].addr); - return ADVERTISEMENT(ADVERTISE_NUS); + return ADVERTISEMENT_DIRECT_NUS(&Peers[PeerIdRight].addr); case DeviceId_Uhk80_Right: if (BtConn_UnusedPeripheralConnectionCount() > 0) { @@ -121,9 +124,7 @@ adv_config_t BtAdvertise_Config() { /* we need to reserve last peripheral slot for a specific target */ connection_type_t selectedConnectionType = Connections_Type(SelectedHostConnectionId); if (selectedConnectionType == ConnectionType_NusDongle) { - // TODO: fix direct advertisement? - // return ADVERTISEMENT_DIRECT_NUS(&HostConnection(SelectedHostConnectionId)->bleAddress); - return ADVERTISEMENT(ADVERTISE_NUS); + return ADVERTISEMENT_DIRECT_NUS(&HostConnection(SelectedHostConnectionId)->bleAddress); } else if (selectedConnectionType == ConnectionType_BtHid) { return ADVERTISEMENT(ADVERTISE_HID); } else { From 051e7ea507100089e78dce9b674ef343e20e812c Mon Sep 17 00:00:00 2001 From: Karel Tucek Date: Wed, 12 Feb 2025 13:07:18 +0100 Subject: [PATCH 07/11] Fix dongle leds. --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 20cfe20a..033c0b06 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,8 +17,8 @@ endif() project(uhk) add_subdirectory(shared) -add_subdirectory(right/src) add_subdirectory(device/src) +add_subdirectory(right/src) target_link_libraries(${PROJECT_NAME} PUBLIC zephyr_interface ) From 90cd19e0c4a9e0eb155ebddc2d19d2a0a5c68d0b Mon Sep 17 00:00:00 2001 From: Karel Tucek Date: Wed, 12 Feb 2025 14:43:33 +0100 Subject: [PATCH 08/11] Fix left side peripheral count. --- device/CMakePresets.json | 4 ++-- device/prj.conf.overlays/nrf_shared.conf | 6 ++---- device/prj.conf.overlays/right.conf | 3 +++ 3 files changed, 7 insertions(+), 6 deletions(-) create mode 100644 device/prj.conf.overlays/right.conf diff --git a/device/CMakePresets.json b/device/CMakePresets.json index ae40300c..e28b6c47 100644 --- a/device/CMakePresets.json +++ b/device/CMakePresets.json @@ -44,7 +44,7 @@ "BOARD": "uhk-80-right", "BOARD_ROOT": "${sourceParentDir}/", "mcuboot_OVERLAY_CONFIG": "${sourceDir}/child_image/mcuboot.conf;${sourceDir}/child_image/uhk-80-right.mcuboot.conf", - "EXTRA_CONF_FILE": "${sourceDir}/prj.conf.overlays/nrf_shared.conf;${sourceDir}/prj.conf.overlays/c2usb.conf;${sourceDir}/prj.conf.overlays/uhk-80.conf;${sourceDir}/prj.conf.overlays/ble_nus.conf;${sourceDir}/prj.conf.overlays/ble_nus_client.conf;${sourceDir}/prj.conf.overlays/ble_hid.conf" + "EXTRA_CONF_FILE": "${sourceDir}/prj.conf.overlays/nrf_shared.conf;${sourceDir}/prj.conf.overlays/c2usb.conf;${sourceDir}/prj.conf.overlays/uhk-80.conf;${sourceDir}/prj.conf.overlays/ble_nus.conf;${sourceDir}/prj.conf.overlays/ble_nus_client.conf;${sourceDir}/prj.conf.overlays/ble_hid.conf;${sourceDir}/prj.conf.overlays/right.conf" } }, { @@ -74,4 +74,4 @@ } } ] -} \ No newline at end of file +} diff --git a/device/prj.conf.overlays/nrf_shared.conf b/device/prj.conf.overlays/nrf_shared.conf index ba52c6f1..b0fc034a 100644 --- a/device/prj.conf.overlays/nrf_shared.conf +++ b/device/prj.conf.overlays/nrf_shared.conf @@ -17,10 +17,8 @@ CONFIG_BT_SMP=y CONFIG_BT_L2CAP_TX_BUF_COUNT=5 -# Todo: place these where they belong -# config for right half host switching -CONFIG_BT_MAX_CONN=4 -CONFIG_BT_CTLR_SDC_PERIPHERAL_COUNT=3 +CONFIG_BT_MAX_CONN=2 +CONFIG_BT_CTLR_SDC_PERIPHERAL_COUNT=1 CONFIG_BT_FILTER_ACCEPT_LIST=y diff --git a/device/prj.conf.overlays/right.conf b/device/prj.conf.overlays/right.conf new file mode 100644 index 00000000..215f3fa5 --- /dev/null +++ b/device/prj.conf.overlays/right.conf @@ -0,0 +1,3 @@ +# config for right half host switching +CONFIG_BT_MAX_CONN=4 +CONFIG_BT_CTLR_SDC_PERIPHERAL_COUNT=3 From 4524f08a107c135fa0db9ca3cb52500e4d758beb Mon Sep 17 00:00:00 2001 From: Karel Tucek Date: Wed, 12 Feb 2025 16:08:14 +0100 Subject: [PATCH 09/11] Name advertisements better and fix the left advertisement conditions. --- device/src/bt_advertise.c | 35 ++++++++++++++++++++++++----------- device/src/bt_conn.c | 6 +++++- 2 files changed, 29 insertions(+), 12 deletions(-) diff --git a/device/src/bt_advertise.c b/device/src/bt_advertise.c index a9223393..9499c4ce 100644 --- a/device/src/bt_advertise.c +++ b/device/src/bt_advertise.c @@ -5,14 +5,13 @@ #include "connections.h" #include "device.h" -#define ADV_DEVICE_NAME CONFIG_BT_DEVICE_NAME -#define ADV_DEVICE_NAME_LEN (sizeof(CONFIG_BT_DEVICE_NAME) - 1) +#define LEN(NAME) (sizeof(NAME) - 1) // Advertisement packets -#define AD_NUS_DATA \ +#define AD_NUS_DATA(NAME) \ BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)), \ - BT_DATA(BT_DATA_NAME_COMPLETE, ADV_DEVICE_NAME, ADV_DEVICE_NAME_LEN), + BT_DATA(BT_DATA_NAME_COMPLETE, NAME, LEN(NAME)), #define AD_HID_DATA \ BT_DATA_BYTES(BT_DATA_GAP_APPEARANCE, (CONFIG_BT_DEVICE_APPEARANCE >> 0) & 0xff, \ @@ -21,17 +20,18 @@ BT_DATA_BYTES(BT_DATA_UUID16_ALL, BT_UUID_16_ENCODE(BT_UUID_HIDS_VAL), \ BT_UUID_16_ENCODE(BT_UUID_BAS_VAL)), -static const struct bt_data adNus[] = {AD_NUS_DATA}; +static const struct bt_data adNusLeft[] = {AD_NUS_DATA("UHK80 Left Nus")}; +static const struct bt_data adNusRight[] = {AD_NUS_DATA("UHK80 Right Nus")}; static const struct bt_data adHid[] = {AD_HID_DATA}; // Scan response packets #define SD_NUS_DATA BT_DATA_BYTES(BT_DATA_UUID128_ALL, BT_UUID_NUS_VAL), -#define SD_HID_DATA BT_DATA(BT_DATA_NAME_COMPLETE, ADV_DEVICE_NAME, ADV_DEVICE_NAME_LEN), +#define SD_HID_DATA(NAME) BT_DATA(BT_DATA_NAME_COMPLETE, NAME, LEN(NAME)), static const struct bt_data sdNus[] = {SD_NUS_DATA}; -static const struct bt_data sdHid[] = {SD_HID_DATA}; +static const struct bt_data sdHid[] = {SD_HID_DATA("UHK 80")}; static const char * advertisingString(uint8_t advType) { switch (advType) { @@ -65,16 +65,25 @@ uint8_t BtAdvertise_Start(adv_config_t advConfig) break; case ADVERTISE_NUS: advParam = *BT_LE_ADV_CONN_ONE_TIME; - err = bt_le_adv_start(&advParam, adNus, ARRAY_SIZE(adNus), sdNus, ARRAY_SIZE(sdNus)); + if (DEVICE_IS_UHK80_RIGHT) { + err = bt_le_adv_start(&advParam, adNusRight, ARRAY_SIZE(adNusRight), sdNus, ARRAY_SIZE(sdNus)); + } else { + err = bt_le_adv_start(&advParam, adNusLeft, ARRAY_SIZE(adNusLeft), sdNus, ARRAY_SIZE(sdNus)); + } break; case ADVERTISE_DIRECTED_NUS: - advParam = *BT_LE_ADV_CONN_ONE_TIME; - err = bt_le_adv_start(&advParam, adNus, ARRAY_SIZE(adNus), sdNus, ARRAY_SIZE(sdNus)); + if (DEVICE_IS_UHK80_RIGHT) { + err = bt_le_adv_start(&advParam, adNusRight, ARRAY_SIZE(adNusRight), sdNus, ARRAY_SIZE(sdNus)); + } else { + err = bt_le_adv_start(&advParam, adNusLeft, ARRAY_SIZE(adNusLeft), sdNus, ARRAY_SIZE(sdNus)); + } + break; // TODO: fix and reenable this? // advParam = *BT_LE_ADV_CONN_DIR_LOW_DUTY(advConfig.addr); // err = bt_le_adv_start(&advParam, adNus, ARRAY_SIZE(adNus), sdNus, ARRAY_SIZE(sdNus)); + break; default: printk("Adv: Attempted to start advertising without any type! Ignoring.\n"); return 0; @@ -116,7 +125,11 @@ static uint8_t connectedHidCount() { adv_config_t BtAdvertise_Config() { switch (DEVICE_ID) { case DeviceId_Uhk80_Left: - return ADVERTISEMENT_DIRECT_NUS(&Peers[PeerIdRight].addr); + if (Peers[PeerIdRight].conn == NULL) { + return ADVERTISEMENT_DIRECT_NUS(&Peers[PeerIdRight].addr); + } else { + return ADVERTISEMENT( 0 ); + } case DeviceId_Uhk80_Right: if (BtConn_UnusedPeripheralConnectionCount() > 0) { diff --git a/device/src/bt_conn.c b/device/src/bt_conn.c index 0cd0e8f5..f105f1a3 100644 --- a/device/src/bt_conn.c +++ b/device/src/bt_conn.c @@ -358,17 +358,19 @@ static void connected(struct bt_conn *conn, uint8_t err) { if (connectionId == ConnectionId_Invalid) { connectUnknown(conn); + BtManager_StartScanningAndAdvertisingAsync(); } else { if (isWanted(conn, connectionType)) { bt_conn_set_security(conn, BT_SECURITY_L4); + // advertising/scanning needs to be started only after peers are assigned :-/ } else { printk("Refusing connenction %d (this is not a selected connection)\n", connectionId); bt_conn_disconnect(conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN); + BtManager_StartScanningAndAdvertisingAsync(); } } - BtManager_StartScanningAndAdvertisingAsync(); return; @@ -455,6 +457,8 @@ static void connectAuthenticatedConnection(struct bt_conn *conn, connection_id_t bt_conn_disconnect(conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN); break; } + + BtManager_StartScanningAndAdvertisingAsync(); } static void securityChanged(struct bt_conn *conn, bt_security_t level, enum bt_security_err err) { From 3a20b69ecac3bc7ab596cc0033f4a7fdb08a6661 Mon Sep 17 00:00:00 2001 From: Karel Tucek Date: Thu, 13 Feb 2025 10:54:26 +0100 Subject: [PATCH 10/11] Refactor advertising code... --- device/src/bt_advertise.c | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/device/src/bt_advertise.c b/device/src/bt_advertise.c index 9499c4ce..590cc992 100644 --- a/device/src/bt_advertise.c +++ b/device/src/bt_advertise.c @@ -1,6 +1,7 @@ #include "bt_advertise.h" #include #include +#include "attributes.h" #include "bt_conn.h" #include "connections.h" #include "device.h" @@ -20,8 +21,8 @@ BT_DATA_BYTES(BT_DATA_UUID16_ALL, BT_UUID_16_ENCODE(BT_UUID_HIDS_VAL), \ BT_UUID_16_ENCODE(BT_UUID_BAS_VAL)), -static const struct bt_data adNusLeft[] = {AD_NUS_DATA("UHK80 Left Nus")}; -static const struct bt_data adNusRight[] = {AD_NUS_DATA("UHK80 Right Nus")}; +ATTR_UNUSED static const struct bt_data adNusLeft[] = {AD_NUS_DATA("UHK80 Left Nus")}; +ATTR_UNUSED static const struct bt_data adNusRight[] = {AD_NUS_DATA("UHK80 Right Nus")}; static const struct bt_data adHid[] = {AD_HID_DATA}; // Scan response packets @@ -33,6 +34,14 @@ static const struct bt_data adHid[] = {AD_HID_DATA}; static const struct bt_data sdNus[] = {SD_NUS_DATA}; static const struct bt_data sdHid[] = {SD_HID_DATA("UHK 80")}; +#if DEVICE_IS_UHK80_RIGHT +#define BY_SIDE(LEFT, RIGHT) RIGHT +#else +#define BY_SIDE(LEFT, RIGHT) LEFT +#endif + +#define BT_LE_ADV_START(PARAM, AD, SD) bt_le_adv_start(PARAM, AD, ARRAY_SIZE(AD), SD, ARRAY_SIZE(SD)); + static const char * advertisingString(uint8_t advType) { switch (advType) { case ADVERTISE_NUS: @@ -61,28 +70,23 @@ uint8_t BtAdvertise_Start(adv_config_t advConfig) case ADVERTISE_NUS | ADVERTISE_HID: /* our devices don't check service uuids, so hid advertisement effectively advertises nus too */ advParam = *BT_LE_ADV_CONN_ONE_TIME; - err = bt_le_adv_start(&advParam, adHid, ARRAY_SIZE(adHid), sdHid, ARRAY_SIZE(sdHid)); + err = BT_LE_ADV_START(&advParam, adHid, sdHid); break; case ADVERTISE_NUS: advParam = *BT_LE_ADV_CONN_ONE_TIME; - if (DEVICE_IS_UHK80_RIGHT) { - err = bt_le_adv_start(&advParam, adNusRight, ARRAY_SIZE(adNusRight), sdNus, ARRAY_SIZE(sdNus)); - } else { - err = bt_le_adv_start(&advParam, adNusLeft, ARRAY_SIZE(adNusLeft), sdNus, ARRAY_SIZE(sdNus)); - } + + err = BT_LE_ADV_START(&advParam, BY_SIDE(adNusLeft, adNusRight), sdNus); break; case ADVERTISE_DIRECTED_NUS: advParam = *BT_LE_ADV_CONN_ONE_TIME; - if (DEVICE_IS_UHK80_RIGHT) { - err = bt_le_adv_start(&advParam, adNusRight, ARRAY_SIZE(adNusRight), sdNus, ARRAY_SIZE(sdNus)); - } else { - err = bt_le_adv_start(&advParam, adNusLeft, ARRAY_SIZE(adNusLeft), sdNus, ARRAY_SIZE(sdNus)); - } + err = BT_LE_ADV_START(&advParam, BY_SIDE(adNusLeft, adNusRight), sdNus); break; - // TODO: fix and reenable this? + //// TODO: fix and reenable this? + // printk("Advertising against %s\n", GetAddrString(advConfig.addr)); // advParam = *BT_LE_ADV_CONN_DIR_LOW_DUTY(advConfig.addr); - // err = bt_le_adv_start(&advParam, adNus, ARRAY_SIZE(adNus), sdNus, ARRAY_SIZE(sdNus)); + // advParam.options |= BT_LE_ADV_OPT_DIR_ADDR_RPA; + // err = BT_LE_ADV_START(&advParam, BY_SIDE(adNusLeft, adNusRight), sdNus); break; default: printk("Adv: Attempted to start advertising without any type! Ignoring.\n"); From 454c6068102c2f355e7d8d97a1db4c8ebba8b2b1 Mon Sep 17 00:00:00 2001 From: Karel Tucek Date: Wed, 19 Feb 2025 13:36:27 +0100 Subject: [PATCH 11/11] Rename the advertisements to be less misleading. (The issue is that once we switch to nus only advertisement, the host still renames the hid connection based on it.) --- device/src/bt_advertise.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/device/src/bt_advertise.c b/device/src/bt_advertise.c index 590cc992..eeb3414e 100644 --- a/device/src/bt_advertise.c +++ b/device/src/bt_advertise.c @@ -22,7 +22,7 @@ BT_UUID_16_ENCODE(BT_UUID_BAS_VAL)), ATTR_UNUSED static const struct bt_data adNusLeft[] = {AD_NUS_DATA("UHK80 Left Nus")}; -ATTR_UNUSED static const struct bt_data adNusRight[] = {AD_NUS_DATA("UHK80 Right Nus")}; +ATTR_UNUSED static const struct bt_data adNusRight[] = {AD_NUS_DATA("UHK 80 Right")}; static const struct bt_data adHid[] = {AD_HID_DATA}; // Scan response packets