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