Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[QPG] LED handling switched from polling to event-based #23526

Merged
merged 11 commits into from
Nov 9, 2022
3 changes: 3 additions & 0 deletions examples/lighting-app/qpg/include/AppTask.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
106 changes: 63 additions & 43 deletions examples/lighting-app/qpg/src/AppTask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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);
}
}
}
}

Expand Down Expand Up @@ -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;
}
}
4 changes: 4 additions & 0 deletions src/platform/qpg/BLEManagerImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down