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