diff --git a/examples/all-clusters-app/telink/CMakeLists.txt b/examples/all-clusters-app/telink/CMakeLists.txt index 86eee4dbb2373f..584806456e5233 100644 --- a/examples/all-clusters-app/telink/CMakeLists.txt +++ b/examples/all-clusters-app/telink/CMakeLists.txt @@ -61,6 +61,7 @@ target_include_directories(app PRIVATE ${ALL_CLUSTERS_COMMON_DIR}/include ${GEN_DIR}/app-common ${GEN_DIR}/all-clusters-app + ${TELINK_COMMON}/common/include ${TELINK_COMMON}/util/include) add_definitions( @@ -69,11 +70,12 @@ add_definitions( target_sources(app PRIVATE src/AppTask.cpp - src/main.cpp src/ZclDoorLockCallbacks.cpp ${ALL_CLUSTERS_COMMON_DIR}/src/static-supported-modes-manager.cpp ${ALL_CLUSTERS_COMMON_DIR}/src/bridged-actions-stub.cpp ${ALL_CLUSTERS_COMMON_DIR}/src/binding-handler.cpp + ${TELINK_COMMON}/common/src/mainCommon.cpp + ${TELINK_COMMON}/common/src/AppTaskCommon.cpp ${TELINK_COMMON}/util/src/LEDWidget.cpp ${TELINK_COMMON}/util/src/ButtonManager.cpp ${TELINK_COMMON}/util/src/ThreadUtil.cpp diff --git a/examples/all-clusters-app/telink/include/AppConfig.h b/examples/all-clusters-app/telink/include/AppConfig.h index 8eb990230520e6..880f3aa7b98c50 100644 --- a/examples/all-clusters-app/telink/include/AppConfig.h +++ b/examples/all-clusters-app/telink/include/AppConfig.h @@ -19,16 +19,10 @@ #pragma once // ---- All Clusters Application example config ---- +#define APP_USE_EXAMPLE_START_BUTTON 0 +#define APP_USE_THREAD_START_BUTTON 1 +#define APP_SET_DEVICE_INFO_PROVIDER 1 +#define APP_SET_NETWORK_COMM_ENDPOINT_SEC 1 +#define APP_USE_IDENTIFY_PWM 1 // APP_USE_IDENTIFY_PWM must be defined before including "AppConfigCommon.h" -// Buttons config -#define BUTTON_PORT DEVICE_DT_GET(DT_NODELABEL(gpioc)) - -#define BUTTON_PIN_1 2 -#define BUTTON_PIN_3 3 -#define BUTTON_PIN_4 1 -#define BUTTON_PIN_2 0 - -// LEDs config -#define LEDS_PORT DEVICE_DT_GET(DT_NODELABEL(gpiob)) -#define SYSTEM_STATE_LED 7 -#define LIGHTING_PWM_SPEC_IDENTIFY_GREEN PWM_DT_SPEC_GET(DT_ALIAS(pwm_led3)) +#include "AppConfigCommon.h" diff --git a/examples/all-clusters-app/telink/include/AppEvent.h b/examples/all-clusters-app/telink/include/AppEvent.h deleted file mode 100644 index b6e45d7d1526c8..00000000000000 --- a/examples/all-clusters-app/telink/include/AppEvent.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * - * Copyright (c) 2022 Project CHIP Authors - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include - -struct AppEvent; -typedef void (*EventHandler)(AppEvent *); - -class LEDWidget; - -struct AppEvent -{ - enum AppEventTypes - { - kEventType_Button = 0, - kEventType_Timer, - kEventType_UpdateLedState, - kEventType_IdentifyStart, - kEventType_IdentifyStop, - }; - - uint16_t Type; - - union - { - struct - { - uint8_t Action; - } ButtonEvent; - struct - { - void * Context; - } TimerEvent; - struct - { - LEDWidget * LedWidget; - } UpdateLedStateEvent; - }; - - EventHandler Handler; -}; diff --git a/examples/all-clusters-app/telink/include/AppTask.h b/examples/all-clusters-app/telink/include/AppTask.h index 88cc4d8418d177..24e00675e78472 100644 --- a/examples/all-clusters-app/telink/include/AppTask.h +++ b/examples/all-clusters-app/telink/include/AppTask.h @@ -18,71 +18,17 @@ #pragma once -#include "AppEvent.h" -#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED -#include "LEDWidget.h" -#endif -#include "PWMDevice.h" +#include "AppTaskCommon.h" -#include - -#include - -#if CONFIG_CHIP_FACTORY_DATA -#include -#endif - -#include - -struct k_timer; -struct Identify; - -class AppTask +class AppTask : public AppTaskCommon { -public: - CHIP_ERROR StartApp(void); - - void PostEvent(AppEvent * event); - static void IdentifyEffectHandler(EmberAfIdentifyEffectIdentifier aEffect); - private: friend AppTask & GetAppTask(void); + friend class AppTaskCommon; - CHIP_ERROR Init(void); - - static void ActionIdentifyStateUpdateHandler(k_timer * timer); - - void DispatchEvent(AppEvent * event); - -#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED - static void UpdateLedStateEventHandler(AppEvent * aEvent); - static void LEDStateUpdateHandler(LEDWidget * ledWidget); - static void UpdateStatusLED(); -#endif - 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 FactoryResetTimerTimeoutCallback(k_timer * timer); - - static void FactoryResetTimerEventHandler(AppEvent * aEvent); - static void FactoryResetHandler(AppEvent * aEvent); - static void StartThreadHandler(AppEvent * aEvent); - static void StartBleAdvHandler(AppEvent * aEvent); - static void UpdateIdentifyStateEventHandler(AppEvent * aEvent); - - static void InitButtons(void); - - static void ThreadProvisioningHandler(const chip::DeviceLayer::ChipDeviceEvent * event, intptr_t arg); + CHIP_ERROR Init(); static AppTask sAppTask; - PWMDevice mPwmIdentifyLed; - -#if CONFIG_CHIP_FACTORY_DATA - chip::DeviceLayer::FactoryDataProvider mFactoryDataProvider; -#endif }; inline AppTask & GetAppTask(void) diff --git a/examples/all-clusters-app/telink/src/AppTask.cpp b/examples/all-clusters-app/telink/src/AppTask.cpp index cffc3cdb6c4426..74f1c4c3ec7494 100644 --- a/examples/all-clusters-app/telink/src/AppTask.cpp +++ b/examples/all-clusters-app/telink/src/AppTask.cpp @@ -17,206 +17,24 @@ */ #include "AppTask.h" - -#include "AppConfig.h" -#include "AppEvent.h" -#include "ButtonManager.h" #include "binding-handler.h" -#include "ThreadUtil.h" - -#include -#include -#include -#include -#include -#include -#include - -#if CONFIG_CHIP_OTA_REQUESTOR -#include "OTAUtil.h" -#endif - -#include -#include -#if CONFIG_CHIP_LIB_SHELL -#include -#include - -static int cmd_telink_reboot(const struct shell * shell, size_t argc, char ** argv) -{ - ARG_UNUSED(argc); - ARG_UNUSED(argv); - - shell_print(shell, "Performing board reboot..."); - sys_reboot(); -} - -SHELL_STATIC_SUBCMD_SET_CREATE(sub_telink, SHELL_CMD(reboot, NULL, "Reboot board command", cmd_telink_reboot), - SHELL_SUBCMD_SET_END); -SHELL_CMD_REGISTER(telink, &sub_telink, "Telink commands", NULL); -#endif // CONFIG_CHIP_LIB_SHELL - LOG_MODULE_DECLARE(app, CONFIG_CHIP_APP_LOG_LEVEL); -using namespace ::chip; -using namespace ::chip::app; -using namespace ::chip::Credentials; -using namespace ::chip::DeviceLayer; - -namespace { -constexpr int kFactoryResetCalcTimeout = 3000; -constexpr int kFactoryResetTriggerCntr = 3; -constexpr int kAppEventQueueSize = 10; -constexpr uint8_t kButtonPushEvent = 1; -constexpr uint8_t kButtonReleaseEvent = 0; -constexpr EndpointId kEndpointId = 1; -constexpr uint8_t kDefaultMinLevel = 0; -constexpr uint8_t kDefaultMaxLevel = 254; -constexpr uint32_t kIdentifyBlinkRateMs = 200; -constexpr uint32_t kIdentifyOkayOnRateMs = 50; -constexpr uint32_t kIdentifyOkayOffRateMs = 950; -constexpr uint32_t kIdentifyFinishOnRateMs = 950; -constexpr uint32_t kIdentifyFinishOffRateMs = 50; -constexpr uint32_t kIdentifyChannelChangeRateMs = 1000; -constexpr uint32_t kIdentifyBreatheRateMs = 1000; - -const struct pwm_dt_spec sPwmIdentifySpecGreenLed = LIGHTING_PWM_SPEC_IDENTIFY_GREEN; - -#if CONFIG_CHIP_FACTORY_DATA -// NOTE! This key is for test/certification only and should not be available in production devices! -uint8_t sTestEventTriggerEnableKey[TestEventTriggerDelegate::kEnableKeyLength] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, - 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }; -#endif - -K_MSGQ_DEFINE(sAppEventQueue, sizeof(AppEvent), kAppEventQueueSize, alignof(AppEvent)); -k_timer sFactoryResetTimer; -uint8_t sFactoryResetCntr = 0; - -#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED -LEDWidget sStatusLED; -#endif - -Button sFactoryResetButton; -Button sThreadStartButton; -Button sBleAdvStartButton; - -bool sIsThreadProvisioned = false; -bool sIsThreadEnabled = false; -bool sIsThreadAttached = false; -bool sHaveBLEConnections = false; - -chip::DeviceLayer::DeviceInfoProviderImpl gExampleDeviceInfoProvider; - -void OnIdentifyTriggerEffect(Identify * identify) -{ - AppTask::IdentifyEffectHandler(identify->mCurrentEffectIdentifier); -} - -Identify sIdentify = { - kEndpointId, - [](Identify *) { ChipLogProgress(Zcl, "OnIdentifyStart"); }, - [](Identify *) { ChipLogProgress(Zcl, "OnIdentifyStop"); }, - EMBER_ZCL_IDENTIFY_IDENTIFY_TYPE_VISIBLE_LED, - OnIdentifyTriggerEffect, -}; - -} // namespace - AppTask AppTask::sAppTask; -class AppFabricTableDelegate : public FabricTable::Delegate -{ - void OnFabricRemoved(const FabricTable & fabricTable, FabricIndex fabricIndex) - { - if (chip::Server::GetInstance().GetFabricTable().FabricCount() == 0) - { - chip::Server::GetInstance().ScheduleFactoryReset(); - } - } -}; - -constexpr EndpointId kNetworkCommissioningEndpointSecondary = 0xFFFE; - CHIP_ERROR AppTask::Init(void) { - LOG_INF("SW Version: %u, %s", CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION, CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING); - - // Initialize LEDs -#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED - LEDWidget::InitGpio(LEDS_PORT); - LEDWidget::SetStateUpdateCallback(LEDStateUpdateHandler); - sStatusLED.Init(SYSTEM_STATE_LED); - - UpdateStatusLED(); -#endif - - InitButtons(); - - // Initialize function button timer - k_timer_init(&sFactoryResetTimer, &AppTask::FactoryResetTimerTimeoutCallback, nullptr); - k_timer_user_data_set(&sFactoryResetTimer, this); - - // Initialize PWM Identify led - CHIP_ERROR err = sAppTask.mPwmIdentifyLed.Init(&sPwmIdentifySpecGreenLed, kDefaultMinLevel, kDefaultMaxLevel, kDefaultMaxLevel); - if (err != CHIP_NO_ERROR) - { - LOG_ERR("Green IDENTIFY PWM Device Init fail"); - return err; - } - - sAppTask.mPwmIdentifyLed.SetCallbacks(nullptr, nullptr, ActionIdentifyStateUpdateHandler); - - // Initialize CHIP server -#if CONFIG_CHIP_FACTORY_DATA - ReturnErrorOnFailure(mFactoryDataProvider.Init()); - SetDeviceInstanceInfoProvider(&mFactoryDataProvider); - SetDeviceAttestationCredentialsProvider(&mFactoryDataProvider); - SetCommissionableDataProvider(&mFactoryDataProvider); - // Read EnableKey from the factory data. - MutableByteSpan enableKey(sTestEventTriggerEnableKey); - err = mFactoryDataProvider.GetEnableKey(enableKey); - if (err != CHIP_NO_ERROR) - { - LOG_ERR("mFactoryDataProvider.GetEnableKey() failed. Could not delegate a test event trigger"); - memset(sTestEventTriggerEnableKey, 0, sizeof(sTestEventTriggerEnableKey)); - } -#else - SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); -#endif - - static CommonCaseDeviceServerInitParams initParams; - (void) initParams.InitializeStaticResourcesBeforeServerInit(); - ReturnErrorOnFailure(chip::Server::GetInstance().Init(initParams)); - gExampleDeviceInfoProvider.SetStorageDelegate(&Server::GetInstance().GetPersistentStorage()); - chip::DeviceLayer::SetDeviceInfoProvider(&gExampleDeviceInfoProvider); - -#if CONFIG_CHIP_OTA_REQUESTOR - InitBasicOTARequestor(); -#endif - - // We only have network commissioning on endpoint 0. - // Set up a valid Network Commissioning cluster on endpoint 0 is done in - // src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.cpp - emberAfEndpointEnableDisable(kNetworkCommissioningEndpointSecondary, false); - - ConfigurationMgr().LogDeviceConfig(); + InitCommonParts(); // Configure Bindings - err = InitBindingHandlers(); + CHIP_ERROR err = InitBindingHandlers(); if (err != CHIP_NO_ERROR) { LOG_ERR("InitBindingHandlers fail"); return err; } - 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); - err = ConnectivityMgr().SetBLEDeviceName("TelinkApp"); if (err != CHIP_NO_ERROR) { @@ -224,312 +42,5 @@ CHIP_ERROR AppTask::Init(void) return err; } - err = chip::Server::GetInstance().GetFabricTable().AddFabricDelegate(new AppFabricTableDelegate); - if (err != CHIP_NO_ERROR) - { - LOG_ERR("AppFabricTableDelegate fail"); - return err; - } - return CHIP_NO_ERROR; } - -CHIP_ERROR AppTask::StartApp(void) -{ - CHIP_ERROR err = Init(); - - if (err != CHIP_NO_ERROR) - { - LOG_ERR("AppTask Init fail"); - return err; - } - - AppEvent event = {}; - - while (true) - { - k_msgq_get(&sAppEventQueue, &event, K_FOREVER); - DispatchEvent(&event); - } -} - -void AppTask::IdentifyEffectHandler(EmberAfIdentifyEffectIdentifier aEffect) -{ - AppEvent event; - event.Type = AppEvent::kEventType_IdentifyStart; - - switch (aEffect) - { - case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BLINK: - ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BLINK"); - event.Handler = [](AppEvent *) { - sAppTask.mPwmIdentifyLed.InitiateBlinkAction(kIdentifyBlinkRateMs, kIdentifyBlinkRateMs); - }; - break; - case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BREATHE: - ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BREATHE"); - event.Handler = [](AppEvent *) { - sAppTask.mPwmIdentifyLed.InitiateBreatheAction(PWMDevice::kBreatheType_Both, kIdentifyBreatheRateMs); - }; - break; - case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_OKAY: - ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_OKAY"); - event.Handler = [](AppEvent *) { - sAppTask.mPwmIdentifyLed.InitiateBlinkAction(kIdentifyOkayOnRateMs, kIdentifyOkayOffRateMs); - }; - break; - case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_CHANNEL_CHANGE: - ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_CHANNEL_CHANGE"); - event.Handler = [](AppEvent *) { - sAppTask.mPwmIdentifyLed.InitiateBlinkAction(kIdentifyChannelChangeRateMs, kIdentifyChannelChangeRateMs); - }; - break; - case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_FINISH_EFFECT: - ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_FINISH_EFFECT"); - event.Handler = [](AppEvent *) { - sAppTask.mPwmIdentifyLed.InitiateBlinkAction(kIdentifyFinishOnRateMs, kIdentifyFinishOffRateMs); - }; - break; - case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_STOP_EFFECT: - ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_STOP_EFFECT"); - event.Handler = [](AppEvent *) { sAppTask.mPwmIdentifyLed.StopAction(); }; - event.Type = AppEvent::kEventType_IdentifyStop; - break; - default: - ChipLogProgress(Zcl, "No identifier effect"); - return; - } - - sAppTask.PostEvent(&event); -} - -void AppTask::FactoryResetButtonEventHandler(void) -{ - AppEvent event; - - event.Type = AppEvent::kEventType_Button; - event.ButtonEvent.Action = kButtonPushEvent; - event.Handler = FactoryResetHandler; - sAppTask.PostEvent(&event); -} - -void AppTask::FactoryResetHandler(AppEvent * aEvent) -{ - if (sFactoryResetCntr == 0) - { - k_timer_start(&sFactoryResetTimer, K_MSEC(kFactoryResetCalcTimeout), K_NO_WAIT); - } - - sFactoryResetCntr++; - LOG_INF("Factory Reset Trigger Counter: %d/%d", sFactoryResetCntr, kFactoryResetTriggerCntr); - - if (sFactoryResetCntr == kFactoryResetTriggerCntr) - { - k_timer_stop(&sFactoryResetTimer); - sFactoryResetCntr = 0; - - chip::Server::GetInstance().ScheduleFactoryReset(); - } -} - -void AppTask::StartThreadButtonEventHandler(void) -{ - AppEvent event; - - event.Type = AppEvent::kEventType_Button; - event.ButtonEvent.Action = kButtonPushEvent; - event.Handler = StartThreadHandler; - sAppTask.PostEvent(&event); -} - -void AppTask::StartThreadHandler(AppEvent * aEvent) -{ - LOG_INF("StartThreadHandler"); - if (!chip::DeviceLayer::ConnectivityMgr().IsThreadProvisioned()) - { - // Switch context from BLE to Thread - Internal::BLEManagerImpl sInstance; - sInstance.SwitchToIeee802154(); - StartDefaultThreadNetwork(); - } - else - { - LOG_INF("Device already commissioned"); - } -} - -void AppTask::StartBleAdvButtonEventHandler(void) -{ - AppEvent event; - - event.Type = AppEvent::kEventType_Button; - event.ButtonEvent.Action = kButtonPushEvent; - event.Handler = StartBleAdvHandler; - sAppTask.PostEvent(&event); -} - -void AppTask::StartBleAdvHandler(AppEvent * aEvent) -{ - LOG_INF("StartBleAdvHandler"); - - // Don't allow on starting Matter service BLE advertising after Thread provisioning. - if (ConnectivityMgr().IsThreadProvisioned()) - { - LOG_INF("Device already commissioned"); - return; - } - - if (ConnectivityMgr().IsBLEAdvertisingEnabled()) - { - LOG_INF("BLE adv already enabled"); - return; - } - - if (chip::Server::GetInstance().GetCommissioningWindowManager().OpenBasicCommissioningWindow() != CHIP_NO_ERROR) - { - LOG_ERR("OpenBasicCommissioningWindow fail"); - } -} - -#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED -void AppTask::UpdateLedStateEventHandler(AppEvent * aEvent) -{ - if (aEvent->Type == AppEvent::kEventType_UpdateLedState) - { - aEvent->UpdateLedStateEvent.LedWidget->UpdateState(); - } -} - -void AppTask::LEDStateUpdateHandler(LEDWidget * ledWidget) -{ - AppEvent event; - event.Type = AppEvent::kEventType_UpdateLedState; - event.Handler = UpdateLedStateEventHandler; - event.UpdateLedStateEvent.LedWidget = ledWidget; - sAppTask.PostEvent(&event); -} - -void AppTask::UpdateStatusLED(void) -{ - if (sIsThreadProvisioned && sIsThreadEnabled) - { - if (sIsThreadAttached) - { - sStatusLED.Blink(950, 50); - } - else - { - sStatusLED.Blink(100, 100); - } - } - else - { - sStatusLED.Blink(50, 950); - } -} -#endif - -void AppTask::ChipEventHandler(const ChipDeviceEvent * event, intptr_t /* arg */) -{ - switch (event->Type) - { - case DeviceEventType::kCHIPoBLEAdvertisingChange: - sHaveBLEConnections = ConnectivityMgr().NumBLEConnections() != 0; -#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED - UpdateStatusLED(); -#endif - break; - case DeviceEventType::kThreadStateChange: - sIsThreadProvisioned = ConnectivityMgr().IsThreadProvisioned(); - sIsThreadEnabled = ConnectivityMgr().IsThreadEnabled(); - sIsThreadAttached = ConnectivityMgr().IsThreadAttached(); -#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED - UpdateStatusLED(); -#endif - break; - case DeviceEventType::kThreadConnectivityChange: -#if CONFIG_CHIP_OTA_REQUESTOR - if (event->ThreadConnectivityChange.Result == kConnectivity_Established) - { - InitBasicOTARequestor(); - } -#endif - break; - default: - break; - } -} - -void AppTask::ActionIdentifyStateUpdateHandler(k_timer * timer) -{ - AppEvent event; - event.Type = AppEvent::kEventType_UpdateLedState; - event.Handler = UpdateIdentifyStateEventHandler; - sAppTask.PostEvent(&event); -} - -void AppTask::UpdateIdentifyStateEventHandler(AppEvent * aEvent) -{ - sAppTask.mPwmIdentifyLed.UpdateAction(); -} - -void AppTask::PostEvent(AppEvent * aEvent) -{ - if (k_msgq_put(&sAppEventQueue, aEvent, K_NO_WAIT) != 0) - { - LOG_INF("PostEvent fail"); - } -} - -void AppTask::DispatchEvent(AppEvent * aEvent) -{ - if (aEvent->Handler) - { - aEvent->Handler(aEvent); - } - else - { - LOG_INF("Dropping event without handler"); - } -} - -void AppTask::FactoryResetTimerTimeoutCallback(k_timer * timer) -{ - if (!timer) - { - return; - } - - AppEvent event; - event.Type = AppEvent::kEventType_Timer; - event.Handler = FactoryResetTimerEventHandler; - sAppTask.PostEvent(&event); -} - -void AppTask::FactoryResetTimerEventHandler(AppEvent * aEvent) -{ - if (aEvent->Type != AppEvent::kEventType_Timer) - { - return; - } - - sFactoryResetCntr = 0; - LOG_INF("Factory Reset Trigger Counter is cleared"); -} - -void AppTask::InitButtons(void) -{ -#if CONFIG_CHIP_BUTTON_MANAGER_IRQ_MODE - sFactoryResetButton.Configure(BUTTON_PORT, BUTTON_PIN_1, FactoryResetButtonEventHandler); - sThreadStartButton.Configure(BUTTON_PORT, BUTTON_PIN_3, StartThreadButtonEventHandler); - sBleAdvStartButton.Configure(BUTTON_PORT, BUTTON_PIN_4, StartBleAdvButtonEventHandler); -#else - sFactoryResetButton.Configure(BUTTON_PORT, BUTTON_PIN_3, BUTTON_PIN_1, FactoryResetButtonEventHandler); - sThreadStartButton.Configure(BUTTON_PORT, BUTTON_PIN_3, BUTTON_PIN_2, StartThreadButtonEventHandler); - sBleAdvStartButton.Configure(BUTTON_PORT, BUTTON_PIN_4, BUTTON_PIN_2, StartBleAdvButtonEventHandler); -#endif - - ButtonManagerInst().AddButton(sFactoryResetButton); - ButtonManagerInst().AddButton(sThreadStartButton); - ButtonManagerInst().AddButton(sBleAdvStartButton); -} diff --git a/examples/all-clusters-app/telink/src/main.cpp b/examples/all-clusters-app/telink/src/main.cpp deleted file mode 100644 index dc8216db43d274..00000000000000 --- a/examples/all-clusters-app/telink/src/main.cpp +++ /dev/null @@ -1,82 +0,0 @@ -/* - * - * Copyright (c) 2022-2023 Project CHIP Authors - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "AppTask.h" - -#include -#include - -#include - -LOG_MODULE_REGISTER(app, CONFIG_CHIP_APP_LOG_LEVEL); - -using namespace ::chip; -using namespace ::chip::Inet; -using namespace ::chip::DeviceLayer; - -int main(void) -{ - CHIP_ERROR err = CHIP_NO_ERROR; - - err = chip::Platform::MemoryInit(); - if (err != CHIP_NO_ERROR) - { - LOG_ERR("MemoryInit fail"); - goto exit; - } - - err = PlatformMgr().InitChipStack(); - if (err != CHIP_NO_ERROR) - { - LOG_ERR("InitChipStack fail"); - goto exit; - } - - err = PlatformMgr().StartEventLoopTask(); - if (err != CHIP_NO_ERROR) - { - LOG_ERR("StartEventLoopTask fail"); - goto exit; - } - - err = ThreadStackMgr().InitThreadStack(); - if (err != CHIP_NO_ERROR) - { - LOG_ERR("InitThreadStack fail"); - goto exit; - } - -#ifdef CONFIG_OPENTHREAD_MTD_SED - err = ConnectivityMgr().SetThreadDeviceType(ConnectivityManager::kThreadDeviceType_SleepyEndDevice); -#elif CONFIG_OPENTHREAD_MTD - err = ConnectivityMgr().SetThreadDeviceType(ConnectivityManager::kThreadDeviceType_MinimalEndDevice); -#else - err = ConnectivityMgr().SetThreadDeviceType(ConnectivityManager::kThreadDeviceType_Router); -#endif - if (err != CHIP_NO_ERROR) - { - LOG_ERR("SetThreadDeviceType fail"); - goto exit; - } - - err = GetAppTask().StartApp(); - -exit: - LOG_ERR("Exit err %" CHIP_ERROR_FORMAT, err.Format()); - return (err == CHIP_NO_ERROR) ? EXIT_SUCCESS : EXIT_FAILURE; -} diff --git a/examples/all-clusters-minimal-app/telink/CMakeLists.txt b/examples/all-clusters-minimal-app/telink/CMakeLists.txt index f5a0eeb9ede2e6..0d7e3a5313b12b 100644 --- a/examples/all-clusters-minimal-app/telink/CMakeLists.txt +++ b/examples/all-clusters-minimal-app/telink/CMakeLists.txt @@ -61,6 +61,7 @@ target_include_directories(app PRIVATE ${ALL_CLUSTERS_COMMON_DIR}/include ${GEN_DIR}/app-common ${GEN_DIR}/all-clusters-minimal-app + ${TELINK_COMMON}/common/include ${TELINK_COMMON}/util/include) add_definitions( @@ -69,10 +70,11 @@ add_definitions( target_sources(app PRIVATE src/AppTask.cpp - src/main.cpp ${ALL_CLUSTERS_COMMON_DIR}/src/static-supported-modes-manager.cpp ${ALL_CLUSTERS_COMMON_DIR}/src/bridged-actions-stub.cpp ${ALL_CLUSTERS_COMMON_DIR}/src/binding-handler.cpp + ${TELINK_COMMON}/common/src/mainCommon.cpp + ${TELINK_COMMON}/common/src/AppTaskCommon.cpp ${TELINK_COMMON}/util/src/LEDWidget.cpp ${TELINK_COMMON}/util/src/ButtonManager.cpp ${TELINK_COMMON}/util/src/ThreadUtil.cpp) diff --git a/examples/all-clusters-minimal-app/telink/include/AppConfig.h b/examples/all-clusters-minimal-app/telink/include/AppConfig.h index 1e0b2ae8e72ec0..10d4d5f281d67a 100644 --- a/examples/all-clusters-minimal-app/telink/include/AppConfig.h +++ b/examples/all-clusters-minimal-app/telink/include/AppConfig.h @@ -18,16 +18,12 @@ #pragma once -// ---- All Clusters Application example config ---- +// ---- All Clusters Minimal Application example config ---- -// Buttons config -#define BUTTON_PORT DEVICE_DT_GET(DT_NODELABEL(gpioc)) +#define APP_USE_EXAMPLE_START_BUTTON 0 +#define APP_USE_THREAD_START_BUTTON 0 +#define APP_SET_DEVICE_INFO_PROVIDER 0 +#define APP_SET_NETWORK_COMM_ENDPOINT_SEC 1 +#define APP_USE_IDENTIFY_PWM 0 // APP_USE_IDENTIFY_PWM must be defined before including "AppConfigCommon.h" -#define BUTTON_PIN_1 2 -#define BUTTON_PIN_3 3 -#define BUTTON_PIN_4 1 -#define BUTTON_PIN_2 0 - -// LEDs config -#define LEDS_PORT DEVICE_DT_GET(DT_NODELABEL(gpiob)) -#define SYSTEM_STATE_LED 7 +#include "AppConfigCommon.h" diff --git a/examples/all-clusters-minimal-app/telink/include/AppTask.h b/examples/all-clusters-minimal-app/telink/include/AppTask.h index 596f0836d2ea2c..24e00675e78472 100644 --- a/examples/all-clusters-minimal-app/telink/include/AppTask.h +++ b/examples/all-clusters-minimal-app/telink/include/AppTask.h @@ -18,53 +18,16 @@ #pragma once -#include "AppEvent.h" -#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED -#include "LEDWidget.h" -#endif +#include "AppTaskCommon.h" -#include - -#include - -#include - -struct k_timer; - -class AppTask +class AppTask : public AppTaskCommon { -public: - CHIP_ERROR StartApp(); - - void PostEvent(AppEvent * event); - private: friend AppTask & GetAppTask(void); + friend class AppTaskCommon; CHIP_ERROR Init(); - void DispatchEvent(AppEvent * event); - -#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED - static void UpdateLedStateEventHandler(AppEvent * aEvent); - static void LEDStateUpdateHandler(LEDWidget * ledWidget); - static void UpdateStatusLED(); -#endif - static void FactoryResetButtonEventHandler(void); - static void StartBleAdvButtonEventHandler(void); - - static void ChipEventHandler(const chip::DeviceLayer::ChipDeviceEvent * event, intptr_t arg); - - static void FactoryResetTimerTimeoutCallback(k_timer * timer); - - static void FactoryResetTimerEventHandler(AppEvent * aEvent); - static void FactoryResetHandler(AppEvent * aEvent); - static void StartBleAdvHandler(AppEvent * aEvent); - - static void InitButtons(void); - - static void ThreadProvisioningHandler(const chip::DeviceLayer::ChipDeviceEvent * event, intptr_t arg); - static AppTask sAppTask; }; diff --git a/examples/all-clusters-minimal-app/telink/prj.conf b/examples/all-clusters-minimal-app/telink/prj.conf index 2c563df99dad1b..7877bed5353dd4 100644 --- a/examples/all-clusters-minimal-app/telink/prj.conf +++ b/examples/all-clusters-minimal-app/telink/prj.conf @@ -52,6 +52,12 @@ CONFIG_CHIP_ENABLE_PAIRING_AUTOSTART=y # CHIP shell CONFIG_CHIP_LIB_SHELL=n +# Disable factory data support. +CONFIG_CHIP_FACTORY_DATA=n +CONFIG_CHIP_FACTORY_DATA_BUILD=n +CONFIG_CHIP_FACTORY_DATA_MERGE_WITH_FIRMWARE=n +CONFIG_CHIP_CERTIFICATION_DECLARATION_STORAGE=n + # Enable Button IRQ mode. The poling mode is used by default. CONFIG_CHIP_BUTTON_MANAGER_IRQ_MODE=n diff --git a/examples/all-clusters-minimal-app/telink/src/AppTask.cpp b/examples/all-clusters-minimal-app/telink/src/AppTask.cpp index 0dc0bb1a320a0d..93a83af0dbf44b 100644 --- a/examples/all-clusters-minimal-app/telink/src/AppTask.cpp +++ b/examples/all-clusters-minimal-app/telink/src/AppTask.cpp @@ -17,147 +17,24 @@ */ #include "AppTask.h" - -#include "AppConfig.h" -#include "AppEvent.h" -#include "ButtonManager.h" #include "binding-handler.h" -#include "ThreadUtil.h" - -#include -#include -#include -#include -#include - -#if CONFIG_CHIP_OTA_REQUESTOR -#include "OTAUtil.h" -#endif - -#include -#include - -#if CONFIG_CHIP_LIB_SHELL -#include -#include - -static int cmd_telink_reboot(const struct shell * shell, size_t argc, char ** argv) -{ - ARG_UNUSED(argc); - ARG_UNUSED(argv); - - shell_print(shell, "Performing board reboot..."); - sys_reboot(); -} - -SHELL_STATIC_SUBCMD_SET_CREATE(sub_telink, SHELL_CMD(reboot, NULL, "Reboot board command", cmd_telink_reboot), - SHELL_SUBCMD_SET_END); -SHELL_CMD_REGISTER(telink, &sub_telink, "Telink commands", NULL); -#endif // CONFIG_CHIP_LIB_SHELL - LOG_MODULE_DECLARE(app, CONFIG_CHIP_APP_LOG_LEVEL); -namespace { -constexpr int kFactoryResetCalcTimeout = 3000; -constexpr int kFactoryResetTriggerCntr = 3; -constexpr int kAppEventQueueSize = 10; -constexpr uint8_t kButtonPushEvent = 1; -constexpr uint8_t kButtonReleaseEvent = 0; - -K_MSGQ_DEFINE(sAppEventQueue, sizeof(AppEvent), kAppEventQueueSize, alignof(AppEvent)); -k_timer sFactoryResetTimer; -uint8_t sFactoryResetCntr = 0; - -#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED -LEDWidget sStatusLED; -#endif - -Button sFactoryResetButton; -Button sBleAdvStartButton; - -bool sIsThreadProvisioned = false; -bool sIsThreadEnabled = false; -bool sIsThreadAttached = false; -bool sHaveBLEConnections = false; - -} // namespace - -using namespace ::chip; -using namespace ::chip::Credentials; -using namespace ::chip::DeviceLayer; -using namespace ::chip::DeviceLayer::Internal; - AppTask AppTask::sAppTask; -class AppFabricTableDelegate : public FabricTable::Delegate -{ - void OnFabricRemoved(const FabricTable & fabricTable, FabricIndex fabricIndex) - { - if (chip::Server::GetInstance().GetFabricTable().FabricCount() == 0) - { - chip::Server::GetInstance().ScheduleFactoryReset(); - } - } -}; - -constexpr EndpointId kNetworkCommissioningEndpointSecondary = 0xFFFE; - CHIP_ERROR AppTask::Init() { - CHIP_ERROR err; - - LOG_INF("SW Version: %u, %s", CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION, CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING); - - // Initialize status LED -#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED - LEDWidget::InitGpio(LEDS_PORT); - LEDWidget::SetStateUpdateCallback(LEDStateUpdateHandler); - sStatusLED.Init(SYSTEM_STATE_LED); - - UpdateStatusLED(); -#endif - - InitButtons(); - - // Initialize function button timer - k_timer_init(&sFactoryResetTimer, &AppTask::FactoryResetTimerTimeoutCallback, nullptr); - k_timer_user_data_set(&sFactoryResetTimer, this); - - // Init ZCL Data Model and start server - static chip::CommonCaseDeviceServerInitParams initParams; - (void) initParams.InitializeStaticResourcesBeforeServerInit(); - chip::Server::GetInstance().Init(initParams); - - // Initialize device attestation config - SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); - -#if CONFIG_CHIP_OTA_REQUESTOR - InitBasicOTARequestor(); -#endif - - // We only have network commissioning on endpoint 0. - // Set up a valid Network Commissioning cluster on endpoint 0 is done in - // src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.cpp - emberAfEndpointEnableDisable(kNetworkCommissioningEndpointSecondary, false); - - ConfigurationMgr().LogDeviceConfig(); + InitCommonParts(); // Configure Bindings - err = InitBindingHandlers(); + CHIP_ERROR err = InitBindingHandlers(); if (err != CHIP_NO_ERROR) { LOG_ERR("InitBindingHandlers fail"); return err; } - 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); - err = ConnectivityMgr().SetBLEDeviceName("TelinkMinApp"); if (err != CHIP_NO_ERROR) { @@ -165,224 +42,5 @@ CHIP_ERROR AppTask::Init() return err; } - err = chip::Server::GetInstance().GetFabricTable().AddFabricDelegate(new AppFabricTableDelegate); - if (err != CHIP_NO_ERROR) - { - LOG_ERR("AppFabricTableDelegate fail"); - return err; - } - return CHIP_NO_ERROR; } - -CHIP_ERROR AppTask::StartApp() -{ - CHIP_ERROR err = Init(); - - if (err != CHIP_NO_ERROR) - { - LOG_ERR("AppTask Init fail"); - return err; - } - - AppEvent event = {}; - - while (true) - { - k_msgq_get(&sAppEventQueue, &event, K_FOREVER); - DispatchEvent(&event); - } -} - -void AppTask::FactoryResetButtonEventHandler(void) -{ - AppEvent event; - - event.Type = AppEvent::kEventType_Button; - event.ButtonEvent.Action = kButtonPushEvent; - event.Handler = FactoryResetHandler; - sAppTask.PostEvent(&event); -} - -void AppTask::FactoryResetHandler(AppEvent * aEvent) -{ - if (sFactoryResetCntr == 0) - { - k_timer_start(&sFactoryResetTimer, K_MSEC(kFactoryResetCalcTimeout), K_NO_WAIT); - } - - sFactoryResetCntr++; - LOG_INF("Factory Reset Trigger Counter: %d/%d", sFactoryResetCntr, kFactoryResetTriggerCntr); - - if (sFactoryResetCntr == kFactoryResetTriggerCntr) - { - k_timer_stop(&sFactoryResetTimer); - sFactoryResetCntr = 0; - - chip::Server::GetInstance().ScheduleFactoryReset(); - } -} - -void AppTask::StartBleAdvButtonEventHandler(void) -{ - AppEvent event; - - event.Type = AppEvent::kEventType_Button; - event.ButtonEvent.Action = kButtonPushEvent; - event.Handler = StartBleAdvHandler; - sAppTask.PostEvent(&event); -} - -void AppTask::StartBleAdvHandler(AppEvent * aEvent) -{ - LOG_INF("StartBleAdvHandler"); - - // Don't allow on starting Matter service BLE advertising after Thread provisioning. - if (ConnectivityMgr().IsThreadProvisioned()) - { - LOG_INF("Device already commissioned"); - return; - } - - if (ConnectivityMgr().IsBLEAdvertisingEnabled()) - { - LOG_INF("BLE adv already enabled"); - return; - } - - if (chip::Server::GetInstance().GetCommissioningWindowManager().OpenBasicCommissioningWindow() != CHIP_NO_ERROR) - { - LOG_ERR("OpenBasicCommissioningWindow fail"); - } -} - -#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED -void AppTask::UpdateLedStateEventHandler(AppEvent * aEvent) -{ - if (aEvent->Type == AppEvent::kEventType_UpdateLedState) - { - aEvent->UpdateLedStateEvent.LedWidget->UpdateState(); - } -} - -void AppTask::LEDStateUpdateHandler(LEDWidget * ledWidget) -{ - AppEvent event; - event.Type = AppEvent::kEventType_UpdateLedState; - event.Handler = UpdateLedStateEventHandler; - event.UpdateLedStateEvent.LedWidget = ledWidget; - sAppTask.PostEvent(&event); -} - -void AppTask::UpdateStatusLED() -{ - if (sIsThreadProvisioned && sIsThreadEnabled) - { - if (sIsThreadAttached) - { - sStatusLED.Blink(950, 50); - } - else - { - sStatusLED.Blink(100, 100); - } - } - else - { - sStatusLED.Blink(50, 950); - } -} -#endif - -void AppTask::ChipEventHandler(const ChipDeviceEvent * event, intptr_t /* arg */) -{ - switch (event->Type) - { - case DeviceEventType::kCHIPoBLEAdvertisingChange: - sHaveBLEConnections = ConnectivityMgr().NumBLEConnections() != 0; -#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED - UpdateStatusLED(); -#endif - break; - case DeviceEventType::kThreadStateChange: - sIsThreadProvisioned = ConnectivityMgr().IsThreadProvisioned(); - sIsThreadEnabled = ConnectivityMgr().IsThreadEnabled(); - sIsThreadAttached = ConnectivityMgr().IsThreadAttached(); -#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED - UpdateStatusLED(); -#endif - break; - case DeviceEventType::kThreadConnectivityChange: -#if CONFIG_CHIP_OTA_REQUESTOR - if (event->ThreadConnectivityChange.Result == kConnectivity_Established) - { - InitBasicOTARequestor(); - } -#endif - break; - default: - break; - } -} - -void AppTask::PostEvent(AppEvent * aEvent) -{ - if (!aEvent) - return; - if (k_msgq_put(&sAppEventQueue, aEvent, K_NO_WAIT) != 0) - { - LOG_INF("PostEvent fail"); - } -} - -void AppTask::DispatchEvent(AppEvent * aEvent) -{ - if (!aEvent) - return; - if (aEvent->Handler) - { - aEvent->Handler(aEvent); - } - else - { - LOG_INF("Dropping event without handler"); - } -} - -void AppTask::FactoryResetTimerTimeoutCallback(k_timer * timer) -{ - if (!timer) - { - return; - } - - AppEvent event; - event.Type = AppEvent::kEventType_Timer; - event.Handler = FactoryResetTimerEventHandler; - sAppTask.PostEvent(&event); -} - -void AppTask::FactoryResetTimerEventHandler(AppEvent * aEvent) -{ - if (aEvent->Type != AppEvent::kEventType_Timer) - { - return; - } - - sFactoryResetCntr = 0; - LOG_INF("Factory Reset Trigger Counter is cleared"); -} - -void AppTask::InitButtons(void) -{ -#if CONFIG_CHIP_BUTTON_MANAGER_IRQ_MODE - sFactoryResetButton.Configure(BUTTON_PORT, BUTTON_PIN_1, FactoryResetButtonEventHandler); - sBleAdvStartButton.Configure(BUTTON_PORT, BUTTON_PIN_4, StartBleAdvButtonEventHandler); -#else - sFactoryResetButton.Configure(BUTTON_PORT, BUTTON_PIN_3, BUTTON_PIN_1, FactoryResetButtonEventHandler); - sBleAdvStartButton.Configure(BUTTON_PORT, BUTTON_PIN_4, BUTTON_PIN_2, StartBleAdvButtonEventHandler); -#endif - - ButtonManagerInst().AddButton(sFactoryResetButton); - ButtonManagerInst().AddButton(sBleAdvStartButton); -} diff --git a/examples/all-clusters-minimal-app/telink/src/main.cpp b/examples/all-clusters-minimal-app/telink/src/main.cpp deleted file mode 100644 index dc8216db43d274..00000000000000 --- a/examples/all-clusters-minimal-app/telink/src/main.cpp +++ /dev/null @@ -1,82 +0,0 @@ -/* - * - * Copyright (c) 2022-2023 Project CHIP Authors - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "AppTask.h" - -#include -#include - -#include - -LOG_MODULE_REGISTER(app, CONFIG_CHIP_APP_LOG_LEVEL); - -using namespace ::chip; -using namespace ::chip::Inet; -using namespace ::chip::DeviceLayer; - -int main(void) -{ - CHIP_ERROR err = CHIP_NO_ERROR; - - err = chip::Platform::MemoryInit(); - if (err != CHIP_NO_ERROR) - { - LOG_ERR("MemoryInit fail"); - goto exit; - } - - err = PlatformMgr().InitChipStack(); - if (err != CHIP_NO_ERROR) - { - LOG_ERR("InitChipStack fail"); - goto exit; - } - - err = PlatformMgr().StartEventLoopTask(); - if (err != CHIP_NO_ERROR) - { - LOG_ERR("StartEventLoopTask fail"); - goto exit; - } - - err = ThreadStackMgr().InitThreadStack(); - if (err != CHIP_NO_ERROR) - { - LOG_ERR("InitThreadStack fail"); - goto exit; - } - -#ifdef CONFIG_OPENTHREAD_MTD_SED - err = ConnectivityMgr().SetThreadDeviceType(ConnectivityManager::kThreadDeviceType_SleepyEndDevice); -#elif CONFIG_OPENTHREAD_MTD - err = ConnectivityMgr().SetThreadDeviceType(ConnectivityManager::kThreadDeviceType_MinimalEndDevice); -#else - err = ConnectivityMgr().SetThreadDeviceType(ConnectivityManager::kThreadDeviceType_Router); -#endif - if (err != CHIP_NO_ERROR) - { - LOG_ERR("SetThreadDeviceType fail"); - goto exit; - } - - err = GetAppTask().StartApp(); - -exit: - LOG_ERR("Exit err %" CHIP_ERROR_FORMAT, err.Format()); - return (err == CHIP_NO_ERROR) ? EXIT_SUCCESS : EXIT_FAILURE; -} diff --git a/examples/bridge-app/telink/CMakeLists.txt b/examples/bridge-app/telink/CMakeLists.txt index 52e498d10927fe..46953af249d8b7 100644 --- a/examples/bridge-app/telink/CMakeLists.txt +++ b/examples/bridge-app/telink/CMakeLists.txt @@ -59,6 +59,7 @@ target_include_directories(app PRIVATE include ${GEN_DIR}/app-common ${GEN_DIR}/bridge-app + ${TELINK_COMMON}/common/include ${TELINK_COMMON}/util/include ${TELINK_COMMON}/app/include) @@ -69,10 +70,11 @@ add_definitions( target_sources(app PRIVATE src/AppTask.cpp - src/main.cpp src/ZclCallbacks.cpp src/Device.cpp src/DeviceCallbacks.cpp + ${TELINK_COMMON}/common/src/mainCommon.cpp + ${TELINK_COMMON}/common/src/AppTaskCommon.cpp ${TELINK_COMMON}/util/src/LEDWidget.cpp ${TELINK_COMMON}/util/src/ButtonManager.cpp ${TELINK_COMMON}/util/src/ThreadUtil.cpp diff --git a/examples/bridge-app/telink/include/AppConfig.h b/examples/bridge-app/telink/include/AppConfig.h index 88918d553e078d..3f7cccb6807d10 100644 --- a/examples/bridge-app/telink/include/AppConfig.h +++ b/examples/bridge-app/telink/include/AppConfig.h @@ -20,20 +20,12 @@ // ---- Bridge App Example Config ---- -// Buttons config -#define BUTTON_PORT DEVICE_DT_GET(DT_NODELABEL(gpioc)) +#define APP_USE_EXAMPLE_START_BUTTON 1 +#define APP_USE_THREAD_START_BUTTON 1 +#define APP_SET_DEVICE_INFO_PROVIDER 1 +#define APP_SET_NETWORK_COMM_ENDPOINT_SEC 0 +#define APP_USE_IDENTIFY_PWM 1 // APP_USE_IDENTIFY_PWM must be defined before including "AppConfigCommon.h" -#define BUTTON_PIN_1 2 -#define BUTTON_PIN_3 3 -#define BUTTON_PIN_4 1 -#define BUTTON_PIN_2 0 - -// LEDs config -#define LEDS_PORT DEVICE_DT_GET(DT_NODELABEL(gpiob)) -#define SYSTEM_STATE_LED 7 - -// Lighting LED config -#define USE_RGB_PWM 0 +#include "AppConfigCommon.h" #define LIGHTING_PWM_SPEC_RGB_BLUE PWM_DT_SPEC_GET(DT_ALIAS(pwm_led0)) -#define LIGHTING_PWM_SPEC_IDENTIFY_GREEN PWM_DT_SPEC_GET(DT_ALIAS(pwm_led3)) diff --git a/examples/bridge-app/telink/include/AppTask.h b/examples/bridge-app/telink/include/AppTask.h index 35e9977ebfa0ac..6b8a60df890dbf 100644 --- a/examples/bridge-app/telink/include/AppTask.h +++ b/examples/bridge-app/telink/include/AppTask.h @@ -18,77 +18,30 @@ #pragma once -#include "AppConfig.h" -#include "AppEvent.h" -#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED -#include "LEDWidget.h" -#endif +#include "AppTaskCommon.h" #include "PWMDevice.h" -#include -#if CONFIG_CHIP_FACTORY_DATA -#include -#endif - -#include - -struct k_timer; -struct Identify; - -class AppTask +class AppTask : public AppTaskCommon { public: - CHIP_ERROR StartApp(void); - - void PostEvent(AppEvent * aEvent); void UpdateClusterState(void); + static void InitServer(intptr_t context); PWMDevice & GetPWMDevice(void) { return mPwmRgbBlueLed; } - static void IdentifyEffectHandler(EmberAfIdentifyEffectIdentifier aEffect); - private: friend AppTask & GetAppTask(void); + friend class AppTaskCommon; + CHIP_ERROR Init(void); static void ActionInitiated(PWMDevice::Action_t aAction, int32_t aActor); static void ActionCompleted(PWMDevice::Action_t aAction, int32_t aActor); - static void ActionIdentifyStateUpdateHandler(k_timer * timer); - - void DispatchEvent(AppEvent * event); -#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED - static void UpdateLedStateEventHandler(AppEvent * aEvent); - static void LEDStateUpdateHandler(LEDWidget * ledWidget); - static void UpdateStatusLED(); -#endif - 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 FactoryResetTimerTimeoutCallback(k_timer * timer); - - static void FactoryResetTimerEventHandler(AppEvent * aEvent); - static void FactoryResetHandler(AppEvent * aEvent); - static void StartThreadHandler(AppEvent * aEvent); static void LightingActionEventHandler(AppEvent * aEvent); - static void StartBleAdvHandler(AppEvent * aEvent); - static void UpdateIdentifyStateEventHandler(AppEvent * aEvent); - - static void InitButtons(void); - static void InitServer(intptr_t context); - - static void ThreadProvisioningHandler(const chip::DeviceLayer::ChipDeviceEvent * event, intptr_t arg); - static AppTask sAppTask; PWMDevice mPwmRgbBlueLed; - PWMDevice mPwmIdentifyLed; -#if CONFIG_CHIP_FACTORY_DATA - chip::DeviceLayer::FactoryDataProvider mFactoryDataProvider; -#endif + static AppTask sAppTask; }; inline AppTask & GetAppTask(void) diff --git a/examples/bridge-app/telink/src/AppTask.cpp b/examples/bridge-app/telink/src/AppTask.cpp index 8a9bcd127c7079..8f6bf092a61649 100644 --- a/examples/bridge-app/telink/src/AppTask.cpp +++ b/examples/bridge-app/telink/src/AppTask.cpp @@ -17,123 +17,16 @@ */ #include "AppTask.h" - -#include "AppConfig.h" -#include "AppEvent.h" -#include "ButtonManager.h" #include "Device.h" -#include -#include -#include -#include -#include - -#include "ThreadUtil.h" -#include #include -#include -#include -#include -#include -#include -#include -#include - -#if CONFIG_CHIP_OTA_REQUESTOR -#include "OTAUtil.h" -#endif - -#include -#include - -#include - -#if CONFIG_CHIP_LIB_SHELL -#include -#include - -static int cmd_telink_reboot(const struct shell * shell, size_t argc, char ** argv) -{ - ARG_UNUSED(argc); - ARG_UNUSED(argv); - - shell_print(shell, "Performing board reboot..."); - sys_reboot(); -} - -SHELL_STATIC_SUBCMD_SET_CREATE(sub_telink, SHELL_CMD(reboot, NULL, "Reboot board command", cmd_telink_reboot), - SHELL_SUBCMD_SET_END); -SHELL_CMD_REGISTER(telink, &sub_telink, "Telink commands", NULL); -#endif // CONFIG_CHIP_LIB_SHELL +#include +#include LOG_MODULE_DECLARE(app, CONFIG_CHIP_APP_LOG_LEVEL); -using namespace ::chip; -using namespace ::chip::app; -using namespace ::chip::Credentials; -using namespace ::chip::DeviceLayer; - namespace { -constexpr int kFactoryResetCalcTimeout = 3000; -constexpr int kFactoryResetTriggerCntr = 3; -constexpr int kAppEventQueueSize = 10; -constexpr uint8_t kButtonPushEvent = 1; -constexpr uint8_t kButtonReleaseEvent = 0; -constexpr EndpointId kLightEndpointId = 1; -constexpr uint8_t kDefaultMinLevel = 0; -constexpr uint8_t kDefaultMaxLevel = 254; -constexpr uint32_t kIdentifyBlinkRateMs = 200; -constexpr uint32_t kIdentifyOkayOnRateMs = 50; -constexpr uint32_t kIdentifyOkayOffRateMs = 950; -constexpr uint32_t kIdentifyFinishOnRateMs = 950; -constexpr uint32_t kIdentifyFinishOffRateMs = 50; -constexpr uint32_t kIdentifyChannelChangeRateMs = 1000; -constexpr uint32_t kIdentifyBreatheRateMs = 1000; - const struct pwm_dt_spec sPwmRgbSpecBlueLed = LIGHTING_PWM_SPEC_RGB_BLUE; - -const struct pwm_dt_spec sPwmIdentifySpecGreenLed = LIGHTING_PWM_SPEC_IDENTIFY_GREEN; - -#if CONFIG_CHIP_FACTORY_DATA -// NOTE! This key is for test/certification only and should not be available in production devices! -uint8_t sTestEventTriggerEnableKey[TestEventTriggerDelegate::kEnableKeyLength] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, - 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }; -#endif - -K_MSGQ_DEFINE(sAppEventQueue, sizeof(AppEvent), kAppEventQueueSize, alignof(AppEvent)); -k_timer sFactoryResetTimer; -uint8_t sFactoryResetCntr = 0; - -#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED -LEDWidget sStatusLED; -#endif - -Button sFactoryResetButton; -Button sLightingButton; -Button sThreadStartButton; -Button sBleAdvStartButton; - -bool sIsThreadProvisioned = false; -bool sIsThreadEnabled = false; -bool sIsThreadAttached = false; -bool sHaveBLEConnections = false; - -chip::DeviceLayer::DeviceInfoProviderImpl gExampleDeviceInfoProvider; - -void OnIdentifyTriggerEffect(Identify * identify) -{ - AppTask::IdentifyEffectHandler(identify->mCurrentEffectIdentifier); -} - -Identify sIdentify = { - kLightEndpointId, - [](Identify *) { ChipLogProgress(Zcl, "OnIdentifyStart"); }, - [](Identify *) { ChipLogProgress(Zcl, "OnIdentifyStop"); }, - EMBER_ZCL_IDENTIFY_IDENTIFY_TYPE_VISIBLE_LED, - OnIdentifyTriggerEffect, -}; - } // namespace AppTask AppTask::sAppTask; @@ -496,53 +389,17 @@ bool emberAfActionsClusterInstantActionCallback(app::CommandHandler * commandObj return true; } -class AppFabricTableDelegate : public FabricTable::Delegate -{ - void OnFabricRemoved(const FabricTable & fabricTable, FabricIndex fabricIndex) - { - if (chip::Server::GetInstance().GetFabricTable().FabricCount() == 0) - { - chip::Server::GetInstance().ScheduleFactoryReset(); - } - } -}; - CHIP_ERROR AppTask::Init(void) { - LOG_INF("SW Version: %u, %s", CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION, CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING); - - // Initialize LEDs -#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED - LEDWidget::InitGpio(LEDS_PORT); - LEDWidget::SetStateUpdateCallback(LEDStateUpdateHandler); - - sStatusLED.Init(SYSTEM_STATE_LED); - - UpdateStatusLED(); -#endif - - InitButtons(); - - // Initialize function button timer - k_timer_init(&sFactoryResetTimer, &AppTask::FactoryResetTimerTimeoutCallback, nullptr); - k_timer_user_data_set(&sFactoryResetTimer, this); - // Init lighting manager uint8_t minLightLevel = kDefaultMinLevel; - Clusters::LevelControl::Attributes::MinLevel::Get(kLightEndpointId, &minLightLevel); + Clusters::LevelControl::Attributes::MinLevel::Get(kExampleEndpointId, &minLightLevel); uint8_t maxLightLevel = kDefaultMaxLevel; - Clusters::LevelControl::Attributes::MaxLevel::Get(kLightEndpointId, &maxLightLevel); + Clusters::LevelControl::Attributes::MaxLevel::Get(kExampleEndpointId, &maxLightLevel); - // Initialize PWM LEDs - CHIP_ERROR err = sAppTask.mPwmIdentifyLed.Init(&sPwmIdentifySpecGreenLed, kDefaultMinLevel, kDefaultMaxLevel, kDefaultMaxLevel); - if (err != CHIP_NO_ERROR) - { - LOG_ERR("Green IDENTIFY PWM Device Init fail"); - return err; - } - - err = sAppTask.mPwmRgbBlueLed.Init(&sPwmRgbSpecBlueLed, minLightLevel, maxLightLevel, maxLightLevel); + // Initialize PWM LED + CHIP_ERROR err = sAppTask.mPwmRgbBlueLed.Init(&sPwmRgbSpecBlueLed, minLightLevel, maxLightLevel, maxLightLevel); if (err != CHIP_NO_ERROR) { LOG_ERR("Blue RGB PWM Device Init fail"); @@ -550,44 +407,11 @@ CHIP_ERROR AppTask::Init(void) } sAppTask.mPwmRgbBlueLed.SetCallbacks(ActionInitiated, ActionCompleted, nullptr); - sAppTask.mPwmIdentifyLed.SetCallbacks(nullptr, nullptr, ActionIdentifyStateUpdateHandler); - - // Initialize CHIP server -#if CONFIG_CHIP_FACTORY_DATA - ReturnErrorOnFailure(mFactoryDataProvider.Init()); - SetDeviceInstanceInfoProvider(&mFactoryDataProvider); - SetDeviceAttestationCredentialsProvider(&mFactoryDataProvider); - SetCommissionableDataProvider(&mFactoryDataProvider); - // Read EnableKey from the factory data. - MutableByteSpan enableKey(sTestEventTriggerEnableKey); - err = mFactoryDataProvider.GetEnableKey(enableKey); - if (err != CHIP_NO_ERROR) - { - LOG_ERR("GetEnableKey fail"); - memset(sTestEventTriggerEnableKey, 0, sizeof(sTestEventTriggerEnableKey)); - } -#else - SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); -#endif - - static CommonCaseDeviceServerInitParams initParams; - (void) initParams.InitializeStaticResourcesBeforeServerInit(); - ReturnErrorOnFailure(chip::Server::GetInstance().Init(initParams)); - - gExampleDeviceInfoProvider.SetStorageDelegate(&Server::GetInstance().GetPersistentStorage()); - chip::DeviceLayer::SetDeviceInfoProvider(&gExampleDeviceInfoProvider); -#if CONFIG_CHIP_OTA_REQUESTOR - InitBasicOTARequestor(); +#if APP_USE_EXAMPLE_START_BUTTON + SetExampleButtonCallbacks(LightingActionEventHandler); #endif - - 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); + InitCommonParts(); err = ConnectivityMgr().SetBLEDeviceName("TelinkLight"); if (err != CHIP_NO_ERROR) @@ -596,13 +420,6 @@ CHIP_ERROR AppTask::Init(void) return err; } - err = chip::Server::GetInstance().GetFabricTable().AddFabricDelegate(new AppFabricTableDelegate); - if (err != CHIP_NO_ERROR) - { - LOG_ERR("AppFabricTableDelegate fail"); - return err; - } - memset(gDevices, 0, sizeof(gDevices)); gLight1.SetReachable(true); @@ -623,28 +440,8 @@ CHIP_ERROR AppTask::Init(void) return CHIP_NO_ERROR; } -CHIP_ERROR AppTask::StartApp(void) +void AppTask::InitServer(intptr_t context) { - CHIP_ERROR err = Init(); - - if (err != CHIP_NO_ERROR) - { - LOG_ERR("AppTask Init fail"); - return err; - } - - AppEvent event = {}; - - while (true) - { - k_msgq_get(&sAppEventQueue, &event, K_FOREVER); - DispatchEvent(&event); - } -} - -static void AppTask::InitServer(intptr_t context) -{ - // Set starting endpoint id where dynamic endpoints will be assigned, which // will be the next consecutive endpoint id after the last fixed endpoint. gFirstDynamicEndpointId = static_cast( @@ -735,16 +532,6 @@ EmberAfStatus HandleReadTempMeasurementAttribute(DeviceTempSensor * dev, chip::A return EMBER_ZCL_STATUS_SUCCESS; } -void AppTask::LightingActionButtonEventHandler(void) -{ - AppEvent event; - - event.Type = AppEvent::kEventType_Button; - event.ButtonEvent.Action = kButtonPushEvent; - event.Handler = LightingActionEventHandler; - sAppTask.PostEvent(&event); -} - void AppTask::LightingActionEventHandler(AppEvent * aEvent) { PWMDevice::Action_t action = PWMDevice::INVALID_ACTION; @@ -767,226 +554,6 @@ void AppTask::LightingActionEventHandler(AppEvent * aEvent) } } -void AppTask::IdentifyEffectHandler(EmberAfIdentifyEffectIdentifier aEffect) -{ - AppEvent event; - event.Type = AppEvent::kEventType_IdentifyStart; - - switch (aEffect) - { - case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BLINK: - ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BLINK"); - event.Handler = [](AppEvent *) { - sAppTask.mPwmIdentifyLed.InitiateBlinkAction(kIdentifyBlinkRateMs, kIdentifyBlinkRateMs); - }; - break; - case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BREATHE: - ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BREATHE"); - event.Handler = [](AppEvent *) { - sAppTask.mPwmIdentifyLed.InitiateBreatheAction(PWMDevice::kBreatheType_Both, kIdentifyBreatheRateMs); - }; - break; - case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_OKAY: - ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_OKAY"); - event.Handler = [](AppEvent *) { - sAppTask.mPwmIdentifyLed.InitiateBlinkAction(kIdentifyOkayOnRateMs, kIdentifyOkayOffRateMs); - }; - break; - case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_CHANNEL_CHANGE: - ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_CHANNEL_CHANGE"); - event.Handler = [](AppEvent *) { - sAppTask.mPwmIdentifyLed.InitiateBlinkAction(kIdentifyChannelChangeRateMs, kIdentifyChannelChangeRateMs); - }; - break; - case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_FINISH_EFFECT: - ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_FINISH_EFFECT"); - event.Handler = [](AppEvent *) { - sAppTask.mPwmIdentifyLed.InitiateBlinkAction(kIdentifyFinishOnRateMs, kIdentifyFinishOffRateMs); - }; - break; - case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_STOP_EFFECT: - ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_STOP_EFFECT"); - event.Handler = [](AppEvent *) { sAppTask.mPwmIdentifyLed.StopAction(); }; - event.Type = AppEvent::kEventType_IdentifyStop; - break; - default: - ChipLogProgress(Zcl, "No identifier effect"); - return; - } - - sAppTask.PostEvent(&event); -} - -void AppTask::FactoryResetButtonEventHandler(void) -{ - AppEvent event; - - event.Type = AppEvent::kEventType_Button; - event.ButtonEvent.Action = kButtonPushEvent; - event.Handler = FactoryResetHandler; - sAppTask.PostEvent(&event); -} - -void AppTask::FactoryResetHandler(AppEvent * aEvent) -{ - if (sFactoryResetCntr == 0) - { - k_timer_start(&sFactoryResetTimer, K_MSEC(kFactoryResetCalcTimeout), K_NO_WAIT); - } - - sFactoryResetCntr++; - LOG_INF("Factory Reset Trigger Counter: %d/%d", sFactoryResetCntr, kFactoryResetTriggerCntr); - - if (sFactoryResetCntr == kFactoryResetTriggerCntr) - { - k_timer_stop(&sFactoryResetTimer); - sFactoryResetCntr = 0; - - chip::Server::GetInstance().ScheduleFactoryReset(); - } -} - -void AppTask::StartThreadButtonEventHandler(void) -{ - AppEvent event; - - event.Type = AppEvent::kEventType_Button; - event.ButtonEvent.Action = kButtonPushEvent; - event.Handler = StartThreadHandler; - sAppTask.PostEvent(&event); -} - -void AppTask::StartThreadHandler(AppEvent * aEvent) -{ - LOG_INF("StartThreadHandler"); - if (!chip::DeviceLayer::ConnectivityMgr().IsThreadProvisioned()) - { - // Switch context from BLE to Thread - Internal::BLEManagerImpl sInstance; - sInstance.SwitchToIeee802154(); - StartDefaultThreadNetwork(); - } - else - { - LOG_INF("Device already commissioned"); - } -} - -void AppTask::StartBleAdvButtonEventHandler(void) -{ - AppEvent event; - - event.Type = AppEvent::kEventType_Button; - event.ButtonEvent.Action = kButtonPushEvent; - event.Handler = StartBleAdvHandler; - sAppTask.PostEvent(&event); -} - -void AppTask::StartBleAdvHandler(AppEvent * aEvent) -{ - LOG_INF("StartBleAdvHandler"); - - // Don't allow on starting Matter service BLE advertising after Thread provisioning. - if (ConnectivityMgr().IsThreadProvisioned()) - { - LOG_INF("Device already commissioned"); - return; - } - - if (ConnectivityMgr().IsBLEAdvertisingEnabled()) - { - LOG_INF("BLE adv already enabled"); - return; - } - - if (chip::Server::GetInstance().GetCommissioningWindowManager().OpenBasicCommissioningWindow() != CHIP_NO_ERROR) - { - LOG_ERR("OpenBasicCommissioningWindow fail"); - } -} - -#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED -void AppTask::UpdateLedStateEventHandler(AppEvent * aEvent) -{ - if (aEvent->Type == AppEvent::kEventType_UpdateLedState) - { - aEvent->UpdateLedStateEvent.LedWidget->UpdateState(); - } -} - -void AppTask::LEDStateUpdateHandler(LEDWidget * ledWidget) -{ - AppEvent event; - event.Type = AppEvent::kEventType_UpdateLedState; - event.Handler = UpdateLedStateEventHandler; - event.UpdateLedStateEvent.LedWidget = ledWidget; - sAppTask.PostEvent(&event); -} - -void AppTask::UpdateStatusLED(void) -{ - if (sIsThreadProvisioned && sIsThreadEnabled) - { - if (sIsThreadAttached) - { - sStatusLED.Blink(950, 50); - } - else - { - sStatusLED.Blink(100, 100); - } - } - else - { - sStatusLED.Blink(50, 950); - } -} -#endif - -void AppTask::ChipEventHandler(const ChipDeviceEvent * event, intptr_t /* arg */) -{ - switch (event->Type) - { - case DeviceEventType::kCHIPoBLEAdvertisingChange: - sHaveBLEConnections = ConnectivityMgr().NumBLEConnections() != 0; -#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED - UpdateStatusLED(); -#endif - break; - case DeviceEventType::kThreadStateChange: - sIsThreadProvisioned = ConnectivityMgr().IsThreadProvisioned(); - sIsThreadEnabled = ConnectivityMgr().IsThreadEnabled(); - sIsThreadAttached = ConnectivityMgr().IsThreadAttached(); -#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED - UpdateStatusLED(); -#endif - break; - case DeviceEventType::kThreadConnectivityChange: -#if CONFIG_CHIP_OTA_REQUESTOR - if (event->ThreadConnectivityChange.Result == kConnectivity_Established) - { - InitBasicOTARequestor(); - } -#endif - break; - default: - break; - } -} - -void AppTask::ActionIdentifyStateUpdateHandler(k_timer * timer) -{ - AppEvent event; - event.Type = AppEvent::kEventType_UpdateLedState; - event.Handler = UpdateIdentifyStateEventHandler; - sAppTask.PostEvent(&event); -} - -void AppTask::UpdateIdentifyStateEventHandler(AppEvent * aEvent) -{ - sAppTask.mPwmIdentifyLed.UpdateAction(); -} - void AppTask::ActionInitiated(PWMDevice::Action_t aAction, int32_t aActor) { if (aAction == PWMDevice::ON_ACTION) @@ -1024,85 +591,21 @@ void AppTask::ActionCompleted(PWMDevice::Action_t aAction, int32_t aActor) } } -void AppTask::PostEvent(AppEvent * aEvent) -{ - if (k_msgq_put(&sAppEventQueue, aEvent, K_NO_WAIT) != 0) - { - LOG_INF("PostEvent fail"); - } -} - -void AppTask::DispatchEvent(AppEvent * aEvent) -{ - if (aEvent->Handler) - { - aEvent->Handler(aEvent); - } - else - { - LOG_INF("Dropping event without handler"); - } -} - void AppTask::UpdateClusterState(void) { bool isTurnedOn = sAppTask.mPwmRgbBlueLed.IsTurnedOn(); // write the new on/off value - EmberAfStatus status = Clusters::OnOff::Attributes::OnOff::Set(kLightEndpointId, isTurnedOn); + EmberAfStatus status = Clusters::OnOff::Attributes::OnOff::Set(kExampleEndpointId, isTurnedOn); if (status != EMBER_ZCL_STATUS_SUCCESS) { LOG_ERR("Update OnOff fail: %x", status); } uint8_t setLevel = sAppTask.mPwmRgbBlueLed.GetLevel(); - status = Clusters::LevelControl::Attributes::CurrentLevel::Set(kLightEndpointId, setLevel); + status = Clusters::LevelControl::Attributes::CurrentLevel::Set(kExampleEndpointId, setLevel); if (status != EMBER_ZCL_STATUS_SUCCESS) { LOG_ERR("Update CurrentLevel fail: %x", status); } } - -void AppTask::FactoryResetTimerTimeoutCallback(k_timer * timer) -{ - if (!timer) - { - return; - } - - AppEvent event; - event.Type = AppEvent::kEventType_Timer; - event.Handler = FactoryResetTimerEventHandler; - sAppTask.PostEvent(&event); -} - -void AppTask::FactoryResetTimerEventHandler(AppEvent * aEvent) -{ - if (aEvent->Type != AppEvent::kEventType_Timer) - { - return; - } - - sFactoryResetCntr = 0; - LOG_INF("Factory Reset Trigger Counter is cleared"); -} - -void AppTask::InitButtons(void) -{ -#if CONFIG_CHIP_BUTTON_MANAGER_IRQ_MODE - sFactoryResetButton.Configure(BUTTON_PORT, BUTTON_PIN_1, FactoryResetButtonEventHandler); - sLightingButton.Configure(BUTTON_PORT, BUTTON_PIN_2, LightingActionButtonEventHandler); - sThreadStartButton.Configure(BUTTON_PORT, BUTTON_PIN_3, StartThreadButtonEventHandler); - sBleAdvStartButton.Configure(BUTTON_PORT, BUTTON_PIN_4, StartBleAdvButtonEventHandler); -#else - sFactoryResetButton.Configure(BUTTON_PORT, BUTTON_PIN_3, BUTTON_PIN_1, FactoryResetButtonEventHandler); - sLightingButton.Configure(BUTTON_PORT, BUTTON_PIN_4, BUTTON_PIN_1, LightingActionButtonEventHandler); - sThreadStartButton.Configure(BUTTON_PORT, BUTTON_PIN_3, BUTTON_PIN_2, StartThreadButtonEventHandler); - sBleAdvStartButton.Configure(BUTTON_PORT, BUTTON_PIN_4, BUTTON_PIN_2, StartBleAdvButtonEventHandler); -#endif - - ButtonManagerInst().AddButton(sFactoryResetButton); - ButtonManagerInst().AddButton(sLightingButton); - ButtonManagerInst().AddButton(sThreadStartButton); - ButtonManagerInst().AddButton(sBleAdvStartButton); -} diff --git a/examples/contact-sensor-app/telink/CMakeLists.txt b/examples/contact-sensor-app/telink/CMakeLists.txt index 8ac2147a9d058b..3f6a32566a3bba 100755 --- a/examples/contact-sensor-app/telink/CMakeLists.txt +++ b/examples/contact-sensor-app/telink/CMakeLists.txt @@ -59,6 +59,7 @@ target_include_directories(app PRIVATE include ${GEN_DIR}/app-common ${GEN_DIR}/contact-sensor-app + ${TELINK_COMMON}/common/include ${TELINK_COMMON}/util/include) add_definitions( @@ -68,8 +69,9 @@ add_definitions( target_sources(app PRIVATE src/AppTask.cpp src/ContactSensorManager.cpp - src/main.cpp src/ZclCallbacks.cpp + ${TELINK_COMMON}/common/src/mainCommon.cpp + ${TELINK_COMMON}/common/src/AppTaskCommon.cpp ${TELINK_COMMON}/util/src/LEDWidget.cpp ${TELINK_COMMON}/util/src/ButtonManager.cpp ${TELINK_COMMON}/util/src/ThreadUtil.cpp diff --git a/examples/contact-sensor-app/telink/include/AppConfig.h b/examples/contact-sensor-app/telink/include/AppConfig.h old mode 100755 new mode 100644 index d32944992e2cfb..2ab155cd590a67 --- a/examples/contact-sensor-app/telink/include/AppConfig.h +++ b/examples/contact-sensor-app/telink/include/AppConfig.h @@ -18,18 +18,13 @@ #pragma once -// ---- Contact Sensor Example App Config ---- +// ---- All Clusters Application example config ---- +#define APP_USE_EXAMPLE_START_BUTTON 1 +#define APP_USE_THREAD_START_BUTTON 0 +#define APP_SET_DEVICE_INFO_PROVIDER 1 +#define APP_SET_NETWORK_COMM_ENDPOINT_SEC 0 +#define APP_USE_IDENTIFY_PWM 1 // APP_USE_IDENTIFY_PWM must be defined before including "AppConfigCommon.h" -// Buttons config -#define BUTTON_PORT DEVICE_DT_GET(DT_NODELABEL(gpioc)) +#include "AppConfigCommon.h" -#define BUTTON_PIN_1 2 -#define BUTTON_PIN_3 3 -#define BUTTON_PIN_4 1 -#define BUTTON_PIN_2 0 - -// LEDs config -#define LEDS_PORT DEVICE_DT_GET(DT_NODELABEL(gpiob)) -#define SYSTEM_STATE_LED 7 #define CONTACT_STATE_LED 6 -#define LIGHTING_PWM_SPEC_IDENTIFY_GREEN PWM_DT_SPEC_GET(DT_ALIAS(pwm_led3)) diff --git a/examples/contact-sensor-app/telink/include/AppEvent.h b/examples/contact-sensor-app/telink/include/AppEvent.h deleted file mode 100755 index 5306a8076d0804..00000000000000 --- a/examples/contact-sensor-app/telink/include/AppEvent.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * - * Copyright (c) 2022 Project CHIP Authors - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include - -struct AppEvent; -typedef void (*EventHandler)(AppEvent *); - -class LEDWidget; - -struct AppEvent -{ - enum AppEventTypes - { - kEventType_Button = 0, - kEventType_Timer, - kEventType_UpdateLedState, - kEventType_IdentifyStart, - kEventType_IdentifyStop, - kEventType_Contact, - }; - - uint16_t Type; - - union - { - struct - { - uint8_t Action; - } ButtonEvent; - struct - { - uint8_t Action; - } ContactEvent; - struct - { - LEDWidget * LedWidget; - } UpdateLedStateEvent; - }; - - EventHandler Handler; -}; diff --git a/examples/contact-sensor-app/telink/include/AppTask.h b/examples/contact-sensor-app/telink/include/AppTask.h index 8c022cd9a585ea..3ac0028c78e3bb 100644 --- a/examples/contact-sensor-app/telink/include/AppTask.h +++ b/examples/contact-sensor-app/telink/include/AppTask.h @@ -18,37 +18,15 @@ #pragma once -#include "AppEvent.h" +#include "AppTaskCommon.h" #include "ContactSensorManager.h" -#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED -#include "LEDWidget.h" -#endif -#include "PWMDevice.h" - -#include - -#include - -#if CONFIG_CHIP_FACTORY_DATA -#include -#endif - -#include // Application-defined error codes in the CHIP_ERROR space. #define APP_ERROR_UNHANDLED_EVENT CHIP_APPLICATION_ERROR(0x03) -struct k_timer; -struct Identify; - -class AppTask +class AppTask : public AppTaskCommon { public: - CHIP_ERROR StartApp(void); - - void PostEvent(AppEvent * event); - static void IdentifyEffectHandler(EmberAfIdentifyEffectIdentifier aEffect); - void PostContactActionRequest(ContactSensorManager::Action aAction); void UpdateClusterState(void); void UpdateDeviceState(void); @@ -58,50 +36,20 @@ class AppTask private: friend AppTask & GetAppTask(void); + friend class AppTaskCommon; CHIP_ERROR Init(void); - static void ActionIdentifyStateUpdateHandler(k_timer * timer); - - void DispatchEvent(AppEvent * event); - static void OnStateChanged(ContactSensorManager::State aState); static void UpdateClusterStateInternal(intptr_t arg); static void UpdateDeviceStateInternal(intptr_t arg); -#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED - static void UpdateLedStateEventHandler(AppEvent * aEvent); - static void LEDStateUpdateHandler(LEDWidget * ledWidget); - static void UpdateStatusLED(); -#endif - static void FactoryResetButtonEventHandler(void); - static void StartBleAdvButtonEventHandler(void); - static void ToggleContactStateButtonEventHandler(void); - - static void ChipEventHandler(const chip::DeviceLayer::ChipDeviceEvent * event, intptr_t arg); - - static void FactoryResetTimerTimeoutCallback(k_timer * timer); - - static void FactoryResetTimerEventHandler(AppEvent * aEvent); - static void FactoryResetHandler(AppEvent * aEvent); - static void StartBleAdvHandler(AppEvent * aEvent); static void ContactActionEventHandler(AppEvent * aEvent); - static void UpdateIdentifyStateEventHandler(AppEvent * aEvent); - - static void InitButtons(void); - - static void ThreadProvisioningHandler(const chip::DeviceLayer::ChipDeviceEvent * event, intptr_t arg); bool mSyncClusterToButtonAction = false; static AppTask sAppTask; - PWMDevice mPwmIdentifyLed; - -#if CONFIG_CHIP_FACTORY_DATA - // chip::DeviceLayer::FactoryDataProvider mFactoryDataProvider; - chip::DeviceLayer::FactoryDataProvider mFactoryDataProvider; -#endif }; inline AppTask & GetAppTask(void) diff --git a/examples/contact-sensor-app/telink/include/ContactSensorManager.h b/examples/contact-sensor-app/telink/include/ContactSensorManager.h index 0f735288b6ee39..81bf56aefebe5a 100644 --- a/examples/contact-sensor-app/telink/include/ContactSensorManager.h +++ b/examples/contact-sensor-app/telink/include/ContactSensorManager.h @@ -21,7 +21,7 @@ #include #include -#include "AppEvent.h" +#include "AppEventCommon.h" class ContactSensorManager { diff --git a/examples/contact-sensor-app/telink/src/AppTask.cpp b/examples/contact-sensor-app/telink/src/AppTask.cpp index 50c0b4c02b7c97..ab1c8aaef7c5af 100644 --- a/examples/contact-sensor-app/telink/src/AppTask.cpp +++ b/examples/contact-sensor-app/telink/src/AppTask.cpp @@ -18,198 +18,44 @@ #include "AppTask.h" -#include "AppConfig.h" -#include "AppEvent.h" -#include "ButtonManager.h" - -#include "ThreadUtil.h" - -#include #include -#include -#include -#include -#include -#include -#include -#include - -#if CONFIG_CHIP_OTA_REQUESTOR -#include "OTAUtil.h" -#endif #include #include LOG_MODULE_DECLARE(app, CONFIG_CHIP_APP_LOG_LEVEL); -using namespace ::chip; -using namespace ::chip::app; -using namespace ::chip::Credentials; -using namespace ::chip::DeviceLayer; - namespace { -constexpr int kFactoryResetCalcTimeout = 3000; -constexpr int kFactoryResetTriggerCntr = 3; -constexpr int kAppEventQueueSize = 10; -constexpr uint8_t kButtonPushEvent = 1; -constexpr uint8_t kButtonReleaseEvent = 0; -constexpr EndpointId kEndpointId = 1; -constexpr uint8_t kDefaultMinLevel = 0; -constexpr uint8_t kDefaultMaxLevel = 254; -constexpr uint32_t kIdentifyBlinkRateMs = 200; -constexpr uint32_t kIdentifyOkayOnRateMs = 50; -constexpr uint32_t kIdentifyOkayOffRateMs = 950; -constexpr uint32_t kIdentifyFinishOnRateMs = 950; -constexpr uint32_t kIdentifyFinishOffRateMs = 50; -constexpr uint32_t kIdentifyChannelChangeRateMs = 1000; -constexpr uint32_t kIdentifyBreatheRateMs = 1000; - -const struct pwm_dt_spec sPwmIdentifySpecGreenLed = LIGHTING_PWM_SPEC_IDENTIFY_GREEN; - -#if CONFIG_CHIP_FACTORY_DATA -// NOTE! This key is for test/certification only and should not be available in production devices! -uint8_t sTestEventTriggerEnableKey[TestEventTriggerDelegate::kEnableKeyLength] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, - 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }; -#endif - -K_MSGQ_DEFINE(sAppEventQueue, sizeof(AppEvent), kAppEventQueueSize, alignof(AppEvent)); -k_timer sFactoryResetTimer; -uint8_t sFactoryResetCntr = 0; - #if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED -LEDWidget sStatusLED; LEDWidget sContactSensorLED; #endif - -Button sFactoryResetButton; -Button sToggleContactStateButton; -Button sBleAdvStartButton; - -bool sIsThreadProvisioned = false; -bool sIsThreadEnabled = false; -bool sIsThreadAttached = false; -bool sHaveBLEConnections = false; - -chip::DeviceLayer::DeviceInfoProviderImpl gExampleDeviceInfoProvider; - -void OnIdentifyTriggerEffect(Identify * identify) -{ - AppTask::IdentifyEffectHandler(identify->mCurrentEffectIdentifier); -} - -Identify sIdentify = { - kEndpointId, - [](Identify *) { ChipLogProgress(Zcl, "OnIdentifyStart"); }, - [](Identify *) { ChipLogProgress(Zcl, "OnIdentifyStop"); }, - EMBER_ZCL_IDENTIFY_IDENTIFY_TYPE_VISIBLE_LED, - OnIdentifyTriggerEffect, -}; - } // namespace AppTask AppTask::sAppTask; -class AppFabricTableDelegate : public FabricTable::Delegate -{ - void OnFabricRemoved(const FabricTable & fabricTable, FabricIndex fabricIndex) - { - if (chip::Server::GetInstance().GetFabricTable().FabricCount() == 0) - { - chip::Server::GetInstance().ScheduleFactoryReset(); - } - } -}; - CHIP_ERROR AppTask::Init(void) { - LOG_INF("SW Version: %u, %s", CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION, CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING); +#if APP_USE_EXAMPLE_START_BUTTON + SetExampleButtonCallbacks(ContactActionEventHandler); +#endif + InitCommonParts(); - // Initialize LEDs #if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED - LEDWidget::InitGpio(LEDS_PORT); - LEDWidget::SetStateUpdateCallback(LEDStateUpdateHandler); - sStatusLED.Init(SYSTEM_STATE_LED); - - UpdateStatusLED(); - sContactSensorLED.Init(CONTACT_STATE_LED); sContactSensorLED.Set(ContactSensorMgr().IsContactClosed()); #endif UpdateDeviceState(); - InitButtons(); - - // Initialize function button timer - k_timer_init(&sFactoryResetTimer, &AppTask::FactoryResetTimerTimeoutCallback, nullptr); - k_timer_user_data_set(&sFactoryResetTimer, this); - - // Initialize PWM Identify led - CHIP_ERROR err = sAppTask.mPwmIdentifyLed.Init(&sPwmIdentifySpecGreenLed, kDefaultMinLevel, kDefaultMaxLevel, kDefaultMaxLevel); - if (err != CHIP_NO_ERROR) - { - LOG_ERR("Green IDENTIFY PWM Device Init fail"); - return err; - } - - sAppTask.mPwmIdentifyLed.SetCallbacks(nullptr, nullptr, ActionIdentifyStateUpdateHandler); - - // Initialize CHIP server -#if CONFIG_CHIP_FACTORY_DATA - ReturnErrorOnFailure(mFactoryDataProvider.Init()); - SetDeviceInstanceInfoProvider(&mFactoryDataProvider); - SetDeviceAttestationCredentialsProvider(&mFactoryDataProvider); - SetCommissionableDataProvider(&mFactoryDataProvider); - // Read EnableKey from the factory data. - MutableByteSpan enableKey(sTestEventTriggerEnableKey); - err = mFactoryDataProvider.GetEnableKey(enableKey); - if (err != CHIP_NO_ERROR) - { - LOG_ERR("GetEnableKey fail"); - memset(sTestEventTriggerEnableKey, 0, sizeof(sTestEventTriggerEnableKey)); - } -#else - SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); -#endif - - static CommonCaseDeviceServerInitParams initParams; - // static OTATestEventTriggerDelegate testEventTriggerDelegate{ ByteSpan(sTestEventTriggerEnableKey) }; - (void) initParams.InitializeStaticResourcesBeforeServerInit(); - // initParams.testEventTriggerDelegate = &testEventTriggerDelegate; - ReturnErrorOnFailure(chip::Server::GetInstance().Init(initParams)); - - gExampleDeviceInfoProvider.SetStorageDelegate(&Server::GetInstance().GetPersistentStorage()); - chip::DeviceLayer::SetDeviceInfoProvider(&gExampleDeviceInfoProvider); - -#if CONFIG_CHIP_OTA_REQUESTOR - InitBasicOTARequestor(); -#endif - - 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); - ContactSensorMgr().SetCallback(OnStateChanged); - err = ConnectivityMgr().SetBLEDeviceName("TelinkSensor"); + CHIP_ERROR err = ConnectivityMgr().SetBLEDeviceName("TelinkSensor"); if (err != CHIP_NO_ERROR) { LOG_ERR("SetBLEDeviceName fail"); return err; } - err = chip::Server::GetInstance().GetFabricTable().AddFabricDelegate(new AppFabricTableDelegate); - if (err != CHIP_NO_ERROR) - { - LOG_ERR("AppFabricTableDelegate fail"); - return err; - } - return CHIP_NO_ERROR; } @@ -239,75 +85,6 @@ void AppTask::OnStateChanged(ContactSensorManager::State aState) } } -CHIP_ERROR AppTask::StartApp(void) -{ - CHIP_ERROR err = Init(); - - if (err != CHIP_NO_ERROR) - { - LOG_ERR("AppTask Init fail"); - return err; - } - - AppEvent event = {}; - - while (true) - { - k_msgq_get(&sAppEventQueue, &event, K_FOREVER); - DispatchEvent(&event); - } -} - -void AppTask::IdentifyEffectHandler(EmberAfIdentifyEffectIdentifier aEffect) -{ - AppEvent event; - event.Type = AppEvent::kEventType_IdentifyStart; - - switch (aEffect) - { - case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BLINK: - ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BLINK"); - event.Handler = [](AppEvent *) { - sAppTask.mPwmIdentifyLed.InitiateBlinkAction(kIdentifyBlinkRateMs, kIdentifyBlinkRateMs); - }; - break; - case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BREATHE: - ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BREATHE"); - event.Handler = [](AppEvent *) { - sAppTask.mPwmIdentifyLed.InitiateBreatheAction(PWMDevice::kBreatheType_Both, kIdentifyBreatheRateMs); - }; - break; - case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_OKAY: - ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_OKAY"); - event.Handler = [](AppEvent *) { - sAppTask.mPwmIdentifyLed.InitiateBlinkAction(kIdentifyOkayOnRateMs, kIdentifyOkayOffRateMs); - }; - break; - case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_CHANNEL_CHANGE: - ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_CHANNEL_CHANGE"); - event.Handler = [](AppEvent *) { - sAppTask.mPwmIdentifyLed.InitiateBlinkAction(kIdentifyChannelChangeRateMs, kIdentifyChannelChangeRateMs); - }; - break; - case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_FINISH_EFFECT: - ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_FINISH_EFFECT"); - event.Handler = [](AppEvent *) { - sAppTask.mPwmIdentifyLed.InitiateBlinkAction(kIdentifyFinishOnRateMs, kIdentifyFinishOffRateMs); - }; - break; - case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_STOP_EFFECT: - ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_STOP_EFFECT"); - event.Handler = [](AppEvent *) { sAppTask.mPwmIdentifyLed.StopAction(); }; - event.Type = AppEvent::kEventType_IdentifyStop; - break; - default: - ChipLogProgress(Zcl, "No identifier effect"); - return; - } - - sAppTask.PostEvent(&event); -} - void AppTask::PostContactActionRequest(ContactSensorManager::Action aAction) { AppEvent event; @@ -318,46 +95,6 @@ void AppTask::PostContactActionRequest(ContactSensorManager::Action aAction) sAppTask.PostEvent(&event); } -void AppTask::ToggleContactStateButtonEventHandler(void) -{ - AppEvent event; - - event.Type = AppEvent::kEventType_Button; - event.ButtonEvent.Action = kButtonPushEvent; - event.Handler = ContactActionEventHandler; - - sAppTask.PostEvent(&event); -} - -void AppTask::FactoryResetButtonEventHandler(void) -{ - AppEvent event; - - event.Type = AppEvent::kEventType_Button; - event.ButtonEvent.Action = kButtonPushEvent; - event.Handler = FactoryResetHandler; - sAppTask.PostEvent(&event); -} - -void AppTask::FactoryResetHandler(AppEvent * aEvent) -{ - if (sFactoryResetCntr == 0) - { - k_timer_start(&sFactoryResetTimer, K_MSEC(kFactoryResetCalcTimeout), K_NO_WAIT); - } - - sFactoryResetCntr++; - LOG_INF("Factory Reset Trigger Counter: %d/%d", sFactoryResetCntr, kFactoryResetTriggerCntr); - - if (sFactoryResetCntr == kFactoryResetTriggerCntr) - { - k_timer_stop(&sFactoryResetTimer); - sFactoryResetCntr = 0; - - chip::Server::GetInstance().ScheduleFactoryReset(); - } -} - void AppTask::UpdateClusterStateInternal(intptr_t arg) { uint8_t newValue = ContactSensorMgr().IsContactClosed(); @@ -408,187 +145,11 @@ void AppTask::ContactActionEventHandler(AppEvent * aEvent) } } -void AppTask::StartBleAdvButtonEventHandler(void) -{ - AppEvent event; - - event.Type = AppEvent::kEventType_Button; - event.ButtonEvent.Action = kButtonPushEvent; - event.Handler = StartBleAdvHandler; - sAppTask.PostEvent(&event); -} - -void AppTask::StartBleAdvHandler(AppEvent * aEvent) -{ - LOG_INF("StartBleAdvHandler"); - - // Don't allow on starting Matter service BLE advertising after Thread provisioning. - if (ConnectivityMgr().IsThreadProvisioned()) - { - LOG_INF("Device already commissioned"); - return; - } - - if (ConnectivityMgr().IsBLEAdvertisingEnabled()) - { - LOG_INF("BLE adv already enabled"); - return; - } - - if (chip::Server::GetInstance().GetCommissioningWindowManager().OpenBasicCommissioningWindow() != CHIP_NO_ERROR) - { - LOG_ERR("OpenBasicCommissioningWindow fail"); - } -} - -#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED -void AppTask::UpdateLedStateEventHandler(AppEvent * aEvent) -{ - if (aEvent->Type == AppEvent::kEventType_UpdateLedState) - { - aEvent->UpdateLedStateEvent.LedWidget->UpdateState(); - } -} - -void AppTask::LEDStateUpdateHandler(LEDWidget * ledWidget) -{ - AppEvent event; - event.Type = AppEvent::kEventType_UpdateLedState; - event.Handler = UpdateLedStateEventHandler; - event.UpdateLedStateEvent.LedWidget = ledWidget; - sAppTask.PostEvent(&event); -} - -void AppTask::UpdateStatusLED(void) -{ - if (sIsThreadProvisioned && sIsThreadEnabled) - { - if (sIsThreadAttached) - { - sStatusLED.Blink(950, 50); - } - else - { - sStatusLED.Blink(100, 100); - } - } - else - { - sStatusLED.Blink(50, 950); - } -} -#endif - -void AppTask::ChipEventHandler(const ChipDeviceEvent * event, intptr_t /* arg */) -{ - switch (event->Type) - { - case DeviceEventType::kCHIPoBLEAdvertisingChange: - sHaveBLEConnections = ConnectivityMgr().NumBLEConnections() != 0; -#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED - UpdateStatusLED(); -#endif - break; - case DeviceEventType::kThreadStateChange: - sIsThreadProvisioned = ConnectivityMgr().IsThreadProvisioned(); - sIsThreadEnabled = ConnectivityMgr().IsThreadEnabled(); - sIsThreadAttached = ConnectivityMgr().IsThreadAttached(); -#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED - UpdateStatusLED(); -#endif - break; - case DeviceEventType::kThreadConnectivityChange: -#if CONFIG_CHIP_OTA_REQUESTOR - if (event->ThreadConnectivityChange.Result == kConnectivity_Established) - { - InitBasicOTARequestor(); - } -#endif - break; - default: - break; - } -} - -void AppTask::ActionIdentifyStateUpdateHandler(k_timer * timer) -{ - AppEvent event; - event.Type = AppEvent::kEventType_UpdateLedState; - event.Handler = UpdateIdentifyStateEventHandler; - sAppTask.PostEvent(&event); -} - -void AppTask::UpdateIdentifyStateEventHandler(AppEvent * aEvent) -{ - sAppTask.mPwmIdentifyLed.UpdateAction(); -} - -void AppTask::PostEvent(AppEvent * aEvent) -{ - if (k_msgq_put(&sAppEventQueue, aEvent, K_NO_WAIT) != 0) - { - LOG_INF("PostEvent fail"); - } -} - -void AppTask::DispatchEvent(AppEvent * aEvent) -{ - if (aEvent->Handler) - { - aEvent->Handler(aEvent); - } - else - { - LOG_INF("Dropping event without handler"); - } -} - void AppTask::UpdateClusterState(void) { PlatformMgr().ScheduleWork(UpdateClusterStateInternal, 0); } -void AppTask::FactoryResetTimerTimeoutCallback(k_timer * timer) -{ - if (!timer) - { - return; - } - - AppEvent event; - event.Type = AppEvent::kEventType_Timer; - event.Handler = FactoryResetTimerEventHandler; - sAppTask.PostEvent(&event); -} - -void AppTask::FactoryResetTimerEventHandler(AppEvent * aEvent) -{ - if (aEvent->Type != AppEvent::kEventType_Timer) - { - return; - } - - sFactoryResetCntr = 0; - LOG_INF("Factory Reset Trigger Counter is cleared"); -} - -void AppTask::InitButtons(void) -{ -#if CONFIG_CHIP_BUTTON_MANAGER_IRQ_MODE - sFactoryResetButton.Configure(BUTTON_PORT, BUTTON_PIN_1, FactoryResetButtonEventHandler); - sToggleContactStateButton.Configure(BUTTON_PORT, BUTTON_PIN_2, ToggleContactStateButtonEventHandler); - sBleAdvStartButton.Configure(BUTTON_PORT, BUTTON_PIN_4, StartBleAdvButtonEventHandler); -#else - sFactoryResetButton.Configure(BUTTON_PORT, BUTTON_PIN_3, BUTTON_PIN_1, FactoryResetButtonEventHandler); - sToggleContactStateButton.Configure(BUTTON_PORT, BUTTON_PIN_4, BUTTON_PIN_1, ToggleContactStateButtonEventHandler); - sBleAdvStartButton.Configure(BUTTON_PORT, BUTTON_PIN_4, BUTTON_PIN_2, StartBleAdvButtonEventHandler); -#endif - - ButtonManagerInst().AddButton(sFactoryResetButton); - ButtonManagerInst().AddButton(sToggleContactStateButton); - ButtonManagerInst().AddButton(sBleAdvStartButton); -} - void AppTask::UpdateDeviceState(void) { PlatformMgr().ScheduleWork(UpdateDeviceStateInternal, 0); diff --git a/examples/contact-sensor-app/telink/src/main.cpp b/examples/contact-sensor-app/telink/src/main.cpp deleted file mode 100755 index 9dd145f55ba0c9..00000000000000 --- a/examples/contact-sensor-app/telink/src/main.cpp +++ /dev/null @@ -1,82 +0,0 @@ -/* - * - * Copyright (c) 2022 Project CHIP Authors - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "AppTask.h" - -#include -#include - -#include - -LOG_MODULE_REGISTER(app, CONFIG_CHIP_APP_LOG_LEVEL); - -using namespace ::chip; -using namespace ::chip::Inet; -using namespace ::chip::DeviceLayer; - -int main(void) -{ - CHIP_ERROR err = CHIP_NO_ERROR; - - err = chip::Platform::MemoryInit(); - if (err != CHIP_NO_ERROR) - { - LOG_ERR("MemoryInit fail"); - goto exit; - } - - err = PlatformMgr().InitChipStack(); - if (err != CHIP_NO_ERROR) - { - LOG_ERR("InitChipStack fail"); - goto exit; - } - - err = PlatformMgr().StartEventLoopTask(); - if (err != CHIP_NO_ERROR) - { - LOG_ERR("StartEventLoopTask fail"); - goto exit; - } - - err = ThreadStackMgr().InitThreadStack(); - if (err != CHIP_NO_ERROR) - { - LOG_ERR("InitThreadStack fail"); - goto exit; - } - -#ifdef CONFIG_OPENTHREAD_MTD_SED - err = ConnectivityMgr().SetThreadDeviceType(ConnectivityManager::kThreadDeviceType_SleepyEndDevice); -#elif CONFIG_OPENTHREAD_MTD - err = ConnectivityMgr().SetThreadDeviceType(ConnectivityManager::kThreadDeviceType_MinimalEndDevice); -#else - err = ConnectivityMgr().SetThreadDeviceType(ConnectivityManager::kThreadDeviceType_Router); -#endif - if (err != CHIP_NO_ERROR) - { - LOG_ERR("SetThreadDeviceType fail"); - goto exit; - } - - err = GetAppTask().StartApp(); - -exit: - LOG_ERR("Exit err %" CHIP_ERROR_FORMAT, err.Format()); - return (err == CHIP_NO_ERROR) ? EXIT_SUCCESS : EXIT_FAILURE; -} diff --git a/examples/light-switch-app/telink/CMakeLists.txt b/examples/light-switch-app/telink/CMakeLists.txt index 4b3ea23b7c9d39..c7339e9f81b623 100755 --- a/examples/light-switch-app/telink/CMakeLists.txt +++ b/examples/light-switch-app/telink/CMakeLists.txt @@ -59,6 +59,7 @@ target_include_directories(app PRIVATE include ${GEN_DIR}/app-common ${GEN_DIR}/light-switch-app + ${TELINK_COMMON}/common/include ${TELINK_COMMON}/util/include ${TELINK_COMMON}/app/include) @@ -68,9 +69,10 @@ add_definitions( target_sources(app PRIVATE src/AppTask.cpp - src/main.cpp src/ZclCallbacks.cpp src/binding-handler.cpp + ${TELINK_COMMON}/common/src/mainCommon.cpp + ${TELINK_COMMON}/common/src/AppTaskCommon.cpp ${TELINK_COMMON}/util/src/LEDWidget.cpp ${TELINK_COMMON}/util/src/ButtonManager.cpp ${TELINK_COMMON}/util/src/ThreadUtil.cpp diff --git a/examples/light-switch-app/telink/include/AppConfig.h b/examples/light-switch-app/telink/include/AppConfig.h old mode 100755 new mode 100644 index d41e4c557b4598..05c6957a92e399 --- a/examples/light-switch-app/telink/include/AppConfig.h +++ b/examples/light-switch-app/telink/include/AppConfig.h @@ -20,15 +20,10 @@ // ---- Light Switch Example App Config ---- -// Buttons config -#define BUTTON_PORT DEVICE_DT_GET(DT_NODELABEL(gpioc)) +#define APP_USE_EXAMPLE_START_BUTTON 1 +#define APP_USE_THREAD_START_BUTTON 1 +#define APP_SET_DEVICE_INFO_PROVIDER 1 +#define APP_SET_NETWORK_COMM_ENDPOINT_SEC 0 +#define APP_USE_IDENTIFY_PWM 1 // APP_USE_IDENTIFY_PWM must be defined before including "AppConfigCommon.h" -#define BUTTON_PIN_1 2 -#define BUTTON_PIN_3 3 -#define BUTTON_PIN_4 1 -#define BUTTON_PIN_2 0 - -// LEDs config -#define LEDS_PORT DEVICE_DT_GET(DT_NODELABEL(gpiob)) -#define SYSTEM_STATE_LED 7 -#define LIGHTING_PWM_SPEC_IDENTIFY_GREEN PWM_DT_SPEC_GET(DT_ALIAS(pwm_led3)) +#include "AppConfigCommon.h" diff --git a/examples/light-switch-app/telink/include/AppEvent.h b/examples/light-switch-app/telink/include/AppEvent.h deleted file mode 100755 index 72554b4bb54b5a..00000000000000 --- a/examples/light-switch-app/telink/include/AppEvent.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * - * Copyright (c) 2022 Project CHIP Authors - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include - -struct AppEvent; -typedef void (*EventHandler)(AppEvent *); - -class LEDWidget; - -struct AppEvent -{ - enum AppEventTypes - { - kEventType_Button = 0, - kEventType_Timer, - kEventType_UpdateLedState, - kEventType_IdentifyStart, - kEventType_IdentifyStop, - kEventType_Lighting, - kEventType_Install, - }; - - uint16_t Type; - - union - { - struct - { - uint8_t Action; - } ButtonEvent; - struct - { - void * Context; - } TimerEvent; - struct - { - uint8_t Action; - int32_t Actor; - } LightingEvent; - struct - { - LEDWidget * LedWidget; - } UpdateLedStateEvent; - }; - - EventHandler Handler; -}; diff --git a/examples/light-switch-app/telink/include/AppTask.h b/examples/light-switch-app/telink/include/AppTask.h index 953b677e083cde..12e09eaf9f1a16 100644 --- a/examples/light-switch-app/telink/include/AppTask.h +++ b/examples/light-switch-app/telink/include/AppTask.h @@ -18,86 +18,22 @@ #pragma once -#include "AppEvent.h" -#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED -#include "LEDWidget.h" -#endif -#include "PWMDevice.h" +#include "AppTaskCommon.h" -#include - -#include - -#if CONFIG_CHIP_FACTORY_DATA -#include -#endif - -#include - -struct k_timer; -struct Identify; - -class AppTask +class AppTask : public AppTaskCommon { public: - CHIP_ERROR StartApp(); - - enum Action_t : uint8_t - { - ON_ACTION = 0, - OFF_ACTION, - LEVEL_ACTION, - - INVALID_ACTION - }; - - void PostLightingActionRequest(Action_t aAction); - void PostEvent(AppEvent * event); void UpdateClusterState(); - static void IdentifyEffectHandler(EmberAfIdentifyEffectIdentifier aEffect); private: friend AppTask & GetAppTask(void); + friend class AppTaskCommon; CHIP_ERROR Init(void); - static void ActionInitiated(AppTask::Action_t aAction, int32_t aActor); - static void ActionCompleted(AppTask::Action_t aAction, int32_t aActor); - static void ActionIdentifyStateUpdateHandler(k_timer * timer); - - void DispatchEvent(AppEvent * event); - -#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED - static void UpdateLedStateEventHandler(AppEvent * aEvent); - static void LEDStateUpdateHandler(LEDWidget * ledWidget); - static void UpdateStatusLED(); -#endif - 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 FactoryResetTimerTimeoutCallback(k_timer * timer); - - static void FactoryResetTimerEventHandler(AppEvent * aEvent); - static void FactoryResetHandler(AppEvent * aEvent); - static void StartThreadHandler(AppEvent * aEvent); static void SwitchActionEventHandler(AppEvent * aEvent); - static void StartBleAdvHandler(AppEvent * aEvent); - static void UpdateIdentifyStateEventHandler(AppEvent * aEvent); - - static void InitButtons(void); - - static void ThreadProvisioningHandler(const chip::DeviceLayer::ChipDeviceEvent * event, intptr_t arg); static AppTask sAppTask; - PWMDevice mPwmIdentifyLed; - -#if CONFIG_CHIP_FACTORY_DATA - chip::DeviceLayer::FactoryDataProvider mFactoryDataProvider; -#endif }; inline AppTask & GetAppTask(void) diff --git a/examples/light-switch-app/telink/src/AppTask.cpp b/examples/light-switch-app/telink/src/AppTask.cpp index ffa763dfe5f7b1..b78a09d547d478 100644 --- a/examples/light-switch-app/telink/src/AppTask.cpp +++ b/examples/light-switch-app/telink/src/AppTask.cpp @@ -17,204 +17,27 @@ */ #include "AppTask.h" - -#include "AppConfig.h" -#include "AppEvent.h" -#include "ButtonManager.h" #include "binding-handler.h" -#include "ThreadUtil.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -#if CONFIG_CHIP_OTA_REQUESTOR -#include "OTAUtil.h" -#endif - -#include -#include - -#include - -#if CONFIG_CHIP_LIB_SHELL -#include -#include - -static int cmd_telink_reboot(const struct shell * shell, size_t argc, char ** argv) -{ - ARG_UNUSED(argc); - ARG_UNUSED(argv); - - shell_print(shell, "Performing board reboot..."); - sys_reboot(); -} - -SHELL_STATIC_SUBCMD_SET_CREATE(sub_telink, SHELL_CMD(reboot, NULL, "Reboot board command", cmd_telink_reboot), - SHELL_SUBCMD_SET_END); -SHELL_CMD_REGISTER(telink, &sub_telink, "Telink commands", NULL); -#endif // CONFIG_CHIP_LIB_SHELL - LOG_MODULE_DECLARE(app, CONFIG_CHIP_APP_LOG_LEVEL); -using namespace ::chip; -using namespace ::chip::app; -using namespace ::chip::Credentials; -using namespace ::chip::DeviceLayer; - -namespace { -constexpr int kFactoryResetCalcTimeout = 3000; -constexpr int kFactoryResetTriggerCntr = 3; -constexpr int kAppEventQueueSize = 10; -constexpr uint8_t kButtonPushEvent = 1; -constexpr uint8_t kButtonReleaseEvent = 0; -constexpr EndpointId kEndpointId = 1; -constexpr uint8_t kDefaultMinLevel = 0; -constexpr uint8_t kDefaultMaxLevel = 254; -constexpr uint32_t kIdentifyBlinkRateMs = 200; -constexpr uint32_t kIdentifyOkayOnRateMs = 50; -constexpr uint32_t kIdentifyOkayOffRateMs = 950; -constexpr uint32_t kIdentifyFinishOnRateMs = 950; -constexpr uint32_t kIdentifyFinishOffRateMs = 50; -constexpr uint32_t kIdentifyChannelChangeRateMs = 1000; -constexpr uint32_t kIdentifyBreatheRateMs = 1000; - -const struct pwm_dt_spec sPwmIdentifySpecGreenLed = LIGHTING_PWM_SPEC_IDENTIFY_GREEN; - -#if CONFIG_CHIP_FACTORY_DATA -// NOTE! This key is for test/certification only and should not be available in production devices! -uint8_t sTestEventTriggerEnableKey[TestEventTriggerDelegate::kEnableKeyLength] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, - 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }; -#endif - -K_MSGQ_DEFINE(sAppEventQueue, sizeof(AppEvent), kAppEventQueueSize, alignof(AppEvent)); -k_timer sFactoryResetTimer; -uint8_t sFactoryResetCntr = 0; - -#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED -LEDWidget sStatusLED; -#endif - -Button sFactoryResetButton; -Button sSwitchButton; -Button sThreadStartButton; -Button sBleAdvStartButton; - -bool sIsThreadProvisioned = false; -bool sIsThreadEnabled = false; -bool sIsThreadAttached = false; -bool sHaveBLEConnections = false; - -chip::DeviceLayer::DeviceInfoProviderImpl gExampleDeviceInfoProvider; - -void OnIdentifyTriggerEffect(Identify * identify) -{ - AppTask::IdentifyEffectHandler(identify->mCurrentEffectIdentifier); -} - -Identify sIdentify = { - kEndpointId, - [](Identify *) { ChipLogProgress(Zcl, "OnIdentifyStart"); }, - [](Identify *) { ChipLogProgress(Zcl, "OnIdentifyStop"); }, - EMBER_ZCL_IDENTIFY_IDENTIFY_TYPE_VISIBLE_LED, - OnIdentifyTriggerEffect, -}; - -} // namespace - AppTask AppTask::sAppTask; -class AppFabricTableDelegate : public FabricTable::Delegate -{ - void OnFabricRemoved(const FabricTable & fabricTable, FabricIndex fabricIndex) - { - if (chip::Server::GetInstance().GetFabricTable().FabricCount() == 0) - { - chip::Server::GetInstance().ScheduleFactoryReset(); - } - } -}; - CHIP_ERROR AppTask::Init(void) { - LOG_INF("SW Version: %u, %s", CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION, CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING); - - // Initialize status LED -#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED - LEDWidget::InitGpio(LEDS_PORT); - LEDWidget::SetStateUpdateCallback(LEDStateUpdateHandler); - sStatusLED.Init(SYSTEM_STATE_LED); - - UpdateStatusLED(); -#endif - - InitButtons(); - - // Initialize function button timer - k_timer_init(&sFactoryResetTimer, &AppTask::FactoryResetTimerTimeoutCallback, nullptr); - k_timer_user_data_set(&sFactoryResetTimer, this); - - // Initialize PWM Identify led - CHIP_ERROR err = sAppTask.mPwmIdentifyLed.Init(&sPwmIdentifySpecGreenLed, kDefaultMinLevel, kDefaultMaxLevel, kDefaultMaxLevel); - if (err != CHIP_NO_ERROR) - { - LOG_ERR("Green IDENTIFY PWM Device Init fail"); - return err; - } - - sAppTask.mPwmIdentifyLed.SetCallbacks(nullptr, nullptr, ActionIdentifyStateUpdateHandler); - - // Initialize CHIP server -#if CONFIG_CHIP_FACTORY_DATA - ReturnErrorOnFailure(mFactoryDataProvider.Init()); - SetDeviceInstanceInfoProvider(&mFactoryDataProvider); - SetDeviceAttestationCredentialsProvider(&mFactoryDataProvider); - SetCommissionableDataProvider(&mFactoryDataProvider); - // Read EnableKey from the factory data. - MutableByteSpan enableKey(sTestEventTriggerEnableKey); - err = mFactoryDataProvider.GetEnableKey(enableKey); - if (err != CHIP_NO_ERROR) - { - LOG_ERR("mFactoryDataProvider.GetEnableKey() failed. Could not delegate a test event trigger"); - memset(sTestEventTriggerEnableKey, 0, sizeof(sTestEventTriggerEnableKey)); - } -#else - SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); -#endif - - static CommonCaseDeviceServerInitParams initParams; - (void) initParams.InitializeStaticResourcesBeforeServerInit(); - ReturnErrorOnFailure(chip::Server::GetInstance().Init(initParams)); - gExampleDeviceInfoProvider.SetStorageDelegate(&Server::GetInstance().GetPersistentStorage()); - chip::DeviceLayer::SetDeviceInfoProvider(&gExampleDeviceInfoProvider); - -#if CONFIG_CHIP_OTA_REQUESTOR - InitBasicOTARequestor(); +#if APP_USE_EXAMPLE_START_BUTTON + SetExampleButtonCallbacks(SwitchActionEventHandler); #endif - - ConfigurationMgr().LogDeviceConfig(); + InitCommonParts(); // Configure Bindings - err = InitBindingHandler(); + CHIP_ERROR err = InitBindingHandler(); if (err != CHIP_NO_ERROR) { LOG_ERR("InitBindingHandler fail"); return err; } - 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); - err = ConnectivityMgr().SetBLEDeviceName("TelinkSwitch"); if (err != CHIP_NO_ERROR) { @@ -222,95 +45,9 @@ CHIP_ERROR AppTask::Init(void) return err; } - err = chip::Server::GetInstance().GetFabricTable().AddFabricDelegate(new AppFabricTableDelegate); - if (err != CHIP_NO_ERROR) - { - LOG_ERR("AppFabricTableDelegate fail"); - return err; - } - return CHIP_NO_ERROR; } -CHIP_ERROR AppTask::StartApp(void) -{ - CHIP_ERROR err = Init(); - - if (err != CHIP_NO_ERROR) - { - LOG_ERR("AppTask Init fail"); - return err; - } - - AppEvent event = {}; - - while (true) - { - k_msgq_get(&sAppEventQueue, &event, K_FOREVER); - DispatchEvent(&event); - } -} - -void AppTask::IdentifyEffectHandler(EmberAfIdentifyEffectIdentifier aEffect) -{ - AppEvent event; - event.Type = AppEvent::kEventType_IdentifyStart; - - switch (aEffect) - { - case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BLINK: - ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BLINK"); - event.Handler = [](AppEvent *) { - sAppTask.mPwmIdentifyLed.InitiateBlinkAction(kIdentifyBlinkRateMs, kIdentifyBlinkRateMs); - }; - break; - case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BREATHE: - ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BREATHE"); - event.Handler = [](AppEvent *) { - sAppTask.mPwmIdentifyLed.InitiateBreatheAction(PWMDevice::kBreatheType_Both, kIdentifyBreatheRateMs); - }; - break; - case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_OKAY: - ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_OKAY"); - event.Handler = [](AppEvent *) { - sAppTask.mPwmIdentifyLed.InitiateBlinkAction(kIdentifyOkayOnRateMs, kIdentifyOkayOffRateMs); - }; - break; - case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_CHANNEL_CHANGE: - ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_CHANNEL_CHANGE"); - event.Handler = [](AppEvent *) { - sAppTask.mPwmIdentifyLed.InitiateBlinkAction(kIdentifyChannelChangeRateMs, kIdentifyChannelChangeRateMs); - }; - break; - case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_FINISH_EFFECT: - ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_FINISH_EFFECT"); - event.Handler = [](AppEvent *) { - sAppTask.mPwmIdentifyLed.InitiateBlinkAction(kIdentifyFinishOnRateMs, kIdentifyFinishOffRateMs); - }; - break; - case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_STOP_EFFECT: - ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_STOP_EFFECT"); - event.Handler = [](AppEvent *) { sAppTask.mPwmIdentifyLed.StopAction(); }; - event.Type = AppEvent::kEventType_IdentifyStop; - break; - default: - ChipLogProgress(Zcl, "No identifier effect"); - return; - } - - sAppTask.PostEvent(&event); -} - -void AppTask::SwitchActionButtonEventHandler(void) -{ - AppEvent event; - - event.Type = AppEvent::kEventType_Button; - event.ButtonEvent.Action = kButtonPushEvent; - event.Handler = SwitchActionEventHandler; - sAppTask.PostEvent(&event); -} - void AppTask::SwitchActionEventHandler(AppEvent * aEvent) { if (aEvent->Type == AppEvent::kEventType_Button) @@ -323,248 +60,4 @@ void AppTask::SwitchActionEventHandler(AppEvent * aEvent) } } -void AppTask::FactoryResetButtonEventHandler(void) -{ - AppEvent event; - - event.Type = AppEvent::kEventType_Button; - event.ButtonEvent.Action = kButtonPushEvent; - event.Handler = FactoryResetHandler; - sAppTask.PostEvent(&event); -} - -void AppTask::FactoryResetHandler(AppEvent * aEvent) -{ - if (sFactoryResetCntr == 0) - { - k_timer_start(&sFactoryResetTimer, K_MSEC(kFactoryResetCalcTimeout), K_NO_WAIT); - } - - sFactoryResetCntr++; - LOG_INF("Factory Reset Trigger Counter: %d/%d", sFactoryResetCntr, kFactoryResetTriggerCntr); - - if (sFactoryResetCntr == kFactoryResetTriggerCntr) - { - k_timer_stop(&sFactoryResetTimer); - sFactoryResetCntr = 0; - - chip::Server::GetInstance().ScheduleFactoryReset(); - } -} - -void AppTask::StartThreadButtonEventHandler(void) -{ - AppEvent event; - - event.Type = AppEvent::kEventType_Button; - event.ButtonEvent.Action = kButtonPushEvent; - event.Handler = StartThreadHandler; - sAppTask.PostEvent(&event); -} - -void AppTask::StartThreadHandler(AppEvent * aEvent) -{ - LOG_INF("StartThreadHandler"); - if (!chip::DeviceLayer::ConnectivityMgr().IsThreadProvisioned()) - { - // Switch context from BLE to Thread - Internal::BLEManagerImpl sInstance; - sInstance.SwitchToIeee802154(); - StartDefaultThreadNetwork(); - } - else - { - LOG_INF("Device already commissioned"); - } -} - -void AppTask::StartBleAdvButtonEventHandler(void) -{ - AppEvent event; - - event.Type = AppEvent::kEventType_Button; - event.ButtonEvent.Action = kButtonPushEvent; - event.Handler = StartBleAdvHandler; - sAppTask.PostEvent(&event); -} - -void AppTask::StartBleAdvHandler(AppEvent * aEvent) -{ - LOG_INF("StartBleAdvHandler"); - - // Don't allow on starting Matter service BLE advertising after Thread provisioning. - if (ConnectivityMgr().IsThreadProvisioned()) - { - LOG_INF("Device already commissioned"); - return; - } - - if (ConnectivityMgr().IsBLEAdvertisingEnabled()) - { - LOG_INF("BLE adv already enabled"); - return; - } - - if (chip::Server::GetInstance().GetCommissioningWindowManager().OpenBasicCommissioningWindow() != CHIP_NO_ERROR) - { - LOG_ERR("OpenBasicCommissioningWindow fail"); - } -} - -#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED -void AppTask::UpdateLedStateEventHandler(AppEvent * aEvent) -{ - if (aEvent->Type == AppEvent::kEventType_UpdateLedState) - { - aEvent->UpdateLedStateEvent.LedWidget->UpdateState(); - } -} - -void AppTask::LEDStateUpdateHandler(LEDWidget * ledWidget) -{ - AppEvent event; - event.Type = AppEvent::kEventType_UpdateLedState; - event.Handler = UpdateLedStateEventHandler; - event.UpdateLedStateEvent.LedWidget = ledWidget; - sAppTask.PostEvent(&event); -} - -void AppTask::UpdateStatusLED(void) -{ - if (sIsThreadProvisioned && sIsThreadEnabled) - { - if (sIsThreadAttached) - { - sStatusLED.Blink(950, 50); - } - else - { - sStatusLED.Blink(100, 100); - } - } - else - { - sStatusLED.Blink(50, 950); - } -} -#endif - -void AppTask::ChipEventHandler(const ChipDeviceEvent * event, intptr_t /* arg */) -{ - switch (event->Type) - { - case DeviceEventType::kCHIPoBLEAdvertisingChange: - sHaveBLEConnections = ConnectivityMgr().NumBLEConnections() != 0; -#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED - UpdateStatusLED(); -#endif - break; - case DeviceEventType::kThreadStateChange: - sIsThreadProvisioned = ConnectivityMgr().IsThreadProvisioned(); - sIsThreadEnabled = ConnectivityMgr().IsThreadEnabled(); - sIsThreadAttached = ConnectivityMgr().IsThreadAttached(); -#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED - UpdateStatusLED(); -#endif - break; - case DeviceEventType::kThreadConnectivityChange: -#if CONFIG_CHIP_OTA_REQUESTOR - if (event->ThreadConnectivityChange.Result == kConnectivity_Established) - { - InitBasicOTARequestor(); - } -#endif - break; - default: - break; - } -} - -void AppTask::ActionIdentifyStateUpdateHandler(k_timer * timer) -{ - AppEvent event; - event.Type = AppEvent::kEventType_UpdateLedState; - event.Handler = UpdateIdentifyStateEventHandler; - sAppTask.PostEvent(&event); -} - -void AppTask::UpdateIdentifyStateEventHandler(AppEvent * aEvent) -{ - sAppTask.mPwmIdentifyLed.UpdateAction(); -} - -void AppTask::ActionInitiated(AppTask::Action_t aAction, int32_t aActor) {} - -void AppTask::ActionCompleted(AppTask::Action_t aAction, int32_t aActor) -{ - if (aActor == AppEvent::kEventType_Button) - { - sAppTask.UpdateClusterState(); - } -} - -void AppTask::PostEvent(AppEvent * aEvent) -{ - if (k_msgq_put(&sAppEventQueue, aEvent, K_NO_WAIT) != 0) - { - LOG_INF("PostEvent fail"); - } -} - -void AppTask::DispatchEvent(AppEvent * aEvent) -{ - if (aEvent->Handler) - { - aEvent->Handler(aEvent); - } - else - { - LOG_INF("Dropping event without handler"); - } -} - void AppTask::UpdateClusterState() {} - -void AppTask::FactoryResetTimerTimeoutCallback(k_timer * timer) -{ - if (!timer) - { - return; - } - - AppEvent event; - event.Type = AppEvent::kEventType_Timer; - event.Handler = FactoryResetTimerEventHandler; - sAppTask.PostEvent(&event); -} - -void AppTask::FactoryResetTimerEventHandler(AppEvent * aEvent) -{ - if (aEvent->Type != AppEvent::kEventType_Timer) - { - return; - } - - sFactoryResetCntr = 0; - LOG_INF("Factory Reset Trigger Counter is cleared"); -} - -void AppTask::InitButtons(void) -{ -#if CONFIG_CHIP_BUTTON_MANAGER_IRQ_MODE - sFactoryResetButton.Configure(BUTTON_PORT, BUTTON_PIN_1, FactoryResetButtonEventHandler); - sSwitchButton.Configure(BUTTON_PORT, BUTTON_PIN_2, SwitchActionButtonEventHandler); - sThreadStartButton.Configure(BUTTON_PORT, BUTTON_PIN_3, StartThreadButtonEventHandler); - sBleAdvStartButton.Configure(BUTTON_PORT, BUTTON_PIN_4, StartBleAdvButtonEventHandler); -#else - sFactoryResetButton.Configure(BUTTON_PORT, BUTTON_PIN_3, BUTTON_PIN_1, FactoryResetButtonEventHandler); - sSwitchButton.Configure(BUTTON_PORT, BUTTON_PIN_4, BUTTON_PIN_1, SwitchActionButtonEventHandler); - sThreadStartButton.Configure(BUTTON_PORT, BUTTON_PIN_3, BUTTON_PIN_2, StartThreadButtonEventHandler); - sBleAdvStartButton.Configure(BUTTON_PORT, BUTTON_PIN_4, BUTTON_PIN_2, StartBleAdvButtonEventHandler); -#endif - - ButtonManagerInst().AddButton(sFactoryResetButton); - ButtonManagerInst().AddButton(sSwitchButton); - ButtonManagerInst().AddButton(sThreadStartButton); - ButtonManagerInst().AddButton(sBleAdvStartButton); -} diff --git a/examples/light-switch-app/telink/src/main.cpp b/examples/light-switch-app/telink/src/main.cpp deleted file mode 100755 index 9dd145f55ba0c9..00000000000000 --- a/examples/light-switch-app/telink/src/main.cpp +++ /dev/null @@ -1,82 +0,0 @@ -/* - * - * Copyright (c) 2022 Project CHIP Authors - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "AppTask.h" - -#include -#include - -#include - -LOG_MODULE_REGISTER(app, CONFIG_CHIP_APP_LOG_LEVEL); - -using namespace ::chip; -using namespace ::chip::Inet; -using namespace ::chip::DeviceLayer; - -int main(void) -{ - CHIP_ERROR err = CHIP_NO_ERROR; - - err = chip::Platform::MemoryInit(); - if (err != CHIP_NO_ERROR) - { - LOG_ERR("MemoryInit fail"); - goto exit; - } - - err = PlatformMgr().InitChipStack(); - if (err != CHIP_NO_ERROR) - { - LOG_ERR("InitChipStack fail"); - goto exit; - } - - err = PlatformMgr().StartEventLoopTask(); - if (err != CHIP_NO_ERROR) - { - LOG_ERR("StartEventLoopTask fail"); - goto exit; - } - - err = ThreadStackMgr().InitThreadStack(); - if (err != CHIP_NO_ERROR) - { - LOG_ERR("InitThreadStack fail"); - goto exit; - } - -#ifdef CONFIG_OPENTHREAD_MTD_SED - err = ConnectivityMgr().SetThreadDeviceType(ConnectivityManager::kThreadDeviceType_SleepyEndDevice); -#elif CONFIG_OPENTHREAD_MTD - err = ConnectivityMgr().SetThreadDeviceType(ConnectivityManager::kThreadDeviceType_MinimalEndDevice); -#else - err = ConnectivityMgr().SetThreadDeviceType(ConnectivityManager::kThreadDeviceType_Router); -#endif - if (err != CHIP_NO_ERROR) - { - LOG_ERR("SetThreadDeviceType fail"); - goto exit; - } - - err = GetAppTask().StartApp(); - -exit: - LOG_ERR("Exit err %" CHIP_ERROR_FORMAT, err.Format()); - return (err == CHIP_NO_ERROR) ? EXIT_SUCCESS : EXIT_FAILURE; -} diff --git a/examples/lighting-app/telink/CMakeLists.txt b/examples/lighting-app/telink/CMakeLists.txt index e56b1f4515b7cf..16f6dfb4244663 100644 --- a/examples/lighting-app/telink/CMakeLists.txt +++ b/examples/lighting-app/telink/CMakeLists.txt @@ -59,6 +59,7 @@ target_include_directories(app PRIVATE include ${GEN_DIR}/app-common ${GEN_DIR}/lighting-app + ${TELINK_COMMON}/common/include ${TELINK_COMMON}/util/include ${TELINK_COMMON}/app/include) @@ -68,8 +69,9 @@ add_definitions( target_sources(app PRIVATE src/AppTask.cpp - src/main.cpp src/ZclCallbacks.cpp + ${TELINK_COMMON}/common/src/mainCommon.cpp + ${TELINK_COMMON}/common/src/AppTaskCommon.cpp ${TELINK_COMMON}/util/src/LEDWidget.cpp ${TELINK_COMMON}/util/src/ButtonManager.cpp ${TELINK_COMMON}/util/src/ThreadUtil.cpp diff --git a/examples/lighting-app/telink/include/AppConfig.h b/examples/lighting-app/telink/include/AppConfig.h index 531cca82215120..eaf1933669106c 100644 --- a/examples/lighting-app/telink/include/AppConfig.h +++ b/examples/lighting-app/telink/include/AppConfig.h @@ -20,17 +20,13 @@ // ---- Lighting Example App Config ---- -// Buttons config -#define BUTTON_PORT DEVICE_DT_GET(DT_NODELABEL(gpioc)) +#define APP_USE_EXAMPLE_START_BUTTON 1 +#define APP_USE_THREAD_START_BUTTON 1 +#define APP_SET_DEVICE_INFO_PROVIDER 1 +#define APP_SET_NETWORK_COMM_ENDPOINT_SEC 0 +#define APP_USE_IDENTIFY_PWM 1 // APP_USE_IDENTIFY_PWM must be defined before including "AppConfigCommon.h" -#define BUTTON_PIN_1 2 -#define BUTTON_PIN_3 3 -#define BUTTON_PIN_4 1 -#define BUTTON_PIN_2 0 - -// LEDs config -#define LEDS_PORT DEVICE_DT_GET(DT_NODELABEL(gpiob)) -#define SYSTEM_STATE_LED 7 +#include "AppConfigCommon.h" // Lighting LED config #define USE_RGB_PWM 0 @@ -40,4 +36,3 @@ #define LIGHTING_PWM_SPEC_RGB_GREEN PWM_DT_SPEC_GET(DT_ALIAS(pwm_led1)) #define LIGHTING_PWM_SPEC_RGB_RED PWM_DT_SPEC_GET(DT_ALIAS(pwm_led2)) #endif -#define LIGHTING_PWM_SPEC_IDENTIFY_GREEN PWM_DT_SPEC_GET(DT_ALIAS(pwm_led3)) diff --git a/examples/lighting-app/telink/include/AppEvent.h b/examples/lighting-app/telink/include/AppEvent.h deleted file mode 100644 index 72554b4bb54b5a..00000000000000 --- a/examples/lighting-app/telink/include/AppEvent.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * - * Copyright (c) 2022 Project CHIP Authors - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include - -struct AppEvent; -typedef void (*EventHandler)(AppEvent *); - -class LEDWidget; - -struct AppEvent -{ - enum AppEventTypes - { - kEventType_Button = 0, - kEventType_Timer, - kEventType_UpdateLedState, - kEventType_IdentifyStart, - kEventType_IdentifyStop, - kEventType_Lighting, - kEventType_Install, - }; - - uint16_t Type; - - union - { - struct - { - uint8_t Action; - } ButtonEvent; - struct - { - void * Context; - } TimerEvent; - struct - { - uint8_t Action; - int32_t Actor; - } LightingEvent; - struct - { - LEDWidget * LedWidget; - } UpdateLedStateEvent; - }; - - EventHandler Handler; -}; diff --git a/examples/lighting-app/telink/include/AppTask.h b/examples/lighting-app/telink/include/AppTask.h index dbfb0bef4fc63d..7157b5a9d3601d 100644 --- a/examples/lighting-app/telink/include/AppTask.h +++ b/examples/lighting-app/telink/include/AppTask.h @@ -18,37 +18,20 @@ #pragma once -#include "AppConfig.h" -#include "AppEvent.h" -#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED -#include "LEDWidget.h" -#endif -#include "PWMDevice.h" -#include - -#if CONFIG_CHIP_FACTORY_DATA -#include -#endif +#include "AppTaskCommon.h" #ifdef CONFIG_CHIP_PW_RPC #include "Rpc.h" #endif -#include - -struct k_timer; -struct Identify; - -class AppTask +class AppTask : public AppTaskCommon { public: - CHIP_ERROR StartApp(void); - void SetInitiateAction(PWMDevice::Action_t aAction, int32_t aActor, uint8_t * value); - void PostEvent(AppEvent * aEvent); void UpdateClusterState(void); PWMDevice & GetPWMDevice(void) { return mPwmRgbBlueLed; } +#ifdef CONFIG_CHIP_PW_RPC enum ButtonId_t { kButtonId_LightingAction = 1, @@ -56,59 +39,30 @@ class AppTask kButtonId_StartThread, kButtonId_StartBleAdv } ButtonId; - - static void IdentifyEffectHandler(EmberAfIdentifyEffectIdentifier aEffect); +#endif private: #ifdef CONFIG_CHIP_PW_RPC friend class chip::rpc::TelinkButton; + static void ButtonEventHandler(ButtonId_t btnId, bool btnPressed); #endif friend AppTask & GetAppTask(void); + friend class AppTaskCommon; + CHIP_ERROR Init(void); static void ActionInitiated(PWMDevice::Action_t aAction, int32_t aActor); static void ActionCompleted(PWMDevice::Action_t aAction, int32_t aActor); - static void ActionIdentifyStateUpdateHandler(k_timer * timer); - void DispatchEvent(AppEvent * event); - -#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED - static void UpdateLedStateEventHandler(AppEvent * aEvent); - static void LEDStateUpdateHandler(LEDWidget * ledWidget); - static void UpdateStatusLED(); -#endif - 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 FactoryResetTimerTimeoutCallback(k_timer * timer); - - static void FactoryResetTimerEventHandler(AppEvent * aEvent); - static void FactoryResetHandler(AppEvent * aEvent); - static void StartThreadHandler(AppEvent * aEvent); static void LightingActionEventHandler(AppEvent * aEvent); - static void StartBleAdvHandler(AppEvent * aEvent); - static void UpdateIdentifyStateEventHandler(AppEvent * aEvent); - static void ButtonEventHandler(ButtonId_t btnId, bool btnPressed); - static void InitButtons(void); - - static void ThreadProvisioningHandler(const chip::DeviceLayer::ChipDeviceEvent * event, intptr_t arg); - - static AppTask sAppTask; PWMDevice mPwmRgbBlueLed; #if USE_RGB_PWM PWMDevice mPwmRgbGreenLed; PWMDevice mPwmRgbRedLed; #endif - PWMDevice mPwmIdentifyLed; -#if CONFIG_CHIP_FACTORY_DATA - chip::DeviceLayer::FactoryDataProvider mFactoryDataProvider; -#endif + static AppTask sAppTask; }; inline AppTask & GetAppTask(void) diff --git a/examples/lighting-app/telink/src/AppTask.cpp b/examples/lighting-app/telink/src/AppTask.cpp index 47332a53748037..1f512e322dc188 100644 --- a/examples/lighting-app/telink/src/AppTask.cpp +++ b/examples/lighting-app/telink/src/AppTask.cpp @@ -18,178 +18,39 @@ #include "AppTask.h" -#include "AppConfig.h" -#include "AppEvent.h" -#include "ButtonManager.h" #include "ColorFormat.h" +#include "PWMDevice.h" -#include "ThreadUtil.h" - -#include #include -#include -#include -#include -#include -#include -#include -#include - -#if CONFIG_CHIP_OTA_REQUESTOR -#include "OTAUtil.h" -#endif - -#include -#include - -#include - -#if CONFIG_CHIP_LIB_SHELL -#include -#include - -static int cmd_telink_reboot(const struct shell * shell, size_t argc, char ** argv) -{ - ARG_UNUSED(argc); - ARG_UNUSED(argv); - - shell_print(shell, "Performing board reboot..."); - sys_reboot(); -} - -SHELL_STATIC_SUBCMD_SET_CREATE(sub_telink, SHELL_CMD(reboot, NULL, "Reboot board command", cmd_telink_reboot), - SHELL_SUBCMD_SET_END); -SHELL_CMD_REGISTER(telink, &sub_telink, "Telink commands", NULL); -#endif // CONFIG_CHIP_LIB_SHELL LOG_MODULE_DECLARE(app, CONFIG_CHIP_APP_LOG_LEVEL); -using namespace ::chip; -using namespace ::chip::app; -using namespace ::chip::Credentials; -using namespace ::chip::DeviceLayer; - namespace { -constexpr int kFactoryResetCalcTimeout = 3000; -constexpr int kFactoryResetTriggerCntr = 3; -constexpr int kAppEventQueueSize = 10; -constexpr uint8_t kButtonPushEvent = 1; -constexpr uint8_t kButtonReleaseEvent = 0; -constexpr EndpointId kLightEndpointId = 1; -constexpr uint8_t kDefaultMinLevel = 0; -constexpr uint8_t kDefaultMaxLevel = 254; -constexpr uint32_t kIdentifyBlinkRateMs = 200; -constexpr uint32_t kIdentifyOkayOnRateMs = 50; -constexpr uint32_t kIdentifyOkayOffRateMs = 950; -constexpr uint32_t kIdentifyFinishOnRateMs = 950; -constexpr uint32_t kIdentifyFinishOffRateMs = 50; -constexpr uint32_t kIdentifyChannelChangeRateMs = 1000; -constexpr uint32_t kIdentifyBreatheRateMs = 1000; - const struct pwm_dt_spec sPwmRgbSpecBlueLed = LIGHTING_PWM_SPEC_RGB_BLUE; #if USE_RGB_PWM const struct pwm_dt_spec sPwmRgbSpecGreenLed = LIGHTING_PWM_SPEC_RGB_GREEN; const struct pwm_dt_spec sPwmRgbSpecRedLed = LIGHTING_PWM_SPEC_RGB_RED; -#endif -const struct pwm_dt_spec sPwmIdentifySpecGreenLed = LIGHTING_PWM_SPEC_IDENTIFY_GREEN; -#if CONFIG_CHIP_FACTORY_DATA -// NOTE! This key is for test/certification only and should not be available in production devices! -uint8_t sTestEventTriggerEnableKey[TestEventTriggerDelegate::kEnableKeyLength] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, - 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }; -#endif - -K_MSGQ_DEFINE(sAppEventQueue, sizeof(AppEvent), kAppEventQueueSize, alignof(AppEvent)); -k_timer sFactoryResetTimer; -uint8_t sFactoryResetCntr = 0; - -#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED -LEDWidget sStatusLED; -#endif -#if USE_RGB_PWM uint8_t sBrightness; PWMDevice::Action_t sColorAction = PWMDevice::INVALID_ACTION; XyColor_t sXY; HsvColor_t sHSV; CtColor_t sCT; #endif - -Button sFactoryResetButton; -Button sLightingButton; -Button sThreadStartButton; -Button sBleAdvStartButton; - -bool sIsThreadProvisioned = false; -bool sIsThreadEnabled = false; -bool sIsThreadAttached = false; -bool sHaveBLEConnections = false; - -chip::DeviceLayer::DeviceInfoProviderImpl gExampleDeviceInfoProvider; - -void OnIdentifyTriggerEffect(Identify * identify) -{ - AppTask::IdentifyEffectHandler(identify->mCurrentEffectIdentifier); -} - -Identify sIdentify = { - kLightEndpointId, - [](Identify *) { ChipLogProgress(Zcl, "OnIdentifyStart"); }, - [](Identify *) { ChipLogProgress(Zcl, "OnIdentifyStop"); }, - EMBER_ZCL_IDENTIFY_IDENTIFY_TYPE_VISIBLE_LED, - OnIdentifyTriggerEffect, -}; - } // namespace AppTask AppTask::sAppTask; -class AppFabricTableDelegate : public FabricTable::Delegate -{ - void OnFabricRemoved(const FabricTable & fabricTable, FabricIndex fabricIndex) - { - if (chip::Server::GetInstance().GetFabricTable().FabricCount() == 0) - { - chip::Server::GetInstance().ScheduleFactoryReset(); - } - } -}; - CHIP_ERROR AppTask::Init(void) { - LOG_INF("SW Version: %u, %s", CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION, CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING); - - // Initialize LEDs -#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED - LEDWidget::InitGpio(LEDS_PORT); - LEDWidget::SetStateUpdateCallback(LEDStateUpdateHandler); - - sStatusLED.Init(SYSTEM_STATE_LED); - - UpdateStatusLED(); -#endif - - InitButtons(); - - // Initialize function button timer - k_timer_init(&sFactoryResetTimer, &AppTask::FactoryResetTimerTimeoutCallback, nullptr); - k_timer_user_data_set(&sFactoryResetTimer, this); - // Init lighting manager uint8_t minLightLevel = kDefaultMinLevel; - Clusters::LevelControl::Attributes::MinLevel::Get(kLightEndpointId, &minLightLevel); + Clusters::LevelControl::Attributes::MinLevel::Get(kExampleEndpointId, &minLightLevel); uint8_t maxLightLevel = kDefaultMaxLevel; - Clusters::LevelControl::Attributes::MaxLevel::Get(kLightEndpointId, &maxLightLevel); + Clusters::LevelControl::Attributes::MaxLevel::Get(kExampleEndpointId, &maxLightLevel); - // Initialize PWM LEDs - CHIP_ERROR err = sAppTask.mPwmIdentifyLed.Init(&sPwmIdentifySpecGreenLed, kDefaultMinLevel, kDefaultMaxLevel, kDefaultMaxLevel); - if (err != CHIP_NO_ERROR) - { - LOG_ERR("Green IDENTIFY PWM Device Init fail"); - return err; - } - - err = sAppTask.mPwmRgbBlueLed.Init(&sPwmRgbSpecBlueLed, minLightLevel, maxLightLevel, maxLightLevel); + CHIP_ERROR err = sAppTask.mPwmRgbBlueLed.Init(&sPwmRgbSpecBlueLed, minLightLevel, maxLightLevel, maxLightLevel); if (err != CHIP_NO_ERROR) { LOG_ERR("Blue RGB PWM Device Init fail"); @@ -211,44 +72,11 @@ CHIP_ERROR AppTask::Init(void) } #endif sAppTask.mPwmRgbBlueLed.SetCallbacks(ActionInitiated, ActionCompleted, nullptr); - sAppTask.mPwmIdentifyLed.SetCallbacks(nullptr, nullptr, ActionIdentifyStateUpdateHandler); - - // Initialize CHIP server -#if CONFIG_CHIP_FACTORY_DATA - ReturnErrorOnFailure(mFactoryDataProvider.Init()); - SetDeviceInstanceInfoProvider(&mFactoryDataProvider); - SetDeviceAttestationCredentialsProvider(&mFactoryDataProvider); - SetCommissionableDataProvider(&mFactoryDataProvider); - // Read EnableKey from the factory data. - MutableByteSpan enableKey(sTestEventTriggerEnableKey); - err = mFactoryDataProvider.GetEnableKey(enableKey); - if (err != CHIP_NO_ERROR) - { - LOG_ERR("GetEnableKey fail"); - memset(sTestEventTriggerEnableKey, 0, sizeof(sTestEventTriggerEnableKey)); - } -#else - SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); -#endif - static CommonCaseDeviceServerInitParams initParams; - (void) initParams.InitializeStaticResourcesBeforeServerInit(); - ReturnErrorOnFailure(chip::Server::GetInstance().Init(initParams)); - - gExampleDeviceInfoProvider.SetStorageDelegate(&Server::GetInstance().GetPersistentStorage()); - chip::DeviceLayer::SetDeviceInfoProvider(&gExampleDeviceInfoProvider); - -#if CONFIG_CHIP_OTA_REQUESTOR - InitBasicOTARequestor(); +#if APP_USE_EXAMPLE_START_BUTTON + SetExampleButtonCallbacks(LightingActionEventHandler); #endif - - 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); + InitCommonParts(); err = ConnectivityMgr().SetBLEDeviceName("TelinkLight"); if (err != CHIP_NO_ERROR) @@ -257,45 +85,9 @@ CHIP_ERROR AppTask::Init(void) return err; } - err = chip::Server::GetInstance().GetFabricTable().AddFabricDelegate(new AppFabricTableDelegate); - if (err != CHIP_NO_ERROR) - { - LOG_ERR("AppFabricTableDelegate fail"); - return err; - } - return CHIP_NO_ERROR; } -CHIP_ERROR AppTask::StartApp(void) -{ - CHIP_ERROR err = Init(); - - if (err != CHIP_NO_ERROR) - { - LOG_ERR("AppTask Init fail"); - return err; - } - - AppEvent event = {}; - - while (true) - { - k_msgq_get(&sAppEventQueue, &event, K_FOREVER); - DispatchEvent(&event); - } -} - -void AppTask::LightingActionButtonEventHandler(void) -{ - AppEvent event; - - event.Type = AppEvent::kEventType_Button; - event.ButtonEvent.Action = kButtonPushEvent; - event.Handler = LightingActionEventHandler; - sAppTask.PostEvent(&event); -} - void AppTask::LightingActionEventHandler(AppEvent * aEvent) { PWMDevice::Action_t action = PWMDevice::INVALID_ACTION; @@ -335,225 +127,31 @@ void AppTask::LightingActionEventHandler(AppEvent * aEvent) } } -void AppTask::IdentifyEffectHandler(EmberAfIdentifyEffectIdentifier aEffect) -{ - AppEvent event; - event.Type = AppEvent::kEventType_IdentifyStart; - - switch (aEffect) - { - case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BLINK: - ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BLINK"); - event.Handler = [](AppEvent *) { - sAppTask.mPwmIdentifyLed.InitiateBlinkAction(kIdentifyBlinkRateMs, kIdentifyBlinkRateMs); - }; - break; - case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BREATHE: - ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BREATHE"); - event.Handler = [](AppEvent *) { - sAppTask.mPwmIdentifyLed.InitiateBreatheAction(PWMDevice::kBreatheType_Both, kIdentifyBreatheRateMs); - }; - break; - case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_OKAY: - ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_OKAY"); - event.Handler = [](AppEvent *) { - sAppTask.mPwmIdentifyLed.InitiateBlinkAction(kIdentifyOkayOnRateMs, kIdentifyOkayOffRateMs); - }; - break; - case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_CHANNEL_CHANGE: - ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_CHANNEL_CHANGE"); - event.Handler = [](AppEvent *) { - sAppTask.mPwmIdentifyLed.InitiateBlinkAction(kIdentifyChannelChangeRateMs, kIdentifyChannelChangeRateMs); - }; - break; - case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_FINISH_EFFECT: - ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_FINISH_EFFECT"); - event.Handler = [](AppEvent *) { - sAppTask.mPwmIdentifyLed.InitiateBlinkAction(kIdentifyFinishOnRateMs, kIdentifyFinishOffRateMs); - }; - break; - case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_STOP_EFFECT: - ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_STOP_EFFECT"); - event.Handler = [](AppEvent *) { sAppTask.mPwmIdentifyLed.StopAction(); }; - event.Type = AppEvent::kEventType_IdentifyStop; - break; - default: - ChipLogProgress(Zcl, "No identifier effect"); - return; - } - - sAppTask.PostEvent(&event); -} - -void AppTask::FactoryResetButtonEventHandler(void) -{ - AppEvent event; - - event.Type = AppEvent::kEventType_Button; - event.ButtonEvent.Action = kButtonPushEvent; - event.Handler = FactoryResetHandler; - sAppTask.PostEvent(&event); -} - -void AppTask::FactoryResetHandler(AppEvent * aEvent) -{ - if (sFactoryResetCntr == 0) - { - k_timer_start(&sFactoryResetTimer, K_MSEC(kFactoryResetCalcTimeout), K_NO_WAIT); - } - - sFactoryResetCntr++; - LOG_INF("Factory Reset Trigger Counter: %d/%d", sFactoryResetCntr, kFactoryResetTriggerCntr); - - if (sFactoryResetCntr == kFactoryResetTriggerCntr) - { - k_timer_stop(&sFactoryResetTimer); - sFactoryResetCntr = 0; - - chip::Server::GetInstance().ScheduleFactoryReset(); - } -} - -void AppTask::StartThreadButtonEventHandler(void) -{ - AppEvent event; - - event.Type = AppEvent::kEventType_Button; - event.ButtonEvent.Action = kButtonPushEvent; - event.Handler = StartThreadHandler; - sAppTask.PostEvent(&event); -} - -void AppTask::StartThreadHandler(AppEvent * aEvent) -{ - LOG_INF("StartThreadHandler"); - if (!chip::DeviceLayer::ConnectivityMgr().IsThreadProvisioned()) - { - // Switch context from BLE to Thread - Internal::BLEManagerImpl sInstance; - sInstance.SwitchToIeee802154(); - StartDefaultThreadNetwork(); - } - else - { - LOG_INF("Device already commissioned"); - } -} - -void AppTask::StartBleAdvButtonEventHandler(void) -{ - AppEvent event; - - event.Type = AppEvent::kEventType_Button; - event.ButtonEvent.Action = kButtonPushEvent; - event.Handler = StartBleAdvHandler; - sAppTask.PostEvent(&event); -} - -void AppTask::StartBleAdvHandler(AppEvent * aEvent) +#ifdef CONFIG_CHIP_PW_RPC +void AppTask::ButtonEventHandler(ButtonId_t btnId, bool btnPressed) { - LOG_INF("StartBleAdvHandler"); - - // Don't allow on starting Matter service BLE advertising after Thread provisioning. - if (ConnectivityMgr().IsThreadProvisioned()) - { - LOG_INF("Device already commissioned"); - return; - } - - if (ConnectivityMgr().IsBLEAdvertisingEnabled()) + if (!btnPressed) { - LOG_INF("BLE adv already enabled"); return; } - if (chip::Server::GetInstance().GetCommissioningWindowManager().OpenBasicCommissioningWindow() != CHIP_NO_ERROR) - { - LOG_ERR("OpenBasicCommissioningWindow fail"); - } -} - -#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED -void AppTask::UpdateLedStateEventHandler(AppEvent * aEvent) -{ - if (aEvent->Type == AppEvent::kEventType_UpdateLedState) - { - aEvent->UpdateLedStateEvent.LedWidget->UpdateState(); - } -} - -void AppTask::LEDStateUpdateHandler(LEDWidget * ledWidget) -{ - AppEvent event; - event.Type = AppEvent::kEventType_UpdateLedState; - event.Handler = UpdateLedStateEventHandler; - event.UpdateLedStateEvent.LedWidget = ledWidget; - sAppTask.PostEvent(&event); -} - -void AppTask::UpdateStatusLED(void) -{ - if (sIsThreadProvisioned && sIsThreadEnabled) - { - if (sIsThreadAttached) - { - sStatusLED.Blink(950, 50); - } - else - { - sStatusLED.Blink(100, 100); - } - } - else - { - sStatusLED.Blink(50, 950); - } -} -#endif - -void AppTask::ChipEventHandler(const ChipDeviceEvent * event, intptr_t /* arg */) -{ - switch (event->Type) + switch (btnId) { - case DeviceEventType::kCHIPoBLEAdvertisingChange: - sHaveBLEConnections = ConnectivityMgr().NumBLEConnections() != 0; -#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED - UpdateStatusLED(); -#endif + case kButtonId_LightingAction: + ExampleActionButtonEventHandler(); break; - case DeviceEventType::kThreadStateChange: - sIsThreadProvisioned = ConnectivityMgr().IsThreadProvisioned(); - sIsThreadEnabled = ConnectivityMgr().IsThreadEnabled(); - sIsThreadAttached = ConnectivityMgr().IsThreadAttached(); -#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED - UpdateStatusLED(); -#endif + case kButtonId_FactoryReset: + FactoryResetButtonEventHandler(); break; - case DeviceEventType::kThreadConnectivityChange: -#if CONFIG_CHIP_OTA_REQUESTOR - if (event->ThreadConnectivityChange.Result == kConnectivity_Established) - { - InitBasicOTARequestor(); - } -#endif + case kButtonId_StartThread: + StartThreadButtonEventHandler(); break; - default: + case kButtonId_StartBleAdv: + StartBleAdvButtonEventHandler(); break; } } - -void AppTask::ActionIdentifyStateUpdateHandler(k_timer * timer) -{ - AppEvent event; - event.Type = AppEvent::kEventType_UpdateLedState; - event.Handler = UpdateIdentifyStateEventHandler; - sAppTask.PostEvent(&event); -} - -void AppTask::UpdateIdentifyStateEventHandler(AppEvent * aEvent) -{ - sAppTask.mPwmIdentifyLed.UpdateAction(); -} +#endif void AppTask::ActionInitiated(PWMDevice::Action_t aAction, int32_t aActor) { @@ -592,36 +190,16 @@ void AppTask::ActionCompleted(PWMDevice::Action_t aAction, int32_t aActor) } } -void AppTask::PostEvent(AppEvent * aEvent) -{ - if (k_msgq_put(&sAppEventQueue, aEvent, K_NO_WAIT) != 0) - { - LOG_INF("PostEvent fail"); - } -} - -void AppTask::DispatchEvent(AppEvent * aEvent) -{ - if (aEvent->Handler) - { - aEvent->Handler(aEvent); - } - else - { - LOG_INF("Dropping event without handler"); - } -} - void AppTask::UpdateClusterState(void) { #if USE_RGB_PWM bool isTurnedOn = sAppTask.mPwmRgbRedLed.IsTurnedOn() || sAppTask.mPwmRgbGreenLed.IsTurnedOn() || sAppTask.mPwmRgbBlueLed.IsTurnedOn(); #else - bool isTurnedOn = sAppTask.mPwmRgbBlueLed.IsTurnedOn(); + bool isTurnedOn = sAppTask.mPwmRgbBlueLed.IsTurnedOn(); #endif // write the new on/off value - EmberAfStatus status = Clusters::OnOff::Attributes::OnOff::Set(kLightEndpointId, isTurnedOn); + EmberAfStatus status = Clusters::OnOff::Attributes::OnOff::Set(kExampleEndpointId, isTurnedOn); if (status != EMBER_ZCL_STATUS_SUCCESS) { @@ -642,81 +220,13 @@ void AppTask::UpdateClusterState(void) #else uint8_t setLevel = sAppTask.mPwmRgbBlueLed.GetLevel(); #endif - status = Clusters::LevelControl::Attributes::CurrentLevel::Set(kLightEndpointId, setLevel); + status = Clusters::LevelControl::Attributes::CurrentLevel::Set(kExampleEndpointId, setLevel); if (status != EMBER_ZCL_STATUS_SUCCESS) { LOG_ERR("Update CurrentLevel fail: %x", status); } } -void AppTask::FactoryResetTimerTimeoutCallback(k_timer * timer) -{ - if (!timer) - { - return; - } - - AppEvent event; - event.Type = AppEvent::kEventType_Timer; - event.Handler = FactoryResetTimerEventHandler; - sAppTask.PostEvent(&event); -} - -void AppTask::FactoryResetTimerEventHandler(AppEvent * aEvent) -{ - if (aEvent->Type != AppEvent::kEventType_Timer) - { - return; - } - - sFactoryResetCntr = 0; - LOG_INF("Factory Reset Trigger Counter is cleared"); -} - -void AppTask::ButtonEventHandler(ButtonId_t btnId, bool btnPressed) -{ - if (!btnPressed) - { - return; - } - - switch (btnId) - { - case kButtonId_LightingAction: - LightingActionButtonEventHandler(); - break; - case kButtonId_FactoryReset: - FactoryResetButtonEventHandler(); - break; - case kButtonId_StartThread: - StartThreadButtonEventHandler(); - break; - case kButtonId_StartBleAdv: - StartBleAdvButtonEventHandler(); - break; - } -} - -void AppTask::InitButtons(void) -{ -#if CONFIG_CHIP_BUTTON_MANAGER_IRQ_MODE - sFactoryResetButton.Configure(BUTTON_PORT, BUTTON_PIN_1, FactoryResetButtonEventHandler); - sLightingButton.Configure(BUTTON_PORT, BUTTON_PIN_2, LightingActionButtonEventHandler); - sThreadStartButton.Configure(BUTTON_PORT, BUTTON_PIN_3, StartThreadButtonEventHandler); - sBleAdvStartButton.Configure(BUTTON_PORT, BUTTON_PIN_4, StartBleAdvButtonEventHandler); -#else - sFactoryResetButton.Configure(BUTTON_PORT, BUTTON_PIN_3, BUTTON_PIN_1, FactoryResetButtonEventHandler); - sLightingButton.Configure(BUTTON_PORT, BUTTON_PIN_4, BUTTON_PIN_1, LightingActionButtonEventHandler); - sThreadStartButton.Configure(BUTTON_PORT, BUTTON_PIN_3, BUTTON_PIN_2, StartThreadButtonEventHandler); - sBleAdvStartButton.Configure(BUTTON_PORT, BUTTON_PIN_4, BUTTON_PIN_2, StartBleAdvButtonEventHandler); -#endif - - ButtonManagerInst().AddButton(sFactoryResetButton); - ButtonManagerInst().AddButton(sLightingButton); - ButtonManagerInst().AddButton(sThreadStartButton); - ButtonManagerInst().AddButton(sBleAdvStartButton); -} - void AppTask::SetInitiateAction(PWMDevice::Action_t aAction, int32_t aActor, uint8_t * value) { #if USE_RGB_PWM diff --git a/examples/lock-app/telink/CMakeLists.txt b/examples/lock-app/telink/CMakeLists.txt index d424f24bcd19f0..98b3e5de27e567 100755 --- a/examples/lock-app/telink/CMakeLists.txt +++ b/examples/lock-app/telink/CMakeLists.txt @@ -59,6 +59,7 @@ target_include_directories(app PRIVATE include ${GEN_DIR}/app-common ${GEN_DIR}/lock-app + ${TELINK_COMMON}/common/include ${TELINK_COMMON}/util/include ${TELINK_COMMON}/app/include) @@ -68,9 +69,10 @@ add_definitions( target_sources(app PRIVATE src/AppTask.cpp - src/main.cpp src/ZclCallbacks.cpp src/BoltLockManager.cpp + ${TELINK_COMMON}/common/src/mainCommon.cpp + ${TELINK_COMMON}/common/src/AppTaskCommon.cpp ${TELINK_COMMON}/util/src/LEDWidget.cpp ${TELINK_COMMON}/util/src/ButtonManager.cpp ${TELINK_COMMON}/util/src/ThreadUtil.cpp diff --git a/examples/lock-app/telink/include/AppConfig.h b/examples/lock-app/telink/include/AppConfig.h old mode 100755 new mode 100644 index a6b0bc0b7f3ddf..ae4c9d5b4fc9c5 --- a/examples/lock-app/telink/include/AppConfig.h +++ b/examples/lock-app/telink/include/AppConfig.h @@ -20,16 +20,12 @@ // ---- Lock Example App Config ---- -// Buttons config -#define BUTTON_PORT DEVICE_DT_GET(DT_NODELABEL(gpioc)) +#define APP_USE_EXAMPLE_START_BUTTON 1 +#define APP_USE_THREAD_START_BUTTON 1 +#define APP_SET_DEVICE_INFO_PROVIDER 1 +#define APP_SET_NETWORK_COMM_ENDPOINT_SEC 0 +#define APP_USE_IDENTIFY_PWM 1 // APP_USE_IDENTIFY_PWM must be defined before including "AppConfigCommon.h" -#define BUTTON_PIN_1 2 -#define BUTTON_PIN_3 3 -#define BUTTON_PIN_4 1 -#define BUTTON_PIN_2 0 +#include "AppConfigCommon.h" -// LEDs config -#define LEDS_PORT DEVICE_DT_GET(DT_NODELABEL(gpiob)) -#define SYSTEM_STATE_LED 7 #define LOCK_STATE_LED 6 -#define LIGHTING_PWM_SPEC_IDENTIFY_GREEN PWM_DT_SPEC_GET(DT_ALIAS(pwm_led3)) diff --git a/examples/lock-app/telink/include/AppEvent.h b/examples/lock-app/telink/include/AppEvent.h deleted file mode 100644 index 9f2436c592dc8c..00000000000000 --- a/examples/lock-app/telink/include/AppEvent.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * - * Copyright (c) 2023 Project CHIP Authors - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include - -struct AppEvent; -typedef void (*EventHandler)(AppEvent *); - -class LEDWidget; - -struct AppEvent -{ - enum AppEventTypes - { - kEventType_Button = 0, - kEventType_Timer, - kEventType_UpdateLedState, - kEventType_IdentifyStart, - kEventType_IdentifyStop, - kEventType_Lighting, - kEventType_Install, - }; - - uint16_t Type; - - union - { - struct - { - uint8_t Action; - } ButtonEvent; - struct - { - void * Context; - } TimerEvent; - struct - { - LEDWidget * LedWidget; - } UpdateLedStateEvent; - }; - - EventHandler Handler; -}; diff --git a/examples/lock-app/telink/include/AppTask.h b/examples/lock-app/telink/include/AppTask.h index 5f26b3d6895634..c63643ca89ca6d 100644 --- a/examples/lock-app/telink/include/AppTask.h +++ b/examples/lock-app/telink/include/AppTask.h @@ -18,72 +18,24 @@ #pragma once -#include "AppEvent.h" +#include "AppTaskCommon.h" #include "BoltLockManager.h" -#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED -#include "LEDWidget.h" -#endif -#include "PWMDevice.h" -#include - -#if CONFIG_CHIP_FACTORY_DATA -#include -#endif - -struct k_timer; -struct Identify; - -class AppTask +class AppTask : public AppTaskCommon { public: - CHIP_ERROR StartApp(); - - void PostEvent(AppEvent * event); void UpdateClusterState(BoltLockManager::State state, BoltLockManager::OperationSource source); - static void IdentifyEffectHandler(EmberAfIdentifyEffectIdentifier aEffect); private: friend AppTask & GetAppTask(void); + friend class AppTaskCommon; CHIP_ERROR Init(void); - static void ActionIdentifyStateUpdateHandler(k_timer * timer); - - void DispatchEvent(AppEvent * event); - -#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED - static void UpdateLedStateEventHandler(AppEvent * aEvent); - static void LEDStateUpdateHandler(LEDWidget * ledWidget); - static void UpdateStatusLED(); -#endif - static void LockActionButtonEventHandler(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 FactoryResetTimerTimeoutCallback(k_timer * timer); - - static void FactoryResetTimerEventHandler(AppEvent * aEvent); - static void FactoryResetHandler(AppEvent * aEvent); - static void StartThreadHandler(AppEvent * aEvent); - static void SwitchActionEventHandler(AppEvent * aEvent); - static void StartBleAdvHandler(AppEvent * aEvent); - static void UpdateIdentifyStateEventHandler(AppEvent * aEvent); - static void LockActionEventHandler(AppEvent * event); static void LockStateChanged(BoltLockManager::State state, BoltLockManager::OperationSource source); - static void InitButtons(void); - static AppTask sAppTask; - PWMDevice mPwmIdentifyLed; - -#if CONFIG_CHIP_FACTORY_DATA - chip::DeviceLayer::FactoryDataProvider mFactoryDataProvider; -#endif }; inline AppTask & GetAppTask(void) diff --git a/examples/lock-app/telink/src/AppTask.cpp b/examples/lock-app/telink/src/AppTask.cpp index 91fc9540b15faf..ca73a27eda6dd1 100644 --- a/examples/lock-app/telink/src/AppTask.cpp +++ b/examples/lock-app/telink/src/AppTask.cpp @@ -17,299 +17,49 @@ */ #include "AppTask.h" - -#include "AppConfig.h" #include "BoltLockManager.h" -#include "ButtonManager.h" - -#include "ThreadUtil.h" -#include #include -#include -#include -#include -#include -#include -#include -#include - -#if CONFIG_CHIP_OTA_REQUESTOR -#include "OTAUtil.h" -#endif - -#include -#include - -#if CONFIG_CHIP_LIB_SHELL -#include -#include - -static int cmd_telink_reboot(const struct shell * shell, size_t argc, char ** argv) -{ - ARG_UNUSED(argc); - ARG_UNUSED(argv); - - shell_print(shell, "Performing board reboot..."); - sys_reboot(); -} - -SHELL_STATIC_SUBCMD_SET_CREATE(sub_telink, SHELL_CMD(reboot, NULL, "Reboot board command", cmd_telink_reboot), - SHELL_SUBCMD_SET_END); -SHELL_CMD_REGISTER(telink, &sub_telink, "Telink commands", NULL); -#endif // CONFIG_CHIP_LIB_SHELL LOG_MODULE_DECLARE(app, CONFIG_CHIP_APP_LOG_LEVEL); -using namespace ::chip; -using namespace ::chip::app; using namespace ::chip::app::Clusters::DoorLock; -using namespace ::chip::Credentials; -using namespace ::chip::DeviceLayer; namespace { -constexpr int kFactoryResetCalcTimeout = 3000; -constexpr int kFactoryResetTriggerCntr = 3; -constexpr int kAppEventQueueSize = 10; -constexpr uint8_t kButtonPushEvent = 1; -constexpr uint8_t kButtonReleaseEvent = 0; -constexpr EndpointId kLockEndpointId = 1; -constexpr uint8_t kDefaultMinLevel = 0; -constexpr uint8_t kDefaultMaxLevel = 254; -constexpr uint32_t kIdentifyBlinkRateMs = 200; -constexpr uint32_t kIdentifyOkayOnRateMs = 50; -constexpr uint32_t kIdentifyOkayOffRateMs = 950; -constexpr uint32_t kIdentifyFinishOnRateMs = 950; -constexpr uint32_t kIdentifyFinishOffRateMs = 50; -constexpr uint32_t kIdentifyChannelChangeRateMs = 1000; -constexpr uint32_t kIdentifyBreatheRateMs = 1000; - -const struct pwm_dt_spec sPwmIdentifySpecGreenLed = LIGHTING_PWM_SPEC_IDENTIFY_GREEN; - -#if CONFIG_CHIP_FACTORY_DATA -// NOTE! This key is for test/certification only and should not be available in production devices! -uint8_t sTestEventTriggerEnableKey[TestEventTriggerDelegate::kEnableKeyLength] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, - 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }; -#endif - -K_MSGQ_DEFINE(sAppEventQueue, sizeof(AppEvent), kAppEventQueueSize, alignof(AppEvent)); -k_timer sFactoryResetTimer; -uint8_t sFactoryResetCntr = 0; - #if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED -LEDWidget sStatusLED; LEDWidget sLockLED; #endif - -Button sFactoryResetButton; -Button sLockButton; -Button sThreadStartButton; -Button sBleAdvStartButton; - -bool sIsThreadProvisioned = false; -bool sIsThreadEnabled = false; -bool sIsThreadAttached = false; -bool sHaveBLEConnections = false; - -chip::DeviceLayer::DeviceInfoProviderImpl gExampleDeviceInfoProvider; - -void OnIdentifyTriggerEffect(Identify * identify) -{ - AppTask::IdentifyEffectHandler(identify->mCurrentEffectIdentifier); -} - -Identify sIdentify = { - kLockEndpointId, - [](Identify *) { ChipLogProgress(Zcl, "OnIdentifyStart"); }, - [](Identify *) { ChipLogProgress(Zcl, "OnIdentifyStop"); }, - EMBER_ZCL_IDENTIFY_IDENTIFY_TYPE_VISIBLE_LED, - OnIdentifyTriggerEffect, -}; - } // namespace AppTask AppTask::sAppTask; -class AppFabricTableDelegate : public FabricTable::Delegate -{ - void OnFabricRemoved(const FabricTable & fabricTable, FabricIndex fabricIndex) - { - if (chip::Server::GetInstance().GetFabricTable().FabricCount() == 0) - { - chip::Server::GetInstance().ScheduleFactoryReset(); - } - } -}; - CHIP_ERROR AppTask::Init(void) { - LOG_INF("SW Version: %u, %s", CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION, CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING); +#if APP_USE_EXAMPLE_START_BUTTON + SetExampleButtonCallbacks(LockActionEventHandler); +#endif + InitCommonParts(); - // Initialize status LED #if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED - LEDWidget::InitGpio(LEDS_PORT); - LEDWidget::SetStateUpdateCallback(LEDStateUpdateHandler); - sStatusLED.Init(SYSTEM_STATE_LED); - - UpdateStatusLED(); - sLockLED.Init(LOCK_STATE_LED); sLockLED.Set(BoltLockMgr().IsLocked()); #endif - InitButtons(); - - // Initialize function button timer - k_timer_init(&sFactoryResetTimer, &AppTask::FactoryResetTimerTimeoutCallback, nullptr); - k_timer_user_data_set(&sFactoryResetTimer, this); - - // Initialize PWM Identify led - CHIP_ERROR err = sAppTask.mPwmIdentifyLed.Init(&sPwmIdentifySpecGreenLed, kDefaultMinLevel, kDefaultMaxLevel, kDefaultMaxLevel); - if (err != CHIP_NO_ERROR) - { - LOG_ERR("Green IDENTIFY PWM Device Init fail"); - return err; - } - - sAppTask.mPwmIdentifyLed.SetCallbacks(nullptr, nullptr, ActionIdentifyStateUpdateHandler); - BoltLockMgr().Init(LockStateChanged); - // Initialize CHIP server -#if CONFIG_CHIP_FACTORY_DATA - ReturnErrorOnFailure(mFactoryDataProvider.Init()); - SetDeviceInstanceInfoProvider(&mFactoryDataProvider); - SetDeviceAttestationCredentialsProvider(&mFactoryDataProvider); - SetCommissionableDataProvider(&mFactoryDataProvider); - // Read EnableKey from the factory data. - MutableByteSpan enableKey(sTestEventTriggerEnableKey); - err = mFactoryDataProvider.GetEnableKey(enableKey); - if (err != CHIP_NO_ERROR) - { - LOG_ERR("mFactoryDataProvider.GetEnableKey() failed. Could not delegate a test event trigger"); - memset(sTestEventTriggerEnableKey, 0, sizeof(sTestEventTriggerEnableKey)); - } -#else - SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); -#endif - - static CommonCaseDeviceServerInitParams initParams; - (void) initParams.InitializeStaticResourcesBeforeServerInit(); - ReturnErrorOnFailure(chip::Server::GetInstance().Init(initParams)); - gExampleDeviceInfoProvider.SetStorageDelegate(&Server::GetInstance().GetPersistentStorage()); - chip::DeviceLayer::SetDeviceInfoProvider(&gExampleDeviceInfoProvider); - -#if CONFIG_CHIP_OTA_REQUESTOR - InitBasicOTARequestor(); -#endif - - 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); - // Disable auto-relock time feature. - DoorLockServer::Instance().SetAutoRelockTime(kLockEndpointId, 0); + DoorLockServer::Instance().SetAutoRelockTime(kExampleEndpointId, 0); - err = ConnectivityMgr().SetBLEDeviceName("Telink Lock"); + CHIP_ERROR err = ConnectivityMgr().SetBLEDeviceName("Telink Lock"); if (err != CHIP_NO_ERROR) { LOG_ERR("SetBLEDeviceName fail"); return err; } - err = chip::Server::GetInstance().GetFabricTable().AddFabricDelegate(new AppFabricTableDelegate); - if (err != CHIP_NO_ERROR) - { - LOG_ERR("AppFabricTableDelegate fail"); - return err; - } - return CHIP_NO_ERROR; } -CHIP_ERROR AppTask::StartApp(void) -{ - CHIP_ERROR err = Init(); - - if (err != CHIP_NO_ERROR) - { - LOG_ERR("AppTask Init fail"); - return err; - } - - AppEvent event = {}; - - while (true) - { - k_msgq_get(&sAppEventQueue, &event, K_FOREVER); - DispatchEvent(&event); - } -} - -void AppTask::IdentifyEffectHandler(EmberAfIdentifyEffectIdentifier aEffect) -{ - AppEvent event; - event.Type = AppEvent::kEventType_IdentifyStart; - - switch (aEffect) - { - case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BLINK: - ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BLINK"); - event.Handler = [](AppEvent *) { - sAppTask.mPwmIdentifyLed.InitiateBlinkAction(kIdentifyBlinkRateMs, kIdentifyBlinkRateMs); - }; - break; - case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BREATHE: - ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BREATHE"); - event.Handler = [](AppEvent *) { - sAppTask.mPwmIdentifyLed.InitiateBreatheAction(PWMDevice::kBreatheType_Both, kIdentifyBreatheRateMs); - }; - break; - case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_OKAY: - ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_OKAY"); - event.Handler = [](AppEvent *) { - sAppTask.mPwmIdentifyLed.InitiateBlinkAction(kIdentifyOkayOnRateMs, kIdentifyOkayOffRateMs); - }; - break; - case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_CHANNEL_CHANGE: - ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_CHANNEL_CHANGE"); - event.Handler = [](AppEvent *) { - sAppTask.mPwmIdentifyLed.InitiateBlinkAction(kIdentifyChannelChangeRateMs, kIdentifyChannelChangeRateMs); - }; - break; - case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_FINISH_EFFECT: - ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_FINISH_EFFECT"); - event.Handler = [](AppEvent *) { - sAppTask.mPwmIdentifyLed.InitiateBlinkAction(kIdentifyFinishOnRateMs, kIdentifyFinishOffRateMs); - }; - break; - case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_STOP_EFFECT: - ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_STOP_EFFECT"); - event.Handler = [](AppEvent *) { sAppTask.mPwmIdentifyLed.StopAction(); }; - event.Type = AppEvent::kEventType_IdentifyStop; - break; - default: - ChipLogProgress(Zcl, "No identifier effect"); - return; - } - - sAppTask.PostEvent(&event); -} - -void AppTask::LockActionButtonEventHandler(void) -{ - AppEvent event; - - event.Type = AppEvent::kEventType_Button; - event.ButtonEvent.Action = kButtonPushEvent; - event.Handler = LockActionEventHandler; - sAppTask.PostEvent(&event); -} - void AppTask::LockActionEventHandler(AppEvent * aEvent) { if (BoltLockMgr().IsLocked()) @@ -322,195 +72,33 @@ void AppTask::LockActionEventHandler(AppEvent * aEvent) } } -void AppTask::FactoryResetButtonEventHandler(void) -{ - AppEvent event; - - event.Type = AppEvent::kEventType_Button; - event.ButtonEvent.Action = kButtonPushEvent; - event.Handler = FactoryResetHandler; - sAppTask.PostEvent(&event); -} - -void AppTask::FactoryResetHandler(AppEvent * aEvent) -{ - if (sFactoryResetCntr == 0) - { - k_timer_start(&sFactoryResetTimer, K_MSEC(kFactoryResetCalcTimeout), K_NO_WAIT); - } - - sFactoryResetCntr++; - LOG_INF("Factory Reset Trigger Counter: %d/%d", sFactoryResetCntr, kFactoryResetTriggerCntr); - - if (sFactoryResetCntr == kFactoryResetTriggerCntr) - { - k_timer_stop(&sFactoryResetTimer); - sFactoryResetCntr = 0; - - chip::Server::GetInstance().ScheduleFactoryReset(); - } -} - -void AppTask::StartThreadButtonEventHandler(void) -{ - AppEvent event; - - event.Type = AppEvent::kEventType_Button; - event.ButtonEvent.Action = kButtonPushEvent; - event.Handler = StartThreadHandler; - sAppTask.PostEvent(&event); -} - -void AppTask::StartThreadHandler(AppEvent * aEvent) -{ - LOG_INF("StartThreadHandler"); - if (!chip::DeviceLayer::ConnectivityMgr().IsThreadProvisioned()) - { - // Switch context from BLE to Thread - Internal::BLEManagerImpl sInstance; - sInstance.SwitchToIeee802154(); - StartDefaultThreadNetwork(); - } - else - { - LOG_INF("Device already commissioned"); - } -} - -void AppTask::StartBleAdvButtonEventHandler(void) -{ - AppEvent event; - - event.Type = AppEvent::kEventType_Button; - event.ButtonEvent.Action = kButtonPushEvent; - event.Handler = StartBleAdvHandler; - sAppTask.PostEvent(&event); -} - -void AppTask::StartBleAdvHandler(AppEvent * aEvent) -{ - LOG_INF("StartBleAdvHandler"); - - // Don't allow on starting Matter service BLE advertising after Thread provisioning. - if (ConnectivityMgr().IsThreadProvisioned()) - { - LOG_INF("Device already commissioned"); - return; - } - - if (ConnectivityMgr().IsBLEAdvertisingEnabled()) - { - LOG_INF("BLE adv already enabled"); - return; - } - - if (chip::Server::GetInstance().GetCommissioningWindowManager().OpenBasicCommissioningWindow() != CHIP_NO_ERROR) - { - LOG_ERR("OpenBasicCommissioningWindow fail"); - } -} - -#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED -void AppTask::UpdateLedStateEventHandler(AppEvent * aEvent) -{ - if (aEvent->Type == AppEvent::kEventType_UpdateLedState) - { - aEvent->UpdateLedStateEvent.LedWidget->UpdateState(); - } -} - -void AppTask::LEDStateUpdateHandler(LEDWidget * ledWidget) -{ - AppEvent event; - event.Type = AppEvent::kEventType_UpdateLedState; - event.Handler = UpdateLedStateEventHandler; - event.UpdateLedStateEvent.LedWidget = ledWidget; - sAppTask.PostEvent(&event); -} - -void AppTask::UpdateStatusLED(void) -{ - if (sIsThreadProvisioned && sIsThreadEnabled) - { - if (sIsThreadAttached) - { - sStatusLED.Blink(950, 50); - } - else - { - sStatusLED.Blink(100, 100); - } - } - else - { - sStatusLED.Blink(50, 950); - } -} -#endif - -void AppTask::ChipEventHandler(const ChipDeviceEvent * event, intptr_t /* arg */) -{ - switch (event->Type) - { - case DeviceEventType::kCHIPoBLEAdvertisingChange: - sHaveBLEConnections = ConnectivityMgr().NumBLEConnections() != 0; -#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED - UpdateStatusLED(); -#endif - break; - case DeviceEventType::kThreadStateChange: - sIsThreadProvisioned = ConnectivityMgr().IsThreadProvisioned(); - sIsThreadEnabled = ConnectivityMgr().IsThreadEnabled(); - sIsThreadAttached = ConnectivityMgr().IsThreadAttached(); -#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED - UpdateStatusLED(); -#endif - break; - case DeviceEventType::kThreadConnectivityChange: -#if CONFIG_CHIP_OTA_REQUESTOR - if (event->ThreadConnectivityChange.Result == kConnectivity_Established) - { - InitBasicOTARequestor(); - } -#endif - break; - default: - break; - } -} - -void AppTask::ActionIdentifyStateUpdateHandler(k_timer * timer) -{ - AppEvent event; - event.Type = AppEvent::kEventType_UpdateLedState; - event.Handler = UpdateIdentifyStateEventHandler; - sAppTask.PostEvent(&event); -} - -void AppTask::UpdateIdentifyStateEventHandler(AppEvent * aEvent) -{ - sAppTask.mPwmIdentifyLed.UpdateAction(); -} - void AppTask::LockStateChanged(BoltLockManager::State state, BoltLockManager::OperationSource source) { switch (state) { case BoltLockManager::State::kLockingInitiated: LOG_INF("Lock action initiated"); +#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED sLockLED.Blink(50, 50); +#endif break; case BoltLockManager::State::kLockingCompleted: LOG_INF("Lock action completed"); +#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED sLockLED.Set(true); +#endif break; case BoltLockManager::State::kUnlockingInitiated: LOG_INF("Unlock action initiated"); +#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED sLockLED.Blink(50, 50); +#endif break; case BoltLockManager::State::kUnlockingCompleted: LOG_INF("Unlock action completed"); +#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED sLockLED.Set(false); +#endif break; } @@ -518,26 +106,6 @@ void AppTask::LockStateChanged(BoltLockManager::State state, BoltLockManager::Op sAppTask.UpdateClusterState(state, source); } -void AppTask::PostEvent(AppEvent * aEvent) -{ - if (k_msgq_put(&sAppEventQueue, aEvent, K_NO_WAIT) != 0) - { - LOG_INF("PostEvent fail"); - } -} - -void AppTask::DispatchEvent(AppEvent * aEvent) -{ - if (aEvent->Handler) - { - aEvent->Handler(aEvent); - } - else - { - LOG_INF("Dropping event without handler"); - } -} - void AppTask::UpdateClusterState(BoltLockManager::State state, BoltLockManager::OperationSource source) { DlLockState newLockState; @@ -557,64 +125,21 @@ void AppTask::UpdateClusterState(BoltLockManager::State state, BoltLockManager:: SystemLayer().ScheduleLambda([newLockState, source] { chip::app::DataModel::Nullable currentLockState; - chip::app::Clusters::DoorLock::Attributes::LockState::Get(kLockEndpointId, currentLockState); + chip::app::Clusters::DoorLock::Attributes::LockState::Get(kExampleEndpointId, currentLockState); if (currentLockState.IsNull()) { // Initialize lock state with start value, but not invoke lock/unlock. - chip::app::Clusters::DoorLock::Attributes::LockState::Set(kLockEndpointId, newLockState); + chip::app::Clusters::DoorLock::Attributes::LockState::Set(kExampleEndpointId, newLockState); } else { LOG_INF("Updating LockState attribute"); - if (!DoorLockServer::Instance().SetLockState(kLockEndpointId, newLockState, source)) + if (!DoorLockServer::Instance().SetLockState(kExampleEndpointId, newLockState, source)) { LOG_ERR("Failed to update LockState attribute"); } } }); } - -void AppTask::FactoryResetTimerTimeoutCallback(k_timer * timer) -{ - if (!timer) - { - return; - } - - AppEvent event; - event.Type = AppEvent::kEventType_Timer; - event.Handler = FactoryResetTimerEventHandler; - sAppTask.PostEvent(&event); -} - -void AppTask::FactoryResetTimerEventHandler(AppEvent * aEvent) -{ - if (aEvent->Type != AppEvent::kEventType_Timer) - { - return; - } - - sFactoryResetCntr = 0; - LOG_INF("Factory Reset Trigger Counter is cleared"); -} - -void AppTask::InitButtons(void) -{ -#if CONFIG_CHIP_BUTTON_MANAGER_IRQ_MODE - sFactoryResetButton.Configure(BUTTON_PORT, BUTTON_PIN_1, FactoryResetButtonEventHandler); - sLockButton.Configure(BUTTON_PORT, BUTTON_PIN_2, LockActionButtonEventHandler); - sThreadStartButton.Configure(BUTTON_PORT, BUTTON_PIN_3, StartThreadButtonEventHandler); - sBleAdvStartButton.Configure(BUTTON_PORT, BUTTON_PIN_4, StartBleAdvButtonEventHandler); -#else - sFactoryResetButton.Configure(BUTTON_PORT, BUTTON_PIN_3, BUTTON_PIN_1, FactoryResetButtonEventHandler); - sLockButton.Configure(BUTTON_PORT, BUTTON_PIN_4, BUTTON_PIN_1, LockActionButtonEventHandler); - sThreadStartButton.Configure(BUTTON_PORT, BUTTON_PIN_3, BUTTON_PIN_2, StartThreadButtonEventHandler); - sBleAdvStartButton.Configure(BUTTON_PORT, BUTTON_PIN_4, BUTTON_PIN_2, StartBleAdvButtonEventHandler); -#endif - ButtonManagerInst().AddButton(sFactoryResetButton); - ButtonManagerInst().AddButton(sLockButton); - ButtonManagerInst().AddButton(sThreadStartButton); - ButtonManagerInst().AddButton(sBleAdvStartButton); -} diff --git a/examples/lock-app/telink/src/BoltLockManager.cpp b/examples/lock-app/telink/src/BoltLockManager.cpp index 3abf145f482653..721fb11e427d72 100644 --- a/examples/lock-app/telink/src/BoltLockManager.cpp +++ b/examples/lock-app/telink/src/BoltLockManager.cpp @@ -19,7 +19,7 @@ #include "BoltLockManager.h" #include "AppConfig.h" -#include "AppEvent.h" +#include "AppEventCommon.h" #include "AppTask.h" #include diff --git a/examples/ota-requestor-app/telink/CMakeLists.txt b/examples/ota-requestor-app/telink/CMakeLists.txt index 9b66cd662f85f2..f9dcafa515b74a 100644 --- a/examples/ota-requestor-app/telink/CMakeLists.txt +++ b/examples/ota-requestor-app/telink/CMakeLists.txt @@ -59,6 +59,7 @@ target_include_directories(app PRIVATE include ${GEN_DIR}/app-common ${GEN_DIR}/ota-requestor-app + ${TELINK_COMMON}/common/include ${TELINK_COMMON}/util/include ${TELINK_COMMON}/app/include) @@ -68,8 +69,9 @@ add_definitions( target_sources(app PRIVATE src/AppTask.cpp - src/main.cpp src/ZclCallbacks.cpp + ${TELINK_COMMON}/common/src/mainCommon.cpp + ${TELINK_COMMON}/common/src/AppTaskCommon.cpp ${TELINK_COMMON}/util/src/LEDWidget.cpp ${TELINK_COMMON}/util/src/ButtonManager.cpp ${TELINK_COMMON}/util/src/ThreadUtil.cpp diff --git a/examples/ota-requestor-app/telink/include/AppConfig.h b/examples/ota-requestor-app/telink/include/AppConfig.h index 468e6440d45e3f..ff96590c376749 100644 --- a/examples/ota-requestor-app/telink/include/AppConfig.h +++ b/examples/ota-requestor-app/telink/include/AppConfig.h @@ -20,15 +20,10 @@ // ---- OTA Requestor Example App Config ---- -// Buttons config -#define BUTTON_PORT DEVICE_DT_GET(DT_NODELABEL(gpioc)) +#define APP_USE_EXAMPLE_START_BUTTON 0 +#define APP_USE_THREAD_START_BUTTON 1 +#define APP_SET_DEVICE_INFO_PROVIDER 1 +#define APP_SET_NETWORK_COMM_ENDPOINT_SEC 1 +#define APP_USE_IDENTIFY_PWM 1 // APP_USE_IDENTIFY_PWM must be defined before including "AppConfigCommon.h" -#define BUTTON_PIN_1 2 -#define BUTTON_PIN_3 3 -#define BUTTON_PIN_4 1 -#define BUTTON_PIN_2 0 - -// LEDs config -#define LEDS_PORT DEVICE_DT_GET(DT_NODELABEL(gpiob)) -#define SYSTEM_STATE_LED 7 -#define LIGHTING_PWM_SPEC_IDENTIFY_GREEN PWM_DT_SPEC_GET(DT_ALIAS(pwm_led3)) +#include "AppConfigCommon.h" diff --git a/examples/ota-requestor-app/telink/include/AppTask.h b/examples/ota-requestor-app/telink/include/AppTask.h index 1a0c2aa4698962..24e00675e78472 100755 --- a/examples/ota-requestor-app/telink/include/AppTask.h +++ b/examples/ota-requestor-app/telink/include/AppTask.h @@ -18,74 +18,17 @@ #pragma once -#include "AppEvent.h" -#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED -#include "LEDWidget.h" -#endif -#include "PWMDevice.h" +#include "AppTaskCommon.h" -#include - -#include - -#include - -struct k_timer; -struct Identify; - -class AppTask +class AppTask : public AppTaskCommon { -public: - CHIP_ERROR StartApp(void); - - enum Action_t : uint8_t - { - ON_ACTION = 0, - OFF_ACTION, - LEVEL_ACTION, - - INVALID_ACTION - }; - - void PostLightingActionRequest(Action_t aAction); - void PostEvent(AppEvent * event); - static void IdentifyEffectHandler(EmberAfIdentifyEffectIdentifier aEffect); - private: friend AppTask & GetAppTask(void); - CHIP_ERROR Init(void); - - static void ActionInitiated(AppTask::Action_t aAction, int32_t aActor); - static void ActionCompleted(AppTask::Action_t aAction, int32_t aActor); - static void ActionIdentifyStateUpdateHandler(k_timer * timer); - - void DispatchEvent(AppEvent * event); - -#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED - static void UpdateLedStateEventHandler(AppEvent * aEvent); - static void LEDStateUpdateHandler(LEDWidget * ledWidget); - static void UpdateStatusLED(); -#endif - 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 FactoryResetTimerTimeoutCallback(k_timer * timer); - - static void FactoryResetTimerEventHandler(AppEvent * aEvent); - static void FactoryResetHandler(AppEvent * aEvent); - static void StartThreadHandler(AppEvent * aEvent); - static void StartBleAdvHandler(AppEvent * aEvent); - static void UpdateIdentifyStateEventHandler(AppEvent * aEvent); - - static void InitButtons(void); + friend class AppTaskCommon; - static void ThreadProvisioningHandler(const chip::DeviceLayer::ChipDeviceEvent * event, intptr_t arg); + CHIP_ERROR Init(); static AppTask sAppTask; - PWMDevice mPwmIdentifyLed; }; inline AppTask & GetAppTask(void) diff --git a/examples/ota-requestor-app/telink/prj.conf b/examples/ota-requestor-app/telink/prj.conf index de139770a43d74..79299b61d3ebc6 100755 --- a/examples/ota-requestor-app/telink/prj.conf +++ b/examples/ota-requestor-app/telink/prj.conf @@ -54,6 +54,12 @@ CONFIG_CHIP_DEVICE_SOFTWARE_VERSION_STRING="2022" # Enable CHIP pairing automatically on application start. CONFIG_CHIP_ENABLE_PAIRING_AUTOSTART=y +# Disable factory data support. +CONFIG_CHIP_FACTORY_DATA=n +CONFIG_CHIP_FACTORY_DATA_BUILD=n +CONFIG_CHIP_FACTORY_DATA_MERGE_WITH_FIRMWARE=n +CONFIG_CHIP_CERTIFICATION_DECLARATION_STORAGE=n + # CHIP shell CONFIG_CHIP_LIB_SHELL=n diff --git a/examples/ota-requestor-app/telink/src/AppTask.cpp b/examples/ota-requestor-app/telink/src/AppTask.cpp index 8cc0cea6e3992d..1742873befdf66 100644 --- a/examples/ota-requestor-app/telink/src/AppTask.cpp +++ b/examples/ota-requestor-app/telink/src/AppTask.cpp @@ -18,501 +18,20 @@ #include "AppTask.h" -#include "AppConfig.h" -#include "AppEvent.h" -#include "ButtonManager.h" - -#include "ThreadUtil.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if CONFIG_CHIP_OTA_REQUESTOR -#include "OTAUtil.h" -#endif - -#include -#include - -#include - -#if CONFIG_CHIP_LIB_SHELL -#include -#include - -static int cmd_telink_reboot(const struct shell * shell, size_t argc, char ** argv) -{ - ARG_UNUSED(argc); - ARG_UNUSED(argv); - - shell_print(shell, "Performing board reboot..."); - sys_reboot(); -} - -SHELL_STATIC_SUBCMD_SET_CREATE(sub_telink, SHELL_CMD(reboot, NULL, "Reboot board command", cmd_telink_reboot), - SHELL_SUBCMD_SET_END); -SHELL_CMD_REGISTER(telink, &sub_telink, "Telink commands", NULL); -#endif // CONFIG_CHIP_LIB_SHELL - LOG_MODULE_DECLARE(app, CONFIG_CHIP_APP_LOG_LEVEL); -using namespace ::chip; -using namespace ::chip::app; -using namespace ::chip::Credentials; -using namespace ::chip::DeviceLayer; - -namespace { -constexpr int kFactoryResetCalcTimeout = 3000; -constexpr int kFactoryResetTriggerCntr = 3; -constexpr int kAppEventQueueSize = 10; -constexpr uint8_t kButtonPushEvent = 1; -constexpr uint8_t kButtonReleaseEvent = 0; -constexpr EndpointId kEndpointId = 1; -constexpr uint8_t kDefaultMinLevel = 0; -constexpr uint8_t kDefaultMaxLevel = 254; -constexpr uint32_t kIdentifyBlinkRateMs = 200; -constexpr uint32_t kIdentifyOkayOnRateMs = 50; -constexpr uint32_t kIdentifyOkayOffRateMs = 950; -constexpr uint32_t kIdentifyFinishOnRateMs = 950; -constexpr uint32_t kIdentifyFinishOffRateMs = 50; -constexpr uint32_t kIdentifyChannelChangeRateMs = 1000; -constexpr uint32_t kIdentifyBreatheRateMs = 1000; - -const struct pwm_dt_spec sPwmIdentifySpecGreenLed = LIGHTING_PWM_SPEC_IDENTIFY_GREEN; - -K_MSGQ_DEFINE(sAppEventQueue, sizeof(AppEvent), kAppEventQueueSize, alignof(AppEvent)); -k_timer sFactoryResetTimer; -uint8_t sFactoryResetCntr = 0; - -#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED -LEDWidget sStatusLED; -#endif - -Button sFactoryResetButton; -Button sThreadStartButton; -Button sBleAdvStartButton; - -bool sIsThreadProvisioned = false; -bool sIsThreadEnabled = false; -bool sIsThreadAttached = false; -bool sHaveBLEConnections = false; - -chip::DeviceLayer::DeviceInfoProviderImpl gExampleDeviceInfoProvider; - -void OnIdentifyTriggerEffect(Identify * identify) -{ - AppTask::IdentifyEffectHandler(identify->mCurrentEffectIdentifier); -} - -Identify sIdentify = { - kEndpointId, - [](Identify *) { ChipLogProgress(Zcl, "OnIdentifyStart"); }, - [](Identify *) { ChipLogProgress(Zcl, "OnIdentifyStop"); }, - EMBER_ZCL_IDENTIFY_IDENTIFY_TYPE_VISIBLE_LED, - OnIdentifyTriggerEffect, -}; - -} // namespace - AppTask AppTask::sAppTask; -class AppFabricTableDelegate : public FabricTable::Delegate -{ - void OnFabricRemoved(const FabricTable & fabricTable, FabricIndex fabricIndex) - { - if (chip::Server::GetInstance().GetFabricTable().FabricCount() == 0) - { - chip::Server::GetInstance().ScheduleFactoryReset(); - } - } -}; - -constexpr EndpointId kNetworkCommissioningEndpointSecondary = 0xFFFE; - CHIP_ERROR AppTask::Init(void) { - LOG_INF("SW Version: %u, %s", CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION, CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING); - - // Initialize LEDs -#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED - LEDWidget::InitGpio(LEDS_PORT); - LEDWidget::SetStateUpdateCallback(LEDStateUpdateHandler); - sStatusLED.Init(SYSTEM_STATE_LED); - - UpdateStatusLED(); -#endif - - InitButtons(); - - // Initialize function button timer - k_timer_init(&sFactoryResetTimer, &AppTask::FactoryResetTimerTimeoutCallback, nullptr); - k_timer_user_data_set(&sFactoryResetTimer, this); - - // Init ZCL Data Model and start server - static chip::CommonCaseDeviceServerInitParams initParams; - (void) initParams.InitializeStaticResourcesBeforeServerInit(); - chip::Server::GetInstance().Init(initParams); - - // Initialize PWM Identify led - CHIP_ERROR err = sAppTask.mPwmIdentifyLed.Init(&sPwmIdentifySpecGreenLed, kDefaultMinLevel, kDefaultMaxLevel, kDefaultMaxLevel); - if (err != CHIP_NO_ERROR) - { - LOG_ERR("Green IDENTIFY PWM Device Init fail"); - return err; - } - - sAppTask.mPwmIdentifyLed.SetCallbacks(nullptr, nullptr, ActionIdentifyStateUpdateHandler); - - // We only have network commissioning on endpoint 0. - // Set up a valid Network Commissioning cluster on endpoint 0 is done in - // src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.cpp - emberAfEndpointEnableDisable(kNetworkCommissioningEndpointSecondary, false); + InitCommonParts(); - // Initialize device attestation config - SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); - - gExampleDeviceInfoProvider.SetStorageDelegate(&chip::Server::GetInstance().GetPersistentStorage()); - chip::DeviceLayer::SetDeviceInfoProvider(&gExampleDeviceInfoProvider); - -#if CONFIG_CHIP_OTA_REQUESTOR - InitBasicOTARequestor(); -#endif - - 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); - - err = ConnectivityMgr().SetBLEDeviceName("TelinkOTAReq"); + CHIP_ERROR err = ConnectivityMgr().SetBLEDeviceName("TelinkOTAReq"); if (err != CHIP_NO_ERROR) { LOG_ERR("SetBLEDeviceName fail"); return err; } - err = chip::Server::GetInstance().GetFabricTable().AddFabricDelegate(new AppFabricTableDelegate); - if (err != CHIP_NO_ERROR) - { - LOG_ERR("AppFabricTableDelegate fail"); - return err; - } - return CHIP_NO_ERROR; } - -CHIP_ERROR AppTask::StartApp(void) -{ - CHIP_ERROR err = Init(); - - if (err != CHIP_NO_ERROR) - { - LOG_ERR("AppTask Init fail"); - return err; - } - - AppEvent event = {}; - - while (true) - { - k_msgq_get(&sAppEventQueue, &event, K_FOREVER); - DispatchEvent(&event); - } -} - -void AppTask::IdentifyEffectHandler(EmberAfIdentifyEffectIdentifier aEffect) -{ - AppEvent event; - event.Type = AppEvent::kEventType_IdentifyStart; - - switch (aEffect) - { - case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BLINK: - ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BLINK"); - event.Handler = [](AppEvent *) { - sAppTask.mPwmIdentifyLed.InitiateBlinkAction(kIdentifyBlinkRateMs, kIdentifyBlinkRateMs); - }; - break; - case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BREATHE: - ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BREATHE"); - event.Handler = [](AppEvent *) { - sAppTask.mPwmIdentifyLed.InitiateBreatheAction(PWMDevice::kBreatheType_Both, kIdentifyBreatheRateMs); - }; - break; - case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_OKAY: - ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_OKAY"); - event.Handler = [](AppEvent *) { - sAppTask.mPwmIdentifyLed.InitiateBlinkAction(kIdentifyOkayOnRateMs, kIdentifyOkayOffRateMs); - }; - break; - case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_CHANNEL_CHANGE: - ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_CHANNEL_CHANGE"); - event.Handler = [](AppEvent *) { - sAppTask.mPwmIdentifyLed.InitiateBlinkAction(kIdentifyChannelChangeRateMs, kIdentifyChannelChangeRateMs); - }; - break; - case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_FINISH_EFFECT: - ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_FINISH_EFFECT"); - event.Handler = [](AppEvent *) { - sAppTask.mPwmIdentifyLed.InitiateBlinkAction(kIdentifyFinishOnRateMs, kIdentifyFinishOffRateMs); - }; - break; - case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_STOP_EFFECT: - ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_STOP_EFFECT"); - event.Handler = [](AppEvent *) { sAppTask.mPwmIdentifyLed.StopAction(); }; - event.Type = AppEvent::kEventType_IdentifyStop; - break; - default: - ChipLogProgress(Zcl, "No identifier effect"); - return; - } - - sAppTask.PostEvent(&event); -} - -void AppTask::FactoryResetButtonEventHandler(void) -{ - AppEvent event; - - event.Type = AppEvent::kEventType_Button; - event.ButtonEvent.Action = kButtonPushEvent; - event.Handler = FactoryResetHandler; - sAppTask.PostEvent(&event); -} - -void AppTask::FactoryResetHandler(AppEvent * aEvent) -{ - if (sFactoryResetCntr == 0) - { - k_timer_start(&sFactoryResetTimer, K_MSEC(kFactoryResetCalcTimeout), K_NO_WAIT); - } - - sFactoryResetCntr++; - LOG_INF("Factory Reset Trigger Counter: %d/%d", sFactoryResetCntr, kFactoryResetTriggerCntr); - - if (sFactoryResetCntr == kFactoryResetTriggerCntr) - { - k_timer_stop(&sFactoryResetTimer); - sFactoryResetCntr = 0; - - chip::Server::GetInstance().ScheduleFactoryReset(); - } -} - -void AppTask::StartThreadButtonEventHandler(void) -{ - AppEvent event; - - event.Type = AppEvent::kEventType_Button; - event.ButtonEvent.Action = kButtonPushEvent; - event.Handler = StartThreadHandler; - sAppTask.PostEvent(&event); -} - -void AppTask::StartThreadHandler(AppEvent * aEvent) -{ - LOG_INF("StartThreadHandler"); - if (!chip::DeviceLayer::ConnectivityMgr().IsThreadProvisioned()) - { - // Switch context from BLE to Thread - Internal::BLEManagerImpl sInstance; - sInstance.SwitchToIeee802154(); - StartDefaultThreadNetwork(); - } - else - { - LOG_INF("Device already commissioned"); - } -} - -void AppTask::StartBleAdvButtonEventHandler(void) -{ - AppEvent event; - - event.Type = AppEvent::kEventType_Button; - event.ButtonEvent.Action = kButtonPushEvent; - event.Handler = StartBleAdvHandler; - sAppTask.PostEvent(&event); -} - -void AppTask::StartBleAdvHandler(AppEvent * aEvent) -{ - LOG_INF("StartBleAdvHandler"); - - // Don't allow on starting Matter service BLE advertising after Thread provisioning. - if (ConnectivityMgr().IsThreadProvisioned()) - { - LOG_INF("Device already commissioned"); - return; - } - - if (ConnectivityMgr().IsBLEAdvertisingEnabled()) - { - LOG_INF("BLE adv already enabled"); - return; - } - - if (chip::Server::GetInstance().GetCommissioningWindowManager().OpenBasicCommissioningWindow() != CHIP_NO_ERROR) - { - LOG_ERR("OpenBasicCommissioningWindow fail"); - } -} - -#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED -void AppTask::UpdateLedStateEventHandler(AppEvent * aEvent) -{ - if (aEvent->Type == AppEvent::kEventType_UpdateLedState) - { - aEvent->UpdateLedStateEvent.LedWidget->UpdateState(); - } -} - -void AppTask::LEDStateUpdateHandler(LEDWidget * ledWidget) -{ - AppEvent event; - event.Type = AppEvent::kEventType_UpdateLedState; - event.Handler = UpdateLedStateEventHandler; - event.UpdateLedStateEvent.LedWidget = ledWidget; - sAppTask.PostEvent(&event); -} - -void AppTask::UpdateStatusLED(void) -{ - if (sIsThreadProvisioned && sIsThreadEnabled) - { - if (sIsThreadAttached) - { - sStatusLED.Blink(950, 50); - } - else - { - sStatusLED.Blink(100, 100); - } - } - else - { - sStatusLED.Blink(50, 950); - } -} -#endif - -void AppTask::ChipEventHandler(const ChipDeviceEvent * event, intptr_t /* arg */) -{ - switch (event->Type) - { - case DeviceEventType::kCHIPoBLEAdvertisingChange: - sHaveBLEConnections = ConnectivityMgr().NumBLEConnections() != 0; -#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED - UpdateStatusLED(); -#endif - break; - case DeviceEventType::kThreadStateChange: - sIsThreadProvisioned = ConnectivityMgr().IsThreadProvisioned(); - sIsThreadEnabled = ConnectivityMgr().IsThreadEnabled(); - sIsThreadAttached = ConnectivityMgr().IsThreadAttached(); -#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED - UpdateStatusLED(); -#endif - break; - case DeviceEventType::kThreadConnectivityChange: -#if CONFIG_CHIP_OTA_REQUESTOR - if (event->ThreadConnectivityChange.Result == kConnectivity_Established) - { - InitBasicOTARequestor(); - } -#endif - break; - default: - break; - } -} - -void AppTask::ActionIdentifyStateUpdateHandler(k_timer * timer) -{ - AppEvent event; - event.Type = AppEvent::kEventType_UpdateLedState; - event.Handler = UpdateIdentifyStateEventHandler; - sAppTask.PostEvent(&event); -} - -void AppTask::UpdateIdentifyStateEventHandler(AppEvent * aEvent) -{ - sAppTask.mPwmIdentifyLed.UpdateAction(); -} - -void AppTask::ActionInitiated(AppTask::Action_t aAction, int32_t aActor) {} - -void AppTask::ActionCompleted(AppTask::Action_t aAction, int32_t aActor) {} - -void AppTask::PostEvent(AppEvent * aEvent) -{ - if (k_msgq_put(&sAppEventQueue, aEvent, K_NO_WAIT) != 0) - { - LOG_INF("PostEvent fail"); - } -} - -void AppTask::DispatchEvent(AppEvent * aEvent) -{ - if (aEvent->Handler) - { - aEvent->Handler(aEvent); - } - else - { - LOG_INF("Dropping event without handler"); - } -} - -void AppTask::FactoryResetTimerTimeoutCallback(k_timer * timer) -{ - if (!timer) - { - return; - } - - AppEvent event; - event.Type = AppEvent::kEventType_Timer; - event.Handler = FactoryResetTimerEventHandler; - sAppTask.PostEvent(&event); -} - -void AppTask::FactoryResetTimerEventHandler(AppEvent * aEvent) -{ - if (aEvent->Type != AppEvent::kEventType_Timer) - { - return; - } - - sFactoryResetCntr = 0; - LOG_INF("Factory Reset Trigger Counter is cleared"); -} - -void AppTask::InitButtons(void) -{ -#if CONFIG_CHIP_BUTTON_MANAGER_IRQ_MODE - sFactoryResetButton.Configure(BUTTON_PORT, BUTTON_PIN_1, FactoryResetButtonEventHandler); - sThreadStartButton.Configure(BUTTON_PORT, BUTTON_PIN_3, StartThreadButtonEventHandler); - sBleAdvStartButton.Configure(BUTTON_PORT, BUTTON_PIN_4, StartBleAdvButtonEventHandler); -#else - sFactoryResetButton.Configure(BUTTON_PORT, BUTTON_PIN_3, BUTTON_PIN_1, FactoryResetButtonEventHandler); - sThreadStartButton.Configure(BUTTON_PORT, BUTTON_PIN_3, BUTTON_PIN_2, StartThreadButtonEventHandler); - sBleAdvStartButton.Configure(BUTTON_PORT, BUTTON_PIN_4, BUTTON_PIN_2, StartBleAdvButtonEventHandler); -#endif - - ButtonManagerInst().AddButton(sFactoryResetButton); - ButtonManagerInst().AddButton(sThreadStartButton); - ButtonManagerInst().AddButton(sBleAdvStartButton); -} diff --git a/examples/ota-requestor-app/telink/src/main.cpp b/examples/ota-requestor-app/telink/src/main.cpp deleted file mode 100644 index dc8216db43d274..00000000000000 --- a/examples/ota-requestor-app/telink/src/main.cpp +++ /dev/null @@ -1,82 +0,0 @@ -/* - * - * Copyright (c) 2022-2023 Project CHIP Authors - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "AppTask.h" - -#include -#include - -#include - -LOG_MODULE_REGISTER(app, CONFIG_CHIP_APP_LOG_LEVEL); - -using namespace ::chip; -using namespace ::chip::Inet; -using namespace ::chip::DeviceLayer; - -int main(void) -{ - CHIP_ERROR err = CHIP_NO_ERROR; - - err = chip::Platform::MemoryInit(); - if (err != CHIP_NO_ERROR) - { - LOG_ERR("MemoryInit fail"); - goto exit; - } - - err = PlatformMgr().InitChipStack(); - if (err != CHIP_NO_ERROR) - { - LOG_ERR("InitChipStack fail"); - goto exit; - } - - err = PlatformMgr().StartEventLoopTask(); - if (err != CHIP_NO_ERROR) - { - LOG_ERR("StartEventLoopTask fail"); - goto exit; - } - - err = ThreadStackMgr().InitThreadStack(); - if (err != CHIP_NO_ERROR) - { - LOG_ERR("InitThreadStack fail"); - goto exit; - } - -#ifdef CONFIG_OPENTHREAD_MTD_SED - err = ConnectivityMgr().SetThreadDeviceType(ConnectivityManager::kThreadDeviceType_SleepyEndDevice); -#elif CONFIG_OPENTHREAD_MTD - err = ConnectivityMgr().SetThreadDeviceType(ConnectivityManager::kThreadDeviceType_MinimalEndDevice); -#else - err = ConnectivityMgr().SetThreadDeviceType(ConnectivityManager::kThreadDeviceType_Router); -#endif - if (err != CHIP_NO_ERROR) - { - LOG_ERR("SetThreadDeviceType fail"); - goto exit; - } - - err = GetAppTask().StartApp(); - -exit: - LOG_ERR("Exit err %" CHIP_ERROR_FORMAT, err.Format()); - return (err == CHIP_NO_ERROR) ? EXIT_SUCCESS : EXIT_FAILURE; -} diff --git a/examples/all-clusters-minimal-app/telink/include/AppEvent.h b/examples/platform/telink/common/include/AppConfigCommon.h old mode 100644 new mode 100755 similarity index 51% rename from examples/all-clusters-minimal-app/telink/include/AppEvent.h rename to examples/platform/telink/common/include/AppConfigCommon.h index 54250995e06ca8..6af3da6bb213cc --- a/examples/all-clusters-minimal-app/telink/include/AppEvent.h +++ b/examples/platform/telink/common/include/AppConfigCommon.h @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2022 Project CHIP Authors + * Copyright (c) 2022-2023 Project CHIP Authors * All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -18,39 +18,17 @@ #pragma once -#include +// Buttons config +#define BUTTON_PORT DEVICE_DT_GET(DT_NODELABEL(gpioc)) -struct AppEvent; -typedef void (*EventHandler)(AppEvent *); +#define BUTTON_PIN_1 2 +#define BUTTON_PIN_3 3 +#define BUTTON_PIN_4 1 +#define BUTTON_PIN_2 0 -class LEDWidget; - -struct AppEvent -{ - enum AppEventTypes - { - kEventType_Button = 0, - kEventType_Timer, - kEventType_UpdateLedState, - }; - - uint16_t Type; - - union - { - struct - { - uint8_t Action; - } ButtonEvent; - struct - { - void * Context; - } TimerEvent; - struct - { - LEDWidget * LedWidget; - } UpdateLedStateEvent; - }; - - EventHandler Handler; -}; +// LEDs config +#define LEDS_PORT DEVICE_DT_GET(DT_NODELABEL(gpiob)) +#define SYSTEM_STATE_LED 7 +#if APP_USE_IDENTIFY_PWM +#define LIGHTING_PWM_SPEC_IDENTIFY_GREEN PWM_DT_SPEC_GET(DT_ALIAS(pwm_led3)) +#endif diff --git a/examples/ota-requestor-app/telink/include/AppEvent.h b/examples/platform/telink/common/include/AppEventCommon.h similarity index 84% rename from examples/ota-requestor-app/telink/include/AppEvent.h rename to examples/platform/telink/common/include/AppEventCommon.h index 72554b4bb54b5a..0110cd3c840e63 100644 --- a/examples/ota-requestor-app/telink/include/AppEvent.h +++ b/examples/platform/telink/common/include/AppEventCommon.h @@ -35,7 +35,10 @@ struct AppEvent kEventType_IdentifyStart, kEventType_IdentifyStop, kEventType_Lighting, + kEventType_Thermostat, kEventType_Install, + kEventType_Contact, + kEventType_Start, }; uint16_t Type; @@ -56,6 +59,15 @@ struct AppEvent int32_t Actor; } LightingEvent; struct + { + uint8_t Action; + } ContactEvent; + struct + { + uint8_t Action; + int32_t Actor; + } StartEvent; + struct { LEDWidget * LedWidget; } UpdateLedStateEvent; diff --git a/examples/platform/telink/common/include/AppTaskCommon.h b/examples/platform/telink/common/include/AppTaskCommon.h new file mode 100644 index 00000000000000..772e2255170890 --- /dev/null +++ b/examples/platform/telink/common/include/AppTaskCommon.h @@ -0,0 +1,113 @@ +/* + * + * Copyright (c) 2022-2023 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include "AppConfig.h" +#include "AppEventCommon.h" + +#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED +#include "LEDWidget.h" +#endif + +#if APP_USE_IDENTIFY_PWM +#include "PWMDevice.h" +#endif + +#include +#include +#include + +#include + +#if CONFIG_CHIP_FACTORY_DATA +#include +#endif + +#include + +#include + +using namespace ::chip; +using namespace ::chip::app; +using namespace ::chip::Credentials; +using namespace ::chip::DeviceLayer; + +namespace { +constexpr EndpointId kExampleEndpointId = 1; +constexpr uint8_t kDefaultMinLevel = 0; +constexpr uint8_t kDefaultMaxLevel = 254; +constexpr uint8_t kButtonPushEvent = 1; +constexpr uint8_t kButtonReleaseEvent = 0; +} // namespace + +class AppTaskCommon +{ +public: + CHIP_ERROR StartApp(); + void PostEvent(AppEvent * event); + + static void IdentifyEffectHandler(EmberAfIdentifyEffectIdentifier aEffect); + +protected: + CHIP_ERROR InitCommonParts(void); + + void DispatchEvent(AppEvent * event); + void GetEvent(AppEvent * aEvent); + + void InitButtons(void); + + static void FactoryResetTimerTimeoutCallback(k_timer * timer); + static void FactoryResetTimerEventHandler(AppEvent * aEvent); + static void FactoryResetButtonEventHandler(void); + static void FactoryResetHandler(AppEvent * aEvent); + + static void StartBleAdvButtonEventHandler(void); + static void StartBleAdvHandler(AppEvent * aEvent); + +#if APP_USE_THREAD_START_BUTTON + static void StartThreadButtonEventHandler(void); + static void StartThreadHandler(AppEvent * aEvent); +#endif + +#if APP_USE_EXAMPLE_START_BUTTON + static void ExampleActionButtonEventHandler(void); + + void SetExampleButtonCallbacks(EventHandler aAction_CB); + EventHandler ExampleActionEventHandler; +#endif + + static void ChipEventHandler(const chip::DeviceLayer::ChipDeviceEvent * event, intptr_t arg); + +#if APP_USE_IDENTIFY_PWM + PWMDevice mPwmIdentifyLed; + + static void ActionIdentifyStateUpdateHandler(k_timer * timer); + static void UpdateIdentifyStateEventHandler(AppEvent * aEvent); +#endif + +#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED + static void UpdateLedStateEventHandler(AppEvent * aEvent); + static void LEDStateUpdateHandler(LEDWidget * ledWidget); + static void UpdateStatusLED(void); +#endif + +#if CONFIG_CHIP_FACTORY_DATA + chip::DeviceLayer::FactoryDataProvider mFactoryDataProvider; +#endif +}; diff --git a/examples/platform/telink/common/src/AppTaskCommon.cpp b/examples/platform/telink/common/src/AppTaskCommon.cpp new file mode 100644 index 00000000000000..37e8bf36d4846a --- /dev/null +++ b/examples/platform/telink/common/src/AppTaskCommon.cpp @@ -0,0 +1,583 @@ +/* + * + * Copyright (c) 2022-2023 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "AppTaskCommon.h" +#include "AppTask.h" + +#include "ButtonManager.h" + +#include "ThreadUtil.h" + +#include +#include +#include +#include +#include + +#if CONFIG_CHIP_OTA_REQUESTOR +#include "OTAUtil.h" +#endif + +LOG_MODULE_DECLARE(app, CONFIG_CHIP_APP_LOG_LEVEL); + +namespace { +constexpr int kFactoryResetCalcTimeout = 3000; +constexpr int kFactoryResetTriggerCntr = 3; +constexpr int kAppEventQueueSize = 10; + +#if APP_USE_IDENTIFY_PWM +constexpr uint32_t kIdentifyBlinkRateMs = 200; +constexpr uint32_t kIdentifyOkayOnRateMs = 50; +constexpr uint32_t kIdentifyOkayOffRateMs = 950; +constexpr uint32_t kIdentifyFinishOnRateMs = 950; +constexpr uint32_t kIdentifyFinishOffRateMs = 50; +constexpr uint32_t kIdentifyChannelChangeRateMs = 1000; +constexpr uint32_t kIdentifyBreatheRateMs = 1000; + +const struct pwm_dt_spec sPwmIdentifySpecGreenLed = LIGHTING_PWM_SPEC_IDENTIFY_GREEN; +#endif + +#if APP_SET_NETWORK_COMM_ENDPOINT_SEC +constexpr EndpointId kNetworkCommissioningEndpointSecondary = 0xFFFE; +#endif + +K_MSGQ_DEFINE(sAppEventQueue, sizeof(AppEvent), kAppEventQueueSize, alignof(AppEvent)); + +#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED +LEDWidget sStatusLED; +#endif + +Button sFactoryResetButton; +Button sBleAdvStartButton; +#if APP_USE_EXAMPLE_START_BUTTON +Button sExampleActionButton; +#endif +#if APP_USE_THREAD_START_BUTTON +Button sThreadStartButton; +#endif + +k_timer sFactoryResetTimer; +uint8_t sFactoryResetCntr = 0; + +bool sIsThreadProvisioned = false; +bool sIsThreadEnabled = false; +bool sIsThreadAttached = false; +bool sHaveBLEConnections = false; + +#if APP_SET_DEVICE_INFO_PROVIDER +chip::DeviceLayer::DeviceInfoProviderImpl gExampleDeviceInfoProvider; +#endif + +#if APP_USE_IDENTIFY_PWM +void OnIdentifyTriggerEffect(Identify * identify) +{ + AppTaskCommon::IdentifyEffectHandler(identify->mCurrentEffectIdentifier); +} + +Identify sIdentify = { + kExampleEndpointId, + [](Identify *) { ChipLogProgress(Zcl, "OnIdentifyStart"); }, + [](Identify *) { ChipLogProgress(Zcl, "OnIdentifyStop"); }, + EMBER_ZCL_IDENTIFY_IDENTIFY_TYPE_VISIBLE_LED, + OnIdentifyTriggerEffect, +}; +#endif + +#if CONFIG_CHIP_FACTORY_DATA +// NOTE! This key is for test/certification only and should not be available in production devices! +uint8_t sTestEventTriggerEnableKey[TestEventTriggerDelegate::kEnableKeyLength] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }; +#endif +} // namespace + +class AppFabricTableDelegate : public FabricTable::Delegate +{ + void OnFabricRemoved(const FabricTable & fabricTable, FabricIndex fabricIndex) + { + if (chip::Server::GetInstance().GetFabricTable().FabricCount() == 0) + { + chip::Server::GetInstance().ScheduleFactoryReset(); + } + } +}; + +#if CONFIG_CHIP_LIB_SHELL +#include +#include + +static int cmd_telink_reboot(const struct shell * shell, size_t argc, char ** argv) +{ + ARG_UNUSED(argc); + ARG_UNUSED(argv); + + shell_print(shell, "Performing board reboot..."); + sys_reboot(); +} + +SHELL_STATIC_SUBCMD_SET_CREATE(sub_telink, SHELL_CMD(reboot, NULL, "Reboot board command", cmd_telink_reboot), + SHELL_SUBCMD_SET_END); +SHELL_CMD_REGISTER(telink, &sub_telink, "Telink commands", NULL); +#endif // CONFIG_CHIP_LIB_SHELL + +CHIP_ERROR AppTaskCommon::StartApp(void) +{ + CHIP_ERROR err = GetAppTask().Init(); + + if (err != CHIP_NO_ERROR) + { + LOG_ERR("AppTask Init fail"); + return err; + } + + AppEvent event = {}; + + while (true) + { + GetEvent(&event); + DispatchEvent(&event); + } +} + +CHIP_ERROR AppTaskCommon::InitCommonParts(void) +{ + CHIP_ERROR err; + LOG_INF("SW Version: %u, %s", CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION, CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING); + + // Initialize status LED +#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED + LEDWidget::InitGpio(LEDS_PORT); + LEDWidget::SetStateUpdateCallback(LEDStateUpdateHandler); + sStatusLED.Init(SYSTEM_STATE_LED); + + UpdateStatusLED(); +#endif + + InitButtons(); + + // Initialize function button timer + k_timer_init(&sFactoryResetTimer, &AppTask::FactoryResetTimerTimeoutCallback, nullptr); + k_timer_user_data_set(&sFactoryResetTimer, this); + +#if APP_USE_IDENTIFY_PWM + // Initialize PWM Identify led + err = GetAppTask().mPwmIdentifyLed.Init(&sPwmIdentifySpecGreenLed, kDefaultMinLevel, kDefaultMaxLevel, kDefaultMaxLevel); + if (err != CHIP_NO_ERROR) + { + LOG_ERR("Green IDENTIFY PWM Device Init fail"); + return err; + } + + GetAppTask().mPwmIdentifyLed.SetCallbacks(nullptr, nullptr, ActionIdentifyStateUpdateHandler); +#endif + + // Initialize CHIP server +#if CONFIG_CHIP_FACTORY_DATA + ReturnErrorOnFailure(mFactoryDataProvider.Init()); + SetDeviceInstanceInfoProvider(&mFactoryDataProvider); + SetDeviceAttestationCredentialsProvider(&mFactoryDataProvider); + SetCommissionableDataProvider(&mFactoryDataProvider); + // Read EnableKey from the factory data. + MutableByteSpan enableKey(sTestEventTriggerEnableKey); + err = mFactoryDataProvider.GetEnableKey(enableKey); + if (err != CHIP_NO_ERROR) + { + LOG_ERR("mFactoryDataProvider.GetEnableKey() failed. Could not delegate a test event trigger"); + memset(sTestEventTriggerEnableKey, 0, sizeof(sTestEventTriggerEnableKey)); + } +#else + SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); +#endif + + // Init ZCL Data Model and start server + static CommonCaseDeviceServerInitParams initParams; + (void) initParams.InitializeStaticResourcesBeforeServerInit(); + ReturnErrorOnFailure(chip::Server::GetInstance().Init(initParams)); + +#if APP_SET_DEVICE_INFO_PROVIDER + gExampleDeviceInfoProvider.SetStorageDelegate(&Server::GetInstance().GetPersistentStorage()); + chip::DeviceLayer::SetDeviceInfoProvider(&gExampleDeviceInfoProvider); +#endif + +#if CONFIG_CHIP_OTA_REQUESTOR + InitBasicOTARequestor(); +#endif + + ConfigurationMgr().LogDeviceConfig(); + PrintOnboardingCodes(chip::RendezvousInformationFlags(chip::RendezvousInformationFlag::kBLE)); + +#if APP_SET_NETWORK_COMM_ENDPOINT_SEC + // We only have network commissioning on endpoint 0. + // Set up a valid Network Commissioning cluster on endpoint 0 is done in + // src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.cpp + emberAfEndpointEnableDisable(kNetworkCommissioningEndpointSecondary, false); +#endif + + // 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); + + err = chip::Server::GetInstance().GetFabricTable().AddFabricDelegate(new AppFabricTableDelegate); + if (err != CHIP_NO_ERROR) + { + LOG_ERR("AppFabricTableDelegate fail"); + return err; + } + + return CHIP_NO_ERROR; +} + +void AppTaskCommon::InitButtons(void) +{ +#if CONFIG_CHIP_BUTTON_MANAGER_IRQ_MODE + sFactoryResetButton.Configure(BUTTON_PORT, BUTTON_PIN_1, FactoryResetButtonEventHandler); + sBleAdvStartButton.Configure(BUTTON_PORT, BUTTON_PIN_4, StartBleAdvButtonEventHandler); +#if APP_USE_THREAD_START_BUTTON + sThreadStartButton.Configure(BUTTON_PORT, BUTTON_PIN_3, StartThreadButtonEventHandler); +#endif +#if APP_USE_EXAMPLE_START_BUTTON + if (ExampleActionEventHandler) + { + sExampleActionButton.Configure(BUTTON_PORT, BUTTON_PIN_2, ExampleActionButtonEventHandler); + } +#endif +#else + sFactoryResetButton.Configure(BUTTON_PORT, BUTTON_PIN_3, BUTTON_PIN_1, FactoryResetButtonEventHandler); + sBleAdvStartButton.Configure(BUTTON_PORT, BUTTON_PIN_4, BUTTON_PIN_2, StartBleAdvButtonEventHandler); +#if APP_USE_THREAD_START_BUTTON + sThreadStartButton.Configure(BUTTON_PORT, BUTTON_PIN_3, BUTTON_PIN_2, StartThreadButtonEventHandler); +#endif +#if APP_USE_EXAMPLE_START_BUTTON + if (ExampleActionEventHandler) + { + sExampleActionButton.Configure(BUTTON_PORT, BUTTON_PIN_4, BUTTON_PIN_1, ExampleActionButtonEventHandler); + } +#endif +#endif + + ButtonManagerInst().AddButton(sFactoryResetButton); + ButtonManagerInst().AddButton(sBleAdvStartButton); +#if APP_USE_THREAD_START_BUTTON + ButtonManagerInst().AddButton(sThreadStartButton); +#endif +#if APP_USE_EXAMPLE_START_BUTTON + if (ExampleActionEventHandler) + { + ButtonManagerInst().AddButton(sExampleActionButton); + } +#endif +} + +#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED +void AppTaskCommon::UpdateLedStateEventHandler(AppEvent * aEvent) +{ + if (aEvent->Type == AppEvent::kEventType_UpdateLedState) + { + aEvent->UpdateLedStateEvent.LedWidget->UpdateState(); + } +} + +void AppTaskCommon::LEDStateUpdateHandler(LEDWidget * ledWidget) +{ + AppEvent event; + event.Type = AppEvent::kEventType_UpdateLedState; + event.Handler = UpdateLedStateEventHandler; + event.UpdateLedStateEvent.LedWidget = ledWidget; + GetAppTask().PostEvent(&event); +} + +void AppTaskCommon::UpdateStatusLED() +{ + if (sIsThreadProvisioned && sIsThreadEnabled) + { + if (sIsThreadAttached) + { + sStatusLED.Blink(950, 50); + } + else + { + sStatusLED.Blink(100, 100); + } + } + else + { + sStatusLED.Blink(50, 950); + } +} +#endif + +#if APP_USE_IDENTIFY_PWM +void AppTaskCommon::ActionIdentifyStateUpdateHandler(k_timer * timer) +{ + AppEvent event; + event.Type = AppEvent::kEventType_UpdateLedState; + event.Handler = UpdateIdentifyStateEventHandler; + GetAppTask().PostEvent(&event); +} + +void AppTaskCommon::UpdateIdentifyStateEventHandler(AppEvent * aEvent) +{ + GetAppTask().mPwmIdentifyLed.UpdateAction(); +} + +void AppTaskCommon::IdentifyEffectHandler(EmberAfIdentifyEffectIdentifier aEffect) +{ + AppEvent event; + event.Type = AppEvent::kEventType_IdentifyStart; + + switch (aEffect) + { + case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BLINK: + ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BLINK"); + event.Handler = [](AppEvent *) { + GetAppTask().mPwmIdentifyLed.InitiateBlinkAction(kIdentifyBlinkRateMs, kIdentifyBlinkRateMs); + }; + break; + case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BREATHE: + ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BREATHE"); + event.Handler = [](AppEvent *) { + GetAppTask().mPwmIdentifyLed.InitiateBreatheAction(PWMDevice::kBreatheType_Both, kIdentifyBreatheRateMs); + }; + break; + case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_OKAY: + ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_OKAY"); + event.Handler = [](AppEvent *) { + GetAppTask().mPwmIdentifyLed.InitiateBlinkAction(kIdentifyOkayOnRateMs, kIdentifyOkayOffRateMs); + }; + break; + case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_CHANNEL_CHANGE: + ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_CHANNEL_CHANGE"); + event.Handler = [](AppEvent *) { + GetAppTask().mPwmIdentifyLed.InitiateBlinkAction(kIdentifyChannelChangeRateMs, kIdentifyChannelChangeRateMs); + }; + break; + case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_FINISH_EFFECT: + ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_FINISH_EFFECT"); + event.Handler = [](AppEvent *) { + GetAppTask().mPwmIdentifyLed.InitiateBlinkAction(kIdentifyFinishOnRateMs, kIdentifyFinishOffRateMs); + }; + break; + case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_STOP_EFFECT: + ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_STOP_EFFECT"); + event.Handler = [](AppEvent *) { GetAppTask().mPwmIdentifyLed.StopAction(); }; + event.Type = AppEvent::kEventType_IdentifyStop; + break; + default: + ChipLogProgress(Zcl, "No identifier effect"); + return; + } + + GetAppTask().PostEvent(&event); +} +#endif + +void AppTaskCommon::StartBleAdvButtonEventHandler(void) +{ + AppEvent event; + + event.Type = AppEvent::kEventType_Button; + event.ButtonEvent.Action = kButtonPushEvent; + event.Handler = StartBleAdvHandler; + GetAppTask().PostEvent(&event); +} + +void AppTaskCommon::StartBleAdvHandler(AppEvent * aEvent) +{ + LOG_INF("StartBleAdvHandler"); + + // Don't allow on starting Matter service BLE advertising after Thread provisioning. + if (ConnectivityMgr().IsThreadProvisioned()) + { + LOG_INF("Device already commissioned"); + return; + } + + if (ConnectivityMgr().IsBLEAdvertisingEnabled()) + { + LOG_INF("BLE adv already enabled"); + return; + } + + if (chip::Server::GetInstance().GetCommissioningWindowManager().OpenBasicCommissioningWindow() != CHIP_NO_ERROR) + { + LOG_ERR("OpenBasicCommissioningWindow fail"); + } +} + +void AppTaskCommon::FactoryResetButtonEventHandler(void) +{ + AppEvent event; + + event.Type = AppEvent::kEventType_Button; + event.ButtonEvent.Action = kButtonPushEvent; + event.Handler = FactoryResetHandler; + GetAppTask().PostEvent(&event); +} + +void AppTaskCommon::FactoryResetHandler(AppEvent * aEvent) +{ + if (sFactoryResetCntr == 0) + { + k_timer_start(&sFactoryResetTimer, K_MSEC(kFactoryResetCalcTimeout), K_NO_WAIT); + } + + sFactoryResetCntr++; + LOG_INF("Factory Reset Trigger Counter: %d/%d", sFactoryResetCntr, kFactoryResetTriggerCntr); + + if (sFactoryResetCntr == kFactoryResetTriggerCntr) + { + k_timer_stop(&sFactoryResetTimer); + sFactoryResetCntr = 0; + + chip::Server::GetInstance().ScheduleFactoryReset(); + } +} + +void AppTaskCommon::FactoryResetTimerTimeoutCallback(k_timer * timer) +{ + if (!timer) + { + return; + } + + AppEvent event; + event.Type = AppEvent::kEventType_Timer; + event.Handler = FactoryResetTimerEventHandler; + GetAppTask().PostEvent(&event); +} + +void AppTaskCommon::FactoryResetTimerEventHandler(AppEvent * aEvent) +{ + if (aEvent->Type != AppEvent::kEventType_Timer) + { + return; + } + + sFactoryResetCntr = 0; + LOG_INF("Factory Reset Trigger Counter is cleared"); +} + +#if APP_USE_THREAD_START_BUTTON +void AppTaskCommon::StartThreadButtonEventHandler(void) +{ + AppEvent event; + + event.Type = AppEvent::kEventType_Button; + event.ButtonEvent.Action = kButtonPushEvent; + event.Handler = StartThreadHandler; + GetAppTask().PostEvent(&event); +} + +void AppTaskCommon::StartThreadHandler(AppEvent * aEvent) +{ + LOG_INF("StartThreadHandler"); + if (!chip::DeviceLayer::ConnectivityMgr().IsThreadProvisioned()) + { + // Switch context from BLE to Thread + Internal::BLEManagerImpl sInstance; + sInstance.SwitchToIeee802154(); + StartDefaultThreadNetwork(); + } + else + { + LOG_INF("Device already commissioned"); + } +} +#endif + +#if APP_USE_EXAMPLE_START_BUTTON +void AppTaskCommon::ExampleActionButtonEventHandler(void) +{ + AppEvent event; + + if (!GetAppTask().ExampleActionEventHandler) + { + return; + } + + event.Type = AppEvent::kEventType_Button; + event.ButtonEvent.Action = kButtonPushEvent; + event.Handler = GetAppTask().ExampleActionEventHandler; + GetAppTask().PostEvent(&event); +} + +void AppTaskCommon::SetExampleButtonCallbacks(EventHandler aAction_CB) +{ + ExampleActionEventHandler = aAction_CB; +} +#endif + +void AppTaskCommon::ChipEventHandler(const ChipDeviceEvent * event, intptr_t /* arg */) +{ + switch (event->Type) + { + case DeviceEventType::kCHIPoBLEAdvertisingChange: + sHaveBLEConnections = ConnectivityMgr().NumBLEConnections() != 0; +#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED + UpdateStatusLED(); +#endif + break; + case DeviceEventType::kThreadStateChange: + sIsThreadProvisioned = ConnectivityMgr().IsThreadProvisioned(); + sIsThreadEnabled = ConnectivityMgr().IsThreadEnabled(); + sIsThreadAttached = ConnectivityMgr().IsThreadAttached(); +#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED + UpdateStatusLED(); +#endif + break; + case DeviceEventType::kThreadConnectivityChange: +#if CONFIG_CHIP_OTA_REQUESTOR + if (event->ThreadConnectivityChange.Result == kConnectivity_Established) + { + InitBasicOTARequestor(); + } +#endif + break; + default: + break; + } +} + +void AppTaskCommon::PostEvent(AppEvent * aEvent) +{ + if (!aEvent) + return; + if (k_msgq_put(&sAppEventQueue, aEvent, K_NO_WAIT) != 0) + { + LOG_INF("PostEvent fail"); + } +} + +void AppTaskCommon::DispatchEvent(AppEvent * aEvent) +{ + if (!aEvent) + return; + if (aEvent->Handler) + { + aEvent->Handler(aEvent); + } + else + { + LOG_INF("Dropping event without handler"); + } +} + +void AppTaskCommon::GetEvent(AppEvent * aEvent) +{ + k_msgq_get(&sAppEventQueue, aEvent, K_FOREVER); +} diff --git a/examples/lighting-app/telink/src/main.cpp b/examples/platform/telink/common/src/mainCommon.cpp similarity index 100% rename from examples/lighting-app/telink/src/main.cpp rename to examples/platform/telink/common/src/mainCommon.cpp diff --git a/examples/pump-app/telink/CMakeLists.txt b/examples/pump-app/telink/CMakeLists.txt index c5478b64704930..03f3012008517b 100755 --- a/examples/pump-app/telink/CMakeLists.txt +++ b/examples/pump-app/telink/CMakeLists.txt @@ -59,6 +59,7 @@ target_include_directories(app PRIVATE include ${GEN_DIR}/app-common ${GEN_DIR}/pump-app + ${TELINK_COMMON}/common/include ${TELINK_COMMON}/util/include ${TELINK_COMMON}/app/include) @@ -68,8 +69,9 @@ add_definitions( target_sources(app PRIVATE src/AppTask.cpp - src/main.cpp src/PumpManager.cpp + ${TELINK_COMMON}/common/src/mainCommon.cpp + ${TELINK_COMMON}/common/src/AppTaskCommon.cpp ${TELINK_COMMON}/util/src/LEDWidget.cpp ${TELINK_COMMON}/util/src/ButtonManager.cpp ${TELINK_COMMON}/util/src/ThreadUtil.cpp diff --git a/examples/pump-app/telink/include/AppConfig.h b/examples/pump-app/telink/include/AppConfig.h old mode 100755 new mode 100644 index 9d54306cc0bb40..a661fd8c3f25e6 --- a/examples/pump-app/telink/include/AppConfig.h +++ b/examples/pump-app/telink/include/AppConfig.h @@ -20,18 +20,14 @@ // ---- Pump Example App Config ---- -// Buttons config -#define BUTTON_PORT DEVICE_DT_GET(DT_NODELABEL(gpioc)) +#define APP_USE_EXAMPLE_START_BUTTON 1 +#define APP_USE_THREAD_START_BUTTON 1 +#define APP_SET_DEVICE_INFO_PROVIDER 1 +#define APP_SET_NETWORK_COMM_ENDPOINT_SEC 0 +#define APP_USE_IDENTIFY_PWM 1 // APP_USE_IDENTIFY_PWM must be defined before including "AppConfigCommon.h" -#define BUTTON_PIN_1 2 -#define BUTTON_PIN_3 3 -#define BUTTON_PIN_4 1 -#define BUTTON_PIN_2 0 +#include "AppConfigCommon.h" -// LEDs config -#define LEDS_PORT DEVICE_DT_GET(DT_NODELABEL(gpiob)) -#define SYSTEM_STATE_LED 7 #define PUMP_STATE_LED 6 -#define LIGHTING_PWM_SPEC_IDENTIFY_GREEN PWM_DT_SPEC_GET(DT_ALIAS(pwm_led3)) // Time it takes in ms for the simulated pump to move from one state to another. #define PUMP_START_PERIOS_MS 2000 diff --git a/examples/pump-app/telink/include/AppEvent.h b/examples/pump-app/telink/include/AppEvent.h deleted file mode 100644 index 3d9b6a28f56689..00000000000000 --- a/examples/pump-app/telink/include/AppEvent.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * - * Copyright (c) 2023 Project CHIP Authors - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include - -struct AppEvent; -typedef void (*EventHandler)(AppEvent *); - -class LEDWidget; - -struct AppEvent -{ - enum AppEventTypes - { - kEventType_Button = 0, - kEventType_Timer, - kEventType_UpdateLedState, - kEventType_IdentifyStart, - kEventType_IdentifyStop, - kEventType_Lighting, - kEventType_Install, - kEventType_Start, - }; - - uint16_t Type; - - union - { - struct - { - uint8_t Action; - } ButtonEvent; - struct - { - void * Context; - } TimerEvent; - struct - { - uint8_t Action; - int32_t Actor; - } StartEvent; - struct - { - LEDWidget * LedWidget; - } UpdateLedStateEvent; - }; - - EventHandler Handler; -}; diff --git a/examples/pump-app/telink/include/AppTask.h b/examples/pump-app/telink/include/AppTask.h index a0ccc23a79dfcb..5d4537b38f54a5 100644 --- a/examples/pump-app/telink/include/AppTask.h +++ b/examples/pump-app/telink/include/AppTask.h @@ -18,75 +18,28 @@ #pragma once -#include "AppEvent.h" +#include "AppTaskCommon.h" #include "PumpManager.h" -#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED -#include "LEDWidget.h" -#endif -#include "PWMDevice.h" -#include - -#if CONFIG_CHIP_FACTORY_DATA -#include -#endif - -struct k_timer; -struct Identify; - -class AppTask +class AppTask : public AppTaskCommon { public: - CHIP_ERROR StartApp(); + void UpdateClusterState(); static void PostStartActionRequest(int32_t actor, PumpManager::Action_t action); - void PostEvent(AppEvent * event); - void UpdateClusterState(); - static void IdentifyEffectHandler(EmberAfIdentifyEffectIdentifier aEffect); private: friend AppTask & GetAppTask(void); + friend class AppTaskCommon; CHIP_ERROR Init(void); - static void ActionIdentifyStateUpdateHandler(k_timer * timer); - static void ActionInitiated(PumpManager::Action_t action, int32_t actor); static void ActionCompleted(PumpManager::Action_t action, int32_t actor); - void DispatchEvent(AppEvent * event); - -#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED - static void UpdateLedStateEventHandler(AppEvent * aEvent); - static void LEDStateUpdateHandler(LEDWidget * ledWidget); - static void UpdateStatusLED(); -#endif - static void StartActionButtonEventHandler(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 FactoryResetTimerTimeoutCallback(k_timer * timer); - - static void FactoryResetTimerEventHandler(AppEvent * aEvent); - static void FactoryResetHandler(AppEvent * aEvent); - static void StartThreadHandler(AppEvent * aEvent); static void StartActionEventHandler(AppEvent * aEvent); - static void StartBleAdvHandler(AppEvent * aEvent); - static void UpdateIdentifyStateEventHandler(AppEvent * aEvent); - - static void LockActionEventHandler(AppEvent * event); - - static void InitButtons(void); static AppTask sAppTask; - PWMDevice mPwmIdentifyLed; - -#if CONFIG_CHIP_FACTORY_DATA - chip::DeviceLayer::FactoryDataProvider mFactoryDataProvider; -#endif }; inline AppTask & GetAppTask(void) diff --git a/examples/pump-app/telink/include/PumpManager.h b/examples/pump-app/telink/include/PumpManager.h index 986e2605e9fa15..230e858144712b 100644 --- a/examples/pump-app/telink/include/PumpManager.h +++ b/examples/pump-app/telink/include/PumpManager.h @@ -22,7 +22,7 @@ #include -#include "AppEvent.h" +#include "AppEventCommon.h" struct k_timer; @@ -86,9 +86,9 @@ class PumpManager void StartTimer(uint32_t aTimeoutMs); static void TimerEventHandler(k_timer * timer); - static void AutoRestartTimerEventHandler(const AppEvent & aEvent); + static void AutoRestartTimerEventHandler(AppEvent * aEvent); - static void PumpStartTimerEventHandler(const AppEvent & aEvent); + static void PumpStartTimerEventHandler(AppEvent * aEvent); static PumpManager sPump; }; diff --git a/examples/pump-app/telink/src/AppTask.cpp b/examples/pump-app/telink/src/AppTask.cpp index 7d7080d82fc721..30aeaf3828badb 100644 --- a/examples/pump-app/telink/src/AppTask.cpp +++ b/examples/pump-app/telink/src/AppTask.cpp @@ -17,487 +17,48 @@ */ #include "AppTask.h" - -#include "AppConfig.h" -#include "ButtonManager.h" #include "PumpManager.h" -#include "ThreadUtil.h" - -#include #include -#include -#include -#include -#include -#include -#include -#include - -#if CONFIG_CHIP_OTA_REQUESTOR -#include "OTAUtil.h" -#endif - -#include -#include - -#if CONFIG_CHIP_LIB_SHELL -#include -#include - -static int cmd_telink_reboot(const struct shell * shell, size_t argc, char ** argv) -{ - ARG_UNUSED(argc); - ARG_UNUSED(argv); - - shell_print(shell, "Performing board reboot..."); - sys_reboot(); -} - -SHELL_STATIC_SUBCMD_SET_CREATE(sub_telink, SHELL_CMD(reboot, NULL, "Reboot board command", cmd_telink_reboot), - SHELL_SUBCMD_SET_END); -SHELL_CMD_REGISTER(telink, &sub_telink, "Telink commands", NULL); -#endif // CONFIG_CHIP_LIB_SHELL LOG_MODULE_DECLARE(app, CONFIG_CHIP_APP_LOG_LEVEL); -using namespace ::chip; -using namespace ::chip::app; -using namespace ::chip::Credentials; -using namespace ::chip::DeviceLayer; - namespace { -constexpr int kFactoryResetCalcTimeout = 3000; -constexpr int kFactoryResetTriggerCntr = 3; -constexpr int kAppEventQueueSize = 10; -constexpr uint8_t kButtonPushEvent = 1; -constexpr uint8_t kButtonReleaseEvent = 0; -constexpr EndpointId kPccClusterEndpoint = 1; -constexpr EndpointId kOnOffClusterEndpoint = 1; -constexpr uint8_t kDefaultMinLevel = 0; -constexpr uint8_t kDefaultMaxLevel = 254; -constexpr uint32_t kIdentifyBlinkRateMs = 200; -constexpr uint32_t kIdentifyOkayOnRateMs = 50; -constexpr uint32_t kIdentifyOkayOffRateMs = 950; -constexpr uint32_t kIdentifyFinishOnRateMs = 950; -constexpr uint32_t kIdentifyFinishOffRateMs = 50; -constexpr uint32_t kIdentifyChannelChangeRateMs = 1000; -constexpr uint32_t kIdentifyBreatheRateMs = 1000; - -const struct pwm_dt_spec sPwmIdentifySpecGreenLed = LIGHTING_PWM_SPEC_IDENTIFY_GREEN; - -#if CONFIG_CHIP_FACTORY_DATA -// NOTE! This key is for test/certification only and should not be available in production devices! -uint8_t sTestEventTriggerEnableKey[TestEventTriggerDelegate::kEnableKeyLength] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, - 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }; -#endif - -K_MSGQ_DEFINE(sAppEventQueue, sizeof(AppEvent), kAppEventQueueSize, alignof(AppEvent)); -k_timer sFactoryResetTimer; -uint8_t sFactoryResetCntr = 0; +constexpr EndpointId kPccClusterEndpoint = 1; +constexpr EndpointId kOnOffClusterEndpoint = 1; #if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED -LEDWidget sStatusLED; LEDWidget sPumpStateLED; #endif - -Button sFactoryResetButton; -Button sPumpButton; -Button sThreadStartButton; -Button sBleAdvStartButton; - -bool sIsThreadProvisioned = false; -bool sIsThreadEnabled = false; -bool sIsThreadAttached = false; -bool sHaveBLEConnections = false; - -chip::DeviceLayer::DeviceInfoProviderImpl gExampleDeviceInfoProvider; - -void OnIdentifyTriggerEffect(Identify * identify) -{ - AppTask::IdentifyEffectHandler(identify->mCurrentEffectIdentifier); -} - -Identify sIdentify = { - kOnOffClusterEndpoint, - [](Identify *) { ChipLogProgress(Zcl, "OnIdentifyStart"); }, - [](Identify *) { ChipLogProgress(Zcl, "OnIdentifyStop"); }, - EMBER_ZCL_IDENTIFY_IDENTIFY_TYPE_VISIBLE_LED, - OnIdentifyTriggerEffect, -}; - } // namespace AppTask AppTask::sAppTask; -class AppFabricTableDelegate : public FabricTable::Delegate -{ - void OnFabricRemoved(const FabricTable & fabricTable, FabricIndex fabricIndex) - { - if (chip::Server::GetInstance().GetFabricTable().FabricCount() == 0) - { - chip::Server::GetInstance().ScheduleFactoryReset(); - } - } -}; - CHIP_ERROR AppTask::Init(void) { - LOG_INF("SW Version: %u, %s", CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION, CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING); +#if APP_USE_EXAMPLE_START_BUTTON + SetExampleButtonCallbacks(StartActionEventHandler); +#endif + InitCommonParts(); - // Initialize status LED #if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED - LEDWidget::InitGpio(LEDS_PORT); - LEDWidget::SetStateUpdateCallback(LEDStateUpdateHandler); - sStatusLED.Init(SYSTEM_STATE_LED); - - UpdateStatusLED(); - sPumpStateLED.Init(PUMP_STATE_LED); sPumpStateLED.Set(!PumpMgr().IsStopped()); #endif - InitButtons(); - - // Initialize function button timer - k_timer_init(&sFactoryResetTimer, &AppTask::FactoryResetTimerTimeoutCallback, nullptr); - k_timer_user_data_set(&sFactoryResetTimer, this); - - // Initialize PWM Identify led - CHIP_ERROR err = sAppTask.mPwmIdentifyLed.Init(&sPwmIdentifySpecGreenLed, kDefaultMinLevel, kDefaultMaxLevel, kDefaultMaxLevel); - if (err != CHIP_NO_ERROR) - { - LOG_ERR("Green IDENTIFY PWM Device Init fail"); - return err; - } - - sAppTask.mPwmIdentifyLed.SetCallbacks(nullptr, nullptr, ActionIdentifyStateUpdateHandler); - PumpMgr().Init(); PumpMgr().SetCallbacks(ActionInitiated, ActionCompleted); - // Initialize CHIP server -#if CONFIG_CHIP_FACTORY_DATA - ReturnErrorOnFailure(mFactoryDataProvider.Init()); - SetDeviceInstanceInfoProvider(&mFactoryDataProvider); - SetDeviceAttestationCredentialsProvider(&mFactoryDataProvider); - SetCommissionableDataProvider(&mFactoryDataProvider); - // Read EnableKey from the factory data. - MutableByteSpan enableKey(sTestEventTriggerEnableKey); - err = mFactoryDataProvider.GetEnableKey(enableKey); - if (err != CHIP_NO_ERROR) - { - LOG_ERR("mFactoryDataProvider.GetEnableKey() failed. Could not delegate a test event trigger"); - memset(sTestEventTriggerEnableKey, 0, sizeof(sTestEventTriggerEnableKey)); - } -#else - SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); -#endif - - static CommonCaseDeviceServerInitParams initParams; - (void) initParams.InitializeStaticResourcesBeforeServerInit(); - ReturnErrorOnFailure(chip::Server::GetInstance().Init(initParams)); - gExampleDeviceInfoProvider.SetStorageDelegate(&Server::GetInstance().GetPersistentStorage()); - chip::DeviceLayer::SetDeviceInfoProvider(&gExampleDeviceInfoProvider); - -#if CONFIG_CHIP_OTA_REQUESTOR - InitBasicOTARequestor(); -#endif - - 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); - - err = ConnectivityMgr().SetBLEDeviceName("Telink Pump"); + CHIP_ERROR err = ConnectivityMgr().SetBLEDeviceName("Telink Pump"); if (err != CHIP_NO_ERROR) { LOG_ERR("SetBLEDeviceName fail"); return err; } - err = chip::Server::GetInstance().GetFabricTable().AddFabricDelegate(new AppFabricTableDelegate); - if (err != CHIP_NO_ERROR) - { - LOG_ERR("AppFabricTableDelegate fail"); - return err; - } - return CHIP_NO_ERROR; } -CHIP_ERROR AppTask::StartApp(void) -{ - CHIP_ERROR err = Init(); - - if (err != CHIP_NO_ERROR) - { - LOG_ERR("AppTask Init fail"); - return err; - } - - AppEvent event = {}; - - while (true) - { - k_msgq_get(&sAppEventQueue, &event, K_FOREVER); - DispatchEvent(&event); - } -} - -void AppTask::IdentifyEffectHandler(EmberAfIdentifyEffectIdentifier aEffect) -{ - AppEvent event; - event.Type = AppEvent::kEventType_IdentifyStart; - - switch (aEffect) - { - case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BLINK: - ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BLINK"); - event.Handler = [](AppEvent *) { - sAppTask.mPwmIdentifyLed.InitiateBlinkAction(kIdentifyBlinkRateMs, kIdentifyBlinkRateMs); - }; - break; - case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BREATHE: - ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BREATHE"); - event.Handler = [](AppEvent *) { - sAppTask.mPwmIdentifyLed.InitiateBreatheAction(PWMDevice::kBreatheType_Both, kIdentifyBreatheRateMs); - }; - break; - case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_OKAY: - ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_OKAY"); - event.Handler = [](AppEvent *) { - sAppTask.mPwmIdentifyLed.InitiateBlinkAction(kIdentifyOkayOnRateMs, kIdentifyOkayOffRateMs); - }; - break; - case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_CHANNEL_CHANGE: - ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_CHANNEL_CHANGE"); - event.Handler = [](AppEvent *) { - sAppTask.mPwmIdentifyLed.InitiateBlinkAction(kIdentifyChannelChangeRateMs, kIdentifyChannelChangeRateMs); - }; - break; - case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_FINISH_EFFECT: - ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_FINISH_EFFECT"); - event.Handler = [](AppEvent *) { - sAppTask.mPwmIdentifyLed.InitiateBlinkAction(kIdentifyFinishOnRateMs, kIdentifyFinishOffRateMs); - }; - break; - case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_STOP_EFFECT: - ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_STOP_EFFECT"); - event.Handler = [](AppEvent *) { sAppTask.mPwmIdentifyLed.StopAction(); }; - event.Type = AppEvent::kEventType_IdentifyStop; - break; - default: - ChipLogProgress(Zcl, "No identifier effect"); - return; - } - - sAppTask.PostEvent(&event); -} - -void AppTask::StartActionButtonEventHandler(void) -{ - AppEvent event; - - event.Type = AppEvent::kEventType_Button; - event.ButtonEvent.Action = kButtonPushEvent; - event.Handler = StartActionEventHandler; - sAppTask.PostEvent(&event); -} - -void AppTask::StartActionEventHandler(AppEvent * aEvent) -{ - PumpManager::Action_t action = PumpManager::INVALID_ACTION; - int32_t actor = 0; - - if (aEvent->Type == AppEvent::kEventType_Start) - { - action = static_cast(aEvent->StartEvent.Action); - actor = aEvent->StartEvent.Actor; - } - else if (aEvent->Type == AppEvent::kEventType_Button) - { - action = PumpMgr().IsStopped() ? PumpManager::START_ACTION : PumpManager::STOP_ACTION; - actor = static_cast(AppEvent::kEventType_Button); - } - - if (action != PumpManager::INVALID_ACTION && !PumpMgr().InitiateAction(actor, action)) - LOG_INF("Action is already in progress or active."); -} - -void AppTask::FactoryResetButtonEventHandler(void) -{ - AppEvent event; - - event.Type = AppEvent::kEventType_Button; - event.ButtonEvent.Action = kButtonPushEvent; - event.Handler = FactoryResetHandler; - sAppTask.PostEvent(&event); -} - -void AppTask::FactoryResetHandler(AppEvent * aEvent) -{ - if (sFactoryResetCntr == 0) - { - k_timer_start(&sFactoryResetTimer, K_MSEC(kFactoryResetCalcTimeout), K_NO_WAIT); - } - - sFactoryResetCntr++; - LOG_INF("Factory Reset Trigger Counter: %d/%d", sFactoryResetCntr, kFactoryResetTriggerCntr); - - if (sFactoryResetCntr == kFactoryResetTriggerCntr) - { - k_timer_stop(&sFactoryResetTimer); - sFactoryResetCntr = 0; - - chip::Server::GetInstance().ScheduleFactoryReset(); - } -} - -void AppTask::StartThreadButtonEventHandler(void) -{ - AppEvent event; - - event.Type = AppEvent::kEventType_Button; - event.ButtonEvent.Action = kButtonPushEvent; - event.Handler = StartThreadHandler; - sAppTask.PostEvent(&event); -} - -void AppTask::StartThreadHandler(AppEvent * aEvent) -{ - LOG_INF("StartThreadHandler"); - if (!chip::DeviceLayer::ConnectivityMgr().IsThreadProvisioned()) - { - // Switch context from BLE to Thread - Internal::BLEManagerImpl sInstance; - sInstance.SwitchToIeee802154(); - StartDefaultThreadNetwork(); - } - else - { - LOG_INF("Device already commissioned"); - } -} - -void AppTask::StartBleAdvButtonEventHandler(void) -{ - AppEvent event; - - event.Type = AppEvent::kEventType_Button; - event.ButtonEvent.Action = kButtonPushEvent; - event.Handler = StartBleAdvHandler; - sAppTask.PostEvent(&event); -} - -void AppTask::StartBleAdvHandler(AppEvent * aEvent) -{ - LOG_INF("StartBleAdvHandler"); - - // Don't allow on starting Matter service BLE advertising after Thread provisioning. - if (ConnectivityMgr().IsThreadProvisioned()) - { - LOG_INF("Device already commissioned"); - return; - } - - if (ConnectivityMgr().IsBLEAdvertisingEnabled()) - { - LOG_INF("BLE adv already enabled"); - return; - } - - if (chip::Server::GetInstance().GetCommissioningWindowManager().OpenBasicCommissioningWindow() != CHIP_NO_ERROR) - { - LOG_ERR("OpenBasicCommissioningWindow fail"); - } -} - -#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED -void AppTask::UpdateLedStateEventHandler(AppEvent * aEvent) -{ - if (aEvent->Type == AppEvent::kEventType_UpdateLedState) - { - aEvent->UpdateLedStateEvent.LedWidget->UpdateState(); - } -} - -void AppTask::LEDStateUpdateHandler(LEDWidget * ledWidget) -{ - AppEvent event; - event.Type = AppEvent::kEventType_UpdateLedState; - event.Handler = UpdateLedStateEventHandler; - event.UpdateLedStateEvent.LedWidget = ledWidget; - sAppTask.PostEvent(&event); -} - -void AppTask::UpdateStatusLED(void) -{ - if (sIsThreadProvisioned && sIsThreadEnabled) - { - if (sIsThreadAttached) - { - sStatusLED.Blink(950, 50); - } - else - { - sStatusLED.Blink(100, 100); - } - } - else - { - sStatusLED.Blink(50, 950); - } -} -#endif - -void AppTask::ChipEventHandler(const ChipDeviceEvent * event, intptr_t /* arg */) -{ - switch (event->Type) - { - case DeviceEventType::kCHIPoBLEAdvertisingChange: - sHaveBLEConnections = ConnectivityMgr().NumBLEConnections() != 0; -#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED - UpdateStatusLED(); -#endif - break; - case DeviceEventType::kThreadStateChange: - sIsThreadProvisioned = ConnectivityMgr().IsThreadProvisioned(); - sIsThreadEnabled = ConnectivityMgr().IsThreadEnabled(); - sIsThreadAttached = ConnectivityMgr().IsThreadAttached(); -#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED - UpdateStatusLED(); -#endif - break; - case DeviceEventType::kThreadConnectivityChange: -#if CONFIG_CHIP_OTA_REQUESTOR - if (event->ThreadConnectivityChange.Result == kConnectivity_Established) - { - InitBasicOTARequestor(); - } -#endif - break; - default: - break; - } -} - -void AppTask::ActionIdentifyStateUpdateHandler(k_timer * timer) -{ - AppEvent event; - event.Type = AppEvent::kEventType_UpdateLedState; - event.Handler = UpdateIdentifyStateEventHandler; - sAppTask.PostEvent(&event); -} - -void AppTask::UpdateIdentifyStateEventHandler(AppEvent * aEvent) -{ - sAppTask.mPwmIdentifyLed.UpdateAction(); -} - void AppTask::ActionInitiated(PumpManager::Action_t action, int32_t actor) { // If the action has been initiated by the pump, update the pump trait @@ -511,7 +72,9 @@ void AppTask::ActionInitiated(PumpManager::Action_t action, int32_t actor) LOG_INF("Pump Stop Action has been initiated"); } +#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED sPumpStateLED.Blink(50, 50); +#endif } void AppTask::ActionCompleted(PumpManager::Action_t action, int32_t actor) @@ -522,12 +85,16 @@ void AppTask::ActionCompleted(PumpManager::Action_t action, int32_t actor) if (action == PumpManager::START_ACTION) { LOG_INF("Pump Start Action has been completed"); +#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED sPumpStateLED.Set(true); +#endif } else if (action == PumpManager::STOP_ACTION) { LOG_INF("Pump Stop Action has been completed"); +#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED sPumpStateLED.Set(false); +#endif } if (actor == static_cast(AppEvent::kEventType_Button)) @@ -546,108 +113,54 @@ void AppTask::PostStartActionRequest(int32_t actor, PumpManager::Action_t action sAppTask.PostEvent(&event); } -void AppTask::PostEvent(AppEvent * aEvent) +void AppTask::StartActionEventHandler(AppEvent * aEvent) { - if (k_msgq_put(&sAppEventQueue, aEvent, K_NO_WAIT) != 0) - { - LOG_INF("PostEvent fail"); - } -} + PumpManager::Action_t action = PumpManager::INVALID_ACTION; + int32_t actor = 0; -void AppTask::DispatchEvent(AppEvent * aEvent) -{ - if (aEvent->Handler) + if (aEvent->Type == AppEvent::kEventType_Start) { - aEvent->Handler(aEvent); + action = static_cast(aEvent->StartEvent.Action); + actor = aEvent->StartEvent.Actor; } - else + else if (aEvent->Type == AppEvent::kEventType_Button) { - LOG_INF("Dropping event without handler"); + action = PumpMgr().IsStopped() ? PumpManager::START_ACTION : PumpManager::STOP_ACTION; + actor = static_cast(AppEvent::kEventType_Button); } + + if (action != PumpManager::INVALID_ACTION && !PumpMgr().InitiateAction(actor, action)) + LOG_INF("Action is already in progress or active."); } void AppTask::UpdateClusterState() { - EmberStatus status; - - ChipLogProgress(NotSpecified, "UpdateClusterState"); - // Write the new values - bool onOffState = !PumpMgr().IsStopped(); - status = Clusters::OnOff::Attributes::OnOff::Set(kOnOffClusterEndpoint, onOffState); + EmberStatus status = Clusters::OnOff::Attributes::OnOff::Set(kOnOffClusterEndpoint, onOffState); if (status != EMBER_ZCL_STATUS_SUCCESS) { - ChipLogError(NotSpecified, "ERR: Updating On/Off state %x", status); + LOG_ERR("ERR: Updating On/Off state %x", status); } - int16_t maxPressure = PumpMgr().GetMaxPressure(); - - uint16_t maxSpeed = PumpMgr().GetMaxSpeed(); - - uint16_t maxFlow = PumpMgr().GetMaxFlow(); - - int16_t minConstPress = PumpMgr().GetMinConstPressure(); - - int16_t maxConstPress = PumpMgr().GetMaxConstPressure(); - - int16_t minCompPress = PumpMgr().GetMinCompPressure(); - - int16_t maxCompPress = PumpMgr().GetMaxCompPressure(); - + int16_t maxPressure = PumpMgr().GetMaxPressure(); + uint16_t maxSpeed = PumpMgr().GetMaxSpeed(); + uint16_t maxFlow = PumpMgr().GetMaxFlow(); + int16_t minConstPress = PumpMgr().GetMinConstPressure(); + int16_t maxConstPress = PumpMgr().GetMaxConstPressure(); + int16_t minCompPress = PumpMgr().GetMinCompPressure(); + int16_t maxCompPress = PumpMgr().GetMaxCompPressure(); uint16_t minConstSpeed = PumpMgr().GetMinConstSpeed(); - uint16_t maxConstSpeed = PumpMgr().GetMaxConstSpeed(); - - uint16_t minConstFlow = PumpMgr().GetMinConstFlow(); - - uint16_t maxConstFlow = PumpMgr().GetMaxConstFlow(); - - int16_t minConstTemp = PumpMgr().GetMinConstTemp(); - - int16_t maxConstTemp = PumpMgr().GetMaxConstTemp(); -} - -void AppTask::FactoryResetTimerTimeoutCallback(k_timer * timer) -{ - if (!timer) - { - return; - } - - AppEvent event; - event.Type = AppEvent::kEventType_Timer; - event.Handler = FactoryResetTimerEventHandler; - sAppTask.PostEvent(&event); -} - -void AppTask::FactoryResetTimerEventHandler(AppEvent * aEvent) -{ - if (aEvent->Type != AppEvent::kEventType_Timer) - { - return; - } - - sFactoryResetCntr = 0; - LOG_INF("Factory Reset Trigger Counter is cleared"); -} - -void AppTask::InitButtons(void) -{ -#if CONFIG_CHIP_BUTTON_MANAGER_IRQ_MODE - sFactoryResetButton.Configure(BUTTON_PORT, BUTTON_PIN_1, FactoryResetButtonEventHandler); - sPumpButton.Configure(BUTTON_PORT, BUTTON_PIN_2, StartActionButtonEventHandler); - sThreadStartButton.Configure(BUTTON_PORT, BUTTON_PIN_3, StartThreadButtonEventHandler); - sBleAdvStartButton.Configure(BUTTON_PORT, BUTTON_PIN_4, StartBleAdvButtonEventHandler); -#else - sFactoryResetButton.Configure(BUTTON_PORT, BUTTON_PIN_3, BUTTON_PIN_1, FactoryResetButtonEventHandler); - sPumpButton.Configure(BUTTON_PORT, BUTTON_PIN_4, BUTTON_PIN_1, StartActionButtonEventHandler); - sThreadStartButton.Configure(BUTTON_PORT, BUTTON_PIN_3, BUTTON_PIN_2, StartThreadButtonEventHandler); - sBleAdvStartButton.Configure(BUTTON_PORT, BUTTON_PIN_4, BUTTON_PIN_2, StartBleAdvButtonEventHandler); -#endif - ButtonManagerInst().AddButton(sFactoryResetButton); - ButtonManagerInst().AddButton(sPumpButton); - ButtonManagerInst().AddButton(sThreadStartButton); - ButtonManagerInst().AddButton(sBleAdvStartButton); + uint16_t minConstFlow = PumpMgr().GetMinConstFlow(); + uint16_t maxConstFlow = PumpMgr().GetMaxConstFlow(); + int16_t minConstTemp = PumpMgr().GetMinConstTemp(); + int16_t maxConstTemp = PumpMgr().GetMaxConstTemp(); + + LOG_INF("UpdateClusterState:\n maxPressure = %d,\t maxSpeed = %d,\t maxFlow = %d\n minConstPress = %d,\t " + "maxConstPress = %d\n minCompPress = %d,\t maxCompPress = %d\n minConstSpeed = %d,\t maxConstSpeed = %d\n" + "minConstFlow = %d,\t maxConstFlow = %d\n minConstTemp = %d,\t maxConstTemp = %d", + maxPressure, maxSpeed, maxFlow, minConstPress, maxConstPress, minCompPress, maxCompPress, minConstSpeed, maxConstSpeed, + minConstFlow, maxConstFlow, minConstTemp, maxConstTemp); } diff --git a/examples/pump-app/telink/src/PumpManager.cpp b/examples/pump-app/telink/src/PumpManager.cpp index 3e8654a1d8efa5..04d2a8a0763fa2 100644 --- a/examples/pump-app/telink/src/PumpManager.cpp +++ b/examples/pump-app/telink/src/PumpManager.cpp @@ -135,9 +135,9 @@ void PumpManager::TimerEventHandler(k_timer * timer) GetAppTask().PostEvent(&event); } -void PumpManager::AutoRestartTimerEventHandler(const AppEvent & aEvent) +void PumpManager::AutoRestartTimerEventHandler(AppEvent * aEvent) { - PumpManager * pump = static_cast(aEvent.TimerEvent.Context); + PumpManager * pump = static_cast(aEvent->TimerEvent.Context); int32_t actor = 0; // Make sure auto start timer is still armed. @@ -151,11 +151,11 @@ void PumpManager::AutoRestartTimerEventHandler(const AppEvent & aEvent) pump->InitiateAction(actor, START_ACTION); } -void PumpManager::PumpStartTimerEventHandler(const AppEvent & aEvent) +void PumpManager::PumpStartTimerEventHandler(AppEvent * aEvent) { Action_t actionCompleted = INVALID_ACTION; - PumpManager * pump = static_cast(aEvent.TimerEvent.Context); + PumpManager * pump = static_cast(aEvent->TimerEvent.Context); if (pump->mState == kState_StartInitiated) { diff --git a/examples/pump-app/telink/src/main.cpp b/examples/pump-app/telink/src/main.cpp deleted file mode 100644 index 71aa52f9d91901..00000000000000 --- a/examples/pump-app/telink/src/main.cpp +++ /dev/null @@ -1,82 +0,0 @@ -/* - * - * Copyright (c) 2023 Project CHIP Authors - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "AppTask.h" - -#include -#include - -#include - -LOG_MODULE_REGISTER(app, CONFIG_CHIP_APP_LOG_LEVEL); - -using namespace ::chip; -using namespace ::chip::Inet; -using namespace ::chip::DeviceLayer; - -int main(void) -{ - CHIP_ERROR err = CHIP_NO_ERROR; - - err = chip::Platform::MemoryInit(); - if (err != CHIP_NO_ERROR) - { - LOG_ERR("MemoryInit fail"); - goto exit; - } - - err = PlatformMgr().InitChipStack(); - if (err != CHIP_NO_ERROR) - { - LOG_ERR("InitChipStack fail"); - goto exit; - } - - err = PlatformMgr().StartEventLoopTask(); - if (err != CHIP_NO_ERROR) - { - LOG_ERR("StartEventLoopTask fail"); - goto exit; - } - - err = ThreadStackMgr().InitThreadStack(); - if (err != CHIP_NO_ERROR) - { - LOG_ERR("InitThreadStack fail"); - goto exit; - } - -#ifdef CONFIG_OPENTHREAD_MTD_SED - err = ConnectivityMgr().SetThreadDeviceType(ConnectivityManager::kThreadDeviceType_SleepyEndDevice); -#elif CONFIG_OPENTHREAD_MTD - err = ConnectivityMgr().SetThreadDeviceType(ConnectivityManager::kThreadDeviceType_MinimalEndDevice); -#else - err = ConnectivityMgr().SetThreadDeviceType(ConnectivityManager::kThreadDeviceType_Router); -#endif - if (err != CHIP_NO_ERROR) - { - LOG_ERR("SetThreadDeviceType fail"); - goto exit; - } - - err = GetAppTask().StartApp(); - -exit: - LOG_ERR("Exit err %" CHIP_ERROR_FORMAT, err.Format()); - return (err == CHIP_NO_ERROR) ? EXIT_SUCCESS : EXIT_FAILURE; -} diff --git a/examples/pump-controller-app/telink/CMakeLists.txt b/examples/pump-controller-app/telink/CMakeLists.txt index 56721841de599f..d5eeb88ee6d202 100755 --- a/examples/pump-controller-app/telink/CMakeLists.txt +++ b/examples/pump-controller-app/telink/CMakeLists.txt @@ -59,6 +59,7 @@ target_include_directories(app PRIVATE include ${GEN_DIR}/app-common ${GEN_DIR}/pump-controller-app + ${TELINK_COMMON}/common/include ${TELINK_COMMON}/util/include ${TELINK_COMMON}/app/include) @@ -68,8 +69,9 @@ add_definitions( target_sources(app PRIVATE src/AppTask.cpp - src/main.cpp src/PumpManager.cpp + ${TELINK_COMMON}/common/src/mainCommon.cpp + ${TELINK_COMMON}/common/src/AppTaskCommon.cpp ${TELINK_COMMON}/util/src/LEDWidget.cpp ${TELINK_COMMON}/util/src/ButtonManager.cpp ${TELINK_COMMON}/util/src/ThreadUtil.cpp diff --git a/examples/pump-controller-app/telink/include/AppConfig.h b/examples/pump-controller-app/telink/include/AppConfig.h old mode 100755 new mode 100644 index 70ee2c5ca0f425..5dd793da63e67e --- a/examples/pump-controller-app/telink/include/AppConfig.h +++ b/examples/pump-controller-app/telink/include/AppConfig.h @@ -20,18 +20,14 @@ // ---- Pump Controller Example App Config ---- -// Buttons config -#define BUTTON_PORT DEVICE_DT_GET(DT_NODELABEL(gpioc)) +#define APP_USE_EXAMPLE_START_BUTTON 1 +#define APP_USE_THREAD_START_BUTTON 1 +#define APP_SET_DEVICE_INFO_PROVIDER 1 +#define APP_SET_NETWORK_COMM_ENDPOINT_SEC 0 +#define APP_USE_IDENTIFY_PWM 1 // APP_USE_IDENTIFY_PWM must be defined before including "AppConfigCommon.h" -#define BUTTON_PIN_1 2 -#define BUTTON_PIN_3 3 -#define BUTTON_PIN_4 1 -#define BUTTON_PIN_2 0 +#include "AppConfigCommon.h" -// LEDs config -#define LEDS_PORT DEVICE_DT_GET(DT_NODELABEL(gpiob)) -#define SYSTEM_STATE_LED 7 #define PUMP_STATE_LED 6 -#define LIGHTING_PWM_SPEC_IDENTIFY_GREEN PWM_DT_SPEC_GET(DT_ALIAS(pwm_led3)) // Time it takes in ms for the simulated pump to move from one state to another. #define PUMP_START_PERIOS_MS 2000 diff --git a/examples/pump-controller-app/telink/include/AppEvent.h b/examples/pump-controller-app/telink/include/AppEvent.h deleted file mode 100644 index 3d9b6a28f56689..00000000000000 --- a/examples/pump-controller-app/telink/include/AppEvent.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * - * Copyright (c) 2023 Project CHIP Authors - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include - -struct AppEvent; -typedef void (*EventHandler)(AppEvent *); - -class LEDWidget; - -struct AppEvent -{ - enum AppEventTypes - { - kEventType_Button = 0, - kEventType_Timer, - kEventType_UpdateLedState, - kEventType_IdentifyStart, - kEventType_IdentifyStop, - kEventType_Lighting, - kEventType_Install, - kEventType_Start, - }; - - uint16_t Type; - - union - { - struct - { - uint8_t Action; - } ButtonEvent; - struct - { - void * Context; - } TimerEvent; - struct - { - uint8_t Action; - int32_t Actor; - } StartEvent; - struct - { - LEDWidget * LedWidget; - } UpdateLedStateEvent; - }; - - EventHandler Handler; -}; diff --git a/examples/pump-controller-app/telink/include/AppTask.h b/examples/pump-controller-app/telink/include/AppTask.h index a0ccc23a79dfcb..5d4537b38f54a5 100644 --- a/examples/pump-controller-app/telink/include/AppTask.h +++ b/examples/pump-controller-app/telink/include/AppTask.h @@ -18,75 +18,28 @@ #pragma once -#include "AppEvent.h" +#include "AppTaskCommon.h" #include "PumpManager.h" -#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED -#include "LEDWidget.h" -#endif -#include "PWMDevice.h" -#include - -#if CONFIG_CHIP_FACTORY_DATA -#include -#endif - -struct k_timer; -struct Identify; - -class AppTask +class AppTask : public AppTaskCommon { public: - CHIP_ERROR StartApp(); + void UpdateClusterState(); static void PostStartActionRequest(int32_t actor, PumpManager::Action_t action); - void PostEvent(AppEvent * event); - void UpdateClusterState(); - static void IdentifyEffectHandler(EmberAfIdentifyEffectIdentifier aEffect); private: friend AppTask & GetAppTask(void); + friend class AppTaskCommon; CHIP_ERROR Init(void); - static void ActionIdentifyStateUpdateHandler(k_timer * timer); - static void ActionInitiated(PumpManager::Action_t action, int32_t actor); static void ActionCompleted(PumpManager::Action_t action, int32_t actor); - void DispatchEvent(AppEvent * event); - -#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED - static void UpdateLedStateEventHandler(AppEvent * aEvent); - static void LEDStateUpdateHandler(LEDWidget * ledWidget); - static void UpdateStatusLED(); -#endif - static void StartActionButtonEventHandler(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 FactoryResetTimerTimeoutCallback(k_timer * timer); - - static void FactoryResetTimerEventHandler(AppEvent * aEvent); - static void FactoryResetHandler(AppEvent * aEvent); - static void StartThreadHandler(AppEvent * aEvent); static void StartActionEventHandler(AppEvent * aEvent); - static void StartBleAdvHandler(AppEvent * aEvent); - static void UpdateIdentifyStateEventHandler(AppEvent * aEvent); - - static void LockActionEventHandler(AppEvent * event); - - static void InitButtons(void); static AppTask sAppTask; - PWMDevice mPwmIdentifyLed; - -#if CONFIG_CHIP_FACTORY_DATA - chip::DeviceLayer::FactoryDataProvider mFactoryDataProvider; -#endif }; inline AppTask & GetAppTask(void) diff --git a/examples/pump-controller-app/telink/include/PumpManager.h b/examples/pump-controller-app/telink/include/PumpManager.h index 11c7b0886bd7b3..715bc45066274a 100644 --- a/examples/pump-controller-app/telink/include/PumpManager.h +++ b/examples/pump-controller-app/telink/include/PumpManager.h @@ -22,7 +22,7 @@ #include -#include "AppEvent.h" +#include "AppEventCommon.h" struct k_timer; @@ -72,9 +72,9 @@ class PumpManager void StartTimer(uint32_t aTimeoutMs); static void TimerEventHandler(k_timer * timer); - static void AutoRestartTimerEventHandler(const AppEvent & aEvent); + static void AutoRestartTimerEventHandler(AppEvent * aEvent); - static void PumpStartTimerEventHandler(const AppEvent & aEvent); + static void PumpStartTimerEventHandler(AppEvent * aEvent); static PumpManager sPump; }; diff --git a/examples/pump-controller-app/telink/src/AppTask.cpp b/examples/pump-controller-app/telink/src/AppTask.cpp index 80dd632d2038f8..13bb753fe0d759 100644 --- a/examples/pump-controller-app/telink/src/AppTask.cpp +++ b/examples/pump-controller-app/telink/src/AppTask.cpp @@ -17,297 +17,46 @@ */ #include "AppTask.h" - -#include "AppConfig.h" -#include "ButtonManager.h" #include "PumpManager.h" -#include "ThreadUtil.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if CONFIG_CHIP_OTA_REQUESTOR -#include "OTAUtil.h" -#endif - -#include -#include - -#if CONFIG_CHIP_LIB_SHELL -#include -#include - -static int cmd_telink_reboot(const struct shell * shell, size_t argc, char ** argv) -{ - ARG_UNUSED(argc); - ARG_UNUSED(argv); - - shell_print(shell, "Performing board reboot..."); - sys_reboot(); -} - -SHELL_STATIC_SUBCMD_SET_CREATE(sub_telink, SHELL_CMD(reboot, NULL, "Reboot board command", cmd_telink_reboot), - SHELL_SUBCMD_SET_END); -SHELL_CMD_REGISTER(telink, &sub_telink, "Telink commands", NULL); -#endif // CONFIG_CHIP_LIB_SHELL - LOG_MODULE_DECLARE(app, CONFIG_CHIP_APP_LOG_LEVEL); -using namespace ::chip; -using namespace ::chip::app; -using namespace ::chip::Credentials; -using namespace ::chip::DeviceLayer; - namespace { -constexpr int kFactoryResetCalcTimeout = 3000; -constexpr int kFactoryResetTriggerCntr = 3; -constexpr int kAppEventQueueSize = 10; -constexpr uint8_t kButtonPushEvent = 1; -constexpr uint8_t kButtonReleaseEvent = 0; -constexpr EndpointId kPccClusterEndpoint = 1; -constexpr EndpointId kOnOffClusterEndpoint = 1; -constexpr uint8_t kDefaultMinLevel = 0; -constexpr uint8_t kDefaultMaxLevel = 254; -constexpr uint32_t kIdentifyBlinkRateMs = 200; -constexpr uint32_t kIdentifyOkayOnRateMs = 50; -constexpr uint32_t kIdentifyOkayOffRateMs = 950; -constexpr uint32_t kIdentifyFinishOnRateMs = 950; -constexpr uint32_t kIdentifyFinishOffRateMs = 50; -constexpr uint32_t kIdentifyChannelChangeRateMs = 1000; -constexpr uint32_t kIdentifyBreatheRateMs = 1000; - -const struct pwm_dt_spec sPwmIdentifySpecGreenLed = LIGHTING_PWM_SPEC_IDENTIFY_GREEN; - -#if CONFIG_CHIP_FACTORY_DATA -// NOTE! This key is for test/certification only and should not be available in production devices! -uint8_t sTestEventTriggerEnableKey[TestEventTriggerDelegate::kEnableKeyLength] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, - 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }; -#endif - -K_MSGQ_DEFINE(sAppEventQueue, sizeof(AppEvent), kAppEventQueueSize, alignof(AppEvent)); -k_timer sFactoryResetTimer; -uint8_t sFactoryResetCntr = 0; +constexpr EndpointId kPccClusterEndpoint = 1; +constexpr EndpointId kOnOffClusterEndpoint = 1; #if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED -LEDWidget sStatusLED; LEDWidget sPumpStateLED; #endif - -Button sFactoryResetButton; -Button sPumpButton; -Button sThreadStartButton; -Button sBleAdvStartButton; - -bool sIsThreadProvisioned = false; -bool sIsThreadEnabled = false; -bool sIsThreadAttached = false; -bool sHaveBLEConnections = false; - -chip::DeviceLayer::DeviceInfoProviderImpl gExampleDeviceInfoProvider; - -void OnIdentifyTriggerEffect(Identify * identify) -{ - AppTask::IdentifyEffectHandler(identify->mCurrentEffectIdentifier); -} - -Identify sIdentify = { - kOnOffClusterEndpoint, - [](Identify *) { ChipLogProgress(Zcl, "OnIdentifyStart"); }, - [](Identify *) { ChipLogProgress(Zcl, "OnIdentifyStop"); }, - EMBER_ZCL_IDENTIFY_IDENTIFY_TYPE_VISIBLE_LED, - OnIdentifyTriggerEffect, -}; - } // namespace AppTask AppTask::sAppTask; -class AppFabricTableDelegate : public FabricTable::Delegate -{ - void OnFabricRemoved(const FabricTable & fabricTable, FabricIndex fabricIndex) - { - if (chip::Server::GetInstance().GetFabricTable().FabricCount() == 0) - { - chip::Server::GetInstance().ScheduleFactoryReset(); - } - } -}; - CHIP_ERROR AppTask::Init(void) { - LOG_INF("SW Version: %u, %s", CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION, CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING); +#if APP_USE_EXAMPLE_START_BUTTON + SetExampleButtonCallbacks(StartActionEventHandler); +#endif + InitCommonParts(); - // Initialize status LED #if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED - LEDWidget::InitGpio(LEDS_PORT); - LEDWidget::SetStateUpdateCallback(LEDStateUpdateHandler); - sStatusLED.Init(SYSTEM_STATE_LED); - - UpdateStatusLED(); - sPumpStateLED.Init(PUMP_STATE_LED); sPumpStateLED.Set(!PumpMgr().IsStopped()); #endif - InitButtons(); - - // Initialize function button timer - k_timer_init(&sFactoryResetTimer, &AppTask::FactoryResetTimerTimeoutCallback, nullptr); - k_timer_user_data_set(&sFactoryResetTimer, this); - - // Initialize PWM Identify led - CHIP_ERROR err = sAppTask.mPwmIdentifyLed.Init(&sPwmIdentifySpecGreenLed, kDefaultMinLevel, kDefaultMaxLevel, kDefaultMaxLevel); - if (err != CHIP_NO_ERROR) - { - LOG_ERR("Green IDENTIFY PWM Device Init fail"); - return err; - } - - sAppTask.mPwmIdentifyLed.SetCallbacks(nullptr, nullptr, ActionIdentifyStateUpdateHandler); - PumpMgr().Init(); PumpMgr().SetCallbacks(ActionInitiated, ActionCompleted); - // Initialize CHIP server -#if CONFIG_CHIP_FACTORY_DATA - ReturnErrorOnFailure(mFactoryDataProvider.Init()); - SetDeviceInstanceInfoProvider(&mFactoryDataProvider); - SetDeviceAttestationCredentialsProvider(&mFactoryDataProvider); - SetCommissionableDataProvider(&mFactoryDataProvider); - // Read EnableKey from the factory data. - MutableByteSpan enableKey(sTestEventTriggerEnableKey); - err = mFactoryDataProvider.GetEnableKey(enableKey); - if (err != CHIP_NO_ERROR) - { - LOG_ERR("mFactoryDataProvider.GetEnableKey() failed. Could not delegate a test event trigger"); - memset(sTestEventTriggerEnableKey, 0, sizeof(sTestEventTriggerEnableKey)); - } -#else - SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); -#endif - - static CommonCaseDeviceServerInitParams initParams; - (void) initParams.InitializeStaticResourcesBeforeServerInit(); - ReturnErrorOnFailure(chip::Server::GetInstance().Init(initParams)); - gExampleDeviceInfoProvider.SetStorageDelegate(&Server::GetInstance().GetPersistentStorage()); - chip::DeviceLayer::SetDeviceInfoProvider(&gExampleDeviceInfoProvider); - -#if CONFIG_CHIP_OTA_REQUESTOR - InitBasicOTARequestor(); -#endif - - 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); - - err = ConnectivityMgr().SetBLEDeviceName("Telink Pump Controller"); + CHIP_ERROR err = ConnectivityMgr().SetBLEDeviceName("Telink Pump Controller"); if (err != CHIP_NO_ERROR) { LOG_ERR("SetBLEDeviceName fail"); return err; } - err = chip::Server::GetInstance().GetFabricTable().AddFabricDelegate(new AppFabricTableDelegate); - if (err != CHIP_NO_ERROR) - { - LOG_ERR("AppFabricTableDelegate fail"); - return err; - } - return CHIP_NO_ERROR; } -CHIP_ERROR AppTask::StartApp(void) -{ - CHIP_ERROR err = Init(); - - if (err != CHIP_NO_ERROR) - { - LOG_ERR("AppTask Init fail"); - return err; - } - - AppEvent event = {}; - - while (true) - { - k_msgq_get(&sAppEventQueue, &event, K_FOREVER); - DispatchEvent(&event); - } -} - -void AppTask::IdentifyEffectHandler(EmberAfIdentifyEffectIdentifier aEffect) -{ - AppEvent event; - event.Type = AppEvent::kEventType_IdentifyStart; - - switch (aEffect) - { - case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BLINK: - ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BLINK"); - event.Handler = [](AppEvent *) { - sAppTask.mPwmIdentifyLed.InitiateBlinkAction(kIdentifyBlinkRateMs, kIdentifyBlinkRateMs); - }; - break; - case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BREATHE: - ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BREATHE"); - event.Handler = [](AppEvent *) { - sAppTask.mPwmIdentifyLed.InitiateBreatheAction(PWMDevice::kBreatheType_Both, kIdentifyBreatheRateMs); - }; - break; - case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_OKAY: - ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_OKAY"); - event.Handler = [](AppEvent *) { - sAppTask.mPwmIdentifyLed.InitiateBlinkAction(kIdentifyOkayOnRateMs, kIdentifyOkayOffRateMs); - }; - break; - case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_CHANNEL_CHANGE: - ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_CHANNEL_CHANGE"); - event.Handler = [](AppEvent *) { - sAppTask.mPwmIdentifyLed.InitiateBlinkAction(kIdentifyChannelChangeRateMs, kIdentifyChannelChangeRateMs); - }; - break; - case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_FINISH_EFFECT: - ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_FINISH_EFFECT"); - event.Handler = [](AppEvent *) { - sAppTask.mPwmIdentifyLed.InitiateBlinkAction(kIdentifyFinishOnRateMs, kIdentifyFinishOffRateMs); - }; - break; - case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_STOP_EFFECT: - ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_STOP_EFFECT"); - event.Handler = [](AppEvent *) { sAppTask.mPwmIdentifyLed.StopAction(); }; - event.Type = AppEvent::kEventType_IdentifyStop; - break; - default: - ChipLogProgress(Zcl, "No identifier effect"); - return; - } - - sAppTask.PostEvent(&event); -} - -void AppTask::StartActionButtonEventHandler(void) -{ - AppEvent event; - - event.Type = AppEvent::kEventType_Button; - event.ButtonEvent.Action = kButtonPushEvent; - event.Handler = StartActionEventHandler; - sAppTask.PostEvent(&event); -} - void AppTask::StartActionEventHandler(AppEvent * aEvent) { PumpManager::Action_t action = PumpManager::INVALID_ACTION; @@ -328,176 +77,6 @@ void AppTask::StartActionEventHandler(AppEvent * aEvent) LOG_INF("Action is already in progress or active."); } -void AppTask::FactoryResetButtonEventHandler(void) -{ - AppEvent event; - - event.Type = AppEvent::kEventType_Button; - event.ButtonEvent.Action = kButtonPushEvent; - event.Handler = FactoryResetHandler; - sAppTask.PostEvent(&event); -} - -void AppTask::FactoryResetHandler(AppEvent * aEvent) -{ - if (sFactoryResetCntr == 0) - { - k_timer_start(&sFactoryResetTimer, K_MSEC(kFactoryResetCalcTimeout), K_NO_WAIT); - } - - sFactoryResetCntr++; - LOG_INF("Factory Reset Trigger Counter: %d/%d", sFactoryResetCntr, kFactoryResetTriggerCntr); - - if (sFactoryResetCntr == kFactoryResetTriggerCntr) - { - k_timer_stop(&sFactoryResetTimer); - sFactoryResetCntr = 0; - - chip::Server::GetInstance().ScheduleFactoryReset(); - } -} - -void AppTask::StartThreadButtonEventHandler(void) -{ - AppEvent event; - - event.Type = AppEvent::kEventType_Button; - event.ButtonEvent.Action = kButtonPushEvent; - event.Handler = StartThreadHandler; - sAppTask.PostEvent(&event); -} - -void AppTask::StartThreadHandler(AppEvent * aEvent) -{ - LOG_INF("StartThreadHandler"); - if (!chip::DeviceLayer::ConnectivityMgr().IsThreadProvisioned()) - { - // Switch context from BLE to Thread - Internal::BLEManagerImpl sInstance; - sInstance.SwitchToIeee802154(); - StartDefaultThreadNetwork(); - } - else - { - LOG_INF("Device already commissioned"); - } -} - -void AppTask::StartBleAdvButtonEventHandler(void) -{ - AppEvent event; - - event.Type = AppEvent::kEventType_Button; - event.ButtonEvent.Action = kButtonPushEvent; - event.Handler = StartBleAdvHandler; - sAppTask.PostEvent(&event); -} - -void AppTask::StartBleAdvHandler(AppEvent * aEvent) -{ - LOG_INF("StartBleAdvHandler"); - - // Don't allow on starting Matter service BLE advertising after Thread provisioning. - if (ConnectivityMgr().IsThreadProvisioned()) - { - LOG_INF("Device already commissioned"); - return; - } - - if (ConnectivityMgr().IsBLEAdvertisingEnabled()) - { - LOG_INF("BLE adv already enabled"); - return; - } - - if (chip::Server::GetInstance().GetCommissioningWindowManager().OpenBasicCommissioningWindow() != CHIP_NO_ERROR) - { - LOG_ERR("OpenBasicCommissioningWindow fail"); - } -} - -#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED -void AppTask::UpdateLedStateEventHandler(AppEvent * aEvent) -{ - if (aEvent->Type == AppEvent::kEventType_UpdateLedState) - { - aEvent->UpdateLedStateEvent.LedWidget->UpdateState(); - } -} - -void AppTask::LEDStateUpdateHandler(LEDWidget * ledWidget) -{ - AppEvent event; - event.Type = AppEvent::kEventType_UpdateLedState; - event.Handler = UpdateLedStateEventHandler; - event.UpdateLedStateEvent.LedWidget = ledWidget; - sAppTask.PostEvent(&event); -} - -void AppTask::UpdateStatusLED(void) -{ - if (sIsThreadProvisioned && sIsThreadEnabled) - { - if (sIsThreadAttached) - { - sStatusLED.Blink(950, 50); - } - else - { - sStatusLED.Blink(100, 100); - } - } - else - { - sStatusLED.Blink(50, 950); - } -} -#endif - -void AppTask::ChipEventHandler(const ChipDeviceEvent * event, intptr_t /* arg */) -{ - switch (event->Type) - { - case DeviceEventType::kCHIPoBLEAdvertisingChange: - sHaveBLEConnections = ConnectivityMgr().NumBLEConnections() != 0; -#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED - UpdateStatusLED(); -#endif - break; - case DeviceEventType::kThreadStateChange: - sIsThreadProvisioned = ConnectivityMgr().IsThreadProvisioned(); - sIsThreadEnabled = ConnectivityMgr().IsThreadEnabled(); - sIsThreadAttached = ConnectivityMgr().IsThreadAttached(); -#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED - UpdateStatusLED(); -#endif - break; - case DeviceEventType::kThreadConnectivityChange: -#if CONFIG_CHIP_OTA_REQUESTOR - if (event->ThreadConnectivityChange.Result == kConnectivity_Established) - { - InitBasicOTARequestor(); - } -#endif - break; - default: - break; - } -} - -void AppTask::ActionIdentifyStateUpdateHandler(k_timer * timer) -{ - AppEvent event; - event.Type = AppEvent::kEventType_UpdateLedState; - event.Handler = UpdateIdentifyStateEventHandler; - sAppTask.PostEvent(&event); -} - -void AppTask::UpdateIdentifyStateEventHandler(AppEvent * aEvent) -{ - sAppTask.mPwmIdentifyLed.UpdateAction(); -} - void AppTask::ActionInitiated(PumpManager::Action_t action, int32_t actor) { // If the action has been initiated by the pump, update the pump trait @@ -511,7 +90,9 @@ void AppTask::ActionInitiated(PumpManager::Action_t action, int32_t actor) LOG_INF("Pump Stop Action has been initiated"); } +#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED sPumpStateLED.Blink(50, 50); +#endif } void AppTask::ActionCompleted(PumpManager::Action_t action, int32_t actor) @@ -522,12 +103,16 @@ void AppTask::ActionCompleted(PumpManager::Action_t action, int32_t actor) if (action == PumpManager::START_ACTION) { LOG_INF("Pump Start Action has been completed"); +#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED sPumpStateLED.Set(true); +#endif } else if (action == PumpManager::STOP_ACTION) { LOG_INF("Pump Stop Action has been completed"); +#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED sPumpStateLED.Set(false); +#endif } if (actor == static_cast(AppEvent::kEventType_Button)) @@ -546,67 +131,4 @@ void AppTask::PostStartActionRequest(int32_t actor, PumpManager::Action_t action sAppTask.PostEvent(&event); } -void AppTask::PostEvent(AppEvent * aEvent) -{ - if (k_msgq_put(&sAppEventQueue, aEvent, K_NO_WAIT) != 0) - { - LOG_INF("PostEvent fail"); - } -} - -void AppTask::DispatchEvent(AppEvent * aEvent) -{ - if (aEvent->Handler) - { - aEvent->Handler(aEvent); - } - else - { - LOG_INF("Dropping event without handler"); - } -} - void AppTask::UpdateClusterState() {} - -void AppTask::FactoryResetTimerTimeoutCallback(k_timer * timer) -{ - if (!timer) - { - return; - } - - AppEvent event; - event.Type = AppEvent::kEventType_Timer; - event.Handler = FactoryResetTimerEventHandler; - sAppTask.PostEvent(&event); -} - -void AppTask::FactoryResetTimerEventHandler(AppEvent * aEvent) -{ - if (aEvent->Type != AppEvent::kEventType_Timer) - { - return; - } - - sFactoryResetCntr = 0; - LOG_INF("Factory Reset Trigger Counter is cleared"); -} - -void AppTask::InitButtons(void) -{ -#if CONFIG_CHIP_BUTTON_MANAGER_IRQ_MODE - sFactoryResetButton.Configure(BUTTON_PORT, BUTTON_PIN_1, FactoryResetButtonEventHandler); - sPumpButton.Configure(BUTTON_PORT, BUTTON_PIN_2, StartActionButtonEventHandler); - sThreadStartButton.Configure(BUTTON_PORT, BUTTON_PIN_3, StartThreadButtonEventHandler); - sBleAdvStartButton.Configure(BUTTON_PORT, BUTTON_PIN_4, StartBleAdvButtonEventHandler); -#else - sFactoryResetButton.Configure(BUTTON_PORT, BUTTON_PIN_3, BUTTON_PIN_1, FactoryResetButtonEventHandler); - sPumpButton.Configure(BUTTON_PORT, BUTTON_PIN_4, BUTTON_PIN_1, StartActionButtonEventHandler); - sThreadStartButton.Configure(BUTTON_PORT, BUTTON_PIN_3, BUTTON_PIN_2, StartThreadButtonEventHandler); - sBleAdvStartButton.Configure(BUTTON_PORT, BUTTON_PIN_4, BUTTON_PIN_2, StartBleAdvButtonEventHandler); -#endif - ButtonManagerInst().AddButton(sFactoryResetButton); - ButtonManagerInst().AddButton(sPumpButton); - ButtonManagerInst().AddButton(sThreadStartButton); - ButtonManagerInst().AddButton(sBleAdvStartButton); -} diff --git a/examples/pump-controller-app/telink/src/PumpManager.cpp b/examples/pump-controller-app/telink/src/PumpManager.cpp index 18b7e655cabaf7..1c2a6ee693d607 100644 --- a/examples/pump-controller-app/telink/src/PumpManager.cpp +++ b/examples/pump-controller-app/telink/src/PumpManager.cpp @@ -135,9 +135,9 @@ void PumpManager::TimerEventHandler(k_timer * timer) GetAppTask().PostEvent(&event); } -void PumpManager::AutoRestartTimerEventHandler(const AppEvent & aEvent) +void PumpManager::AutoRestartTimerEventHandler(AppEvent * aEvent) { - PumpManager * pump = static_cast(aEvent.TimerEvent.Context); + PumpManager * pump = static_cast(aEvent->TimerEvent.Context); int32_t actor = 0; // Make sure auto start timer is still armed. @@ -151,11 +151,11 @@ void PumpManager::AutoRestartTimerEventHandler(const AppEvent & aEvent) pump->InitiateAction(actor, START_ACTION); } -void PumpManager::PumpStartTimerEventHandler(const AppEvent & aEvent) +void PumpManager::PumpStartTimerEventHandler(AppEvent * aEvent) { Action_t actionCompleted = INVALID_ACTION; - PumpManager * pump = static_cast(aEvent.TimerEvent.Context); + PumpManager * pump = static_cast(aEvent->TimerEvent.Context); if (pump->mState == kState_StartInitiated) { diff --git a/examples/pump-controller-app/telink/src/main.cpp b/examples/pump-controller-app/telink/src/main.cpp deleted file mode 100644 index 71aa52f9d91901..00000000000000 --- a/examples/pump-controller-app/telink/src/main.cpp +++ /dev/null @@ -1,82 +0,0 @@ -/* - * - * Copyright (c) 2023 Project CHIP Authors - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "AppTask.h" - -#include -#include - -#include - -LOG_MODULE_REGISTER(app, CONFIG_CHIP_APP_LOG_LEVEL); - -using namespace ::chip; -using namespace ::chip::Inet; -using namespace ::chip::DeviceLayer; - -int main(void) -{ - CHIP_ERROR err = CHIP_NO_ERROR; - - err = chip::Platform::MemoryInit(); - if (err != CHIP_NO_ERROR) - { - LOG_ERR("MemoryInit fail"); - goto exit; - } - - err = PlatformMgr().InitChipStack(); - if (err != CHIP_NO_ERROR) - { - LOG_ERR("InitChipStack fail"); - goto exit; - } - - err = PlatformMgr().StartEventLoopTask(); - if (err != CHIP_NO_ERROR) - { - LOG_ERR("StartEventLoopTask fail"); - goto exit; - } - - err = ThreadStackMgr().InitThreadStack(); - if (err != CHIP_NO_ERROR) - { - LOG_ERR("InitThreadStack fail"); - goto exit; - } - -#ifdef CONFIG_OPENTHREAD_MTD_SED - err = ConnectivityMgr().SetThreadDeviceType(ConnectivityManager::kThreadDeviceType_SleepyEndDevice); -#elif CONFIG_OPENTHREAD_MTD - err = ConnectivityMgr().SetThreadDeviceType(ConnectivityManager::kThreadDeviceType_MinimalEndDevice); -#else - err = ConnectivityMgr().SetThreadDeviceType(ConnectivityManager::kThreadDeviceType_Router); -#endif - if (err != CHIP_NO_ERROR) - { - LOG_ERR("SetThreadDeviceType fail"); - goto exit; - } - - err = GetAppTask().StartApp(); - -exit: - LOG_ERR("Exit err %" CHIP_ERROR_FORMAT, err.Format()); - return (err == CHIP_NO_ERROR) ? EXIT_SUCCESS : EXIT_FAILURE; -} diff --git a/examples/temperature-measurement-app/telink/CMakeLists.txt b/examples/temperature-measurement-app/telink/CMakeLists.txt index 04233bf515e522..022eef1d319bce 100644 --- a/examples/temperature-measurement-app/telink/CMakeLists.txt +++ b/examples/temperature-measurement-app/telink/CMakeLists.txt @@ -59,6 +59,7 @@ target_include_directories(app PRIVATE include ${GEN_DIR}/app-common ${GEN_DIR}/temperature-measurement-app + ${TELINK_COMMON}/common/include ${TELINK_COMMON}/util/include ${TELINK_COMMON}/app/include ) @@ -70,7 +71,8 @@ add_definitions( target_sources(app PRIVATE src/AppTask.cpp src/SensorManager.cpp - src/main.cpp + ${TELINK_COMMON}/common/src/mainCommon.cpp + ${TELINK_COMMON}/common/src/AppTaskCommon.cpp ${TELINK_COMMON}/util/src/LEDWidget.cpp ${TELINK_COMMON}/util/src/ButtonManager.cpp ${TELINK_COMMON}/util/src/ThreadUtil.cpp diff --git a/examples/temperature-measurement-app/telink/include/AppConfig.h b/examples/temperature-measurement-app/telink/include/AppConfig.h index f3daa577c44063..c2955144027fb2 100644 --- a/examples/temperature-measurement-app/telink/include/AppConfig.h +++ b/examples/temperature-measurement-app/telink/include/AppConfig.h @@ -20,14 +20,10 @@ // ---- Temperature measurement Example App Config ---- -// Buttons config -#define BUTTON_PORT DEVICE_DT_GET(DT_NODELABEL(gpioc)) +#define APP_USE_EXAMPLE_START_BUTTON 0 +#define APP_USE_THREAD_START_BUTTON 1 +#define APP_SET_DEVICE_INFO_PROVIDER 1 +#define APP_SET_NETWORK_COMM_ENDPOINT_SEC 0 +#define APP_USE_IDENTIFY_PWM 0 // APP_USE_IDENTIFY_PWM must be defined before including "AppConfigCommon.h" -#define BUTTON_PIN_1 2 -#define BUTTON_PIN_3 3 -#define BUTTON_PIN_4 1 -#define BUTTON_PIN_2 0 - -// LEDs config -#define LEDS_PORT DEVICE_DT_GET(DT_NODELABEL(gpiob)) -#define SYSTEM_STATE_LED 7 +#include "AppConfigCommon.h" diff --git a/examples/temperature-measurement-app/telink/include/AppEvent.h b/examples/temperature-measurement-app/telink/include/AppEvent.h deleted file mode 100644 index d38fb150212a85..00000000000000 --- a/examples/temperature-measurement-app/telink/include/AppEvent.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * - * Copyright (c) 2023 Project CHIP Authors - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include - -struct AppEvent; -typedef void (*EventHandler)(AppEvent *); - -class LEDWidget; - -struct AppEvent -{ - enum AppEventTypes - { - kEventType_Button = 0, - kEventType_Timer, - kEventType_UpdateLedState, - kEventType_Install, - }; - - uint16_t Type; - - union - { - struct - { - uint8_t Action; - } ButtonEvent; - struct - { - void * Context; - } TimerEvent; - struct - { - LEDWidget * LedWidget; - } UpdateLedStateEvent; - }; - - EventHandler Handler; -}; diff --git a/examples/temperature-measurement-app/telink/include/AppTask.h b/examples/temperature-measurement-app/telink/include/AppTask.h index b67d2ee6f1944a..f681fa37fa2378 100644 --- a/examples/temperature-measurement-app/telink/include/AppTask.h +++ b/examples/temperature-measurement-app/telink/include/AppTask.h @@ -18,65 +18,20 @@ #pragma once -#include "AppConfig.h" -#include "AppEvent.h" -#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED -#include "LEDWidget.h" -#endif -#include "PWMDevice.h" -#include +#include "AppTaskCommon.h" -#if CONFIG_CHIP_FACTORY_DATA -#include -#endif - -#include - -struct k_timer; - -class AppTask +class AppTask : public AppTaskCommon { -public: - CHIP_ERROR StartApp(void); - - void SetInitiateAction(PWMDevice::Action_t aAction, int32_t aActor, uint8_t * value); - void PostEvent(AppEvent * aEvent); - private: friend AppTask & GetAppTask(void); - CHIP_ERROR Init(void); - - void DispatchEvent(AppEvent * event); + friend class AppTaskCommon; -#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED - static void UpdateLedStateEventHandler(AppEvent * aEvent); - static void LEDStateUpdateHandler(LEDWidget * ledWidget); - static void UpdateStatusLED(); -#endif - static void FactoryResetButtonEventHandler(void); - static void StartThreadButtonEventHandler(void); - static void StartBleAdvButtonEventHandler(void); - - static void ChipEventHandler(const chip::DeviceLayer::ChipDeviceEvent * event, intptr_t arg); + CHIP_ERROR Init(void); static void TemperatureMeasurementTimerTimeoutCallback(k_timer * timer); static void TemperatureMeasurementTimerEventHandler(AppEvent * aEvent); - static void FactoryResetTimerTimeoutCallback(k_timer * timer); - static void FactoryResetTimerEventHandler(AppEvent * aEvent); - static void FactoryResetHandler(AppEvent * aEvent); - static void StartThreadHandler(AppEvent * aEvent); - static void StartBleAdvHandler(AppEvent * aEvent); - - static void InitButtons(void); - - static void ThreadProvisioningHandler(const chip::DeviceLayer::ChipDeviceEvent * event, intptr_t arg); - static AppTask sAppTask; - -#if CONFIG_CHIP_FACTORY_DATA - chip::DeviceLayer::FactoryDataProvider mFactoryDataProvider; -#endif }; inline AppTask & GetAppTask(void) diff --git a/examples/temperature-measurement-app/telink/include/SensorManager.h b/examples/temperature-measurement-app/telink/include/SensorManager.h index b7059808601010..df1ffcf9378657 100644 --- a/examples/temperature-measurement-app/telink/include/SensorManager.h +++ b/examples/temperature-measurement-app/telink/include/SensorManager.h @@ -21,7 +21,7 @@ #include #include -#include "AppEvent.h" +#include "AppEventCommon.h" #include #include diff --git a/examples/temperature-measurement-app/telink/src/AppTask.cpp b/examples/temperature-measurement-app/telink/src/AppTask.cpp index 9d84f94fa98d9b..38d99ed3b190ab 100644 --- a/examples/temperature-measurement-app/telink/src/AppTask.cpp +++ b/examples/temperature-measurement-app/telink/src/AppTask.cpp @@ -17,172 +17,26 @@ */ #include "AppTask.h" - -#include "AppConfig.h" -#include "AppEvent.h" -#include "ButtonManager.h" #include "SensorManager.h" -#include "ThreadUtil.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -#if CONFIG_CHIP_OTA_REQUESTOR -#include "OTAUtil.h" -#endif - -#include -#include - -#include - -#if CONFIG_CHIP_LIB_SHELL -#include -#include - -static int cmd_telink_reboot(const struct shell * shell, size_t argc, char ** argv) -{ - ARG_UNUSED(argc); - ARG_UNUSED(argv); - - shell_print(shell, "Performing board reboot..."); - sys_reboot(); -} - -SHELL_STATIC_SUBCMD_SET_CREATE(sub_telink, SHELL_CMD(reboot, NULL, "Reboot board command", cmd_telink_reboot), - SHELL_SUBCMD_SET_END); -SHELL_CMD_REGISTER(telink, &sub_telink, "Telink commands", NULL); -#endif // CONFIG_CHIP_LIB_SHELL - LOG_MODULE_DECLARE(app, CONFIG_CHIP_APP_LOG_LEVEL); -using namespace ::chip; -using namespace ::chip::app; -using namespace ::chip::Credentials; -using namespace ::chip::DeviceLayer; - namespace { -constexpr int kFactoryResetCalcTimeout = 3000; -constexpr int kFactoryResetTriggerCntr = 3; -constexpr int kAppEventQueueSize = 10; -constexpr uint8_t kButtonPushEvent = 1; -constexpr uint8_t kButtonReleaseEvent = 0; -constexpr EndpointId kEndpointId = 1; -constexpr uint8_t kDefaultMinLevel = 0; -constexpr uint8_t kDefaultMaxLevel = 254; - -#if CONFIG_CHIP_FACTORY_DATA -// NOTE! This key is for test/certification only and should not be available in production devices! -uint8_t sTestEventTriggerEnableKey[TestEventTriggerDelegate::kEnableKeyLength] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, - 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }; -#endif - -K_MSGQ_DEFINE(sAppEventQueue, sizeof(AppEvent), kAppEventQueueSize, alignof(AppEvent)); -k_timer sFactoryResetTimer; -uint8_t sFactoryResetCntr = 0; - k_timer sTemperatureMeasurementTimer; constexpr uint16_t kSensorTimerPeriodMs = 5000; // 5s timer period - -#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED -LEDWidget sStatusLED; -#endif - -Button sFactoryResetButton; -Button sThreadStartButton; -Button sBleAdvStartButton; - -bool sIsThreadProvisioned = false; -bool sIsThreadEnabled = false; -bool sIsThreadAttached = false; -bool sHaveBLEConnections = false; - -chip::DeviceLayer::DeviceInfoProviderImpl gExampleDeviceInfoProvider; - } // namespace AppTask AppTask::sAppTask; -class AppFabricTableDelegate : public FabricTable::Delegate -{ - void OnFabricRemoved(const FabricTable & fabricTable, FabricIndex fabricIndex) - { - if (chip::Server::GetInstance().GetFabricTable().FabricCount() == 0) - { - chip::Server::GetInstance().ScheduleFactoryReset(); - } - } -}; - CHIP_ERROR AppTask::Init(void) { - LOG_INF("SW Version: %u, %s", CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION, CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING); - - // Initialize LEDs -#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED - LEDWidget::InitGpio(LEDS_PORT); - LEDWidget::SetStateUpdateCallback(LEDStateUpdateHandler); - - sStatusLED.Init(SYSTEM_STATE_LED); - - UpdateStatusLED(); -#endif - - InitButtons(); - - // Initialize function button timer - k_timer_init(&sFactoryResetTimer, &AppTask::FactoryResetTimerTimeoutCallback, nullptr); - k_timer_user_data_set(&sFactoryResetTimer, this); + InitCommonParts(); // Initialize temperature measurement timer k_timer_init(&sTemperatureMeasurementTimer, &AppTask::TemperatureMeasurementTimerTimeoutCallback, nullptr); k_timer_user_data_set(&sTemperatureMeasurementTimer, this); k_timer_start(&sTemperatureMeasurementTimer, K_MSEC(kSensorTimerPeriodMs), K_NO_WAIT); - // Initialize CHIP server -#if CONFIG_CHIP_FACTORY_DATA - ReturnErrorOnFailure(mFactoryDataProvider.Init()); - SetDeviceInstanceInfoProvider(&mFactoryDataProvider); - SetDeviceAttestationCredentialsProvider(&mFactoryDataProvider); - SetCommissionableDataProvider(&mFactoryDataProvider); - // Read EnableKey from the factory data. - MutableByteSpan enableKey(sTestEventTriggerEnableKey); - err = mFactoryDataProvider.GetEnableKey(enableKey); - if (err != CHIP_NO_ERROR) - { - LOG_ERR("GetEnableKey fail"); - memset(sTestEventTriggerEnableKey, 0, sizeof(sTestEventTriggerEnableKey)); - } -#else - SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); -#endif - - static CommonCaseDeviceServerInitParams initParams; - (void) initParams.InitializeStaticResourcesBeforeServerInit(); - ReturnErrorOnFailure(chip::Server::GetInstance().Init(initParams)); - - gExampleDeviceInfoProvider.SetStorageDelegate(&Server::GetInstance().GetPersistentStorage()); - chip::DeviceLayer::SetDeviceInfoProvider(&gExampleDeviceInfoProvider); - -#if CONFIG_CHIP_OTA_REQUESTOR - InitBasicOTARequestor(); -#endif - - 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); - // Init Temperature Sensor CHIP_ERROR err = SensorMgr().Init(); if (err != CHIP_NO_ERROR) @@ -192,8 +46,8 @@ CHIP_ERROR AppTask::Init(void) } PlatformMgr().LockChipStack(); - app::Clusters::TemperatureMeasurement::Attributes::MinMeasuredValue::Set(kEndpointId, SensorMgr().GetMinMeasuredValue()); - app::Clusters::TemperatureMeasurement::Attributes::MaxMeasuredValue::Set(kEndpointId, SensorMgr().GetMaxMeasuredValue()); + app::Clusters::TemperatureMeasurement::Attributes::MinMeasuredValue::Set(kExampleEndpointId, SensorMgr().GetMinMeasuredValue()); + app::Clusters::TemperatureMeasurement::Attributes::MaxMeasuredValue::Set(kExampleEndpointId, SensorMgr().GetMaxMeasuredValue()); PlatformMgr().UnlockChipStack(); err = ConnectivityMgr().SetBLEDeviceName("TelinkTerm"); @@ -203,212 +57,9 @@ CHIP_ERROR AppTask::Init(void) return err; } - err = chip::Server::GetInstance().GetFabricTable().AddFabricDelegate(new AppFabricTableDelegate); - if (err != CHIP_NO_ERROR) - { - LOG_ERR("AppFabricTableDelegate fail"); - return err; - } - return CHIP_NO_ERROR; } -CHIP_ERROR AppTask::StartApp(void) -{ - CHIP_ERROR err = Init(); - - if (err != CHIP_NO_ERROR) - { - LOG_ERR("AppTask Init fail"); - return err; - } - - AppEvent event = {}; - - while (true) - { - k_msgq_get(&sAppEventQueue, &event, K_FOREVER); - DispatchEvent(&event); - } -} - -void AppTask::FactoryResetButtonEventHandler(void) -{ - AppEvent event; - - event.Type = AppEvent::kEventType_Button; - event.ButtonEvent.Action = kButtonPushEvent; - event.Handler = FactoryResetHandler; - sAppTask.PostEvent(&event); -} - -void AppTask::FactoryResetHandler(AppEvent * aEvent) -{ - if (sFactoryResetCntr == 0) - { - k_timer_start(&sFactoryResetTimer, K_MSEC(kFactoryResetCalcTimeout), K_NO_WAIT); - } - - sFactoryResetCntr++; - LOG_INF("Factory Reset Trigger Counter: %d/%d", sFactoryResetCntr, kFactoryResetTriggerCntr); - - if (sFactoryResetCntr == kFactoryResetTriggerCntr) - { - k_timer_stop(&sFactoryResetTimer); - sFactoryResetCntr = 0; - - chip::Server::GetInstance().ScheduleFactoryReset(); - } -} - -void AppTask::StartThreadButtonEventHandler(void) -{ - AppEvent event; - - event.Type = AppEvent::kEventType_Button; - event.ButtonEvent.Action = kButtonPushEvent; - event.Handler = StartThreadHandler; - sAppTask.PostEvent(&event); -} - -void AppTask::StartThreadHandler(AppEvent * aEvent) -{ - LOG_INF("StartThreadHandler"); - if (!chip::DeviceLayer::ConnectivityMgr().IsThreadProvisioned()) - { - // Switch context from BLE to Thread - Internal::BLEManagerImpl sInstance; - sInstance.SwitchToIeee802154(); - StartDefaultThreadNetwork(); - } - else - { - LOG_INF("Device already commissioned"); - } -} - -void AppTask::StartBleAdvButtonEventHandler(void) -{ - AppEvent event; - - event.Type = AppEvent::kEventType_Button; - event.ButtonEvent.Action = kButtonPushEvent; - event.Handler = StartBleAdvHandler; - sAppTask.PostEvent(&event); -} - -void AppTask::StartBleAdvHandler(AppEvent * aEvent) -{ - LOG_INF("StartBleAdvHandler"); - - // Don't allow on starting Matter service BLE advertising after Thread provisioning. - if (ConnectivityMgr().IsThreadProvisioned()) - { - LOG_INF("Device already commissioned"); - return; - } - - if (ConnectivityMgr().IsBLEAdvertisingEnabled()) - { - LOG_INF("BLE adv already enabled"); - return; - } - - if (chip::Server::GetInstance().GetCommissioningWindowManager().OpenBasicCommissioningWindow() != CHIP_NO_ERROR) - { - LOG_ERR("OpenBasicCommissioningWindow fail"); - } -} - -#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED -void AppTask::UpdateLedStateEventHandler(AppEvent * aEvent) -{ - if (aEvent->Type == AppEvent::kEventType_UpdateLedState) - { - aEvent->UpdateLedStateEvent.LedWidget->UpdateState(); - } -} - -void AppTask::LEDStateUpdateHandler(LEDWidget * ledWidget) -{ - AppEvent event; - event.Type = AppEvent::kEventType_UpdateLedState; - event.Handler = UpdateLedStateEventHandler; - event.UpdateLedStateEvent.LedWidget = ledWidget; - sAppTask.PostEvent(&event); -} - -void AppTask::UpdateStatusLED(void) -{ - if (sIsThreadProvisioned && sIsThreadEnabled) - { - if (sIsThreadAttached) - { - sStatusLED.Blink(950, 50); - } - else - { - sStatusLED.Blink(100, 100); - } - } - else - { - sStatusLED.Blink(50, 950); - } -} -#endif - -void AppTask::ChipEventHandler(const ChipDeviceEvent * event, intptr_t /* arg */) -{ - switch (event->Type) - { - case DeviceEventType::kCHIPoBLEAdvertisingChange: - sHaveBLEConnections = ConnectivityMgr().NumBLEConnections() != 0; -#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED - UpdateStatusLED(); -#endif - break; - case DeviceEventType::kThreadStateChange: - sIsThreadProvisioned = ConnectivityMgr().IsThreadProvisioned(); - sIsThreadEnabled = ConnectivityMgr().IsThreadEnabled(); - sIsThreadAttached = ConnectivityMgr().IsThreadAttached(); -#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED - UpdateStatusLED(); -#endif - break; - case DeviceEventType::kThreadConnectivityChange: -#if CONFIG_CHIP_OTA_REQUESTOR - if (event->ThreadConnectivityChange.Result == kConnectivity_Established) - { - InitBasicOTARequestor(); - } -#endif - break; - default: - break; - } -} - -void AppTask::PostEvent(AppEvent * aEvent) -{ - if (k_msgq_put(&sAppEventQueue, aEvent, K_NO_WAIT) != 0) - { - LOG_INF("PostEvent fail"); - } -} - -void AppTask::DispatchEvent(AppEvent * aEvent) -{ - if (aEvent->Handler) - { - aEvent->Handler(aEvent); - } - else - { - LOG_INF("Dropping event without handler"); - } -} - void AppTask::TemperatureMeasurementTimerTimeoutCallback(k_timer * timer) { if (!timer) @@ -430,7 +81,7 @@ void AppTask::TemperatureMeasurementTimerEventHandler(AppEvent * aEvent) } PlatformMgr().LockChipStack(); - app::Clusters::TemperatureMeasurement::Attributes::MeasuredValue::Set(kEndpointId, SensorMgr().GetMeasuredValue()); + app::Clusters::TemperatureMeasurement::Attributes::MeasuredValue::Set(kExampleEndpointId, SensorMgr().GetMeasuredValue()); PlatformMgr().UnlockChipStack(); LOG_INF("Current temperature is (%d*0.01)°C", SensorMgr().GetMeasuredValue()); @@ -438,44 +89,3 @@ void AppTask::TemperatureMeasurementTimerEventHandler(AppEvent * aEvent) // Start next timer to handle temp sensor. k_timer_start(&sTemperatureMeasurementTimer, K_MSEC(kSensorTimerPeriodMs), K_NO_WAIT); } - -void AppTask::FactoryResetTimerTimeoutCallback(k_timer * timer) -{ - if (!timer) - { - return; - } - - AppEvent event; - event.Type = AppEvent::kEventType_Timer; - event.Handler = FactoryResetTimerEventHandler; - sAppTask.PostEvent(&event); -} - -void AppTask::FactoryResetTimerEventHandler(AppEvent * aEvent) -{ - if (aEvent->Type != AppEvent::kEventType_Timer) - { - return; - } - - sFactoryResetCntr = 0; - LOG_INF("Factory Reset Trigger Counter is cleared"); -} - -void AppTask::InitButtons(void) -{ -#if CONFIG_CHIP_BUTTON_MANAGER_IRQ_MODE - sFactoryResetButton.Configure(BUTTON_PORT, BUTTON_PIN_1, FactoryResetButtonEventHandler); - sThreadStartButton.Configure(BUTTON_PORT, BUTTON_PIN_3, StartThreadButtonEventHandler); - sBleAdvStartButton.Configure(BUTTON_PORT, BUTTON_PIN_4, StartBleAdvButtonEventHandler); -#else - sFactoryResetButton.Configure(BUTTON_PORT, BUTTON_PIN_3, BUTTON_PIN_1, FactoryResetButtonEventHandler); - sThreadStartButton.Configure(BUTTON_PORT, BUTTON_PIN_3, BUTTON_PIN_2, StartThreadButtonEventHandler); - sBleAdvStartButton.Configure(BUTTON_PORT, BUTTON_PIN_4, BUTTON_PIN_2, StartBleAdvButtonEventHandler); -#endif - - ButtonManagerInst().AddButton(sFactoryResetButton); - ButtonManagerInst().AddButton(sThreadStartButton); - ButtonManagerInst().AddButton(sBleAdvStartButton); -} diff --git a/examples/temperature-measurement-app/telink/src/SensorManager.cpp b/examples/temperature-measurement-app/telink/src/SensorManager.cpp index b108c59fab83a1..8ab8a42d9cc276 100644 --- a/examples/temperature-measurement-app/telink/src/SensorManager.cpp +++ b/examples/temperature-measurement-app/telink/src/SensorManager.cpp @@ -18,7 +18,6 @@ #include "SensorManager.h" #include "AppConfig.h" -#include "AppEvent.h" #include "AppTask.h" #define TEMPERATURE_SIMULATION_IS_USED diff --git a/examples/temperature-measurement-app/telink/src/main.cpp b/examples/temperature-measurement-app/telink/src/main.cpp deleted file mode 100644 index 71aa52f9d91901..00000000000000 --- a/examples/temperature-measurement-app/telink/src/main.cpp +++ /dev/null @@ -1,82 +0,0 @@ -/* - * - * Copyright (c) 2023 Project CHIP Authors - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "AppTask.h" - -#include -#include - -#include - -LOG_MODULE_REGISTER(app, CONFIG_CHIP_APP_LOG_LEVEL); - -using namespace ::chip; -using namespace ::chip::Inet; -using namespace ::chip::DeviceLayer; - -int main(void) -{ - CHIP_ERROR err = CHIP_NO_ERROR; - - err = chip::Platform::MemoryInit(); - if (err != CHIP_NO_ERROR) - { - LOG_ERR("MemoryInit fail"); - goto exit; - } - - err = PlatformMgr().InitChipStack(); - if (err != CHIP_NO_ERROR) - { - LOG_ERR("InitChipStack fail"); - goto exit; - } - - err = PlatformMgr().StartEventLoopTask(); - if (err != CHIP_NO_ERROR) - { - LOG_ERR("StartEventLoopTask fail"); - goto exit; - } - - err = ThreadStackMgr().InitThreadStack(); - if (err != CHIP_NO_ERROR) - { - LOG_ERR("InitThreadStack fail"); - goto exit; - } - -#ifdef CONFIG_OPENTHREAD_MTD_SED - err = ConnectivityMgr().SetThreadDeviceType(ConnectivityManager::kThreadDeviceType_SleepyEndDevice); -#elif CONFIG_OPENTHREAD_MTD - err = ConnectivityMgr().SetThreadDeviceType(ConnectivityManager::kThreadDeviceType_MinimalEndDevice); -#else - err = ConnectivityMgr().SetThreadDeviceType(ConnectivityManager::kThreadDeviceType_Router); -#endif - if (err != CHIP_NO_ERROR) - { - LOG_ERR("SetThreadDeviceType fail"); - goto exit; - } - - err = GetAppTask().StartApp(); - -exit: - LOG_ERR("Exit err %" CHIP_ERROR_FORMAT, err.Format()); - return (err == CHIP_NO_ERROR) ? EXIT_SUCCESS : EXIT_FAILURE; -} diff --git a/examples/thermostat/telink/CMakeLists.txt b/examples/thermostat/telink/CMakeLists.txt index e42891919e8b59..63744747849bfe 100755 --- a/examples/thermostat/telink/CMakeLists.txt +++ b/examples/thermostat/telink/CMakeLists.txt @@ -59,6 +59,7 @@ target_include_directories(app PRIVATE include ${GEN_DIR}/app-common ${GEN_DIR}/thermostat + ${TELINK_COMMON}/common/include ${TELINK_COMMON}/util/include ${TELINK_COMMON}/app/include) @@ -70,8 +71,9 @@ target_sources(app PRIVATE src/AppTask.cpp src/SensorManager.cpp src/TemperatureManager.cpp - src/main.cpp src/ZclCallbacks.cpp + ${TELINK_COMMON}/common/src/mainCommon.cpp + ${TELINK_COMMON}/common/src/AppTaskCommon.cpp ${TELINK_COMMON}/util/src/LEDWidget.cpp ${TELINK_COMMON}/util/src/ButtonManager.cpp ${TELINK_COMMON}/util/src/ThreadUtil.cpp diff --git a/examples/thermostat/telink/include/AppConfig.h b/examples/thermostat/telink/include/AppConfig.h old mode 100755 new mode 100644 index 4e023cca312073..4b74db57e3091d --- a/examples/thermostat/telink/include/AppConfig.h +++ b/examples/thermostat/telink/include/AppConfig.h @@ -20,15 +20,10 @@ // ---- Thermostat Example App Config ---- -// Buttons config -#define BUTTON_PORT DEVICE_DT_GET(DT_NODELABEL(gpioc)) +#define APP_USE_EXAMPLE_START_BUTTON 0 +#define APP_USE_THREAD_START_BUTTON 1 +#define APP_SET_DEVICE_INFO_PROVIDER 1 +#define APP_SET_NETWORK_COMM_ENDPOINT_SEC 0 +#define APP_USE_IDENTIFY_PWM 1 // APP_USE_IDENTIFY_PWM must be defined before including "AppConfigCommon.h" -#define BUTTON_PIN_1 2 -#define BUTTON_PIN_3 3 -#define BUTTON_PIN_4 1 -#define BUTTON_PIN_2 0 - -// LEDs config -#define LEDS_PORT DEVICE_DT_GET(DT_NODELABEL(gpiob)) -#define SYSTEM_STATE_LED 7 -#define LIGHTING_PWM_SPEC_IDENTIFY_GREEN PWM_DT_SPEC_GET(DT_ALIAS(pwm_led3)) +#include "AppConfigCommon.h" diff --git a/examples/thermostat/telink/include/AppEvent.h b/examples/thermostat/telink/include/AppEvent.h deleted file mode 100755 index 3d5d5bc78d5883..00000000000000 --- a/examples/thermostat/telink/include/AppEvent.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * - * Copyright (c) 2022 Project CHIP Authors - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include - -struct AppEvent; -typedef void (*EventHandler)(AppEvent *); - -class LEDWidget; - -struct AppEvent -{ - enum AppEventTypes - { - kEventType_Button = 0, - kEventType_Timer, - kEventType_UpdateLedState, - kEventType_IdentifyStart, - kEventType_IdentifyStop, - kEventType_Thermostat, - kEventType_Install, - }; - - uint16_t Type; - - union - { - struct - { - uint8_t Action; - } ButtonEvent; - struct - { - void * Context; - } TimerEvent; - struct - { - LEDWidget * LedWidget; - } UpdateLedStateEvent; - }; - - EventHandler Handler; -}; diff --git a/examples/thermostat/telink/include/AppTask.h b/examples/thermostat/telink/include/AppTask.h index facc5e7fb63d2e..8babf015ba4817 100755 --- a/examples/thermostat/telink/include/AppTask.h +++ b/examples/thermostat/telink/include/AppTask.h @@ -18,75 +18,23 @@ #pragma once -#include "AppEvent.h" -#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED -#include "LEDWidget.h" -#endif -#include "PWMDevice.h" +#include "AppTaskCommon.h" #include "SensorManager.h" #include "TemperatureManager.h" -#include - -#include - -#if CONFIG_CHIP_FACTORY_DATA -#include -#endif - -#include - -struct k_timer; -struct Identify; - -class AppTask +class AppTask : public AppTaskCommon { public: - CHIP_ERROR StartApp(void); - - void PostEvent(AppEvent * event); - static void IdentifyEffectHandler(EmberAfIdentifyEffectIdentifier aEffect); - void UpdateClusterState(void); void UpdateThermoStatUI(void); private: friend AppTask & GetAppTask(void); - CHIP_ERROR Init(void); - - static void ActionIdentifyStateUpdateHandler(k_timer * timer); + friend class AppTaskCommon; - void DispatchEvent(AppEvent * event); - -#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED - static void UpdateLedStateEventHandler(AppEvent * aEvent); - static void LEDStateUpdateHandler(LEDWidget * ledWidget); - static void UpdateStatusLED(); -#endif - 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 FactoryResetTimerTimeoutCallback(k_timer * timer); - - static void FactoryResetTimerEventHandler(AppEvent * aEvent); - static void FactoryResetHandler(AppEvent * aEvent); - static void StartThreadHandler(AppEvent * aEvent); - static void StartBleAdvHandler(AppEvent * aEvent); - static void UpdateIdentifyStateEventHandler(AppEvent * aEvent); - - static void InitButtons(void); - - static void ThreadProvisioningHandler(const chip::DeviceLayer::ChipDeviceEvent * event, intptr_t arg); + CHIP_ERROR Init(void); static AppTask sAppTask; - PWMDevice mPwmIdentifyLed; - -#if CONFIG_CHIP_FACTORY_DATA - chip::DeviceLayer::FactoryDataProvider mFactoryDataProvider; -#endif }; inline AppTask & GetAppTask(void) diff --git a/examples/thermostat/telink/include/SensorManager.h b/examples/thermostat/telink/include/SensorManager.h index 828b3ef01d6120..2d2cdb9dd44fc6 100644 --- a/examples/thermostat/telink/include/SensorManager.h +++ b/examples/thermostat/telink/include/SensorManager.h @@ -21,7 +21,7 @@ #include #include -#include "AppEvent.h" +#include "AppEventCommon.h" #include #include diff --git a/examples/thermostat/telink/include/TemperatureManager.h b/examples/thermostat/telink/include/TemperatureManager.h index c55f064f8b8ecb..976e01ab86c523 100644 --- a/examples/thermostat/telink/include/TemperatureManager.h +++ b/examples/thermostat/telink/include/TemperatureManager.h @@ -21,7 +21,7 @@ #include #include -#include "AppEvent.h" +#include "AppEventCommon.h" #include diff --git a/examples/thermostat/telink/src/AppTask.cpp b/examples/thermostat/telink/src/AppTask.cpp index d7ab453dffce17..11b082e36b6e3e 100644 --- a/examples/thermostat/telink/src/AppTask.cpp +++ b/examples/thermostat/telink/src/AppTask.cpp @@ -18,194 +18,15 @@ #include "AppTask.h" -#include "AppConfig.h" -#include "AppEvent.h" -#include "ButtonManager.h" - -#include "ThreadUtil.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -#if CONFIG_CHIP_OTA_REQUESTOR -#include "OTAUtil.h" -#endif - -#include -#include - -#include - -#if CONFIG_CHIP_LIB_SHELL -#include -#include - -static int cmd_telink_reboot(const struct shell * shell, size_t argc, char ** argv) -{ - ARG_UNUSED(argc); - ARG_UNUSED(argv); - - shell_print(shell, "Performing board reboot..."); - sys_reboot(); -} - -SHELL_STATIC_SUBCMD_SET_CREATE(sub_telink, SHELL_CMD(reboot, NULL, "Reboot board command", cmd_telink_reboot), - SHELL_SUBCMD_SET_END); -SHELL_CMD_REGISTER(telink, &sub_telink, "Telink commands", NULL); -#endif // CONFIG_CHIP_LIB_SHELL - LOG_MODULE_DECLARE(app, CONFIG_CHIP_APP_LOG_LEVEL); -using namespace ::chip; -using namespace ::chip::app; -using namespace ::chip::Credentials; -using namespace ::chip::DeviceLayer; - -namespace { -constexpr int kFactoryResetCalcTimeout = 3000; -constexpr int kFactoryResetTriggerCntr = 3; -constexpr int kAppEventQueueSize = 10; -constexpr uint8_t kButtonPushEvent = 1; -constexpr uint8_t kButtonReleaseEvent = 0; -constexpr EndpointId kEndpointId = 1; -constexpr uint8_t kDefaultMinLevel = 0; -constexpr uint8_t kDefaultMaxLevel = 254; -constexpr uint32_t kIdentifyBlinkRateMs = 200; -constexpr uint32_t kIdentifyOkayOnRateMs = 50; -constexpr uint32_t kIdentifyOkayOffRateMs = 950; -constexpr uint32_t kIdentifyFinishOnRateMs = 950; -constexpr uint32_t kIdentifyFinishOffRateMs = 50; -constexpr uint32_t kIdentifyChannelChangeRateMs = 1000; -constexpr uint32_t kIdentifyBreatheRateMs = 1000; - -const struct pwm_dt_spec sPwmIdentifySpecGreenLed = LIGHTING_PWM_SPEC_IDENTIFY_GREEN; - -#if CONFIG_CHIP_FACTORY_DATA -// NOTE! This key is for test/certification only and should not be available in production devices! -uint8_t sTestEventTriggerEnableKey[TestEventTriggerDelegate::kEnableKeyLength] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, - 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }; -#endif - -K_MSGQ_DEFINE(sAppEventQueue, sizeof(AppEvent), kAppEventQueueSize, alignof(AppEvent)); -k_timer sFactoryResetTimer; -uint8_t sFactoryResetCntr = 0; - -#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED -LEDWidget sStatusLED; -#endif - -Button sFactoryResetButton; -Button sThreadStartButton; -Button sBleAdvStartButton; - -bool sIsThreadProvisioned = false; -bool sIsThreadEnabled = false; -bool sIsThreadAttached = false; -bool sHaveBLEConnections = false; - -chip::DeviceLayer::DeviceInfoProviderImpl gExampleDeviceInfoProvider; - -void OnIdentifyTriggerEffect(Identify * identify) -{ - AppTask::IdentifyEffectHandler(identify->mCurrentEffectIdentifier); -} - -Identify sIdentify = { - kEndpointId, - [](Identify *) { ChipLogProgress(Zcl, "OnIdentifyStart"); }, - [](Identify *) { ChipLogProgress(Zcl, "OnIdentifyStop"); }, - EMBER_ZCL_IDENTIFY_IDENTIFY_TYPE_VISIBLE_LED, - OnIdentifyTriggerEffect, -}; - -} // namespace - AppTask AppTask::sAppTask; -class AppFabricTableDelegate : public FabricTable::Delegate -{ - void OnFabricRemoved(const FabricTable & fabricTable, FabricIndex fabricIndex) - { - if (chip::Server::GetInstance().GetFabricTable().FabricCount() == 0) - { - chip::Server::GetInstance().ScheduleFactoryReset(); - } - } -}; - CHIP_ERROR AppTask::Init(void) { - LOG_INF("SW Version: %u, %s", CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION, CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING); - - // Initialize LEDs -#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED - LEDWidget::InitGpio(LEDS_PORT); - LEDWidget::SetStateUpdateCallback(LEDStateUpdateHandler); - sStatusLED.Init(SYSTEM_STATE_LED); - - UpdateStatusLED(); -#endif - - InitButtons(); - - // Initialize function button timer - k_timer_init(&sFactoryResetTimer, &AppTask::FactoryResetTimerTimeoutCallback, nullptr); - k_timer_user_data_set(&sFactoryResetTimer, this); - - // Initialize PWM Identify led - CHIP_ERROR err = sAppTask.mPwmIdentifyLed.Init(&sPwmIdentifySpecGreenLed, kDefaultMinLevel, kDefaultMaxLevel, kDefaultMaxLevel); - if (err != CHIP_NO_ERROR) - { - LOG_ERR("Green IDENTIFY PWM Device Init fail"); - return err; - } - - sAppTask.mPwmIdentifyLed.SetCallbacks(nullptr, nullptr, ActionIdentifyStateUpdateHandler); - - // Initialize CHIP server -#if CONFIG_CHIP_FACTORY_DATA - ReturnErrorOnFailure(mFactoryDataProvider.Init()); - SetDeviceInstanceInfoProvider(&mFactoryDataProvider); - SetDeviceAttestationCredentialsProvider(&mFactoryDataProvider); - SetCommissionableDataProvider(&mFactoryDataProvider); - // Read EnableKey from the factory data. - MutableByteSpan enableKey(sTestEventTriggerEnableKey); - err = mFactoryDataProvider.GetEnableKey(enableKey); - if (err != CHIP_NO_ERROR) - { - LOG_ERR("GetEnableKey fail"); - memset(sTestEventTriggerEnableKey, 0, sizeof(sTestEventTriggerEnableKey)); - } -#else - SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); -#endif - - static CommonCaseDeviceServerInitParams initParams; - (void) initParams.InitializeStaticResourcesBeforeServerInit(); - ReturnErrorOnFailure(chip::Server::GetInstance().Init(initParams)); - - gExampleDeviceInfoProvider.SetStorageDelegate(&Server::GetInstance().GetPersistentStorage()); - chip::DeviceLayer::SetDeviceInfoProvider(&gExampleDeviceInfoProvider); - -#if CONFIG_CHIP_OTA_REQUESTOR - InitBasicOTARequestor(); -#endif - - ConfigurationMgr().LogDeviceConfig(); - PrintOnboardingCodes(chip::RendezvousInformationFlags(chip::RendezvousInformationFlag::kBLE)); + InitCommonParts(); - // 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); - - err = SensorMgr().Init(); + CHIP_ERROR err = SensorMgr().Init(); if (err != CHIP_NO_ERROR) { LOG_ERR("SensorMgr Init fail"); @@ -225,320 +46,13 @@ CHIP_ERROR AppTask::Init(void) return err; } - err = chip::Server::GetInstance().GetFabricTable().AddFabricDelegate(new AppFabricTableDelegate); - if (err != CHIP_NO_ERROR) - { - LOG_ERR("AppFabricTableDelegate fail"); - return err; - } - return CHIP_NO_ERROR; } -CHIP_ERROR AppTask::StartApp(void) -{ - CHIP_ERROR err = Init(); - - if (err != CHIP_NO_ERROR) - { - LOG_ERR("AppTask Init fail"); - return err; - } - - AppEvent event = {}; - - while (true) - { - k_msgq_get(&sAppEventQueue, &event, K_FOREVER); - DispatchEvent(&event); - } -} - -void AppTask::IdentifyEffectHandler(EmberAfIdentifyEffectIdentifier aEffect) -{ - AppEvent event; - event.Type = AppEvent::kEventType_IdentifyStart; - - switch (aEffect) - { - case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BLINK: - ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BLINK"); - event.Handler = [](AppEvent *) { - sAppTask.mPwmIdentifyLed.InitiateBlinkAction(kIdentifyBlinkRateMs, kIdentifyBlinkRateMs); - }; - break; - case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BREATHE: - ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BREATHE"); - event.Handler = [](AppEvent *) { - sAppTask.mPwmIdentifyLed.InitiateBreatheAction(PWMDevice::kBreatheType_Both, kIdentifyBreatheRateMs); - }; - break; - case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_OKAY: - ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_OKAY"); - event.Handler = [](AppEvent *) { - sAppTask.mPwmIdentifyLed.InitiateBlinkAction(kIdentifyOkayOnRateMs, kIdentifyOkayOffRateMs); - }; - break; - case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_CHANNEL_CHANGE: - ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_CHANNEL_CHANGE"); - event.Handler = [](AppEvent *) { - sAppTask.mPwmIdentifyLed.InitiateBlinkAction(kIdentifyChannelChangeRateMs, kIdentifyChannelChangeRateMs); - }; - break; - case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_FINISH_EFFECT: - ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_FINISH_EFFECT"); - event.Handler = [](AppEvent *) { - sAppTask.mPwmIdentifyLed.InitiateBlinkAction(kIdentifyFinishOnRateMs, kIdentifyFinishOffRateMs); - }; - break; - case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_STOP_EFFECT: - ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_STOP_EFFECT"); - event.Handler = [](AppEvent *) { sAppTask.mPwmIdentifyLed.StopAction(); }; - event.Type = AppEvent::kEventType_IdentifyStop; - break; - default: - ChipLogProgress(Zcl, "No identifier effect"); - return; - } - - sAppTask.PostEvent(&event); -} - void AppTask::UpdateThermoStatUI(void) { LOG_INF("Thermostat Status - M:%d T:%d'C H:%d'C C:%d'C", TempMgr().GetMode(), TempMgr().GetCurrentTemp(), TempMgr().GetHeatingSetPoint(), TempMgr().GetCoolingSetPoint()); } -void AppTask::FactoryResetButtonEventHandler(void) -{ - AppEvent event; - - event.Type = AppEvent::kEventType_Button; - event.ButtonEvent.Action = kButtonPushEvent; - event.Handler = FactoryResetHandler; - sAppTask.PostEvent(&event); -} - -void AppTask::FactoryResetHandler(AppEvent * aEvent) -{ - if (sFactoryResetCntr == 0) - { - k_timer_start(&sFactoryResetTimer, K_MSEC(kFactoryResetCalcTimeout), K_NO_WAIT); - } - - sFactoryResetCntr++; - LOG_INF("Factory Reset Trigger Counter: %d/%d", sFactoryResetCntr, kFactoryResetTriggerCntr); - - if (sFactoryResetCntr == kFactoryResetTriggerCntr) - { - k_timer_stop(&sFactoryResetTimer); - sFactoryResetCntr = 0; - - chip::Server::GetInstance().ScheduleFactoryReset(); - } -} - -void AppTask::StartThreadButtonEventHandler(void) -{ - AppEvent event; - - event.Type = AppEvent::kEventType_Button; - event.ButtonEvent.Action = kButtonPushEvent; - event.Handler = StartThreadHandler; - sAppTask.PostEvent(&event); -} - -void AppTask::StartThreadHandler(AppEvent * aEvent) -{ - LOG_INF("StartThreadHandler"); - if (!chip::DeviceLayer::ConnectivityMgr().IsThreadProvisioned()) - { - // Switch context from BLE to Thread - Internal::BLEManagerImpl sInstance; - sInstance.SwitchToIeee802154(); - StartDefaultThreadNetwork(); - } - else - { - LOG_INF("Device already commissioned"); - } -} - -void AppTask::StartBleAdvButtonEventHandler(void) -{ - AppEvent event; - - event.Type = AppEvent::kEventType_Button; - event.ButtonEvent.Action = kButtonPushEvent; - event.Handler = StartBleAdvHandler; - sAppTask.PostEvent(&event); -} - -void AppTask::StartBleAdvHandler(AppEvent * aEvent) -{ - LOG_INF("StartBleAdvHandler"); - - // Don't allow on starting Matter service BLE advertising after Thread provisioning. - if (ConnectivityMgr().IsThreadProvisioned()) - { - LOG_INF("Device already commissioned"); - return; - } - - if (ConnectivityMgr().IsBLEAdvertisingEnabled()) - { - LOG_INF("BLE adv already enabled"); - return; - } - - if (chip::Server::GetInstance().GetCommissioningWindowManager().OpenBasicCommissioningWindow() != CHIP_NO_ERROR) - { - LOG_ERR("OpenBasicCommissioningWindow fail"); - } -} - -#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED -void AppTask::UpdateLedStateEventHandler(AppEvent * aEvent) -{ - if (aEvent->Type == AppEvent::kEventType_UpdateLedState) - { - aEvent->UpdateLedStateEvent.LedWidget->UpdateState(); - } -} - -void AppTask::LEDStateUpdateHandler(LEDWidget * ledWidget) -{ - AppEvent event; - event.Type = AppEvent::kEventType_UpdateLedState; - event.Handler = UpdateLedStateEventHandler; - event.UpdateLedStateEvent.LedWidget = ledWidget; - sAppTask.PostEvent(&event); -} - -void AppTask::UpdateStatusLED(void) -{ - if (sIsThreadProvisioned && sIsThreadEnabled) - { - if (sIsThreadAttached) - { - sStatusLED.Blink(950, 50); - } - else - { - sStatusLED.Blink(100, 100); - } - } - else - { - sStatusLED.Blink(50, 950); - } -} -#endif - -void AppTask::ChipEventHandler(const ChipDeviceEvent * event, intptr_t /* arg */) -{ - switch (event->Type) - { - case DeviceEventType::kCHIPoBLEAdvertisingChange: - sHaveBLEConnections = ConnectivityMgr().NumBLEConnections() != 0; -#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED - UpdateStatusLED(); -#endif - break; - case DeviceEventType::kThreadStateChange: - sIsThreadProvisioned = ConnectivityMgr().IsThreadProvisioned(); - sIsThreadEnabled = ConnectivityMgr().IsThreadEnabled(); - sIsThreadAttached = ConnectivityMgr().IsThreadAttached(); -#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED - UpdateStatusLED(); -#endif - break; - case DeviceEventType::kThreadConnectivityChange: -#if CONFIG_CHIP_OTA_REQUESTOR - if (event->ThreadConnectivityChange.Result == kConnectivity_Established) - { - InitBasicOTARequestor(); - } -#endif - break; - default: - break; - } -} - -void AppTask::ActionIdentifyStateUpdateHandler(k_timer * timer) -{ - AppEvent event; - event.Type = AppEvent::kEventType_UpdateLedState; - event.Handler = UpdateIdentifyStateEventHandler; - sAppTask.PostEvent(&event); -} - -void AppTask::UpdateIdentifyStateEventHandler(AppEvent * aEvent) -{ - sAppTask.mPwmIdentifyLed.UpdateAction(); -} - -void AppTask::PostEvent(AppEvent * aEvent) -{ - if (k_msgq_put(&sAppEventQueue, aEvent, K_NO_WAIT) != 0) - { - LOG_INF("PostEvent fail"); - } -} - -void AppTask::DispatchEvent(AppEvent * aEvent) -{ - if (aEvent->Handler) - { - aEvent->Handler(aEvent); - } - else - { - LOG_INF("Dropping event without handler"); - } -} - void AppTask::UpdateClusterState() {} - -void AppTask::FactoryResetTimerTimeoutCallback(k_timer * timer) -{ - if (!timer) - { - return; - } - - AppEvent event; - event.Type = AppEvent::kEventType_Timer; - event.Handler = FactoryResetTimerEventHandler; - sAppTask.PostEvent(&event); -} - -void AppTask::FactoryResetTimerEventHandler(AppEvent * aEvent) -{ - if (aEvent->Type != AppEvent::kEventType_Timer) - { - return; - } - - sFactoryResetCntr = 0; - LOG_INF("Factory Reset Trigger Counter is cleared"); -} - -void AppTask::InitButtons(void) -{ -#if CONFIG_CHIP_BUTTON_MANAGER_IRQ_MODE - sFactoryResetButton.Configure(BUTTON_PORT, BUTTON_PIN_1, FactoryResetButtonEventHandler); - sThreadStartButton.Configure(BUTTON_PORT, BUTTON_PIN_3, StartThreadButtonEventHandler); - sBleAdvStartButton.Configure(BUTTON_PORT, BUTTON_PIN_4, StartBleAdvButtonEventHandler); -#else - sFactoryResetButton.Configure(BUTTON_PORT, BUTTON_PIN_3, BUTTON_PIN_1, FactoryResetButtonEventHandler); - sThreadStartButton.Configure(BUTTON_PORT, BUTTON_PIN_3, BUTTON_PIN_2, StartThreadButtonEventHandler); - sBleAdvStartButton.Configure(BUTTON_PORT, BUTTON_PIN_4, BUTTON_PIN_2, StartBleAdvButtonEventHandler); -#endif - - ButtonManagerInst().AddButton(sFactoryResetButton); - ButtonManagerInst().AddButton(sThreadStartButton); - ButtonManagerInst().AddButton(sBleAdvStartButton); -} diff --git a/examples/thermostat/telink/src/SensorManager.cpp b/examples/thermostat/telink/src/SensorManager.cpp index 0dac8019360967..534a519b049cf4 100644 --- a/examples/thermostat/telink/src/SensorManager.cpp +++ b/examples/thermostat/telink/src/SensorManager.cpp @@ -18,7 +18,6 @@ #include "SensorManager.h" #include "AppConfig.h" -#include "AppEvent.h" #include "AppTask.h" LOG_MODULE_DECLARE(app, CONFIG_CHIP_APP_LOG_LEVEL); diff --git a/examples/thermostat/telink/src/TemperatureManager.cpp b/examples/thermostat/telink/src/TemperatureManager.cpp index b0e7929cf490f5..ca8b0eb4d98cb4 100644 --- a/examples/thermostat/telink/src/TemperatureManager.cpp +++ b/examples/thermostat/telink/src/TemperatureManager.cpp @@ -18,7 +18,6 @@ #include "TemperatureManager.h" #include "AppConfig.h" -#include "AppEvent.h" #include "AppTask.h" #include diff --git a/examples/thermostat/telink/src/main.cpp b/examples/thermostat/telink/src/main.cpp deleted file mode 100755 index 9dd145f55ba0c9..00000000000000 --- a/examples/thermostat/telink/src/main.cpp +++ /dev/null @@ -1,82 +0,0 @@ -/* - * - * Copyright (c) 2022 Project CHIP Authors - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "AppTask.h" - -#include -#include - -#include - -LOG_MODULE_REGISTER(app, CONFIG_CHIP_APP_LOG_LEVEL); - -using namespace ::chip; -using namespace ::chip::Inet; -using namespace ::chip::DeviceLayer; - -int main(void) -{ - CHIP_ERROR err = CHIP_NO_ERROR; - - err = chip::Platform::MemoryInit(); - if (err != CHIP_NO_ERROR) - { - LOG_ERR("MemoryInit fail"); - goto exit; - } - - err = PlatformMgr().InitChipStack(); - if (err != CHIP_NO_ERROR) - { - LOG_ERR("InitChipStack fail"); - goto exit; - } - - err = PlatformMgr().StartEventLoopTask(); - if (err != CHIP_NO_ERROR) - { - LOG_ERR("StartEventLoopTask fail"); - goto exit; - } - - err = ThreadStackMgr().InitThreadStack(); - if (err != CHIP_NO_ERROR) - { - LOG_ERR("InitThreadStack fail"); - goto exit; - } - -#ifdef CONFIG_OPENTHREAD_MTD_SED - err = ConnectivityMgr().SetThreadDeviceType(ConnectivityManager::kThreadDeviceType_SleepyEndDevice); -#elif CONFIG_OPENTHREAD_MTD - err = ConnectivityMgr().SetThreadDeviceType(ConnectivityManager::kThreadDeviceType_MinimalEndDevice); -#else - err = ConnectivityMgr().SetThreadDeviceType(ConnectivityManager::kThreadDeviceType_Router); -#endif - if (err != CHIP_NO_ERROR) - { - LOG_ERR("SetThreadDeviceType fail"); - goto exit; - } - - err = GetAppTask().StartApp(); - -exit: - LOG_ERR("Exit err %" CHIP_ERROR_FORMAT, err.Format()); - return (err == CHIP_NO_ERROR) ? EXIT_SUCCESS : EXIT_FAILURE; -} diff --git a/examples/window-app/telink/CMakeLists.txt b/examples/window-app/telink/CMakeLists.txt index ad23d3201a455b..ef7801e3728e6c 100644 --- a/examples/window-app/telink/CMakeLists.txt +++ b/examples/window-app/telink/CMakeLists.txt @@ -59,6 +59,7 @@ target_include_directories(app PRIVATE include ${GEN_DIR}/app-common ${GEN_DIR}/window-app + ${TELINK_COMMON}/common/include ${TELINK_COMMON}/util/include ${TELINK_COMMON}/app/include) @@ -68,9 +69,10 @@ add_definitions( target_sources(app PRIVATE src/AppTask.cpp - src/main.cpp src/ZclCallbacks.cpp src/WindowCovering.cpp + ${TELINK_COMMON}/common/src/mainCommon.cpp + ${TELINK_COMMON}/common/src/AppTaskCommon.cpp ${TELINK_COMMON}/util/src/LEDWidget.cpp ${TELINK_COMMON}/util/src/ButtonManager.cpp ${TELINK_COMMON}/util/src/ThreadUtil.cpp diff --git a/examples/window-app/telink/include/AppConfig.h b/examples/window-app/telink/include/AppConfig.h index 3193c1b186b21b..261c67234d043c 100644 --- a/examples/window-app/telink/include/AppConfig.h +++ b/examples/window-app/telink/include/AppConfig.h @@ -20,20 +20,13 @@ // ---- Window App Example Config ---- -// Buttons config -#define BUTTON_PORT DEVICE_DT_GET(DT_NODELABEL(gpioc)) +#define APP_USE_EXAMPLE_START_BUTTON 0 +#define APP_USE_THREAD_START_BUTTON 0 +#define APP_SET_DEVICE_INFO_PROVIDER 1 +#define APP_SET_NETWORK_COMM_ENDPOINT_SEC 0 +#define APP_USE_IDENTIFY_PWM 1 // APP_USE_IDENTIFY_PWM must be defined before including "AppConfigCommon.h" -#define BUTTON_PIN_1 2 -#define BUTTON_PIN_3 3 -#define BUTTON_PIN_4 1 -#define BUTTON_PIN_2 0 - -// LEDs config -#define LEDS_PORT DEVICE_DT_GET(DT_NODELABEL(gpiob)) -#define SYSTEM_STATE_LED 7 -#define LIFT_STATE_LED 6 - -#define LIGHTING_PWM_SPEC_IDENTIFY_GREEN PWM_DT_SPEC_GET(DT_ALIAS(pwm_led3)) +#include "AppConfigCommon.h" #define LIGHTING_PWM_SPEC_RGB_BLUE PWM_DT_SPEC_GET(DT_ALIAS(pwm_led0)) // NOTE: pwm_led1 by default DTS is used by PE0, so get an external LED connected to that pin diff --git a/examples/window-app/telink/include/AppEvent.h b/examples/window-app/telink/include/AppEvent.h deleted file mode 100644 index c6c12517c32b66..00000000000000 --- a/examples/window-app/telink/include/AppEvent.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * - * Copyright (c) 2023 Project CHIP Authors - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include - -struct AppEvent; -typedef void (*EventHandler)(AppEvent *); - -class LEDWidget; - -struct AppEvent -{ - enum AppEventTypes - { - kEventType_Button = 0, - kEventType_Timer, - kEventType_UpdateLedState, - kEventType_IdentifyStart, - kEventType_IdentifyStop, - }; - - uint16_t Type; - - union - { - struct - { - uint8_t PinNo; - uint8_t Action; - } ButtonEvent; - struct - { - void * Context; - } TimerEvent; - struct - { - LEDWidget * LedWidget; - } UpdateLedStateEvent; - }; - - EventHandler Handler; -}; diff --git a/examples/window-app/telink/include/AppTask.h b/examples/window-app/telink/include/AppTask.h index 9bfe3a8ec76a4c..05a356f4531226 100644 --- a/examples/window-app/telink/include/AppTask.h +++ b/examples/window-app/telink/include/AppTask.h @@ -18,89 +18,38 @@ #pragma once -#include "AppConfig.h" -#include "AppEvent.h" +#include "AppTaskCommon.h" #include "WindowCovering.h" -#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED -#include "LEDWidget.h" -#endif -#include "PWMDevice.h" -#include - -#if CONFIG_CHIP_FACTORY_DATA -#include -#endif #ifdef CONFIG_CHIP_PW_RPC #include "Rpc.h" #endif -#include - -struct k_timer; -struct Identify; - -class AppTask +class AppTask : public AppTaskCommon { -public: - CHIP_ERROR StartApp(void); - - void PostEvent(AppEvent * aEvent); - void UpdateClusterState(void); - - static void IdentifyEffectHandler(EmberAfIdentifyEffectIdentifier aEffect); - private: #ifdef CONFIG_CHIP_PW_RPC friend class chip::rpc::TelinkButton; #endif friend AppTask & GetAppTask(void); - CHIP_ERROR Init(void); - - static void ActionInitiated(PWMDevice::Action_t aAction, int32_t aActor); - static void ActionCompleted(PWMDevice::Action_t aAction, int32_t aActor); - static void ActionIdentifyStateUpdateHandler(k_timer * timer); + friend class AppTaskCommon; - void DispatchEvent(AppEvent * event); + CHIP_ERROR Init(void); -#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED - static void UpdateLedStateEventHandler(AppEvent * aEvent); - static void LEDStateUpdateHandler(LEDWidget * ledWidget); - static void UpdateStatusLED(); -#endif - static void LightingActionButtonEventHandler(void); static void OpenActionAndToggleMoveTypeButtonEventHandler(void); static void CloseActionButtonEventHandler(void); - static void FactoryResetButtonEventHandler(void); - static void StartBleAdvButtonEventHandler(void); - - static void ChipEventHandler(const chip::DeviceLayer::ChipDeviceEvent * event, intptr_t arg); - static void FactoryResetTimerTimeoutCallback(k_timer * timer); static void OpenTimerTimeoutCallback(k_timer * timer); static void OpenTimerEventHandler(AppEvent * aEvent); static void ToggleMoveTypeHandler(AppEvent * aEvent); - static void FactoryResetTimerEventHandler(AppEvent * aEvent); - static void FactoryResetHandler(AppEvent * aEvent); - static void LightingActionEventHandler(AppEvent * aEvent); - static void StartBleAdvHandler(AppEvent * aEvent); - static void UpdateIdentifyStateEventHandler(AppEvent * aEvent); - static void OpenHandler(AppEvent * aEvent); static void CloseHandler(AppEvent * aEvent); static void ToggleMoveType(); - static void InitButtons(void); - - static AppTask sAppTask; - PWMDevice mPwmIdentifyLed; - OperationalState mMoveType{ OperationalState::MovingUpOrOpen }; -#if CONFIG_CHIP_FACTORY_DATA - chip::DeviceLayer::FactoryDataProvider mFactoryDataProvider; -#endif + static AppTask sAppTask; }; inline AppTask & GetAppTask(void) diff --git a/examples/window-app/telink/src/AppTask.cpp b/examples/window-app/telink/src/AppTask.cpp index 6f86059a8b6b40..e79e03cc5b4058 100644 --- a/examples/window-app/telink/src/AppTask.cpp +++ b/examples/window-app/telink/src/AppTask.cpp @@ -17,244 +17,52 @@ */ #include "AppTask.h" - -#include "AppConfig.h" -#include "AppEvent.h" #include "ButtonManager.h" #include "WindowCovering.h" -#include "ThreadUtil.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if CONFIG_CHIP_OTA_REQUESTOR -#include "OTAUtil.h" -#endif - -#include -#include - -#include - -#if CONFIG_CHIP_LIB_SHELL -#include -#include - -static int cmd_telink_reboot(const struct shell * shell, size_t argc, char ** argv) -{ - ARG_UNUSED(argc); - ARG_UNUSED(argv); - - shell_print(shell, "Performing board reboot..."); - sys_reboot(); -} - -SHELL_STATIC_SUBCMD_SET_CREATE(sub_telink, SHELL_CMD(reboot, NULL, "Reboot board command", cmd_telink_reboot), - SHELL_SUBCMD_SET_END); -SHELL_CMD_REGISTER(telink, &sub_telink, "Telink commands", NULL); -#endif // CONFIG_CHIP_LIB_SHELL - LOG_MODULE_DECLARE(app, CONFIG_CHIP_APP_LOG_LEVEL); -using namespace ::chip; -using namespace ::chip::app; -using namespace ::chip::Credentials; -using namespace ::chip::DeviceLayer; - namespace { -constexpr int kFactoryResetCalcTimeout = 3000; -constexpr int kToggleMoveTypeTriggerTimeout = 700; -constexpr int kFactoryResetTriggerCntr = 3; -constexpr int kAppEventQueueSize = 10; -constexpr uint8_t kButtonPushEvent = 1; -constexpr uint8_t kButtonReleaseEvent = 0; -constexpr EndpointId kLightEndpointId = 1; -constexpr uint8_t kDefaultMinLevel = 0; -constexpr uint8_t kDefaultMaxLevel = 254; -constexpr uint32_t kIdentifyBlinkRateMs = 200; -constexpr uint32_t kIdentifyOkayOnRateMs = 50; -constexpr uint32_t kIdentifyOkayOffRateMs = 950; -constexpr uint32_t kIdentifyFinishOnRateMs = 950; -constexpr uint32_t kIdentifyFinishOffRateMs = 50; -constexpr uint32_t kIdentifyChannelChangeRateMs = 1000; -constexpr uint32_t kIdentifyBreatheRateMs = 1000; +constexpr int kToggleMoveTypeTriggerTimeout = 700; -const struct pwm_dt_spec sPwmIdentifySpecGreenLed = LIGHTING_PWM_SPEC_IDENTIFY_GREEN; - -#if CONFIG_CHIP_FACTORY_DATA -// NOTE! This key is for test/certification only and should not be available in production devices! -uint8_t sTestEventTriggerEnableKey[TestEventTriggerDelegate::kEnableKeyLength] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, - 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }; -#endif - -K_MSGQ_DEFINE(sAppEventQueue, sizeof(AppEvent), kAppEventQueueSize, alignof(AppEvent)); -k_timer sFactoryResetTimer; k_timer sToggleMoveTypeTimer; -uint8_t sFactoryResetCntr = 0; - -#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED -LEDWidget sStatusLED; -LEDWidget sIdentifyLED; -#endif - -Button sFactoryResetButton; -Button sBleAdvStartButton; Button sOpenButton; Button sCloseButton; -bool sIsThreadProvisioned = false; -bool sIsThreadEnabled = false; -bool sIsThreadAttached = false; -bool sHaveBLEConnections = false; bool sIsToggleMoveTypeTimerActive = false; - -chip::DeviceLayer::DeviceInfoProviderImpl gExampleDeviceInfoProvider; - -void OnIdentifyTriggerEffect(Identify * identify) -{ - AppTask::IdentifyEffectHandler(identify->mCurrentEffectIdentifier); -} - -Identify sIdentify = { - kLightEndpointId, - [](Identify *) { ChipLogProgress(Zcl, "OnIdentifyStart"); }, - [](Identify *) { ChipLogProgress(Zcl, "OnIdentifyStop"); }, - EMBER_ZCL_IDENTIFY_IDENTIFY_TYPE_VISIBLE_LED, - OnIdentifyTriggerEffect, -}; - } // namespace AppTask AppTask::sAppTask; -class AppFabricTableDelegate : public FabricTable::Delegate -{ - void OnFabricRemoved(const FabricTable & fabricTable, FabricIndex fabricIndex) - { - if (chip::Server::GetInstance().GetFabricTable().FabricCount() == 0) - { - chip::Server::GetInstance().ScheduleFactoryReset(); - } - } -}; - CHIP_ERROR AppTask::Init(void) { - LOG_INF("SW Version: %u, %s", CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION, CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING); - - // Initialize LEDs -#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED - LEDWidget::InitGpio(LEDS_PORT); - LEDWidget::SetStateUpdateCallback(LEDStateUpdateHandler); - - sStatusLED.Init(SYSTEM_STATE_LED); - sIdentifyLED.Init(LIFT_STATE_LED); - sIdentifyLED.Set(false); + InitCommonParts(); - UpdateStatusLED(); +#if CONFIG_CHIP_BUTTON_MANAGER_IRQ_MODE + sOpenButton.Configure(BUTTON_PORT, BUTTON_PIN_2, OpenActionAndToggleMoveTypeButtonEventHandler); + sCloseButton.Configure(BUTTON_PORT, BUTTON_PIN_3, CloseActionButtonEventHandler); +#else + sOpenButton.Configure(BUTTON_PORT, BUTTON_PIN_4, BUTTON_PIN_1, OpenActionAndToggleMoveTypeButtonEventHandler); + sCloseButton.Configure(BUTTON_PORT, BUTTON_PIN_3, BUTTON_PIN_2, CloseActionButtonEventHandler); #endif + ButtonManagerInst().AddButton(sOpenButton); + ButtonManagerInst().AddButton(sCloseButton); - InitButtons(); - - // Initialize function button timer - k_timer_init(&sFactoryResetTimer, &AppTask::FactoryResetTimerTimeoutCallback, nullptr); - k_timer_user_data_set(&sFactoryResetTimer, this); // Initialize ToggleMoveType timer k_timer_init(&sToggleMoveTypeTimer, &AppTask::OpenTimerTimeoutCallback, nullptr); k_timer_user_data_set(&sToggleMoveTypeTimer, this); - // // Initialize PWM LEDs - CHIP_ERROR err = sAppTask.mPwmIdentifyLed.Init(&sPwmIdentifySpecGreenLed, kDefaultMinLevel, kDefaultMaxLevel, kDefaultMaxLevel); - if (err != CHIP_NO_ERROR) - { - LOG_ERR("Green IDENTIFY PWM Device Init fail"); - return err; - } - sAppTask.mPwmIdentifyLed.SetCallbacks(nullptr, nullptr, ActionIdentifyStateUpdateHandler); - - // Initialize CHIP server -#if CONFIG_CHIP_FACTORY_DATA - ReturnErrorOnFailure(mFactoryDataProvider.Init()); - SetDeviceInstanceInfoProvider(&mFactoryDataProvider); - SetDeviceAttestationCredentialsProvider(&mFactoryDataProvider); - SetCommissionableDataProvider(&mFactoryDataProvider); - // Read EnableKey from the factory data. - MutableByteSpan enableKey(sTestEventTriggerEnableKey); - err = mFactoryDataProvider.GetEnableKey(enableKey); - if (err != CHIP_NO_ERROR) - { - LOG_ERR("GetEnableKey fail"); - memset(sTestEventTriggerEnableKey, 0, sizeof(sTestEventTriggerEnableKey)); - } -#else - SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); -#endif - - static CommonCaseDeviceServerInitParams initParams; - (void) initParams.InitializeStaticResourcesBeforeServerInit(); - ReturnErrorOnFailure(chip::Server::GetInstance().Init(initParams)); - - gExampleDeviceInfoProvider.SetStorageDelegate(&Server::GetInstance().GetPersistentStorage()); - chip::DeviceLayer::SetDeviceInfoProvider(&gExampleDeviceInfoProvider); - -#if CONFIG_CHIP_OTA_REQUESTOR - InitBasicOTARequestor(); -#endif - - 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); - - err = ConnectivityMgr().SetBLEDeviceName("TelinkWindow"); + CHIP_ERROR err = ConnectivityMgr().SetBLEDeviceName("TelinkWindow"); if (err != CHIP_NO_ERROR) { LOG_ERR("SetBLEDeviceName fail"); return err; } - err = chip::Server::GetInstance().GetFabricTable().AddFabricDelegate(new AppFabricTableDelegate); - if (err != CHIP_NO_ERROR) - { - LOG_ERR("AppFabricTableDelegate fail"); - return err; - } - return CHIP_NO_ERROR; } -CHIP_ERROR AppTask::StartApp(void) -{ - CHIP_ERROR err = Init(); - - if (err != CHIP_NO_ERROR) - { - LOG_ERR("AppTask Init fail"); - return err; - } - - AppEvent event = {}; - - while (true) - { - k_msgq_get(&sAppEventQueue, &event, K_FOREVER); - DispatchEvent(&event); - } -} - void AppTask::OpenActionAndToggleMoveTypeButtonEventHandler(void) { AppEvent event; @@ -275,118 +83,6 @@ void AppTask::CloseActionButtonEventHandler(void) sAppTask.PostEvent(&event); } -void AppTask::IdentifyEffectHandler(EmberAfIdentifyEffectIdentifier aEffect) -{ - AppEvent event; - event.Type = AppEvent::kEventType_IdentifyStart; - - switch (aEffect) - { - case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BLINK: - ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BLINK"); - event.Handler = [](AppEvent *) { - sAppTask.mPwmIdentifyLed.InitiateBlinkAction(kIdentifyBlinkRateMs, kIdentifyBlinkRateMs); - }; - break; - case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BREATHE: - ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BREATHE"); - event.Handler = [](AppEvent *) { - sAppTask.mPwmIdentifyLed.InitiateBreatheAction(PWMDevice::kBreatheType_Both, kIdentifyBreatheRateMs); - }; - break; - case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_OKAY: - ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_OKAY"); - event.Handler = [](AppEvent *) { - sAppTask.mPwmIdentifyLed.InitiateBlinkAction(kIdentifyOkayOnRateMs, kIdentifyOkayOffRateMs); - }; - break; - case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_CHANNEL_CHANGE: - ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_CHANNEL_CHANGE"); - event.Handler = [](AppEvent *) { - sAppTask.mPwmIdentifyLed.InitiateBlinkAction(kIdentifyChannelChangeRateMs, kIdentifyChannelChangeRateMs); - }; - break; - case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_FINISH_EFFECT: - ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_FINISH_EFFECT"); - event.Handler = [](AppEvent *) { - sAppTask.mPwmIdentifyLed.InitiateBlinkAction(kIdentifyFinishOnRateMs, kIdentifyFinishOffRateMs); - }; - break; - case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_STOP_EFFECT: - ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_STOP_EFFECT"); - event.Handler = [](AppEvent *) { sAppTask.mPwmIdentifyLed.StopAction(); }; - event.Type = AppEvent::kEventType_IdentifyStop; - break; - default: - ChipLogProgress(Zcl, "No identifier effect"); - return; - } - - sAppTask.PostEvent(&event); -} - -void AppTask::FactoryResetButtonEventHandler(void) -{ - AppEvent event; - - event.Type = AppEvent::kEventType_Button; - event.ButtonEvent.Action = kButtonPushEvent; - event.Handler = FactoryResetHandler; - sAppTask.PostEvent(&event); -} - -void AppTask::FactoryResetHandler(AppEvent * aEvent) -{ - if (sFactoryResetCntr == 0) - { - k_timer_start(&sFactoryResetTimer, K_MSEC(kFactoryResetCalcTimeout), K_NO_WAIT); - } - - sFactoryResetCntr++; - LOG_INF("Factory Reset Trigger Counter: %d/%d", sFactoryResetCntr, kFactoryResetTriggerCntr); - - if (sFactoryResetCntr == kFactoryResetTriggerCntr) - { - k_timer_stop(&sFactoryResetTimer); - sFactoryResetCntr = 0; - - chip::Server::GetInstance().ScheduleFactoryReset(); - } -} - -void AppTask::StartBleAdvButtonEventHandler(void) -{ - AppEvent event; - - event.Type = AppEvent::kEventType_Button; - event.ButtonEvent.Action = kButtonPushEvent; - event.Handler = StartBleAdvHandler; - sAppTask.PostEvent(&event); -} - -void AppTask::StartBleAdvHandler(AppEvent * aEvent) -{ - LOG_INF("StartBleAdvHandler"); - - // Don't allow on starting Matter service BLE advertising after Thread provisioning. - if (ConnectivityMgr().IsThreadProvisioned()) - { - LOG_INF("Device already commissioned"); - return; - } - - if (ConnectivityMgr().IsBLEAdvertisingEnabled()) - { - LOG_INF("BLE adv already enabled"); - return; - } - - if (chip::Server::GetInstance().GetCommissioningWindowManager().OpenBasicCommissioningWindow() != CHIP_NO_ERROR) - { - LOG_ERR("OpenBasicCommissioningWindow fail"); - } -} - void AppTask::OpenTimerTimeoutCallback(k_timer * timer) { if (!timer) @@ -451,181 +147,3 @@ void AppTask::ToggleMoveType() LOG_INF("Window covering move: lift"); } } - -#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED -void AppTask::UpdateLedStateEventHandler(AppEvent * aEvent) -{ - if (aEvent->Type == AppEvent::kEventType_UpdateLedState) - { - aEvent->UpdateLedStateEvent.LedWidget->UpdateState(); - } -} - -void AppTask::LEDStateUpdateHandler(LEDWidget * ledWidget) -{ - AppEvent event; - event.Type = AppEvent::kEventType_UpdateLedState; - event.Handler = UpdateLedStateEventHandler; - event.UpdateLedStateEvent.LedWidget = ledWidget; - sAppTask.PostEvent(&event); -} - -void AppTask::UpdateStatusLED(void) -{ - if (sIsThreadProvisioned && sIsThreadEnabled) - { - if (sIsThreadAttached) - { - sStatusLED.Blink(950, 50); - } - else - { - sStatusLED.Blink(100, 100); - } - } - else - { - sStatusLED.Blink(50, 950); - } -} -#endif - -void AppTask::ChipEventHandler(const ChipDeviceEvent * event, intptr_t /* arg */) -{ - switch (event->Type) - { - case DeviceEventType::kCHIPoBLEAdvertisingChange: - sHaveBLEConnections = ConnectivityMgr().NumBLEConnections() != 0; -#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED - UpdateStatusLED(); -#endif - break; - case DeviceEventType::kThreadStateChange: - sIsThreadProvisioned = ConnectivityMgr().IsThreadProvisioned(); - sIsThreadEnabled = ConnectivityMgr().IsThreadEnabled(); - sIsThreadAttached = ConnectivityMgr().IsThreadAttached(); -#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED - UpdateStatusLED(); -#endif - break; - case DeviceEventType::kThreadConnectivityChange: -#if CONFIG_CHIP_OTA_REQUESTOR - if (event->ThreadConnectivityChange.Result == kConnectivity_Established) - { - InitBasicOTARequestor(); - } -#endif - break; - default: - break; - } -} - -void AppTask::ActionIdentifyStateUpdateHandler(k_timer * timer) -{ - AppEvent event; - event.Type = AppEvent::kEventType_UpdateLedState; - event.Handler = UpdateIdentifyStateEventHandler; - sAppTask.PostEvent(&event); -} - -void AppTask::UpdateIdentifyStateEventHandler(AppEvent * aEvent) -{ - sAppTask.mPwmIdentifyLed.UpdateAction(); -} - -void AppTask::ActionInitiated(PWMDevice::Action_t aAction, int32_t aActor) -{ - if (aAction == PWMDevice::ON_ACTION) - { - LOG_DBG("ON_ACTION initiated"); - } - else if (aAction == PWMDevice::OFF_ACTION) - { - LOG_DBG("OFF_ACTION initiated"); - } - else if (aAction == PWMDevice::LEVEL_ACTION) - { - LOG_DBG("LEVEL_ACTION initiated"); - } -} - -void AppTask::ActionCompleted(PWMDevice::Action_t aAction, int32_t aActor) -{ - if (aAction == PWMDevice::ON_ACTION) - { - LOG_DBG("ON_ACTION completed"); - } - else if (aAction == PWMDevice::OFF_ACTION) - { - LOG_DBG("OFF_ACTION completed"); - } - else if (aAction == PWMDevice::LEVEL_ACTION) - { - LOG_DBG("LEVEL_ACTION completed"); - } -} - -void AppTask::PostEvent(AppEvent * aEvent) -{ - if (k_msgq_put(&sAppEventQueue, aEvent, K_NO_WAIT) != 0) - { - LOG_INF("PostEvent fail"); - } -} - -void AppTask::DispatchEvent(AppEvent * aEvent) -{ - if (aEvent->Handler) - { - aEvent->Handler(aEvent); - } - else - { - LOG_INF("Dropping event without handler"); - } -} - -void AppTask::FactoryResetTimerTimeoutCallback(k_timer * timer) -{ - if (!timer) - { - return; - } - - AppEvent event; - event.Type = AppEvent::kEventType_Timer; - event.Handler = FactoryResetTimerEventHandler; - sAppTask.PostEvent(&event); -} - -void AppTask::FactoryResetTimerEventHandler(AppEvent * aEvent) -{ - if (aEvent->Type != AppEvent::kEventType_Timer) - { - return; - } - - sFactoryResetCntr = 0; - LOG_INF("Factory Reset Trigger Counter is cleared"); -} - -void AppTask::InitButtons(void) -{ -#if CONFIG_CHIP_BUTTON_MANAGER_IRQ_MODE - sFactoryResetButton.Configure(BUTTON_PORT, BUTTON_PIN_1, FactoryResetButtonEventHandler); - sOpenButton.Configure(BUTTON_PORT, BUTTON_PIN_2, OpenActionAndToggleMoveTypeButtonEventHandler); - sCloseButton.Configure(BUTTON_PORT, BUTTON_PIN_3, CloseActionButtonEventHandler); - sBleAdvStartButton.Configure(BUTTON_PORT, BUTTON_PIN_4, StartBleAdvButtonEventHandler); -#else - sFactoryResetButton.Configure(BUTTON_PORT, BUTTON_PIN_3, BUTTON_PIN_1, FactoryResetButtonEventHandler); - sOpenButton.Configure(BUTTON_PORT, BUTTON_PIN_4, BUTTON_PIN_1, OpenActionAndToggleMoveTypeButtonEventHandler); - sCloseButton.Configure(BUTTON_PORT, BUTTON_PIN_3, BUTTON_PIN_2, CloseActionButtonEventHandler); - sBleAdvStartButton.Configure(BUTTON_PORT, BUTTON_PIN_4, BUTTON_PIN_2, StartBleAdvButtonEventHandler); -#endif - - ButtonManagerInst().AddButton(sFactoryResetButton); - ButtonManagerInst().AddButton(sOpenButton); - ButtonManagerInst().AddButton(sCloseButton); - ButtonManagerInst().AddButton(sBleAdvStartButton); -} diff --git a/examples/window-app/telink/src/main.cpp b/examples/window-app/telink/src/main.cpp deleted file mode 100644 index 1d423f0a516457..00000000000000 --- a/examples/window-app/telink/src/main.cpp +++ /dev/null @@ -1,90 +0,0 @@ -/* - * - * Copyright (c) 2023 Project CHIP Authors - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "AppTask.h" - -#include -#include - -#include - -#ifdef CONFIG_CHIP_PW_RPC -#include "Rpc.h" -#endif - -LOG_MODULE_REGISTER(app, CONFIG_CHIP_APP_LOG_LEVEL); - -using namespace ::chip; -using namespace ::chip::Inet; -using namespace ::chip::DeviceLayer; - -int main(void) -{ - CHIP_ERROR err = CHIP_NO_ERROR; - -#ifdef CONFIG_CHIP_PW_RPC - rpc::Init(); -#endif - - err = chip::Platform::MemoryInit(); - if (err != CHIP_NO_ERROR) - { - LOG_ERR("MemoryInit fail"); - goto exit; - } - - err = PlatformMgr().InitChipStack(); - if (err != CHIP_NO_ERROR) - { - LOG_ERR("InitChipStack fail"); - goto exit; - } - - err = PlatformMgr().StartEventLoopTask(); - if (err != CHIP_NO_ERROR) - { - LOG_ERR("StartEventLoopTask fail"); - goto exit; - } - - err = ThreadStackMgr().InitThreadStack(); - if (err != CHIP_NO_ERROR) - { - LOG_ERR("InitThreadStack fail"); - goto exit; - } - -#ifdef CONFIG_OPENTHREAD_MTD_SED - err = ConnectivityMgr().SetThreadDeviceType(ConnectivityManager::kThreadDeviceType_SleepyEndDevice); -#elif CONFIG_OPENTHREAD_MTD - err = ConnectivityMgr().SetThreadDeviceType(ConnectivityManager::kThreadDeviceType_MinimalEndDevice); -#else - err = ConnectivityMgr().SetThreadDeviceType(ConnectivityManager::kThreadDeviceType_Router); -#endif - if (err != CHIP_NO_ERROR) - { - LOG_ERR("SetThreadDeviceType fail"); - goto exit; - } - - err = GetAppTask().StartApp(); - -exit: - LOG_ERR("Exit err %" CHIP_ERROR_FORMAT, err.Format()); - return (err == CHIP_NO_ERROR) ? EXIT_SUCCESS : EXIT_FAILURE; -}