Merge test folder of test branch
[iotivity.git] / test / src / iBtestapp / modules / ns / c_cpp / cpp / src / NSProviderCppApp.cpp
1 /******************************************************************
2  *
3  * Copyright 2017 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
22 #include "NSCppAppUtility.h"
23 #ifdef __LINUX__
24 #include <execinfo.h>
25 #endif
26 #include <signal.h>
27 #include <stdlib.h>
28 #include <stdio.h>
29 #include <unistd.h>
30 #include <iomanip>
31 using namespace OIC::Service;
32 using namespace std;
33
34 typedef OIC::Service::NSResult Result;
35
36 OIC::Service::NSProviderService* g_providerService = nullptr;
37 list< string > m_ConsumerList;
38 bool g_isAutoAccept = false;
39 bool g_isRemoteEnable = false;
40 bool g_isExit = false;
41 bool g_isProviderStarted = false;
42 string REMOTE_SERVER_ADDRESS;
43 int id = 0;
44
45 void handler(int sig)
46 {
47     void *array[1000];
48     size_t size;
49
50 #ifdef __LINUX__
51     // get void*'s for all entries on the stack
52     size = backtrace(array, 1000);
53 #endif
54
55     // print out all the frames to stderr
56     fprintf(stderr, "Error: signal %d:\n", sig);
57
58 #ifdef __LINUX__
59     backtrace_symbols_fd(array, size, STDERR_FILENO);
60 #endif
61
62     exit(1);
63 }
64
65 char* exe = 0;
66
67 void initialiseExecutableName()
68 {
69     char link[1024];
70     exe = new char[1024];
71     snprintf(link,sizeof link,"/proc/%d/exe",getpid());
72     if(readlink(link,exe,sizeof link)==-1) {
73         fprintf(stderr,"ERRORRRRR\n");
74         exit(1);
75     }
76     printf("Executable name initialised: %s\n",exe);
77 }
78
79 const char* getExecutableName()
80 {
81     if (exe == 0)
82         initialiseExecutableName();
83     return exe;
84 }
85
86 void onProviderSyncInfo(OIC::Service::NSSyncInfo syncInfo)
87 {
88     cout << "syncInfoCallback Called" << endl;
89     cout << "Provider SyncInfo changed for providerID: " << syncInfo.getProviderId()
90             << " Message ID: " << syncInfo.getMessageId() << endl;
91
92     OIC::Service::NSSyncInfo::NSSyncType state = syncInfo.getState();
93
94     switch (state)
95     {
96         case OIC::Service::NSSyncInfo::NSSyncType::NS_SYNC_READ:
97             cout << "Sync for Read" << endl;
98             break;
99
100         case OIC::Service::NSSyncInfo::NSSyncType::NS_SYNC_UNREAD:
101             cout << "Sync for UnRead" << endl;
102             break;
103
104         case OIC::Service::NSSyncInfo::NSSyncType::NS_SYNC_DELETED:
105             cout << "Sync for Delete" << endl;
106             break;
107
108         default:
109             cout << "Unknown Sync" << endl;
110     }
111 }
112
113 void onSubscribeRequest(shared_ptr< OIC::Service::NSConsumer > consumer)
114 {
115     if (consumer)
116     {
117         cout << "subRequestCallback Called" << endl;
118
119         cout << "Subscription request received from Consumer with ID: "
120                 << consumer->getConsumerId() << endl;
121         bool exist = false;
122         for (string id : m_ConsumerList)
123         {
124             if (consumer->getConsumerId().compare(id) == 0)
125             {
126                 exist = true;
127                 break;
128             }
129         }
130         if(!exist)
131         {
132             m_ConsumerList.push_back(consumer->getConsumerId());
133         }
134
135
136     }
137 }
138
139 // Print Menu Items
140 void showMainMenu()
141 {
142     cout << endl;
143     cout << "=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=" << endl << endl;
144
145     cout << "  " << setw(2) << START_PROVIDER
146             << ".  Start the Notification Provider(Accepter: Provider)" << endl;
147     cout << "  " << setw(2) << START_PROVIDER_AUTO_ACCEPT
148             << ".  Start the Notification Provider(Accepter: Consumer)" << endl;
149     cout << "  " << setw(2) << STOP_PROVIDER << ".  Stop Provider" << endl;
150     cout << "  " << setw(2) << ACCEPT_SUBSCRIPTION << ".  Accept Subscriptions" << endl;
151     cout << "  " << setw(2) << REJECT_SUBSCRIPTION << ".  Reject Subcriptions" << endl;
152     cout << "  " << setw(2) << SEND_NOTIFICATION << ".  Send Notification" << endl;
153     cout << "  " << setw(2) << PROVIDER_SEND_SYNC_INFO << ".  Send Sync Info" << endl;
154     cout << "  " << setw(2) << ADD_TOPIC << ".  Add Topic" << endl;
155     cout << "  " << setw(2) << DELETE_TOPIC << ".  Delete Topic" << endl;
156     cout << "  " << setw(2) << SELECT_TOPIC << ".  Select Topic" << endl;
157     cout << "  " << setw(2) << UNSELECT_TOPIC << ".  Unselect Topic" << endl;
158     cout << "  " << setw(2) << CONSUMER_TOPICS << ".  Consumer Topics" << endl;
159     cout << "  " << setw(2) << PROVIDER_TOPICS << ".  Show Topics" << endl;
160     cout << "  " << setw(2) << ACCEPTED_CONSUMER_LIST << ".  List of Accepted Consumer" << endl;
161     cout << "  " << setw(2) << PROVIDER_ENABLE_REMOTE_SERVICE << ".  Enable Remote Service" << endl;
162     cout << "  " << setw(2) << PROVIDER_DISABLE_REMOTE_SERVICE << ".  Disable Remote Service"
163             << endl;
164     cout << endl;
165
166     cout << "  " << setw(2) << PROVIDER_EXIT << ".  Exit" << endl;
167
168     cout << "=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=" << endl;
169     cout << endl;
170
171     cout << "\tPlease Choose a Menu: ";
172 }
173
174 void startProvider(bool policy)
175 {
176     g_isAutoAccept = policy;
177     OIC::Service::NSProviderService::ProviderConfig config;
178     config.subControllability = g_isAutoAccept;
179     config.m_subscribeRequestCb = onSubscribeRequest;
180     config.m_syncInfoCb = onProviderSyncInfo;
181     config.userInfo = "OCF_NOTIFICATION";
182
183     OIC::Service::NSResult result = g_providerService->start(config);
184
185     if (result == Result::OK)
186     {
187         g_isProviderStarted = true;
188         cout << "Provider started successfully" << endl;
189     }
190     else
191     {
192         g_isProviderStarted = false;
193         cout << "Can't start provider" << endl;
194     }
195 }
196
197 void stopProvider()
198 {
199     OIC::Service::NSResult result = g_providerService->stop();
200
201     if (result == Result::OK)
202     {
203         cout << "Provider stopped successfully" << endl;
204     }
205     else
206     {
207         cout << "Cannot stop provider" << endl;
208     }
209 }
210
211 void acceptSubscription()
212 {
213     if (m_ConsumerList.size() > 0)
214     {
215         cout << "Accepting Subscription: " << endl;
216         for (string consumerId : m_ConsumerList)
217         {
218
219             g_providerService->getConsumer(consumerId)->acceptSubscription(true);
220             cout << "Accepted subscription for consumer with ID: " << consumerId
221                     << endl;
222
223         }
224     }
225     else
226     {
227         cout << "No Consumer Subscription request found!!" << endl;
228     }
229 }
230
231 void rejectSubscription()
232 {
233     cout << "Rejecting Subscription" << endl;
234     for (string consumerId : m_ConsumerList)
235     {
236
237         g_providerService->getConsumer(consumerId)->acceptSubscription(false);
238
239     }
240 }
241
242 void sendNotification()
243 {
244     OIC::Service::NSMessage msg = g_providerService->createMessage();
245
246     id++;
247     msg.setTitle("TestApp title " + id);
248     msg.setContentText("TestApp body " + id);
249
250     msg.setSourceName("OCF");
251     msg.setTopic(TOPIC_1);
252
253     OIC::Service::NSResult result = g_providerService->sendMessage(msg);
254
255     if (result == Result::OK)
256     {
257         cout << "Fail to send notification" << endl;
258     }
259 }
260
261 string getConsumerId()
262 {
263     string consumerId = "";
264
265     if (m_ConsumerList.size() != 0)
266     {
267         consumerId = m_ConsumerList.back();
268     }
269     else
270     {
271         cout << "Subscribed consumer is empty." << endl;
272     }
273
274     return consumerId;
275 }
276
277 void printConsumerList(NSAcceptedConsumers* aConsumerList)
278 {
279     cout << "Consumer List: " << endl;
280     for (auto consumer : aConsumerList->getConsumers())
281     {
282         cout << "id: " << consumer.second->getConsumerId() << endl;
283     }
284 }
285
286 // This function is for menu selection
287 void menuSelection(ProviderCppAppMenu menu)
288 {
289     OIC::Service::NSResult result;
290     switch (menu)
291     {
292         case START_PROVIDER:
293             startProvider(true);
294             break;
295
296         case START_PROVIDER_AUTO_ACCEPT:
297             startProvider(false);
298             break;
299
300         case STOP_PROVIDER:
301             signal(SIGSEGV, handler);
302             stopProvider();
303             break;
304
305         case ACCEPT_SUBSCRIPTION:
306             acceptSubscription();
307             break;
308
309         case REJECT_SUBSCRIPTION:
310             rejectSubscription();
311             break;
312
313         case SEND_NOTIFICATION:
314             sendNotification();
315             break;
316
317         case PROVIDER_SEND_SYNC_INFO:
318         {
319             g_providerService->sendSyncInfo(1, OIC::Service::NSSyncInfo::NSSyncType::NS_SYNC_READ);
320         }
321             break;
322
323         case ADD_TOPIC:
324         {
325             result = g_providerService->registerTopic(TOPIC_1);
326             result = g_providerService->registerTopic(TOPIC_2);
327             result = g_providerService->registerTopic(TOPIC_3);
328             result = g_providerService->registerTopic(TOPIC_4);
329
330             if (OIC::Service::NSResult::OK == result)
331             {
332                 std::cout << "Registered topic Successfully" << std::endl;
333             }
334             else
335             {
336                 std::cout << "Register topic failed...." << std::endl;
337             }
338         }
339             break;
340
341         case DELETE_TOPIC:
342             result = g_providerService->unregisterTopic(TOPIC_2);
343             if (OIC::Service::NSResult::OK  == result)
344             {
345                 std::cout << "Unregistered topic Successfully" << std::endl;
346             }
347             else
348             {
349                 std::cout << "Unregister topic failed...." << std::endl;
350             }
351             break;
352
353         case SELECT_TOPIC:
354         {
355             for (string consumerId : m_ConsumerList)
356             {
357                 auto consumer = g_providerService->getConsumer(consumerId);
358                 if (consumer != nullptr)
359                 {
360                     result = consumer->setTopic(TOPIC_1);
361                     result = consumer->setTopic(TOPIC_2);
362                     result = consumer->setTopic(TOPIC_3);
363                     result = consumer->setTopic(TOPIC_4);
364
365                     if (OIC::Service::NSResult::OK == result)
366                     {
367                         std::cout << "SelectTopic completed for consumer with ID: "
368                                 << consumerId << std::endl;
369                     }
370                     else
371                     {
372                         std::cout << "SelectTopic failed for consumer with ID: "
373                                 << consumerId << std::endl;
374                     }
375
376                 }
377             }
378         }
379             break;
380
381         case UNSELECT_TOPIC:
382         {
383             for (string consumerId : m_ConsumerList)
384             {
385                 auto consumer = g_providerService->getConsumer(consumerId);
386                 if (consumer != nullptr)
387                 {
388                     result = consumer->unsetTopic(TOPIC_1);
389
390                     if (OIC::Service::NSResult::OK == result)
391                     {
392                         std::cout << "UnSelectTopic completed for consumer with ID: "
393                                 << consumer->getConsumerId() << std::endl;
394                     }
395                     else
396                     {
397                         std::cout << "UnSelectTopic failed for consumer with ID: "
398                                 << consumer->getConsumerId() << std::endl;
399                     }
400
401                 }
402             }
403         }
404             break;
405
406         case CONSUMER_TOPICS:
407         {
408             for (string consumerId : m_ConsumerList)
409             {
410                 auto consumer = g_providerService->getConsumer(consumerId);
411                 if (consumer != nullptr)
412                 {
413                     std::shared_ptr< NSTopicsList > nsTopics = consumer->getConsumerTopicList();
414                     if (nsTopics != nullptr)
415                     {
416                         for (auto it : nsTopics->getTopicsList())
417                         {
418
419                             std::cout << it.getTopicName() << std::endl;
420                             std::cout << (int) it.getState() << std::endl;
421                         }
422                     }
423                     std::cout << "GetConsumerTopics completed" << std::endl;
424                 }
425             }
426         }
427             break;
428
429         case PROVIDER_TOPICS:
430         {
431             shared_ptr< NSTopicsList > nsTopics = g_providerService->getRegisteredTopicList();
432             for (auto it : nsTopics->getTopicsList())
433             {
434
435                 std::cout << it.getTopicName() << std::endl;
436                 std::cout << (int) it.getState() << std::endl;
437             }
438         }
439             break;
440
441         case ACCEPTED_CONSUMER_LIST:
442         {
443             NSAcceptedConsumers* conList = g_providerService->getAcceptedConsumers();
444             printConsumerList(conList);
445         }
446             break;
447
448         case PROVIDER_ENABLE_REMOTE_SERVICE:
449         {
450             std::cout << "Input the Server Address :";
451             std::cin >> REMOTE_SERVER_ADDRESS;
452             g_providerService->enableRemoteService(REMOTE_SERVER_ADDRESS);
453
454             g_isRemoteEnable = true;
455         }
456             break;
457
458         case PROVIDER_DISABLE_REMOTE_SERVICE:
459         {
460             std::cout << "Input the Server Address :";
461             g_providerService->disableRemoteService(REMOTE_SERVER_ADDRESS);
462         }
463             break;
464
465         case ProviderCppAppMenu::PROVIDER_EXIT:
466         {
467             if (g_isProviderStarted)
468             {
469                 g_providerService->stop();
470             }
471
472             g_isExit = true;
473             cout << "Quit from NS Provider TestApp..." << endl << endl;
474         }
475             break;
476
477         default:
478             cout << "Invalid manu selection, please select a valid menu..." << endl << endl;
479     }
480 }
481
482 void *OCProcessThread(void *ptr)
483 {
484     (void) ptr;
485     while (!g_isExit)
486     {
487         if (OCProcess() != OC_STACK_OK)
488         {
489             std::cout << "OCStack process error" << std::endl;
490             return NULL;
491         }
492     }
493
494     return NULL;
495 }
496
497 // This is the main function the RE Test Application
498 int main(void)
499 {
500     signal(SIGSEGV, handler);
501     pthread_t processThread;
502     /* Install our signal handler */
503     struct sigaction sa;
504
505     sa.sa_sigaction = (void *) handler;
506     sigemptyset (&sa.sa_mask);
507     sa.sa_flags = SA_RESTART | SA_SIGINFO;
508
509     sigaction(SIGSEGV, &sa, NULL);
510     sigaction(SIGUSR1, &sa, NULL);
511
512     if (OCInit(NULL, 0, OC_CLIENT_SERVER) != OC_STACK_OK)
513     {
514         std::cout << "OCStack init error" << std::endl;
515         return 0;
516     }
517
518 //    pthread_create(&processThread, NULL, OCProcessThread, NULL);
519
520     try
521     {
522         OC::OCPlatform::stopPresence();
523     }
524     catch (...)
525     {
526         cout << "Can't stop presence..." << endl;
527     }
528
529     g_providerService = OIC::Service::NSProviderService::getInstance();
530     while (!g_isExit)
531     {
532         int menuItem;
533         showMainMenu();
534         cin >> menuItem;
535         menuSelection(ProviderCppAppMenu(menuItem));
536     }
537
538     return 0;
539 }