Merge "Added style formatting config files for iotivity coding standards"
[platform/upstream/iotivity.git] / resource / examples / garageserver.cpp
1 //******************************************************************
2 //
3 // Copyright 2014 Intel Mobile Communications GmbH 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 ///
22 /// This sample provides using varous json types in the representation.
23 ///
24
25 #include <functional>
26
27 #include <pthread.h>
28 #include <mutex>
29 #include <condition_variable>
30
31 #include "OCPlatform.h"
32 #include "OCApi.h"
33
34 using namespace OC;
35 using namespace std;
36
37 // Forward declaring the entityHandler
38 OCEntityHandlerResult entityHandler(std::shared_ptr<OCResourceRequest> request);
39
40 /// This class represents a single resource named 'lightResource'. This resource has
41
42 class GarageResource
43 {
44 public:
45     /// Access this property from a TB client
46     std::string m_name;
47     bool m_state;
48     std::string m_garageUri;
49     OCResourceHandle m_resourceHandle;
50     OCRepresentation m_garageRep;
51     ObservationIds m_interestedObservers;
52
53     // array of lights representation with in GarageResource
54     OCRepresentation m_lightRep;
55     std::vector<OCRepresentation> m_reps;
56
57 public:
58     /// Constructor
59     GarageResource(): m_name("John's Garage"), m_state(false), m_garageUri("/a/garage") {
60         // Initialize representation
61         m_garageRep.setUri(m_garageUri);
62
63         m_garageRep.setValue("state", m_state);
64         m_garageRep.setValue("name", m_name);
65
66         // For demonstration purpose we are setting x to nullptr here.
67         // In reality it may happen else where.
68         int* x = nullptr;
69
70         // Check for nullptr and set null for that attribute
71         if(x == nullptr)
72         {
73             m_garageRep.setNULL("nullAttribute");
74         }
75
76         std::vector<bool> lightStates;
77         std::vector<int>  lightPowers;
78
79         for(int i = 0; i <= 9; i++)
80         {
81             lightStates.push_back(i % 2 == 0);
82             lightPowers.push_back(i);
83         }
84
85         m_lightRep.setValue("states", lightStates);
86         m_lightRep.setValue("powers", lightPowers);
87
88         // Storing another representation within a representation
89         m_garageRep.setValue("light", m_lightRep);
90
91         OCRepresentation rep1;
92         int value1 = 5;
93         rep1.setValue("key1", value1);
94         OCRepresentation rep2;
95         int value2 = 10;
96         rep2.setValue("key2", value2);
97
98         m_reps.push_back(rep1);
99         m_reps.push_back(rep2);
100
101         // storing array of representations
102         m_garageRep.setValue("reps", m_reps);
103
104
105         // setting json string
106         std::string json = "{\"num\":10,\"rno\":23.5,\"aoa\":[[1,2],[3]],\"str\":\"john\",\
107 \"object\":{\"bl1\":false,\"ar\":[2,3]}, \"objects\":[{\"bl2\":true,\"nl\":null},{\"ar1\":[1,2]}]}";
108         m_garageRep.setValue("json", json);
109     }
110
111     /* Note that this does not need to be a member function: for classes you do not have
112     access to, you can accomplish this with a free function: */
113
114     /// This function internally calls registerResource API.
115     void createResource()
116     {
117         std::string resourceURI = m_garageUri; // URI of the resource
118         std::string resourceTypeName = "core.garage"; // resource type name.
119         std::string resourceInterface = DEFAULT_INTERFACE; // resource interface.
120
121         // OCResourceProperty is defined ocstack.h
122         uint8_t resourceProperty = OC_DISCOVERABLE | OC_OBSERVABLE;
123
124         // This will internally create and register the resource.
125         OCStackResult result = OCPlatform::registerResource(
126                                     m_resourceHandle, resourceURI, resourceTypeName,
127                                     resourceInterface, &entityHandler, resourceProperty);
128
129         if (OC_STACK_OK != result)
130         {
131             cout << "Resource creation was unsuccessful\n";
132         }
133     }
134
135     OCResourceHandle getHandle()
136     {
137         return m_resourceHandle;
138     }
139
140     // Puts representation.
141     // Gets values from the representation and
142     // updates the internal state
143     void put(OCRepresentation& rep)
144     {
145         try {
146             if (rep.getValue("state", m_state))
147             {
148                 cout << "\t\t\t\t" << "state: " << m_state << endl;
149             }
150             else
151             {
152                 cout << "\t\t\t\t" << "state not found in the representation" << endl;
153             }
154         }
155         catch (exception& e)
156         {
157             cout << e.what() << endl;
158         }
159
160     }
161
162     // gets the updated representation.
163     // Updates the representation with latest internal state before
164     // sending out.
165     OCRepresentation get()
166     {
167         m_garageRep.setValue("state", m_state);
168
169         return m_garageRep;
170     }
171
172 };
173
174 // Create the instance of the resource class (in this case instance of class 'GarageResource').
175 GarageResource myGarage;
176
177 OCStackResult sendResponse(std::shared_ptr<OCResourceRequest> pRequest)
178 {
179     auto pResponse = std::make_shared<OC::OCResourceResponse>();
180     pResponse->setRequestHandle(pRequest->getRequestHandle());
181     pResponse->setResourceHandle(pRequest->getResourceHandle());
182     pResponse->setResourceRepresentation(myGarage.get());
183     pResponse->setErrorCode(200);
184     pResponse->setResponseResult(OC_EH_OK);
185
186     return OCPlatform::sendResponse(pResponse);
187 }
188
189 OCEntityHandlerResult entityHandler(std::shared_ptr<OCResourceRequest> request)
190 {
191     cout << "\tIn Server CPP entity handler:\n";
192     OCEntityHandlerResult ehResult = OC_EH_ERROR;
193
194     if(request)
195     {
196         // Get the request type and request flag
197         std::string requestType = request->getRequestType();
198         int requestFlag = request->getRequestHandlerFlag();
199
200         if(requestFlag & RequestHandlerFlag::InitFlag)
201         {
202             cout << "\t\trequestFlag : Init\n";
203
204             // entity handler to perform resource initialization operations
205         }
206         if(requestFlag & RequestHandlerFlag::RequestFlag)
207         {
208             cout << "\t\trequestFlag : Request\n";
209
210             // If the request type is GET
211             if(requestType == "GET")
212             {
213                 cout << "\t\t\trequestType : GET\n";
214                 if(OC_STACK_OK == sendResponse(request))
215                 {
216                     ehResult = OC_EH_OK;
217                 }
218             }
219             else if(requestType == "PUT")
220             {
221                 cout << "\t\t\trequestType : PUT\n";
222                 OCRepresentation rep = request->getResourceRepresentation();
223                 // Do related operations related to PUT request
224                 myGarage.put(rep);
225                 if(OC_STACK_OK == sendResponse(request))
226                 {
227                     ehResult = OC_EH_OK;
228                 }
229             }
230             else if(requestType == "POST")
231             {
232                 // POST request operations
233             }
234             else if(requestType == "DELETE")
235             {
236                 // DELETE request operations
237             }
238         }
239         if(requestFlag & RequestHandlerFlag::ObserverFlag)
240         {
241             // OBSERVE operations
242         }
243     }
244     else
245     {
246         std::cout << "Request invalid" << std::endl;
247     }
248
249     return ehResult;
250 }
251
252 int main(int argc, char* argv[1])
253 {
254     // Create PlatformConfig object
255     PlatformConfig cfg {
256         OC::ServiceType::InProc,
257         OC::ModeType::Server,
258         "0.0.0.0", // By setting to "0.0.0.0", it binds to all available interfaces
259         0,         // Uses randomly available port
260         OC::QualityOfService::LowQos
261     };
262
263     OCPlatform::Configure(cfg);
264     try
265     {
266         // Invoke createResource function of class light.
267         myGarage.createResource();
268
269         // A condition variable will free the mutex it is given, then do a non-
270         // intensive block until 'notify' is called on it.  In this case, since we
271         // don't ever call cv.notify, this should be a non-processor intensive version
272         // of while(true);
273         std::mutex blocker;
274         std::condition_variable cv;
275         std::unique_lock<std::mutex> lock(blocker);
276         cv.wait(lock);
277     }
278     catch(OCException e)
279     {
280         //log(e.what());
281     }
282
283     // No explicit call to stop the OCPlatform
284     // When OCPlatform destructor is invoked, internally we do Platform cleanup
285
286     return 0;
287 }