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