Initial version
[platform/core/service/cloud/ua-client.git] / src / ua_client.cpp
1 #include <memory>
2 #include <iostream>
3 #include <stdexcept>
4 #include <condition_variable>
5 #include <map>
6 #include <vector>
7 #include <string>
8 #include <unistd.h>
9 #include <mutex>
10 #include <glib.h>
11 #include <signal.h>
12 #include <pthread.h>
13 #include <gio/gio.h>
14
15 #include "ocstack.h"
16 #include "ocpayload.h"
17 #include "RDClient.h"
18 #include "logger.h"
19
20 #include "OCApi.h"
21 #include "OCPlatform.h"
22
23 #include <wifi.h>
24
25
26 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
27 #include "ocprovisioningmanager.h"
28 #include "mbedtls/ssl_ciphersuites.h"
29 #include "byte_array.h"
30 #include <ca_adapter_net_ssl.h>
31 #endif // WITH_DTLS__ or __WITH_TLS__
32
33 #include "ua_client.h"
34
35 #define OC_SECURITY_DB_DAT_FILE_NAME            "oic_svr_db.dat"
36 #define OC_RSRVD_PROTOCOL_INDEPENDENT_ID        "piid"
37 #define OC_CONTROLEE_DATA_FILE_PATH                     "/opt/usr/data/ua_client/"
38 #define OC_CONTROLEE_DB_DAT_FILE_NAME           ".firmware_controlee.dat"
39
40 #define UA_OCF_SERVER_URL                       "13.124.29.169:5683"
41 #define UA_CONTENTS_SERVER_URL          "http://13.124.95.191:8000"
42
43 using namespace OC;
44 using namespace std;
45
46 static GMainLoop* mainloop = NULL;
47
48 string              g_host;
49
50 condition_variable g_callbackLock;
51 string             g_uid;
52 string             g_accesstoken;
53
54 static void _set_device_info(const char *key, const char *value);
55 static void _get_device_info(ua_device_info_s *device);
56 static void _exec_update();
57
58 class Resource
59 {
60     public:
61         OCResourceHandle m_handle;
62         Resource(string uri, vector<string> rt, vector<string> itf)
63         {
64             m_representation.setUri(uri);
65             m_representation.setResourceTypes(rt);
66             m_representation.setResourceInterfaces(itf);
67         }
68
69         string getResourceUri()
70         {
71             return m_representation.getUri();
72         }
73
74         vector<string> getResourceType()
75         {
76             return m_representation.getResourceTypes();
77         }
78
79         vector<string> getInterfaces()
80         {
81             return m_representation.getResourceInterfaces();
82         }
83
84         OCRepresentation getRepresentation(void)
85         {
86             m_representation.clearChildren();
87             for (auto it = m_childResources.begin(); it != m_childResources.end(); it++)
88             {
89                 m_representation.addChild((*it)->getRepresentation());
90             }
91             return m_representation;
92         }
93
94         OCStackResult addChildResource(Resource  *childResource)
95         {
96             m_childResources.push_back(childResource);
97             return OCPlatform::bindResource(m_handle, childResource->m_handle);
98         }
99
100         OCStackResult sendRepresentation(shared_ptr<OCResourceRequest> pRequest)
101         {
102             auto pResponse = make_shared<OC::OCResourceResponse>();
103             pResponse->setRequestHandle(pRequest->getRequestHandle());
104             pResponse->setResourceHandle(pRequest->getResourceHandle());
105
106             // Check for query params (if any)
107             QueryParamsMap queryParamsMap = pRequest->getQueryParameters();
108
109             UA_LOG("\tquery params:");
110             for (auto it = queryParamsMap.begin(); it != queryParamsMap.end(); it++)
111             {
112 //                UA_LOG("\t\t%s : %s", query1, query2);
113             }
114
115             auto findRes = queryParamsMap.find("if");
116
117             if (findRes != queryParamsMap.end())
118             {
119                 pResponse->setResourceRepresentation(getRepresentation(), findRes->second);
120             }
121             else
122             {
123                 pResponse->setResourceRepresentation(getRepresentation(), DEFAULT_INTERFACE);
124             }
125
126             pResponse->setResponseResult(OC_EH_OK);
127
128             return OCPlatform::sendResponse(pResponse);
129         }
130
131         OCStackResult propagate()
132         {
133             if (m_interestedObservers.size() > 0)
134             {
135                 shared_ptr<OCResourceResponse> resourceResponse =
136                 { make_shared<OCResourceResponse>() };
137
138                 resourceResponse->setResourceRepresentation(getRepresentation(), DEFAULT_INTERFACE);
139
140                 return OCPlatform::notifyListOfObservers(m_handle,
141                         m_interestedObservers,
142                         resourceResponse);
143             }
144
145             return OC_STACK_OK;
146         }
147
148         virtual OCEntityHandlerResult entityHandler(shared_ptr<OCResourceRequest> request) = 0;
149
150     protected:
151         OCRepresentation    m_representation;
152         vector<Resource *>  m_childResources;
153         ObservationIds      m_interestedObservers;
154 };
155
156
157 class FirmwareResource : public Resource // x.samsung.firmware
158 {
159     private:
160         string  m_currentversion;
161         int     m_state;    //0: Idle, 1: Downloading, 2: Downloaded, 3: Updating
162         int     m_result;   //0: Initial, 1: success, 2: not enough space, 3: out of ram, 4: connection lost, 5: invalid binary, 6: invalid uri, 7: update failed, 8: unsupport protocol
163         string  m_packageuri;
164         string  m_newversion;
165
166         int m_update; // 0: initial value  1: download , 2: upgrade, 3: auto
167
168         char szState[2] = {0,};
169
170     public:
171         FirmwareResource(string uri, vector<string> rt, vector<string> itf, string cur_ver, string new_ver, string url, int update_state)
172             : Resource(uri, rt, itf)
173         {
174             m_currentversion = cur_ver;
175             update_state == 3 ? m_state = 0 : m_state = update_state;
176             m_result = 0;
177             m_packageuri = url;
178             m_newversion = new_ver;
179             m_update = 0;
180
181             m_representation.setValue<string>("currentversion", m_currentversion);
182             m_representation.setValue<int>("state", m_state);
183             m_representation.setValue<int>("result", m_result);
184
185             m_representation.setValue<string>("packageuri", m_packageuri);
186             m_representation.setValue<string>("newversion", m_newversion);
187             m_representation.setValue<int>("update", m_update);
188         }
189
190         void onUpdateFirmware()
191         {
192                 UA_LOG("onUpdateFirmware() called");
193                 if ((m_state == 0 && m_update == 1) || (m_state == 0 && m_update == 3)) {
194                                 UA_LOG("currentversion [%s]", m_currentversion.c_str());
195                                 UA_LOG("newversion [%s]", m_newversion.c_str());
196
197                                 if(g_strcmp0(m_currentversion.c_str(), m_newversion.c_str()) == 0 ||
198                                         g_strcmp0(m_newversion.c_str(), "") == 0) {
199                                         UA_LOG("no need for update cur=[%s], new=[%s]", m_currentversion.c_str(), m_newversion.c_str());
200                                         return;
201                                 }
202
203                                 UA_LOG("***Downloading image from [%s] ***", m_packageuri.c_str());
204                                 //Downloading, Initial
205                                 m_state = 1;
206                                 m_representation.setValue<int>("state", m_state);
207                                 m_representation.setValue<int>("result", 0);
208                                 propagate();
209
210                                 snprintf(szState, sizeof(szState), "%d", m_state);
211                                 _set_device_info("firmware_update_state", szState);
212
213                                 if (ua_http_download_file(m_packageuri.c_str()) != 0) {
214                                         UA_LOG("ua_http_download_file() is failed");
215                                         m_state = 0;
216                                         m_representation.setValue<int>("state", m_state);
217                                         snprintf(szState, sizeof(szState), "%d", m_state);
218                                         _set_device_info("firmware_update_state", szState);
219                                         return;
220                                 }
221
222                                 UA_LOG("***Firmware Image downloaded***");
223                                 //Downloaded
224                                 m_state = 2;
225                                 m_representation.setValue<int>("state", m_state);
226                                 propagate();
227
228                                 snprintf(szState, sizeof(szState), "%d", m_state);
229                                 _set_device_info("firmware_update_state", szState);
230                 }
231
232             if ((m_state == 2 && m_update == 2) || (m_state == 2 && m_update == 3)) {
233                                 //Updating
234                 m_state = 3;
235                                 m_representation.setValue<int>("state", m_update);
236                                 propagate();
237
238                                 snprintf(szState, sizeof(szState), "%d", m_state);
239                                 _set_device_info("firmware_update_state", szState);
240
241                     //After Upgrade, state = Idle
242                                 m_state = 0;
243                     m_representation.setValue<int>("state", m_state);
244                     m_representation.setValue<int>("result", 1);
245
246                     m_newversion = m_representation.getValue<string>("newversion");
247                     m_currentversion = m_representation.getValue<string>("currentversion");
248
249                     UA_LOG("*** Update completed from %s to %s ***", m_currentversion.c_str(), m_newversion.c_str());
250
251                     m_representation.setValue<string>("currentversion", m_newversion);
252                     m_representation.setValue<string>("newversion", "");
253                     m_representation.setValue<string>("packageuri", "");
254                                 m_currentversion = m_newversion;
255                                 m_newversion ="";
256                                 m_packageuri ="";
257                     propagate();
258
259                                 snprintf(szState, sizeof(szState), "%d", m_state);
260                                 _set_device_info("firmware_update_state", szState);
261
262                                 _set_device_info("firmware_ver", m_currentversion.c_str());
263
264                                 _exec_update();
265
266             }
267         }
268
269         static void *_worker(void *pArg)
270         {
271             FirmwareResource *pThread = (FirmwareResource *)pArg;
272             pThread->onUpdateFirmware();
273             return NULL;
274         }
275
276         void setFirmwareRepresentation(OCRepresentation &rep)
277         {
278                 UA_LOG("");
279             bool hasUpdates = false;
280                         string tmpStr;
281                         int tmpUpdate;
282             if (rep.getValue<string>("packageuri", tmpStr))
283             {
284                 m_packageuri = tmpStr;
285                 UA_LOG("\tpackageuri: %s", m_packageuri.c_str());
286                 m_representation.setValue<string>("packageuri", m_packageuri);
287                 hasUpdates = true;
288             }
289             if (rep.getValue<string>("newversion", tmpStr))
290             {
291                 m_newversion = tmpStr;
292                 UA_LOG("\tnewversion: %s", m_newversion.c_str());
293                 m_representation.setValue<string>("newversion", m_newversion);
294                 hasUpdates = true;
295             }
296
297 //            if (rep.getValue<int>("updatemethod", m_updatemethod))
298 //            {
299 //                UA_LOG("\t\t\t\t updatemethod: %d", m_updatemethod);
300 //                m_representation.setValue<int>("updatemethod", m_updatemethod);
301 //                hasUpdates = true;
302 //            }
303
304             if (rep.getValue<int>("update", tmpUpdate))
305             {
306                 m_update = tmpUpdate;
307                 UA_LOG("\tupdate: %d", m_update);
308                 hasUpdates = true;
309
310                                 pthread_t hThread;
311                                 //Start temp thread to manage update simulator
312                                 pthread_create(&hThread, NULL, (void *(*)(void *))_worker, (void *)this);
313             }
314
315             if (hasUpdates)
316             {
317                 propagate();
318             }
319         }
320
321         OCEntityHandlerResult entityHandler(shared_ptr<OCResourceRequest> request)
322         {
323             UA_LOG("\tIn Server Firmware entity handler:");
324             OCEntityHandlerResult ehResult = OC_EH_ERROR;
325
326             if (request)
327             {
328                 // Get the request type and request flag
329                 string requestType = request->getRequestType();
330                 int requestFlag = request->getRequestHandlerFlag();
331
332                 if (requestFlag & RequestHandlerFlag::RequestFlag)
333                 {
334                     UA_LOG("\trequestFlag : Request");
335
336                     // If the request type is GET
337                     if (requestType == "GET")
338                     {
339                         UA_LOG("\trequestType : GET");
340                         if (OC_STACK_OK == sendRepresentation(request))
341                         {
342                             ehResult = OC_EH_OK;
343                         }
344                     }
345                     else if (requestType == "PUT")
346                     {
347                         UA_LOG("\ttrequestType : PUT");
348                         // PUT requeist operations
349                     }
350                     else if (requestType == "POST")
351                     {
352                         UA_LOG("\trequestType : POST");
353                         // POST request operations
354                         OCRepresentation    rep = request->getResourceRepresentation();
355                         setFirmwareRepresentation(rep);
356
357                         if (OC_STACK_OK == sendRepresentation(request))
358                         {
359                             ehResult = OC_EH_OK;
360                         }
361                     }
362                     else if (requestType == "DELETE")
363                     {
364                         UA_LOG("\trequestType : DELETE");
365                         // DELETE request operations
366                     }
367                 }
368
369                 if (requestFlag & RequestHandlerFlag::ObserverFlag)
370                 {
371                     UA_LOG("\trequestFlag : Observer");
372
373                     ObservationInfo observationInfo = request->getObservationInfo();
374                     if (ObserveAction::ObserveRegister == observationInfo.action)
375                     {
376                         m_interestedObservers.push_back(observationInfo.obsId);
377                     }
378                     else if (ObserveAction::ObserveUnregister == observationInfo.action)
379                     {
380                         m_interestedObservers.erase(remove(
381                                                         m_interestedObservers.begin(),
382                                                         m_interestedObservers.end(),
383                                                         observationInfo.obsId),
384                                                         m_interestedObservers.end());
385                     }
386                 }
387             }
388             else
389             {
390                 UA_LOG("Request invalid");
391             }
392
393             return ehResult;
394         }
395 };
396
397 #define UPDATE_FILE "/opt/usr/data/fota/init_tota"
398
399 static void _exec_update()
400 {
401         FILE* fp = fopen(UPDATE_FILE, "w");
402         if(!fp) {
403                 UA_LOG("fopen error: %d", errno);
404         }
405         fclose(fp);
406 }
407
408 #if 0
409 static void _exec_update()
410 {
411         UA_LOG("");
412         GError *gerror = NULL;
413
414 #if !GLIB_CHECK_VERSION(2, 36, 0)
415         g_type_init();
416 #endif
417
418         GCancellable *proxy_cancel = g_cancellable_new();
419         GDBusProxy* bproxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
420                                     G_DBUS_PROXY_FLAGS_NONE,
421                                     NULL,
422                                     "org.tizen.system.tota",
423                                     "/Org/Tizen/System/Tota",
424                                     "org.tizen.system.tota",
425                                     proxy_cancel,
426                                     &gerror);
427
428         if (!bproxy) {
429                 UA_LOG ("g_dbus_proxy_new_for_bus_sync error [%s]", gerror->message);
430                 if (bproxy)
431                         g_object_unref (bproxy);
432                 if (proxy_cancel)
433                         g_object_unref(proxy_cancel);
434                 if (gerror)
435                         g_error_free (gerror);
436                 return;
437         }
438
439         GVariant *result = g_dbus_proxy_call_sync (bproxy,
440                         NULL,
441                         NULL,
442                         G_DBUS_CALL_FLAGS_NONE,
443                         -1,  /* msec, 5s*/
444                         NULL,
445                         &gerror);
446
447
448         if (!result) {
449                 UA_LOG ("g_dbus_proxy_call_sync error [%s]", gerror->message);
450                 if (bproxy)
451                         g_object_unref (bproxy);
452
453                 if (proxy_cancel)
454                         g_object_unref(proxy_cancel);
455
456                 if (gerror)
457                         g_error_free (gerror);
458                 return;
459         }
460
461
462         UA_LOG ("success");
463         if (bproxy)
464                 g_object_unref (bproxy);
465
466         if (proxy_cancel)
467                 g_object_unref(proxy_cancel);
468
469         if (gerror)
470                 g_error_free (gerror);
471 }
472 #endif
473
474 static void _set_device_info(const char *key, const char *value)
475 {
476         UA_LOG("_set_device_info() key = %s, value = %s", key, value);
477         GKeyFile *keyfile;
478         GKeyFileFlags flags = G_KEY_FILE_NONE;
479         GError *error = NULL;
480         char file_path[256] = {0,};
481
482         keyfile = g_key_file_new();
483
484         snprintf(file_path, sizeof(file_path), "%s/%s", OC_CONTROLEE_DATA_FILE_PATH, "device_info.ini");
485
486         if (!g_key_file_load_from_file(keyfile, file_path, flags, &error)) {
487                 UA_LOG("error=[%s]", error->message);
488         } else {
489                 g_key_file_set_string(keyfile, "device_info", key, value);
490                 g_key_file_save_to_file(keyfile, file_path, NULL);
491                 g_key_file_unref(keyfile);
492         }
493 }
494
495
496 static void _get_device_info(ua_device_info_s *device)
497 {
498         GKeyFile *keyfile;
499         GKeyFileFlags flags = G_KEY_FILE_NONE;
500         GError *error = NULL;
501         char file_path[256] = {0,};
502
503         keyfile = g_key_file_new();
504
505         snprintf(file_path, sizeof(file_path), "%s/%s", OC_CONTROLEE_DATA_FILE_PATH, "device_info.ini");
506
507         // wait for /opt/ mount
508         do {
509                 sleep(5);
510         } while(!g_key_file_load_from_file(keyfile, file_path, flags, &error));
511
512         if (!g_key_file_load_from_file(keyfile, file_path, flags, &error)) {
513                 UA_LOG("error=[%s]", error->message);
514         } else {
515
516                 device->manufacturer = g_key_file_get_string(keyfile, "device_info", "manufacturer", NULL);
517                 device->model_name = g_key_file_get_string(keyfile, "device_info", "model_name", NULL);
518                 device->firmware_ver = g_key_file_get_string(keyfile, "device_info", "firmware_ver", NULL);
519                 device->firmware_update_state = g_key_file_get_string(keyfile, "device_info", "firmware_update_state", NULL);
520                 device->uuid = g_key_file_get_string(keyfile, "device_info", "uuid", NULL);
521                 device->access_token = g_key_file_get_string(keyfile, "device_info", "access_token", NULL);
522
523                 g_key_file_unref(keyfile);
524         }
525
526         UA_LOG("manufacturer=[%s]", device->manufacturer);
527         UA_LOG("model_name=[%s]", device->model_name);
528         UA_LOG("firmware_ver=[%s]", device->firmware_ver);
529         UA_LOG("firmware_update_state=[%s]", device->firmware_update_state);
530         UA_LOG("uuid=[%s]", device->uuid);
531         UA_LOG("access_token=[%s]", device->access_token);
532 }
533
534 void onPublish(const OCRepresentation &, const int &eCode)
535 {
536     UA_LOG("Publish resource response received, code: %d", eCode);
537
538     g_callbackLock.notify_all();
539 }
540
541 void printRepresentation(OCRepresentation rep)
542 {
543     for (auto itr = rep.begin(); itr != rep.end(); ++itr)
544     {
545         UA_LOG("\t%s:\t%s", (itr->attrname()).c_str(), (itr->getValueToString()).c_str());
546         if (itr->type() == AttributeType::Vector)
547         {
548             switch (itr->base_type())
549             {
550                 case AttributeType::OCRepresentation:
551                     for (auto itr2 : (*itr).getValue<vector<OCRepresentation> >())
552                     {
553                         printRepresentation(itr2);
554                     }
555                     break;
556
557                 case AttributeType::Integer:
558                     for (auto itr2 : (*itr).getValue<vector<int> >())
559                     {
560                         UA_LOG("\t\t%d", itr2);
561                     }
562                     break;
563
564                 case AttributeType::String:
565                     for (auto itr2 : (*itr).getValue<vector<string> >())
566                     {
567                         UA_LOG("\t\t%s", itr2.c_str());
568                     }
569                     break;
570
571                 default:
572                     UA_LOG("Unhandled base type = %d" , itr->base_type());
573                     break;
574             }
575         }
576         else if (itr->type() == AttributeType::OCRepresentation)
577         {
578             printRepresentation((*itr).getValue<OCRepresentation>());
579         }
580     }
581 }
582
583 void handleSignupCB(const HeaderOptions &,
584                       const OCRepresentation &rep, const int ecode)
585 {
586     UA_LOG("Auth response received code: %d", ecode);
587
588     if (rep.getPayload() != NULL)
589     {
590         printRepresentation(rep);
591     }
592
593     if (ecode == 4)
594     {
595         g_accesstoken = rep.getValueToString("accesstoken");
596         g_uid = rep.getValueToString("uid");
597
598         _set_device_info("uuid", g_uid.c_str());
599         _set_device_info("access_token", g_accesstoken.c_str());
600     }
601
602     g_callbackLock.notify_all();
603 }
604
605
606 void handleSigninCB(const HeaderOptions &,
607                       const OCRepresentation &rep, const int ecode)
608 {
609     UA_LOG("Auth response received code: %d", ecode);
610
611     if (rep.getPayload() != NULL)
612     {
613         printRepresentation(rep);
614     }
615
616     g_callbackLock.notify_all();
617 }
618
619 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
620 int saveTrustCert(void)
621 {
622     OCStackResult res = OC_STACK_ERROR;
623     uint16_t g_credId = 0;
624
625     UA_LOG("Save Trust Cert. Chain into Cred of SVR");
626
627     ByteArray trustCertChainArray = {0, 0};
628
629     FILE *fp = fopen("rootca.crt", "rb+");
630
631     if (fp)
632     {
633         size_t fsize;
634         if (fseeko(fp, 0, SEEK_END) == 0 && (fsize = ftello(fp)) > 0)
635         {
636             trustCertChainArray.data = (uint8_t *)malloc(fsize);
637             trustCertChainArray.len = fsize;
638             if (NULL == trustCertChainArray.data)
639             {
640                 UA_LOG("Failed to allocate memory");
641                 fclose(fp);
642                 return res;
643             }
644             rewind(fp);
645             if (fsize != fread(trustCertChainArray.data, 1, fsize, fp))
646             {
647                 UA_LOG("Certiface not read completely");
648             }
649             fclose(fp);
650         }
651     }
652
653     res = OCSaveTrustCertChain(trustCertChainArray.data, trustCertChainArray.len, OIC_ENCODING_PEM,
654                                &g_credId);
655
656     if (OC_STACK_OK != res)
657     {
658         UA_LOG("OCSaveTrustCertChainBin API error");
659         return res;
660     }
661     UA_LOG("CredId of Saved Trust Cert. Chain into Cred of SVR : %d", g_credId);
662
663     return res;
664 }
665 #endif
666
667 static FILE *client_open(const char *path, const char *mode)
668 {
669     if (0 == strcmp(path, OC_SECURITY_DB_DAT_FILE_NAME))
670     {
671         char *file_path = g_strconcat(OC_CONTROLEE_DATA_FILE_PATH, OC_CONTROLEE_DB_DAT_FILE_NAME, NULL);
672         FILE *fp = fopen(file_path, mode);
673         g_free(file_path);
674         return fp;
675     }
676     else
677     {
678         return fopen(path, mode);
679     }
680 }
681
682 OCStackResult SetDeviceInfo()
683 {
684     OCStackResult result = OC_STACK_ERROR;
685
686     OCResourceHandle handle = OCGetResourceHandleAtUri(OC_RSRVD_DEVICE_URI);
687
688     if (handle == NULL)
689     {
690         UA_LOG("Failed to find resource [%s]", OC_RSRVD_DEVICE_URI);
691         return result;
692     }
693
694     //result = OCBindResourceTypeToResource(handle, "oic.d.airconditioner");
695     result = OCBindResourceTypeToResource(handle, "x.tizen.ri3");
696
697     if (result != OC_STACK_OK)
698     {
699         UA_LOG("Failed to add device type");
700         return result;
701     }
702
703     result = OCPlatform::setPropertyValue(PAYLOAD_TYPE_DEVICE, OC_RSRVD_DEVICE_NAME, "TIZEN_RI3");
704
705     if (result != OC_STACK_OK)
706     {
707         UA_LOG("Failed to set device name");
708         return result;
709     }
710
711     result = OCPlatform::setPropertyValue(PAYLOAD_TYPE_DEVICE, OC_RSRVD_PROTOCOL_INDEPENDENT_ID,
712                                           "d7d2b492-83ac-4783-9dcc-b1b54587ebed");
713
714     if (result != OC_STACK_OK)
715     {
716         UA_LOG("Failed to set piid");
717         return result;
718     }
719
720     return OC_STACK_OK;
721 }
722
723 //#include <wifi.h>
724 #include <net_connection.h>
725
726 connection_cellular_state_e get_cellular_network_state()
727 {
728         connection_h connection;
729         connection_create(&connection);
730
731         connection_cellular_state_e cellular_state;
732         connection_get_cellular_state(connection, &cellular_state);
733         connection_destroy(connection);
734
735         return cellular_state;
736 }
737
738 connection_wifi_state_e get_wifi_network_state()
739 {
740         connection_h connection;
741         connection_create(&connection);
742
743         connection_wifi_state_e wifi_state;
744         connection_get_wifi_state(connection, &wifi_state);
745         connection_destroy(connection);
746
747         return wifi_state;
748 }
749
750
751 int is_network_connected()
752 {
753         //cellular
754         int network_state = 0;
755
756         if (get_cellular_network_state() == CONNECTION_CELLULAR_STATE_CONNECTED)
757         {
758                 network_state = true;
759         }
760
761         // ethernet
762         if (get_wifi_network_state() == CONNECTION_ETHERNET_STATE_CONNECTED)
763         {
764                 network_state = true;
765         }
766
767         //wifi
768         if (get_wifi_network_state() == CONNECTION_WIFI_STATE_CONNECTED)
769         {
770                 network_state = true;
771         }
772
773         return network_state;
774 }
775
776
777 void *_start_ua_client(void *data)
778 {
779         UA_LOG("");
780
781         ua_device_info_s *device =  (ua_device_info_s *)data;
782
783     mutex blocker;
784     unique_lock<mutex> lock(blocker);
785
786     UA_LOG("Registering firmware resources to platform...");
787
788         OCStackResult result = OC_STACK_ERROR;
789         string uri;
790         string rt;
791         string itf;
792
793 #if 1
794         /* Check new firmware version at content server */
795         char *http_url = g_strconcat(UA_CONTENTS_SERVER_URL, "/firmware", "?manufacturer=", device->manufacturer, "&model=", device->model_name, \
796                                                                 "&version=", device->firmware_ver, NULL);
797
798         char *httr_res_header = NULL;
799         char *httr_res_body = NULL;
800
801         char *old_ver = NULL;
802         char *new_ver = NULL;
803         char *download_url = NULL;
804         char *priority = NULL;
805
806         if (ua_http_send_request(UA_HTTP_GET, http_url, &httr_res_header, &httr_res_body) != 0) {
807                 UA_LOG("ua_http_send_request() is failed");
808         }
809
810         if (httr_res_body) {
811                 ua_json_parser_firmware_info(httr_res_body, &old_ver, &new_ver, &download_url, &priority);
812         }
813
814         UA_LOG("firm_ver: %s , new_ver: %s", device->firmware_ver, new_ver);
815
816         string cur_firmware_ver((device->firmware_ver)?device->firmware_ver:"");
817         string new_firmware_ver((new_ver)?new_ver:"");
818         string new_url((download_url)?download_url:"");
819
820         UA_LOG("device->firmware_update_state: %s", device->firmware_update_state);
821         FirmwareResource     firmware("/firmware", { "x.samsung.firmware" }, { DEFAULT_INTERFACE }, \
822                                                                         cur_firmware_ver, new_firmware_ver, new_url, atoi(device->firmware_update_state));
823
824 #else
825         string cur_firmware_ver(device->firmware_ver);
826         string new_firmware_ver("");
827
828         FirmwareResource     firmware("/firmware", { "x.samsung.firmware" }, { DEFAULT_INTERFACE }, \
829                                                                         cur_firmware_ver, new_firmware_ver, atoi(device->firmware_update_state));
830
831 #endif
832         uri = firmware.getResourceUri();
833         rt = firmware.getResourceType()[0];
834         itf = firmware.getInterfaces()[0];
835
836         // Time to Live is 30 seconds
837         OCPlatform::startPresence(30);
838
839         result = OCPlatform::registerResource(firmware.m_handle,
840                                                                            uri,
841                                                                            rt,
842                                                                            itf,
843                                                                            bind(&FirmwareResource::entityHandler,
844                                                                                         &firmware, placeholders::_1),
845                                                                                 OC_DISCOVERABLE | OC_OBSERVABLE);
846
847         UA_LOG("registerResource firmware: result = %d", result);
848         if (result != OC_STACK_OK) {
849                 UA_LOG("Resource registration was unsuccessful, [%d]", result);
850                 return NULL;
851         }
852
853         UA_LOG("Publishing resources to cloud");
854
855         result = SetDeviceInfo();
856         if (result != OC_STACK_OK) {
857                 UA_LOG("SetDeviceInfo() is failed, [%d]", result);
858                 return NULL;
859         }
860
861         OCPlatform::stopPresence();
862
863         ResourceHandles resourceHandles;
864
865         result = RDClient::Instance().publishResourceToRD(g_host, OCConnectivityType::CT_ADAPTER_TCP,
866                   resourceHandles,
867                   &onPublish);
868
869         UA_LOG(" result: %d, Waiting Publish default resource response from cloud", result);
870
871         resourceHandles.push_back(firmware.m_handle);
872
873         result = RDClient::Instance().publishResourceToRD(g_host, OCConnectivityType::CT_ADAPTER_TCP,
874                   resourceHandles,
875                   &onPublish);
876
877         UA_LOG(" result: %d, Waiting Publish user resource response from cloud", result);
878
879         g_callbackLock.wait(lock);
880
881         while(true) {
882                 // Running....
883         }
884
885         return NULL;
886 }
887
888
889 int main(int argc, char *argv[])
890 {
891 #if !GLIB_CHECK_VERSION(2, 31, 0)
892     g_thread_init(NULL);
893 #endif
894
895 #if !GLIB_CHECK_VERSION(2, 36, 0)
896     g_type_init();
897 #endif
898
899     signal(SIGCHLD, SIG_IGN);
900         signal(SIGINT, SIG_IGN);
901         signal(SIGPIPE, SIG_IGN);
902
903
904         GThread *main_thd = NULL;
905
906     mutex blocker;
907     unique_lock<mutex> lock(blocker);
908
909
910     OCPersistentStorage ps{ client_open, fread, fwrite, fclose, unlink };
911
912     PlatformConfig cfg
913     {
914         ServiceType::InProc,
915         ModeType::Both,
916         "0.0.0.0", // By setting to "0.0.0.0", it binds to all available interfaces
917         0,         // Uses randomly available port
918         QualityOfService::LowQos,
919         &ps
920     };
921
922     OCPlatform::Configure(cfg);
923
924     g_host = "coap+tcp://";
925
926 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
927     g_host = "coaps+tcp://";
928 #endif
929
930
931 #if 0
932     g_host += argv[1];
933 #else
934     string ocf_server_url(UA_OCF_SERVER_URL);
935     g_host += ocf_server_url;
936
937     ua_device_info_s *device = (ua_device_info_s *)calloc(1, sizeof(ua_device_info_s));
938
939     _get_device_info(device);
940 #endif
941     UA_LOG("host address = %s", g_host.c_str());
942
943     OCAccountManager::Ptr accountMgr = OCPlatform::constructAccountManagerObject(g_host,
944                                        CT_ADAPTER_TCP);
945
946
947 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
948     UA_LOG("Security Mode");
949     if (CA_STATUS_OK != saveTrustCert())
950     {
951         UA_LOG("saveTrustCert returned an error");
952     }
953
954     uint16_t cipher = MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256;
955     if (CA_STATUS_OK != CASelectCipherSuite(cipher, CA_ADAPTER_TCP))
956     {
957         UA_LOG("CASelectCipherSuite returned an error");
958     }
959 #endif
960
961         // wait for network connection
962         while(is_network_connected() == 0){
963                 UA_LOG("network not ready");
964                 sleep(5);
965         }
966
967     try {
968         if (device->uuid == NULL || (device->uuid && strlen(device->uuid) == 0)) {
969             if (argc != 3)
970             {
971                         fprintf(stderr, "\n\nPut \"[authprovider] [authcode]\" for sign-up and sign-in and publish resources!!\n\n");
972                         return 0;
973             }
974                         UA_LOG("Sign-up...");
975                         accountMgr->signUp(argv[1], argv[2], &handleSignupCB);
976                         g_callbackLock.wait(lock);
977                         UA_LOG("Sign-In...");
978                         accountMgr->signIn(g_uid, g_accesstoken, &handleSigninCB);
979                         g_callbackLock.wait(lock);
980         } else {
981                 UA_LOG("Sign-In...");
982                 string uuid(device->uuid);
983                 string access_token(device->access_token);
984                         accountMgr->signIn(uuid, access_token, &handleSigninCB);
985                         g_callbackLock.wait(lock);
986         }
987     }
988     catch (exception& e){
989         UA_LOG("Authentication failed");
990         goto _END_OF_PROC;
991     }
992
993         main_thd = g_thread_new("ua_client", _start_ua_client, (void *)device);
994         if (main_thd == NULL) {
995                 UA_LOG("Fail to run main thread");
996         }
997
998     mainloop = g_main_loop_new(NULL, FALSE);
999
1000     if (mainloop != NULL) {
1001         UA_LOG("Start ua_client");
1002         g_main_loop_run(mainloop);
1003     } else {
1004         UA_LOG("Fail to start ua_client");
1005     }
1006
1007
1008 _END_OF_PROC:
1009         g_free(device->manufacturer);
1010         g_free(device->model_name);
1011         g_free(device->firmware_ver);
1012         g_free(device->firmware_update_state);
1013         g_free(device->uuid);
1014         g_free(device->access_token);
1015         g_free(device);
1016
1017
1018         return 0;
1019 }