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 "callback_manager.h"
17 #include "channel_manager.h"
18 #include "device_auth_defines.h"
19 #include "hc_log.h"
20 #include "hc_mutex.h"
21 #include "hc_types.h"
22 #include "hc_vector.h"
23 #include "securec.h"
24 #include "string_util.h"
25
26 typedef struct {
27 char *appId;
28 DeviceAuthCallback *callback;
29 } CallbackEntry;
30
31 DECLARE_HC_VECTOR(GMCallbackEntryVec, CallbackEntry);
32 IMPLEMENT_HC_VECTOR(GMCallbackEntryVec, CallbackEntry, 1)
33 static GMCallbackEntryVec g_callbackVec;
34 static HcMutex *g_callbackMutex = NULL;
35
UpdateCallbackIfExist(const char * appId,const DeviceAuthCallback * callback)36 static int32_t UpdateCallbackIfExist(const char *appId, const DeviceAuthCallback *callback)
37 {
38 uint32_t index;
39 CallbackEntry *entry = NULL;
40 (void)LockHcMutex(g_callbackMutex);
41 FOR_EACH_HC_VECTOR(g_callbackVec, index, entry) {
42 if (IsStrEqual(entry->appId, appId)) {
43 if (memcpy_s(entry->callback, sizeof(DeviceAuthCallback),
44 callback, sizeof(DeviceAuthCallback)) != EOK) {
45 UnlockHcMutex(g_callbackMutex);
46 LOGE("Failed to copy service callback!");
47 return HC_ERR_MEMORY_COPY;
48 }
49 UnlockHcMutex(g_callbackMutex);
50 LOGI("Successfully updated a callback! [AppId]: %" LOG_PUB "s", appId);
51 return HC_SUCCESS;
52 }
53 }
54 UnlockHcMutex(g_callbackMutex);
55 return HC_ERR_CALLBACK_NOT_FOUND;
56 }
57
AddCallbackIfNotExist(const char * appId,const DeviceAuthCallback * callback)58 static int32_t AddCallbackIfNotExist(const char *appId, const DeviceAuthCallback *callback)
59 {
60 uint32_t appIdLen = HcStrlen(appId) + 1;
61 char *copyAppId = (char *)HcMalloc(appIdLen, 0);
62 if (copyAppId == NULL) {
63 LOGE("Failed to allocate copyAppId memory!");
64 return HC_ERR_ALLOC_MEMORY;
65 }
66 if (strcpy_s(copyAppId, appIdLen, appId) != EOK) {
67 LOGE("Failed to copy appId!");
68 HcFree(copyAppId);
69 return HC_ERR_MEMORY_COPY;
70 }
71 DeviceAuthCallback *copyCallback = (DeviceAuthCallback *)HcMalloc(sizeof(DeviceAuthCallback), 0);
72 if (copyCallback == NULL) {
73 LOGE("Failed to allocate copyCallback memory!");
74 HcFree(copyAppId);
75 return HC_ERR_ALLOC_MEMORY;
76 }
77 if (memcpy_s(copyCallback, sizeof(DeviceAuthCallback), callback, sizeof(DeviceAuthCallback)) != EOK) {
78 LOGE("Failed to copy service callback!");
79 HcFree(copyAppId);
80 HcFree(copyCallback);
81 return HC_ERR_MEMORY_COPY;
82 }
83 CallbackEntry entry;
84 entry.appId = copyAppId;
85 entry.callback = copyCallback;
86 (void)LockHcMutex(g_callbackMutex);
87 if (g_callbackVec.pushBack(&g_callbackVec, &entry) == NULL) {
88 LOGE("Failed to push callback to vector!");
89 HcFree(copyAppId);
90 HcFree(copyCallback);
91 UnlockHcMutex(g_callbackMutex);
92 return HC_ERR_MEMORY_COPY;
93 }
94 UnlockHcMutex(g_callbackMutex);
95 LOGI("Successfully added a callback! [AppId]: %" LOG_PUB "s", appId);
96 return HC_SUCCESS;
97 }
98
ProcessTransmitCallback(int64_t reqId,const uint8_t * data,uint32_t dataLen,const DeviceAuthCallback * callback)99 bool ProcessTransmitCallback(int64_t reqId, const uint8_t *data, uint32_t dataLen, const DeviceAuthCallback *callback)
100 {
101 if ((callback != NULL) && (callback->onTransmit != NULL)) {
102 LOGI("[Service][In]: ProcessTransmitCallback! [DataLen]: %" LOG_PUB "u, [ReqId]: %" LOG_PUB PRId64,
103 dataLen, reqId);
104 bool res = callback->onTransmit(reqId, data, dataLen);
105 LOGI("[Service][Out]: ProcessTransmitCallback!");
106 return res;
107 }
108 LOGE("[OnTransmit]: Currently, the service callback is NULL! [ReqId]: %" LOG_PUB PRId64, reqId);
109 return false;
110 }
111
ProcessSessionKeyCallback(int64_t reqId,const uint8_t * sessionKey,uint32_t sessionKeyLen,const DeviceAuthCallback * callback)112 void ProcessSessionKeyCallback(int64_t reqId, const uint8_t *sessionKey, uint32_t sessionKeyLen,
113 const DeviceAuthCallback *callback)
114 {
115 if ((callback != NULL) && (callback->onSessionKeyReturned != NULL)) {
116 LOGI("[Service][In]: ProcessSessionKeyCallback! [ReqId]: %" LOG_PUB PRId64, reqId);
117 callback->onSessionKeyReturned(reqId, sessionKey, sessionKeyLen);
118 LOGI("[Service][Out]: ProcessSessionKeyCallback!");
119 return;
120 }
121 LOGE("[OnSessionKeyReturned]: Currently, the service callback is NULL! [ReqId]: %" LOG_PUB PRId64, reqId);
122 }
123
ProcessFinishCallback(int64_t reqId,int operationCode,const char * returnData,const DeviceAuthCallback * callback)124 void ProcessFinishCallback(int64_t reqId, int operationCode, const char *returnData,
125 const DeviceAuthCallback *callback)
126 {
127 if ((callback != NULL) && (callback->onFinish != NULL)) {
128 LOGI("[Service][In]: ProcessFinishCallback! [ReqId]: %" LOG_PUB PRId64, reqId);
129 callback->onFinish(reqId, operationCode, returnData);
130 LOGI("[Service][Out]: ProcessFinishCallback!");
131 return;
132 }
133 LOGE("[OnFinish]: Currently, the service callback is NULL! [ReqId]: %" LOG_PUB PRId64, reqId);
134 }
135
ProcessErrorCallback(int64_t reqId,int operationCode,int errorCode,const char * errorReturn,const DeviceAuthCallback * callback)136 void ProcessErrorCallback(int64_t reqId, int operationCode, int errorCode, const char *errorReturn,
137 const DeviceAuthCallback *callback)
138 {
139 if ((callback != NULL) && (callback->onError != NULL)) {
140 LOGI("[Service][In]: ProcessErrorCallback! [ReqId]: %" LOG_PUB PRId64, reqId);
141 callback->onError(reqId, operationCode, errorCode, errorReturn);
142 LOGI("[Service][Out]: ProcessErrorCallback!");
143 return;
144 }
145 LOGE("[OnError]: Currently, the service callback is NULL! [ReqId]: %" LOG_PUB PRId64, reqId);
146 }
147
ProcessRequestCallback(int64_t reqId,int operationCode,const char * reqParams,const DeviceAuthCallback * callback)148 char *ProcessRequestCallback(int64_t reqId, int operationCode, const char *reqParams,
149 const DeviceAuthCallback *callback)
150 {
151 if ((callback != NULL) && (callback->onRequest != NULL)) {
152 LOGI("[Service][In]: ProcessRequestCallback! [ReqId]: %" LOG_PUB PRId64, reqId);
153 char *returnData = callback->onRequest(reqId, operationCode, reqParams);
154 LOGI("[Service][Out]: ProcessRequestCallback!");
155 return returnData;
156 }
157 LOGE("[OnRequest]: Currently, the service callback is NULL! [ReqId]: %" LOG_PUB PRId64, reqId);
158 return NULL;
159 }
160
GetGMCallbackByAppId(const char * appId)161 const DeviceAuthCallback *GetGMCallbackByAppId(const char *appId)
162 {
163 uint32_t index;
164 CallbackEntry *entry = NULL;
165 (void)LockHcMutex(g_callbackMutex);
166 FOR_EACH_HC_VECTOR(g_callbackVec, index, entry) {
167 if (IsStrEqual(entry->appId, appId)) {
168 UnlockHcMutex(g_callbackMutex);
169 return entry->callback;
170 }
171 }
172 UnlockHcMutex(g_callbackMutex);
173 return NULL;
174 }
175
RegGroupManagerCallback(const char * appId,const DeviceAuthCallback * callback)176 int32_t RegGroupManagerCallback(const char *appId, const DeviceAuthCallback *callback)
177 {
178 if ((appId == NULL) || (callback == NULL)) {
179 LOGE("The input parameters contains NULL value!");
180 return HC_ERR_INVALID_PARAMS;
181 }
182 if (UpdateCallbackIfExist(appId, callback) == HC_SUCCESS) {
183 return HC_SUCCESS;
184 }
185 return AddCallbackIfNotExist(appId, callback);
186 }
187
UnRegGroupManagerCallback(const char * appId)188 int32_t UnRegGroupManagerCallback(const char *appId)
189 {
190 SET_LOG_MODE(NORMAL_MODE);
191 if (appId == NULL) {
192 LOGE("The input appId is NULL!");
193 return HC_ERR_INVALID_PARAMS;
194 }
195 uint32_t index;
196 CallbackEntry *entry = NULL;
197 (void)LockHcMutex(g_callbackMutex);
198 FOR_EACH_HC_VECTOR(g_callbackVec, index, entry) {
199 if (IsStrEqual(entry->appId, appId)) {
200 HcFree(entry->appId);
201 HcFree(entry->callback);
202 CallbackEntry tempEntry;
203 HC_VECTOR_POPELEMENT(&g_callbackVec, &tempEntry, index);
204 UnlockHcMutex(g_callbackMutex);
205 LOGI("Successfully removed a callback. [AppId]: %" LOG_PUB "s", appId);
206 return HC_SUCCESS;
207 }
208 }
209 UnlockHcMutex(g_callbackMutex);
210 LOGI("The callback does not exist! [AppId]: %" LOG_PUB "s", appId);
211 return HC_SUCCESS;
212 }
213
InitCallbackManager(void)214 int32_t InitCallbackManager(void)
215 {
216 if (g_callbackMutex == NULL) {
217 g_callbackMutex = (HcMutex *)HcMalloc(sizeof(HcMutex), 0);
218 if (g_callbackMutex == NULL) {
219 LOGE("Failed to allocate broadcast mutex memory!");
220 return HC_ERR_ALLOC_MEMORY;
221 }
222 if (InitHcMutex(g_callbackMutex, false) != HC_SUCCESS) {
223 LOGE("Init mutex failed!");
224 HcFree(g_callbackMutex);
225 g_callbackMutex = NULL;
226 return HC_ERROR;
227 }
228 }
229 g_callbackVec = CREATE_HC_VECTOR(GMCallbackEntryVec);
230 return HC_SUCCESS;
231 }
232
DestroyCallbackManager(void)233 void DestroyCallbackManager(void)
234 {
235 uint32_t index;
236 CallbackEntry *entry = NULL;
237 (void)LockHcMutex(g_callbackMutex);
238 FOR_EACH_HC_VECTOR(g_callbackVec, index, entry) {
239 HcFree(entry->appId);
240 HcFree(entry->callback);
241 }
242 DESTROY_HC_VECTOR(GMCallbackEntryVec, &g_callbackVec);
243 UnlockHcMutex(g_callbackMutex);
244 DestroyHcMutex(g_callbackMutex);
245 HcFree(g_callbackMutex);
246 g_callbackMutex = NULL;
247 }