• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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 "softbus_listener.h"
17 
18 #include <securec.h>
19 #include <unistd.h>
20 #if defined(__LITEOS_M__)
21 #include "dm_mutex.h"
22 #include "dm_thread.h"
23 #else
24 #include <thread>
25 #include <mutex>
26 #endif
27 
28 #include "device_manager_service.h"
29 #include "dm_constants.h"
30 #include "dm_device_info.h"
31 #include "dm_log.h"
32 #include "parameter.h"
33 #include "system_ability_definition.h"
34 
35 namespace OHOS {
36 namespace DistributedHardware {
37 const int32_t DISCOVER_STATUS_LEN = 20;
38 const int32_t SOFTBUS_CHECK_INTERVAL = 100000; // 100ms
39 
40 constexpr const char* DISCOVER_STATUS_KEY = "persist.distributed_hardware.device_manager.discover_status";
41 constexpr const char* DISCOVER_STATUS_ON = "1";
42 constexpr const char* DISCOVER_STATUS_OFF = "0";
43 
44 SoftbusListener::PulishStatus SoftbusListener::publishStatus = SoftbusListener::STATUS_UNKNOWN;
45 IPublishCb SoftbusListener::softbusPublishCallback_ = {
46     .OnPublishResult = SoftbusListener::OnPublishResult,
47 };
48 
49 INodeStateCb SoftbusListener::softbusNodeStateCb_ = {
50     .events = EVENT_NODE_STATE_ONLINE | EVENT_NODE_STATE_OFFLINE | EVENT_NODE_STATE_INFO_CHANGED,
51     .onNodeOnline = SoftbusListener::OnSoftBusDeviceOnline,
52     .onNodeOffline = SoftbusListener::OnSoftbusDeviceOffline,
53     .onNodeBasicInfoChanged = SoftbusListener::OnSoftbusDeviceInfoChanged};
54 
DeviceOnLine(DmDeviceInfo deviceInfo)55 void DeviceOnLine(DmDeviceInfo deviceInfo)
56 {
57 #if defined(__LITEOS_M__)
58     DmMutex lockDeviceOnLine;
59 #else
60     std::mutex lockDeviceOnLine;
61     std::lock_guard<std::mutex> lock(lockDeviceOnLine);
62 #endif
63     DeviceManagerService::GetInstance().HandleDeviceOnline(deviceInfo);
64 }
65 
DeviceOffLine(DmDeviceInfo deviceInfo)66 void DeviceOffLine(DmDeviceInfo deviceInfo)
67 {
68 #if defined(__LITEOS_M__)
69     DmMutex lockDeviceOffLine;
70 #else
71     std::mutex lockDeviceOffLine;
72     std::lock_guard<std::mutex> lock(lockDeviceOffLine);
73 #endif
74     DeviceManagerService::GetInstance().HandleDeviceOffline(deviceInfo);
75 }
76 
SoftbusListener()77 SoftbusListener::SoftbusListener()
78 {
79     ISessionListener sessionListener = {.OnSessionOpened = SoftbusListener::OnSessionOpened,
80                                         .OnSessionClosed = SoftbusListener::OnSessionClosed,
81                                         .OnBytesReceived = SoftbusListener::OnBytesReceived,
82                                         .OnMessageReceived = nullptr,
83                                         .OnStreamReceived = nullptr};
84     int32_t ret = CreateSessionServer(DM_PKG_NAME, DM_SESSION_NAME, &sessionListener);
85     if (ret != DM_OK) {
86         LOGE("CreateSessionServer failed");
87     } else {
88         LOGI("CreateSessionServer ok");
89     }
90     Init();
91 }
92 
~SoftbusListener()93 SoftbusListener::~SoftbusListener()
94 {
95     RemoveSessionServer(DM_PKG_NAME, DM_SESSION_NAME);
96     LOGI("SoftbusListener destructor");
97 }
98 
SetPublishInfo(PublishInfo & dmPublishInfo)99 void SoftbusListener::SetPublishInfo(PublishInfo &dmPublishInfo)
100 {
101     dmPublishInfo.publishId = DISTRIBUTED_HARDWARE_DEVICEMANAGER_SA_ID;
102     dmPublishInfo.mode = DiscoverMode::DISCOVER_MODE_ACTIVE;
103     dmPublishInfo.medium = ExchangeMedium::AUTO;
104     dmPublishInfo.freq = ExchangeFreq::HIGH;
105     dmPublishInfo.capability = DM_CAPABILITY_OSD;
106     dmPublishInfo.ranging = false;
107     return;
108 }
109 
Init()110 int32_t SoftbusListener::Init()
111 {
112     int32_t ret;
113     int32_t retryTimes = 0;
114     do {
115         ret = RegNodeDeviceStateCb(DM_PKG_NAME, &softbusNodeStateCb_);
116         if (ret != DM_OK) {
117             ++retryTimes;
118             LOGE("RegNodeDeviceStateCb failed with ret %d, retryTimes %d", ret, retryTimes);
119             usleep(SOFTBUS_CHECK_INTERVAL);
120         }
121     } while (ret != DM_OK);
122 
123     PublishInfo dmPublishInfo;
124     (void)memset_s(&dmPublishInfo, sizeof(PublishInfo), 0, sizeof(PublishInfo));
125     SetPublishInfo(dmPublishInfo);
126 #if (defined(__LITEOS_M__) || defined(LITE_DEVICE))
127     ret = PublishLNN(DM_PKG_NAME, &dmPublishInfo, &softbusPublishCallback_);
128     if (ret == DM_OK) {
129         publishStatus = ALLOW_BE_DISCOVERY;
130     }
131 #else
132     char discoverStatus[DISCOVER_STATUS_LEN + 1] = {0};
133     ret = GetParameter(DISCOVER_STATUS_KEY, "not exist", discoverStatus, DISCOVER_STATUS_LEN);
134     if (strcmp(discoverStatus, "not exist") == 0) {
135         ret = SetParameter(DISCOVER_STATUS_KEY, DISCOVER_STATUS_ON);
136         LOGI("service set parameter result is : %d", ret);
137 
138         ret = PublishLNN(DM_PKG_NAME, &dmPublishInfo, &softbusPublishCallback_);
139         if (ret == DM_OK) {
140             publishStatus = ALLOW_BE_DISCOVERY;
141         }
142         LOGI("service publish result is : %d", ret);
143     } else if (ret >= 0 && strcmp(discoverStatus, DISCOVER_STATUS_ON) == 0) {
144         ret = PublishLNN(DM_PKG_NAME, &dmPublishInfo, &softbusPublishCallback_);
145         if (ret == DM_OK) {
146             publishStatus = ALLOW_BE_DISCOVERY;
147         }
148         LOGI("service publish result is : %d", ret);
149     } else if (ret >= 0 && strcmp(discoverStatus, DISCOVER_STATUS_OFF) == 0) {
150         ret = StopPublishLNN(DM_PKG_NAME, DISTRIBUTED_HARDWARE_DEVICEMANAGER_SA_ID);
151         if (ret == DM_OK) {
152             publishStatus = NOT_ALLOW_BE_DISCOVERY;
153         }
154         LOGI("service unpublish result is : %d", ret);
155     }
156 
157     ret = WatchParameter(DISCOVER_STATUS_KEY, &SoftbusListener::OnParameterChgCallback, nullptr);
158 #endif
159     return ret;
160 }
161 
GetTrustedDeviceList(std::vector<DmDeviceInfo> & deviceInfoList)162 int32_t SoftbusListener::GetTrustedDeviceList(std::vector<DmDeviceInfo> &deviceInfoList)
163 {
164     int32_t infoNum = 0;
165     NodeBasicInfo *nodeInfo = nullptr;
166     int32_t ret = GetAllNodeDeviceInfo(DM_PKG_NAME, &nodeInfo, &infoNum);
167     if (ret != 0) {
168         LOGE("GetAllNodeDeviceInfo failed with ret %d", ret);
169         return ERR_DM_FAILED;
170     }
171     DmDeviceInfo *info = static_cast<DmDeviceInfo *>(malloc(sizeof(DmDeviceInfo) * (infoNum)));
172     if (info == nullptr) {
173         FreeNodeInfo(nodeInfo);
174         return ERR_DM_MALLOC_FAILED;
175     }
176     DmDeviceInfo **pInfoList = &info;
177     for (int32_t i = 0; i < infoNum; ++i) {
178         NodeBasicInfo *nodeBasicInfo = nodeInfo + i;
179         DmDeviceInfo *deviceInfo = *pInfoList + i;
180         ConvertNodeBasicInfoToDmDevice(*nodeBasicInfo, *deviceInfo);
181         deviceInfoList.push_back(*deviceInfo);
182     }
183     FreeNodeInfo(nodeInfo);
184     free(info);
185     LOGI("SoftbusListener::GetTrustDevices success, deviceCount %d", infoNum);
186     return DM_OK;
187 }
188 
GetLocalDeviceInfo(DmDeviceInfo & deviceInfo)189 int32_t SoftbusListener::GetLocalDeviceInfo(DmDeviceInfo &deviceInfo)
190 {
191     NodeBasicInfo nodeBasicInfo;
192     int32_t ret = GetLocalNodeDeviceInfo(DM_PKG_NAME, &nodeBasicInfo);
193     if (ret != 0) {
194         LOGE("GetLocalNodeDeviceInfo failed with ret %d", ret);
195         return ERR_DM_FAILED;
196     }
197     ConvertNodeBasicInfoToDmDevice(nodeBasicInfo, deviceInfo);
198     return DM_OK;
199 }
200 
GetUdidByNetworkId(const char * networkId,std::string & udid)201 int32_t SoftbusListener::GetUdidByNetworkId(const char *networkId, std::string &udid)
202 {
203     uint8_t mUdid[UDID_BUF_LEN] = {0};
204     int32_t ret =
205         GetNodeKeyInfo(DM_PKG_NAME, networkId, NodeDeviceInfoKey::NODE_KEY_UDID, mUdid, sizeof(mUdid));
206     if (ret != DM_OK) {
207         LOGE("GetUdidByNetworkId GetNodeKeyInfo failed");
208         return ERR_DM_FAILED;
209     }
210     udid = reinterpret_cast<char *>(mUdid);
211     return DM_OK;
212 }
213 
GetUuidByNetworkId(const char * networkId,std::string & uuid)214 int32_t SoftbusListener::GetUuidByNetworkId(const char *networkId, std::string &uuid)
215 {
216     uint8_t mUuid[UUID_BUF_LEN] = {0};
217     int32_t ret =
218         GetNodeKeyInfo(DM_PKG_NAME, networkId, NodeDeviceInfoKey::NODE_KEY_UUID, mUuid, sizeof(mUuid));
219     if (ret != DM_OK) {
220         LOGE("GetUuidByNetworkId GetNodeKeyInfo failed");
221         return ERR_DM_FAILED;
222     }
223     uuid = reinterpret_cast<char *>(mUuid);
224     return DM_OK;
225 }
226 
OnSoftBusDeviceOnline(NodeBasicInfo * info)227 void SoftbusListener::OnSoftBusDeviceOnline(NodeBasicInfo *info)
228 {
229     LOGI("OnSoftBusDeviceOnline: received device online callback from softbus.");
230     if (info == nullptr) {
231         LOGE("SoftbusListener::OnSoftbusDeviceOffline NodeBasicInfo is nullptr");
232         return;
233     }
234     DmDeviceInfo dmDeviceInfo;
235     ConvertNodeBasicInfoToDmDevice(*info, dmDeviceInfo);
236 #if defined(__LITEOS_M__)
237     DmThread deviceOnLine(DeviceOnLine, dmDeviceInfo);
238     deviceOnLine.DmCreatThread();
239 #else
240     std::thread deviceOnLine(DeviceOnLine, dmDeviceInfo);
241     deviceOnLine.detach();
242 #endif
243 }
244 
OnSoftbusDeviceOffline(NodeBasicInfo * info)245 void SoftbusListener::OnSoftbusDeviceOffline(NodeBasicInfo *info)
246 {
247     LOGI("OnSoftBusDeviceOnline: received device offline callback from softbus.");
248     if (info == nullptr) {
249         LOGE("OnSoftbusDeviceOffline NodeBasicInfo is nullptr");
250         return;
251     }
252     DmDeviceInfo dmDeviceInfo;
253     ConvertNodeBasicInfoToDmDevice(*info, dmDeviceInfo);
254 #if defined(__LITEOS_M__)
255     DmThread deviceOffLine(DeviceOffLine, dmDeviceInfo);
256     deviceOffLine.DmCreatThread();
257 #else
258     std::thread deviceOffLine(DeviceOffLine, dmDeviceInfo);
259     deviceOffLine.detach();
260 #endif
261 }
262 
ConvertNodeBasicInfoToDmDevice(const NodeBasicInfo & nodeBasicInfo,DmDeviceInfo & dmDeviceInfo)263 int32_t SoftbusListener::ConvertNodeBasicInfoToDmDevice(const NodeBasicInfo &nodeBasicInfo, DmDeviceInfo &dmDeviceInfo)
264 {
265     (void)memset_s(&dmDeviceInfo, sizeof(DmDeviceInfo), 0, sizeof(DmDeviceInfo));
266     if (memcpy_s(dmDeviceInfo.deviceId, sizeof(dmDeviceInfo.deviceId), nodeBasicInfo.networkId,
267                  std::min(sizeof(dmDeviceInfo.deviceId), sizeof(nodeBasicInfo.networkId))) != DM_OK) {
268         LOGE("ConvertNodeBasicInfoToDmDevice copy deviceId data failed");
269     }
270 
271     if (memcpy_s(dmDeviceInfo.networkId, sizeof(dmDeviceInfo.networkId), nodeBasicInfo.networkId,
272                  std::min(sizeof(dmDeviceInfo.networkId), sizeof(nodeBasicInfo.networkId))) != DM_OK) {
273         LOGE("ConvertNodeBasicInfoToDmDevice copy networkId data failed");
274     }
275 
276     if (memcpy_s(dmDeviceInfo.deviceName, sizeof(dmDeviceInfo.deviceName), nodeBasicInfo.deviceName,
277                  std::min(sizeof(dmDeviceInfo.deviceName), sizeof(nodeBasicInfo.deviceName))) != DM_OK) {
278         LOGE("ConvertNodeBasicInfoToDmDevice copy deviceName data failed");
279     }
280     dmDeviceInfo.deviceTypeId = nodeBasicInfo.deviceTypeId;
281     return DM_OK;
282 }
283 
OnParameterChgCallback(const char * key,const char * value,void * context)284 void SoftbusListener::OnParameterChgCallback(const char *key, const char *value, void *context)
285 {
286     if (strcmp(value, DISCOVER_STATUS_ON) == 0 && publishStatus != ALLOW_BE_DISCOVERY) {
287         PublishInfo dmPublishInfo;
288         (void)memset_s(&dmPublishInfo, sizeof(PublishInfo), 0, sizeof(PublishInfo));
289         dmPublishInfo.publishId = DISTRIBUTED_HARDWARE_DEVICEMANAGER_SA_ID;
290         dmPublishInfo.mode = DiscoverMode::DISCOVER_MODE_ACTIVE;
291         dmPublishInfo.medium = ExchangeMedium::AUTO;
292         dmPublishInfo.freq = ExchangeFreq::HIGH;
293         dmPublishInfo.capability = DM_CAPABILITY_OSD;
294         dmPublishInfo.ranging = false;
295         int32_t ret = ::PublishLNN(DM_PKG_NAME, &dmPublishInfo, &softbusPublishCallback_);
296         if (ret == DM_OK) {
297             publishStatus = ALLOW_BE_DISCOVERY;
298         }
299         LOGI("service publish result is : %d", ret);
300     } else if (strcmp(value, DISCOVER_STATUS_OFF) == 0 && publishStatus != NOT_ALLOW_BE_DISCOVERY) {
301         int32_t ret = ::StopPublishLNN(DM_PKG_NAME, DISTRIBUTED_HARDWARE_DEVICEMANAGER_SA_ID);
302         if (ret == DM_OK) {
303             publishStatus = NOT_ALLOW_BE_DISCOVERY;
304         }
305         LOGI("service unpublish result is : %d", ret);
306     }
307 }
308 
OnSessionOpened(int sessionId,int result)309 int SoftbusListener::OnSessionOpened(int sessionId, int result)
310 {
311     return DeviceManagerService::GetInstance().OnSessionOpened(sessionId, result);
312 }
313 
OnSessionClosed(int sessionId)314 void SoftbusListener::OnSessionClosed(int sessionId)
315 {
316     DeviceManagerService::GetInstance().OnSessionClosed(sessionId);
317 }
318 
OnBytesReceived(int sessionId,const void * data,unsigned int dataLen)319 void SoftbusListener::OnBytesReceived(int sessionId, const void *data, unsigned int dataLen)
320 {
321     DeviceManagerService::GetInstance().OnBytesReceived(sessionId, data, dataLen);
322 }
323 
OnPublishResult(int publishId,PublishResult result)324 void SoftbusListener::OnPublishResult(int publishId, PublishResult result)
325 {
326     LOGD("SoftbusListener::OnPublishResult, publishId: %d, result: %d", publishId, result);
327 }
328 
OnSoftbusDeviceInfoChanged(NodeBasicInfoType type,NodeBasicInfo * info)329 void SoftbusListener::OnSoftbusDeviceInfoChanged(NodeBasicInfoType type, NodeBasicInfo *info)
330 {
331     LOGD("SoftbusListener::OnSoftbusDeviceInfoChanged.");
332 }
333 } // namespace DistributedHardware
334 } // namespace OHOS