Fix for x86_64 build fail
[platform/upstream/connectedhomeip.git] / examples / lock-app / cc13x2x7_26x2x7 / main / AppTask.cpp
1 /*
2  *
3  *    Copyright (c) 2020 Project CHIP Authors
4  *    Copyright (c) 2020 Texas Instruments Incorporated
5  *    All rights reserved.
6  *
7  *    Licensed under the Apache License, Version 2.0 (the "License");
8  *    you may not use this file except in compliance with the License.
9  *    You may obtain a copy of the License at
10  *
11  *        http://www.apache.org/licenses/LICENSE-2.0
12  *
13  *    Unless required by applicable law or agreed to in writing, software
14  *    distributed under the License is distributed on an "AS IS" BASIS,
15  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  *    See the License for the specific language governing permissions and
17  *    limitations under the License.
18  */
19
20 #include "AppTask.h"
21 #include "AppConfig.h"
22 #include "AppEvent.h"
23 #include "Server.h"
24
25 #include "FreeRTOS.h"
26
27 #include <platform/CHIPDeviceLayer.h>
28 #include <support/CHIPMem.h>
29 #include <support/CHIPPlatformMemory.h>
30
31 #include "OnboardingCodesUtil.h"
32
33 #include "DataModelHandler.h"
34
35 #include <ti/drivers/apps/Button.h>
36 #include <ti/drivers/apps/LED.h>
37
38 /* syscfg */
39 #include <ti_drivers_config.h>
40
41 #define APP_TASK_STACK_SIZE (4096)
42 #define APP_TASK_PRIORITY 4
43 #define APP_EVENT_QUEUE_SIZE 10
44
45 using namespace ::chip::DeviceLayer;
46
47 static TaskHandle_t sAppTaskHandle;
48 static QueueHandle_t sAppEventQueue;
49
50 static LED_Handle sAppRedHandle;
51 static LED_Handle sAppGreenHandle;
52 static Button_Handle sAppLeftHandle;
53 static Button_Handle sAppRightHandle;
54
55 AppTask AppTask::sAppTask;
56
57 int AppTask::StartAppTask()
58 {
59     int ret = 0;
60
61     sAppEventQueue = xQueueCreate(APP_EVENT_QUEUE_SIZE, sizeof(AppEvent));
62     if (sAppEventQueue == NULL)
63     {
64         PLAT_LOG("Failed to allocate app event queue");
65         while (1)
66             ;
67     }
68
69     // Start App task.
70     if (xTaskCreate(AppTaskMain, "APP", APP_TASK_STACK_SIZE / sizeof(StackType_t), NULL, APP_TASK_PRIORITY, &sAppTaskHandle) !=
71         pdPASS)
72     {
73         PLAT_LOG("Failed to create app task");
74         while (1)
75             ;
76     }
77     return ret;
78 }
79
80 int AppTask::Init()
81 {
82     int ret = CHIP_ERROR_MAX;
83     LED_Params ledParams;
84     Button_Params buttionParams;
85     ConnectivityManager::ThreadPollingConfig pollingConfig;
86
87     cc13x2_26x2LogInit();
88
89     // Init Chip memory management before the stack
90     chip::Platform::MemoryInit();
91
92     ret = PlatformMgr().InitChipStack();
93     if (ret != CHIP_NO_ERROR)
94     {
95         PLAT_LOG("PlatformMgr().InitChipStack() failed");
96         while (1)
97             ;
98     }
99
100     ret = ThreadStackMgr().InitThreadStack();
101     if (ret != CHIP_NO_ERROR)
102     {
103         PLAT_LOG("ThreadStackMgr().InitThreadStack() failed");
104         while (1)
105             ;
106     }
107
108     ret = ConnectivityMgr().SetThreadDeviceType(ConnectivityManager::kThreadDeviceType_Router);
109     if (ret != CHIP_NO_ERROR)
110     {
111         PLAT_LOG("ConnectivityMgr().SetThreadDeviceType() failed");
112         while (1)
113             ;
114     }
115
116     pollingConfig.Clear();
117     pollingConfig.ActivePollingIntervalMS   = 5000; // ms
118     pollingConfig.InactivePollingIntervalMS = 5000; // ms
119
120     ret = ConnectivityMgr().SetThreadPollingConfig(pollingConfig);
121     if (ret != CHIP_NO_ERROR)
122     {
123         PLAT_LOG("ConnectivityMgr().SetThreadPollingConfig() failed");
124         while (1)
125             ;
126     }
127
128     ret = PlatformMgr().StartEventLoopTask();
129     if (ret != CHIP_NO_ERROR)
130     {
131         PLAT_LOG("PlatformMgr().StartEventLoopTask() failed");
132         while (1)
133             ;
134     }
135
136     ret = ThreadStackMgrImpl().StartThreadTask();
137     if (ret != CHIP_NO_ERROR)
138     {
139         PLAT_LOG("ThreadStackMgr().StartThreadTask() failed");
140         while (1)
141             ;
142     }
143
144     // Init ZCL Data Model and start server
145     PLAT_LOG("Initialize Server");
146     InitServer();
147
148     // Initialize LEDs
149     PLAT_LOG("Initialize LEDs");
150     LED_init();
151
152     LED_Params_init(&ledParams); // default PWM LED
153     sAppRedHandle = LED_open(CONFIG_LED_RED, &ledParams);
154     LED_setOff(sAppRedHandle);
155
156     LED_Params_init(&ledParams); // default PWM LED
157     sAppGreenHandle = LED_open(CONFIG_LED_GREEN, &ledParams);
158     LED_setOff(sAppGreenHandle);
159
160     // Initialize buttons
161     PLAT_LOG("Initialize buttons");
162     Button_init();
163
164     Button_Params_init(&buttionParams);
165     buttionParams.buttonEventMask   = Button_EV_CLICKED | Button_EV_LONGCLICKED;
166     buttionParams.longPressDuration = 1000U; // ms
167     sAppLeftHandle                  = Button_open(CONFIG_BTN_LEFT, ButtonLeftEventHandler, &buttionParams);
168
169     Button_Params_init(&buttionParams);
170     buttionParams.buttonEventMask   = Button_EV_CLICKED | Button_EV_LONGCLICKED;
171     buttionParams.longPressDuration = 1000U; // ms
172     sAppRightHandle                 = Button_open(CONFIG_BTN_RIGHT, ButtonRightEventHandler, &buttionParams);
173
174     // Initialize BoltLock module
175     PLAT_LOG("Initialize BoltLock");
176     BoltLockMgr().Init();
177
178     BoltLockMgr().SetCallbacks(ActionInitiated, ActionCompleted);
179
180     ConfigurationMgr().LogDeviceConfig();
181
182     // QR code will be used with CHIP Tool
183     PrintOnboardingCodes(chip::RendezvousInformationFlags::kBLE);
184
185     return 0;
186 }
187
188 void AppTask::AppTaskMain(void * pvParameter)
189 {
190     AppEvent event;
191
192     sAppTask.Init();
193
194     while (1)
195     {
196         /* Task pend until we have stuff to do */
197         if (xQueueReceive(sAppEventQueue, &event, portMAX_DELAY) == pdTRUE)
198         {
199             sAppTask.DispatchEvent(&event);
200         }
201     }
202 }
203
204 void AppTask::PostEvent(const AppEvent * aEvent)
205 {
206     if (xQueueSend(sAppEventQueue, aEvent, 0) != pdPASS)
207     {
208         /* Failed to post the message */
209     }
210 }
211
212 void AppTask::ButtonLeftEventHandler(Button_Handle handle, Button_EventMask events)
213 {
214     AppEvent event;
215     event.Type = AppEvent::kEventType_ButtonLeft;
216
217     if (events & Button_EV_CLICKED)
218     {
219         event.ButtonEvent.Type = AppEvent::kAppEventButtonType_Clicked;
220     }
221     else if (events & Button_EV_LONGCLICKED)
222     {
223         event.ButtonEvent.Type = AppEvent::kAppEventButtonType_LongClicked;
224     }
225     // button callbacks are in ISR context
226     if (xQueueSendFromISR(sAppEventQueue, &event, NULL) != pdPASS)
227     {
228         /* Failed to post the message */
229     }
230 }
231
232 void AppTask::ButtonRightEventHandler(Button_Handle handle, Button_EventMask events)
233 {
234     AppEvent event;
235     event.Type = AppEvent::kEventType_ButtonRight;
236
237     if (events & Button_EV_CLICKED)
238     {
239         event.ButtonEvent.Type = AppEvent::kAppEventButtonType_Clicked;
240     }
241     else if (events & Button_EV_LONGCLICKED)
242     {
243         event.ButtonEvent.Type = AppEvent::kAppEventButtonType_LongClicked;
244     }
245     // button callbacks are in ISR context
246     if (xQueueSendFromISR(sAppEventQueue, &event, NULL) != pdPASS)
247     {
248         /* Failed to post the message */
249     }
250 }
251
252 void AppTask::ActionInitiated(BoltLockManager::Action_t aAction, int32_t aActor)
253 {
254     // If the action has been initiated by the lock, update the bolt lock trait
255     // and start flashing the LEDs rapidly to indicate action initiation.
256     if (aAction == BoltLockManager::LOCK_ACTION)
257     {
258         PLAT_LOG("Lock initiated");
259         ; // TODO
260     }
261     else if (aAction == BoltLockManager::UNLOCK_ACTION)
262     {
263         PLAT_LOG("Unlock initiated");
264         ; // TODO
265     }
266
267     LED_setOn(sAppGreenHandle, LED_BRIGHTNESS_MAX);
268     LED_startBlinking(sAppGreenHandle, 50 /* ms */, LED_BLINK_FOREVER);
269     LED_setOn(sAppRedHandle, LED_BRIGHTNESS_MAX);
270     LED_startBlinking(sAppRedHandle, 110 /* ms */, LED_BLINK_FOREVER);
271 }
272
273 void AppTask::ActionCompleted(BoltLockManager::Action_t aAction)
274 {
275     // if the action has been completed by the lock, update the bolt lock trait.
276     // Turn on the lock LED if in a LOCKED state OR
277     // Turn off the lock LED if in an UNLOCKED state.
278     if (aAction == BoltLockManager::LOCK_ACTION)
279     {
280         PLAT_LOG("Lock completed");
281         LED_stopBlinking(sAppGreenHandle);
282         LED_setOn(sAppGreenHandle, LED_BRIGHTNESS_MAX);
283         LED_stopBlinking(sAppRedHandle);
284         LED_setOn(sAppRedHandle, LED_BRIGHTNESS_MAX);
285     }
286     else if (aAction == BoltLockManager::UNLOCK_ACTION)
287     {
288         PLAT_LOG("Unlock completed");
289         LED_stopBlinking(sAppGreenHandle);
290         LED_setOff(sAppGreenHandle);
291         LED_stopBlinking(sAppRedHandle);
292         LED_setOff(sAppRedHandle);
293     }
294 }
295
296 void AppTask::DispatchEvent(AppEvent * aEvent)
297 {
298     switch (aEvent->Type)
299     {
300     case AppEvent::kEventType_ButtonLeft:
301         if (AppEvent::kAppEventButtonType_Clicked == aEvent->ButtonEvent.Type)
302         {
303             if (!BoltLockMgr().IsUnlocked())
304             {
305                 BoltLockMgr().InitiateAction(0, BoltLockManager::UNLOCK_ACTION);
306             }
307         }
308         else if (AppEvent::kAppEventButtonType_LongClicked == aEvent->ButtonEvent.Type)
309         {
310             // Disable BLE advertisements
311             if (ConnectivityMgr().IsBLEAdvertisingEnabled())
312             {
313                 ConnectivityMgr().SetBLEAdvertisingEnabled(false);
314                 PLAT_LOG("Disabled BLE Advertisements");
315             }
316         }
317         break;
318
319     case AppEvent::kEventType_ButtonRight:
320         if (AppEvent::kAppEventButtonType_Clicked == aEvent->ButtonEvent.Type)
321         {
322             if (BoltLockMgr().IsUnlocked())
323             {
324                 BoltLockMgr().InitiateAction(0, BoltLockManager::LOCK_ACTION);
325             }
326         }
327         else if (AppEvent::kAppEventButtonType_LongClicked == aEvent->ButtonEvent.Type)
328         {
329             // Enable BLE advertisements
330             if (!ConnectivityMgr().IsBLEAdvertisingEnabled())
331             {
332                 ConnectivityMgr().SetBLEAdvertisingEnabled(true);
333                 PLAT_LOG("Enabled BLE Advertisements");
334             }
335         }
336         break;
337
338     case AppEvent::kEventType_AppEvent:
339         if (NULL != aEvent->Handler)
340         {
341             aEvent->Handler(aEvent);
342         }
343         break;
344
345     case AppEvent::kEventType_None:
346     default:
347         break;
348     }
349 }