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