hub: fix missed notification when connecting

This fixes the first notification being missed due to the notification
handler not being started until after notifications are enabled.

It also fixes the DidConnect action changing the state to Unknown after
a notification was received that set the state to a known value.
This commit is contained in:
David Lechner
2021-03-10 10:30:15 -06:00
parent 430147487e
commit 4b3a6fea5e
2 changed files with 29 additions and 12 deletions
+29 -10
View File
@@ -190,6 +190,16 @@ function* connect(_action: BleDeviceConnectAction): Generator {
);
});
const pybricksControlChannelTask = yield* takeEvery(
pybricksControlChannel,
handlePybricksControlValueChanged,
);
const pybricksControlWriteTask = yield* takeEvery(
BlePybricksServiceActionType.WriteCommand,
writePybricksCommand,
pybricksControlChar,
);
try {
// REVISIT: possible Pybricks firmware bug (or chromium bug on Linux)
// where 'characteristicvaluechanged' is not called after disconnecting
@@ -199,6 +209,8 @@ function* connect(_action: BleDeviceConnectAction): Generator {
yield* call([pybricksControlChar, 'stopNotifications']);
yield* call([pybricksControlChar, 'startNotifications']);
} catch (err) {
yield* cancel(pybricksControlChannelTask);
yield* cancel(pybricksControlWriteTask);
pybricksControlChannel.close();
server.disconnect();
yield* takeMaybe(disconnectChannel);
@@ -210,6 +222,8 @@ function* connect(_action: BleDeviceConnectAction): Generator {
try {
uartService = yield* call([server, 'getPrimaryService'], uartServiceUUID);
} catch (err) {
yield* cancel(pybricksControlChannelTask);
yield* cancel(pybricksControlWriteTask);
pybricksControlChannel.close();
server.disconnect();
yield* takeMaybe(disconnectChannel);
@@ -225,6 +239,8 @@ function* connect(_action: BleDeviceConnectAction): Generator {
try {
uartRxChar = yield* call([uartService, 'getCharacteristic'], uartRxCharUUID);
} catch (err) {
yield* cancel(pybricksControlChannelTask);
yield* cancel(pybricksControlWriteTask);
pybricksControlChannel.close();
server.disconnect();
yield* takeMaybe(disconnectChannel);
@@ -236,6 +252,8 @@ function* connect(_action: BleDeviceConnectAction): Generator {
try {
uartTxChar = yield* call([uartService, 'getCharacteristic'], uartTxCharUUID);
} catch (err) {
yield* cancel(pybricksControlChannelTask);
yield* cancel(pybricksControlWriteTask);
pybricksControlChannel.close();
server.disconnect();
yield* takeMaybe(disconnectChannel);
@@ -255,6 +273,13 @@ function* connect(_action: BleDeviceConnectAction): Generator {
uartTxChar.removeEventListener('characteristicvaluechanged', listener);
});
const uartTxChannelTask = yield* takeEvery(uartTxChannel, handleUartValueChanged);
const uartTxWriteTask = yield* takeEvery(
BleUartActionType.Write,
writeUart,
uartRxChar,
);
try {
// REVISIT: possible Pybricks firmware bug (or chromium bug on Linux)
// where 'characteristicvaluechanged' is not called after disconnecting
@@ -264,7 +289,11 @@ function* connect(_action: BleDeviceConnectAction): Generator {
yield* call([uartTxChar, 'stopNotifications']);
yield* call([uartTxChar, 'startNotifications']);
} catch (err) {
yield* cancel(uartTxWriteTask);
yield* cancel(uartTxChannelTask);
uartTxChannel.close();
yield* cancel(pybricksControlChannelTask);
yield* cancel(pybricksControlWriteTask);
pybricksControlChannel.close();
server.disconnect();
yield* takeMaybe(disconnectChannel);
@@ -272,16 +301,6 @@ function* connect(_action: BleDeviceConnectAction): Generator {
return;
}
yield* takeEvery(pybricksControlChannel, handlePybricksControlValueChanged);
yield* takeEvery(
BlePybricksServiceActionType.WriteCommand,
writePybricksCommand,
pybricksControlChar,
);
yield* takeEvery(uartTxChannel, handleUartValueChanged);
yield* takeEvery(BleUartActionType.Write, writeUart, uartRxChar);
yield* put(didConnect());
yield* takeMaybe(disconnectChannel);
-2
View File
@@ -49,8 +49,6 @@ const runtime: Reducer<HubRuntimeState, Action> = (
switch (action.type) {
case BleDeviceActionType.DidDisconnect:
return HubRuntimeState.Disconnected;
case BleDeviceActionType.DidConnect:
return HubRuntimeState.Unknown;
case HubMessageActionType.RuntimeStatus:
switch (action.newStatus) {
case HubRuntimeStatusType.Idle: