1 //******************************************************************
3 // Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved.
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
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
11 // http://www.apache.org/licenses/LICENSE-2.0
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.
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
23 // Do not remove the include below
32 #include "oic_lanLib.h"
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
43 PROGMEM const char TAG[] = "TrackeeSensor";
45 OCResourceHandle m_handle; // OIC base를 handling하기위해서 필요한 handler.
48 #include "proximity.h"
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 "\"}}"
63 typedef struct PROXIRESOURCE {
64 float m_distance[SLAVER_EA];
65 float m_proximity[SLAVER_EA];
70 int rssi[SLAVER_EA][arraysize];
71 int rssicnt[SLAVER_EA] = {0,};
72 int startindex[SLAVER_EA] = {0,};
73 int flag[SLAVER_EA] = {0,};
75 //bool bleWrite = true;
80 char trackeeID[13] = "9059AF16FEF7";
83 char slaveList[SLAVER_EA][13]={"9059AF1700EE","34B1F7D004D2"};
84 int g_PROXIUnderObservation = 0;
88 const char *getResult(OCStackResult result);
89 void createResource();
93 bool JsonGenerator( char* jsonBuf, uint16_t buf_length )
95 if( g_PROXIUnderObservation == 1 )
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);
105 OC_LOG_V(INFO, TAG, "base length = %d, buf_length=%d", base_length, buf_length );
107 if( ((long)buf_length - (long)base_length) < LENGTH_VAR )
109 OC_LOG_V(ERROR, TAG, "Error : length is very long.");
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 );
121 OC_LOG_V(INFO, TAG, "json length = %u", strlen(jsonBuf) );
125 #else // Slave Json Code.
131 OC_LOG_V(INFO, TAG, "Not Support Observer unfounded mode." );
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()
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
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));
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 )
159 OCEntityHandlerResult ehRet = OC_EH_OK;
160 OCEntityHandlerResponse response = {0};
161 char payload[MAX_RESPONSE_LENGTH] = {0};
163 if(entityHandlerRequest && (flag & OC_REQUEST_FLAG))
165 OC_LOG (INFO, TAG, PCF("Flag includes OC_REQUEST_FLAG"));
166 if(OC_REST_GET == entityHandlerRequest->method)
168 if(JsonGenerator(payload, MAX_RESPONSE_LENGTH))
176 if(OC_REST_PUT == entityHandlerRequest->method)
178 //Do something with the 'put' payload
179 if (JsonGenerator(payload, MAX_RESPONSE_LENGTH))
189 if (ehRet == OC_EH_OK)
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;
204 if (OCDoResponse(&response) != OC_STACK_OK)
206 OC_LOG(ERROR, TAG, "Error sending response");
211 if (entityHandlerRequest && (flag & OC_OBSERVE_FLAG))
213 if (OC_OBSERVE_REGISTER == entityHandlerRequest->obsInfo.action)
215 OC_LOG (INFO, TAG, PCF("Received OC_OBSERVE_REGISTER from client"));
216 g_PROXIUnderObservation = 1;
218 else if (OC_OBSERVE_DEREGISTER == entityHandlerRequest->obsInfo.action)
220 OC_LOG (INFO, TAG, PCF("Received OC_OBSERVE_DEREGISTER from client"));
228 void ChangePROXIRepresentation (void *param)
231 OCStackResult result = OC_STACK_ERROR;
232 float avg[SLAVER_EA] = {0,};
234 for(int i = 0; i < SLAVER_EA; i++)
236 if( rssicnt[i] > arraysize - 1)
238 rssicnt[i] = rssicnt[i] % arraysize;
241 ble.streamDummy(NULL, NULL);
243 while(ble.pollingConnect(&slaveList[slaver_num][0]) == false){
244 ble.streamDummy(NULL, NULL);
247 if( ble.IsConnected() == true )
249 // print the string when a newline arrives:
250 OC_LOG_V(INFO, TAG, "Connected. (%s)\r\n", slaveList[slaver_num]);
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]]);
258 while( ble.IsSelfArduino() == false )
259 ble.pollingDisconnect();
262 slaver_num = slaver_num % SLAVER_EA;
265 avg[i] = CalculateExponentialAverage(RSSI_EA, rssi[i], startindex[i], flag[i]);
266 Serial.println(avg[i]);
267 Serial.print("distance : ");
269 PROXI.m_distance[i] = calculateDistance(avg[i], -58);
271 if(PROXI.m_distance[i] <= 1){
272 PROXI.m_proximity[i] = 1;
274 else if(PROXI.m_distance[i] <= 2){
275 PROXI.m_proximity[i] = 2;
278 PROXI.m_proximity[i] = 3;
281 Serial.println(PROXI.m_distance[i]);
282 Serial.println(PROXI.m_proximity[i]);
284 startindex[i] += RSSI_EA;
286 // This call displays the amount of free SRAM available on Arduino
287 PrintArduinoMemoryStats();
289 if(startindex[i] >= arraysize){
293 if(flag[i] < (arraysize / RSSI_EA))
299 result = OCNotifyAllObservers (m_handle, OC_NA_QOS);
301 if (OC_STACK_NO_OBSERVERS == result)
303 OC_LOG_V(INFO, TAG, "g_PROXIUnderObservation is 0." );
304 g_PROXIUnderObservation = 0;
313 //The setup function is called once at startup of the sketch
316 Serial.begin(115200);
318 // Add your initialization code here
321 OC_LOG(DEBUG, TAG, PCF("OCServer is starting..."));
322 // uint16_t port = OC_WELL_KNOWN_PORT;
324 // Connect to Ethernet or WiFi network
325 if (ConnectToNetwork() != 0)
327 OC_LOG(ERROR, TAG, "Unable to connect to network");
331 // Initialize the OC Stack in Server mode
332 if (OCInit(NULL, OC_WELL_KNOWN_PORT, OC_SERVER) != OC_STACK_OK)
334 OC_LOG(ERROR, TAG, PCF("OCStack init error"));
339 // Declare and create the example resource
342 // This call displays the amount of free SRAM available on Arduino
343 PrintArduinoMemoryStats();
345 ble.init( (long)115200, BLE_MASTER, trackeeID);
347 ble.init( (long)115200, BLE_SLAVER, slaveList[0]);
349 ble.init( (long)115200, BLE_SLAVER, slaveList[1]);
354 OC_LOG_V(INFO, TAG, "Program Start-\r\n");
358 // The loop function is called in an endless loop
361 // This artificial delay is kept here to avoid endless spinning
362 // of Arduino microcontroller. Modify it as per specfic application needs.
364 if (OCProcess() != OC_STACK_OK)
366 OC_LOG(ERROR, TAG, PCF("OCStack process error"));
370 ChangePROXIRepresentation(NULL);
372 char* user_cmd = NULL;
374 // ble.pollingDisconnect();
376 user_cmd = ble.Debug2BLE(true);
377 ble.BLE2Debug( true );
394 void createResource() {
396 OCStackResult res = OCCreateResource(&m_handle,
397 "SoftSensorManager.Sensor",
401 OC_DISCOVERABLE|OC_OBSERVABLE);
402 OC_LOG_V(INFO, TAG, "Created PROXI resource with result: %s", getResult(res));
405 const char *getResult(OCStackResult result) {
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";
438 return "OC_STACK_ERROR";