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 "dslm_core_process.h"
17
18 #include <securec.h>
19 #include <unistd.h>
20
21 #include "utils_datetime.h"
22 #include "utils_log.h"
23 #include "utils_mem.h"
24 #include "utils_timer.h"
25
26 #include "dslm_credential.h"
27 #include "dslm_device_list.h"
28 #include "dslm_fsm_process.h"
29 #include "dslm_hievent.h"
30 #include "dslm_messenger_wrapper.h"
31 #include "dslm_msg_utils.h"
32 #include "dslm_notify_node.h"
33
34 #ifdef __cplusplus
35 extern "C" {
36 #endif
37
38 static const DeviceIdentify *RefreshDeviceOnlineStatus(const DeviceIdentify *deviceId);
39
OnPeerMsgRequestInfoReceived(const DeviceIdentify * deviceId,const uint8_t * msg,uint32_t len)40 int32_t OnPeerMsgRequestInfoReceived(const DeviceIdentify *deviceId, const uint8_t *msg, uint32_t len)
41 {
42 if (deviceId == NULL || msg == NULL || len == 0) {
43 return ERR_INVALID_PARA;
44 }
45
46 SECURITY_LOG_DEBUG("OnPeerMsgRequestInfoReceived msg is %s", (char *)msg);
47 MessageBuff buff = {.length = len, .buff = (uint8_t *)msg};
48
49 RequestObject reqObject;
50 memset_s(&reqObject, sizeof(RequestObject), 0, sizeof(RequestObject));
51
52 // Parse the msg
53 int32_t ret = ParseDeviceSecInfoRequest(&buff, &reqObject);
54 if (ret != SUCCESS) {
55 return ret;
56 }
57
58 // process
59 DslmCredBuff *cred = NULL;
60 ret = DefaultRequestDslmCred(deviceId, &reqObject, &cred);
61 if (ret != SUCCESS) {
62 return ret;
63 }
64
65 // build and send response
66 MessageBuff *resBuff = NULL;
67 ret = BuildDeviceSecInfoResponse(reqObject.challenge, cred, &resBuff);
68 if (ret == SUCCESS) {
69 SendMsgToDevice(0, deviceId, resBuff->buff, resBuff->length);
70 FreeMessageBuff(resBuff);
71 }
72 DestroyDslmCred(cred);
73
74 return SUCCESS;
75 }
76
OnPeerMsgResponseInfoReceived(const DeviceIdentify * deviceId,const uint8_t * msg,uint32_t len)77 int32_t OnPeerMsgResponseInfoReceived(const DeviceIdentify *deviceId, const uint8_t *msg, uint32_t len)
78 {
79 if (deviceId == NULL || msg == NULL || len == 0) {
80 return ERR_INVALID_PARA;
81 }
82 SECURITY_LOG_DEBUG("OnPeerMsgResponseInfoReceived msg is %s", (char *)msg);
83
84 DslmDeviceInfo *deviceInfo = GetDslmDeviceInfo(deviceId);
85 if (deviceInfo == NULL) {
86 SECURITY_LOG_ERROR("OnPeerMsgResponseInfoReceived no existed device");
87 return ERR_NOEXIST_DEVICE;
88 }
89
90 MessageBuff buff = {
91 .length = len,
92 .buff = (uint8_t *)msg,
93 };
94
95 ScheduleDslmStateMachine(deviceInfo, EVENT_CRED_RSP, &buff);
96 ReportHiEventInfoSync(deviceInfo);
97 return SUCCESS;
98 }
99
OnMsgSendResultNotifier(const DeviceIdentify * deviceId,uint64_t transNo,uint32_t result)100 int32_t OnMsgSendResultNotifier(const DeviceIdentify *deviceId, uint64_t transNo, uint32_t result)
101 {
102 SECURITY_LOG_INFO("OnMsgSendResultNotifier msg trans is %{public}u result %{public}u", (uint32_t)transNo, result);
103
104 if (result == SUCCESS) {
105 return SUCCESS;
106 }
107
108 DslmDeviceInfo *deviceInfo = GetDslmDeviceInfo(deviceId);
109 if (deviceInfo == NULL) {
110 return SUCCESS;
111 }
112
113 SECURITY_LOG_INFO("current DslmDeviceInfo transNum is %{public}u", (uint32_t)deviceInfo->transNum);
114 if (deviceInfo->transNum != transNo) {
115 return SUCCESS;
116 }
117
118 if (deviceInfo->credInfo.credLevel != 0) {
119 return SUCCESS;
120 }
121
122 ScheduleDslmStateMachine(deviceInfo, EVENT_MSG_SEND_FAILED, &result);
123
124 return SUCCESS;
125 }
126
OnRequestDeviceSecLevelInfo(const DeviceIdentify * deviceId,const RequestOption * option,uint32_t owner,uint32_t cookie,RequestCallback callback)127 int32_t OnRequestDeviceSecLevelInfo(const DeviceIdentify *deviceId, const RequestOption *option, uint32_t owner,
128 uint32_t cookie, RequestCallback callback)
129 {
130 if (deviceId == NULL || option == NULL || callback == NULL) {
131 SECURITY_LOG_ERROR("OnRequestDeviceSecLevelInfo invalid para");
132 return ERR_INVALID_PARA;
133 }
134
135 if (GetMessengerStatus() != true) {
136 SECURITY_LOG_ERROR("OnRequestDeviceSecLevelInfo softbus service not startup complete");
137 return ERR_MSG_NOT_INIT;
138 }
139
140 const DeviceIdentify *curr = RefreshDeviceOnlineStatus(deviceId);
141
142 DslmDeviceInfo *deviceInfo = GetDslmDeviceInfo(curr);
143 if (deviceInfo == NULL) {
144 SECURITY_LOG_ERROR("OnRequestDeviceSecLevelInfo input device not exist");
145 return ERR_NOEXIST_DEVICE;
146 }
147
148 ReportHiEventAppInvoke(deviceInfo);
149
150 if (deviceInfo->onlineStatus != ONLINE_STATUS_ONLINE) {
151 SECURITY_LOG_ERROR("OnRequestDeviceSecLevelInfo input device not online");
152 return ERR_NOT_ONLINE;
153 }
154 DslmNotifyListNode *nofityNode = MALLOC(sizeof(DslmNotifyListNode));
155 if (nofityNode == NULL) {
156 SECURITY_LOG_ERROR("OnRequestDeviceSecLevelInfo malloc error");
157 return ERR_NO_MEMORY;
158 }
159 nofityNode->owner = owner;
160 nofityNode->cookie = cookie;
161 nofityNode->requestCallback = callback;
162 nofityNode->start = GetMillisecondSinceBoot();
163 nofityNode->keep = option->timeout * 1000; // 1000 ms per second
164 ScheduleDslmStateMachine(deviceInfo, EVENT_SDK_GET, nofityNode);
165 return SUCCESS;
166 }
167
OnPeerStatusReceiver(const DeviceIdentify * deviceId,uint32_t status,uint32_t devType)168 int32_t OnPeerStatusReceiver(const DeviceIdentify *deviceId, uint32_t status, uint32_t devType)
169 {
170 DslmDeviceInfo *info = CreatOrGetDslmDeviceInfo(deviceId);
171 if (info == NULL) {
172 return SUCCESS;
173 }
174
175 if (info->onlineStatus == status) {
176 return SUCCESS;
177 }
178
179 uint32_t event = (status == ONLINE_STATUS_ONLINE) ? EVENT_DEVICE_ONLINE : EVENT_DEVICE_OFFLINE;
180 ScheduleDslmStateMachine(info, event, &devType);
181 return SUCCESS;
182 }
183
InitSelfDeviceSecureLevel(void)184 bool InitSelfDeviceSecureLevel(void)
185 {
186 uint32_t devType = 0;
187 const DeviceIdentify *device = GetSelfDevice(&devType);
188 if (device->length == 0) {
189 SECURITY_LOG_ERROR("InitDeviceSecLevel, GetSelfDevice failed");
190 return false;
191 }
192
193 DslmDeviceInfo *info = CreatOrGetDslmDeviceInfo(device);
194 if (info == NULL) {
195 SECURITY_LOG_ERROR("InitDeviceSecLevel, CreatOrGetDslmDeviceInfo failed");
196 return false;
197 }
198
199 info->deviceType = devType;
200 info->onlineStatus = ONLINE_STATUS_ONLINE;
201
202 if (info->credInfo.credLevel > 0) {
203 info->result = SUCCESS;
204 return true;
205 }
206 int32_t ret = DefaultInitDslmCred(&info->credInfo);
207 if (ret == SUCCESS && info->credInfo.credLevel > 0) {
208 return true;
209 }
210
211 ret = OnPeerStatusReceiver(device, ONLINE_STATUS_ONLINE, devType);
212 if (ret != SUCCESS) {
213 SECURITY_LOG_ERROR("InitDeviceSecLevel, make self online failed");
214 }
215 return true;
216 }
217
InitDslmProcess(void)218 bool InitDslmProcess(void)
219 {
220 static bool isInited = false;
221 static Mutex initMutex = INITED_MUTEX;
222
223 if (GetMessengerStatus() == false) {
224 return false;
225 }
226
227 if (isInited == true) {
228 return true;
229 }
230
231 LockMutex(&initMutex);
232 bool result = InitSelfDeviceSecureLevel();
233 if (result) {
234 isInited = true;
235 }
236 UnlockMutex(&initMutex);
237 return isInited;
238 }
239
DeinitDslmProcess(void)240 bool DeinitDslmProcess(void)
241 {
242 return true;
243 }
244
RefreshDeviceOnlineStatus(const DeviceIdentify * deviceId)245 static const DeviceIdentify *RefreshDeviceOnlineStatus(const DeviceIdentify *deviceId)
246 {
247 uint32_t devType = 0;
248 if (deviceId == NULL) {
249 return NULL;
250 }
251
252 if (deviceId->identity[0] == 0) {
253 SECURITY_LOG_INFO("RefreshDeviceOnlineStatus to self");
254 return GetSelfDevice(&devType);
255 }
256
257 if (GetPeerDeviceOnlineStatus(deviceId, &devType)) {
258 OnPeerStatusReceiver(deviceId, ONLINE_STATUS_ONLINE, devType);
259 }
260
261 return deviceId;
262 }
263
264 #ifdef __cplusplus
265 }
266 #endif
267