1a299bc30Sopenharmony_ci/*
2a299bc30Sopenharmony_ci * Copyright (c) 2020-2022 Huawei Device Co., Ltd.
3a299bc30Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4a299bc30Sopenharmony_ci * you may not use this file except in compliance with the License.
5a299bc30Sopenharmony_ci * You may obtain a copy of the License at
6a299bc30Sopenharmony_ci *
7a299bc30Sopenharmony_ci *    http://www.apache.org/licenses/LICENSE-2.0
8a299bc30Sopenharmony_ci *
9a299bc30Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10a299bc30Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11a299bc30Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12a299bc30Sopenharmony_ci * See the License for the specific language governing permissions and
13a299bc30Sopenharmony_ci * limitations under the License.
14a299bc30Sopenharmony_ci */
15a299bc30Sopenharmony_ci
16a299bc30Sopenharmony_ci#include "example.h"
17a299bc30Sopenharmony_ci#include <stdint.h>
18a299bc30Sopenharmony_ci#include <ohos_init.h>
19a299bc30Sopenharmony_ci#include <securec.h>
20a299bc30Sopenharmony_ci#include <los_base.h>
21a299bc30Sopenharmony_ci#include <cmsis_os.h>
22a299bc30Sopenharmony_ci#include <samgr_maintenance.h>
23a299bc30Sopenharmony_ci#include "iunknown.h"
24a299bc30Sopenharmony_ci#include "feature.h"
25a299bc30Sopenharmony_ci#include "service.h"
26a299bc30Sopenharmony_ci#include "samgr_lite.h"
27a299bc30Sopenharmony_ci#include "time_adapter.h"
28a299bc30Sopenharmony_ci
29a299bc30Sopenharmony_ci#define WAIT_FEATURE_PROC 1000
30a299bc30Sopenharmony_ci
31a299bc30Sopenharmony_cienum MessageId {
32a299bc30Sopenharmony_ci    MSG_PROC,
33a299bc30Sopenharmony_ci    MSG_TIME_PROC,
34a299bc30Sopenharmony_ci};
35a299bc30Sopenharmony_ci
36a299bc30Sopenharmony_cistruct Payload {
37a299bc30Sopenharmony_ci    int id;
38a299bc30Sopenharmony_ci    const char *name;
39a299bc30Sopenharmony_ci    int value;
40a299bc30Sopenharmony_ci};
41a299bc30Sopenharmony_ci
42a299bc30Sopenharmony_citypedef struct DemoApi {
43a299bc30Sopenharmony_ci    INHERIT_IUNKNOWN;
44a299bc30Sopenharmony_ci    BOOL (*AsyncCall)(IUnknown *iUnknown, const char *buff);
45a299bc30Sopenharmony_ci    BOOL (*AsyncTimeCall)(IUnknown *iUnknown);
46a299bc30Sopenharmony_ci    BOOL (*SyncCall)(IUnknown *iUnknown, struct Payload *payload);
47a299bc30Sopenharmony_ci    BOOL (*AsyncCallBack)(IUnknown *iUnknown, const char *buff, Handler handler);
48a299bc30Sopenharmony_ci} DemoApi;
49a299bc30Sopenharmony_ci
50a299bc30Sopenharmony_citypedef struct DemoFeature {
51a299bc30Sopenharmony_ci    INHERIT_FEATURE;
52a299bc30Sopenharmony_ci    INHERIT_IUNKNOWNENTRY(DemoApi);
53a299bc30Sopenharmony_ci    Identity identity;
54a299bc30Sopenharmony_ci} DemoFeature;
55a299bc30Sopenharmony_ci
56a299bc30Sopenharmony_cistatic BOOL AsyncCall(IUnknown *iUnknown, const char *body);
57a299bc30Sopenharmony_cistatic BOOL AsyncTimeCall(IUnknown *iUnknown);
58a299bc30Sopenharmony_cistatic BOOL SyncCall(IUnknown *iUnknown, struct Payload *payload);
59a299bc30Sopenharmony_cistatic BOOL AsyncCallBack(IUnknown *iUnknown, const char *body, Handler handler);
60a299bc30Sopenharmony_cistatic const char *FEATURE_GetName(Feature *feature);
61a299bc30Sopenharmony_cistatic void FEATURE_OnInitialize(Feature *feature, Service *parent, Identity identity);
62a299bc30Sopenharmony_cistatic void FEATURE_OnStop(Feature *feature, Identity identity);
63a299bc30Sopenharmony_cistatic BOOL FEATURE_OnMessage(Feature *feature, Request *request);
64a299bc30Sopenharmony_cistatic DemoFeature g_example = {
65a299bc30Sopenharmony_ci    .GetName = FEATURE_GetName,
66a299bc30Sopenharmony_ci    .OnInitialize = FEATURE_OnInitialize,
67a299bc30Sopenharmony_ci    .OnStop = FEATURE_OnStop,
68a299bc30Sopenharmony_ci    .OnMessage = FEATURE_OnMessage,
69a299bc30Sopenharmony_ci    DEFAULT_IUNKNOWN_ENTRY_BEGIN,
70a299bc30Sopenharmony_ci    .AsyncCall = AsyncCall,
71a299bc30Sopenharmony_ci    .AsyncTimeCall = AsyncTimeCall,
72a299bc30Sopenharmony_ci    .SyncCall = SyncCall,
73a299bc30Sopenharmony_ci    .AsyncCallBack = AsyncCallBack,
74a299bc30Sopenharmony_ci    DEFAULT_IUNKNOWN_ENTRY_END,
75a299bc30Sopenharmony_ci    .identity = {-1, -1, NULL},
76a299bc30Sopenharmony_ci};
77a299bc30Sopenharmony_cistatic uint32_t g_regStep = 0;
78a299bc30Sopenharmony_ci
79a299bc30Sopenharmony_cistatic const char *FEATURE_GetName(Feature *feature)
80a299bc30Sopenharmony_ci{
81a299bc30Sopenharmony_ci    (void)feature;
82a299bc30Sopenharmony_ci    return EXAMPLE_FEATURE;
83a299bc30Sopenharmony_ci}
84a299bc30Sopenharmony_ci
85a299bc30Sopenharmony_cistatic void FEATURE_OnInitialize(Feature *feature, Service *parent, Identity identity)
86a299bc30Sopenharmony_ci{
87a299bc30Sopenharmony_ci    DemoFeature *demoFeature = (DemoFeature *)feature;
88a299bc30Sopenharmony_ci    demoFeature->identity = identity;
89a299bc30Sopenharmony_ci    printf("[Register Test][TaskID:%u][Step:%u][Reg Finish S:%s, F:%s]Time: %llu!\n",
90a299bc30Sopenharmony_ci           (int)osThreadGetId(), g_regStep++, parent->GetName(parent), feature->GetName(feature),
91a299bc30Sopenharmony_ci           SAMGR_GetProcessTime());
92a299bc30Sopenharmony_ci}
93a299bc30Sopenharmony_ci
94a299bc30Sopenharmony_cistatic void FEATURE_OnStop(Feature *feature, Identity identity)
95a299bc30Sopenharmony_ci{
96a299bc30Sopenharmony_ci    (void)feature;
97a299bc30Sopenharmony_ci    (void)identity;
98a299bc30Sopenharmony_ci    g_example.identity.queueId = NULL;
99a299bc30Sopenharmony_ci    g_example.identity.featureId = -1;
100a299bc30Sopenharmony_ci    g_example.identity.serviceId = -1;
101a299bc30Sopenharmony_ci}
102a299bc30Sopenharmony_ci
103a299bc30Sopenharmony_cistatic volatile uint32 g_asyncStep = 0;
104a299bc30Sopenharmony_ci
105a299bc30Sopenharmony_cistatic BOOL FEATURE_OnMessage(Feature *feature, Request *request)
106a299bc30Sopenharmony_ci{
107a299bc30Sopenharmony_ci    (void)feature;
108a299bc30Sopenharmony_ci    if (request->msgId == MSG_PROC) {
109a299bc30Sopenharmony_ci        printf("[LPC Test][TaskID:%u][Step:%u][OnMessage: S:%s, F:%s] msgId<MSG_PROC> %s \n",
110a299bc30Sopenharmony_ci               (int)osThreadGetId(), g_asyncStep++, EXAMPLE_SERVICE, feature->GetName(feature),
111a299bc30Sopenharmony_ci               (char *)request->data);
112a299bc30Sopenharmony_ci        Response response = {.data = "Yes, you did!", .len = 0};
113a299bc30Sopenharmony_ci        SAMGR_SendResponse(request, &response);
114a299bc30Sopenharmony_ci        return TRUE;
115a299bc30Sopenharmony_ci    } else {
116a299bc30Sopenharmony_ci        if (request->msgId == MSG_TIME_PROC) {
117a299bc30Sopenharmony_ci            LOS_Msleep(WAIT_FEATURE_PROC * 11); // sleep 11 seconds
118a299bc30Sopenharmony_ci            printf("[LPC Test][TaskID:%u][OnMessage: S:%s, F:%s] Time Message Get Value<%s>!",
119a299bc30Sopenharmony_ci                (int)osThreadGetId(), EXAMPLE_SERVICE, feature->GetName(feature),
120a299bc30Sopenharmony_ci                request->msgValue ? "TRUE" : "FALSE");
121a299bc30Sopenharmony_ci            AsyncTimeCall(GET_IUNKNOWN(g_example));
122a299bc30Sopenharmony_ci            return FALSE;
123a299bc30Sopenharmony_ci        }
124a299bc30Sopenharmony_ci    }
125a299bc30Sopenharmony_ci    printf("[LPC Test][TaskID:%u][Step:%u][OnMessage S:%s, F:%s] Inner Error! \n",
126a299bc30Sopenharmony_ci           (int)osThreadGetId(), g_asyncStep++, EXAMPLE_SERVICE, feature->GetName(feature));
127a299bc30Sopenharmony_ci    return FALSE;
128a299bc30Sopenharmony_ci}
129a299bc30Sopenharmony_ci
130a299bc30Sopenharmony_cistatic BOOL SyncCall(IUnknown *iUnknown, struct Payload *payload)
131a299bc30Sopenharmony_ci{
132a299bc30Sopenharmony_ci    (void)iUnknown;
133a299bc30Sopenharmony_ci    if (payload != NULL && payload->id >= 0 && payload->name != NULL) {
134a299bc30Sopenharmony_ci        printf("[LPC Test][TaskID:%u][Step:%u][SyncCall API] Id:%d, name:%s, value:%d \n",
135a299bc30Sopenharmony_ci               (int)osThreadGetId(), g_asyncStep++, payload->id, payload->name, payload->value);
136a299bc30Sopenharmony_ci        return TRUE;
137a299bc30Sopenharmony_ci    }
138a299bc30Sopenharmony_ci    printf("[LPC Test][TaskID:%u][Step:%u][SyncCall API] Input Error! \n", (int)osThreadGetId(), g_asyncStep++);
139a299bc30Sopenharmony_ci    return FALSE;
140a299bc30Sopenharmony_ci}
141a299bc30Sopenharmony_ci
142a299bc30Sopenharmony_cistatic BOOL AsyncCall(IUnknown *iUnknown, const char *body)
143a299bc30Sopenharmony_ci{
144a299bc30Sopenharmony_ci    Request request = {.msgId = MSG_PROC, .msgValue = 0};
145a299bc30Sopenharmony_ci    request.len = (uint32_t)(strlen(body) + 1);
146a299bc30Sopenharmony_ci    request.data = malloc(request.len);
147a299bc30Sopenharmony_ci    if (request.data == NULL) {
148a299bc30Sopenharmony_ci        return FALSE;
149a299bc30Sopenharmony_ci    }
150a299bc30Sopenharmony_ci    if (strcpy_s(request.data, request.len, body) != EOK) {
151a299bc30Sopenharmony_ci        free(request.data);
152a299bc30Sopenharmony_ci        return FALSE;
153a299bc30Sopenharmony_ci    }
154a299bc30Sopenharmony_ci    DemoFeature *feature = GET_OBJECT(iUnknown, DemoFeature, iUnknown);
155a299bc30Sopenharmony_ci    printf("[LPC Test][TaskID:%u][Step:%u][AsyncCall API] Send request! \n", (int)osThreadGetId(), g_asyncStep++);
156a299bc30Sopenharmony_ci    return SAMGR_SendRequest(&feature->identity, &request, NULL);
157a299bc30Sopenharmony_ci}
158a299bc30Sopenharmony_ci
159a299bc30Sopenharmony_cistatic BOOL AsyncTimeCall(IUnknown *iUnknown)
160a299bc30Sopenharmony_ci{
161a299bc30Sopenharmony_ci    static int8 cnt = 0;
162a299bc30Sopenharmony_ci    cnt = (cnt + 1) % 2; // mod 2 to get async status
163a299bc30Sopenharmony_ci    Request request = {.msgId = MSG_TIME_PROC, .msgValue = cnt};
164a299bc30Sopenharmony_ci    DemoFeature *feature = GET_OBJECT(iUnknown, DemoFeature, iUnknown);
165a299bc30Sopenharmony_ci    return SAMGR_SendRequest(&feature->identity, &request, NULL);
166a299bc30Sopenharmony_ci}
167a299bc30Sopenharmony_ci
168a299bc30Sopenharmony_cistatic BOOL AsyncCallBack(IUnknown *iUnknown, const char *body, Handler handler)
169a299bc30Sopenharmony_ci{
170a299bc30Sopenharmony_ci    Request request = {.msgId = MSG_PROC, .msgValue = 0};
171a299bc30Sopenharmony_ci    request.len = (uint32_t)(strlen(body) + 1);
172a299bc30Sopenharmony_ci    request.data = malloc(request.len);
173a299bc30Sopenharmony_ci    if (request.data == NULL) {
174a299bc30Sopenharmony_ci        return FALSE;
175a299bc30Sopenharmony_ci    }
176a299bc30Sopenharmony_ci    if (strcpy_s(request.data, request.len, body) != EOK) {
177a299bc30Sopenharmony_ci        free(request.data);
178a299bc30Sopenharmony_ci        return FALSE;
179a299bc30Sopenharmony_ci    }
180a299bc30Sopenharmony_ci    DemoFeature *feature = GET_OBJECT(iUnknown, DemoFeature, iUnknown);
181a299bc30Sopenharmony_ci    printf("[LPC Test][TaskID:%u][Step:%u][AsyncCallBack API] Send request! \n",
182a299bc30Sopenharmony_ci           (int)osThreadGetId(), g_asyncStep++);
183a299bc30Sopenharmony_ci    return SAMGR_SendRequest(&feature->identity, &request, handler);
184a299bc30Sopenharmony_ci}
185a299bc30Sopenharmony_ci
186a299bc30Sopenharmony_cistatic void Init(void)
187a299bc30Sopenharmony_ci{
188a299bc30Sopenharmony_ci    SAMGR_GetInstance()->RegisterFeature(EXAMPLE_SERVICE, (Feature *)&g_example);
189a299bc30Sopenharmony_ci    SAMGR_GetInstance()->RegisterFeatureApi(EXAMPLE_SERVICE, EXAMPLE_FEATURE, GET_IUNKNOWN(g_example));
190a299bc30Sopenharmony_ci    printf("[Register Test][TaskID:%u][Step:%u][Reg S:%s, F:%s]Time: %llu!\n",
191a299bc30Sopenharmony_ci           (int)osThreadGetId(), g_regStep++, EXAMPLE_SERVICE, EXAMPLE_FEATURE, SAMGR_GetProcessTime());
192a299bc30Sopenharmony_ci}
193a299bc30Sopenharmony_ci
194a299bc30Sopenharmony_ciSYSEX_FEATURE_INIT(Init);
195a299bc30Sopenharmony_ci
196a299bc30Sopenharmony_cistatic uint32_t g_discoverStep = 0;
197a299bc30Sopenharmony_ci
198a299bc30Sopenharmony_cistatic DemoApi *CASE_GetIUnknown(void)
199a299bc30Sopenharmony_ci{
200a299bc30Sopenharmony_ci    DemoApi *demoApi = NULL;
201a299bc30Sopenharmony_ci    printf("[Discover Test][TaskID:%u][Step:%u][GetIUnknown S:%s, F:%s]: BEGIN\n",
202a299bc30Sopenharmony_ci           (int)osThreadGetId(), g_discoverStep++, EXAMPLE_SERVICE, EXAMPLE_FEATURE);
203a299bc30Sopenharmony_ci    IUnknown *iUnknown = SAMGR_GetInstance()->GetFeatureApi(EXAMPLE_SERVICE, EXAMPLE_FEATURE);
204a299bc30Sopenharmony_ci    if (iUnknown == NULL) {
205a299bc30Sopenharmony_ci        printf("[Discover Test][TaskID:%u][Step:%u][GetFeatureApi S:%s, F:%s]Error is NULL!\n",
206a299bc30Sopenharmony_ci               (int)osThreadGetId(), g_discoverStep++, EXAMPLE_SERVICE, EXAMPLE_FEATURE);
207a299bc30Sopenharmony_ci        goto END;
208a299bc30Sopenharmony_ci    }
209a299bc30Sopenharmony_ci    int result = iUnknown->QueryInterface(iUnknown, DEFAULT_VERSION, (void **)&demoApi);
210a299bc30Sopenharmony_ci    if (result != 0 || demoApi == NULL) {
211a299bc30Sopenharmony_ci        printf("[Discover Test][TaskID:%u][Step:%u][QueryInterface S:%s, F:%s]Error is NULL!\n",
212a299bc30Sopenharmony_ci               (int)osThreadGetId(), g_discoverStep++, EXAMPLE_SERVICE, EXAMPLE_FEATURE);
213a299bc30Sopenharmony_ci        goto END;
214a299bc30Sopenharmony_ci    }
215a299bc30Sopenharmony_ci    printf("[Discover Test][TaskID:%u][Step:%u][GetIUnknown S:%s, F:%s]Success\n",
216a299bc30Sopenharmony_ci           (int)osThreadGetId(), g_discoverStep++, EXAMPLE_SERVICE, EXAMPLE_FEATURE);
217a299bc30Sopenharmony_ciEND:
218a299bc30Sopenharmony_ci    printf("[Discover Test][TaskID:%u][Step:%u][GetIUnknown S:%s, F:%s]: END\n",
219a299bc30Sopenharmony_ci           (int)osThreadGetId(), g_discoverStep++, EXAMPLE_SERVICE, EXAMPLE_FEATURE);
220a299bc30Sopenharmony_ci    return demoApi;
221a299bc30Sopenharmony_ci}
222a299bc30Sopenharmony_ci
223a299bc30Sopenharmony_cistatic void CASE_SyncCall(DemoApi *demoApi)
224a299bc30Sopenharmony_ci{
225a299bc30Sopenharmony_ci    if (demoApi->SyncCall == NULL) {
226a299bc30Sopenharmony_ci        return;
227a299bc30Sopenharmony_ci    }
228a299bc30Sopenharmony_ci    printf("[LPC Test][TaskID:%u][Step:%u][SyncCall]: BEGIN! \n", (int)osThreadGetId(), g_asyncStep++);
229a299bc30Sopenharmony_ci    struct Payload payload = {
230a299bc30Sopenharmony_ci        .id = 0,
231a299bc30Sopenharmony_ci        .name = "I want to sync call good result!",
232a299bc30Sopenharmony_ci        .value = 1
233a299bc30Sopenharmony_ci    };
234a299bc30Sopenharmony_ci    if (!demoApi->SyncCall((IUnknown *)demoApi, &payload)) {
235a299bc30Sopenharmony_ci        printf("[LPC Test][TaskID:%u][Step:%u][SyncCall]Error return false! \n",
236a299bc30Sopenharmony_ci               (int)osThreadGetId(), g_asyncStep++);
237a299bc30Sopenharmony_ci        goto END;
238a299bc30Sopenharmony_ci    }
239a299bc30Sopenharmony_ci    printf("[LPC Test][TaskID:%u][Step:%u][SyncCall]Success!\n",
240a299bc30Sopenharmony_ci           (int)osThreadGetId(), g_asyncStep++);
241a299bc30Sopenharmony_ciEND:
242a299bc30Sopenharmony_ci    printf("[LPC Test][TaskID:%u][Step:%u][SyncCall]: END\n",
243a299bc30Sopenharmony_ci           (int)osThreadGetId(), g_asyncStep++);
244a299bc30Sopenharmony_ci}
245a299bc30Sopenharmony_ci
246a299bc30Sopenharmony_ci
247a299bc30Sopenharmony_cistatic void CASE_AsyncCall(DemoApi *demoApi)
248a299bc30Sopenharmony_ci{
249a299bc30Sopenharmony_ci    if (demoApi->AsyncCall == NULL) {
250a299bc30Sopenharmony_ci        return;
251a299bc30Sopenharmony_ci    }
252a299bc30Sopenharmony_ci    printf("[LPC Test][TaskID:%u][Step:%u][AsyncCall]: BEGIN! \n", (int)osThreadGetId(), g_asyncStep++);
253a299bc30Sopenharmony_ci    uint32 count = g_asyncStep;
254a299bc30Sopenharmony_ci    demoApi->AsyncCall((IUnknown *)demoApi, "I want to async call good result!");
255a299bc30Sopenharmony_ci    LOS_Msleep(WAIT_FEATURE_PROC);
256a299bc30Sopenharmony_ci    if (count == g_asyncStep) {
257a299bc30Sopenharmony_ci        printf("[LPC Test][TaskID:%u][Step:%u][AsyncCall] result is failed! \n", (int)osThreadGetId(),
258a299bc30Sopenharmony_ci               g_asyncStep++);
259a299bc30Sopenharmony_ci        goto END;
260a299bc30Sopenharmony_ci    }
261a299bc30Sopenharmony_ci    printf("[LPC Test][TaskID:%u][Step:%u][AsyncCall]Success! \n", (int)osThreadGetId(), g_asyncStep++);
262a299bc30Sopenharmony_ciEND:
263a299bc30Sopenharmony_ci    printf("[LPC Test][TaskID:%u][Step:%u][AsyncCall]: END! \n", (int)osThreadGetId(), g_asyncStep++);
264a299bc30Sopenharmony_ci}
265a299bc30Sopenharmony_ci
266a299bc30Sopenharmony_cistatic void CASE_AsyncTimeCall(DemoApi *demoApi)
267a299bc30Sopenharmony_ci{
268a299bc30Sopenharmony_ci    if (demoApi->AsyncCall == NULL) {
269a299bc30Sopenharmony_ci        return;
270a299bc30Sopenharmony_ci    }
271a299bc30Sopenharmony_ci    demoApi->AsyncTimeCall((IUnknown *)demoApi);
272a299bc30Sopenharmony_ci}
273a299bc30Sopenharmony_ci
274a299bc30Sopenharmony_cistatic void AsyncHandler(const Request *request, const Response *response)
275a299bc30Sopenharmony_ci{
276a299bc30Sopenharmony_ci    (void)request;
277a299bc30Sopenharmony_ci    printf("[LPC Test][TaskID:%u][Step:%u][AsyncCallBack]Success! Response:%s \n",
278a299bc30Sopenharmony_ci           (int)osThreadGetId(), g_asyncStep++, (char *)response->data);
279a299bc30Sopenharmony_ci    printf("[LPC Test][TaskID:%u][Step:%u][AsyncCallBack]: END! \n", (int)osThreadGetId(), g_asyncStep++);
280a299bc30Sopenharmony_ci}
281a299bc30Sopenharmony_ci
282a299bc30Sopenharmony_cistatic void CASE_AsyncCallBack(DemoApi *demoApi)
283a299bc30Sopenharmony_ci{
284a299bc30Sopenharmony_ci    if (demoApi->AsyncCallBack == NULL) {
285a299bc30Sopenharmony_ci        return;
286a299bc30Sopenharmony_ci    }
287a299bc30Sopenharmony_ci    printf("[LPC Test][TaskID:%u][Step:%u][AsyncCallBack]: BEGIN! \n", (int)osThreadGetId(), g_asyncStep++);
288a299bc30Sopenharmony_ci    demoApi->AsyncCallBack((IUnknown *)demoApi, "I want to async call callback good result!", AsyncHandler);
289a299bc30Sopenharmony_ci    printf("[LPC Test][TaskID:%u][Step:%u][AsyncCallBack]Wait for response! \n",
290a299bc30Sopenharmony_ci           (int)osThreadGetId(), g_asyncStep++);
291a299bc30Sopenharmony_ci}
292a299bc30Sopenharmony_ci
293a299bc30Sopenharmony_cistatic void CASE_ReleaseIUnknown(DemoApi *demoApi)
294a299bc30Sopenharmony_ci{
295a299bc30Sopenharmony_ci    printf("[Discover Test][TaskID:%u][Step:%u][ReleaseIUnknown S:%s, F:%s]: BEGIN\n",
296a299bc30Sopenharmony_ci           (int)osThreadGetId(), g_discoverStep++, EXAMPLE_SERVICE, EXAMPLE_FEATURE);
297a299bc30Sopenharmony_ci    int32 ref = demoApi->Release((IUnknown *)demoApi);
298a299bc30Sopenharmony_ci    if (ref <= 0) {
299a299bc30Sopenharmony_ci        printf("[Discover Test][TaskID:%u][Step:%u][ReleaseIUnknown S:%s, F:%s]Error ref is %d!\n",
300a299bc30Sopenharmony_ci               (int)osThreadGetId(), g_discoverStep++, EXAMPLE_SERVICE, EXAMPLE_FEATURE, ref);
301a299bc30Sopenharmony_ci        goto END;
302a299bc30Sopenharmony_ci    }
303a299bc30Sopenharmony_ci    printf("[Discover Test][TaskID:%u][Step:%u][ReleaseIUnknown S:%s, F:%s]Success\n",
304a299bc30Sopenharmony_ci           (int)osThreadGetId(), g_discoverStep++, EXAMPLE_SERVICE, EXAMPLE_FEATURE);
305a299bc30Sopenharmony_ciEND:
306a299bc30Sopenharmony_ci    printf("[Discover Test][TaskID:%u][Step:%u][ReleaseIUnknown S:%s, F:%s]: END\n",
307a299bc30Sopenharmony_ci           (int)osThreadGetId(), g_discoverStep++, EXAMPLE_SERVICE, EXAMPLE_FEATURE);
308a299bc30Sopenharmony_ci}
309a299bc30Sopenharmony_ci
310a299bc30Sopenharmony_cistatic void RunTestCase(void)
311a299bc30Sopenharmony_ci{
312a299bc30Sopenharmony_ci    DemoApi *demoApi = CASE_GetIUnknown();
313a299bc30Sopenharmony_ci    CASE_SyncCall(demoApi);
314a299bc30Sopenharmony_ci    CASE_AsyncCall(demoApi);
315a299bc30Sopenharmony_ci    CASE_AsyncCallBack(demoApi);
316a299bc30Sopenharmony_ci    CASE_AsyncTimeCall(demoApi);
317a299bc30Sopenharmony_ci    CASE_ReleaseIUnknown(demoApi);
318a299bc30Sopenharmony_ci}
319a299bc30Sopenharmony_ci
320a299bc30Sopenharmony_ciLAYER_INITCALL_DEF(RunTestCase, test, "test");
321