b26bc9112416616cbc4641ca64cd9f92c370b53c
[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     if(InitProvisioning()== ES_ERROR)
192     {
193         OC_LOG(ERROR, TAG, "Init Provisioning Failed");
194         return;
195     }
196 }
197
198 void StopEasySetup()
199 {
200     OC_LOG(DEBUG, TAG, "Stopping EasySetup is invoked...");
201
202     g_isInitialized = false;
203
204     if(TerminateEasySetup()== ES_ERROR)
205     {
206         OC_LOG(ERROR, TAG, "TerminateEasySetup Failed");
207         return;
208     }
209 }
210
211
212 //The setup function is called once at startup of the sketch
213 void setup()
214 {
215     // Add your initialization code here
216     // Note : This will initialize Serial port on Arduino at 115200 bauds
217     OC_LOG_INIT();
218
219     Serial.println("#########################");
220     Serial.println("EasySetup Enrollee SAMPLE");
221     Serial.println("#########################");
222     PrintMenu();
223 }
224
225 // The loop function is called in an endless loop
226 void loop()
227 {
228     char buffer[5] = {0};
229     size_t len;
230     if (Serial.available() > 0)
231     {
232         GetData(buffer, sizeof(buffer), &len);
233         if (0 >= len)
234         {
235             Serial.println("Input Error err");
236             return;
237         }
238         switch (toupper(buffer[0]))
239         {
240             case 'H': // help
241                 PrintMenu();
242                 break;
243
244             case 'Q': // quit
245                 Serial.println("quit");
246                 return;
247
248             case 'S': // start easy setup
249                 StartEasySetup();
250                 break;
251
252             case 'P': // start provisioning
253                 StartProvisioning();
254                 break;
255
256             case 'T': // stop easy setup
257                 StopEasySetup();
258                 break;
259
260             default:
261                 Serial.println("wrong option");
262                 break;
263         }
264     }
265
266     //check g_isInitialized to see if stack init is success
267     if (g_isInitialized)
268     {
269         // This call displays the amount of free SRAM available on Arduino
270         PrintArduinoMemoryStats();
271         if (WiFi.status() == WL_CONNECTED)
272             is_connected = true;
273         else if (is_connected)
274             TerminateEasySetup();
275
276         // Give CPU cycles to OCStack to perform send/recv and other OCStack stuff
277         if (OCProcess() != OC_STACK_OK)
278         {
279             OC_LOG(ERROR, TAG, "OCStack process error");
280             return;
281         }
282     }
283
284     // This artificial delay is kept here to avoid endless spinning
285     // of Arduino microcontroller. Modify it as per specific application needs.
286     delay(2000);
287 }