Sample implementation of ocf_light
[iotivity.git] / resource / examples / ocf_light / DimmingResource.cpp
1 /*
2  *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
3  *
4  * Copyright 2018 Intel Corporation All Rights Reserved.
5  *
6  *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
21  */
22
23 #include <iostream>
24
25 #include "DimmingResource.h"
26 #include "OCPlatform.h"
27
28 #define INTERFACE_KEY "if"
29
30 using namespace OC;
31 namespace PH = std::placeholders;
32
33 DimmingResource::DimmingResource(std::string resourceUri):
34         m_nr_resource_types{1},
35         m_nr_resource_interfaces{2},
36         m_interestedObservers{},
37         m_var_value_dimmingSetting{100},
38         m_var_value_n{},
39         m_var_value_if{},
40         m_var_value_rt{}
41 {
42     std::cout << "Running: DimmingResource constructor" << std::endl;
43     std::string resourceURI = "/dimming";
44
45     // VS2013 will fail list initialization so use array initialization
46     m_resourceUri = resourceUri;
47     m_RESOURCE_TYPE[0] = "oic.r.light.dimming";
48     m_RESOURCE_INTERFACE[0] = "oic.if.baseline";
49     m_RESOURCE_INTERFACE[1] = "oic.if.a";
50     m_IF_UPDATE[0] = "oic.if.a";
51     m_IF_UPDATE[1] = "oic.if.rw";
52     m_IF_UPDATE[2] = "oic.if.baseline";
53     m_var_name_dimmingSetting = "dimmingSetting";
54     m_var_name_n = "n";
55     m_var_name_if = "if";
56     m_var_name_rt = "rt";
57
58     // initialize member variables /dimming
59     m_var_value_dimmingSetting = 0; // current value of property "dimmingSetting"
60     m_var_value_n = "";  // current value of property "n"
61     // initialize vector if
62     m_var_value_if.push_back("oic.if.baseline");
63     m_var_value_if.push_back("oic.if.a");
64     // initialize vector rt
65     m_var_value_rt.push_back("oic.r.light.dimming");
66 }
67
68 DimmingResource::~DimmingResource(void) { }
69
70 OCStackResult DimmingResource::registerResource(uint8_t resourceProperty)
71 {
72     EntityHandler cb = std::bind(&DimmingResource::entityHandler, this, PH::_1);
73     OCStackResult result = OC_STACK_ERROR;
74     result = OCPlatform::registerResource(m_resourceHandle,
75                                           m_resourceUri,
76                                           m_RESOURCE_TYPE[0],
77                                           m_RESOURCE_INTERFACE[0],
78                                           cb,
79                                           resourceProperty);
80     if (OC_STACK_OK != result)
81     {
82         std::cerr << "Failed to register BinarySwitchResoruce." << std::endl;
83         return result;
84     }
85
86     /// add the additional resource types
87     for( int a = 1; a < m_nr_resource_types; a++ )
88     {
89         result = OCPlatform::bindTypeToResource(m_resourceHandle, m_RESOURCE_TYPE[a].c_str());
90         if (OC_STACK_OK != result)
91         {
92             std::cerr << "Could not bind resource type:" << m_RESOURCE_INTERFACE[a] << std::endl;
93             return result;
94         }
95     }
96     // add the additional interfaces
97     for( int a = 1; a < m_nr_resource_interfaces; a++)
98     {
99         result = OCPlatform::bindInterfaceToResource(m_resourceHandle, m_RESOURCE_INTERFACE[a].c_str());
100         if (OC_STACK_OK != result)
101         {
102             std::cerr << "Could not bind interface:" << m_RESOURCE_INTERFACE[a] << std::endl;
103             return result;
104         }
105     }
106
107     std::cout << "DimmingResource:" << std::endl;
108     std::cout << "\t" << "# resource interfaces: " << m_nr_resource_interfaces << std::endl;
109     std::cout << "\t" << "# resource types     : " << m_nr_resource_types << std::endl;
110
111     return result;
112 }
113
114 int DimmingResource::getDimmingSetting(void)
115 {
116     return m_var_value_dimmingSetting;
117 }
118
119 void DimmingResource::setDimmingSetting(int dimmingSetting)
120 {
121     if (dimmingSetting >= 0 && dimmingSetting <= 100)
122     {
123         m_var_value_dimmingSetting = dimmingSetting;
124         std::cout << "\t\t" << "property 'dimmingSetting': " << m_var_value_dimmingSetting << std::endl;
125     } else {
126         std::cerr << "the dimmingSetting must between 0 and 100" << std::endl;
127     }
128 }
129
130 OCStackResult DimmingResource::sendNotification(void)
131 {
132     OCStackResult sResult = OC_STACK_OK;
133     if ( m_interestedObservers.size() > 0) {
134         std::cout << "Notifying list"  << m_interestedObservers.size() << " of observers\n";
135         auto pResponse = std::make_shared<OC::OCResourceResponse>();
136         sResult = OCPlatform::notifyListOfObservers(m_resourceHandle,
137                                                     m_interestedObservers,
138                                                     pResponse);
139     }
140     return sResult;
141 }
142
143 OC::OCRepresentation DimmingResource::get(OC::QueryParamsMap queries)
144 {
145     OC_UNUSED(queries);
146
147     m_rep.setValue(m_var_name_dimmingSetting, m_var_value_dimmingSetting );
148     m_rep.setValue(m_var_name_n, m_var_value_n );
149     m_rep.setValue(m_var_name_if,  m_var_value_if );
150     m_rep.setValue(m_var_name_rt,  m_var_value_rt );
151
152     return m_rep;
153 }
154
155 OCEntityHandlerResult DimmingResource::post(OC::QueryParamsMap queries, const OC::OCRepresentation& rep)
156 {
157     OCEntityHandlerResult ehResult = OC_EH_OK;
158     OC_UNUSED(queries);
159
160     try {
161         if (rep.hasAttribute(m_var_name_dimmingSetting))
162         {
163             // allocate the variable
164             int value;
165             // get the actual value from the payload
166             rep.getValue(m_var_name_dimmingSetting, value);
167
168             // value exist in payload
169         }
170     }
171     catch (std::exception& e)
172     {
173         std::cout << e.what() << std::endl;
174     }
175
176     if (ehResult == OC_EH_OK)
177     {
178         // no error: assign the variables
179         try {
180             // value exist in payload
181             if (rep.getValue(m_var_name_dimmingSetting, m_var_value_dimmingSetting ))
182             {
183                 std::cout << "\t\t" << "property 'dimmingSetting': " << m_var_value_dimmingSetting << std::endl;
184             }
185             else
186             {
187                 std::cout << "\t\t" << "property 'dimmingSetting' not found in the representation" << std::endl;
188             }
189         }
190         catch (std::exception& e)
191         {
192             std::cout << e.what() << std::endl;
193         }
194
195         try {
196             if (rep.getValue(m_var_name_n, m_var_value_n ))
197             {
198                 std::cout << "\t\t" << "property 'n' : " << m_var_value_n << std::endl;
199             }
200             else
201             {
202                 std::cout << "\t\t" << "property 'n' not found in the representation" << std::endl;
203             }
204         }
205         catch (std::exception& e)
206         {
207             std::cout << e.what() << std::endl;
208         }
209
210         try {
211             if (rep.hasAttribute(m_var_name_if))
212             {
213                 rep.getValue(m_var_name_if, m_var_value_if);
214                 int first = 1;
215                 std::cout << "\t\t" << "property 'if' : " ;
216                 for(auto myvar: m_var_value_if)
217                 {
218                     if (first)
219                     {
220                         std::cout << myvar;
221                         first = 0;
222                     }
223                     else
224                     {
225                         std::cout << "," << myvar;
226                     }
227                 }
228                 std::cout <<  std::endl;
229             }
230             else
231             {
232                 std::cout << "\t\t" << "property 'if' not found in the representation" << std::endl;
233             }
234         }
235         catch (std::exception& e)
236         {
237             std::cout << e.what() << std::endl;
238         }
239
240         try {
241             if (rep.hasAttribute(m_var_name_rt))
242             {
243                 rep.getValue(m_var_name_rt, m_var_value_rt);
244                 int first = 1;
245                 std::cout << "\t\t" << "property 'rt' : " ;
246                 for(auto myvar: m_var_value_rt)
247                 {
248                     if (first)
249                     {
250                         std::cout << myvar;
251                         first = 0;
252                     }
253                     else
254                     {
255                         std::cout << "," << myvar;
256                     }
257                 }
258                 std::cout <<  std::endl;
259             }
260             else
261             {
262                 std::cout << "\t\t" << "property 'rt' not found in the representation" << std::endl;
263             }
264         }
265         catch (std::exception& e)
266         {
267             std::cout << e.what() << std::endl;
268         }
269     }
270     return ehResult;
271 }
272
273 OCEntityHandlerResult DimmingResource::entityHandler(std::shared_ptr<OC::OCResourceRequest> request)
274 {
275     OCEntityHandlerResult ehResult = OC_EH_ERROR;
276
277     if (request)
278     {
279         std::cout << "In entity handler for DimmingResource, URI is : "
280                 << request->getResourceUri() << std::endl;
281
282         // Check for query params (if any)
283         QueryParamsMap queries = request->getQueryParameters();
284         if (!queries.empty())
285         {
286             std::cout << "\nQuery processing up to entityHandler" << std::endl;
287         }
288         for (auto it : queries)
289         {
290             std::cout << "Query key: " << it.first << " value : " << it.second
291                     << std::endl;
292         }
293         // get the value, so that we can AND it to check which flags are set
294         int requestFlag = request->getRequestHandlerFlag();
295
296         if (requestFlag & RequestHandlerFlag::RequestFlag)
297         {
298             // request flag is set
299             auto pResponse = std::make_shared<OC::OCResourceResponse>();
300             pResponse->setRequestHandle(request->getRequestHandle());
301             pResponse->setResourceHandle(request->getResourceHandle());
302
303             if (request->getRequestType() == "GET")
304             {
305                 std::cout<<"DimmingResource Get Request"<< std::endl;
306
307                 pResponse->setResourceRepresentation(get(queries), "");
308                 if (OC_STACK_OK == OCPlatform::sendResponse(pResponse))
309                 {
310                     ehResult = OC_EH_OK;
311                 }
312             }
313
314             else if (request->getRequestType() == "POST")
315             {
316                 std::cout <<"DimmingResource Post Request"<<std::endl;
317                 bool  handle_post = true;
318
319                 if (queries.size() > 0)
320                 {
321                     for (const auto &eachQuery : queries)
322                     {
323                         std::string key = eachQuery.first;
324                         if (key.compare(INTERFACE_KEY) == 0)
325                         {
326                             std::string value = eachQuery.second;
327                             if (in_updatable_interfaces(value) == false)
328                             {
329                                 std::cout << "Update request received via interface: " << value
330                                         << " . This interface is not authorized to update resource!!" << std::endl;
331                                 pResponse->setResponseResult(OCEntityHandlerResult::OC_EH_FORBIDDEN);
332                                 handle_post = false;
333                                 ehResult = OC_EH_ERROR;
334                                 break;
335                             }
336                         }
337                     }
338                 }
339                 if (handle_post)
340                 {
341                     ehResult = post(queries, request->getResourceRepresentation());
342                     if (ehResult == OC_EH_OK)
343                     {
344                         pResponse->setResourceRepresentation(get(queries), "");
345                     }
346                     else
347                     {
348                         pResponse->setResponseResult(OCEntityHandlerResult::OC_EH_ERROR);
349                     }
350                     if (OC_STACK_OK == OCPlatform::sendResponse(pResponse))
351                     {
352                         if (OC_STACK_OK != sendNotification() )
353                         {
354                             std::cerr << "NOTIFY failed." << std::endl;
355                         }
356                     }
357                 }
358             }
359             else
360             {
361                 std::cout << "DimmingResource unsupported request type (delete,put,..)"
362                         << request->getRequestType() << std::endl;
363                 pResponse->setResponseResult(OC_EH_ERROR);
364                 OCPlatform::sendResponse(pResponse);
365                 ehResult = OC_EH_ERROR;
366             }
367         }
368
369         if (requestFlag & RequestHandlerFlag::ObserverFlag)
370         {
371             // observe flag is set
372             std::cout << "\t\trequestFlag : Observer ";
373             ObservationInfo observationInfo = request->getObservationInfo();
374             ((ObserveAction::ObserveRegister == observationInfo.action) ? std::cout << "Register\n" : std::cout << "Unregister\n");
375             if (ObserveAction::ObserveRegister == observationInfo.action)
376             {
377                 // add observer
378                 m_interestedObservers.push_back(observationInfo.obsId);
379             }
380             else if (ObserveAction::ObserveUnregister == observationInfo.action)
381             {
382                 // delete observer
383                 m_interestedObservers.erase(std::remove(
384                                             m_interestedObservers.begin(),
385                                             m_interestedObservers.end(),
386                                             observationInfo.obsId),
387                                             m_interestedObservers.end());
388             }
389             ehResult = OC_EH_OK;
390         }
391     }
392     return ehResult;
393 }