• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2020 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 "endpoint.h"
16 
17 #include <log.h>
18 #include <ohos_errno.h>
19 #include <securec.h>
20 #include <service.h>
21 #include <stdlib.h>
22 #include <unistd.h>
23 
24 #include "default_client.h"
25 #include "ipc_skeleton.h"
26 #include "iproxy_server.h"
27 #include "memory_adapter.h"
28 #include "policy_define.h"
29 #include "pthread.h"
30 #include "serializer.h"
31 #include "thread_adapter.h"
32 #include "samgr_ipc_adapter.h"
33 
34 static int CompareIServerProxy(const IServerProxy *proxy1, const IServerProxy *proxy2);
35 static IServerProxy *GetIServerProxy(const Router *router);
36 static int AddPolicyToRouter(const Endpoint *endpoint, const SvcIdentity *saInfo,
37                              const PolicyTrans *policy, uint32 policyNum);
38 static int RegisterRemoteEndpoint(SvcIdentity *identity, int token, const char *service, const char *feature);
39 
SAMGR_CreateEndpoint(const char * name,RegisterEndpoint registry)40 Endpoint *SAMGR_CreateEndpoint(const char *name, RegisterEndpoint registry)
41 {
42     Endpoint *endpoint = SAMGR_Malloc(sizeof(Endpoint));
43     if (endpoint == NULL) {
44         return NULL;
45     }
46     endpoint->deadId = INVALID_INDEX;
47     endpoint->boss = NULL;
48     endpoint->routers = VECTOR_Make((VECTOR_Key)GetIServerProxy, (VECTOR_Compare)CompareIServerProxy);
49     endpoint->name = name;
50     endpoint->running = FALSE;
51     endpoint->identity.handle = (int32_t)INVALID_INDEX;
52     endpoint->identity.token = (uint32_t)INVALID_INDEX;
53     endpoint->identity.cookie = (uint32_t)INVALID_INDEX;
54     endpoint->registerEP = (registry == NULL) ? RegisterRemoteEndpoint : registry;
55     TB_InitBucket(&endpoint->bucket, MAX_BUCKET_RATE, MAX_BURST_RATE);
56     return endpoint;
57 }
58 
SAMGR_AddRouter(Endpoint * endpoint,const SaName * saName,const Identity * id,IUnknown * proxy)59 int SAMGR_AddRouter(Endpoint *endpoint, const SaName *saName, const Identity *id, IUnknown *proxy)
60 {
61     if (endpoint == NULL || id == NULL || proxy == NULL || saName == NULL) {
62         return EC_INVALID;
63     }
64     IServerProxy *serverProxy = NULL;
65     proxy->QueryInterface(proxy, SERVER_PROXY_VER, (void *)&serverProxy);
66 #ifndef MINI_SAMGR_LITE_RPC
67     if (serverProxy == NULL) {
68         return EC_INVALID;
69     }
70     int index = VECTOR_FindByKey(&endpoint->routers, proxy);
71     if (index != INVALID_INDEX) {
72         serverProxy->Release((IUnknown *)serverProxy);
73         return index;
74     }
75 #else
76     int index = VECTOR_FindByKey(&endpoint->routers, proxy);
77     if (index != INVALID_INDEX) {
78         serverProxy->Release((IUnknown *)serverProxy);
79     }
80 #endif
81     Router *router = SAMGR_Malloc(sizeof(Router));
82     if (router == NULL) {
83         HILOG_ERROR(HILOG_MODULE_SAMGR, "Memory is not enough! Identity<%d, %d>",
84                     id->serviceId, id->featureId);
85         return EC_NOMEMORY;
86     }
87     router->saName = *saName;
88     router->identity = *id;
89     router->proxy = serverProxy;
90     router->policy = NULL;
91     router->policyNum = 0;
92     index = VECTOR_Add(&endpoint->routers, router);
93     if (index == INVALID_INDEX) {
94         SAMGR_Free(router);
95         return EC_FAILURE;
96     }
97     Listen(endpoint, index, saName->service, saName->feature);
98     return index;
99 }
100 
SAMGR_AddSysCap(const Endpoint * endpoint,const char * sysCap,BOOL isReg)101 int32 SAMGR_AddSysCap(const Endpoint *endpoint, const char *sysCap, BOOL isReg)
102 {
103     if (endpoint == NULL) {
104         return EC_INVALID;
105     }
106     HILOG_DEBUG(HILOG_MODULE_SAMGR, "SAMGR_AddSysCap begin");
107     IpcIo req;
108     uint8 data[MAX_DATA_LEN];
109     IpcIoInit(&req, data, MAX_DATA_LEN, 0);
110     WriteInt32(&req, 0);
111     WriteUint32(&req, RES_SYSCAP);
112     WriteUint32(&req, OP_PUT);
113     WriteBool(&req, sysCap);
114     WriteBool(&req, isReg);
115 
116     IpcIo reply;
117     void *replyBuf = NULL;
118     const SvcIdentity *samgr = GetContextObject();
119     if (samgr == NULL) {
120         return EC_INVALID;
121     }
122     MessageOption option;
123     MessageOptionInit(&option);
124     int ret = SendRequest(*samgr, INVALID_INDEX, &req, &reply,
125                           option, (uintptr_t *)&replyBuf);
126     ret = -ret;
127     int32_t ipcRet = ret;
128     if (ret == EC_SUCCESS) {
129         ReadInt32(&reply, &ipcRet);
130     }
131 
132     if (replyBuf != NULL) {
133         FreeBuffer(replyBuf);
134     }
135     HILOG_DEBUG(HILOG_MODULE_SAMGR, "SAMGR_AddSysCap ret = %d", ipcRet);
136 
137     return ipcRet;
138 }
139 
SAMGR_GetSysCap(const Endpoint * endpoint,const char * sysCap,BOOL * isReg)140 int32 SAMGR_GetSysCap(const Endpoint *endpoint, const char *sysCap, BOOL *isReg)
141 {
142     if (endpoint == NULL) {
143         return EC_INVALID;
144     }
145     HILOG_DEBUG(HILOG_MODULE_SAMGR, "SAMGR_GetSysCap begin");
146     IpcIo req;
147     uint8 data[MAX_DATA_LEN];
148     IpcIoInit(&req, data, MAX_DATA_LEN, 0);
149     WriteInt32(&req, 0);
150     WriteUint32(&req, RES_SYSCAP);
151     WriteUint32(&req, OP_GET);
152     WriteBool(&req, sysCap);
153 
154     IpcIo reply;
155     void *replyBuf = NULL;
156     const SvcIdentity *samgr = GetContextObject();
157     if (samgr == NULL) {
158         return EC_INVALID;
159     }
160     MessageOption option;
161     MessageOptionInit(&option);
162     int ret = SendRequest(*samgr, INVALID_INDEX, &req, &reply,
163                           option, (uintptr_t *)&replyBuf);
164     ret = -ret;
165     *isReg = FALSE;
166     int32_t ipcRet = ret;
167     if (ret == EC_SUCCESS) {
168         (void)ReadInt32(&reply, &ipcRet);
169     }
170     if (ipcRet == EC_SUCCESS) {
171         (void)ReadBool(&reply, (bool *)isReg);
172     }
173     if (replyBuf != NULL) {
174         FreeBuffer(replyBuf);
175     }
176     HILOG_DEBUG(HILOG_MODULE_SAMGR, "SAMGR_GetSysCap ret = %d", ipcRet);
177     return ipcRet;
178 }
179 
SendGetAllSysCapsRequest(const Endpoint * endpoint,uint32 startIdx,IpcIo * reply,void ** replyBuf)180 static int SendGetAllSysCapsRequest(const Endpoint *endpoint, uint32 startIdx, IpcIo *reply, void **replyBuf)
181 {
182     IpcIo req;
183     uint8 data[MAX_DATA_LEN];
184     IpcIoInit(&req, data, MAX_DATA_LEN, 0);
185     WriteInt32(&req, 0);
186     WriteUint32(&req, RES_SYSCAP);
187     WriteUint32(&req, OP_ALL);
188     WriteUint32(&req, startIdx);
189     const SvcIdentity *samgr = GetContextObject();
190     if (samgr == NULL) {
191         return EC_INVALID;
192     }
193     MessageOption option;
194     MessageOptionInit(&option);
195     int ret = SendRequest(*samgr, INVALID_INDEX, &req, reply,
196                           option, (uintptr_t *)replyBuf);
197     HILOG_DEBUG(HILOG_MODULE_SAMGR, "SendGetAllSysCapsRequest startIdx:%u, ret:%d!", startIdx, ret);
198     return -ret;
199 }
200 
ParseGetAllSysCapsReply(IpcIo * reply,char sysCaps[MAX_SYSCAP_NUM][MAX_SYSCAP_NAME_LEN],int32 * sysCapNum,BOOL * isEnd,uint32 * nextRequestIdx)201 static int32 ParseGetAllSysCapsReply(IpcIo *reply, char sysCaps[MAX_SYSCAP_NUM][MAX_SYSCAP_NAME_LEN],
202                                      int32 *sysCapNum, BOOL *isEnd, uint32 *nextRequestIdx)
203 {
204     if (isEnd == NULL) {
205         return EC_INVALID;
206     }
207     int32_t ret;
208     if (ReadInt32(reply, &ret)) {
209         if (ret != EC_SUCCESS) {
210             *isEnd = TRUE;
211             return ret;
212         }
213     } else {
214         *isEnd = TRUE;
215         return EC_INVALID;
216     }
217 
218     (void)ReadBool(reply, (bool *)isEnd);
219     (void)ReadUint32(reply, nextRequestIdx);
220     uint32 size;
221     (void)ReadUint32(reply, &size);
222     size = ((size > MAX_SYSCAP_NUM) ? MAX_SYSCAP_NUM : size);
223     int cnt = *sysCapNum;
224     for (uint32 i = 0; i < size; i++) {
225         uint32 len = 0;
226         char *sysCap = (char *)ReadString(reply, (size_t *)&len);
227         if (sysCap == NULL || len == 0) {
228             continue;
229         }
230         if (strcpy_s(sysCaps[cnt], sizeof(sysCaps[cnt]), sysCap) != EC_SUCCESS) {
231             continue;
232         }
233         cnt++;
234     }
235     *sysCapNum = cnt;
236 
237     return ret;
238 }
239 
SAMGR_GetSystemCapabilities(const Endpoint * endpoint,char sysCaps[MAX_SYSCAP_NUM][MAX_SYSCAP_NAME_LEN],int32 * sysCapNum)240 int32 SAMGR_GetSystemCapabilities(const Endpoint *endpoint,
241                                   char sysCaps[MAX_SYSCAP_NUM][MAX_SYSCAP_NAME_LEN], int32 *sysCapNum)
242 {
243     if (sysCapNum == NULL) {
244         return EC_INVALID;
245     }
246     *sysCapNum = 0;
247     if (endpoint == NULL) {
248         return EC_INVALID;
249     }
250     HILOG_DEBUG(HILOG_MODULE_SAMGR, "SAMGR_GetSystemCapabilities begin");
251     IpcIo reply;
252     void *replyBuf = NULL;
253     uint32 startIdx = 0;
254     BOOL isEnd = TRUE;
255     int ret;
256     do {
257         ret = SendGetAllSysCapsRequest(endpoint, startIdx, &reply, &replyBuf);
258         if (ret == EC_SUCCESS) {
259             ret = ParseGetAllSysCapsReply(&reply, sysCaps, sysCapNum, &isEnd, &startIdx);
260         }
261         if (replyBuf != NULL) {
262             FreeBuffer(replyBuf);
263         }
264     } while (isEnd == FALSE && ret == EC_SUCCESS);
265     HILOG_DEBUG(HILOG_MODULE_SAMGR, "SAMGR_GetSystemCapabilities ret = %d", ret);
266     return ret;
267 }
268 
SAMGR_ProcPolicy(const Endpoint * endpoint,const SaName * saName,int token)269 int SAMGR_ProcPolicy(const Endpoint *endpoint, const SaName *saName, int token)
270 {
271     if (endpoint == NULL || saName == NULL || token == INVALID_INDEX) {
272         return EC_INVALID;
273     }
274     // retry until success or 20 seconds.
275     int ret = EC_INVALID;
276     uint8 retry = 0;
277     SvcIdentity saInfo = {INVALID_INDEX, token, INVALID_INDEX};
278     while (retry < MAX_REGISTER_RETRY_TIMES) {
279         ++retry;
280         PolicyTrans *policy = NULL;
281         uint32 policyNum = 0;
282         ret = RegisterIdentity(saName,  &saInfo, &policy, &policyNum);
283         if (ret != EC_SUCCESS || policy == NULL) {
284             SAMGR_Free(policy);
285             continue;
286         }
287         HILOG_INFO(HILOG_MODULE_SAMGR, "Register server sa<%s, %s> id<%d> retry:%d ret:%d!",
288                    saName->service, saName->feature, saInfo.handle, retry, ret);
289         ret = AddPolicyToRouter(endpoint, &saInfo, policy, policyNum);
290         SAMGR_Free(policy);
291         if (ret == EC_SUCCESS) {
292             break;
293         }
294         sleep(REGISTER_RETRY_INTERVAL);
295     }
296     return ret;
297 }
298 
AddPolicyToRouter(const Endpoint * endpoint,const SvcIdentity * saInfo,const PolicyTrans * policy,uint32 policyNum)299 static int AddPolicyToRouter(const Endpoint *endpoint, const SvcIdentity *saInfo,
300                              const PolicyTrans *policy, uint32 policyNum)
301 {
302     if (endpoint == NULL || saInfo == NULL || policy == NULL) {
303         return EC_INVALID;
304     }
305 
306     Router *router = VECTOR_At((Vector *)&endpoint->routers, saInfo->token);
307     if (router == NULL) {
308         HILOG_ERROR(HILOG_MODULE_SAMGR, "Router <%s> is NULL", endpoint->name);
309         return EC_INVALID;
310     }
311 
312     if (router->policy != NULL) {
313         return EC_SUCCESS;
314     }
315     router->policyNum = policyNum;
316     if (policyNum == 0) {
317         return EC_INVALID;
318     }
319     router->policy = (PolicyTrans *)SAMGR_Malloc(sizeof(PolicyTrans) * policyNum);
320     if (router->policy == NULL) {
321         return EC_NOMEMORY;
322     }
323     if (memcpy_s(router->policy, sizeof(PolicyTrans) * policyNum, policy,
324                  sizeof(PolicyTrans) * policyNum) != EOK) {
325         SAMGR_Free(router->policy);
326         router->policy = NULL;
327         HILOG_ERROR(HILOG_MODULE_SAMGR, "Add Policy <%s, %s, %s> Failed!",
328                     endpoint->name, router->saName.service, router->saName.feature);
329         return EC_FAILURE;
330     }
331     HILOG_DEBUG(HILOG_MODULE_SAMGR, "Add Policy <%s, %s, %s> Success",
332                 endpoint->name, router->saName.service, router->saName.feature);
333     return EC_SUCCESS;
334 }
335 
CompareIServerProxy(const IServerProxy * proxy1,const IServerProxy * proxy2)336 static int CompareIServerProxy(const IServerProxy *proxy1, const IServerProxy *proxy2)
337 {
338     if (proxy1 == proxy2) {
339         return 0;
340     }
341     return (proxy1 > proxy2) ? 1 : -1;
342 }
343 
GetIServerProxy(const Router * router)344 static IServerProxy *GetIServerProxy(const Router *router)
345 {
346     if (router == NULL) {
347         return NULL;
348     }
349     return router->proxy;
350 }
351 
RegisterRemoteEndpoint(SvcIdentity * identity,int token,const char * service,const char * feature)352 static int RegisterRemoteEndpoint(SvcIdentity *identity, int token, const char *service, const char *feature)
353 {
354     return ClientRegisterRemoteEndpoint(identity, token, service, feature);
355 }