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 "reclientmain.h"
27 #include "RCSDiscoveryManager.h"
28 #include "RCSRemoteResourceObject.h"
29 #include "RCSResourceAttributes.h"
30 #include "RCSAddress.h"
32 #include "OCPlatform.h"
34 # define checkResource nullptr == resource?false:true
38 using namespace OIC::Service;
40 constexpr int CORRECT_INPUT = 1;
41 constexpr int INCORRECT_INPUT = 2;
42 constexpr int QUIT_INPUT = 3;
44 std::shared_ptr<RCSRemoteResourceObject> resource;
45 std::vector<RCSRemoteResourceObject::Ptr> resourceList;
46 std::unique_ptr<RCSDiscoveryManager::DiscoveryTask> discoveryTask;
48 const std::string defaultKey = "Temperature";
49 const std::string resourceType = "oic.r.temperaturesensor";
51 static Evas_Object *log_entry = NULL;
52 static Evas_Object *list = NULL;
53 static Evas_Object *naviframe = NULL;
55 typedef struct temperature_popup
59 } temperature_popup_fields;
61 // Function to update the log in UI
62 void *updateGroupLog(void *data)
64 string *log = (string *)data;
66 elm_entry_entry_append(log_entry, (*log).c_str());
67 elm_entry_cursor_end_set(log_entry);
71 static void onDestroy()
73 dlog_print(DLOG_INFO, LOG_TAG, "#### Destroy sequence called");
78 void onResourceDiscovered(std::shared_ptr<RCSRemoteResourceObject> foundResource)
80 dlog_print(DLOG_INFO, LOG_TAG, "#### onResourceDiscovered callback");
82 std::string resourceURI = foundResource->getUri();
83 std::string hostAddress = foundResource->getAddress();
85 int resourceSize = resourceList.size() + 1;
86 string logMessage = "Resource Found : " + std::to_string(resourceSize) + "<br>";
87 logMessage = logMessage + "URI: " + resourceURI + "<br>";
88 logMessage = logMessage + "Host:" + hostAddress + "<br>";
89 logMessage += "----------------------<br>";
90 dlog_print(DLOG_INFO, LOG_TAG, "#### %s", logMessage.c_str());
91 ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateGroupLog,
94 resourceList.push_back(foundResource);
96 if ("/a/TempSensor" == resourceURI)
97 resource = foundResource;
100 void onResourceStateChanged(const ResourceState &resourceState)
102 dlog_print(DLOG_INFO, LOG_TAG, "#### onResourceStateChanged");
104 std::string logMessage = "State changed to : ";
106 switch (resourceState)
108 case ResourceState::NONE:
109 logMessage = logMessage + "NOT_MONITORING <br>";
112 case ResourceState::ALIVE:
113 logMessage = logMessage + "ALIVE <br>";
116 case ResourceState::REQUESTED:
117 logMessage = logMessage + "REQUESTED <br>";
120 case ResourceState::LOST_SIGNAL:
121 logMessage = logMessage + "LOST_SIGNAL <br>";
125 case ResourceState::DESTROYED:
126 logMessage = logMessage + "DESTROYED <br>";
130 dlog_print(DLOG_INFO, LOG_TAG, "#### %s", logMessage.c_str());
131 ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateGroupLog,
135 void onCacheUpdated(const RCSResourceAttributes &attributes)
137 dlog_print(DLOG_INFO, LOG_TAG, "#### onCacheUpdated callback");
139 string logMessage = "Cache Updated : <br> ";
141 if (attributes.empty())
143 logMessage + logMessage + "Attribute is Empty <br>";
147 for (const auto & attr : attributes)
149 logMessage = logMessage + "KEY:" + attr.key().c_str() + "<br>";
150 logMessage = logMessage + "VALUE:" + attr.value().toString().c_str() + "<br>";
152 dlog_print(DLOG_INFO, LOG_TAG, "#### %s", logMessage.c_str());
153 ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateGroupLog,
157 void onRemoteAttributesReceived(const RCSResourceAttributes &attributes, int)
159 dlog_print(DLOG_INFO, LOG_TAG, "#### onRemoteAttributesReceived entry");
161 string logMessage = "Remote Attribute Updated : <br> ";
163 if (attributes.empty())
165 logMessage + logMessage + "Attribute is Empty <br>";
169 for (const auto & attr : attributes)
171 logMessage = logMessage + "KEY:" + attr.key().c_str() + "<br>";
172 logMessage = logMessage + "VALUE:" + attr.value().toString().c_str() + "<br>";
175 dlog_print(DLOG_INFO, LOG_TAG, "#### %s", logMessage.c_str());
176 ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateGroupLog,
180 static void startMonitoring(void *data, Evas_Object *obj, void *event_info)
182 string logMessage = "";
186 if (!resource->isMonitoring())
190 logMessage = logMessage + "Started Monitoring <br>";
191 resource->startMonitoring(&onResourceStateChanged);
193 catch (const RCSBadRequestException &e)
195 logMessage = logMessage + "Exception BadRequest<br>";
196 dlog_print(DLOG_INFO, LOG_TAG, "#### Exception in isMonitoring : %s", e.what());
198 catch (const RCSInvalidParameterException &e)
200 logMessage = logMessage + "Exception Invalid Param<br>";
201 dlog_print(DLOG_INFO, LOG_TAG, "#### Exception in isMonitoring : %s", e.what());
206 logMessage = logMessage + "Already Monitoring <br>";
211 logMessage = logMessage + "No Resource to monitor <br>";
214 dlog_print(DLOG_INFO, LOG_TAG, "#### %s", logMessage.c_str());
215 ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateGroupLog,
219 static void stopMonitoring(void *data, Evas_Object *obj, void *event_info)
221 string logMessage = "";
225 if (resource->isMonitoring())
227 resource->stopMonitoring();
228 logMessage = logMessage + "Stopped Monitoring <br>";
232 logMessage = logMessage + "Monitoring not started <br>";
237 logMessage = logMessage + "NO Resource to stop monitor <br>";
240 dlog_print(DLOG_INFO, LOG_TAG, " %s", logMessage.c_str());
241 ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateGroupLog,
245 static void list_selected_cb(void *data, Evas_Object *obj, void *event_info)
247 Elm_Object_Item *it = (Elm_Object_Item *)event_info;
248 elm_list_item_selected_set(it, EINA_FALSE);
251 static void getAttributeFromRemoteServer(void *data, Evas_Object *obj, void *event_info)
255 resource->getRemoteAttributes(&onRemoteAttributesReceived);
259 dlog_print(DLOG_INFO, LOG_TAG, "#### No Resource to getAttributeFromRemoteServer...");
263 static void setAttributeToRemoteServer(int setTemperature)
265 string key = "Temperature";
266 string logMessage = "";
268 RCSResourceAttributes setAttribute;
269 setAttribute[key] = setTemperature;
273 resource->setRemoteAttributes(setAttribute,
274 &onRemoteAttributesReceived);
278 logMessage = "No Resource to setAttributeToRemoteServer";
281 dlog_print(DLOG_INFO, LOG_TAG, "#### %s", logMessage.c_str());
282 ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateGroupLog,
286 static void startCaching(std::function <void (const RCSResourceAttributes &)>cb)
288 string logMessage = "";
292 if (!resource->isCaching())
298 logMessage = logMessage + "Caching with callback <br>";
299 resource->startCaching(&onCacheUpdated);
301 catch (const RCSBadRequestException &e)
303 logMessage = logMessage + "Exception BadRequest<br>";
304 dlog_print(DLOG_INFO, LOG_TAG, "#### Exception in startCaching : %s", e.what());
312 logMessage = logMessage + "Caching without callback <br>";
313 resource->startCaching();
315 catch (const RCSBadRequestException &e)
317 logMessage = logMessage + "Exception BadRequest<br>";
318 dlog_print(DLOG_INFO, LOG_TAG, "#### Exception in startCaching : %s", e.what());
324 logMessage = logMessage + "Caching Already Started <br>";
329 logMessage = logMessage + "No resource to start Caching <br>";
332 dlog_print(DLOG_INFO, LOG_TAG, "#### %s", logMessage.c_str());
333 ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateGroupLog,
337 static void startCachingWithoutCallback(void *data, Evas_Object *obj, void *event_info)
339 startCaching(nullptr);
342 static void startCachingWithCallback(void *data, Evas_Object *obj, void *event_info)
344 startCaching(onCacheUpdated);
347 static void getResourceCacheState(void *data, Evas_Object *obj, void *event_info)
349 string logMessage = "CACHE STATE : ";
350 switch (resource->getCacheState())
352 case CacheState::READY:
353 logMessage = logMessage + "READY <br>";
356 case CacheState::UNREADY:
357 logMessage = logMessage + "UNREADY <br>";
360 case CacheState::LOST_SIGNAL:
361 logMessage = logMessage + "LOST_SIGNAL <br>";
364 case CacheState::NONE:
365 logMessage = logMessage + "NONE <br>";
372 dlog_print(DLOG_INFO, LOG_TAG, "#### %s", logMessage.c_str());
373 ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateGroupLog,
377 static void getCachedAttributes(void *data, Evas_Object *obj, void *event_info)
379 string logMessage = "";
385 if (resource->getCachedAttributes().empty())
387 logMessage = "Cached attribute empty<br>";
391 for (const auto & attr : resource->getCachedAttributes())
393 logMessage = logMessage + "KEY:" + attr.key().c_str() + "<br>";
394 logMessage = logMessage + "VALUE:" + attr.value().toString().c_str() + "<br>";
395 dlog_print(DLOG_INFO, LOG_TAG, "#### Cached attributes received ");
399 catch (const RCSBadRequestException &e)
401 logMessage = "Exception Received<br>";
402 dlog_print(DLOG_INFO, LOG_TAG, "#### Exception in getCachedAttributes : %s", e.what());
407 logMessage = logMessage + "No Resource<br>";
408 dlog_print(DLOG_INFO, LOG_TAG, "#### No Resource to getCachedAttributes...");
411 dlog_print(DLOG_INFO, LOG_TAG, "#### %s", logMessage.c_str());
412 ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateGroupLog,
416 static void getCachedAttribute(void *data, Evas_Object *obj, void *event_info)
418 string logMessage = "";
424 logMessage = logMessage + "KEY:" + defaultKey.c_str() + "<br>";
425 int attrValue = resource->getCachedAttribute(defaultKey).get< int >();
426 logMessage = logMessage + "VALUE:" + to_string(attrValue) + "<br>";
428 catch (const RCSBadRequestException &e)
430 logMessage = logMessage + "Exception BadRequest<br>";
431 dlog_print(DLOG_INFO, LOG_TAG, "#### Exception in getCachedAttribute : %s", e.what());
433 catch (const RCSBadGetException &e)
435 logMessage = logMessage + "Exception BadGet<br>";
436 dlog_print(DLOG_INFO, LOG_TAG, "#### Exception in getCachedAttribute : %s", e.what());
441 logMessage = logMessage + "No resource<br>";
444 dlog_print(DLOG_INFO, LOG_TAG, "#### %s", logMessage.c_str());
445 ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateGroupLog,
449 static void stopCaching(void *data, Evas_Object *obj, void *event_info)
451 string logMessage = "";
455 if (resource->isCaching())
457 resource->stopCaching();
458 logMessage = logMessage + "Caching stopped <br>";
462 logMessage = logMessage + "Caching not started <br>";
467 logMessage = logMessage + "No resource found<br>";
470 dlog_print(DLOG_INFO, LOG_TAG, " %s", logMessage.c_str());
471 ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateGroupLog,
475 void discoverResource()
477 dlog_print(DLOG_INFO, LOG_TAG, "#### discovery started");
479 while (!discoveryTask)
483 discoveryTask = RCSDiscoveryManager::getInstance()->discoverResourceByType(
484 RCSAddress::multicast(), resourceType, &onResourceDiscovered);
486 catch (const RCSPlatformException &e)
488 std::cout << e.what() << std::endl;
492 dlog_print(DLOG_INFO, LOG_TAG, "#### Discovery over");
495 void cancelDiscoverResource()
497 dlog_print(DLOG_INFO, LOG_TAG, "#### cancelDiscoverResource entry");
498 string logMessage = "";
502 logMessage += "There is no discovery request <br>";
506 discoveryTask->cancel();
508 logMessage += "Discovery canceled <br>";
510 int resourceSize = resourceList.size();
513 logMessage += "No Resource Discovered <br>";
517 logMessage += std::to_string(resourceSize) + " : Resource Discovered <br>";
518 ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))showClientAPIs, NULL);
523 dlog_print(DLOG_INFO, LOG_TAG, "#### %s", logMessage.c_str());
524 ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateGroupLog,
529 popup_cancel_clicked_cb(void *data, Evas_Object *obj, void *event_info)
531 temperature_popup_fields *popup_fields = (temperature_popup_fields *)data;
532 evas_object_del(popup_fields->popup);
537 popup_set_clicked_cb(void *data, Evas_Object *obj, void *event_info)
539 temperature_popup_fields *popup_fields = (temperature_popup_fields *)data;
540 Evas_Object *entry = popup_fields->entry;
541 const char *temperatureString = elm_entry_entry_get(entry);
542 // Remove white spaces(if any) at the beginning
544 while (temperatureString[beginning] == ' ')
549 int len = strlen(temperatureString);
550 if (NULL == temperatureString || 1 > len)
552 dlog_print(DLOG_INFO, LOG_TAG, "#### Read NULL Temperature Value");
553 string logMessage = "Temperature Cannot be NULL<br>";
554 logMessage += "----------------------<br>";
555 dlog_print(DLOG_INFO, LOG_TAG, " %s", logMessage.c_str());
556 ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateGroupLog, &logMessage);
560 int temperate = atoi(temperatureString);
561 string tempString(temperatureString);
562 setAttributeToRemoteServer(temperate);
563 dlog_print(DLOG_INFO, LOG_TAG, "#### Temperature to set : %d", temperate);
565 string logMessage = "Temperature to set : " + tempString + "<br>";
566 logMessage += "----------------------<br>";
567 dlog_print(DLOG_INFO, LOG_TAG, " %s", logMessage.c_str());
568 ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateGroupLog,
571 evas_object_del(popup_fields->popup);
576 list_scheduled_actionset_cb(void *data, Evas_Object *obj, void *event_info)
578 Evas_Object *popup, *btn;
579 Evas_Object *nf = naviframe;
584 popup = elm_popup_add(nf);
585 elm_popup_align_set(popup, ELM_NOTIFY_ALIGN_FILL, 1.0);
586 eext_object_event_callback_add(popup, EEXT_CALLBACK_BACK, eext_popup_back_cb, NULL);
587 evas_object_size_hint_weight_set(popup, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
588 elm_object_part_text_set(popup, "title,text", "Enter the temperature");
590 layout = elm_layout_add(popup);
591 elm_layout_file_set(layout, ELM_DEMO_EDJ, "popup_datetime_text");
592 evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
593 elm_object_content_set(popup, layout);
595 entry = elm_entry_add(layout);
596 elm_entry_single_line_set(entry, EINA_TRUE);
597 elm_entry_scrollable_set(entry, EINA_TRUE);
598 evas_object_size_hint_weight_set(entry, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
599 evas_object_size_hint_align_set(entry, EVAS_HINT_FILL, EVAS_HINT_FILL);
600 eext_entry_selection_back_event_allow_set(entry, EINA_TRUE);
601 elm_object_part_text_set(entry, "elm.guide", "in degree celsius");
602 elm_entry_input_panel_layout_set(entry, ELM_INPUT_PANEL_LAYOUT_NUMBER);
603 elm_object_part_content_set(layout, "elm.swallow.content", entry);
605 temperature_popup_fields *popup_fields;
606 popup_fields = (temperature_popup_fields *)malloc(sizeof(temperature_popup_fields));
607 if (NULL == popup_fields)
609 dlog_print(DLOG_INFO, LOG_TAG, "#### Memory allocation failed");
613 popup_fields->popup = popup;
614 popup_fields->entry = entry;
618 btn = elm_button_add(popup);
619 elm_object_style_set(btn, "popup");
620 elm_object_text_set(btn, "Cancel");
621 elm_object_part_content_set(popup, "button1", btn);
622 evas_object_smart_callback_add(btn, "clicked", popup_cancel_clicked_cb, popup_fields);
625 btn = elm_button_add(popup);
626 elm_object_style_set(btn, "popup");
627 elm_object_text_set(btn, "Set");
628 elm_object_part_content_set(popup, "button2", btn);
629 evas_object_smart_callback_add(btn, "clicked", popup_set_clicked_cb, popup_fields);
631 evas_object_show(popup);
634 // Method to be called when the Start Discovery UI Button is selected
636 find_resource_cb(void *data, Evas_Object *obj, void *event_info)
644 dlog_print(DLOG_ERROR, "find_resource_cb", "list is NULL - So unable to add items!!!");
648 // Method to be called when the Cancel Discovery UI Button is selected
650 cancel_resource_cb(void *data, Evas_Object *obj, void *event_info)
654 cancelDiscoverResource();
658 dlog_print(DLOG_ERROR, "cancel_resource_cb", "list is NULL - So unable to add items!!!");
662 void *showClientAPIs(void *data)
664 // Add items to the list only if the list is empty
665 const Eina_List *eina_list = elm_list_items_get(list);
666 int count = eina_list_count(eina_list);
669 elm_list_item_append(list, "1. Start Monitoring", NULL, NULL,
670 startMonitoring, NULL);
672 elm_list_item_append(list, "2. Stop Monitoring", NULL, NULL,
673 stopMonitoring, NULL);
675 elm_list_item_append(list, "3. Get Attribute", NULL, NULL,
676 getAttributeFromRemoteServer, NULL);
678 elm_list_item_append(list, "4. Set Attribute", NULL, NULL,
679 list_scheduled_actionset_cb, NULL);
681 elm_list_item_append(list, "5. Start Caching - No update", NULL, NULL,
682 startCachingWithoutCallback, NULL);
684 elm_list_item_append(list, "6. Start Caching - With update", NULL, NULL,
685 startCachingWithCallback, NULL);
687 elm_list_item_append(list, "7. Get Cache State", NULL, NULL,
688 getResourceCacheState, NULL);
690 elm_list_item_append(list, "8. Get cached attributes", NULL, NULL,
691 getCachedAttributes, NULL);
693 elm_list_item_append(list, "9. Stop Caching", NULL, NULL,
702 naviframe_pop_cb(void *data, Elm_Object_Item *it)
706 if (NULL != log_entry)
708 evas_object_del(log_entry);
713 evas_object_del(list);
719 // Method to be called when the Group APIs UI Button is selected
720 void client_cb(void *data, Evas_Object *obj, void *event_info)
723 Evas_Object *scroller;
724 Evas_Object *nf = (Evas_Object *)data;
725 Evas_Object *button1;
726 Evas_Object *button2;
727 Elm_Object_Item *nf_it;
732 scroller = elm_scroller_add(nf);
733 elm_scroller_bounce_set(scroller, EINA_FALSE, EINA_TRUE);
734 elm_scroller_policy_set(scroller, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_AUTO);
737 layout = elm_layout_add(nf);
738 elm_layout_file_set(layout, ELM_DEMO_EDJ, "group_layout");
739 evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
741 elm_object_content_set(scroller, layout);
743 // Start Discovery Button
744 button1 = elm_button_add(layout);
745 elm_object_part_content_set(layout, "button1", button1);
746 elm_object_text_set(button1, "Start Discovery");
747 evas_object_smart_callback_add(button1, "clicked", find_resource_cb, NULL);
749 // Cancel Discovery Button
750 button2 = elm_button_add(layout);
751 elm_object_part_content_set(layout, "button2", button2);
752 elm_object_text_set(button2, "Cancel Discovery");
753 evas_object_smart_callback_add(button2, "clicked", cancel_resource_cb, NULL);
756 list = elm_list_add(layout);
757 elm_list_mode_set(list, ELM_LIST_COMPRESS);
758 evas_object_smart_callback_add(list, "selected", list_selected_cb, NULL);
759 elm_object_part_content_set(layout, "list", list);
762 // log_entry - textarea for log
763 log_entry = elm_entry_add(layout);
764 elm_entry_scrollable_set(log_entry, EINA_TRUE);
765 elm_entry_editable_set(log_entry, EINA_FALSE);
766 elm_object_part_text_set(log_entry, "elm.guide", "Logs will be updated here!!!");
767 evas_object_size_hint_weight_set(log_entry, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
768 evas_object_size_hint_align_set(log_entry, EVAS_HINT_FILL, EVAS_HINT_FILL);
769 elm_object_part_content_set(layout, "log", log_entry);
771 nf_it = elm_naviframe_item_push(nf, "Resource Encapsulation", NULL, NULL, scroller, NULL);
772 elm_naviframe_item_pop_cb_set(nf_it, naviframe_pop_cb, NULL);