1 //******************************************************************
3 // Copyright 2015 Samsung Electronics All Rights Reserved.
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
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
11 // http://www.apache.org/licenses/LICENSE-2.0
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.
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
22 #include <condition_variable>
24 #include "OCPlatform.h"
26 #include "OCProvisioningManager.h"
28 #include "EasySetup.h"
29 #include "ESRichCommon.h"
31 #define ES_SAMPLE_APP_TAG "ES_SAMPLE_APP_TAG"
32 #define DECLARE_MENU(FUNC, ...) { #FUNC, FUNC }
34 #define JSON_DB_PATH "./oic_svr_db_client.dat"
37 using namespace OIC::Service;
39 static std::shared_ptr<RemoteEnrollee> remoteEnrollee = nullptr;
40 static std::shared_ptr<OC::OCResource> curResource = nullptr;
42 static std::mutex g_discoverymtx;
43 static std::condition_variable g_cond;
45 #define PROV_RESOURCE_TYPE "ocf.wk.prov"
47 typedef void (*Runner)();
51 int processUserInput(int min = std::numeric_limits<int>::min(),
52 int max = std::numeric_limits<int>::max())
59 std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
61 if (!std::cin.fail() && min <= input && input <= max) return input;
64 std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
66 throw std::runtime_error("Invalid Input, please try again");
69 void printConfiguration(EnrolleeConf conf)
71 cout << "===========================================" << endl;
72 DeviceConfig devConfig = conf.getDevConf();
73 WiFiConfig wifiConfig = conf.getWiFiConf();
75 cout << "\tDeviceConfig.name : " << devConfig.name << endl;
76 cout << "\tDeviceConfig.language : " << devConfig.language << endl;
77 cout << "\tDeviceConfig.country : " << devConfig.country << endl;
79 for(auto mode = wifiConfig.modes.begin(); mode != wifiConfig.modes.end(); ++mode)
81 cout << "\tnetInfo.modes : " << static_cast<int>(*mode) << endl;
83 cout << "\tnetInfo.freq : " << static_cast<int>(wifiConfig.freq) << endl;
84 cout << "===========================================" << endl;
87 void printStatus(EnrolleeStatus status)
89 cout << "===========================================" << endl;
90 cout << "\tEnrolleeStatus.provStatus : " << status.provStatus << endl;
91 cout << "\tEnrolleeStatus.lastErrCode : " << status.lastErrCode << endl;
92 cout << "===========================================" << endl;
95 void provisionSecurity()
100 void getStatusCallback(std::shared_ptr< GetEnrolleeStatus > getEnrolleeStatus)
102 if(getEnrolleeStatus->getESResult() != ES_OK)
104 cout << "getStatus is failed." << endl;
109 cout << "getStatus is success." << endl;
110 printStatus(getEnrolleeStatus->getEnrolleeStatus());
122 remoteEnrollee->getStatus(getStatusCallback);
124 catch (OCException &e)
126 std::cout << "Exception during getConfiguration call" << e.reason();
131 void getConfigurationCallback(std::shared_ptr< GetConfigurationStatus > getConfigurationStatus)
133 if(getConfigurationStatus->getESResult() != ES_OK)
135 cout << "GetConfigurationStatus is failed." << endl;
140 cout << "GetConfigurationStatus is success." << endl;
141 printConfiguration(getConfigurationStatus->getEnrolleeConf());
145 void getConfiguration()
152 remoteEnrollee->getConfiguration(getConfigurationCallback);
154 catch (OCException &e)
156 std::cout << "Exception during getConfiguration call" << e.reason();
161 void deviceProvisioningStatusCallback(std::shared_ptr< DevicePropProvisioningStatus > provStatus)
163 if(provStatus->getESResult() != ES_OK)
165 cout << "Device Provisioning is failed." << endl;
170 cout << "Device Provisioning is success." << endl;
174 void provisionDeviceProperty()
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";
189 remoteEnrollee->provisionDeviceProperties(deviceProp, deviceProvisioningStatusCallback);
191 catch (OCException &e)
193 std::cout << "Exception during provisionDeviceProperties call" << e.reason();
198 void cloudProvisioningStatusCallback(std::shared_ptr< CloudPropProvisioningStatus > provStatus)
200 switch (provStatus->getESCloudState())
202 case ES_CLOUD_PROVISIONING_ERROR:
203 cout << "Cloud Provisioning is failed." << endl;
205 case ES_CLOUD_PROVISIONING_SUCCESS:
206 cout << "Cloud Provisioning is success." << endl;
208 case ES_CLOUD_ENROLLEE_FOUND:
209 cout << "Enrollee is found in a given network." << endl;
211 case ES_CLOUD_ENROLLEE_NOT_FOUND:
212 cout << "Enrollee is not found in a given network." << endl;
217 void provisionCloudProperty()
223 cloudProp.authCode = "authCode";
224 cloudProp.authProvider = "authProvider";
225 cloudProp.ciServer = "ciServer";
229 remoteEnrollee->provisionCloudProperties(cloudProp, cloudProvisioningStatusCallback);
231 catch (OCException &e)
233 std::cout << "Exception during provisionCloudProperties call" << e.reason();
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;
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";
254 int selection = processUserInput(PROVISION_SECURITY, PROVISION_CLOUD_PROPERTY);
258 case PROVISION_SECURITY:
264 case GET_CONFIGURATION:
267 case PROVISION_DEVICE_PROPERTY:
268 provisionDeviceProperty();
270 case PROVISION_CLOUD_PROPERTY:
271 provisionCloudProperty();
278 // Callback to found resources
279 void foundResource(std::shared_ptr<OC::OCResource> resource)
281 std::string resourceURI;
282 std::string hostAddress;
285 // Do some operations with resource object.
288 resource->getResourceTypes().at(0) == PROV_RESOURCE_TYPE)
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;
295 // Get the resource host address
296 hostAddress = resource->host();
297 std::cout << "\tHost address of the resource: " << hostAddress << std::endl;
299 // Get the resource types
300 std::cout << "\tList of resource types: " << std::endl;
301 for(auto &resourceTypes : resource->getResourceTypes())
303 std::cout << "\t\t" << resourceTypes << std::endl;
306 // Get the resource interfaces
307 std::cout << "\tList of resource interfaces: " << std::endl;
308 for(auto &resourceInterfaces : resource->getResourceInterfaces())
310 std::cout << "\t\t" << resourceInterfaces << std::endl;
313 if(curResource == nullptr)
315 remoteEnrollee = EasySetup::getInstance()->createRemoteEnrollee(resource);
318 std::cout << "RemoteEnrollee object is failed for some reasons!" << std::endl;
322 curResource = resource;
323 std::cout << "RemoteEnrollee object is successfully created!" << std::endl;
329 catch(std::exception& e)
331 std::cerr << "Exception in foundResource: "<< e.what() << std::endl;
335 static FILE* client_open(const char *UNUSED_PARAM, const char *mode)
338 return fopen(JSON_DB_PATH, mode);
343 std::ostringstream requestURI;
344 OCPersistentStorage ps {client_open, fread, fwrite, fclose, unlink };
346 PlatformConfig config
348 OC::ServiceType::InProc, ModeType::Both, "0.0.0.0", 0, OC::QualityOfService::LowQos, &ps
351 OCPlatform::Configure(config);
354 //Initializing the provisioning client stack using the db path provided by the application.
355 OCStackResult result = OCSecure::provisionInit("");
357 if (result != OC_STACK_OK)
365 requestURI << OC_RSRVD_WELL_KNOWN_URI << "?rt=" << PROV_RESOURCE_TYPE;
367 OCPlatform::findResource("", requestURI.str(), CT_DEFAULT, &foundResource);
368 std::cout<< "Finding Resource... " <<std::endl;
370 std::unique_lock<std::mutex> lck(g_discoverymtx);
371 g_cond.wait_for(lck, std::chrono::seconds(4));
373 }catch(OCException& e)
375 oclog() << "Exception in main: "<<e.what();
384 catch (const std::exception& e)
386 std::cout << "Exception caught in main " << e.what() << std::endl;
390 std::cout << "Stopping the client" << std::endl;