update openharmony 1.0.1

This commit is contained in:
mamingshuai 2021-03-11 18:43:06 +08:00
parent 60297fdbc7
commit b37b00220d
49 changed files with 4665 additions and 569 deletions

View File

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

View File

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

View File

@ -27,6 +27,11 @@ lite_component("samgr") {
}
}
copy("ConfigFiles") {
sources = [ "config/system_capability.json" ]
outputs = [ "$target_out_dir/config/system_capability.json" ]
}
ndk_lib("samgr_lite_ndk") {
if (ohos_kernel_type == "liteos_m") {
lib_extension = ".a"
@ -38,18 +43,21 @@ ndk_lib("samgr_lite_ndk") {
"samgr",
]
head_files = [
"//foundation/distributedschedule/interfaces/kits/samgr_lite/samgr",
"//foundation/distributedschedule/interfaces/kits/samgr_lite/communication/broadcast",
"//foundation/distributedschedule/samgr_lite/interfaces/kits/samgr",
"//foundation/distributedschedule/samgr_lite/interfaces/kits/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",
"//foundation/distributedschedule/samgr_lite/interfaces/kits/registry",
]
}
}
generate_notice_file("samgr_notice_file") {
module_name = "samgr"
module_source_dir_list = [ "//third_party/bounds_checking_function" ]
module_source_dir_list = [
"//third_party/bounds_checking_function",
"//third_party/cJSON",
]
}

633
README.md Executable file
View File

@ -0,0 +1,633 @@
# samgr\_lite<a name="EN-US_TOPIC_0000001081604584"></a>
- [Introduction](#section11660541593)
- [Directory Structure](#section1464106163817)
- [Constraints](#section1718733212019)
- [Developing a Service](#section159991817144514)
- [Developing a Feature of a Service](#section11510542164514)
- [Developing an External API for Intra-Process Communication](#section1685211117463)
- [Invoking a Service in the Same Process](#section3690162916462)
- [Developing an External API for IPC](#section9220246194615)
- [Invoking a Service in Another Process](#section114372711475)
- [Developing a Client Proxy for Inter-Process Service Invocation](#section09341923114710)
- [Repositories Involved](#section10365113863719)
## Introduction<a name="section11660541593"></a>
Due to limited platform resources, a unified system ability \(SA\) framework is provided to harmonize differences of hardware architectures \(for example, RISC-V, Cortex-M, and Cortex-A\), resources, and running modes. Two types of hardware platforms \(M- and A-core\) are defined.
- M-core: hardware platforms with Cortex-M or equivalent processing capabilities. The system memory is generally less than 512 KB. There is only a lightweight file system that can be used in limited scenarios, or no file system at all. M-core platforms comply with the Cortex Microcontroller Software Interface Standard \(CMSIS\).
- A-core: hardware platforms with Cortex-A or equivalent processing capabilities. The system memory is greater than 512 KB. There is a comprehensive file system for storing a large amount of data. A-core platforms comply with the Portable Operating System Interface \(POSIX\) specifications.
This service-oriented SA framework enables you to develop services, features, and external APIs, and implement multi-service process sharing and service invoking for inter-process communication \(IPC\). Wherein:
- M core provides services, features, external APIs, and multi-service process sharing development.
- In addition to the capabilities provided by M-core, A-core provides capabilities such as IPC service invoking, permission control for IPC service invoking, and IPC service API development.
Service-oriented architecture
![](figures/en-us_image_0000001128146921.png)
- Provider: a service provider that provides capabilities \(external APIs\) for the system
- Consumer: a service consumer that invokes the features \(external APIs\) provided by the service
- Samgr: an agency that manages capabilities provided by providers and helps consumers discover providers' capabilities
Main objects of the SA framework:
![](figures/en-us_image_0000001081285004.png)
- SamgrLite: provides service registration and discovery.
- Service: implements lifecycle APIs of the service during service development.
- Feature: implements lifecycle APIs of the feature during feature development.
- IUnknown: implements external APIs for services or features based on **IUnknown**.
- IClientProxy: implements the consumer's proxy to send messages during IPC invoking.
- IServerProxy: implements the provider's proxy during IPC invoking, which needs to be implemented by developers.
## Directory Structure<a name="section1464106163817"></a>
**Table 1** Structure of the source code directory of the SA framework
<a name="table2977131081412"></a>
<table><thead align="left"><tr id="row7977610131417"><th class="cellrowborder" valign="top" width="31.3%" id="mcps1.2.3.1.1"><p id="p18792459121314"><a name="p18792459121314"></a><a name="p18792459121314"></a>Directory</p>
</th>
<th class="cellrowborder" valign="top" width="68.7%" id="mcps1.2.3.1.2"><p id="p77921459191317"><a name="p77921459191317"></a><a name="p77921459191317"></a>Description</p>
</th>
</tr>
</thead>
<tbody><tr id="row17977171010144"><td class="cellrowborder" valign="top" width="31.3%" headers="mcps1.2.3.1.1 "><p id="p2793159171311"><a name="p2793159171311"></a><a name="p2793159171311"></a>interfaces/kits/samgr_lite/samgr</p>
</td>
<td class="cellrowborder" valign="top" width="68.7%" headers="mcps1.2.3.1.2 "><p id="p879375920132"><a name="p879375920132"></a><a name="p879375920132"></a>External APIs of the M- and A-core SA frameworks</p>
</td>
</tr>
<tr id="row6978161091412"><td class="cellrowborder" valign="top" width="31.3%" headers="mcps1.2.3.1.1 "><p id="p37931659101311"><a name="p37931659101311"></a><a name="p37931659101311"></a>interfaces/kits/samgr_lite/registry</p>
</td>
<td class="cellrowborder" valign="top" width="68.7%" headers="mcps1.2.3.1.2 "><p id="p6793059171318"><a name="p6793059171318"></a><a name="p6793059171318"></a>External APIs for service invocation between A-core processes</p>
</td>
</tr>
<tr id="row6978201031415"><td class="cellrowborder" valign="top" width="31.3%" headers="mcps1.2.3.1.1 "><p id="p117935599130"><a name="p117935599130"></a><a name="p117935599130"></a>interfaces/kits/samgr_lite/communication/broadcast</p>
</td>
<td class="cellrowborder" valign="top" width="68.7%" headers="mcps1.2.3.1.2 "><p id="p0793185971316"><a name="p0793185971316"></a><a name="p0793185971316"></a>External APIs of the event broadcast service within M- and A-core processes</p>
</td>
</tr>
<tr id="row124243183397"><td class="cellrowborder" valign="top" width="31.3%" headers="mcps1.2.3.1.1 "><p id="p104249183396"><a name="p104249183396"></a><a name="p104249183396"></a>services/samgr_lite/samgr/adapter</p>
</td>
<td class="cellrowborder" valign="top" width="68.7%" headers="mcps1.2.3.1.2 "><p id="p2424318203914"><a name="p2424318203914"></a><a name="p2424318203914"></a>POSIX and CMSIS interface adaptation layer, which is used to harmonize the differences between the APIs of M- and A-core</p>
</td>
</tr>
<tr id="row1634915717405"><td class="cellrowborder" valign="top" width="31.3%" headers="mcps1.2.3.1.1 "><p id="p193493571406"><a name="p193493571406"></a><a name="p193493571406"></a>services/samgr_lite/samgr/registry</p>
</td>
<td class="cellrowborder" valign="top" width="68.7%" headers="mcps1.2.3.1.2 "><p id="p14349257184012"><a name="p14349257184012"></a><a name="p14349257184012"></a>Stub functions for M-core service registration and discovery</p>
</td>
</tr>
<tr id="row1385432741312"><td class="cellrowborder" valign="top" width="31.3%" headers="mcps1.2.3.1.1 "><p id="p1485582714135"><a name="p1485582714135"></a><a name="p1485582714135"></a>services/samgr_lite/samgr/source</p>
</td>
<td class="cellrowborder" valign="top" width="68.7%" headers="mcps1.2.3.1.2 "><p id="p085522751319"><a name="p085522751319"></a><a name="p085522751319"></a>Basic code for the M- and A-core SA frameworks</p>
</td>
</tr>
<tr id="row7968155877"><td class="cellrowborder" valign="top" width="31.3%" headers="mcps1.2.3.1.1 "><p id="p89681851717"><a name="p89681851717"></a><a name="p89681851717"></a>services/samgr_lite/samgr_client</p>
</td>
<td class="cellrowborder" valign="top" width="68.7%" headers="mcps1.2.3.1.2 "><p id="p169681051873"><a name="p169681051873"></a><a name="p169681051873"></a>Registration and discovery for service invocation between A-core processes</p>
</td>
</tr>
<tr id="row18291912179"><td class="cellrowborder" valign="top" width="31.3%" headers="mcps1.2.3.1.1 "><p id="p1729111214715"><a name="p1729111214715"></a><a name="p1729111214715"></a>services/samgr_lite/samgr_server</p>
</td>
<td class="cellrowborder" valign="top" width="68.7%" headers="mcps1.2.3.1.2 "><p id="p7839893352"><a name="p7839893352"></a><a name="p7839893352"></a>IPC address management and access control for service invocation between A-core processes</p>
</td>
</tr>
<tr id="row6971514279"><td class="cellrowborder" valign="top" width="31.3%" headers="mcps1.2.3.1.1 "><p id="p1797118141671"><a name="p1797118141671"></a><a name="p1797118141671"></a>services/samgr_lite/samgr_endpoint</p>
</td>
<td class="cellrowborder" valign="top" width="68.7%" headers="mcps1.2.3.1.2 "><p id="p597119145716"><a name="p597119145716"></a><a name="p597119145716"></a>Packet RX/TX management for A-core IPC</p>
</td>
</tr>
<tr id="row33121991272"><td class="cellrowborder" valign="top" width="31.3%" headers="mcps1.2.3.1.1 "><p id="p143121991875"><a name="p143121991875"></a><a name="p143121991875"></a>services/samgr_lite/communication/broadcast</p>
</td>
<td class="cellrowborder" valign="top" width="68.7%" headers="mcps1.2.3.1.2 "><p id="p16312169179"><a name="p16312169179"></a><a name="p16312169179"></a>Event broadcast service for M- and A-core processes</p>
</td>
</tr>
</tbody>
</table>
## Constraints<a name="section1718733212019"></a>
- The SA framework is developed using the C programming language.
- Services in the same process use **IUnknown** for invoking. Messages are passed to the service through **IUnknown**.
- The service name and feature name must be constant character strings and the length must be less than 16 bytes.
- More-core depends on the Bootstrap service and calls the **OHOS\_SystemInit\(\)** function in the system startup function.
- A-core depends on the Samgr library and calls the **SAMGR\_Bootstrap\(\)** function in the **main** function.
## Developing a Service<a name="section159991817144514"></a>
- Inherit and redefine a service.
```
typedef struct ExampleService {
INHERIT_SERVICE;
INHERIT_IUNKNOWNENTRY(DefaultFeatureApi);
Identity identity;
} ExampleService;
```
- Implement the lifecycle function of the service.
```
static const char *GetName(Service *service)
{
return EXAMPLE_SERVICE;
}
static BOOL Initialize(Service *service, Identity identity)
{
ExampleService *example = (ExampleService *)service;
// Save the unique ID of the service, which is used when IUnknown is used to send messages to the service.
example->identity = identity;
return TRUE;
}
static BOOL MessageHandle(Service *service, Request *msg)
{
ExampleService *example = (ExampleService *)service;
switch (msg->msgId) {
case MSG_SYNC:
// Process the service.
break;
default:break;
}
return FALSE;
}
static TaskConfig GetTaskConfig(Service *service)
{
TaskConfig config = {LEVEL_HIGH, PRI_BELOW_NORMAL,
0x800, 20, SHARED_TASK};
return config;
}
```
- Create a service object.
```
static ExampleService g_example = {
.GetName = GetName,
.Initialize = Initialize,
.MessageHandle = MessageHandle,
.GetTaskConfig = GetTaskConfig,
SERVER_IPROXY_IMPL_BEGIN,
.Invoke = NULL,
.SyncCall = SyncCall,
IPROXY_END,
};
```
- Register the service and API with Samgr.
```
static void Init(void)
{
SAMGR_GetInstance()->RegisterService((Service *)&g_example);
SAMGR_GetInstance()->RegisterDefaultFeatureApi(EXAMPLE_SERVICE, GET_IUNKNOWN(g_example));
}
```
- Define the initializer of the service.
```
SYSEX_SERVICE_INIT(Init);
```
## Developing a Feature of a Service<a name="section11510542164514"></a>
- Inherit and redefine a feature.
```
typedef struct DemoFeature {
INHERIT_FEATURE;
INHERIT_IUNKNOWNENTRY(DemoApi);
Identity identity;
Service *parent;
} DemoFeature;
```
- Implement the lifecycle function of the feature.
```
static const char *FEATURE_GetName(Feature *feature)
{
return EXAMPLE_FEATURE;
}
static void FEATURE_OnInitialize(Feature *feature, Service *parent, Identity identity)
{
DemoFeature *demoFeature = (DemoFeature *)feature;
demoFeature->identity = identity;
demoFeature->parent = parent;
}
static void FEATURE_OnStop(Feature *feature, Identity identity)
{
g_example.identity.queueId = NULL;
g_example.identity.featureId = -1;
g_example.identity.serviceId = -1;
}
static BOOL FEATURE_OnMessage(Feature *feature, Request *request)
{
if (request->msgId == MSG_PROC) {
Response response = {.data = "Yes, you did!", .len = 0};
SAMGR_SendResponse(request, &response);
return TRUE;
} else {
if (request->msgId == MSG_TIME_PROC) {
LOS_Msleep(WAIT_FEATURE_PROC * 10);
if (request->msgValue) {
SAMGR_PrintServices();
} else {
SAMGR_PrintOperations();
}
AsyncTimeCall(GET_IUNKNOWN(g_example));
return FALSE;
}
}
return FALSE;
}
```
- Create a feature object.
```
static DemoFeature g_example = {
.GetName = FEATURE_GetName,
.OnInitialize = FEATURE_OnInitialize,
.OnStop = FEATURE_OnStop,
.OnMessage = FEATURE_OnMessage,
DEFAULT_IUNKNOWN_ENTRY_BEGIN,
.AsyncCall = AsyncCall,
.AsyncTimeCall = AsyncTimeCall,
.SyncCall = SyncCall,
.AsyncCallBack = AsyncCallBack,
DEFAULT_IUNKNOWN_ENTRY_END,
.identity = {-1, -1, NULL},
};
```
- Register the feature and API with Samgr.
```
static void Init(void){
SAMGR_GetInstance()->RegisterFeature(EXAMPLE_SERVICE, (Feature *)&g_example);
SAMGR_GetInstance()->RegisterFeatureApi(EXAMPLE_SERVICE, EXAMPLE_FEATURE, GET_IUNKNOWN(g_example));
}
```
- Define the initializer of the feature.
```
SYSEX_FEATURE_INIT(Init);
```
## Developing an External API for Intra-Process Communication<a name="section1685211117463"></a>
- Define the **IUnknown** API.
```
typedef struct DemoApi {
INHERIT_IUNKNOWN;
BOOL (*AsyncCall)(IUnknown *iUnknown, const char *buff);
BOOL (*AsyncTimeCall)(IUnknown *iUnknown);
BOOL (*SyncCall)(IUnknown *iUnknown, struct Payload *payload);
BOOL (*AsyncCallBack)(IUnknown *iUnknown, const char *buff, Handler handler);
} DemoApi;
```
- Define the reference object of **IUnknown**.
```
typedef struct DemoRefApi {
INHERIT_IUNKNOWNENTRY(DemoApi);
} DemoRefApi;
```
- Initialize the object of **IUnknown**.
```
static DemoRefApi api = {
DEFAULT_IUNKNOWN_ENTRY_BEGIN,
.AsyncCall = AsyncCall,
.AsyncTimeCall = AsyncTimeCall,
.SyncCall = SyncCall,
.AsyncCallBack = AsyncCallBack,
DEFAULT_IUNKNOWN_ENTRY_END,
};
```
- Register the feature API.
```
SAMGR_GetInstance()->RegisterFeatureApi(EXAMPLE_SERVICE, EXAMPLE_FEATURE, GET_IUNKNOWN(api));
```
## Invoking a Service in the Same Process<a name="section3690162916462"></a>
- Obtain the external API of the service.
```
DemoApi *demoApi = NULL;
IUnknown *iUnknown = SAMGR_GetInstance()->GetFeatureApi(EXAMPLE_SERVICE, EXAMPLE_FEATURE);
if (iUnknown == NULL) {
return NULL;
}
int result = iUnknown->QueryInterface(iUnknown, DEFAULT_VERSION, (void **)&demoApi);
if (result != 0 || demoApi == NULL) {
return NULL;
}
```
- Call the API.
```
if (demoApi->AsyncCallBack == NULL) {
return NULL;
}
demoApi->AsyncCallBack((IUnknown *)demoApi, "I wanna async call callback good result!", AsyncHandler);
```
- Release the API.
```
int32 ref = demoApi->Release((IUnknown *)demoApi);
```
## Developing an External API for IPC<a name="section9220246194615"></a>
- Inherit **IServerProxy** to replace **IUnknown**: INHERIT\_SERVER\_IPROXY
```
typedef struct DemoFeatureApi {
INHERIT_SERVER_IPROXY;
BOOL (*AsyncCall)(IUnknown *iUnknown, const char *buff);
BOOL (*AsyncTimeCall)(IUnknown *iUnknown);
BOOL (*SyncCall)(IUnknown *iUnknown, struct Payload *payload);
BOOL (*AsyncCallBack)(IUnknown *iUnknown, const char *buff, IOwner notify, INotifyFunc handler);
} DemoFeatureApi;
```
- Initialize the **IServerProxy** object.
```
static DemoFeature g_example = {
SERVER_IPROXY_IMPL_BEGIN,
.Invoke = Invoke,
.AsyncCall = AsyncCall,
.AsyncTimeCall = AsyncTimeCall,
.SyncCall = SyncCall,
.AsyncCallBack = AsyncCallBack,
IPROXY_END,
};
```
- Implement the **Invoke** function to process IPC messages.
```
static int32 Invoke(IServerProxy *iProxy, int funcId, void *origin, IpcIo *req, IpcIo *reply)
{
DemoFeatureApi *api = (DemoFeatureApi *)iProxy;
BOOL ret;
size_t len = 0;
switch (funcId) {
case ID_ASYNCALL:
ret = api->AsyncCall((IUnknown *)iProxy, (char *)IpcIoPopString(req, &len));
IpcIoPushBool(reply, ret);
break;
case ID_ASYNTIMECALL:
ret = api->AsyncTimeCall((IUnknown *)iProxy);
IpcIoPushBool(reply, ret);
break;
case ID_SYNCCALL: {
struct Payload payload;
payload.id = IpcIoPopInt32(req);
payload.value = IpcIoPopInt32(req);
payload.name = (char *)IpcIoPopString(req, &len);
ret = api->SyncCall((IUnknown *)iProxy, &payload);
IpcIoPushString(reply, ret ? "TRUE" : "FALSE");
}
break;
case ID_ASYNCCALLBACK: { // convert to sync proxy
IpcIoPushString(reply, "Yes, you did!");
IpcIoPushBool(reply, TRUE);
}
break;
default:
IpcIoPushBool(reply, FALSE);
break;
}
return EC_SUCCESS;
}
```
- Register the API. This step is same as the API registration for intra-process communication.
```
SAMGR_GetInstance()->RegisterFeatureApi(EXAMPLE_SERVICE, EXAMPLE_FEATURE, GET_IUNKNOWN(g_example));
```
## Invoking a Service in Another Process<a name="section114372711475"></a>
- Obtain the external API of the service in another process.
```
IClientProxy *demoApi = NULL;
IUnknown *iUnknown = SAMGR_GetInstance()->GetFeatureApi(EXAMPLE_SERVICE, EXAMPLE_FEATURE);
if (iUnknown == NULL) {
return NULL;
}
int result = iUnknown->QueryInterface(iUnknown, CLIENT_PROXY_VER, (void **)&demoApi);
if (result != 0 || demoApi == NULL) {
return NULL;
}
```
- Invoke the API for sending IPC messages.
```
IpcIo request;char data[250];
IpcIoInit(&request, data, sizeof(data), 0);
demoApi->Invoke(demoApi, 0, &request, NULL, NULL);
```
- Release the API.
```
int32 ref = demoApi->Release((IUnknown *)demoApi);
```
## Developing a Client Proxy for Inter-Process Service Invocation<a name="section09341923114710"></a>
- Define a client proxy for the IPC API.
```
typedef struct DemoClientProxy {
INHERIT_CLIENT_IPROXY;
BOOL (*AsyncCall)(IUnknown *iUnknown, const char *buff);
BOOL (*AsyncTimeCall)(IUnknown *iUnknown);
BOOL (*SyncCall)(IUnknown *iUnknown, struct Payload *payload);
BOOL (*AsyncCallBack)(IUnknown *iUnknown, const char *buff, IOwner notify, INotifyFunc handler);
} DemoClientProxy;
typedef struct DemoClientEntry {
INHERIT_IUNKNOWNENTRY(DemoClientProxy);
} DemoClientEntry;
```
- Enable the client proxy to encapsulate the IPC message API.
```
static BOOL AsyncCall(IUnknown *iUnknown, const char *buff)
{
DemoClientProxy *proxy = (DemoClientProxy *)iUnknown;
IpcIo request;
char data[MAX_DATA_LEN];
IpcIoInit(&request, data, MAX_DATA_LEN, 0);
IpcIoPushString(&request, buff);
int ret = proxy->Invoke((IClientProxy *)proxy, ID_ASYNCALL, &request, NULL, NULL);
return ret == EC_SUCCESS;
}
static BOOL AsyncTimeCall(IUnknown *iUnknown)
{
DemoClientProxy *proxy = (DemoClientProxy *)iUnknown;
IpcIo request;
char data[MAX_DATA_LEN];
IpcIoInit(&request, data, MAX_DATA_LEN, 0);
int ret = proxy->Invoke((IClientProxy *)proxy, ID_ASYNTIMECALL, &request, NULL, NULL);
return ret == EC_SUCCESS;
}
static int Callback(IOwner owner, int code, IpcIo *reply)
{
size_t len = 0;
return strcpy_s(owner, MAX_DATA_LEN, (char *)IpcIoPopString(reply, &len));
}
static BOOL SyncCall(IUnknown *iUnknown, struct Payload *payload)
{
DemoClientProxy *proxy = (DemoClientProxy *)iUnknown;
IpcIo request;
char data[MAX_DATA_LEN];
IpcIoInit(&request, data, MAX_DATA_LEN, 0);
IpcIoPushInt32(&request, payload->id);
IpcIoPushInt32(&request, payload->value);
IpcIoPushString(&request, payload->name);
int ret = proxy->Invoke((IClientProxy *)proxy, ID_SYNCCALL, &request, data, Callback);
data[MAX_DATA_LEN - 1] = 0;
HILOG_INFO(HILOG_MODULE_APP, "[TID:0x%lx]Remote response is %s!", pthread_self(), data);
return ret == EC_SUCCESS;
}
struct CurrentNotify {
IOwner notify;
INotifyFunc handler;
};
static int CurrentCallback(IOwner owner, int code, IpcIo *reply)
{
struct CurrentNotify *notify = (struct CurrentNotify *)owner;
size_t len = 0;
char *response = (char *)IpcIoPopString(reply, &len);
HILOG_INFO(HILOG_MODULE_APP, "[TID:0x%lx]Notify Remote response is %s!", pthread_self(), response);
notify->handler(notify->notify, response);
return EC_SUCCESS;
}
static BOOL AsyncCallBack(IUnknown *iUnknown, const char *buff, IOwner notify, INotifyFunc handler)
{
struct CurrentNotify owner = {notify, handler};
DemoClientProxy *proxy = (DemoClientProxy *)iUnknown;
IpcIo request;
char data[MAX_DATA_LEN];
IpcIoInit(&request, data, MAX_DATA_LEN, 0);
IpcIoPushString(&request, buff);
int ret = proxy->Invoke((IClientProxy *)proxy, ID_ASYNCCALLBACK, &request, &owner, CurrentCallback);
return ret == EC_SUCCESS;
}
```
- Implement the factory method for creating the client proxy.
```
void *DEMO_CreatClient(const char *service, const char *feature, uint32 size)
{
(void)service;
(void)feature;
uint32 len = size + sizeof(DemoClientEntry);
uint8 *client = malloc(len);
(void)memset_s(client, len, 0, len);
DemoClientEntry *entry = (DemoClientEntry *)&client[size];
entry->ver = ((uint16)CLIENT_PROXY_VER | (uint16)DEFAULT_VERSION);
entry->ref = 1;
entry->iUnknown.QueryInterface = IUNKNOWN_QueryInterface;
entry->iUnknown.AddRef = IUNKNOWN_AddRef;
entry->iUnknown.Release = IUNKNOWN_Release;
entry->iUnknown.Invoke = NULL;
entry->iUnknown.AsyncCall = AsyncCall;
entry->iUnknown.AsyncTimeCall = AsyncTimeCall;
entry->iUnknown.SyncCall = SyncCall;
entry->iUnknown.AsyncCallBack = AsyncCallBack;
return client;
}
void DEMO_DestroyClient(const char *service, const char *feature, void *iproxy)
{
free(iproxy);
}
```
- Register the factory method of the client proxy with Samgr.
```
SAMGR_RegisterFactory(EXAMPLE_SERVICE, EXAMPLE_FEATURE, DEMO_CreatClient, DEMO_DestroyClient);
```
- Obtain the external API of the service in another process.
```
DemoClientProxy *demoApi = NULL;
IUnknown *iUnknown = SAMGR_GetInstance()->GetFeatureApi(EXAMPLE_SERVICE, EXAMPLE_FEATURE);
if (iUnknown == NULL) {
return NULL;
}
int result = iUnknown->QueryInterface(iUnknown, DEFAULT_VERSION, (void **)&demoApi);
if (result != 0 || demoApi == NULL) {
return NULL;
}
```
- Invoke the client proxy API of the service in another process.
```
if (demoApi->AsyncCallBack == NULL) {
return NULL;
}
demoApi->AsyncCallBack((IUnknown *)demoApi,
"I wanna async call callback good result!", NULL, AsyncHandler);
```
- Release the API.
```
int32 ref = demoApi->Release((IUnknown *)demoApi);
```
## Repositories Involved<a name="section10365113863719"></a>
[Distributed Scheduler subsystem](en-us_topic_0000001115719369.md)
**[samgr\_lite](https://gitee.com/openharmony/distributedschedule_services_samgr_lite)**

633
README_zh.md Executable file
View File

@ -0,0 +1,633 @@
# 介绍<a name="ZH-CN_TOPIC_0000001081604584"></a>
- [简介](#section11660541593)
- [目录](#section1464106163817)
- [约束](#section1718733212019)
- [开发服务](#section159991817144514)
- [开发服务的子功能](#section11510542164514)
- [开发进程内对外接口](#section1685211117463)
- [调用进程内服务](#section3690162916462)
- [开发跨进程间对外接口](#section9220246194615)
- [调用跨进程间服务](#section114372711475)
- [开发跨进程间服务调用客户端代理](#section09341923114710)
- [涉及仓](#section10365113863719)
## 简介<a name="section11660541593"></a>
由于平台资源有限且硬件平台多样因此需要屏蔽不同硬件架构和平台资源的不同、以及运行形态的不同提供统一化的系统服务开发框架。根据RISC-V、Cortex-M、Cortex-A不同硬件平台分为两种硬件平台以下简称M核、A核。
- M核处理器架构为Cortex-M或同等处理能力的硬件平台系统内存一般低于512KB无文件系统或者仅提供一个可有限使用的轻量级文件系统遵循CMSIS接口规范。
- A核处理器架构为Cortex-A或同等处理能力的硬件平台内存资源大于512KB文件系统完善可存储大量数据遵循POSIX接口规范。
系统服务框架基于面向服务的架构,提供了服务开发、服务的子功能开发、对外接口的开发、以及多服务共进程、进程间服务调用等开发能力。其中:
- M核包含服务开发、服务的子功能开发、对外接口的开发以及多服务共进程的开发框架。
- A核在M核能力基础之上包含了进程间服务调用、进程间服务调用权限控制、进程间服务接口的开发等能力。
面向服务的架构:
![](figures/zh-cn_image_0000001128146921.png)
- Provider服务的提供者为系统提供能力对外接口
- Consumer服务的消费者调用服务提供的功能对外接口
- Samgr作为中介者管理Provider提供的能力同时帮助Consumer发现Provider的能力。
系统服务开发框架主体对象:
![](figures/zh-cn_image_0000001081285004.png)
- SamgrLite主要提供服务的注册与发现能力。
- Service开发服务时需要实现的服务的生命周期接口。
- Feature开发功能时需要实现的功能的生命周期接口。
- IUnknown基于IUnknown开发服务或功能的对外接口。
- IClientProxyIPC调用时消费者的消息发送代理。
- IServerProxyIPC调用时开发者需要实现提供者的消息处理接口。
## 目录<a name="section1464106163817"></a>
**表 1** 系统服务框架源代码目录结构
<a name="table2977131081412"></a>
<table><thead align="left"><tr id="row7977610131417"><th class="cellrowborder" valign="top" width="31.3%" id="mcps1.2.3.1.1"><p id="p18792459121314"><a name="p18792459121314"></a><a name="p18792459121314"></a>名称</p>
</th>
<th class="cellrowborder" valign="top" width="68.7%" id="mcps1.2.3.1.2"><p id="p77921459191317"><a name="p77921459191317"></a><a name="p77921459191317"></a>描述</p>
</th>
</tr>
</thead>
<tbody><tr id="row17977171010144"><td class="cellrowborder" valign="top" width="31.3%" headers="mcps1.2.3.1.1 "><p id="p2793159171311"><a name="p2793159171311"></a><a name="p2793159171311"></a>interfaces/kits/samgr_lite/samgr</p>
</td>
<td class="cellrowborder" valign="top" width="68.7%" headers="mcps1.2.3.1.2 "><p id="p879375920132"><a name="p879375920132"></a><a name="p879375920132"></a>M核和A核系统服务框架对外接口定义。</p>
</td>
</tr>
<tr id="row6978161091412"><td class="cellrowborder" valign="top" width="31.3%" headers="mcps1.2.3.1.1 "><p id="p37931659101311"><a name="p37931659101311"></a><a name="p37931659101311"></a>interfaces/kits/samgr_lite/registry</p>
</td>
<td class="cellrowborder" valign="top" width="68.7%" headers="mcps1.2.3.1.2 "><p id="p6793059171318"><a name="p6793059171318"></a><a name="p6793059171318"></a>A核进程间服务调用的对外接口定义。</p>
</td>
</tr>
<tr id="row6978201031415"><td class="cellrowborder" valign="top" width="31.3%" headers="mcps1.2.3.1.1 "><p id="p117935599130"><a name="p117935599130"></a><a name="p117935599130"></a>interfaces/kits/samgr_lite/communication/broadcast</p>
</td>
<td class="cellrowborder" valign="top" width="68.7%" headers="mcps1.2.3.1.2 "><p id="p0793185971316"><a name="p0793185971316"></a><a name="p0793185971316"></a>M核和A核进程内事件广播服务的对外接口定义。</p>
</td>
</tr>
<tr id="row124243183397"><td class="cellrowborder" valign="top" width="31.3%" headers="mcps1.2.3.1.1 "><p id="p104249183396"><a name="p104249183396"></a><a name="p104249183396"></a>services/samgr_lite/samgr/adapter</p>
</td>
<td class="cellrowborder" valign="top" width="68.7%" headers="mcps1.2.3.1.2 "><p id="p2424318203914"><a name="p2424318203914"></a><a name="p2424318203914"></a>POSIX和CMSIS接口适配层来屏蔽A核M核接口差异。</p>
</td>
</tr>
<tr id="row1634915717405"><td class="cellrowborder" valign="top" width="31.3%" headers="mcps1.2.3.1.1 "><p id="p193493571406"><a name="p193493571406"></a><a name="p193493571406"></a>services/samgr_lite/samgr/registry</p>
</td>
<td class="cellrowborder" valign="top" width="68.7%" headers="mcps1.2.3.1.2 "><p id="p14349257184012"><a name="p14349257184012"></a><a name="p14349257184012"></a>M核服务注册发现的桩函数。</p>
</td>
</tr>
<tr id="row1385432741312"><td class="cellrowborder" valign="top" width="31.3%" headers="mcps1.2.3.1.1 "><p id="p1485582714135"><a name="p1485582714135"></a><a name="p1485582714135"></a>services/samgr_lite/samgr/source</p>
</td>
<td class="cellrowborder" valign="top" width="68.7%" headers="mcps1.2.3.1.2 "><p id="p085522751319"><a name="p085522751319"></a><a name="p085522751319"></a>M核和A核系统服务开发框架基础代码。</p>
</td>
</tr>
<tr id="row7968155877"><td class="cellrowborder" valign="top" width="31.3%" headers="mcps1.2.3.1.1 "><p id="p89681851717"><a name="p89681851717"></a><a name="p89681851717"></a>services/samgr_lite/samgr_client</p>
</td>
<td class="cellrowborder" valign="top" width="68.7%" headers="mcps1.2.3.1.2 "><p id="p169681051873"><a name="p169681051873"></a><a name="p169681051873"></a>A核进程间服务调用的注册与发现。</p>
</td>
</tr>
<tr id="row18291912179"><td class="cellrowborder" valign="top" width="31.3%" headers="mcps1.2.3.1.1 "><p id="p1729111214715"><a name="p1729111214715"></a><a name="p1729111214715"></a>services/samgr_lite/samgr_server</p>
</td>
<td class="cellrowborder" valign="top" width="68.7%" headers="mcps1.2.3.1.2 "><p id="p7839893352"><a name="p7839893352"></a><a name="p7839893352"></a>A核进程间服务调用的IPC地址管理和访问控制。</p>
</td>
</tr>
<tr id="row6971514279"><td class="cellrowborder" valign="top" width="31.3%" headers="mcps1.2.3.1.1 "><p id="p1797118141671"><a name="p1797118141671"></a><a name="p1797118141671"></a>services/samgr_lite/samgr_endpoint</p>
</td>
<td class="cellrowborder" valign="top" width="68.7%" headers="mcps1.2.3.1.2 "><p id="p597119145716"><a name="p597119145716"></a><a name="p597119145716"></a>A核IPC通信消息收发包管理。</p>
</td>
</tr>
<tr id="row33121991272"><td class="cellrowborder" valign="top" width="31.3%" headers="mcps1.2.3.1.1 "><p id="p143121991875"><a name="p143121991875"></a><a name="p143121991875"></a>services/samgr_lite/communication/broadcast</p>
</td>
<td class="cellrowborder" valign="top" width="68.7%" headers="mcps1.2.3.1.2 "><p id="p16312169179"><a name="p16312169179"></a><a name="p16312169179"></a>M核和A核进程内事件广播服务。</p>
</td>
</tr>
</tbody>
</table>
## 约束<a name="section1718733212019"></a>
- 系统服务开发框架统一使用C开发。
- 同进程内服务间调用统一使用IUnknown接口对外象消息接口统一由IUnknown接口传递给本服务。
- 服务名和功能名必需使用常量字符串且长度小于16个字节。
- M核系统依赖上bootstrap服务在系统启动函数中调用OHOS\_SystemInit\(\)函数。
- A核系统依赖samgr库在main函数中调用SAMGR\_Bootstrap\(\)函数。
## 开发服务<a name="section159991817144514"></a>
- 继承并重新定义服务:
```
typedef struct ExampleService {
INHERIT_SERVICE;
INHERIT_IUNKNOWNENTRY(DefaultFeatureApi);
Identity identity;
} ExampleService;
```
- 实现服务的生命周期函数:
```
static const char *GetName(Service *service)
{
return EXAMPLE_SERVICE;
}
static BOOL Initialize(Service *service, Identity identity)
{
ExampleService *example = (ExampleService *)service;
// 保存服务的唯一身份标识用来自己的IUnknown接口对服务发消息时使用。
example->identity = identity;
return TRUE;
}
static BOOL MessageHandle(Service *service, Request *msg)
{
ExampleService *example = (ExampleService *)service;
switch (msg->msgId) {
case MSG_SYNC:
// 业务处理
break;
default:break;
}
return FALSE;
}
static TaskConfig GetTaskConfig(Service *service)
{
TaskConfig config = {LEVEL_HIGH, PRI_BELOW_NORMAL,
0x800, 20, SHARED_TASK};
return config;
}
```
- 创建服务对象:
```
static ExampleService g_example = {
.GetName = GetName,
.Initialize = Initialize,
.MessageHandle = MessageHandle,
.GetTaskConfig = GetTaskConfig,
SERVER_IPROXY_IMPL_BEGIN,
.Invoke = NULL,
.SyncCall = SyncCall,
IPROXY_END,
};
```
- 向SAMGR注册服务及接口
```
static void Init(void)
{
SAMGR_GetInstance()->RegisterService((Service *)&g_example);
SAMGR_GetInstance()->RegisterDefaultFeatureApi(EXAMPLE_SERVICE, GET_IUNKNOWN(g_example));
}
```
- 定义服务的初始化入口:
```
SYSEX_SERVICE_INIT(Init);
```
## 开发服务的子功能<a name="section11510542164514"></a>
- 继承并重新定义功能:
```
typedef struct DemoFeature {
INHERIT_FEATURE;
INHERIT_IUNKNOWNENTRY(DemoApi);
Identity identity;
Service *parent;
} DemoFeature;
```
- 实现功能的生命周期函数:
```
static const char *FEATURE_GetName(Feature *feature)
{
return EXAMPLE_FEATURE;
}
static void FEATURE_OnInitialize(Feature *feature, Service *parent, Identity identity)
{
DemoFeature *demoFeature = (DemoFeature *)feature;
demoFeature->identity = identity;
demoFeature->parent = parent;
}
static void FEATURE_OnStop(Feature *feature, Identity identity)
{
g_example.identity.queueId = NULL;
g_example.identity.featureId = -1;
g_example.identity.serviceId = -1;
}
static BOOL FEATURE_OnMessage(Feature *feature, Request *request)
{
if (request->msgId == MSG_PROC) {
Response response = {.data = "Yes, you did!", .len = 0};
SAMGR_SendResponse(request, &response);
return TRUE;
} else {
if (request->msgId == MSG_TIME_PROC) {
LOS_Msleep(WAIT_FEATURE_PROC * 10);
if (request->msgValue) {
SAMGR_PrintServices();
} else {
SAMGR_PrintOperations();
}
AsyncTimeCall(GET_IUNKNOWN(g_example));
return FALSE;
}
}
return FALSE;
}
```
- 创建功能对象:
```
static DemoFeature g_example = {
.GetName = FEATURE_GetName,
.OnInitialize = FEATURE_OnInitialize,
.OnStop = FEATURE_OnStop,
.OnMessage = FEATURE_OnMessage,
DEFAULT_IUNKNOWN_ENTRY_BEGIN,
.AsyncCall = AsyncCall,
.AsyncTimeCall = AsyncTimeCall,
.SyncCall = SyncCall,
.AsyncCallBack = AsyncCallBack,
DEFAULT_IUNKNOWN_ENTRY_END,
.identity = {-1, -1, NULL},
};
```
- 向SAMGR注册功能及接口
```
static void Init(void){
SAMGR_GetInstance()->RegisterFeature(EXAMPLE_SERVICE, (Feature *)&g_example);
SAMGR_GetInstance()->RegisterFeatureApi(EXAMPLE_SERVICE, EXAMPLE_FEATURE, GET_IUNKNOWN(g_example));
}
```
- 定义功能的初始化入口:
```
SYSEX_FEATURE_INIT(Init);
```
## 开发进程内对外接口<a name="section1685211117463"></a>
- 定义IUnknown接口
```
typedef struct DemoApi {
INHERIT_IUNKNOWN;
BOOL (*AsyncCall)(IUnknown *iUnknown, const char *buff);
BOOL (*AsyncTimeCall)(IUnknown *iUnknown);
BOOL (*SyncCall)(IUnknown *iUnknown, struct Payload *payload);
BOOL (*AsyncCallBack)(IUnknown *iUnknown, const char *buff, Handler handler);
} DemoApi;
```
- 定义IUnknown的引用对象
```
typedef struct DemoRefApi {
INHERIT_IUNKNOWNENTRY(DemoApi);
} DemoRefApi;
```
- 初始化接口对象:
```
static DemoRefApi api = {
DEFAULT_IUNKNOWN_ENTRY_BEGIN,
.AsyncCall = AsyncCall,
.AsyncTimeCall = AsyncTimeCall,
.SyncCall = SyncCall,
.AsyncCallBack = AsyncCallBack,
DEFAULT_IUNKNOWN_ENTRY_END,
};
```
- 注册服务接口:
```
SAMGR_GetInstance()->RegisterFeatureApi(EXAMPLE_SERVICE, EXAMPLE_FEATURE, GET_IUNKNOWN(api));
```
## 调用进程内服务<a name="section3690162916462"></a>
- 获取服务的对外接口:
```
DemoApi *demoApi = NULL;
IUnknown *iUnknown = SAMGR_GetInstance()->GetFeatureApi(EXAMPLE_SERVICE, EXAMPLE_FEATURE);
if (iUnknown == NULL) {
return NULL;
}
int result = iUnknown->QueryInterface(iUnknown, DEFAULT_VERSION, (void **)&demoApi);
if (result != 0 || demoApi == NULL) {
return NULL;
}
```
- 接口调用:
```
if (demoApi->AsyncCallBack == NULL) {
return NULL;
}
demoApi->AsyncCallBack((IUnknown *)demoApi, "I wanna async call callback good result!", AsyncHandler);
```
- 释放接口:
```
int32 ref = demoApi->Release((IUnknown *)demoApi);
```
## 开发跨进程间对外接口<a name="section9220246194615"></a>
- 继承IServerProxy替代继承IUnknownINHERIT\_SERVER\_IPROXY
```
typedef struct DemoFeatureApi {
INHERIT_SERVER_IPROXY;
BOOL (*AsyncCall)(IUnknown *iUnknown, const char *buff);
BOOL (*AsyncTimeCall)(IUnknown *iUnknown);
BOOL (*SyncCall)(IUnknown *iUnknown, struct Payload *payload);
BOOL (*AsyncCallBack)(IUnknown *iUnknown, const char *buff, IOwner notify, INotifyFunc handler);
} DemoFeatureApi;
```
- 初始化IServerProxy对象
```
static DemoFeature g_example = {
SERVER_IPROXY_IMPL_BEGIN,
.Invoke = Invoke,
.AsyncCall = AsyncCall,
.AsyncTimeCall = AsyncTimeCall,
.SyncCall = SyncCall,
.AsyncCallBack = AsyncCallBack,
IPROXY_END,
};
```
- 实现Invoke函数来处理Ipc消息
```
static int32 Invoke(IServerProxy *iProxy, int funcId, void *origin, IpcIo *req, IpcIo *reply)
{
DemoFeatureApi *api = (DemoFeatureApi *)iProxy;
BOOL ret;
size_t len = 0;
switch (funcId) {
case ID_ASYNCALL:
ret = api->AsyncCall((IUnknown *)iProxy, (char *)IpcIoPopString(req, &len));
IpcIoPushBool(reply, ret);
break;
case ID_ASYNTIMECALL:
ret = api->AsyncTimeCall((IUnknown *)iProxy);
IpcIoPushBool(reply, ret);
break;
case ID_SYNCCALL: {
struct Payload payload;
payload.id = IpcIoPopInt32(req);
payload.value = IpcIoPopInt32(req);
payload.name = (char *)IpcIoPopString(req, &len);
ret = api->SyncCall((IUnknown *)iProxy, &payload);
IpcIoPushString(reply, ret ? "TRUE" : "FALSE");
}
break;
case ID_ASYNCCALLBACK: { // convert to sync proxy
IpcIoPushString(reply, "Yes, you did!");
IpcIoPushBool(reply, TRUE);
}
break;
default:
IpcIoPushBool(reply, FALSE);
break;
}
return EC_SUCCESS;
}
```
- 注册接口:与进程内接口注册一致
```
SAMGR_GetInstance()->RegisterFeatureApi(EXAMPLE_SERVICE, EXAMPLE_FEATURE, GET_IUNKNOWN(g_example));
```
## 调用跨进程间服务<a name="section114372711475"></a>
- 获取跨进程服务的对外接口:
```
IClientProxy *demoApi = NULL;
IUnknown *iUnknown = SAMGR_GetInstance()->GetFeatureApi(EXAMPLE_SERVICE, EXAMPLE_FEATURE);
if (iUnknown == NULL) {
return NULL;
}
int result = iUnknown->QueryInterface(iUnknown, CLIENT_PROXY_VER, (void **)&demoApi);
if (result != 0 || demoApi == NULL) {
return NULL;
}
```
- 调用Ipc消息接口
```
IpcIo request;char data[250];
IpcIoInit(&request, data, sizeof(data), 0);
demoApi->Invoke(demoApi, 0, &request, NULL, NULL);
```
- 释放接口:
```
int32 ref = demoApi->Release((IUnknown *)demoApi);
```
## 开发跨进程间服务调用客户端代理<a name="section09341923114710"></a>
- 定义IPC接口客户端代理
```
typedef struct DemoClientProxy {
INHERIT_CLIENT_IPROXY;
BOOL (*AsyncCall)(IUnknown *iUnknown, const char *buff);
BOOL (*AsyncTimeCall)(IUnknown *iUnknown);
BOOL (*SyncCall)(IUnknown *iUnknown, struct Payload *payload);
BOOL (*AsyncCallBack)(IUnknown *iUnknown, const char *buff, IOwner notify, INotifyFunc handler);
} DemoClientProxy;
typedef struct DemoClientEntry {
INHERIT_IUNKNOWNENTRY(DemoClientProxy);
} DemoClientEntry;
```
- 实现客户端代理封装Ipc消息接口
```
static BOOL AsyncCall(IUnknown *iUnknown, const char *buff)
{
DemoClientProxy *proxy = (DemoClientProxy *)iUnknown;
IpcIo request;
char data[MAX_DATA_LEN];
IpcIoInit(&request, data, MAX_DATA_LEN, 0);
IpcIoPushString(&request, buff);
int ret = proxy->Invoke((IClientProxy *)proxy, ID_ASYNCALL, &request, NULL, NULL);
return ret == EC_SUCCESS;
}
static BOOL AsyncTimeCall(IUnknown *iUnknown)
{
DemoClientProxy *proxy = (DemoClientProxy *)iUnknown;
IpcIo request;
char data[MAX_DATA_LEN];
IpcIoInit(&request, data, MAX_DATA_LEN, 0);
int ret = proxy->Invoke((IClientProxy *)proxy, ID_ASYNTIMECALL, &request, NULL, NULL);
return ret == EC_SUCCESS;
}
static int Callback(IOwner owner, int code, IpcIo *reply)
{
size_t len = 0;
return strcpy_s(owner, MAX_DATA_LEN, (char *)IpcIoPopString(reply, &len));
}
static BOOL SyncCall(IUnknown *iUnknown, struct Payload *payload)
{
DemoClientProxy *proxy = (DemoClientProxy *)iUnknown;
IpcIo request;
char data[MAX_DATA_LEN];
IpcIoInit(&request, data, MAX_DATA_LEN, 0);
IpcIoPushInt32(&request, payload->id);
IpcIoPushInt32(&request, payload->value);
IpcIoPushString(&request, payload->name);
int ret = proxy->Invoke((IClientProxy *)proxy, ID_SYNCCALL, &request, data, Callback);
data[MAX_DATA_LEN - 1] = 0;
HILOG_INFO(HILOG_MODULE_APP, "[TID:0x%lx]Remote response is %s!", pthread_self(), data);
return ret == EC_SUCCESS;
}
struct CurrentNotify {
IOwner notify;
INotifyFunc handler;
};
static int CurrentCallback(IOwner owner, int code, IpcIo *reply)
{
struct CurrentNotify *notify = (struct CurrentNotify *)owner;
size_t len = 0;
char *response = (char *)IpcIoPopString(reply, &len);
HILOG_INFO(HILOG_MODULE_APP, "[TID:0x%lx]Notify Remote response is %s!", pthread_self(), response);
notify->handler(notify->notify, response);
return EC_SUCCESS;
}
static BOOL AsyncCallBack(IUnknown *iUnknown, const char *buff, IOwner notify, INotifyFunc handler)
{
struct CurrentNotify owner = {notify, handler};
DemoClientProxy *proxy = (DemoClientProxy *)iUnknown;
IpcIo request;
char data[MAX_DATA_LEN];
IpcIoInit(&request, data, MAX_DATA_LEN, 0);
IpcIoPushString(&request, buff);
int ret = proxy->Invoke((IClientProxy *)proxy, ID_ASYNCCALLBACK, &request, &owner, CurrentCallback);
return ret == EC_SUCCESS;
}
```
- 实现客户端代理的工厂方法:
```
void *DEMO_CreatClient(const char *service, const char *feature, uint32 size)
{
(void)service;
(void)feature;
uint32 len = size + sizeof(DemoClientEntry);
uint8 *client = malloc(len);
(void)memset_s(client, len, 0, len);
DemoClientEntry *entry = (DemoClientEntry *)&client[size];
entry->ver = ((uint16)CLIENT_PROXY_VER | (uint16)DEFAULT_VERSION);
entry->ref = 1;
entry->iUnknown.QueryInterface = IUNKNOWN_QueryInterface;
entry->iUnknown.AddRef = IUNKNOWN_AddRef;
entry->iUnknown.Release = IUNKNOWN_Release;
entry->iUnknown.Invoke = NULL;
entry->iUnknown.AsyncCall = AsyncCall;
entry->iUnknown.AsyncTimeCall = AsyncTimeCall;
entry->iUnknown.SyncCall = SyncCall;
entry->iUnknown.AsyncCallBack = AsyncCallBack;
return client;
}
void DEMO_DestroyClient(const char *service, const char *feature, void *iproxy)
{
free(iproxy);
}
```
- 将客户端代理的工厂方法注册到SAMGR
```
SAMGR_RegisterFactory(EXAMPLE_SERVICE, EXAMPLE_FEATURE, DEMO_CreatClient, DEMO_DestroyClient);
```
- 获取跨进程服务的对外接口:
```
DemoClientProxy *demoApi = NULL;
IUnknown *iUnknown = SAMGR_GetInstance()->GetFeatureApi(EXAMPLE_SERVICE, EXAMPLE_FEATURE);
if (iUnknown == NULL) {
return NULL;
}
int result = iUnknown->QueryInterface(iUnknown, DEFAULT_VERSION, (void **)&demoApi);
if (result != 0 || demoApi == NULL) {
return NULL;
}
```
- 调用跨进程服务的客户端代理接口:
```
if (demoApi->AsyncCallBack == NULL) {
return NULL;
}
demoApi->AsyncCallBack((IUnknown *)demoApi,
"I wanna async call callback good result!", NULL, AsyncHandler);
```
- 释放接口:
```
int32 ref = demoApi->Release((IUnknown *)demoApi);
```
## 涉及仓<a name="section10365113863719"></a>
**[分布式任务调度子系统](zh-cn_topic_0000001115719369.md)**
[samgr\_lite](https://gitee.com/openharmony/distributedschedule_services_samgr_lite)

View File

@ -13,9 +13,9 @@
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",
"//foundation/distributedschedule/samgr_lite/interfaces/kits/communication/broadcast",
"//foundation/distributedschedule/samgr_lite/interfaces/kits/samgr",
"//foundation/distributedschedule/samgr_lite/samgr/adapter",
"//utils/native/lite/include",
]
}
@ -29,7 +29,7 @@ if (ohos_kernel_type == "liteos_m") {
]
public_configs = [ ":broadcast_public" ]
cflags = [ "-Wall" ]
include_dirs = [ "//kernel/liteos_m/kal" ]
include_dirs = []
}
}
@ -52,7 +52,7 @@ if (ohos_kernel_type == "liteos_a" || ohos_kernel_type == "linux") {
"//kernel/liteos_a/kernel/common",
]
public_deps = [
"//foundation/distributedschedule/services/samgr_lite/samgr:samgr",
"//foundation/distributedschedule/samgr_lite/samgr:samgr",
"//third_party/bounds_checking_function:libsec_shared",
]
}

104
config/system_capability.json Executable file
View File

@ -0,0 +1,104 @@
{
"systemCapability":[
{
"name":"SystemCapability.Dms.SamgrLite",
"register-on-startup":true
},
{
"name":"SystemCapability.Dms.FwkLite",
"register-on-startup":true
},
{
"name":"SystemCapability.Dms.SafwkLite",
"register-on-startup":true
},
{
"name":"SysPart.ai.engine",
"register-on-startup":true
},
{
"name":"SystemCapability.Sensors.Sensor_lite",
"register-on-startup":true
},
{
"name":"SystemCapability.Sensors.MiscDevice_lite",
"register-on-startup":true
},
{
"name":"SystemCapability.ACE.UIEngineLite",
"register-on-startup":true
},
{
"name":"SystemCapability.Startup.SysInfo",
"register-on-startup":true
},
{
"name":"SystemCapability.Startup.AppSpawn",
"register-on-startup":true
},
{
"name":"SystemCapability.Startup.Bootstrap",
"register-on-startup":true
},
{
"name":"SystemCapability.Startup.Init",
"register-on-startup":true
},
{
"name":"SystemCapability.HiviewDFX.HilogLite",
"register-on-startup":true
},
{
"name":"SystemCapability.HiviewDFX.HieventLite",
"register-on-startup":true
},
{
"name":"SystemCapability.HiviewDFX.HiviewLite",
"register-on-startup":true
},
{
"name":"SystemCapability.Graphic.UI",
"register-on-startup":true
},
{
"name":"SystemCapability.Graphic.WMS",
"register-on-startup":false
},
{
"name":"SystemCapability.Security.Permission",
"register-on-startup":true
},
{
"name":"SystemCapability.Security.AppVerify",
"register-on-startup":true
},
{
"name":"SystemCapability.Security.CryptoLite",
"register-on-startup":true
},
{
"name":"SystemCapability.Security.Huks",
"register-on-startup":true
},
{
"name":"SysCap.Updater.Raw",
"register-on-startup":true
},
{
"name":"SystemCapability.Multimedia.Camera",
"register-on-startup":true
},
{
"name":"SystemCapability.Multimedia.Audio",
"register-on-startup":true
},
{
"name":"SystemCapability.Multimedia.Media",
"register-on-startup":true
},
{
"name":"SystemCapability.Communication.IPC",
"register-on-startup":true
}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 222 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 283 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

177
interfaces/innerkits/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,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 OHOS_DISTRIBUTEDSCHEDULE_INTERFACE_H
#define OHOS_DISTRIBUTEDSCHEDULE_INTERFACE_H
#include "feature.h"
#include "iproxy_server.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif
#define DISTRIBUTED_SCHEDULE_SERVICE "dtbschedsrv"
#define DMSLITE_FEATURE "dmslite"
typedef enum {
DMS_EC_SUCCESS = 0,
DMS_EC_START_ABILITY_SYNC_SUCCESS = 1,
DMS_EC_START_ABILITY_ASYNC_SUCCESS = 2,
DMS_EC_PARSE_TLV_FAILURE = 3,
DMS_EC_UNKNOWN_COMMAND_ID = 4,
DMS_EC_GET_BMS_FAILURE = 5,
DMS_EC_GET_BUNDLEINFO_FAILURE = 6,
DMS_EC_CHECK_PERMISSION_FAILURE = 7,
DMS_EC_GET_AMS_FAILURE = 8,
DMS_EC_REGISTE_IPC_CALLBACK_FAILURE = 9,
DMS_EC_FILL_WANT_FAILURE = 10,
DMS_EC_START_ABILITY_SYNC_FAILURE = 11,
DMS_EC_START_ABILITY_ASYNC_FAILURE = 12,
DMS_EC_FAILURE = 13
} DmsLiteCommonErrorCode;
typedef struct {
INHERIT_SERVER_IPROXY;
} DmsLiteInterface;
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif
#endif // OHOS_DISTRIBUTEDSCHEDULE_INTERFACE_H

177
interfaces/kits/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,235 @@
/*
* 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.
*/
/**
* @addtogroup Broadcast
* @{
*
* @brief Provides data subscription and data push for services.
*
* With this module, the Service, Feature, or other modules can broadcast events or data. \n
* All services that listen to these events or data can receive these broadcasts. \n
*
* @since 1.0
* @version 1.0
*/
/**
* @file broadcast_intertface.h
*
* @brief Provides the external interfaces and basic type definitions of the broadcast service.
*
* The interface and type are used for subscribing to and publishing events and data. \n
*
* @since 1.0
* @version 1.0
*/
#ifndef LITE_BROADCAST_INTERFACE_H
#define LITE_BROADCAST_INTERFACE_H
#include <ohos_errno.h>
#include "feature.h"
#include "iunknown.h"
#include "message.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif
/**
* @brief Indicates the name of the broadcast service.
*
* @since 1.0
* @version 1.0 */
#define BROADCAST_SERVICE "Broadcast"
/**
* @brief Indicates the name of the pub/sub feature.
*
* @since 1.0
* @version 1.0
*/
#define PUB_SUB_FEATURE "Provider and subscriber"
/**
* @brief Indicates the topic of an event or data, which is used to distinguish different types of
* events or data.
*
* @since 1.0
* @version 1.0
*/
typedef uint32 Topic;
/**
* @brief Enumerates error codes unique to the Broadcast service.
*/
enum BroadcastErrCode {
/** Error code showing that a topic has been subscribed to */
EC_ALREADY_SUBSCRIBED = EC_SUCCESS + 1
};
typedef struct Consumer Consumer;
/**
* @brief Defines the topic consumer used to receive events and push data. You need to implement
* this struct for your application.
*/
struct Consumer {
/** Consumer ID */
const Identity *identity;
/**
* @brief Defines how the consumer will process the events or data of a released topic.
*
* You can implement this function for consumers to process topics associated with the them. \n
* Note that the passed topic must have been subscribed by the consumer. Otherwise, the
* function does nothing. \n
*
* @param consumer Indicates <b>this</b> pointer of the consumer.
* @param topic Indicates the pointer to the topic to be processed.
* @param origin Indicates the pointer to the data to be processed.
* @since 1.0
* @version 1.0
*/
void (*Notify)(Consumer *consumer, const Topic *topic, const Request *origin);
/**
* @brief Checks whether two consumers are equal.
*
* You need to implement this function to prevent repeated topic subscription. \n
*
* @param current Indicates the pointer to the current consumer.
* @param other Indicates the pointer to the target consumer to compare.
* @return Returns <b>TRUE</b> if the two consumers are equal; returns <b>FALSE</b> otherwise.
* @since 1.0
* @version 1.0
*/
BOOL (*Equal)(const Consumer *current, const Consumer *other);
};
typedef struct Provider Provider;
/**
* @brief Defines the provider of events and data of a topic.
*/
struct Provider {
/**
* @brief Publishes events and data of a specified topic.
*
* The events or data is published by the publisher, sent to all consumers who have subscribed
* to the topic, and processed by the consumers. \n
*
* @param iUnknown Indicates external interface of the pub/sub feature.
* @param topic Indicates the pointer to the topic to publish.
* @param data Indicates the pointer to the data to publish.
* @param len Indicates the length of the data to be published. The length must be the same as
* the <b>data</b> length. The caller must ensure the validity of this parameter.
* @return Returns <b>TRUE</b> if the topic is successfully published; returns <b>FALSE</b>
* otherwise.
* @since 1.0
* @version 1.0
*/
BOOL (*Publish)(IUnknown *iUnknown, const Topic *topic, uint8 *data, int16 len);
};
typedef struct Subscriber Subscriber;
/**
* @brief Defines the subscriber for external interfaces to subscribe to events and data of a topic.
*/
struct Subscriber {
/**
* @brief Adds a specified topic to the Broadcast service.
*
* The specified topic is added by the subscriber. \n
* A topic can be subscribed to only after being added. \n
*
* @param iUnknown Indicates external interface of the pub/sub feature.
* @param topic Indicates the topic to be subscribed to.
* @return Returns <b>EC_SUCCESS</b> if the topic is successfully added; returns other error
* codes if the topic fails to be added.
* @since 1.0
* @version 1.0
*/
int (*AddTopic)(IUnknown *iUnknown, const Topic *topic);
/**
* @brief Subscribes to a specified topic for consumers.
*
* Call this function on the subscriber. The topic to be subscribed to must have been added to
* the Broadcast service. \n
*
* @param iUnknown Indicates external interface of the pub/sub feature.
* @param topic Indicates the topic to be subscribed to.
* @param consumer Indicates the consumer who subscribes to the topic.
* @return Returns <b>EC_SUCCESS</b> if the subscription is successful; returns other error
* codes if the subscription fails.
* @since 1.0
* @version 1.0
*/
int (*Subscribe)(IUnknown *iUnknown, const Topic *topic, Consumer *consumer);
/**
* @brief Modifies the consumer of a specified topic.
*
*
*
* @param iUnknown Indicates the pointer to the external interface of the pub/sub feature.
* @param topic Indicates the pointer to the topic whose consumer will be modified.
* @param old Indicates the pointer to the original consumer of the topic.
* @param current Indicates the pointer to the new consumer of the topic.
* @return Returns the pointer of the original consumer if the modification is successful;
* returns <b>NULL</b> otherwise.
* @since 1.0
* @version 1.0
*/
Consumer *(*ModifyConsumer)(IUnknown *iUnknown, const Topic *topic, Consumer *old, Consumer *current);
/**
* @brief Unsubscribes from a specified topic.
*
* This function cancels the subscription relationship between the specified topic and
* consumer. \n
*
* @param iUnknown Indicates external interface of the pub/sub feature. This parameter is used
* to obtain subscription relationships.
* @param topic Indicates the pointer to the topic to unsubscribe from.
* @param consumer Indicates the pointer to the consumer.
* @return Returns the pointer of the consumer if the unsubscription is successful; returns
* <b>NULL</b> otherwise.
* @since 1.0
* @version 1.0
*/
Consumer *(*Unsubscribe)(IUnknown *iUnknown, const Topic *topic, const Consumer *consumer);
};
typedef struct PubSubInterface PubSubInterface;
struct PubSubInterface {
INHERIT_IUNKNOWN;
Subscriber subscriber;
Provider provider;
};
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif
#endif // LITE_BROADCAST_INTERFACE_H
/** @} */

View File

@ -0,0 +1,150 @@
/*
* 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.
*/
/**
* @addtogroup Registry
* @{
*
* @brief Provides APIs for registering and discovering inter-process communication (IPC)
* capabilities.
*
* Based on the Samgr development framework, this module helps you to develop system capabilities
* and implement cross-process calls. \n
* This module is used when system capabilities need to be provided across processes. \n
*
* @since 1.0
* @version 1.0
*/
/**
* @file iproxy_client.h
*
* @brief Provides the client proxy class.
*
* When you need to call system capabilities of other processes, obtain the class from Samgr. \n
*
* @since 1.0
* @version 1.0
*/
#ifndef LITE_IPROXY_CLIENT_H
#define LITE_IPROXY_CLIENT_H
#include "iunknown.h"
#include "message.h"
#include "serializer.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif
#define CLIENT_PROXY_VER 0x40
/**
* @brief Indicates the inherited macro of the client proxy.
*
* This constant is used when a client proxy needs to be customized or generated by a tool. \n
*
*/
#define INHERIT_CLIENT_IPROXY \
INHERIT_IUNKNOWN; \
int (*Invoke)(IClientProxy *proxy, int funcId, IpcIo *request, IOwner owner, INotify notify)
typedef void *IOwner;
/**
* @brief Called when a client request is responded.
*
* The client implements this <b>INotify</b> callback to receive response data from the server. \n
* <b>owner</b> indicates the client proxy that receives the response data; <b>code</b> indicates
* the error code of the response data from the server; <b>reply</b> indicates the response data. \n
*
*/
typedef int (*INotify)(IOwner owner, int code, IpcIo *reply);
typedef struct IClientProxy IClientProxy;
/**
* @brief Defines the client proxy object.
*
* This object is used for the IPC with the server. \n
* If you want to use the same invocation mode as that on the server, create an object inherited
* from {@code IClientProxy} and implement serialization.
*
* @since 1.0
* @version 1.0
*/
struct IClientProxy {
/** Inherites the <b>IUnknown</b> base class. */
INHERIT_IUNKNOWN;
/**
* @brief Sends an IPC message from the client to the <b>IServerProxy</b>.
*
* This function is used for IPC. \n
* The passed <b>proxy</b> is used to obtain the server information. Then, <b>request</b>
* carries the request message to be sent to the server and processed by the function specified
* by <b>funcId</b>. <b>notify</b> is a callback function used to process the response message. \n
*
* @param proxy Indicates the pointer of the client proxy object.
* @param funcId Indicates the ID of the function implemented on the server.
* @param request Indicates the pointer to the serialized request message.
* @param owner Indicates the receiver (generics type) of the response message.
* @param notify Indicates the callback function that notifies the client of the response
* message.
* @return Returns <b>EC_SUCCESS</b> if the IPC message is sent successfully; returns other
* error codes if the message fails to be sent.
* @since 1.0
* @version 1.0
*/
int (*Invoke)(IClientProxy *proxy, int funcId, IpcIo *request, IOwner owner, INotify notify);
};
#define INHERIT_IPROXY_ENTRY(T) INHERIT_IUNKNOWNENTRY(T)
#define CLIENT_IPROXY_BEGIN IUNKNOWN_ENTRY_BEGIN(CLIENT_PROXY_VER)
#define IPROXY_END IUNKNOWN_ENTRY_END
/**
* @brief Obtains the IPC address of a remote service and feature based on the service name
* and feature name.
*
* This function is used when {@link IClientProxy} cannot meet your requirements for calling IPCs. \n
* For example, if you need to receive the death notification of a remote service or feature,
* you can call this function to obtain the address of the remote service or feature
* and subscribe to the death notification from the IPC. \n
*
* @param service Indicates the pointer to the name of the remote service.
* @param feature Indicates the pointer to the name of the remote feature.
* @return Returns the IPC address of the remote service or feature. When the handle of the
* obtained address structure {@link SvcIdentity} is <b>0xFFFFFFFF</b>, the address is invalid.
* @attention This function can be called only after <b>GetFeatureApi</b> in {@link SamgrLite}
* is successfully called. Otherwise, an invalid address is returned. When the service or feature
* does not support IPC communication, an invalid address will be returned.
* @since 1.0
* @version 1.0
*/
SvcIdentity SAMGR_GetRemoteIdentity(const char *service, const char *feature);
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif
#endif // LITE_IPROXY_CLIENT_H
/** @} */

View File

@ -0,0 +1,144 @@
/*
* 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.
*/
/**
* @addtogroup Registry
* @{
*
* @brief Provides APIs for registering and discovering inter-process communication (IPC)
* capabilities.
*
* Based on the Samgr development framework, this module helps you to develop system capabilities
* and implement cross-process calls. \n
* This module is used when system capabilities need to be provided across processes. \n
*
* @since 1.0
* @version 1.0
*/
/**
* @file iproxy_server.h
*
* @brief Provides the server proxy.
*
* This feature is required for providing cross-process system capabilities. \n
*
* @since 1.0
* @version 1.0
*/
#ifndef LITE_IPROXY_SERVER_H
#define LITE_IPROXY_SERVER_H
#include "iunknown.h"
#include "message.h"
#include "serializer.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif
/**
* @brief Defines the default version number of the server proxy.
*
* The cross-process system capabilities are registered when Samgr uses <b>SERVER_PROXY_VER</b>
* to query the registered server proxy. \n
*
*/
#define SERVER_PROXY_VER 0x80
#define SERVER_IMPL_PROXY_VER ((uint16)SERVER_PROXY_VER | (uint16)DEFAULT_VERSION)
/**
* @brief Inherits the server proxy function.
*
* When the server provides cross-process system capabilities, it uses <b>INHERIT_SERVER_IPROXY</b>
* to define the server proxy function. \n
*
*/
#define INHERIT_SERVER_IPROXY \
INHERIT_IUNKNOWN; \
int32 (*Invoke)(IServerProxy *iProxy, int funcId, void *origin, IpcIo *req, IpcIo *reply)
typedef struct IServerProxy IServerProxy;
/**
* @brief Defines the base class of the server proxy object.
*
* When the server provides cross-process system capabilities, it uses <b>INHERIT_SERVER_IPROXY</b>
* to define the server proxy. \n
*/
struct IServerProxy {
/** This class inherits from <b>IUnknown</b>. */
INHERIT_IUNKNOWN;
/**
* @brief Unmarshals the IPC message received by the server.
*
* This function is implemented by developers and called by the system. \n
* This function runs in the message processing thread of the service. Do not block the message
* processing thread; otherwise, the function may fail to be executed. \n
*
* @param Proxy Indicates the pointer to the server proxy object.
* @param funcId Indicates the ID of the server function to be invoked by the client.
* @param origin Indicates the original IPC message, from which the header information can be
* obtained.
* @param req ipc Indicates the message body, from which data can be obtained.
* @param reply Indicates the output parameter, which is used to respond to the message.
* The value can contain a maximum of five objects and 200 bytes.
* @return Returns <b>EC_SUCCESS</b> if the unmarshalling is successful; returns other error
* codes if the unmarshalling fails.
* @since 1.0
* @version 1.0
*/
int32 (*Invoke)(IServerProxy *iProxy, int funcId, void *origin, IpcIo *req, IpcIo *reply);
};
/**
* @brief Inherits the server proxy class.
*
* When the server provides cross-process system capabilities, it uses <b>INHERIT_IPROXY_ENTRY</b>
* to define the server proxy class. \n
*
*/
#define INHERIT_IPROXY_ENTRY(T) INHERIT_IUNKNOWNENTRY(T)
/**
* @brief Defines the beginning of the default initialization for the server proxy class.
*
* This macro is used for developing the server proxy class. You can inherit this macro to
* reduce the code amount and prevent class definition inconsistency. \n
*
*/
#define SERVER_IPROXY_BEGIN IUNKNOWN_ENTRY_BEGIN(SERVER_PROXY_VER)
#define SERVER_IPROXY_IMPL_BEGIN IUNKNOWN_ENTRY_BEGIN(SERVER_IMPL_PROXY_VER)
/**
* @brief Defines the end of the default initialization for the server proxy class.
*
* This macro is used for developing the server proxy class. You can inherit this macro to
* reduce the code amount and prevent class definition inconsistency. \n
*
*/
#define IPROXY_END IUNKNOWN_ENTRY_END
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif
#endif // LITE_IPROXY_SERVER_H
/** @} */

View File

@ -0,0 +1,111 @@
/*
* 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.
*/
/**
* @addtogroup Registry
* @{
*
* @brief Provides APIs for registering and discovering inter-process communication (IPC)
* capabilities.
*
* Based on the Samgr development framework, this module helps you to develop system capabilities
* and implement cross-process calls. \n
* This module is used when system capabilities need to be provided across processes. \n
*
* @since 1.0
* @version 1.0
*/
/**
* @file registry.h
*
* @brief Provides basic APIs for remote service registration and discovery.
*
* APIs provided by this file include the factory registration function of the client code. \n
* This file is used when there are customized client objects. \n
*
* @since 1.0
* @version 1.0
*/
#ifndef LITE_REGISTRY_H
#define LITE_REGISTRY_H
#include <ohos_types.h>
#include <iunknown.h>
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif
/**
* @brief Indicates the creator of the customized client proxy.
*
* This macro creates a local client proxy for remote service APIs.
* If you want to call the remote APIs in the way that local APIs are called, implement this macro
* to encapsulate serialized data into the proxy. \n
* The system automatically calls this macro when creating a proxy object. \n
*
* @param service Indicates the pointer to the name of the service to which the function belongs.
* @param feature Indicates the pointer to the name of the feature to which the function belongs.
* @param size Indicates the size of the head to be added when a client proxy is created. The
* required memory capacity is the head size plus the object size.
* @return void * Returns the applied memory capacity and initialize the memory for the client
* proxy.
*/
typedef void *(*Creator)(const char *service, const char *feature, uint32 size);
/**
* @brief Indicates the destroyer of the customized client proxy.
*
* This macro destroys local client proxy for remote service APIs.
* If you want to call the remote APIs in the way that local APIs are called, implement this macro
* to encapsulate serialized data into the proxy. \n
* The system automatically calls this macro when destroying a proxy object. \n
*
* @param service Indicates the pointer to the name of the service to which the function belongs.
* @param feature Indicates the pointer to the name of the feature to which the function belongs.
* @param iproxy Indicates the pointer to the start address of the memory that is applied by
* <b>Creator</b>.
*/
typedef void (*Destroyer)(const char *service, const char *feature, void *iproxy);
/**
* @brief Registers the factory method of the client proxy object with the Samgr.
*
*
* If you want to call the remote APIs in the way that local APIs are called, implement this
* function to encapsulate serialized data into the proxy. \n
* During system initialization, the module that uses the remote proxy calls the function as
* required. \n
*
* @param service Indicates the pointer to the service name of the client proxy.
* @param feature Indicates the pointer to the feature name of the client proxy.
* @param creator Indicates the <b>Creator</b> function of the client proxy.
* @param destroyer Indicates the <b>Destroyer</b> function of the client proxy.
* @return Returns <b>EC_SUCCESS</b> if the registration is successful; returns other error codes
* if the registration fails.
* @since 1.0
* @version 1.0
*/
int SAMGR_RegisterFactory(const char *service, const char *feature, Creator creator, Destroyer destroyer);
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif
#endif // LITE_REGISTRY_H
/** @} */

260
interfaces/kits/samgr/common.h Executable file
View File

@ -0,0 +1,260 @@
/*
* 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.
*/
/**
* @addtogroup Samgr
* @{
*
* @brief Manages system capabilities.
*
* This module provides the development framework base of the service-oriented architecture (SOA).
* You can develop your own abilities based on the Samgr development framework. \n
* This module provides basic models of services, features, and functions, and registration and
* discovery capabilities. \n
*
* @since 1.0
* @version 1.0
*/
/**
* @file common.h
*
* @brief Provides common objects and functions for Samgr and external modules.
*
*
* This file provides simplified vector containers and downcast functions. \n
*
* @since 1.0
* @version 1.0
*/
#ifndef LITE_COMMON_H
#define LITE_COMMON_H
#include "ohos_types.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif
typedef void *MQueueId;
typedef void *MutexId;
typedef void *ThreadId;
/**
* @brief Calculates the offset of the member in the T type.
*
*
*
* @param Indicates the T type.
* @param member Indicates the name of the T member variable.
*
* @since 1.0
* @version 1.0
*/
#define GET_OFFSIZE(T, member) (long)((char *)&(((T *)(0))->member))
/**
* @brief Downcasts the pointer to the T type.
*
*
*
* @param Ptr Indicates the current pointer, which is the address of the T member variable.
* @param T Indicates the target type of the downcast.
* @param member Indicates the name of the {@code Ptr} as a T member variable.
*
* @since 1.0
* @version 1.0
*/
#define GET_OBJECT(Ptr, T, member) (T *)(((char *)(Ptr)) - GET_OFFSIZE(T, member))
/**
* @brief Indicates an invalid vector index. The value is <b>-1</b>.
*
* This macro indicates that the vector operation fails. \n
* <b>INVALID_INDEX</b> is returned if an element cannot be found by {@link VECTOR_Find} or added
* to <b>VECTOR_Add</b>.
*
*/
#define INVALID_INDEX (-1)
typedef void *(*VECTOR_Key)(const void *);
typedef int (*VECTOR_Compare)(const void *, const void *);
/**
* @brief Defines the simplified vector class, which is extended by four elements.
*
*
* This class is applicable to the C language development scenario where the data volume is small
* and dynamic expansion is required. \n
*
*/
typedef struct SimpleVector {
/** Maximum number of data records that can be stored. The initial value is <b>0</b>. */
int16 max;
/** Peak value of the number of stored data records. The initial value is <b>0</b>. */
int16 top;
/** Number of data records that have been released. The initial value is <b>0</b>. */
int16 free;
/** Data storage pointer */
void **data;
/**
* Converts a data element into a key for comparison. The key is provided by users, and the
* default value is <b>NULL</b>.
*/
VECTOR_Key key;
/**
* Compares the sizes of key1 and key2, which are provided by users. The value <b>1</b>
* indicates that key1 is greater than key2, the value <b>0</b> indicates that key1 is equal
* to key2, and the value <b>-1</b> indicates that key1 is less than key2. The default value
* is <b>NULL</b>.
*/
VECTOR_Compare compare;
} Vector;
/**
* @brief Creates or initializes a vector object.
*
* This function is used to create or initialize a vector object. \n
*
* @param key Indicates the pointer to the function provided by users for converting data elements
* into key values. If this function is not provided, set it to <b>NULL</b>.
* @param compare Indicates the pointer to the function for comparing the sizes of two elements.
* If this function is not provided, set it to <b>NULL</b>.
* @return Returns the vector right value object.
* @since 1.0
* @version 1.0
*/
Vector VECTOR_Make(VECTOR_Key key, VECTOR_Compare compare);
/**
* @brief Destruct a vector object.
*
* This function is used to clear the memory applied by the vector after the temporary vector in
* the stack is used. \n
*
* @param vector Indicates the pointer to the vector to clear.
* @since 1.0
* @version 1.0
*/
void VECTOR_Clear(Vector *vector);
/**
* @brief Adds an element to the vector.
*
* This function is used to add an element to the vector. \n
*
* @param vector Indicates the <b>this</b> pointer to the vector.
* @param element Indicates the element to add.
* @return Returns the location of the element to be added if the operation is successful; returns
* {@link INVALID_INDEX} if the operation fails.
* @since 1.0
* @version 1.0 */
int16 VECTOR_Add(Vector *vector, void *element);
/**
* @brief Obtains the number of elements in the vector, including elements that have been set to
* <b>NULL</b>.
*
* This function is used for full traversal. \n
*
* @param vector Indicates the <b>this</b> pointer to the vector.
* @return Returns the top value of the vector, which indicates the number of elements.
* @since 1.0
* @version 1.0
*/
int16 VECTOR_Size(Vector *vector);
/**
* @brief Obtains the number of valid elements in the vector, excluding elements that have been set
* to <b>NULL</b>.
*
* This function is used to check whether the number of elements reaches the upper limit. \n
*
* @param vector Indicates the <b>this</b> pointer to the vector.
* @return Returns the top - free value of the vector, which indicates the number of non-null
* elements.
* @since 1.0
* @version 1.0
*/
int16 VECTOR_Num(Vector *vector);
/**
* @brief Obtains the element at a specified position.
*
* This function is used to obtain the element at a specified position.
*
* @param vector Indicates the <b>this</b> pointer to the vector.
* @param index Indicates the subscript to be obtained.
* @return Returns the element if obtained; returns <b>NULL</b> otherwise.
* @since 1.0
* @version 1.0
*/
void *VECTOR_At(Vector *vector, int16 index);
/**
* @brief Swaps the element at a specified position in a vector with another element.
*
* This function is used to clear, sort, or update elements in the vector. \n
*
* @param vector Indicates the <b>this</b> pointer to the vector.
* @param index Indicates the position of the element to be swapped.
* @param element Indicates the pointer to the new element.
* @attention Before using this function, ensure that the index is valid. You can use
* <b>VECTOR_Size</b> to obtain the upper limit of the index.
* @return Returns the original element if the swapping is successful; returns <b>NULL</b>
* if the swapping fails.
* @see VECTOR_Size
* @since 1.0
* @version 1.0
*/
void *VECTOR_Swap(Vector *vector, int16 index, void *element);
/**
* @brief Checks the position of an element.
*
* This function is used to check whether a vector has a specified element. \n
*
* @param vector Indicates the <b>this</b> pointer to the vector.
* @param element Indicates the element to be checked.
* @return Returns the index of the element that is not less than 0 if the check is successful;
* returns {@link INVALID_INDEX} if the check fails.
* @since 1.0
* @version 1.0
*/
int16 VECTOR_Find(Vector *vector, const void *element);
/**
* @brief Checks the position of the element with a specified key.
*
* This function is used to check an element based on its key value. \n
*
* @param vector Indicates the <b>this</b> pointer to the vector.
* @param key Indicates the pointer to the key value of the element to check.
* @return Returns the index of the key element that is not less than 0 if the check is successful;
* returns {@link INVALID_INDEX} if the check fails.
* @since 1.0
* @version 1.0
*/
int16 VECTOR_FindByKey(Vector *vector, const void *key);
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif
#endif // LITE_COMMON_H
/** @} */

145
interfaces/kits/samgr/feature.h Executable file
View File

@ -0,0 +1,145 @@
/*
* 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.
*/
/**
* @addtogroup Samgr
* @{
*
* @brief Manages system capabilities.
*
* This module provides the development framework base of the service-oriented architecture (SOA).
* You can develop your own abilities based on the Samgr development framework. \n
* This module provides basic models of services, features, and functions, and registration and
* discovery capabilities. \n
*
* @since 1.0
* @version 1.0
*/
/**
* @file feature.h
*
* @brief Defines the base class of a feature.
*
* This class is used to develop service features. \n
* It provides functions for the feature lifecycle of a service. \n
*
* @since 1.0
* @version 1.0
*/
#ifndef LITE_FEATURE_H
#define LITE_FEATURE_H
#include "message.h"
#include "service.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif
typedef struct Feature Feature;
/**
* @brief Defines the base class of a feature.
*
* You need to implement the pointer to the feature. \n
*
* @since 1.0
* @version 1.0
*/
struct Feature {
/**
* @brief Obtains a feature name.
*
* This function is implemented by developers and called by Samgr during feature registration
* and startup. \n
*
* @param feature Indicates the pointer to the feature.
* @return Returns a constant character string less than 16 bytes if the operation is
* successful; returns <b>NULL</b> if the operation fails.
*
* @since 1.0
* @version 1.0
*/
const char *(*GetName)(Feature *feature);
/**
* @brief Initializes a feature.
*
* This function is implemented by developers. After Samgr dispatches tasks to a service, the
* service calls this function in its own tasks. \n
*
* @param feature Indicates the pointer to the feature.
* @param parent Indicates the pointer to the {@link Service} to which the feature belongs.
* @param identity Indicates the identity of a feature dispatched by the system.
*
* @since 1.0
* @version 1.0
*/
void (*OnInitialize)(Feature *feature, Service *parent, Identity identity);
/**
* @brief Stops a feature.
*
* This function is implemented by developers and is called by Samgr when a feature is
* deregistered to stop running services. \n
*
* @param feature Indicates the pointer to the feature.
* @param identity Indicates the {@link Identity} of the feature to be stopped.
* @since 1.0
* @version 1.0
*/
void (*OnStop)(Feature *feature, Identity identity);
/**
* @brief Processes a feature message.
*
* This function is implemented by developers to process requests sent by callers through
* IUnknown. \n
*
* @param feature Indicates the pointer to the feature.
* @param request Indicates the request message.
* @return Returns <b>TRUE</b> if the processing is successful; returns <b>FALSE</b> if
* the processing fails.
*
* @since 1.0
* @version 1.0
*/
BOOL (*OnMessage)(Feature *feature, Request *request);
};
/**
* @brief Inherits from the macro of the feature class.
*
* This macro provides the capability of inheriting the feature lifecycle. \n
*
*/
#define INHERIT_FEATURE \
const char *(*GetName)(Feature *feature); \
void (*OnInitialize)(Feature *feature, Service *parent, Identity identity); \
void (*OnStop)(Feature *feature, Identity identity); \
BOOL (*OnMessage)(Feature *feature, Request *request)
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif
#endif // LITE_FEATURE_H
/** @} */

250
interfaces/kits/samgr/iunknown.h Executable file
View File

@ -0,0 +1,250 @@
/*
* 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.
*/
/**
* @addtogroup Samgr
* @{
*
* @brief Manages system capabilities.
*
* This module provides the development framework base of the service-oriented architecture (SOA).
* You can develop your own abilities based on the Samgr development framework. \n
* This module provides basic models of services, features, and functions, and registration and
* discovery capabilities. \n
*
* @since 1.0
* @version 1.0
*/
/**
* @file iunknown.h
*
* @brief Provides the base class and default implementation for external functions of system capabilities.
*
* @since 1.0
* @version 1.0
*/
#ifndef LITE_IUNKOWN_H
#define LITE_IUNKOWN_H
#include "common.h"
#include "ohos_errno.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif
typedef struct IUnknown IUnknown;
/**
* @brief Defines the default IUnknown version. You can customize the version.
*
* The <b>IUnknown</b> interface of the default version can be called only in the current process.
* Inter-process communication is not supported. \n
*
* @since 1.0
* @version 1.0
*/
#define DEFAULT_VERSION 0x20
/**
* @brief Defines the macro for inheriting the <b>IUnknown</b> interface.
*
* When developing a subclass of the <b>IUnknown</b> class, you can use this macro to inherit the
* structures of the <b>IUnknown</b> interface. \n
*
*/
#define INHERIT_IUNKNOWN \
int (*QueryInterface)(IUnknown *iUnknown, int version, void **target); \
int (*AddRef)(IUnknown *iUnknown); \
int (*Release)(IUnknown *iUnknown)
/**
* @brief Defines the macro for inheriting the classes that implement the <b>IUnknown</b>
* interface.
*
* When developing a subclass of a class that implements the <b>IUnknown</b> interface, you can use
* this macro to inherit the structures of the <b>IUnknown</b> implementation class. \n
*
*/
#define INHERIT_IUNKNOWNENTRY(T) \
uint16 ver; \
int16 ref; \
T iUnknown
/**
* @brief Defines the default marco for initializing the <b>IUnknown</b> interface.
*
* When creating a subclass object of the <b>IUnknown</b> interface, you can use this macro to
* initialize members of the <b>IUnknown</b> interface to their default values. \n
*
*/
#define DEFAULT_IUNKNOWN_IMPL \
.QueryInterface = IUNKNOWN_QueryInterface, \
.AddRef = IUNKNOWN_AddRef, \
.Release = IUNKNOWN_Release
/**
* @brief Defines the macro for initializing the classes that implement the <b>IUnknown</b>
* interface.
*
* When creating a subclass object of a class that implements the <b>IUnknown</b> interface, you
* can use this macro to initialize members of the <b>IUnknown</b> implementation class to their
* default values. \n
* You need to add the initialization of the customized member variable. \n
*
*/
#define IUNKNOWN_ENTRY_BEGIN(version) \
.ver = (version), \
.ref = 1, \
.iUnknown = { \
DEFAULT_IUNKNOWN_IMPL
/**
* @brief IUnknown Defines the end macro for initializing the <b>IUnknown</b> implementation
* object.
*
* This macro is used when a subclass object of the <b>IUnknown</b> implementation class is
* initialized. \n
*
*/
#define IUNKNOWN_ENTRY_END }
#define DEFAULT_IUNKNOWN_ENTRY_BEGIN IUNKNOWN_ENTRY_BEGIN(DEFAULT_VERSION)
#define DEFAULT_IUNKNOWN_ENTRY_END IUNKNOWN_ENTRY_END
/**
* @brief Obtains the pointer of the <b>IUnknown</b> interface object from the subclass object T
* (generic macro) of the <b>IUnknown</b> implementation class.
*
* Use this macro when registering <b>IUnknown</b> interfaces with Samgr so that you can obtain
* the interfaces from the subclass objects of different <b>IUnknown</b> implementation classes. \n
*
* @since 1.0
* @version 1.0
*/
#define GET_IUNKNOWN(T) (IUnknown *)(&((T).iUnknown))
/**
* @brief Defines the <b>IUnknown</b> class.
*
* You need to inherit this structure when developing a subclass of the <b>IUnknown</b> interface. \n
*
*/
struct IUnknown {
/**
* Queries the subclass object of the <b>IUnknown</b> interface of a specified version
* (downcasting).
*/
int (*QueryInterface)(IUnknown *iUnknown, int version, void **target);
/** Adds the reference count. */
int (*AddRef)(IUnknown *iUnknown);
/** Release the reference to an <b>IUnknown</b> interface. */
int (*Release)(IUnknown *iUnknown);
};
/**
* @brief Defines the <b>IUnknown</b> implementation class.
*
* You need to inherit this structure when developing a subclass of the <b>IUnknown</b>
* implementation class. \n
*
* Each <b>IUnknown</b> interface must correspond to one or more <b>IUnknown</b> implementation
* classes. \n
*
*/
typedef struct IUnknownEntry {
/** Version information of <b>IUnknown</b> interface. */
uint16 ver;
/** Reference count of <b>IUnknown</b> interface. */
int16 ref;
/**
* Implementation of <b>IUnknown</b> interface, which is related to the specific definition
* implementation.
*/
IUnknown iUnknown;
} IUnknownEntry;
/**
* @brief Increments the reference count in this <b>IUnknown</b> interface.
*
* This function is called in <b>QueryInterface</b>. Do not call this function in the
* <b>IUnknown<b> interface. \n
*
* When the <b>QueryInterface</b> function is re-implemented, you need to call this function
* in the new <b>QueryInterface</b>.
*
* The system does not provide a lock to protect functions. Therefore, you need to re-implement
* functions if multiple developers are using them. \n
*
* @param iUnknown Indicates the pointer to the <b>IUnknown<b> interface object.
* @return Indicates the number of objects that reference the <b>IUnknown<b> interface.
*
* @since 1.0
* @version 1.0
*/
int IUNKNOWN_AddRef(IUnknown *iUnknown);
/**
* @brief Queries the <b>IUnknown</b> interfaces of a specified version (downcasting).
*
* After obtaining the <b>IUnknown</b> interface object, the function caller uses
* <b>QueryInterface</b> to convert the object to the required subclass type. \n
* The system converts {@link DEFAULT_VERSION} into the subclass type required by the caller.
* If the type conversion requirements cannot be met, you need to re-implement this function. \n
*
* @param iUnknown Indicates the pointer to the <b>IUnknown</b> interface.
* @param version Indicates the version of the <b>IUnknown</b> interface object to be converted.
* @param target Indicates the <b>IUnknown</b> subclass type required by the caller. This is an
* output parameter.
* @return Returns <b>EC_SUCCESS</b> if the conversion is successful; returns other error codes
* if the conversion fails.
*
* @since 1.0
* @version 1.0
*/
int IUNKNOWN_QueryInterface(IUnknown *iUnknown, int ver, void **target);
/**
* @brief Releases a reference to an <b>IUnknown</b> interface that is no longer used.
*
* In the default implementation provided by the system, if the reference count is <b>0</b>,
* the memory of the <b>IUnknown</b> interface object and implementation object is not released. \n
*
* If the memory of the <b>IUnknown</b> interface object and implementation object is dynamically
* allocated, this function needs to be re-implemented. \n
* If the reference count is <b>0</b>, the memory of the <b>IUnknown</b> interface object and
* implementation object is released. \n
*
* @param iUnknown Indicates the pointer to the <b>IUnknown<b> interface object.
* @return Indicates the number of <b>IUnknown<b> interface objects that are referenced after the
* current reference is released.
*
* @since 1.0
* @version 1.0
*/
int IUNKNOWN_Release(IUnknown *iUnknown);
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif
#endif // LITE_IUNKOWN_H
/** @} */

249
interfaces/kits/samgr/message.h Executable file
View File

@ -0,0 +1,249 @@
/*
* 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.
*/
/**
* @addtogroup Samgr
* @{
*
* @brief Manages system capabilities.
*
* This module provides the development framework base of the service-oriented architecture (SOA).
* You can develop your own abilities based on the Samgr development framework. \n
* This module provides basic models of services, features, and functions, and registration and
* discovery capabilities. \n
*
* @since 1.0
* @version 1.0
*/
/**
* @file message.h
*
* @brief Provides message communication APIs that help you to implement asynchronous functions
* of {@link IUnknown}.
*
* This API is used to implement asynchronous functions of {@link IUnknown}. \n
*
* @since 1.0
* @version 1.0
*/
#ifndef LITE_MESSAGE_H
#define LITE_MESSAGE_H
#include "common.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif
typedef struct Identity Identity;
typedef struct Request Request;
typedef struct Response Response;
/**
* @brief Handles asynchronous responses.
*
* This function will be used when a service or feature uses {@link IUnknown} to send a request. \n
* If the caller is a feature, this function is used to handle the response that is sent after the
* feature processes a request. \n
* If the caller is a service, <b>Handler</b> will run in the service thread. \n
*
*/
typedef void (*Handler)(const Request *request, const Response *response);
// Will be used for message interaction, so use one-byte alignment
#pragma pack(1)
/**
* @brief Identifies a service and feature.
*
* You can use this structure to identity a {@link IUnknown} feature to which messages will be
* sent through the asynchronous function of {@link IUnknown}. \n
*
*/
struct Identity {
/** Service ID */
int16 serviceId;
/** Feature ID */
int16 featureId;
/** Message queue ID */
MQueueId queueId;
};
/**
* @brief Defines a request.
*
* You can use this structure to define the request that will be sent to a feature through the
* asynchronous function of {@link IUnknown}. \n
* Request, which is data that is packed to send to a feature. \n
* If the data is not empty and the length is not 0, the system automatically releases the data. \n
*
*/
struct Request {
/** Message ID */
int16 msgId;
/** Data length */
int16 len;
/** Data content */
void *data;
/** Message value, which is defined by developers */
uint32 msgValue;
};
/**
* @brief Defines a response.
*
* This structure is used to send a response after the message processing function of a service
* or feature processes a request. \n
* If the data is not empty and the length is not 0, the system automatically releases the data. \n
*
*/
struct Response {
/** Data content */
void *data;
/** Data length */
int16 len;
};
#pragma pack()
/**
* @brief Sends a request to a service or feature of a specified identity.
*
* This function is called by a service to send messages to its own features through the
* asynchronous function of {@link IUnknown}. \n
*
* @param identity Indicates the pointer to the ID of the feature or service that processes
* the message.
* @param request Indicates the pointer to the request.
* @param handler Indicates the function handling the response. If the value is <b>NULL</b>,
* no response is required.
* @return Returns <b>EC_SUCCESS</b> if the request is sent successfully; returns other error codes
* if the request fails to be sent. The caller needs to release the memory applied in the request.
* @since 1.0
* @version 1.0
*/
int32 SAMGR_SendRequest(const Identity *identity, const Request *request, Handler handler);
/**
* @brief Sends a request to multiple services or features to save memory.
*
* This function is used to publish topics for the {@link Broadcast} service to broadcast messages. \n
*
* @param identity Indicates the pointer to the IDs of services or features, to which requests
* are sent.
* @param request Indicates the pointer to the request.
* @param token Indicates the pointer to reference counting.
* @param handler Indicates the function handling the response. If the value is <b>NULL</b>,
* no response is required.
* @retval Returns the token if the request is sent successfully; returns <b>NULL</b> if the
* request fails to be sent.
* @attention
* <ul><li>Ensure that the thread specified by <b>identity</b> processes the message after
* all messages are sent. Common practice: Add a lock before sending a request and add
* the same lock during processing. </li>
* <li>If <b>NULL</b> is returned, the caller needs to release the memory of the request. </li></ul>
* @since 1.0
* @version 1.0
*/
uint32 *SAMGR_SendSharedRequest(const Identity *identity, const Request *request, uint32 *token, Handler handler);
/**
* @brief Sends a request and response of a caller to the feature thread. The handler is directly
* called to process the request and response without using the message processing functions.
* (Customized function for the broadcast service)
*
* This function is used to publish topics for the {@link Broadcast} service to broadcast messages. \n
* The value of reference counting is incremented by one each time this function is called. \n
*
* @param id Indicates the pointer to the IDs of services or features, to which the request and
* response are sent.
* @param request Indicates the pointer to the request.
* @param resp Indicates the pointer to the response.
* @param ref Indicates the reference counting.
* @param handler Indicates the function for handling the request and response. This parameter
* cannot be <b>NULL</b>.
* @return Returns <b>EC_SUCCESS</b> if the request and response are sent successfully; returns
* other error codes if the request and response fail to be sent.
* @attention
* <ul><li>Ensure that the thread specified by <b>identity</b> processes the message after all
* messages are sent. Common practice: Add a lock before sending a request and add the same lock
* during processing. </li>
* <li>If <b>NULL</b> is returned, the caller needs to release the memory of the request and
* response. </li>
* <li>If the response changes each time when a request is sent, ensure that the response
* will not be released. (Set <b>len</b> to <b>0</b>, the <b>data</b> of response will be
* the resident memory.) </li></ul>
* @since 1.0
* @version 1.0
*/
int32 SAMGR_SendSharedDirectRequest(const Identity *id, const Request *req, const Response *resp, uint32 **ref,
Handler handler);
/**
* @brief Sends a response after processing a request.
*
* This function is called to send a response after processing a request by {@link MessageHandle}
* of a service or {@link OnMessage} of a feature. \n
*
* @param request Indicates the pointer to the original request.
* @param response Indicates the pointer to the response content.
* @return Returns <b>EC_SUCCESS</b> if the response is sent successfully; returns other error
* codes if the response fails to be sent.
* @attention
* <ul><li>This function can be called only in {@link MessageHandle} or {@link OnMessage}. </li>
* <li>The request must be the original one passed from {@link MessageHandle} or
* {@link OnMessage}. Otherwise, a memory exception occurs. </li>
* <li> When the caller sends a request, the <b>handler</b> callback function must be carried. </li>
* <li>The response is sent to the message queue of the service to which the requester belongs
* for processing. Therefore, the requester should wait for the response in non-blocking mode. </li></ul>
* @since 1.0
* @version 1.0
*/
int32 SAMGR_SendResponse(const Request *request, const Response *response);
/**
* @brief Sends a response to a specified service or feature after processing the original request.
* (Customized function for <b>bootstrap</b>)
*
* This function is called to send a response after processing a request by {@link MessageHandle}
* of a service or {@link OnMessage} of a feature. \n
* This function can be customized to implement phased startup of different types of services. \n
*
* @param id Indicates the pointer to the ID of a service or feature. The response is sent to the
* thread of the service or feature for processing.
* @param request Indicates the pointer to the original request.
* @param response Indicates the pointer to the response content.
* @return Returns <b>EC_SUCCESS</b> if the response is sent successfully; returns other error
* codes if the response fails to be sent.
* @attention
* <ul><li>This function can be called only in <b>MessageHandle</b> or <b>OnMessage</b>. </li>
* <li>The request must be the original one passed from <b>MessageHandle</b> or <b>OnMessage</b>.
* Otherwise, a memory exception occurs. </li>
* <li> When the caller sends a request, the <b>handler</b> callback function must be carried. </li>
* <li>The response is sent to the message queue of a specified ID for processing. Therefore,
* wait for the response in non-blocking mode. </li></ul>
* @since 1.0
* @version 1.0
*/
int32 SAMGR_SendResponseByIdentity(const Identity *id, const Request *request, const Response *response);
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif
#endif // LITE_MESSAGE_H
/** @} */

View File

@ -0,0 +1,321 @@
/*
* 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.
*/
/**
* @addtogroup Samgr
* @{
*
* @brief Manages system capabilities.
*
* This module provides the development framework base of the service-oriented architecture (SOA).
* You can develop your own abilities based on the Samgr development framework. \n
* This module provides basic models of services, features, and functions, and registration and
* discovery capabilities. \n
*
* @since 1.0
* @version 1.0
*/
/**
* @file samgr_lite.h
*
* @brief Manages system capabilities.
*
* This is used when services, features, and functions are registered with and discovered by Samgr. \n
*
* @since 1.0
* @version 1.0
*/
#ifndef LITE_SAMGR_H
#define LITE_SAMGR_H
#include "common.h"
#include "iunknown.h"
#include "service.h"
#include "feature.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif
/**
* @brief Starts a bootstrap service, which is used by samgr and implemented by system service
* developers.
*/
#define BOOTSTRAP_SERVICE "Bootstrap"
/**
* @brief Defines the maximun num of system capabilities.
*/
#define MAX_SYSCAP_NUM 512
/**
* @brief Defines the maximun length of the system capabiliy name.
*/
#define MAX_SYSCAP_NAME_LEN 64
/**
* @brief Enumerates the IDs of the message to be processed for starting the bootstrap service.
*
* This function is implemented by developers of the system service. \n
* Messages sent to the bootstrap service when Samgr is started. \n
*
*/
typedef enum BootMessage {
/** Message indicating that the core system service is initialized */
BOOT_SYS_COMPLETED,
/** Message indicating that the system and application-layer services are initialized */
BOOT_APP_COMPLETED,
/** Message indicating service registration during running */
BOOT_REG_SERVICE,
/** Maximum number of message IDs */
BOOTSTRAP_BUTT
} BootMessage;
/**
* @brief Represents the system ability management class.
*
* This class is used for registering and discovering services, features, and functions. \n
*
* @since 1.0
* @version 1.0
*/
typedef struct SamgrLite {
/**
* @brief Registers a service.
*
* You need to call this function in the startup entry of each service. \n
* {@link Service} and {@link Service} structure members to be registered cannot be empty. \n
*
* @param service Indicates the service to be registered.
* @return Returns <b>TRUE</b> if the registration is successful; returns <b>FALSE</b>
* if the registration fails.
* @since 1.0
* @version 1.0
*/
BOOL (*RegisterService)(Service *service);
/**
* @brief Unregisters a service.
*
* You need to call this function when the service is no longer required. \n
*
* @param name Indicates the name of the service to be unregistered.
* @attention Before unregistering the service, you must unregister its features and functions.
* @return Returns the unregistered service object if the unregistration is successful.
* The memory is released by the caller. Returns <b>NULL</b> if the unregistration fails.
* @since 1.0
* @version 1.0
*/
Service *(*UnregisterService)(const char *name);
/**
* @brief Registers a feature.
*
* You need to call this function in the startup entry of each feature. \n
* {@link Feature} and {@link Feature} structure members to be registered cannot be empty. \n
*
* @param feature Indicates the feature to be registered.
* @return Returns <b>TRUE</b> if the registration is successful; returns <b>FALSE</b>
* if the registration fails.
* @since 1.0
* @version 1.0
*/
BOOL (*RegisterFeature)(const char *serviceName, Feature *feature);
/**
* @brief Unregisters a feature.
*
* You need to call this function when the feature is no longer required. \n
*
* @param serviceName Indicates the name of the service whose feature will be unregistered.
* @param featureName Indicates the name of the feature to be unregistered.
* @attention Before unregistering the feature, you must unregister its functions. Otherwise,
* the unregistration fails.
* @return Returns the unregistered feature object if the unregistration is successful.
* The memory is released by the caller. Returns <b>NULL</b> if the unregistration fails.
* @since 1.0
* @version 1.0
*/
Feature *(*UnregisterFeature)(const char *serviceName, const char *featureName);
/**
* @brief Registers the API for the default feature of a service.
*
* You need to call this function after the service is registered. \n
* The pointers to the {@link IUnknown} and {@link IUnknown} members to be registered
* cannot be empty. \n
*
* @param service Indicates the name of the service whose default feature's API will be
* registered.
* @param publicApi Indicates the API to be registered.
* @return Returns <b>TRUE</b> if the registration is successful; returns <b>FALSE</b>
* if the registration fails.
* @since 1.0
* @version 1.0
*/
BOOL (*RegisterDefaultFeatureApi)(const char *service, IUnknown *publicApi);
/**
* @brief Unregisters the API from the default feature of a service.
*
* You need to call this function to unregister {@link IUnknown} if the service to which
* the default feature belongs is no longer required. \n
*
* @param service Indicates the name of the service whose default feature's API will be
* unregistered.
* @return Returns the unregistered function object if the unregistration is successful.
* The memory is released by the caller. Returns <b>NULL</b> if the unregistration fails.
* @since 1.0
* @version 1.0
*/
IUnknown *(*UnregisterDefaultFeatureApi)(const char *service);
/**
* @brief Registers the API for a feature.
*
* You can call this function only if the feature has been registered. \n
* The pointers to the {@link IUnknown} and {@link IUnknown} members to be registered cannot
* be empty. \n
*
* @param service Indicates the name of the service whose API will be registered.
* @param feature Indicates the name of the feature whose API will be registered.
* @param publicApi Indicates the API to be registered.
* @return Returns <b>TRUE</b> if the registration is successful; returns <b>FALSE</b>
* if the registration fails.
* @since 1.0
* @version 1.0
*/
BOOL (*RegisterFeatureApi)(const char *service, const char *feature, IUnknown *publicApi);
/**
* @brief Unregisters the API from a feature.
*
* You must call this function before unregistering the feature no longer required. \n
*
* @param service Indicates the name of the service whose API will be unregistered.
* @param feature Indicates the name of the feature whose API will be unregistered.
* @return Returns the unregistered function object if the unregistration is successful.
* The memory is released by the caller. Returns <b>NULL</b> if the unregistration fails.
* @since 1.0
* @version 1.0
*/
IUnknown *(*UnregisterFeatureApi)(const char *service, const char *feature);
/**
* @brief Obtains the API specific to the default feature.
*
* You need to call this function before using the system capabilities of the service involved. \n
*
*
* @param service Indicates the name of the service to which the default feature belongs.
* @return Returns the <b>IUnknown *</b> object that can be called if the operation is
* successful; returns <b>NULL</b> if the operation fails.
* @since 1.0
* @version 1.0
*/
IUnknown *(*GetDefaultFeatureApi)(const char *service);
/**
* @brief Obtains the API specific to the feature.
*
* You need to call this function before using the system capabilities of the service involved. \n
*
*
* @param service Indicates the name of the service to which the feature belongs.
* @param feature Indicates the name of the feature whose API will be obtained.
* @return Returns the <b>IUnknown *</b> object that can be called if the operation is
* successful; returns <b>NULL</b> if the operation fails.
* @since 1.0
* @version 1.0
*/
IUnknown *(*GetFeatureApi)(const char *serviceName, const char *feature);
/**
* @brief Adds system capablity.
*
* You can call this function to add the system capability. \n
*
* @param sysCap Indicates the name of the system capablity.
* @return Returns <b>EC_SUCCESS</b> if this function is successfully called; returns another error code otherwise.
* @since 1.0
* @version 1.0
*/
int32 (*AddSystemCapability)(const char *sysCap);
/**
* @brief Checks system capability is existed.
*
* You can call this function to check whether the system capability is existed. \n
*
* @param sysCap Indicates the name of the system capablity.
* @return Returns <b>TRUE</b> if the system capablity is existed; returns <b>FALSE</b> otherwise.
* @since 1.0
* @version 1.0
*/
BOOL (*HasSystemCapability)(const char *sysCap);
/**
* @brief Obtains all the available system capabilities.
*
* You need to ensure that there is enough memory to save all available system capabilities
* before call this function. \n
*
* @return Returns <b>EC_SUCCESS</b> if this function is successfully called; returns another error code otherwise.
* the num of available system capabilities saved in sysCapNum and
* all available system capabilities saved in sysCaps.
* @since 1.0
* @version 1.0
*/
int32 (*GetSystemAvailableCapabilities)(char sysCaps[MAX_SYSCAP_NUM][MAX_SYSCAP_NAME_LEN], int32 *sysCapNum);
} SamgrLite;
/**
* @brief Obtains the singleton Samgr instance.
*
* You need to call this function before using the Samgr capabilities. \n
*
* @return Returns the pointer to the singleton instance {@link SamgrLite}.
* @since 1.0
* @version 1.0
*/
SamgrLite *SAMGR_GetInstance(void);
/**
* @brief Starts system services and features.
*
* This function is called in the <b>main</b> function to start all services when an independent
* process is developed. \n
* This function is called after the dynamic library (containing system services and features) is
* loaded during system running. \n
*
* @attention This function cannot be called frequently. Otherwise, problems such as repeated
* service startup may occur. It is recommended that this function be called once in the
* <b>main</b> function or after the dynamic library is loaded.
* @since 1.0
* @version 1.0
*/
void SAMGR_Bootstrap(void);
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif
#endif // LITE_SAMGR_H
/** @} */

225
interfaces/kits/samgr/service.h Executable file
View File

@ -0,0 +1,225 @@
/*
* 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.
*/
/**
* @addtogroup Samgr
* @{
*
* @brief Manages system capabilities.
*
* This module provides the development framework base of the service-oriented architecture (SOA).
* You can develop your own abilities based on the Samgr development framework. \n
* This module provides basic models of services, features, and functions, and registration and
* discovery capabilities. \n
*
* @since 1.0
* @version 1.0
*/
/**
* @file service.h
*
* @brief Provides basic types and constants of services.
*
* This file is mainly used for service development. \n
* This file provides basic capabilities such as lifecycle functions of services, inherited macros,
* and task configuration. \n
*
* @since 1.0
* @version 1.0
*/
#ifndef LITE_SERVICE_H
#define LITE_SERVICE_H
#include "message.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif
typedef struct TaskConfig TaskConfig;
typedef struct Service Service;
/**
* @brief Enumerates task types.
*
* These enumerations are used for configuring the task type. \n
*
* @since 1.0
* @version 1.0
*/
typedef enum TaskType {
/** Tasks shared based on their priority by services */
SHARED_TASK = 0,
/** Task exclusively occupied by a service */
SINGLE_TASK = 1,
/** A specified task shared by multiple services */
SPECIFIED_TASK = 2,
/** No task for the service. Generally, this situation does not occur. */
NO_TASK = 0xFF,
} TaskType;
/**
* @brief Specifies the tag for the task shared by multiple services.
*
* These enumerations are used for specifying a multi-service sharing task. \n
*
* @since 1.0
* @version 1.0
*/
typedef enum SpecifyTag {
/** Preset tag */
LEVEL_HIGH = 0,
/** Preset tag */
LEVEL_MIDDLE = 1,
/** Preset tag */
LEVEL_LOW = 2,
/** Customized tag */
LEVEL_CUSTOM_BEGIN,
} SpecifyTag;
/**
* @brief Enumerates task priority.
*
* These enumerations are used for configuring the task priority. \n
* The valid range of the priority is (9, 39). \n
*
* @since 1.0
* @version 1.0
*/
typedef enum TaskPriority {
/** Low-priority: (9, 15) */
PRI_LOW = 9,
/** Lower than the normal priority: [16, 23) */
PRI_BELOW_NORMAL = 16,
/** Normal priority: [24, 31). The log service is available. */
PRI_NORMAL = 24,
/** Higher than the normal priority: [32, 39). The communication service is available. */
PRI_ABOVE_NORMAL = 32,
/** Upper limit of the priority */
PRI_BUTT = 39,
} TaskPriority;
#pragma pack(1)
/**
* @brief Defines task configurations for a service.
*
* This structure defines task configurations for a service, including the task priority,
* stack size, queue size, task type, and shared task ID. \n
*
*/
struct TaskConfig {
/**
* ID of a multi-service sharing task. For details about the level definition,
* see {@link SpecifyTag}.
*/
int16 level;
/** Task priority. For details about the definition of priority, see {@link TaskPriority}. */
int16 priority;
/** Size of a task stack */
uint16 stackSize;
/** Size of a task queue */
uint16 queueSize;
/** Task type. For details about the taskFlags definition, see {@link TaskType}. */
uint8 taskFlags;
};
#pragma pack()
/**
* @brief Indicates the basic type of a service.
*
* You need to implement the function pointers of <b>Service</b>. \n
*
*/
struct Service {
/**
* @brief Obtains the name of a service.
*
* This function is called by Samgr during service registration and startup. You need to
* implement this function. \n
*
* @param service Indicates the pointer to the service.
* @return Returns a constant string no more than 16 bytes if the service name is obtained
* successfully; returns <b>NULL</b> if the service name fails to be obtained.
* @since 1.0
* @version 1.0 */
const char *(*GetName)(Service *service);
/**
* @brief Initializes the service.
*
* After Samgr assigns tasks to a service, the service calls the function in its own tasks.
* You need to implement this function. \n
*
* @param service Indicates the pointer to the service.
* @param identity Indicates the ID allocated by the system to the service. For details,
* see {@link Identity}.
* @return Returns <b>TRUE</b> if the initialization is successful; returns <b>FALSE</b>
* otherwise.
* @since 1.0
* @version 1.0
*/
BOOL (*Initialize)(Service *service, Identity identity);
/**
* @brief Processes service messages.
*
* This function is used to process requests sent by the caller through {@link IUnknown}.
* You need to implement this function. \n
*
* @param service Indicates the pointer to the service.
* @param request Indicates the pointer to the request data.
* @return Returns <b>TRUE</b> if the message processing is successful; returns <b>FALSE</b>
* if the processing fails.
* @since 1.0
* @version 1.0
*/
BOOL (*MessageHandle)(Service *service, Request *request);
/**
* @brief Obtains task configurations of a service.
*
* This function is used to return task configurations. You need to implement this function. \n
*
* @param service Indicates the pointer to the service.
* @return Returns {@link TaskConfig}.
*
* @since 1.0
* @version 1.0 */
TaskConfig (*GetTaskConfig)(Service *service);
};
/**
* @brief Indicates the macro used to inherit the members from the <b>service</b> class.
*
* This macro provides the capability of inheriting the lifecycle functions of the <b>service</b>
* class. You can use this macro to customize the service structure. \n
*/
#define INHERIT_SERVICE \
const char *(*GetName)(Service * service); \
BOOL (*Initialize)(Service * service, Identity identity); \
BOOL (*MessageHandle)(Service * service, Request * request); \
TaskConfig (*GetTaskConfig)(Service * service)
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif
#endif // LITE_SERVICE_H
/** @} */

View File

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

View File

@ -18,8 +18,8 @@ config("samgr_public") {
include_dirs = [
"adapter",
"registry",
"//foundation/distributedschedule/interfaces/kits/samgr_lite/registry",
"//foundation/distributedschedule/interfaces/kits/samgr_lite/samgr",
"//foundation/distributedschedule/samgr_lite/interfaces/kits/registry",
"//foundation/distributedschedule/samgr_lite/interfaces/kits/samgr",
"//utils/native/lite/include",
]
}
@ -34,14 +34,12 @@ if (ohos_kernel_type == "liteos_m") {
public_configs = [ ":samgr_public" ]
cflags = [ "-Wall" ]
include_dirs = [
"//base/hiviewdfx/interfaces/kits/hilog_lite",
"//kernel/liteos_m/kal/cmsis",
]
include_dirs =
[ "//base/hiviewdfx/hilog_lite/interfaces/native/kits/hilog_lite" ]
public_deps = [
"//foundation/distributedschedule/services/samgr_lite/samgr/adapter:samgr_adapter",
"//foundation/distributedschedule/services/samgr_lite/samgr/source:samgr_source",
"//foundation/distributedschedule/samgr_lite/samgr/adapter:samgr_adapter",
"//foundation/distributedschedule/samgr_lite/samgr/source:samgr_source",
]
}
}
@ -60,12 +58,14 @@ if (ohos_kernel_type == "liteos_a" || ohos_kernel_type == "linux") {
include_dirs = [
"//kernel/liteos_a/kernel/include/",
"//third_party/bounds_checking_function/include",
"//third_party/cJSON",
]
public_deps = [
"//foundation/communication/frameworks/ipc_lite:liteipc_adapter",
"//foundation/distributedschedule/services/samgr_lite/samgr/source:samgr_source",
"//foundation/distributedschedule/services/samgr_lite/samgr_client:client",
"//build/lite/config/component/cJSON:cjson_shared",
"//foundation/communication/ipc_lite:liteipc_adapter",
"//foundation/distributedschedule/samgr_lite/samgr/source:samgr_source",
"//foundation/distributedschedule/samgr_lite/samgr_client:client",
]
public_configs += [ ":external_settings_shared" ]

View File

@ -14,7 +14,7 @@
config("samgr_adapter_public") {
include_dirs = [
"./",
"//foundation/distributedschedule/interfaces/kits/samgr_lite/samgr",
"//foundation/distributedschedule/samgr_lite/interfaces/kits/samgr",
"//utils/native/lite/include",
]
}
@ -34,6 +34,7 @@ if (ohos_kernel_type == "liteos_m") {
include_dirs = [
"//kernel/liteos_m/kal/",
"//kernel/liteos_m/kal/cmsis",
"//kernel/liteos_m/kal/posix/include/malloc.h",
]
}
}

View File

@ -16,6 +16,8 @@
#include <ohos_errno.h>
#include <cmsis_os.h>
#define MS_PER_SECOND 1000
int32 WDT_Start(uint32 ms)
{
return WDT_Reset(ms);
@ -39,5 +41,5 @@ uint64 SAMGR_GetProcessTime(void)
if (ticksPerSecond == 0) {
return 0;
}
return (uint64)tick * 1000 / ticksPerSecond;
return (uint64)tick * MS_PER_SECOND / ticksPerSecond;
}

View File

@ -14,7 +14,6 @@
*/
#include "lock_free_queue.h"
#include <ohos_errno.h>
#include <pthread.h>
#include <securec.h>
#include <memory_adapter.h>

View File

@ -90,4 +90,4 @@ int QUEUE_Destroy(MQueueId queueId)
SAMGR_Free(queue->queue);
SAMGR_Free(queue);
return EC_SUCCESS;
}
}

View File

@ -70,26 +70,13 @@ 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};
int policy = SCHED_OTHER;
const int ROOT_UID = 0;
if (geteuid() == ROOT_UID) {
/*
* Real-time scheduling policy requires superuser privileges.
* Note: additionally, real-time thread can be scheduled before
* normal thread even if it yields CPU using sched_yield().
* To actually yield real-time thread one could
* sleep() rather than yield().
*/
policy = SCHED_RR;
}
#else
struct sched_param sched = {PRI_BUTT - attr->priority};
int policy = SCHED_RR;
#endif
pthread_attr_setschedpolicy(&threadAttr, policy);
pthread_attr_setinheritsched(&threadAttr, PTHREAD_EXPLICIT_SCHED);
pthread_attr_setschedpolicy(&threadAttr, SCHED_RR);
pthread_attr_setschedparam(&threadAttr, &sched);
(void) pthread_once(&g_localKeyOnce, KeyCreate);
pthread_t threadId = 0;

View File

@ -14,7 +14,6 @@
*/
#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)
@ -33,12 +32,23 @@ IUnknown *__attribute__((weak)) SAMGR_FindServiceApi(const char *service, const
return NULL;
}
int __attribute__((weak)) SAMGR_RegisterFactory(const char *service, const char *feature,
Creator creator, Destroyer destroyer)
int32 __attribute__((weak)) SAMGR_RegisterSystemCapabilityApi(const char *sysCap, BOOL isReg)
{
(void)service;
(void)feature;
(void)creator;
(void)destroyer;
return EC_INVALID;
(void)sysCap;
(void)isReg;
return EC_FAILURE;
}
BOOL __attribute__((weak)) SAMGR_QuerySystemCapabilityApi(const char *sysCap)
{
(void)sysCap;
return FALSE;
}
int32 __attribute__((weak)) SAMGR_GetSystemCapabilitiesApi(char sysCaps[MAX_SYSCAP_NUM][MAX_SYSCAP_NAME_LEN],
int32 *size)
{
(void)sysCaps;
(void)size;
return EC_FAILURE;
}

View File

@ -23,10 +23,13 @@
extern "C" {
#endif
#endif
#define MAX_SYSCAP_NUM 512
#define MAX_SYSCAP_NAME_LEN 64
int SAMGR_RegisterServiceApi(const char *service, const char *feature, const Identity *identity, IUnknown *iUnknown);
IUnknown *SAMGR_FindServiceApi(const char *service, const char *feature);
int32 SAMGR_RegisterSystemCapabilityApi(const char *sysCap, BOOL isReg);
BOOL SAMGR_QuerySystemCapabilityApi(const char *sysCap);
int32 SAMGR_GetSystemCapabilitiesApi(char sysCaps[MAX_SYSCAP_NUM][MAX_SYSCAP_NAME_LEN], int32 *size);
#ifdef __cplusplus
#if __cplusplus
}

View File

@ -15,8 +15,8 @@ config("samgr_source_public") {
include_dirs = [
"../adapter",
"../registry",
"//foundation/distributedschedule/interfaces/kits/samgr_lite/registry",
"//foundation/distributedschedule/interfaces/kits/samgr_lite/samgr",
"//foundation/distributedschedule/samgr_lite/interfaces/kits/registry",
"//foundation/distributedschedule/samgr_lite/interfaces/kits/samgr",
"//utils/native/lite/include",
]
}
@ -35,12 +35,11 @@ if (ohos_kernel_type == "liteos_m") {
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/kal/cmsis",
public_deps = [
"//foundation/distributedschedule/samgr_lite/samgr/adapter:samgr_adapter",
]
include_dirs = [ "//base/hiviewdfx/hilog_lite/interfaces/native/kits/hilog_lite" ]
}
}
@ -63,8 +62,8 @@ if (ohos_kernel_type == "liteos_a" || ohos_kernel_type == "linux") {
public_configs = [ ":samgr_source_public" ]
public_deps = [
"//base/hiviewdfx/frameworks/hilog_lite/featured:hilog_shared",
"//foundation/distributedschedule/services/samgr_lite/samgr/adapter:samgr_adapter",
"//base/hiviewdfx/hilog_lite/frameworks/featured:hilog_shared",
"//foundation/distributedschedule/samgr_lite/samgr/adapter:samgr_adapter",
]
include_dirs = [

View File

@ -42,7 +42,9 @@ static BOOL RegisterDefaultFeatureApi(const char *serviceName, IUnknown *publicA
static IUnknown *UnregisterDefaultFeatureApi(const char *serviceName);
static IUnknown *GetDefaultFeatureApi(const char *serviceName);
static IUnknown *GetFeatureApi(const char *serviceName, const char *feature);
static int32 AddSystemCapability(const char *sysCap);
static BOOL HasSystemCapability(const char *sysCap);
static int32 GetSystemAvailableCapabilities(char sysCaps[MAX_SYSCAP_NUM][MAX_SYSCAP_NAME_LEN], int32 *size);
/* **************************************************************************************************
* Samgr Lite location functions
* ************************************************************************************************* */
@ -91,6 +93,9 @@ static void Init(void)
g_samgrImpl.vtbl.UnregisterDefaultFeatureApi = UnregisterDefaultFeatureApi;
g_samgrImpl.vtbl.GetDefaultFeatureApi = GetDefaultFeatureApi;
g_samgrImpl.vtbl.GetFeatureApi = GetFeatureApi;
g_samgrImpl.vtbl.AddSystemCapability = AddSystemCapability;
g_samgrImpl.vtbl.HasSystemCapability = HasSystemCapability;
g_samgrImpl.vtbl.GetSystemAvailableCapabilities = GetSystemAvailableCapabilities;
g_samgrImpl.status = BOOT_SYS;
g_samgrImpl.services = VECTOR_Make((VECTOR_Key)GetServiceName, (VECTOR_Compare)strcmp);
g_samgrImpl.mutex = MUTEX_InitValue();
@ -352,6 +357,30 @@ static IUnknown *GetDefaultFeatureApi(const char *serviceName)
return GetFeatureApi(serviceName, NULL);
}
static int32 AddSystemCapability(const char *sysCap)
{
if (sysCap == NULL || strlen(sysCap) == 0 || strlen(sysCap) > MAX_SYSCAP_NAME_LEN) {
return EC_INVALID;
}
return SAMGR_RegisterSystemCapabilityApi(sysCap, TRUE);
}
static BOOL HasSystemCapability(const char *sysCap)
{
if (sysCap == NULL || strlen(sysCap) == 0 || strlen(sysCap) > MAX_SYSCAP_NAME_LEN) {
return FALSE;
}
return SAMGR_QuerySystemCapabilityApi(sysCap);
}
static int32 GetSystemAvailableCapabilities(char sysCaps[MAX_SYSCAP_NUM][MAX_SYSCAP_NAME_LEN], int32 *sysCapNum)
{
if (sysCaps == NULL || sysCapNum == NULL) {
return EC_INVALID;
}
return SAMGR_GetSystemCapabilitiesApi(sysCaps, sysCapNum);
}
static IUnknown *GetFeatureApi(const char *serviceName, const char *feature)
{
ServiceImpl *serviceImpl = GetService(serviceName);
@ -532,4 +561,4 @@ static TaskPool *GetSpecifiedTaskPool(TaskConfig *config)
}
MUTEX_Unlock(samgr->mutex);
return NULL;
}
}

View File

@ -1,98 +0,0 @@
/*
* 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

@ -1,29 +0,0 @@
/*
* 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

View File

@ -36,7 +36,6 @@ enum InitStatus {
#ifndef MAX_FEATURE_NUM
#define MAX_FEATURE_NUM 0x70
#endif
#pragma pack(1)
typedef struct Operations Operations;
struct Operations {
uint8 abnormal;
@ -54,7 +53,6 @@ struct ServiceImpl {
uint8 inited;
Operations ops;
};
#pragma pack()
inline static BOOL IsInvalidService(Service *service)
{

42
samgr_client/BUILD.gn Executable file → Normal file
View File

@ -12,29 +12,27 @@
# limitations under the License.
source_set("client") {
sources = [
"source/remote_register.c",
]
sources = [ "source/remote_register.c" ]
cflags = [
"-fPIC",
"-Wall"
]
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",
]
include_dirs = [
"../samgr_endpoint/source",
"//foundation/distributedschedule/samgr_lite/interfaces/kits/samgr",
"//foundation/distributedschedule/samgr_lite/interfaces/kits/registry",
"//utils/native/lite/include",
"//kernel/liteos_a/kernel/include",
"//kernel/liteos_a/kernel/common",
"//third_party/bounds_checking_function/include",
"//base/security/permission/services/permission_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",
]
public_deps = [
"//foundation/communication/ipc_lite:liteipc_adapter",
"//foundation/distributedschedule/samgr_lite/samgr_endpoint:endpoint_source",
"//third_party/bounds_checking_function:libsec_shared",
]
}

View File

@ -31,16 +31,12 @@
#define RETRY_INTERVAL 2
#define MAX_RETRY_TIMES 10
#define MAX_POLICY_NUM 8
#define ABILITY_UID_START 100
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;
static BOOL g_isAbilityInited = FALSE;
int __attribute__((weak)) SAMGR_RegisterServiceApi(const char *service, const char *feature,
const Identity *identity, IUnknown *iUnknown)
int SAMGR_RegisterServiceApi(const char *service, const char *feature, const Identity *identity, IUnknown *iUnknown)
{
if (service == NULL) {
return EC_INVALID;
@ -56,8 +52,11 @@ int __attribute__((weak)) SAMGR_RegisterServiceApi(const char *service, const ch
return SAMGR_ProcPolicy(g_remoteRegister.endpoint, &saName, token);
}
IUnknown *__attribute__((weak)) SAMGR_FindServiceApi(const char *service, const char *feature)
IUnknown *SAMGR_FindServiceApi(const char *service, const char *feature)
{
if (service == NULL) {
return NULL;
}
InitializeRegistry();
SaName key = {service, feature};
// the proxy already exits.
@ -65,142 +64,76 @@ IUnknown *__attribute__((weak)) SAMGR_FindServiceApi(const char *service, const
if (index != INVALID_INDEX) {
return VECTOR_At(&g_remoteRegister.clients, index);
}
SvcIdentity identity = QueryRemoteIdentity(service, feature);
if (identity.handle == INVALID_INDEX) {
IUnknown *proxy = SAMGR_CreateIProxy(g_remoteRegister.endpoint->context, service, feature);
if (proxy == NULL) {
return NULL;
}
MUTEX_Lock(g_remoteRegister.mtx);
index = VECTOR_FindByKey(&g_remoteRegister.clients, &key);
if (index != INVALID_INDEX) {
MUTEX_Unlock(g_remoteRegister.mtx);
proxy->Release(proxy);
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);
HILOG_INFO(HILOG_MODULE_SAMGR, "Create remote sa proxy[%p]<%s, %s>!",
proxy, service, feature);
return proxy;
}
static SvcIdentity QueryRemoteIdentity(const char *service, const char *feature)
int32 SAMGR_RegisterSystemCapabilityApi(const char *sysCap, BOOL isReg)
{
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;
InitializeRegistry();
return SAMGR_AddSysCap(g_remoteRegister.endpoint, sysCap, isReg);
}
static int RegisterRemoteIdentity(const char *service, const char *feature, SvcIdentity *saInfo,
PolicyTrans **policy, uint32 *policyNum)
BOOL SAMGR_QuerySystemCapabilityApi(const char *sysCap)
{
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);
InitializeRegistry();
BOOL isReg = FALSE;
if (SAMGR_GetSysCap(g_remoteRegister.endpoint, sysCap, &isReg) != EC_SUCCESS) {
return FALSE;
}
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;
return isReg;
}
static void GetRemotePolicy(IpcIo *reply, PolicyTrans **policy, uint32 *policyNum)
int32 SAMGR_GetSystemCapabilitiesApi(char sysCaps[MAX_SYSCAP_NUM][MAX_SYSCAP_NAME_LEN], int32 *size)
{
if (reply == NULL) {
InitializeRegistry();
return SAMGR_GetSystemCapabilities(g_remoteRegister.endpoint, sysCaps, size);
}
static void ClearRegistry(void)
{
if (g_remoteRegister.endpoint == 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;
}
}
HILOG_INFO(HILOG_MODULE_SAMGR, "Clear Client Registry!");
SAMGR_Free(g_remoteRegister.mtx);
g_remoteRegister.mtx = NULL;
VECTOR_Clear(&(g_remoteRegister.clients));
VECTOR_Clear(&(g_remoteRegister.endpoint->routers));
CloseLiteIpc(g_remoteRegister.endpoint->context);
SAMGR_Free(g_remoteRegister.endpoint);
g_remoteRegister.endpoint = NULL;
}
static void InitializeRegistry(void)
{
if (getuid() >= ABILITY_UID_START && !g_isAbilityInited) {
ClearRegistry();
g_isAbilityInited = TRUE;
}
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);
HILOG_INFO(HILOG_MODULE_SAMGR, "Initialize Client Registry!");
MUTEX_GlobalLock();
if (g_remoteRegister.endpoint == NULL) {
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);
}
MUTEX_GlobalUnlock();
}

86
samgr_endpoint/BUILD.gn Executable file → Normal file
View File

@ -12,58 +12,62 @@
# 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",
]
include_dirs = [
"../samgr/adapter",
"//foundation/distributedschedule/samgr_lite/interfaces/kits/samgr",
"//foundation/distributedschedule/samgr_lite/interfaces/kits/registry",
"//utils/native/lite/include",
"//foundation/communication/ipc_lite/interfaces/kits",
"//third_party/bounds_checking_function/include",
"//base/security/permission/services/permission_lite/ipc_auth/include",
"//kernel/liteos_a/kernel/include/",
"//kernel/liteos_a/kernel/common",
]
}
config("endpoint_internal") {
include_dirs = [ "../samgr/registry" ]
}
source_set("endpoint_source") {
sources = [
"source/client_factory.c",
"source/default_client.c",
"source/endpoint.c",
"source/token_bucket.c"
]
sources = [
"source/client_factory.c",
"source/default_client.c",
"source/endpoint.c",
"source/token_bucket.c",
]
cflags = [
"-fPIC",
"-Wall"
]
cflags = [
"-fPIC",
"-Wall",
]
if (ohos_kernel_type == "linux") {
defines = ["LITE_LINUX_BINDER_IPC"]
}
if (ohos_kernel_type == "linux") {
defines = [ "LITE_LINUX_BINDER_IPC" ]
}
public_configs = [":endpoint_public"]
configs += [ ":endpoint_internal" ]
public_deps = [
"//third_party/bounds_checking_function:libsec_shared",
"//foundation/communication/frameworks/ipc_lite:liteipc_adapter",
"//base/hiviewdfx/frameworks/hilog_lite/featured:hilog_shared",
]
public_configs = [ ":endpoint_public" ]
public_deps = [
"//base/hiviewdfx/hilog_lite/frameworks/featured:hilog_shared",
"//foundation/communication/ipc_lite:liteipc_adapter",
"//third_party/bounds_checking_function:libsec_shared",
]
}
source_set("store_source") {
sources = [
"source/sa_store.c",
]
sources = [ "source/sa_store.c" ]
cflags = [
"-fPIC",
"-Wall"
]
cflags = [
"-fPIC",
"-Wall",
]
public_configs = [":endpoint_public"]
configs += [ ":endpoint_internal" ]
public_deps = [
"//third_party/bounds_checking_function:libsec_shared",
]
public_configs = [ ":endpoint_public" ]
public_deps = [ "//third_party/bounds_checking_function:libsec_shared" ]
}

0
samgr_endpoint/source/client_factory.h Executable file → Normal file
View File

View File

@ -16,16 +16,17 @@
#include <ohos_errno.h>
#include <string.h>
#include <log.h>
#include <service_registry.h>
#include "client_factory.h"
#include "iproxy_client.h"
#include "memory_adapter.h"
#include "thread_adapter.h"
#include "endpoint.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;
@ -51,13 +52,14 @@ 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 SvcIdentity QueryIdentity(const IpcContext *context, const char *service, const char *feature);
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)
IUnknown *SAMGR_CreateIProxy(const IpcContext *context, const char *service, const char *feature)
{
if (g_queryID == NULL) {
SvcIdentity identity = QueryIdentity(context, service, feature);
if (identity.handle == INVALID_INDEX) {
return NULL;
}
@ -84,26 +86,20 @@ IUnknown *SAMGR_CreateIProxy(const IpcContext *context, const char *service, con
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};
IUnknown *iUnknown = SAMGR_FindServiceApi(service, feature);
if (iUnknown == NULL) {
return identity;
}
IClientProxy *proxy = NULL;
if (iUnknown->QueryInterface(iUnknown, CLIENT_PROXY_VER, (void **)&proxy) != EC_SUCCESS || proxy == NULL) {
return identity;
}
struct IDefaultClient *client = GET_OBJECT(proxy, struct IDefaultClient, entry.iUnknown);
identity = client->header.target;
proxy->Release((IUnknown *)proxy);
return identity;
}
@ -175,7 +171,7 @@ static int ProxyInvoke(IClientProxy *proxy, int funcId, IpcIo *request, IOwner o
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);
header->target = QueryIdentity(header->context, header->key.service, header->key.feature);
if (header->target.handle == INVALID_INDEX) {
return EC_INVALID;
}
@ -210,6 +206,9 @@ static int OnServiceExit(const IpcContext *context, void *ipcMsg, IpcIo *data, v
(void)data;
IClientHeader *header = (IClientHeader *)argv;
(void)UnregisterDeathCallback(header->target, header->deadId);
#ifdef __LINUX__
BinderRelease(context, header->target.handle);
#endif
header->deadId = INVALID_INDEX;
header->target.handle = INVALID_INDEX;
header->target.token = INVALID_INDEX;
@ -220,3 +219,39 @@ static int OnServiceExit(const IpcContext *context, void *ipcMsg, IpcIo *data, v
HILOG_ERROR(HILOG_MODULE_SAMGR, "Miss the remote service<%u, %u>!", header->target.handle, header->target.token);
return EC_SUCCESS;
}
static SvcIdentity QueryIdentity(const IpcContext *context, const char *service, const char *feature)
{
IpcIo req;
uint8 data[MAX_DATA_LEN];
IpcIoInit(&req, data, MAX_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(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) {
#ifdef __LINUX__
BinderAcquire(svc->ipcContext, svc->handle);
#endif
target = *svc;
}
}
if (ret == EC_PERMISSION) {
HILOG_INFO(HILOG_MODULE_SAMGR, "Cannot Access<%s, %s> No Permission!", service, feature);
}
if (replyBuf != NULL) {
FreeBuffer(context, replyBuf);
}
return target;
}

View File

@ -28,9 +28,7 @@ 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);
IUnknown *SAMGR_CreateIProxy(const IpcContext *context, const char *service, const char *feature);
SaName *SAMGR_GetSAName(const IUnknown *proxy);
int SAMGR_CompareSAName(const SaName *key1, const SaName *key2);
#ifdef __cplusplus

View File

@ -18,6 +18,7 @@
#include <ohos_errno.h>
#include <service.h>
#include <log.h>
#include "policy_define.h"
#include "iproxy_server.h"
#include "memory_adapter.h"
#include "thread_adapter.h"
@ -28,12 +29,17 @@
#define LOG_TAG "Samgr"
#define LOG_DOMAIN 0xD001800
#ifdef LITE_LINUX_BINDER_IPC
#define MAX_STACK_SIZE 0x100000
#else
#define MAX_STACK_SIZE 0x1000
#endif
#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
#define MAX_POLICY_NUM 8
#ifndef MAX_BUCKET_RATE
#define MAX_BUCKET_RATE 1000
@ -43,6 +49,13 @@
#define MAX_BURST_RATE (MAX_BUCKET_RATE + (MAX_BUCKET_RATE >> 1))
#endif
#ifndef MAX_SYSCAP_NUM
#define MAX_SYSCAP_NUM 512
#endif
#ifndef MAX_SYSCAP_NAME_LEN
#define MAX_SYSCAP_NAME_LEN 64
#endif
#define SAMGR_SERVICE "samgr"
typedef struct Router {
@ -66,16 +79,9 @@ 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;
}
static int RegisterIdentity(const IpcContext *context, const SaName *saName, SvcIdentity *saInfo,
PolicyTrans **policy, uint32 *policyNum);
static void GetRemotePolicy(IpcIo *reply, PolicyTrans **policy, uint32 *policyNum);
Endpoint *SAMGR_CreateEndpoint(const char *name, RegisterEndpoint registry)
{
@ -135,6 +141,144 @@ int SAMGR_AddRouter(Endpoint *endpoint, const SaName *saName, const Identity *id
return index;
}
int32 SAMGR_AddSysCap(const Endpoint *endpoint, const char *sysCap, BOOL isReg)
{
if (endpoint == NULL) {
return EC_INVALID;
}
HILOG_DEBUG(HILOG_MODULE_SAMGR, "SAMGR_AddSysCap begin");
IpcIo req;
uint8 data[MAX_DATA_LEN];
IpcIoInit(&req, data, MAX_DATA_LEN, 0);
IpcIoPushUint32(&req, RES_SYSCAP);
IpcIoPushUint32(&req, OP_PUT);
IpcIoPushString(&req, sysCap);
IpcIoPushBool(&req, isReg);
IpcIo reply;
void *replyBuf = NULL;
SvcIdentity samgr = {SAMGR_HANDLE, SAMGR_TOKEN, SAMGR_COOKIE};
int ret = Transact(endpoint->context, samgr, INVALID_INDEX, &req, &reply,
LITEIPC_FLAG_DEFAULT, (uintptr_t *)&replyBuf);
ret = -ret;
if (ret == LITEIPC_OK) {
ret = IpcIoPopInt32(&reply);
}
if (replyBuf != NULL) {
FreeBuffer(endpoint, replyBuf);
}
HILOG_DEBUG(HILOG_MODULE_SAMGR, "SAMGR_AddSysCap ret = %d", ret);
return ret;
}
int32 SAMGR_GetSysCap(const Endpoint *endpoint, const char *sysCap, BOOL *isReg)
{
if (endpoint == NULL) {
return EC_INVALID;
}
HILOG_DEBUG(HILOG_MODULE_SAMGR, "SAMGR_GetSysCap begin");
IpcIo req;
uint8 data[MAX_DATA_LEN];
IpcIoInit(&req, data, MAX_DATA_LEN, 0);
IpcIoPushUint32(&req, RES_SYSCAP);
IpcIoPushUint32(&req, OP_GET);
IpcIoPushString(&req, sysCap);
IpcIo reply;
void *replyBuf = NULL;
SvcIdentity samgr = {SAMGR_HANDLE, SAMGR_TOKEN, SAMGR_COOKIE};
int ret = Transact(endpoint->context, samgr, INVALID_INDEX, &req, &reply,
LITEIPC_FLAG_DEFAULT, (uintptr_t *)&replyBuf);
ret = -ret;
*isReg = FALSE;
if (ret == LITEIPC_OK) {
ret = IpcIoPopInt32(&reply);
}
if (ret == EC_SUCCESS) {
*isReg = IpcIoPopBool(&reply);
}
if (replyBuf != NULL) {
FreeBuffer(endpoint, replyBuf);
}
HILOG_DEBUG(HILOG_MODULE_SAMGR, "SAMGR_GetSysCap ret = %d", ret);
return ret;
}
static int SendGetAllSysCapsRequest(const Endpoint *endpoint, uint32 startIdx, IpcIo *reply, void **replyBuf)
{
IpcIo req;
uint8 data[MAX_DATA_LEN];
IpcIoInit(&req, data, MAX_DATA_LEN, 0);
IpcIoPushUint32(&req, RES_SYSCAP);
IpcIoPushUint32(&req, OP_ALL);
IpcIoPushUint32(&req, startIdx);
SvcIdentity samgr = {SAMGR_HANDLE, SAMGR_TOKEN, SAMGR_COOKIE};
int ret = Transact(endpoint->context, samgr, INVALID_INDEX, &req, reply,
LITEIPC_FLAG_DEFAULT, (uintptr_t *)replyBuf);
HILOG_DEBUG(HILOG_MODULE_SAMGR, "SendGetAllSysCapsRequest startIdx:%d, ret:%d!", startIdx, ret);
return -ret;
}
static int32 ParseGetAllSysCapsReply(IpcIo *reply, char sysCaps[MAX_SYSCAP_NUM][MAX_SYSCAP_NAME_LEN],
int32 *sysCapNum, BOOL *isEnd, uint32 *nextRequestIdx)
{
int32 ret = IpcIoPopInt32(reply);
if (ret != EC_SUCCESS) {
*isEnd = TRUE;
return ret;
}
*isEnd = IpcIoPopBool(reply);
*nextRequestIdx = IpcIoPopUint32(reply);
uint32 size = IpcIoPopUint32(reply);
size = ((size > MAX_SYSCAP_NUM) ? MAX_SYSCAP_NUM : size);
int cnt = *sysCapNum;
for (int i = 0; i < size; i++) {
int len = 0;
char *sysCap = (char *)IpcIoPopString(reply, &len);
if (sysCap == NULL || len == 0) {
continue;
}
if (strcpy_s(sysCaps[cnt], sizeof(sysCaps[cnt]), sysCap) != EC_SUCCESS) {
continue;
}
cnt++;
}
*sysCapNum = cnt;
return ret;
}
int32 SAMGR_GetSystemCapabilities(const Endpoint *endpoint,
char sysCaps[MAX_SYSCAP_NUM][MAX_SYSCAP_NAME_LEN], int32 *sysCapNum)
{
if (sysCapNum == NULL) {
return EC_INVALID;
}
*sysCapNum = 0;
if (endpoint == NULL) {
return EC_INVALID;
}
HILOG_DEBUG(HILOG_MODULE_SAMGR, "SAMGR_GetSystemCapabilities begin");
IpcIo reply;
void *replyBuf = NULL;
int startIdx = 0;
BOOL isEnd = TRUE;
int ret;
do {
ret = SendGetAllSysCapsRequest(endpoint, startIdx, &reply, &replyBuf);
if (ret == EC_SUCCESS) {
ret = ParseGetAllSysCapsReply(&reply, sysCaps, sysCapNum, &isEnd, &startIdx);
}
if (replyBuf != NULL) {
FreeBuffer(endpoint, replyBuf);
}
} while (isEnd == FALSE && ret == EC_SUCCESS);
HILOG_DEBUG(HILOG_MODULE_SAMGR, "SAMGR_GetSystemCapabilities ret = %d", ret);
return ret;
}
int SAMGR_ProcPolicy(const Endpoint *endpoint, const SaName *saName, int token)
{
if (endpoint == NULL || saName == NULL || token == INVALID_INDEX) {
@ -148,7 +292,7 @@ int SAMGR_ProcPolicy(const Endpoint *endpoint, const SaName *saName, int token)
++retry;
PolicyTrans *policy = NULL;
uint32 policyNum = 0;
ret = g_registerID(saName->service, saName->feature, &saInfo, &policy, &policyNum);
ret = RegisterIdentity(endpoint->context, saName, &saInfo, &policy, &policyNum);
if (ret != EC_SUCCESS || policy == NULL) {
SAMGR_Free(policy);
continue;
@ -156,11 +300,10 @@ int SAMGR_ProcPolicy(const Endpoint *endpoint, const SaName *saName, int token)
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);
SAMGR_Free(policy);
if (ret == EC_SUCCESS) {
SAMGR_Free(policy);
break;
}
SAMGR_Free(policy);
sleep(REGISTER_RETRY_INTERVAL);
}
return ret;
@ -320,8 +463,8 @@ static void HandleIpc(const Request *request, const Response *response)
IpcIo req;
IpcIoInitFromMsg(&req, ipcMsg);
IpcIo reply;
uint8 data[MAX_DATA_LEN];
IpcIoInit(&reply, data, MAX_DATA_LEN, MAX_OBJECT_NUM);
uint8 data[IPC_IO_DATA_MAX];
IpcIoInit(&reply, data, IPC_IO_DATA_MAX, MAX_OBJECT_NUM);
router->proxy->Invoke(router->proxy, request->msgValue, ipcMsg, &req, &reply);
uint32_t flag = 0;
GetFlag(ipcMsg, &flag);
@ -347,12 +490,41 @@ static IServerProxy *GetIServerProxy(const Router *router)
return router->proxy;
}
static int RegisterIdentity(const IpcContext *context, const SaName *saName, SvcIdentity *saInfo,
PolicyTrans **policy, uint32 *policyNum)
{
IpcIo req;
uint8 data[MAX_DATA_LEN];
IpcIoInit(&req, data, MAX_DATA_LEN, 0);
IpcIoPushUint32(&req, RES_FEATURE);
IpcIoPushUint32(&req, OP_PUT);
IpcIoPushString(&req, saName->service);
IpcIoPushBool(&req, saName->feature == NULL);
if (saName->feature != NULL) {
IpcIoPushString(&req, saName->feature);
}
IpcIoPushUint32(&req, saInfo->token);
IpcIo reply;
void *replyBuf = NULL;
SvcIdentity samgr = {SAMGR_HANDLE, SAMGR_TOKEN, SAMGR_COOKIE};
int ret = Transact(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(context, replyBuf);
}
return ret;
}
static int RegisterRemoteFeatures(Endpoint *endpoint)
{
int nums = 0;
if (g_registerID == NULL) {
return nums;
}
int size = VECTOR_Size(&endpoint->routers);
int i;
SvcIdentity identity;
@ -364,8 +536,8 @@ static int RegisterRemoteFeatures(Endpoint *endpoint)
identity.handle = endpoint->identity.handle;
identity.token = i;
int ret = g_registerID(router->saName.service, router->saName.feature, &identity,
&(router->policy), &(router->policyNum));
int ret = RegisterIdentity(endpoint->context, &(router->saName), &identity, &(router->policy),
&(router->policyNum));
if (ret == EC_SUCCESS) {
++nums;
}
@ -446,6 +618,47 @@ static int OnSamgrServerExit(const IpcContext *context, void *ipcMsg, IpcIo *dat
return EC_SUCCESS;
}
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 boolean JudgePolicy(uid_t callingUid, const PolicyTrans *policy, uint32 policyNum)
{
if (policy == NULL) {

View File

@ -16,7 +16,6 @@
#define LITE_ENDPOINT_H
#include <stddef.h>
#include "policy_define.h"
#include "common.h"
#include "iproxy_server.h"
#include "default_client.h"
@ -37,6 +36,7 @@ extern "C" {
typedef enum ResourceID {
RES_ENDPOINT,
RES_FEATURE,
RES_SYSCAP,
RES_BUTT,
} ResourceID;
@ -45,10 +45,9 @@ typedef enum OptionID {
OP_POST,
OP_PUT,
OP_DELETE,
OP_ALL,
} 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;
@ -62,7 +61,6 @@ struct Endpoint {
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);

46
samgr_server/BUILD.gn Executable file → Normal file
View File

@ -12,31 +12,29 @@
# limitations under the License.
shared_library("server") {
sources = [
"source/samgr_server.c",
]
sources = [ "source/samgr_server.c" ]
cflags = [
"-fPIC",
"-Wall"
]
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",
]
include_dirs = [
"../samgr_endpoint/source",
"//foundation/distributedschedule/samgr_lite/interfaces/kits/samgr",
"//foundation/distributedschedule/samgr_lite/interfaces/kits/registry",
"//utils/native/lite/include",
"//kernel/liteos_a/kernel/include/",
"//kernel/liteos_a/kernel/common",
"//third_party/bounds_checking_function/include",
"//base/security/permission/interfaces/innerkits/permission_lite",
"//base/security/permission/services/permission_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",
]
public_deps = [
"//foundation/communication/ipc_lite:liteipc_adapter",
"//foundation/distributedschedule/samgr_lite/samgr:samgr",
"//foundation/distributedschedule/samgr_lite/samgr_endpoint:store_source",
"//third_party/bounds_checking_function:libsec_shared",
]
}

View File

@ -13,12 +13,16 @@
* limitations under the License.
*/
#include "samgr_server.h"
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <ohos_init.h>
#include <ohos_types.h>
#include <ohos_errno.h>
#include <liteipc_adapter.h>
#include <log.h>
#include "cJSON.h"
#include "policy_define.h"
#include "samgr_lite.h"
#include "memory_adapter.h"
@ -34,6 +38,8 @@ typedef int(*ProcFunc)(SamgrServer *server, int32 option, void *origin, IpcIo *r
#define MAX_SA_SIZE 0x100
#define RETRY_TIMES 3
#define RETRY_INTERVAL 1
#define UID_HAP 10000
#define MAX_SYSCAP_NUM_PER_REPLY 118
static const char *GetName(Service *service);
static BOOL Initialize(Service *service, Identity identity);
@ -45,14 +51,13 @@ static int ProcEndpoint(SamgrServer *server, int32 option, void *origin, IpcIo *
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 int ProcSysCap(SamgrServer *server, int32 option, void *origin, IpcIo *req, IpcIo *reply);
static void ParseSysCap(void);
static SamgrServer g_server = {
.GetName = GetName,
@ -67,62 +72,35 @@ static SamgrServer g_server = {
static ProcFunc g_functions[] = {
[RES_ENDPOINT] = ProcEndpoint,
[RES_FEATURE] = ProcFeature,
[RES_SYSCAP] = ProcSysCap,
};
static const char *GetSysCapName(const SysCapImpl *serviceImpl)
{
if (serviceImpl == NULL) {
return NULL;
}
return serviceImpl->name;
}
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);
g_server.sysCapMtx = MUTEX_InitValue();
g_server.sysCapabilitys = VECTOR_Make((VECTOR_Key)GetSysCapName, (VECTOR_Compare)strcmp);
ParseSysCap();
HILOG_INFO(HILOG_MODULE_SAMGR, "InitializeRegistry ParseSysCap size: %d", VECTOR_Size(&(g_server.sysCapabilitys)));
}
SYS_SERVICE_INIT(InitializeRegistry);
int SAMGR_RegisterServiceApi(const char *service, const char *feature, const Identity *identity, IUnknown *iUnknown)
static BOOL CanRequest(const void *origin)
{
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;
pid_t uid = GetCallingUid(origin);
return uid < UID_HAP;
}
static const char *GetName(Service *service)
@ -158,7 +136,7 @@ static BOOL MessageHandle(Service *service, Request *request)
static TaskConfig GetTaskConfig(Service *service)
{
(void)service;
TaskConfig config = {LEVEL_HIGH, PRI_NORMAL, 0x400, 20, SINGLE_TASK};
TaskConfig config = {LEVEL_HIGH, PRI_BUTT - 1, 0x400, 20, SINGLE_TASK}; // Cannot use PRI_BUTT directly, so minus 1
return config;
}
@ -167,7 +145,7 @@ static int32 Invoke(IServerProxy *iProxy, int funcId, void *origin, IpcIo *req,
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) {
if (server == NULL || 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;
}
@ -188,6 +166,9 @@ static int ProcEndpoint(SamgrServer *server, int32 option, void *origin, IpcIo *
if (index == INVALID_INDEX) {
SvcIdentity identity = {(uint32)INVALID_INDEX, (uint32)INVALID_INDEX, (uint32)INVALID_INDEX};
(void)GenServiceHandle(&identity, GetCallingTid(origin));
#ifdef __LINUX__
BinderAcquire(g_server.samgr->context, identity.handle);
#endif
handle.pid = pid;
handle.uid = GetCallingUid(origin);
@ -195,8 +176,8 @@ static int ProcEndpoint(SamgrServer *server, int32 option, void *origin, IpcIo *
handle.deadId = INVALID_INDEX;
(void)SASTORA_SaveHandleByPid(&server->store, handle);
(void)UnregisterDeathCallback(identity, handle.deadId);
(void)RegisterDeathCallback(server->endpoint->context, identity, OnEndpointExit, (void*)((uintptr_t)pid),
&handle.deadId);
(void)RegisterDeathCallback(server->samgr->context, identity, OnEndpointExit, (void*)((uintptr_t)pid),
&handle.deadId);
}
MUTEX_Unlock(server->mtx);
IpcIoPushUint32(reply, handle.handle);
@ -237,7 +218,7 @@ static int32 ProcPutFeature(SamgrServer *server, const void *origin, IpcIo *req,
uint32 policyNum = 0;
int ret = g_server.ipcAuth->GetCommunicationStrategy(regParams, &policy, &policyNum);
if (ret != EC_SUCCESS || policy == NULL) {
MUTEX_Unlock(g_server.mtx);
MUTEX_Unlock(server->mtx);
SAMGR_Free(policy);
HILOG_DEBUG(HILOG_MODULE_SAMGR, "Remote Get Communication Strategy<%s, %s> No Permission<%d>!",
service, feature, ret);
@ -368,57 +349,145 @@ static int ProcFeature(SamgrServer *server, int32 option, void *origin, IpcIo *r
if (option == OP_GET) {
ret = ProcGetFeature(server, origin, req, reply, &identity);
IpcIoPushInt32(reply, ret);
IpcIoPushSvc(reply, &identity);
if (ret == EC_SUCCESS) {
IpcIoPushSvc(reply, &identity);
}
}
return ret;
}
static SvcIdentity QueryLocalIdentity(const char *service, const char *feature)
static int32 ProcAddSysCap(SamgrServer *server, IpcIo *req)
{
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;
size_t len = 0;
char *sysCap = (char *)IpcIoPopString(req, &len);
if (sysCap == NULL || len == 0 || len > MAX_SYSCAP_NAME_LEN) {
HILOG_ERROR(HILOG_MODULE_SAMGR, "ProcAddSysCap sysCap invalid");
return EC_INVALID;
}
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");
MUTEX_Lock(server->sysCapMtx);
Vector *sysCapablitys = &(server->sysCapabilitys);
int16 pos = VECTOR_FindByKey(sysCapablitys, (void *)sysCap);
if (pos < 0) {
MUTEX_Unlock(server->sysCapMtx);
return EC_FAILURE;
}
ret = g_server.ipcAuth->GetCommunicationStrategy(regParams, policy, policyNum);
return ret;
SysCapImpl *serviceImpl = (SysCapImpl *)VECTOR_At(sysCapablitys, pos);
if (serviceImpl == NULL || serviceImpl->name == NULL) {
MUTEX_Unlock(server->sysCapMtx);
return EC_FAILURE;
}
serviceImpl->isRegister = TRUE;
MUTEX_Unlock(server->sysCapMtx);
return EC_SUCCESS;
}
static BOOL ProcGetSysCap(const SamgrServer *server, IpcIo *req)
{
size_t len = 0;
char *sysCap = (char *)IpcIoPopString(req, &len);
if (sysCap == NULL || len == 0 || len > MAX_SYSCAP_NAME_LEN) {
HILOG_ERROR(HILOG_MODULE_SAMGR, "ProcGetSysCap sysCap invalid");
return FALSE;
}
MUTEX_Lock(server->sysCapMtx);
Vector *sysCapablitys = &(server->sysCapabilitys);
int16 pos = VECTOR_FindByKey(sysCapablitys, (void *)sysCap);
if (pos < 0) {
MUTEX_Unlock(server->sysCapMtx);
return FALSE;
}
SysCapImpl *serviceImpl = (SysCapImpl *)VECTOR_At(sysCapablitys, pos);
if (serviceImpl == NULL) {
MUTEX_Unlock(server->sysCapMtx);
return FALSE;
}
BOOL res = (serviceImpl->isRegister == TRUE);
MUTEX_Unlock(server->sysCapMtx);
return res;
}
static int32 GetReplyNumAndNextReqIdx(const Vector *sysCapablitys, int32 startIdx, int32 *nextRequestIdx)
{
int32 registerNum = 0;
int32 size = VECTOR_Num(sysCapablitys);
int32 i = startIdx;
for (; i < size && registerNum < MAX_SYSCAP_NUM_PER_REPLY; i++) {
SysCapImpl *serviceImpl = (SysCapImpl *)VECTOR_At(sysCapablitys, i);
if (serviceImpl->isRegister == FALSE) {
continue;
}
registerNum++;
}
*nextRequestIdx = i;
return registerNum;
}
void ProcGetAllSysCap(const SamgrServer *server, IpcIo *req, IpcIo *reply)
{
uint32_t startIdx = IpcIoPopUint32(req);
MUTEX_Lock(server->sysCapMtx);
Vector *sysCapablitys = &(server->sysCapabilitys);
int32 size = VECTOR_Num(sysCapablitys);
if (size == INVALID_INDEX) {
IpcIoPushInt32(reply, EC_FAILURE);
IpcIoPushBool(reply, TRUE);
IpcIoPushUint32(reply, startIdx);
IpcIoPushUint32(reply, 0);
MUTEX_Unlock(server->sysCapMtx);
return;
}
int32 nextRequestIdx = startIdx;
int32 replyNum = GetReplyNumAndNextReqIdx(sysCapablitys, startIdx, &nextRequestIdx);
HILOG_DEBUG(HILOG_MODULE_SAMGR, "ProcGetAllSysCap replyNum: %d, size: %d, startIdx: %d, nextRequestIdx: %d",
replyNum, size, startIdx, nextRequestIdx);
IpcIoPushInt32(reply, EC_SUCCESS);
// indicate is the last reply
IpcIoPushBool(reply, nextRequestIdx == size);
// indicate is the next start idx
IpcIoPushUint32(reply, nextRequestIdx);
IpcIoPushUint32(reply, replyNum);
int32 cnt = 0;
int32 i = startIdx;
for (; i < size && cnt < replyNum; i++) {
SysCapImpl *serviceImpl = (SysCapImpl *)VECTOR_At(sysCapablitys, i);
if (serviceImpl->isRegister == FALSE) {
continue;
}
IpcIoPushString(reply, serviceImpl->name);
cnt++;
}
MUTEX_Unlock(server->sysCapMtx);
}
static int ProcSysCap(SamgrServer *server, int32 option, void *origin, IpcIo *req, IpcIo *reply)
{
if (CanRequest(origin) == FALSE) {
HILOG_ERROR(HILOG_MODULE_SAMGR, "ProcSysCap no permission");
IpcIoPushInt32(reply, EC_PERMISSION);
return EC_PERMISSION;
}
if (option != OP_PUT && option != OP_GET && option != OP_ALL) {
IpcIoPushInt32(reply, EC_INVALID);
return EC_INVALID;
}
HILOG_DEBUG(HILOG_MODULE_SAMGR, "ProcSysCap option: %d begin", option);
if (option == OP_PUT) {
int32 ret = ProcAddSysCap(server, req);
IpcIoPushInt32(reply, ret);
} else if (option == OP_GET) {
BOOL ret = ProcGetSysCap(server, req);
IpcIoPushInt32(reply, EC_SUCCESS);
IpcIoPushBool(reply, ret);
} else if (option == OP_ALL) {
ProcGetAllSysCap(server, req, reply);
} else {
HILOG_WARN(HILOG_MODULE_SAMGR, "ProcSysCap error option: %d", option);
IpcIoPushInt32(reply, EC_INVALID);
return EC_INVALID;
}
HILOG_DEBUG(HILOG_MODULE_SAMGR, "ProcSysCap end");
return EC_SUCCESS;
}
static int RegisterSamgrEndpoint(const IpcContext* context, SvcIdentity* identity)
@ -439,7 +508,7 @@ static int OnEndpointExit(const IpcContext *context, void* ipcMsg, IpcIo* data,
{
(void)data;
if (ipcMsg != NULL) {
FreeBuffer(g_server.endpoint->context, ipcMsg);
FreeBuffer(context, ipcMsg);
}
pid_t pid = (pid_t)((uintptr_t)argv);
Request request = {0};
@ -455,6 +524,13 @@ static int OnEndpointExit(const IpcContext *context, void* ipcMsg, IpcIo* data,
sleep(RETRY_INTERVAL);
--retry;
}
#ifdef __LINUX__
PidHandle handle;
int err = SASTORA_FindHandleByPid(&g_server.store, pid, &handle);
if (err != INVALID_INDEX) {
BinderRelease(context, handle.handle);
}
#endif
HILOG_ERROR(HILOG_MODULE_SAMGR, "IPC pid<%d> exit! send clean request retry(%d), ret(%d)!", pid, retry, ret);
return EC_SUCCESS;
}
@ -470,3 +546,89 @@ static IpcAuthInterface *GetIpcAuthInterface(void)
(void)iUnknown->QueryInterface(iUnknown, DEFAULT_VERSION, (void **)&ipcAuth);
return ipcAuth;
}
static cJSON *GetJsonStream()
{
const char *path = "/etc/system_capability.json";
struct stat fileInfo;
int32_t size = 0;
if (stat(path, &fileInfo) != 0 || (size = fileInfo.st_size) == 0) {
return NULL;
}
int32_t fp = open(path, O_RDONLY, S_IRUSR);
if (fp < 0) {
return NULL;
}
char *json = (char *)SAMGR_Malloc(size * sizeof(char));
if (json == NULL) {
close(fp);
return NULL;
}
if (read(fp, json, size * sizeof(char)) != size * sizeof(char)) {
SAMGR_Free(json);
close(fp);
return NULL;
}
close(fp);
cJSON *root = cJSON_Parse(json);
SAMGR_Free(json);
json = NULL;
return root;
}
static void ParseSysCap(void)
{
cJSON *root = GetJsonStream();
if (root == NULL) {
HILOG_ERROR(HILOG_MODULE_SAMGR, "ParseSysCap GetJsonStream failed!");
return;
}
cJSON *sysCaps = cJSON_GetObjectItem(root, "systemCapability");
if (!cJSON_IsArray(sysCaps)) {
cJSON_Delete(root);
HILOG_ERROR(HILOG_MODULE_SAMGR, "ParseSysCap format failed!");
return;
}
int32_t size = cJSON_GetArraySize(sysCaps);
int32_t sysCapNum = 0;
for (int32_t i = 0; i < size; i++) {
if (sysCapNum >= MAX_SYSCAP_NUM) {
HILOG_ERROR(HILOG_MODULE_SAMGR, "ParseSycCapMap system capability exceed");
break;
}
cJSON *item = cJSON_GetArrayItem(sysCaps, i);
if (!cJSON_IsObject(item)) {
continue;
}
cJSON *name = cJSON_GetObjectItem(item, "name");
cJSON *isRegister = cJSON_GetObjectItem(item, "register-on-startup");
if (!cJSON_IsString(name) || !cJSON_IsBool(isRegister)) {
continue;
}
char *nameStr = cJSON_GetStringValue(name);
if (VECTOR_FindByKey(&(g_server.sysCapabilitys), nameStr) != INVALID_INDEX) {
HILOG_WARN(HILOG_MODULE_SAMGR, "Duplicate system capability %s register!", nameStr);
continue;
}
SysCapImpl *impl = (SysCapImpl *)SAMGR_Malloc(sizeof(SysCapImpl));
if (impl == NULL) {
continue;
}
if (strcpy_s(impl->name, sizeof(impl->name), cJSON_GetStringValue(name)) != EC_SUCCESS) {
SAMGR_Free(impl);
continue;
}
impl->isRegister = cJSON_IsTrue(isRegister);
if (VECTOR_Add(&(g_server.sysCapabilitys), impl) == INVALID_INDEX) {
SAMGR_Free(impl);
HILOG_ERROR(HILOG_MODULE_SAMGR, "system capability %s register failed!", impl->name);
continue;
}
sysCapNum++;
}
cJSON_Delete(root);
}

View File

@ -27,8 +27,10 @@ extern "C" {
#endif
#endif
#define SAMGR_SERVICE "samgr"
#define MAX_SYSCAP_NAME_LEN 64
typedef struct SamgrServer SamgrServer;
typedef struct SamgrProxy SamgrProxy;
typedef struct SysCapImpl SysCapImpl;
typedef enum MsgId {
MSG_CLEAN,
}MsgId;
@ -41,11 +43,16 @@ struct SamgrServer {
INHERIT_IPROXY_ENTRY(SamgrProxy);
Identity identity;
Endpoint *samgr;
Endpoint *endpoint;
Vector clients;
MutexId mtx;
SAStore store;
IpcAuthInterface *ipcAuth;
MutexId sysCapMtx;
Vector sysCapabilitys;
};
struct SysCapImpl {
char name[MAX_SYSCAP_NAME_LEN + 1];
BOOL isRegister;
};
#ifdef __cplusplus