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