6f837c5d7b93ca5c23203e6dfdb84e4762f492b1
[platform/upstream/iotivity.git] / service / resource-encapsulation / examples / tizen / RESampleServerApp / src / reserver.cpp
1 /******************************************************************
2  *
3  * Copyright 2015 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 "reserver.h"
22
23 #include "remain.h"
24 #include "PrimitiveResource.h"
25 #include "RCSResourceObject.h"
26
27 #include <string>
28
29 using namespace std;
30 using namespace OC;
31 using namespace OIC::Service;
32
33 RCSResourceObject::Ptr server;
34 static bool serverCallback = false;
35
36 # define checkServer NULL!=server?true:false
37
38 static Evas_Object *log_entry = NULL;
39 static Evas_Object *list = NULL;
40 static Evas_Object *naviframe = NULL;
41
42 typedef struct datetime_popup
43 {
44     Evas_Object *popup;
45     Evas_Object *entry;
46 } datetime_popup_fields;
47
48 // Function to update the log in UI
49 void *updateGroupLog(void *data)
50 {
51     string *log = (string *)data;
52     // Show the log
53     elm_entry_entry_append(log_entry, (*log).c_str());
54     elm_entry_cursor_end_set(log_entry);
55     return NULL;
56 }
57
58 void printAttribute(const RCSResourceAttributes &attrs)
59 {
60     string logMessage = "";
61     for (const auto & attr : attrs)
62     {
63         logMessage = logMessage + "KEY:" + attr.key().c_str() + "<br>";
64         logMessage = logMessage + "VALUE:" + attr.value().toString().c_str() + "<br>";
65     }
66     dlog_print(DLOG_INFO, LOG_TAG, " %s", logMessage.c_str());
67     ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateGroupLog,
68                                           &logMessage);
69 }
70
71 static void onDestroy()
72 {
73     server = NULL;
74     string logMessage = "SERVER DESTROYED";
75
76     if(isPresenceOn == PRESENCE_ON)
77     {
78         OCPlatform::stopPresence();
79     }
80
81     dlog_print(DLOG_INFO, LOG_TAG, "#### %s", logMessage.c_str());
82     ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateGroupLog,
83                                           &logMessage);
84 }
85
86 //hander for get request (if developer choose second option for resource Creation)
87 RCSGetResponse requestHandlerForGet(const RCSRequest &request,
88                                     RCSResourceAttributes &attrs)
89 {
90     string logMessage = "GET REQUEST RECEIVED<br>";
91
92     RCSResourceObject::LockGuard lock(*server);
93     RCSResourceAttributes attributes = server->getAttributes();
94     printAttribute(attributes);
95     logMessage += "RESPONSE SENT<br>";
96
97     dlog_print(DLOG_INFO, LOG_TAG, "#### %s", logMessage.c_str());
98     ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateGroupLog,
99                                           &logMessage);
100     return RCSGetResponse::defaultAction();
101 }
102
103 //hander for set request (if developer choose second option for resource Creation)
104 RCSSetResponse requestHandlerForSet(const RCSRequest &request,
105                                     RCSResourceAttributes &attrs)
106 {
107     string logMessage = "SET REQUEST RECEIVED<br>";
108
109     RCSResourceObject::LockGuard lock(*server);
110     for (const auto & attr : attrs)
111     {
112         logMessage = logMessage + "KEY:" + attr.key().c_str() + "<br>";
113         logMessage = logMessage + "VALUE:" + attr.value().toString().c_str() + "<br>";
114         server->setAttribute(attr.key(), attr.value());
115     }
116
117     printAttribute(attrs);
118     logMessage += "RESPONSE SENT<br>";
119     dlog_print(DLOG_INFO, LOG_TAG, "#### %s", logMessage.c_str());
120     ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateGroupLog,
121                                           &logMessage);
122
123     return RCSSetResponse::defaultAction();
124 }
125
126 static void list_selected_cb(void *data, Evas_Object *obj, void *event_info)
127 {
128     Elm_Object_Item *it = (Elm_Object_Item *)event_info;
129     elm_list_item_selected_set(it, EINA_FALSE);
130 }
131
132 static void increaseTemp(void *data, Evas_Object *obj, void *event_info)
133 {
134     string logMessage = "";
135
136     if (checkServer)
137     {
138         RCSResourceObject::LockGuard lock(server);
139         server->getAttributes()[attributeKey] = server->getAttribute<int>(attributeKey) + 10;
140         string tempString  = std::to_string(server->getAttribute<int>(attributeKey));
141         logMessage = "TEMPERATURE CHANGED : " + tempString + "<br>";
142
143     }
144     else
145     {
146         logMessage = "NO SERRVER <br>";
147     }
148
149     dlog_print(DLOG_INFO, LOG_TAG, "#### %s", logMessage.c_str());
150     logMessage += "----------------------<br>";
151     ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateGroupLog,
152                                           &logMessage);
153 }
154
155 static void decreaseTemp(void *data, Evas_Object *obj, void *event_info)
156 {
157     string logMessage = "";
158
159     if (checkServer)
160     {
161         RCSResourceObject::LockGuard lock(server);
162         server->getAttributes()[attributeKey] = server->getAttribute<int>(attributeKey) - 10;
163         string tempString  = std::to_string(server->getAttribute<int>(attributeKey));
164         logMessage = "TEMPERATURE CHANGED : " + tempString + "<br>";
165     }
166     else
167     {
168         logMessage = "NO SERRVER <br>";
169     }
170
171     dlog_print(DLOG_INFO, LOG_TAG, "#### %s", logMessage.c_str());
172     logMessage += "----------------------<br>";
173     ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateGroupLog,
174                                           &logMessage);
175 }
176
177 static void initServer()
178 {
179     OCPlatform::startPresence(3);
180
181     try
182     {
183         server = RCSResourceObject::Builder(resourceUri, resourceType,
184                                             resourceInterface).setDiscoverable(true).setObservable(true).build();
185     }
186     catch (const RCSPlatformException &e)
187     {
188         dlog_print(DLOG_ERROR, LOG_TAG, "#### Create resource exception! (%s)", e.what());
189     }
190
191     server->setAutoNotifyPolicy(RCSResourceObject::AutoNotifyPolicy::UPDATED);
192     server->setSetRequestHandlerPolicy(RCSResourceObject::SetRequestHandlerPolicy::NEVER);
193     server->setAttribute(attributeKey, DEFALUT_VALUE);
194
195     string logMessage = "SERVER CREATED<br>";
196     dlog_print(DLOG_INFO, LOG_TAG, "#### %s", logMessage.c_str());
197     ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateGroupLog,
198                                           &logMessage);
199
200     ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))showGroupAPIs, NULL);
201 }
202
203 static void
204 popup_cancel_clicked_cb(void *data, Evas_Object *obj, void *event_info)
205 {
206     datetime_popup_fields *popup_fields = (datetime_popup_fields *)data;
207     evas_object_del(popup_fields->popup);
208     free(popup_fields);
209 }
210
211 static void
212 popup_set_clicked_cb(void *data, Evas_Object *obj, void *event_info)
213 {
214     datetime_popup_fields *popup_fields = (datetime_popup_fields *)data;
215     Evas_Object *entry = popup_fields->entry;
216     const char *temperatureString = elm_entry_entry_get(entry);
217     // Remove white spaces(if any) at the beginning
218     string logMessage = "";
219     int beginning = 0;
220     while (temperatureString[beginning] == ' ')
221     {
222         (beginning)++;
223     }
224
225     int len = strlen(temperatureString);
226     if (NULL == temperatureString || 1 > len)
227     {
228         dlog_print(DLOG_INFO, LOG_TAG, "#### Read NULL Temperature Value");
229         logMessage = "Temperature Cannot be NULL<br>";
230     }
231     else
232     {
233         if (checkServer)
234         {
235             RCSResourceObject::LockGuard lock(server);
236             int temperate = atoi(temperatureString);
237             server->getAttributes()[attributeKey] = temperate;
238             logMessage = "TEMPERATURE CHANGED : " + to_string(server->getAttribute<int>
239                          (attributeKey)) + "<br>";
240         }
241         else
242         {
243             logMessage += "NO SERVER<br>";
244         }
245     }
246     dlog_print(DLOG_INFO, LOG_TAG, "#### %s", logMessage.c_str());
247     logMessage += "----------------------<br>";
248     ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateGroupLog,
249                                           &logMessage);
250
251     evas_object_del(popup_fields->popup);
252     free(popup_fields);
253 }
254
255 static void
256 list_get_temperaure_cb(void *data, Evas_Object *obj, void *event_info)
257 {
258     Evas_Object *popup, *btn;
259     Evas_Object *nf = naviframe;
260     Evas_Object *entry;
261     Evas_Object *layout;
262
263     /* pop up */
264     popup = elm_popup_add(nf);
265     elm_popup_align_set(popup, ELM_NOTIFY_ALIGN_FILL, 1.0);
266     eext_object_event_callback_add(popup, EEXT_CALLBACK_BACK, eext_popup_back_cb, NULL);
267     evas_object_size_hint_weight_set(popup, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
268     elm_object_part_text_set(popup, "title,text", "Enter the temperature");
269
270     layout = elm_layout_add(popup);
271     elm_layout_file_set(layout, ELM_DEMO_EDJ, "popup_datetime_text");
272     evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
273     elm_object_content_set(popup, layout);
274
275     entry = elm_entry_add(layout);
276     elm_entry_single_line_set(entry, EINA_TRUE);
277     elm_entry_scrollable_set(entry, EINA_TRUE);
278     evas_object_size_hint_weight_set(entry, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
279     evas_object_size_hint_align_set(entry, EVAS_HINT_FILL, EVAS_HINT_FILL);
280     eext_entry_selection_back_event_allow_set(entry, EINA_TRUE);
281     elm_object_part_text_set(entry, "elm.guide", "in degree celsius");
282     elm_entry_input_panel_layout_set(entry, ELM_INPUT_PANEL_LAYOUT_NUMBER);
283     elm_object_part_content_set(layout, "elm.swallow.content", entry);
284
285     datetime_popup_fields *popup_fields;
286     popup_fields = (datetime_popup_fields *)malloc(sizeof(datetime_popup_fields));
287     if (NULL == popup_fields)
288     {
289         dlog_print(DLOG_INFO, LOG_TAG, "#### Memory allocation failed");
290     }
291     else
292     {
293         popup_fields->popup = popup;
294         popup_fields->entry = entry;
295     }
296
297     /* Cancel button */
298     btn = elm_button_add(popup);
299     elm_object_style_set(btn, "popup");
300     elm_object_text_set(btn, "Cancel");
301     elm_object_part_content_set(popup, "button1", btn);
302     evas_object_smart_callback_add(btn, "clicked", popup_cancel_clicked_cb, popup_fields);
303
304     /* Set button */
305     btn = elm_button_add(popup);
306     elm_object_style_set(btn, "popup");
307     elm_object_text_set(btn, "Set");
308     elm_object_part_content_set(popup, "button2", btn);
309     evas_object_smart_callback_add(btn, "clicked", popup_set_clicked_cb, popup_fields);
310
311     evas_object_show(popup);
312 }
313
314 void *showGroupAPIs(void *data)
315 {
316     // Add items to the list only if the list is empty
317     const Eina_List *eina_list = elm_list_items_get(list);
318     int count = eina_list_count(eina_list);
319     if (!count)
320     {
321         elm_list_item_append(list, "1. Increase Temperature", NULL, NULL,
322                              increaseTemp, NULL);
323
324         elm_list_item_append(list, "2. Decrease Temperature", NULL, NULL,
325                              decreaseTemp, NULL);
326
327         elm_list_item_append(list, "3. Set Temperature", NULL, NULL,
328                              list_get_temperaure_cb, NULL);
329
330         elm_list_go(list);
331     }
332     return NULL;
333 }
334
335 static Eina_Bool
336 naviframe_pop_cb(void *data, Elm_Object_Item *it)
337 {
338     onDestroy();
339
340     if (NULL != log_entry)
341     {
342         evas_object_del(log_entry);
343         log_entry = NULL;
344     }
345     if (NULL != list)
346     {
347         evas_object_del(list);
348         list = NULL;
349     }
350     return EINA_TRUE;
351 }
352
353 // Method to set up server screens
354 void serverCreateUI(void *data, Evas_Object *obj, void *event_info)
355 {
356     Evas_Object *layout;
357     Evas_Object *scroller;
358     Evas_Object *nf = (Evas_Object *)data;
359     Evas_Object *button1;
360     Evas_Object *button2;
361     Elm_Object_Item *nf_it;
362     naviframe = nf;
363
364     // Scroller
365     scroller = elm_scroller_add(nf);
366     elm_scroller_bounce_set(scroller, EINA_FALSE, EINA_TRUE);
367     elm_scroller_policy_set(scroller, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_AUTO);
368
369     // Layout
370     layout = elm_layout_add(nf);
371     elm_layout_file_set(layout, ELM_DEMO_EDJ, "server_layout");
372     evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
373
374     elm_object_content_set(scroller, layout);
375
376     // Button
377     button1 = elm_button_add(layout);
378     elm_object_part_content_set(layout, "button1", button1);
379     elm_object_text_set(button1, "Auto Control");
380     evas_object_smart_callback_add(button1, "clicked", start_server, NULL);
381
382     // Button
383     button2 = elm_button_add(layout);
384     elm_object_part_content_set(layout, "button2", button2);
385     elm_object_text_set(button2, "Dev Control");
386     evas_object_smart_callback_add(button2, "clicked", start_server_cb, NULL);
387
388     // List
389     list = elm_list_add(layout);
390     elm_list_mode_set(list, ELM_LIST_COMPRESS);
391     evas_object_smart_callback_add(list, "selected", list_selected_cb, NULL);
392     elm_object_part_content_set(layout, "list", list);
393     elm_list_go(list);
394
395     // log_entry - text area for log
396     log_entry = elm_entry_add(layout);
397     elm_entry_scrollable_set(log_entry, EINA_TRUE);
398     elm_entry_editable_set(log_entry, EINA_FALSE);
399     elm_object_part_text_set(log_entry, "elm.guide", "Logs will be updated here!!!");
400     evas_object_size_hint_weight_set(log_entry, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
401     evas_object_size_hint_align_set(log_entry, EVAS_HINT_FILL, EVAS_HINT_FILL);
402     elm_object_part_content_set(layout, "log", log_entry);
403
404     nf_it = elm_naviframe_item_push(nf, "Resource Encapsulation", NULL, NULL, scroller, NULL);
405     elm_naviframe_item_pop_cb_set(nf_it, naviframe_pop_cb, NULL);
406 }
407
408 void start_server(void *data, Evas_Object *obj, void *event_info)
409 {
410     server = NULL;
411     string logMessage = "SERVER WITHOUT CALLBACK<br>";
412
413     serverCallback = false;
414     initServer();
415
416     dlog_print(DLOG_INFO, LOG_TAG, "#### %s", logMessage.c_str());
417     ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateGroupLog,
418                                           &logMessage);
419 }
420
421 void start_server_cb(void *data, Evas_Object *obj, void *event_info)
422 {
423     server = NULL;
424     string logMessage = "SERVER WITH CALLBACK<br>";
425
426     serverCallback = true;
427     initServer();
428
429     if (checkServer)
430     {
431         server->setGetRequestHandler(requestHandlerForGet);
432         server->setSetRequestHandler(requestHandlerForSet);
433         logMessage = "HANDLERS SET<br>";
434     }
435     else
436     {
437         logMessage = "NO SERRVER FOUND<br>";
438     }
439
440     dlog_print(DLOG_INFO, LOG_TAG, "#### %s", logMessage.c_str());
441     ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateGroupLog,
442                                           &logMessage);
443
444 }