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