Add getStatus API in RemoteEnrollee to get provisioning resource properties
[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     DeviceConfig devConfig = conf.getDevConf();
73     WiFiConfig wifiConfig = conf.getWiFiConf();
74
75     cout << "\tDeviceConfig.name : " << devConfig.name << endl;
76     cout << "\tDeviceConfig.language : " << devConfig.language << endl;
77     cout << "\tDeviceConfig.country : " << devConfig.country << endl;
78
79     for(auto mode = wifiConfig.modes.begin(); mode != wifiConfig.modes.end(); ++mode)
80     {
81         cout << "\tnetInfo.modes : " << static_cast<int>(*mode) << endl;
82     }
83     cout << "\tnetInfo.freq : " << static_cast<int>(wifiConfig.freq) << endl;
84     cout << "===========================================" << endl;
85 }
86
87 void printStatus(EnrolleeStatus status)
88 {
89     cout << "===========================================" << endl;
90     cout << "\tEnrolleeStatus.provStatus : " << status.provStatus << endl;
91     cout << "\tEnrolleeStatus.lastErrCode : " << status.lastErrCode << endl;
92     cout << "===========================================" << endl;
93 }
94
95 void provisionSecurity()
96 {
97     // TODO
98 }
99
100 void getStatusCallback(std::shared_ptr< GetEnrolleeStatus > getEnrolleeStatus)
101 {
102     if(getEnrolleeStatus->getESResult() != ES_OK)
103     {
104       cout << "getStatus is failed." << endl;
105       return;
106     }
107     else
108     {
109       cout << "getStatus is success." << endl;
110       printStatus(getEnrolleeStatus->getEnrolleeStatus());
111     }
112 }
113
114
115 void getStatus()
116 {
117     if(!remoteEnrollee)
118         return;
119
120     try
121     {
122         remoteEnrollee->getStatus(getStatusCallback);
123     }
124     catch (OCException &e)
125     {
126         std::cout << "Exception during getConfiguration call" << e.reason();
127         return;
128     }
129 }
130
131 void getConfigurationCallback(std::shared_ptr< GetConfigurationStatus > getConfigurationStatus)
132 {
133     if(getConfigurationStatus->getESResult() != ES_OK)
134     {
135       cout << "GetConfigurationStatus is failed." << endl;
136       return;
137     }
138     else
139     {
140       cout << "GetConfigurationStatus is success." << endl;
141       printConfiguration(getConfigurationStatus->getEnrolleeConf());
142     }
143 }
144
145 void getConfiguration()
146 {
147     if(!remoteEnrollee)
148         return;
149
150     try
151     {
152         remoteEnrollee->getConfiguration(getConfigurationCallback);
153     }
154     catch (OCException &e)
155     {
156         std::cout << "Exception during getConfiguration call" << e.reason();
157         return;
158     }
159 }
160
161 void deviceProvisioningStatusCallback(std::shared_ptr< DevicePropProvisioningStatus > provStatus)
162 {
163     if(provStatus->getESResult() != ES_OK)
164     {
165       cout << "Device Provisioning is failed." << endl;
166       return;
167     }
168     else
169     {
170       cout << "Device Provisioning is success." << endl;
171     }
172 }
173
174 void provisionDeviceProperty()
175 {
176     if(!remoteEnrollee)
177         return;
178
179     DeviceProp deviceProp;
180     deviceProp.WIFI.ssid = "Iotivity_SSID";
181     deviceProp.WIFI.pwd = "Iotivity_PWD";
182     deviceProp.WIFI.authtype = WPA2_PSK;
183     deviceProp.WIFI.enctype = TKIP_AES;
184     deviceProp.Device.language = "korean";
185     deviceProp.Device.country = "Korea";
186
187     try
188     {
189         remoteEnrollee->provisionDeviceProperties(deviceProp, deviceProvisioningStatusCallback);
190     }
191     catch (OCException &e)
192     {
193         std::cout << "Exception during provisionDeviceProperties call" << e.reason();
194         return;
195     }
196 }
197
198 void cloudProvisioningStatusCallback(std::shared_ptr< CloudPropProvisioningStatus > provStatus)
199 {
200     switch (provStatus->getESCloudState())
201     {
202         case ES_CLOUD_PROVISIONING_ERROR:
203             cout << "Cloud Provisioning is failed." << endl;
204             break;
205         case ES_CLOUD_PROVISIONING_SUCCESS:
206             cout << "Cloud Provisioning is success." << endl;
207             break;
208         case ES_CLOUD_ENROLLEE_FOUND:
209             cout << "Enrollee is found in a given network." << endl;
210             break;
211         case ES_CLOUD_ENROLLEE_NOT_FOUND:
212             cout << "Enrollee is not found in a given network." << endl;
213             break;
214     }
215 }
216
217 void provisionCloudProperty()
218 {
219     if(!remoteEnrollee)
220         return;
221
222     CloudProp cloudProp;
223     cloudProp.authCode = "authCode";
224     cloudProp.authProvider = "authProvider";
225     cloudProp.ciServer = "ciServer";
226
227     try
228     {
229         remoteEnrollee->provisionCloudProperties(cloudProp, cloudProvisioningStatusCallback);
230     }
231     catch (OCException &e)
232     {
233         std::cout << "Exception during provisionCloudProperties call" << e.reason();
234         return;
235     }
236 }
237
238 void DisplayMenu()
239 {
240     constexpr int PROVISION_SECURITY = 1;
241     constexpr int GET_STATUS = 2;
242     constexpr int GET_CONFIGURATION = 3;
243     constexpr int PROVISION_DEVICE_PROPERTY = 4;
244     constexpr int PROVISION_CLOUD_PROPERTY = 5;
245
246     std::cout << "========================================================\n";
247     std::cout << PROVISION_SECURITY << ". Provision Security to Enrollee  \n";
248     std::cout << GET_STATUS << ". Get Status from Enrollee  \n";
249     std::cout << GET_CONFIGURATION << ". Get Configuration from Enrollee  \n";
250     std::cout << PROVISION_DEVICE_PROPERTY << ". Provision Device Property\n";
251     std::cout << PROVISION_CLOUD_PROPERTY << ". Provision Cloud Property  \n";
252     std::cout << "========================================================\n";
253
254     int selection = processUserInput(PROVISION_SECURITY, PROVISION_CLOUD_PROPERTY);
255
256     switch (selection)
257     {
258         case PROVISION_SECURITY:
259             provisionSecurity();
260             break;
261         case GET_STATUS:
262             getStatus();
263             break;
264         case GET_CONFIGURATION:
265             getConfiguration();
266             break;
267         case PROVISION_DEVICE_PROPERTY:
268             provisionDeviceProperty();
269             break;
270         case PROVISION_CLOUD_PROPERTY:
271             provisionCloudProperty();
272             break;
273         default:
274             break;
275     };
276 }
277
278 // Callback to found resources
279 void foundResource(std::shared_ptr<OC::OCResource> resource)
280 {
281     std::string resourceURI;
282     std::string hostAddress;
283     try
284     {
285         // Do some operations with resource object.
286         if(resource &&
287            !curResource &&
288            resource->getResourceTypes().at(0) == PROV_RESOURCE_TYPE)
289         {
290             std::cout<<"DISCOVERED Resource:"<<std::endl;
291             // Get the resource URI
292             resourceURI = resource->uri();
293             std::cout << "\tURI of the resource: " << resourceURI << std::endl;
294
295             // Get the resource host address
296             hostAddress = resource->host();
297             std::cout << "\tHost address of the resource: " << hostAddress << std::endl;
298
299             // Get the resource types
300             std::cout << "\tList of resource types: " << std::endl;
301             for(auto &resourceTypes : resource->getResourceTypes())
302             {
303                 std::cout << "\t\t" << resourceTypes << std::endl;
304             }
305
306             // Get the resource interfaces
307             std::cout << "\tList of resource interfaces: " << std::endl;
308             for(auto &resourceInterfaces : resource->getResourceInterfaces())
309             {
310                 std::cout << "\t\t" << resourceInterfaces << std::endl;
311             }
312
313             if(curResource == nullptr)
314             {
315                 remoteEnrollee = EasySetup::getInstance()->createRemoteEnrollee(resource);
316                 if(!remoteEnrollee)
317                 {
318                     std::cout << "RemoteEnrollee object is failed for some reasons!" << std::endl;
319                 }
320                 else
321                 {
322                     curResource = resource;
323                     std::cout << "RemoteEnrollee object is successfully created!" << std::endl;
324                     g_cond.notify_all();
325                 }
326             }
327         }
328     }
329     catch(std::exception& e)
330     {
331         std::cerr << "Exception in foundResource: "<< e.what() << std::endl;
332     }
333 }
334
335 static FILE* client_open(const char *UNUSED_PARAM, const char *mode)
336 {
337     (void)UNUSED_PARAM;
338     return fopen(JSON_DB_PATH, mode);
339 }
340
341 int main()
342 {
343     std::ostringstream requestURI;
344     OCPersistentStorage ps {client_open, fread, fwrite, fclose, unlink };
345
346     PlatformConfig config
347     {
348         OC::ServiceType::InProc, ModeType::Both, "0.0.0.0", 0, OC::QualityOfService::LowQos, &ps
349     };
350
351     OCPlatform::Configure(config);
352
353 #ifdef __WITH_DTLS__
354     //Initializing the provisioning client stack using the db path provided by the application.
355     OCStackResult result = OCSecure::provisionInit("");
356
357     if (result != OC_STACK_OK)
358     {
359         return -1;
360     }
361 #endif
362
363     try
364     {
365         requestURI << OC_RSRVD_WELL_KNOWN_URI << "?rt=" << PROV_RESOURCE_TYPE;
366
367         OCPlatform::findResource("", requestURI.str(), CT_DEFAULT, &foundResource);
368         std::cout<< "Finding Resource... " <<std::endl;
369
370         std::unique_lock<std::mutex> lck(g_discoverymtx);
371         g_cond.wait_for(lck, std::chrono::seconds(4));
372
373     }catch(OCException& e)
374     {
375         oclog() << "Exception in main: "<<e.what();
376     }
377
378     while (true)
379     {
380         try
381         {
382             DisplayMenu();
383         }
384         catch (const std::exception& e)
385         {
386             std::cout << "Exception caught in main " << e.what() << std::endl;
387         }
388     }
389
390     std::cout << "Stopping the client" << std::endl;
391
392     return 0;
393 }
394