@@ -42,6 +42,10 @@ using namespace ::chip;
42
42
#include < credentials/DeviceAttestationCredsProvider.h>
43
43
#include < credentials/examples/DeviceAttestationCredsExample.h>
44
44
45
+ #if defined(QORVO_QPINCFG_ENABLE)
46
+ #include " qPinCfg.h"
47
+ #endif // QORVO_QPINCFG_ENABLE
48
+
45
49
#include < inet/EndPointStateOpenThread.h>
46
50
47
51
#include < DeviceInfoProviderImpl.h>
@@ -58,9 +62,16 @@ using namespace ::chip::DeviceLayer;
58
62
59
63
#define FACTORY_RESET_TRIGGER_TIMEOUT 3000
60
64
#define FACTORY_RESET_CANCEL_WINDOW_TIMEOUT 3000
65
+ #define SWITCH_MULTIPRESS_WINDOW_MS 500
66
+ #define SWITCH_LONGPRESS_WINDOW_MS 3000
67
+ #define SWITCH_BUTTON_PRESSED 1
68
+ #define SWITCH_BUTTON_UNPRESSED 0
69
+
61
70
#define APP_TASK_STACK_SIZE (2 * 1024 )
62
71
#define APP_TASK_PRIORITY 2
63
72
#define APP_EVENT_QUEUE_SIZE 10
73
+ #define SECONDS_IN_HOUR (3600 ) // we better keep this 3600
74
+ #define TOTAL_OPERATIONAL_HOURS_SAVE_INTERVAL_SECONDS (1 * SECONDS_IN_HOUR) // increment every hour
64
75
65
76
namespace {
66
77
TaskHandle_t sAppTaskHandle ;
@@ -70,6 +81,9 @@ bool sIsThreadProvisioned = false;
70
81
bool sIsThreadEnabled = false ;
71
82
bool sHaveBLEConnections = false ;
72
83
bool sIsBLEAdvertisingEnabled = false ;
84
+ bool sIsMultipressOngoing = false ;
85
+ bool sLongPressDetected = false ;
86
+ uint8_t sSwitchButtonState = SWITCH_BUTTON_UNPRESSED;
73
87
74
88
// NOTE! This key is for test/certification only and should not be available in production devices!
75
89
uint8_t sTestEventTriggerEnableKey [TestEventTriggerDelegate::kEnableKeyLength ] = { 0x00 , 0x11 , 0x22 , 0x33 , 0x44 , 0x55 , 0x66 , 0x77 ,
@@ -141,11 +155,19 @@ void OnTriggerIdentifyEffect(Identify * identify)
141
155
}
142
156
}
143
157
144
- Identify gIdentify = {
158
+ Identify gIdentifyEp1 = {
145
159
chip::EndpointId{ 1 },
146
160
[](Identify *) { ChipLogProgress (Zcl, " onIdentifyStart" ); },
147
161
[](Identify *) { ChipLogProgress (Zcl, " onIdentifyStop" ); },
148
- Clusters::Identify::IdentifyTypeEnum::kVisibleIndicator ,
162
+ Clusters::Identify::IdentifyTypeEnum::kNone ,
163
+ OnTriggerIdentifyEffect,
164
+ };
165
+
166
+ Identify gIdentifyEp2 = {
167
+ chip::EndpointId{ 2 },
168
+ [](Identify *) { ChipLogProgress (Zcl, " onIdentifyStart" ); },
169
+ [](Identify *) { ChipLogProgress (Zcl, " onIdentifyStop" ); },
170
+ Clusters::Identify::IdentifyTypeEnum::kNone ,
149
171
OnTriggerIdentifyEffect,
150
172
};
151
173
@@ -224,6 +246,14 @@ CHIP_ERROR AppTask::Init()
224
246
{
225
247
CHIP_ERROR err = CHIP_NO_ERROR;
226
248
249
+ #if defined(QORVO_QPINCFG_ENABLE)
250
+ qResult_t res = Q_OK;
251
+ res = qPinCfg_Init (NULL );
252
+ if (res != Q_OK)
253
+ {
254
+ ChipLogError (NotSpecified, " qPinCfg_Init failed: %d" , res);
255
+ }
256
+ #endif // QORVO_QPINCFG_ENABLE
227
257
PlatformMgr ().AddEventHandler (MatterEventHandler, 0 );
228
258
229
259
ChipLogProgress (NotSpecified, " Current Software Version: %s" , CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING);
@@ -255,6 +285,14 @@ CHIP_ERROR AppTask::Init()
255
285
sIsBLEAdvertisingEnabled = ConnectivityMgr ().IsBLEAdvertisingEnabled ();
256
286
UpdateLEDs ();
257
287
288
+ err = chip::DeviceLayer::SystemLayer ().StartTimer (chip::System::Clock::Seconds32 (TOTAL_OPERATIONAL_HOURS_SAVE_INTERVAL_SECONDS),
289
+ TotalHoursTimerHandler, this );
290
+
291
+ if (err != CHIP_NO_ERROR)
292
+ {
293
+ ChipLogError (NotSpecified, " StartTimer failed %s: " , chip::ErrorStr (err));
294
+ }
295
+
258
296
return err;
259
297
}
260
298
@@ -275,7 +313,9 @@ void AppTask::AppTaskMain(void * pvParameter)
275
313
276
314
void AppTask::ButtonEventHandler (uint8_t btnIdx, bool btnPressed)
277
315
{
278
- ChipLogProgress (NotSpecified, " ButtonEventHandler %d, %d" , btnIdx, btnPressed);
316
+ CHIP_ERROR err = CHIP_NO_ERROR;
317
+
318
+ ChipLogDetail (NotSpecified, " ButtonEventHandler %d, %d" , btnIdx, btnPressed);
279
319
280
320
AppEvent button_event = {};
281
321
button_event.Type = AppEvent::kEventType_Button ;
@@ -297,13 +337,54 @@ void AppTask::ButtonEventHandler(uint8_t btnIdx, bool btnPressed)
297
337
case APP_FUNCTION2_SWITCH: {
298
338
if (!btnPressed)
299
339
{
300
- ChipLogProgress (NotSpecified, " Switch release press" );
301
- button_event.Handler = SwitchMgr ().GenericSwitchReleasePressHandler ;
340
+ ChipLogDetail (NotSpecified, " Switch button released" );
341
+
342
+ button_event.Handler =
343
+ sLongPressDetected ? SwitchMgr ().GenericSwitchLongReleaseHandler : SwitchMgr ().GenericSwitchShortReleaseHandler ;
344
+
345
+ sIsMultipressOngoing = true ;
346
+ sSwitchButtonState = SWITCH_BUTTON_UNPRESSED;
347
+ sLongPressDetected = false ;
348
+
349
+ chip::DeviceLayer::SystemLayer ().CancelTimer (MultiPressTimeoutHandler, NULL );
350
+ // we start the MultiPress feature window after releasing the button
351
+ err = chip::DeviceLayer::SystemLayer ().StartTimer (chip::System::Clock::Milliseconds32 (SWITCH_MULTIPRESS_WINDOW_MS),
352
+ MultiPressTimeoutHandler, NULL );
353
+
354
+ if (err != CHIP_NO_ERROR)
355
+ {
356
+ ChipLogError (NotSpecified, " StartTimer failed %s: " , chip::ErrorStr (err));
357
+ }
302
358
}
303
359
else
304
360
{
305
- ChipLogProgress (NotSpecified, " Switch initial press" );
306
- button_event.Handler = SwitchMgr ().GenericSwitchInitialPressHandler ;
361
+ ChipLogDetail (NotSpecified, " Switch button pressed" );
362
+
363
+ sSwitchButtonState = SWITCH_BUTTON_PRESSED;
364
+
365
+ chip::DeviceLayer::SystemLayer ().CancelTimer (LongPressTimeoutHandler, NULL );
366
+ // we need to check if this is short or long press
367
+ err = chip::DeviceLayer::SystemLayer ().StartTimer (chip::System::Clock::Milliseconds32 (SWITCH_LONGPRESS_WINDOW_MS),
368
+ LongPressTimeoutHandler, NULL );
369
+
370
+ if (err != CHIP_NO_ERROR)
371
+ {
372
+ ChipLogError (NotSpecified, " StartTimer failed %s: " , chip::ErrorStr (err));
373
+ }
374
+
375
+ // if we have active multipress window we need to send extra event
376
+ if (sIsMultipressOngoing )
377
+ {
378
+ ChipLogDetail (NotSpecified, " Switch MultipressOngoing" );
379
+ button_event.Handler = SwitchMgr ().GenericSwitchInitialPressHandler ;
380
+ sAppTask .PostEvent (&button_event);
381
+ chip::DeviceLayer::SystemLayer ().CancelTimer (MultiPressTimeoutHandler, NULL );
382
+ button_event.Handler = SwitchMgr ().GenericSwitchMultipressOngoingHandler ;
383
+ }
384
+ else
385
+ {
386
+ button_event.Handler = SwitchMgr ().GenericSwitchInitialPressHandler ;
387
+ }
307
388
}
308
389
break ;
309
390
}
@@ -348,6 +429,69 @@ void AppTask::TimerEventHandler(chip::System::Layer * aLayer, void * aAppState)
348
429
sAppTask .PostEvent (&event);
349
430
}
350
431
432
+ void AppTask::MultiPressTimeoutHandler (chip::System::Layer * aLayer, void * aAppState)
433
+ {
434
+ ChipLogDetail (NotSpecified, " MultiPressTimeoutHandler" );
435
+
436
+ sIsMultipressOngoing = false ;
437
+
438
+ AppEvent multipress_event = {};
439
+ multipress_event.Type = AppEvent::kEventType_Button ;
440
+ multipress_event.Handler = SwitchMgr ().GenericSwitchMultipressCompleteHandler ;
441
+
442
+ sAppTask .PostEvent (&multipress_event);
443
+ }
444
+
445
+ void AppTask::LongPressTimeoutHandler (chip::System::Layer * aLayer, void * aAppState)
446
+ {
447
+ ChipLogDetail (NotSpecified, " LongPressTimeoutHandler" );
448
+
449
+ // if the button is still pressed after threshold time, this is a LongPress, otherwise jsut ignore it
450
+ if (sSwitchButtonState == SWITCH_BUTTON_PRESSED)
451
+ {
452
+ sLongPressDetected = true ;
453
+ AppEvent longpress_event = {};
454
+ longpress_event.Type = AppEvent::kEventType_Button ;
455
+ longpress_event.Handler = SwitchMgr ().GenericSwitchLongPressHandler ;
456
+
457
+ sAppTask .PostEvent (&longpress_event);
458
+ }
459
+ }
460
+
461
+ void AppTask::TotalHoursTimerHandler (chip::System::Layer * aLayer, void * aAppState)
462
+ {
463
+ ChipLogDetail (NotSpecified, " HourlyTimer" );
464
+
465
+ CHIP_ERROR err;
466
+ uint32_t totalOperationalHours = 0 ;
467
+
468
+ err = ConfigurationMgr ().GetTotalOperationalHours (totalOperationalHours);
469
+
470
+ if (err == CHIP_NO_ERROR)
471
+ {
472
+ ConfigurationMgr ().StoreTotalOperationalHours (totalOperationalHours +
473
+ (TOTAL_OPERATIONAL_HOURS_SAVE_INTERVAL_SECONDS / SECONDS_IN_HOUR));
474
+ }
475
+ else if (err == CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND)
476
+ {
477
+ totalOperationalHours = 0 ; // set this explicitly to 0 for safety
478
+ ConfigurationMgr ().StoreTotalOperationalHours (totalOperationalHours +
479
+ (TOTAL_OPERATIONAL_HOURS_SAVE_INTERVAL_SECONDS / SECONDS_IN_HOUR));
480
+ }
481
+ else
482
+ {
483
+ ChipLogError (DeviceLayer, " Failed to get total operational hours of the Node" );
484
+ }
485
+
486
+ err = chip::DeviceLayer::SystemLayer ().StartTimer (chip::System::Clock::Seconds32 (TOTAL_OPERATIONAL_HOURS_SAVE_INTERVAL_SECONDS),
487
+ TotalHoursTimerHandler, nullptr );
488
+
489
+ if (err != CHIP_NO_ERROR)
490
+ {
491
+ ChipLogError (NotSpecified, " StartTimer failed %s: " , chip::ErrorStr (err));
492
+ }
493
+ }
494
+
351
495
void AppTask::FunctionTimerEventHandler (AppEvent * aEvent)
352
496
{
353
497
if (aEvent->Type != AppEvent::kEventType_Timer )
0 commit comments