Imported Upstream version 0.9.1
[platform/upstream/iotivity.git] / service / notification-manager / 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 = "Resource.Hosting";
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                 "NotificationManager.Hosting"; // resource type name. In this case, it is light
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             }
277
278             else if (requestType == "DELETE")
279             {
280                 cout << "\t\trequestType : DELETE\n";
281                 cout << "DeviceResource Delete Request" << std::endl;
282
283                 if (myResource.deleteDeviceResource() == OC_STACK_OK)
284                 {
285                     cout << "\tSuccess DELETE\n";
286                     pResponse->setErrorCode(200);
287                     pResponse->setResponseResult(OC_EH_RESOURCE_DELETED);
288                     ehResult = OC_EH_OK;
289                 }
290                 else
291                 {
292                     pResponse->setResponseResult(OC_EH_ERROR);
293                     ehResult = OC_EH_ERROR;
294                 }
295
296                 OCPlatform::sendResponse(pResponse);
297             }
298         }
299         if (requestFlag & RequestHandlerFlag::ObserverFlag)
300         {
301             pthread_t threadId;
302
303             ObservationInfo observationInfo = request->getObservationInfo();
304             if (ObserveAction::ObserveRegister == observationInfo.action)
305             {
306                 myResource.m_interestedObservers.push_back(observationInfo.obsId);
307             }
308             else if (ObserveAction::ObserveUnregister == observationInfo.action)
309             {
310                 myResource.m_interestedObservers.erase(std::remove(
311                         myResource.m_interestedObservers.begin(),
312                         myResource.m_interestedObservers.end(),
313                         observationInfo.obsId),
314                                                        myResource.m_interestedObservers.end());
315             }
316
317             cout << request->getResourceUri() << endl;
318             cout << request->getResourceRepresentation().getUri() << endl;
319
320             cout << "========================================================" << endl;
321             cout << "Receive ObserverFlag : Start Observe\n";
322             cout << "========================================================" << endl;
323             g_Observation = 1;
324
325             cout << "\t\trequestFlag : Observer\n";
326             static int startedThread = 0;
327             if (!startedThread)
328             {
329                 cout << "\t\tpthrerad_create\n";
330                 pthread_create(&threadId , NULL , ChangeLightRepresentation , (void *) NULL);
331                 startedThread = 1;
332             }
333             ehResult = OC_EH_OK;
334         }
335     }
336     else
337     {
338         std::cout << "Request invalid" << std::endl;
339     }
340
341     return ehResult;
342 }
343
344 void quitProcess()
345 {
346     unregisterResource(myResource.m_resourceHandle);
347     stopPresence();
348     exit(0);
349 }
350
351 void handleSigInt(int signum)
352 {
353     if (signum == SIGINT)
354     {
355         std::cout << " handleSigInt in" << std::endl;
356         quitProcess();
357     }
358 }
359
360 int main()
361 {
362     PlatformConfig cfg
363     {
364         OC::ServiceType::InProc,
365         OC::ModeType::Server,
366         "0.0.0.0",
367         0,
368         OC::QualityOfService::LowQos
369     };
370
371     OCPlatform::Configure(cfg);
372
373     int number = 0;
374
375     try
376     {
377         startPresence(30);
378
379         myResource.createResource();
380
381         signal(SIGINT, handleSigInt);
382         while (true)
383         {
384             bool end = false;
385             cout << endl;
386             cout << "========================================================" << endl;
387             cout << "1. Temp is up" << endl;
388             cout << "2. Temp is down" << endl;
389             cout << "3. This Program will be ended." << endl;
390             cout << "========================================================" << endl;
391
392             cin >> number;
393             if(std::cin.fail())
394             {
395                 std::cin.clear();
396                 std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
397                 std::cout << "Invalid input type, please try again" << std::endl;
398                 continue;
399             }
400
401             switch (number)
402             {
403                 case 1:
404                     {
405                         cout << "Temp is up!" << endl;
406                         myResource.m_temp += 10;
407                         pthread_cond_signal(&m_cond);
408                         cout << "ChangeLightRepresentation Done!" << endl;
409                         break;
410                     }
411                 case 2:
412                     {
413                         cout << "Temp is down!" << endl;
414                         myResource.m_temp -= 10;
415                         pthread_cond_signal(&m_cond);
416                         cout << "ChangeLightRepresentation Done!" << endl;
417                         break;
418                     }
419                 case 3:
420                     {
421                         cout << "Bye!" << endl;
422                         stopPresence();
423                         end = true;
424                         quitProcess();
425                         break;
426                     }
427                 default:
428                     {
429                         cout << "Invalid input. Please try again." << endl;
430                         break;
431                     }
432             }
433             if (end == true)
434             {
435                 break;
436             }
437         }
438     }
439     catch (exception &e)
440     {
441         cout << "main exception  : " << e.what() << endl;
442     }
443
444
445 }