iotivity 0.9.0
[platform/upstream/iotivity.git] / service / notification-manager / SampleApp / arduino / thserver.cpp
1 //******************************************************************
2 //
3 // Copyright 2014 Intel Corporation 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 #include "Arduino.h"
22
23 #include "logger.h"
24 #include "ocstack.h"
25 #include  <string.h>
26
27 #include <EthernetServer.h>
28 #include <Ethernet.h>
29 #include <Dns.h>
30 #include <EthernetClient.h>
31 #include <util.h>
32 #include <EthernetUdp.h>
33 #include <Dhcp.h>
34
35 const char *getResult(OCStackResult result);
36
37 #define PCF(str) ((const prog_char*)(F(str)))
38 #define dht11_pin 7  //Temperature & Humidity pin
39
40 const prog_char TAG[] PROGMEM = "THServer";
41
42 int gQuitFlag = 0;
43 int gTHUnderObservation = 0;
44
45 void createTHResource();
46 typedef struct THRESOURCE {
47     OCResourceHandle handle;
48     int temp;
49     int humid;
50 } THResource;
51
52 static THResource TH;
53
54 String responsePayloadPut = "{\"oc\":[{\"href\":\"\",\"rep\":{\"temperature\":\"0\",\"humidity\":\"0\"}}]}";
55 String responsePayloadGet = "{\"oc\":[{\"href\":\"\",\"rep\":{\"temperature\":\"0\",\"humidity\":\"0\"}}]}";
56
57
58 /* read pin data */
59 byte read_dht11_dat()
60 {
61   byte i = 0;
62   byte result=0;
63   for(i=0; i< 8; i++)
64   {
65     while (!digitalRead(dht11_pin));
66     delayMicroseconds(30);
67     if (digitalRead(dht11_pin) != 0 )
68       bitSet(result, 7-i);
69     while (digitalRead(dht11_pin));
70   }
71   return result;
72 }
73
74 /* Json Generator */
75 String JsonGenerator(THResource TH){
76    String a = "{\"oc\":[{\"href\":\"\",\"rep\":{\"temperature\":\"";
77    String b = "\",\"humidity\":\"";
78    String c = "\"}}]}";
79
80    String ss;
81
82     ss = a + TH.temp + b + TH.humid + c;
83         return ss;
84 }
85
86 static uint8_t modCounter = 0;
87 void *ChangeTHRepresentation (void *param)
88 {
89     (void)param;
90     OCStackResult result = OC_STACK_ERROR;
91
92     modCounter += 1;
93     if(modCounter % 10 == 0)  // Matching the timing that the Linux Server App uses for the same functionality.
94     {
95          /* Temperature & Humidity value check */
96          byte dht11_dat[5];
97          byte i;// start condition
98
99          digitalWrite(dht11_pin, LOW);
100          delay(18);
101          digitalWrite(dht11_pin, HIGH);
102          delayMicroseconds(1);
103
104          pinMode(dht11_pin, INPUT);
105          delayMicroseconds(40);
106
107          if (digitalRead(dht11_pin))
108          {
109            Serial.println("dht11 start condition 1 not met");  // wait for DHT response signal: LOW
110            delay(1000);
111            return NULL;
112
113          }
114          delayMicroseconds(80);
115          if (!digitalRead(dht11_pin))
116          {
117            Serial.println("dht11 start condition 2 not met");  // wait for second response signal:HIGH
118            return NULL;
119          }
120
121          delayMicroseconds(80);                         // now ready for data reception
122          for (i=0; i<5; i++)
123          {  dht11_dat[i] = read_dht11_dat();}           // recieved 40 bits data. 
124
125          pinMode(dht11_pin, OUTPUT);
126          digitalWrite(dht11_pin, HIGH);
127          byte dht11_check_sum = dht11_dat[0]+dht11_dat[2];     // check check_sum
128          if(dht11_dat[4]!= dht11_check_sum)
129          {
130            Serial.println("DHT11 checksum error");
131          }
132
133          delay(2000);                                   // fresh time
134          TH.humid = dht11_dat[0];
135          TH.temp = dht11_dat[2];
136
137          responsePayloadGet = JsonGenerator(TH);
138
139 /* observe */
140         if (gTHUnderObservation)
141         {
142             OC_LOG_V(INFO, TAG, " =====> Notifying stack of new humid level %d\n", TH.humid);
143             OC_LOG_V(INFO, TAG, " =====> Notifying stack of new temp level %d\n", TH.temp);
144
145             result = OCNotifyObservers (TH.handle);
146
147             if (OC_STACK_NO_OBSERVERS == result)
148             {
149                 gTHUnderObservation = 0;
150             }
151         }
152     }
153     return NULL;
154 }
155
156 OCEntityHandlerResult OCEntityHandlerCb(OCEntityHandlerFlag flag, OCEntityHandlerRequest * entityHandlerRequest ) {
157     const char* typeOfMessage;
158
159     OCEntityHandlerResult ehRet = OC_EH_OK;
160
161     switch (flag) {
162     case OC_INIT_FLAG:
163         typeOfMessage = "OC_INIT_FLAG";
164         break;
165     case OC_REQUEST_FLAG:
166         typeOfMessage = "OC_REQUEST_FLAG";
167         break;
168     case OC_OBSERVE_FLAG:
169         typeOfMessage = "OC_OBSERVE_FLAG";
170         break;
171     default:
172         typeOfMessage = "UNKNOWN";
173     }
174     OC_LOG_V(INFO, TAG, "Receiving message type: %s", typeOfMessage);
175     if(entityHandlerRequest && flag == OC_REQUEST_FLAG) { 
176         if(OC_REST_GET == entityHandlerRequest->method) {
177
178             int str_len = responsePayloadGet.length() + 1;
179             char charBuf[str_len+1];
180
181             responsePayloadGet.toCharArray(charBuf, str_len);
182
183             if(strlen(charBuf) < entityHandlerRequest->resJSONPayloadLen)
184             {
185             strncpy((char *)entityHandlerRequest->resJSONPayload, charBuf, entityHandlerRequest->resJSONPayloadLen);
186             }
187             else
188                 ehRet = OC_EH_ERROR;
189         }
190         if(OC_REST_PUT == entityHandlerRequest->method) {
191
192             int str_len1 = responsePayloadPut.length() + 1;
193             char charBuf1[str_len1];
194
195             responsePayloadPut.toCharArray(charBuf1, str_len1);
196
197              if(strlen(charBuf1) < entityHandlerRequest->resJSONPayloadLen)
198             {
199             strncpy((char *)entityHandlerRequest->resJSONPayload, charBuf1, entityHandlerRequest->resJSONPayloadLen);
200             }
201              else
202                ehRet = OC_EH_ERROR;
203         }
204     } else if (entityHandlerRequest && flag == OC_OBSERVE_FLAG) {
205         gTHUnderObservation = 1;
206     }
207
208     return ehRet;
209 }
210
211 /* The setup function is called once at startup of the sketch */
212 void setup()
213 {
214     pinMode(dht11_pin, OUTPUT);   
215     digitalWrite(dht11_pin, HIGH);
216
217     OC_LOG_INIT();
218
219     OC_LOG(DEBUG, TAG, PCF("THServer is starting..."));
220     uint16_t port = USE_RANDOM_PORT;
221
222     /* Mac address of my ethernet shield */
223     uint8_t ETHERNET_MAC[] = {0x90, 0xA2, 0xDA, 0x0E, 0xB8, 0xAB};
224     uint8_t error = Ethernet.begin(ETHERNET_MAC);
225     Serial.print(Ethernet.localIP());
226     if (error  == 0)
227     {
228         OC_LOG_V(ERROR, TAG, "error is: %d", error);
229         return;
230     }
231
232     if (OCInit(NULL, port, OC_SERVER) != OC_STACK_OK)
233     {
234         OC_LOG(ERROR, TAG, PCF("OCStack init error"));
235         return;
236     }
237
238     /*
239      * Declare and create the resource: TH
240      */
241
242     createTHResource();
243
244 }
245
246 /* The loop function is called in an endless loop */
247 void loop()
248 {
249     delay(1000);
250     if (OCProcess() != OC_STACK_OK)
251     {
252         OC_LOG(ERROR, TAG, PCF("OCStack process error"));
253         return;
254     }
255     ChangeTHRepresentation(NULL);
256 }
257
258 void createTHResource() {
259     TH.humid = 0;
260     TH.temp = 0;
261
262     OCStackResult res = OCCreateResource(&TH.handle,
263                                          "SoftSensorManager.Sensor",
264                                          "oc.mi.def",
265                                          "/Thing_TempHumSensor",
266                                          OCEntityHandlerCb,
267                                          OC_DISCOVERABLE|OC_OBSERVABLE);
268     OC_LOG_V(INFO, TAG, "Created TH resource with result: %s", getResult(res));
269 }
270
271 const char *getResult(OCStackResult result) {
272     switch (result) {
273     case OC_STACK_OK:
274         return "OC_STACK_OK";
275     case OC_STACK_INVALID_URI:
276         return "OC_STACK_INVALID_URI";
277     case OC_STACK_INVALID_QUERY:
278         return "OC_STACK_INVALID_QUERY";
279     case OC_STACK_INVALID_IP:
280         return "OC_STACK_INVALID_IP";
281     case OC_STACK_INVALID_PORT:
282         return "OC_STACK_INVALID_PORT";
283     case OC_STACK_INVALID_CALLBACK:
284         return "OC_STACK_INVALID_CALLBACK";
285     case OC_STACK_INVALID_METHOD:
286         return "OC_STACK_INVALID_METHOD";
287     case OC_STACK_NO_MEMORY:
288         return "OC_STACK_NO_MEMORY";
289     case OC_STACK_COMM_ERROR:
290         return "OC_STACK_COMM_ERROR";
291     case OC_STACK_INVALID_PARAM:
292         return "OC_STACK_INVALID_PARAM";
293     case OC_STACK_NOTIMPL:
294         return "OC_STACK_NOTIMPL";
295     case OC_STACK_NO_RESOURCE:
296         return "OC_STACK_NO_RESOURCE";
297     case OC_STACK_RESOURCE_ERROR:
298         return "OC_STACK_RESOURCE_ERROR";
299     case OC_STACK_SLOW_RESOURCE:
300         return "OC_STACK_SLOW_RESOURCE";
301     case OC_STACK_NO_OBSERVERS:
302         return "OC_STACK_NO_OBSERVERS";
303     case OC_STACK_ERROR:
304         return "OC_STACK_ERROR";
305     default:
306         return "UNKNOWN";
307     }
308 }
309
310