From 1387936d05d498abf5ad892ecf4bf26f84f3c490 Mon Sep 17 00:00:00 2001 From: Adam Bodurka Date: Wed, 9 Nov 2022 01:18:37 +0100 Subject: [PATCH] [QPG] LED handling switched from polling to event-based (#23526) * Switched to callbacks * LEDs are behaving the same * Cleanup * BLE is now also handled by events * Better variable name * Logs removed * switch-case is more elegant here * Moved LED handling to separate func * AppTask stack reduced to 2kB * Restyled by clang-format * Updating LEDs only on connectivity change Co-authored-by: Restyled.io --- examples/lighting-app/qpg/include/AppTask.h | 3 + examples/lighting-app/qpg/src/AppTask.cpp | 106 ++++++++++++-------- src/platform/qpg/BLEManagerImpl.cpp | 4 + 3 files changed, 70 insertions(+), 43 deletions(-) diff --git a/examples/lighting-app/qpg/include/AppTask.h b/examples/lighting-app/qpg/include/AppTask.h index f91eb971c2ca17..7651124669546d 100644 --- a/examples/lighting-app/qpg/include/AppTask.h +++ b/examples/lighting-app/qpg/include/AppTask.h @@ -64,6 +64,9 @@ class AppTask static void LightingActionEventHandler(AppEvent * aEvent); static void TimerEventHandler(chip::System::Layer * aLayer, void * aAppState); + static void MatterEventHandler(const chip::DeviceLayer::ChipDeviceEvent * event, intptr_t arg); + static void UpdateLEDs(void); + void StartTimer(uint32_t aTimeoutMs); void CancelTimer(void); diff --git a/examples/lighting-app/qpg/src/AppTask.cpp b/examples/lighting-app/qpg/src/AppTask.cpp index 2f99b8e97edca3..27724b1f271329 100644 --- a/examples/lighting-app/qpg/src/AppTask.cpp +++ b/examples/lighting-app/qpg/src/AppTask.cpp @@ -57,7 +57,7 @@ using namespace ::chip::DeviceLayer; #define FACTORY_RESET_TRIGGER_TIMEOUT 3000 #define FACTORY_RESET_CANCEL_WINDOW_TIMEOUT 3000 -#define APP_TASK_STACK_SIZE (3 * 1024) +#define APP_TASK_STACK_SIZE (2 * 1024) #define APP_TASK_PRIORITY 2 #define APP_EVENT_QUEUE_SIZE 10 #define QPG_LIGHT_ENDPOINT_ID (1) @@ -260,6 +260,8 @@ CHIP_ERROR AppTask::Init() { CHIP_ERROR err = CHIP_NO_ERROR; + PlatformMgr().AddEventHandler(MatterEventHandler, 0); + ChipLogProgress(NotSpecified, "Current Software Version: %s", CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING); // Init ZCL Data Model and start server @@ -303,53 +305,12 @@ void AppTask::AppTaskMain(void * pvParameter) while (true) { - BaseType_t eventReceived = xQueueReceive(sAppEventQueue, &event, pdMS_TO_TICKS(10)); + BaseType_t eventReceived = xQueueReceive(sAppEventQueue, &event, portMAX_DELAY); while (eventReceived == pdTRUE) { sAppTask.DispatchEvent(&event); eventReceived = xQueueReceive(sAppEventQueue, &event, 0); } - - // Collect connectivity and configuration state from the CHIP stack. Because - // the CHIP event loop is being run in a separate task, the stack must be - // locked while these values are queried. However we use a non-blocking - // lock request (TryLockCHIPStack()) to avoid blocking other UI activities - // when the CHIP task is busy (e.g. with a long crypto operation). - if (PlatformMgr().TryLockChipStack()) - { - sIsThreadProvisioned = ConnectivityMgr().IsThreadProvisioned(); - sIsThreadEnabled = ConnectivityMgr().IsThreadEnabled(); - sHaveBLEConnections = (ConnectivityMgr().NumBLEConnections() != 0); - PlatformMgr().UnlockChipStack(); - } - - // Update the status LED if factory reset has not been initiated. - // - // If system has "full connectivity", keep the LED On constantly. - // - // If thread and service provisioned, but not attached to the thread network - // yet OR no connectivity to the service OR subscriptions are not fully - // established THEN blink the LED Off for a short period of time. - // - // If the system has ble connection(s) uptill the stage above, THEN blink - // the LEDs at an even rate of 100ms. - // - // Otherwise, blink the LED ON for a very short time. - if (sAppTask.mFunction != kFunction_FactoryReset) - { - if (sIsThreadProvisioned && sIsThreadEnabled) - { - qvIO_LedBlink(SYSTEM_STATE_LED, 950, 50); - } - else if (sHaveBLEConnections) - { - qvIO_LedBlink(SYSTEM_STATE_LED, 100, 100); - } - else - { - qvIO_LedBlink(SYSTEM_STATE_LED, 50, 950); - } - } } } @@ -621,3 +582,62 @@ void AppTask::UpdateClusterState(void) ChipLogError(NotSpecified, "ERR: updating level %x", status); } } + +void AppTask::UpdateLEDs(void) +{ + // If system has "full connectivity", keep the LED On constantly. + // + // If thread and service provisioned, but not attached to the thread network + // yet OR no connectivity to the service OR subscriptions are not fully + // established THEN blink the LED Off for a short period of time. + // + // If the system has ble connection(s) uptill the stage above, THEN blink + // the LEDs at an even rate of 100ms. + // + // Otherwise, blink the LED ON for a very short time. + if (sIsThreadProvisioned && sIsThreadEnabled) + { + qvIO_LedBlink(SYSTEM_STATE_LED, 950, 50); + } + else if (sHaveBLEConnections) + { + qvIO_LedBlink(SYSTEM_STATE_LED, 100, 100); + } + else + { + qvIO_LedBlink(SYSTEM_STATE_LED, 50, 950); + } +} + +void AppTask::MatterEventHandler(const ChipDeviceEvent * event, intptr_t) +{ + switch (event->Type) + { + case DeviceEventType::kServiceProvisioningChange: { + sIsThreadProvisioned = event->ServiceProvisioningChange.IsServiceProvisioned; + UpdateLEDs(); + break; + } + + case DeviceEventType::kThreadConnectivityChange: { + sIsThreadEnabled = (event->ThreadConnectivityChange.Result == kConnectivity_Established); + UpdateLEDs(); + break; + } + + case DeviceEventType::kCHIPoBLEConnectionEstablished: { + sHaveBLEConnections = true; + UpdateLEDs(); + break; + } + + case DeviceEventType::kCHIPoBLEConnectionClosed: { + sHaveBLEConnections = false; + UpdateLEDs(); + break; + } + + default: + break; + } +} diff --git a/src/platform/qpg/BLEManagerImpl.cpp b/src/platform/qpg/BLEManagerImpl.cpp index 0b4fe14ee0bf9e..f466491ff724c8 100644 --- a/src/platform/qpg/BLEManagerImpl.cpp +++ b/src/platform/qpg/BLEManagerImpl.cpp @@ -201,8 +201,12 @@ void BLEManagerImpl::_OnPlatformEvent(const ChipDeviceEvent * event) break; case DeviceEventType::kCHIPoBLEUnsubscribe: { + ChipDeviceEvent connClosedEvent; + ChipLogProgress(DeviceLayer, "_OnPlatformEvent kCHIPoBLEUnsubscribe"); HandleUnsubscribeReceived(event->CHIPoBLEUnsubscribe.ConId, &CHIP_BLE_SVC_ID, &chipUUID_CHIPoBLEChar_TX); + connClosedEvent.Type = DeviceEventType::kCHIPoBLEConnectionClosed; + PlatformMgr().PostEventOrDie(&connClosedEvent); } break;