1a34a8711Sopenharmony_ci/* 2a34a8711Sopenharmony_ci * Copyright (C) 2022 Huawei Device Co., Ltd. 3a34a8711Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4a34a8711Sopenharmony_ci * you may not use this file except in compliance with the License. 5a34a8711Sopenharmony_ci * You may obtain a copy of the License at 6a34a8711Sopenharmony_ci * 7a34a8711Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8a34a8711Sopenharmony_ci * 9a34a8711Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10a34a8711Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11a34a8711Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12a34a8711Sopenharmony_ci * See the License for the specific language governing permissions and 13a34a8711Sopenharmony_ci * limitations under the License. 14a34a8711Sopenharmony_ci */ 15a34a8711Sopenharmony_ci 16a34a8711Sopenharmony_ci#include "dbinder_stub.h" 17a34a8711Sopenharmony_ci 18a34a8711Sopenharmony_ci#include <stdbool.h> 19a34a8711Sopenharmony_ci 20a34a8711Sopenharmony_ci#include "dbinder_service_inner.h" 21a34a8711Sopenharmony_ci#include "ipc_process_skeleton.h" 22a34a8711Sopenharmony_ci#include "ipc_skeleton.h" 23a34a8711Sopenharmony_ci#include "ipc_thread_pool.h" 24a34a8711Sopenharmony_ci#include "rpc_errno.h" 25a34a8711Sopenharmony_ci#include "rpc_log.h" 26a34a8711Sopenharmony_ci#include "securec.h" 27a34a8711Sopenharmony_ci 28a34a8711Sopenharmony_ci#define IPC_INVALID_HANDLE (-1) 29a34a8711Sopenharmony_ci 30a34a8711Sopenharmony_cistatic int32_t GetDigits(int32_t number) 31a34a8711Sopenharmony_ci{ 32a34a8711Sopenharmony_ci int32_t n = 0; 33a34a8711Sopenharmony_ci while (number > 0) { 34a34a8711Sopenharmony_ci n++; 35a34a8711Sopenharmony_ci number /= ID_DIGITS; 36a34a8711Sopenharmony_ci } 37a34a8711Sopenharmony_ci if (n == 0) { 38a34a8711Sopenharmony_ci n++; 39a34a8711Sopenharmony_ci } 40a34a8711Sopenharmony_ci return n; 41a34a8711Sopenharmony_ci} 42a34a8711Sopenharmony_ci 43a34a8711Sopenharmony_cistatic char *CreateDatabusName(void) 44a34a8711Sopenharmony_ci{ 45a34a8711Sopenharmony_ci int32_t pid = (int32_t)GetCallingPid(); 46a34a8711Sopenharmony_ci int32_t pidLen = GetDigits(pid); 47a34a8711Sopenharmony_ci int32_t uid = (int32_t)GetCallingUid(); 48a34a8711Sopenharmony_ci int32_t uidLen = GetDigits(uid); 49a34a8711Sopenharmony_ci 50a34a8711Sopenharmony_ci uint32_t sessionNameLen = SESSION_NAME_LEGNTH + pidLen + uidLen; 51a34a8711Sopenharmony_ci char *sessionName = (char *)malloc(sessionNameLen + 1); 52a34a8711Sopenharmony_ci if (sessionName == NULL) { 53a34a8711Sopenharmony_ci RPC_LOG_ERROR("sessionName mallo failed"); 54a34a8711Sopenharmony_ci return NULL; 55a34a8711Sopenharmony_ci } 56a34a8711Sopenharmony_ci if (sprintf_s(sessionName, sessionNameLen + 1, "DBinder%d_%d", uid, pid) == -1) { 57a34a8711Sopenharmony_ci RPC_LOG_ERROR("sessionName sprintf failed"); 58a34a8711Sopenharmony_ci free(sessionName); 59a34a8711Sopenharmony_ci return NULL; 60a34a8711Sopenharmony_ci } 61a34a8711Sopenharmony_ci return sessionName; 62a34a8711Sopenharmony_ci} 63a34a8711Sopenharmony_ci 64a34a8711Sopenharmony_cistatic int32_t ProcessProto(uint32_t code, IpcIo *data, IpcIo *reply, MessageOption *option) 65a34a8711Sopenharmony_ci{ 66a34a8711Sopenharmony_ci int32_t result = ERR_NONE; 67a34a8711Sopenharmony_ci ThreadContext *threadContext = GetCurrentThreadContext(); 68a34a8711Sopenharmony_ci if (threadContext == NULL) { 69a34a8711Sopenharmony_ci RPC_LOG_ERROR("ProcessProto threadContext is null"); 70a34a8711Sopenharmony_ci return ERR_FAILED; 71a34a8711Sopenharmony_ci } 72a34a8711Sopenharmony_ci 73a34a8711Sopenharmony_ci SessionInfo *session = QuerySessionObject((uintptr_t)threadContext->objectStub); 74a34a8711Sopenharmony_ci if (session == NULL) { 75a34a8711Sopenharmony_ci RPC_LOG_ERROR("client find session is null"); 76a34a8711Sopenharmony_ci return ERR_FAILED; 77a34a8711Sopenharmony_ci } 78a34a8711Sopenharmony_ci const char *localBusName = CreateDatabusName(); 79a34a8711Sopenharmony_ci if (localBusName == NULL) { 80a34a8711Sopenharmony_ci RPC_LOG_ERROR("ProcessProto CreateDatabusName failed"); 81a34a8711Sopenharmony_ci return ERR_FAILED; 82a34a8711Sopenharmony_ci } 83a34a8711Sopenharmony_ci 84a34a8711Sopenharmony_ci switch (session->type) { 85a34a8711Sopenharmony_ci case DATABUS_TYPE: { 86a34a8711Sopenharmony_ci WriteUint32(reply, IF_PROT_DATABUS); 87a34a8711Sopenharmony_ci WriteUint64(reply, session->stubIndex); 88a34a8711Sopenharmony_ci WriteString(reply, session->serviceName); 89a34a8711Sopenharmony_ci WriteString(reply, session->deviceIdInfo.toDeviceId); 90a34a8711Sopenharmony_ci WriteString(reply, session->deviceIdInfo.fromDeviceId); 91a34a8711Sopenharmony_ci WriteString(reply, localBusName); 92a34a8711Sopenharmony_ci break; 93a34a8711Sopenharmony_ci } 94a34a8711Sopenharmony_ci default: { 95a34a8711Sopenharmony_ci result = ERR_FAILED; 96a34a8711Sopenharmony_ci break; 97a34a8711Sopenharmony_ci } 98a34a8711Sopenharmony_ci } 99a34a8711Sopenharmony_ci free((void *)localBusName); 100a34a8711Sopenharmony_ci return result; 101a34a8711Sopenharmony_ci} 102a34a8711Sopenharmony_ci 103a34a8711Sopenharmony_cistatic int32_t DBinderRemoteRequest(uint32_t code, IpcIo *data, IpcIo *reply, MessageOption *option) 104a34a8711Sopenharmony_ci{ 105a34a8711Sopenharmony_ci int32_t ret = -1; 106a34a8711Sopenharmony_ci switch (code) { 107a34a8711Sopenharmony_ci case GET_PROTO_INFO: { 108a34a8711Sopenharmony_ci ret = ProcessProto(code, data, reply, option); 109a34a8711Sopenharmony_ci break; 110a34a8711Sopenharmony_ci } 111a34a8711Sopenharmony_ci default: { 112a34a8711Sopenharmony_ci RPC_LOG_ERROR("unknown dbinder code %u", code); 113a34a8711Sopenharmony_ci break; 114a34a8711Sopenharmony_ci } 115a34a8711Sopenharmony_ci } 116a34a8711Sopenharmony_ci return ret; 117a34a8711Sopenharmony_ci} 118a34a8711Sopenharmony_ci 119a34a8711Sopenharmony_ciint32_t GetDBinderStub(const char *serviceName, const char *deviceID, 120a34a8711Sopenharmony_ci uintptr_t binderObject, DBinderServiceStub *dBinderServiceStub) 121a34a8711Sopenharmony_ci{ 122a34a8711Sopenharmony_ci if (strcpy_s(dBinderServiceStub->serviceName, SERVICENAME_LENGTH + 1, serviceName) != EOK 123a34a8711Sopenharmony_ci || strcpy_s(dBinderServiceStub->deviceID, DEVICEID_LENGTH + 1, deviceID) != EOK) { 124a34a8711Sopenharmony_ci RPC_LOG_ERROR("dBinderServiceStub string copy failed"); 125a34a8711Sopenharmony_ci return ERR_FAILED; 126a34a8711Sopenharmony_ci } 127a34a8711Sopenharmony_ci 128a34a8711Sopenharmony_ci IpcObjectStub *objectStub = (IpcObjectStub *)malloc(sizeof(IpcObjectStub)); 129a34a8711Sopenharmony_ci if (objectStub == NULL) { 130a34a8711Sopenharmony_ci RPC_LOG_ERROR("objectStub malloc failed"); 131a34a8711Sopenharmony_ci return ERR_FAILED; 132a34a8711Sopenharmony_ci } 133a34a8711Sopenharmony_ci objectStub->func = (OnRemoteRequest)DBinderRemoteRequest; 134a34a8711Sopenharmony_ci objectStub->isRemote = true; 135a34a8711Sopenharmony_ci 136a34a8711Sopenharmony_ci dBinderServiceStub->binderObject = binderObject; 137a34a8711Sopenharmony_ci dBinderServiceStub->svc.handle = IPC_INVALID_HANDLE; 138a34a8711Sopenharmony_ci dBinderServiceStub->svc.token = (uintptr_t)objectStub; 139a34a8711Sopenharmony_ci dBinderServiceStub->svc.cookie = (uintptr_t)objectStub; 140a34a8711Sopenharmony_ci return ERR_NONE; 141a34a8711Sopenharmony_ci} 142