replace : iotivity -> iotivity-sec
[platform/upstream/iotivity.git] / service / easy-setup / sampleapp / enrollee / tizen-sdb / EnrolleeSample / enrolleewifi.cpp
1 //******************************************************************
2 //
3 // Copyright 2016 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
22 #include "easysetup.h"
23 #include "easysetup_wifi_conn.h"
24
25 #include <unistd.h>
26 #include <string.h>
27 #include <iostream>
28 #include <pthread.h>
29 #include <glib.h>
30 #include <limits>
31 #include <unistd.h>
32 #define TAG "TIZEN_ES"
33
34 using namespace std;
35
36 gboolean mainThread(GIOChannel *source, GIOCondition condition, gpointer data);
37 void *listeningFunc(void *);
38
39 GMainLoop *gMainloop;
40 static pthread_t gThreadHandle = 0;
41
42
43 /**
44  * Secure Virtual Resource database for Iotivity Server
45  * It contains Server's Identity and the PSK credentials
46  * of other devices which the server trusts
47  */
48 static char CRED_FILE[] = "oic_svr_db_server.dat";
49
50 OCPersistentStorage ps;
51
52 /**
53  * @var gIsSecured
54  * @brief Variable to check if secure mode is enabled or not.
55  */
56 static bool gIsSecured = false;
57 static bool gWiFiCBflag = false;
58 static char gSSID[OIC_STRING_MAX_VALUE];
59 static char gPasswd[OIC_STRING_MAX_VALUE];
60
61 void PrintMenu()
62 {
63     cout << "========================" << endl;
64     cout << "A: Enabled Security" << endl;
65     cout << "B: Init & Start EasySetup" << endl;
66     cout << "C: Set DeviceInfo" << endl;
67     cout << "D: Connect to TargetAP" << endl;
68     cout << "E: Show Menu......." << endl;
69     cout << "Q: Terminate" << endl;
70     cout << "========================" << endl;
71 }
72
73 void ConnectRequestCbInApp(ESConnectRequest *connectRequest)
74 {
75     cout << "ConnectRequestCbInApp IN" << endl;
76
77     if(connectRequest == NULL)
78     {
79         cout << "connectRequest is NULL" << endl;
80         return ;
81     }
82
83     for(int i = 0 ; i < connectRequest->numRequest ; ++i)
84     {
85         cout << "connect : " << connectRequest->connect[i] << endl;
86     }
87
88     cout << "ConnectRequestCbInApp OUT" << endl;
89     PrintMenu();
90 }
91
92 void WiFiConfProvCbInApp(ESWiFiConfData *eventData)
93 {
94     cout << "WiFiConfProvCbInApp IN" << endl;
95     gWiFiCBflag = true;
96
97     ESSetState(ES_STATE_CONNECTING_TO_ENROLLER);
98
99     if(eventData == NULL)
100     {
101         cout << "ESWiFiConfData is NULL" << endl;
102         return ;
103     }
104
105     cout << "SSID : " << eventData->ssid << endl;
106     cout << "Password : " << eventData->pwd << endl;
107     cout << "AuthType : " << eventData->authtype << endl;
108     cout << "EncType : " << eventData->enctype << endl;
109
110     memset(gSSID, 0, OIC_STRING_MAX_VALUE);
111     memset(gPasswd, 0, OIC_STRING_MAX_VALUE);
112     if(eventData->ssid != NULL)
113     {
114         strncpy(gSSID, eventData->ssid, strlen(eventData->ssid));
115     }
116
117     if(eventData->pwd != NULL)
118     {
119         strncpy(gPasswd, eventData->pwd, strlen(eventData->pwd));
120     }
121
122     cout << "WiFiConfProvCbInApp OUT" << endl;
123     PrintMenu();
124 }
125
126 void DevConfProvCbInApp(ESDevConfData *eventData)
127 {
128     cout << "DevConfProvCbInApp IN" << endl;
129
130     if(eventData == NULL)
131     {
132         cout << "ESDevConfData is NULL" << endl;
133         return ;
134     }
135
136     cout << "DevConfProvCbInApp OUT" << endl;
137     PrintMenu();
138 }
139
140 void CoapCloudConfProvCbInApp(ESCoapCloudConfData *eventData)
141 {
142     cout << "CoapCloudConfProvCbInApp IN" << endl;
143
144     if(eventData == NULL)
145     {
146         cout << "ESCoapCloudConfData is NULL" << endl;
147         return ;
148     }
149
150     cout << "AuthCode : " << eventData->authCode << endl;
151     cout << "AuthProvider : " << eventData->authProvider << endl;
152     cout << "CI Server : " << eventData->ciServer << endl;
153     cout << "CoapCloudConfProvCbInApp OUT" << endl;
154     PrintMenu();
155 }
156
157 ESProvisioningCallbacks gCallbacks = {
158     .ConnectRequestCb = &ConnectRequestCbInApp,
159     .WiFiConfProvCb = &WiFiConfProvCbInApp,
160     .DevConfProvCb = &DevConfProvCbInApp,
161     .CoapCloudConfProvCb = &CoapCloudConfProvCbInApp
162 };
163
164 FILE* server_fopen(const char *path, const char *mode)
165 {
166     (void) path;
167     return fopen(CRED_FILE, mode);
168 }
169
170 void EnableSecurity()
171 {
172     printf("Inside EnableSecurity API..\n");
173
174     gIsSecured = true;
175
176     // Initialize Persistent Storage for SVR database
177     ps = (OCPersistentStorage){ server_fopen, fread, fwrite, fclose, unlink };
178     OCRegisterPersistentStorageHandler(&ps);
179 }
180
181 void StartEasySetup()
182 {
183     cout << "StartEasySetup IN" << endl;
184
185     if (OCInit(NULL, 0, OC_SERVER) != OC_STACK_OK)
186     {
187         cout << "OCStack init error!!" << endl;
188         return;
189     }
190
191     ESResourceMask resourcemMask = (ESResourceMask) (ES_WIFICONF_RESOURCE | ES_COAPCLOUDCONF_RESOURCE | ES_DEVCONF_RESOURCE);
192     cout << "resourcemMask : " << resourcemMask << endl;
193     if(ESInitEnrollee(gIsSecured, resourcemMask, gCallbacks) != ES_OK)
194     {
195         cout << "OCStack init error!!" << endl;
196         return;
197     }
198
199     cout << "ESInitEnrollee Success" << endl;
200
201     if(gThreadHandle == 0) {
202
203         if (pthread_create(&gThreadHandle, NULL, listeningFunc, NULL)) {
204             cout << "Thread creation failed" << endl;
205             return;
206         }
207
208     }
209
210     ESSetState(ES_STATE_INIT);
211     ESSetErrorCode(ES_ERRCODE_NO_ERROR);
212
213     int ret = 0;
214
215     ret = TizenWiFiInit();
216     if(ret != WIFI_NO_ERROR) {
217         cout << "WiFi Init Error" << endl;
218     }
219     else
220         cout << "WiFi Init Success" << endl;
221
222     ret = TizenWiFiScanStart();
223     if(ret != WIFI_NO_ERROR) {
224         cout << "WiFi Scan Error" << endl;
225     }
226     else
227         cout << "WiFi Scan Success" << endl;
228
229     cout << "StartEasySetup OUT" << endl;
230 }
231
232 void SetDeviceInfo()
233 {
234     cout << "SetDeviceInfo IN" << endl;
235
236     ESDeviceProperty deviceProperty = {
237         {{WIFI_11G, WIFI_11N, WIFI_11AC, WiFi_EOF}, WIFI_5G}, {"Tizen Device"}
238     };
239
240     if(ESSetDeviceProperty(&deviceProperty) == ES_ERROR)
241     {
242         cout << "ESSetDeviceProperty Error" << endl;
243     }
244
245     // Set user properties if needed
246
247     cout << "SetDeviceInfo OUT" << endl;
248 }
249
250 void StopEasySetup()
251 {
252     cout << "StopEasySetup IN" << endl;
253     if (ESTerminateEnrollee() == ES_ERROR)
254     {
255         cout << "ESTerminateEnrollee Failed!!" << endl;
256         return;
257     }
258
259     // Deinit Tizen Wifi
260     TizenWiFiDeinit();
261
262     // Stop OC Stack
263     if (OCStop() != OC_STACK_OK)
264     {
265         cout << "OCStack stop failed!!" << endl;
266         return;
267     }
268
269     if(gThreadHandle != 0) {
270         pthread_cancel(gThreadHandle);
271         pthread_join(gThreadHandle, NULL);
272     }
273
274     cout << "StopEasySetup OUT" << endl;
275 }
276
277 void ConnectToTargetAP()
278 {
279     if(!gWiFiCBflag){
280         cout << "WiFi Provisioning is needed to be preceded" << endl;
281         return;
282     }
283
284     WiFiConnErrCode ret = WIFI_NO_ERROR;
285     ret = TizenWiFiScanStart();
286     if(ret != WIFI_NO_ERROR){
287         ESSetState(ES_STATE_FAILED_TO_CONNECT_TO_ENROLLER);
288         ESSetErrorCode(ES_ERRCODE_UNKNOWN);
289         cout << "WiFi Scan Error" << endl;
290         return;
291     }
292     else{
293         cout << "WiFi Scan Succss" << endl;
294     }
295
296     ret = TizenWiFiConn(gSSID, gPasswd);
297     if(ret != WIFI_NO_ERROR) {
298         ESSetState(ES_STATE_FAILED_TO_CONNECT_TO_ENROLLER);
299
300         if(ret == WIFI_NOTFOUND_SSID_ERROR) {
301             ESSetErrorCode(ES_ERRCODE_SSID_NOT_FOUND);
302         }
303         else if(ret == WIFI_WRONG_PWD_ERROR) {
304             ESSetErrorCode(ES_ERRCODE_PW_WRONG);
305         }
306         else {
307             ESSetErrorCode(ES_ERRCODE_TIMEOUT);
308         }
309         cout << "WiFi Connection Error" << endl;
310         return;
311     }
312     else {
313         cout << "WIFI Connection Success" << endl;
314         ESSetState(ES_STATE_CONNECTED_TO_ENROLLER);
315         ESSetErrorCode(ES_ERRCODE_NO_ERROR);
316     }
317 }
318
319 gboolean mainThread(GIOChannel *source, GIOCondition condition, gpointer data)
320 {
321     char entered;
322     cin >> entered;
323     cin.ignore(numeric_limits<streamsize>::max(), '\n');
324
325     switch (entered) {
326         case 'Q': // quit
327         case 'q':
328             StopEasySetup();
329             break;
330
331         case 'A': // Enable Security
332         case 'a':
333 #ifdef __WITH_DTLS__
334             EnableSecurity();
335 #else
336             cout << "Sample is not built with secured mode" << endl;
337 #endif
338             PrintMenu();
339             break;
340
341         case 'B': // Init EasySetup
342         case 'b':
343             StartEasySetup();
344             PrintMenu();
345             break;
346
347         case 'C': // Set Device Info
348         case 'c':
349             SetDeviceInfo();
350             PrintMenu();
351             break;
352
353         case 'D': // Start to connect target AP
354         case 'd':
355             ConnectToTargetAP();
356             PrintMenu();
357             break;
358
359         case 'E': // Print Menu
360         case 'e':
361             PrintMenu();
362             break;
363
364         default:
365             cout << "Wrong option" << endl;
366             PrintMenu();
367             break;
368     }
369
370     if(entered == 'q' || entered == 'Q'){
371         g_main_loop_quit(gMainloop);
372     }
373
374     return TRUE;
375 }
376
377 int main()
378 {
379     cout << "#########################" << endl;
380     cout << "EasySetup Enrollee SAMPLE" << endl;
381     cout << "#########################" << endl;
382     PrintMenu();
383
384     gMainloop = g_main_loop_new (NULL, FALSE);
385     if(gMainloop == NULL) {
386         cout << "Create Main Loop Error" << endl;
387         return 0;
388     }
389
390     GIOChannel *channel = g_io_channel_unix_new(0);
391     g_io_add_watch(channel, (GIOCondition)(G_IO_IN|G_IO_ERR|G_IO_HUP|G_IO_NVAL), mainThread, NULL);
392
393     g_main_loop_run (gMainloop);
394
395     cout << "#########################" << endl;
396     cout << "Terminate Enrollee SAMPLE" << endl;
397     cout << "#########################" << endl;
398
399     return 0;
400 }
401
402 void *listeningFunc(void*)
403 {
404     OCStackResult result;
405
406     while (true)
407     {
408         result = OCProcess();
409         if (result != OC_STACK_OK)
410         {
411            cout<<"OCStack stop error";
412         }
413     }
414     return NULL;
415 }
416