Fix for x86_64 build fail
[platform/upstream/connectedhomeip.git] / examples / all-clusters-app / esp32 / main / DeviceCallbacks.cpp
1 /*
2  *
3  *    Copyright (c) 2020 Project CHIP Authors
4  *    All rights reserved.
5  *
6  *    Licensed under the Apache License, Version 2.0 (the "License");
7  *    you may not use this file except in compliance with the License.
8  *    You may obtain a copy of the License at
9  *
10  *        http://www.apache.org/licenses/LICENSE-2.0
11  *
12  *    Unless required by applicable law or agreed to in writing, software
13  *    distributed under the License is distributed on an "AS IS" BASIS,
14  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  *    See the License for the specific language governing permissions and
16  *    limitations under the License.
17  */
18
19 /**
20  * @file DeviceCallbacks.cpp
21  *
22  * Implements all the callbacks to the application from the CHIP Stack
23  *
24  **/
25 #include "DeviceCallbacks.h"
26
27 #include "CHIPDeviceManager.h"
28 #include "Globals.h"
29 #include "LEDWidget.h"
30 #include "WiFiWidget.h"
31 #include "esp_heap_caps.h"
32 #include "esp_log.h"
33 #include "gen/attribute-id.h"
34 #include "gen/cluster-id.h"
35 #include <app/server/Mdns.h>
36 #include <app/util/basic-types.h>
37 #include <app/util/util.h>
38 #include <lib/mdns/Advertiser.h>
39 #include <support/CodeUtils.h>
40
41 static const char * TAG = "app-devicecallbacks";
42
43 using namespace ::chip;
44 using namespace ::chip::Inet;
45 using namespace ::chip::System;
46 using namespace ::chip::DeviceLayer;
47
48 uint32_t identifyTimerCount;
49 constexpr uint32_t kIdentifyTimerDelayMS = 250;
50
51 void DeviceCallbacks::DeviceEventCallback(const ChipDeviceEvent * event, intptr_t arg)
52 {
53     switch (event->Type)
54     {
55     case DeviceEventType::kInternetConnectivityChange:
56         OnInternetConnectivityChange(event);
57         break;
58
59     case DeviceEventType::kSessionEstablished:
60         OnSessionEstablished(event);
61         break;
62     case DeviceEventType::kInterfaceIpAddressChanged:
63         if ((event->InterfaceIpAddressChanged.Type == InterfaceIpChangeType::kIpV4_Assigned) ||
64             (event->InterfaceIpAddressChanged.Type == InterfaceIpChangeType::kIpV6_Assigned))
65         {
66             // MDNS server restart on any ip assignment: if link local ipv6 is configured, that
67             // will not trigger a 'internet connectivity change' as there is no internet
68             // connectivity. MDNS still wants to refresh its listening interfaces to include the
69             // newly selected address.
70             chip::app::Mdns::StartServer();
71         }
72         break;
73     }
74
75     ESP_LOGI(TAG, "Current free heap: %d\n", heap_caps_get_free_size(MALLOC_CAP_8BIT));
76 }
77
78 void DeviceCallbacks::PostAttributeChangeCallback(EndpointId endpointId, ClusterId clusterId, AttributeId attributeId, uint8_t mask,
79                                                   uint16_t manufacturerCode, uint8_t type, uint8_t size, uint8_t * value)
80 {
81     ESP_LOGI(TAG, "PostAttributeChangeCallback - Cluster ID: '0x%04x', EndPoint ID: '0x%02x', Attribute ID: '0x%04x'", clusterId,
82              endpointId, attributeId);
83
84     switch (clusterId)
85     {
86     case ZCL_ON_OFF_CLUSTER_ID:
87         OnOnOffPostAttributeChangeCallback(endpointId, attributeId, value);
88         break;
89
90     case ZCL_IDENTIFY_CLUSTER_ID:
91         OnIdentifyPostAttributeChangeCallback(endpointId, attributeId, value);
92         break;
93
94     default:
95         ESP_LOGI(TAG, "Unhandled cluster ID: %d", clusterId);
96         break;
97     }
98
99     ESP_LOGI(TAG, "Current free heap: %d\n", heap_caps_get_free_size(MALLOC_CAP_8BIT));
100 }
101
102 void DeviceCallbacks::OnInternetConnectivityChange(const ChipDeviceEvent * event)
103 {
104     if (event->InternetConnectivityChange.IPv4 == kConnectivity_Established)
105     {
106         ESP_LOGI(TAG, "Server ready at: %s:%d", event->InternetConnectivityChange.address, CHIP_PORT);
107         wifiLED.Set(true);
108         chip::app::Mdns::StartServer();
109     }
110     else if (event->InternetConnectivityChange.IPv4 == kConnectivity_Lost)
111     {
112         ESP_LOGE(TAG, "Lost IPv4 connectivity...");
113         wifiLED.Set(false);
114     }
115     if (event->InternetConnectivityChange.IPv6 == kConnectivity_Established)
116     {
117         ESP_LOGI(TAG, "IPv6 Server ready...");
118         chip::app::Mdns::StartServer();
119     }
120     else if (event->InternetConnectivityChange.IPv6 == kConnectivity_Lost)
121     {
122         ESP_LOGE(TAG, "Lost IPv6 connectivity...");
123     }
124 }
125
126 void DeviceCallbacks::OnSessionEstablished(const ChipDeviceEvent * event)
127 {
128     if (event->SessionEstablished.IsCommissioner)
129     {
130         ESP_LOGI(TAG, "Commissioner detected!");
131     }
132 }
133
134 void DeviceCallbacks::OnOnOffPostAttributeChangeCallback(EndpointId endpointId, AttributeId attributeId, uint8_t * value)
135 {
136     VerifyOrExit(attributeId == ZCL_ON_OFF_ATTRIBUTE_ID, ESP_LOGI(TAG, "Unhandled Attribute ID: '0x%04x", attributeId));
137     VerifyOrExit(endpointId == 1 || endpointId == 2, ESP_LOGE(TAG, "Unexpected EndPoint ID: `0x%02x'", endpointId));
138
139     // At this point we can assume that value points to a bool value.
140     endpointId == 1 ? statusLED1.Set(*value) : statusLED2.Set(*value);
141
142 exit:
143     return;
144 }
145
146 void IdentifyTimerHandler(Layer * systemLayer, void * appState, Error error)
147 {
148     statusLED1.Animate();
149
150     if (identifyTimerCount)
151     {
152         SystemLayer.StartTimer(kIdentifyTimerDelayMS, IdentifyTimerHandler, appState);
153         // Decrement the timer count.
154         identifyTimerCount--;
155     }
156 }
157
158 void DeviceCallbacks::OnIdentifyPostAttributeChangeCallback(EndpointId endpointId, AttributeId attributeId, uint8_t * value)
159 {
160     VerifyOrExit(attributeId == ZCL_IDENTIFY_TIME_ATTRIBUTE_ID, ESP_LOGI(TAG, "Unhandled Attribute ID: '0x%04x", attributeId));
161     VerifyOrExit(endpointId == 1, ESP_LOGE(TAG, "Unexpected EndPoint ID: `0x%02x'", endpointId));
162
163     statusLED1.Blink(kIdentifyTimerDelayMS * 2);
164
165     // timerCount represents the number of callback executions before we stop the timer.
166     // value is expressed in seconds and the timer is fired every 250ms, so just multiply value by 4.
167     // Also, we want timerCount to be odd number, so the ligth state ends in the same state it starts.
168     identifyTimerCount = (*value) * 4;
169
170     SystemLayer.CancelTimer(IdentifyTimerHandler, this);
171     SystemLayer.StartTimer(kIdentifyTimerDelayMS, IdentifyTimerHandler, this);
172
173 exit:
174     return;
175 }
176
177 bool emberAfBasicClusterMfgSpecificPingCallback(void)
178 {
179     emberAfSendDefaultResponse(emberAfCurrentCommand(), EMBER_ZCL_STATUS_SUCCESS);
180     return true;
181 }