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 }