1 /*
2 * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "distributed_hardware_stub.h"
17
18 #include <cinttypes>
19
20 #include "nlohmann/json.hpp"
21 #include "accesstoken_kit.h"
22 #include "anonymous_string.h"
23 #include "constants.h"
24 #include "dhardware_ipc_interface_code.h"
25 #include "distributed_hardware_errno.h"
26 #include "distributed_hardware_log.h"
27 #include "ipc_skeleton.h"
28 #include "publisher_listener_proxy.h"
29
30 namespace OHOS {
31 namespace DistributedHardware {
OnRemoteRequest(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)32 int32_t DistributedHardwareStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply,
33 MessageOption &option)
34 {
35 if (data.ReadInterfaceToken() != GetDescriptor()) {
36 DHLOGE("IPC Token valid fail!");
37 return ERR_INVALID_DATA;
38 }
39 switch (code) {
40 case static_cast<uint32_t>(DHMsgInterfaceCode::REG_PUBLISHER_LISTNER): {
41 return RegisterPublisherListenerInner(data, reply);
42 }
43 case static_cast<uint32_t>(DHMsgInterfaceCode::UNREG_PUBLISHER_LISTENER): {
44 return UnregisterPublisherListenerInner(data, reply);
45 }
46 case static_cast<uint32_t>(DHMsgInterfaceCode::PUBLISH_MESSAGE): {
47 return PublishMessageInner(data, reply);
48 }
49 case static_cast<uint32_t>(DHMsgInterfaceCode::INIT_CTL_CEN): {
50 return InitializeAVCenterInner(data, reply);
51 }
52 case static_cast<uint32_t>(DHMsgInterfaceCode::RELEASE_CTL_CEN): {
53 return ReleaseAVCenterInner(data, reply);
54 }
55 case static_cast<uint32_t>(DHMsgInterfaceCode::CREATE_CTL_CEN_CHANNEL): {
56 return CreateControlChannelInner(data, reply);
57 }
58 case static_cast<uint32_t>(DHMsgInterfaceCode::NOTIFY_AV_EVENT): {
59 return NotifyAVCenterInner(data, reply);
60 }
61 case static_cast<uint32_t>(DHMsgInterfaceCode::REGISTER_CTL_CEN_CALLBACK): {
62 return RegisterControlCenterCallbackInner(data, reply);
63 }
64 case static_cast<uint32_t>(DHMsgInterfaceCode::QUERY_LOCAL_SYS_SPEC): {
65 return QueryLocalSysSpecInner(data, reply);
66 }
67 case static_cast<uint32_t>(DHMsgInterfaceCode::NOTIFY_SOURCE_DEVICE_REMOTE_DMSDP_STARTED): {
68 return HandleNotifySourceRemoteSinkStarted(data, reply);
69 }
70 case static_cast<uint32_t>(DHMsgInterfaceCode::PAUSE_DISTRIBUTED_HARDWARE): {
71 return PauseDistributedHardwareInner(data, reply);
72 }
73 case static_cast<uint32_t>(DHMsgInterfaceCode::RESUME_DISTRIBUTED_HARDWARE): {
74 return ResumeDistributedHardwareInner(data, reply);
75 }
76 case static_cast<uint32_t>(DHMsgInterfaceCode::STOP_DISTRIBUTED_HARDWARE): {
77 return StopDistributedHardwareInner(data, reply);
78 }
79 default:
80 return IPCObjectStub::OnRemoteRequest(code, data, reply, option);
81 }
82 return DH_FWK_SUCCESS;
83 }
84
RegisterPublisherListenerInner(MessageParcel & data,MessageParcel & reply)85 int32_t DistributedHardwareStub::RegisterPublisherListenerInner(MessageParcel &data, MessageParcel &reply)
86 {
87 uint32_t topicInt = data.ReadUint32();
88 if (!ValidTopic(topicInt)) {
89 DHLOGE("Topic invalid: %" PRIu32, topicInt);
90 reply.WriteInt32(ERR_DH_FWK_PARA_INVALID);
91 return ERR_DH_FWK_PARA_INVALID;
92 }
93
94 DHTopic topic = (DHTopic)topicInt;
95 sptr<IPublisherListener> listener = iface_cast<IPublisherListener>(data.ReadRemoteObject());
96 if (listener == nullptr) {
97 DHLOGE("Register publisher listener is null");
98 reply.WriteInt32(ERR_DH_FWK_PARA_INVALID);
99 return ERR_DH_FWK_PARA_INVALID;
100 }
101 DHLOGI("Register listener, topic: %" PRIu32, (uint32_t)topic);
102 RegisterPublisherListener(topic, listener);
103 reply.WriteInt32(DH_FWK_SUCCESS);
104 return DH_FWK_SUCCESS;
105 }
106
UnregisterPublisherListenerInner(MessageParcel & data,MessageParcel & reply)107 int32_t DistributedHardwareStub::UnregisterPublisherListenerInner(MessageParcel &data, MessageParcel &reply)
108 {
109 uint32_t topicInt = data.ReadUint32();
110 if (!ValidTopic(topicInt)) {
111 DHLOGE("Topic invalid: %" PRIu32, topicInt);
112 reply.WriteInt32(ERR_DH_FWK_PARA_INVALID);
113 return ERR_DH_FWK_PARA_INVALID;
114 }
115
116 DHTopic topic = (DHTopic)topicInt;
117 sptr<IPublisherListener> listener = iface_cast<IPublisherListener>(data.ReadRemoteObject());
118 if (listener == nullptr) {
119 DHLOGE("Unregister publisher listener is null");
120 reply.WriteInt32(ERR_DH_FWK_PARA_INVALID);
121 return ERR_DH_FWK_PARA_INVALID;
122 }
123 DHLOGI("Unregister listener, topic: %" PRIu32, (uint32_t)topic);
124 UnregisterPublisherListener(topic, listener);
125 reply.WriteInt32(DH_FWK_SUCCESS);
126 return DH_FWK_SUCCESS;
127 }
128
PublishMessageInner(MessageParcel & data,MessageParcel & reply)129 int32_t DistributedHardwareStub::PublishMessageInner(MessageParcel &data, MessageParcel &reply)
130 {
131 uint32_t topicInt = data.ReadUint32();
132 if (!ValidTopic(topicInt)) {
133 DHLOGE("Topic invalid: %" PRIu32, topicInt);
134 reply.WriteInt32(ERR_DH_FWK_PARA_INVALID);
135 return ERR_DH_FWK_PARA_INVALID;
136 }
137
138 DHTopic topic = (DHTopic)topicInt;
139 std::string message = data.ReadString();
140 DHLOGI("Publish message, topic: %" PRIu32, (uint32_t)topic);
141 PublishMessage(topic, message);
142 reply.WriteInt32(DH_FWK_SUCCESS);
143 return DH_FWK_SUCCESS;
144 }
145
QueryLocalSysSpecInner(MessageParcel & data,MessageParcel & reply)146 int32_t DistributedHardwareStub::QueryLocalSysSpecInner(MessageParcel &data, MessageParcel &reply)
147 {
148 uint32_t specInt = data.ReadUint32();
149 if (!ValidQueryLocalSpec(specInt)) {
150 DHLOGE("Spec invalid: %" PRIu32, specInt);
151 reply.WriteInt32(ERR_DH_FWK_PARA_INVALID);
152 return ERR_DH_FWK_PARA_INVALID;
153 }
154
155 QueryLocalSysSpecType spec = (QueryLocalSysSpecType)specInt;
156 DHLOGI("Query Local Sys Spec: %" PRIu32, (uint32_t)spec);
157 std::string res = QueryLocalSysSpec(spec);
158 DHLOGI("Get Local spec: %s", res.c_str());
159 reply.WriteString(res);
160 return DH_FWK_SUCCESS;
161 }
162
InitializeAVCenterInner(MessageParcel & data,MessageParcel & reply)163 int32_t DistributedHardwareStub::InitializeAVCenterInner(MessageParcel &data, MessageParcel &reply)
164 {
165 TransRole transRole = (TransRole)(data.ReadUint32());
166 int32_t engineId = 0;
167 int32_t ret = InitializeAVCenter(transRole, engineId);
168 if (!reply.WriteInt32(engineId)) {
169 DHLOGE("Write engine id failed");
170 return ERR_DH_FWK_SERVICE_WRITE_INFO_FAIL;
171 }
172 if (!reply.WriteInt32(ret)) {
173 DHLOGE("Write ret code failed");
174 return ERR_DH_FWK_SERVICE_WRITE_INFO_FAIL;
175 }
176 return DH_FWK_SUCCESS;
177 }
178
ReleaseAVCenterInner(MessageParcel & data,MessageParcel & reply)179 int32_t DistributedHardwareStub::ReleaseAVCenterInner(MessageParcel &data, MessageParcel &reply)
180 {
181 int32_t engineId = data.ReadInt32();
182 int32_t ret = ReleaseAVCenter(engineId);
183 if (!reply.WriteInt32(ret)) {
184 DHLOGE("Write ret code failed");
185 return ERR_DH_FWK_SERVICE_WRITE_INFO_FAIL;
186 }
187 return DH_FWK_SUCCESS;
188 }
189
CreateControlChannelInner(MessageParcel & data,MessageParcel & reply)190 int32_t DistributedHardwareStub::CreateControlChannelInner(MessageParcel &data, MessageParcel &reply)
191 {
192 int32_t engineId = data.ReadInt32();
193 std::string peerDevId = data.ReadString();
194 int32_t ret = CreateControlChannel(engineId, peerDevId);
195 if (!reply.WriteInt32(ret)) {
196 DHLOGE("Write ret code failed");
197 return ERR_DH_FWK_SERVICE_WRITE_INFO_FAIL;
198 }
199 return DH_FWK_SUCCESS;
200 }
201
NotifyAVCenterInner(MessageParcel & data,MessageParcel & reply)202 int32_t DistributedHardwareStub::NotifyAVCenterInner(MessageParcel &data, MessageParcel &reply)
203 {
204 int32_t engineId = data.ReadInt32();
205 uint32_t type = data.ReadUint32();
206 std::string content = data.ReadString();
207 std::string peerDevId = data.ReadString();
208 int32_t ret = NotifyAVCenter(engineId, AVTransEvent{ (EventType)type, content, peerDevId });
209 if (!reply.WriteInt32(ret)) {
210 DHLOGE("Write ret code failed");
211 return ERR_DH_FWK_SERVICE_WRITE_INFO_FAIL;
212 }
213 return DH_FWK_SUCCESS;
214 }
215
RegisterControlCenterCallbackInner(MessageParcel & data,MessageParcel & reply)216 int32_t DistributedHardwareStub::RegisterControlCenterCallbackInner(MessageParcel &data, MessageParcel &reply)
217 {
218 int32_t engineId = data.ReadInt32();
219 sptr<IAVTransControlCenterCallback> callback = iface_cast<IAVTransControlCenterCallback>(data.ReadRemoteObject());
220 if (callback == nullptr) {
221 DHLOGE("Input av control center callback is null");
222 return ERR_DH_FWK_PARA_INVALID;
223 }
224
225 int32_t ret = RegisterCtlCenterCallback(engineId, callback);
226 if (!reply.WriteInt32(ret)) {
227 DHLOGE("Write ret code failed");
228 return ERR_DH_FWK_SERVICE_WRITE_INFO_FAIL;
229 }
230 return DH_FWK_SUCCESS;
231 }
232
HandleNotifySourceRemoteSinkStarted(MessageParcel & data,MessageParcel & reply)233 int32_t OHOS::DistributedHardware::DistributedHardwareStub::HandleNotifySourceRemoteSinkStarted(MessageParcel &data,
234 MessageParcel &reply)
235 {
236 DHLOGI("DistributedHardwareStub HandleNotifySourceRemoteSinkStarted Start.");
237 std::string deviceId = data.ReadString();
238 int32_t ret = NotifySourceRemoteSinkStarted(deviceId);
239 if (!reply.WriteInt32(ret)) {
240 DHLOGE("write ret failed.");
241 return ERR_DH_FWK_SERVICE_WRITE_INFO_FAIL;
242 }
243 DHLOGI("DistributedHardwareStub HandleNotifySourceRemoteSinkStarted End.");
244 return DH_FWK_SUCCESS;
245 }
246
ValidTopic(uint32_t topic)247 bool DistributedHardwareStub::ValidTopic(uint32_t topic)
248 {
249 if (topic <= (uint32_t)DHTopic::TOPIC_MIN || topic >= (uint32_t)DHTopic::TOPIC_MAX) {
250 return false;
251 }
252 return true;
253 }
254
ValidQueryLocalSpec(uint32_t spec)255 bool DistributedHardwareStub::ValidQueryLocalSpec(uint32_t spec)
256 {
257 if (spec <= (uint32_t)QueryLocalSysSpecType::MIN || spec >= (uint32_t)QueryLocalSysSpecType::MAX) {
258 return false;
259 }
260 return true;
261 }
262
PauseDistributedHardwareInner(MessageParcel & data,MessageParcel & reply)263 int32_t DistributedHardwareStub::PauseDistributedHardwareInner(MessageParcel &data, MessageParcel &reply)
264 {
265 if (!HasAccessDHPermission()) {
266 DHLOGE("The caller has no ACCESS_DISTRIBUTED_HARDWARE permission.");
267 return ERR_DH_FWK_ACCESS_PERMISSION_CHECK_FAIL;
268 }
269 DHType dhType = static_cast<DHType>(data.ReadInt32());
270 std::string networkId = data.ReadString();
271 int32_t ret = PauseDistributedHardware(dhType, networkId);
272 if (!reply.WriteInt32(ret)) {
273 DHLOGE("Write ret code failed");
274 return ERR_DH_FWK_SERVICE_WRITE_INFO_FAIL;
275 }
276 return DH_FWK_SUCCESS;
277 }
278
ResumeDistributedHardwareInner(MessageParcel & data,MessageParcel & reply)279 int32_t DistributedHardwareStub::ResumeDistributedHardwareInner(MessageParcel &data, MessageParcel &reply)
280 {
281 if (!HasAccessDHPermission()) {
282 DHLOGE("The caller has no ACCESS_DISTRIBUTED_HARDWARE permission.");
283 return ERR_DH_FWK_ACCESS_PERMISSION_CHECK_FAIL;
284 }
285 DHType dhType = static_cast<DHType>(data.ReadInt32());
286 std::string networkId = data.ReadString();
287 int32_t ret = ResumeDistributedHardware(dhType, networkId);
288 if (!reply.WriteInt32(ret)) {
289 DHLOGE("Write ret code failed");
290 return ERR_DH_FWK_SERVICE_WRITE_INFO_FAIL;
291 }
292 return DH_FWK_SUCCESS;
293 }
294
StopDistributedHardwareInner(MessageParcel & data,MessageParcel & reply)295 int32_t DistributedHardwareStub::StopDistributedHardwareInner(MessageParcel &data, MessageParcel &reply)
296 {
297 if (!HasAccessDHPermission()) {
298 DHLOGE("The caller has no ACCESS_DISTRIBUTED_HARDWARE permission.");
299 return ERR_DH_FWK_ACCESS_PERMISSION_CHECK_FAIL;
300 }
301 DHType dhType = static_cast<DHType>(data.ReadInt32());
302 std::string networkId = data.ReadString();
303 int32_t ret = StopDistributedHardware(dhType, networkId);
304 if (!reply.WriteInt32(ret)) {
305 DHLOGE("Write ret code failed");
306 return ERR_DH_FWK_SERVICE_WRITE_INFO_FAIL;
307 }
308 return DH_FWK_SUCCESS;
309 }
310
HasAccessDHPermission()311 bool DistributedHardwareStub::HasAccessDHPermission()
312 {
313 Security::AccessToken::AccessTokenID callerToken = IPCSkeleton::GetCallingTokenID();
314 const std::string permissionName = "ohos.permission.ACCESS_DISTRIBUTED_HARDWARE";
315 int32_t result = Security::AccessToken::AccessTokenKit::VerifyAccessToken(callerToken,
316 permissionName);
317 return (result == Security::AccessToken::PERMISSION_GRANTED);
318 }
319 } // namespace DistributedHardware
320 } // namespace OHOS
321