[IOT-1808]Changes in C++ APIs to remove TopicList raw pointers.
[platform/upstream/iotivity.git] / service / notification / cpp-wrapper / examples / linux / notificationserviceconsumer.cpp
1 /******************************************************************
2  *
3  * Copyright 2016 Samsung Electronics All Rights Reserved.
4  *
5  *
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  ******************************************************************/
20
21 #include <iostream>
22 #include <limits>
23
24 #include <unistd.h>
25 #include "NSConsumerService.h"
26 #include "NSMessage.h"
27 #include "NSProvider.h"
28 #include "NSTopicsList.h"
29 #include "ocstack.h"
30
31 #define TAG "NotiConsumerWrapperExample"
32 using namespace std;
33 using namespace OIC::Service;
34
35 bool isExit = false;
36 std::string REMOTE_SERVER_ADDRESS;
37 std::string mainProvider;
38 uint64_t mainMessageId = 0;
39
40 FILE *server_fopen(const char *path, const char *mode)
41 {
42     if (0 == strcmp(path, OC_SECURITY_DB_DAT_FILE_NAME))
43     {
44         return fopen("oic_ns_provider_db.dat", mode);
45     }
46     else
47     {
48         return fopen(path, mode);
49     }
50 }
51
52 void onNotificationPostedCb(OIC::Service::NSMessage notification)
53 {
54     std::cout << "------------------------------------" << std::endl;
55     std::cout << "Message Received " << std::endl;
56     std::cout << "------------------------------------" << std::endl;
57     std::cout << "id : " << notification.getMessageId() << std::endl;
58     std::cout << "title : " << notification.getTitle() << std::endl;
59     std::cout << "content : " <<  notification.getContentText() << std::endl;
60     std::cout << "source : " <<  notification.getSourceName() << std::endl;
61     std::cout << "topic : " <<  notification.getTopic() << std::endl;
62     std::cout << "type : " <<  (int) notification.getType() << std::endl;
63     std::cout << "TTL : " <<  notification.getTTL() << std::endl;
64     std::cout << "time : " <<  notification.getTime() << std::endl;
65     if (notification.getMediaContents() != nullptr)
66     {
67         std::cout << "MediaContents IconImage : " <<  notification.getMediaContents()->getIconImage()
68                   << std::endl;
69     }
70     std::cout << "ExtraInfo " << std::endl;
71     OC::OCRepresentation rep = notification.getExtraInfo();
72     for (auto it : rep.getResourceTypes())
73     {
74         std::cout << "resourceType : " << it << std::endl;
75     }
76     for (auto it : rep.getResourceInterfaces())
77     {
78         std::cout << "Interface : " << it << std::endl;
79     }
80     for (auto it : rep.getValues())
81     {
82         std::cout << "Key : " << it.first << std::endl;
83     }
84     mainMessageId = notification.getMessageId();
85 }
86
87 void onNotificationSyncCb(OIC::Service::NSSyncInfo sync)
88 {
89     std::cout << "------------------------------------" << std::endl;
90     std::cout << "SyncInfo Received " << std::endl;
91     std::cout << "------------------------------------" << std::endl;
92     std::cout << "Sync ID : " <<  sync.getMessageId() << std::endl;
93     std::cout << "Provider ID : " <<  sync.getProviderId() << std::endl;
94     std::cout << "Sync STATE : " << (int) sync.getState() << std::endl;
95 }
96
97 void onProviderStateChangedCb(OIC::Service::NSProviderState state)
98 {
99     std::cout << "onProviderStateChangedCb" << std::endl;
100     if (state == OIC::Service::NSProviderState::ALLOW)
101     {
102         std::cout << "Provider Subscription Accepted" << std::endl;
103     }
104     else if (state == OIC::Service::NSProviderState::DENY)
105     {
106         std::cout << "Provider Subscription Denied" << std::endl;
107         std::cout << "------------------------------------" << std::endl;
108     }
109     else if (state == OIC::Service::NSProviderState::TOPIC)
110     {
111         std::shared_ptr<OIC::Service::NSProvider> provider =
112             NSConsumerService::getInstance()->getProvider(mainProvider);
113         if (provider != nullptr)
114         {
115             auto topicList = provider->getTopicList();
116             if (topicList != nullptr)
117             {
118                 for (auto it : topicList->getTopicsList())
119                 {
120                     std::cout << "Topic Name: " << it.getTopicName() << std::endl;
121                     std::cout << "Topic state: " << (int) it.getState() << std::endl;
122                 }
123             }
124         }
125     }
126     else if (state == OIC::Service::NSProviderState::STOPPED)
127     {
128         std::cout << "Provider Stopped" << std::endl;
129         std::cout << "------------------------------------" << std::endl;
130     }
131 }
132
133 void onDiscoverNotificationCb(std::shared_ptr<OIC::Service::NSProvider> provider)
134 {
135     std::cout << "Notification Resource Discovered" << std::endl;
136     std::cout << "SetListeners for callbacks" << std::endl;
137     std::cout << "ProviderID : " << provider->getProviderId() << std::endl;
138     provider->setListener(onProviderStateChangedCb, onNotificationPostedCb, onNotificationSyncCb);
139     if (!provider->isSubscribed())
140     {
141         std::cout << "startSubscribing" << std::endl;
142         provider->subscribe();
143     }
144     if (mainProvider.empty())
145     {
146         mainProvider = provider->getProviderId();
147     }
148 }
149
150 void *OCProcessThread(void *ptr)
151 {
152     (void) ptr;
153
154     while (!isExit)
155     {
156         usleep(2000);
157         if (OCProcess() != OC_STACK_OK)
158         {
159             OCStop();
160             break;
161         }
162     }
163
164     return NULL;
165 }
166
167 int main(void)
168 {
169     pthread_t OCThread = 0;
170
171     std::cout << "start Iotivity" << std::endl;
172
173     // open oic_db
174     static OCPersistentStorage ps = {server_fopen, fread, fwrite, fclose, unlink};
175     OCRegisterPersistentStorageHandler(&ps);
176
177     if (OCInit1(OC_CLIENT_SERVER, OC_DEFAULT_FLAGS, OC_DEFAULT_FLAGS) != OC_STACK_OK)
178     {
179         std::cout << "OCInit fail" << std::endl;
180         return 0;
181     }
182
183     pthread_create(&OCThread, NULL, OCProcessThread, NULL);
184
185     std::cout << "Start notification consumer service" << std::endl;
186     while (!isExit)
187     {
188         int num = 0;
189
190         std::cout << "1. Start Consumer" << std::endl;
191         std::cout << "2. Stop Consumer" << std::endl;
192         std::cout << "3. SendSyncInfo" << std::endl;
193         std::cout << "4. GetTopicList" << std::endl;
194         std::cout << "5. UpdateTopicList" << std::endl;
195         std::cout << "6. Subscribe provider" << std::endl;
196         std::cout << "7. UnSubscribe provider" << std::endl;
197         std::cout << "8. Rescan provider" << std::endl;
198 #ifdef WITH_CLOUD
199         std::cout << "9. Enable  NS Consumer RemoteService" << std::endl;
200 #endif
201         std::cout << "10. Exit" << std::endl;
202
203         std::cout << "Input: " << std::endl;
204         std::cin >> num;
205         switch (num)
206         {
207             case 1:
208                 {
209                     std::cout << "Start the Notification Consumer" << std::endl;
210                     NSConsumerService::getInstance()->start(onDiscoverNotificationCb);
211                     break;
212                 }
213             case 2:
214                 {
215                     std::cout << "Stop the Notification Consumer" << std::endl;
216                     NSConsumerService::getInstance()->stop();
217                     break;
218                 }
219             case 3:
220                 {
221                     std::cout <<  "SendSyncInfo" << std::endl;
222                     if (!mainMessageId)
223                     {
224                         std::cout <<  "Message ID is empty" << std::endl;
225                         break;
226                     }
227                     std::cout << "1. Send Read Sync" << std::endl;
228                     std::cout << "2. Send Delete Sync" << std::endl;
229                     int syn = 0;
230                     while (!(std::cin >> syn))
231                     {
232                         std::cout << "Bad value!" << std::endl;;
233                         std::cin.clear();
234                         std::cin.ignore(numeric_limits<streamsize>::max(), '\n');
235                     }
236                     switch (syn)
237                     {
238                         case 1:
239                             {
240                                 std::cout << "Sending Read Sync" << std::endl;
241                                 auto provider = NSConsumerService::getInstance()->getProvider(
242                                                     mainProvider);
243                                 if (provider != nullptr)
244                                 {
245                                     provider->sendSyncInfo(mainMessageId,
246                                                            OIC::Service::NSSyncInfo::NSSyncType::NS_SYNC_READ);
247                                 }
248                             }
249                             break;
250                         case 2:
251                             {
252                                 std::cout << "Sending Delete Sync" << std::endl;
253                                 auto provider = NSConsumerService::getInstance()->getProvider(
254                                                     mainProvider);
255                                 if (provider != nullptr)
256                                 {
257                                     provider->sendSyncInfo(mainMessageId,
258                                                            OIC::Service::NSSyncInfo::NSSyncType::NS_SYNC_DELETED);
259                                 }
260                             }
261                             break;
262                         default:
263                             {
264                                 cout << "Invalid Input!. sending default Read Sync";
265                                 auto provider = NSConsumerService::getInstance()->getProvider(
266                                                     mainProvider);
267                                 if (provider != nullptr)
268                                 {
269                                     provider->sendSyncInfo(mainMessageId,
270                                                            OIC::Service::NSSyncInfo::NSSyncType::NS_SYNC_READ);
271                                 }
272                                 std::cin.clear();
273                                 std::cin.ignore(numeric_limits<streamsize>::max(), '\n');
274                                 break;
275                             }
276                     }
277                     break;
278                 }
279             case 4:
280                 {
281                     std::cout <<  "GetTopicList" << std::endl;
282                     std::shared_ptr<OIC::Service::NSProvider> provider =
283                         NSConsumerService::getInstance()->getProvider(mainProvider);
284                     if (provider != nullptr)
285                     {
286                         auto topicList = provider->getTopicList();
287                         if (topicList != nullptr)
288                         {
289                             for (auto it : topicList->getTopicsList())
290                             {
291                                 std::cout << "Topic Name: " << it.getTopicName() << std::endl;
292                                 std::cout << "Topic state: " << (int) it.getState() << std::endl;
293                             }
294                         }
295                     }
296                     break;
297                 }
298             case 5:
299                 {
300                     std::cout <<  "UpdateTopicList" << std::endl;
301                     std::shared_ptr<OIC::Service::NSProvider> provider =
302                         NSConsumerService::getInstance()->getProvider(mainProvider);
303                     if (provider != nullptr)
304                     {
305                         std::shared_ptr<NSTopicsList> topicList = std::make_shared<NSTopicsList>();
306                         topicList->addTopic("OCF_TOPIC1", NSTopic::NSTopicState::SUBSCRIBED);
307                         topicList->addTopic("OCF_TOPIC2", NSTopic::NSTopicState::SUBSCRIBED);
308                         topicList->addTopic("OCF_TOPIC3", NSTopic::NSTopicState::UNSUBSCRIBED);
309
310                         provider->updateTopicList(topicList);
311                     }
312                     break;
313                 }
314             case 6:
315                 {
316                     std::cout << "Subscribe provider" << std::endl;
317                     if (!mainProvider.empty())
318                     {
319                         std::shared_ptr<OIC::Service::NSProvider> provider =
320                             NSConsumerService::getInstance()->getProvider(mainProvider);
321                         if (provider != nullptr )
322                         {
323                             std::cout << "calling Subscribe on discovered mainProvider" << std::endl;
324                             if (!provider->isSubscribed())
325                             {
326                                 std::cout << "start Subscribing" << std::endl;
327                                 provider->subscribe();
328                             }
329                         }
330                     }
331                     break;
332                 }
333             case 7:
334                 {
335                     std::cout << "UnSubscribe provider" << std::endl;
336                     if (!mainProvider.empty())
337                     {
338                         std::shared_ptr<OIC::Service::NSProvider> provider =
339                             NSConsumerService::getInstance()->getProvider(mainProvider);
340                         if (provider != nullptr )
341                         {
342                             std::cout << "calling UnSubscribe on discovered mainProvider" << std::endl;
343                             if (provider->isSubscribed())
344                             {
345                                 std::cout << "start UnSubscribing" << std::endl;
346                                 provider->unsubscribe();
347                             }
348                         }
349                     }
350                     break;
351                 }
352             case 8:
353                 {
354                     std::cout << "Rescan Provider" << std::endl;
355                     NSConsumerService::getInstance()->rescanProvider();
356                     break;
357                 }
358
359 #ifdef WITH_CLOUD
360             case 9:
361                 {
362                     std::cout << "Enable NS Consumer RemoteService" << std::endl;
363                     std::cout << "Input the Server Address :";
364                     std::cin >> REMOTE_SERVER_ADDRESS;
365                     NSConsumerService::getInstance()->enableRemoteService(REMOTE_SERVER_ADDRESS);
366                     break;
367                 }
368 #endif
369             case 10:
370                 {
371                     std::cout << "Exit" << std::endl;
372                     NSConsumerService::getInstance()->stop();
373                     isExit = true;
374                     break;
375                 }
376             default:
377                 {
378                     std::cout << "Under Construction" << std::endl;
379                     std::cin.clear();
380                     std::cin.ignore(numeric_limits<streamsize>::max(), '\n');
381                     break;
382                 }
383         }
384     }
385
386     return 0;
387 }