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"
26 #include "RCSDiscoveryManager.h"
27 #include "RCSRemoteResourceObject.h"
28 #include "RCSResourceAttributes.h"
29 #include "RCSAddress.h"
30 #include "OCPlatform.h"
32 # define checkResource nullptr == resource?false:true
36 using namespace OIC::Service;
38 std::shared_ptr<RCSRemoteResourceObject> resource;
39 std::vector<RCSRemoteResourceObject::Ptr> resourceList;
40 std::unique_ptr<RCSDiscoveryManager::DiscoveryTask> discoveryTask;
42 std::string g_resourceUri;
43 std::string g_resourceType;
44 std::string g_attributeKey;
46 static Evas_Object *log_entry = NULL;
47 static Evas_Object *list = NULL;
48 static Evas_Object *naviframe = NULL;
50 typedef struct temperature_popup
54 } temperature_popup_fields;
56 // Function to update the log in UI
57 void *updateGroupLog(void *data)
59 string *log = (string *)data;
61 elm_entry_entry_append(log_entry, (*log).c_str());
62 elm_entry_cursor_end_set(log_entry);
66 static void onDestroy()
68 dlog_print(DLOG_INFO, LOG_TAG, "#### Destroy sequence called");
73 void onResourceDiscovered(std::shared_ptr<RCSRemoteResourceObject> foundResource)
75 dlog_print(DLOG_INFO, LOG_TAG, "#### onResourceDiscovered callback");
77 std::string resourceURI = foundResource->getUri();
78 std::string hostAddress = foundResource->getAddress();
80 int resourceSize = resourceList.size() + 1;
81 string logMessage = "Resource Found : " + std::to_string(resourceSize) + "<br>";
82 logMessage = logMessage + "URI: " + resourceURI + "<br>";
83 logMessage = logMessage + "Host:" + hostAddress + "<br>";
84 logMessage += "----------------------<br>";
85 dlog_print(DLOG_INFO, LOG_TAG, "#### %s", logMessage.c_str());
86 ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateGroupLog,
89 resourceList.push_back(foundResource);
91 if (g_resourceUri == resourceURI)
92 resource = foundResource;
95 void onResourceStateChanged(const ResourceState &resourceState)
97 dlog_print(DLOG_INFO, LOG_TAG, "#### onResourceStateChanged");
99 std::string logMessage = "State changed to : ";
101 switch (resourceState)
103 case ResourceState::NONE:
104 logMessage = logMessage + "NOT_MONITORING <br>";
107 case ResourceState::ALIVE:
108 logMessage = logMessage + "ALIVE <br>";
111 case ResourceState::REQUESTED:
112 logMessage = logMessage + "REQUESTED <br>";
115 case ResourceState::LOST_SIGNAL:
116 logMessage = logMessage + "LOST_SIGNAL <br>";
120 case ResourceState::DESTROYED:
121 logMessage = logMessage + "DESTROYED <br>";
125 dlog_print(DLOG_INFO, LOG_TAG, "#### %s", logMessage.c_str());
126 ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateGroupLog,
130 void onCacheUpdated(const RCSResourceAttributes &attributes)
132 dlog_print(DLOG_INFO, LOG_TAG, "#### onCacheUpdated callback");
134 string logMessage = "Cache Updated : <br> ";
136 if (attributes.empty())
138 logMessage + logMessage + "Attribute is Empty <br>";
142 for (const auto & attr : attributes)
144 logMessage = logMessage + "KEY:" + attr.key().c_str() + "<br>";
145 logMessage = logMessage + "VALUE:" + attr.value().toString().c_str() + "<br>";
147 dlog_print(DLOG_INFO, LOG_TAG, "#### %s", logMessage.c_str());
148 ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateGroupLog,
152 void onRemoteAttributesReceived(const RCSResourceAttributes &attributes, int)
154 dlog_print(DLOG_INFO, LOG_TAG, "#### onRemoteAttributesReceived entry");
156 string logMessage = "Remote Attribute Updated : <br> ";
158 if (attributes.empty())
160 logMessage + logMessage + "Attribute is Empty <br>";
164 for (const auto & attr : attributes)
166 logMessage = logMessage + "KEY:" + attr.key().c_str() + "<br>";
167 logMessage = logMessage + "VALUE:" + attr.value().toString().c_str() + "<br>";
170 dlog_print(DLOG_INFO, LOG_TAG, "#### %s", logMessage.c_str());
171 ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateGroupLog,
175 static void startMonitoring(void *data, Evas_Object *obj, void *event_info)
177 string logMessage = "";
181 if (!resource->isMonitoring())
185 logMessage = logMessage + "Started Monitoring <br>";
186 resource->startMonitoring(&onResourceStateChanged);
188 catch (const RCSBadRequestException &e)
190 logMessage = logMessage + "Exception BadRequest<br>";
191 dlog_print(DLOG_INFO, LOG_TAG, "#### Exception in isMonitoring : %s", e.what());
193 catch (const RCSInvalidParameterException &e)
195 logMessage = logMessage + "Exception Invalid Param<br>";
196 dlog_print(DLOG_INFO, LOG_TAG, "#### Exception in isMonitoring : %s", e.what());
201 logMessage = logMessage + "Already Monitoring <br>";
206 logMessage = logMessage + "No Resource to monitor <br>";
209 dlog_print(DLOG_INFO, LOG_TAG, "#### %s", logMessage.c_str());
210 ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateGroupLog,
214 static void stopMonitoring(void *data, Evas_Object *obj, void *event_info)
216 string logMessage = "";
220 if (resource->isMonitoring())
222 resource->stopMonitoring();
223 logMessage = logMessage + "Stopped Monitoring <br>";
227 logMessage = logMessage + "Monitoring not started <br>";
232 logMessage = logMessage + "NO Resource to stop monitor <br>";
235 dlog_print(DLOG_INFO, LOG_TAG, " %s", logMessage.c_str());
236 ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateGroupLog,
240 static void list_selected_cb(void *data, Evas_Object *obj, void *event_info)
242 Elm_Object_Item *it = (Elm_Object_Item *)event_info;
243 elm_list_item_selected_set(it, EINA_FALSE);
246 static void getAttributeFromRemoteServer(void *data, Evas_Object *obj, void *event_info)
250 resource->getRemoteAttributes(&onRemoteAttributesReceived);
254 dlog_print(DLOG_INFO, LOG_TAG, "#### No Resource to getAttributeFromRemoteServer...");
258 static void setAttributeToRemoteServer(int setValue)
260 string logMessage = "";
262 RCSResourceAttributes setAttribute;
263 setAttribute[g_attributeKey] = setValue;
267 resource->setRemoteAttributes(setAttribute,
268 &onRemoteAttributesReceived);
272 logMessage = "No Resource to setAttributeToRemoteServer";
275 dlog_print(DLOG_INFO, LOG_TAG, "#### %s", logMessage.c_str());
276 ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateGroupLog,
280 static void startCaching(std::function <void (const RCSResourceAttributes &)>cb)
282 string logMessage = "";
286 if (!resource->isCaching())
292 logMessage = logMessage + "Caching with callback <br>";
293 resource->startCaching(&onCacheUpdated);
295 catch (const RCSBadRequestException &e)
297 logMessage = logMessage + "Exception BadRequest<br>";
298 dlog_print(DLOG_INFO, LOG_TAG, "#### Exception in startCaching : %s", e.what());
306 logMessage = logMessage + "Caching without callback <br>";
307 resource->startCaching();
309 catch (const RCSBadRequestException &e)
311 logMessage = logMessage + "Exception BadRequest<br>";
312 dlog_print(DLOG_INFO, LOG_TAG, "#### Exception in startCaching : %s", e.what());
318 logMessage = logMessage + "Caching Already Started <br>";
323 logMessage = logMessage + "No resource to start Caching <br>";
326 dlog_print(DLOG_INFO, LOG_TAG, "#### %s", logMessage.c_str());
327 ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateGroupLog,
331 static void startCachingWithoutCallback(void *data, Evas_Object *obj, void *event_info)
333 startCaching(nullptr);
336 static void startCachingWithCallback(void *data, Evas_Object *obj, void *event_info)
338 startCaching(onCacheUpdated);
341 static void getResourceCacheState(void *data, Evas_Object *obj, void *event_info)
343 string logMessage = "CACHE STATE : ";
344 switch (resource->getCacheState())
346 case CacheState::READY:
347 logMessage = logMessage + "READY <br>";
350 case CacheState::UNREADY:
351 logMessage = logMessage + "UNREADY <br>";
354 case CacheState::LOST_SIGNAL:
355 logMessage = logMessage + "LOST_SIGNAL <br>";
358 case CacheState::NONE:
359 logMessage = logMessage + "NONE <br>";
366 dlog_print(DLOG_INFO, LOG_TAG, "#### %s", logMessage.c_str());
367 ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateGroupLog,
371 static void getCachedAttributes(void *data, Evas_Object *obj, void *event_info)
373 string logMessage = "";
379 if (resource->getCachedAttributes().empty())
381 logMessage = "Cached attribute empty<br>";
385 for (const auto & attr : resource->getCachedAttributes())
387 logMessage = logMessage + "KEY:" + attr.key().c_str() + "<br>";
388 logMessage = logMessage + "VALUE:" + attr.value().toString().c_str() + "<br>";
389 dlog_print(DLOG_INFO, LOG_TAG, "#### Cached attributes received ");
393 catch (const RCSBadRequestException &e)
395 logMessage = "Exception Received<br>";
396 dlog_print(DLOG_INFO, LOG_TAG, "#### Exception in getCachedAttributes : %s", e.what());
401 logMessage = logMessage + "No Resource<br>";
402 dlog_print(DLOG_INFO, LOG_TAG, "#### No Resource to getCachedAttributes...");
405 dlog_print(DLOG_INFO, LOG_TAG, "#### %s", logMessage.c_str());
406 ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateGroupLog,
410 static void getCachedAttribute(void *data, Evas_Object *obj, void *event_info)
412 string logMessage = "";
418 logMessage = logMessage + "KEY:" + g_attributeKey.c_str() + "<br>";
419 int attrValue = resource->getCachedAttribute(g_attributeKey).get< int >();
420 logMessage = logMessage + "VALUE:" + to_string(attrValue) + "<br>";
422 catch (const RCSBadRequestException &e)
424 logMessage = logMessage + "Exception BadRequest<br>";
425 dlog_print(DLOG_INFO, LOG_TAG, "#### Exception in getCachedAttribute : %s", e.what());
427 catch (const RCSBadGetException &e)
429 logMessage = logMessage + "Exception BadGet<br>";
430 dlog_print(DLOG_INFO, LOG_TAG, "#### Exception in getCachedAttribute : %s", e.what());
435 logMessage = logMessage + "No resource<br>";
438 dlog_print(DLOG_INFO, LOG_TAG, "#### %s", logMessage.c_str());
439 ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateGroupLog,
443 static void stopCaching(void *data, Evas_Object *obj, void *event_info)
445 string logMessage = "";
449 if (resource->isCaching())
451 resource->stopCaching();
452 logMessage = logMessage + "Caching stopped <br>";
456 logMessage = logMessage + "Caching not started <br>";
461 logMessage = logMessage + "No resource found<br>";
464 dlog_print(DLOG_INFO, LOG_TAG, " %s", logMessage.c_str());
465 ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateGroupLog,
469 void discoverResource()
471 dlog_print(DLOG_INFO, LOG_TAG, "#### discovery started");
473 while (!discoveryTask)
475 resourceList.clear();
479 discoveryTask = RCSDiscoveryManager::getInstance()->discoverResourceByType(
480 RCSAddress::multicast(), g_resourceType, &onResourceDiscovered);
482 catch (const RCSPlatformException &e)
484 std::cout << e.what() << std::endl;
488 dlog_print(DLOG_INFO, LOG_TAG, "#### Discovery over");
491 void cancelDiscoverResource()
493 dlog_print(DLOG_INFO, LOG_TAG, "#### cancelDiscoverResource entry");
494 string logMessage = "";
498 logMessage += "There is no discovery request <br>";
502 discoveryTask->cancel();
503 discoveryTask = nullptr;
505 logMessage += "Discovery canceled <br>";
507 int resourceSize = resourceList.size();
510 logMessage += "No Resource Discovered <br>";
514 logMessage += std::to_string(resourceSize) + " : Resource Discovered <br>";
515 ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))showClientAPIs, NULL);
520 dlog_print(DLOG_INFO, LOG_TAG, "#### %s", logMessage.c_str());
521 ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateGroupLog,
526 popup_cancel_clicked_cb(void *data, Evas_Object *obj, void *event_info)
528 temperature_popup_fields *popup_fields = (temperature_popup_fields *)data;
529 evas_object_del(popup_fields->popup);
534 popup_set_clicked_cb(void *data, Evas_Object *obj, void *event_info)
536 temperature_popup_fields *popup_fields = (temperature_popup_fields *)data;
537 Evas_Object *entry = popup_fields->entry;
538 const char *attributeString = elm_entry_entry_get(entry);
539 // Remove white spaces(if any) at the beginning
544 while (attributeString[beginning] == ' ')
549 int len = strlen(attributeString);
551 if((len >= 1) && ( '-' == attributeString[0]))
556 if(((len > 3) && negative) || (len > 2 && (!negative)) || (len==1 && negative))
559 dlog_print(DLOG_INFO, LOG_TAG, "#### Not in allowed Range [-99 to 99]");
560 string logMessage = g_attributeKey + " Not in allowed Range [-99 to 99]<br>";
561 logMessage += "----------------------<br>";
562 dlog_print(DLOG_INFO, LOG_TAG, " %s", logMessage.c_str());
563 ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateGroupLog,
568 if (NULL == attributeString || 1 > len)
571 dlog_print(DLOG_INFO, LOG_TAG, "#### Read NULL attribute Value");
572 string logMessage = g_attributeKey + " Cannot be NULL<br>";
573 logMessage += "----------------------<br>";
574 dlog_print(DLOG_INFO, LOG_TAG, " %s", logMessage.c_str());
575 ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateGroupLog,
583 if(attributeString[i] < '0' || attributeString[i] > '9')
586 dlog_print(DLOG_INFO, LOG_TAG, "#### Read invalid attribute Value");
587 string logMessage = g_attributeKey + " Invalid charaters in input<br>";
588 logMessage += "----------------------<br>";
589 dlog_print(DLOG_INFO, LOG_TAG, " %s", logMessage.c_str());
590 ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateGroupLog,
600 int attributeValue = atoi(attributeString);
601 string attrString(attributeString);
602 setAttributeToRemoteServer(attributeValue);
603 dlog_print(DLOG_INFO, LOG_TAG, "#### Attribute to set : %d", attributeValue);
604 string logMessage = g_attributeKey + " to set : " + attrString + "<br>";
605 logMessage += "----------------------<br>";
606 dlog_print(DLOG_INFO, LOG_TAG, " %s", logMessage.c_str());
607 ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateGroupLog,
610 evas_object_del(popup_fields->popup);
615 list_get_attribute_value_cb(void *data, Evas_Object *obj, void *event_info)
617 Evas_Object *popup, *btn;
618 Evas_Object *nf = naviframe;
623 popup = elm_popup_add(nf);
624 elm_popup_align_set(popup, ELM_NOTIFY_ALIGN_FILL, 1.0);
625 eext_object_event_callback_add(popup, EEXT_CALLBACK_BACK, eext_popup_back_cb, NULL);
626 evas_object_size_hint_weight_set(popup, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
627 if (LIGHT_RT == g_resourceType)
629 elm_object_part_text_set(popup, "title,text", "Enter the brightness");
633 elm_object_part_text_set(popup, "title,text", "Enter the temperature");
636 layout = elm_layout_add(popup);
637 elm_layout_file_set(layout, ELM_DEMO_EDJ, "popup_datetime_text");
638 evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
639 elm_object_content_set(popup, layout);
641 entry = elm_entry_add(layout);
642 elm_entry_single_line_set(entry, EINA_TRUE);
643 elm_entry_scrollable_set(entry, EINA_TRUE);
644 evas_object_size_hint_weight_set(entry, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
645 evas_object_size_hint_align_set(entry, EVAS_HINT_FILL, EVAS_HINT_FILL);
646 eext_entry_selection_back_event_allow_set(entry, EINA_TRUE);
647 if (LIGHT_RT == g_resourceType)
649 elm_object_part_text_set(entry, "elm.guide", "RANGE (0 - 50)");
653 elm_object_part_text_set(entry, "elm.guide", "in degree celsius");
655 elm_entry_input_panel_layout_set(entry, ELM_INPUT_PANEL_LAYOUT_NUMBER);
656 elm_object_part_content_set(layout, "elm.swallow.content", entry);
658 temperature_popup_fields *popup_fields;
659 popup_fields = (temperature_popup_fields *)malloc(sizeof(temperature_popup_fields));
660 if (NULL == popup_fields)
662 dlog_print(DLOG_INFO, LOG_TAG, "#### Memory allocation failed");
666 popup_fields->popup = popup;
667 popup_fields->entry = entry;
671 btn = elm_button_add(popup);
672 elm_object_style_set(btn, "popup");
673 elm_object_text_set(btn, "Cancel");
674 elm_object_part_content_set(popup, "button1", btn);
675 evas_object_smart_callback_add(btn, "clicked", popup_cancel_clicked_cb, popup_fields);
678 btn = elm_button_add(popup);
679 elm_object_style_set(btn, "popup");
680 elm_object_text_set(btn, "Set");
681 elm_object_part_content_set(popup, "button2", btn);
682 evas_object_smart_callback_add(btn, "clicked", popup_set_clicked_cb, popup_fields);
684 evas_object_show(popup);
687 // Method to be called when the Start Discovery UI Button is selected
689 find_resource_cb(void *data, Evas_Object *obj, void *event_info)
697 dlog_print(DLOG_ERROR, "find_resource_cb", "list is NULL - So unable to add items!!!");
701 // Method to be called when the Cancel Discovery UI Button is selected
703 cancel_resource_cb(void *data, Evas_Object *obj, void *event_info)
707 cancelDiscoverResource();
711 dlog_print(DLOG_ERROR, "cancel_resource_cb", "list is NULL - So unable to add items!!!");
715 void *showClientAPIs(void *data)
717 // Add items to the list only if the list is empty
718 const Eina_List *eina_list = elm_list_items_get(list);
719 int count = eina_list_count(eina_list);
722 elm_list_item_append(list, "1. Start Monitoring", NULL, NULL,
723 startMonitoring, NULL);
725 elm_list_item_append(list, "2. Stop Monitoring", NULL, NULL,
726 stopMonitoring, NULL);
728 elm_list_item_append(list, "3. Get Attribute", NULL, NULL,
729 getAttributeFromRemoteServer, NULL);
731 elm_list_item_append(list, "4. Set Attribute", NULL, NULL,
732 list_get_attribute_value_cb, NULL);
734 elm_list_item_append(list, "5. Start Caching - No update", NULL, NULL,
735 startCachingWithoutCallback, NULL);
737 elm_list_item_append(list, "6. Start Caching - With update", NULL, NULL,
738 startCachingWithCallback, NULL);
740 elm_list_item_append(list, "7. Get Cache State", NULL, NULL,
741 getResourceCacheState, NULL);
743 elm_list_item_append(list, "8. Get cached attributes", NULL, NULL,
744 getCachedAttributes, NULL);
746 elm_list_item_append(list, "9. Stop Caching", NULL, NULL,
755 naviframe_pop_cb(void *data, Elm_Object_Item *it)
759 if (NULL != log_entry)
761 evas_object_del(log_entry);
766 evas_object_del(list);
772 void client_cb(void *data)
775 Evas_Object *scroller;
776 Evas_Object *nf = (Evas_Object *)data;
777 Evas_Object *button1;
778 Evas_Object *button2;
779 Elm_Object_Item *nf_it;
784 scroller = elm_scroller_add(nf);
785 elm_scroller_bounce_set(scroller, EINA_FALSE, EINA_TRUE);
786 elm_scroller_policy_set(scroller, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_AUTO);
789 layout = elm_layout_add(nf);
790 elm_layout_file_set(layout, ELM_DEMO_EDJ, "group_layout");
791 evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
793 elm_object_content_set(scroller, layout);
795 // Start Discovery Button
796 button1 = elm_button_add(layout);
797 elm_object_part_content_set(layout, "button1", button1);
798 elm_object_text_set(button1, "Start Discovery");
799 evas_object_smart_callback_add(button1, "clicked", find_resource_cb, NULL);
801 // Cancel Discovery Button
802 button2 = elm_button_add(layout);
803 elm_object_part_content_set(layout, "button2", button2);
804 elm_object_text_set(button2, "Cancel Discovery");
805 evas_object_smart_callback_add(button2, "clicked", cancel_resource_cb, NULL);
808 list = elm_list_add(layout);
809 elm_list_mode_set(list, ELM_LIST_COMPRESS);
810 evas_object_smart_callback_add(list, "selected", list_selected_cb, NULL);
811 elm_object_part_content_set(layout, "list", list);
814 // log_entry - textarea for log
815 log_entry = elm_entry_add(layout);
816 elm_entry_scrollable_set(log_entry, EINA_TRUE);
817 elm_entry_editable_set(log_entry, EINA_FALSE);
818 elm_object_part_text_set(log_entry, "elm.guide", "Logs will be updated here!!!");
819 evas_object_size_hint_weight_set(log_entry, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
820 evas_object_size_hint_align_set(log_entry, EVAS_HINT_FILL, EVAS_HINT_FILL);
821 elm_object_part_content_set(layout, "log", log_entry);
823 nf_it = elm_naviframe_item_push(nf, "Resource Encapsulation", NULL, NULL, scroller, NULL);
824 elm_naviframe_item_pop_cb_set(nf_it, naviframe_pop_cb, NULL);
827 void discoverTempSensor(void *data, Evas_Object *obj, void *event_info)
829 g_resourceUri = TEMPERATURE_URI;
830 g_resourceType = TEMPERATURE_RT;
831 g_attributeKey = TEMPERATURE_AK;
836 void discoverLight(void *data, Evas_Object *obj, void *event_info)
838 g_resourceUri = LIGHT_URI;
839 g_resourceType = LIGHT_RT;
840 g_attributeKey = LIGHT_AK;