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