add OpenHarmony 1.0 baseline

This commit is contained in:
wenjun 2020-09-08 10:21:39 +08:00
parent 312809e7c8
commit ba18e3df61
62 changed files with 6279 additions and 0 deletions

13
.gitee/ISSUE_TEMPLATE.zh-CN.md Executable file
View File

@ -0,0 +1,13 @@
### 该问题是怎么引起的?
### 重现步骤
### 报错信息

View File

@ -0,0 +1,15 @@
### 相关的Issue
### 原因(目的、解决的问题等)
### 描述(做了什么,变更了什么)
### 测试用例(新增、改动、可能影响的功能)

57
BUILD.gn Executable file
View File

@ -0,0 +1,57 @@
# Copyright (c) 2020 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//build/lite/config/component/lite_component.gni")
import("//build/lite/ndk/ndk.gni")
lite_component("samgr") {
features = [
"samgr",
"communication/broadcast",
]
if (ohos_kernel_type == "liteos_a" || ohos_kernel_type == "linux"){
features += [
"samgr_server:server",
"samgr_client:client",
]
}
}
ndk_lib("samgr_lite_ndk") {
if(ohos_kernel_type == "liteos_riscv" || ohos_kernel_type == "liteos_m") {
lib_extension = ".a"
} else if (ohos_kernel_type == "liteos_a" || ohos_kernel_type == "linux") {
lib_extension = ".so"
}
deps = [
"samgr",
"communication/broadcast",
]
head_files = [
"//foundation/distributedschedule/interfaces/kits/samgr_lite/samgr",
"//foundation/distributedschedule/interfaces/kits/samgr_lite/communication/broadcast",
]
if (ohos_kernel_type == "liteos_a" || ohos_kernel_type == "linux"){
deps += [
"samgr_server:server",
]
head_files += ["//foundation/distributedschedule/interfaces/kits/samgr_lite/registry"]
}
}
generate_notice_file("samgr_notice_file") {
module_name = "samgr"
module_source_dir_list = [
"//third_party/bounds_checking_function"
]
}

177
LICENSE Executable file
View File

@ -0,0 +1,177 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS

View File

@ -0,0 +1,61 @@
# Copyright (c) 2020 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
config("broadcast_public") {
include_dirs = [
"//foundation/distributedschedule/interfaces/kits/samgr_lite/communication/broadcast",
"//foundation/distributedschedule/interfaces/kits/samgr_lite/samgr",
"//foundation/distributedschedule/services/samgr_lite/samgr/adapter",
"//utils/native/lite/include",
]
}
if (ohos_kernel_type == "liteos_riscv" || ohos_kernel_type == "liteos_m") {
static_library("broadcast") {
sources = [
"source/pub_sub_implement.c",
"source/pub_sub_feature.c",
"source/broadcast_service.c",
]
public_configs = [":broadcast_public"]
cflags = [ "-Wall" ]
include_dirs = [
"//kernel/liteos_m/components/cmsis",
]
}
}
if (ohos_kernel_type == "liteos_a" || ohos_kernel_type == "linux") {
shared_library("broadcast") {
sources = [
"source/pub_sub_implement.c",
"source/pub_sub_feature.c",
"source/broadcast_service.c",
]
public_configs = [":broadcast_public"]
configs -= [ "//build/lite/config:language_c" ]
cflags_c = [
"-std=c11",
"-Wall"
]
include_dirs = [
"//kernel/liteos_a/kernel/include/",
"//third_party/bounds_checking_function/include",
"//kernel/liteos_a/kernel/common",
]
public_deps = [
"//third_party/bounds_checking_function:libsec_shared",
"//foundation/distributedschedule/services/samgr_lite/samgr:samgr",
]
}
}

View File

@ -0,0 +1,71 @@
/*
* Copyright (c) 2020 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "broadcast_service.h"
#include "ohos_init.h"
#include "common.h"
#include "samgr_lite.h"
#include "thread_adapter.h"
#include "pub_sub_feature.h"
static const char *GetName(Service *service);
static BOOL Initialize(Service *service, Identity identity);
static TaskConfig GetTaskConfig(Service *service);
static BOOL MessageHandle(Service *service, Request *request);
static BroadcastService g_broadcastService = {
GetName,
Initialize,
MessageHandle,
GetTaskConfig,
};
static void Init(void)
{
SAMGR_GetInstance()->RegisterService((Service *)&g_broadcastService);
}
SYS_SERVICE_INIT(Init);
static const char *GetName(Service *service)
{
(void)service;
return BROADCAST_SERVICE;
}
static BOOL Initialize(Service *service, Identity identity)
{
(void)identity;
if (service == NULL) {
return FALSE;
}
return TRUE;
}
static BOOL MessageHandle(Service *service, Request *request)
{
(void)service;
switch (request->msgId) {
case BROADCAST_MSG:
break;
default:
break;
}
return TRUE;
}
static TaskConfig GetTaskConfig(Service *service)
{
(void)service;
TaskConfig config = {LEVEL_HIGH, PRI_ABOVE_NORMAL, 0x800, 40, SPECIFIED_TASK};
return config;
}

View File

@ -0,0 +1,41 @@
/*
* Copyright (c) 2020 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef LITE_BROADCAST_SERVICE_H
#define LITE_BROADCAST_SERVICE_H
#include "service.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif
enum BroadcastMsgType {
BROADCAST_MSG,
};
typedef struct BroadcastService BroadcastService;
struct BroadcastService {
INHERIT_SERVICE;
};
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif
#endif // LITE_BROADCAST_SERVICE_H

View File

@ -0,0 +1,116 @@
/*
* Copyright (c) 2020 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "pub_sub_feature.h"
#include <ohos_init.h>
#include "samgr_lite.h"
#include "thread_adapter.h"
#include "pub_sub_implement.h"
static const char *GetName(Feature *feature);
static void OnInitialize(Feature *feature, Service *parent, Identity identity);
static void OnStop(Feature *feature, Identity identity);
static BOOL OnMessage(Feature *feature, Request *request);
static Relation *GetRelation(PubSubFeature *feature, const Topic *topic);
static BOOL IsTopicEqual(const Topic *current, const Topic *other);
static PubSubFeature g_broadcastFeature = {
.GetName = GetName,
.OnInitialize = OnInitialize,
.OnStop = OnStop,
.OnMessage = OnMessage,
.GetRelation = GetRelation,
};
static void Init(void)
{
PubSubFeature *feature = &g_broadcastFeature;
feature->relations.topic = -1;
feature->relations.callbacks.consumer = NULL;
UtilsListInit(&feature->relations.callbacks.node);
UtilsListInit(&feature->relations.node);
feature->mutex = MUTEX_InitValue();
SAMGR_GetInstance()->RegisterFeature(BROADCAST_SERVICE, (Feature *)feature);
PubSubImplement *apiEntry = BCE_CreateInstance((Feature *)feature);
SAMGR_GetInstance()->RegisterFeatureApi(BROADCAST_SERVICE, PUB_SUB_FEATURE, GET_IUNKNOWN(*apiEntry));
}
SYS_FEATURE_INIT(Init);
static const char *GetName(Feature *feature)
{
(void)feature;
return PUB_SUB_FEATURE;
}
static void OnInitialize(Feature *feature, Service *parent, Identity identity)
{
(void)parent;
((PubSubFeature *)feature)->identity = identity;
}
static void OnStop(Feature *feature, Identity identity)
{
(void)feature;
(void)identity;
}
static BOOL OnMessage(Feature *feature, Request *request)
{
PubSubFeature *broadcast = (PubSubFeature *)feature;
switch (request->msgId) {
case MSG_PUBLISH: {
Topic topic = request->msgValue;
Relation *relation = broadcast->GetRelation(broadcast, &topic);
if (relation == NULL) {
return FALSE;
}
MUTEX_Lock(broadcast->mutex);
ConsumerNode *item = NULL;
UTILS_DL_LIST_FOR_EACH_ENTRY(item, &relation->callbacks.node, ConsumerNode, node) {
if (item->consumer->identity == NULL) {
item->consumer->Notify(item->consumer, &topic, request);
}
}
MUTEX_Unlock(broadcast->mutex);
}
break;
default:
break;
}
return TRUE;
}
static Relation *GetRelation(PubSubFeature *feature, const Topic *topic)
{
if (feature == NULL || topic == NULL) {
return NULL;
}
UTILS_DL_LIST *list = &feature->relations.node;
Relation *item = NULL;
MUTEX_Lock(feature->mutex);
UTILS_DL_LIST_FOR_EACH_ENTRY(item, list, Relation, node) {
if (IsTopicEqual(&item->topic, topic)) {
MUTEX_Unlock(feature->mutex);
return item;
}
}
MUTEX_Unlock(feature->mutex);
return NULL;
}
static BOOL IsTopicEqual(const Topic *current, const Topic *other)
{
return *current == *other;
}

View File

@ -0,0 +1,56 @@
/*
* Copyright (c) 2020 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef LITE_PUB_SUB_FEATURE_H
#define LITE_PUB_SUB_FEATURE_H
#include "utils_list.h"
#include "message.h"
#include "feature.h"
#include "common.h"
#include "broadcast_interface.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif
typedef struct ConsumerNode {
UTILS_DL_LIST node;
Consumer *consumer;
} ConsumerNode;
typedef struct Relation {
UTILS_DL_LIST node;
ConsumerNode callbacks;
Topic topic;
} Relation;
typedef struct PubSubFeature PubSubFeature;
struct PubSubFeature {
INHERIT_FEATURE;
Relation *(*GetRelation)(PubSubFeature *feature, const Topic *topic);
MutexId mutex;
Relation relations;
Identity identity;
};
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif
#endif // LITE_PUB_SUB_FEATURE_H

View File

@ -0,0 +1,256 @@
/*
* Copyright (c) 2020 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "pub_sub_implement.h"
#include "securec.h"
#include "ohos_errno.h"
#include "memory_adapter.h"
#include "thread_adapter.h"
static int AddTopic(IUnknown *iUnknown, const Topic *topic);
static int Subscribe(IUnknown *iUnknown, const Topic *topic, Consumer *consumer);
static Consumer *ModifyConsumer(IUnknown *iUnknown, const Topic *topic, Consumer *oldConsumer, Consumer *newConsumer);
static Consumer *Unsubscribe(IUnknown *iUnknown, const Topic *topic, const Consumer *consumer);
static BOOL Publish(IUnknown *iUnknown, const Topic *topic, uint8 *data, int16 len);
static void DefaultHandle(const Request *request, const Response *response);
static BOOL ImmediatelyPublish(PubSubFeature *feature, const Topic *topic, const Request *request);
static PubSubImplement g_pubSubImplement = {
DEFAULT_IUNKNOWN_ENTRY_BEGIN,
.subscriber.AddTopic = AddTopic,
.subscriber.Subscribe = Subscribe,
.subscriber.ModifyConsumer = ModifyConsumer,
.subscriber.Unsubscribe = Unsubscribe,
.provider.Publish = Publish,
DEFAULT_IUNKNOWN_ENTRY_END,
.feature = NULL
};
PubSubImplement *BCE_CreateInstance(Feature *feature)
{
g_pubSubImplement.feature = (PubSubFeature *)feature;
return &g_pubSubImplement;
}
static int AddTopic(IUnknown *iUnknown, const Topic *topic)
{
if (iUnknown == NULL || topic == NULL) {
return EC_INVALID;
}
PubSubImplement *broadcast = GET_OBJECT(iUnknown, PubSubImplement, iUnknown);
if (broadcast->feature == NULL || broadcast->feature->GetRelation == NULL) {
return EC_FAILURE;
}
if (broadcast->feature->GetRelation(broadcast->feature, topic) != NULL) {
return EC_FAILURE;
}
Relation *head = &broadcast->feature->relations;
Relation *newRelation = (Relation *)SAMGR_Malloc(sizeof(Relation));
if (newRelation == NULL) {
return EC_NOMEMORY;
}
newRelation->topic = *topic;
newRelation->callbacks.consumer = NULL;
UtilsListInit(&newRelation->callbacks.node);
MUTEX_Lock(broadcast->feature->mutex);
UtilsListAdd(&head->node, &(newRelation->node));
MUTEX_Unlock(broadcast->feature->mutex);
return EC_SUCCESS;
}
static int Subscribe(IUnknown *iUnknown, const Topic *topic, Consumer *consumer)
{
if (iUnknown == NULL || topic == NULL || consumer == NULL) {
return EC_INVALID;
}
PubSubImplement *broadcast = GET_OBJECT(iUnknown, PubSubImplement, iUnknown);
if (broadcast->feature == NULL || broadcast->feature->GetRelation == NULL) {
return EC_FAILURE;
}
Relation *relation = broadcast->feature->GetRelation(broadcast->feature, topic);
if (relation == NULL) {
return EC_FAILURE;
}
MUTEX_Lock(broadcast->feature->mutex);
ConsumerNode *item = NULL;
UTILS_DL_LIST_FOR_EACH_ENTRY(item, &relation->callbacks.node, ConsumerNode, node) {
if (item->consumer->Equal(item->consumer, consumer)) {
MUTEX_Unlock(broadcast->feature->mutex);
return EC_ALREADY_SUBSCRIBED;
}
}
MUTEX_Unlock(broadcast->feature->mutex);
ConsumerNode *consumerNode = (ConsumerNode *)SAMGR_Malloc(sizeof(ConsumerNode));
if (consumerNode == NULL) {
return EC_NOMEMORY;
}
UtilsListInit(&consumerNode->node);
consumerNode->consumer = consumer;
MUTEX_Lock(broadcast->feature->mutex);
ConsumerNode *head = &relation->callbacks;
UtilsListAdd(&head->node, &consumerNode->node);
MUTEX_Unlock(broadcast->feature->mutex);
return EC_SUCCESS;
}
static Consumer *ModifyConsumer(IUnknown *iUnknown, const Topic *topic, Consumer *oldConsumer, Consumer *newConsumer)
{
if (iUnknown == NULL || topic == NULL || oldConsumer == NULL || newConsumer == NULL) {
return NULL;
}
PubSubImplement *broadcast = GET_OBJECT(iUnknown, PubSubImplement, iUnknown);
if (broadcast->feature == NULL || broadcast->feature->GetRelation == NULL) {
return NULL;
}
Relation *relation = broadcast->feature->GetRelation(broadcast->feature, topic);
if (relation == NULL) {
return NULL;
}
MUTEX_Lock(broadcast->feature->mutex);
ConsumerNode *item = NULL;
UTILS_DL_LIST_FOR_EACH_ENTRY(item, &relation->callbacks.node, ConsumerNode, node) {
if (item->consumer->Equal(item->consumer, oldConsumer)) {
Consumer *older = item->consumer;
item->consumer = newConsumer;
MUTEX_Unlock(broadcast->feature->mutex);
return older;
}
}
MUTEX_Unlock(broadcast->feature->mutex);
return NULL;
}
static Consumer *Unsubscribe(IUnknown *iUnknown, const Topic *topic, const Consumer *consumer)
{
if (iUnknown == NULL || topic == NULL || consumer == NULL) {
return NULL;
}
PubSubImplement *broadcast = GET_OBJECT(iUnknown, PubSubImplement, iUnknown);
if (broadcast->feature == NULL || broadcast->feature->GetRelation == NULL) {
return NULL;
}
Relation *relation = broadcast->feature->GetRelation(broadcast->feature, topic);
if (relation == NULL) {
return NULL;
}
MUTEX_Lock(broadcast->feature->mutex);
ConsumerNode *item = NULL;
UTILS_DL_LIST_FOR_EACH_ENTRY(item, &relation->callbacks.node, ConsumerNode, node) {
if (item->consumer->Equal(item->consumer, consumer)) {
UtilsListDelete(&item->node);
break;
}
}
MUTEX_Unlock(broadcast->feature->mutex);
if (item == &relation->callbacks || item == NULL) {
return NULL;
}
Consumer *oldConsumer = item->consumer;
SAMGR_Free(item);
return oldConsumer;
}
static BOOL Publish(IUnknown *iUnknown, const Topic *topic, uint8 *data, int16 len)
{
PubSubImplement *broadcast = GET_OBJECT(iUnknown, PubSubImplement, iUnknown);
PubSubFeature *feature = broadcast->feature;
if (feature == NULL) {
return FALSE;
}
Request request = {MSG_PUBLISH, 0, NULL, *(uint32 *)topic};
if (data != NULL && len > 0) {
request.data = (uint8 *)SAMGR_Malloc(len);
if (request.data == NULL) {
return FALSE;
}
request.len = len;
// There is no problem, the request.data length is equal the input data length.
(void)memcpy_s(request.data, request.len, data, len);
}
if (!ImmediatelyPublish(feature, topic, &request)) {
(void)SAMGR_Free(request.data);
request.data = NULL;
request.len = 0;
return FALSE;
}
return TRUE;
}
static BOOL ImmediatelyPublish(PubSubFeature *feature, const Topic *topic, const Request *request)
{
if (feature->GetRelation == NULL) {
return FALSE;
}
Relation *relation = feature->GetRelation(feature, topic);
if (relation == NULL) {
return FALSE;
}
if (UtilsListEmpty(&relation->callbacks.node)) {
return FALSE;
}
BOOL needAync = FALSE;
ConsumerNode *item = NULL;
uint32 *token = NULL;
MUTEX_Lock(feature->mutex);
UTILS_DL_LIST_FOR_EACH_ENTRY(item, &relation->callbacks.node, ConsumerNode, node) {
if (item->consumer->identity == NULL) {
needAync = TRUE;
continue;
}
Response response = {item->consumer, 0};
int ret = SAMGR_SendSharedDirectRequest(item->consumer->identity, request, &response, &token, DefaultHandle);
if (ret != EC_SUCCESS) {
needAync = FALSE;
break;
}
}
if (needAync) {
token = SAMGR_SendSharedRequest(&feature->identity, request, token, NULL);
}
MUTEX_Unlock(feature->mutex);
return (token != NULL);
}
static void DefaultHandle(const Request *request, const Response *response)
{
Consumer *consumer = (Consumer *)response->data;
if (consumer == NULL || consumer->Notify == NULL || g_pubSubImplement.feature == NULL) {
return;
}
// wait ImmediatelyPublish finished.
MUTEX_Lock(g_pubSubImplement.feature->mutex);
MUTEX_Unlock(g_pubSubImplement.feature->mutex);
Topic topic = request->msgValue;
consumer->Notify(consumer, &topic, request);
}

View File

@ -0,0 +1,44 @@
/*
* Copyright (c) 2020 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef LITE_PUB_SUB_IMPLEMENT_H
#define LITE_PUB_SUB_IMPLEMENT_H
#include "broadcast_interface.h"
#include "pub_sub_feature.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif
enum MessageID {
MSG_PUBLISH = 1,
MSG_BUTT
};
typedef struct PubSubImplement {
INHERIT_IUNKNOWNENTRY(PubSubInterface);
PubSubFeature *feature;
} PubSubImplement;
PubSubImplement *BCE_CreateInstance(Feature *feature);
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif
#endif // LITE_PUB_SUB_IMPLEMENT_H

1
readme.md Executable file
View File

@ -0,0 +1 @@
详见https://gitee.com/openharmony/docs/blob/master/readme/系统服务框架子系统README.md

75
samgr/BUILD.gn Executable file
View File

@ -0,0 +1,75 @@
# Copyright (c) 2020 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
config("external_settings_shared") {
defines = ["LAYER_INIT_SHARED_LIB"]
}
config("samgr_public") {
include_dirs = [
"adapter",
"registry",
"//foundation/distributedschedule/interfaces/kits/samgr_lite/registry",
"//foundation/distributedschedule/interfaces/kits/samgr_lite/samgr",
"//utils/native/lite/include",
]
}
if (ohos_kernel_type == "liteos_riscv" || ohos_kernel_type == "liteos_m") {
static_library("samgr") {
sources = [
"source/samgr_lite.c",
"registry/service_registry.c",
]
public_configs = [":samgr_public"]
cflags = [ "-Wall" ]
include_dirs = [
"//base/hiviewdfx/interfaces/kits/hilog_lite",
"//kernel/liteos_m/components/cmsis",
]
public_deps = [
"//foundation/distributedschedule/services/samgr_lite/samgr/adapter:samgr_adapter",
"//foundation/distributedschedule/services/samgr_lite/samgr/source:samgr_source"
]
}
}
if (ohos_kernel_type == "liteos_a" || ohos_kernel_type == "linux") {
shared_library("samgr") {
sources = [
"source/samgr_lite.c",
]
cflags = [
"-fPIC",
"-Wall"
]
public_configs = [":samgr_public"]
include_dirs = [
"//kernel/liteos_a/kernel/include/",
"//third_party/bounds_checking_function/include",
]
public_deps = [
"//foundation/distributedschedule/services/samgr_lite/samgr/source:samgr_source",
"//foundation/distributedschedule/services/samgr_lite/samgr_client:client",
"//foundation/communication/frameworks/ipc_lite:liteipc_adapter",
]
public_configs += [":external_settings_shared"]
}
}

70
samgr/adapter/BUILD.gn Executable file
View File

@ -0,0 +1,70 @@
# Copyright (c) 2020 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
config("samgr_adapter_public") {
include_dirs = [
"./",
"//foundation/distributedschedule/interfaces/kits/samgr_lite/samgr",
"//utils/native/lite/include",
]
}
if (ohos_kernel_type == "liteos_riscv" || ohos_kernel_type == "liteos_m") {
static_library("samgr_adapter") {
sources = [
"cmsis/memory_adapter.c",
"cmsis/queue_adapter.c",
"cmsis/thread_adapter.c",
"cmsis/time_adapter.c",
]
public_configs = [":samgr_adapter_public"]
cflags = [ "-Wall" ]
include_dirs = [
"//kernel/liteos_m/components/cmsis",
"//kernel/liteos_m/components/kal/include",
]
}
}
if (ohos_kernel_type == "liteos_a" || ohos_kernel_type == "linux") {
source_set("samgr_adapter") {
sources = [
"posix/lock_free_queue.c",
"posix/memory_adapter.c",
"posix/queue_adapter.c",
"posix/thread_adapter.c",
"posix/time_adapter.c",
]
public_configs = [":samgr_adapter_public"]
include_dirs = [
"//kernel/liteos_a/kernel/include/",
"//third_party/bounds_checking_function/include",
]
cflags = [
"-fPIC",
"-Wall"
]
public_deps = [
"//third_party/bounds_checking_function:libsec_shared"
]
defines = [ "_GNU_SOURCE" ]
if (ohos_kernel_type == "linux") {
defines += [ "SAMGR_LINUX_ADAPTER" ]
}
}
}

View File

@ -0,0 +1,32 @@
/*
* Copyright (c) 2020 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "memory_adapter.h"
#include <los_memory.h>
void *SAMGR_Malloc(uint32 size)
{
if (size == 0) {
return NULL;
}
return LOS_MemAlloc(m_aucSysMem0, (UINT32)size);
}
void SAMGR_Free(void *buffer)
{
if (buffer == NULL) {
return;
}
(void)LOS_MemFree(m_aucSysMem0, buffer);
}

View File

@ -0,0 +1,53 @@
/*
* Copyright (c) 2020 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "queue_adapter.h"
#include <cmsis_os.h>
#include <ohos_types.h>
#include <ohos_errno.h>
MQueueId QUEUE_Create(const char *name, int size, int count)
{
osMessageQueueAttr_t queueAttr = {name, 0, NULL, 0, NULL, 0};
return (MQueueId)osMessageQueueNew(count, size, &queueAttr);
}
int QUEUE_Put(MQueueId queueId, const void *element, uint8 pri, int timeout)
{
uint32_t waitTime = (timeout <= 0) ? 0 : (uint32_t)timeout;
osStatus_t ret = osMessageQueuePut(queueId, element, pri, waitTime);
if (ret != osOK) {
return EC_BUSBUSY;
}
return EC_SUCCESS;
}
int QUEUE_Pop(MQueueId queueId, void *element, uint8 *pri, int timeout)
{
uint32_t waitTime = (timeout <= 0) ? osWaitForever : (uint32_t)timeout;
osStatus_t evt = osMessageQueueGet(queueId, element, pri, waitTime);
if (evt != osOK) {
return EC_BUSBUSY;
}
return EC_SUCCESS;
}
int QUEUE_Destroy(MQueueId queueId)
{
osStatus_t evt = osMessageQueueDelete(queueId);
if (evt != osOK) {
return EC_FAILURE;
}
return EC_SUCCESS;
}

View File

@ -0,0 +1,72 @@
/*
* Copyright (c) 2020 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "thread_adapter.h"
#include "common.h"
#include <los_task.h>
#include <cmsis_os.h>
extern void *osThreadGetArgument(void);
MutexId MUTEX_InitValue()
{
return osMutexNew(NULL);
}
void MUTEX_Lock(MutexId mutex)
{
if (mutex == NULL) {
return;
}
osMutexAcquire(mutex, LOS_WAIT_FOREVER);
}
void MUTEX_Unlock(MutexId mutex)
{
if (mutex == NULL) {
return;
}
osMutexRelease(mutex);
}
void MUTEX_GlobalLock(void)
{
LOS_TaskLock();
}
void MUTEX_GlobalUnlock(void)
{
LOS_TaskUnlock();
}
ThreadId THREAD_Create(Runnable run, void *argv, const ThreadAttr *attr)
{
osThreadAttr_t taskAttr = {attr->name, 0, NULL, 0, NULL, attr->stackSize, attr->priority, 0, 0};
return (ThreadId)osThreadNew((osThreadFunc_t)run, argv, &taskAttr);
}
int THREAD_Total(void)
{
return osThreadGetCount();
}
void *THREAD_GetThreadLocal(void)
{
return osThreadGetArgument();
}
void THREAD_SetThreadLocal(const void *local)
{
(void)local;
}

View File

@ -0,0 +1,40 @@
/*
* Copyright (c) 2020 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "time_adapter.h"
#include <ohos_errno.h>
#include <cmsis_os.h>
#include <kal.h>
int32 WDT_Start(uint32 ms)
{
return WDT_Reset(ms);
}
int32 WDT_Reset(uint32 ms)
{
(void)ms;
return EC_FAILURE;
}
int32 WDT_Stop(void)
{
return EC_FAILURE;
}
uint64 SAMGR_GetProcessTime(void)
{
uint32 tick = osKernelGetTickCount();
return KalTickToMs(tick);
}

35
samgr/adapter/memory_adapter.h Executable file
View File

@ -0,0 +1,35 @@
/*
* Copyright (c) 2020 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef LITE_MEMORY_ADAPTER_H
#define LITE_MEMORY_ADAPTER_H
#include "ohos_types.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif
void *SAMGR_Malloc(uint32 size);
void SAMGR_Free(void *buffer);
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif
#endif // LITE_MEMORY_ADAPTER_H

View File

@ -0,0 +1,119 @@
/*
* Copyright (c) 2020 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "lock_free_queue.h"
#include <ohos_errno.h>
#include <pthread.h>
#include <securec.h>
#include <memory_adapter.h>
LockFreeQueue *LFQUE_Create(int size, int count)
{
if (size <= 0 || count <= 0) {
return NULL;
}
int total = size * count + 1;
if (total <= 0) {
return NULL;
}
register LockFreeQueue *queue = (LockFreeQueue *)SAMGR_Malloc(sizeof(LockFreeQueue) + total);
if (queue == NULL) {
return NULL;
}
queue->write = 0;
queue->read = 0;
queue->itemSize = size;
queue->totalSize = total;
return queue;
}
BOOL LFQUE_IsFull(LockFreeQueue *queue)
{
uint32 nextWrite = queue->write + 1;
if (nextWrite >= queue->totalSize) {
nextWrite = 0;
}
return (nextWrite == queue->read);
}
BOOL LFQUE_IsEmpty(LockFreeQueue *queue)
{
return (queue->write == queue->read);
}
int LFQUE_Push(LockFreeQueue *queue, const void *element, uint8 pri)
{
(void)pri;
if (queue == NULL || element == NULL) {
return EC_INVALID;
}
if (LFQUE_IsFull(queue)) {
return EC_BUSBUSY;
}
uint32 copyLen = (queue->totalSize - queue->write < queue->itemSize) ?
(queue->totalSize - queue->write) : queue->itemSize;
if (memcpy_s(&queue->buffer[queue->write], copyLen, element, copyLen) != EOK) {
return EC_INVALID;
}
element += copyLen;
copyLen = queue->itemSize - copyLen;
if (copyLen > 0) {
if (memcpy_s(queue->buffer, copyLen, element, copyLen) != EOK) {
return EC_INVALID;
}
}
uint32 write = queue->write + queue->itemSize;
if (write >= queue->totalSize) {
write = write - queue->totalSize;
}
queue->write = write;
return EC_SUCCESS;
}
int LFQUE_Pop(LockFreeQueue *queue, void *element, uint8 *pri)
{
(void)pri;
if (queue == NULL || element == NULL) {
return EC_INVALID;
}
if (LFQUE_IsEmpty(queue)) {
return EC_FAILURE;
}
uint32 copyLen = (queue->totalSize - queue->read < queue->itemSize) ?
(queue->totalSize - queue->read) : queue->itemSize;
if (memcpy_s(element, copyLen, &queue->buffer[queue->read], copyLen) != EOK) {
return EC_FAILURE;
}
element += copyLen;
copyLen = queue->itemSize - copyLen;
if (copyLen > 0) {
if (memcpy_s(element, copyLen, queue->buffer, copyLen) != EOK) {
return EC_FAILURE;
}
}
uint32 read = queue->read + queue->itemSize;
if (read >= queue->totalSize) {
read = read - queue->totalSize;
}
queue->read = read;
return EC_SUCCESS;
}

View File

@ -0,0 +1,49 @@
/*
* Copyright (c) 2020 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef LITE_LOCK_FREE_QUEUE_H
#define LITE_LOCK_FREE_QUEUE_H
#include <ohos_types.h>
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif
typedef struct LockFreeQueue LockFreeQueue;
struct LockFreeQueue {
uint32 write;
uint32 read;
uint32 itemSize;
uint32 totalSize;
uint8 buffer[0];
};
LockFreeQueue *LFQUE_Create(int size, int count);
BOOL LFQUE_IsEmpty(LockFreeQueue *queue);
BOOL LFQUE_IsFull(LockFreeQueue *queue);
int LFQUE_Push(LockFreeQueue *queue, const void *element, uint8 pri);
int LFQUE_Pop(LockFreeQueue *queue, void *element, uint8 *pri);
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif
#endif // LITE_LOCK_FREE_QUEUE_H

View File

@ -0,0 +1,31 @@
/*
* Copyright (c) 2020 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "memory_adapter.h"
#include <stdlib.h>
void *SAMGR_Malloc(uint32 size)
{
if (size == 0) {
return NULL;
}
return malloc(size);
}
void SAMGR_Free(void *buffer)
{
if (buffer == NULL) {
return;
}
(void)free(buffer);
}

View File

@ -0,0 +1,93 @@
/*
* Copyright (c) 2020 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "queue_adapter.h"
#include <ohos_errno.h>
#include <pthread.h>
#include "memory_adapter.h"
#include "lock_free_queue.h"
typedef struct LockFreeBlockQueue LockFreeBlockQueue;
struct LockFreeBlockQueue {
pthread_mutex_t wMutex;
pthread_mutex_t rMutex;
pthread_cond_t cond;
LockFreeQueue *queue;
};
MQueueId QUEUE_Create(const char *name, int size, int count)
{
LockFreeBlockQueue *queue = (LockFreeBlockQueue *)SAMGR_Malloc(sizeof(LockFreeBlockQueue));
if (queue == NULL) {
return NULL;
}
queue->queue = LFQUE_Create(size, count);
if (queue->queue == NULL) {
SAMGR_Free(queue);
return NULL;
}
pthread_mutex_init(&queue->wMutex, NULL);
pthread_mutex_init(&queue->rMutex, NULL);
pthread_cond_init(&queue->cond, NULL);
return (MQueueId)queue;
}
int QUEUE_Put(MQueueId queueId, const void *element, uint8 pri, int timeout)
{
if (queueId == NULL || element == NULL || timeout > 0) {
return EC_INVALID;
}
LockFreeBlockQueue *queue = (LockFreeBlockQueue *)queueId;
pthread_mutex_lock(&queue->wMutex);
int ret = LFQUE_Push(queue->queue, element, pri);
pthread_mutex_unlock(&queue->wMutex);
pthread_mutex_lock(&queue->rMutex);
pthread_cond_signal(&queue->cond);
pthread_mutex_unlock(&queue->rMutex);
return ret;
}
int QUEUE_Pop(MQueueId queueId, void *element, uint8 *pri, int timeout)
{
if (queueId == NULL || element == NULL || timeout > 0) {
return EC_INVALID;
}
LockFreeBlockQueue *queue = (LockFreeBlockQueue *)queueId;
if (LFQUE_Pop(queue->queue, element, pri) == EC_SUCCESS) {
return EC_SUCCESS;
}
pthread_mutex_lock(&queue->rMutex);
while (LFQUE_Pop(queue->queue, element, pri) != EC_SUCCESS) {
pthread_cond_wait(&queue->cond, &queue->rMutex);
}
pthread_mutex_unlock(&queue->rMutex);
return EC_SUCCESS;
}
int QUEUE_Destroy(MQueueId queueId)
{
if (queueId == NULL) {
return EC_INVALID;
}
LockFreeBlockQueue *queue = (LockFreeBlockQueue *)queueId;
pthread_mutex_destroy(&queue->wMutex);
pthread_mutex_destroy(&queue->rMutex);
pthread_cond_destroy(&queue->cond);
SAMGR_Free(queue->queue);
SAMGR_Free(queue);
return EC_SUCCESS;
}

View File

@ -0,0 +1,101 @@
/*
* Copyright (c) 2020 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "thread_adapter.h"
#include <pthread.h>
#include <unistd.h>
#include "common.h"
#include "memory_adapter.h"
#define PRI_BUTT 39
#define MIN_STACK_SIZE 0x8000
static int g_threadCount = 0;
static pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_key_t g_localKey = 0;
MutexId MUTEX_InitValue()
{
pthread_mutex_t *mutex = SAMGR_Malloc(sizeof(pthread_mutex_t));
if (mutex == NULL) {
return NULL;
}
(void)pthread_mutex_init(mutex, NULL);
return (MutexId)mutex;
}
void MUTEX_Lock(MutexId mutex)
{
if (mutex == NULL) {
return;
}
pthread_mutex_lock((pthread_mutex_t *)mutex);
}
void MUTEX_Unlock(MutexId mutex)
{
if (mutex == NULL) {
return;
}
pthread_mutex_unlock((pthread_mutex_t *)mutex);
}
void MUTEX_GlobalLock(void)
{
pthread_mutex_lock(&g_mutex);
}
void MUTEX_GlobalUnlock(void)
{
pthread_mutex_unlock(&g_mutex);
}
ThreadId THREAD_Create(Runnable run, void *argv, const ThreadAttr *attr)
{
pthread_attr_t threadAttr;
pthread_attr_init(&threadAttr);
pthread_attr_setstacksize(&threadAttr, (attr->stackSize | MIN_STACK_SIZE));
pthread_attr_setinheritsched(&threadAttr, PTHREAD_EXPLICIT_SCHED);
#ifdef SAMGR_LINUX_ADAPTER
struct sched_param sched = {attr->priority};
#else
struct sched_param sched = {PRI_BUTT - attr->priority};
#endif
pthread_attr_setschedpolicy(&threadAttr, SCHED_RR);
pthread_attr_setschedparam(&threadAttr, &sched);
pthread_key_create(&g_localKey, NULL);
pthread_t threadId = 0;
int errno = pthread_create(&threadId, &threadAttr, run, argv);
if (errno != 0) {
return NULL;
}
MUTEX_GlobalLock();
g_threadCount++;
MUTEX_GlobalUnlock();
return (ThreadId)threadId;
}
int THREAD_Total(void)
{
return g_threadCount;
}
void *THREAD_GetThreadLocal(void)
{
return pthread_getspecific(g_localKey);
}
void THREAD_SetThreadLocal(const void *local)
{
pthread_setspecific(g_localKey, local);
}

View File

@ -0,0 +1,43 @@
/*
* Copyright (c) 2020 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "time_adapter.h"
#include <ohos_errno.h>
#include <time.h>
#define MS_PER_SECOND 1000
#define NS_PER_MS 1000000
int32 WDT_Start(uint32 ms)
{
return WDT_Reset(ms);
}
int32 WDT_Reset(uint32 ms)
{
(void)ms;
return EC_FAILURE;
}
int32 WDT_Stop(void)
{
return EC_FAILURE;
}
uint64 SAMGR_GetProcessTime(void)
{
struct timespec ts = {0, 0};
clock_gettime(CLOCK_REALTIME, &ts);
return ((ts.tv_sec * MS_PER_SECOND) + (ts.tv_nsec / NS_PER_MS));
}

40
samgr/adapter/queue_adapter.h Executable file
View File

@ -0,0 +1,40 @@
/*
* Copyright (c) 2020 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef LITE_QUEUE_ADAPTER_H
#define LITE_QUEUE_ADAPTER_H
#include <ohos_types.h>
#include "common.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif
MQueueId QUEUE_Create(const char *name, int size, int count);
int QUEUE_Put(MQueueId queueId, const void *element, uint8 pri, int timeout);
int QUEUE_Pop(MQueueId queueId, void *element, uint8 *pri, int timeout);
int QUEUE_Destroy(MQueueId queueId);
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif
#endif // LITE_QUEUE_ADAPTER_H

60
samgr/adapter/thread_adapter.h Executable file
View File

@ -0,0 +1,60 @@
/*
* Copyright (c) 2020 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef LITE_THREAD_ADAPTER_H
#define LITE_THREAD_ADAPTER_H
#include <ohos_types.h>
#include "common.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif
/// \details Mutex ID identifies the mutex.
typedef void *(*Runnable)(void *argv);
typedef struct ThreadAttr ThreadAttr;
struct ThreadAttr {
const char *name; // name of the thread
uint32 stackSize; // size of stack
uint8 priority; // initial thread priority
uint8 reserved1; // reserved1 (must be 0)
uint16 reserved2; // reserved2 (must be 0)
};
MutexId MUTEX_InitValue(void);
void MUTEX_Lock(MutexId mutex);
void MUTEX_Unlock(MutexId mutex);
void MUTEX_GlobalLock(void);
void MUTEX_GlobalUnlock(void);
ThreadId THREAD_Create(Runnable run, void *argv, const ThreadAttr *attr);
int THREAD_Total(void);
void *THREAD_GetThreadLocal(void);
void THREAD_SetThreadLocal(const void *local);
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif
#endif // LITE_THREAD_ADAPTER_H

39
samgr/adapter/time_adapter.h Executable file
View File

@ -0,0 +1,39 @@
/*
* Copyright (c) 2020 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef LITE_TIME_ADAPTER_H
#define LITE_TIME_ADAPTER_H
#include <ohos_types.h>
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif
int32 WDT_Start(uint32 ms);
int32 WDT_Reset(uint32 ms);
int32 WDT_Stop(void);
uint64 SAMGR_GetProcessTime(void);
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif
#endif // LITE_TIME_ADAPTER_H

View File

@ -0,0 +1,44 @@
/*
* Copyright (c) 2020 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "service_registry.h"
#include <ohos_errno.h>
#include <registry.h>
int __attribute__((weak)) SAMGR_RegisterServiceApi(const char *service, const char *feature,
const Identity *identity, IUnknown *iUnknown)
{
(void)service;
(void)feature;
(void)iUnknown;
(void)identity;
return EC_FAILURE;
}
IUnknown *__attribute__((weak)) SAMGR_FindServiceApi(const char *service, const char *feature)
{
(void)service;
(void)feature;
return NULL;
}
int __attribute__((weak)) SAMGR_RegisterFactory(const char *service, const char *feature,
Creator creator, Destroyer destroyer)
{
(void)service;
(void)feature;
(void)creator;
(void)destroyer;
return EC_INVALID;
}

View File

@ -0,0 +1,35 @@
/*
* Copyright (c) 2020 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef LITE_SERVICE_REGISTRY_H
#define LITE_SERVICE_REGISTRY_H
#include <iunknown.h>
#include <message.h>
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif
int SAMGR_RegisterServiceApi(const char *service, const char *feature, const Identity *identity, IUnknown *iUnknown);
IUnknown *SAMGR_FindServiceApi(const char *service, const char *feature);
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif
#endif // LITE_SERVICE_REGISTRY_H

77
samgr/source/BUILD.gn Executable file
View File

@ -0,0 +1,77 @@
# Copyright (c) 2020 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
config("samgr_source_public") {
include_dirs = [
"../adapter",
"../registry",
"//foundation/distributedschedule/interfaces/kits/samgr_lite/registry",
"//foundation/distributedschedule/interfaces/kits/samgr_lite/samgr",
"//utils/native/lite/include",
]
}
if (ohos_kernel_type == "liteos_riscv" || ohos_kernel_type == "liteos_m") {
static_library("samgr_source") {
sources = [
"common.c",
"iunknown.c",
"feature.c",
"service.c",
"message.c",
"task_manager.c",
]
public_configs = [":samgr_source_public"]
cflags = [ "-Wall" ]
public_deps = [
"//foundation/distributedschedule/services/samgr_lite/samgr/adapter:samgr_adapter"
]
include_dirs = [
"//base/hiviewdfx/interfaces/kits/hilog_lite",
"//kernel/liteos_m/components/cmsis",
]
}
}
if (ohos_kernel_type == "liteos_a" || ohos_kernel_type == "linux") {
source_set("samgr_source") {
sources = [
"common.c",
"iunknown.c",
"feature.c",
"service.c",
"message.c",
"task_manager.c",
]
cflags = [
"-fPIC",
"-Wall"
]
public_configs = [":samgr_source_public"]
public_deps = [
"//foundation/distributedschedule/services/samgr_lite/samgr/adapter:samgr_adapter",
"//base/hiviewdfx/frameworks/hilog_lite/featured:hilog_shared",
]
include_dirs = [
"//kernel/liteos_a/kernel/include/",
"//third_party/bounds_checking_function/include",
]
}
}

154
samgr/source/common.c Executable file
View File

@ -0,0 +1,154 @@
/*
* Copyright (c) 2020 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "common.h"
#include <securec.h>
#include "memory_adapter.h"
#define GROW_STEP 4
Vector VECTOR_Make(VECTOR_Key key, VECTOR_Compare compare)
{
Vector vector = {0, 0, 0, NULL, key, compare};
return vector;
}
void VECTOR_Clear(Vector *vector)
{
if (vector == NULL) {
return;
}
if (vector->data == NULL) {
return;
}
SAMGR_Free(vector->data);
vector->max = 0;
vector->top = 0;
vector->free = 0;
vector->data = NULL;
}
int16 VECTOR_Add(Vector *vector, void *element)
{
if (vector == NULL || element == NULL) {
return INVALID_INDEX;
}
if (vector->top >= vector->max) {
int16 i;
// use released data elements preferentially
for (i = vector->top - (int16)1; i >= 0; --i) {
if (vector->data[i] == NULL) {
vector->data[i] = element;
vector->free--;
return i;
}
}
if (vector->max + GROW_STEP < 0) {
return INVALID_INDEX;
}
void **data = (void **)SAMGR_Malloc(sizeof(void *) * (vector->max + GROW_STEP));
if (data == NULL) {
return INVALID_INDEX;
}
if (vector->data != NULL) {
// data's length is bigger than vector->data's length and only copy vector->data's length's memory;
// no need to check return value
(void)memcpy_s(data, sizeof(void *) * (vector->max + GROW_STEP),
vector->data, sizeof(void *) * vector->max);
SAMGR_Free(vector->data);
}
vector->data = data;
vector->max += GROW_STEP;
}
vector->data[vector->top] = element;
return vector->top++;
}
void *VECTOR_At(Vector *vector, int16 index)
{
if (vector == NULL || vector->top <= index || index < 0) {
return NULL;
}
return vector->data[index];
}
void *VECTOR_Swap(Vector *vector, int16 index, void *element)
{
if (vector == NULL || vector->top <= index || index < 0) {
return NULL;
}
if (element == NULL) {
vector->free++;
}
void *oldElement = vector->data[index];
vector->data[index] = element;
return oldElement;
}
int16 VECTOR_Find(Vector *vector, const void *element)
{
if (vector == NULL || element == NULL) {
return INVALID_INDEX;
}
return VECTOR_FindByKey(vector, (vector->key == NULL) ? element : vector->key(element));
}
int16 VECTOR_FindByKey(Vector *vector, const void *key)
{
if (vector == NULL || key == NULL) {
return INVALID_INDEX;
}
int16 i;
for (i = 0; i < vector->top; ++i) {
if (vector->data[i] == NULL) {
continue;
}
void *first = (vector->key != NULL) ? vector->key(vector->data[i]) : vector->data[i];
if (first == key) {
return i;
}
if (vector->compare == NULL || first == NULL) {
continue;
}
if (vector->compare(first, key) == 0) {
return i;
}
}
return INVALID_INDEX;
}
int16 VECTOR_Size(Vector *vector)
{
if (vector == NULL) {
return INVALID_INDEX;
}
return vector->top;
}
int16 VECTOR_Num(Vector *vector)
{
if (vector == NULL) {
return INVALID_INDEX;
}
return vector->top - vector->free;
}

64
samgr/source/feature.c Executable file
View File

@ -0,0 +1,64 @@
/*
* Copyright (c) 2020 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "feature.h"
#include "feature_impl.h"
#include "memory_adapter.h"
BOOL SAMGR_AddInterface(FeatureImpl *featureImpl, IUnknown *iUnknown)
{
if (featureImpl == NULL || iUnknown == NULL || featureImpl->iUnknown != NULL) {
return FALSE;
}
featureImpl->iUnknown = iUnknown;
return TRUE;
}
IUnknown *SAMGR_DelInterface(FeatureImpl *featureImpl)
{
if (featureImpl == NULL) {
return NULL;
}
IUnknown *iUnknown = featureImpl->iUnknown;
featureImpl->iUnknown = NULL;
return iUnknown;
}
IUnknown *SAMGR_GetInterface(FeatureImpl *featureImpl)
{
if (featureImpl == NULL) {
return NULL;
}
return featureImpl->iUnknown;
}
BOOL SAMGR_IsNoInterface(FeatureImpl *featureImpl)
{
return (BOOL)(featureImpl == NULL || featureImpl->iUnknown == NULL);
}
FeatureImpl *FEATURE_CreateInstance(Feature *feature)
{
if (feature == NULL) {
return NULL;
}
FeatureImpl *featureImpl = (FeatureImpl *)SAMGR_Malloc(sizeof(FeatureImpl));
if (featureImpl == NULL) {
return NULL;
}
featureImpl->feature = feature;
featureImpl->iUnknown = NULL;
return featureImpl;
}

57
samgr/source/feature_impl.h Executable file
View File

@ -0,0 +1,57 @@
/*
* Copyright (c) 2020 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef LITE_FEATUREIMPL_H
#define LITE_FEATUREIMPL_H
#include "common.h"
#include "iunknown.h"
#include "feature.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif
typedef struct FeatureImpl FeatureImpl;
struct FeatureImpl {
Feature *feature;
IUnknown *iUnknown;
};
inline static BOOL IsInvalidFeature(Feature *feature)
{
return (feature == NULL || feature->GetName == NULL || feature->OnInitialize == NULL ||
feature->OnMessage == NULL || feature->OnStop == NULL);
}
inline static BOOL IsInvalidIUnknown(IUnknown *iUnknown)
{
return (iUnknown == NULL || iUnknown->QueryInterface == NULL || iUnknown->AddRef == NULL ||
iUnknown->Release == NULL);
}
BOOL SAMGR_AddInterface(FeatureImpl *featureImpl, IUnknown *iUnknown);
IUnknown *SAMGR_DelInterface(FeatureImpl *featureImpl);
IUnknown *SAMGR_GetInterface(FeatureImpl *featureImpl);
BOOL SAMGR_IsNoInterface(FeatureImpl *featureImpl);
FeatureImpl *FEATURE_CreateInstance(Feature *feature);
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif
#endif // LITE_FEATUREIMPL_H

72
samgr/source/iunknown.c Executable file
View File

@ -0,0 +1,72 @@
/*
* Copyright (c) 2020 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "iunknown.h"
#include "common.h"
#define OLD_VERSION 0
int IUNKNOWN_AddRef(IUnknown *iUnknown)
{
if (iUnknown == NULL) {
return EC_INVALID;
}
IUnknownEntry *entry = GET_OBJECT(iUnknown, IUnknownEntry, iUnknown);
entry->ref++;
return entry->ref;
}
int IUNKNOWN_QueryInterface(IUnknown *iUnknown, int ver, void **target)
{
if (iUnknown == NULL || target == NULL) {
return EC_INVALID;
}
IUnknownEntry *entry = GET_OBJECT(iUnknown, IUnknownEntry, iUnknown);
if ((entry->ver & (uint16)ver) != ver) {
return EC_INVALID;
}
if (ver == OLD_VERSION &&
entry->ver != OLD_VERSION &&
(entry->ver & (uint16)DEFAULT_VERSION) != DEFAULT_VERSION) {
return EC_INVALID;
}
*target = iUnknown;
iUnknown->AddRef(iUnknown);
return EC_SUCCESS;
}
int IUNKNOWN_Release(IUnknown *iUnknown)
{
if (iUnknown == NULL) {
return EC_INVALID;
}
IUnknownEntry *entry = GET_OBJECT(iUnknown, IUnknownEntry, iUnknown);
int ref = entry->ref - 1;
if (ref < 0) {
// The iUnknown is already freed, there is some exception;
} else {
if (ref == 0) {
// Nobody reference to the iUnknown, should delete it.
// But iUnknown may be global variable, so the default version don`t delete it.
} else {
entry->ref = ref;
}
}
return ref;
}

229
samgr/source/message.c Executable file
View File

@ -0,0 +1,229 @@
/*
* Copyright (c) 2020 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "message_inner.h"
#include <ohos_errno.h>
#include <log.h>
#include "memory_adapter.h"
#include "queue_adapter.h"
#include "securec.h"
#include "task_manager.h"
#undef LOG_TAG
#undef LOG_DOMAIN
#define LOG_TAG "Samgr"
#define LOG_DOMAIN 0xD001800
#define DONT_WAIT 0
#define WAIT_FOREVER (-1)
static int32 SharedSend(MQueueId queueId, Exchange *exchange);
static BOOL FreeReference(Exchange *exchange);
int32 SAMGR_SendRequest(const Identity *identity, const Request *request, Handler handler)
{
if (request == NULL || identity == NULL) {
return EC_INVALID;
}
Exchange exchange = {*identity, *request, {NULL, 0}, MSG_NON, handler, NULL};
exchange.id.queueId = NULL;
if (handler != NULL) {
exchange.id.queueId = SAMGR_GetCurrentQueueID();
exchange.type = MSG_CON;
}
return QUEUE_Put(identity->queueId, &exchange, 0, DONT_WAIT);
}
int32 SAMGR_SendResponse(const Request *request, const Response *response)
{
// we need send the default the con message or not?
if (request == NULL) {
return EC_INVALID;
}
Exchange *exchange = GET_OBJECT(request, Exchange, request);
if (exchange->type == MSG_NON) {
return EC_INVALID;
}
if (exchange->handler == NULL) {
return EC_SUCCESS;
}
exchange->type = MSG_ACK;
exchange->response.data = NULL;
exchange->response.len = 0;
if (response != NULL) {
exchange->response = *response;
}
// If there is no task queue, we will call the response processor in current task.
if (exchange->id.queueId == NULL) {
exchange->handler(&exchange->request, &exchange->response);
return EC_SUCCESS;
}
// Send back to the origin to process the task.
int32 ret = SharedSend(exchange->id.queueId, exchange);
if (ret != EC_SUCCESS) {
exchange->handler(&exchange->request, &exchange->response);
(void)FreeReference(exchange);
}
return EC_SUCCESS;
}
int32 SAMGR_MsgRecv(MQueueId queueId, uint8 *interMsg, uint32 size)
{
if (queueId == NULL || interMsg == NULL || size == 0) {
return EC_INVALID;
}
if (memset_s(interMsg, size, 0x00, size) != EOK) {
return EC_FAILURE;
}
return QUEUE_Pop(queueId, interMsg, 0, WAIT_FOREVER);
}
int32 SAMGR_FreeMsg(Exchange *exchange)
{
if (!FreeReference(exchange)) {
return EC_SUCCESS;
}
if (exchange->request.len > 0) {
SAMGR_Free(exchange->request.data);
exchange->request.data = NULL;
}
if (exchange->response.len > 0) {
SAMGR_Free(exchange->response.data);
exchange->response.data = NULL;
}
return EC_SUCCESS;
}
uint32 *SAMGR_SendSharedRequest(const Identity *identity, const Request *request, uint32 *token, Handler handler)
{
if (identity == NULL || request == NULL) {
return NULL;
}
Exchange exchange = {*identity, *request, {NULL, 0}, MSG_NON, handler, token};
exchange.type = (handler == NULL) ? MSG_NON : MSG_CON;
exchange.id.queueId = NULL;
int32 err = SharedSend(identity->queueId, &exchange);
if (err != EC_SUCCESS) {
HILOG_ERROR(HILOG_MODULE_SAMGR, "SharedSend [%p] failed(%d)!", identity->queueId, err);
(void)FreeReference(&exchange);
}
return exchange.sharedRef;
}
int32 SAMGR_SendSharedDirectRequest(const Identity *id, const Request *req, const Response *resp, uint32 **ref,
Handler handler)
{
if (handler == NULL || ref == NULL) {
return EC_INVALID;
}
Exchange exchange = {0};
if (req != NULL) {
exchange.request = *req;
}
if (resp != NULL) {
exchange.response = *resp;
}
exchange.handler = handler;
exchange.sharedRef = *ref;
exchange.type = MSG_DIRECT;
exchange.id = *id;
exchange.id.queueId = NULL;
int32 err = SharedSend(id->queueId, &exchange);
if (err != EC_SUCCESS) {
HILOG_ERROR(HILOG_MODULE_SAMGR, "SharedSend [%p] failed(%d)!", id->queueId, err);
(void)FreeReference(&exchange);
}
*ref = exchange.sharedRef;
return err;
}
int32 SAMGR_SendResponseByIdentity(const Identity *id, const Request *request, const Response *response)
{
// we need send the default the con message or not?
if (request == NULL || id == NULL) {
return EC_INVALID;
}
Exchange *exchange = GET_OBJECT(request, Exchange, request);
if (exchange->type == MSG_NON) {
return EC_INVALID;
}
exchange->id.queueId = id->queueId;
return SAMGR_SendResponse(request, response);
}
static int32 SharedSend(MQueueId queueId, Exchange *exchange)
{
/* if the msg data and response is NULL, we just direct copy, no need shared the message. */
if ((exchange->request.data == NULL || exchange->request.len <= 0) &&
(exchange->response.data == NULL || exchange->response.len <= 0)) {
return QUEUE_Put(queueId, exchange, 0, DONT_WAIT);
}
/* 1.add reference */
MUTEX_GlobalLock();
if (exchange->sharedRef == NULL) {
exchange->sharedRef = (uint32 *)SAMGR_Malloc(sizeof(uint32));
if (exchange->sharedRef == NULL) {
MUTEX_GlobalUnlock();
return EC_NOMEMORY;
}
*(exchange->sharedRef) = 0;
}
(*(exchange->sharedRef))++;
MUTEX_GlobalUnlock();
return QUEUE_Put(queueId, exchange, 0, DONT_WAIT);
}
static BOOL FreeReference(Exchange *exchange)
{
if (exchange == NULL) {
return FALSE;
}
BOOL needFree = TRUE;
/* 1. check the shared reference */
MUTEX_GlobalLock();
if (exchange->sharedRef != NULL) {
if (*(exchange->sharedRef) > 0) {
(*(exchange->sharedRef))--;
}
if (*(exchange->sharedRef) > 0) {
needFree = FALSE;
}
}
MUTEX_GlobalUnlock();
if (needFree) {
SAMGR_Free(exchange->sharedRef);
exchange->sharedRef = NULL;
}
return needFree;
}

63
samgr/source/message_inner.h Executable file
View File

@ -0,0 +1,63 @@
/*
* Copyright (c) 2020 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef LITE_MESSAGEINNER_H
#define LITE_MESSAGEINNER_H
#include "message.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif
enum ExchangeType {
MSG_EXIT = -1,
MSG_NON = 0,
MSG_CON = 1,
MSG_ACK = 2,
MSG_SYNC = 3,
MSG_DIRECT = 4,
};
// Will be used for message interaction, so use one-byte alignment
#pragma pack(1)
typedef struct Exchange Exchange;
struct Exchange {
Identity id; /**< The target service or feature identity. */
Request request;
Response response;
short type; /**< The exchange type. */
Handler handler; /**< async response or immediately request callback function */
uint32 *sharedRef; /**< use to share the request and response for saving memory */
};
#pragma pack()
int32 SAMGR_MsgRecv(MQueueId queueId, uint8 *interMsg, uint32 size);
/**
* The function just release the Message->data and Message->sharedRef(use free), not release the msg entry.
* If you alloc the msg on the heep, you should release it by yourself, you`d better alloc on the stack.
* The function will be called automatically.
* Do not call this function manually, except the SM_SendRequest return error!
*
**/
int32 SAMGR_FreeMsg(Exchange *exchange);
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif
#endif // LITE_MESSAGEINNER_H

535
samgr/source/samgr_lite.c Executable file
View File

@ -0,0 +1,535 @@
/*
* Copyright (c) 2020 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "samgr_lite_inner.h"
#include <string.h>
#include <securec.h>
#include <ohos_errno.h>
#include <log.h>
#include "memory_adapter.h"
#include "time_adapter.h"
#include "thread_adapter.h"
#include "service_impl.h"
#include "feature_impl.h"
#include "service_registry.h"
#undef LOG_TAG
#undef LOG_DOMAIN
#define LOG_TAG "Samgr"
#define LOG_DOMAIN 0xD001800
/* **************************************************************************************************
* Samgr Lite public interfaces
* ************************************************************************************************* */
static BOOL RegisterService(Service *service);
static Service *UnregisterService(const char *name);
static BOOL RegisterFeature(const char *serviceName, Feature *feature);
static Feature *UnregisterFeature(const char *serviceName, const char *featureName);
static BOOL RegisterFeatureApi(const char *serviceName, const char *feature, IUnknown *publicApi);
static IUnknown *UnregisterFeatureApi(const char *serviceName, const char *feature);
static BOOL RegisterDefaultFeatureApi(const char *serviceName, IUnknown *publicApi);
static IUnknown *UnregisterDefaultFeatureApi(const char *serviceName);
static IUnknown *GetDefaultFeatureApi(const char *serviceName);
static IUnknown *GetFeatureApi(const char *serviceName, const char *feature);
/* **************************************************************************************************
* Samgr Lite location functions
* ************************************************************************************************* */
static void InitializeAllServices(Vector *services);
static void InitializeSingleService(ServiceImpl *service);
static int32 SendBootRequest(int msgId, uint32 msgValue);
static const char *GetServiceName(const ServiceImpl *serviceImpl);
static short GetUninitializedPos(void);
static void AddTaskPool(ServiceImpl *service, TaskConfig *cfg, const char *name);
static int32 InitCompleted(void);
static void HandleInitRequest(const Request *request, const Response *response);
static SamgrLiteImpl *GetImplement(void);
static ServiceImpl *GetService(const char *name);
static TaskPool *GetSpecifiedTaskPool(TaskConfig *config);
static void Init(void);
/* **************************************************************************************************
* Samgr Lite location structure and local variable
* ************************************************************************************************* */
static SamgrLiteImpl g_samgrImpl;
#define TO_NEXT_STATUS(status) (BootStatus)((uint8)(status) | 0x1)
SamgrLite *SAMGR_GetInstance(void)
{
if (g_samgrImpl.mutex == NULL) {
Init();
}
return &(GetImplement()->vtbl);
}
static SamgrLiteImpl *GetImplement(void)
{
return &g_samgrImpl;
}
static void Init(void)
{
WDT_Start(WDG_SAMGR_INIT_TIME);
g_samgrImpl.vtbl.RegisterService = RegisterService;
g_samgrImpl.vtbl.UnregisterService = UnregisterService;
g_samgrImpl.vtbl.RegisterFeature = RegisterFeature;
g_samgrImpl.vtbl.UnregisterFeature = UnregisterFeature;
g_samgrImpl.vtbl.RegisterFeatureApi = RegisterFeatureApi;
g_samgrImpl.vtbl.UnregisterFeatureApi = UnregisterFeatureApi;
g_samgrImpl.vtbl.RegisterDefaultFeatureApi = RegisterDefaultFeatureApi;
g_samgrImpl.vtbl.UnregisterDefaultFeatureApi = UnregisterDefaultFeatureApi;
g_samgrImpl.vtbl.GetDefaultFeatureApi = GetDefaultFeatureApi;
g_samgrImpl.vtbl.GetFeatureApi = GetFeatureApi;
g_samgrImpl.status = BOOT_SYS;
g_samgrImpl.services = VECTOR_Make((VECTOR_Key)GetServiceName, (VECTOR_Compare)strcmp);
g_samgrImpl.mutex = MUTEX_InitValue();
(void)memset_s(g_samgrImpl.sharedPool, sizeof(TaskPool *) * MAX_POOL_NUM, 0,
sizeof(TaskPool *) * MAX_POOL_NUM);
WDT_Reset(WDG_SVC_REG_TIME);
}
void SAMGR_Bootstrap(void)
{
SamgrLiteImpl *samgr = GetImplement();
if (samgr->mutex == NULL) {
HILOG_INFO(HILOG_MODULE_SAMGR, "Samgr is not init, no service!");
return;
}
WDT_Reset(WDG_SVC_BOOT_TIME);
Vector initServices = VECTOR_Make(NULL, NULL);
MUTEX_Lock(samgr->mutex);
samgr->status = TO_NEXT_STATUS(samgr->status);
int16 size = VECTOR_Size(&(samgr->services));
int16 i;
for (i = 0; i < size; ++i) {
ServiceImpl *serviceImpl = (ServiceImpl *)VECTOR_At(&(samgr->services), i);
if (serviceImpl == NULL || serviceImpl->inited != SVC_INIT) {
continue;
}
VECTOR_Add(&initServices, serviceImpl);
}
MUTEX_Unlock(samgr->mutex);
HILOG_INFO(HILOG_MODULE_SAMGR, BOOT_FMT(samgr->status), VECTOR_Size(&initServices));
InitializeAllServices(&initServices);
VECTOR_Clear(&initServices);
int32 err = InitCompleted();
if (err != EC_SUCCESS) {
HILOG_INFO(HILOG_MODULE_SAMGR, "Goto next boot step failed! errno:%d", err);
}
}
ServiceImpl *SAMGR_GetServiceByID(int16 serviceId)
{
SamgrLiteImpl *manager = GetImplement();
MUTEX_Lock(manager->mutex);
int16 size = VECTOR_Size(&(manager->services));
if (serviceId < 0 || serviceId > size) {
MUTEX_Unlock(manager->mutex);
return NULL;
}
ServiceImpl *serviceImpl = (ServiceImpl *)VECTOR_At(&(manager->services), serviceId);
MUTEX_Unlock(manager->mutex);
return serviceImpl;
}
static int32 InitCompleted(void)
{
// Did all services be inited?
SamgrLiteImpl *manager = GetImplement();
int16 pos = GetUninitializedPos();
int16 size = VECTOR_Size(&(manager->services));
if (pos < size) {
return EC_SUCCESS;
}
MUTEX_Lock(manager->mutex);
if (manager->status == BOOT_SYS_WAIT) {
manager->status = BOOT_APP;
MUTEX_Unlock(manager->mutex);
HILOG_INFO(HILOG_MODULE_SAMGR, "Initialized all core system services!");
WDT_Reset(WDG_SVC_REG_TIME);
return SendBootRequest(BOOT_SYS_COMPLETED, pos);
}
if (manager->status == BOOT_APP_WAIT) {
manager->status = BOOT_DYNAMIC;
MUTEX_Unlock(manager->mutex);
HILOG_INFO(HILOG_MODULE_SAMGR, "Initialized all system and application services!");
WDT_Reset(WDG_SVC_TEST_TIME);
return SendBootRequest(BOOT_APP_COMPLETED, pos);
}
MUTEX_Unlock(manager->mutex);
WDT_Stop();
return EC_SUCCESS;
}
static void InitializeAllServices(Vector *services)
{
int16 size = VECTOR_Size(services);
int16 i;
for (i = 0; i < size; ++i) {
ServiceImpl *serviceImpl = (ServiceImpl *)VECTOR_At(services, i);
if (serviceImpl == NULL) {
continue;
}
TaskConfig config = serviceImpl->service->GetTaskConfig(serviceImpl->service);
const char *name = serviceImpl->service->GetName(serviceImpl->service);
AddTaskPool(serviceImpl, &config, name);
HILOG_INFO(HILOG_MODULE_SAMGR, "Init service:%s TaskPool:%p", name, serviceImpl->taskPool);
InitializeSingleService(serviceImpl);
}
SamgrLiteImpl *samgr = GetImplement();
MUTEX_Lock(samgr->mutex);
for (i = 0; i < size; ++i) {
ServiceImpl *serviceImpl = (ServiceImpl *)VECTOR_At(services, i);
if (serviceImpl == NULL) {
continue;
}
const char *name = serviceImpl->service->GetName(serviceImpl->service);
SAMGR_StartTaskPool(serviceImpl->taskPool, name);
}
MUTEX_Unlock(samgr->mutex);
}
static BOOL RegisterService(Service *service)
{
if (IsInvalidService(service)) {
return FALSE;
}
SamgrLiteImpl *samgr = GetImplement();
MUTEX_Lock(samgr->mutex);
int16 pos = VECTOR_FindByKey(&(samgr->services), (void *)service->GetName(service));
if (pos >= 0) {
MUTEX_Unlock(samgr->mutex);
return FALSE;
}
if (VECTOR_Num(&(samgr->services)) >= MAX_SERVICE_NUM) {
MUTEX_Unlock(samgr->mutex);
return FALSE;
}
ServiceImpl *serviceImpl = SAMGR_CreateServiceImpl(service, samgr->status);
if (serviceImpl == NULL) {
MUTEX_Unlock(samgr->mutex);
return FALSE;
}
serviceImpl->serviceId = VECTOR_Add(&(samgr->services), serviceImpl);
MUTEX_Unlock(samgr->mutex);
if (serviceImpl->serviceId == INVALID_INDEX) {
SAMGR_Free(serviceImpl);
return FALSE;
}
return TRUE;
}
static Service *UnregisterService(const char *name)
{
if (name == NULL) {
return NULL;
}
SamgrLiteImpl *samgr = GetImplement();
MUTEX_Lock(samgr->mutex);
Vector *services = &(samgr->services);
int16 pos = VECTOR_FindByKey(services, (void *)name);
ServiceImpl *serviceImpl = (ServiceImpl *)VECTOR_At(services, pos);
if (serviceImpl == NULL || serviceImpl->defaultApi != NULL || VECTOR_Num(&serviceImpl->features) > 0) {
MUTEX_Unlock(samgr->mutex);
return NULL;
}
VECTOR_Swap(services, pos, NULL);
// release task pool must be in the lock to keep atomicity of the reference
SAMGR_ReleaseTaskPool(serviceImpl->taskPool);
MUTEX_Unlock(samgr->mutex);
Service *service = serviceImpl->service;
VECTOR_Clear(&serviceImpl->features);
SAMGR_Free(serviceImpl);
return service;
}
static BOOL RegisterFeature(const char *serviceName, Feature *feature)
{
if (IsInvalidFeature(feature)) {
return FALSE;
}
ServiceImpl *serviceImpl = GetService(serviceName);
if (serviceImpl == NULL || serviceImpl->inited != SVC_INIT) {
return FALSE;
}
if (DEFAULT_GetFeature(serviceImpl, feature->GetName(feature)) != NULL) {
return FALSE;
}
int16 featureId = DEFAULT_AddFeature(serviceImpl, feature);
if (featureId < 0) {
return FALSE;
}
return TRUE;
}
static Feature *UnregisterFeature(const char *serviceName, const char *featureName)
{
ServiceImpl *serviceImpl = GetService(serviceName);
if (serviceImpl == NULL) {
return NULL;
}
return DEFAULT_DeleteFeature(serviceImpl, featureName);
}
static BOOL RegisterFeatureApi(const char *serviceName, const char *feature, IUnknown *publicApi)
{
if (IsInvalidIUnknown(publicApi)) {
return FALSE;
}
ServiceImpl *serviceImpl = GetService(serviceName);
if (serviceImpl == NULL) {
return FALSE;
}
if (feature == NULL) {
if (serviceImpl->defaultApi != NULL) {
return FALSE;
}
serviceImpl->defaultApi = publicApi;
return TRUE;
}
FeatureImpl *featureImpl = DEFAULT_GetFeature(serviceImpl, feature);
if (featureImpl == NULL) {
return FALSE;
}
return SAMGR_AddInterface(featureImpl, publicApi);
}
static IUnknown *UnregisterFeatureApi(const char *serviceName, const char *feature)
{
ServiceImpl *serviceImpl = GetService(serviceName);
if (serviceImpl == NULL) {
return NULL;
}
if (feature == NULL) {
IUnknown *iUnknown = serviceImpl->defaultApi;
serviceImpl->defaultApi = NULL;
return iUnknown;
}
return SAMGR_DelInterface(DEFAULT_GetFeature(serviceImpl, feature));
}
static BOOL RegisterDefaultFeatureApi(const char *serviceName, IUnknown *publicApi)
{
return RegisterFeatureApi(serviceName, NULL, publicApi);
}
static IUnknown *UnregisterDefaultFeatureApi(const char *serviceName)
{
return UnregisterFeatureApi(serviceName, NULL);
}
static IUnknown *GetDefaultFeatureApi(const char *serviceName)
{
return GetFeatureApi(serviceName, NULL);
}
static IUnknown *GetFeatureApi(const char *serviceName, const char *feature)
{
ServiceImpl *serviceImpl = GetService(serviceName);
if (serviceImpl == NULL) {
return SAMGR_FindServiceApi(serviceName, feature);
}
FeatureImpl *featureImpl = DEFAULT_GetFeature(serviceImpl, feature);
if (featureImpl == NULL && feature == NULL) {
return serviceImpl->defaultApi;
}
return SAMGR_GetInterface(featureImpl);
}
static short GetUninitializedPos()
{
SamgrLiteImpl *manager = GetImplement();
MUTEX_Lock(manager->mutex);
int16 size = VECTOR_Size(&(manager->services));
int16 i;
for (i = 0; i < size; ++i) {
ServiceImpl *service = (ServiceImpl *)VECTOR_At(&(manager->services), i);
if (service == NULL) {
continue;
}
if (service->inited == SVC_INIT) {
MUTEX_Unlock(manager->mutex);
return i;
}
}
MUTEX_Unlock(manager->mutex);
return size;
}
static const char *GetServiceName(const ServiceImpl *serviceImpl)
{
if (serviceImpl == NULL) {
return NULL;
}
return serviceImpl->service->GetName(serviceImpl->service);
}
static void AddTaskPool(ServiceImpl *service, TaskConfig *cfg, const char *name)
{
if (service->taskPool != NULL) {
return;
}
if (cfg->priority < PRI_LOW || cfg->priority >= PRI_BUTT) {
HILOG_ERROR(HILOG_MODULE_SAMGR, "The %s service pri(%d) is out of range!", name, cfg->priority);
cfg->priority = PRI_LOW;
}
switch (cfg->taskFlags) {
case SHARED_TASK: {
int pos = (int)cfg->priority / PROPERTY_STEP;
SamgrLiteImpl *samgr = GetImplement();
if (samgr->sharedPool[pos] == NULL) {
TaskConfig shareCfg = DEFAULT_TASK_CFG(pos);
samgr->sharedPool[pos] = SAMGR_CreateFixedTaskPool(&shareCfg, name, DEFAULT_SIZE);
}
service->taskPool = samgr->sharedPool[pos];
if (SAMGR_ReferenceTaskPool(service->taskPool) == NULL) {
HILOG_ERROR(HILOG_MODULE_SAMGR, "shared task:%p pri:%d ref is full", service->taskPool, cfg->priority);
samgr->sharedPool[pos] = NULL;
}
}
break;
case SPECIFIED_TASK:
service->taskPool = GetSpecifiedTaskPool(cfg);
if (service->taskPool != NULL) {
break;
}
// fallthrough
case SINGLE_TASK:
service->taskPool = SAMGR_CreateFixedTaskPool(cfg, name, SINGLE_SIZE);
break;
default:
break;
}
if (service->taskPool == NULL) {
HILOG_ERROR(HILOG_MODULE_SAMGR, "Service<name:%s, flag:%d> create taskPool failed!", name, cfg->taskFlags);
}
}
static ServiceImpl *GetService(const char *name)
{
if (name == NULL) {
return NULL;
}
SamgrLiteImpl *manager = GetImplement();
MUTEX_Lock(manager->mutex);
Vector *services = &(manager->services);
short pos = VECTOR_FindByKey(services, (void *)name);
if (pos < 0) {
MUTEX_Unlock(manager->mutex);
return NULL;
}
ServiceImpl *serviceImpl = (ServiceImpl *)VECTOR_At(services, pos);
MUTEX_Unlock(manager->mutex);
return serviceImpl;
}
static int32 SendBootRequest(int msgId, uint32 msgValue)
{
Identity id = DEFAULT_GetFeatureId(GetService(BOOTSTRAP_SERVICE), NULL);
Request request = {msgId, 0, NULL, msgValue};
return SAMGR_SendRequest(&id, &request, (Handler)SAMGR_Bootstrap);
}
static void HandleInitRequest(const Request *request, const Response *response)
{
ServiceImpl *serviceImpl = (ServiceImpl *)request->data;
if (serviceImpl == NULL) {
HILOG_ERROR(HILOG_MODULE_SAMGR, "Init service Request:<%d,%d>, Response:<%p,%d>!",
request->msgId, request->msgValue, response->data, response->len);
return;
}
uint32 lastTime = serviceImpl->ops.timestamp;
DEFAULT_Initialize(serviceImpl);
serviceImpl->ops.timestamp = SAMGR_GetProcessTime();
serviceImpl->inited = SVC_IDLE;
HILOG_INFO(HILOG_MODULE_SAMGR, "Init service %s <time: %ums> success!",
serviceImpl->service->GetName(serviceImpl->service), serviceImpl->ops.timestamp - lastTime);
int32 err = InitCompleted();
if (err != EC_SUCCESS) {
HILOG_INFO(HILOG_MODULE_SAMGR, "Goto next boot step failed! errno:%d", err);
}
}
static void InitializeSingleService(ServiceImpl *service)
{
// service is guaranteed not to be NULL by the caller; and it's a static function, won't have external call.
if (service->taskPool == NULL) {
DEFAULT_Initialize(service);
return;
}
Identity identity = {service->serviceId, INVALID_INDEX, service->taskPool->queueId};
Request request = {0, 0, service, 0};
uint32 *ref = NULL;
(void)SAMGR_SendSharedDirectRequest(&identity, &request, NULL, &ref, HandleInitRequest);
}
static TaskPool *GetSpecifiedTaskPool(TaskConfig *config)
{
SamgrLiteImpl *samgr = GetImplement();
Vector *services = &(samgr->services);
MUTEX_Lock(samgr->mutex);
int16 serviceNum = VECTOR_Size(services);
int i;
for (i = 0; i < serviceNum; ++i) {
ServiceImpl *impl = VECTOR_At(services, i);
if (impl == NULL) {
continue;
}
TaskConfig cfg = impl->service->GetTaskConfig(impl->service);
if (memcmp(&cfg, config, sizeof(TaskConfig)) != 0) {
continue;
}
if (impl->taskPool == NULL) {
break;
}
TaskPool *taskPool = SAMGR_ReferenceTaskPool(impl->taskPool);
if (taskPool != NULL) {
MUTEX_Unlock(samgr->mutex);
return taskPool;
}
}
MUTEX_Unlock(samgr->mutex);
return NULL;
}

68
samgr/source/samgr_lite_inner.h Executable file
View File

@ -0,0 +1,68 @@
/*
* Copyright (c) 2020 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef LITE_SAMGR_LITE_INNER_H
#define LITE_SAMGR_LITE_INNER_H
#include "samgr_lite.h"
#include "task_manager.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif
#ifndef MAX_SERVICE_NUM
#define MAX_SERVICE_NUM 0x7FF0
#endif
#define DEFAULT_SIZE 1
#define SINGLE_SIZE 1
#define MAX_POOL_NUM 8
#define PROPERTY_STEP 8
#define DEFAULT_TASK_CFG(pos) {LEVEL_HIGH, (int16) ((pos) * PROPERTY_STEP + 1), 0x800, 25, SHARED_TASK}
#define WDG_SAMGR_INIT_TIME 1000
#define WDG_SVC_REG_TIME 5000
#define WDG_SVC_BOOT_TIME 5000
#define WDG_SVC_TEST_TIME 100000
#define BOOT_FMT(status) ((status) == BOOT_SYS_WAIT ? "Bootstrap core services(count:%d)." : \
((status) == BOOT_APP_WAIT ? "Bootstrap system and application services(count:%d)." : \
((status) == BOOT_DYNAMIC_WAIT ? "Bootstrap dynamic registered services(count:%d)." : \
"Bootstrap other services(count:%d).")))
typedef enum {
BOOT_SYS = 0,
BOOT_SYS_WAIT = 1,
BOOT_APP = 2,
BOOT_APP_WAIT = 3,
BOOT_DYNAMIC = 4,
BOOT_DYNAMIC_WAIT = 5,
} BootStatus;
typedef struct SamgrLiteImpl SamgrLiteImpl;
struct SamgrLiteImpl {
SamgrLite vtbl;
MutexId mutex;
BootStatus status;
Vector services;
TaskPool *sharedPool[MAX_POOL_NUM];
};
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif
#endif // LITE_SAMGR_LITE_INNER_H

View File

@ -0,0 +1,98 @@
/*
* Copyright (c) 2020 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "samgr_maintenance.h"
#include <log.h>
#include "service_impl.h"
#include "samgr_lite_inner.h"
#include "time_adapter.h"
void SAMGR_PrintServices(void)
{
SamgrLiteImpl *samgr = GET_OBJECT(SAMGR_GetInstance(), SamgrLiteImpl, vtbl);
int16 num = VECTOR_Num(&samgr->services);
HILOG_INFO(HILOG_MODULE_SAMGR, "[Maintenance]Print Services(%d) Information:", num);
if (num == 0) {
return;
}
MUTEX_Lock(samgr->mutex);
int16 size = VECTOR_Size(&(samgr->services));
int i;
for (i = 0; i < size; ++i) {
ServiceImpl *impl = VECTOR_At(&(samgr->services), i);
if (impl == NULL) {
continue;
}
MUTEX_Unlock(samgr->mutex);
const char *name = impl->service->GetName(impl->service);
HILOG_INFO(HILOG_MODULE_SAMGR, "[Service:%d]<status:%d, name:%s, default:%p, features:%d, task:%p>",
impl->serviceId, impl->inited, name, impl->defaultApi, VECTOR_Num(&impl->features), impl->taskPool);
TaskPool *pool = impl->taskPool;
if (pool != NULL) {
HILOG_INFO(HILOG_MODULE_SAMGR, "[TaskPool:%p]<tid:%p, qid:%p, ref:%d, pri:%d, stack:0x%x>",
pool, pool->tasks[0], pool->queueId, pool->ref, pool->priority, pool->stackSize);
}
int16 featureSize = VECTOR_Size(&impl->features);
int j;
for (j = 0; j < featureSize; ++j) {
FeatureImpl *feature = VECTOR_At(&impl->features, j);
if (feature == NULL) {
continue;
}
name = feature->feature->GetName(feature->feature);
HILOG_INFO(HILOG_MODULE_SAMGR, "[Feature:%d]<name:%s, api:%p>", j, name, feature->iUnknown);
}
MUTEX_Lock(samgr->mutex);
}
MUTEX_Unlock(samgr->mutex);
}
void SAMGR_PrintOperations(void)
{
SamgrLiteImpl *samgr = GET_OBJECT(SAMGR_GetInstance(), SamgrLiteImpl, vtbl);
int16 num = VECTOR_Num(&samgr->services);
HILOG_INFO(HILOG_MODULE_SAMGR, "[Maintenance]Print Services(%d) Statistics:", num);
if (num == 0) {
return;
}
uint32 now = SAMGR_GetProcessTime();
MUTEX_Lock(samgr->mutex);
int16 size = VECTOR_Size(&(samgr->services));
int i;
for (i = 0; i < size; ++i) {
ServiceImpl *impl = VECTOR_At(&(samgr->services), i);
if (impl == NULL) {
continue;
}
MUTEX_Unlock(samgr->mutex);
const char *name = impl->service->GetName(impl->service);
uint8 abnormal = impl->ops.abnormal;
if (impl->inited == SVC_BUSY) {
if (GET_INTERVAL(impl->ops.timestamp, now) > MSG_PROC_THRESHOLD) {
abnormal = abnormal + 1;
}
}
MQueueId queueId = ((impl->taskPool == NULL) ? NULL : impl->taskPool->queueId);
HILOG_INFO(HILOG_MODULE_SAMGR, "[Qid:%p] <status:%d, name:%s, abnormal:%d, total:%d, time:%ums>",
queueId, impl->inited, name, abnormal, impl->ops.messages, impl->ops.timestamp);
MUTEX_Lock(samgr->mutex);
}
MUTEX_Unlock(samgr->mutex);
}

View File

@ -0,0 +1,29 @@
/*
* Copyright (c) 2020 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef LITE_SAMGR_MAINTENANCE_H
#define LITE_SAMGR_MAINTENANCE_H
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif
void SAMGR_PrintServices(void);
void SAMGR_PrintOperations(void);
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif
#endif // LITE_SAMGR_MAINTENANCE_H

195
samgr/source/service.c Executable file
View File

@ -0,0 +1,195 @@
/*
* Copyright (c) 2020 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "service_impl.h"
#include <string.h>
#include "memory_adapter.h"
#include "thread_adapter.h"
#include "time_adapter.h"
#include "feature_impl.h"
#include "service_registry.h"
static const char *GetFeatureName(const FeatureImpl *featureImpl);
ServiceImpl *SAMGR_CreateServiceImpl(Service *service, uint8 step)
{
ServiceImpl *impl = (ServiceImpl *)SAMGR_Malloc(sizeof(ServiceImpl));
if (impl == NULL) {
return NULL;
}
impl->service = service;
impl->defaultApi = NULL;
impl->taskPool = NULL;
impl->features = VECTOR_Make((VECTOR_Key)GetFeatureName, (VECTOR_Compare)strcmp);
impl->serviceId = INVALID_INDEX;
impl->inited = SVC_INIT;
impl->ops.abnormal = 0;
impl->ops.messages = 0;
impl->ops.step = step;
impl->ops.timestamp = (uint32)SAMGR_GetProcessTime();
return impl;
}
int16 DEFAULT_AddFeature(ServiceImpl *serviceImpl, Feature *feature)
{
if (serviceImpl == NULL || feature == NULL) {
return INVALID_INDEX;
}
if (VECTOR_Num(&(serviceImpl->features)) >= MAX_FEATURE_NUM) {
return INVALID_INDEX;
}
FeatureImpl *impl = FEATURE_CreateInstance(feature);
if (impl == NULL) {
return INVALID_INDEX;
}
int16 featureId = VECTOR_Add(&(serviceImpl->features), impl);
if (featureId == INVALID_INDEX) {
SAMGR_Free(impl);
}
return featureId;
}
void DEFAULT_Initialize(ServiceImpl *impl)
{
if (impl == NULL) {
return;
}
Identity id = {impl->serviceId, INVALID_INDEX, (impl->taskPool != NULL) ? impl->taskPool->queueId : NULL};
impl->service->Initialize(impl->service, id);
const char *serviceName = impl->service->GetName(impl->service);
SAMGR_RegisterServiceApi(serviceName, NULL, &id, impl->defaultApi);
int16 size = VECTOR_Size(&impl->features);
int16 i;
for (i = 0; i < size; ++i) {
FeatureImpl *feature = (FeatureImpl *)VECTOR_At(&(impl->features), i);
if (feature == NULL) {
continue;
}
id.featureId = i;
feature->feature->OnInitialize(feature->feature, impl->service, id);
SAMGR_RegisterServiceApi(serviceName, feature->feature->GetName(feature->feature), &id, feature->iUnknown);
}
}
void DEFAULT_MessageHandle(ServiceImpl *serviceImpl, const Identity *identity, Request *msg)
{
if (serviceImpl->serviceId != identity->serviceId) {
return;
}
if (identity->featureId < 0) {
if (serviceImpl->service->MessageHandle != NULL) {
serviceImpl->service->MessageHandle(serviceImpl->service, msg);
}
return;
}
if (VECTOR_Size(&serviceImpl->features) <= identity->featureId) {
return;
}
FeatureImpl *featureImpl = (FeatureImpl *)VECTOR_At(&(serviceImpl->features), identity->featureId);
if (featureImpl == NULL) {
return;
}
featureImpl->feature->OnMessage(featureImpl->feature, msg);
}
void DEFAULT_StopService(ServiceImpl *service)
{
if (service == NULL) {
return;
}
Identity id = {service->serviceId, INVALID_INDEX, (service->taskPool != NULL) ? service->taskPool->queueId : NULL};
int16 size = VECTOR_Size(&service->features);
int16 i;
for (i = 0; i < size; ++i) {
FeatureImpl *featureImpl = (FeatureImpl *)VECTOR_At(&(service->features), i);
if (featureImpl == NULL) {
continue;
}
id.featureId = i;
featureImpl->feature->OnStop(featureImpl->feature, id);
}
service->inited = SVC_INIT;
}
FeatureImpl *DEFAULT_GetFeature(ServiceImpl *serviceImpl, const char *featureName)
{
if (serviceImpl == NULL || featureName == NULL) {
return NULL;
}
short pos = VECTOR_FindByKey(&(serviceImpl->features), (void *)featureName);
return (FeatureImpl *)VECTOR_At(&(serviceImpl->features), pos);
}
Identity DEFAULT_GetFeatureId(ServiceImpl *serviceImpl, const char *feature)
{
Identity identity = {INVALID_INDEX, INVALID_INDEX, NULL};
if (serviceImpl == NULL) {
return identity;
}
identity.serviceId = serviceImpl->serviceId;
if (serviceImpl->taskPool != NULL) {
identity.queueId = serviceImpl->taskPool->queueId;
}
int16 pos = VECTOR_FindByKey(&(serviceImpl->features), (void *)feature);
FeatureImpl *featureImpl = (FeatureImpl *)VECTOR_At(&(serviceImpl->features), pos);
if (featureImpl == NULL) {
return identity;
}
identity.featureId = pos;
return identity;
}
Feature *DEFAULT_DeleteFeature(ServiceImpl *serviceImpl, const char *featureName)
{
if (serviceImpl == NULL || featureName == NULL) {
return NULL;
}
int16 pos = VECTOR_FindByKey(&(serviceImpl->features), (void *)featureName);
if (pos < 0 || !SAMGR_IsNoInterface((FeatureImpl *)VECTOR_At(&serviceImpl->features, pos))) {
return NULL;
}
FeatureImpl *featureImpl = (FeatureImpl *)VECTOR_Swap(&(serviceImpl->features), pos, NULL);
if (featureImpl == NULL) {
return NULL;
}
Identity id = {serviceImpl->serviceId, INVALID_INDEX, NULL};
featureImpl->feature->OnStop(featureImpl->feature, id);
Feature *feature = featureImpl->feature;
SAMGR_Free(featureImpl);
return feature;
}
static const char *GetFeatureName(const FeatureImpl *featureImpl)
{
if (featureImpl == NULL) {
return NULL;
}
return featureImpl->feature->GetName(featureImpl->feature);
}

80
samgr/source/service_impl.h Executable file
View File

@ -0,0 +1,80 @@
/*
* Copyright (c) 2020 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef LITE_SERVICEIMPL_H
#define LITE_SERVICEIMPL_H
#include "common.h"
#include "iunknown.h"
#include "service.h"
#include "feature_impl.h"
#include "task_manager.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif
enum InitStatus {
SVC_INIT = 0,
SVC_IDLE,
SVC_BUSY,
};
#ifndef MAX_FEATURE_NUM
#define MAX_FEATURE_NUM 0x70
#endif
#pragma pack(1)
typedef struct Operations Operations;
struct Operations {
uint8 abnormal;
uint8 step;
uint16 messages;
uint32 timestamp;
};
typedef struct ServiceImpl ServiceImpl;
struct ServiceImpl {
Service *service;
IUnknown *defaultApi;
TaskPool *taskPool;
Vector features;
int16 serviceId;
uint8 inited;
Operations ops;
};
#pragma pack()
inline static BOOL IsInvalidService(Service *service)
{
return (service == NULL || service->GetName == NULL || service->Initialize == NULL ||
service->GetTaskConfig == NULL || service->MessageHandle == NULL);
}
int16 DEFAULT_AddFeature(ServiceImpl *serviceImpl, Feature *feature);
void DEFAULT_Initialize(ServiceImpl *impl);
void DEFAULT_MessageHandle(ServiceImpl *serviceImpl, const Identity *identity, Request *msg);
void DEFAULT_StopService(ServiceImpl *service);
FeatureImpl *DEFAULT_GetFeature(ServiceImpl *serviceImpl, const char *featureName);
Feature *DEFAULT_DeleteFeature(ServiceImpl *serviceImpl, const char *featureName);
Identity DEFAULT_GetFeatureId(ServiceImpl *serviceImpl, const char *feature);
ServiceImpl *SAMGR_CreateServiceImpl(Service *service, uint8 step);
ServiceImpl *SAMGR_GetServiceByID(int16 serviceId);
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif
#endif // LITE_SERVICEIMPL_H

248
samgr/source/task_manager.c Executable file
View File

@ -0,0 +1,248 @@
/*
* Copyright (c) 2020 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "task_manager.h"
#include <securec.h>
#include <log.h>
#include <ohos_errno.h>
#include "memory_adapter.h"
#include "time_adapter.h"
#include "queue_adapter.h"
#include "service_impl.h"
#include "message_inner.h"
#include "samgr_lite_inner.h"
#undef LOG_TAG
#undef LOG_DOMAIN
#define LOG_TAG "Samgr"
#define LOG_DOMAIN 0xD001800
#define DONT_WAIT 0
static void BeginWork(ServiceImpl *service);
static void EndWork(ServiceImpl *service, const Exchange *exchange);
static void *TaskEntry(void *);
static void ProcRequest(Exchange *exchange, ServiceImpl *serviceImpl);
static void ProcDirectRequest(Exchange *exchange);
static void ProcResponse(Exchange *exchange);
static ServiceImpl *CorrectServiceImpl(Exchange *exchange, ServiceImpl *serviceImpl);
TaskPool *SAMGR_CreateFixedTaskPool(const TaskConfig *config, const char *name, uint8 size)
{
if (config == NULL || size == 0 || MAX_TASK_SIZE <= THREAD_Total()) {
return NULL;
}
MQueueId queueId = (MQueueId)QUEUE_Create(name, sizeof(Exchange), config->queueSize);
if (queueId == NULL) {
HILOG_ERROR(HILOG_MODULE_SAMGR, "Create Queue<%s> size:%d failed!", name, config->queueSize);
return NULL;
}
TaskPool *taskPool = (TaskPool *)SAMGR_Malloc(sizeof(TaskPool) + sizeof(ThreadId) * size);
if (taskPool == NULL) {
HILOG_ERROR(HILOG_MODULE_SAMGR, "Create TaskPool<%s> size:%d failed!", name, config->queueSize);
QUEUE_Destroy(queueId);
return NULL;
}
(void)memset_s(taskPool, sizeof(TaskPool) + sizeof(ThreadId) * size, 0,
sizeof(TaskPool) + sizeof(ThreadId) * size);
taskPool->queueId = queueId;
taskPool->stackSize = config->stackSize;
taskPool->priority = (uint8)config->priority;
taskPool->size = size;
taskPool->top = 0;
taskPool->ref = 1;
return taskPool;
}
int32 SAMGR_StartTaskPool(TaskPool *pool, const char *name)
{
if (pool == NULL) {
return EC_INVALID;
}
if (pool->top > 0) {
return EC_SUCCESS;
}
ThreadAttr attr = {name, pool->stackSize, pool->priority, 0, 0};
while (pool->top < pool->size) {
register ThreadId threadId = (ThreadId)THREAD_Create(TaskEntry, pool->queueId, &attr);
if (threadId == NULL) {
HILOG_ERROR(HILOG_MODULE_SAMGR, "Start Task<%s, %d, %d> failed!", name, pool->stackSize, pool->priority);
break;
}
pool->tasks[pool->top] = threadId;
++(pool->top);
}
return EC_SUCCESS;
}
int32 SAMGR_ReleaseTaskPool(TaskPool *pool)
{
if (pool == NULL) {
return EC_INVALID;
}
pool->ref--;
if (pool->ref == 0) {
Exchange exchange = {0};
exchange.type = MSG_EXIT;
QUEUE_Put(pool->queueId, &exchange, 0, DONT_WAIT);
SAMGR_Free(pool);
}
return EC_SUCCESS;
}
TaskPool *SAMGR_ReferenceTaskPool(TaskPool *pool)
{
if (pool == NULL) {
return NULL;
}
if (pool->ref >= MAX_REF_NUM) {
return NULL;
}
pool->ref++;
return pool;
}
static void *TaskEntry(void *argv)
{
ServiceImpl *serviceImpl = NULL;
THREAD_SetThreadLocal(argv);
while (TRUE) {
Exchange exchange;
uint32 msgRcvRet = SAMGR_MsgRecv((MQueueId)argv, (uint8 *)&exchange, sizeof(Exchange));
if (msgRcvRet != EC_SUCCESS) {
continue;
}
if (exchange.type == MSG_EXIT) {
SAMGR_FreeMsg(&exchange);
break;
}
serviceImpl = CorrectServiceImpl(&exchange, serviceImpl);
BeginWork(serviceImpl);
ProcResponse(&exchange);
ProcDirectRequest(&exchange);
ProcRequest(&exchange, serviceImpl);
EndWork(serviceImpl, &exchange);
SAMGR_FreeMsg(&exchange);
}
QUEUE_Destroy((MQueueId)argv);
return NULL;
}
static void ProcRequest(Exchange *exchange, ServiceImpl *serviceImpl)
{
if (serviceImpl == NULL || exchange->type == MSG_ACK || exchange->type == MSG_DIRECT) {
return;
}
DEFAULT_MessageHandle(serviceImpl, &(exchange->id), &(exchange->request));
if (exchange->type == MSG_CON) {
SAMGR_SendResponse(&exchange->request, &exchange->response);
}
}
static void ProcResponse(Exchange *exchange)
{
if (exchange->handler == NULL) {
return;
}
if (exchange->type != MSG_ACK) {
return;
}
exchange->handler(&exchange->request, &exchange->response);
}
static void ProcDirectRequest(Exchange *exchange)
{
if (exchange->handler == NULL) {
return;
}
if (exchange->type != MSG_DIRECT) {
return;
}
exchange->handler(&exchange->request, &exchange->response);
}
static ServiceImpl *CorrectServiceImpl(Exchange *exchange, ServiceImpl *serviceImpl)
{
if (exchange->type == MSG_ACK) {
// The ack message use the last service.
return serviceImpl;
}
if (serviceImpl == NULL || serviceImpl->serviceId != exchange->id.serviceId) {
serviceImpl = SAMGR_GetServiceByID(exchange->id.serviceId);
}
if (serviceImpl == NULL) {
return NULL;
}
return serviceImpl;
}
MQueueId SAMGR_GetCurrentQueueID()
{
return (MQueueId)THREAD_GetThreadLocal();
}
static void BeginWork(ServiceImpl *service)
{
if (service == NULL || service->inited != SVC_IDLE) {
return;
}
if (service->ops.step == BOOT_SYS_WAIT) {
WDT_Start(MSG_PROC_THRESHOLD);
}
service->ops.messages++;
service->ops.timestamp = SAMGR_GetProcessTime();
service->inited = SVC_BUSY;
}
static void EndWork(ServiceImpl *service, const Exchange *exchange)
{
if (service == NULL || service->inited != SVC_BUSY) {
return;
}
if (service->ops.step == BOOT_SYS_WAIT) {
WDT_Stop();
}
uint32 lastTime = service->ops.timestamp;
service->ops.timestamp = (uint32)SAMGR_GetProcessTime();
uint32 interval = GET_INTERVAL(lastTime, service->ops.timestamp);
if (interval > MSG_PROC_THRESHOLD) {
const char *name = service->service->GetName(service->service);
HILOG_INFO(HILOG_MODULE_SAMGR, "Message Timeout <service:%s, feature:%d, type:%d, reqId:%d, time:%ums>",
name, exchange->id.featureId, exchange->type, exchange->request.msgId, interval);
service->ops.abnormal++;
}
service->inited = SVC_IDLE;
}

58
samgr/source/task_manager.h Executable file
View File

@ -0,0 +1,58 @@
/*
* Copyright (c) 2020 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef LITE_TASKMANAGER_H
#define LITE_TASKMANAGER_H
#include <ohos_types.h>
#include "thread_adapter.h"
#include "service.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif
#ifndef MAX_TASK_SIZE
#define MAX_TASK_SIZE 0xFFFFFF
#endif
#define MAX_REF_NUM 15
#define MSG_PROC_THRESHOLD (10 * 1000)
#define GET_REMAIN_TIME(time) ((0xFFFFFFFF - (time)) + 1)
#define GET_INTERVAL(last, now) (((last) > (now)) ? (GET_REMAIN_TIME(last) + (now)) : ((now) - (last)))
typedef struct TaskPool TaskPool;
struct TaskPool {
MQueueId queueId;
uint16 stackSize;
uint8 priority; // task run priority
uint8 size;
uint8 top;
int8 ref;
ThreadId tasks[0];
};
TaskPool *SAMGR_CreateFixedTaskPool(const TaskConfig *config, const char *name, uint8 size);
int32 SAMGR_StartTaskPool(TaskPool *pool, const char *name);
int32 SAMGR_ReleaseTaskPool(TaskPool *pool);
TaskPool *SAMGR_ReferenceTaskPool(TaskPool *pool);
MQueueId SAMGR_GetCurrentQueueID(void);
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif
#endif // LITE_TASKMANAGER_H

40
samgr_client/BUILD.gn Executable file
View File

@ -0,0 +1,40 @@
# Copyright (c) 2020 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
source_set("client") {
sources = [
"source/remote_register.c",
]
cflags = [
"-fPIC",
"-Wall"
]
include_dirs = [
"../samgr_endpoint/source",
"//foundation/distributedschedule/interfaces/kits/samgr_lite/samgr",
"//foundation/distributedschedule/interfaces/kits/samgr_lite/registry",
"//utils/native/lite/include",
"//kernel/liteos_a/kernel/include",
"//kernel/liteos_a/kernel/common",
"//third_party/bounds_checking_function/include",
"//base/security/services/iam_lite/include",
]
public_deps = [
"//foundation/distributedschedule/services/samgr_lite/samgr_endpoint:endpoint_source",
"//third_party/bounds_checking_function:libsec_shared",
"//foundation/communication/frameworks/ipc_lite:liteipc_adapter",
]
}

View File

@ -0,0 +1,206 @@
/*
* Copyright (c) 2020 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "remote_register.h"
#include <ohos_errno.h>
#include <ohos_init.h>
#include <liteipc_adapter.h>
#include <log.h>
#include "policy_define.h"
#include "samgr_lite.h"
#include "memory_adapter.h"
#include "thread_adapter.h"
#include "iproxy_client.h"
#include "default_client.h"
#undef LOG_TAG
#undef LOG_DOMAIN
#define LOG_TAG "Samgr"
#define LOG_DOMAIN 0xD001800
#define RETRY_INTERVAL 2
#define MAX_RETRY_TIMES 10
#define MAX_POLICY_NUM 8
static void InitializeRegistry(void);
static SvcIdentity QueryRemoteIdentity(const char *service, const char *feature);
static int RegisterRemoteIdentity(const char *service, const char *feature, SvcIdentity *saInfo,
PolicyTrans **policy, uint32 *policyNum);
static void GetRemotePolicy(IpcIo *reply, PolicyTrans **policy, uint32 *policyNum);
static RemoteRegister g_remoteRegister;
int __attribute__((weak)) SAMGR_RegisterServiceApi(const char *service, const char *feature,
const Identity *identity, IUnknown *iUnknown)
{
if (service == NULL) {
return EC_INVALID;
}
InitializeRegistry();
MUTEX_Lock(g_remoteRegister.mtx);
SaName saName = {service, feature};
int32 token = SAMGR_AddRouter(g_remoteRegister.endpoint, &saName, identity, iUnknown);
MUTEX_Unlock(g_remoteRegister.mtx);
if (token < 0 || !g_remoteRegister.endpoint->running) {
return token;
}
return SAMGR_ProcPolicy(g_remoteRegister.endpoint, &saName, token);
}
IUnknown *__attribute__((weak)) SAMGR_FindServiceApi(const char *service, const char *feature)
{
InitializeRegistry();
SaName key = {service, feature};
// the proxy already exits.
int index = VECTOR_FindByKey(&g_remoteRegister.clients, &key);
if (index != INVALID_INDEX) {
return VECTOR_At(&g_remoteRegister.clients, index);
}
SvcIdentity identity = QueryRemoteIdentity(service, feature);
if (identity.handle == INVALID_INDEX) {
return NULL;
}
MUTEX_Lock(g_remoteRegister.mtx);
index = VECTOR_FindByKey(&g_remoteRegister.clients, &key);
if (index != INVALID_INDEX) {
MUTEX_Unlock(g_remoteRegister.mtx);
return VECTOR_At(&g_remoteRegister.clients, index);
}
IUnknown *proxy = SAMGR_CreateIProxy(g_remoteRegister.endpoint->context, service, feature, identity);
VECTOR_Add(&g_remoteRegister.clients, proxy);
MUTEX_Unlock(g_remoteRegister.mtx);
HILOG_INFO(HILOG_MODULE_SAMGR, "Create remote sa proxy[%p]<%s, %s> id<%u,%u>!",
proxy, service, feature, identity.handle, identity.token);
return proxy;
}
static SvcIdentity QueryRemoteIdentity(const char *service, const char *feature)
{
IpcIo req;
uint8 data[MIN_DATA_LEN];
IpcIoInit(&req, data, MIN_DATA_LEN, 0);
IpcIoPushUint32(&req, RES_FEATURE);
IpcIoPushUint32(&req, OP_GET);
IpcIoPushString(&req, service);
IpcIoPushBool(&req, feature == NULL);
if (feature != NULL) {
IpcIoPushString(&req, feature);
}
IpcIo reply;
void *replyBuf = NULL;
SvcIdentity samgr = {SAMGR_HANDLE, SAMGR_TOKEN, SAMGR_COOKIE};
int ret = Transact(g_remoteRegister.endpoint->context, samgr, INVALID_INDEX, &req, &reply,
LITEIPC_FLAG_DEFAULT, (uintptr_t *)&replyBuf);
ret = (ret != LITEIPC_OK) ? EC_FAILURE : IpcIoPopInt32(&reply);
SvcIdentity target = {INVALID_INDEX, INVALID_INDEX, INVALID_INDEX};
if (ret == EC_SUCCESS) {
SvcIdentity *svc = IpcIoPopSvc(&reply);
if (svc != NULL) {
target = *svc;
}
}
if (ret == EC_PERMISSION) {
HILOG_INFO(HILOG_MODULE_SAMGR, "Cannot Access<%s, %s> No Permission!", service, feature);
}
if (replyBuf != NULL) {
FreeBuffer(g_remoteRegister.endpoint->context, replyBuf);
}
return target;
}
static int RegisterRemoteIdentity(const char *service, const char *feature, SvcIdentity *saInfo,
PolicyTrans **policy, uint32 *policyNum)
{
IpcIo req;
uint8 data[MIN_DATA_LEN];
IpcIoInit(&req, data, MIN_DATA_LEN, 0);
IpcIoPushUint32(&req, RES_FEATURE);
IpcIoPushUint32(&req, OP_PUT);
IpcIoPushString(&req, service);
IpcIoPushBool(&req, feature == NULL);
if (feature != NULL) {
IpcIoPushString(&req, feature);
}
IpcIoPushUint32(&req, saInfo->token);
IpcIo reply;
void *replyBuf = NULL;
SvcIdentity samgr = {SAMGR_HANDLE, SAMGR_TOKEN, SAMGR_COOKIE};
int ret = Transact(g_remoteRegister.endpoint->context, samgr, INVALID_INDEX, &req, &reply,
LITEIPC_FLAG_DEFAULT, (uintptr_t *)&replyBuf);
ret = -ret;
if (ret == LITEIPC_OK) {
ret = IpcIoPopInt32(&reply);
}
if (ret == EC_SUCCESS) {
saInfo = IpcIoPopSvc(&reply);
GetRemotePolicy(&reply, policy, policyNum);
}
if (replyBuf != NULL) {
FreeBuffer(g_remoteRegister.endpoint->context, replyBuf);
}
return ret;
}
static void GetRemotePolicy(IpcIo *reply, PolicyTrans **policy, uint32 *policyNum)
{
if (reply == NULL) {
return;
}
uint32 i;
uint32 j;
*policyNum = IpcIoPopUint32(reply);
if (*policyNum > MAX_POLICY_NUM) {
*policyNum = MAX_POLICY_NUM;
}
SAMGR_Free(*policy);
if (*policyNum == 0) {
*policy = NULL;
return;
}
*policy = (PolicyTrans *)SAMGR_Malloc(sizeof(PolicyTrans) * (*policyNum));
if (*policy == NULL) {
return;
}
for (i = 0; i < *policyNum; i++) {
(*policy)[i].type = IpcIoPopInt32(reply);
switch ((*policy)[i].type) {
case RANGE:
(*policy)[i].uidMin = IpcIoPopInt32(reply);
(*policy)[i].uidMax = IpcIoPopInt32(reply);
break;
case FIXED:
for (j = 0; j < UID_SIZE; j++) {
(*policy)[i].fixedUid[j] = IpcIoPopInt32(reply);
}
break;
case BUNDLENAME:
(*policy)[i].fixedUid[0] = IpcIoPopInt32(reply);
break;
default:
break;
}
}
}
static void InitializeRegistry(void)
{
if (g_remoteRegister.endpoint != NULL) {
return;
}
HILOG_INFO(HILOG_MODULE_SAMGR, "Initialize Registry!");
SAMGR_RegisterQueryIdentity(QueryRemoteIdentity);
SAMGR_RegisterRegisterIdentity(RegisterRemoteIdentity);
g_remoteRegister.mtx = MUTEX_InitValue();
g_remoteRegister.clients = VECTOR_Make((VECTOR_Key)SAMGR_GetSAName, (VECTOR_Compare)SAMGR_CompareSAName);
g_remoteRegister.endpoint = SAMGR_CreateEndpoint("ipc client", NULL);
}

View File

@ -0,0 +1,38 @@
/*
* Copyright (c) 2020 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef LITE_REMOTE_REGISTER_H
#define LITE_REMOTE_REGISTER_H
#include "common.h"
#include "endpoint.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif
typedef struct RemoteRegister RemoteRegister;
struct RemoteRegister {
MutexId mtx;
Endpoint *endpoint;
Vector clients;
};
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif
#endif // LITE_REMOTE_REGISTER_H

69
samgr_endpoint/BUILD.gn Executable file
View File

@ -0,0 +1,69 @@
# Copyright (c) 2020 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
config("endpoint_public") {
include_dirs = [
"../samgr/adapter",
"//foundation/distributedschedule/interfaces/kits/samgr_lite/samgr",
"//foundation/distributedschedule/interfaces/kits/samgr_lite/registry",
"//utils/native/lite/include",
"//foundation/communication/interfaces/kits/ipc_lite",
"//third_party/bounds_checking_function/include",
"//base/security/services/iam_lite/ipc_auth/include",
"//kernel/liteos_a/kernel/include/",
"//kernel/liteos_a/kernel/common",
]
}
source_set("endpoint_source") {
sources = [
"source/client_factory.c",
"source/default_client.c",
"source/endpoint.c",
"source/token_bucket.c"
]
cflags = [
"-fPIC",
"-Wall"
]
if (ohos_kernel_type == "linux") {
defines = ["LITE_LINUX_BINDER_IPC"]
}
public_configs = [":endpoint_public"]
public_deps = [
"//third_party/bounds_checking_function:libsec_shared",
"//foundation/communication/frameworks/ipc_lite:liteipc_adapter",
"//base/hiviewdfx/frameworks/hilog_lite/featured:hilog_shared",
]
}
source_set("store_source") {
sources = [
"source/sa_store.c",
]
cflags = [
"-fPIC",
"-Wall"
]
public_configs = [":endpoint_public"]
public_deps = [
"//third_party/bounds_checking_function:libsec_shared",
]
}

View File

@ -0,0 +1,118 @@
/*
* Copyright (c) 2020 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "client_factory.h"
#include <ohos_errno.h>
#include "registry.h"
#include "memory_adapter.h"
#include "thread_adapter.h"
#include "default_client.h"
typedef struct Factory Factory;
struct Factory {
SaName key;
Creator creator;
Destroyer destroyer;
};
static Vector g_factories;
static MutexId g_mutex;
static Factory *GetFactory(const char *service, const char *feature);
void *SAMGR_CreateIClient(const char *service, const char *feature, uint32 size)
{
if (service == NULL) {
return NULL;
}
if (g_mutex == NULL) {
return NULL;
}
Factory *factory = GetFactory(service, feature);
if (factory == NULL) {
return NULL;
}
return factory->creator(service, feature, size);
}
int SAMGR_ReleaseIClient(const char *service, const char *feature, void *iClient)
{
if (service == NULL || iClient == NULL) {
return EC_INVALID;
}
if (g_mutex == NULL) {
return EC_NOHANDLER;
}
Factory *factory = GetFactory(service, feature);
if (factory == NULL) {
return EC_NOHANDLER;
}
factory->destroyer(service, feature, iClient);
return EC_SUCCESS;
}
int SAMGR_RegisterFactory(const char *service, const char *feature, Creator creator, Destroyer destroyer)
{
if (service == NULL || creator == NULL || destroyer == NULL) {
return EC_INVALID;
}
if (g_mutex == NULL) {
g_factories = VECTOR_Make(NULL, (VECTOR_Compare)SAMGR_CompareSAName);
g_mutex = MUTEX_InitValue();
if (g_mutex == NULL) {
return EC_NOMEMORY;
}
}
Factory *factory = GetFactory(service, feature);
if (factory != NULL) {
return EC_SUCCESS;
}
MUTEX_Lock(g_mutex);
factory = SAMGR_Malloc(sizeof(Factory));
if (factory == NULL) {
MUTEX_Unlock(g_mutex);
return EC_NOMEMORY;
}
factory->key.service = service;
factory->key.feature = feature;
factory->creator = creator;
factory->destroyer = destroyer;
int ret = VECTOR_Add(&g_factories, factory);
MUTEX_Unlock(g_mutex);
if (ret == INVALID_INDEX) {
SAMGR_Free(factory);
return EC_NOMEMORY;
}
return EC_SUCCESS;
}
static Factory *GetFactory(const char *service, const char *feature)
{
SaName key = {service, feature};
Factory *factory = NULL;
MUTEX_Lock(g_mutex);
int index = VECTOR_FindByKey(&g_factories, &key);
if (index != INVALID_INDEX) {
factory = VECTOR_At(&g_factories, index);
}
MUTEX_Unlock(g_mutex);
return factory;
}

View File

@ -0,0 +1,32 @@
/*
* Copyright (c) 2020 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef LITE_CLIENT_FACTORY_H
#define LITE_CLIENT_FACTORY_H
#include <ohos_types.h>
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif
void *SAMGR_CreateIClient(const char *service, const char *feature, uint32 size);
int SAMGR_ReleaseIClient(const char *service, const char *feature, void *iClient);
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif
#endif // LITE_CLIENT_FACTORY_H

View File

@ -0,0 +1,222 @@
/*
* Copyright (c) 2020 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "default_client.h"
#include <ohos_errno.h>
#include <string.h>
#include <log.h>
#include "client_factory.h"
#include "iproxy_client.h"
#include "memory_adapter.h"
#include "thread_adapter.h"
#undef LOG_TAG
#undef LOG_DOMAIN
#define LOG_TAG "Samgr"
#define LOG_DOMAIN 0xD001800
typedef struct IClientHeader IClientHeader;
typedef struct IDefaultClient IDefaultClient;
typedef struct IClientEntry IClientEntry;
struct IClientHeader {
SaName key;
SvcIdentity target;
uint32 deadId;
const IpcContext *context;
};
struct IClientEntry {
INHERIT_IUNKNOWNENTRY(IClientProxy);
};
#pragma pack(1)
struct IDefaultClient {
IClientHeader header;
IClientEntry entry;
};
#pragma pack()
static int AddRef(IUnknown *iUnknown);
static int Release(IUnknown *proxy);
static int ProxyInvoke(IClientProxy *proxy, int funcId, IpcIo *request, IOwner owner, INotify notify);
static int OnServiceExit(const IpcContext *context, void *ipcMsg, IpcIo *data, void *argv);
static const IClientEntry DEFAULT_ENTRY = {CLIENT_IPROXY_BEGIN, .Invoke = ProxyInvoke, IPROXY_END};
static MutexId g_mutex = NULL;
static QueryIdentity g_queryID = NULL;
IUnknown *SAMGR_CreateIProxy(const IpcContext *context, const char *service, const char *feature, SvcIdentity identity)
{
if (g_queryID == NULL) {
return NULL;
}
IDefaultClient *client = SAMGR_CreateIClient(service, feature, sizeof(IClientHeader));
if (client == NULL) {
client = SAMGR_Malloc(sizeof(IDefaultClient));
if (client == NULL) {
return NULL;
}
client->entry = DEFAULT_ENTRY;
}
IClientHeader *header = &client->header;
header->target = identity;
header->key.service = service;
header->key.feature = feature;
header->context = context;
(void)RegisteDeathCallback(context, identity, OnServiceExit, client, &header->deadId);
IClientEntry *entry = &client->entry;
entry->iUnknown.Invoke = ProxyInvoke;
entry->iUnknown.AddRef = AddRef;
entry->iUnknown.Release = Release;
return GET_IUNKNOWN(*entry);
}
int SAMGR_RegisterQueryIdentity(QueryIdentity query)
{
if (g_mutex == NULL) {
g_mutex = MUTEX_InitValue();
}
if (query == NULL || g_queryID != NULL) {
return EC_INVALID;
}
g_queryID = query;
return EC_SUCCESS;
}
SvcIdentity SAMGR_GetRemoteIdentity(const char *service, const char *feature)
{
if (g_queryID != NULL) {
return g_queryID(service, feature);
}
SvcIdentity identity = {INVALID_INDEX, INVALID_INDEX, INVALID_INDEX};
return identity;
}
SaName *SAMGR_GetSAName(const IUnknown *proxy)
{
IDefaultClient *client = GET_OBJECT(proxy, IDefaultClient, entry.iUnknown);
return &(client->header.key);
}
int SAMGR_CompareSAName(const SaName *key1, const SaName *key2)
{
if (key1 == key2) {
return 0;
}
if (key1->service != key2->service) {
int ret = strcmp(key1->service, key2->service);
if (ret != 0) {
return ret;
}
}
if (key1->feature == key2->feature) {
return 0;
}
if (key1->feature == NULL) {
return -1;
}
if (key2->feature == NULL) {
return 1;
}
return strcmp(key1->feature, key2->feature);
}
static int AddRef(IUnknown *iUnknown)
{
MUTEX_Lock(g_mutex);
int ref = IUNKNOWN_AddRef(iUnknown);
MUTEX_Unlock(g_mutex);
return ref;
}
static int Release(IUnknown *proxy)
{
MUTEX_Lock(g_mutex);
int ref = IUNKNOWN_Release(proxy);
MUTEX_Unlock(g_mutex);
if (ref != 0) {
return ref;
}
IDefaultClient *client = GET_OBJECT(proxy, IDefaultClient, entry.iUnknown);
int ret = SAMGR_ReleaseIClient(client->header.key.service, client->header.key.feature, client);
if (ret == EC_NOHANDLER) {
SAMGR_Free(client);
return EC_SUCCESS;
}
return ret;
}
static int ProxyInvoke(IClientProxy *proxy, int funcId, IpcIo *request, IOwner owner, INotify notify)
{
if (proxy == NULL) {
return EC_INVALID;
}
IDefaultClient *client = GET_OBJECT(proxy, IDefaultClient, entry.iUnknown);
IClientHeader *header = &client->header;
if (header->target.handle == INVALID_INDEX) {
header->target = g_queryID(header->key.service, header->key.feature);
if (header->target.handle == INVALID_INDEX) {
return EC_INVALID;
}
(void)RegisteDeathCallback(header->context, header->target, OnServiceExit, header, &header->deadId);
}
IpcIo reply;
void *replyBuf = NULL;
IpcFlag flag = (notify == NULL) ? LITEIPC_FLAG_ONEWAY : LITEIPC_FLAG_DEFAULT;
int ret = Transact(header->context, header->target, funcId, request, &reply, flag, (uintptr_t *)&replyBuf);
if (ret != LITEIPC_OK) {
(void)UnRegisteDeathCallback(header->target, header->deadId);
header->deadId = INVALID_INDEX;
header->target.handle = INVALID_INDEX;
header->target.token = INVALID_INDEX;
header->target.cookie = INVALID_INDEX;
return EC_FAILURE;
}
if (notify != NULL) {
notify(owner, ret, &reply);
}
if (replyBuf != NULL) {
FreeBuffer(header->context, replyBuf);
}
return ret;
}
static int OnServiceExit(const IpcContext *context, void *ipcMsg, IpcIo *data, void *argv)
{
(void)data;
IClientHeader *header = (IClientHeader *)argv;
(void)UnRegisteDeathCallback(header->target, header->deadId);
header->deadId = INVALID_INDEX;
header->target.handle = INVALID_INDEX;
header->target.token = INVALID_INDEX;
header->target.cookie = INVALID_INDEX;
if (ipcMsg != NULL) {
FreeBuffer(header->context, ipcMsg);
}
HILOG_ERROR(HILOG_MODULE_SAMGR, "Miss the remote service<%u, %u>!", header->target.handle, header->target.token);
return EC_SUCCESS;
}

View File

@ -0,0 +1,41 @@
/*
* Copyright (c) 2020 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef LITE_DEFAULT_CLIENT_H
#define LITE_DEFAULT_CLIENT_H
#include <liteipc_adapter.h>
#include "iunknown.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif
typedef struct SaName SaName;
struct SaName {
const char *service;
const char *feature;
};
typedef SvcIdentity (*QueryIdentity)(const char *service, const char *feature);
int SAMGR_RegisterQueryIdentity(QueryIdentity query);
IUnknown *SAMGR_CreateIProxy(const IpcContext *context, const char *service, const char *feature, SvcIdentity identity);
SaName *SAMGR_GetSAName(const IUnknown *proxy);
int SAMGR_CompareSAName(const SaName *key1, const SaName *key2);
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif
#endif // LITE_DEFAULT_CLIENT_H

475
samgr_endpoint/source/endpoint.c Executable file
View File

@ -0,0 +1,475 @@
/*
* Copyright (c) 2020 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "endpoint.h"
#include <stdlib.h>
#include <securec.h>
#include <ohos_errno.h>
#include <service.h>
#include <log.h>
#include "iproxy_server.h"
#include "memory_adapter.h"
#include "thread_adapter.h"
#include "default_client.h"
#undef LOG_TAG
#undef LOG_DOMAIN
#define LOG_TAG "Samgr"
#define LOG_DOMAIN 0xD001800
#define MAX_STACK_SIZE 0x1000
#define MAX_OBJECT_NUM 5
#define MAX_RETRY_TIMES 3
#define RETRY_INTERVAL 5
#define MAX_REGISTER_RETRY_TIMES 10
#define REGISTER_RETRY_INTERVAL 2
#ifndef MAX_BUCKET_RATE
#define MAX_BUCKET_RATE 1000
#endif
#ifndef MAX_BURST_RATE
#define MAX_BURST_RATE (MAX_BUCKET_RATE + (MAX_BUCKET_RATE >> 1))
#endif
#define SAMGR_SERVICE "samgr"
typedef struct Router {
SaName saName;
Identity identity;
IServerProxy *proxy;
PolicyTrans *policy;
uint32 policyNum;
} Router;
static int CompareIServerProxy(const IServerProxy *proxy1, const IServerProxy *proxy2);
static IServerProxy *GetIServerProxy(const Router *router);
static void *Receive(void *argv);
static int Dispatch(const IpcContext *context, void *ipcMsg, IpcIo *data, void *argv);
static void HandleIpc(const Request *request, const Response *response);
static int OnSamgrServerExit(const IpcContext *context, void *ipcMsg, IpcIo *data, void *argv);
static int RegisterRemoteFeatures(Endpoint *endpoint);
static void Listen(Endpoint *endpoint);
static boolean JudgePolicy(uid_t callingUid, const PolicyTrans *policy, uint32 policyNum);
static boolean SearchFixedPolicy(uid_t callingUid, PolicyTrans policy);
static int AddPolicyToRouter(const Endpoint *endpoint, const SvcIdentity *saInfo,
const PolicyTrans *policy, uint32 policyNum);
static int RegisterRemoteEndpoint(const IpcContext *context, SvcIdentity *identity);
static RegisterIdentity g_registerID = NULL;
int SAMGR_RegisterRegisterIdentity(RegisterIdentity action)
{
if (action == NULL || g_registerID != NULL) {
return EC_INVALID;
}
g_registerID = action;
return EC_SUCCESS;
}
Endpoint *SAMGR_CreateEndpoint(const char *name, RegisterEndpoint registry)
{
Endpoint *endpoint = SAMGR_Malloc(sizeof(Endpoint));
if (endpoint == NULL) {
return NULL;
}
endpoint->deadId = INVALID_INDEX;
endpoint->context = OpenLiteIpc(LITEIPC_DEFAULT_MAP_SIZE);
endpoint->boss = NULL;
endpoint->routers = VECTOR_Make((VECTOR_Key)GetIServerProxy, (VECTOR_Compare)CompareIServerProxy);
endpoint->name = name;
endpoint->running = FALSE;
endpoint->identity.handle = (uint32_t)INVALID_INDEX;
endpoint->identity.token = (uint32_t)INVALID_INDEX;
endpoint->identity.cookie = (uint32_t)INVALID_INDEX;
endpoint->registerEP = (registry == NULL) ? RegisterRemoteEndpoint : registry;
TB_InitBucket(&endpoint->bucket, MAX_BUCKET_RATE, MAX_BURST_RATE);
return endpoint;
}
int SAMGR_AddRouter(Endpoint *endpoint, const SaName *saName, const Identity *id, IUnknown *proxy)
{
if (endpoint == NULL || id == NULL || proxy == NULL || saName == NULL) {
return EC_INVALID;
}
IServerProxy *serverProxy = NULL;
proxy->QueryInterface(proxy, SERVER_PROXY_VER, (void *)&serverProxy);
if (serverProxy == NULL) {
return EC_INVALID;
}
// Lock the multi-write
int index = VECTOR_FindByKey(&endpoint->routers, proxy);
if (index != INVALID_INDEX) {
serverProxy->Release((IUnknown *)serverProxy);
return index;
}
Router *router = SAMGR_Malloc(sizeof(Router));
if (router == NULL) {
HILOG_ERROR(HILOG_MODULE_SAMGR, "Memory is not enough! Identity<%d, %d, %p>",
id->serviceId, id->featureId, id->queueId);
return EC_NOMEMORY;
}
router->saName = *saName;
router->identity = *id;
router->proxy = serverProxy;
router->policy = NULL;
router->policyNum = 0;
index = VECTOR_Add(&endpoint->routers, router);
if (index == INVALID_INDEX) {
SAMGR_Free(router);
return EC_FAILURE;
}
Listen(endpoint);
return index;
}
int SAMGR_ProcPolicy(const Endpoint *endpoint, const SaName *saName, int token)
{
if (endpoint == NULL || saName == NULL || token == INVALID_INDEX) {
return EC_INVALID;
}
// retry until success or 20 seconds.
int ret = EC_INVALID;
uint8 retry = 0;
SvcIdentity saInfo = {INVALID_INDEX, token, INVALID_INDEX};
while (retry < MAX_REGISTER_RETRY_TIMES) {
++retry;
PolicyTrans *policy = NULL;
uint32 policyNum = 0;
ret = g_registerID(saName->service, saName->feature, &saInfo, &policy, &policyNum);
if (ret != EC_SUCCESS || policy == NULL) {
SAMGR_Free(policy);
continue;
}
HILOG_INFO(HILOG_MODULE_SAMGR, "Register server sa<%s, %s> id<%u, %u> retry:%d ret:%d!",
saName->service, saName->feature, saInfo.handle, saInfo.token, retry, ret);
ret = AddPolicyToRouter(endpoint, &saInfo, policy, policyNum);
if (ret == EC_SUCCESS) {
SAMGR_Free(policy);
break;
}
SAMGR_Free(policy);
sleep(REGISTER_RETRY_INTERVAL);
}
return ret;
}
static void Listen(Endpoint *endpoint)
{
if (endpoint->boss != NULL) {
return;
}
ThreadAttr attr = {endpoint->name, MAX_STACK_SIZE, PRI_ABOVE_NORMAL, 0, 0};
endpoint->boss = (ThreadId)THREAD_Create(Receive, endpoint, &attr);
}
static int AddPolicyToRouter(const Endpoint *endpoint, const SvcIdentity *saInfo,
const PolicyTrans *policy, uint32 policyNum)
{
if (endpoint == NULL || saInfo == NULL || policy == NULL) {
return EC_INVALID;
}
Router *router = VECTOR_At((Vector *)&endpoint->routers, saInfo->token);
if (router == NULL) {
HILOG_ERROR(HILOG_MODULE_SAMGR, "Router <%s, %u> is NULL", endpoint->name, saInfo->token);
return EC_INVALID;
}
if (router->policy != NULL) {
return EC_SUCCESS;
}
router->policyNum = policyNum;
if (policyNum == 0) {
return EC_INVALID;
}
router->policy = (PolicyTrans *)SAMGR_Malloc(sizeof(PolicyTrans) * policyNum);
if (router->policy == NULL) {
return EC_NOMEMORY;
}
if (memcpy_s(router->policy, sizeof(PolicyTrans) * policyNum, policy, sizeof(PolicyTrans) * policyNum) != EOK) {
SAMGR_Free(router->policy);
router->policy = NULL;
HILOG_ERROR(HILOG_MODULE_SAMGR, "Add Policy <%s, %s, %s> Failed!",
endpoint->name, router->saName.service, router->saName.feature);
return EC_FAILURE;
}
HILOG_DEBUG(HILOG_MODULE_SAMGR, "Add Policy <%s, %s, %s> Success",
endpoint->name, router->saName.service, router->saName.feature);
return EC_SUCCESS;
}
static void *Receive(void *argv)
{
Endpoint *endpoint = (Endpoint *)argv;
if (endpoint == NULL || endpoint->registerEP == NULL) {
return NULL;
}
int ret = EC_INVALID;
uint8 retry = 0;
while (retry < MAX_RETRY_TIMES) {
ret = endpoint->registerEP(endpoint->context, &endpoint->identity);
if (ret == EC_SUCCESS) {
SvcIdentity samgr = {SAMGR_HANDLE, SAMGR_TOKEN, SAMGR_COOKIE};
(void)UnRegisteDeathCallback(samgr, endpoint->deadId);
(void)RegisteDeathCallback(endpoint->context, samgr, OnSamgrServerExit, endpoint, &endpoint->deadId);
break;
}
++retry;
sleep(RETRY_INTERVAL);
}
if (ret != EC_SUCCESS) {
HILOG_FATAL(HILOG_MODULE_SAMGR, "Register endpoint<%s>, handle<%u> failed! will exit to recover!",
endpoint->name, endpoint->identity.handle);
exit(-ret);
}
endpoint->running = TRUE;
if (endpoint->identity.handle != SAMGR_HANDLE) {
int remain = RegisterRemoteFeatures(endpoint);
HILOG_INFO(HILOG_MODULE_SAMGR, "Register endpoint<%s> and iunknown finished! remain<%d> iunknown!",
endpoint->name, remain);
}
StartLoop(endpoint->context, Dispatch, endpoint);
return NULL;
}
static int Dispatch(const IpcContext *context, void *ipcMsg, IpcIo *data, void *argv)
{
if (argv == NULL || ipcMsg == NULL) {
return EC_INVALID;
}
Endpoint *endpoint = (Endpoint *)argv;
uint32_t token = (uint32_t)INVALID_INDEX;
GetToken(ipcMsg, &token);
if (TB_CheckMessage(&endpoint->bucket) == BUCKET_BUSY) {
HILOG_WARN(HILOG_MODULE_SAMGR, "Flow Control <%u> is NULL", token);
goto ERROR;
}
Router *router = VECTOR_At(&endpoint->routers, token);
if (router == NULL) {
HILOG_ERROR(HILOG_MODULE_SAMGR, "Router <%s, %u> is NULL", endpoint->name, token);
goto ERROR;
}
Response resp = {0};
resp.data = endpoint;
Request request = {0};
request.msgId = token;
request.data = ipcMsg;
request.msgValue = INVALID_INDEX;
GetCode(ipcMsg, &request.msgValue);
#ifdef LITE_LINUX_BINDER_IPC
HandleIpc(&request, &resp);
#else
uint32 *ref = NULL;
int ret = SAMGR_SendSharedDirectRequest(&router->identity, &request, &resp, &ref, HandleIpc);
if (ret != EC_SUCCESS) {
HILOG_ERROR(HILOG_MODULE_SAMGR, "Router[%u] Service<%d, %d, %p> is busy",
token, router->identity.serviceId, router->identity.featureId, router->identity.queueId);
goto ERROR;
}
#endif
return EC_SUCCESS;
ERROR:
if (ipcMsg != NULL) {
FreeBuffer(endpoint->context, ipcMsg);
}
return EC_INVALID;
}
static void HandleIpc(const Request *request, const Response *response)
{
void *ipcMsg = (void *)request->data;
Endpoint *endpoint = (Endpoint *)response->data;
Router *router = VECTOR_At(&endpoint->routers, request->msgId);
if (ipcMsg == NULL) {
return;
}
if (router == NULL || router->proxy == NULL || router->proxy->Invoke == NULL) {
FreeBuffer(endpoint->context, ipcMsg);
HILOG_ERROR(HILOG_MODULE_SAMGR, "Invalid IPC router<%p>!", router);
return;
}
uid_t uid = GetCallingUid(ipcMsg);
if ((strcmp(router->saName.service, SAMGR_SERVICE) != 0) &&
!JudgePolicy(uid, (const PolicyTrans *)(router->policy), router->policyNum)) {
FreeBuffer(endpoint->context, ipcMsg);
HILOG_ERROR(HILOG_MODULE_SAMGR, "Consumer uid<%d> has no permission to access<%s, %d, %d>!",
uid, router->saName.service, router->identity.serviceId, router->identity.featureId);
return;
}
IpcIo req;
IpcIoInitFromMsg(&req, ipcMsg);
IpcIo reply;
uint8 data[MAX_DATA_LEN];
IpcIoInit(&reply, data, MAX_DATA_LEN, MAX_OBJECT_NUM);
router->proxy->Invoke(router->proxy, request->msgValue, ipcMsg, &req, &reply);
uint32_t flag = 0;
GetFlag(ipcMsg, &flag);
if (flag == LITEIPC_FLAG_DEFAULT) {
SendReply(endpoint->context, ipcMsg, &reply);
} else {
FreeBuffer(endpoint->context, ipcMsg);
}
}
static int CompareIServerProxy(const IServerProxy *proxy1, const IServerProxy *proxy2)
{
if (proxy1 == proxy2) {
return 0;
}
return (proxy1 > proxy2) ? 1 : -1;
}
static IServerProxy *GetIServerProxy(const Router *router)
{
if (router == NULL) {
return NULL;
}
return router->proxy;
}
static int RegisterRemoteFeatures(Endpoint *endpoint)
{
int nums = 0;
if (g_registerID == NULL) {
return nums;
}
int size = VECTOR_Size(&endpoint->routers);
int i;
SvcIdentity identity;
for (i = 0; i < size; ++i) {
Router *router = VECTOR_At(&endpoint->routers, i);
if (router == NULL) {
continue;
}
identity.handle = endpoint->identity.handle;
identity.token = i;
int ret = g_registerID(router->saName.service, router->saName.feature, &identity,
&(router->policy), &(router->policyNum));
if (ret == EC_SUCCESS) {
++nums;
}
HILOG_DEBUG(HILOG_MODULE_SAMGR, "RegisterRemoteFeatures<%s, %s> ret:%d",
router->saName.service, router->saName.feature, ret);
}
return VECTOR_Num(&endpoint->routers) - nums;
}
static int RegisterRemoteEndpoint(const IpcContext *context, SvcIdentity *identity)
{
IpcIo req;
uint8 data[MAX_DATA_LEN];
IpcIoInit(&req, data, MAX_DATA_LEN, 0);
IpcIoPushUint32(&req, RES_ENDPOINT);
IpcIoPushUint32(&req, OP_POST);
IpcIoPushUint32(&req, identity->handle);
uint8 retry = 0;
while (retry < MAX_RETRY_TIMES) {
++retry;
IpcIo reply;
void *replyBuf = NULL;
SvcIdentity samgr = {SAMGR_HANDLE, SAMGR_TOKEN, SAMGR_COOKIE};
int err = Transact(context, samgr, INVALID_INDEX, &req, &reply, LITEIPC_FLAG_DEFAULT, (uintptr_t *)&replyBuf);
if (err == LITEIPC_OK) {
identity->handle = IpcIoPopUint32(&reply);
if (replyBuf != NULL) {
FreeBuffer(context, replyBuf);
}
if (identity->handle == (uint32)INVALID_INDEX) {
continue;
}
return EC_SUCCESS;
}
sleep(RETRY_INTERVAL);
}
return EC_FAILURE;
}
static int OnSamgrServerExit(const IpcContext *context, void *ipcMsg, IpcIo *data, void *argv)
{
(void)data;
HILOG_ERROR(HILOG_MODULE_SAMGR, "Disconnect to samgr server!");
Endpoint *endpoint = (Endpoint *)argv;
if (endpoint == NULL || endpoint->registerEP == NULL) {
return EC_FAILURE;
}
if (ipcMsg != NULL) {
FreeBuffer(endpoint->context, ipcMsg);
}
int size = VECTOR_Size(&endpoint->routers);
int i;
for (i = 0; i < size; i++) {
Router *router = VECTOR_At(&endpoint->routers, i);
if (router == NULL) {
continue;
}
SAMGR_Free(router->policy);
router->policy = NULL;
router->policyNum = 0;
}
while (endpoint->registerEP(endpoint->context, &endpoint->identity) != EC_SUCCESS) {
HILOG_ERROR(HILOG_MODULE_SAMGR, "Reconnect to samgr server failed!");
sleep(RETRY_INTERVAL);
}
SvcIdentity identity;
identity.handle = SAMGR_HANDLE;
identity.token = SAMGR_TOKEN;
identity.cookie = SAMGR_COOKIE;
(void)UnRegisteDeathCallback(identity, endpoint->deadId);
(void)RegisteDeathCallback(endpoint->context, identity, OnSamgrServerExit, endpoint, &endpoint->deadId);
int remain = RegisterRemoteFeatures(endpoint);
HILOG_INFO(HILOG_MODULE_SAMGR, "Reconnect and register finished! remain<%d> iunknown!", remain);
return EC_SUCCESS;
}
static boolean JudgePolicy(uid_t callingUid, const PolicyTrans *policy, uint32 policyNum)
{
if (policy == NULL) {
HILOG_ERROR(HILOG_MODULE_SAMGR, "Policy is NULL! Num is %u", policyNum);
return FALSE;
}
uint32 i;
for (i = 0; i < policyNum; i++) {
if (policy[i].type == RANGE && callingUid >= policy[i].uidMin && callingUid <= policy[i].uidMax) {
return TRUE;
}
if (policy[i].type == FIXED && SearchFixedPolicy(callingUid, policy[i])) {
return TRUE;
}
}
return FALSE;
}
static boolean SearchFixedPolicy(uid_t callingUid, PolicyTrans policy)
{
int i;
for (i = 0; i < UID_SIZE; i++) {
if (callingUid == policy.fixedUid[i]) {
return TRUE;
}
}
return FALSE;
}

View File

@ -0,0 +1,75 @@
/*
* Copyright (c) 2020 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef LITE_ENDPOINT_H
#define LITE_ENDPOINT_H
#include <stddef.h>
#include "policy_define.h"
#include "common.h"
#include "iproxy_server.h"
#include "default_client.h"
#include "token_bucket.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif
#define SAMGR_HANDLE 0
#define SAMGR_TOKEN 0
#define SAMGR_COOKIE 0
#define MAX_DATA_LEN 0x100
#define MIN_DATA_LEN 0x40
typedef enum ResourceID {
RES_ENDPOINT,
RES_FEATURE,
RES_BUTT,
} ResourceID;
typedef enum OptionID {
OP_GET,
OP_POST,
OP_PUT,
OP_DELETE,
} OptionID;
typedef struct Endpoint Endpoint;
typedef int (*RegisterIdentity)(const char *service, const char *feature, SvcIdentity *identity,
PolicyTrans **policy, uint32 *policyNum);
typedef int (*RegisterEndpoint)(const IpcContext *context, SvcIdentity *identity);
struct Endpoint {
const char *name;
IpcContext *context;
Vector routers;
ThreadId boss;
uint32 deadId;
int running;
SvcIdentity identity;
RegisterEndpoint registerEP;
TokenBucket bucket;
};
int SAMGR_RegisterRegisterIdentity(RegisterIdentity action);
Endpoint *SAMGR_CreateEndpoint(const char *name, RegisterEndpoint registry);
int SAMGR_AddRouter(Endpoint *endpoint, const SaName *saName, const Identity *id, IUnknown *proxy);
int SAMGR_ProcPolicy(const Endpoint *endpoint, const SaName *saName, int token);
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif
#endif // LITE_ENDPOINT_H

251
samgr_endpoint/source/sa_store.c Executable file
View File

@ -0,0 +1,251 @@
/*
* Copyright (c) 2020 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "sa_store.h"
#include <ohos_errno.h>
#include <securec.h>
#include "common.h"
#include "memory_adapter.h"
#define GROW_STEP 4
#define MAX_SA_NUM 300
static void FreeTreeNode(SAStore *saStore, ListNode *node);
static void SASTORA_ClearServiceByHandle(SAStore *saStore, uint32 handle);
static inline ListNode *FindServiceByName(ListNode *curNode, const char *service)
{
while (curNode != NULL) {
if (strncmp(curNode->info.name, service, MAX_NAME_LEN) == 0) {
break;
}
curNode = curNode->next;
}
return curNode;
}
static inline FeatureNode *FindFeatureByName(FeatureNode *curNode, const char *feature)
{
while (curNode != NULL) {
if ((feature == NULL && curNode->isDefault) ||
(feature != NULL && strncmp(curNode->name, feature, MAX_NAME_LEN) == 0)) {
break;
}
curNode = curNode->next;
}
return curNode;
}
int SASTORA_Save(SAStore *saStore, const char *service, const char *feature, const SvcIdentity *identity)
{
if (saStore == NULL || service == NULL || identity == NULL) {
return EC_INVALID;
}
ListNode *curNode = FindServiceByName(saStore->root, service);
FeatureNode *fNode = (curNode == NULL) ? NULL : curNode->info.head;
fNode = FindFeatureByName(fNode, feature);
if (fNode != NULL) {
return EC_SUCCESS;
}
if (saStore->saSize >= MAX_SA_NUM) {
return EC_NOSPACE;
}
fNode = SAMGR_Malloc(sizeof(FeatureNode));
if (fNode == NULL) {
return EC_NOMEMORY;
}
fNode->token = identity->token;
fNode->isDefault = feature == NULL;
fNode->name[0] = 0;
if (feature != NULL) {
if (strcpy_s(fNode->name, MAX_NAME_LEN, feature) != EOK) {
SAMGR_Free(fNode);
return EC_INVALID;
}
}
if (curNode == NULL) {
curNode = SAMGR_Malloc(sizeof(ListNode));
if (curNode == NULL) {
SAMGR_Free(fNode);
return EC_NOMEMORY;
}
if (strcpy_s(curNode->info.name, MAX_NAME_LEN, service) != EOK) {
SAMGR_Free(fNode);
SAMGR_Free(curNode);
return EC_INVALID;
}
curNode->info.handle = identity->handle;
curNode->info.head = NULL;
curNode->next = saStore->root;
saStore->root = curNode;
}
fNode->next = curNode->info.head;
curNode->info.head = fNode;
saStore->saSize++;
return EC_SUCCESS;
}
int SASTORA_SaveHandleByPid(SAStore *saStore, PidHandle handle)
{
PidHandle saved = {.handle = INVALID_INDEX};
int index = SASTORA_FindHandleByPid(saStore, handle.pid, &saved);
if (saved.handle == handle.handle) {
return EC_SUCCESS;
}
if (index != INVALID_INDEX) {
saStore->maps[index] = handle;
return EC_SUCCESS;
}
if (saStore->mapSize <= saStore->mapTop) {
PidHandle *newMap = (PidHandle *)SAMGR_Malloc(sizeof(PidHandle) * (saStore->mapSize + GROW_STEP));
if (newMap == NULL) {
return EC_NOMEMORY;
}
if (saStore->maps != NULL) {
(void)memcpy_s(newMap, sizeof(PidHandle) * (saStore->mapSize + GROW_STEP),
saStore->maps, sizeof(PidHandle) * saStore->mapSize);
}
PidHandle *oldMap = saStore->maps;
saStore->maps = newMap;
saStore->mapSize += GROW_STEP;
SAMGR_Free(oldMap);
}
int i;
for (i = saStore->mapTop - 1; i >= 0; --i) {
if (saStore->maps[i].pid < handle.pid) {
break;
}
saStore->maps[i + 1] = saStore->maps[i];
}
saStore->maps[i + 1] = handle;
++(saStore->mapTop);
return EC_SUCCESS;
}
int SASTORA_FindHandleByPid(SAStore *saStore, pid_t callingPid, PidHandle *handle)
{
if (saStore == NULL || saStore->maps == NULL || handle == NULL) {
return INVALID_INDEX;
}
int16 high = saStore->mapTop - 1;
int16 low = 0;
while (low <= high) {
// binary search need div 2
int16 mid = (high + low) / 2;
if (saStore->maps[mid].pid == callingPid) {
*handle = saStore->maps[mid];
return mid;
}
if (saStore->maps[mid].pid < callingPid) {
low = mid + 1;
continue;
}
high = mid - 1;
}
return INVALID_INDEX;
}
PidHandle SASTORA_FindPidHandleByIpcHandle(const SAStore *saStore, uint32 handle)
{
PidHandle pidHandle = {INVALID_INDEX, INVALID_INDEX, INVALID_INDEX, INVALID_INDEX};
if (saStore == NULL || saStore->maps == NULL) {
return pidHandle;
}
int i;
for (i = 0; i < saStore->mapTop; i++) {
if (saStore->maps[i].handle == handle) {
return saStore->maps[i];
}
}
return pidHandle;
}
SvcIdentity SASTORA_Find(SAStore *saStore, const char *service, const char *feature)
{
SvcIdentity identity = {(uint32)INVALID_INDEX, (uint32)INVALID_INDEX, (uint32)INVALID_INDEX};
ListNode *curNode = FindServiceByName(saStore->root, service);
if (curNode == NULL) {
return identity;
}
identity.handle = curNode->info.handle;
FeatureNode *featureNode = FindFeatureByName(curNode->info.head, feature);
if (featureNode != NULL) {
identity.token = featureNode->token;
}
return identity;
}
int SASTORA_ClearByPid(SAStore *saStore, pid_t pid)
{
PidHandle pidHandle;
int index = SASTORA_FindHandleByPid(saStore, pid, &pidHandle);
if (index == INVALID_INDEX) {
return EC_INVALID;
}
SASTORA_ClearServiceByHandle(saStore, pidHandle.handle);
if (saStore->mapTop <= (index + 1)) {
saStore->mapTop--;
return EC_SUCCESS;
}
errno_t err = memmove_s(&saStore->maps[index], sizeof(PidHandle) * (saStore->mapTop - index),
&saStore->maps[index + 1], sizeof(PidHandle) * (saStore->mapTop - index - 1));
if (err != EOK) {
return EC_FAILURE;
}
saStore->mapTop--;
return EC_SUCCESS;
}
static void SASTORA_ClearServiceByHandle(SAStore *saStore, uint32 handle)
{
ListNode *node = saStore->root;
ListNode *prev = NULL;
while (node != NULL) {
if (node->info.handle == handle) {
ListNode *freeNode = node;
if (prev != NULL) {
prev->next = node->next;
node = node->next;
} else {
saStore->root = node->next;
node = node->next;
}
FreeTreeNode(saStore, freeNode);
continue;
}
prev = node;
node = node->next;
}
}
static void FreeTreeNode(SAStore *saStore, ListNode *node)
{
while (node->info.head != NULL) {
FeatureNode *freeNode = node->info.head;
node->info.head = node->info.head->next;
SAMGR_Free(freeNode);
saStore->saSize--;
}
SAMGR_Free(node);
}

View File

@ -0,0 +1,87 @@
/*
* Copyright (c) 2020 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef LITE_SA_STORE_H
#define LITE_SA_STORE_H
#include <ohos_types.h>
#include <liteipc_adapter.h>
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif
#define MAX_NAME_LEN 16
typedef struct ServiceInfo ServiceInfo;
typedef struct FeatureNode FeatureNode;
typedef struct SAStore SAStore;
typedef struct ListNode ListNode;
typedef struct PidHandle PidHandle;
struct ServiceInfo {
char name[MAX_NAME_LEN];
uint32 handle;
FeatureNode *head;
};
struct FeatureNode {
char name[MAX_NAME_LEN];
uint32 isDefault;
uint32 token;
FeatureNode *next;
};
struct SAStore {
int saSize;
ListNode *root;
int16 mapSize;
int16 mapTop;
PidHandle *maps;
};
struct ListNode {
ListNode *next;
ServiceInfo info;
};
struct PidHandle {
pid_t pid;
uid_t uid;
uint32 handle;
uint32 deadId;
};
static inline void SASTORA_Init(SAStore *saStore)
{
saStore->saSize = 0;
saStore->root = NULL;
saStore->mapTop = 0;
saStore->mapSize = 0;
saStore->maps = NULL;
}
int SASTORA_Save(SAStore *saStore, const char *service, const char *feature, const SvcIdentity *identity);
int SASTORA_SaveHandleByPid(SAStore *saStore, PidHandle handle);
int SASTORA_FindHandleByPid(SAStore *saStore, pid_t callingPid, PidHandle *handle);
SvcIdentity SASTORA_Find(SAStore *saStore, const char *service, const char *feature);
int SASTORA_ClearByPid(SAStore *saStore, pid_t pid);
PidHandle SASTORA_FindPidHandleByIpcHandle(const SAStore *saStore, uint32 handle);
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif
#endif // LITE_SA_STORE_H

View File

@ -0,0 +1,34 @@
/*
* Copyright (c) 2020 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "token_bucket.h"
#include <ohos_types.h>
#include <common.h>
#include "time_adapter.h"
int TB_CheckMessage(TokenBucket *bucket)
{
if (bucket == NULL) {
return BUCKET_INVALID;
}
uint64 now = SAMGR_GetProcessTime();
uint64 generated = (now > bucket->last) ? ((now - bucket->last) * bucket->rate) : 0;
int used = bucket->used + TOKEN_PRE_MSG;
used = (generated > used) ? 0 : (used - (int)generated);
if (used >= bucket->burst * TOKEN_PRE_MSG) {
return BUCKET_BUSY;
}
bucket->used = used;
bucket->last = now;
return BUCKET_IDLE;
}

View File

@ -0,0 +1,52 @@
/*
* Copyright (c) 2020 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef LITE_TOKEN_BUCKET_H
#define LITE_TOKEN_BUCKET_H
#include <ohos_types.h>
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif
#define TOKEN_PRE_MSG 1000
typedef struct TokenBucket TokenBucket;
struct TokenBucket {
int rate; // The rate of token generation per millisecond. Now, we use the TPS instead.
int burst; // The burst size of the token bucket
uint64 last; // The time of the last message
int used; // The used buckets. When the rate is TPS, the value is used * TOKEN_PRE_MSG.
};
typedef enum BucketStatus {
BUCKET_BUSY,
BUCKET_IDLE,
BUCKET_INVALID,
} BucketStatus;
inline static void TB_InitBucket(TokenBucket *bucket, int rate, int burst)
{
bucket->last = 0;
bucket->rate = rate;
bucket->burst = burst;
bucket->used = 0;
}
int TB_CheckMessage(TokenBucket *bucket);
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif
#endif // LITE_TOKEN_BUCKET_H

42
samgr_server/BUILD.gn Executable file
View File

@ -0,0 +1,42 @@
# Copyright (c) 2020 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
shared_library("server") {
sources = [
"source/samgr_server.c",
]
cflags = [
"-fPIC",
"-Wall"
]
include_dirs = [
"../samgr_endpoint/source",
"//foundation/distributedschedule/interfaces/kits/samgr_lite/samgr",
"//foundation/distributedschedule/interfaces/kits/samgr_lite/registry",
"//utils/native/lite/include",
"//kernel/liteos_a/kernel/include/",
"//kernel/liteos_a/kernel/common",
"//third_party/bounds_checking_function/include",
"//base/security/interfaces/innerkits/iam_lite",
"//base/security/services/iam_lite/pms_base/include",
]
public_deps = [
"//third_party/bounds_checking_function:libsec_shared",
"//foundation/distributedschedule/services/samgr_lite/samgr:samgr",
"//foundation/distributedschedule/services/samgr_lite/samgr_endpoint:store_source",
"//foundation/communication/frameworks/ipc_lite:liteipc_adapter",
]
}

View File

@ -0,0 +1,475 @@
/*
* Copyright (c) 2020 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "samgr_server.h"
#include <stdlib.h>
#include <ohos_init.h>
#include <ohos_types.h>
#include <ohos_errno.h>
#include <liteipc_adapter.h>
#include <log.h>
#include "policy_define.h"
#include "samgr_lite.h"
#include "memory_adapter.h"
#include "thread_adapter.h"
#include "default_client.h"
#undef LOG_TAG
#undef LOG_DOMAIN
#define LOG_TAG "Samgr"
#define LOG_DOMAIN 0xD001800
typedef int(*ProcFunc)(SamgrServer *server, int32 option, void *origin, IpcIo *req, IpcIo *reply);
#define MAX_SA_SIZE 0x100
#define RETRY_TIMES 3
#define RETRY_INTERVAL 1
static const char *GetName(Service *service);
static BOOL Initialize(Service *service, Identity identity);
static TaskConfig GetTaskConfig(Service *service);
static BOOL MessageHandle(Service *service, Request *request);
static int32 Invoke(IServerProxy *iProxy, int funcId, void *origin, IpcIo *req, IpcIo *reply);
static int OnEndpointExit(const IpcContext *context, void* ipcMsg, IpcIo* data, void* argv);
static int ProcEndpoint(SamgrServer *server, int32 option, void *origin, IpcIo *req, IpcIo *reply);
static int32 ProcPutFeature(SamgrServer *server, const void *origin, IpcIo *req, IpcIo *reply, SvcIdentity *identity);
static int32 ProcGetFeature(SamgrServer *server, const void *origin, IpcIo *req, IpcIo *reply, SvcIdentity *identity);
static int ProcFeature(SamgrServer *server, int32 option, void *origin, IpcIo *req, IpcIo *reply);
static SvcIdentity QueryLocalIdentity(const char *service, const char *feature);
static int RegisterLocalIdentity(const char *service, const char *feature, SvcIdentity *identity,
PolicyTrans **policy, uint32 *policyNum);
static int RegisterSamgrEndpoint(const IpcContext* context, SvcIdentity* identity);
static void TransmitPolicy(int ret, const SvcIdentity* identity, IpcIo *reply,
const PolicyTrans *policy, uint32 policyNum);
static void TransmitFixedPolicy(IpcIo *reply, PolicyTrans policy);
static IpcAuthInterface *GetIpcAuthInterface(void);
static SamgrServer g_server = {
.GetName = GetName,
.Initialize = Initialize,
.GetTaskConfig = GetTaskConfig,
.MessageHandle = MessageHandle,
SERVER_IPROXY_IMPL_BEGIN,
.Invoke = Invoke,
IPROXY_END,
};
static ProcFunc g_functions[] = {
[RES_ENDPOINT] = ProcEndpoint,
[RES_FEATURE] = ProcFeature,
};
static void InitializeRegistry(void)
{
HILOG_INFO(HILOG_MODULE_SAMGR, "Initialize Registry!");
SAMGR_RegisterQueryIdentity(QueryLocalIdentity);
SAMGR_RegisterRegisterIdentity(RegisterLocalIdentity);
g_server.mtx = MUTEX_InitValue();
g_server.clients = VECTOR_Make((VECTOR_Key)SAMGR_GetSAName, (VECTOR_Compare)SAMGR_CompareSAName);
SASTORA_Init(&g_server.store);
g_server.samgr = SAMGR_CreateEndpoint("samgr", RegisterSamgrEndpoint);
g_server.endpoint = SAMGR_CreateEndpoint("ipc receive", NULL);
SAMGR_GetInstance()->RegisterService((Service *)&g_server);
}
SYS_SERVICE_INIT(InitializeRegistry);
int SAMGR_RegisterServiceApi(const char *service, const char *feature, const Identity *identity, IUnknown *iUnknown)
{
if (service == NULL) {
return EC_INVALID;
}
MUTEX_Lock(g_server.mtx);
SaName saName = {service, feature};
int32 token = SAMGR_AddRouter(g_server.endpoint, &saName, identity, iUnknown);
MUTEX_Unlock(g_server.mtx);
if (token < 0 || !g_server.endpoint->running) {
return token;
}
return SAMGR_ProcPolicy(g_server.endpoint, &saName, token);
}
IUnknown *SAMGR_FindServiceApi(const char *service, const char *feature)
{
SaName key = {service, feature};
// the proxy already exits.
int index = VECTOR_FindByKey(&g_server.clients, &key);
if (index != INVALID_INDEX) {
return VECTOR_At(&g_server.clients, index);
}
SvcIdentity identity = QueryLocalIdentity(service, feature);
if (identity.handle == INVALID_INDEX) {
return NULL;
}
MUTEX_Lock(g_server.mtx);
index = VECTOR_FindByKey(&g_server.clients, &key);
if (index != INVALID_INDEX) {
MUTEX_Unlock(g_server.mtx);
return VECTOR_At(&g_server.clients, index);
}
IUnknown* client = SAMGR_CreateIProxy(g_server.endpoint->context, service, feature, identity);
(void)VECTOR_Add(&g_server.clients, client);
MUTEX_Unlock(g_server.mtx);
HILOG_INFO(HILOG_MODULE_SAMGR, "Create proxy[%p]<%s, %s, %u, %u>",
client, service, feature, identity.handle, identity.token);
return client;
}
static const char *GetName(Service *service)
{
(void)service;
return SAMGR_SERVICE;
}
static BOOL Initialize(Service *service, Identity identity)
{
SamgrServer *server = (SamgrServer *)service;
server->identity = identity;
SaName saName = {SAMGR_SERVICE, NULL};
SAMGR_AddRouter(server->samgr, &saName, &server->identity, GET_IUNKNOWN(*server));
return TRUE;
}
static BOOL MessageHandle(Service *service, Request *request)
{
SamgrServer *server = (SamgrServer *)service;
switch (request->msgId) {
case MSG_CLEAN:
MUTEX_Lock(server->mtx);
SASTORA_ClearByPid(&server->store, request->msgValue);
MUTEX_Unlock(server->mtx);
break;
default:
break;
}
return TRUE;
}
static TaskConfig GetTaskConfig(Service *service)
{
(void)service;
TaskConfig config = {LEVEL_HIGH, PRI_NORMAL, 0x400, 20, SINGLE_TASK};
return config;
}
static int32 Invoke(IServerProxy *iProxy, int funcId, void *origin, IpcIo *req, IpcIo *reply)
{
SamgrServer *server = GET_OBJECT(iProxy, SamgrServer, iUnknown);
int32 resource = IpcIoPopUint32(req);
int32 option = IpcIoPopUint32(req);
if (resource >= RES_BUTT || resource < 0 || g_functions[resource] == NULL) {
HILOG_ERROR(HILOG_MODULE_SAMGR, "Invalid Msg<%d, %d, %d>", resource, option, funcId);
return EC_INVALID;
}
return g_functions[resource](server, option, origin, req, reply);
}
static int ProcEndpoint(SamgrServer *server, int32 option, void *origin, IpcIo *req, IpcIo *reply)
{
if (option != OP_POST) {
IpcIoPushUint32(reply, (uint32)INVALID_INDEX);
return EC_FAILURE;
}
pid_t pid = GetCallingPid(origin);
PidHandle handle;
MUTEX_Lock(server->mtx);
int index = SASTORA_FindHandleByPid(&g_server.store, pid, &handle);
if (index == INVALID_INDEX) {
SvcIdentity identity = {(uint32)INVALID_INDEX, (uint32)INVALID_INDEX, (uint32)INVALID_INDEX};
identity.handle = IpcIoPopUint32(req);
if (identity.handle == (uint32)INVALID_INDEX) { // generate handle
(void)GenServiceHandle(&identity, GetCallingTid(origin));
}
handle.pid = pid;
handle.uid = GetCallingUid(origin);
handle.handle = identity.handle;
handle.deadId = INVALID_INDEX;
(void)SASTORA_SaveHandleByPid(&server->store, handle);
(void)UnRegisteDeathCallback(identity, handle.deadId);
(void)RegisteDeathCallback(server->endpoint->context, identity, OnEndpointExit, (void*)((uintptr_t)pid),
&handle.deadId);
}
MUTEX_Unlock(server->mtx);
IpcIoPushUint32(reply, handle.handle);
HILOG_INFO(HILOG_MODULE_SAMGR, "Register Endpoint<%d, %d, %d>", handle.pid, handle.handle, handle.deadId);
return EC_SUCCESS;
}
static int32 ProcPutFeature(SamgrServer *server, const void *origin, IpcIo *req, IpcIo *reply, SvcIdentity *identity)
{
size_t len = 0;
char *service = (char *)IpcIoPopString(req, &len);
if (service == NULL || len == 0) {
IpcIoPushInt32(reply, EC_INVALID);
return EC_INVALID;
}
pid_t pid = GetCallingPid(origin);
char *feature = IpcIoPopBool(req) ? NULL : (char *)IpcIoPopString(req, &len);
MUTEX_Lock(server->mtx);
PidHandle handle;
int index = SASTORA_FindHandleByPid(&server->store, pid, &handle);
if (index == INVALID_INDEX) {
MUTEX_Unlock(server->mtx);
HILOG_ERROR(HILOG_MODULE_SAMGR, "Endpoint[%d] is not register", pid);
IpcIoPushInt32(reply, EC_NOSERVICE);
return EC_NOSERVICE;
}
*identity = SASTORA_Find(&server->store, service, feature);
if (identity->handle != INVALID_INDEX && identity->handle != handle.handle) {
MUTEX_Unlock(server->mtx);
IpcIoPushInt32(reply, EC_INVALID);
return EC_INVALID;
}
identity->token = IpcIoPopUint32(req);
identity->handle = handle.handle;
PolicyTrans *policy = NULL;
RegParams regParams = {service, feature, handle.uid, handle.pid};
uint32 policyNum = 0;
int ret = g_server.ipcAuth->GetCommunicationStrategy(regParams, &policy, &policyNum);
if (ret != EC_SUCCESS || policy == NULL) {
MUTEX_Unlock(g_server.mtx);
SAMGR_Free(policy);
HILOG_DEBUG(HILOG_MODULE_SAMGR, "Remote Get Communication Strategy<%s, %s> No Permission<%d>!",
service, feature, ret);
IpcIoPushInt32(reply, EC_PERMISSION);
return EC_PERMISSION;
}
ret = SASTORA_Save(&server->store, service, feature, identity);
MUTEX_Unlock(server->mtx);
HILOG_DEBUG(HILOG_MODULE_SAMGR, "Register Feature<%s, %s> pid<%d>, id<%d, %d> ret:%d",
service, feature, pid, identity->handle, identity->token, ret);
TransmitPolicy(ret, identity, reply, policy, policyNum);
SAMGR_Free(policy);
return ret;
}
static void TransmitPolicy(int ret, const SvcIdentity* identity, IpcIo *reply,
const PolicyTrans *policy, uint32 policyNum)
{
if (identity == NULL || reply == NULL || policy == NULL) {
IpcIoPushInt32(reply, EC_INVALID);
return;
}
if (ret != EC_SUCCESS) {
IpcIoPushInt32(reply, ret);
return;
}
IpcIoPushInt32(reply, ret);
IpcIoPushSvc(reply, identity);
IpcIoPushUint32(reply, policyNum);
uint32 i;
for (i = 0; i < policyNum; i++) {
IpcIoPushInt32(reply, policy[i].type);
switch (policy[i].type) {
case RANGE:
IpcIoPushInt32(reply, policy[i].uidMin);
IpcIoPushInt32(reply, policy[i].uidMax);
break;
case FIXED:
TransmitFixedPolicy(reply, policy[i]);
break;
case BUNDLENAME:
IpcIoPushInt32(reply, policy[i].fixedUid[0]);
break;
default:
break;
}
}
}
static void TransmitFixedPolicy(IpcIo *reply, PolicyTrans policy)
{
if (reply == NULL) {
return;
}
uint32 i;
for (i = 0; i < UID_SIZE; i++) {
IpcIoPushInt32(reply, policy.fixedUid[i]);
}
}
static int32 ProcGetFeature(SamgrServer *server, const void *origin, IpcIo *req, IpcIo *reply, SvcIdentity *identity)
{
size_t len = 0;
char *service = (char *)IpcIoPopString(req, &len);
if (service == NULL || len == 0) {
IpcIoPushInt32(reply, EC_INVALID);
return EC_INVALID;
}
char *feature = IpcIoPopBool(req) ? NULL : (char *)IpcIoPopString(req, &len);
MUTEX_Lock(server->mtx);
*identity = SASTORA_Find(&server->store, service, feature);
if (identity->handle == INVALID_INDEX) {
MUTEX_Unlock(server->mtx);
HILOG_DEBUG(HILOG_MODULE_SAMGR, "Cannot Find Feature<%s, %s> id<%d, %d> ret:%d",
service, feature, identity->handle, identity->token, EC_NOSERVICE);
return EC_NOSERVICE;
}
PidHandle providerPid = SASTORA_FindPidHandleByIpcHandle(&server->store, identity->handle);
MUTEX_Unlock(server->mtx);
if (providerPid.pid == INVALID_INDEX || providerPid.uid == INVALID_INDEX) {
HILOG_DEBUG(HILOG_MODULE_SAMGR, "Cannot Find PidHandle<%s, %s> id<%d, %d> ret:%d",
service, feature, identity->handle, identity->token, EC_FAILURE);
return EC_FAILURE;
}
AuthParams authParams = {
.providerService = service,
.providerfeature = feature,
.consumerPid = GetCallingPid(origin),
.consumerUid = GetCallingUid(origin),
.providerPid = providerPid.pid,
.providerUid = providerPid.uid
};
int isAuth = g_server.ipcAuth->IsCommunicationAllowed(authParams);
HILOG_DEBUG(HILOG_MODULE_SAMGR, "Judge Auth<%s, %s> ret:%d", service, feature, isAuth);
int32 ret = (isAuth == EC_SUCCESS) ? AddServiceAccess(*identity, GetCallingTid(origin)) : EC_PERMISSION;
HILOG_DEBUG(HILOG_MODULE_SAMGR, "Find Feature<%s, %s> id<%d, %d> ret:%d",
service, feature, identity->handle, identity->token, ret);
return ret;
}
static int ProcFeature(SamgrServer *server, int32 option, void *origin, IpcIo *req, IpcIo *reply)
{
if (option != OP_PUT && option != OP_GET) {
IpcIoPushInt32(reply, EC_INVALID);
return EC_INVALID;
}
if (g_server.ipcAuth == NULL) {
g_server.ipcAuth = GetIpcAuthInterface();
}
if (g_server.ipcAuth == NULL) {
IpcIoPushInt32(reply, EC_NOINIT);
return EC_NOINIT;
}
int ret = EC_SUCCESS;
SvcIdentity identity = {INVALID_INDEX, INVALID_INDEX, INVALID_INDEX};
if (option == OP_PUT) {
ret = ProcPutFeature(server, origin, req, reply, &identity);
}
if (ret != EC_SUCCESS) {
return ret;
}
if (option == OP_GET) {
ret = ProcGetFeature(server, origin, req, reply, &identity);
IpcIoPushInt32(reply, ret);
IpcIoPushSvc(reply, &identity);
}
return ret;
}
static SvcIdentity QueryLocalIdentity(const char *service, const char *feature)
{
MUTEX_Lock(g_server.mtx);
SvcIdentity saInfo = SASTORA_Find(&g_server.store, service, feature);
MUTEX_Unlock(g_server.mtx);
return saInfo;
}
static int RegisterLocalIdentity(const char *service, const char *feature, SvcIdentity *identity,
PolicyTrans **policy, uint32 *policyNum)
{
pid_t selfPid = getpid();
MUTEX_Lock(g_server.mtx);
PidHandle pidHandle = {INVALID_INDEX, INVALID_INDEX, INVALID_INDEX, INVALID_INDEX};
int ret = SASTORA_FindHandleByPid(&g_server.store, selfPid, &pidHandle);
if (ret != INVALID_INDEX) {
identity->handle = pidHandle.handle;
ret = SASTORA_Save(&g_server.store, service, feature, identity);
} else {
ret = EC_NODEVICE;
}
HILOG_DEBUG(HILOG_MODULE_SAMGR, "RegisterIdentity <%s, %s> pid<%d> <%u, %u> ",
service, feature, selfPid, identity->handle, identity->token);
if (ret != EC_SUCCESS) {
MUTEX_Unlock(g_server.mtx);
HILOG_DEBUG(HILOG_MODULE_SAMGR, "SaStore Save FAILED(%d), <%s, %s> <%u, %u> ",
ret, service, feature, identity->handle, identity->token);
return ret;
}
MUTEX_Unlock(g_server.mtx);
RegParams regParams = {
.service = (char *)service,
.feature = (char *)feature,
.uid = getuid(),
.pid = selfPid
};
if (g_server.ipcAuth == NULL) {
g_server.ipcAuth = GetIpcAuthInterface();
}
if (g_server.ipcAuth == NULL) {
HILOG_DEBUG(HILOG_MODULE_SAMGR, "g_server.ipcAuth is NULL");
return EC_FAILURE;
}
ret = g_server.ipcAuth->GetCommunicationStrategy(regParams, policy, policyNum);
return ret;
}
static int RegisterSamgrEndpoint(const IpcContext* context, SvcIdentity* identity)
{
int ret = SetSaManager(context, MAX_SA_SIZE);
if (ret != LITEIPC_OK) {
HILOG_FATAL(HILOG_MODULE_SAMGR, "Set sa manager<%d> failed!", ret);
// Set sa manager failed! We need restart to recover
exit(-ret);
}
identity->handle = SAMGR_HANDLE;
identity->token = SAMGR_TOKEN;
identity->cookie = SAMGR_COOKIE;
return EC_SUCCESS;
}
static int OnEndpointExit(const IpcContext *context, void* ipcMsg, IpcIo* data, void* argv)
{
(void)data;
if (ipcMsg != NULL) {
FreeBuffer(g_server.endpoint->context, ipcMsg);
}
pid_t pid = (pid_t)((uintptr_t)argv);
Request request = {0};
request.msgId = MSG_CLEAN;
request.msgValue = pid;
int retry = RETRY_TIMES;
int ret = EC_INVALID;
while (retry > 0) {
ret = SAMGR_SendRequest(&g_server.identity, &request, NULL);
if (ret == EC_SUCCESS) {
break;
}
sleep(RETRY_INTERVAL);
--retry;
}
HILOG_ERROR(HILOG_MODULE_SAMGR, "IPC pid<%d> exit! send clean request retry(%d), ret(%d)!", pid, retry, ret);
return EC_SUCCESS;
}
static IpcAuthInterface *GetIpcAuthInterface(void)
{
IpcAuthInterface *ipcAuth = NULL;
IUnknown *iUnknown = SAMGR_GetInstance()->GetFeatureApi(PERMISSION_SERVICE, IPCAUTH);
if (iUnknown == NULL) {
HILOG_ERROR(HILOG_MODULE_SAMGR, "Get IpcAuthInterface: IUnknown NULL");
return NULL;
}
(void)iUnknown->QueryInterface(iUnknown, DEFAULT_VERSION, (void **)&ipcAuth);
return ipcAuth;
}

View File

@ -0,0 +1,56 @@
/*
* Copyright (c) 2020 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef LITE_IPC_MANAGER_H
#define LITE_IPC_MANAGER_H
#include <ipc_auth_interface.h>
#include "service.h"
#include "iproxy_server.h"
#include "endpoint.h"
#include "sa_store.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif
#define SAMGR_SERVICE "samgr"
typedef struct SamgrServer SamgrServer;
typedef struct SamgrProxy SamgrProxy;
typedef enum MsgId {
MSG_CLEAN,
}MsgId;
struct SamgrProxy {
INHERIT_SERVER_IPROXY;
};
struct SamgrServer {
INHERIT_SERVICE;
INHERIT_IPROXY_ENTRY(SamgrProxy);
Identity identity;
Endpoint *samgr;
Endpoint *endpoint;
Vector clients;
MutexId mtx;
SAStore store;
IpcAuthInterface *ipcAuth;
};
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif
#endif // LITE_IPC_MANAGER_H