Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions device/src/bt_conn.c
Original file line number Diff line number Diff line change
Expand Up @@ -498,17 +498,18 @@ static bool isWanted(struct bt_conn *conn, connection_id_t connectionId, connect
bool isSelectedConnection = BtAddrEq(addr, &HostConnection(CurrentHostConnectionId)->bleAddress);
bool isSelectedSlotEmpty = Connections_Type(CurrentHostConnectionId) == ConnectionType_Empty;
bool isPeerConnection = connectionType == ConnectionType_NusLeft || connectionType == ConnectionType_NusRight;
bool isOobPairingPeer = BtPair_OobPairingInProgress && BtAddrEq(addr, &BtPair_GetRemoteOob()->addr);
bool weHaveSlotToSpare = BtConn_UnusedPeripheralConnectionCount() > 1 || !shouldReserveForCurrentConnection();

bool result = false;
if (Cfg.Bt_AlwaysAdvertise) {
result = isPeerConnection || isSelectedConnection || isSelectedSlotEmpty || weHaveSlotToSpare;
result = isPeerConnection || isSelectedConnection || isSelectedSlotEmpty || isOobPairingPeer || weHaveSlotToSpare;
} else {
result = isPeerConnection || isSelectedConnection || isSelectedSlotEmpty;
result = isPeerConnection || isSelectedConnection || isSelectedSlotEmpty || isOobPairingPeer;
}

if (!result) {
LOG_INF(" Not wanted: haveSlot: %d, isSelected: %d (selected %d, this %d (%d)), isPeer: %d, isEmptySlot: %d", weHaveSlotToSpare, isSelectedConnection, CurrentHostConnectionId, connectionId, connectionType, isPeerConnection, isSelectedSlotEmpty);
LOG_INF(" Not wanted: haveSlot: %d, isSelected: %d (selected %d, this %d (%d)), isPeer: %d, isEmptySlot: %d, isOobPeer: %d", weHaveSlotToSpare, isSelectedConnection, CurrentHostConnectionId, connectionId, connectionType, isPeerConnection, isSelectedSlotEmpty, isOobPairingPeer);
}
return result;
}
Expand Down Expand Up @@ -1154,7 +1155,6 @@ void BtConn_ReserveConnections() {
BtConn_DisconnectAllUnidentified();

uint8_t unusedConnectionCount = BtConn_UnusedPeripheralConnectionCount();
bool selectedConnectionIsBleHid = Connections_Type(CurrentHostConnectionId) == ConnectionType_BtHid;

if (unusedConnectionCount == 0) {
disconnectOldestHost();
Expand Down
19 changes: 18 additions & 1 deletion device/src/connections.c
Original file line number Diff line number Diff line change
Expand Up @@ -454,6 +454,18 @@ static void setDongleToStandby(connection_id_t connectionId) {
}
}

static void disconnectOldHost(connection_id_t oldConnectionId) {
switch (Connections_Type(oldConnectionId)) {
case ConnectionType_BtHid:
case ConnectionType_NusDongle:
LOG_INF("Switchover: disconnecting the old host %d", oldConnectionId);
BtConn_DisconnectOne(oldConnectionId);
break;
default:
break;
}
}

static void updateLastConnection(connection_id_t lastConnId, connection_id_t newConnId) {
if (
LastHostConnectionId != lastConnId
Expand All @@ -477,7 +489,12 @@ static connection_id_t findReadySwitchoverHost(void) {

static void switchOver(connection_id_t connectionId, bool explicitlySelected) {
if (connectionId != CurrentHostConnectionId) {
setDongleToStandby(CurrentHostConnectionId);
if (Cfg.Bt_KeepConnectionsAlive || Cfg.Bt_AlwaysAdvertise) {
setDongleToStandby(CurrentHostConnectionId);
} else {
// The old host occupies a peripheral slot that the new host may need.
disconnectOldHost(CurrentHostConnectionId);
}
}

updateLastConnection(CurrentHostConnectionId, connectionId);
Expand Down
8 changes: 0 additions & 8 deletions device/src/messenger.c
Original file line number Diff line number Diff line change
Expand Up @@ -227,14 +227,6 @@ static void processSyncablePropertyDongle(device_id_t src, const uint8_t* data,
return;
}

#if DEVICE_IS_UHK_DONGLE
if (!Connections_IsCurrentHostAwake()) {
// We received a report to relay but our USB host is suspended - ask it
// to wake up instead of just failing to deliver.
USB_RemoteWakeup();
}
#endif

errno_t ATTR_UNUSED ret = sendDongleReport(propertyId, message);

#if DEVICE_IS_UHK_DONGLE
Expand Down
7 changes: 6 additions & 1 deletion doc-dev/reference-manual.md
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,8 @@ COMMAND = set leds.fadeTimeout <seconds to fade after (INT)>
COMMAND = set leds.{keyBacklightFadeTimeout|keyBacklightFadeBatteryTimeout|displayFadeTimeout|displayFadeBatteryTimeout} <seconds to fade after (INT)>
COMMAND = set battery.chargeLimit { full | optimizeHealth }
COMMAND = set bluetooth.enabled BOOL
COMMAND = set bluetooth.alwaysAdvertise BOOL
COMMAND = set bluetooth.keepConnectionsAlive BOOL
COMMAND = set modifierLayerTriggers.{shift|alt|super|ctrl} {left|right|both}
COMMAND = &macroArg.<macro argument index (INT)>
CONDITION = <condition>
Expand Down Expand Up @@ -319,7 +321,6 @@ COMMAND = set leds.alwaysOn BOOL
COMMAND = set bluetooth.peripheralConnectionCount INT
COMMAND = set bluetooth.minAdvertisingDelay INT
COMMAND = set bluetooth.directedAdvertisingAllowed BOOL
COMMAND = set bluetooth.alwaysAdvertise BOOL
COMMAND = set devMode BOOL
COMMAND = set log.sink.usb BOOL
COMMAND = set log.sink.oled BOOL
Expand Down Expand Up @@ -766,6 +767,10 @@ Key actions can be parametrized with macro arguments. These arguments can be exp
- `leds.brightness <0-1 multiple of default (FLOAT)>` allows scaling default brightness. E.g., `0.5` will dim the entire keyboard to half of the default values that are configured in Agent
- `leds.fadeTimeout <seconds to fade after (INT)>` will make uhk turn off all leds after the configured interval. (This is an alias that sets all of `{keyBacklightFadeTimeout|keyBacklightFadeBatteryTimeout|displayFadeTimeout|displayFadeBatteryTimeout}`)

- bluetooth:
- `set bluetooth.alwaysAdvertise BOOL` makes uhk keep advertising even when the current host is already connected, as long as there is a free peripheral connection slot. This lets other configured hosts (dongles, ble hids) connect in the background, so that switching to them later is instantaneous. Default is off. Implies `bluetooth.keepConnectionsAlive`.
- `set bluetooth.keepConnectionsAlive BOOL` keeps the old host connected when you switch away from it. By default, switching hosts disconnects the previous ble host or dongle in order to free its peripheral connection slot for the new host. Default is off.

- modifier layer triggers:
- `set modifierLayerTriggers.{shift|alt|super|ctrl} {left|right|both}` controls whether modifier layers are triggered by left or right or either of the modifiers.

Expand Down
1 change: 1 addition & 0 deletions right/src/config_manager.c
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,7 @@ const config_t DefaultCfg = (config_t){
#endif
.Bt_Enabled = true,
.Bt_AlwaysAdvertise = false,
.Bt_KeepConnectionsAlive = false,
.Bt_MaxPeripheralConnections = 3,
.Bt_MinAdvertisingDelay = 250,
.Bt_DirectedAdvertisingAllowed = false,
Expand Down
1 change: 1 addition & 0 deletions right/src/config_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@

// bluetooth
bool Bt_AlwaysAdvertise;
bool Bt_KeepConnectionsAlive;
bool Bt_DirectedAdvertisingAllowed;
bool Bt_Enabled;

Expand Down
15 changes: 14 additions & 1 deletion right/src/hid/transport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,11 @@ static report_sink_t determineSink()
LOG_WRN("Can't send report - selected connection is not ready!\n");
Connections_HandleSwitchover(ConnectionId_Invalid, false);
if (!Connections_IsReady(CurrentHostConnectionId)) {
return ReportSink_Usb;
if (connectionType == ConnectionType_UsbHidRight) {
return ReportSink_Usb;
} else {
return ReportSink_BlackHole;
}
}
}

Expand Down Expand Up @@ -252,6 +256,9 @@ extern "C" errno_t Hid_SendKeyboardReport(const hid_keyboard_report_t *report)
TestHooks_CaptureReport(report);
Hid_KeyboardReportSentCallback(ReportSink_Usb);
break;
case ReportSink_BlackHole:
err = -EHOSTUNREACH;
break;
default:
LOG_WRN("Unhandled and unexpected switch state!\n");
err = -EHOSTUNREACH;
Expand Down Expand Up @@ -324,6 +331,9 @@ extern "C" errno_t Hid_SendMouseReport(const hid_mouse_report_t *report)
}
break;
#endif
case ReportSink_BlackHole:
err = -EHOSTUNREACH;
break;
default:
LOG_WRN("Unhandled and unexpected switch state!\n");
err = -EHOSTUNREACH;
Expand Down Expand Up @@ -390,6 +400,9 @@ extern "C" errno_t Hid_SendControlsReport(const hid_controls_report_t *report)
}
break;
#endif
case ReportSink_BlackHole:
err = -EHOSTUNREACH;
break;
default:
LOG_WRN("Unhandled and unexpected switch state!\n");
err = -EHOSTUNREACH;
Expand Down
1 change: 1 addition & 0 deletions right/src/hid/transport.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ typedef enum {
ReportSink_BleHid,
ReportSink_Dongle,
ReportSink_TestSuite,
ReportSink_BlackHole,
} report_sink_t;

typedef enum
Expand Down
2 changes: 2 additions & 0 deletions right/src/macros/set_command.c
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,8 @@ static macro_variable_t bluetooth(parser_context_t* ctx, set_command_action_t ac
#ifdef __ZEPHYR__
BtManager_StartScanningAndAdvertisingAsync(false, "set_command - alwaysAdvertise changed");
#endif
} else if (ConsumeToken(ctx, "keepConnectionsAlive")) {
ASSIGN_BOOL(Cfg.Bt_KeepConnectionsAlive);
} else if (ConsumeToken(ctx, "directedAdvertisingAllowed")) {
ASSIGN_BOOL(Cfg.Bt_DirectedAdvertisingAllowed);
#ifdef __ZEPHYR__
Expand Down
2 changes: 1 addition & 1 deletion right/src/usb_state.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ static void recalculateConnectionState(void) {
#if DEVICE_IS_UHK_DONGLE
StateSync_UpdateProperty(StateSyncPropertyId_DongleHostAwake, &UsbState_Awake);
#elif defined(__ZEPHYR__)
Connections_SetStateAsync(ConnectionId_UsbHidRight, UsbState_Awake ? ConnectionState_Ready : ConnectionState_Disconnected);
Connections_SetStateAsync(ConnectionId_UsbHidRight, UsbState_TransportUp ? ConnectionState_Ready : ConnectionState_Disconnected);
EventScheduler_Schedule(Timer_GetCurrentTime(), EventSchedulerEvent_PowerModeUpdate, "no host short wakeup");
WIDGET_REFRESH(&TargetWidget);
#else
Expand Down
Loading