fc5d18a6150bdb819735c3192668a4d865e3f4a1
[platform/upstream/connectedhomeip.git] / examples / bridge-app / linux / main.cpp
1 /*
2  *
3  *    Copyright (c) 2021 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 #include <platform/CHIPDeviceLayer.h>
20 #include <platform/PlatformManager.h>
21
22 #include "af.h"
23 #include "gen/attribute-id.h"
24 #include "gen/cluster-id.h"
25 #include <app/chip-zcl-zpro-codec.h>
26 #include <app/util/af-types.h>
27 #include <app/util/attribute-storage.h>
28 #include <app/util/util.h>
29 #include <core/CHIPError.h>
30 #include <setup_payload/QRCodeSetupPayloadGenerator.h>
31 #include <setup_payload/SetupPayload.h>
32 #include <support/CHIPMem.h>
33 #include <support/RandUtils.h>
34
35 #include "LightingManager.h"
36 #include "Options.h"
37 #include "Server.h"
38
39 #include <cassert>
40 #include <iostream>
41
42 using namespace chip;
43 using namespace chip::Inet;
44 using namespace chip::Transport;
45 using namespace chip::DeviceLayer;
46
47 void emberAfPostAttributeChangeCallback(EndpointId endpoint, ClusterId clusterId, AttributeId attributeId, uint8_t mask,
48                                         uint16_t manufacturerCode, uint8_t type, uint8_t size, uint8_t * value)
49 {
50     if (clusterId != ZCL_ON_OFF_CLUSTER_ID)
51     {
52         ChipLogProgress(Zcl, "Unknown cluster ID: %d", clusterId);
53         return;
54     }
55
56     if (attributeId != ZCL_ON_OFF_ATTRIBUTE_ID)
57     {
58         ChipLogProgress(Zcl, "Unknown attribute ID: %d", attributeId);
59         return;
60     }
61
62     if (*value)
63     {
64         LightingMgr().InitiateAction(LightingManager::ON_ACTION);
65     }
66     else
67     {
68         LightingMgr().InitiateAction(LightingManager::OFF_ACTION);
69     }
70 }
71
72 /** @brief OnOff Cluster Init
73  *
74  * This function is called when a specific cluster is initialized. It gives the
75  * application an opportunity to take care of cluster initialization procedures.
76  * It is called exactly once for each endpoint where cluster is present.
77  *
78  * @param endpoint   Ver.: always
79  *
80  * TODO Issue #3841
81  * emberAfOnOffClusterInitCallback happens before the stack initialize the cluster
82  * attributes to the default value.
83  * The logic here expects something similar to the deprecated Plugins callback
84  * emberAfPluginOnOffClusterServerPostInitCallback.
85  *
86  */
87 void emberAfOnOffClusterInitCallback(EndpointId endpoint)
88 {
89     // TODO: implement any additional Cluster Server init actions
90 }
91
92 namespace {
93 void EventHandler(const chip::DeviceLayer::ChipDeviceEvent * event, intptr_t arg)
94 {
95     (void) arg;
96     if (event->Type == chip::DeviceLayer::DeviceEventType::kCHIPoBLEConnectionEstablished)
97     {
98         ChipLogProgress(DeviceLayer, "Receive kCHIPoBLEConnectionEstablished");
99     }
100 }
101
102 CHIP_ERROR PrintQRCodeContent()
103 {
104     CHIP_ERROR err = CHIP_NO_ERROR;
105     // If we do not have a discriminator, generate one
106     chip::SetupPayload payload;
107     uint32_t setUpPINCode;
108     uint16_t setUpDiscriminator;
109     uint16_t vendorId;
110     uint16_t productId;
111     std::string result;
112
113     err = ConfigurationMgr().GetSetupPinCode(setUpPINCode);
114     SuccessOrExit(err);
115
116     err = ConfigurationMgr().GetSetupDiscriminator(setUpDiscriminator);
117     SuccessOrExit(err);
118
119     err = ConfigurationMgr().GetVendorId(vendorId);
120     SuccessOrExit(err);
121
122     err = ConfigurationMgr().GetProductId(productId);
123     SuccessOrExit(err);
124
125     payload.version       = 1;
126     payload.vendorID      = vendorId;
127     payload.productID     = productId;
128     payload.setUpPINCode  = setUpPINCode;
129     payload.discriminator = setUpDiscriminator;
130
131     // Wrap it so SuccessOrExit can work
132     {
133         chip::QRCodeSetupPayloadGenerator generator(payload);
134         err = generator.payloadBase41Representation(result);
135         SuccessOrExit(err);
136     }
137
138     std::cout << "SetupPINCode: [" << setUpPINCode << "]" << std::endl;
139     // There might be whitespace in setup QRCode, add brackets to make it clearer.
140     std::cout << "SetupQRCode:  [" << result << "]" << std::endl;
141
142 exit:
143     if (err != CHIP_NO_ERROR)
144     {
145         std::cerr << "Failed to generate QR Code: " << ErrorStr(err) << std::endl;
146     }
147     return err;
148 }
149 } // namespace
150
151 int main(int argc, char * argv[])
152 {
153     CHIP_ERROR err = CHIP_NO_ERROR;
154
155     err = chip::Platform::MemoryInit();
156     SuccessOrExit(err);
157
158     err = ParseArguments(argc, argv);
159     SuccessOrExit(err);
160
161     err = chip::DeviceLayer::PlatformMgr().InitChipStack();
162     SuccessOrExit(err);
163
164     err = PrintQRCodeContent();
165     SuccessOrExit(err);
166
167     chip::DeviceLayer::PlatformMgrImpl().AddEventHandler(EventHandler, 0);
168
169     chip::DeviceLayer::ConnectivityMgr().SetBLEDeviceName(nullptr); // Use default device name (CHIP-XXXX)
170
171 #ifdef CONFIG_NETWORK_BLE
172     chip::DeviceLayer::Internal::BLEMgrImpl().ConfigureBle(LinuxDeviceOptions::GetInstance().mBleDevice, false);
173 #endif
174
175     chip::DeviceLayer::ConnectivityMgr().SetBLEAdvertisingEnabled(true);
176
177     LightingMgr().Init();
178
179     // Init ZCL Data Model and CHIP App Server
180     InitServer();
181
182     chip::DeviceLayer::PlatformMgr().RunEventLoop();
183
184 exit:
185     if (err != CHIP_NO_ERROR)
186     {
187         std::cerr << "Failed to run Linux Bridge App: " << ErrorStr(err) << std::endl;
188         // End the program with non zero error code to indicate a error.
189         return 1;
190     }
191     return 0;
192 }