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