1 /*
2  * Copyright (c) 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 "dsoftbus_handler.h"
17 
18 #include "ipc_skeleton.h"
19 #include "token_setproc.h"
20 
21 #include "device.h"
22 #include "devicestatus_define.h"
23 #include "utility.h"
24 
25 #undef LOG_TAG
26 #define LOG_TAG "DSoftbusHandler"
27 
28 namespace OHOS {
29 namespace Msdp {
30 namespace DeviceStatus {
31 namespace Cooperate {
32 constexpr int32_t MAX_INPUT_DEV_NUM { 100 };
33 constexpr int32_t INVALID_DEVICE_ID { -1 };
34 
DSoftbusHandler(IContext * env)35 DSoftbusHandler::DSoftbusHandler(IContext *env)
36     : env_(env)
37 {
38     handles_ = {
39         { static_cast<int32_t>(MessageId::DSOFTBUS_START_COOPERATE),
40         [this] (const std::string &networkId, NetPacket &packet) {
41             this->OnStartCooperate(networkId, packet);}},
42         { static_cast<int32_t>(MessageId::DSOFTBUS_STOP_COOPERATE),
43         [this] (const std::string &networkId, NetPacket &packet) {
44             this->OnStopCooperate(networkId, packet);}},
45         { static_cast<int32_t>(MessageId::DSOFTBUS_COME_BACK),
46         [this] (const std::string &networkId, NetPacket &packet) {
47             this->OnComeBack(networkId, packet);}},
48         { static_cast<int32_t>(MessageId::DSOFTBUS_RELAY_COOPERATE),
49         [this] (const std::string &networkId, NetPacket &packet) {
50             this->OnRelayCooperate(networkId, packet);}},
51         { static_cast<int32_t>(MessageId::DSOFTBUS_RELAY_COOPERATE_FINISHED),
52         [this] (const std::string &networkId, NetPacket &packet) {
53             this->OnRelayCooperateFinish(networkId, packet);}},
54         { static_cast<int32_t>(MessageId::DSOFTBUS_SUBSCRIBE_MOUSE_LOCATION),
55         [this] (const std::string &networkId, NetPacket &packet) {
56             this->OnSubscribeMouseLocation(networkId, packet);}},
57         { static_cast<int32_t>(MessageId::DSOFTBUS_UNSUBSCRIBE_MOUSE_LOCATION),
58         [this] (const std::string &networkId, NetPacket &packet) {
59             this->OnUnSubscribeMouseLocation(networkId, packet);}},
60         { static_cast<int32_t>(MessageId::DSOFTBUS_REPLY_SUBSCRIBE_MOUSE_LOCATION),
61         [this] (const std::string &networkId, NetPacket &packet) {
62             this->OnReplySubscribeLocation(networkId, packet);}},
63         { static_cast<int32_t>(MessageId::DSOFTBUS_REPLY_UNSUBSCRIBE_MOUSE_LOCATION),
64         [this] (const std::string &networkId, NetPacket &packet) {
65             this->OnReplyUnSubscribeLocation(networkId, packet);}},
66         { static_cast<int32_t>(MessageId::DSOFTBUS_MOUSE_LOCATION),
67         [this] (const std::string &networkId, NetPacket &packet) {
68             this->OnRemoteMouseLocation(networkId, packet);}},
69         { static_cast<int32_t>(MessageId::DSOFTBUS_INPUT_DEV_SYNC),
70         [this] (const std::string &networkId, NetPacket &packet) {
71             this->OnRemoteInputDevice(networkId, packet);}},
72         { static_cast<int32_t>(MessageId::DSOFTBUS_INPUT_DEV_HOT_PLUG),
73         [this] (const std::string &networkId, NetPacket &packet) {
74             this->OnRemoteHotPlug(networkId, packet);}}
75     };
76     observer_ = std::make_shared<DSoftbusObserver>(*this);
77     CHKPV(env_);
78     env_->GetDSoftbus().AddObserver(observer_);
79 }
80 
~DSoftbusHandler()81 DSoftbusHandler::~DSoftbusHandler()
82 {
83     CHKPV(env_);
84     env_->GetDSoftbus().RemoveObserver(observer_);
85 }
86 
AttachSender(Channel<CooperateEvent>::Sender sender)87 void DSoftbusHandler::AttachSender(Channel<CooperateEvent>::Sender sender)
88 {
89     CALL_DEBUG_ENTER;
90     std::lock_guard guard(lock_);
91     sender_ = sender;
92 }
93 
OpenSession(const std::string & networkId)94 int32_t DSoftbusHandler::OpenSession(const std::string &networkId)
95 {
96     CALL_INFO_TRACE;
97     auto tokenId = OHOS::IPCSkeleton::GetCallingTokenID();
98     int ret = SetFirstCallerTokenID(tokenId);
99     if (ret != RET_OK) {
100         FI_HILOGW("Failed to SetFirstCallerTokenID, ret:%{public}d", ret);
101     }
102     return env_->GetDSoftbus().OpenSession(networkId);
103 }
104 
CloseSession(const std::string & networkId)105 void DSoftbusHandler::CloseSession(const std::string &networkId)
106 {
107     CALL_INFO_TRACE;
108     env_->GetDSoftbus().CloseSession(networkId);
109 }
110 
CloseAllSessions()111 void DSoftbusHandler::CloseAllSessions()
112 {
113     CALL_INFO_TRACE;
114     env_->GetDSoftbus().CloseAllSessions();
115 }
116 
StartCooperate(const std::string & networkId,const DSoftbusStartCooperate & event)117 int32_t DSoftbusHandler::StartCooperate(const std::string &networkId, const DSoftbusStartCooperate &event)
118 {
119     CALL_INFO_TRACE;
120     NetPacket packet(MessageId::DSOFTBUS_START_COOPERATE);
121     packet << event.originNetworkId << event.cursorPos.x
122         << event.cursorPos.y << event.success << event.extra.priv;
123     if (packet.ChkRWError()) {
124         FI_HILOGE("Failed to write data packet");
125         return RET_ERR;
126     }
127     int32_t ret = env_->GetDSoftbus().SendPacket(networkId, packet);
128     if (ret != RET_OK) {
129         OnCommunicationFailure(networkId);
130     }
131     return ret;
132 }
133 
StopCooperate(const std::string & networkId,const DSoftbusStopCooperate & event)134 int32_t DSoftbusHandler::StopCooperate(const std::string &networkId, const DSoftbusStopCooperate &event)
135 {
136     CALL_INFO_TRACE;
137     NetPacket packet(MessageId::DSOFTBUS_STOP_COOPERATE);
138     int32_t ret = env_->GetDSoftbus().SendPacket(networkId, packet);
139     if (ret != RET_OK) {
140         OnCommunicationFailure(networkId);
141     }
142     return ret;
143 }
144 
ComeBack(const std::string & networkId,const DSoftbusComeBack & event)145 int32_t DSoftbusHandler::ComeBack(const std::string &networkId, const DSoftbusComeBack &event)
146 {
147     CALL_INFO_TRACE;
148     NetPacket packet(MessageId::DSOFTBUS_COME_BACK);
149     packet << event.originNetworkId << event.cursorPos.x << event.cursorPos.y << event.extra.priv;
150     if (packet.ChkRWError()) {
151         FI_HILOGE("Failed to write data packet");
152         return RET_ERR;
153     }
154     int32_t ret = env_->GetDSoftbus().SendPacket(networkId, packet);
155     if (ret != RET_OK) {
156         OnCommunicationFailure(networkId);
157     }
158     return ret;
159 }
160 
RelayCooperate(const std::string & networkId,const DSoftbusRelayCooperate & event)161 int32_t DSoftbusHandler::RelayCooperate(const std::string &networkId, const DSoftbusRelayCooperate &event)
162 {
163     CALL_INFO_TRACE;
164     NetPacket packet(MessageId::DSOFTBUS_RELAY_COOPERATE);
165     packet << event.targetNetworkId;
166     if (packet.ChkRWError()) {
167         FI_HILOGE("Failed to write data packet");
168         return RET_ERR;
169     }
170     int32_t ret = env_->GetDSoftbus().SendPacket(networkId, packet);
171     if (ret != RET_OK) {
172         OnCommunicationFailure(networkId);
173     }
174     return ret;
175 }
176 
RelayCooperateFinish(const std::string & networkId,const DSoftbusRelayCooperateFinished & event)177 int32_t DSoftbusHandler::RelayCooperateFinish(const std::string &networkId, const DSoftbusRelayCooperateFinished &event)
178 {
179     CALL_INFO_TRACE;
180     NetPacket packet(MessageId::DSOFTBUS_RELAY_COOPERATE_FINISHED);
181     packet << event.targetNetworkId << event.normal;
182     if (packet.ChkRWError()) {
183         FI_HILOGE("Failed to write data packet");
184         return RET_ERR;
185     }
186     int32_t ret = env_->GetDSoftbus().SendPacket(networkId, packet);
187     if (ret != RET_OK) {
188         OnCommunicationFailure(networkId);
189     }
190     return ret;
191 }
192 
GetLocalNetworkId()193 std::string DSoftbusHandler::GetLocalNetworkId()
194 {
195     return IDSoftbusAdapter::GetLocalNetworkId();
196 }
197 
OnBind(const std::string & networkId)198 void DSoftbusHandler::OnBind(const std::string &networkId)
199 {
200     FI_HILOGI("Bind to \'%{public}s\'", Utility::Anonymize(networkId).c_str());
201     SendEvent(CooperateEvent(
202         CooperateEventType::DSOFTBUS_SESSION_OPENED,
203         DSoftbusSessionOpened {
204             .networkId = networkId
205         }));
206 }
207 
OnShutdown(const std::string & networkId)208 void DSoftbusHandler::OnShutdown(const std::string &networkId)
209 {
210     FI_HILOGI("Connection with \'%{public}s\' shutdown", Utility::Anonymize(networkId).c_str());
211     SendEvent(CooperateEvent(
212         CooperateEventType::DSOFTBUS_SESSION_CLOSED,
213         DSoftbusSessionClosed {
214             .networkId = networkId
215         }));
216 }
217 
OnConnected(const std::string & networkId)218 void DSoftbusHandler::OnConnected(const std::string &networkId)
219 {
220     FI_HILOGI("Connection to \'%{public}s\' successfully", Utility::Anonymize(networkId).c_str());
221     SendEvent(CooperateEvent(
222         CooperateEventType::DSOFTBUS_SESSION_OPENED,
223         DSoftbusSessionOpened {
224             .networkId = networkId
225         }));
226 }
227 
OnPacket(const std::string & networkId,NetPacket & packet)228 bool DSoftbusHandler::OnPacket(const std::string &networkId, NetPacket &packet)
229 {
230     CALL_DEBUG_ENTER;
231     int32_t messageId = static_cast<int32_t>(packet.GetMsgId());
232     auto it = handles_.find(messageId);
233     if (it != handles_.end()) {
234         (it->second)(networkId, packet);
235         return true;
236     }
237     FI_HILOGD("Unsupported messageId: %{public}d from %{public}s", messageId,
238         Utility::Anonymize(networkId).c_str());
239     return false;
240 }
241 
SendEvent(const CooperateEvent & event)242 void DSoftbusHandler::SendEvent(const CooperateEvent &event)
243 {
244     std::lock_guard guard(lock_);
245     auto ret = sender_.Send(event);
246     if (ret != Channel<CooperateEvent>::NO_ERROR) {
247         FI_HILOGE("Failed to send event via channel, error:%{public}d", ret);
248     }
249 }
250 
OnCommunicationFailure(const std::string & networkId)251 void DSoftbusHandler::OnCommunicationFailure(const std::string &networkId)
252 {
253     env_->GetDSoftbus().CloseSession(networkId);
254     FI_HILOGI("Notify communication failure with peer(%{public}s)", Utility::Anonymize(networkId).c_str());
255     SendEvent(CooperateEvent(
256         CooperateEventType::DSOFTBUS_SESSION_CLOSED,
257         DSoftbusSessionClosed {
258             .networkId = networkId
259         }));
260 }
261 
OnStartCooperate(const std::string & networkId,NetPacket & packet)262 void DSoftbusHandler::OnStartCooperate(const std::string &networkId, NetPacket &packet)
263 {
264     CALL_INFO_TRACE;
265     DSoftbusStartCooperate event {
266         .networkId = networkId,
267     };
268     packet >> event.originNetworkId >> event.cursorPos.x
269         >> event.cursorPos.y >> event.success;
270     if (packet.ChkRWError()) {
271         FI_HILOGE("Failed to read data packet");
272         return;
273     }
274     packet >> event.extra.priv;
275     if (packet.ChkRWError()) {
276         event.extra.priv = 0;
277     }
278     SendEvent(CooperateEvent(
279         CooperateEventType::DSOFTBUS_START_COOPERATE,
280         event));
281 }
282 
OnStopCooperate(const std::string & networkId,NetPacket & packet)283 void DSoftbusHandler::OnStopCooperate(const std::string &networkId, NetPacket &packet)
284 {
285     CALL_INFO_TRACE;
286     DSoftbusStopCooperate event {
287         .networkId = networkId,
288         .normal = true,
289     };
290     SendEvent(CooperateEvent(
291         CooperateEventType::DSOFTBUS_STOP_COOPERATE,
292         event));
293 }
294 
OnComeBack(const std::string & networkId,NetPacket & packet)295 void DSoftbusHandler::OnComeBack(const std::string &networkId, NetPacket &packet)
296 {
297     CALL_INFO_TRACE;
298     DSoftbusComeBack event {
299         .networkId = networkId,
300         .success = true,
301     };
302     packet >> event.originNetworkId >> event.cursorPos.x >> event.cursorPos.y;
303     if (packet.ChkRWError()) {
304         FI_HILOGE("Failed to read data packet");
305         return;
306     }
307     packet >> event.extra.priv;
308     if (packet.ChkRWError()) {
309         event.extra.priv = 0;
310     }
311     SendEvent(CooperateEvent(
312         CooperateEventType::DSOFTBUS_COME_BACK,
313         event));
314 }
315 
OnRelayCooperate(const std::string & networkId,NetPacket & packet)316 void DSoftbusHandler::OnRelayCooperate(const std::string &networkId, NetPacket &packet)
317 {
318     CALL_INFO_TRACE;
319     DSoftbusRelayCooperate event {
320         .networkId = networkId,
321         .normal = true,
322     };
323     packet >> event.targetNetworkId;
324     if (packet.ChkRWError()) {
325         FI_HILOGE("Failed to read data packet");
326         return;
327     }
328     SendEvent(CooperateEvent(
329         CooperateEventType::DSOFTBUS_RELAY_COOPERATE,
330         event));
331 }
332 
OnRelayCooperateFinish(const std::string & networkId,NetPacket & packet)333 void DSoftbusHandler::OnRelayCooperateFinish(const std::string &networkId, NetPacket &packet)
334 {
335     CALL_INFO_TRACE;
336     DSoftbusRelayCooperate event {
337         .networkId = networkId,
338     };
339     packet >> event.targetNetworkId >> event.normal;
340     if (packet.ChkRWError()) {
341         FI_HILOGE("Failed to read data packet");
342         return;
343     }
344     SendEvent(CooperateEvent(
345         CooperateEventType::DSOFTBUS_RELAY_COOPERATE_FINISHED,
346         event));
347 }
348 
OnSubscribeMouseLocation(const std::string & networKId,NetPacket & packet)349 void DSoftbusHandler::OnSubscribeMouseLocation(const std::string &networKId, NetPacket &packet)
350 {
351     CALL_INFO_TRACE;
352     DSoftbusSubscribeMouseLocation event;
353     packet >> event.networkId >> event.remoteNetworkId;
354     if (packet.ChkRWError()) {
355         FI_HILOGE("Failed to read data packet");
356         return;
357     }
358     SendEvent(CooperateEvent(
359         CooperateEventType::DSOFTBUS_SUBSCRIBE_MOUSE_LOCATION,
360         event));
361 }
362 
OnUnSubscribeMouseLocation(const std::string & networKId,NetPacket & packet)363 void DSoftbusHandler::OnUnSubscribeMouseLocation(const std::string& networKId, NetPacket &packet)
364 {
365     CALL_INFO_TRACE;
366     DSoftbusUnSubscribeMouseLocation event;
367     packet >> event.networkId >> event.remoteNetworkId;
368     if (packet.ChkRWError()) {
369         FI_HILOGE("Failed to read data packet");
370         return;
371     }
372     SendEvent(CooperateEvent(
373         CooperateEventType::DSOFTBUS_UNSUBSCRIBE_MOUSE_LOCATION,
374         event));
375 }
376 
OnReplySubscribeLocation(const std::string & networKId,NetPacket & packet)377 void DSoftbusHandler::OnReplySubscribeLocation(const std::string& networKId, NetPacket &packet)
378 {
379     CALL_INFO_TRACE;
380     DSoftbusReplySubscribeMouseLocation event;
381     packet >> event.networkId >> event.remoteNetworkId >> event.result;
382     if (packet.ChkRWError()) {
383         FI_HILOGE("Failed to read data packet");
384         return;
385     }
386     SendEvent(CooperateEvent(
387         CooperateEventType::DSOFTBUS_REPLY_SUBSCRIBE_MOUSE_LOCATION,
388         event));
389 }
390 
OnReplyUnSubscribeLocation(const std::string & networKId,NetPacket & packet)391 void DSoftbusHandler::OnReplyUnSubscribeLocation(const std::string& networKId, NetPacket &packet)
392 {
393     CALL_INFO_TRACE;
394     DSoftbusReplyUnSubscribeMouseLocation event;
395     packet >> event.networkId >> event.remoteNetworkId >> event.result;
396     if (packet.ChkRWError()) {
397         FI_HILOGE("Failed to read data packet");
398         return;
399     }
400     SendEvent(CooperateEvent(
401         CooperateEventType::DSOFTBUS_REPLY_UNSUBSCRIBE_MOUSE_LOCATION,
402         event));
403 }
404 
OnRemoteMouseLocation(const std::string & networKId,NetPacket & packet)405 void DSoftbusHandler::OnRemoteMouseLocation(const std::string& networKId, NetPacket &packet)
406 {
407     CALL_DEBUG_ENTER;
408     DSoftbusSyncMouseLocation event;
409     packet >> event.networkId >> event.remoteNetworkId >> event.mouseLocation.displayX >>
410         event.mouseLocation.displayY >> event.mouseLocation.displayWidth >> event.mouseLocation.displayHeight;
411     if (packet.ChkRWError()) {
412         FI_HILOGE("Failed to read data packet");
413         return;
414     }
415     SendEvent(CooperateEvent(
416         CooperateEventType::DSOFTBUS_MOUSE_LOCATION,
417         event));
418 }
419 
OnRemoteInputDevice(const std::string & networkId,NetPacket & packet)420 void DSoftbusHandler::OnRemoteInputDevice(const std::string& networkId, NetPacket &packet)
421 {
422     CALL_INFO_TRACE;
423     DSoftbusSyncInputDevice event;
424     int32_t devNum { -1 };
425     packet >> devNum;
426     event.networkId = networkId;
427     FI_HILOGI("devNum:%{public}d", devNum);
428     if (devNum <= 0 || devNum >= MAX_INPUT_DEV_NUM) {
429         FI_HILOGE("Invalid devNum:%{public}d", devNum);
430         return;
431     }
432     for (int32_t i = 0; i < devNum; i++) {
433         auto device = std::make_shared<Device>(INVALID_DEVICE_ID);
434         if (DeserializeDevice(device, packet) != RET_OK) {
435             FI_HILOGE("DeserializeDevice failed");
436             return;
437         }
438         event.devices.push_back(device);
439     }
440     SendEvent(CooperateEvent(
441         CooperateEventType::DSOFTBUS_INPUT_DEV_SYNC,
442         event));
443 }
444 
OnRemoteHotPlug(const std::string & networkId,NetPacket & packet)445 void DSoftbusHandler::OnRemoteHotPlug(const std::string &networkId, NetPacket &packet)
446 {
447     CALL_INFO_TRACE;
448     DSoftbusHotPlugEvent event;
449     packet >> event.type;
450     FI_HILOGI("Hot plug type:%{public}d", event.type);
451     auto device = std::make_shared<Device>(INVALID_DEVICE_ID);
452     if (DeserializeDevice(device, packet) != RET_OK) {
453         FI_HILOGE("DeserializeDevice failed");
454         return;
455     }
456     event.device = device;
457     SendEvent(CooperateEvent(
458         CooperateEventType::DSOFTBUS_INPUT_DEV_HOT_PLUG,
459         event));
460 }
461 
DeserializeDevice(std::shared_ptr<IDevice> device,NetPacket & packet)462 int32_t DSoftbusHandler::DeserializeDevice(std::shared_ptr<IDevice> device, NetPacket &packet)
463 {
464     CALL_DEBUG_ENTER;
465     CHKPR(device, RET_ERR);
466     int32_t data;
467     std::string str;
468     packet >> data;
469     device->SetId(data);
470     packet >> str;
471     device->SetDevPath(str);
472     packet >> str;
473     device->SetSysPath(str);
474     packet >> data;
475     device->SetBus(data);
476     packet >> data;
477     device->SetVendor(data);
478     packet >> data;
479     device->SetProduct(data);
480     packet >> data;
481     device->SetVersion(data);
482     packet >> str;
483     device->SetName(str);
484     packet >> str;
485     device->SetPhys(str);
486     packet >> str;
487     device->SetUniq(str);
488     bool isPointerDevice { false };
489     packet >> isPointerDevice;
490     if (isPointerDevice) {
491         device->AddCapability(IDevice::Capability::DEVICE_CAP_POINTER);
492     }
493     bool isKeyboard { false };
494     packet >> isKeyboard;
495     if (isKeyboard) {
496         device->AddCapability(IDevice::Capability::DEVICE_CAP_KEYBOARD);
497     }
498     int32_t keyboardType { static_cast<int32_t> (IDevice::KeyboardType::KEYBOARD_TYPE_NONE) };
499     packet >> keyboardType;
500     device->SetKeyboardType(static_cast<IDevice::KeyboardType>(keyboardType));
501     if (packet.ChkRWError()) {
502         FI_HILOGE("Packet read type failed");
503         return RET_ERR;
504     }
505     return RET_OK;
506 }
507 } // namespace Cooperate
508 } // namespace DeviceStatus
509 } // namespace Msdp
510 } // namespace OHOS
511