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