xref: /aosp_15_r20/external/ot-br-posix/src/dbus/server/dbus_thread_object_ncp.cpp (revision 4a64e381480ef79f0532b2421e44e6ee336b8e0d)
1 /*
2  *    Copyright (c) 2024, The OpenThread Authors.
3  *    All rights reserved.
4  *
5  *    Redistribution and use in source and binary forms, with or without
6  *    modification, are permitted provided that the following conditions are met:
7  *    1. Redistributions of source code must retain the above copyright
8  *       notice, this list of conditions and the following disclaimer.
9  *    2. Redistributions in binary form must reproduce the above copyright
10  *       notice, this list of conditions and the following disclaimer in the
11  *       documentation and/or other materials provided with the distribution.
12  *    3. Neither the name of the copyright holder nor the
13  *       names of its contributors may be used to endorse or promote products
14  *       derived from this software without specific prior written permission.
15  *
16  *    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  *    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  *    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  *    ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20  *    LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  *    CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  *    SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  *    INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  *    CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  *    ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  *    POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 #include "dbus_thread_object_ncp.hpp"
30 
31 #include "common/api_strings.hpp"
32 #include "common/byteswap.hpp"
33 #include "common/code_utils.hpp"
34 #include "dbus/common/constants.hpp"
35 #include "dbus/server/dbus_agent.hpp"
36 #include "utils/thread_helper.hpp"
37 
38 using std::placeholders::_1;
39 using std::placeholders::_2;
40 
41 namespace otbr {
42 namespace DBus {
43 
DBusThreadObjectNcp(DBusConnection & aConnection,const std::string & aInterfaceName,otbr::Ncp::NcpHost & aHost)44 DBusThreadObjectNcp::DBusThreadObjectNcp(DBusConnection     &aConnection,
45                                          const std::string  &aInterfaceName,
46                                          otbr::Ncp::NcpHost &aHost)
47     : DBusObject(&aConnection, OTBR_DBUS_OBJECT_PREFIX + aInterfaceName)
48     , mHost(aHost)
49 {
50 }
51 
Init(void)52 otbrError DBusThreadObjectNcp::Init(void)
53 {
54     otbrError error = OTBR_ERROR_NONE;
55 
56     SuccessOrExit(error = DBusObject::Initialize(true));
57 
58     RegisterAsyncGetPropertyHandler(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_PROPERTY_DEVICE_ROLE,
59                                     std::bind(&DBusThreadObjectNcp::AsyncGetDeviceRoleHandler, this, _1));
60 
61     RegisterMethod(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_JOIN_METHOD,
62                    std::bind(&DBusThreadObjectNcp::JoinHandler, this, _1));
63     RegisterMethod(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_LEAVE_NETWORK_METHOD,
64                    std::bind(&DBusThreadObjectNcp::LeaveHandler, this, _1));
65     RegisterMethod(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_SCHEDULE_MIGRATION_METHOD,
66                    std::bind(&DBusThreadObjectNcp::ScheduleMigrationHandler, this, _1));
67 
68     SuccessOrExit(error = Signal(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_SIGNAL_READY, std::make_tuple()));
69 exit:
70     return error;
71 }
72 
AsyncGetDeviceRoleHandler(DBusRequest & aRequest)73 void DBusThreadObjectNcp::AsyncGetDeviceRoleHandler(DBusRequest &aRequest)
74 {
75     otDeviceRole role = mHost.GetDeviceRole();
76 
77     ReplyAsyncGetProperty(aRequest, GetDeviceRoleName(role));
78 }
79 
ReplyAsyncGetProperty(DBusRequest & aRequest,const std::string & aContent)80 void DBusThreadObjectNcp::ReplyAsyncGetProperty(DBusRequest &aRequest, const std::string &aContent)
81 {
82     UniqueDBusMessage reply{dbus_message_new_method_return(aRequest.GetMessage())};
83     DBusMessageIter   replyIter;
84     otError           error = OT_ERROR_NONE;
85 
86     dbus_message_iter_init_append(reply.get(), &replyIter);
87     SuccessOrExit(error = OtbrErrorToOtError(DBusMessageEncodeToVariant(&replyIter, aContent)));
88 
89 exit:
90     if (error == OT_ERROR_NONE)
91     {
92         dbus_connection_send(aRequest.GetConnection(), reply.get(), nullptr);
93     }
94     else
95     {
96         aRequest.ReplyOtResult(error);
97     }
98 }
99 
JoinHandler(DBusRequest & aRequest)100 void DBusThreadObjectNcp::JoinHandler(DBusRequest &aRequest)
101 {
102     std::vector<uint8_t>     dataset;
103     otOperationalDatasetTlvs activeOpDatasetTlvs;
104     otError                  error = OT_ERROR_NONE;
105 
106     auto args = std::tie(dataset);
107 
108     SuccessOrExit(DBusMessageToTuple(*aRequest.GetMessage(), args), error = OT_ERROR_INVALID_ARGS);
109 
110     VerifyOrExit(dataset.size() <= sizeof(activeOpDatasetTlvs.mTlvs), error = OT_ERROR_INVALID_ARGS);
111     std::copy(dataset.begin(), dataset.end(), activeOpDatasetTlvs.mTlvs);
112     activeOpDatasetTlvs.mLength = dataset.size();
113 
114     mHost.Join(activeOpDatasetTlvs, [aRequest](otError aError, const std::string &aErrorInfo) mutable {
115         OT_UNUSED_VARIABLE(aErrorInfo);
116         aRequest.ReplyOtResult(aError);
117     });
118 
119 exit:
120     if (error != OT_ERROR_NONE)
121     {
122         aRequest.ReplyOtResult(error);
123     }
124 }
125 
LeaveHandler(DBusRequest & aRequest)126 void DBusThreadObjectNcp::LeaveHandler(DBusRequest &aRequest)
127 {
128     mHost.Leave([aRequest](otError aError, const std::string &aErrorInfo) mutable {
129         OT_UNUSED_VARIABLE(aErrorInfo);
130         aRequest.ReplyOtResult(aError);
131     });
132 }
133 
ScheduleMigrationHandler(DBusRequest & aRequest)134 void DBusThreadObjectNcp::ScheduleMigrationHandler(DBusRequest &aRequest)
135 {
136     std::vector<uint8_t>     dataset;
137     uint32_t                 delayInMilli;
138     otOperationalDatasetTlvs pendingOpDatasetTlvs;
139     otError                  error = OT_ERROR_NONE;
140 
141     auto args = std::tie(dataset, delayInMilli);
142 
143     SuccessOrExit(DBusMessageToTuple(*aRequest.GetMessage(), args), error = OT_ERROR_INVALID_ARGS);
144 
145     VerifyOrExit(dataset.size() <= sizeof(pendingOpDatasetTlvs.mTlvs), error = OT_ERROR_INVALID_ARGS);
146     std::copy(dataset.begin(), dataset.end(), pendingOpDatasetTlvs.mTlvs);
147     pendingOpDatasetTlvs.mLength = dataset.size();
148 
149     SuccessOrExit(error = agent::ThreadHelper::ProcessDatasetForMigration(pendingOpDatasetTlvs, delayInMilli));
150 
151     mHost.ScheduleMigration(pendingOpDatasetTlvs, [aRequest](otError aError, const std::string &aErrorInfo) mutable {
152         OT_UNUSED_VARIABLE(aErrorInfo);
153         aRequest.ReplyOtResult(aError);
154     });
155 
156 exit:
157     if (error != OT_ERROR_NONE)
158     {
159         aRequest.ReplyOtResult(error);
160     }
161 }
162 
163 } // namespace DBus
164 } // namespace otbr
165