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 <stdint.h>
17#include "samgr_lite.h"
18#include "broadcast_interface.h"
19#include <ohos_init.h>
20#include <securec.h>
21#include <los_base.h>
22#include <cmsis_os.h>
23#include "time_adapter.h"
24
25#define TEST_LEN 10
26#define WAIT_PUB_PROC 1000
27#define BROADCAST_TEST_SERVICE "broadcast test"
28
29static uint32_t g_callbackStep = 0;
30
31static void C1Callback(Consumer *consumer, const Topic *topic, const Request *request)
32{
33    (void)consumer;
34    (void)topic;
35    printf("[Broadcast Test][TaskID:%u][Step:%u][C1 Callback]c1 is being called data is :%s \n",
36           (int)osThreadGetId(), g_callbackStep++, (char *)request->data);
37}
38
39static void C2Callback(Consumer *consumer, const Topic *topic, const Request *request)
40{
41    (void)consumer;
42    (void)topic;
43    printf("[Broadcast Test][TaskID:%u][Step:%u][C2 Callback]c2 is being called data is :%s \n",
44           (int)osThreadGetId(), g_callbackStep++, (char *)request->data);
45}
46
47static BOOL Equal(const Consumer *current, const Consumer *other)
48{
49    return  (current->Notify == other->Notify);
50}
51
52static const char *GetName(Service *service)
53{
54    (void)service;
55    return BROADCAST_TEST_SERVICE;
56};
57
58static Identity g_identity = { -1, -1, NULL};
59static volatile uint32_t g_broadcastStep = 0;
60
61static BOOL Initialize(Service *service, Identity identity)
62{
63    g_identity = identity;
64    (void)service;
65    printf("[Broadcast Test][TaskID:%u][Step:%u][Reg Finish S:%s]Time: %llu!\n",
66           (int)osThreadGetId(), g_broadcastStep++, BROADCAST_TEST_SERVICE, SAMGR_GetProcessTime());
67    return TRUE;
68};
69
70static BOOL MessageHandle(Service *service, Request *msg)
71{
72    printf("[Broadcast Test][TaskID:%u] msgId<%d>: %s \n", (int)osThreadGetId(), msg->msgId, (char *)msg->data);
73    (void)service;
74    return FALSE;
75};
76
77static TaskConfig GetTaskConfig(Service *service)
78{
79    TaskConfig config = {LEVEL_HIGH, PRI_ABOVE_NORMAL, 0x800, 20, SHARED_TASK};
80    (void)service;
81    return config;
82};
83
84static Service g_testService = {GetName, Initialize, MessageHandle, GetTaskConfig};
85
86static void Init(void)
87{
88    SAMGR_GetInstance()->RegisterService(&g_testService);
89    printf("[Broadcast Test][TaskID:%u][Step:%u][Reg S:%s]Time: %llu!\n",
90           (int)osThreadGetId(), g_broadcastStep++, BROADCAST_TEST_SERVICE, SAMGR_GetProcessTime());
91}
92
93SYSEX_SERVICE_INIT(Init);
94
95static PubSubInterface *CASE_GetIUnknown(void)
96{
97    PubSubInterface *fapi = NULL;
98    printf("[Broadcast Test][TaskID:%u][Step:%u][GetIUnknown S:%s]: BEGIN\n",
99           (int)osThreadGetId(), g_broadcastStep++, BROADCAST_TEST_SERVICE);
100    IUnknown *iUnknown = SAMGR_GetInstance()->GetFeatureApi(BROADCAST_SERVICE, PUB_SUB_FEATURE);
101    if (iUnknown == NULL) {
102        printf("[Broadcast Test][TaskID:%u][Step:%u][GetDefaultFeatureApi S:%s]Error is NULL!\n",
103               (int)osThreadGetId(), g_broadcastStep++, BROADCAST_TEST_SERVICE);
104        goto END;
105    }
106
107    int result = iUnknown->QueryInterface(iUnknown, DEFAULT_VERSION, (void **)&fapi);
108    if (result != 0 || fapi == NULL) {
109        printf("[Broadcast Test][TaskID:%u][Step:%u][QueryInterface S:%s]Error is NULL!\n",
110               (int)osThreadGetId(), g_broadcastStep++, BROADCAST_TEST_SERVICE);
111        goto END;
112    }
113    printf("[Broadcast Test][TaskID:%u][Step:%u][GetIUnknown S:%s]Success\n",
114           (int)osThreadGetId(), g_broadcastStep++, BROADCAST_TEST_SERVICE);
115END:
116    printf("[Broadcast Test][TaskID:%u][Step:%u][GetIUnknown S:%s]: END\n",
117           (int)osThreadGetId(), g_broadcastStep++, BROADCAST_TEST_SERVICE);
118    return fapi;
119}
120
121static uint32_t g_addTopicStep = 0;
122static uint32_t g_unsubscribeTopicStep = 0;
123
124static void CASE_AddAndUnsubscribeTopic(PubSubInterface *fapi)
125{
126    Subscriber *subscriber = &fapi->subscriber;
127    Provider *provider = &fapi->provider;
128    static Consumer c1 = {.identity = &g_identity, .Notify = C1Callback, .Equal = Equal};
129    static Consumer c2 = {.identity = &g_identity, .Notify = C2Callback, .Equal = Equal};
130    // add topic test
131    printf("[Topic Test][TaskID:%u][Step:%u][Add Topic]: BEGIN\n", (int)osThreadGetId(), g_addTopicStep++);
132    Topic topic0 = 0;
133    subscriber->AddTopic((IUnknown *)fapi, &topic0);
134    subscriber->Subscribe((IUnknown *)fapi, &topic0, &c1);
135    subscriber->Subscribe((IUnknown *)fapi, &topic0, &c2);
136    provider->Publish((IUnknown *)fapi, &topic0, (uint8_t *) "==>111<==", TEST_LEN);
137    Topic topic1 = 0x10000;
138    subscriber->AddTopic((IUnknown *)fapi, &topic1);
139    subscriber->Subscribe((IUnknown *)fapi, &topic1, &c1);
140    subscriber->Subscribe((IUnknown *)fapi, &topic1, &c2);
141    provider->Publish((IUnknown *)fapi, &topic1, (uint8_t *) "==>444<==", TEST_LEN);
142    printf("[Topic Test][TaskID:%u][Step:%u][Add  Topic]: Success!\n", (int)osThreadGetId(), g_addTopicStep++);
143    printf("[Topic Test][TaskID:%u][Step:%u][Add  Topic]: END\n", (int)osThreadGetId(), g_addTopicStep++);
144    // unsubscribe topic0 test
145    printf("[Topic Test][TaskID:%u][Step:%u][Unsubscribe Topic]: BEGIN\n", (int)osThreadGetId(),
146           g_unsubscribeTopicStep++);
147    LOS_Msleep(WAIT_PUB_PROC);
148    subscriber->Unsubscribe((IUnknown *)fapi, &topic0, &c1);
149    provider->Publish((IUnknown *)fapi, &topic0, (uint8_t *) "@@@222@@@", TEST_LEN);
150    LOS_Msleep(WAIT_PUB_PROC);
151    subscriber->Unsubscribe((IUnknown *)fapi, &topic0, &c2);
152    provider->Publish((IUnknown *)fapi, &topic0, (uint8_t *) "@@@333@@@", TEST_LEN);
153    provider->Publish((IUnknown *)fapi, &topic1, (uint8_t *) "@@@444@@@", TEST_LEN);
154    printf("[Topic Test][TaskID:%u][Step:%u][Unsubscribe Topic]: Success!\n",
155           (int)osThreadGetId(), g_unsubscribeTopicStep++);
156    printf("[Topic Test][TaskID:%u][Step:%u][Unsubscribe Topic]: END\n", (int)osThreadGetId(),
157           g_unsubscribeTopicStep++);
158}
159
160static uint32_t g_modifyConsumerStep = 0;
161
162static void CASE_ModifyConsumer(PubSubInterface *fapi)
163{
164    Subscriber *subscriber = &fapi->subscriber;
165    Provider *provider = &fapi->provider;
166    static Consumer c1 = {.identity = &g_identity, .Notify = C1Callback, .Equal = Equal};
167    static Consumer c2 = {.identity = &g_identity, .Notify = C2Callback, .Equal = Equal};
168    // modify consumer test
169    printf("[Topic Test][TaskID:%u][Step:%u][Modify Consumer]: BEGIN\n", (int)osThreadGetId(),
170           g_modifyConsumerStep++);
171    Topic topic2 = 0x100;
172    subscriber->AddTopic((IUnknown *)fapi, &topic2);
173    subscriber->Subscribe((IUnknown *)fapi, &topic2, &c1);
174    provider->Publish((IUnknown *)fapi, &topic2, (uint8_t *) "==>555<==", TEST_LEN);
175    LOS_Msleep(WAIT_PUB_PROC);
176    subscriber->ModifyConsumer((IUnknown *)fapi, &topic2, &c1, &c2);
177    provider->Publish((IUnknown *)fapi, &topic2, (uint8_t *) "@@@555@@@", TEST_LEN);
178    printf("[Topic Test][TaskID:%u][Step:%u][Modify Consumer]: Success!\n", (int)osThreadGetId(),
179           g_modifyConsumerStep++);
180    printf("[Topic Test][TaskID:%u][Step:%u][Modify Consumer]: END\n", (int)osThreadGetId(),
181           g_modifyConsumerStep++);
182}
183
184static uint32_t g_reUnsubscribeTopic = 0;
185
186static void CASE_ReUnsubscribeTopic(PubSubInterface *fapi)
187{
188    Subscriber *subscriber = &fapi->subscriber;
189    Provider *provider = &fapi->provider;
190    static Consumer c1 = {.identity = &g_identity, .Notify = C1Callback, .Equal = Equal};
191    printf("[Topic Test][TaskID:%u][Step:%u][ReUnsubscribe Topic]: BEGIN\n", (int)osThreadGetId(),
192           g_reUnsubscribeTopic++);
193    Topic topic3 = 0x1000;
194    subscriber->AddTopic((IUnknown *)fapi, &topic3);
195    subscriber->Subscribe((IUnknown *)fapi, &topic3, &c1);
196    provider->Publish((IUnknown *)fapi, &topic3, (uint8_t *) "==>666<==", TEST_LEN);
197    LOS_Msleep(WAIT_PUB_PROC);
198    Consumer *retConsumer = subscriber->Unsubscribe((IUnknown *)fapi, &topic3, &c1);
199    if (retConsumer == NULL) {
200        printf("[Topic Test][TaskID:%u][Step:%u][ReUnsubscribe Topic]: Unsubscribe Topic lead to NULL return value\n",
201               (int)osThreadGetId(), g_reUnsubscribeTopic++);
202    }
203    retConsumer = subscriber->Unsubscribe((IUnknown *)fapi, &topic3, &c1);
204    if (retConsumer == NULL) {
205        printf("[Topic Test][TaskID:%u][Step:%u][ReUnsubscribe Topic]: ReUnsubscribe Topic lead to NULL return value\n",
206               (int)osThreadGetId(), g_reUnsubscribeTopic++);
207    }
208    provider->Publish((IUnknown *)fapi, &topic3, (uint8_t *) "@@@666@@@", TEST_LEN);
209    printf("[Topic Test][TaskID:%u][Step:%u][ReUnsubscribe Topic]: Success!\n",
210           (int)osThreadGetId(), g_reUnsubscribeTopic++);
211    printf("[Topic Test][TaskID:%u][Step:%u][ReUnsubscribe Topic]: END\n", (int)osThreadGetId(),
212           g_reUnsubscribeTopic++);
213}
214
215static void CASE_ReleaseIUnknown(PubSubInterface *fapi)
216{
217    printf("[Broadcast Test][TaskID:%u][Step:%u][ReleaseIUnknown S:%s]: BEGIN\n",
218           (int)osThreadGetId(), g_broadcastStep++, BROADCAST_TEST_SERVICE);
219    int32 ref = fapi->Release((IUnknown *)fapi);
220    if (ref <= 0) {
221        printf("[Broadcast Test][TaskID:%u][Step:%u][ReleaseIUnknown S:%s]Error ref is %d!\n",
222               (int)osThreadGetId(), g_broadcastStep++, BROADCAST_TEST_SERVICE, ref);
223        goto END;
224    }
225    printf("[Broadcast Test][TaskID:%u][Step:%u][ReleaseIUnknown S:%s]Success\n",
226           (int)osThreadGetId(), g_broadcastStep++, BROADCAST_TEST_SERVICE);
227END:
228    printf("[Broadcast Test][TaskID:%u][Step:%u][ReleaseIUnknown S:%s]: END\n",
229           (int)osThreadGetId(), g_broadcastStep++, BROADCAST_TEST_SERVICE);
230}
231
232static void RunTestCase(void)
233{
234    PubSubInterface *fapi = CASE_GetIUnknown();
235    CASE_AddAndUnsubscribeTopic(fapi);
236    CASE_ModifyConsumer(fapi);
237    CASE_ReUnsubscribeTopic(fapi);
238    CASE_ReleaseIUnknown(fapi);
239}
240
241LAYER_INITCALL_DEF(RunTestCase, test, "test");
242