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