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"
28 #include "EasySetup.hpp"
29 #include "ESSCCommon.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;
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 SCEnrolleeConf& conf)
73 cout << "===========================================" << endl;
74 cout << "\tDevice Name : " << conf.getDeviceName() << endl;
75 cout << "\tModel Number : " << conf.getModelNumber() << endl;
77 for(auto it : conf.getWiFiModes())
79 cout << "\tSupported WiFi modes : " << it << endl;
82 cout << "\tSupported WiFi freq : " << static_cast<int>(conf.getWiFiFreq()) << endl;
83 cout << "\tCloud accessibility: " << conf.isCloudAccessible() << endl;
84 cout << "\tDevice Type: " << conf.getDeviceType() << endl;
85 cout << "\tDevice Sub-Type: " << conf.getDeviceSubType() << endl;
86 cout << "\tRegister Set Device: " << conf.getRegisterSetDevice() << endl;
87 cout << "\tNetwork Provisioning Info: " << conf.getNetworkProvisioningInfo() << endl;
88 cout << "\tSSOList: " << conf.getSSOList() << endl;
89 cout << "\tPnP Pin: " << conf.getPnpPin() << endl;
90 cout << "\tNetwork Connection State : " << conf.getNetConnectionState() << endl;
91 cout << "\tBSSID : " << conf.getBSSID() << endl;
92 cout << "\tUTC time: " << conf.getUTCDatetime() << endl;
93 cout << "\tRegional time: " << conf.getRegionalDatetime() << endl;
94 cout << "\tEasy Setup Protocol Version: " << conf.getESProtocolVersion() << endl;
95 std::vector<SCCandidateAPInfo> candidateInfo = conf.getCandidateAPList();
96 int size = candidateInfo.size();
97 for(int i=0;i< size;i++)
99 cout << "[SC] Candidate Bssid :" << candidateInfo[i].bssid << endl;
100 cout << "[SC] Candidate Channel :" << candidateInfo[i].channel << endl;
101 cout << "[SC] Candidate Passphrase :" << candidateInfo[i].passphrase << endl;
102 cout << "[SC] Candidate SSID :" << candidateInfo[i].ssid << endl;
104 cout << "===========================================" << endl;
107 void printStatus(const SCEnrolleeStatus& status)
109 cout << "===========================================" << endl;
110 cout << "\tProvStatus : " << status.getProvStatus() << endl;
111 cout << "\tLastErrCode : " << status.getLastErrCode() << endl;
112 cout << "\tNetwork Connection State : " << status.getNetConnectionState() << endl;
113 cout << "===========================================" << endl;
116 void provisionSecurityStatusCallback(std::shared_ptr<SecProvisioningStatus> secProvisioningStatus)
118 if(secProvisioningStatus->getESResult() != ES_OK)
120 cout << "provisionSecurity is failed." << endl;
125 cout << "provisionSecurity is success." << endl;
126 cout << "uuid : " << secProvisioningStatus->getDeviceUUID()<< endl;
130 void provisionSecurity()
134 remoteEnrollee->provisionSecurity((SecurityProvStatusCb)provisionSecurityStatusCallback);
136 catch (OCException &e)
138 std::cout << "Exception during provisionSecurity call" << e.reason();
143 void getStatusCallback(std::shared_ptr< GetEnrolleeStatus > getEnrolleeStatus)
145 if(getEnrolleeStatus->getESResult() != ES_OK)
147 cout << "getStatus is failed." << endl;
152 cout << "getStatus is success." << endl;
153 printStatus(std::move(getEnrolleeStatus->getEnrolleeStatus()));
167 remoteEnrollee->getStatus(getStatusCallback);
169 catch (OCException &e)
171 std::cout << "Exception during getConfiguration call" << e.reason();
176 void getConfigurationCallback(std::shared_ptr< GetConfigurationStatus > getConfigurationStatus)
178 if(getConfigurationStatus->getESResult() != ES_OK)
180 cout << "GetConfigurationStatus is failed." << endl;
185 cout << "GetConfigurationStatus is success." << endl;
186 printConfiguration(std::move(getConfigurationStatus->getEnrolleeConf()));
190 void getConfiguration()
199 remoteEnrollee->getConfiguration(getConfigurationCallback);
201 catch (OCException &e)
203 std::cout << "Exception during getConfiguration call" << e.reason();
208 void deviceProvisioningStatusCallback(std::shared_ptr< DevicePropProvisioningStatus > provStatus)
210 if(provStatus->getESResult() != ES_OK)
212 cout << "Device Provisioning is failed." << endl;
217 cout << "Device Provisioning is success." << endl;
221 void provisionDeviceProperty()
228 SCDeviceProp scDevProp;
229 scDevProp.setWiFiProp("Iotivity_SSID", "Iotivity_PWD", WPA2_PSK, TKIP_AES);
230 scDevProp.setDevConfProp("korean", "Korea", "Location");
231 scDevProp.setDiscoveryChannel(11);
232 scDevProp.setBSSID("aa:aa:aa:aa:aa:aa");
234 std::vector<std::string> locations;
235 locations.push_back("addr=Seoul, Rep. of Korea");
236 locations.push_back("zip=02848");
237 locations.push_back("bd=apartment");
238 scDevProp.setSCLocation(locations);
239 scDevProp.setRegisterMobileDevice("{\"wm\":\"00:11:22:33:44:55\",\"pm\":\"00:11:22:33:44:55\",\"bm\":\"00:11:22:33:44:55\",\"dt\":\"0\",\"it\":\"0\"}");
240 scDevProp.setSSOList("[{\"AvailableCount\" : \"1\", \"RegisteredCount\" : \"3\", \"AccountList\" : {\"aaa@samsung.com\", \"bbb@samsung.com\",\"ccc@samsung.com\"} }] ");
242 SCCandidateAPInfo candidateAPInfo[2];
243 candidateAPInfo[0].ssid = "x_5GHz";
244 candidateAPInfo[0].passphrase= "12345678";
245 candidateAPInfo[0].channel = 149;
246 candidateAPInfo[0].bssid = "aa:bb:cc:dd:ee:01";
247 candidateAPInfo[1].ssid = "y_5GHz";
248 candidateAPInfo[1].passphrase= "12345678";
249 candidateAPInfo[1].channel = 161;
250 candidateAPInfo[1].bssid = "aa:bb:cc:dd:ee:02";
251 scDevProp.setCandidateAPList(candidateAPInfo,2);
253 // Set UTC and regional date
254 time_t t = time(NULL);
256 char utcTimeStr[33] = {0};
257 struct tm *utcTime = gmtime(&t);
258 snprintf(utcTimeStr, 33, "[%04d]-[%02d]-[%02d]T[%02d]:[%02d]:[%02d]Z",
259 utcTime->tm_year+1900, utcTime->tm_mon+1, utcTime->tm_mday, utcTime->tm_hour, utcTime->tm_min, utcTime->tm_sec);
261 char localTimeStr[33] = {0};
262 struct tm *localTime = localtime(&t);
263 snprintf(localTimeStr, 33, "[%04d]-[%02d]-[%02d]T[%02d]:[%02d]:[%02d]Z",
264 localTime->tm_year+1900, localTime->tm_mon+1, localTime->tm_mday, localTime->tm_hour, localTime->tm_min, localTime->tm_sec);
266 scDevProp.setUTCDatetime(utcTimeStr);
267 scDevProp.setRegionalDatetime(localTimeStr);
271 remoteEnrollee->provisionDeviceProperties(scDevProp, deviceProvisioningStatusCallback);
273 catch (OCException &e)
275 std::cout << "Exception during provisionDeviceProperties call" << e.reason();
280 void cloudProvisioningStatusCallback(std::shared_ptr< CloudPropProvisioningStatus > provStatus)
282 switch (provStatus->getESResult())
285 cout << "Cloud Provisioning is success." << endl;
287 case ES_SECURE_RESOURCE_DISCOVERY_FAILURE:
288 cout << "Enrollee is not found in a given network." << endl;
290 case ES_ACL_PROVISIONING_FAILURE:
291 cout << "ACL provisioning is failed." << endl;
293 case ES_CERT_PROVISIONING_FAILURE:
294 cout << "CERT provisioning is failed." << endl;
297 cout << "Cloud Provisioning is failed." << endl;
302 void provisionCloudProperty()
309 SCCloudProp cloudProp;
310 cloudProp.setCloudProp("authCode", "authProvider", "ciServer");
311 cloudProp.setCloudID("f002ae8b-c42c-40d3-8b8d-1927c17bd1b3");
312 cloudProp.setCredID(1);
313 cloudProp.setClientID("166135d296");
317 remoteEnrollee->provisionCloudProperties(cloudProp, cloudProvisioningStatusCallback);
319 catch (OCException &e)
321 std::cout << "Exception during provisionCloudProperties call" << e.reason();
328 constexpr int PROVISION_SECURITY = 1;
329 constexpr int GET_STATUS = 2;
330 constexpr int GET_CONFIGURATION = 3;
331 constexpr int PROVISION_DEVICE_PROPERTY = 4;
332 constexpr int PROVISION_CLOUD_PROPERTY = 5;
334 std::cout << "========================================================\n";
335 std::cout << PROVISION_SECURITY << ". Provision Security to Enrollee \n";
336 std::cout << GET_STATUS << ". Get Status from Enrollee \n";
337 std::cout << GET_CONFIGURATION << ". Get Configuration from Enrollee \n";
338 std::cout << PROVISION_DEVICE_PROPERTY << ". Provision Device Property\n";
339 std::cout << PROVISION_CLOUD_PROPERTY << ". Provision Cloud Property \n";
340 std::cout << "========================================================\n";
342 int selection = processUserInput(PROVISION_SECURITY, PROVISION_CLOUD_PROPERTY);
346 case PROVISION_SECURITY:
352 case GET_CONFIGURATION:
355 case PROVISION_DEVICE_PROPERTY:
356 provisionDeviceProperty();
358 case PROVISION_CLOUD_PROPERTY:
359 provisionCloudProperty();
366 // Callback to found resources
367 void foundResource(std::shared_ptr<OC::OCResource> resource)
369 std::string resourceURI;
370 std::string hostAddress;
373 // Do some operations with resource object.
376 resource->getResourceTypes().at(0) == OC_RSRVD_ES_RES_TYPE_EASYSETUP)
378 std::cout<<"DISCOVERED Resource:"<<std::endl;
379 // Get the resource URI
380 resourceURI = resource->uri();
381 std::cout << "\tURI of the resource: " << resourceURI << std::endl;
383 // Get the resource host address
384 hostAddress = resource->host();
385 std::cout << "\tHost address of the resource: " << hostAddress << std::endl;
387 // Get the resource types
388 std::cout << "\tList of resource types: " << std::endl;
389 for(auto &resourceTypes : resource->getResourceTypes())
391 std::cout << "\t\t" << resourceTypes << std::endl;
394 // Get the resource interfaces
395 std::cout << "\tList of resource interfaces: " << std::endl;
396 for(auto &resourceInterfaces : resource->getResourceInterfaces())
398 std::cout << "\t\t" << resourceInterfaces << std::endl;
401 if(curResource == nullptr)
403 remoteEnrollee = EasySetup::getInstance()->createRemoteEnrollee(resource);
406 std::cout << "RemoteEnrollee object is failed for some reasons!" << std::endl;
410 curResource = resource;
411 std::cout << "RemoteEnrollee object is successfully created!" << std::endl;
417 catch(std::exception &e)
419 std::cerr << "Exception in foundResource: "<< e.what() << std::endl;
423 static FILE* client_open(const char *UNUSED_PARAM, const char *mode)
426 return fopen(JSON_DB_PATH, mode);
431 std::ostringstream requestURI;
432 OCPersistentStorage ps {client_open, fread, fwrite, fclose, unlink };
434 PlatformConfig config
436 OC::ServiceType::InProc, ModeType::Both, "0.0.0.0", 0, OC::QualityOfService::HighQos, &ps
439 OCPlatform::Configure(config);
444 //Initializing the provisioning client stack using the db path provided by the application.
445 OCStackResult result = OCSecure::provisionInit("");
447 if (result != OC_STACK_OK)
453 requestURI << OC_RSRVD_WELL_KNOWN_URI << "?rt=" << OC_RSRVD_ES_RES_TYPE_EASYSETUP;
455 OCPlatform::findResource("", requestURI.str(), CT_DEFAULT, &foundResource);
456 std::cout<< "Finding Resource... " <<std::endl;
458 std::unique_lock<std::mutex> lck(g_discoverymtx);
459 g_cond.wait_for(lck, std::chrono::seconds(4));
464 oclog() << "Exception in main";
475 std::cout << "Exception caught in main";
479 std::cout << "Stopping the client" << std::endl;