iotivity 0.9.0
[platform/upstream/iotivity.git] / service / soft-sensor-manager / SampleApp / arduino / Reference_Thing / src / reference.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 // Do not remove the include below
22 #include "Arduino.h"
23 #include "bleLib.h"
24 #include <stdio.h>
25
26 #include "logger.h"
27 #include "ocstack.h"
28 #include <string.h>
29
30 #include "oic_lanLib.h"
31
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
35
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 "\"}}"
40
41 typedef struct REFERRESOURCE {
42     OCResourceHandle m_handle;
43     char* m_macaddress;
44     char* m_servicetype;
45 } REFERResource;
46
47 PROGMEM const char TAG[] = "ReferenceSensor";
48
49 REFERResource REFER;
50 Cble ble;
51
52 char macaddress[13]={"9059AF1704D7"};
53 char servicetype[15]={"BOOK"};
54
55 int g_REFERUnderObservation = 0;
56
57 const char *getResult(OCStackResult result);
58 void createREFERResource();
59
60 #define LENGTH_VAR              100
61 static int base_length = 0;
62
63 bool JsonGenerator( REFERResource& ref, char* jsonBuf, uint16_t buf_length )
64 {
65         if( (buf_length - base_length) < LENGTH_VAR )
66         {
67                 OC_LOG_V(ERROR, TAG, "Error : length is very long.");
68                 return false;
69         }
70
71         sprintf(jsonBuf, JSON_BASE00 JSON_BASE01"%s",ref.m_macaddress);
72         sprintf(jsonBuf+strlen(jsonBuf), JSON_BASE02"%s"JSON_BASE03, ref.m_servicetype);
73
74         Serial.println(jsonBuf);
75
76         return true;
77 }
78
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()
85 {
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
91     int tmp;
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));
95 #endif
96 }
97
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 )
101 {
102     OCEntityHandlerResult ehRet = OC_EH_OK;
103     OCEntityHandlerResponse response = {0};
104     char payload[MAX_RESPONSE_LENGTH] = {0};
105
106     if(entityHandlerRequest && (flag & OC_REQUEST_FLAG))
107     {
108         OC_LOG (INFO, TAG, PCF("Flag includes OC_REQUEST_FLAG"));
109         if(OC_REST_GET == entityHandlerRequest->method)
110         {
111                  if(JsonGenerator( REFER, payload, MAX_RESPONSE_LENGTH))
112                  {
113                  }
114            else
115             {
116                 ehRet = OC_EH_ERROR;
117             }
118         }
119         if(OC_REST_PUT == entityHandlerRequest->method)
120         {
121             //Do something with the 'put' payload
122             if (JsonGenerator( REFER, payload, MAX_RESPONSE_LENGTH))
123             {
124             }
125             else
126             {
127                 ehRet = OC_EH_ERROR;
128             }
129          }
130     }
131
132     if (ehRet == OC_EH_OK)
133    {
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;
145
146            // Send the response
147            if (OCDoResponse(&response) != OC_STACK_OK)
148            {
149                    OC_LOG(ERROR, TAG, "Error sending response");
150                    ehRet = OC_EH_ERROR;
151            }
152     }
153
154     if (entityHandlerRequest && (flag & OC_OBSERVE_FLAG))
155     {
156         if (OC_OBSERVE_REGISTER == entityHandlerRequest->obsInfo.action)
157         {
158             OC_LOG (INFO, TAG, PCF("Received OC_OBSERVE_REGISTER from client"));
159             g_REFERUnderObservation = 1;
160         }
161         else if (OC_OBSERVE_DEREGISTER == entityHandlerRequest->obsInfo.action)
162         {
163             OC_LOG (INFO, TAG, PCF("Received OC_OBSERVE_DEREGISTER from client"));
164         }
165     }
166
167     return ehRet;
168 }
169
170
171 char tempdata[200];
172 void ChangeREFERRepresentation (void *param)
173 {
174         (void)param;
175         OCStackResult result = OC_STACK_ERROR;
176         result = OCNotifyAllObservers (REFER.m_handle, OC_NA_QOS);
177
178         OC_LOG_V(INFO, TAG, "%s", JsonGenerator( REFER, tempdata, 200));
179
180         if (OC_STACK_NO_OBSERVERS == result)
181         {
182                 OC_LOG_V(INFO, TAG, "g_REFERUnderObservation is 0." );
183                 g_REFERUnderObservation = 0;
184         }
185 }
186
187 //The setup function is called once at startup of the sketch
188 void setup()
189 {
190         Serial.begin(115200);
191
192    REFER.m_macaddress = macaddress;
193    REFER.m_servicetype = servicetype;
194
195         // Add your initialization code here
196         OC_LOG_INIT();
197
198         OC_LOG(DEBUG, TAG, PCF("OCServer is starting..."));
199
200         // Connect to Ethernet or WiFi network
201         if (ConnectToNetwork() != 0)
202         {
203                 OC_LOG(ERROR, TAG, "Unable to connect to network");
204                 return;
205         }
206
207         // Initialize the OC Stack in Server mode
208         if (OCInit(NULL, OC_WELL_KNOWN_PORT, OC_SERVER) != OC_STACK_OK)
209         {
210                 OC_LOG(ERROR, TAG, PCF("OCStack init error"));
211                 return;
212         }
213
214     OCStartPresence(60);
215         // Declare and create the example resource: PROXI
216         createREFERResource();
217
218         ble.init( (long)115200, BLE_SLAVER,  REFER.m_macaddress);
219
220 //      ble.StatusRead();
221
222         char str0[] = JSON_BASE00;
223         char str1[] = JSON_BASE01;
224         char str2[] = JSON_BASE02;
225         char str3[] = JSON_BASE03;
226
227         base_length = strlen(str0)+ strlen(str1)+ strlen(str2)+ strlen(str3);
228
229         OC_LOG_V(INFO, TAG, "Program Start-\r\n");
230 }
231
232 // The loop function is called in an endless loop
233 void loop()
234 {
235     // This artificial delay is kept here to avoid endless spinning
236     // of Arduino microcontroller. Modify it as per specfic application needs.
237
238     // This call displays the amount of free SRAM available on Arduino
239     PrintArduinoMemoryStats();
240         delay(5000);
241         if (OCProcess() != OC_STACK_OK)
242         {
243                 OC_LOG(ERROR, TAG, PCF("OCStack process error"));
244                 return;
245         }
246         ChangeREFERRepresentation(NULL);
247
248         char* user_msg = NULL;
249         user_msg = ble.Debug2BLE( true );
250         ble.BLE2Debug( true );
251
252         if ( user_msg )
253         {
254                 free( user_msg );
255                 user_msg = NULL;
256         }
257 }
258
259 void createREFERResource() {
260
261     OCStackResult res = OCCreateResource(&REFER.m_handle,
262                                          "SoftSensorManager.Sensor",
263                                          "oc.mi.def",
264                                          "/Reference_Thing",
265                                          OCEntityHandlerCb,
266                                          OC_DISCOVERABLE|OC_OBSERVABLE);
267     OC_LOG_V(INFO, TAG, "Created REFER resource with result: %s", getResult(res));
268 }
269
270 const char *getResult(OCStackResult result) {
271     switch (result) {
272     case OC_STACK_OK:
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";
302     case OC_STACK_ERROR:
303         return "OC_STACK_ERROR";
304     default:
305         return "UNKNOWN";
306     }
307 }
308