Imported Upstream version 0.9.2
[platform/upstream/iotivity.git] / service / things-manager / sampleapp / tizen / ConServerApp / src / conserverapp.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 "conserverapp.h"
22
23 #include <tizen.h>
24 #include <pthread.h>
25
26 #include "configurationresource.h"
27 #include "diagnosticsresource.h"
28 #include "factorysetresource.h"
29
30 using namespace std;
31 using namespace OC;
32 using namespace OIC;
33
34 namespace PH = std::placeholders;
35
36 /* Default system configuration value's variables
37    The variable's names should be same as the names of "extern" variables defined in
38    "configurationresource.h" */
39 std::string defaultLocation;
40 std::string defaultRegion;
41 std::string defaultSystemTime;
42 std::string defaultCurrency;
43
44 static ThingsManager *g_thingsmanager;
45
46 const int SUCCESS_RESPONSE = 0;
47
48 bool resources_created = false;
49
50 // Forward declaring the entityHandler (Configuration)
51 bool prepareResponseForResource(std::shared_ptr< OCResourceRequest > request);
52 OCStackResult sendResponseForResource(std::shared_ptr< OCResourceRequest > pRequest);
53 OCEntityHandlerResult entityHandlerForResource(std::shared_ptr< OCResourceRequest > request);
54
55 ConfigurationResource *myConfigurationResource;
56 DiagnosticsResource *myDiagnosticsResource;
57 FactorySetResource *myFactorySetResource;
58
59 typedef std::function< void(OCRepresentation &) > putFunc;
60 typedef std::function< OCRepresentation(void) > getFunc;
61
62 typedef struct appdata
63 {
64     Evas_Object *win;
65     Evas_Object *conform;
66     Evas_Object *naviframe;
67     Evas_Object *scroller;
68     Evas_Object *layout, *base_layout;
69     Evas_Object *bootButton;
70     Evas_Object *createConfButton;
71 } appdata_s;
72
73 Evas_Object *log_entry;
74
75 std::string logMessage;
76
77 getFunc getGetFunction(std::string uri)
78 {
79     getFunc res = NULL;
80
81     if (uri == myConfigurationResource->getUri())
82     {
83         res = std::bind(&ConfigurationResource::getConfigurationRepresentation,
84                         myConfigurationResource);
85     }
86     else if (uri == myDiagnosticsResource->getUri())
87     {
88         res = std::bind(&DiagnosticsResource::getDiagnosticsRepresentation,
89                         myDiagnosticsResource);
90     }
91
92     return res;
93 }
94
95 putFunc getPutFunction(std::string uri)
96 {
97     putFunc res = NULL;
98
99     if (uri == myConfigurationResource->getUri())
100     {
101         res = std::bind(&ConfigurationResource::setConfigurationRepresentation,
102                         myConfigurationResource, std::placeholders::_1);
103     }
104     else if (uri == myDiagnosticsResource->getUri())
105     {
106         res = std::bind(&DiagnosticsResource::setDiagnosticsRepresentation,
107                         myDiagnosticsResource, std::placeholders::_1);
108     }
109
110     return res;
111 }
112
113 // This function prepares a response for the incoming request
114 bool prepareResponseForResource(std::shared_ptr< OCResourceRequest > request)
115 {
116     dlog_print(DLOG_INFO, LOG_TAG, "#### In Server CPP prepareResponseForResource");
117     bool result = false;
118     if (request)
119     {
120         // Get the request type and request flag
121         std::string requestType = request->getRequestType();
122         int requestFlag = request->getRequestHandlerFlag();
123
124         if (requestFlag == RequestHandlerFlag::RequestFlag)
125         {
126             dlog_print(DLOG_INFO, LOG_TAG, "#### requestFlag : Request");
127
128             // If the request type is GET
129             if (requestType == "GET")
130             {
131                 dlog_print(DLOG_INFO, LOG_TAG, "#### requestType : GET");
132
133                 // GET operations are directly handled while sending the response
134                 result = true;
135             }
136             else if (requestType == "PUT")
137             {
138                 dlog_print(DLOG_INFO, LOG_TAG, "#### requestType : PUT");
139                 putFunc putFunction;
140                 OCRepresentation rep = request->getResourceRepresentation();
141
142                 // Get appropriate function to be called for the PUT request
143                 putFunction = getPutFunction(request->getResourceUri());
144
145                 // Do related operations related to PUT request
146                 putFunction(rep);
147                 result = true;
148             }
149             else if (requestType == "POST")
150             {
151                 // POST request operations
152             }
153             else if (requestType == "DELETE")
154             {
155                 // DELETE request operations
156             }
157         }
158         else if (requestFlag == RequestHandlerFlag::ObserverFlag)
159         {
160             dlog_print(DLOG_INFO, LOG_TAG, "#### requestFlag : Observer");
161         }
162     }
163     else
164     {
165         dlog_print(DLOG_INFO, LOG_TAG, "#### Request invalid");
166     }
167
168     return result;
169 }
170
171 // This function sends a response for the incoming request
172 OCStackResult sendResponseForResource(std::shared_ptr< OCResourceRequest > pRequest)
173 {
174     auto pResponse = std::make_shared< OC::OCResourceResponse >();
175
176     // Check for query params (if any)
177     QueryParamsMap queryParamsMap = pRequest->getQueryParameters();
178
179     pResponse->setRequestHandle(pRequest->getRequestHandle());
180     pResponse->setResourceHandle(pRequest->getResourceHandle());
181
182     getFunc getFunction;
183     getFunction = getGetFunction(pRequest->getResourceUri());
184
185     OCRepresentation rep;
186     rep = getFunction();
187
188     auto findRes = queryParamsMap.find("if");
189
190     if (findRes != queryParamsMap.end())
191     {
192         pResponse->setResourceRepresentation(rep, findRes->second);
193     }
194     else
195     {
196         pResponse->setResourceRepresentation(rep, DEFAULT_INTERFACE);
197     }
198
199     pResponse->setErrorCode(200);
200     pResponse->setResponseResult(OC_EH_OK);
201
202     return OCPlatform::sendResponse(pResponse);
203 }
204
205 // This function handles the requests and sends the response
206 OCEntityHandlerResult entityHandlerForResource(std::shared_ptr< OCResourceRequest > request)
207 {
208     dlog_print(DLOG_INFO, LOG_TAG, "#### In Server CPP (entityHandlerForResource) entity"
209                "handler:");
210     OCEntityHandlerResult ehResult = OC_EH_ERROR;
211
212     if (prepareResponseForResource(request))
213     {
214         if (OC_STACK_OK == sendResponseForResource(request))
215         {
216             ehResult = OC_EH_OK;
217             dlog_print(DLOG_INFO, LOG_TAG, "#### sendResponse success.");
218         }
219         else
220         {
221             dlog_print(DLOG_INFO, LOG_TAG, "#### sendResponse failed.");
222         }
223     }
224     else
225     {
226         dlog_print(DLOG_INFO, LOG_TAG, "#### PrepareResponse failed.");
227     }
228     return ehResult;
229 }
230
231 // Updates the log in the UI
232 void *updateLog(void *data)
233 {
234     string *log = (string *)data;
235     //Show the log
236     elm_entry_entry_append(log_entry, log->c_str());
237     elm_entry_cursor_end_set(log_entry);
238
239     dlog_print(DLOG_INFO, LOG_TAG, "%s", log->c_str());
240     dlog_print(DLOG_INFO, LOG_TAG, "#### updateLog exit!!!!");
241
242     return NULL;
243 }
244
245 static void
246 win_delete_request_cb(void *data , Evas_Object *obj , void *event_info)
247 {
248     ui_app_exit();
249 }
250
251 // Function to delete all the configuration resources which are created
252 void deleteResources()
253 {
254     if (NULL != myConfigurationResource)
255         myConfigurationResource->deleteResource();
256     if (NULL != myDiagnosticsResource)
257         myDiagnosticsResource->deleteResource();
258     if (NULL != myFactorySetResource)
259         myFactorySetResource->deleteResource();
260 }
261
262 static void
263 win_back_cb(void *data, Evas_Object *obj, void *event_info)
264 {
265
266     deleteResources();
267
268     ui_app_exit();
269 }
270
271 /* Callback Function to be called by the platform
272    when response arrives from the BootStrap Server */
273 void onBootStrapCallback(const HeaderOptions &headerOptions, const OCRepresentation &rep,
274                          const int eCode)
275 {
276     dlog_print(DLOG_INFO, LOG_TAG, "#### onBootStrap entry");
277
278     if (SUCCESS_RESPONSE != eCode)
279     {
280         dlog_print(DLOG_INFO, LOG_TAG, "#### onBootStrap -- onGET Response error: %d", eCode);
281         return ;
282     }
283
284     dlog_print(DLOG_INFO, LOG_TAG, "#### onBootStrap -- GET request was successful");
285     dlog_print(DLOG_INFO, LOG_TAG, "#### onBootStrap -- Resource URI: %s", rep.getUri().c_str());
286
287     logMessage = "----------------------------<br>";
288     logMessage += "GET request was successful<br>";
289     logMessage += "URI : " + rep.getUri() + "<br>";
290
291     defaultRegion = rep.getValue< std::string >("r");
292     defaultSystemTime = rep.getValue< std::string >("st");
293     defaultCurrency = rep.getValue< std::string >("c");
294     defaultLocation = rep.getValue< std::string >("loc");
295
296     logMessage += "Location : " + defaultLocation + "<br>";
297     logMessage += "SystemTime : " + defaultSystemTime + "<br>";
298     logMessage += "currency : " + defaultCurrency + "<br>";
299     logMessage += "Region : " + defaultRegion + "<br>";
300
301     dlog_print(DLOG_INFO, LOG_TAG, "  %s", logMessage.c_str());
302
303     //Call updateLog in the thread safe mode
304     ecore_main_loop_thread_safe_call_sync(updateLog, &logMessage);
305
306 }
307
308 // Function to be called when the doBootStrap UI button is clicked
309 static void
310 doBootStrap_cb(void *data , Evas_Object *obj , void *event_info)
311 {
312     OCStackResult result = g_thingsmanager->doBootstrap(&onBootStrapCallback);
313     if (OC_STACK_OK == result)
314     {
315         dlog_print(DLOG_INFO, LOG_TAG, "#### doBootstrap returned OC_STACK_OK");
316     }
317     else
318     {
319         dlog_print(DLOG_INFO, LOG_TAG, "#### doBootstrap failed");
320     }
321 }
322
323 // Function to be called when Create Configuration Resources UI button is clicked
324 static void
325 createConfResource_cb(void *data , Evas_Object *obj , void *event_info)
326 {
327     logMessage = "----------------------------<br>";
328     if (!resources_created)
329     {
330         resources_created = true;
331         myConfigurationResource = new ConfigurationResource();
332         myConfigurationResource->createResource(&entityHandlerForResource);
333
334         myDiagnosticsResource = new DiagnosticsResource();
335         myDiagnosticsResource->createResource(&entityHandlerForResource);
336
337         myFactorySetResource = new FactorySetResource();
338         myFactorySetResource->createResource(&entityHandlerForResource);
339
340         myDiagnosticsResource->factoryReset = std::function < void()
341                                               > (std::bind(&ConfigurationResource::factoryReset,
342                                                       myConfigurationResource));
343
344         logMessage += "Resources Created Successfully!!! Server is Ready!!!<br>";
345     }
346     else
347     {
348         logMessage += "Resources were created already!!! <br>";
349     }
350
351     dlog_print(DLOG_INFO, LOG_TAG, "  %s", logMessage.c_str());
352     // Show the log in the UI
353     ecore_main_loop_thread_safe_call_sync(updateLog, &logMessage);
354 }
355
356 static void
357 create_base_gui(appdata_s *ad)
358 {
359     // Window
360     ad->win = elm_win_util_standard_add(PACKAGE, PACKAGE);
361     elm_win_autodel_set(ad->win, EINA_TRUE);
362
363     if (elm_win_wm_rotation_supported_get(ad->win))
364     {
365         int rots[4] = { 0, 90, 180, 270 };
366         elm_win_wm_rotation_available_rotations_set(ad->win, (const int *)(&rots), 4);
367     }
368
369     evas_object_smart_callback_add(ad->win, "delete,request", win_delete_request_cb, NULL);
370     eext_object_event_callback_add(ad->win, EEXT_CALLBACK_BACK, win_back_cb, ad);
371
372     // Conformant
373     ad->conform = elm_conformant_add(ad->win);
374     evas_object_size_hint_weight_set(ad->conform, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
375     elm_win_resize_object_add(ad->win, ad->conform);
376     evas_object_show(ad->conform);
377
378     // Base Layout
379     ad->base_layout = elm_layout_add(ad->conform);
380     evas_object_size_hint_weight_set(ad->base_layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
381     elm_layout_theme_set(ad->base_layout, "layout", "application", "default");
382     evas_object_show(ad->base_layout);
383
384     elm_object_content_set(ad->conform, ad->base_layout);
385
386     // naviframe
387     ad->naviframe = elm_naviframe_add(ad->base_layout);
388     elm_object_part_content_set(ad->base_layout, "elm.swallow.content", ad->naviframe);
389
390     // Scroller
391     ad->scroller = elm_scroller_add(ad->naviframe);
392     elm_scroller_bounce_set(ad->scroller, EINA_FALSE, EINA_TRUE);
393     elm_scroller_policy_set(ad->scroller, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_AUTO);
394
395     // layout
396     ad->layout = elm_layout_add(ad->naviframe);
397     evas_object_size_hint_weight_set(ad->layout, EVAS_HINT_EXPAND, 0.0);
398     elm_layout_file_set(ad->layout, ELM_DEMO_EDJ, "mainpage_layout");
399
400     elm_object_content_set(ad->scroller, ad->layout);
401
402     ad->bootButton = elm_button_add(ad->layout);
403     elm_object_text_set(ad->bootButton, "doBootStrap");
404     evas_object_size_hint_weight_set(ad->bootButton, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
405     evas_object_size_hint_align_set(ad->bootButton, EVAS_HINT_FILL, EVAS_HINT_FILL);
406     evas_object_smart_callback_add(ad->bootButton, "clicked", doBootStrap_cb, ad);
407     elm_object_part_content_set(ad->layout, "bootstrap_button", ad->bootButton);
408
409     ad->createConfButton = elm_button_add(ad->layout);
410     elm_object_text_set(ad->createConfButton, "Create Configuration Resources");
411     evas_object_size_hint_weight_set(ad->createConfButton, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
412     evas_object_size_hint_align_set(ad->createConfButton, EVAS_HINT_FILL, EVAS_HINT_FILL);
413     evas_object_smart_callback_add(ad->createConfButton, "clicked", createConfResource_cb, ad);
414     elm_object_part_content_set(ad->layout, "create_conf_button", ad->createConfButton);
415
416     log_entry = elm_entry_add(ad->layout);
417     elm_entry_scrollable_set(log_entry, EINA_TRUE);
418     elm_entry_editable_set(log_entry, EINA_FALSE);
419     elm_object_part_text_set(log_entry, "elm.guide", "Logs will be updated here!!!");
420     evas_object_size_hint_weight_set(log_entry, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
421     evas_object_size_hint_align_set(log_entry, EVAS_HINT_FILL, EVAS_HINT_FILL);
422     elm_object_part_content_set(ad->layout, "log", log_entry);
423
424     elm_naviframe_item_push(ad->naviframe, "Configuration Server", NULL, NULL, ad->scroller, NULL);
425
426     // Show window after base gui is set up
427     evas_object_show(ad->win);
428 }
429
430 // Function which configures the OCPlatform
431 static void
432 configure_platform()
433 {
434     try
435     {
436         PlatformConfig config
437         { OC::ServiceType::InProc, ModeType::Both, "0.0.0.0", 0, OC::QualityOfService::LowQos };
438
439         OCPlatform::Configure(config);
440
441         dlog_print(DLOG_INFO, LOG_TAG, "#### Platform configuration done!!!!");
442     }
443     catch (OCException &e)
444     {
445         dlog_print(DLOG_ERROR, LOG_TAG, "Exception occured! (%s)", e.what());
446     }
447 }
448
449
450 static bool
451 app_create(void *data)
452 {
453     /* Hook to take necessary actions before main event loop starts
454         Initialize UI resources and application's data
455         If this function returns true, the main loop of application starts
456         If this function returns false, the application is terminated */
457     appdata_s *ad = (appdata_s *)data;
458
459     elm_app_base_scale_set(1.8);
460
461     // Create and show the UI
462     create_base_gui(ad);
463
464     // Configure the OCPlatform
465     configure_platform();
466
467     g_thingsmanager = new ThingsManager();
468
469     return true;
470 }
471
472 static void
473 app_control(app_control_h app_control, void *data)
474 {
475     // Handle the launch request.
476 }
477
478 static void
479 app_pause(void *data)
480 {
481     // Take necessary actions when application becomes invisible.
482 }
483
484 static void
485 app_resume(void *data)
486 {
487     // Take necessary actions when application becomes visible.
488 }
489
490 static void
491 app_terminate(void *data)
492 {
493     // Release all resources.
494 }
495
496 static void
497 ui_app_lang_changed(app_event_info_h event_info, void *user_data)
498 {
499     // APP_EVENT_LANGUAGE_CHANGED
500     char *locale = NULL;
501     system_settings_get_value_string(SYSTEM_SETTINGS_KEY_LOCALE_LANGUAGE, &locale);
502     elm_language_set(locale);
503     free(locale);
504     return;
505 }
506
507 static void
508 ui_app_orient_changed(app_event_info_h event_info, void *user_data)
509 {
510     // APP_EVENT_DEVICE_ORIENTATION_CHANGED
511     return;
512 }
513
514 static void
515 ui_app_region_changed(app_event_info_h event_info, void *user_data)
516 {
517     // APP_EVENT_REGION_FORMAT_CHANGED
518 }
519
520 static void
521 ui_app_low_battery(app_event_info_h event_info, void *user_data)
522 {
523     // APP_EVENT_LOW_BATTERY
524 }
525
526 static void
527 ui_app_low_memory(app_event_info_h event_info, void *user_data)
528 {
529     // APP_EVENT_LOW_MEMORY
530 }
531
532 int
533 main(int argc, char *argv[])
534 {
535     appdata_s ad = {0,};
536     int ret = 0;
537
538     ui_app_lifecycle_callback_s event_callback = {0,};
539     app_event_handler_h handlers[5] = {NULL, };
540
541     event_callback.create = app_create;
542     event_callback.terminate = app_terminate;
543     event_callback.pause = app_pause;
544     event_callback.resume = app_resume;
545     event_callback.app_control = app_control;
546
547     ui_app_add_event_handler(&handlers[APP_EVENT_LOW_BATTERY], APP_EVENT_LOW_BATTERY,
548                              ui_app_low_battery, &ad);
549     ui_app_add_event_handler(&handlers[APP_EVENT_LOW_MEMORY], APP_EVENT_LOW_MEMORY,
550                              ui_app_low_memory, &ad);
551     ui_app_add_event_handler(&handlers[APP_EVENT_DEVICE_ORIENTATION_CHANGED],
552                              APP_EVENT_DEVICE_ORIENTATION_CHANGED, ui_app_orient_changed, &ad);
553     ui_app_add_event_handler(&handlers[APP_EVENT_LANGUAGE_CHANGED], APP_EVENT_LANGUAGE_CHANGED,
554                              ui_app_lang_changed, &ad);
555     ui_app_add_event_handler(&handlers[APP_EVENT_REGION_FORMAT_CHANGED],
556                              APP_EVENT_REGION_FORMAT_CHANGED, ui_app_region_changed, &ad);
557     ui_app_remove_event_handler(handlers[APP_EVENT_LOW_MEMORY]);
558
559     ret = ui_app_main(argc, argv, &event_callback, &ad);
560     if (APP_ERROR_NONE != ret)
561     {
562         dlog_print(DLOG_ERROR, LOG_TAG, "app_main() is failed. err = %d", ret);
563     }
564
565     return ret;
566 }