Skip to content

Commit

Permalink
[Telink] Factory reset using power on sequence (#28519)
Browse files Browse the repository at this point in the history
  • Loading branch information
andriy-bilynskyy authored and pull[bot] committed Feb 20, 2024
1 parent d0b20f5 commit fe08feb
Show file tree
Hide file tree
Showing 6 changed files with 141 additions and 1 deletion.
8 changes: 8 additions & 0 deletions config/telink/chip-module/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -207,3 +207,11 @@ config CHIP_MAX_PREFERRED_SUBSCRIPTION_REPORT_INTERVAL
the initiator device to detect the publisher absence reasonably fast due to not sending
the reports too rarely. The current algorithm is to select bigger value from the one
requested by the initiator and the one preferred by the publisher.

config CHIP_ENABLE_POWER_ON_FACTORY_RESET
bool "Enable power on factory reset sequence"
default n
help
Enable power on factory reset sequence. If device power triggered off during
first 5 seconds after power on and this sequence repeated 5 times - factory
reset will be involved.
9 changes: 9 additions & 0 deletions examples/lighting-app/telink/include/AppTask.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@
class AppTask : public AppTaskCommon
{
public:
#ifdef CONFIG_CHIP_ENABLE_POWER_ON_FACTORY_RESET
void PowerOnFactoryReset(void);
#endif /* CONFIG_CHIP_ENABLE_POWER_ON_FACTORY_RESET */
void SetInitiateAction(PWMDevice::Action_t aAction, int32_t aActor, uint8_t * value);
void UpdateClusterState(void);
PWMDevice & GetPWMDevice(void) { return mPwmRgbBlueLed; }
Expand All @@ -37,7 +40,13 @@ class AppTask : public AppTaskCommon
static void ActionCompleted(PWMDevice::Action_t aAction, int32_t aActor);

static void LightingActionEventHandler(AppEvent * aEvent);
#ifdef CONFIG_CHIP_ENABLE_POWER_ON_FACTORY_RESET
static void PowerOnFactoryResetEventHandler(AppEvent * aEvent);
static void PowerOnFactoryResetTimerEvent(struct k_timer * dummy);

static unsigned int sPowerOnFactoryResetTimerCnt;
static k_timer sPowerOnFactoryResetTimer;
#endif /* CONFIG_CHIP_ENABLE_POWER_ON_FACTORY_RESET */
PWMDevice mPwmRgbBlueLed;
#if USE_RGB_PWM
PWMDevice mPwmRgbGreenLed;
Expand Down
51 changes: 51 additions & 0 deletions examples/lighting-app/telink/src/AppTask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
*/

#include "AppTask.h"
#include <app/server/Server.h>

#include "ColorFormat.h"
#include "PWMDevice.h"
Expand All @@ -41,6 +42,17 @@ CtColor_t sCT;

AppTask AppTask::sAppTask;

#ifdef CONFIG_CHIP_ENABLE_POWER_ON_FACTORY_RESET
void AppTask::PowerOnFactoryReset(void)
{
LOG_INF("Lighting App Power On Factory Reset");
AppEvent event;
event.Type = AppEvent::kEventType_Lighting;
event.Handler = PowerOnFactoryResetEventHandler;
GetAppTask().PostEvent(&event);
}
#endif /* CONFIG_CHIP_ENABLE_POWER_ON_FACTORY_RESET */

CHIP_ERROR AppTask::Init(void)
{
// Init lighting manager
Expand Down Expand Up @@ -284,3 +296,42 @@ void AppTask::SetInitiateAction(PWMDevice::Action_t aAction, int32_t aActor, uin
}
#endif
}

#ifdef CONFIG_CHIP_ENABLE_POWER_ON_FACTORY_RESET
static constexpr uint32_t kPowerOnFactoryResetIndicationMax = 4;
static constexpr uint32_t kPowerOnFactoryResetIndicationTimeMs = 1000;

unsigned int AppTask::sPowerOnFactoryResetTimerCnt;
k_timer AppTask::sPowerOnFactoryResetTimer;

void AppTask::PowerOnFactoryResetEventHandler(AppEvent * aEvent)
{
LOG_INF("Lighting App Power On Factory Reset Handler");
sPowerOnFactoryResetTimerCnt = 1;
sAppTask.mPwmRgbBlueLed.Set(sPowerOnFactoryResetTimerCnt % 2);
#if USE_RGB_PWM
sAppTask.mPwmRgbRedLed.Set(sPowerOnFactoryResetTimerCnt % 2);
sAppTask.mPwmRgbGreenLed.Set(sPowerOnFactoryResetTimerCnt % 2);
#endif
k_timer_init(&sPowerOnFactoryResetTimer, PowerOnFactoryResetTimerEvent, nullptr);
k_timer_start(&sPowerOnFactoryResetTimer, K_MSEC(kPowerOnFactoryResetIndicationTimeMs),
K_MSEC(kPowerOnFactoryResetIndicationTimeMs));
}

void AppTask::PowerOnFactoryResetTimerEvent(struct k_timer * timer)
{
sPowerOnFactoryResetTimerCnt++;
LOG_INF("Lighting App Power On Factory Reset Handler %u", sPowerOnFactoryResetTimerCnt);
sAppTask.mPwmRgbBlueLed.Set(sPowerOnFactoryResetTimerCnt % 2);
#if USE_RGB_PWM
sAppTask.mPwmRgbRedLed.Set(sPowerOnFactoryResetTimerCnt % 2);
sAppTask.mPwmRgbGreenLed.Set(sPowerOnFactoryResetTimerCnt % 2);
#endif
if (sPowerOnFactoryResetTimerCnt > kPowerOnFactoryResetIndicationMax)
{
k_timer_stop(timer);
LOG_INF("schedule factory reset");
chip::Server::GetInstance().ScheduleFactoryReset();
}
}
#endif /* CONFIG_CHIP_ENABLE_POWER_ON_FACTORY_RESET */
3 changes: 3 additions & 0 deletions examples/platform/telink/common/include/AppTaskCommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@ constexpr uint8_t kButtonReleaseEvent = 0;
class AppTaskCommon
{
public:
#ifdef CONFIG_CHIP_ENABLE_POWER_ON_FACTORY_RESET
void PowerOnFactoryReset(void);
#endif /* CONFIG_CHIP_ENABLE_POWER_ON_FACTORY_RESET */
CHIP_ERROR StartApp();
void PostEvent(AppEvent * event);

Expand Down
8 changes: 8 additions & 0 deletions examples/platform/telink/common/src/AppTaskCommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,14 @@ SHELL_STATIC_SUBCMD_SET_CREATE(sub_telink, SHELL_CMD(reboot, NULL, "Reboot board
SHELL_CMD_REGISTER(telink, &sub_telink, "Telink commands", NULL);
#endif // CONFIG_CHIP_LIB_SHELL

#ifdef CONFIG_CHIP_ENABLE_POWER_ON_FACTORY_RESET
void AppTaskCommon::PowerOnFactoryReset(void)
{
LOG_INF("schedule factory reset");
chip::Server::GetInstance().ScheduleFactoryReset();
}
#endif /* CONFIG_CHIP_ENABLE_POWER_ON_FACTORY_RESET */

CHIP_ERROR AppTaskCommon::StartApp(void)
{
CHIP_ERROR err = GetAppTask().Init();
Expand Down
63 changes: 62 additions & 1 deletion examples/platform/telink/common/src/mainCommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,65 @@ using namespace ::chip;
using namespace ::chip::Inet;
using namespace ::chip::DeviceLayer;

#ifdef CONFIG_CHIP_ENABLE_POWER_ON_FACTORY_RESET
static constexpr uint32_t kFactoryResetOnBootMaxCnt = 5;
static constexpr const char * kFactoryResetOnBootStoreKey = "TelinkFactoryResetOnBootCnt";
static constexpr uint32_t kFactoryResetUsualBootTimeoutMs = 5000;

static k_timer FactoryResetUsualBootTimer;

static void FactoryResetUsualBoot(struct k_timer * dummy)
{
(void) dummy;
(void) chip::DeviceLayer::PersistedStorage::KeyValueStoreMgr().Delete(kFactoryResetOnBootStoreKey);
LOG_INF("Schedule factory counter deleted");
}

static void FactoryResetOnBoot(void)
{
uint32_t FactoryResetOnBootCnt;
CHIP_ERROR FactoryResetOnBootErr = chip::DeviceLayer::PersistedStorage::KeyValueStoreMgr().Get(
kFactoryResetOnBootStoreKey, &FactoryResetOnBootCnt, sizeof(FactoryResetOnBootCnt));

if (FactoryResetOnBootErr == CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND)
{
FactoryResetOnBootCnt = 1;
if (chip::DeviceLayer::PersistedStorage::KeyValueStoreMgr().Put(kFactoryResetOnBootStoreKey, &FactoryResetOnBootCnt,
sizeof(FactoryResetOnBootCnt)) != CHIP_NO_ERROR)
{
LOG_ERR("FactoryResetOnBootCnt write fail");
}
else
{
LOG_INF("Schedule factory counter %u", FactoryResetOnBootCnt);
}
}
else if (FactoryResetOnBootErr == CHIP_NO_ERROR)
{
FactoryResetOnBootCnt++;
if (chip::DeviceLayer::PersistedStorage::KeyValueStoreMgr().Put(kFactoryResetOnBootStoreKey, &FactoryResetOnBootCnt,
sizeof(FactoryResetOnBootCnt)) != CHIP_NO_ERROR)
{
LOG_ERR("FactoryResetOnBootCnt write fail");
}
else
{
LOG_INF("Schedule factory counter %u", FactoryResetOnBootCnt);
if (FactoryResetOnBootCnt >= kFactoryResetOnBootMaxCnt)
{
GetAppTask().PowerOnFactoryReset();
}
}
}
else
{
LOG_ERR("FactoryResetOnBootCnt read fail");
}
k_timer_init(&FactoryResetUsualBootTimer, FactoryResetUsualBoot, nullptr);
k_timer_start(&FactoryResetUsualBootTimer, K_MSEC(kFactoryResetUsualBootTimeoutMs), K_NO_WAIT);
}
#endif /* CONFIG_CHIP_ENABLE_POWER_ON_FACTORY_RESET */

int main(void)
{
CHIP_ERROR err = CHIP_NO_ERROR;
Expand Down Expand Up @@ -61,7 +120,9 @@ int main(void)
LOG_ERR("StartEventLoopTask fail");
goto exit;
}

#ifdef CONFIG_CHIP_ENABLE_POWER_ON_FACTORY_RESET
FactoryResetOnBoot();
#endif /* CONFIG_CHIP_ENABLE_POWER_ON_FACTORY_RESET */
err = ThreadStackMgr().InitThreadStack();
if (err != CHIP_NO_ERROR)
{
Expand Down

0 comments on commit fe08feb

Please sign in to comment.