Imported Upstream version 0.9.1
[platform/upstream/iotivity.git] / service / soft-sensor-manager / SampleApp / arduino / Trackee_Thing / src / trackee.cpp
1 /******************************************************************
2 *
3 * Copyright 2014 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
23 // Do not remove the include below
24 #include "Arduino.h"
25 #include "bleLib.h"
26 #include <stdio.h>
27
28 #include "logger.h"
29 #include "ocstack.h"
30 #include <string.h>
31
32 #include "oic_lanLib.h"
33 #include "trackee.h"
34
35 // proximity code s
36 #define DATA_EA     400
37 #define SLAVER_EA   2
38
39 #define ARDUINO_AVR_MEGA2560 1
40 /// This is the port which Arduino Server will use for all unicast communication with it's peers
41 #define OC_WELL_KNOWN_PORT 5683
42
43 PROGMEM const char TAG[] = "TrackeeSensor";
44
45 OCResourceHandle m_handle;
46
47 #if (ARDUINO == 0)
48 #include "proximity.h"
49
50 #define JSON_BASE "{\"href\":\"\",\"rep\":{"
51 #define JSON_BASE00 "\"0\":\"trackeeID\",\"1\":\"string\",\"2\":\""
52 #define JSON_BASE01 "\",\"3\":\"things\",\"4\":\"int\",\"5\":\""
53 #define JSON_BASE02 "\",\"6\":\"ID\",\"7\":\"string\",\"8\":\""
54 #define JSON_BASE03 "\",\"9\":\"distance\",\"10\":\"float\",\"11\":\""
55 #define JSON_BASE04 "\",\"12\":\"proximity\",\"13\":\"int\",\"14\":\""
56 #define JSON_BASE05 "\",\"15\":\"SD\",\"16\":\"float\",\"17\":\""
57 #define JSON_BASE06 "\",\"18\":\"ID\",\"19\":\"string\",\"20\":\""
58 #define JSON_BASE07 "\",\"21\":\"distance\",\"22\":\"float\",\"23\":\""
59 #define JSON_BASE08 "\",\"24\":\"proximity\",\"25\":\"int\",\"26\":\""
60 #define JSON_BASE09 "\",\"27\":\"SD\",\"28\":\"float\",\"29\":\""
61 #define JSON_BASE10 "\"}}"
62
63 typedef struct PROXIRESOURCE
64 {
65     float m_distance[SLAVER_EA];
66     float m_proximity[SLAVER_EA];
67 } PROXIResource;
68
69 PROXIResource PROXI;
70
71 int rssi[SLAVER_EA][arraysize];
72 int rssicnt[SLAVER_EA] = {0,};
73 int startindex[SLAVER_EA] = {0,};
74 int flag[SLAVER_EA] = {0,};
75 //#else
76 //bool bleWrite = true;
77 #endif
78
79 Cble ble;
80 //char trackeeID[13] = "9059AF170C1D";
81 char trackeeID[13] = "9059AF16FEF7";
82 int slaver_num = 0;
83 //char slaveList[SLAVER_EA][13]={"9059AF1704D7"};
84 char slaveList[SLAVER_EA][13] = {"9059AF1700EE", "34B1F7D004D2"};
85 int g_PROXIUnderObservation = 0;
86
87
88
89 const char *getResult(OCStackResult result);
90 void createResource();
91
92
93 #define LENGTH_VAR      50
94 bool JsonGenerator( char *jsonBuf, uint16_t buf_length )
95 {
96     if ( g_PROXIUnderObservation == 1 )
97     {
98 #if (ARDUINO == 0)
99         PROXIResource *ref = &PROXI;
100         int ref_cnt = SLAVER_EA;
101         uint16_t base_length = 0;
102         base_length = strlen(JSON_BASE) + strlen(JSON_BASE00) + strlen(JSON_BASE01) + strlen(
103                           JSON_BASE02) + strlen(JSON_BASE03) + \
104                       strlen(JSON_BASE04) + strlen(JSON_BASE05) + strlen(JSON_BASE06) + strlen(JSON_BASE07) + \
105                       strlen(JSON_BASE08) + strlen(JSON_BASE09) + strlen(JSON_BASE10);
106
107 //      base_length = strlen(JSON_BASE00)+ strlen(JSON_BASE01)+ strlen(JSON_BASE02)+ strlen(JSON_BASE03)+\
108 //                    strlen(JSON_BASE04)+ strlen(JSON_BASE05)+ strlen(JSON_BASE10);
109
110         OC_LOG_V(INFO, TAG, "base length = %d, buf_length=%d", base_length, buf_length );
111
112         if ( ((long)buf_length - (long)base_length) < LENGTH_VAR )
113         {
114             OC_LOG_V(ERROR, TAG, "Error : length is very long.");
115             return false;
116         }
117
118         sprintf(jsonBuf, JSON_BASE );
119         sprintf(jsonBuf + strlen(jsonBuf), JSON_BASE00"%s"JSON_BASE01"%d", trackeeID, ref_cnt);
120         sprintf(jsonBuf + strlen(jsonBuf), JSON_BASE02"%s"JSON_BASE03"%d.%03d", slaveList[0],
121                 (int)ref->m_distance[0], (int)((ref->m_distance[0] - (int)ref->m_distance[0]) * 1000.0) );
122         sprintf(jsonBuf + strlen(jsonBuf), JSON_BASE04"%d"JSON_BASE05"0.0", (int)ref->m_proximity[0] );
123         sprintf(jsonBuf + strlen(jsonBuf), JSON_BASE06"%s"JSON_BASE07"%d.%03d", slaveList[1],
124                 (int)ref->m_distance[1], (int)((ref->m_distance[1] - (int)ref->m_distance[1]) * 1000.0) );
125         sprintf(jsonBuf + strlen(jsonBuf), JSON_BASE08"%d"JSON_BASE09"0.0", (int)ref->m_proximity[1] );
126         strcpy(jsonBuf + strlen(jsonBuf), JSON_BASE10 );
127
128         OC_LOG_V(INFO, TAG, "json length = %u", strlen(jsonBuf) );
129
130         return true;
131
132 #else       // Slave Json Code.
133
134         return true;
135 #endif
136     }
137
138     OC_LOG_V(INFO, TAG, "Not Support Observer unfounded mode." );
139     return false;
140 }
141
142
143 // On Arduino Atmel boards with Harvard memory architecture, the stack grows
144 // downwards from the top and the heap grows upwards. This method will print
145 // the distance(in terms of bytes) between those two.
146 // See here for more details :
147 // http://www.atmel.com/webdoc/AVRLibcReferenceManual/malloc_1malloc_intro.html
148 void PrintArduinoMemoryStats()
149 {
150 #ifdef ARDUINO_AVR_MEGA2560
151     //This var is declared in avr-libc/stdlib/malloc.c
152     //It keeps the largest address not allocated for heap
153     extern char *__brkval;
154     //address of tmp gives us the current stack boundry
155     int tmp;
156     OC_LOG_V(INFO, TAG, "Stack: %u         Heap: %u", (unsigned int)&tmp, (unsigned int)__brkval);
157     OC_LOG_V(INFO, TAG, "Unallocated Memory between heap and stack: %u",
158              ((unsigned int)&tmp - (unsigned int)__brkval));
159 #endif
160 }
161
162 // This is the entity handler for the registered resource.
163 // This is invoked by OCStack whenever it recevies a request for this resource.
164 OCEntityHandlerResult OCEntityHandlerCb(OCEntityHandlerFlag flag,
165                                         OCEntityHandlerRequest *entityHandlerRequest )
166 {
167     OCEntityHandlerResult ehRet = OC_EH_OK;
168
169     if (entityHandlerRequest && (flag & OC_REQUEST_FLAG))
170     {
171         OC_LOG (INFO, TAG, PCF("Flag includes OC_REQUEST_FLAG"));
172         if (OC_REST_GET == entityHandlerRequest->method)
173         {
174             if (JsonGenerator((char *)entityHandlerRequest->resJSONPayload, \
175                               entityHandlerRequest->resJSONPayloadLen))
176             {
177             }
178             else
179             {
180                 ehRet = OC_EH_ERROR;
181             }
182         }
183         if (OC_REST_PUT == entityHandlerRequest->method)
184         {
185             //Do something with the 'put' payload
186             if (JsonGenerator((char *)entityHandlerRequest->resJSONPayload, \
187                               entityHandlerRequest->resJSONPayloadLen))
188             {
189             }
190             else
191             {
192                 ehRet = OC_EH_ERROR;
193             }
194         }
195     }
196     if (entityHandlerRequest && (flag & OC_OBSERVE_FLAG))
197     {
198         if (OC_OBSERVE_REGISTER == entityHandlerRequest->obsInfo->action)
199         {
200             OC_LOG (INFO, TAG, PCF("Received OC_OBSERVE_REGISTER from client"));
201             g_PROXIUnderObservation = 1;
202         }
203         else if (OC_OBSERVE_DEREGISTER == entityHandlerRequest->obsInfo->action)
204         {
205             OC_LOG (INFO, TAG, PCF("Received OC_OBSERVE_DEREGISTER from client"));
206         }
207     }
208
209     return ehRet;
210 }
211
212
213 #if (ARDUINO == 0)
214 void ChangePROXIRepresentation (void *param)
215 {
216     (void)param;
217     OCStackResult result = OC_STACK_ERROR;
218     float avg[SLAVER_EA] = {0,};
219
220     for (int i = 0; i < SLAVER_EA; i++)
221     {
222         if ( rssicnt[i] > arraysize - 1)
223         {
224             rssicnt[i] = rssicnt[i] % arraysize;
225         }
226
227         ble.streamDummy(NULL, NULL);
228         /*  if( ble.pollingConnect(&slaveList[slaver_num][0]) == false )
229             {
230                 OC_LOG_V("Error : Not Connected.\r\n");
231             }*/
232         while (ble.pollingConnect(&slaveList[slaver_num][0]) == false)
233         {
234             ble.streamDummy(NULL, NULL);
235         }
236
237         if ( ble.IsConnected() == true )
238         {
239             // print the string when a newline arrives:
240             OC_LOG_V(INFO, TAG, "Connected. (%s)\r\n", slaveList[slaver_num]);
241
242 //          time = millis();
243             for (int j = 0; j < RSSI_EA; j++)
244             {
245                 rssi[i][rssicnt[i]] = ble.pollingGetRSSI();
246                 OC_LOG_V(INFO, TAG, "rssi val : %d \r\n", rssi[i][rssicnt[i]]);
247                 rssicnt[i]++;
248             }
249 //          oldTime = millis();
250 //          float TpR = (float)(((oldTime-time)/1000.0)/20.0);
251 //          OC_LOG_V("time per rssi : %d.%03d\r\n", (int)TpR, (int)(TpR*1000.0 -((int)TpR)*1000.0) );
252
253             while ( ble.IsSelfArduino() == false )
254                 ble.pollingDisconnect();
255
256             slaver_num++;
257             slaver_num = slaver_num % SLAVER_EA;
258         }
259
260         avg[i] = CalculateExponentialAverage(RSSI_EA, rssi[i], startindex[i], flag[i]);
261         Serial.println(avg[i]);
262         Serial.print("distance : ");
263
264         PROXI.m_distance[i] = calculateDistance(avg[i], -58);
265
266         if (PROXI.m_distance[i] <= 1)
267         {
268             PROXI.m_proximity[i] = 1;
269         }
270         else if (PROXI.m_distance[i] <= 2)
271         {
272             PROXI.m_proximity[i] = 2;
273         }
274         else
275         {
276             PROXI.m_proximity[i] = 3;
277         }
278
279         Serial.println(PROXI.m_distance[i]);
280         Serial.println(PROXI.m_proximity[i]);
281         //Serial.println(calculateDistance(avg[i], -58));
282         startindex[i] += RSSI_EA;
283
284         // This call displays the amount of free SRAM available on Arduino
285         PrintArduinoMemoryStats();
286
287         if (startindex[i] >= arraysize)
288         {
289             startindex[i] = 0;
290         }
291
292         if (flag[i] < (arraysize / RSSI_EA))
293         {
294             flag[i]++;
295         }
296     }
297
298     result = OCNotifyAllObservers (m_handle, OC_NA_QOS);
299
300     if (OC_STACK_NO_OBSERVERS == result)
301     {
302         OC_LOG_V(INFO, TAG, "g_PROXIUnderObservation is 0." );
303         g_PROXIUnderObservation = 0;
304     }
305
306 }
307 #endif
308
309
310
311
312 //The setup function is called once at startup of the sketch
313 void setup()
314 {
315     Serial.begin(115200);
316
317     // Add your initialization code here
318     OC_LOG_INIT();
319
320     OC_LOG(DEBUG, TAG, PCF("OCServer is starting..."));
321     //    uint16_t port = OC_WELL_KNOWN_PORT;
322
323     // Connect to Ethernet or WiFi network
324     if (ConnectToNetwork() != 0)
325     {
326         OC_LOG(ERROR, TAG, "Unable to connect to network");
327         return;
328     }
329
330     // Initialize the OC Stack in Server mode
331     if (OCInit(NULL, OC_WELL_KNOWN_PORT, OC_SERVER) != OC_STACK_OK)
332     {
333         OC_LOG(ERROR, TAG, PCF("OCStack init error"));
334         return;
335     }
336
337     OCStartPresence(60);
338     // Declare and create the example resource
339     createResource();
340
341     // This call displays the amount of free SRAM available on Arduino
342     PrintArduinoMemoryStats();
343 #if (ARDUINO == 0)
344     ble.init( (long)115200, BLE_MASTER, trackeeID);
345 #elif (ARDUINO == 1)
346     ble.init( (long)115200, BLE_SLAVER, slaveList[0]);
347 #elif (ARDUINO == 2)
348     ble.init( (long)115200, BLE_SLAVER, slaveList[1]);
349 #endif
350
351 //  ble.StatusRead();
352
353     OC_LOG_V(INFO, TAG, "Program Start-\r\n");
354 }
355
356
357 // The loop function is called in an endless loop
358 void loop()
359 {
360     // This artificial delay is kept here to avoid endless spinning
361     // of Arduino microcontroller. Modify it as per specfic application needs.
362
363     if (OCProcess() != OC_STACK_OK)
364     {
365         OC_LOG(ERROR, TAG, PCF("OCStack process error"));
366         return;
367     }
368 #if (ARDUINO == 0)
369     ChangePROXIRepresentation(NULL);
370 #else
371     char *user_cmd = NULL;
372
373 //  ble.pollingDisconnect();
374
375     user_cmd = ble.Debug2BLE(true);
376     ble.BLE2Debug( true );
377
378     if ( user_cmd )
379     {
380         free( user_cmd );
381         user_cmd = NULL;
382     }
383
384 #endif
385 }
386
387
388
389
390
391
392
393 void createResource()
394 {
395
396     OCStackResult res = OCCreateResource(&m_handle,
397                                          "SSManager.Sensor",
398                                          OC_RSRVD_INTERFACE_DEFAULT,
399                                          "/Tracker_Thing",
400                                          OCEntityHandlerCb,
401                                          OC_DISCOVERABLE | OC_OBSERVABLE);
402     OC_LOG_V(INFO, TAG, "Created PROXI resource with result: %s", getResult(res));
403 }
404
405 const char *getResult(OCStackResult result)
406 {
407     switch (result)
408     {
409         case OC_STACK_OK:
410             return "OC_STACK_OK";
411         case OC_STACK_INVALID_URI:
412             return "OC_STACK_INVALID_URI";
413         case OC_STACK_INVALID_QUERY:
414             return "OC_STACK_INVALID_QUERY";
415         case OC_STACK_INVALID_IP:
416             return "OC_STACK_INVALID_IP";
417         case OC_STACK_INVALID_PORT:
418             return "OC_STACK_INVALID_PORT";
419         case OC_STACK_INVALID_CALLBACK:
420             return "OC_STACK_INVALID_CALLBACK";
421         case OC_STACK_INVALID_METHOD:
422             return "OC_STACK_INVALID_METHOD";
423         case OC_STACK_NO_MEMORY:
424             return "OC_STACK_NO_MEMORY";
425         case OC_STACK_COMM_ERROR:
426             return "OC_STACK_COMM_ERROR";
427         case OC_STACK_INVALID_PARAM:
428             return "OC_STACK_INVALID_PARAM";
429         case OC_STACK_NOTIMPL:
430             return "OC_STACK_NOTIMPL";
431         case OC_STACK_NO_RESOURCE:
432             return "OC_STACK_NO_RESOURCE";
433         case OC_STACK_RESOURCE_ERROR:
434             return "OC_STACK_RESOURCE_ERROR";
435         case OC_STACK_SLOW_RESOURCE:
436             return "OC_STACK_SLOW_RESOURCE";
437         case OC_STACK_NO_OBSERVERS:
438             return "OC_STACK_NO_OBSERVERS";
439         case OC_STACK_ERROR:
440             return "OC_STACK_ERROR";
441         default:
442             return "UNKNOWN";
443     }
444 }
445