Merge "Merge branch 'master' into notification-service" into notification-service
[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 WiFiProvCbInApp(ESWiFiProvData *eventData)
74 {
75     cout << "WiFiProvCbInApp IN" << endl;
76     gWiFiCBflag = true;
77
78     ESSetState(ES_STATE_CONNECTING_TO_ENROLLER);
79
80     if(eventData == NULL)
81     {
82         cout << "ESWiFiProvData is NULL" << endl;
83         return ;
84     }
85
86     cout << "SSID : " << eventData->ssid << endl;
87     cout << "Password : " << eventData->pwd << endl;
88     cout << "AuthType : " << eventData->authtype << endl;
89     cout << "EncType : " << eventData->enctype << endl;
90
91     memset(gSSID, 0, OIC_STRING_MAX_VALUE);
92     memset(gPasswd, 0, OIC_STRING_MAX_VALUE);
93     if(eventData->ssid != NULL)
94     {
95         strncpy(gSSID, eventData->ssid, strlen(eventData->ssid));
96     }
97
98     if(eventData->pwd != NULL)
99     {
100         strncpy(gPasswd, eventData->pwd, strlen(eventData->pwd));
101     }
102
103     cout << "WiFiProvCbInApp OUT" << endl;
104     PrintMenu();
105 }
106
107 void DevConfProvCbInApp(ESDevConfProvData *eventData)
108 {
109     cout << "DevConfProvCbInApp IN" << endl;
110
111     if(eventData == NULL)
112     {
113         cout << "ESDevConfProvData is NULL" << endl;
114         return ;
115     }
116
117     cout << "Language : " << eventData->language << endl;
118     cout << "Country : " << eventData->country << endl;
119     cout << "DevConfProvCbInApp OUT" << endl;
120     PrintMenu();
121 }
122
123 void CloudDataProvCbInApp(ESCloudProvData *eventData)
124 {
125     cout << "CloudDataProvCbInApp IN" << endl;
126
127     if(eventData == NULL)
128     {
129         cout << "ESCloudProvData is NULL" << endl;
130         return ;
131     }
132
133     cout << "AuthCode : " << eventData->authCode << endl;
134     cout << "AuthProvider : " << eventData->authProvider << endl;
135     cout << "CI Server : " << eventData->ciServer << endl;
136     cout << "CloudDataProvCbInApp OUT" << endl;
137     PrintMenu();
138 }
139
140 ESProvisioningCallbacks gCallbacks = {
141     .WiFiProvCb = &WiFiProvCbInApp,
142     .DevConfProvCb = &DevConfProvCbInApp,
143     .CloudDataProvCb = &CloudDataProvCbInApp
144 };
145
146 FILE* server_fopen(const char *path, const char *mode)
147 {
148     (void) path;
149     return fopen(CRED_FILE, mode);
150 }
151
152 void EnableSecurity()
153 {
154     printf("Inside EnableSecurity API..\n");
155
156     gIsSecured = true;
157
158     // Initialize Persistent Storage for SVR database
159     ps = (OCPersistentStorage){ server_fopen, fread, fwrite, fclose, unlink };
160     OCRegisterPersistentStorageHandler(&ps);
161 }
162
163 void StartEasySetup()
164 {
165     cout << "StartEasySetup IN" << endl;
166
167     if (OCInit(NULL, 0, OC_SERVER) != OC_STACK_OK)
168     {
169         cout << "OCStack init error!!" << endl;
170         return;
171     }
172
173     ESResourceMask resourcemMask = (ESResourceMask) (ES_WIFI_RESOURCE | ES_CLOUD_RESOURCE | ES_DEVCONF_RESOURCE);
174     cout << "resourcemMask : " << resourcemMask << endl;
175     if(ESInitEnrollee(gIsSecured, resourcemMask, gCallbacks) != ES_OK)
176     {
177         cout << "OCStack init error!!" << endl;
178         return;
179     }
180
181     cout << "ESInitEnrollee Success" << endl;
182
183     if(gThreadHandle == 0) {
184
185         if (pthread_create(&gThreadHandle, NULL, listeningFunc, NULL)) {
186             cout << "Thread creation failed" << endl;
187             return;
188         }
189
190     }
191
192     ESSetState(ES_STATE_INIT);
193     ESSetErrorCode(ES_ERRCODE_NO_ERROR);
194
195     int ret = 0;
196
197     ret = TizenWiFiInit();
198     if(ret != WIFI_NO_ERROR) {
199         cout << "WiFi Init Error" << endl;
200     }
201     else
202         cout << "WiFi Init Success" << endl;
203
204     ret = TizenWiFiScanStart();
205     if(ret != WIFI_NO_ERROR) {
206         cout << "WiFi Scan Error" << endl;
207     }
208     else
209         cout << "WiFi Scan Success" << endl;
210
211     cout << "StartEasySetup OUT" << endl;
212 }
213
214 void SetDeviceInfo()
215 {
216     cout << "SetDeviceInfo IN" << endl;
217
218     ESDeviceProperty deviceProperty = {
219         {{WIFI_11G, WIFI_11N, WIFI_11AC, WiFi_EOF}, WIFI_5G}, {"Tizen Device"}
220     };
221
222     if(ESSetDeviceProperty(&deviceProperty) == ES_ERROR)
223     {
224         cout << "ESSetDeviceProperty Error" << endl;
225     }
226
227     // Set user properties if needed
228
229     cout << "SetDeviceInfo OUT" << endl;
230 }
231
232 void StopEasySetup()
233 {
234     cout << "StopEasySetup IN" << endl;
235     if (ESTerminateEnrollee() == ES_ERROR)
236     {
237         cout << "ESTerminateEnrollee Failed!!" << endl;
238         return;
239     }
240
241     // Deinit Tizen Wifi
242     TizenWiFiDeinit();
243
244     // Stop OC Stack
245     if (OCStop() != OC_STACK_OK)
246     {
247         cout << "OCStack stop failed!!" << endl;
248         return;
249     }
250
251     if(gThreadHandle != 0) {
252         pthread_cancel(gThreadHandle);
253         pthread_join(gThreadHandle, NULL);
254     }
255
256     cout << "StopEasySetup OUT" << endl;
257 }
258
259 void ConnectToTargetAP()
260 {
261     if(!gWiFiCBflag){
262         cout << "WiFi Provisioning is needed to be preceded" << endl;
263         return;
264     }
265
266     WiFiConnErrCode ret = WIFI_NO_ERROR;
267     ret = TizenWiFiScanStart();
268     if(ret != WIFI_NO_ERROR){
269         ESSetState(ES_STATE_CONNECTED_FAIL_TO_ENROLLER);
270         ESSetErrorCode(ES_ERRCODE_UNKNOWN);
271         cout << "WiFi Scan Error" << endl;
272         return;
273     }
274     else{
275         cout << "WiFi Scan Succss" << endl;
276     }
277
278     ret = TizenWiFiConn(gSSID, gPasswd);
279     if(ret != WIFI_NO_ERROR) {
280         ESSetState(ES_STATE_CONNECTED_FAIL_TO_ENROLLER);
281
282         if(ret == WIFI_NOTFOUND_SSID_ERROR) {
283             ESSetErrorCode(ES_ERRCODE_SSID_NOT_FOUND);
284         }
285         else if(ret == WIFI_WRONG_PWD_ERROR) {
286             ESSetErrorCode(ES_ERRCODE_PW_WRONG);
287         }
288         else {
289             ESSetErrorCode(ES_ERRCODE_TIMEOUT);
290         }
291         cout << "WiFi Connection Error" << endl;
292         return;
293     }
294     else {
295         cout << "WIFI Connection Success" << endl;
296         ESSetState(ES_STATE_CONNECTED_TO_ENROLLER);
297         ESSetErrorCode(ES_ERRCODE_NO_ERROR);
298     }
299 }
300
301 gboolean mainThread(GIOChannel *source, GIOCondition condition, gpointer data)
302 {
303     char entered;
304     cin >> entered;
305     cin.ignore(numeric_limits<streamsize>::max(), '\n');
306
307     switch (entered) {
308         case 'Q': // quit
309         case 'q':
310             StopEasySetup();
311             break;
312
313         case 'A': // Enable Security
314         case 'a':
315 #ifdef __WITH_DTLS__
316             EnableSecurity();
317 #else
318             cout << "Sample is not built with secured mode" << endl;
319 #endif
320             PrintMenu();
321             break;
322
323         case 'B': // Init EasySetup
324         case 'b':
325             StartEasySetup();
326             PrintMenu();
327             break;
328
329         case 'C': // Set Device Info
330         case 'c':
331             SetDeviceInfo();
332             PrintMenu();
333             break;
334
335         case 'D': // Start to connect target AP
336         case 'd':
337             ConnectToTargetAP();
338             PrintMenu();
339             break;
340
341         case 'E': // Print Menu
342         case 'e':
343             PrintMenu();
344             break;
345
346         default:
347             cout << "Wrong option" << endl;
348             PrintMenu();
349             break;
350     }
351
352     if(entered == 'q' || entered == 'Q'){
353         g_main_loop_quit(gMainloop);
354     }
355
356     return TRUE;
357 }
358
359 int main()
360 {
361     cout << "#########################" << endl;
362     cout << "EasySetup Enrollee SAMPLE" << endl;
363     cout << "#########################" << endl;
364     PrintMenu();
365
366     gMainloop = g_main_loop_new (NULL, FALSE);
367     if(gMainloop == NULL) {
368         cout << "Create Min Loop Error" << endl;
369         return 0;
370     }
371
372     GIOChannel *channel = g_io_channel_unix_new(0);
373     g_io_add_watch(channel, (GIOCondition)(G_IO_IN|G_IO_ERR|G_IO_HUP|G_IO_NVAL), mainThread, NULL);
374
375     g_main_loop_run (gMainloop);
376
377     cout << "#########################" << endl;
378     cout << "Terminate Enrollee SAMPLE" << endl;
379     cout << "#########################" << endl;
380
381     return 0;
382 }
383
384 void *listeningFunc(void*)
385 {
386     OCStackResult result;
387
388     while (true)
389     {
390         result = OCProcess();
391         if (result != OC_STACK_OK)
392         {
393            cout<<"OCStack stop error";
394         }
395     }
396     return NULL;
397 }
398