Apply to Resource Hosting to RE resource server added feature.
[platform/upstream/iotivity.git] / service / resource-hosting / SampleApp / linux / sampleProvider / SampleProvider.cpp
1 //******************************************************************
2 //
3 // Copyright 2015 Samsung Electronics 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 <functional>
22
23 #include <pthread.h>
24 #include <signal.h>
25
26 #include "OCPlatform.h"
27 #include "OCApi.h"
28 #include "OCResourceResponse.h"
29
30 #include <memory>
31
32 using namespace OC;
33 using namespace std;
34 using namespace OC::OCPlatform;
35
36 int g_Observation = 0;
37 int gQuitFlag = 0;
38
39 pthread_cond_t m_cond = PTHREAD_COND_INITIALIZER;
40 pthread_mutex_t m_mutex = PTHREAD_MUTEX_INITIALIZER;
41
42
43
44 OCEntityHandlerResult entityHandler(std::shared_ptr< OCResourceRequest > request);
45
46 class TempHumidResource
47 {
48     public:
49
50         int m_temp;
51         int m_humid;
52         std::string m_uri;
53         OCResourceHandle m_resourceHandle;
54         ObservationIds m_interestedObservers;
55         OCRepresentation m_Rep;
56
57     public:
58         TempHumidResource() :
59             m_temp(0), m_humid(0), m_uri("/a/TempHumSensor"), m_resourceHandle(NULL)
60         {
61         }
62
63         void createResource()
64         {
65             std::string resourceURI = "/a/TempHumSensor/hosting";
66             std::string resourceTypeName = "oic.r.resourcehosting";
67             std::string resourceInterface = DEFAULT_INTERFACE;
68
69             m_uri = resourceURI;
70
71             uint8_t resourceProperty = OC_DISCOVERABLE | OC_OBSERVABLE;
72
73             OCStackResult result = OCPlatform::registerResource(m_resourceHandle , resourceURI ,
74                                    resourceTypeName , resourceInterface , &entityHandler , resourceProperty);
75
76             if (OC_STACK_OK != result)
77             {
78                 cout << "Resource creation was unsuccessful\n";
79             }
80         }
81
82         OCStackResult createResource1()
83         {
84             std::string resourceURI = "/a/NM/TempHumSensor1"; // URI of the resource
85             std::string resourceTypeName =
86                 "oic.r.resourcehosting"; // resource type name.
87             std::string resourceInterface = DEFAULT_INTERFACE; // resource interface.
88
89             // OCResourceProperty is defined ocstack.h
90             uint8_t resourceProperty = OC_DISCOVERABLE | OC_OBSERVABLE;
91
92             OCResourceHandle resHandle;
93
94             // This will internally create and register the resource.
95             OCStackResult result = OCPlatform::registerResource(
96                                        resHandle, resourceURI, resourceTypeName,
97                                        resourceInterface, &entityHandler, resourceProperty);
98
99             if (OC_STACK_OK != result)
100             {
101                 cout << "Resource creation was unsuccessful\n";
102             }
103
104             return result;
105         }
106
107         OCResourceHandle getHandle()
108         {
109             return m_resourceHandle;
110         }
111
112         OCRepresentation post(OCRepresentation &rep)
113         {
114             static int first = 1;
115             // for the first time it tries to create a resource
116             if (first)
117             {
118                 first = 0;
119
120                 if (OC_STACK_OK == createResource1())
121                 {
122                     OCRepresentation rep1;
123                     rep1.setValue("createduri", std::string("/a/light1"));
124
125                     return rep1;
126                 }
127             }
128
129             // from second time onwards it just puts
130             put(rep);
131             return get();
132         }
133
134         void put(OCRepresentation &rep)
135         {
136             try
137             {
138                 if (rep.getValue("temperature", m_temp))
139                 {
140                     cout << "\t\t\t\t" << "temperature: " << m_temp << endl;
141                 }
142                 else
143                 {
144                     cout << "\t\t\t\t" << "temperature not found in the representation" << endl;
145                 }
146
147                 if (rep.getValue("humidity", m_humid))
148                 {
149                     cout << "\t\t\t\t" << "humidity: " << m_humid << endl;
150                 }
151                 else
152                 {
153                     cout << "\t\t\t\t" << "humidity not found in the representation" << endl;
154                 }
155             }
156             catch (exception &e)
157             {
158                 cout << e.what() << endl;
159             }
160
161         }
162
163         OCRepresentation get()
164         {
165             m_Rep.setValue("temperature", m_temp);
166             m_Rep.setValue("humidity", m_humid);
167             return m_Rep;
168         }
169         OCStackResult deleteDeviceResource()
170         {
171             OCStackResult result = OCPlatform::unregisterResource(m_resourceHandle);
172             if (OC_STACK_OK != result)
173             {
174                 throw std::runtime_error(
175                     std::string("Device Resource failed to unregister/delete") + std::to_string(result));
176             }
177             return result;
178         }
179 };
180
181 TempHumidResource myResource;
182
183 void *ChangeLightRepresentation(void */*param*/)
184 {
185     cout << "ChangeLigthRepresentation Enter\n";
186     while (1)
187     {
188         cout << "pthread_cond_wait\n";
189         pthread_cond_wait(&m_cond, &m_mutex);
190         cout << "pthread_cond_start\n";
191         if (g_Observation)
192         {
193
194             cout << endl;
195             cout << "========================================================" << endl;
196             cout << "HUMTepm updated to : " << myResource.m_temp << endl;
197             cout << "Notifying observers with resource handle: " << myResource.getHandle() << endl;
198
199             cout << endl;
200             cout << "========================================================" << endl;
201             cout << "Send data : \n";
202             cout << "Attribute Name: Temp\tvalue: " << myResource.m_temp << endl;
203             cout << "Attribute Name: Humid\tvalue: " << myResource.m_humid << endl;
204
205             OCStackResult result = OCPlatform::notifyAllObservers(myResource.getHandle());
206             cout << "Notify Success\n";
207
208             if (OC_STACK_NO_OBSERVERS == result)
209             {
210                 cout << "No More observers, stopping notifications" << endl;
211                 g_Observation = 0;
212             }
213         }
214         cout << "ChangeLigthRepresentation Out\n";
215
216     }
217     return NULL;
218 }
219
220 OCEntityHandlerResult entityHandler(std::shared_ptr< OCResourceRequest > request)
221 {
222     cout << "Sample Provider entityHandler\n";
223
224     OCEntityHandlerResult ehResult = OC_EH_ERROR;
225     if (request)
226     {
227         cout << "flag : request\n";
228         std::string requestType = request->getRequestType();
229         int requestFlag = request->getRequestHandlerFlag();
230
231         if (requestFlag == RequestHandlerFlag::RequestFlag)
232         {
233             cout << "\t\trequestFlag : Request\n";
234             auto pResponse = std::make_shared<OC::OCResourceResponse>();
235             pResponse->setRequestHandle(request->getRequestHandle());
236             pResponse->setResourceHandle(request->getResourceHandle());
237
238             if (requestType == "GET")
239             {
240                 cout << "\t\trequestType : GET\n";
241
242                 pResponse->setErrorCode(200);
243                 pResponse->setResponseResult(OC_EH_OK);
244                 pResponse->setResourceRepresentation(myResource.get());
245                 if (OC_STACK_OK == OCPlatform::sendResponse(pResponse))
246                 {
247                     ehResult = OC_EH_OK;
248                 }
249             }
250
251             else if (requestType == "PUT")
252             {
253                 cout << "\t\t\trequestType : PUT\n";
254
255                 OCRepresentation rep = request->getResourceRepresentation();
256                 myResource.put(rep);
257
258                 if (pResponse)
259                 {
260                     pResponse->setErrorCode(200);
261                     pResponse->setResourceRepresentation(myResource.get());
262                 }
263                 if (OC_STACK_OK == OCPlatform::sendResponse(pResponse))
264                 {
265                     ehResult = OC_EH_OK;
266                 }
267                 else
268                 {
269                     cout << "put request Error\n";
270                 }
271             }
272
273             else if (requestType == "POST")
274             {
275                 cout << "\t\t\trequestType : POST\n";
276                 OCRepresentation rep = request->getResourceRepresentation();
277                 myResource.put(rep);
278
279                 if (pResponse)
280                 {
281                     pResponse->setErrorCode(200);
282                     pResponse->setResourceRepresentation(myResource.get());
283                 }
284                 if (OC_STACK_OK == OCPlatform::sendResponse(pResponse))
285                 {
286                     ehResult = OC_EH_OK;
287                 }
288                 else
289                 {
290                     cout << "post request Error\n";
291                 }
292             }
293
294             else if (requestType == "DELETE")
295             {
296                 cout << "\t\trequestType : DELETE\n";
297                 cout << "DeviceResource Delete Request" << std::endl;
298
299                 if (myResource.deleteDeviceResource() == OC_STACK_OK)
300                 {
301                     cout << "\tSuccess DELETE\n";
302                     pResponse->setErrorCode(200);
303                     pResponse->setResponseResult(OC_EH_RESOURCE_DELETED);
304                     ehResult = OC_EH_OK;
305                 }
306                 else
307                 {
308                     pResponse->setResponseResult(OC_EH_ERROR);
309                     ehResult = OC_EH_ERROR;
310                 }
311
312                 OCPlatform::sendResponse(pResponse);
313             }
314         }
315         if (requestFlag & RequestHandlerFlag::ObserverFlag)
316         {
317             pthread_t threadId;
318
319             ObservationInfo observationInfo = request->getObservationInfo();
320             if (ObserveAction::ObserveRegister == observationInfo.action)
321             {
322                 myResource.m_interestedObservers.push_back(observationInfo.obsId);
323             }
324             else if (ObserveAction::ObserveUnregister == observationInfo.action)
325             {
326                 myResource.m_interestedObservers.erase(std::remove(
327                         myResource.m_interestedObservers.begin(),
328                         myResource.m_interestedObservers.end(),
329                         observationInfo.obsId),
330                                                        myResource.m_interestedObservers.end());
331             }
332
333             cout << request->getResourceUri() << endl;
334             cout << request->getResourceRepresentation().getUri() << endl;
335
336             cout << "========================================================" << endl;
337             cout << "Receive ObserverFlag : Start Observe\n";
338             cout << "========================================================" << endl;
339             g_Observation = 1;
340
341             cout << "\t\trequestFlag : Observer\n";
342             static int startedThread = 0;
343             if (!startedThread)
344             {
345                 cout << "\t\tpthrerad_create\n";
346                 pthread_create(&threadId , NULL , ChangeLightRepresentation , (void *) NULL);
347                 startedThread = 1;
348             }
349             ehResult = OC_EH_OK;
350         }
351     }
352     else
353     {
354         std::cout << "Request invalid" << std::endl;
355     }
356
357     return ehResult;
358 }
359
360 void quitProcess()
361 {
362     unregisterResource(myResource.m_resourceHandle);
363     stopPresence();
364     exit(0);
365 }
366
367 void handleSigInt(int signum)
368 {
369     if (signum == SIGINT)
370     {
371         std::cout << " handleSigInt in" << std::endl;
372         quitProcess();
373     }
374 }
375
376 int main()
377 {
378     PlatformConfig cfg
379     {
380         OC::ServiceType::InProc,
381         OC::ModeType::Server,
382         "0.0.0.0",
383         0,
384         OC::QualityOfService::LowQos
385     };
386
387     OCPlatform::Configure(cfg);
388
389     int number = 0;
390
391     try
392     {
393         startPresence(30);
394
395         myResource.createResource();
396
397         signal(SIGINT, handleSigInt);
398         while (true)
399         {
400             bool end = false;
401             cout << endl;
402             cout << "========================================================" << endl;
403             cout << "1. Temp is up" << endl;
404             cout << "2. Temp is down" << endl;
405             cout << "3. This Program will be ended." << endl;
406             cout << "========================================================" << endl;
407
408             cin >> number;
409             if(std::cin.fail())
410             {
411                 std::cin.clear();
412                 std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
413                 std::cout << "Invalid input type, please try again" << std::endl;
414                 continue;
415             }
416
417             switch (number)
418             {
419                 case 1:
420                     {
421                         cout << "Temp is up!" << endl;
422                         myResource.m_temp += 10;
423                         pthread_cond_signal(&m_cond);
424                         cout << "ChangeLightRepresentation Done!" << endl;
425                         break;
426                     }
427                 case 2:
428                     {
429                         cout << "Temp is down!" << endl;
430                         myResource.m_temp -= 10;
431                         pthread_cond_signal(&m_cond);
432                         cout << "ChangeLightRepresentation Done!" << endl;
433                         break;
434                     }
435                 case 3:
436                     {
437                         cout << "Bye!" << endl;
438                         stopPresence();
439                         end = true;
440                         quitProcess();
441                         break;
442                     }
443                 default:
444                     {
445                         cout << "Invalid input. Please try again." << endl;
446                         break;
447                     }
448             }
449             if (end == true)
450             {
451                 break;
452             }
453         }
454     }
455     catch (exception &e)
456     {
457         cout << "main exception  : " << e.what() << endl;
458     }
459
460
461 }