Merge branch 'master' into cloud-interface
[platform/upstream/iotivity.git] / service / resource-encapsulation / examples / linux / NestedAttributesServer.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 "RCSResourceObject.h"
22 #include "OCPlatform.h"
23 #include "OCApi.h"
24
25 #define nestedAtrribute std::vector<std::vector<RCSResourceAttributes>>
26
27 using namespace OC;
28 using namespace OC::OCPlatform;
29 using namespace OIC::Service;
30
31 constexpr int DEFAULT_SPEED = 30;
32 constexpr int UP_SPEED = 50;
33 constexpr int DOWN_SPEED = 10;
34
35 constexpr int DEFALUT_SERVER = 1;
36 constexpr int CUSTOM_SERVER = 2;
37 constexpr int STOP = 3;
38
39 constexpr int PRINT_ATTRIBUTES = 1;
40 constexpr int INCREASE_SPEEDATTRIBUTE = 2;
41 constexpr int DECREASE_SPEEDATTRIBUTE = 3;
42 constexpr int STOP_SENSOR = 4;
43
44 constexpr int CORRECT_INPUT = 1;
45 constexpr int INCORRECT_INPUT = 2;
46 constexpr int QUIT = 3;
47
48 std::string resourceUri = "/a/airConditioner";
49 std::string resourceType = "core.ac";
50 std::string resourceInterface = "oic.if.";
51 std::string attributeKey = "deviceInfo";
52
53 RCSResourceAttributes model;
54 RCSResourceAttributes speed;
55 RCSResourceAttributes airCirculation;
56 RCSResourceAttributes temperature;
57 RCSResourceAttributes humidity;
58 RCSResourceAttributes power;
59 RCSResourceAttributes capacity;
60 RCSResourceAttributes weight;
61 RCSResourceAttributes dimensions;
62 RCSResourceAttributes red;
63 RCSResourceAttributes green;
64
65 std::vector<RCSResourceAttributes> generalInfo;
66 std::vector<RCSResourceAttributes> fan;
67 std::vector<RCSResourceAttributes> tempSensor;
68 std::vector<RCSResourceAttributes> efficiency;
69 std::vector<RCSResourceAttributes> light;
70
71 RCSResourceObject::Ptr server;
72
73 void displayMenu()
74 {
75     std::cout << "====================================================================="
76               << std::endl;
77     std::cout << "   1 - Creation of Resource [Auto control for requests]" << std::endl;
78     std::cout << "   2 - Creation of Resource [Developer control for Get and Set requests]"
79               << std::endl;
80     std::cout << "   3 - Quit" << std::endl;
81     std::cout << "====================================================================="
82               << std::endl;
83 }
84
85 void displayControlMenu()
86 {
87     std::cout << "========================================================" << std::endl;
88     std::cout << "1. Print Nested attributes" << std::endl;
89     std::cout << "2. Increase Speed attributes" << std::endl;
90     std::cout << "3. Decrease Speed attributes" << std::endl;
91     std::cout << "4. Stop the Sensor" << std::endl;
92     std::cout << "========================================================" << std::endl;
93 }
94
95 nestedAtrribute createNestedAttribute(int speedValue)
96 {
97     nestedAtrribute *acServer = new nestedAtrribute();
98
99     model["model"] = "SamsungAC";
100
101     speed["speed"] = speedValue;
102     airCirculation["air"] = 425;
103
104     temperature["temp"] = 30;
105     humidity["humidity"] = 30;
106
107     power["power"] = 1600;
108     capacity["capacity"] = 1;
109
110     weight["weight"] = 3;
111     dimensions["dimensions"] = "10x25x35";
112
113     red["red"] = 50;
114     green["green"] = 60;
115
116     generalInfo.clear();
117     generalInfo.push_back(model);
118     generalInfo.push_back(weight);
119     generalInfo.push_back(dimensions);
120
121     fan.clear();
122     fan.push_back(speed);
123     fan.push_back(airCirculation);
124
125     tempSensor.clear();
126     tempSensor.push_back(temperature);
127     tempSensor.push_back(humidity);
128
129     efficiency.clear();
130     efficiency.push_back(power);
131     efficiency.push_back(capacity);
132
133     light.clear();
134     light.push_back(red);
135     light.push_back(green);
136
137     if (nullptr == acServer)
138     {
139          std::cout << "Null nestedAtrribute" << std::endl;
140     }
141     else
142     {
143         acServer->push_back(generalInfo);
144         acServer->push_back(fan);
145         acServer->push_back(tempSensor);
146         acServer->push_back(efficiency);
147         acServer->push_back(light);
148     }
149
150     return *acServer;
151 }
152
153 void printAttribute(const RCSResourceAttributes &attrs)
154 {
155     for (const auto & attr : attrs)
156     {
157         std::cout << "\tkey : " << attr.key() << "\n\tvalue : "
158                   << attr.value().toString() << std::endl;
159         std::cout << "=============================================\n" << std::endl;
160
161         OIC::Service::RCSResourceAttributes::Value attrValue =  attr.value();
162         std::vector< std::vector<RCSResourceAttributes >> attrVector =
163                     attrValue.get<std::vector< std::vector<RCSResourceAttributes >>>();
164
165         for (auto itr = attrVector.begin(); itr != attrVector.end(); ++itr)
166         {
167             std::vector<RCSResourceAttributes > attrKeyVector = *itr;
168             for (auto itrKey = attrKeyVector.begin(); itrKey != attrKeyVector.end(); ++itrKey)
169             {
170                 for (const auto & attribute : *itrKey)
171                 {
172                     std::cout << "\t" << attribute.key() << "  :  "  << attribute.value().toString() << std::endl;
173                 }
174             }
175             std::cout << std::endl;
176         }
177         std::cout << "=============================================\n" << std::endl;
178     }
179 }
180
181 void printNestedAttribute()
182 {
183     RCSResourceObject::LockGuard lock(*server);
184     RCSResourceAttributes attributes = server->getAttributes();
185
186     std::cout << "\nPrinting nested attributes" << std::endl;
187     printAttribute(attributes);
188     return;
189 }
190
191 void changeSpeedAttribute(int state)
192 {
193     nestedAtrribute attr;
194
195     if (INCREASE_SPEEDATTRIBUTE == state)
196     {
197         std::cout << "Increasing speed  attribute to : " << UP_SPEED  <<  std::endl;
198         attr = createNestedAttribute(UP_SPEED);
199     }
200     else if (DECREASE_SPEEDATTRIBUTE == state)
201     {
202         std::cout << "Decreasing speed  attribute to : " << DOWN_SPEED << std::endl;
203         attr = createNestedAttribute(DOWN_SPEED);
204     }
205
206     RCSResourceObject::LockGuard lock(*server);
207     server->getAttributes()[attributeKey] = attr;
208     printNestedAttribute();
209 }
210
211 //hander for get request (if developer choose second option for resource Creation)
212 RCSGetResponse requestHandlerForGet(const RCSRequest& /*request*/,
213                                     RCSResourceAttributes& /*attrs*/)
214 {
215     std::cout << "Recieved a Get request from Client" << std::endl;
216
217     RCSResourceObject::LockGuard lock(*server);
218     RCSResourceAttributes attributes = server->getAttributes();
219
220     std::cout << "\nSending response to Client : " << std::endl;
221     printAttribute(attributes);
222
223     return RCSGetResponse::defaultAction();
224 }
225
226 //hander for set request (if developer choose second option for resource Creation)
227 RCSSetResponse requestHandlerForSet(const RCSRequest& /*request*/,
228                                     RCSResourceAttributes &attrs)
229 {
230     std::cout << "Recieved a Set request from Client" << std::endl;
231
232     std::cout << "\n\nSending response to Client : " << std::endl;
233     RCSResourceObject::LockGuard lock(*server);
234     printAttribute(attrs);
235     return RCSSetResponse::defaultAction();
236 }
237
238 void createResource()
239 {
240     server = RCSResourceObject::Builder(resourceUri, resourceType,
241                                         resourceInterface).setDiscoverable(true).setObservable(true).build();
242 }
243
244 void initServer()
245 {
246     try
247     {
248         createResource();
249     }
250     catch (const RCSPlatformException &e)
251     {
252         std::cout << "Exception in initServer : " << e.what() << std::endl;
253     }
254
255     if (nullptr == server)
256     {
257          std::cout << "Null server resource" << std::endl;
258          return;
259     }
260
261     server->setAutoNotifyPolicy(RCSResourceObject::AutoNotifyPolicy::UPDATED);
262     server->setSetRequestHandlerPolicy(RCSResourceObject::SetRequestHandlerPolicy::NEVER);
263
264     nestedAtrribute attr = createNestedAttribute(DEFAULT_SPEED);
265     server->setAttribute(attributeKey, attr);
266 }
267
268 int processUserInput()
269 {
270     int userInput;
271     std::cin >> userInput;
272     if (std::cin.fail())
273     {
274         std::cin.clear();
275         std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
276         return -1;
277     }
278     return userInput;
279 }
280
281 int selectControlMenu()
282 {
283     switch (processUserInput())
284     {
285         case PRINT_ATTRIBUTES:
286             printNestedAttribute();
287             return CORRECT_INPUT;
288
289         case INCREASE_SPEEDATTRIBUTE:
290             changeSpeedAttribute(INCREASE_SPEEDATTRIBUTE);
291             return CORRECT_INPUT;
292
293         case DECREASE_SPEEDATTRIBUTE:
294             changeSpeedAttribute(DECREASE_SPEEDATTRIBUTE);
295             return CORRECT_INPUT;
296
297         case STOP_SENSOR:
298             return QUIT;
299
300         default:
301             std::cout << "Invalid input. Please try again." << std::endl;
302             return INCORRECT_INPUT;
303     }
304 }
305
306 int selectServerMenu()
307 {
308     switch (processUserInput())
309     {
310         case DEFALUT_SERVER: // Creation of Resource & Auto control for all requests from Client.
311             initServer();
312             return CORRECT_INPUT;
313
314         case CUSTOM_SERVER:
315             // Creation of Resource & setting get and set handler for handling get and
316             // set request from client in application.
317             initServer();
318
319             server->setGetRequestHandler(requestHandlerForGet);
320             server->setSetRequestHandler(requestHandlerForSet);
321             return CORRECT_INPUT;
322         case STOP :
323             return QUIT;
324
325         default :
326             std::cout << "Invalid input, please try again" << std::endl;
327             return INCORRECT_INPUT;
328     }
329 }
330
331 void process()
332 {
333     while (true)
334     {
335         displayMenu();
336
337         int ret = selectServerMenu();
338
339         if (ret == QUIT) return;
340         if (ret == CORRECT_INPUT) break;
341     }
342
343     while (true)
344     {
345         displayControlMenu();
346
347         if (selectControlMenu() == QUIT) return;
348     }
349 }
350
351 int main(void)
352 {
353     startPresence(3);
354
355     try
356     {
357         process();
358         server = NULL;
359     }
360     catch (const std::exception &e)
361     {
362         std::cout << "main exception  : " << e.what() << std::endl;
363     }
364
365     std::cout << "Stopping the Server" << std::endl;
366 }