Add cloud provisioning feature & modify mediator C++ class in easy setup
[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<stdio.h>
23
24 #include "oic_string.h"
25 #include "EasySetup.h"
26 #include "ESRichCommon.h"
27 #include "OCPlatform.h"
28 #include "logger.h"
29 #include "OCProvisioningManager.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 EasySetup *easySetupIntance = nullptr;
40 static std::shared_ptr<RemoteEnrollee> remoteEnrollee = nullptr;
41
42 static std::string ipaddress, ssid, pwd;
43 char security;
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 printPropertyData(PropertyData propData)
68 {
69     cout << "===========================================" << endl;
70     DeviceConfig devConfig = propData.getDevInfo();
71     NetworkInfo netInfo = propData.getNetInfo();
72     bool cloudable = propData.isCloudable();
73
74     cout << "\tDeviceConfig.id : " << devConfig.id << endl;
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 type = netInfo.types.begin(); type != netInfo.types.end(); ++type)
80     {
81         cout << "\tnetInfo.types : " << static_cast<int>(*type) << endl;
82     }
83     cout << "\tnetInfo.freq : " << static_cast<int>(netInfo.freq) << endl;
84     cout << "===========================================" << endl;
85 }
86
87 void RequestPropertyDataStatusCallback(std::shared_ptr< RequestPropertyDataStatus > requestPropertyDataStatus)
88 {
89     cout << "Enter RequestPropertyDataStatusCb." << endl;
90
91     if(requestPropertyDataStatus->getESResult() != ES_OK)
92     {
93       cout << "requestPropertyDataStatus is failed." << endl;
94       return;
95     }
96     else
97     {
98       cout << "requestPropertyDataStatus is success." << endl;
99       printPropertyData(requestPropertyDataStatus->getPropertyData());
100     }
101 }
102
103 void dataProvisioningStatusCallback(std::shared_ptr< DataProvisioningStatus > provStatus)
104 {
105     cout << "Enter dataProvisioningStatusCallback." << endl;
106
107     if(provStatus->getESResult() != ES_OK)
108     {
109       cout << "dataProvisioningStatusCallback is failed." << endl;
110       return;
111     }
112     else
113     {
114       cout << "dataProvisioningStatusCallback is success." << endl;
115       cout << "ESState : " << provStatus->getESState() << endl;
116     }
117 }
118
119 void cloudProvisioningStatusCallback(std::shared_ptr< CloudProvisioningStatus > status)
120 {
121     cout << "Enter cloudProvisioningStatusCallback." << endl;
122     cout << "CloudProvStatus : " <<  status->getESCloudState() << endl;
123 }
124
125 void createRemoteEnrollee()
126 {
127     easySetupIntance = EasySetup::getInstance();
128     try
129     {
130         remoteEnrollee = easySetupIntance->createRemoteEnrollee();
131     }
132     catch (OCException &e)
133     {
134         std::cout << "Exception during createEnrolleeDevice call" << e.reason();
135         return;
136     }
137     cout << "createRemoteEnrollee is success." << endl;
138 }
139
140 void initRemoteEnrollee()
141 {
142     try
143     {
144         remoteEnrollee->initRemoteEnrollee();
145     }
146     catch (OCException &e)
147     {
148         std::cout << "Exception during initRemoteEnrollee call" << e.reason();
149         return;
150     }
151 }
152
153 void requestPropertyData()
154 {
155     try
156     {
157         remoteEnrollee->requestPropertyData(RequestPropertyDataStatusCallback);
158     }
159     catch (OCException &e)
160     {
161         std::cout << "Exception during requestPropertyData call" << e.reason();
162         return;
163     }
164 }
165
166 void setDataProvInfo()
167 {
168     DataProvInfo dataProvInfo;
169     dataProvInfo.WIFI.ssid = "Iotivity_2.4G";
170     dataProvInfo.WIFI.pwd = "1234567890";
171     dataProvInfo.WIFI.authtype = WPA2_PSK;
172     dataProvInfo.WIFI.enctype = TKIP_AES;
173     dataProvInfo.Device.language = "korean";
174     dataProvInfo.Device.country = "korea";
175
176     remoteEnrollee->setDataProvInfo(dataProvInfo);
177 }
178
179 void setCloudProvInfo()
180 {
181     CloudProvInfo cloudProvInfo;
182     cloudProvInfo.authCode = "authCode";
183     cloudProvInfo.authProvider = "authProvider";
184     cloudProvInfo.ciServer = "ciServer";
185
186     remoteEnrollee->setCloudProvInfo(cloudProvInfo);
187 }
188
189 void startDataProvisioning()
190 {
191     try
192     {
193         remoteEnrollee->startDataProvisioning(dataProvisioningStatusCallback);
194     }
195     catch (OCException &e)
196     {
197         std::cout << "Exception during startDataProvisioning call" << e.reason();
198         return;
199     }
200 }
201
202 void startCloudProvisioning()
203 {
204     try
205     {
206         remoteEnrollee->startCloudProvisioning(cloudProvisioningStatusCallback);
207     }
208     catch (OCException &e)
209     {
210         std::cout << "Exception during startDataProvisioning call" << e.reason();
211         return;
212     }
213 }
214
215 void DisplayMenu()
216 {
217     constexpr int CREATE_REMOTE_ENROLLEE = 1;
218     constexpr int EASY_SETUP_INIT = 2;
219     constexpr int REQUEST_PROPERTY_DATA = 3;
220     constexpr int SET_DATA_PROVISIONING_INFO = 4;
221     constexpr int START_DATA_PROVISIONING = 5;
222     constexpr int SET_CLOUD_PROVISIONING_INFO = 6;
223     constexpr int START_CLOUD_PROVISIONING = 7;
224
225     std::cout << "========================================================\n";
226     std::cout << CREATE_REMOTE_ENROLLEE << ". Create Remote Enrollee                    \n";
227     std::cout << EASY_SETUP_INIT << ". Easy Setup Init                    \n";
228     std::cout << REQUEST_PROPERTY_DATA << ". Request PropertyData              \n";
229     std::cout << SET_DATA_PROVISIONING_INFO << ". Set Data Provisioning Info              \n";
230     std::cout << START_DATA_PROVISIONING << ". Start Data Provisioning              \n";
231     std::cout << SET_CLOUD_PROVISIONING_INFO << ". Set Cloud Provisioning Info              \n";
232     std::cout << START_CLOUD_PROVISIONING << ". Start Cloud Provisioning              \n";
233     std::cout << "========================================================\n";
234
235     int selection = processUserInput(CREATE_REMOTE_ENROLLEE, START_CLOUD_PROVISIONING);
236
237     switch (selection)
238     {
239         case CREATE_REMOTE_ENROLLEE:
240             createRemoteEnrollee();
241             break;
242         case EASY_SETUP_INIT:
243             initRemoteEnrollee();
244             break;
245         case REQUEST_PROPERTY_DATA:
246             requestPropertyData();
247             break;
248         case SET_DATA_PROVISIONING_INFO:
249             setDataProvInfo();
250             break;
251         case START_DATA_PROVISIONING:
252             startDataProvisioning();
253             break;
254         case SET_CLOUD_PROVISIONING_INFO:
255             setCloudProvInfo();
256             break;
257         case START_CLOUD_PROVISIONING:
258             startCloudProvisioning();
259             break;
260         default:
261             break;
262     };
263 }
264
265 static FILE* client_open(const char *UNUSED_PARAM, const char *mode)
266 {
267     (void)UNUSED_PARAM;
268     return fopen(JSON_DB_PATH, mode);
269 }
270
271 int main()
272 {
273     OCPersistentStorage ps {client_open, fread, fwrite, fclose, unlink };
274
275     PlatformConfig config
276     {
277         OC::ServiceType::InProc, ModeType::Both, "0.0.0.0", 0, OC::QualityOfService::LowQos, &ps
278     };
279
280     OCPlatform::Configure(config);
281
282 #ifdef __WITH_DTLS__
283     //Initializing the provisioning client stack using the db path provided by the application.
284     OCStackResult result = OCSecure::provisionInit("");
285
286     if (result != OC_STACK_OK)
287     {
288         return -1;
289     }
290 #endif
291
292     while (true)
293     {
294         try
295         {
296             DisplayMenu();
297         }
298         catch (const std::exception& e)
299         {
300             std::cout << "Exception caught in main " << e.what() << std::endl;
301         }
302     }
303
304     std::cout << "Stopping the client" << std::endl;
305
306     return 0;
307 }
308