19c6d7c21Sopenharmony_ci# samgr_lite
29c6d7c21Sopenharmony_ci
39c6d7c21Sopenharmony_ci## Introduction
49c6d7c21Sopenharmony_ci
59c6d7c21Sopenharmony_ciDue to limited platform resources, a unified system ability framework is provided to harmonize differences of hardware architectures (for example, RISC-V, Cortex-M, and Cortex-A), platform resources, and running modes. Two types of hardware platforms (M- and A-core) are defined.
69c6d7c21Sopenharmony_ci
79c6d7c21Sopenharmony_ci-   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).
89c6d7c21Sopenharmony_ci-   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.
99c6d7c21Sopenharmony_ci
109c6d7c21Sopenharmony_ciThis service-oriented system ability framework enables you to develop services, features, and external APIs, and implement multi-service process sharing and service invoking for inter-process communication (IPC). Where:
119c6d7c21Sopenharmony_ci
129c6d7c21Sopenharmony_ci-   M core provides services, features, external APIs, and multi-service process sharing development.
139c6d7c21Sopenharmony_ci-   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.
149c6d7c21Sopenharmony_ci
159c6d7c21Sopenharmony_ci## System Architecture
169c6d7c21Sopenharmony_ci
179c6d7c21Sopenharmony_ciFigure 1 Service-oriented architecture
189c6d7c21Sopenharmony_ci
199c6d7c21Sopenharmony_ci
209c6d7c21Sopenharmony_ci![](figures/en-us_image_0000001128146921.png)
219c6d7c21Sopenharmony_ci
229c6d7c21Sopenharmony_ci-   Provider: a service provider that provides capabilities (external APIs) for the system.
239c6d7c21Sopenharmony_ci-   Consumer: a service consumer that invokes the features (external APIs) provided by the service.
249c6d7c21Sopenharmony_ci-   Samgr: an agency that manages capabilities provided by providers and helps consumers discover providers' capabilities.
259c6d7c21Sopenharmony_ci
269c6d7c21Sopenharmony_ci**Figure 2** Main objects of the system ability framework
279c6d7c21Sopenharmony_ci
289c6d7c21Sopenharmony_ci![](figures/en-us_image_0000001081285004.png)
299c6d7c21Sopenharmony_ci
309c6d7c21Sopenharmony_ci-   SamgrLite: provides service registration and discovery.
319c6d7c21Sopenharmony_ci-   Service: implements lifecycle APIs of the service during service development.
329c6d7c21Sopenharmony_ci-   Feature: implements lifecycle APIs of the feature during feature development.
339c6d7c21Sopenharmony_ci-   IUnknown: implements external APIs for services or features based on **IUnknown**.
349c6d7c21Sopenharmony_ci-   IClientProxy: implements the consumer's proxy to send messages during IPC invoking.
359c6d7c21Sopenharmony_ci-   IServerProxy: implements the provider's proxy during IPC invoking, which needs to be implemented by developers.
369c6d7c21Sopenharmony_ci
379c6d7c21Sopenharmony_ci## Directory Structure
389c6d7c21Sopenharmony_ci
399c6d7c21Sopenharmony_ci**Figure 1** Structure of the source code directory of the system ability framework
409c6d7c21Sopenharmony_ci
419c6d7c21Sopenharmony_ci| Name                                              | Description                                        |
429c6d7c21Sopenharmony_ci| -------------------------------------------------- | -------------------------------------------- |
439c6d7c21Sopenharmony_ci| interfaces/kits/samgr_lite/samgr                   | External APIs of the M- and A-core system ability frameworks.          |
449c6d7c21Sopenharmony_ci| interfaces/kits/samgr_lite/registry                | External APIs for service invocation between A-core processes.           |
459c6d7c21Sopenharmony_ci| interfaces/kits/samgr_lite/communication/broadcast | External APIs of the event broadcast service within M- and A-core processes.  |
469c6d7c21Sopenharmony_ci| services/samgr_lite/samgr/adapter                  | POSIX and CMSIS interface adaptation layer, which is used to harmonize the differences between the APIs of M- and A-core.|
479c6d7c21Sopenharmony_ci| services/samgr_lite/samgr/registry                 | Stub functions for M-core service registration and discovery.                   |
489c6d7c21Sopenharmony_ci| services/samgr_lite/samgr/source                   | Basic code for the M- and A-core system ability frameworks.          |
499c6d7c21Sopenharmony_ci| services/samgr_lite/samgr_client                   | Registration and discovery for service invocation between A-core processes.             |
509c6d7c21Sopenharmony_ci| services/samgr_lite/samgr_server                   | IPC address management and access control for service invocation between A-core processes.  |
519c6d7c21Sopenharmony_ci| services/samgr_lite/samgr_endpoint                 | Packet Rx/Tx management for A-core IPC.                  |
529c6d7c21Sopenharmony_ci| services/samgr_lite/communication/broadcast        | Event broadcast service for M- and A-core processes.                |
539c6d7c21Sopenharmony_ci
549c6d7c21Sopenharmony_ci## Constraints
559c6d7c21Sopenharmony_ci
569c6d7c21Sopenharmony_ci-   The system ability framework is developed using the C programming language.
579c6d7c21Sopenharmony_ci-   Services in the same process use **IUnknown** for invoking. Messages are passed to the service through **IUnknown**.
589c6d7c21Sopenharmony_ci-   The service name and feature name must be constant strings and the length must be less than 16 bytes.
599c6d7c21Sopenharmony_ci-   More-core depends on the Bootstrap service and calls the **OHOS_SystemInit()** function in the system startup function.
609c6d7c21Sopenharmony_ci-   A-core depends on the Samgr library and calls the **SAMGR_Bootstrap()** function in the **main** function.
619c6d7c21Sopenharmony_ci
629c6d7c21Sopenharmony_ci## Developing a Service
639c6d7c21Sopenharmony_ci
649c6d7c21Sopenharmony_ci-   Inherit and redefine a service.
659c6d7c21Sopenharmony_ci
669c6d7c21Sopenharmony_ci    ```
679c6d7c21Sopenharmony_ci    typedef struct ExampleService {
689c6d7c21Sopenharmony_ci        INHERIT_SERVICE;
699c6d7c21Sopenharmony_ci        INHERIT_IUNKNOWNENTRY(DefaultFeatureApi);
709c6d7c21Sopenharmony_ci        Identity identity;
719c6d7c21Sopenharmony_ci    } ExampleService;
729c6d7c21Sopenharmony_ci    ```
739c6d7c21Sopenharmony_ci
749c6d7c21Sopenharmony_ci-   Implement the lifecycle function of the service.
759c6d7c21Sopenharmony_ci
769c6d7c21Sopenharmony_ci    ```
779c6d7c21Sopenharmony_ci    static const char *GetName(Service *service)
789c6d7c21Sopenharmony_ci    {
799c6d7c21Sopenharmony_ci        return EXAMPLE_SERVICE;
809c6d7c21Sopenharmony_ci    }
819c6d7c21Sopenharmony_ci    
829c6d7c21Sopenharmony_ci    static BOOL Initialize(Service *service, Identity identity)
839c6d7c21Sopenharmony_ci    {
849c6d7c21Sopenharmony_ci        ExampleService *example = (ExampleService *)service;
859c6d7c21Sopenharmony_ci        // Save the unique ID of the service, which is used when IUnknown is used to send messages to the service.
869c6d7c21Sopenharmony_ci        example->identity = identity;
879c6d7c21Sopenharmony_ci        return TRUE;
889c6d7c21Sopenharmony_ci    }
899c6d7c21Sopenharmony_ci    static BOOL MessageHandle(Service *service, Request *msg)
909c6d7c21Sopenharmony_ci    {
919c6d7c21Sopenharmony_ci        ExampleService *example = (ExampleService *)service;
929c6d7c21Sopenharmony_ci        switch (msg->msgId) {
939c6d7c21Sopenharmony_ci            case MSG_SYNC:
949c6d7c21Sopenharmony_ci                // Process the service.
959c6d7c21Sopenharmony_ci                break;
969c6d7c21Sopenharmony_ci            default:break;
979c6d7c21Sopenharmony_ci        }
989c6d7c21Sopenharmony_ci        return FALSE;
999c6d7c21Sopenharmony_ci    }
1009c6d7c21Sopenharmony_ci    static TaskConfig GetTaskConfig(Service *service)
1019c6d7c21Sopenharmony_ci    {
1029c6d7c21Sopenharmony_ci        TaskConfig config = {LEVEL_HIGH, PRI_BELOW_NORMAL,
1039c6d7c21Sopenharmony_ci                             0x800, 20, SHARED_TASK};
1049c6d7c21Sopenharmony_ci        return config;
1059c6d7c21Sopenharmony_ci    }
1069c6d7c21Sopenharmony_ci    ```
1079c6d7c21Sopenharmony_ci
1089c6d7c21Sopenharmony_ci-   Create a service object.
1099c6d7c21Sopenharmony_ci
1109c6d7c21Sopenharmony_ci    ```
1119c6d7c21Sopenharmony_ci    static ExampleService g_example = {
1129c6d7c21Sopenharmony_ci        .GetName = GetName,
1139c6d7c21Sopenharmony_ci        .Initialize = Initialize,
1149c6d7c21Sopenharmony_ci        .MessageHandle = MessageHandle,
1159c6d7c21Sopenharmony_ci        .GetTaskConfig = GetTaskConfig,
1169c6d7c21Sopenharmony_ci        SERVER_IPROXY_IMPL_BEGIN,
1179c6d7c21Sopenharmony_ci            .Invoke = NULL,
1189c6d7c21Sopenharmony_ci            .SyncCall = SyncCall,
1199c6d7c21Sopenharmony_ci        IPROXY_END,
1209c6d7c21Sopenharmony_ci    };
1219c6d7c21Sopenharmony_ci    ```
1229c6d7c21Sopenharmony_ci
1239c6d7c21Sopenharmony_ci-   Register the service and API with Samgr.
1249c6d7c21Sopenharmony_ci
1259c6d7c21Sopenharmony_ci    ```
1269c6d7c21Sopenharmony_ci    static void Init(void)
1279c6d7c21Sopenharmony_ci    {
1289c6d7c21Sopenharmony_ci        SAMGR_GetInstance()->RegisterService((Service *)&g_example);
1299c6d7c21Sopenharmony_ci        SAMGR_GetInstance()->RegisterDefaultFeatureApi(EXAMPLE_SERVICE, GET_IUNKNOWN(g_example));
1309c6d7c21Sopenharmony_ci    }
1319c6d7c21Sopenharmony_ci    ```
1329c6d7c21Sopenharmony_ci
1339c6d7c21Sopenharmony_ci-   Define the initializer of the service.
1349c6d7c21Sopenharmony_ci
1359c6d7c21Sopenharmony_ci    ```
1369c6d7c21Sopenharmony_ci    SYSEX_SERVICE_INIT(Init);
1379c6d7c21Sopenharmony_ci    
1389c6d7c21Sopenharmony_ci    ```
1399c6d7c21Sopenharmony_ci
1409c6d7c21Sopenharmony_ci
1419c6d7c21Sopenharmony_ci## Developing a Feature of a Service
1429c6d7c21Sopenharmony_ci
1439c6d7c21Sopenharmony_ci-   Inherit and redefine a feature.
1449c6d7c21Sopenharmony_ci
1459c6d7c21Sopenharmony_ci    ```
1469c6d7c21Sopenharmony_ci    typedef struct DemoFeature {
1479c6d7c21Sopenharmony_ci        INHERIT_FEATURE;
1489c6d7c21Sopenharmony_ci        INHERIT_IUNKNOWNENTRY(DemoApi);
1499c6d7c21Sopenharmony_ci        Identity identity;
1509c6d7c21Sopenharmony_ci        Service *parent;
1519c6d7c21Sopenharmony_ci    } DemoFeature;
1529c6d7c21Sopenharmony_ci    ```
1539c6d7c21Sopenharmony_ci
1549c6d7c21Sopenharmony_ci-   Implement the lifecycle function of the feature.
1559c6d7c21Sopenharmony_ci
1569c6d7c21Sopenharmony_ci    ```
1579c6d7c21Sopenharmony_ci    static const char *FEATURE_GetName(Feature *feature)
1589c6d7c21Sopenharmony_ci    {
1599c6d7c21Sopenharmony_ci        return EXAMPLE_FEATURE;
1609c6d7c21Sopenharmony_ci    }
1619c6d7c21Sopenharmony_ci    
1629c6d7c21Sopenharmony_ci    static void FEATURE_OnInitialize(Feature *feature, Service *parent, Identity identity)
1639c6d7c21Sopenharmony_ci    {
1649c6d7c21Sopenharmony_ci        DemoFeature *demoFeature = (DemoFeature *)feature;
1659c6d7c21Sopenharmony_ci        demoFeature->identity = identity;
1669c6d7c21Sopenharmony_ci        demoFeature->parent = parent;
1679c6d7c21Sopenharmony_ci    }
1689c6d7c21Sopenharmony_ci    
1699c6d7c21Sopenharmony_ci    static void FEATURE_OnStop(Feature *feature, Identity identity)
1709c6d7c21Sopenharmony_ci    {
1719c6d7c21Sopenharmony_ci        g_example.identity.queueId = NULL;
1729c6d7c21Sopenharmony_ci        g_example.identity.featureId = -1;
1739c6d7c21Sopenharmony_ci        g_example.identity.serviceId = -1;
1749c6d7c21Sopenharmony_ci    }
1759c6d7c21Sopenharmony_ci    
1769c6d7c21Sopenharmony_ci    static BOOL FEATURE_OnMessage(Feature *feature, Request *request)
1779c6d7c21Sopenharmony_ci    {
1789c6d7c21Sopenharmony_ci        if (request->msgId == MSG_PROC) {
1799c6d7c21Sopenharmony_ci            Response response = {.data = "Yes, you did!", .len = 0};
1809c6d7c21Sopenharmony_ci            SAMGR_SendResponse(request, &response);
1819c6d7c21Sopenharmony_ci            return TRUE;
1829c6d7c21Sopenharmony_ci        } else {
1839c6d7c21Sopenharmony_ci            if (request->msgId == MSG_TIME_PROC) {
1849c6d7c21Sopenharmony_ci                LOS_Msleep(WAIT_FEATURE_PROC * 10);
1859c6d7c21Sopenharmony_ci                if (request->msgValue) {
1869c6d7c21Sopenharmony_ci                    SAMGR_PrintServices();
1879c6d7c21Sopenharmony_ci                } else {
1889c6d7c21Sopenharmony_ci                    SAMGR_PrintOperations();
1899c6d7c21Sopenharmony_ci                }
1909c6d7c21Sopenharmony_ci                AsyncTimeCall(GET_IUNKNOWN(g_example));
1919c6d7c21Sopenharmony_ci                return FALSE;
1929c6d7c21Sopenharmony_ci            }
1939c6d7c21Sopenharmony_ci        }
1949c6d7c21Sopenharmony_ci        return FALSE;
1959c6d7c21Sopenharmony_ci    }
1969c6d7c21Sopenharmony_ci    ```
1979c6d7c21Sopenharmony_ci
1989c6d7c21Sopenharmony_ci-   Create a feature object.
1999c6d7c21Sopenharmony_ci
2009c6d7c21Sopenharmony_ci    ```
2019c6d7c21Sopenharmony_ci    static DemoFeature g_example = {
2029c6d7c21Sopenharmony_ci        .GetName = FEATURE_GetName,
2039c6d7c21Sopenharmony_ci        .OnInitialize = FEATURE_OnInitialize,
2049c6d7c21Sopenharmony_ci        .OnStop = FEATURE_OnStop,
2059c6d7c21Sopenharmony_ci        .OnMessage = FEATURE_OnMessage,
2069c6d7c21Sopenharmony_ci        DEFAULT_IUNKNOWN_ENTRY_BEGIN,
2079c6d7c21Sopenharmony_ci            .AsyncCall = AsyncCall,
2089c6d7c21Sopenharmony_ci            .AsyncTimeCall = AsyncTimeCall,
2099c6d7c21Sopenharmony_ci            .SyncCall = SyncCall,
2109c6d7c21Sopenharmony_ci            .AsyncCallBack = AsyncCallBack,
2119c6d7c21Sopenharmony_ci        DEFAULT_IUNKNOWN_ENTRY_END,
2129c6d7c21Sopenharmony_ci        .identity = {-1, -1, NULL},
2139c6d7c21Sopenharmony_ci    };
2149c6d7c21Sopenharmony_ci    ```
2159c6d7c21Sopenharmony_ci
2169c6d7c21Sopenharmony_ci-   Register the feature and API with Samgr.
2179c6d7c21Sopenharmony_ci
2189c6d7c21Sopenharmony_ci    ```
2199c6d7c21Sopenharmony_ci    static void Init(void){
2209c6d7c21Sopenharmony_ci        SAMGR_GetInstance()->RegisterFeature(EXAMPLE_SERVICE, (Feature *)&g_example);
2219c6d7c21Sopenharmony_ci        SAMGR_GetInstance()->RegisterFeatureApi(EXAMPLE_SERVICE, EXAMPLE_FEATURE, GET_IUNKNOWN(g_example));
2229c6d7c21Sopenharmony_ci    }
2239c6d7c21Sopenharmony_ci    ```
2249c6d7c21Sopenharmony_ci
2259c6d7c21Sopenharmony_ci-   Define the initializer of the feature.
2269c6d7c21Sopenharmony_ci
2279c6d7c21Sopenharmony_ci    ```
2289c6d7c21Sopenharmony_ci    SYSEX_FEATURE_INIT(Init);
2299c6d7c21Sopenharmony_ci    
2309c6d7c21Sopenharmony_ci    ```
2319c6d7c21Sopenharmony_ci
2329c6d7c21Sopenharmony_ci
2339c6d7c21Sopenharmony_ci## Developing an External API for Intra-Process Communication
2349c6d7c21Sopenharmony_ci
2359c6d7c21Sopenharmony_ci-   Define the **IUnknown** API.
2369c6d7c21Sopenharmony_ci
2379c6d7c21Sopenharmony_ci    ```
2389c6d7c21Sopenharmony_ci    typedef struct DemoApi {
2399c6d7c21Sopenharmony_ci        INHERIT_IUNKNOWN;
2409c6d7c21Sopenharmony_ci        BOOL (*AsyncCall)(IUnknown *iUnknown, const char *buff);
2419c6d7c21Sopenharmony_ci        BOOL (*AsyncTimeCall)(IUnknown *iUnknown);
2429c6d7c21Sopenharmony_ci        BOOL (*SyncCall)(IUnknown *iUnknown, struct Payload *payload);
2439c6d7c21Sopenharmony_ci        BOOL (*AsyncCallBack)(IUnknown *iUnknown, const char *buff, Handler handler);
2449c6d7c21Sopenharmony_ci    } DemoApi;
2459c6d7c21Sopenharmony_ci    ```
2469c6d7c21Sopenharmony_ci
2479c6d7c21Sopenharmony_ci-   Define the reference object of **IUnknown**.
2489c6d7c21Sopenharmony_ci
2499c6d7c21Sopenharmony_ci    ```
2509c6d7c21Sopenharmony_ci    typedef struct DemoRefApi {
2519c6d7c21Sopenharmony_ci        INHERIT_IUNKNOWNENTRY(DemoApi);
2529c6d7c21Sopenharmony_ci    } DemoRefApi;
2539c6d7c21Sopenharmony_ci    ```
2549c6d7c21Sopenharmony_ci
2559c6d7c21Sopenharmony_ci-   Initialize the object of **IUnknown**.
2569c6d7c21Sopenharmony_ci
2579c6d7c21Sopenharmony_ci    ```
2589c6d7c21Sopenharmony_ci    static DemoRefApi api = {
2599c6d7c21Sopenharmony_ci        DEFAULT_IUNKNOWN_ENTRY_BEGIN,
2609c6d7c21Sopenharmony_ci            .AsyncCall = AsyncCall,
2619c6d7c21Sopenharmony_ci            .AsyncTimeCall = AsyncTimeCall,
2629c6d7c21Sopenharmony_ci            .SyncCall = SyncCall,
2639c6d7c21Sopenharmony_ci            .AsyncCallBack = AsyncCallBack,
2649c6d7c21Sopenharmony_ci        DEFAULT_IUNKNOWN_ENTRY_END,
2659c6d7c21Sopenharmony_ci    };
2669c6d7c21Sopenharmony_ci    ```
2679c6d7c21Sopenharmony_ci
2689c6d7c21Sopenharmony_ci-   Register the feature API.
2699c6d7c21Sopenharmony_ci
2709c6d7c21Sopenharmony_ci    ```
2719c6d7c21Sopenharmony_ci    SAMGR_GetInstance()->RegisterFeatureApi(EXAMPLE_SERVICE, EXAMPLE_FEATURE, GET_IUNKNOWN(api));
2729c6d7c21Sopenharmony_ci    
2739c6d7c21Sopenharmony_ci    ```
2749c6d7c21Sopenharmony_ci
2759c6d7c21Sopenharmony_ci
2769c6d7c21Sopenharmony_ci## Invoking a Service in the Same Process
2779c6d7c21Sopenharmony_ci
2789c6d7c21Sopenharmony_ci-   Obtain the external API of the service.
2799c6d7c21Sopenharmony_ci
2809c6d7c21Sopenharmony_ci    ```
2819c6d7c21Sopenharmony_ci    DemoApi *demoApi = NULL;
2829c6d7c21Sopenharmony_ci    IUnknown *iUnknown = SAMGR_GetInstance()->GetFeatureApi(EXAMPLE_SERVICE, EXAMPLE_FEATURE);
2839c6d7c21Sopenharmony_ci    if (iUnknown == NULL) {
2849c6d7c21Sopenharmony_ci        return NULL;
2859c6d7c21Sopenharmony_ci    }
2869c6d7c21Sopenharmony_ci    int result = iUnknown->QueryInterface(iUnknown, DEFAULT_VERSION, (void **)&demoApi);
2879c6d7c21Sopenharmony_ci    if (result != 0 || demoApi == NULL) {
2889c6d7c21Sopenharmony_ci        return NULL;
2899c6d7c21Sopenharmony_ci    }
2909c6d7c21Sopenharmony_ci    ```
2919c6d7c21Sopenharmony_ci
2929c6d7c21Sopenharmony_ci-   Call the API.
2939c6d7c21Sopenharmony_ci
2949c6d7c21Sopenharmony_ci    ```
2959c6d7c21Sopenharmony_ci    if (demoApi->AsyncCallBack == NULL) {
2969c6d7c21Sopenharmony_ci        return NULL;
2979c6d7c21Sopenharmony_ci    }
2989c6d7c21Sopenharmony_ci    demoApi->AsyncCallBack((IUnknown *)demoApi, "I wanna async call callback good result!", AsyncHandler);
2999c6d7c21Sopenharmony_ci    ```
3009c6d7c21Sopenharmony_ci
3019c6d7c21Sopenharmony_ci-   Release the API.
3029c6d7c21Sopenharmony_ci
3039c6d7c21Sopenharmony_ci    ```
3049c6d7c21Sopenharmony_ci    int32 ref = demoApi->Release((IUnknown *)demoApi);
3059c6d7c21Sopenharmony_ci    
3069c6d7c21Sopenharmony_ci    ```
3079c6d7c21Sopenharmony_ci
3089c6d7c21Sopenharmony_ci
3099c6d7c21Sopenharmony_ci## Developing an External API for IPC
3109c6d7c21Sopenharmony_ci
3119c6d7c21Sopenharmony_ci-   Inherit **IServerProxy** to replace **IUnknown**: INHERIT\_SERVER\_IPROXY
3129c6d7c21Sopenharmony_ci
3139c6d7c21Sopenharmony_ci    ```
3149c6d7c21Sopenharmony_ci    typedef struct DemoFeatureApi {
3159c6d7c21Sopenharmony_ci        INHERIT_SERVER_IPROXY;
3169c6d7c21Sopenharmony_ci        BOOL (*AsyncCall)(IUnknown *iUnknown, const char *buff);
3179c6d7c21Sopenharmony_ci        BOOL (*AsyncTimeCall)(IUnknown *iUnknown);
3189c6d7c21Sopenharmony_ci        BOOL (*SyncCall)(IUnknown *iUnknown, struct Payload *payload);
3199c6d7c21Sopenharmony_ci        BOOL (*AsyncCallBack)(IUnknown *iUnknown, const char *buff, IOwner notify, INotifyFunc handler);
3209c6d7c21Sopenharmony_ci    } DemoFeatureApi;
3219c6d7c21Sopenharmony_ci    ```
3229c6d7c21Sopenharmony_ci
3239c6d7c21Sopenharmony_ci-   Initialize the **IServerProxy** object.
3249c6d7c21Sopenharmony_ci
3259c6d7c21Sopenharmony_ci    ```
3269c6d7c21Sopenharmony_ci    static DemoFeature g_example = {
3279c6d7c21Sopenharmony_ci        SERVER_IPROXY_IMPL_BEGIN,
3289c6d7c21Sopenharmony_ci        .Invoke = Invoke,
3299c6d7c21Sopenharmony_ci        .AsyncCall = AsyncCall,
3309c6d7c21Sopenharmony_ci        .AsyncTimeCall = AsyncTimeCall,
3319c6d7c21Sopenharmony_ci        .SyncCall = SyncCall,
3329c6d7c21Sopenharmony_ci        .AsyncCallBack = AsyncCallBack,
3339c6d7c21Sopenharmony_ci        IPROXY_END,
3349c6d7c21Sopenharmony_ci    };
3359c6d7c21Sopenharmony_ci    ```
3369c6d7c21Sopenharmony_ci
3379c6d7c21Sopenharmony_ci-   Implement the **Invoke** function to process IPC messages.
3389c6d7c21Sopenharmony_ci
3399c6d7c21Sopenharmony_ci    ```
3409c6d7c21Sopenharmony_ci    static int32 Invoke(IServerProxy *iProxy, int funcId, void *origin, IpcIo *req, IpcIo *reply)
3419c6d7c21Sopenharmony_ci    {
3429c6d7c21Sopenharmony_ci        DemoFeatureApi *api = (DemoFeatureApi *)iProxy;
3439c6d7c21Sopenharmony_ci        BOOL ret;
3449c6d7c21Sopenharmony_ci        size_t len = 0;
3459c6d7c21Sopenharmony_ci        switch (funcId) {
3469c6d7c21Sopenharmony_ci            case ID_ASYNCALL:
3479c6d7c21Sopenharmony_ci                ret = api->AsyncCall((IUnknown *)iProxy, (char *)IpcIoPopString(req, &len));
3489c6d7c21Sopenharmony_ci                IpcIoPushBool(reply, ret);
3499c6d7c21Sopenharmony_ci                break;
3509c6d7c21Sopenharmony_ci            case ID_ASYNTIMECALL:
3519c6d7c21Sopenharmony_ci                ret = api->AsyncTimeCall((IUnknown *)iProxy);
3529c6d7c21Sopenharmony_ci                IpcIoPushBool(reply, ret);
3539c6d7c21Sopenharmony_ci                break;
3549c6d7c21Sopenharmony_ci            case ID_SYNCCALL: {
3559c6d7c21Sopenharmony_ci                struct Payload payload;
3569c6d7c21Sopenharmony_ci                payload.id = IpcIoPopInt32(req);
3579c6d7c21Sopenharmony_ci                payload.value = IpcIoPopInt32(req);
3589c6d7c21Sopenharmony_ci                payload.name = (char *)IpcIoPopString(req, &len);
3599c6d7c21Sopenharmony_ci                ret = api->SyncCall((IUnknown *)iProxy, &payload);
3609c6d7c21Sopenharmony_ci                IpcIoPushString(reply, ret ? "TRUE" : "FALSE");
3619c6d7c21Sopenharmony_ci            }
3629c6d7c21Sopenharmony_ci                break;
3639c6d7c21Sopenharmony_ci            case ID_ASYNCCALLBACK: { // convert to sync proxy
3649c6d7c21Sopenharmony_ci                IpcIoPushString(reply, "Yes, you did!");
3659c6d7c21Sopenharmony_ci                IpcIoPushBool(reply, TRUE);
3669c6d7c21Sopenharmony_ci            }
3679c6d7c21Sopenharmony_ci                break;
3689c6d7c21Sopenharmony_ci            default:
3699c6d7c21Sopenharmony_ci                IpcIoPushBool(reply, FALSE);
3709c6d7c21Sopenharmony_ci                break;
3719c6d7c21Sopenharmony_ci        }
3729c6d7c21Sopenharmony_ci        return EC_SUCCESS;
3739c6d7c21Sopenharmony_ci    }
3749c6d7c21Sopenharmony_ci    ```
3759c6d7c21Sopenharmony_ci
3769c6d7c21Sopenharmony_ci-   Register the API. This step is same as the API registration for intra-process communication.
3779c6d7c21Sopenharmony_ci
3789c6d7c21Sopenharmony_ci    ```
3799c6d7c21Sopenharmony_ci    SAMGR_GetInstance()->RegisterFeatureApi(EXAMPLE_SERVICE, EXAMPLE_FEATURE, GET_IUNKNOWN(g_example));
3809c6d7c21Sopenharmony_ci    
3819c6d7c21Sopenharmony_ci    ```
3829c6d7c21Sopenharmony_ci
3839c6d7c21Sopenharmony_ci
3849c6d7c21Sopenharmony_ci## Invoking a Service in Another Process
3859c6d7c21Sopenharmony_ci
3869c6d7c21Sopenharmony_ci-   Obtain the external API of the service in another process.
3879c6d7c21Sopenharmony_ci
3889c6d7c21Sopenharmony_ci    ```
3899c6d7c21Sopenharmony_ci    IClientProxy *demoApi = NULL;
3909c6d7c21Sopenharmony_ci    IUnknown *iUnknown = SAMGR_GetInstance()->GetFeatureApi(EXAMPLE_SERVICE, EXAMPLE_FEATURE);
3919c6d7c21Sopenharmony_ci    if (iUnknown == NULL) {
3929c6d7c21Sopenharmony_ci        return NULL;
3939c6d7c21Sopenharmony_ci    }
3949c6d7c21Sopenharmony_ci    int result = iUnknown->QueryInterface(iUnknown, CLIENT_PROXY_VER, (void **)&demoApi);
3959c6d7c21Sopenharmony_ci    if (result != 0 || demoApi == NULL) {
3969c6d7c21Sopenharmony_ci        return NULL;
3979c6d7c21Sopenharmony_ci    }
3989c6d7c21Sopenharmony_ci    ```
3999c6d7c21Sopenharmony_ci
4009c6d7c21Sopenharmony_ci-   Invoke the API for sending IPC messages.
4019c6d7c21Sopenharmony_ci
4029c6d7c21Sopenharmony_ci    ```
4039c6d7c21Sopenharmony_ci    IpcIo request;char data[250];
4049c6d7c21Sopenharmony_ci    IpcIoInit(&request, data, sizeof(data), 0);
4059c6d7c21Sopenharmony_ci    demoApi->Invoke(demoApi, 0, &request, NULL, NULL);
4069c6d7c21Sopenharmony_ci    ```
4079c6d7c21Sopenharmony_ci
4089c6d7c21Sopenharmony_ci-   Release the API.
4099c6d7c21Sopenharmony_ci
4109c6d7c21Sopenharmony_ci    ```
4119c6d7c21Sopenharmony_ci    int32 ref = demoApi->Release((IUnknown *)demoApi);
4129c6d7c21Sopenharmony_ci    
4139c6d7c21Sopenharmony_ci    ```
4149c6d7c21Sopenharmony_ci
4159c6d7c21Sopenharmony_ci
4169c6d7c21Sopenharmony_ci## Developing a Client Proxy for Inter-Process Service Invocation
4179c6d7c21Sopenharmony_ci
4189c6d7c21Sopenharmony_ci-   Define a client proxy for the IPC API.
4199c6d7c21Sopenharmony_ci
4209c6d7c21Sopenharmony_ci    ```
4219c6d7c21Sopenharmony_ci    typedef struct DemoClientProxy {
4229c6d7c21Sopenharmony_ci        INHERIT_CLIENT_IPROXY;
4239c6d7c21Sopenharmony_ci        BOOL (*AsyncCall)(IUnknown *iUnknown, const char *buff);
4249c6d7c21Sopenharmony_ci        BOOL (*AsyncTimeCall)(IUnknown *iUnknown);
4259c6d7c21Sopenharmony_ci        BOOL (*SyncCall)(IUnknown *iUnknown, struct Payload *payload);
4269c6d7c21Sopenharmony_ci        BOOL (*AsyncCallBack)(IUnknown *iUnknown, const char *buff, IOwner notify, INotifyFunc handler);
4279c6d7c21Sopenharmony_ci    } DemoClientProxy;
4289c6d7c21Sopenharmony_ci    typedef struct DemoClientEntry {
4299c6d7c21Sopenharmony_ci        INHERIT_IUNKNOWNENTRY(DemoClientProxy);
4309c6d7c21Sopenharmony_ci    } DemoClientEntry;
4319c6d7c21Sopenharmony_ci    ```
4329c6d7c21Sopenharmony_ci
4339c6d7c21Sopenharmony_ci-   Enable the client proxy to encapsulate the IPC message API.
4349c6d7c21Sopenharmony_ci
4359c6d7c21Sopenharmony_ci    ```
4369c6d7c21Sopenharmony_ci    static BOOL AsyncCall(IUnknown *iUnknown, const char *buff)
4379c6d7c21Sopenharmony_ci    {
4389c6d7c21Sopenharmony_ci        DemoClientProxy *proxy = (DemoClientProxy *)iUnknown;
4399c6d7c21Sopenharmony_ci        IpcIo request;
4409c6d7c21Sopenharmony_ci        char data[MAX_DATA_LEN];
4419c6d7c21Sopenharmony_ci        IpcIoInit(&request, data, MAX_DATA_LEN, 0);
4429c6d7c21Sopenharmony_ci        IpcIoPushString(&request, buff);
4439c6d7c21Sopenharmony_ci        int ret = proxy->Invoke((IClientProxy *)proxy, ID_ASYNCALL, &request, NULL, NULL);
4449c6d7c21Sopenharmony_ci        return ret == EC_SUCCESS;
4459c6d7c21Sopenharmony_ci    }
4469c6d7c21Sopenharmony_ci    
4479c6d7c21Sopenharmony_ci    static BOOL AsyncTimeCall(IUnknown *iUnknown)
4489c6d7c21Sopenharmony_ci    {
4499c6d7c21Sopenharmony_ci        DemoClientProxy *proxy = (DemoClientProxy *)iUnknown;
4509c6d7c21Sopenharmony_ci        IpcIo request;
4519c6d7c21Sopenharmony_ci        char data[MAX_DATA_LEN];
4529c6d7c21Sopenharmony_ci        IpcIoInit(&request, data, MAX_DATA_LEN, 0);
4539c6d7c21Sopenharmony_ci        int ret = proxy->Invoke((IClientProxy *)proxy, ID_ASYNTIMECALL, &request, NULL, NULL);
4549c6d7c21Sopenharmony_ci        return ret == EC_SUCCESS;
4559c6d7c21Sopenharmony_ci    }
4569c6d7c21Sopenharmony_ci    
4579c6d7c21Sopenharmony_ci    static int Callback(IOwner owner, int code, IpcIo *reply)
4589c6d7c21Sopenharmony_ci    {
4599c6d7c21Sopenharmony_ci        size_t len = 0;
4609c6d7c21Sopenharmony_ci        return strcpy_s(owner, MAX_DATA_LEN, (char *)IpcIoPopString(reply, &len));
4619c6d7c21Sopenharmony_ci    }
4629c6d7c21Sopenharmony_ci    
4639c6d7c21Sopenharmony_ci    static BOOL SyncCall(IUnknown *iUnknown, struct Payload *payload)
4649c6d7c21Sopenharmony_ci    {
4659c6d7c21Sopenharmony_ci        DemoClientProxy *proxy = (DemoClientProxy *)iUnknown;
4669c6d7c21Sopenharmony_ci        IpcIo request;
4679c6d7c21Sopenharmony_ci        char data[MAX_DATA_LEN];
4689c6d7c21Sopenharmony_ci        IpcIoInit(&request, data, MAX_DATA_LEN, 0);
4699c6d7c21Sopenharmony_ci        IpcIoPushInt32(&request, payload->id);
4709c6d7c21Sopenharmony_ci        IpcIoPushInt32(&request, payload->value);
4719c6d7c21Sopenharmony_ci        IpcIoPushString(&request, payload->name);
4729c6d7c21Sopenharmony_ci        int ret = proxy->Invoke((IClientProxy *)proxy, ID_SYNCCALL, &request, data, Callback);
4739c6d7c21Sopenharmony_ci        data[MAX_DATA_LEN - 1] = 0;
4749c6d7c21Sopenharmony_ci        HILOG_INFO(HILOG_MODULE_APP, "[TID:0x%lx]Remote response is %s!", pthread_self(), data);
4759c6d7c21Sopenharmony_ci        return ret == EC_SUCCESS;
4769c6d7c21Sopenharmony_ci    }
4779c6d7c21Sopenharmony_ci    
4789c6d7c21Sopenharmony_ci    struct CurrentNotify {
4799c6d7c21Sopenharmony_ci        IOwner notify;
4809c6d7c21Sopenharmony_ci        INotifyFunc handler;
4819c6d7c21Sopenharmony_ci    };
4829c6d7c21Sopenharmony_ci    
4839c6d7c21Sopenharmony_ci    static int CurrentCallback(IOwner owner, int code, IpcIo *reply)
4849c6d7c21Sopenharmony_ci    {
4859c6d7c21Sopenharmony_ci        struct CurrentNotify *notify = (struct CurrentNotify *)owner;
4869c6d7c21Sopenharmony_ci        size_t len = 0;
4879c6d7c21Sopenharmony_ci        char *response = (char *)IpcIoPopString(reply, &len);
4889c6d7c21Sopenharmony_ci        HILOG_INFO(HILOG_MODULE_APP, "[TID:0x%lx]Notify Remote response is %s!", pthread_self(), response);
4899c6d7c21Sopenharmony_ci        notify->handler(notify->notify, response);
4909c6d7c21Sopenharmony_ci        return EC_SUCCESS;
4919c6d7c21Sopenharmony_ci    }
4929c6d7c21Sopenharmony_ci    
4939c6d7c21Sopenharmony_ci    static BOOL AsyncCallBack(IUnknown *iUnknown, const char *buff, IOwner notify, INotifyFunc handler)
4949c6d7c21Sopenharmony_ci    {
4959c6d7c21Sopenharmony_ci        struct CurrentNotify owner = {notify, handler};
4969c6d7c21Sopenharmony_ci        DemoClientProxy *proxy = (DemoClientProxy *)iUnknown;
4979c6d7c21Sopenharmony_ci        IpcIo request;
4989c6d7c21Sopenharmony_ci        char data[MAX_DATA_LEN];
4999c6d7c21Sopenharmony_ci        IpcIoInit(&request, data, MAX_DATA_LEN, 0);
5009c6d7c21Sopenharmony_ci        IpcIoPushString(&request, buff);
5019c6d7c21Sopenharmony_ci        int ret = proxy->Invoke((IClientProxy *)proxy, ID_ASYNCCALLBACK, &request, &owner, CurrentCallback);
5029c6d7c21Sopenharmony_ci        return ret == EC_SUCCESS;
5039c6d7c21Sopenharmony_ci    }
5049c6d7c21Sopenharmony_ci    ```
5059c6d7c21Sopenharmony_ci
5069c6d7c21Sopenharmony_ci-   Implement the factory method for creating the client proxy.
5079c6d7c21Sopenharmony_ci
5089c6d7c21Sopenharmony_ci    ```
5099c6d7c21Sopenharmony_ci    void *DEMO_CreatClient(const char *service, const char *feature, uint32 size)
5109c6d7c21Sopenharmony_ci    {
5119c6d7c21Sopenharmony_ci        (void)service;
5129c6d7c21Sopenharmony_ci        (void)feature;
5139c6d7c21Sopenharmony_ci        uint32 len = size + sizeof(DemoClientEntry);
5149c6d7c21Sopenharmony_ci        uint8 *client = malloc(len);
5159c6d7c21Sopenharmony_ci        (void)memset_s(client, len, 0, len);
5169c6d7c21Sopenharmony_ci        DemoClientEntry *entry = (DemoClientEntry *)&client[size];
5179c6d7c21Sopenharmony_ci        entry->ver = ((uint16)CLIENT_PROXY_VER | (uint16)DEFAULT_VERSION);
5189c6d7c21Sopenharmony_ci        entry->ref = 1;
5199c6d7c21Sopenharmony_ci        entry->iUnknown.QueryInterface = IUNKNOWN_QueryInterface;
5209c6d7c21Sopenharmony_ci        entry->iUnknown.AddRef = IUNKNOWN_AddRef;
5219c6d7c21Sopenharmony_ci        entry->iUnknown.Release = IUNKNOWN_Release;
5229c6d7c21Sopenharmony_ci        entry->iUnknown.Invoke = NULL;
5239c6d7c21Sopenharmony_ci        entry->iUnknown.AsyncCall = AsyncCall;
5249c6d7c21Sopenharmony_ci        entry->iUnknown.AsyncTimeCall = AsyncTimeCall;
5259c6d7c21Sopenharmony_ci        entry->iUnknown.SyncCall = SyncCall;
5269c6d7c21Sopenharmony_ci        entry->iUnknown.AsyncCallBack = AsyncCallBack;
5279c6d7c21Sopenharmony_ci        return client;
5289c6d7c21Sopenharmony_ci    }
5299c6d7c21Sopenharmony_ci    void DEMO_DestroyClient(const char *service, const char *feature, void *iproxy)
5309c6d7c21Sopenharmony_ci    {
5319c6d7c21Sopenharmony_ci        free(iproxy);
5329c6d7c21Sopenharmony_ci    }
5339c6d7c21Sopenharmony_ci    ```
5349c6d7c21Sopenharmony_ci
5359c6d7c21Sopenharmony_ci-   Register the factory method of the client proxy with Samgr.
5369c6d7c21Sopenharmony_ci
5379c6d7c21Sopenharmony_ci    ```
5389c6d7c21Sopenharmony_ci    SAMGR_RegisterFactory(EXAMPLE_SERVICE, EXAMPLE_FEATURE, DEMO_CreatClient, DEMO_DestroyClient);
5399c6d7c21Sopenharmony_ci    ```
5409c6d7c21Sopenharmony_ci
5419c6d7c21Sopenharmony_ci-   Obtain the external API of the service in another process.
5429c6d7c21Sopenharmony_ci
5439c6d7c21Sopenharmony_ci    ```
5449c6d7c21Sopenharmony_ci    DemoClientProxy *demoApi = NULL;
5459c6d7c21Sopenharmony_ci    IUnknown *iUnknown = SAMGR_GetInstance()->GetFeatureApi(EXAMPLE_SERVICE, EXAMPLE_FEATURE);
5469c6d7c21Sopenharmony_ci    if (iUnknown == NULL) {
5479c6d7c21Sopenharmony_ci        return NULL;
5489c6d7c21Sopenharmony_ci    }
5499c6d7c21Sopenharmony_ci    int result = iUnknown->QueryInterface(iUnknown, DEFAULT_VERSION, (void **)&demoApi);
5509c6d7c21Sopenharmony_ci    if (result != 0 || demoApi == NULL) {
5519c6d7c21Sopenharmony_ci        return NULL;
5529c6d7c21Sopenharmony_ci    }
5539c6d7c21Sopenharmony_ci    ```
5549c6d7c21Sopenharmony_ci
5559c6d7c21Sopenharmony_ci-   Invoke the client proxy API of the service in another process.
5569c6d7c21Sopenharmony_ci
5579c6d7c21Sopenharmony_ci    ```
5589c6d7c21Sopenharmony_ci    if (demoApi->AsyncCallBack == NULL) {
5599c6d7c21Sopenharmony_ci        return NULL;
5609c6d7c21Sopenharmony_ci    }
5619c6d7c21Sopenharmony_ci    demoApi->AsyncCallBack((IUnknown *)demoApi,
5629c6d7c21Sopenharmony_ci                           "I wanna async call callback good result!", NULL, AsyncHandler);
5639c6d7c21Sopenharmony_ci    ```
5649c6d7c21Sopenharmony_ci
5659c6d7c21Sopenharmony_ci-   Release the API.
5669c6d7c21Sopenharmony_ci
5679c6d7c21Sopenharmony_ci    ```
5689c6d7c21Sopenharmony_ci    int32 ref = demoApi->Release((IUnknown *)demoApi);
5699c6d7c21Sopenharmony_ci    ```
5709c6d7c21Sopenharmony_ci
5719c6d7c21Sopenharmony_ci
5729c6d7c21Sopenharmony_ci## Repositories Involved
5739c6d7c21Sopenharmony_ci
5749c6d7c21Sopenharmony_ciSamgr
5759c6d7c21Sopenharmony_ci
5769c6d7c21Sopenharmony_ci[**systemabilitymgr\_samgr\_lite**](https://gitee.com/openharmony/systemabilitymgr_samgr_lite)
5779c6d7c21Sopenharmony_ci
5789c6d7c21Sopenharmony_ci[systemabilitymgr\_samgr](https://gitee.com/openharmony/systemabilitymgr_samgr)
5799c6d7c21Sopenharmony_ci
5809c6d7c21Sopenharmony_ci[systemabilitymgr\_safwk](https://gitee.com/openharmony/systemabilitymgr_safwk)
5819c6d7c21Sopenharmony_ci
5829c6d7c21Sopenharmony_ci[systemabilitymgr\_safwk\_lite](https://gitee.com/openharmony/systemabilitymgr_safwk_lite)
583