Imported Upstream version 0.9.1
[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         }
218         else
219         {
220             dlog_print(DLOG_INFO, LOG_TAG, "#### sendResponse failed.");
221         }
222     }
223     else
224     {
225         dlog_print(DLOG_INFO, LOG_TAG, "#### PrepareResponse failed.");
226     }
227     return ehResult;
228 }
229
230 // Updates the log in the UI
231 void *updateLog(void *data)
232 {
233     string *log = (string *)data;
234     //Show the log
235     elm_entry_entry_append(log_entry, log->c_str());
236     elm_entry_cursor_end_set(log_entry);
237
238     dlog_print(DLOG_INFO, LOG_TAG, "#### updateLog exit!!!!");
239
240     return NULL;
241 }
242
243 static void
244 win_delete_request_cb(void *data , Evas_Object *obj , void *event_info)
245 {
246     ui_app_exit();
247 }
248
249 // Function to delete all the configuration resources which are created
250 void deleteResources()
251 {
252     if (NULL != myConfigurationResource)
253         myConfigurationResource->deleteResource();
254     if (NULL != myDiagnosticsResource)
255         myDiagnosticsResource->deleteResource();
256     if (NULL != myFactorySetResource)
257         myFactorySetResource->deleteResource();
258 }
259
260 static void
261 win_back_cb(void *data, Evas_Object *obj, void *event_info)
262 {
263
264     deleteResources();
265
266     ui_app_exit();
267 }
268
269 /* Callback Function to be called by the platform
270    when response arrives from the BootStrap Server */
271 void onBootStrapCallback(const HeaderOptions &headerOptions, const OCRepresentation &rep,
272                          const int eCode)
273 {
274     dlog_print(DLOG_INFO, LOG_TAG, "#### onBootStrap entry");
275
276     if (SUCCESS_RESPONSE != eCode)
277     {
278         dlog_print(DLOG_INFO, LOG_TAG, "#### onBootStrap -- onGET Response error: %d", eCode);
279         return ;
280     }
281
282     dlog_print(DLOG_INFO, LOG_TAG, "#### onBootStrap -- GET request was successful");
283     dlog_print(DLOG_INFO, LOG_TAG, "#### onBootStrap -- Resource URI: %s", rep.getUri().c_str());
284
285     logMessage = "----------------------------<br>";
286     logMessage += "GET request was successful<br>";
287     logMessage += "URI : " + rep.getUri() + "<br>";
288
289     defaultRegion = rep.getValue< std::string >("r");
290     defaultSystemTime = rep.getValue< std::string >("st");
291     defaultCurrency = rep.getValue< std::string >("c");
292     defaultLocation = rep.getValue< std::string >("loc");
293
294     logMessage += "Location : " + defaultLocation + "<br>";
295     logMessage += "SystemTime : " + defaultSystemTime + "<br>";
296     logMessage += "currency : " + defaultCurrency + "<br>";
297     logMessage += "Region : " + defaultRegion + "<br>";
298
299     //Call updateLog in the thread safe mode
300     ecore_main_loop_thread_safe_call_sync(updateLog, &logMessage);
301
302 }
303
304 // Function to be called when the doBootStrap UI button is clicked
305 static void
306 doBootStrap_cb(void *data , Evas_Object *obj , void *event_info)
307 {
308     OCStackResult result = g_thingsmanager->doBootstrap(&onBootStrapCallback);
309     if (OC_STACK_OK == result)
310     {
311         dlog_print(DLOG_INFO, LOG_TAG, "#### doBootstrap returned OC_STACK_OK");
312     }
313     else
314     {
315         dlog_print(DLOG_INFO, LOG_TAG, "#### doBootstrap failed");
316     }
317 }
318
319 // Function to be called when Create Configuration Resources UI button is clicked
320 static void
321 createConfResource_cb(void *data , Evas_Object *obj , void *event_info)
322 {
323     logMessage = "----------------------------<br>";
324     if (!resources_created)
325     {
326         resources_created = true;
327         myConfigurationResource = new ConfigurationResource();
328         myConfigurationResource->createResource(&entityHandlerForResource);
329
330         myDiagnosticsResource = new DiagnosticsResource();
331         myDiagnosticsResource->createResource(&entityHandlerForResource);
332
333         myFactorySetResource = new FactorySetResource();
334         myFactorySetResource->createResource(&entityHandlerForResource);
335
336         myDiagnosticsResource->factoryReset = std::function < void()
337                                               > (std::bind(&ConfigurationResource::factoryReset,
338                                                       myConfigurationResource));
339
340         logMessage += "Resources Created Successfully!!! Server is Ready!!!<br>";
341     }
342     else
343     {
344         logMessage += "Resources were created already!!! <br>";
345     }
346     // Show the log in the UI
347     ecore_main_loop_thread_safe_call_sync(updateLog, &logMessage);
348 }
349
350 static void
351 create_base_gui(appdata_s *ad)
352 {
353     // Window
354     ad->win = elm_win_util_standard_add(PACKAGE, PACKAGE);
355     elm_win_autodel_set(ad->win, EINA_TRUE);
356
357     if (elm_win_wm_rotation_supported_get(ad->win))
358     {
359         int rots[4] = { 0, 90, 180, 270 };
360         elm_win_wm_rotation_available_rotations_set(ad->win, (const int *)(&rots), 4);
361     }
362
363     evas_object_smart_callback_add(ad->win, "delete,request", win_delete_request_cb, NULL);
364     eext_object_event_callback_add(ad->win, EEXT_CALLBACK_BACK, win_back_cb, ad);
365
366     // Conformant
367     ad->conform = elm_conformant_add(ad->win);
368     evas_object_size_hint_weight_set(ad->conform, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
369     elm_win_resize_object_add(ad->win, ad->conform);
370     evas_object_show(ad->conform);
371
372     // Base Layout
373     ad->base_layout = elm_layout_add(ad->conform);
374     evas_object_size_hint_weight_set(ad->base_layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
375     elm_layout_theme_set(ad->base_layout, "layout", "application", "default");
376     evas_object_show(ad->base_layout);
377
378     elm_object_content_set(ad->conform, ad->base_layout);
379
380     // naviframe
381     ad->naviframe = elm_naviframe_add(ad->base_layout);
382     elm_object_part_content_set(ad->base_layout, "elm.swallow.content", ad->naviframe);
383
384     // Scroller
385     ad->scroller = elm_scroller_add(ad->naviframe);
386     elm_scroller_bounce_set(ad->scroller, EINA_FALSE, EINA_TRUE);
387     elm_scroller_policy_set(ad->scroller, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_AUTO);
388
389     // layout
390     ad->layout = elm_layout_add(ad->naviframe);
391     evas_object_size_hint_weight_set(ad->layout, EVAS_HINT_EXPAND, 0.0);
392     elm_layout_file_set(ad->layout, ELM_DEMO_EDJ, "mainpage_layout");
393
394     elm_object_content_set(ad->scroller, ad->layout);
395
396     ad->bootButton = elm_button_add(ad->layout);
397     elm_object_text_set(ad->bootButton, "doBootStrap");
398     evas_object_size_hint_weight_set(ad->bootButton, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
399     evas_object_size_hint_align_set(ad->bootButton, EVAS_HINT_FILL, EVAS_HINT_FILL);
400     evas_object_smart_callback_add(ad->bootButton, "clicked", doBootStrap_cb, ad);
401     elm_object_part_content_set(ad->layout, "bootstrap_button", ad->bootButton);
402
403     ad->createConfButton = elm_button_add(ad->layout);
404     elm_object_text_set(ad->createConfButton, "Create Configuration Resources");
405     evas_object_size_hint_weight_set(ad->createConfButton, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
406     evas_object_size_hint_align_set(ad->createConfButton, EVAS_HINT_FILL, EVAS_HINT_FILL);
407     evas_object_smart_callback_add(ad->createConfButton, "clicked", createConfResource_cb, ad);
408     elm_object_part_content_set(ad->layout, "create_conf_button", ad->createConfButton);
409
410     log_entry = elm_entry_add(ad->layout);
411     elm_entry_scrollable_set(log_entry, EINA_TRUE);
412     elm_entry_editable_set(log_entry, EINA_FALSE);
413     elm_object_part_text_set(log_entry, "elm.guide", "Logs will be updated here!!!");
414     evas_object_size_hint_weight_set(log_entry, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
415     evas_object_size_hint_align_set(log_entry, EVAS_HINT_FILL, EVAS_HINT_FILL);
416     elm_object_part_content_set(ad->layout, "log", log_entry);
417
418     elm_naviframe_item_push(ad->naviframe, "Configuration Server", NULL, NULL, ad->scroller, NULL);
419
420     // Show window after base gui is set up
421     evas_object_show(ad->win);
422 }
423
424 // Function which configures the OCPlatform
425 static void
426 configure_platform()
427 {
428     try
429     {
430         PlatformConfig config
431         { OC::ServiceType::InProc, ModeType::Both, "0.0.0.0", 0, OC::QualityOfService::LowQos };
432
433         OCPlatform::Configure(config);
434
435         dlog_print(DLOG_INFO, LOG_TAG, "#### Platform configuration done!!!!");
436     }
437     catch (OCException &e)
438     {
439         dlog_print(DLOG_ERROR, LOG_TAG, "Exception occured! (%s)", e.what());
440     }
441 }
442
443
444 static bool
445 app_create(void *data)
446 {
447     /* Hook to take necessary actions before main event loop starts
448         Initialize UI resources and application's data
449         If this function returns true, the main loop of application starts
450         If this function returns false, the application is terminated */
451     appdata_s *ad = (appdata_s *)data;
452
453     elm_app_base_scale_set(1.8);
454
455     // Create and show the UI
456     create_base_gui(ad);
457
458     // Configure the OCPlatform
459     configure_platform();
460
461     g_thingsmanager = new ThingsManager();
462
463     return true;
464 }
465
466 static void
467 app_control(app_control_h app_control, void *data)
468 {
469     // Handle the launch request.
470 }
471
472 static void
473 app_pause(void *data)
474 {
475     // Take necessary actions when application becomes invisible.
476 }
477
478 static void
479 app_resume(void *data)
480 {
481     // Take necessary actions when application becomes visible.
482 }
483
484 static void
485 app_terminate(void *data)
486 {
487     // Release all resources.
488 }
489
490 static void
491 ui_app_lang_changed(app_event_info_h event_info, void *user_data)
492 {
493     // APP_EVENT_LANGUAGE_CHANGED
494     char *locale = NULL;
495     system_settings_get_value_string(SYSTEM_SETTINGS_KEY_LOCALE_LANGUAGE, &locale);
496     elm_language_set(locale);
497     free(locale);
498     return;
499 }
500
501 static void
502 ui_app_orient_changed(app_event_info_h event_info, void *user_data)
503 {
504     // APP_EVENT_DEVICE_ORIENTATION_CHANGED
505     return;
506 }
507
508 static void
509 ui_app_region_changed(app_event_info_h event_info, void *user_data)
510 {
511     // APP_EVENT_REGION_FORMAT_CHANGED
512 }
513
514 static void
515 ui_app_low_battery(app_event_info_h event_info, void *user_data)
516 {
517     // APP_EVENT_LOW_BATTERY
518 }
519
520 static void
521 ui_app_low_memory(app_event_info_h event_info, void *user_data)
522 {
523     // APP_EVENT_LOW_MEMORY
524 }
525
526 int
527 main(int argc, char *argv[])
528 {
529     appdata_s ad = {0,};
530     int ret = 0;
531
532     ui_app_lifecycle_callback_s event_callback = {0,};
533     app_event_handler_h handlers[5] = {NULL, };
534
535     event_callback.create = app_create;
536     event_callback.terminate = app_terminate;
537     event_callback.pause = app_pause;
538     event_callback.resume = app_resume;
539     event_callback.app_control = app_control;
540
541     ui_app_add_event_handler(&handlers[APP_EVENT_LOW_BATTERY], APP_EVENT_LOW_BATTERY,
542                              ui_app_low_battery, &ad);
543     ui_app_add_event_handler(&handlers[APP_EVENT_LOW_MEMORY], APP_EVENT_LOW_MEMORY,
544                              ui_app_low_memory, &ad);
545     ui_app_add_event_handler(&handlers[APP_EVENT_DEVICE_ORIENTATION_CHANGED],
546                              APP_EVENT_DEVICE_ORIENTATION_CHANGED, ui_app_orient_changed, &ad);
547     ui_app_add_event_handler(&handlers[APP_EVENT_LANGUAGE_CHANGED], APP_EVENT_LANGUAGE_CHANGED,
548                              ui_app_lang_changed, &ad);
549     ui_app_add_event_handler(&handlers[APP_EVENT_REGION_FORMAT_CHANGED],
550                              APP_EVENT_REGION_FORMAT_CHANGED, ui_app_region_changed, &ad);
551     ui_app_remove_event_handler(handlers[APP_EVENT_LOW_MEMORY]);
552
553     ret = ui_app_main(argc, argv, &event_callback, &ad);
554     if (APP_ERROR_NONE != ret)
555     {
556         dlog_print(DLOG_ERROR, LOG_TAG, "app_main() is failed. err = %d", ret);
557     }
558
559     return ret;
560 }