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