Merge branch 'master' into extended-easysetup
[platform/upstream/iotivity.git] / service / easy-setup / sampleapp / mediator / linux / richsdk_sample / mediator_cpp.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 <iostream>
22 #include <condition_variable>
23
24 #include "OCPlatform.h"
25 #include "OCApi.h"
26 #include "OCProvisioningManager.h"
27
28 #include "EasySetup.h"
29 #include "ESRichCommon.h"
30
31 #define ES_SAMPLE_APP_TAG "ES_SAMPLE_APP_TAG"
32 #define DECLARE_MENU(FUNC, ...) { #FUNC, FUNC }
33
34 #define JSON_DB_PATH "./oic_svr_db_client.dat"
35
36 using namespace OC;
37 using namespace OIC::Service;
38
39 static std::shared_ptr<RemoteEnrollee> remoteEnrollee = nullptr;
40 static std::shared_ptr<OC::OCResource> curResource = nullptr;
41
42 static std::mutex g_discoverymtx;
43 static std::condition_variable g_cond;
44
45 #define PROV_RESOURCE_TYPE "ocf.wk.prov"
46
47 typedef void (*Runner)();
48
49 Runner g_currentRun;
50
51 int processUserInput(int min = std::numeric_limits<int>::min(),
52         int max = std::numeric_limits<int>::max())
53 {
54     assert(min <= max);
55
56     int input;
57
58     std::cin >> input;
59     std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
60
61     if (!std::cin.fail() && min <= input && input <= max) return input;
62
63     std::cin.clear();
64     std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
65
66     throw std::runtime_error("Invalid Input, please try again");
67 }
68
69 void printConfiguration(EnrolleeConf conf)
70 {
71     cout << "===========================================" << endl;
72     cout << "\tDevice Name : " << conf.getDeviceName() << endl;
73
74     for(auto it : conf.getWiFiModes())
75     {
76         cout << "\tSupported WiFi modes : " << it << endl;
77     }
78
79     cout << "\tSupported WiFi freq : " << static_cast<int>(conf.getWiFiFreq()) << endl;
80     cout << "\tCloud accessibility: " << conf.isCloudAccessible() << endl;
81     cout << "===========================================" << endl;
82 }
83
84 void printStatus(EnrolleeStatus status)
85 {
86     cout << "===========================================" << endl;
87     cout << "\tProvStatus : " << status.getProvStatus() << endl;
88     cout << "\tLastErrCode : " << status.getLastErrCode() << endl;
89     cout << "===========================================" << endl;
90 }
91
92 void provisionSecurityStatusCallback(std::shared_ptr<SecProvisioningStatus> secProvisioningStatus)
93 {
94     if(secProvisioningStatus->getESResult() != ES_OK)
95     {
96       cout << "provisionSecurity is failed." << endl;
97       return;
98     }
99     else
100     {
101       cout << "provisionSecurity is success." << endl;
102       cout << "uuid : " << secProvisioningStatus->getDeviceUUID()<< endl;
103     }
104 }
105
106 void provisionSecurity()
107 {
108     remoteEnrollee->provisionSecurity(provisionSecurityStatusCallback);
109 }
110
111 void getStatusCallback(std::shared_ptr< GetEnrolleeStatus > getEnrolleeStatus)
112 {
113     if(getEnrolleeStatus->getESResult() != ES_OK)
114     {
115       cout << "getStatus is failed." << endl;
116       return;
117     }
118     else
119     {
120       cout << "getStatus is success." << endl;
121       printStatus(getEnrolleeStatus->getEnrolleeStatus());
122     }
123 }
124
125
126 void getStatus()
127 {
128     if(!remoteEnrollee)
129         return;
130
131     try
132     {
133         remoteEnrollee->getStatus(getStatusCallback);
134     }
135     catch (OCException &e)
136     {
137         std::cout << "Exception during getConfiguration call" << e.reason();
138         return;
139     }
140 }
141
142 void getConfigurationCallback(std::shared_ptr< GetConfigurationStatus > getConfigurationStatus)
143 {
144     if(getConfigurationStatus->getESResult() != ES_OK)
145     {
146       cout << "GetConfigurationStatus is failed." << endl;
147       return;
148     }
149     else
150     {
151       cout << "GetConfigurationStatus is success." << endl;
152       printConfiguration(getConfigurationStatus->getEnrolleeConf());
153     }
154 }
155
156 void getConfiguration()
157 {
158     if(!remoteEnrollee)
159         return;
160
161     try
162     {
163         remoteEnrollee->getConfiguration(getConfigurationCallback);
164     }
165     catch (OCException &e)
166     {
167         std::cout << "Exception during getConfiguration call" << e.reason();
168         return;
169     }
170 }
171
172 void deviceProvisioningStatusCallback(std::shared_ptr< DevicePropProvisioningStatus > provStatus)
173 {
174     if(provStatus->getESResult() != ES_OK)
175     {
176       cout << "Device Provisioning is failed." << endl;
177       return;
178     }
179     else
180     {
181       cout << "Device Provisioning is success." << endl;
182     }
183 }
184
185 void provisionDeviceProperty()
186 {
187     if(!remoteEnrollee)
188         return;
189
190     DeviceProp devProp;
191     devProp.setWiFiProp("Iotivity_SSID", "Iotivity_PWD", WPA2_PSK, TKIP_AES);
192     devProp.setDevConfProp("korean", "Korea");
193
194     try
195     {
196         //remoteEnrollee->provisionDeviceProperties(deviceProp, deviceProvisioningStatusCallback);
197         remoteEnrollee->provisionDeviceProperties(devProp, deviceProvisioningStatusCallback);
198     }
199     catch (OCException &e)
200     {
201         std::cout << "Exception during provisionDeviceProperties call" << e.reason();
202         return;
203     }
204 }
205
206 void cloudProvisioningStatusCallback(std::shared_ptr< CloudPropProvisioningStatus > provStatus)
207 {
208     switch (provStatus->getESCloudState())
209     {
210         case ES_CLOUD_PROVISIONING_ERROR:
211             cout << "Cloud Provisioning is failed." << endl;
212             break;
213         case ES_CLOUD_PROVISIONING_SUCCESS:
214             cout << "Cloud Provisioning is success." << endl;
215             break;
216         case ES_CLOUD_ENROLLEE_FOUND:
217             cout << "Enrollee is found in a given network." << endl;
218             break;
219         case ES_CLOUD_ENROLLEE_NOT_FOUND:
220             cout << "Enrollee is not found in a given network." << endl;
221             break;
222     }
223 }
224
225 void provisionCloudProperty()
226 {
227     if(!remoteEnrollee)
228         return;
229
230     CloudProp cloudProp;
231     cloudProp.setCloudProp("authCode", "authProvider", "ciServer");
232     cloudProp.setCloudID("f002ae8b-c42c-40d3-8b8d-1927c17bd1b3");
233
234     try
235     {
236         remoteEnrollee->provisionCloudProperties(cloudProp, cloudProvisioningStatusCallback);
237     }
238     catch (OCException &e)
239     {
240         std::cout << "Exception during provisionCloudProperties call" << e.reason();
241         return;
242     }
243 }
244
245 void DisplayMenu()
246 {
247     constexpr int PROVISION_SECURITY = 1;
248     constexpr int GET_STATUS = 2;
249     constexpr int GET_CONFIGURATION = 3;
250     constexpr int PROVISION_DEVICE_PROPERTY = 4;
251     constexpr int PROVISION_CLOUD_PROPERTY = 5;
252
253     std::cout << "========================================================\n";
254     std::cout << PROVISION_SECURITY << ". Provision Security to Enrollee  \n";
255     std::cout << GET_STATUS << ". Get Status from Enrollee  \n";
256     std::cout << GET_CONFIGURATION << ". Get Configuration from Enrollee  \n";
257     std::cout << PROVISION_DEVICE_PROPERTY << ". Provision Device Property\n";
258     std::cout << PROVISION_CLOUD_PROPERTY << ". Provision Cloud Property  \n";
259     std::cout << "========================================================\n";
260
261     int selection = processUserInput(PROVISION_SECURITY, PROVISION_CLOUD_PROPERTY);
262
263     switch (selection)
264     {
265         case PROVISION_SECURITY:
266             provisionSecurity();
267             break;
268         case GET_STATUS:
269             getStatus();
270             break;
271         case GET_CONFIGURATION:
272             getConfiguration();
273             break;
274         case PROVISION_DEVICE_PROPERTY:
275             provisionDeviceProperty();
276             break;
277         case PROVISION_CLOUD_PROPERTY:
278             provisionCloudProperty();
279             break;
280         default:
281             break;
282     };
283 }
284
285 // Callback to found resources
286 void foundResource(std::shared_ptr<OC::OCResource> resource)
287 {
288     std::string resourceURI;
289     std::string hostAddress;
290     try
291     {
292         // Do some operations with resource object.
293         if(resource &&
294            !curResource &&
295            resource->getResourceTypes().at(0) == PROV_RESOURCE_TYPE)
296         {
297             std::cout<<"DISCOVERED Resource:"<<std::endl;
298             // Get the resource URI
299             resourceURI = resource->uri();
300             std::cout << "\tURI of the resource: " << resourceURI << std::endl;
301
302             // Get the resource host address
303             hostAddress = resource->host();
304             std::cout << "\tHost address of the resource: " << hostAddress << std::endl;
305
306             // Get the resource types
307             std::cout << "\tList of resource types: " << std::endl;
308             for(auto &resourceTypes : resource->getResourceTypes())
309             {
310                 std::cout << "\t\t" << resourceTypes << std::endl;
311             }
312
313             // Get the resource interfaces
314             std::cout << "\tList of resource interfaces: " << std::endl;
315             for(auto &resourceInterfaces : resource->getResourceInterfaces())
316             {
317                 std::cout << "\t\t" << resourceInterfaces << std::endl;
318             }
319
320             if(curResource == nullptr)
321             {
322                 remoteEnrollee = EasySetup::getInstance()->createRemoteEnrollee(resource);
323                 if(!remoteEnrollee)
324                 {
325                     std::cout << "RemoteEnrollee object is failed for some reasons!" << std::endl;
326                 }
327                 else
328                 {
329                     curResource = resource;
330                     std::cout << "RemoteEnrollee object is successfully created!" << std::endl;
331                     g_cond.notify_all();
332                 }
333             }
334         }
335     }
336     catch(std::exception& e)
337     {
338         std::cerr << "Exception in foundResource: "<< e.what() << std::endl;
339     }
340 }
341
342 static FILE* client_open(const char *UNUSED_PARAM, const char *mode)
343 {
344     (void)UNUSED_PARAM;
345     return fopen(JSON_DB_PATH, mode);
346 }
347
348 int main()
349 {
350     std::ostringstream requestURI;
351     OCPersistentStorage ps {client_open, fread, fwrite, fclose, unlink };
352
353     PlatformConfig config
354     {
355         OC::ServiceType::InProc, ModeType::Both, "0.0.0.0", 0, OC::QualityOfService::LowQos, &ps
356     };
357
358     OCPlatform::Configure(config);
359
360 #ifdef __WITH_DTLS__
361     //Initializing the provisioning client stack using the db path provided by the application.
362     OCStackResult result = OCSecure::provisionInit("");
363
364     if (result != OC_STACK_OK)
365     {
366         return -1;
367     }
368 #endif
369
370     try
371     {
372         requestURI << OC_RSRVD_WELL_KNOWN_URI << "?rt=" << PROV_RESOURCE_TYPE;
373
374         OCPlatform::findResource("", requestURI.str(), CT_DEFAULT, &foundResource);
375         std::cout<< "Finding Resource... " <<std::endl;
376
377         std::unique_lock<std::mutex> lck(g_discoverymtx);
378         g_cond.wait_for(lck, std::chrono::seconds(4));
379
380     }catch(OCException& e)
381     {
382         oclog() << "Exception in main: "<<e.what();
383     }
384
385     while (true)
386     {
387         try
388         {
389             DisplayMenu();
390         }
391         catch (const std::exception& e)
392         {
393             std::cout << "Exception caught in main " << e.what() << std::endl;
394         }
395     }
396
397     std::cout << "Stopping the client" << std::endl;
398
399     return 0;
400 }
401