1 /******************************************************************
3 * Copyright 2015 Samsung Electronics All Rights Reserved.
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 ******************************************************************/
25 #include "condition_variable"
27 #include "reclientmain.h"
29 #include "RCSDiscoveryManager.h"
30 #include "RCSRemoteResourceObject.h"
31 #include "RCSResourceAttributes.h"
32 #include "RCSAddress.h"
34 #include "OCPlatform.h"
36 # define checkResource nullptr == resource?false:true
40 using namespace OIC::Service;
42 constexpr int CORRECT_INPUT = 1;
43 constexpr int INCORRECT_INPUT = 2;
44 constexpr int QUIT_INPUT = 3;
46 std::shared_ptr<RCSRemoteResourceObject> resource;
48 const std::string defaultKey = "Temperature";
49 const std::string resourceType = "?rt=core.TemperatureSensor";
50 const std::string targetUri = OC_RSRVD_WELL_KNOWN_URI + resourceType;
53 std::condition_variable cond;
55 static Evas_Object *log_entry = NULL;
56 static Evas_Object *list = NULL;
57 static Evas_Object *naviframe = NULL;
59 typedef struct temperature_popup
63 } temperature_popup_fields;
65 // Function to update the log in UI
66 void *updateGroupLog(void *data)
68 string *log = (string *)data;
70 elm_entry_entry_append(log_entry, (*log).c_str());
71 elm_entry_cursor_end_set(log_entry);
75 static void onDestroy()
77 dlog_print(DLOG_INFO, LOG_TAG, "#### Destroy sequence called");
81 void onResourceDiscovered(std::shared_ptr<RCSRemoteResourceObject> foundResource)
83 dlog_print(DLOG_INFO, LOG_TAG, "#### onResourceDiscovered callback");
85 std::string resourceURI = foundResource->getUri();
86 std::string hostAddress = foundResource->getAddress();
88 dlog_print(DLOG_INFO, LOG_TAG, "#### Resource URI : %s", resourceURI.c_str());
89 dlog_print(DLOG_INFO, LOG_TAG, "#### Resource Host : %S", hostAddress.c_str());
91 string logMessage = "Resource Found <br>";
92 logMessage = logMessage + "URI: " + resourceURI + "<br>";
93 logMessage = logMessage + "Host:" + hostAddress + "<br>";
94 logMessage += "----------------------<br>";
95 dlog_print(DLOG_INFO, LOG_TAG, " %s", logMessage.c_str());
96 ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateGroupLog,
99 resource = foundResource;
101 ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))showClientAPIs, NULL);
105 void onResourceStateChanged(const ResourceState &resourceState)
107 dlog_print(DLOG_INFO, LOG_TAG, "#### onResourceStateChanged");
109 std::string logMessage = "State changed to : ";
111 switch (resourceState)
113 case ResourceState::NONE:
114 logMessage = logMessage + "NOT_MONITORING <br>";
117 case ResourceState::ALIVE:
118 logMessage = logMessage + "ALIVE <br>";
121 case ResourceState::REQUESTED:
122 logMessage = logMessage + "REQUESTED <br>";
125 case ResourceState::LOST_SIGNAL:
126 logMessage = logMessage + "LOST_SIGNAL <br>";
130 case ResourceState::DESTROYED:
131 logMessage = logMessage + "DESTROYED <br>";
135 dlog_print(DLOG_INFO, LOG_TAG, "#### %s", logMessage.c_str());
136 ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateGroupLog,
140 void onCacheUpdated(const RCSResourceAttributes &attributes)
142 dlog_print(DLOG_INFO, LOG_TAG, "#### onCacheUpdated callback");
144 string logMessage = "Cache Updated : <br> ";
146 if (attributes.empty())
148 logMessage + logMessage + "Attribute is Empty <br>";
152 for (const auto & attr : attributes)
154 logMessage = logMessage + "KEY:" + attr.key().c_str() + "<br>";
155 logMessage = logMessage + "VALUE:" + attr.value().toString().c_str() + "<br>";
157 dlog_print(DLOG_INFO, LOG_TAG, "#### %s", logMessage.c_str());
158 ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateGroupLog,
162 void onRemoteAttributesReceivedCallback(const RCSResourceAttributes &attributes)
164 dlog_print(DLOG_INFO, LOG_TAG, "#### onRemoteAttributesReceivedCallback callback");
166 string logMessage = "Remote Attribute Updated : <br> ";
168 if (attributes.empty())
170 logMessage + logMessage + "Attribute is Empty <br>";
174 for (const auto & attr : attributes)
176 logMessage = logMessage + "KEY:" + attr.key().c_str() + "<br>";
177 logMessage = logMessage + "VALUE:" + attr.value().toString().c_str() + "<br>";
180 dlog_print(DLOG_INFO, LOG_TAG, "#### %s", logMessage.c_str());
181 ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateGroupLog,
185 static void startMonitoring(void *data, Evas_Object *obj, void *event_info)
187 string logMessage = "";
191 if (!resource->isMonitoring())
195 logMessage = logMessage + "Started Monitoring <br>";
196 resource->startMonitoring(&onResourceStateChanged);
198 catch (const RCSBadRequestException &e)
200 logMessage = logMessage + "Exception BadRequest<br>";
201 dlog_print(DLOG_INFO, LOG_TAG, "#### Exception in isMonitoring : %s", e.what());
203 catch (const RCSInvalidParameterException &e)
205 logMessage = logMessage + "Exception Invalid Param<br>";
206 dlog_print(DLOG_INFO, LOG_TAG, "#### Exception in isMonitoring : %s", e.what());
211 logMessage = logMessage + "Already Monitoring <br>";
216 logMessage = logMessage + "No Resource to monitor <br>";
219 dlog_print(DLOG_INFO, LOG_TAG, "#### %s", logMessage.c_str());
220 ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateGroupLog,
224 static void stopMonitoring(void *data, Evas_Object *obj, void *event_info)
226 string logMessage = "";
230 if (resource->isMonitoring())
232 resource->stopMonitoring();
233 logMessage = logMessage + "Stopped Monitoring <br>";
237 logMessage = logMessage + "Monitoring not started <br>";
242 logMessage = logMessage + "NO Resource to stop monitor <br>";
245 dlog_print(DLOG_INFO, LOG_TAG, " %s", logMessage.c_str());
246 ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateGroupLog,
250 static void list_selected_cb(void *data, Evas_Object *obj, void *event_info)
252 Elm_Object_Item *it = (Elm_Object_Item *)event_info;
253 elm_list_item_selected_set(it, EINA_FALSE);
256 static void getAttributeFromRemoteServer(void *data, Evas_Object *obj, void *event_info)
260 resource->getRemoteAttributes(&onRemoteAttributesReceivedCallback);
264 dlog_print(DLOG_INFO, LOG_TAG, "#### No Resource to getAttributeFromRemoteServer...");
268 static void setAttributeToRemoteServer(int setTemperature)
270 string key = "Temperature";
271 string logMessage = "";
273 RCSResourceAttributes setAttribute;
274 setAttribute[key] = setTemperature;
278 resource->setRemoteAttributes(setAttribute,
279 &onRemoteAttributesReceivedCallback);
283 logMessage = "No Resource to setAttributeToRemoteServer";
286 dlog_print(DLOG_INFO, LOG_TAG, "#### %s", logMessage.c_str());
287 ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateGroupLog,
291 static void startCaching(std::function <void (const RCSResourceAttributes &)>cb)
293 string logMessage = "";
297 if (!resource->isCaching())
303 logMessage = logMessage + "Caching with callback <br>";
304 resource->startCaching(&onCacheUpdated);
306 catch (const RCSBadRequestException &e)
308 logMessage = logMessage + "Exception BadRequest<br>";
309 dlog_print(DLOG_INFO, LOG_TAG, "#### Exception in startCaching : %s", e.what());
317 logMessage = logMessage + "Caching without callback <br>";
318 resource->startCaching();
320 catch (const RCSBadRequestException &e)
322 logMessage = logMessage + "Exception BadRequest<br>";
323 dlog_print(DLOG_INFO, LOG_TAG, "#### Exception in startCaching : %s", e.what());
329 logMessage = logMessage + "Caching Already Started <br>";
334 logMessage = logMessage + "No resource to start Caching <br>";
337 dlog_print(DLOG_INFO, LOG_TAG, "#### %s", logMessage.c_str());
338 ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateGroupLog,
342 static void startCachingWithoutCallback(void *data, Evas_Object *obj, void *event_info)
344 startCaching(nullptr);
347 static void startCachingWithCallback(void *data, Evas_Object *obj, void *event_info)
349 startCaching(onCacheUpdated);
352 static void getResourceCacheState(void *data, Evas_Object *obj, void *event_info)
354 string logMessage = "CACHE STATE : ";
355 switch (resource->getCacheState())
357 case CacheState::READY:
358 logMessage = logMessage + "READY <br>";
361 case CacheState::UNREADY:
362 logMessage = logMessage + "UNREADY <br>";
365 case CacheState::LOST_SIGNAL:
366 logMessage = logMessage + "LOST_SIGNAL <br>";
369 case CacheState::NONE:
370 logMessage = logMessage + "NONE <br>";
377 dlog_print(DLOG_INFO, LOG_TAG, "#### %s", logMessage.c_str());
378 ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateGroupLog,
382 static void getCachedAttributes(void *data, Evas_Object *obj, void *event_info)
384 string logMessage = "";
390 if (resource->getCachedAttributes().empty())
392 logMessage = "Cached attribute empty<br>";
396 for (const auto & attr : resource->getCachedAttributes())
398 logMessage = logMessage + "KEY:" + attr.key().c_str() + "<br>";
399 logMessage = logMessage + "VALUE:" + attr.value().toString().c_str() + "<br>";
400 dlog_print(DLOG_INFO, LOG_TAG, "#### Cached attributes received ");
404 catch (const RCSBadRequestException &e)
406 logMessage = "Exception Received<br>";
407 dlog_print(DLOG_INFO, LOG_TAG, "#### Exception in getCachedAttributes : %s", e.what());
412 logMessage = logMessage + "No Resource<br>";
413 dlog_print(DLOG_INFO, LOG_TAG, "#### No Resource to getCachedAttributes...");
416 dlog_print(DLOG_INFO, LOG_TAG, "#### %s", logMessage.c_str());
417 ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateGroupLog,
421 static void getCachedAttribute(void *data, Evas_Object *obj, void *event_info)
423 string logMessage = "";
429 logMessage = logMessage + "KEY:" + defaultKey.c_str() + "<br>";
430 int attrValue = resource->getCachedAttribute(defaultKey).get< int >();
431 logMessage = logMessage + "VALUE:" + to_string(attrValue) + "<br>";
433 catch (const RCSBadRequestException &e)
435 logMessage = logMessage + "Exception BadRequest<br>";
436 dlog_print(DLOG_INFO, LOG_TAG, "#### Exception in getCachedAttribute : %s", e.what());
438 catch (const RCSBadGetException &e)
440 logMessage = logMessage + "Exception BadGet<br>";
441 dlog_print(DLOG_INFO, LOG_TAG, "#### Exception in getCachedAttribute : %s", e.what());
446 logMessage = logMessage + "No resource<br>";
449 dlog_print(DLOG_INFO, LOG_TAG, "#### %s", logMessage.c_str());
450 ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateGroupLog,
454 static void stopCaching(void *data, Evas_Object *obj, void *event_info)
456 string logMessage = "";
460 if (resource->isCaching())
462 resource->stopCaching();
463 logMessage = logMessage + "Caching stopped <br>";
467 logMessage = logMessage + "Caching not started <br>";
472 logMessage = logMessage + "No resource found<br>";
475 dlog_print(DLOG_INFO, LOG_TAG, " %s", logMessage.c_str());
476 ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateGroupLog,
480 void discoverResource()
482 dlog_print(DLOG_INFO, LOG_TAG, "#### Wait 2 seconds until discovered");
484 RCSDiscoveryManager::getInstance()->discoverResource(RCSAddress::multicast(), targetUri,
485 &onResourceDiscovered);
487 std::unique_lock<std::mutex> lck(mtx);
488 cond.wait_for(lck, std::chrono::seconds(2));
490 dlog_print(DLOG_INFO, LOG_TAG, "#### Discovery over");
494 popup_cancel_clicked_cb(void *data, Evas_Object *obj, void *event_info)
496 temperature_popup_fields *popup_fields = (temperature_popup_fields *)data;
497 evas_object_del(popup_fields->popup);
502 popup_set_clicked_cb(void *data, Evas_Object *obj, void *event_info)
504 temperature_popup_fields *popup_fields = (temperature_popup_fields *)data;
505 Evas_Object *entry = popup_fields->entry;
506 const char *temperatureString = elm_entry_entry_get(entry);
507 // Remove white spaces(if any) at the beginning
509 while (temperatureString[beginning] == ' ')
514 int len = strlen(temperatureString);
515 if (NULL == temperatureString || 1 > len)
517 dlog_print(DLOG_INFO, LOG_TAG, "#### Read NULL Temperature Value");
518 string logMessage = "Temperature Cannot be NULL<br>";
519 logMessage += "----------------------<br>";
520 dlog_print(DLOG_INFO, LOG_TAG, " %s", logMessage.c_str());
521 ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateGroupLog, &logMessage);
525 int temperate = atoi(temperatureString);
526 string tempString(temperatureString);
527 setAttributeToRemoteServer(temperate);
528 dlog_print(DLOG_INFO, LOG_TAG, "#### Temperature to set : %d", temperate);
530 string logMessage = "Temperature to set : " + tempString + "<br>";
531 logMessage += "----------------------<br>";
532 dlog_print(DLOG_INFO, LOG_TAG, " %s", logMessage.c_str());
533 ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateGroupLog,
536 evas_object_del(popup_fields->popup);
541 list_scheduled_actionset_cb(void *data, Evas_Object *obj, void *event_info)
543 Evas_Object *popup, *btn;
544 Evas_Object *nf = naviframe;
549 popup = elm_popup_add(nf);
550 elm_popup_align_set(popup, ELM_NOTIFY_ALIGN_FILL, 1.0);
551 eext_object_event_callback_add(popup, EEXT_CALLBACK_BACK, eext_popup_back_cb, NULL);
552 evas_object_size_hint_weight_set(popup, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
553 elm_object_part_text_set(popup, "title,text", "Enter the temperature");
555 layout = elm_layout_add(popup);
556 elm_layout_file_set(layout, ELM_DEMO_EDJ, "popup_datetime_text");
557 evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
558 elm_object_content_set(popup, layout);
560 entry = elm_entry_add(layout);
561 elm_entry_single_line_set(entry, EINA_TRUE);
562 elm_entry_scrollable_set(entry, EINA_TRUE);
563 evas_object_size_hint_weight_set(entry, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
564 evas_object_size_hint_align_set(entry, EVAS_HINT_FILL, EVAS_HINT_FILL);
565 eext_entry_selection_back_event_allow_set(entry, EINA_TRUE);
566 elm_object_part_text_set(entry, "elm.guide", "in degree celsius");
567 elm_entry_input_panel_layout_set(entry, ELM_INPUT_PANEL_LAYOUT_NUMBER);
568 elm_object_part_content_set(layout, "elm.swallow.content", entry);
570 temperature_popup_fields *popup_fields;
571 popup_fields = (temperature_popup_fields *)malloc(sizeof(temperature_popup_fields));
572 if (NULL == popup_fields)
574 dlog_print(DLOG_INFO, LOG_TAG, "#### Memory allocation failed");
578 popup_fields->popup = popup;
579 popup_fields->entry = entry;
583 btn = elm_button_add(popup);
584 elm_object_style_set(btn, "popup");
585 elm_object_text_set(btn, "Cancel");
586 elm_object_part_content_set(popup, "button1", btn);
587 evas_object_smart_callback_add(btn, "clicked", popup_cancel_clicked_cb, popup_fields);
590 btn = elm_button_add(popup);
591 elm_object_style_set(btn, "popup");
592 elm_object_text_set(btn, "Set");
593 elm_object_part_content_set(popup, "button2", btn);
594 evas_object_smart_callback_add(btn, "clicked", popup_set_clicked_cb, popup_fields);
596 evas_object_show(popup);
599 // Method to be called when the Discover Resource UI Button is selected
601 find_resource_cb(void *data, Evas_Object *obj, void *event_info)
609 dlog_print(DLOG_ERROR, "find_resource_cb", "list is NULL - So unable to add items!!!");
613 void *showClientAPIs(void *data)
615 // Add items to the list only if the list is empty
616 const Eina_List *eina_list = elm_list_items_get(list);
617 int count = eina_list_count(eina_list);
620 elm_list_item_append(list, "1. Start Monitoring", NULL, NULL,
621 startMonitoring, NULL);
623 elm_list_item_append(list, "2. Stop Monitoring", NULL, NULL,
624 stopMonitoring, NULL);
626 elm_list_item_append(list, "3. Get Attribute", NULL, NULL,
627 getAttributeFromRemoteServer, NULL);
629 elm_list_item_append(list, "4. Set Attribute", NULL, NULL,
630 list_scheduled_actionset_cb, NULL);
632 elm_list_item_append(list, "5. Start Caching - No update", NULL, NULL,
633 startCachingWithoutCallback, NULL);
635 elm_list_item_append(list, "6. Start Caching - With update", NULL, NULL,
636 startCachingWithCallback, NULL);
638 elm_list_item_append(list, "7. Get Cache State", NULL, NULL,
639 getResourceCacheState, NULL);
641 elm_list_item_append(list, "8. Get cached attributes", NULL, NULL,
642 getCachedAttributes, NULL);
644 elm_list_item_append(list, "9. Stop Caching", NULL, NULL,
653 naviframe_pop_cb(void *data, Elm_Object_Item *it)
657 if (NULL != log_entry)
659 evas_object_del(log_entry);
664 evas_object_del(list);
670 // Method to be called when the Group APIs UI Button is selected
671 void group_cb(void *data, Evas_Object *obj, void *event_info)
674 Evas_Object *scroller;
675 Evas_Object *nf = (Evas_Object *)data;
676 Evas_Object *find_button;
677 Elm_Object_Item *nf_it;
682 scroller = elm_scroller_add(nf);
683 elm_scroller_bounce_set(scroller, EINA_FALSE, EINA_TRUE);
684 elm_scroller_policy_set(scroller, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_AUTO);
687 layout = elm_layout_add(nf);
688 elm_layout_file_set(layout, ELM_DEMO_EDJ, "group_layout");
689 evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
691 elm_object_content_set(scroller, layout);
694 find_button = elm_button_add(layout);
695 elm_object_part_content_set(layout, "find_button", find_button);
696 elm_object_text_set(find_button, "Discover Resource");
697 evas_object_smart_callback_add(find_button, "clicked", find_resource_cb, NULL);
700 list = elm_list_add(layout);
701 elm_list_mode_set(list, ELM_LIST_COMPRESS);
702 evas_object_smart_callback_add(list, "selected", list_selected_cb, NULL);
703 elm_object_part_content_set(layout, "list", list);
706 // log_entry - textarea for log
707 log_entry = elm_entry_add(layout);
708 elm_entry_scrollable_set(log_entry, EINA_TRUE);
709 elm_entry_editable_set(log_entry, EINA_FALSE);
710 elm_object_part_text_set(log_entry, "elm.guide", "Logs will be updated here!!!");
711 evas_object_size_hint_weight_set(log_entry, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
712 evas_object_size_hint_align_set(log_entry, EVAS_HINT_FILL, EVAS_HINT_FILL);
713 elm_object_part_content_set(layout, "log", log_entry);
715 nf_it = elm_naviframe_item_push(nf, "Resource Encapsulation", NULL, NULL, scroller, NULL);
716 elm_naviframe_item_pop_cb_set(nf_it, naviframe_pop_cb, NULL);