diff --git a/examples/light-switch-app/telink/include/AppTask.h b/examples/light-switch-app/telink/include/AppTask.h index 70abb978d2cdc1..b682884b30155d 100755 --- a/examples/light-switch-app/telink/include/AppTask.h +++ b/examples/light-switch-app/telink/include/AppTask.h @@ -56,11 +56,14 @@ class AppTask void DispatchEvent(AppEvent * event); + static void UpdateStatusLED(); static void SwitchActionButtonEventHandler(void); static void FactoryResetButtonEventHandler(void); static void StartThreadButtonEventHandler(void); static void StartBleAdvButtonEventHandler(void); + static void ChipEventHandler(const chip::DeviceLayer::ChipDeviceEvent * event, intptr_t arg); + static void FactoryResetHandler(AppEvent * aEvent); static void StartThreadHandler(AppEvent * aEvent); static void SwitchActionEventHandler(AppEvent * aEvent); diff --git a/examples/light-switch-app/telink/src/AppTask.cpp b/examples/light-switch-app/telink/src/AppTask.cpp index 8078ac9fff1b6f..8b8bac4ed2d878 100755 --- a/examples/light-switch-app/telink/src/AppTask.cpp +++ b/examples/light-switch-app/telink/src/AppTask.cpp @@ -86,6 +86,8 @@ CHIP_ERROR AppTask::Init() LEDWidget::InitGpio(SYSTEM_STATE_LED_PORT); sStatusLED.Init(SYSTEM_STATE_LED_PIN); + UpdateStatusLED(); + InitButtons(); // Init ZCL Data Model and start server @@ -108,6 +110,11 @@ CHIP_ERROR AppTask::Init() PrintOnboardingCodes(chip::RendezvousInformationFlags(chip::RendezvousInformationFlag::kBLE)); + // Add CHIP event handler and start CHIP thread. + // Note that all the initialization code should happen prior to this point to avoid data races + // between the main and the CHIP threads. + PlatformMgr().AddEventHandler(ChipEventHandler, 0); + ret = ConnectivityMgr().SetBLEDeviceName("TelinkSwitch"); if (ret != CHIP_NO_ERROR) { @@ -140,37 +147,6 @@ CHIP_ERROR AppTask::StartApp() ret = k_msgq_get(&sAppEventQueue, &event, K_NO_WAIT); } - // 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(); - sIsThreadAttached = ConnectivityMgr().IsThreadAttached(); - sHaveBLEConnections = (ConnectivityMgr().NumBLEConnections() != 0); - PlatformMgr().UnlockChipStack(); - } - - if (sIsThreadProvisioned && sIsThreadEnabled) - { - if (sIsThreadAttached) - { - sStatusLED.Blink(950, 50); - } - else - { - sStatusLED.Blink(100, 100); - } - } - else - { - sStatusLED.Blink(50, 950); - } - sStatusLED.Animate(); } } @@ -273,6 +249,52 @@ void AppTask::StartBleAdvHandler(AppEvent * aEvent) } } +void AppTask::UpdateStatusLED() +{ + if (sIsThreadProvisioned && sIsThreadEnabled) + { + if (sIsThreadAttached) + { + sStatusLED.Blink(950, 50); + } + else + { + sStatusLED.Blink(100, 100); + } + } + else + { + sStatusLED.Blink(50, 950); + } +} + +void AppTask::ChipEventHandler(const ChipDeviceEvent * event, intptr_t /* arg */) +{ + switch (event->Type) + { + case DeviceEventType::kCHIPoBLEAdvertisingChange: + sHaveBLEConnections = ConnectivityMgr().NumBLEConnections() != 0; + UpdateStatusLED(); + break; + case DeviceEventType::kThreadStateChange: + sIsThreadProvisioned = ConnectivityMgr().IsThreadProvisioned(); + sIsThreadEnabled = ConnectivityMgr().IsThreadEnabled(); + sIsThreadAttached = ConnectivityMgr().IsThreadAttached(); + UpdateStatusLED(); + break; + case DeviceEventType::kThreadConnectivityChange: +#if CONFIG_CHIP_OTA_REQUESTOR + if (event->ThreadConnectivityChange.Result == kConnectivity_Established) + { + InitBasicOTARequestor(); + } +#endif + break; + default: + break; + } +} + void AppTask::ActionInitiated(AppTask::Action_t aAction, int32_t aActor) {} void AppTask::ActionCompleted(AppTask::Action_t aAction, int32_t aActor) diff --git a/examples/lighting-app/telink/include/AppTask.h b/examples/lighting-app/telink/include/AppTask.h index d660ea20fbe0c2..d926c5286f41f3 100644 --- a/examples/lighting-app/telink/include/AppTask.h +++ b/examples/lighting-app/telink/include/AppTask.h @@ -46,11 +46,14 @@ class AppTask void DispatchEvent(AppEvent * event); + static void UpdateStatusLED(); static void LightingActionButtonEventHandler(void); static void FactoryResetButtonEventHandler(void); static void StartThreadButtonEventHandler(void); static void StartBleAdvButtonEventHandler(void); + static void ChipEventHandler(const chip::DeviceLayer::ChipDeviceEvent * event, intptr_t arg); + static void FactoryResetHandler(AppEvent * aEvent); static void StartThreadHandler(AppEvent * aEvent); static void LightingActionEventHandler(AppEvent * aEvent); diff --git a/examples/lighting-app/telink/src/AppTask.cpp b/examples/lighting-app/telink/src/AppTask.cpp index f2e370faae8f17..18a99610cdbab8 100644 --- a/examples/lighting-app/telink/src/AppTask.cpp +++ b/examples/lighting-app/telink/src/AppTask.cpp @@ -86,6 +86,8 @@ CHIP_ERROR AppTask::Init() LEDWidget::InitGpio(SYSTEM_STATE_LED_PORT); sStatusLED.Init(SYSTEM_STATE_LED_PIN); + UpdateStatusLED(); + InitButtons(); // Init lighting manager @@ -109,6 +111,11 @@ CHIP_ERROR AppTask::Init() ConfigurationMgr().LogDeviceConfig(); PrintOnboardingCodes(chip::RendezvousInformationFlags(chip::RendezvousInformationFlag::kBLE)); + // Add CHIP event handler and start CHIP thread. + // Note that all the initialization code should happen prior to this point to avoid data races + // between the main and the CHIP threads. + PlatformMgr().AddEventHandler(ChipEventHandler, 0); + ret = ConnectivityMgr().SetBLEDeviceName("TelinkLight"); if (ret != CHIP_NO_ERROR) { @@ -141,37 +148,6 @@ CHIP_ERROR AppTask::StartApp() ret = k_msgq_get(&sAppEventQueue, &event, K_NO_WAIT); } - // 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(); - sIsThreadAttached = ConnectivityMgr().IsThreadAttached(); - sHaveBLEConnections = (ConnectivityMgr().NumBLEConnections() != 0); - PlatformMgr().UnlockChipStack(); - } - - if (sIsThreadProvisioned && sIsThreadEnabled) - { - if (sIsThreadAttached) - { - sStatusLED.Blink(950, 50); - } - else - { - sStatusLED.Blink(100, 100); - } - } - else - { - sStatusLED.Blink(50, 950); - } - sStatusLED.Animate(); } } @@ -282,6 +258,52 @@ void AppTask::StartBleAdvHandler(AppEvent * aEvent) } } +void AppTask::UpdateStatusLED() +{ + if (sIsThreadProvisioned && sIsThreadEnabled) + { + if (sIsThreadAttached) + { + sStatusLED.Blink(950, 50); + } + else + { + sStatusLED.Blink(100, 100); + } + } + else + { + sStatusLED.Blink(50, 950); + } +} + +void AppTask::ChipEventHandler(const ChipDeviceEvent * event, intptr_t /* arg */) +{ + switch (event->Type) + { + case DeviceEventType::kCHIPoBLEAdvertisingChange: + sHaveBLEConnections = ConnectivityMgr().NumBLEConnections() != 0; + UpdateStatusLED(); + break; + case DeviceEventType::kThreadStateChange: + sIsThreadProvisioned = ConnectivityMgr().IsThreadProvisioned(); + sIsThreadEnabled = ConnectivityMgr().IsThreadEnabled(); + sIsThreadAttached = ConnectivityMgr().IsThreadAttached(); + UpdateStatusLED(); + break; + case DeviceEventType::kThreadConnectivityChange: +#if CONFIG_CHIP_OTA_REQUESTOR + if (event->ThreadConnectivityChange.Result == kConnectivity_Established) + { + InitBasicOTARequestor(); + } +#endif + break; + default: + break; + } +} + void AppTask::ActionInitiated(LightingManager::Action_t aAction, int32_t aActor) { if (aAction == LightingManager::ON_ACTION)