1 /*
2 * Copyright (c) 2021-2025 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 "lnn_coap_discovery_impl.h"
17
18 #include <securec.h>
19 #include <unistd.h>
20
21 #include "anonymizer.h"
22 #include "auth_interface.h"
23 #include "bus_center_manager.h"
24 #include "g_enhance_lnn_func.h"
25 #include "g_enhance_lnn_func_pack.h"
26 #include "lnn_log.h"
27 #include "softbus_adapter_crypto.h"
28 #include "softbus_adapter_mem.h"
29 #include "softbus_def.h"
30 #include "softbus_error_code.h"
31 #include "softbus_utils.h"
32 #include "softbus_init_common.h"
33
34 #define LNN_DISC_CAPABILITY "ddmpCapability"
35 #define LNN_SUBSCRIBE_ID 0
36 #define LNN_PUBLISH_ID 0
37
38 #define LNN_SHORT_HASH_LEN 8
39 #define LNN_SHORT_HASH_HEX_LEN 16
40 #define TYPE_PRINTER 0x09
41
42 static LnnDiscoveryImplCallback g_callback;
43
44 static void DeviceFound(const DeviceInfo *device, const InnerDeviceInfoAddtions *additions);
45
46 static DiscInnerCallback g_discCb = {
47 .OnDeviceFound = DeviceFound,
48 };
49
LnnCheckDiscoveryDeviceInfo(const DeviceInfo * device)50 static int32_t LnnCheckDiscoveryDeviceInfo(const DeviceInfo *device)
51 {
52 if (device->addr[0].type != CONNECTION_ADDR_WLAN && device->addr[0].type != CONNECTION_ADDR_ETH) {
53 LNN_LOGE(LNN_BUILDER, "discovery get invalid addrType=%{public}d", device->addr[0].type);
54 return SOFTBUS_INVALID_PARAM;
55 }
56 if (device->addr[0].info.ip.port == 0) {
57 LNN_LOGD(LNN_BUILDER, "discovery get port is 0!");
58 LnnCoapConnectPacked(device->addr[0].info.ip.ip);
59 return SOFTBUS_INVALID_PARAM;
60 }
61 return SOFTBUS_OK;
62 }
63
GetConnectDeviceInfo(const DeviceInfo * device,ConnectionAddr * addr)64 static int32_t GetConnectDeviceInfo(const DeviceInfo *device, ConnectionAddr *addr)
65 {
66 addr->type = device->addr[0].type;
67 if (strcpy_s(addr->info.ip.ip, IP_STR_MAX_LEN, device->addr[0].info.ip.ip) != EOK) {
68 LNN_LOGE(LNN_BUILDER, "strcpy ip failed");
69 return SOFTBUS_STRCPY_ERR;
70 }
71 if (strcpy_s((char *)addr->info.ip.udidHash, UDID_HASH_LEN, device->devId) != EOK) {
72 LNN_LOGE(LNN_BUILDER, "strcpy udidHash failed");
73 return SOFTBUS_STRCPY_ERR;
74 }
75 addr->info.ip.port = device->addr[0].info.ip.port;
76 if (memcpy_s(addr->peerUid, MAX_ACCOUNT_HASH_LEN, device->accountHash, MAX_ACCOUNT_HASH_LEN) != EOK) {
77 LNN_LOGE(LNN_BUILDER, "memcpy_s peer uid failed");
78 return SOFTBUS_MEM_ERR;
79 }
80 return SOFTBUS_OK;
81 }
82
DeviceFound(const DeviceInfo * device,const InnerDeviceInfoAddtions * additions)83 static void DeviceFound(const DeviceInfo *device, const InnerDeviceInfoAddtions *additions)
84 {
85 ConnectionAddr addr;
86 (void) additions;
87
88 if (device == NULL) {
89 LNN_LOGE(LNN_BUILDER, "device para is null");
90 return;
91 }
92 (void)memset_s(&addr, sizeof(ConnectionAddr), 0, sizeof(ConnectionAddr));
93 char *anonyDevId = NULL;
94 Anonymize(device->devId, &anonyDevId);
95 char *anonyDevName = NULL;
96 AnonymizeDeviceName(device->devName, &anonyDevName);
97 // devId format is hex hash string here
98 LNN_LOGI(LNN_BUILDER, "DeviceFound devName=%{public}s, devId=%{public}s, devType=%{public}03X, port=%{public}u",
99 AnonymizeWrapper(anonyDevName), AnonymizeWrapper(anonyDevId), device->devType, device->addr[0].info.ip.port);
100 AnonymizeFree(anonyDevName);
101 if (!AuthIsPotentialTrusted(device, true)) {
102 LNN_LOGW(LNN_BUILDER, "discovery device is not potential trusted, devId=%{public}s, "
103 "accountHash=%{public}02X%{public}02X", AnonymizeWrapper(anonyDevId),
104 device->accountHash[0], device->accountHash[1]);
105 AnonymizeFree(anonyDevId);
106 return;
107 }
108 AnonymizeFree(anonyDevId);
109 if (LnnCheckDiscoveryDeviceInfo(device) != SOFTBUS_OK) {
110 LNN_LOGE(LNN_BUILDER, "get invalid device para");
111 return;
112 }
113 if (GetConnectDeviceInfo(device, &addr) != SOFTBUS_OK) {
114 LNN_LOGE(LNN_BUILDER, "get connect device info fail");
115 return;
116 }
117 LnnDfxDeviceInfoReport info;
118 (void)memset_s(&info, sizeof(LnnDfxDeviceInfoReport), 0, sizeof(LnnDfxDeviceInfoReport));
119 info.type = device->devType;
120 if ((uint32_t)info.type == TYPE_PRINTER) {
121 LNN_LOGI(LNN_BUILDER, "restrict printer");
122 return;
123 }
124 if (g_callback.onDeviceFound) {
125 g_callback.onDeviceFound(&addr, &info);
126 }
127 }
128
LnnStartCoapPublish(void)129 int32_t LnnStartCoapPublish(void)
130 {
131 PublishInfo publishInfo = {
132 .publishId = LNN_PUBLISH_ID,
133 .mode = DISCOVER_MODE_PASSIVE,
134 .medium = COAP,
135 .freq = HIGH,
136 .capability = LNN_DISC_CAPABILITY,
137 .capabilityData = (unsigned char *)LNN_DISC_CAPABILITY,
138 .dataLen = strlen(LNN_DISC_CAPABILITY),
139 };
140 LNN_LOGD(LNN_BUILDER, "lnn start coap publish");
141 int32_t pid = getpid();
142 return LnnPublishService(NULL, &publishInfo, true, pid);
143 }
144
LnnStopCoapPublish(void)145 int32_t LnnStopCoapPublish(void)
146 {
147 LNN_LOGD(LNN_BUILDER, "lnn stop coap publish");
148 int32_t pid = getpid();
149 return LnnUnPublishService(NULL, LNN_PUBLISH_ID, true, pid);
150 }
151
LnnStopCoapDiscovery(void)152 int32_t LnnStopCoapDiscovery(void)
153 {
154 int32_t pid = getpid();
155 return LnnStopDiscDevice(NULL, LNN_SUBSCRIBE_ID, true, pid);
156 }
157
LnnStartCoapDiscovery(void)158 int32_t LnnStartCoapDiscovery(void)
159 {
160 SubscribeInfo subscribeInfo = {
161 .subscribeId = LNN_SUBSCRIBE_ID,
162 .mode = DISCOVER_MODE_ACTIVE,
163 .medium = COAP,
164 .freq = HIGH,
165 .isSameAccount = false,
166 .isWakeRemote = false,
167 .capability = LNN_DISC_CAPABILITY,
168 .capabilityData = (unsigned char *)LNN_DISC_CAPABILITY,
169 .dataLen = strlen(LNN_DISC_CAPABILITY),
170 };
171 InnerCallback callback = {
172 .innerCb = g_discCb,
173 };
174 LnnDestroyCoapConnectListPacked();
175 int32_t pid = getpid();
176 return LnnStartDiscDevice(NULL, &subscribeInfo, &callback, true, pid);
177 }
178
LnnInitCoapDiscovery(LnnDiscoveryImplCallback * callback)179 int32_t LnnInitCoapDiscovery(LnnDiscoveryImplCallback *callback)
180 {
181 if (callback == NULL) {
182 LNN_LOGE(LNN_BUILDER, "coap discovery callback is null");
183 return SOFTBUS_INVALID_PARAM;
184 }
185 g_callback.onDeviceFound = callback->onDeviceFound;
186 return SOFTBUS_OK;
187 }
188