replace : iotivity -> iotivity-sec
[platform/upstream/iotivity.git] / service / resource-encapsulation / examples / linux / NestedAttributesClient.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 <mutex>
24 #include <condition_variable>
25
26 #include "RCSDiscoveryManager.h"
27 #include "RCSRemoteResourceObject.h"
28 #include "RCSResourceAttributes.h"
29 #include "RCSAddress.h"
30
31 #include "OCPlatform.h"
32
33 using namespace OC;
34 using namespace OIC::Service;
35
36 constexpr int CORRECT_INPUT = 1;
37 constexpr int INCORRECT_INPUT = 2;
38 constexpr int QUIT_INPUT = 3;
39
40 enum Menu
41 {
42     GET_ATTRIBUTE = 1,
43     SET_ATTRIBUTE,
44     QUIT,
45     END_OF_MENU
46 };
47
48 typedef void(*ClientMenuHandler)();
49 typedef int ReturnValue;
50
51 struct ClientMenu
52 {
53     Menu m_menu;
54     ClientMenuHandler m_handler;
55     ReturnValue m_result;
56 };
57
58 void getAttributeFromRemoteServer();
59 void setAttributeToRemoteServer();
60
61 ClientMenu clientMenu[] =
62 {
63     {Menu::GET_ATTRIBUTE, getAttributeFromRemoteServer, CORRECT_INPUT},
64     {Menu::SET_ATTRIBUTE, setAttributeToRemoteServer, CORRECT_INPUT},
65     {Menu::QUIT, [](){}, QUIT_INPUT},
66     {Menu::END_OF_MENU, nullptr, INCORRECT_INPUT}
67 };
68
69 const std::string defaultKey = "deviceInfo";
70 const std::string resourceType = "core.ac";
71
72 std::mutex mtx;
73 std::condition_variable cond;
74
75 RCSRemoteResourceObject::Ptr g_resource;
76
77 void displayMenu()
78 {
79     std::cout << std::endl;
80     std::cout << "1 :: Get Attribute" << std::endl;
81     std::cout << "2 :: Set Attribute" << std::endl;
82 }
83
84 void onResourceDiscovered(RCSRemoteResourceObject::Ptr foundResource)
85 {
86     std::cout << "onResourceDiscovered callback" << std::endl;
87
88     std::cout << "\t\tResource URI : " << foundResource->getUri() << std::endl;
89     std::cout << "\t\tResource Host : " << foundResource->getAddress() << std::endl;
90
91     g_resource = foundResource;
92
93     cond.notify_all();
94 }
95
96 void onRemoteAttributesReceivedCallback(const RCSResourceAttributes &attributes, int /*eCode*/)
97 {
98     std::cout << "onRemoteAttributesReceivedCallback callback\n" << std::endl;
99
100     if (attributes.empty())
101     {
102         std::cout << "\tAttribute is Empty" << std::endl;
103         return;
104     }
105
106     for (const auto & attr : attributes)
107     {
108         std::cout << "\tkey : " << attr.key() << "\n\tvalue : "
109                   << attr.value().toString() << std::endl;
110         std::cout << "=============================================\n" << std::endl;
111
112         const auto& doubleVector = attr.value().
113                 get< std::vector< std::vector< RCSResourceAttributes > > >();
114
115         for (const auto& vector : doubleVector)
116         {
117             for (const auto& attrs : vector)
118             {
119                 for (const auto & kvPair : attrs)
120                 {
121                     std::cout << "\t" << kvPair.key() << " : "  <<
122                             kvPair.value().toString() << std::endl;
123                 }
124             }
125             std::cout << std::endl;
126         }
127         std::cout << "=============================================\n" << std::endl;
128     }
129     displayMenu();
130 }
131
132 std::vector< std::vector< RCSResourceAttributes > > createNestedAttribute(int speedValue,
133         int aircValue)
134 {
135     RCSResourceAttributes model;
136     RCSResourceAttributes weight;
137     RCSResourceAttributes dimensions;
138
139     model["model"] = "SamsungAC";
140     weight["weight"] = 3;
141     dimensions["dimensions"] = "10x25x35";
142
143     RCSResourceAttributes speed;
144     RCSResourceAttributes airCirculation;
145
146     speed["speed"] = speedValue;
147     airCirculation["air"] = aircValue;
148
149     RCSResourceAttributes temperature;
150     RCSResourceAttributes humidity;
151
152     temperature["temp"] = 30;
153     humidity["humidity"] = 30;
154
155     RCSResourceAttributes power;
156     RCSResourceAttributes capacity;
157
158     power["power"] = 1600;
159     capacity["capacity"] = 1;
160
161     RCSResourceAttributes red;
162     RCSResourceAttributes green;
163
164     red["red"] = 50;
165     green["green"] = 60;
166
167     std::vector< RCSResourceAttributes > generalInfo{ model, weight, dimensions };
168     std::vector< RCSResourceAttributes > fan{ speed, airCirculation } ;
169     std::vector< RCSResourceAttributes > tempSensor{ temperature, humidity } ;
170     std::vector< RCSResourceAttributes > efficiency{ power, capacity };
171     std::vector< RCSResourceAttributes > light{ red, green };
172
173     std::vector< std::vector< RCSResourceAttributes > > acServer;
174
175     acServer.push_back(generalInfo);
176     acServer.push_back(fan);
177     acServer.push_back(tempSensor);
178     acServer.push_back(efficiency);
179     acServer.push_back(light);
180
181     return acServer;
182 }
183
184 int processUserInput()
185 {
186     int userInput = 0;
187     std::cin >> userInput;
188     if (std::cin.fail())
189     {
190         std::cin.clear();
191         std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
192         return -1;
193     }
194     return userInput;
195 }
196
197 void getAttributeFromRemoteServer()
198 {
199     g_resource->getRemoteAttributes(&onRemoteAttributesReceivedCallback);
200 }
201
202 void setAttributeToRemoteServer()
203 {
204     int speed = 0;
205     int airc = 0;
206
207     std::cout << "\tEnter the Fan Speed you want to set : ";
208     std::cin >> speed;
209     std::cout << "\tEnter the Air circulation value you want to set :";
210     std::cin >> airc;
211
212     RCSResourceAttributes setAttribute;
213     setAttribute[defaultKey] = createNestedAttribute(speed, airc);
214
215     g_resource->setRemoteAttributes(setAttribute,
216                                   &onRemoteAttributesReceivedCallback);
217 }
218
219 int selectClientMenu(int selectedMenu)
220 {
221     for (int i = 0; clientMenu[i].m_menu != Menu::END_OF_MENU; i++)
222     {
223         if (clientMenu[i].m_menu == selectedMenu)
224         {
225             clientMenu[i].m_handler();
226             return clientMenu[i].m_result;
227         }
228     }
229
230     std::cout << "Invalid input, please try again" << std::endl;
231
232     return INCORRECT_INPUT;
233 }
234
235 void process()
236 {
237     while (true)
238     {
239         displayMenu();
240
241         if (selectClientMenu(processUserInput()) == QUIT_INPUT)
242         {
243             break;
244         }
245     }
246 }
247
248 void platFormConfigure()
249 {
250     PlatformConfig config
251     {
252         OC::ServiceType::InProc, ModeType::Client, "0.0.0.0", 0, OC::QualityOfService::LowQos
253     };
254     OCPlatform::Configure(config);
255 }
256
257 bool discoverResource()
258 {
259     std::cout << "Wait 2 seconds until discovered." << std::endl;
260
261     try
262     {
263         RCSDiscoveryManager::getInstance()->discoverResourceByType(RCSAddress::multicast(),
264                 resourceType, &onResourceDiscovered);
265     }
266     catch (const RCSPlatformException& e)
267     {
268          std::cout << e.what() << std::endl;
269     }
270     catch (...)
271     {
272          std::cout << "unknown exception" << std::endl;
273     }
274     std::unique_lock<std::mutex> lck(mtx);
275     cond.wait_for(lck, std::chrono::seconds(2));
276
277     return g_resource != nullptr;
278 }
279
280 int main()
281 {
282     platFormConfigure();
283
284     if (!discoverResource())
285     {
286         std::cout << "Can't discovered Server... Exiting the Client." << std::endl;
287         return -1;
288     }
289
290     try
291     {
292         process();
293     }
294     catch (const std::exception &e)
295     {
296         std::cout << "main exception : " << e.what() << std::endl;
297     }
298
299     std::cout << "Stopping the client" << std::endl;
300
301     return 0;
302 }