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 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
21 // Do not remove the include below
30 #include "oic_lanLib.h"
32 #define ARDUINO_AVR_MEGA2560 1
33 /// This is the port which Arduino Server will use for all unicast communication with it's peers
34 #define OC_WELL_KNOWN_PORT 5683
36 #define JSON_BASE00 "{\"href\":\"\",\"rep\":{"
37 #define JSON_BASE01 "\"0\":\"MAC\",\"1\":\"string\",\"2\":\""
38 #define JSON_BASE02 "\",\"3\":\"SERVICETYPE\",\"4\":\"string\",\"5\":\""
39 #define JSON_BASE03 "\"}}"
41 typedef struct REFERRESOURCE {
42 OCResourceHandle m_handle;
47 PROGMEM const char TAG[] = "ReferenceSensor";
52 char macaddress[13]={"9059AF1704D7"};
53 char servicetype[15]={"BOOK"};
55 int g_REFERUnderObservation = 0;
57 const char *getResult(OCStackResult result);
58 void createREFERResource();
60 #define LENGTH_VAR 100
61 static int base_length = 0;
63 bool JsonGenerator( REFERResource& ref, char* jsonBuf, uint16_t buf_length )
65 if( (buf_length - base_length) < LENGTH_VAR )
67 OC_LOG_V(ERROR, TAG, "Error : length is very long.");
71 sprintf(jsonBuf, JSON_BASE00 JSON_BASE01"%s",ref.m_macaddress);
72 sprintf(jsonBuf+strlen(jsonBuf), JSON_BASE02"%s"JSON_BASE03, ref.m_servicetype);
74 Serial.println(jsonBuf);
79 // On Arduino Atmel boards with Harvard memory architecture, the stack grows
80 // downwards from the top and the heap grows upwards. This method will print
81 // the distance(in terms of bytes) between those two.
82 // See here for more details :
83 // http://www.atmel.com/webdoc/AVRLibcReferenceManual/malloc_1malloc_intro.html
84 void PrintArduinoMemoryStats()
86 #ifdef ARDUINO_AVR_MEGA2560
87 //This var is declared in avr-libc/stdlib/malloc.c
88 //It keeps the largest address not allocated for heap
89 extern char *__brkval;
90 //address of tmp gives us the current stack boundry
92 OC_LOG_V(INFO, TAG, "Stack: %u Heap: %u", (unsigned int)&tmp, (unsigned int)__brkval);
93 OC_LOG_V(INFO, TAG, "Unallocated Memory between heap and stack: %u",
94 ((unsigned int)&tmp - (unsigned int)__brkval));
98 // This is the entity handler for the registered resource.
99 // This is invoked by OCStack whenever it recevies a request for this resource.
100 OCEntityHandlerResult OCEntityHandlerCb(OCEntityHandlerFlag flag, OCEntityHandlerRequest * entityHandlerRequest )
102 OCEntityHandlerResult ehRet = OC_EH_OK;
103 OCEntityHandlerResponse response = {0};
104 char payload[MAX_RESPONSE_LENGTH] = {0};
106 if(entityHandlerRequest && (flag & OC_REQUEST_FLAG))
108 OC_LOG (INFO, TAG, PCF("Flag includes OC_REQUEST_FLAG"));
109 if(OC_REST_GET == entityHandlerRequest->method)
111 if(JsonGenerator( REFER, payload, MAX_RESPONSE_LENGTH))
119 if(OC_REST_PUT == entityHandlerRequest->method)
121 //Do something with the 'put' payload
122 if (JsonGenerator( REFER, payload, MAX_RESPONSE_LENGTH))
132 if (ehRet == OC_EH_OK)
134 // Format the response. Note this requires some info about the request
135 response.requestHandle = entityHandlerRequest->requestHandle;
136 response.resourceHandle = entityHandlerRequest->resource;
137 response.ehResult = ehRet;
138 response.payload = (unsigned char *)payload;
139 response.payloadSize = strlen(payload);
140 response.numSendVendorSpecificHeaderOptions = 0;
141 memset(response.sendVendorSpecificHeaderOptions, 0, sizeof response.sendVendorSpecificHeaderOptions);
142 memset(response.resourceUri, 0, sizeof response.resourceUri);
143 // Indicate that response is NOT in a persistent buffer
144 response.persistentBufferFlag = 0;
147 if (OCDoResponse(&response) != OC_STACK_OK)
149 OC_LOG(ERROR, TAG, "Error sending response");
154 if (entityHandlerRequest && (flag & OC_OBSERVE_FLAG))
156 if (OC_OBSERVE_REGISTER == entityHandlerRequest->obsInfo.action)
158 OC_LOG (INFO, TAG, PCF("Received OC_OBSERVE_REGISTER from client"));
159 g_REFERUnderObservation = 1;
161 else if (OC_OBSERVE_DEREGISTER == entityHandlerRequest->obsInfo.action)
163 OC_LOG (INFO, TAG, PCF("Received OC_OBSERVE_DEREGISTER from client"));
172 void ChangeREFERRepresentation (void *param)
175 OCStackResult result = OC_STACK_ERROR;
176 result = OCNotifyAllObservers (REFER.m_handle, OC_NA_QOS);
178 OC_LOG_V(INFO, TAG, "%s", JsonGenerator( REFER, tempdata, 200));
180 if (OC_STACK_NO_OBSERVERS == result)
182 OC_LOG_V(INFO, TAG, "g_REFERUnderObservation is 0." );
183 g_REFERUnderObservation = 0;
187 //The setup function is called once at startup of the sketch
190 Serial.begin(115200);
192 REFER.m_macaddress = macaddress;
193 REFER.m_servicetype = servicetype;
195 // Add your initialization code here
198 OC_LOG(DEBUG, TAG, PCF("OCServer is starting..."));
200 // Connect to Ethernet or WiFi network
201 if (ConnectToNetwork() != 0)
203 OC_LOG(ERROR, TAG, "Unable to connect to network");
207 // Initialize the OC Stack in Server mode
208 if (OCInit(NULL, OC_WELL_KNOWN_PORT, OC_SERVER) != OC_STACK_OK)
210 OC_LOG(ERROR, TAG, PCF("OCStack init error"));
215 // Declare and create the example resource: PROXI
216 createREFERResource();
218 ble.init( (long)115200, BLE_SLAVER, REFER.m_macaddress);
222 char str0[] = JSON_BASE00;
223 char str1[] = JSON_BASE01;
224 char str2[] = JSON_BASE02;
225 char str3[] = JSON_BASE03;
227 base_length = strlen(str0)+ strlen(str1)+ strlen(str2)+ strlen(str3);
229 OC_LOG_V(INFO, TAG, "Program Start-\r\n");
232 // The loop function is called in an endless loop
235 // This artificial delay is kept here to avoid endless spinning
236 // of Arduino microcontroller. Modify it as per specfic application needs.
238 // This call displays the amount of free SRAM available on Arduino
239 PrintArduinoMemoryStats();
241 if (OCProcess() != OC_STACK_OK)
243 OC_LOG(ERROR, TAG, PCF("OCStack process error"));
246 ChangeREFERRepresentation(NULL);
248 char* user_msg = NULL;
249 user_msg = ble.Debug2BLE( true );
250 ble.BLE2Debug( true );
259 void createREFERResource() {
261 OCStackResult res = OCCreateResource(&REFER.m_handle,
262 "SoftSensorManager.Sensor",
266 OC_DISCOVERABLE|OC_OBSERVABLE);
267 OC_LOG_V(INFO, TAG, "Created REFER resource with result: %s", getResult(res));
270 const char *getResult(OCStackResult result) {
273 return "OC_STACK_OK";
274 case OC_STACK_INVALID_URI:
275 return "OC_STACK_INVALID_URI";
276 case OC_STACK_INVALID_QUERY:
277 return "OC_STACK_INVALID_QUERY";
278 case OC_STACK_INVALID_IP:
279 return "OC_STACK_INVALID_IP";
280 case OC_STACK_INVALID_PORT:
281 return "OC_STACK_INVALID_PORT";
282 case OC_STACK_INVALID_CALLBACK:
283 return "OC_STACK_INVALID_CALLBACK";
284 case OC_STACK_INVALID_METHOD:
285 return "OC_STACK_INVALID_METHOD";
286 case OC_STACK_NO_MEMORY:
287 return "OC_STACK_NO_MEMORY";
288 case OC_STACK_COMM_ERROR:
289 return "OC_STACK_COMM_ERROR";
290 case OC_STACK_INVALID_PARAM:
291 return "OC_STACK_INVALID_PARAM";
292 case OC_STACK_NOTIMPL:
293 return "OC_STACK_NOTIMPL";
294 case OC_STACK_NO_RESOURCE:
295 return "OC_STACK_NO_RESOURCE";
296 case OC_STACK_RESOURCE_ERROR:
297 return "OC_STACK_RESOURCE_ERROR";
298 case OC_STACK_SLOW_RESOURCE:
299 return "OC_STACK_SLOW_RESOURCE";
300 case OC_STACK_NO_OBSERVERS:
301 return "OC_STACK_NO_OBSERVERS";
303 return "OC_STACK_ERROR";