Modifying version number for building on tizen 3.0
[platform/upstream/iotivity.git] / examples / OICSensorBoard / server.cpp
1 //******************************************************************
2 //
3 // Copyright 2014 Intel Corporation.
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 #include <signal.h>
21 #include <thread>
22 #include <functional>
23 #include "server.h"
24 #include "sensors.h"
25 #include "namedefs.h"
26 using namespace Sensors;
27
28 void IoTServer::initializePlatform()
29 {
30     cout << "Running IoTServer constructor" << endl;
31     m_platformConfig = make_shared<PlatformConfig>(ServiceType::InProc, ModeType::Server, "0.0.0.0",
32                                                    0, OC::QualityOfService::HighQos);
33     OCPlatform::Configure(*m_platformConfig);
34 }
35
36 IoTServer::IoTServer()
37 {
38     initializePlatform();
39     setupResources();
40     m_temperatureRepresentation.setValue(TEMPERATURE_RESOURCE_KEY, (float) 0.0f);
41     m_ambientLightRepresentation.setValue(LIGHT_RESOURCE_KEY, 0);
42     m_ledRepresentation.setValue(LED_RESOURCE_KEY, 0);
43     SetupPins();
44 }
45
46 IoTServer::~IoTServer()
47 {
48     cout << "Running IoTServer destructor" << endl;
49     ClosePins();
50 }
51
52 void IoTServer::setupResources()
53 {
54     EntityHandler cb1 = bind(&IoTServer::temperatureEntityHandler, this, placeholders::_1);
55     createResource(TEMPERATURE_RESOURCE_ENDPOINT, TEMPERATURE_RESOURCE_TYPE, cb1,
56                    m_temperatureResource);
57     IoTObserverCb tempObsCb = bind(&IoTServer::temperatureObserverLoop, this);
58     m_temperatureObserverLoop = make_shared<IoTObserver>(tempObsCb);
59
60     EntityHandler cb2 = bind(&IoTServer::lightEntityHandler, this, placeholders::_1);
61     createResource(LIGHT_RESOURCE_ENDPOINT, LIGHT_RESOURCE_TYPE, cb2, m_ambientLightResource);
62     IoTObserverCb lightObsCb = bind(&IoTServer::lightObserverLoop, this);
63     m_ambientLightObserverLoop = make_shared<IoTObserver>(lightObsCb);
64
65     EntityHandler cb3 = bind(&IoTServer::LEDEntityHandler, this, placeholders::_1);
66     createResource(LED_RESOURCE_ENDPOINT, LED_RESOURCE_TYPE, cb3, m_ledResource);
67 }
68
69 void IoTServer::createResource(string Uri, string Type, EntityHandler Cb, OCResourceHandle& Handle)
70 {
71     string resourceUri = Uri;
72     string resourceType = Type;
73     string resourceInterface = EDISON_RESOURCE_INTERFACE;
74     uint8_t resourceFlag = OC_DISCOVERABLE | OC_OBSERVABLE;
75
76     OCStackResult result = OCPlatform::registerResource(Handle, resourceUri, resourceType,
77                                                         resourceInterface, Cb, resourceFlag);
78
79     if (result != OC_STACK_OK)
80         cerr << "Could not create " << Type << " resource" << endl;
81     else
82         cout << "Successfully created " << Type << " resource" << endl;
83 }
84
85 void IoTServer::putLEDRepresentation()
86 {
87     int state = 0;
88     m_ledRepresentation.getValue(LED_RESOURCE_KEY, state);
89     SetOnboardLed(state);
90     if (state == 0)
91         cout << "Turned off LED" << endl;
92     else if (state == 1)
93         cout << "Turned on LED" << endl;
94     else
95         cerr << "Invalid request value" << endl;
96 }
97
98 OCRepresentation IoTServer::getLEDRepresentation()
99 {
100     return m_ledRepresentation;
101 }
102
103 void IoTServer::temperatureObserverLoop()
104 {
105     usleep(1500000);
106     cout << "Temperature Observer Callback" << endl;
107     shared_ptr<OCResourceResponse> resourceResponse(new OCResourceResponse());
108     resourceResponse->setErrorCode(200);
109     resourceResponse->setResourceRepresentation(getTemperatureRepresentation(),
110     EDISON_RESOURCE_INTERFACE);
111     OCStackResult result = OCPlatform::notifyListOfObservers(m_temperatureResource,
112                                                              m_temperatureObservers,
113                                                              resourceResponse);
114     if (result == OC_STACK_NO_OBSERVERS)
115     {
116         cout << "No more observers..Stopping observer loop..." << endl;
117         m_temperatureObserverLoop->stop();
118     }
119 }
120
121 void IoTServer::lightObserverLoop()
122 {
123     usleep(1500000);
124     cout << "Light Observer Callback" << endl;
125     shared_ptr<OCResourceResponse> resourceResponse(new OCResourceResponse());
126     resourceResponse->setErrorCode(200);
127     resourceResponse->setResourceRepresentation(getLightRepresentation(),
128     EDISON_RESOURCE_INTERFACE);
129     OCStackResult result = OCPlatform::notifyListOfObservers(m_ambientLightResource,
130                                                              m_ambientLightObservers,
131                                                              resourceResponse);
132     if (result == OC_STACK_NO_OBSERVERS)
133     {
134         cout << "No more observers..Stopping observer loop..." << endl;
135         m_ambientLightObserverLoop->stop();
136     }
137 }
138
139 OCRepresentation IoTServer::getTemperatureRepresentation()
140 {
141     m_temperatureRepresentation.setValue(TEMPERATURE_RESOURCE_KEY, GetTemperatureInC());
142     return m_temperatureRepresentation;
143 }
144
145 OCRepresentation IoTServer::getLightRepresentation()
146 {
147     m_ambientLightRepresentation.setValue(LIGHT_RESOURCE_KEY, GetLightLevel());
148     return m_ambientLightRepresentation;
149 }
150
151 OCEntityHandlerResult IoTServer::lightEntityHandler(shared_ptr<OCResourceRequest> Request)
152 {
153     OCEntityHandlerResult result = OC_EH_ERROR;
154     if (Request)
155     {
156         string requestType = Request->getRequestType();
157         int requestFlag = Request->getRequestHandlerFlag();
158         if (requestFlag & RequestHandlerFlag::RequestFlag)
159         {
160             auto Response = std::make_shared<OC::OCResourceResponse>();
161             Response->setRequestHandle(Request->getRequestHandle());
162             Response->setResourceHandle(Request->getResourceHandle());
163             if (requestType == "GET")
164             {
165                 cout << "GET request for ambient light reading" << endl;
166                 if (Response)
167                 {
168                     Response->setErrorCode(200);
169                     Response->setResponseResult(OC_EH_OK);
170                     Response->setResourceRepresentation(getLightRepresentation());
171                     if (OCPlatform::sendResponse(Response) == OC_STACK_OK)
172                     {
173                         result = OC_EH_OK;
174                     }
175                 }
176             }
177             else
178             {
179                 Response->setResponseResult(OC_EH_ERROR);
180                 OCPlatform::sendResponse(Response);
181                 cerr << "Unsupported request type" << endl;
182                 return result;
183             }
184         }
185         if (requestFlag & RequestHandlerFlag::ObserverFlag)
186         {
187             ObservationInfo observationInfo = Request->getObservationInfo();
188             if (ObserveAction::ObserveRegister == observationInfo.action)
189             {
190                 cout << "Starting observer for ambient light sensor" << endl;
191                 m_ambientLightObservers.push_back(observationInfo.obsId);
192                 m_ambientLightObserverLoop->start();
193             }
194             else if (ObserveAction::ObserveUnregister == observationInfo.action)
195             {
196                 m_ambientLightObservers.erase(
197                         remove(m_ambientLightObservers.begin(), m_ambientLightObservers.end(),
198                                observationInfo.obsId),
199                         m_ambientLightObservers.end());
200             }
201         }
202     }
203     return result;
204 }
205
206 OCEntityHandlerResult IoTServer::temperatureEntityHandler(shared_ptr<OCResourceRequest> Request)
207 {
208     OCEntityHandlerResult result = OC_EH_ERROR;
209     if (Request)
210     {
211         string requestType = Request->getRequestType();
212         int requestFlag = Request->getRequestHandlerFlag();
213         if (requestFlag & RequestHandlerFlag::RequestFlag)
214         {
215             auto Response = std::make_shared<OC::OCResourceResponse>();
216             Response->setRequestHandle(Request->getRequestHandle());
217             Response->setResourceHandle(Request->getResourceHandle());
218             if (requestType == "GET")
219             {
220                 cout << "GET request for temperature sensor reading" << endl;
221                 if (Response)
222                 {
223                     Response->setErrorCode(200);
224                     Response->setResponseResult(OC_EH_OK);
225                     Response->setResourceRepresentation(getTemperatureRepresentation());
226                     if (OCPlatform::sendResponse(Response) == OC_STACK_OK)
227                     {
228                         result = OC_EH_OK;
229                     }
230                 }
231             }
232             else
233             {
234                 Response->setResponseResult(OC_EH_ERROR);
235                 OCPlatform::sendResponse(Response);
236                 cerr << "Unsupported request type" << endl;
237                 return result;
238             }
239         }
240         if (requestFlag & RequestHandlerFlag::ObserverFlag)
241         {
242             ObservationInfo observationInfo = Request->getObservationInfo();
243             if (ObserveAction::ObserveRegister == observationInfo.action)
244             {
245                 cout << "Starting observer for temperature sensor" << endl;
246                 m_temperatureObservers.push_back(observationInfo.obsId);
247                 m_temperatureObserverLoop->start();
248             }
249             else if (ObserveAction::ObserveUnregister == observationInfo.action)
250             {
251                 m_temperatureObservers.erase(
252                         remove(m_temperatureObservers.begin(), m_temperatureObservers.end(),
253                                observationInfo.obsId),
254                         m_temperatureObservers.end());
255             }
256         }
257     }
258     return result;
259 }
260
261 OCEntityHandlerResult IoTServer::LEDEntityHandler(shared_ptr<OCResourceRequest> Request)
262 {
263     OCEntityHandlerResult result = OC_EH_ERROR;
264     if (Request)
265     {
266         string requestType = Request->getRequestType();
267         int requestFlag = Request->getRequestHandlerFlag();
268         if (requestFlag & RequestHandlerFlag::RequestFlag)
269         {
270             auto Response = std::make_shared<OC::OCResourceResponse>();
271             Response->setRequestHandle(Request->getRequestHandle());
272             Response->setResourceHandle(Request->getResourceHandle());
273             if (requestType == "PUT")
274             {
275                 cout << "PUT request for platform LED" << endl;
276                 OCRepresentation requestRep = Request->getResourceRepresentation();
277                 if (requestRep.hasAttribute(LED_RESOURCE_KEY))
278                 {
279                     try
280                     {
281                         requestRep.getValue<int>(LED_RESOURCE_KEY);
282                     }
283                     catch (...)
284                     {
285                         Response->setResponseResult(OC_EH_ERROR);
286                         OCPlatform::sendResponse(Response);
287                         cerr << "Client sent invalid resource value type" << endl;
288                         return result;
289                     }
290                 }
291                 else
292                 {
293                     Response->setResponseResult(OC_EH_ERROR);
294                     OCPlatform::sendResponse(Response);
295                     cerr << "Client sent invalid resource key" << endl;
296                     return result;
297                 }
298                 m_ledRepresentation = requestRep;
299                 putLEDRepresentation();
300                 if (Response)
301                 {
302                     Response->setErrorCode(200);
303                     Response->setResourceRepresentation(getLEDRepresentation());
304                     Response->setResponseResult(OC_EH_OK);
305                     if (OCPlatform::sendResponse(Response) == OC_STACK_OK)
306                     {
307                         result = OC_EH_OK;
308                     }
309                 }
310             }
311             else if (requestType == "GET")
312             {
313                 cout << "GET request for platform LED" << endl;
314                 if (Response)
315                 {
316                     Response->setErrorCode(200);
317                     Response->setResourceRepresentation(getLEDRepresentation());
318                     Response->setResponseResult(OC_EH_OK);
319                     if (OCPlatform::sendResponse(Response) == OC_STACK_OK)
320                     {
321                         result = OC_EH_OK;
322                     }
323                 }
324             }
325             else
326             {
327                 Response->setResponseResult(OC_EH_ERROR);
328                 OCPlatform::sendResponse(Response);
329                 cerr << "Unsupported request type" << endl;
330             }
331         }
332     }
333     return result;
334 }
335
336 int quit = 0;
337
338 void handle_signal(int signal)
339 {
340     quit = 1;
341 }
342
343 int main()
344 {
345     struct sigaction sa;
346     sigfillset(&sa.sa_mask);
347     sa.sa_flags = 0;
348     sa.sa_handler = handle_signal;
349     sigaction(SIGINT, &sa, NULL);
350     cout << "Press Ctrl-C to quit...." << endl;
351     IoTServer server;
352     do
353     {
354         usleep(2000000);
355     }
356     while (quit != 1);
357     return 0;
358 }
359