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      g_callbackMutex->lock(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                  g_callbackMutex->unlock(g_callbackMutex);
45                  LOGE("Failed to copy service callback!");
46                  return HC_ERR_MEMORY_COPY;
47              }
48              g_callbackMutex->unlock(g_callbackMutex);
49              LOGI("Successfully updated a callback! [AppId]: %s", appId);
50              return HC_SUCCESS;
51          }
52      }
53      g_callbackMutex->unlock(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      g_callbackMutex->lock(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          g_callbackMutex->unlock(g_callbackMutex);
91          return HC_ERR_MEMORY_COPY;
92      }
93      g_callbackMutex->unlock(g_callbackMutex);
94      LOGI("Successfully added a callback! [AppId]: %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]: %u, [ReqId]: %" PRId64, dataLen, reqId);
102          bool res = callback->onTransmit(reqId, data, dataLen);
103          LOGI("[Service][Out]: ProcessTransmitCallback!");
104          return res;
105      }
106      LOGE("[OnTransmit]: Currently, the service callback is NULL! [ReqId]: %" PRId64, reqId);
107      return false;
108  }
109  
ProcessSessionKeyCallback(int64_t reqId,const uint8_t * sessionKey,uint32_t sessionKeyLen,const DeviceAuthCallback * callback)110  void ProcessSessionKeyCallback(int64_t reqId, const uint8_t *sessionKey, uint32_t sessionKeyLen,
111      const DeviceAuthCallback *callback)
112  {
113      if ((callback != NULL) && (callback->onSessionKeyReturned != NULL)) {
114          LOGI("[Service][In]: ProcessSessionKeyCallback! [ReqId]: %" PRId64, reqId);
115          callback->onSessionKeyReturned(reqId, sessionKey, sessionKeyLen);
116          LOGI("[Service][Out]: ProcessSessionKeyCallback!");
117          return;
118      }
119      LOGE("[OnSessionKeyReturned]: Currently, the service callback is NULL! [ReqId]: %" PRId64, reqId);
120  }
121  
ProcessFinishCallback(int64_t reqId,int operationCode,const char * returnData,const DeviceAuthCallback * callback)122  void ProcessFinishCallback(int64_t reqId, int operationCode, const char *returnData,
123      const DeviceAuthCallback *callback)
124  {
125      if ((callback != NULL) && (callback->onFinish != NULL)) {
126          LOGI("[Service][In]: ProcessFinishCallback! [ReqId]: %" PRId64, reqId);
127          callback->onFinish(reqId, operationCode, returnData);
128          LOGI("[Service][Out]: ProcessFinishCallback!");
129          return;
130      }
131      LOGE("[OnFinish]: Currently, the service callback is NULL! [ReqId]: %" PRId64, reqId);
132  }
133  
ProcessErrorCallback(int64_t reqId,int operationCode,int errorCode,const char * errorReturn,const DeviceAuthCallback * callback)134  void ProcessErrorCallback(int64_t reqId, int operationCode, int errorCode, const char *errorReturn,
135      const DeviceAuthCallback *callback)
136  {
137      if ((callback != NULL) && (callback->onError != NULL)) {
138          LOGI("[Service][In]: ProcessErrorCallback! [ReqId]: %" PRId64, reqId);
139          callback->onError(reqId, operationCode, errorCode, errorReturn);
140          LOGI("[Service][Out]: ProcessErrorCallback!");
141          return;
142      }
143      LOGE("[OnError]: Currently, the service callback is NULL! [ReqId]: %" PRId64, reqId);
144  }
145  
ProcessRequestCallback(int64_t reqId,int operationCode,const char * reqParams,const DeviceAuthCallback * callback)146  char *ProcessRequestCallback(int64_t reqId, int operationCode, const char *reqParams,
147      const DeviceAuthCallback *callback)
148  {
149      if ((callback != NULL) && (callback->onRequest != NULL)) {
150          LOGI("[Service][In]: ProcessRequestCallback! [ReqId]: %" PRId64, reqId);
151          char *returnData = callback->onRequest(reqId, operationCode, reqParams);
152          LOGI("[Service][Out]: ProcessRequestCallback!");
153          return returnData;
154      }
155      LOGE("[OnRequest]: Currently, the service callback is NULL! [ReqId]: %" PRId64, reqId);
156      return NULL;
157  }
158  
GetGMCallbackByAppId(const char * appId)159  const DeviceAuthCallback *GetGMCallbackByAppId(const char *appId)
160  {
161      uint32_t index;
162      CallbackEntry *entry = NULL;
163      g_callbackMutex->lock(g_callbackMutex);
164      FOR_EACH_HC_VECTOR(g_callbackVec, index, entry) {
165          if (strcmp(entry->appId, appId) == 0) {
166              g_callbackMutex->unlock(g_callbackMutex);
167              return entry->callback;
168          }
169      }
170      g_callbackMutex->unlock(g_callbackMutex);
171      return NULL;
172  }
173  
RegGroupManagerCallback(const char * appId,const DeviceAuthCallback * callback)174  int32_t RegGroupManagerCallback(const char *appId, const DeviceAuthCallback *callback)
175  {
176      if ((appId == NULL) || (callback == NULL)) {
177          LOGE("The input parameters contains NULL value!");
178          return HC_ERR_INVALID_PARAMS;
179      }
180      if (UpdateCallbackIfExist(appId, callback) == HC_SUCCESS) {
181          return HC_SUCCESS;
182      }
183      return AddCallbackIfNotExist(appId, callback);
184  }
185  
UnRegGroupManagerCallback(const char * appId)186  int32_t UnRegGroupManagerCallback(const char *appId)
187  {
188      SET_LOG_MODE(NORMAL_MODE);
189      if (appId == NULL) {
190          LOGE("The input appId is NULL!");
191          return HC_ERR_INVALID_PARAMS;
192      }
193      uint32_t index;
194      CallbackEntry *entry = NULL;
195      g_callbackMutex->lock(g_callbackMutex);
196      FOR_EACH_HC_VECTOR(g_callbackVec, index, entry) {
197          if (strcmp(entry->appId, appId) == 0) {
198              HcFree(entry->appId);
199              HcFree(entry->callback);
200              CallbackEntry tempEntry;
201              HC_VECTOR_POPELEMENT(&g_callbackVec, &tempEntry, index);
202              g_callbackMutex->unlock(g_callbackMutex);
203              LOGI("Successfully removed a callback. [AppId]: %s", appId);
204              return HC_SUCCESS;
205          }
206      }
207      g_callbackMutex->unlock(g_callbackMutex);
208      LOGI("The callback does not exist! [AppId]: %s", appId);
209      return HC_SUCCESS;
210  }
211  
InitCallbackManager(void)212  int32_t InitCallbackManager(void)
213  {
214      if (g_callbackMutex == NULL) {
215          g_callbackMutex = (HcMutex *)HcMalloc(sizeof(HcMutex), 0);
216          if (g_callbackMutex == NULL) {
217              LOGE("Failed to allocate broadcast mutex memory!");
218              return HC_ERR_ALLOC_MEMORY;
219          }
220          if (InitHcMutex(g_callbackMutex) != HC_SUCCESS) {
221              LOGE("Init mutex failed!");
222              HcFree(g_callbackMutex);
223              g_callbackMutex = NULL;
224              return HC_ERROR;
225          }
226      }
227      g_callbackVec = CREATE_HC_VECTOR(GMCallbackEntryVec);
228      return HC_SUCCESS;
229  }
230  
DestroyCallbackManager(void)231  void DestroyCallbackManager(void)
232  {
233      uint32_t index;
234      CallbackEntry *entry = NULL;
235      g_callbackMutex->lock(g_callbackMutex);
236      FOR_EACH_HC_VECTOR(g_callbackVec, index, entry) {
237          HcFree(entry->appId);
238          HcFree(entry->callback);
239      }
240      DESTROY_HC_VECTOR(GMCallbackEntryVec, &g_callbackVec);
241      g_callbackMutex->unlock(g_callbackMutex);
242      DestroyHcMutex(g_callbackMutex);
243      HcFree(g_callbackMutex);
244      g_callbackMutex = NULL;
245  }