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.hpp"
27 #include "securevirtualresourcetypes.h"
29 #include "EasySetup.hpp"
30 #include "ESRichCommon.h"
32 #define ES_SAMPLE_APP_TAG "ES_SAMPLE_APP_TAG"
33 #define DECLARE_MENU(FUNC, ...) { #FUNC, FUNC }
35 #define JSON_DB_PATH "./oic_svr_db_client.dat"
38 using namespace OIC::Service;
40 static std::shared_ptr<RemoteEnrollee> remoteEnrollee = nullptr;
41 static std::shared_ptr<OC::OCResource> curResource = nullptr;
43 static std::mutex g_discoverymtx;
44 static std::condition_variable g_cond;
46 typedef void (*Runner)();
50 int processUserInput(int min = std::numeric_limits<int>::min(),
51 int max = std::numeric_limits<int>::max())
58 std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
60 if (!std::cin.fail() && min <= input && input <= max)
66 std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
68 throw std::runtime_error("Invalid Input, please try again");
71 void printConfiguration(const EnrolleeConf& conf)
73 cout << "===========================================" << endl;
74 cout << "\tProvStatus : " << conf.getProvStatus() << endl;
75 cout << "\tLastErrCode : " << conf.getLastErrCode() << endl;
76 cout << "\tDevice Name : " << conf.getDeviceName() << endl;
78 for(auto it : conf.getWiFiModes())
80 cout << "\tSupported WiFi modes : " << it << endl;
83 cout << "\tSupported WiFi freq : " << static_cast<int>(conf.getWiFiFreq()) << endl;
84 cout << "\tCloud accessibility: " << conf.isCloudAccessible() << endl;
85 cout << "===========================================" << endl;
88 void printStatus(const EnrolleeStatus& status)
90 cout << "===========================================" << endl;
91 cout << "\tProvStatus : " << status.getProvStatus() << endl;
92 cout << "\tLastErrCode : " << status.getLastErrCode() << endl;
93 cout << "===========================================" << endl;
96 ESOwnershipTransferData provisionSecurityStatusCallback(std::shared_ptr<SecProvisioningStatus> secProvisioningStatus)
98 cout << "provisionSecurityStatusCallback IN" << endl;
99 cout << "ESResult : " << secProvisioningStatus->getESResult() << std::endl;
100 cout << "Device ID : " << secProvisioningStatus->getDeviceUUID() << std::endl;
102 if(secProvisioningStatus->getESResult() == ES_SECURE_RESOURCE_IS_DISCOVERED)
105 cout << "Owned Status : " << secProvisioningStatus->isOwnedDevice() << std::endl;
106 if(secProvisioningStatus->isOwnedDevice())
108 cout << "Owner ID : " << secProvisioningStatus->getOwnerID() << std::endl;
110 cout << "OT Method : " << secProvisioningStatus->getSelectedOTMethod() << std::endl;
111 #ifdef MULTIPLE_OWNER
112 cout << "MOT Enabled : " << secProvisioningStatus->isMOTEnabled() << std::endl;
115 ESOwnershipTransferData OTData;
116 OTData.setMOTMethod(OIC_PRECONFIG_PIN, "12345678");
118 cout << "Enter!" << std::endl;
125 else if(secProvisioningStatus->getESResult() == ES_OK)
127 cout << "provisionSecurity is success." << std::endl;
131 cout << "provisionSecurity is failed." << endl;
137 void provisionSecurity()
141 std::cout << "RemoteEnrollee is null, retry Discovery EnrolleeResource." << endl;
147 remoteEnrollee->provisionSecurity((SecurityProvStatusCbWithOption)provisionSecurityStatusCallback);
149 catch (OCException &e)
151 std::cout << "Exception during provisionSecurity call" << e.reason();
156 void getStatusCallback(std::shared_ptr< GetEnrolleeStatus > getEnrolleeStatus)
158 if(getEnrolleeStatus->getESResult() != ES_OK)
160 cout << "getStatus is failed." << endl;
165 cout << "getStatus is success." << endl;
166 printStatus(getEnrolleeStatus->getEnrolleeStatus());
175 std::cout << "RemoteEnrollee is null, retry Discovery EnrolleeResource." << endl;
181 remoteEnrollee->getStatus(getStatusCallback);
183 catch (OCException &e)
185 std::cout << "Exception during getConfiguration call" << e.reason();
190 void getConfigurationCallback(std::shared_ptr< GetConfigurationStatus > getConfigurationStatus)
192 if(getConfigurationStatus->getESResult() != ES_OK)
194 cout << "GetConfigurationStatus is failed." << endl;
199 cout << "GetConfigurationStatus is success." << endl;
200 printConfiguration(getConfigurationStatus->getEnrolleeConf());
204 void getConfiguration()
208 std::cout << "RemoteEnrollee is null, retry Discovery EnrolleeResource." << endl;
214 remoteEnrollee->getConfiguration(getConfigurationCallback);
216 catch (OCException &e)
218 std::cout << "Exception during getConfiguration call" << e.reason();
223 void deviceProvisioningStatusCallback(std::shared_ptr< DevicePropProvisioningStatus > provStatus)
225 if(provStatus->getESResult() != ES_OK)
227 cout << "Device Provisioning is failed." << endl;
232 cout << "Device Provisioning is success." << endl;
236 void provisionDeviceProperty()
240 std::cout << "RemoteEnrollee is null, retry Discovery EnrolleeResource." << endl;
245 devProp.setWiFiProp("Iotivity_SSID", "Iotivity_PWD", WPA2_PSK, TKIP_AES);
249 remoteEnrollee->provisionDeviceProperties(devProp, deviceProvisioningStatusCallback);
251 catch (OCException &e)
253 std::cout << "Exception during provisionDeviceProperties call" << e.reason();
258 void connectRequestStatusCallback(std::shared_ptr< ConnectRequestStatus > requestStatus)
260 if(requestStatus->getESResult() != ES_OK)
262 cout << "Request to connection is failed." << endl;
267 cout << "Request to connection is success." << endl;
271 void requestToConnect()
275 std::cout << "RemoteEnrollee is null, retry Discovery EnrolleeResource." << endl;
281 std::vector<ES_CONNECT_TYPE> types;
282 types.push_back(ES_CONNECT_WIFI);
283 types.push_back(ES_CONNECT_COAPCLOUD);
284 remoteEnrollee->requestToConnect(types, connectRequestStatusCallback);
286 catch (OCException &e)
288 std::cout << "Exception during provisionDeviceProperties call" << e.reason();
293 void cloudProvisioningStatusCallback(std::shared_ptr< CloudPropProvisioningStatus > provStatus)
295 switch (provStatus->getESResult())
298 cout << "Cloud Provisioning is success." << endl;
300 case ES_SECURE_RESOURCE_DISCOVERY_FAILURE:
301 cout << "Enrollee is not found in a given network." << endl;
303 case ES_ACL_PROVISIONING_FAILURE:
304 cout << "ACL provisioning is failed." << endl;
306 case ES_CERT_PROVISIONING_FAILURE:
307 cout << "CERT provisioning is failed." << endl;
310 cout << "Cloud Provisioning is failed." << endl;
315 void provisionCloudProperty()
319 std::cout << "RemoteEnrollee is null, retry Discovery EnrolleeResource." << endl;
324 cloudProp.setCloudPropWithAccessToken("accessToken", OAUTH_TOKENTYPE_BEARER, "authProvider", "ciServer");
325 cloudProp.setCloudID("f002ae8b-c42c-40d3-8b8d-1927c17bd1b3");
326 cloudProp.setCredID(1);
330 remoteEnrollee->provisionCloudProperties(cloudProp, cloudProvisioningStatusCallback);
332 catch (OCException &e)
334 std::cout << "Exception during provisionCloudProperties call" << e.reason();
339 // Callback to found resources
340 void foundResource(std::shared_ptr<OC::OCResource> resource)
342 std::string resourceURI;
343 std::string hostAddress;
346 // Do some operations with resource object.
349 resource->getResourceTypes().at(0) == OC_RSRVD_ES_RES_TYPE_EASYSETUP)
351 std::cout<<"DISCOVERED Resource:"<<std::endl;
352 // Get the resource URI
353 resourceURI = resource->uri();
354 std::cout << "\tURI of the resource: " << resourceURI << std::endl;
356 // Get the resource host address
357 hostAddress = resource->host();
358 std::cout << "\tHost address of the resource: " << hostAddress << std::endl;
360 // Get the resource types
361 std::cout << "\tList of resource types: " << std::endl;
362 for(auto &resourceTypes : resource->getResourceTypes())
364 std::cout << "\t\t" << resourceTypes << std::endl;
367 // Get the resource interfaces
368 std::cout << "\tList of resource interfaces: " << std::endl;
369 for(auto &resourceInterfaces : resource->getResourceInterfaces())
371 std::cout << "\t\t" << resourceInterfaces << std::endl;
374 if(curResource == nullptr)
376 remoteEnrollee = EasySetup::getInstance()->createRemoteEnrollee(resource);
379 std::cout << "RemoteEnrollee object is failed for some reasons!" << std::endl;
383 curResource = resource;
384 std::cout << "RemoteEnrollee object is successfully created!" << std::endl;
390 catch(std::exception& e)
392 std::cerr << "Exception in foundResource: "<< e.what() << std::endl;
396 void discoveryEnrolleeResource()
400 std::ostringstream requestURI;
401 requestURI << OC_RSRVD_WELL_KNOWN_URI << "?rt=" << OC_RSRVD_ES_RES_TYPE_EASYSETUP;
402 OCPlatform::findResource("", requestURI.str(), CT_DEFAULT, &foundResource);
403 std::cout<< "Finding Resource... " <<std::endl;
405 std::unique_lock<std::mutex> lck(g_discoverymtx);
406 g_cond.wait_for(lck, std::chrono::seconds(5));
408 catch (OCException &e)
410 std::cout << "Exception in discoveryEnrolleeResource: "<<e.what();
416 constexpr int DISCOVERY_ENROLLEE = 1;
417 constexpr int PROVISION_SECURITY = 2;
418 constexpr int GET_STATUS = 3;
419 constexpr int GET_CONFIGURATION = 4;
420 constexpr int PROVISION_DEVICE_PROPERTY = 5;
421 constexpr int REQUEST_TO_CONNECT = 6;
422 constexpr int PROVISION_CLOUD_PROPERTY = 7;
424 std::cout << "========================================================\n";
425 std::cout << DISCOVERY_ENROLLEE << ". Discovery Enrollee Resource \n";
426 std::cout << PROVISION_SECURITY << ". Provision Security to Enrollee \n";
427 std::cout << GET_STATUS << ". Get Status from Enrollee \n";
428 std::cout << GET_CONFIGURATION << ". Get Configuration from Enrollee \n";
429 std::cout << PROVISION_DEVICE_PROPERTY << ". Provision Device Property\n";
430 std::cout << REQUEST_TO_CONNECT << ". Request to Connect \n";
431 std::cout << PROVISION_CLOUD_PROPERTY << ". Provision Cloud Property \n";
432 std::cout << "========================================================\n";
434 int selection = processUserInput(DISCOVERY_ENROLLEE, PROVISION_CLOUD_PROPERTY);
438 case DISCOVERY_ENROLLEE:
439 discoveryEnrolleeResource();
441 case PROVISION_SECURITY:
447 case GET_CONFIGURATION:
450 case PROVISION_DEVICE_PROPERTY:
451 provisionDeviceProperty();
453 case REQUEST_TO_CONNECT:
456 case PROVISION_CLOUD_PROPERTY:
457 provisionCloudProperty();
464 static FILE* client_open(const char *UNUSED_PARAM, const char *mode)
467 return fopen(JSON_DB_PATH, mode);
472 OCPersistentStorage ps {client_open, fread, fwrite, fclose, unlink };
474 PlatformConfig config
476 OC::ServiceType::InProc, ModeType::Both, "0.0.0.0", 0, OC::QualityOfService::HighQos, &ps
479 OCPlatform::Configure(config);
484 //Initializing the provisioning client stack using the db path provided by the application.
485 OCStackResult result = OCSecure::provisionInit("");
487 if (result != OC_STACK_OK)
494 std::cout << "Exception in main: " << std::endl;
505 std::cout << "Exception caught in main " << std::endl;
509 std::cout << "Stopping the client" << std::endl;