Restructuring of the easy-setup service.
[platform/upstream/iotivity.git] / service / easy-setup / sampleapp / enrollee / arduino / enrolleewifi.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 "Arduino.h"
22
23 #include "logger.h"
24 #include <string.h>
25
26 #ifdef ARDUINOWIFI
27 // Arduino WiFi Shield
28 #include <SPI.h>
29 #include <WiFi.h>
30 #include <WiFiUdp.h>
31 #else
32 // Arduino Ethernet Shield
33 #include <EthernetServer.h>
34 #include <Ethernet.h>
35 #include <Dns.h>
36 #include <EthernetClient.h>
37 #include <util.h>
38 #include <EthernetUdp.h>
39 #include <Dhcp.h>
40 #endif
41
42 #include "easysetup.h"
43
44 #define TAG "TS"
45
46 const char *getResult(OCStackResult result);
47
48 /**
49  * @var ssid
50  * @brief Target SSID of the Soft Access point to which the device has to connect
51  */
52 static char ssid[] = "EasySetup123";
53
54 /**
55  * @var passwd
56  * @brief Password of the Soft Access point to which the device has to connect
57  */
58 static char passwd[] = "EasySetup123";
59
60 /**
61  * @var g_OnBoardingSucceeded
62  * @brief This variable will be set if OnBoarding is successful
63  */
64 static bool g_OnBoardingSucceeded = false;
65
66 /**
67  * @var g_ProvisioningSucceeded
68  * @brief This variable will be set if Provisioning is successful
69  */
70 static bool g_ProvisioningSucceeded = false;
71
72 static bool g_isInitialized = false;
73
74 bool is_connected=false;
75
76 void GetData(char *readInput, size_t bufferLength, size_t *dataLength)
77 {
78     if (!readInput || bufferLength == 0 || !dataLength)
79     {
80         Serial.println("Invalid buffer");
81         return;
82     }
83
84     while (!Serial.available())
85     {
86         delay(500);
87     }
88     int len = 0;
89     while (Serial.available())
90     {
91         delay(100);
92         char c = Serial.read();
93         if ('\n' != c && '\r' != c && len < bufferLength - 1)
94         {
95             readInput[len++] = c;
96         }
97         else
98         {
99             break;
100         }
101     }
102
103     readInput[len] = '\0';
104     Serial.flush();
105     Serial.print("PD: ");
106     Serial.println(readInput);
107     (*dataLength) = len;
108 }
109
110 void PrintMenu()
111 {
112     Serial.println("============");
113     Serial.println("s: start easy setup");
114     Serial.println("p: start provisioning resources");
115     Serial.println("t: terminate");
116     Serial.println("q: quit");
117     Serial.println("============");
118 }
119
120 void EventCallbackInApp(ESResult esResult, EnrolleeState enrolleeState)
121 {
122     Serial.println("callback!!! in app");
123
124     if(esResult == ES_OK)
125     {
126         if(!g_OnBoardingSucceeded){
127             Serial.println("Device is successfully OnBoarded");
128             g_OnBoardingSucceeded = true;
129         }
130         else if(g_OnBoardingSucceeded & enrolleeState == ES_ON_BOARDED_STATE){
131             Serial.println("Device is successfully OnBoared with SoftAP");
132             g_ProvisioningSucceeded = true;
133         }
134     }
135     else if (esResult == ES_ERROR)
136     {
137         if(g_OnBoardingSucceeded)
138         {
139             OC_LOG_V(ERROR, TAG, "Failure in Provisioning. \
140                                         Current Enrollee State: %d",enrolleeState);
141             g_OnBoardingSucceeded = false;
142         }
143         else if(g_ProvisioningSucceeded)
144         {
145             OC_LOG_V(ERROR, TAG, "Failure in connect to target network. \
146                                         Current Enrollee State: %d",enrolleeState);
147             g_ProvisioningSucceeded = false;
148         }
149     }
150     PrintMenu();
151 }
152
153 // On Arduino Atmel boards with Harvard memory architecture, the stack grows
154 // downwards from the top and the heap grows upwards. This method will print
155 // the distance(in terms of bytes) between those two.
156 // See here for more details :
157 // http://www.atmel.com/webdoc/AVRLibcReferenceManual/malloc_1malloc_intro.html
158 void PrintArduinoMemoryStats()
159 {
160 #ifdef ARDUINO_AVR_MEGA2560
161     //This var is declared in avr-libc/stdlib/malloc.c
162     //It keeps the largest address not allocated for heap
163     extern char *__brkval;
164     //address of tmp gives us the current stack boundry
165     int tmp;
166     OC_LOG_V(INFO, TAG, "Stack: %u         Heap: %u", (unsigned int)&tmp, (unsigned int)__brkval);
167     OC_LOG_V(INFO, TAG, "Unallocated Memory between heap and stack: %u",
168             ((unsigned int)&tmp - (unsigned int)__brkval));
169 #endif
170 }
171
172 void StartEasySetup()
173 {
174     OC_LOG(DEBUG, TAG, "OCServer is starting...");
175
176     if(InitEasySetup(CT_ADAPTER_IP, ssid, passwd, EventCallbackInApp) == ES_ERROR)
177     {
178         OC_LOG(ERROR, TAG, "OnBoarding Failed");
179         return;
180     }
181
182     g_isInitialized = true;
183
184     OC_LOG_V(ERROR, TAG, "OnBoarding succeded. Successfully connected to ssid : %s",ssid);
185 }
186
187 void StartProvisioning()
188 {
189     OC_LOG(DEBUG, TAG, "StartProvisioning is invoked...");
190
191     // Initialize the OC Stack in Server mode
192     if (OCInit(NULL, 0, OC_SERVER) != OC_STACK_OK)
193     {
194         OC_LOG(ERROR, TAG, "OCStack init error!!");
195         return;
196     }
197
198     if (InitProvisioning() == ES_ERROR)
199     {
200         OC_LOG(ERROR, TAG, "Init Provisioning Failed!!");
201         return;
202     }
203 }
204
205 void StopEasySetup()
206 {
207     OC_LOG(DEBUG, TAG, "Stopping EasySetup is invoked...");
208
209     g_isInitialized = false;
210
211     if (TerminateEasySetup() == ES_ERROR)
212     {
213         OC_LOG(ERROR, TAG, "TerminateEasySetup Failed!!");
214         return;
215     }
216
217     //stop OC Stack
218     if (OCStop() != OC_STACK_OK)
219     {
220         OC_LOG(ERROR, TAG, "OCStack stop failed!!");
221         return;
222     }
223
224     OC_LOG(DEBUG, TAG, "Stopping EasySetup done");
225 }
226
227
228 //The setup function is called once at startup of the sketch
229 void setup()
230 {
231     // Add your initialization code here
232     // Note : This will initialize Serial port on Arduino at 115200 bauds
233     OC_LOG_INIT();
234
235     Serial.println("#########################");
236     Serial.println("EasySetup Enrollee SAMPLE");
237     Serial.println("#########################");
238     PrintMenu();
239 }
240
241 // The loop function is called in an endless loop
242 void loop()
243 {
244     char buffer[5] = {0};
245     size_t len;
246     if (Serial.available() > 0)
247     {
248         GetData(buffer, sizeof(buffer), &len);
249         if (0 >= len)
250         {
251             Serial.println("Input Error err");
252             return;
253         }
254         switch (toupper(buffer[0]))
255         {
256             case 'H': // help
257                 PrintMenu();
258                 break;
259
260             case 'Q': // quit
261                 Serial.println("quit");
262                 return;
263
264             case 'S': // start easy setup
265                 StartEasySetup();
266                 break;
267
268             case 'P': // start provisioning
269                 StartProvisioning();
270                 break;
271
272             case 'T': // stop easy setup
273                 StopEasySetup();
274                 break;
275
276             default:
277                 Serial.println("wrong option");
278                 break;
279         }
280     }
281
282     //check g_isInitialized to see if stack init is success
283     if (g_isInitialized)
284     {
285         // This call displays the amount of free SRAM available on Arduino
286         PrintArduinoMemoryStats();
287         if (WiFi.status() == WL_CONNECTED)
288             is_connected = true;
289         else if (is_connected)
290             TerminateEasySetup();
291
292         // Give CPU cycles to OCStack to perform send/recv and other OCStack stuff
293         if (OCProcess() != OC_STACK_OK)
294         {
295             OC_LOG(ERROR, TAG, "OCStack process error");
296             return;
297         }
298     }
299
300     // This artificial delay is kept here to avoid endless spinning
301     // of Arduino microcontroller. Modify it as per specific application needs.
302     delay(2000);
303 }