Apply Upstream code (2021-03-15)
[platform/upstream/connectedhomeip.git] / src / app / util / ember-compatibility-functions.cpp
1 /*
2  *
3  *    Copyright (c) 2021 Project CHIP Authors
4  *
5  *    Licensed under the Apache License, Version 2.0 (the "License");
6  *    you may not use this file except in compliance with the License.
7  *    You may obtain a copy of the License at
8  *
9  *        http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *    Unless required by applicable law or agreed to in writing, software
12  *    distributed under the License is distributed on an "AS IS" BASIS,
13  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *    See the License for the specific language governing permissions and
15  *    limitations under the License.
16  */
17
18 /**
19  *    @file
20  *          Contains the functions for compatibility with ember ZCL inner state
21  *          when calling ember callbacks.
22  */
23
24 #include "ember-compatibility-functions.h"
25
26 #include <app/Command.h>
27 #include <lib/core/CHIPCore.h>
28 #include <lib/core/CHIPTLV.h>
29 #include <lib/support/CodeUtils.h>
30 #include <util/util.h>
31
32 namespace chip {
33 namespace app {
34 namespace Compatibility {
35 namespace {
36 EmberAfClusterCommand imCompatibilityEmberAfCluster;
37 EmberApsFrame imCompatibilityEmberApsFrame;
38 EmberAfInterpanHeader imCompatibilityInterpanHeader;
39 Command * currentCommandObject;
40 } // namespace
41
42 void SetupEmberAfObjects(Command * command, ClusterId clusterId, CommandId commandId, EndpointId endpointId)
43 {
44     const Messaging::ExchangeContext * commandExchangeCtx = command->GetExchangeContext();
45
46     imCompatibilityEmberApsFrame.clusterId           = clusterId;
47     imCompatibilityEmberApsFrame.destinationEndpoint = endpointId;
48     imCompatibilityEmberApsFrame.sourceEndpoint      = 1; // source endpoint is fixed to 1 for now.
49     imCompatibilityEmberApsFrame.sequence = (commandExchangeCtx != nullptr ? commandExchangeCtx->GetExchangeId() & 0xFF : 0);
50
51     imCompatibilityEmberAfCluster.commandId      = commandId;
52     imCompatibilityEmberAfCluster.apsFrame       = &imCompatibilityEmberApsFrame;
53     imCompatibilityEmberAfCluster.interPanHeader = &imCompatibilityInterpanHeader;
54     imCompatibilityEmberAfCluster.source =
55         (commandExchangeCtx != nullptr ? commandExchangeCtx->GetSecureSessionHandle().GetPeerNodeId() : 0); // 0 is "Any" NodeId.
56
57     emAfCurrentCommand   = &imCompatibilityEmberAfCluster;
58     currentCommandObject = command;
59 }
60
61 bool IMEmberAfSendDefaultResponseWithCallback(EmberAfStatus status)
62 {
63     if (currentCommandObject == nullptr)
64     {
65         // If this command is not handled by IM, then let ember send response.
66         return false;
67     }
68     CHIP_ERROR err = CHIP_NO_ERROR;
69     (void) status;
70
71     // TODO: handle the response according to status value
72     chip::app::Command::CommandParams returnCommandParam = { imCompatibilityEmberApsFrame.sourceEndpoint,
73                                                              0, // GroupId
74                                                              imCompatibilityEmberApsFrame.clusterId,
75                                                              imCompatibilityEmberAfCluster.commandId,
76                                                              (chip::app::Command::CommandPathFlags::kEndpointIdValid) };
77
78     chip::TLV::TLVType dummyType = chip::TLV::kTLVType_NotSpecified;
79     chip::TLV::TLVWriter writer  = currentCommandObject->CreateCommandDataElementTLVWriter();
80
81     SuccessOrExit(err = writer.StartContainer(chip::TLV::AnonymousTag, chip::TLV::kTLVType_Structure, dummyType));
82     SuccessOrExit(err = writer.EndContainer(dummyType));
83     SuccessOrExit(err = writer.Finalize());
84     SuccessOrExit(err = currentCommandObject->AddCommand(returnCommandParam));
85 exit:
86     return true;
87 }
88
89 void ResetEmberAfObjects()
90 {
91     emAfCurrentCommand   = nullptr;
92     currentCommandObject = nullptr;
93 }
94
95 } // namespace Compatibility
96 } // namespace app
97 } // namespace chip