README.md
1# samgr\_lite<a name="EN-US_TOPIC_0000001081604584"></a>
2
3- [Introduction](#section11660541593)
4- [Directory Structure](#section1464106163817)
5- [Constraints](#section1718733212019)
6- [Developing a Service](#section159991817144514)
7- [Developing a Feature of a Service](#section11510542164514)
8- [Developing an External API for Intra-Process Communication](#section1685211117463)
9- [Invoking a Service in the Same Process](#section3690162916462)
10- [Developing an External API for IPC](#section9220246194615)
11- [Invoking a Service in Another Process](#section114372711475)
12- [Developing a Client Proxy for Inter-Process Service Invocation](#section09341923114710)
13- [Repositories Involved](#section10365113863719)
14
15## Introduction<a name="section11660541593"></a>
16
17Due 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.
18
19- 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\).
20- 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.
21
22This 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:
23
24- M core provides services, features, external APIs, and multi-service process sharing development.
25- 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.
26
27Service-oriented architecture
28
29
30
31- Provider: a service provider that provides capabilities \(external APIs\) for the system
32- Consumer: a service consumer that invokes the features \(external APIs\) provided by the service
33- Samgr: an agency that manages capabilities provided by providers and helps consumers discover providers' capabilities
34
35Main objects of the SA framework:
36
37
38
39- SamgrLite: provides service registration and discovery.
40- Service: implements lifecycle APIs of the service during service development.
41- Feature: implements lifecycle APIs of the feature during feature development.
42- IUnknown: implements external APIs for services or features based on **IUnknown**.
43- IClientProxy: implements the consumer's proxy to send messages during IPC invoking.
44- IServerProxy: implements the provider's proxy during IPC invoking, which needs to be implemented by developers.
45
46## Directory Structure<a name="section1464106163817"></a>
47
48**Table 1** Structure of the source code directory of the SA framework
49
50<a name="table2977131081412"></a>
51<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>
52</th>
53<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>
54</th>
55</tr>
56</thead>
57<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>
58</td>
59<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>
60</td>
61</tr>
62<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>
63</td>
64<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>
65</td>
66</tr>
67<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>
68</td>
69<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>
70</td>
71</tr>
72<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>
73</td>
74<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>
75</td>
76</tr>
77<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>
78</td>
79<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>
80</td>
81</tr>
82<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>
83</td>
84<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>
85</td>
86</tr>
87<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>
88</td>
89<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>
90</td>
91</tr>
92<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>
93</td>
94<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>
95</td>
96</tr>
97<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>
98</td>
99<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>
100</td>
101</tr>
102<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>
103</td>
104<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>
105</td>
106</tr>
107</tbody>
108</table>
109
110## Constraints<a name="section1718733212019"></a>
111
112- The SA framework is developed using the C programming language.
113- Services in the same process use **IUnknown** for invoking. Messages are passed to the service through **IUnknown**.
114- The service name and feature name must be constant character strings and the length must be less than 16 bytes.
115- More-core depends on the Bootstrap service and calls the **OHOS\_SystemInit\(\)** function in the system startup function.
116- A-core depends on the Samgr library and calls the **SAMGR\_Bootstrap\(\)** function in the **main** function.
117
118## Developing a Service<a name="section159991817144514"></a>
119
120- Inherit and redefine a service.
121
122 ```
123 typedef struct ExampleService {
124 INHERIT_SERVICE;
125 INHERIT_IUNKNOWNENTRY(DefaultFeatureApi);
126 Identity identity;
127 } ExampleService;
128 ```
129
130- Implement the lifecycle function of the service.
131
132 ```
133 static const char *GetName(Service *service)
134 {
135 return EXAMPLE_SERVICE;
136 }
137
138 static BOOL Initialize(Service *service, Identity identity)
139 {
140 ExampleService *example = (ExampleService *)service;
141 // Save the unique ID of the service, which is used when IUnknown is used to send messages to the service.
142 example->identity = identity;
143 return TRUE;
144 }
145 static BOOL MessageHandle(Service *service, Request *msg)
146 {
147 ExampleService *example = (ExampleService *)service;
148 switch (msg->msgId) {
149 case MSG_SYNC:
150 // Process the service.
151 break;
152 default:break;
153 }
154 return FALSE;
155 }
156 static TaskConfig GetTaskConfig(Service *service)
157 {
158 TaskConfig config = {LEVEL_HIGH, PRI_BELOW_NORMAL,
159 0x800, 20, SHARED_TASK};
160 return config;
161 }
162 ```
163
164- Create a service object.
165
166 ```
167 static ExampleService g_example = {
168 .GetName = GetName,
169 .Initialize = Initialize,
170 .MessageHandle = MessageHandle,
171 .GetTaskConfig = GetTaskConfig,
172 SERVER_IPROXY_IMPL_BEGIN,
173 .Invoke = NULL,
174 .SyncCall = SyncCall,
175 IPROXY_END,
176 };
177 ```
178
179- Register the service and API with Samgr.
180
181 ```
182 static void Init(void)
183 {
184 SAMGR_GetInstance()->RegisterService((Service *)&g_example);
185 SAMGR_GetInstance()->RegisterDefaultFeatureApi(EXAMPLE_SERVICE, GET_IUNKNOWN(g_example));
186 }
187 ```
188
189- Define the initializer of the service.
190
191 ```
192 SYSEX_SERVICE_INIT(Init);
193
194 ```
195
196
197## Developing a Feature of a Service<a name="section11510542164514"></a>
198
199- Inherit and redefine a feature.
200
201 ```
202 typedef struct DemoFeature {
203 INHERIT_FEATURE;
204 INHERIT_IUNKNOWNENTRY(DemoApi);
205 Identity identity;
206 Service *parent;
207 } DemoFeature;
208 ```
209
210- Implement the lifecycle function of the feature.
211
212 ```
213 static const char *FEATURE_GetName(Feature *feature)
214 {
215 return EXAMPLE_FEATURE;
216 }
217
218 static void FEATURE_OnInitialize(Feature *feature, Service *parent, Identity identity)
219 {
220 DemoFeature *demoFeature = (DemoFeature *)feature;
221 demoFeature->identity = identity;
222 demoFeature->parent = parent;
223 }
224
225 static void FEATURE_OnStop(Feature *feature, Identity identity)
226 {
227 g_example.identity.queueId = NULL;
228 g_example.identity.featureId = -1;
229 g_example.identity.serviceId = -1;
230 }
231
232 static BOOL FEATURE_OnMessage(Feature *feature, Request *request)
233 {
234 if (request->msgId == MSG_PROC) {
235 Response response = {.data = "Yes, you did!", .len = 0};
236 SAMGR_SendResponse(request, &response);
237 return TRUE;
238 } else {
239 if (request->msgId == MSG_TIME_PROC) {
240 LOS_Msleep(WAIT_FEATURE_PROC * 10);
241 if (request->msgValue) {
242 SAMGR_PrintServices();
243 } else {
244 SAMGR_PrintOperations();
245 }
246 AsyncTimeCall(GET_IUNKNOWN(g_example));
247 return FALSE;
248 }
249 }
250 return FALSE;
251 }
252 ```
253
254- Create a feature object.
255
256 ```
257 static DemoFeature g_example = {
258 .GetName = FEATURE_GetName,
259 .OnInitialize = FEATURE_OnInitialize,
260 .OnStop = FEATURE_OnStop,
261 .OnMessage = FEATURE_OnMessage,
262 DEFAULT_IUNKNOWN_ENTRY_BEGIN,
263 .AsyncCall = AsyncCall,
264 .AsyncTimeCall = AsyncTimeCall,
265 .SyncCall = SyncCall,
266 .AsyncCallBack = AsyncCallBack,
267 DEFAULT_IUNKNOWN_ENTRY_END,
268 .identity = {-1, -1, NULL},
269 };
270 ```
271
272- Register the feature and API with Samgr.
273
274 ```
275 static void Init(void){
276 SAMGR_GetInstance()->RegisterFeature(EXAMPLE_SERVICE, (Feature *)&g_example);
277 SAMGR_GetInstance()->RegisterFeatureApi(EXAMPLE_SERVICE, EXAMPLE_FEATURE, GET_IUNKNOWN(g_example));
278 }
279 ```
280
281- Define the initializer of the feature.
282
283 ```
284 SYSEX_FEATURE_INIT(Init);
285
286 ```
287
288
289## Developing an External API for Intra-Process Communication<a name="section1685211117463"></a>
290
291- Define the **IUnknown** API.
292
293 ```
294 typedef struct DemoApi {
295 INHERIT_IUNKNOWN;
296 BOOL (*AsyncCall)(IUnknown *iUnknown, const char *buff);
297 BOOL (*AsyncTimeCall)(IUnknown *iUnknown);
298 BOOL (*SyncCall)(IUnknown *iUnknown, struct Payload *payload);
299 BOOL (*AsyncCallBack)(IUnknown *iUnknown, const char *buff, Handler handler);
300 } DemoApi;
301 ```
302
303- Define the reference object of **IUnknown**.
304
305 ```
306 typedef struct DemoRefApi {
307 INHERIT_IUNKNOWNENTRY(DemoApi);
308 } DemoRefApi;
309 ```
310
311- Initialize the object of **IUnknown**.
312
313 ```
314 static DemoRefApi api = {
315 DEFAULT_IUNKNOWN_ENTRY_BEGIN,
316 .AsyncCall = AsyncCall,
317 .AsyncTimeCall = AsyncTimeCall,
318 .SyncCall = SyncCall,
319 .AsyncCallBack = AsyncCallBack,
320 DEFAULT_IUNKNOWN_ENTRY_END,
321 };
322 ```
323
324- Register the feature API.
325
326 ```
327 SAMGR_GetInstance()->RegisterFeatureApi(EXAMPLE_SERVICE, EXAMPLE_FEATURE, GET_IUNKNOWN(api));
328
329 ```
330
331
332## Invoking a Service in the Same Process<a name="section3690162916462"></a>
333
334- Obtain the external API of the service.
335
336 ```
337 DemoApi *demoApi = NULL;
338 IUnknown *iUnknown = SAMGR_GetInstance()->GetFeatureApi(EXAMPLE_SERVICE, EXAMPLE_FEATURE);
339 if (iUnknown == NULL) {
340 return NULL;
341 }
342 int result = iUnknown->QueryInterface(iUnknown, DEFAULT_VERSION, (void **)&demoApi);
343 if (result != 0 || demoApi == NULL) {
344 return NULL;
345 }
346 ```
347
348- Call the API.
349
350 ```
351 if (demoApi->AsyncCallBack == NULL) {
352 return NULL;
353 }
354 demoApi->AsyncCallBack((IUnknown *)demoApi, "I wanna async call callback good result!", AsyncHandler);
355 ```
356
357- Release the API.
358
359 ```
360 int32 ref = demoApi->Release((IUnknown *)demoApi);
361
362 ```
363
364
365## Developing an External API for IPC<a name="section9220246194615"></a>
366
367- Inherit **IServerProxy** to replace **IUnknown**: INHERIT\_SERVER\_IPROXY
368
369 ```
370 typedef struct DemoFeatureApi {
371 INHERIT_SERVER_IPROXY;
372 BOOL (*AsyncCall)(IUnknown *iUnknown, const char *buff);
373 BOOL (*AsyncTimeCall)(IUnknown *iUnknown);
374 BOOL (*SyncCall)(IUnknown *iUnknown, struct Payload *payload);
375 BOOL (*AsyncCallBack)(IUnknown *iUnknown, const char *buff, IOwner notify, INotifyFunc handler);
376 } DemoFeatureApi;
377 ```
378
379- Initialize the **IServerProxy** object.
380
381 ```
382 static DemoFeature g_example = {
383 SERVER_IPROXY_IMPL_BEGIN,
384 .Invoke = Invoke,
385 .AsyncCall = AsyncCall,
386 .AsyncTimeCall = AsyncTimeCall,
387 .SyncCall = SyncCall,
388 .AsyncCallBack = AsyncCallBack,
389 IPROXY_END,
390 };
391 ```
392
393- Implement the **Invoke** function to process IPC messages.
394
395 ```
396 static int32 Invoke(IServerProxy *iProxy, int funcId, void *origin, IpcIo *req, IpcIo *reply)
397 {
398 DemoFeatureApi *api = (DemoFeatureApi *)iProxy;
399 BOOL ret;
400 size_t len = 0;
401 switch (funcId) {
402 case ID_ASYNCALL:
403 ret = api->AsyncCall((IUnknown *)iProxy, (char *)IpcIoPopString(req, &len));
404 IpcIoPushBool(reply, ret);
405 break;
406 case ID_ASYNTIMECALL:
407 ret = api->AsyncTimeCall((IUnknown *)iProxy);
408 IpcIoPushBool(reply, ret);
409 break;
410 case ID_SYNCCALL: {
411 struct Payload payload;
412 payload.id = IpcIoPopInt32(req);
413 payload.value = IpcIoPopInt32(req);
414 payload.name = (char *)IpcIoPopString(req, &len);
415 ret = api->SyncCall((IUnknown *)iProxy, &payload);
416 IpcIoPushString(reply, ret ? "TRUE" : "FALSE");
417 }
418 break;
419 case ID_ASYNCCALLBACK: { // convert to sync proxy
420 IpcIoPushString(reply, "Yes, you did!");
421 IpcIoPushBool(reply, TRUE);
422 }
423 break;
424 default:
425 IpcIoPushBool(reply, FALSE);
426 break;
427 }
428 return EC_SUCCESS;
429 }
430 ```
431
432- Register the API. This step is same as the API registration for intra-process communication.
433
434 ```
435 SAMGR_GetInstance()->RegisterFeatureApi(EXAMPLE_SERVICE, EXAMPLE_FEATURE, GET_IUNKNOWN(g_example));
436
437 ```
438
439
440## Invoking a Service in Another Process<a name="section114372711475"></a>
441
442- Obtain the external API of the service in another process.
443
444 ```
445 IClientProxy *demoApi = NULL;
446 IUnknown *iUnknown = SAMGR_GetInstance()->GetFeatureApi(EXAMPLE_SERVICE, EXAMPLE_FEATURE);
447 if (iUnknown == NULL) {
448 return NULL;
449 }
450 int result = iUnknown->QueryInterface(iUnknown, CLIENT_PROXY_VER, (void **)&demoApi);
451 if (result != 0 || demoApi == NULL) {
452 return NULL;
453 }
454 ```
455
456- Invoke the API for sending IPC messages.
457
458 ```
459 IpcIo request;char data[250];
460 IpcIoInit(&request, data, sizeof(data), 0);
461 demoApi->Invoke(demoApi, 0, &request, NULL, NULL);
462 ```
463
464- Release the API.
465
466 ```
467 int32 ref = demoApi->Release((IUnknown *)demoApi);
468
469 ```
470
471
472## Developing a Client Proxy for Inter-Process Service Invocation<a name="section09341923114710"></a>
473
474- Define a client proxy for the IPC API.
475
476 ```
477 typedef struct DemoClientProxy {
478 INHERIT_CLIENT_IPROXY;
479 BOOL (*AsyncCall)(IUnknown *iUnknown, const char *buff);
480 BOOL (*AsyncTimeCall)(IUnknown *iUnknown);
481 BOOL (*SyncCall)(IUnknown *iUnknown, struct Payload *payload);
482 BOOL (*AsyncCallBack)(IUnknown *iUnknown, const char *buff, IOwner notify, INotifyFunc handler);
483 } DemoClientProxy;
484 typedef struct DemoClientEntry {
485 INHERIT_IUNKNOWNENTRY(DemoClientProxy);
486 } DemoClientEntry;
487 ```
488
489- Enable the client proxy to encapsulate the IPC message API.
490
491 ```
492 static BOOL AsyncCall(IUnknown *iUnknown, const char *buff)
493 {
494 DemoClientProxy *proxy = (DemoClientProxy *)iUnknown;
495 IpcIo request;
496 char data[MAX_DATA_LEN];
497 IpcIoInit(&request, data, MAX_DATA_LEN, 0);
498 IpcIoPushString(&request, buff);
499 int ret = proxy->Invoke((IClientProxy *)proxy, ID_ASYNCALL, &request, NULL, NULL);
500 return ret == EC_SUCCESS;
501 }
502
503 static BOOL AsyncTimeCall(IUnknown *iUnknown)
504 {
505 DemoClientProxy *proxy = (DemoClientProxy *)iUnknown;
506 IpcIo request;
507 char data[MAX_DATA_LEN];
508 IpcIoInit(&request, data, MAX_DATA_LEN, 0);
509 int ret = proxy->Invoke((IClientProxy *)proxy, ID_ASYNTIMECALL, &request, NULL, NULL);
510 return ret == EC_SUCCESS;
511 }
512
513 static int Callback(IOwner owner, int code, IpcIo *reply)
514 {
515 size_t len = 0;
516 return strcpy_s(owner, MAX_DATA_LEN, (char *)IpcIoPopString(reply, &len));
517 }
518
519 static BOOL SyncCall(IUnknown *iUnknown, struct Payload *payload)
520 {
521 DemoClientProxy *proxy = (DemoClientProxy *)iUnknown;
522 IpcIo request;
523 char data[MAX_DATA_LEN];
524 IpcIoInit(&request, data, MAX_DATA_LEN, 0);
525 IpcIoPushInt32(&request, payload->id);
526 IpcIoPushInt32(&request, payload->value);
527 IpcIoPushString(&request, payload->name);
528 int ret = proxy->Invoke((IClientProxy *)proxy, ID_SYNCCALL, &request, data, Callback);
529 data[MAX_DATA_LEN - 1] = 0;
530 HILOG_INFO(HILOG_MODULE_APP, "[TID:0x%lx]Remote response is %s!", pthread_self(), data);
531 return ret == EC_SUCCESS;
532 }
533
534 struct CurrentNotify {
535 IOwner notify;
536 INotifyFunc handler;
537 };
538
539 static int CurrentCallback(IOwner owner, int code, IpcIo *reply)
540 {
541 struct CurrentNotify *notify = (struct CurrentNotify *)owner;
542 size_t len = 0;
543 char *response = (char *)IpcIoPopString(reply, &len);
544 HILOG_INFO(HILOG_MODULE_APP, "[TID:0x%lx]Notify Remote response is %s!", pthread_self(), response);
545 notify->handler(notify->notify, response);
546 return EC_SUCCESS;
547 }
548
549 static BOOL AsyncCallBack(IUnknown *iUnknown, const char *buff, IOwner notify, INotifyFunc handler)
550 {
551 struct CurrentNotify owner = {notify, handler};
552 DemoClientProxy *proxy = (DemoClientProxy *)iUnknown;
553 IpcIo request;
554 char data[MAX_DATA_LEN];
555 IpcIoInit(&request, data, MAX_DATA_LEN, 0);
556 IpcIoPushString(&request, buff);
557 int ret = proxy->Invoke((IClientProxy *)proxy, ID_ASYNCCALLBACK, &request, &owner, CurrentCallback);
558 return ret == EC_SUCCESS;
559 }
560 ```
561
562- Implement the factory method for creating the client proxy.
563
564 ```
565 void *DEMO_CreatClient(const char *service, const char *feature, uint32 size)
566 {
567 (void)service;
568 (void)feature;
569 uint32 len = size + sizeof(DemoClientEntry);
570 uint8 *client = malloc(len);
571 (void)memset_s(client, len, 0, len);
572 DemoClientEntry *entry = (DemoClientEntry *)&client[size];
573 entry->ver = ((uint16)CLIENT_PROXY_VER | (uint16)DEFAULT_VERSION);
574 entry->ref = 1;
575 entry->iUnknown.QueryInterface = IUNKNOWN_QueryInterface;
576 entry->iUnknown.AddRef = IUNKNOWN_AddRef;
577 entry->iUnknown.Release = IUNKNOWN_Release;
578 entry->iUnknown.Invoke = NULL;
579 entry->iUnknown.AsyncCall = AsyncCall;
580 entry->iUnknown.AsyncTimeCall = AsyncTimeCall;
581 entry->iUnknown.SyncCall = SyncCall;
582 entry->iUnknown.AsyncCallBack = AsyncCallBack;
583 return client;
584 }
585 void DEMO_DestroyClient(const char *service, const char *feature, void *iproxy)
586 {
587 free(iproxy);
588 }
589 ```
590
591- Register the factory method of the client proxy with Samgr.
592
593 ```
594 SAMGR_RegisterFactory(EXAMPLE_SERVICE, EXAMPLE_FEATURE, DEMO_CreatClient, DEMO_DestroyClient);
595 ```
596
597- Obtain the external API of the service in another process.
598
599 ```
600 DemoClientProxy *demoApi = NULL;
601 IUnknown *iUnknown = SAMGR_GetInstance()->GetFeatureApi(EXAMPLE_SERVICE, EXAMPLE_FEATURE);
602 if (iUnknown == NULL) {
603 return NULL;
604 }
605 int result = iUnknown->QueryInterface(iUnknown, DEFAULT_VERSION, (void **)&demoApi);
606 if (result != 0 || demoApi == NULL) {
607 return NULL;
608 }
609 ```
610
611- Invoke the client proxy API of the service in another process.
612
613 ```
614 if (demoApi->AsyncCallBack == NULL) {
615 return NULL;
616 }
617 demoApi->AsyncCallBack((IUnknown *)demoApi,
618 "I wanna async call callback good result!", NULL, AsyncHandler);
619 ```
620
621- Release the API.
622
623 ```
624 int32 ref = demoApi->Release((IUnknown *)demoApi);
625 ```
626
627
628## Repositories Involved<a name="section10365113863719"></a>
629
630Distributed Scheduler subsystem
631
632**samgr\_lite**
633
634
README_zh.md
1# 介绍<a name="ZH-CN_TOPIC_0000001081604584"></a>
2
3- [简介](#section11660541593)
4- [目录](#section1464106163817)
5- [约束](#section1718733212019)
6- [开发服务](#section159991817144514)
7- [开发服务的子功能](#section11510542164514)
8- [开发进程内对外接口](#section1685211117463)
9- [调用进程内服务](#section3690162916462)
10- [开发跨进程间对外接口](#section9220246194615)
11- [调用跨进程间服务](#section114372711475)
12- [开发跨进程间服务调用客户端代理](#section09341923114710)
13- [涉及仓](#section10365113863719)
14
15## 简介<a name="section11660541593"></a>
16
17由于平台资源有限,且硬件平台多样,因此需要屏蔽不同硬件架构和平台资源的不同、以及运行形态的不同,提供统一化的系统服务开发框架。根据RISC-V、Cortex-M、Cortex-A不同硬件平台,分为两种硬件平台,以下简称M核、A核。
18
19- M核:处理器架构为Cortex-M或同等处理能力的硬件平台,系统内存一般低于512KB,无文件系统或者仅提供一个可有限使用的轻量级文件系统,遵循CMSIS接口规范。
20- A核:处理器架构为Cortex-A或同等处理能力的硬件平台,内存资源大于512KB,文件系统完善,可存储大量数据,遵循POSIX接口规范。
21
22系统服务框架基于面向服务的架构,提供了服务开发、服务的子功能开发、对外接口的开发、以及多服务共进程、进程间服务调用等开发能力。其中:
23
24- M核:包含服务开发、服务的子功能开发、对外接口的开发以及多服务共进程的开发框架。
25- A核:在M核能力基础之上,包含了进程间服务调用、进程间服务调用权限控制、进程间服务接口的开发等能力。
26
27面向服务的架构:
28
29
30
31- Provider:服务的提供者,为系统提供能力(对外接口)。
32- Consumer:服务的消费者,调用服务提供的功能(对外接口)。
33- Samgr:作为中介者,管理Provider提供的能力,同时帮助Consumer发现Provider的能力。
34
35系统服务开发框架主体对象:
36
37
38
39- SamgrLite:主要提供服务的注册与发现能力。
40- Service:开发服务时,需要实现的服务的生命周期接口。
41- Feature:开发功能时,需要实现的功能的生命周期接口。
42- IUnknown:基于IUnknown开发服务或功能的对外接口。
43- IClientProxy:IPC调用时,消费者的消息发送代理。
44- IServerProxy:IPC调用时,开发者需要实现提供者的消息处理接口。
45
46## 目录<a name="section1464106163817"></a>
47
48**表 1** 系统服务框架源代码目录结构
49
50<a name="table2977131081412"></a>
51<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>
52</th>
53<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>
54</th>
55</tr>
56</thead>
57<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>
58</td>
59<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>
60</td>
61</tr>
62<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>
63</td>
64<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>
65</td>
66</tr>
67<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>
68</td>
69<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>
70</td>
71</tr>
72<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>
73</td>
74<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>
75</td>
76</tr>
77<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>
78</td>
79<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>
80</td>
81</tr>
82<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>
83</td>
84<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>
85</td>
86</tr>
87<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>
88</td>
89<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>
90</td>
91</tr>
92<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>
93</td>
94<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>
95</td>
96</tr>
97<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>
98</td>
99<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>
100</td>
101</tr>
102<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>
103</td>
104<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>
105</td>
106</tr>
107</tbody>
108</table>
109
110## 约束<a name="section1718733212019"></a>
111
112- 系统服务开发框架统一使用C开发。
113- 同进程内服务间调用统一使用IUnknown接口对外象,消息接口统一由IUnknown接口传递给本服务。
114- 服务名和功能名必需使用常量字符串且长度小于16个字节。
115- M核:系统依赖上bootstrap服务,在系统启动函数中调用OHOS\_SystemInit\(\)函数。
116- A核:系统依赖samgr库,在main函数中调用SAMGR\_Bootstrap\(\)函数。
117
118## 开发服务<a name="section159991817144514"></a>
119
120- 继承并重新定义服务:
121
122 ```
123 typedef struct ExampleService {
124 INHERIT_SERVICE;
125 INHERIT_IUNKNOWNENTRY(DefaultFeatureApi);
126 Identity identity;
127 } ExampleService;
128 ```
129
130- 实现服务的生命周期函数:
131
132 ```
133 static const char *GetName(Service *service)
134 {
135 return EXAMPLE_SERVICE;
136 }
137
138 static BOOL Initialize(Service *service, Identity identity)
139 {
140 ExampleService *example = (ExampleService *)service;
141 // 保存服务的唯一身份标识,用来自己的IUnknown接口对服务发消息时使用。
142 example->identity = identity;
143 return TRUE;
144 }
145 static BOOL MessageHandle(Service *service, Request *msg)
146 {
147 ExampleService *example = (ExampleService *)service;
148 switch (msg->msgId) {
149 case MSG_SYNC:
150 // 业务处理
151 break;
152 default:break;
153 }
154 return FALSE;
155 }
156 static TaskConfig GetTaskConfig(Service *service)
157 {
158 TaskConfig config = {LEVEL_HIGH, PRI_BELOW_NORMAL,
159 0x800, 20, SHARED_TASK};
160 return config;
161 }
162 ```
163
164- 创建服务对象:
165
166 ```
167 static ExampleService g_example = {
168 .GetName = GetName,
169 .Initialize = Initialize,
170 .MessageHandle = MessageHandle,
171 .GetTaskConfig = GetTaskConfig,
172 SERVER_IPROXY_IMPL_BEGIN,
173 .Invoke = NULL,
174 .SyncCall = SyncCall,
175 IPROXY_END,
176 };
177 ```
178
179- 向SAMGR注册服务及接口:
180
181 ```
182 static void Init(void)
183 {
184 SAMGR_GetInstance()->RegisterService((Service *)&g_example);
185 SAMGR_GetInstance()->RegisterDefaultFeatureApi(EXAMPLE_SERVICE, GET_IUNKNOWN(g_example));
186 }
187 ```
188
189- 定义服务的初始化入口:
190
191 ```
192 SYSEX_SERVICE_INIT(Init);
193
194 ```
195
196
197## 开发服务的子功能<a name="section11510542164514"></a>
198
199- 继承并重新定义功能:
200
201 ```
202 typedef struct DemoFeature {
203 INHERIT_FEATURE;
204 INHERIT_IUNKNOWNENTRY(DemoApi);
205 Identity identity;
206 Service *parent;
207 } DemoFeature;
208 ```
209
210- 实现功能的生命周期函数:
211
212 ```
213 static const char *FEATURE_GetName(Feature *feature)
214 {
215 return EXAMPLE_FEATURE;
216 }
217
218 static void FEATURE_OnInitialize(Feature *feature, Service *parent, Identity identity)
219 {
220 DemoFeature *demoFeature = (DemoFeature *)feature;
221 demoFeature->identity = identity;
222 demoFeature->parent = parent;
223 }
224
225 static void FEATURE_OnStop(Feature *feature, Identity identity)
226 {
227 g_example.identity.queueId = NULL;
228 g_example.identity.featureId = -1;
229 g_example.identity.serviceId = -1;
230 }
231
232 static BOOL FEATURE_OnMessage(Feature *feature, Request *request)
233 {
234 if (request->msgId == MSG_PROC) {
235 Response response = {.data = "Yes, you did!", .len = 0};
236 SAMGR_SendResponse(request, &response);
237 return TRUE;
238 } else {
239 if (request->msgId == MSG_TIME_PROC) {
240 LOS_Msleep(WAIT_FEATURE_PROC * 10);
241 if (request->msgValue) {
242 SAMGR_PrintServices();
243 } else {
244 SAMGR_PrintOperations();
245 }
246 AsyncTimeCall(GET_IUNKNOWN(g_example));
247 return FALSE;
248 }
249 }
250 return FALSE;
251 }
252 ```
253
254- 创建功能对象:
255
256 ```
257 static DemoFeature g_example = {
258 .GetName = FEATURE_GetName,
259 .OnInitialize = FEATURE_OnInitialize,
260 .OnStop = FEATURE_OnStop,
261 .OnMessage = FEATURE_OnMessage,
262 DEFAULT_IUNKNOWN_ENTRY_BEGIN,
263 .AsyncCall = AsyncCall,
264 .AsyncTimeCall = AsyncTimeCall,
265 .SyncCall = SyncCall,
266 .AsyncCallBack = AsyncCallBack,
267 DEFAULT_IUNKNOWN_ENTRY_END,
268 .identity = {-1, -1, NULL},
269 };
270 ```
271
272- 向SAMGR注册功能及接口:
273
274 ```
275 static void Init(void){
276 SAMGR_GetInstance()->RegisterFeature(EXAMPLE_SERVICE, (Feature *)&g_example);
277 SAMGR_GetInstance()->RegisterFeatureApi(EXAMPLE_SERVICE, EXAMPLE_FEATURE, GET_IUNKNOWN(g_example));
278 }
279 ```
280
281- 定义功能的初始化入口:
282
283 ```
284 SYSEX_FEATURE_INIT(Init);
285
286 ```
287
288
289## 开发进程内对外接口<a name="section1685211117463"></a>
290
291- 定义IUnknown接口:
292
293 ```
294 typedef struct DemoApi {
295 INHERIT_IUNKNOWN;
296 BOOL (*AsyncCall)(IUnknown *iUnknown, const char *buff);
297 BOOL (*AsyncTimeCall)(IUnknown *iUnknown);
298 BOOL (*SyncCall)(IUnknown *iUnknown, struct Payload *payload);
299 BOOL (*AsyncCallBack)(IUnknown *iUnknown, const char *buff, Handler handler);
300 } DemoApi;
301 ```
302
303- 定义IUnknown的引用对象:
304
305 ```
306 typedef struct DemoRefApi {
307 INHERIT_IUNKNOWNENTRY(DemoApi);
308 } DemoRefApi;
309 ```
310
311- 初始化接口对象:
312
313 ```
314 static DemoRefApi api = {
315 DEFAULT_IUNKNOWN_ENTRY_BEGIN,
316 .AsyncCall = AsyncCall,
317 .AsyncTimeCall = AsyncTimeCall,
318 .SyncCall = SyncCall,
319 .AsyncCallBack = AsyncCallBack,
320 DEFAULT_IUNKNOWN_ENTRY_END,
321 };
322 ```
323
324- 注册服务接口:
325
326 ```
327 SAMGR_GetInstance()->RegisterFeatureApi(EXAMPLE_SERVICE, EXAMPLE_FEATURE, GET_IUNKNOWN(api));
328
329 ```
330
331
332## 调用进程内服务<a name="section3690162916462"></a>
333
334- 获取服务的对外接口:
335
336 ```
337 DemoApi *demoApi = NULL;
338 IUnknown *iUnknown = SAMGR_GetInstance()->GetFeatureApi(EXAMPLE_SERVICE, EXAMPLE_FEATURE);
339 if (iUnknown == NULL) {
340 return NULL;
341 }
342 int result = iUnknown->QueryInterface(iUnknown, DEFAULT_VERSION, (void **)&demoApi);
343 if (result != 0 || demoApi == NULL) {
344 return NULL;
345 }
346 ```
347
348- 接口调用:
349
350 ```
351 if (demoApi->AsyncCallBack == NULL) {
352 return NULL;
353 }
354 demoApi->AsyncCallBack((IUnknown *)demoApi, "I wanna async call callback good result!", AsyncHandler);
355 ```
356
357- 释放接口:
358
359 ```
360 int32 ref = demoApi->Release((IUnknown *)demoApi);
361
362 ```
363
364
365## 开发跨进程间对外接口<a name="section9220246194615"></a>
366
367- 继承IServerProxy替代继承IUnknown:INHERIT\_SERVER\_IPROXY
368
369 ```
370 typedef struct DemoFeatureApi {
371 INHERIT_SERVER_IPROXY;
372 BOOL (*AsyncCall)(IUnknown *iUnknown, const char *buff);
373 BOOL (*AsyncTimeCall)(IUnknown *iUnknown);
374 BOOL (*SyncCall)(IUnknown *iUnknown, struct Payload *payload);
375 BOOL (*AsyncCallBack)(IUnknown *iUnknown, const char *buff, IOwner notify, INotifyFunc handler);
376 } DemoFeatureApi;
377 ```
378
379- 初始化IServerProxy对象:
380
381 ```
382 static DemoFeature g_example = {
383 SERVER_IPROXY_IMPL_BEGIN,
384 .Invoke = Invoke,
385 .AsyncCall = AsyncCall,
386 .AsyncTimeCall = AsyncTimeCall,
387 .SyncCall = SyncCall,
388 .AsyncCallBack = AsyncCallBack,
389 IPROXY_END,
390 };
391 ```
392
393- 实现Invoke函数来处理Ipc消息:
394
395 ```
396 static int32 Invoke(IServerProxy *iProxy, int funcId, void *origin, IpcIo *req, IpcIo *reply)
397 {
398 DemoFeatureApi *api = (DemoFeatureApi *)iProxy;
399 BOOL ret;
400 size_t len = 0;
401 switch (funcId) {
402 case ID_ASYNCALL:
403 ret = api->AsyncCall((IUnknown *)iProxy, (char *)IpcIoPopString(req, &len));
404 IpcIoPushBool(reply, ret);
405 break;
406 case ID_ASYNTIMECALL:
407 ret = api->AsyncTimeCall((IUnknown *)iProxy);
408 IpcIoPushBool(reply, ret);
409 break;
410 case ID_SYNCCALL: {
411 struct Payload payload;
412 payload.id = IpcIoPopInt32(req);
413 payload.value = IpcIoPopInt32(req);
414 payload.name = (char *)IpcIoPopString(req, &len);
415 ret = api->SyncCall((IUnknown *)iProxy, &payload);
416 IpcIoPushString(reply, ret ? "TRUE" : "FALSE");
417 }
418 break;
419 case ID_ASYNCCALLBACK: { // convert to sync proxy
420 IpcIoPushString(reply, "Yes, you did!");
421 IpcIoPushBool(reply, TRUE);
422 }
423 break;
424 default:
425 IpcIoPushBool(reply, FALSE);
426 break;
427 }
428 return EC_SUCCESS;
429 }
430 ```
431
432- 注册接口:与进程内接口注册一致
433
434 ```
435 SAMGR_GetInstance()->RegisterFeatureApi(EXAMPLE_SERVICE, EXAMPLE_FEATURE, GET_IUNKNOWN(g_example));
436
437 ```
438
439
440## 调用跨进程间服务<a name="section114372711475"></a>
441
442- 获取跨进程服务的对外接口:
443
444 ```
445 IClientProxy *demoApi = NULL;
446 IUnknown *iUnknown = SAMGR_GetInstance()->GetFeatureApi(EXAMPLE_SERVICE, EXAMPLE_FEATURE);
447 if (iUnknown == NULL) {
448 return NULL;
449 }
450 int result = iUnknown->QueryInterface(iUnknown, CLIENT_PROXY_VER, (void **)&demoApi);
451 if (result != 0 || demoApi == NULL) {
452 return NULL;
453 }
454 ```
455
456- 调用Ipc消息接口:
457
458 ```
459 IpcIo request;char data[250];
460 IpcIoInit(&request, data, sizeof(data), 0);
461 demoApi->Invoke(demoApi, 0, &request, NULL, NULL);
462 ```
463
464- 释放接口:
465
466 ```
467 int32 ref = demoApi->Release((IUnknown *)demoApi);
468
469 ```
470
471
472## 开发跨进程间服务调用客户端代理<a name="section09341923114710"></a>
473
474- 定义IPC接口客户端代理:
475
476 ```
477 typedef struct DemoClientProxy {
478 INHERIT_CLIENT_IPROXY;
479 BOOL (*AsyncCall)(IUnknown *iUnknown, const char *buff);
480 BOOL (*AsyncTimeCall)(IUnknown *iUnknown);
481 BOOL (*SyncCall)(IUnknown *iUnknown, struct Payload *payload);
482 BOOL (*AsyncCallBack)(IUnknown *iUnknown, const char *buff, IOwner notify, INotifyFunc handler);
483 } DemoClientProxy;
484 typedef struct DemoClientEntry {
485 INHERIT_IUNKNOWNENTRY(DemoClientProxy);
486 } DemoClientEntry;
487 ```
488
489- 实现客户端代理封装Ipc消息接口:
490
491 ```
492 static BOOL AsyncCall(IUnknown *iUnknown, const char *buff)
493 {
494 DemoClientProxy *proxy = (DemoClientProxy *)iUnknown;
495 IpcIo request;
496 char data[MAX_DATA_LEN];
497 IpcIoInit(&request, data, MAX_DATA_LEN, 0);
498 IpcIoPushString(&request, buff);
499 int ret = proxy->Invoke((IClientProxy *)proxy, ID_ASYNCALL, &request, NULL, NULL);
500 return ret == EC_SUCCESS;
501 }
502
503 static BOOL AsyncTimeCall(IUnknown *iUnknown)
504 {
505 DemoClientProxy *proxy = (DemoClientProxy *)iUnknown;
506 IpcIo request;
507 char data[MAX_DATA_LEN];
508 IpcIoInit(&request, data, MAX_DATA_LEN, 0);
509 int ret = proxy->Invoke((IClientProxy *)proxy, ID_ASYNTIMECALL, &request, NULL, NULL);
510 return ret == EC_SUCCESS;
511 }
512
513 static int Callback(IOwner owner, int code, IpcIo *reply)
514 {
515 size_t len = 0;
516 return strcpy_s(owner, MAX_DATA_LEN, (char *)IpcIoPopString(reply, &len));
517 }
518
519 static BOOL SyncCall(IUnknown *iUnknown, struct Payload *payload)
520 {
521 DemoClientProxy *proxy = (DemoClientProxy *)iUnknown;
522 IpcIo request;
523 char data[MAX_DATA_LEN];
524 IpcIoInit(&request, data, MAX_DATA_LEN, 0);
525 IpcIoPushInt32(&request, payload->id);
526 IpcIoPushInt32(&request, payload->value);
527 IpcIoPushString(&request, payload->name);
528 int ret = proxy->Invoke((IClientProxy *)proxy, ID_SYNCCALL, &request, data, Callback);
529 data[MAX_DATA_LEN - 1] = 0;
530 HILOG_INFO(HILOG_MODULE_APP, "[TID:0x%lx]Remote response is %s!", pthread_self(), data);
531 return ret == EC_SUCCESS;
532 }
533
534 struct CurrentNotify {
535 IOwner notify;
536 INotifyFunc handler;
537 };
538
539 static int CurrentCallback(IOwner owner, int code, IpcIo *reply)
540 {
541 struct CurrentNotify *notify = (struct CurrentNotify *)owner;
542 size_t len = 0;
543 char *response = (char *)IpcIoPopString(reply, &len);
544 HILOG_INFO(HILOG_MODULE_APP, "[TID:0x%lx]Notify Remote response is %s!", pthread_self(), response);
545 notify->handler(notify->notify, response);
546 return EC_SUCCESS;
547 }
548
549 static BOOL AsyncCallBack(IUnknown *iUnknown, const char *buff, IOwner notify, INotifyFunc handler)
550 {
551 struct CurrentNotify owner = {notify, handler};
552 DemoClientProxy *proxy = (DemoClientProxy *)iUnknown;
553 IpcIo request;
554 char data[MAX_DATA_LEN];
555 IpcIoInit(&request, data, MAX_DATA_LEN, 0);
556 IpcIoPushString(&request, buff);
557 int ret = proxy->Invoke((IClientProxy *)proxy, ID_ASYNCCALLBACK, &request, &owner, CurrentCallback);
558 return ret == EC_SUCCESS;
559 }
560 ```
561
562- 实现客户端代理的工厂方法:
563
564 ```
565 void *DEMO_CreatClient(const char *service, const char *feature, uint32 size)
566 {
567 (void)service;
568 (void)feature;
569 uint32 len = size + sizeof(DemoClientEntry);
570 uint8 *client = malloc(len);
571 (void)memset_s(client, len, 0, len);
572 DemoClientEntry *entry = (DemoClientEntry *)&client[size];
573 entry->ver = ((uint16)CLIENT_PROXY_VER | (uint16)DEFAULT_VERSION);
574 entry->ref = 1;
575 entry->iUnknown.QueryInterface = IUNKNOWN_QueryInterface;
576 entry->iUnknown.AddRef = IUNKNOWN_AddRef;
577 entry->iUnknown.Release = IUNKNOWN_Release;
578 entry->iUnknown.Invoke = NULL;
579 entry->iUnknown.AsyncCall = AsyncCall;
580 entry->iUnknown.AsyncTimeCall = AsyncTimeCall;
581 entry->iUnknown.SyncCall = SyncCall;
582 entry->iUnknown.AsyncCallBack = AsyncCallBack;
583 return client;
584 }
585 void DEMO_DestroyClient(const char *service, const char *feature, void *iproxy)
586 {
587 free(iproxy);
588 }
589 ```
590
591- 将客户端代理的工厂方法注册到SAMGR:
592
593 ```
594 SAMGR_RegisterFactory(EXAMPLE_SERVICE, EXAMPLE_FEATURE, DEMO_CreatClient, DEMO_DestroyClient);
595 ```
596
597- 获取跨进程服务的对外接口:
598
599 ```
600 DemoClientProxy *demoApi = NULL;
601 IUnknown *iUnknown = SAMGR_GetInstance()->GetFeatureApi(EXAMPLE_SERVICE, EXAMPLE_FEATURE);
602 if (iUnknown == NULL) {
603 return NULL;
604 }
605 int result = iUnknown->QueryInterface(iUnknown, DEFAULT_VERSION, (void **)&demoApi);
606 if (result != 0 || demoApi == NULL) {
607 return NULL;
608 }
609 ```
610
611- 调用跨进程服务的客户端代理接口:
612
613 ```
614 if (demoApi->AsyncCallBack == NULL) {
615 return NULL;
616 }
617 demoApi->AsyncCallBack((IUnknown *)demoApi,
618 "I wanna async call callback good result!", NULL, AsyncHandler);
619 ```
620
621- 释放接口:
622
623 ```
624 int32 ref = demoApi->Release((IUnknown *)demoApi);
625 ```
626
627
628## 涉及仓<a name="section10365113863719"></a>
629
630分布式任务调度子系统
631
632**samgr\_lite**
633
634