1 /*
2 * Copyright (c) 2022 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 #include "samgr_ipc_adapter.h"
16 #include "samgr_server.h"
17 #include "dbinder_service.h"
18 static int Dispatch(uint32_t code, IpcIo *data, IpcIo *reply, MessageOption option);
19 static void HandleIpc(const Request *request, const Response *response);
20 static void GetRemotePolicy(IpcIo *reply, PolicyTrans **policy, uint32 *policyNum);
ClientRegisterRemoteEndpoint(SvcIdentity * identity,int token,const char * service,const char * feature)21 int ClientRegisterRemoteEndpoint(SvcIdentity *identity, int token, const char *service, const char *feature)
22 {
23 IpcObjectStub *objectStubOne = (IpcObjectStub *)calloc(1, sizeof(IpcObjectStub));
24 if (objectStubOne == NULL) {
25 return -1;
26 }
27 objectStubOne->func = Dispatch;
28 objectStubOne->isRemote = true;
29 // handle is used by rpc, should be bigger than 0
30 identity->handle = token + 1;
31 identity->cookie = objectStubOne;
32 // token is used by router index, should be itself, and save in SaNode
33 identity->token = token;
34 return AddEndpoint(*identity, service, feature);
35 }
36
Listen(Endpoint * endpoint,int token,const char * service,const char * feature)37 void Listen(Endpoint *endpoint, int token, const char *service, const char *feature)
38 {
39 endpoint->registerEP(&endpoint->identity, token, service, feature);
40 }
41
Dispatch(uint32_t code,IpcIo * data,IpcIo * reply,MessageOption option)42 static int Dispatch(uint32_t code, IpcIo *data, IpcIo *reply, MessageOption option)
43 {
44 Endpoint *endpoint = g_remoteRegister.endpoint;
45 int token = GetRemoteToken(data);
46 if (token == EC_INVALID) {
47 goto ERROR;
48 }
49 if (TB_CheckMessage(&endpoint->bucket) == BUCKET_BUSY) {
50 HILOG_WARN(HILOG_MODULE_SAMGR, "Flow Control <%u> is NULL", token);
51 goto ERROR;
52 }
53
54 Router *router = VECTOR_At(&endpoint->routers, token);
55 if (router == NULL) {
56 HILOG_ERROR(HILOG_MODULE_SAMGR, "Router <%s, %u> is NULL", endpoint->name, token);
57 goto ERROR;
58 }
59 Response resp = {0};
60 resp.data = endpoint;
61 Request request = {0};
62 request.msgId = token;
63 request.data = data;
64 resp.reply = reply;
65 request.msgValue = code;
66 uint32 *ref = NULL;
67 int ret = SAMGR_SendSharedDirectRequest(&router->identity, &request, &resp, &ref, HandleIpc);
68 if (ret != EC_SUCCESS) {
69 HILOG_ERROR(HILOG_MODULE_SAMGR, "Router[%u] Service<%d, %d> is busy",
70 token, router->identity.serviceId, router->identity.featureId);
71 goto ERROR;
72 }
73
74 return EC_SUCCESS;
75 ERROR:
76 return EC_INVALID;
77 }
78
HandleIpc(const Request * request,const Response * response)79 static void HandleIpc(const Request *request, const Response *response)
80 {
81 Endpoint *endpoint = (Endpoint *)response->data;
82 Router *router = VECTOR_At(&endpoint->routers, request->msgId);
83
84 router->proxy->Invoke(router->proxy, request->msgValue, NULL, request->data, response->reply);
85 }
86
RegisterIdentity(const SaName * saName,SvcIdentity * saInfo,PolicyTrans ** policy,uint32 * policyNum)87 int RegisterIdentity(const SaName *saName, SvcIdentity *saInfo, PolicyTrans **policy, uint32 *policyNum)
88 {
89 IpcIo req;
90 uint8 data[MAX_DATA_LEN];
91 IpcIoInit(&req, data, MAX_DATA_LEN, 0);
92 WriteUint32(&req, RES_FEATURE);
93 WriteUint32(&req, OP_PUT);
94 WriteString(&req, saName->service);
95 WriteBool(&req, saName->feature == NULL);
96 if (saName->feature != NULL) {
97 WriteBool(&req, saName->feature);
98 }
99 WriteUint32(&req, saInfo->token);
100 IpcIo reply;
101 void *replyBuf = NULL;
102 SvcIdentity *samgr = GetContextObject();
103 MessageOption option;
104 MessageOptionInit(&option);
105 int ret = SendRequest(*samgr, INVALID_INDEX, &req, &reply, option,
106 (uintptr_t *)&replyBuf);
107 ret = -ret;
108 int32_t ipcRet = EC_FAILURE;
109 if (ret == EC_SUCCESS) {
110 ret = ReadInt32(&reply, &ipcRet);
111 }
112 if (ipcRet == EC_SUCCESS) {
113 SvcIdentity target;
114 (void)ReadRemoteObject(&reply, &target);
115 GetRemotePolicy(&reply, policy, policyNum);
116 }
117 if (replyBuf != NULL) {
118 FreeBuffer(replyBuf);
119 }
120 return ret;
121 }
122
GetRemoteToken(IpcIo * data)123 int GetRemoteToken(IpcIo *data)
124 {
125 uintptr_t saId = 0;
126 ReadInt32(data, &saId);
127 SaNode *saNode = GetSaNodeBySaId(saId);
128 if (saNode == NULL) {
129 HILOG_WARN(HILOG_MODULE_SAMGR, "get sa node by sa id %d is NULL", saId);
130 return EC_INVALID;
131 }
132 return saNode->token;
133 }
134
GetRemotePolicy(IpcIo * reply,PolicyTrans ** policy,uint32 * policyNum)135 static void GetRemotePolicy(IpcIo *reply, PolicyTrans **policy, uint32 *policyNum)
136 {
137 if (reply == NULL) {
138 return;
139 }
140 ReadUint32(reply, policyNum);
141 if (*policyNum > MAX_POLICY_NUM) {
142 *policyNum = MAX_POLICY_NUM;
143 }
144 SAMGR_Free(*policy);
145 if (*policyNum == 0) {
146 *policy = NULL;
147 return;
148 }
149 *policy = (PolicyTrans *)SAMGR_Malloc(sizeof(PolicyTrans) * (*policyNum));
150 if (*policy == NULL) {
151 return;
152 }
153 for (uint32 i = 0; i < *policyNum; i++) {
154 if (!ReadInt32(reply, &(*policy)[i].type)) {
155 continue;
156 }
157 switch ((*policy)[i].type) {
158 case RANGE:
159 ReadInt32(reply, &((*policy)[i].uidMin));
160 ReadInt32(reply, &((*policy)[i].uidMax));
161 break;
162 case FIXED:
163 for (uint32 j = 0; j < UID_SIZE; j++) {
164 ReadInt32(reply, &((*policy)[i].fixedUid[j]));
165 }
166 break;
167 case BUNDLENAME:
168 ReadInt32(reply, &((*policy)[i].fixedUid[0]));
169 break;
170 default:
171 break;
172 }
173 }
174 }