replace : iotivity -> iotivity-sec
[platform/upstream/iotivity.git] / service / resource-encapsulation / examples / linux / SampleResourceServer.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 "RCSRequest.h"
23 #include "OCPlatform.h"
24
25 using namespace OC::OCPlatform;
26 using namespace OIC::Service;
27
28 struct CloseApp{};
29
30 constexpr int RESOURCE_TEMP = 1;
31 constexpr int RESOURCE_LIGHT = 2;
32
33 constexpr int DEFAULT_SERVER = 1;
34 constexpr int CUSTOM_SERVER = 2;
35
36 constexpr int INCREASE = 1;
37 constexpr int DECREASE = 2;
38
39 const std::string BASELINE_INTERFACE = "oic.if.baseline";
40 const std::string ACTUATOR_INTERFACE = "oic.if.a";
41 const std::string SENSOR_INTERFACE = "oic.if.s";
42 const std::string CUSTOM_INTERFACE = "test.custom";
43
44 typedef void (*DisplayControlMenuFunc)();
45 typedef std::function<void()> Run;
46
47 Run g_currentRun;
48
49 bool g_isPresenceStarted = false;
50
51 RCSResourceObject::Ptr g_resource;
52
53 int processUserInput(int min, int max)
54 {
55     assert(min <= max);
56
57     int input = 0;
58
59     std::cin >> input;
60
61     if (!std::cin.fail())
62     {
63         if (input == max + 1)
64         {
65             throw CloseApp();
66         }
67         if (min <= input && input <= max)
68         {
69             return input;
70         }
71     }
72
73     std::cin.clear();
74     std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
75
76     throw std::runtime_error("Invalid Input, please try again");
77 }
78
79 void displayControlTemperatureMenu()
80 {
81     std::cout << "========================================================\n";
82     std::cout << INCREASE << ". Increase Temperature by 1 degree          \n";
83     std::cout << DECREASE << ". Decrease Temperature by 1 degree          \n";
84     std::cout << DECREASE + 1 << ". Quit                                  \n";
85     std::cout << "========================================================\n";
86 }
87
88 void displayControlLightMenu()
89 {
90     std::cout << "========================================================\n";
91     std::cout << INCREASE << ". Increase Brightness by 1 stage            \n";
92     std::cout << DECREASE << ". Decrease Brightness by 1 stage            \n";
93     std::cout << DECREASE + 1 << ". Quit                                  \n";
94     std::cout << "========================================================\n";
95 }
96
97 void printAttributes(const RCSResourceAttributes& attrs)
98 {
99     for (const auto& attr : attrs)
100     {
101         std::cout << "\tkey : " << attr.key() << "\n\tvalue : "
102                   << attr.value().toString() << std::endl;
103     }
104 }
105
106 RCSGetResponse requestHandlerForGet(const RCSRequest & req, RCSResourceAttributes& attrs)
107 {
108     std::cout << "Received a Get request from Client" << std::endl;
109     printAttributes(attrs);
110
111     {
112         RCSResourceObject::LockGuard lock(g_resource);
113         std::cout << "\nSending response to Client : " << std::endl;
114         if (req.getInterface() == CUSTOM_INTERFACE)
115         {
116             auto attr = g_resource->getAttributes();
117             static RCSByteString::DataType binval {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
118                                                    0x9, 0x0, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF};
119             attr["blob"] = RCSByteString {binval};
120             printAttributes(attr);
121             return RCSGetResponse::create(attr);
122         }
123         else
124         {
125             printAttributes(g_resource->getAttributes());
126             return RCSGetResponse::defaultAction();
127         }
128     }
129 }
130
131 RCSSetResponse requestHandlerForSet(const RCSRequest&, RCSResourceAttributes& attrs)
132 {
133     std::cout << "Received a Set request from Client" << std::endl;
134     printAttributes(attrs);
135
136     return RCSSetResponse::defaultAction();
137 }
138
139 void initServer(const std::string& resourceUri, const std::string& resourceType,
140         const std::string& attrKey)
141 {
142     g_resource = RCSResourceObject::Builder(resourceUri, resourceType, ACTUATOR_INTERFACE)
143             .addInterface(CUSTOM_INTERFACE)
144             .addInterface(SENSOR_INTERFACE)
145             .setDefaultInterface(BASELINE_INTERFACE)
146             .setDiscoverable(true)
147             .setObservable(true)
148             .build();
149
150     g_resource->setAutoNotifyPolicy(RCSResourceObject::AutoNotifyPolicy::UPDATED);
151     g_resource->setSetRequestHandlerPolicy(RCSResourceObject::SetRequestHandlerPolicy::NEVER);
152     g_resource->setAttribute(attrKey, 0);
153 }
154
155 void updateAttribute(const std::string& attrKey, int control)
156 {
157     const int diff = control == INCREASE ? 1 : - 1;
158
159     {
160         RCSResourceObject::LockGuard lock(g_resource);
161         auto& attrs = g_resource->getAttributes();
162         attrs[attrKey] = attrs[attrKey].get<int>() + diff;
163     }
164
165     if (control == INCREASE)
166     {
167         std::cout << attrKey << " increased." << std::endl;
168     }
169     else
170     {
171         std::cout << attrKey << " decreased." << std::endl;
172     }
173     std::cout << "\nCurrent " << attrKey << ": "
174             << g_resource->getAttributeValue(attrKey).get<int>() << std::endl;
175 }
176
177 void runResourceControl(DisplayControlMenuFunc displayMenuFunc, const std::string& attrKey)
178 {
179     displayMenuFunc();
180     updateAttribute(attrKey, processUserInput(INCREASE, DECREASE));
181 }
182
183 void runResourceTypeSelection(int resourceMode)
184 {
185     std::cout << "========================================================\n";
186     std::cout << "Select Resource Type                                    \n";
187     std::cout << RESOURCE_TEMP << ". Temperature                          \n";
188     std::cout << RESOURCE_LIGHT << ". Light                               \n";
189     std::cout << RESOURCE_LIGHT + 1 << ". Quit                            \n";
190     std::cout << "========================================================\n";
191
192     int resourceType = processUserInput(RESOURCE_TEMP, RESOURCE_LIGHT);
193     DisplayControlMenuFunc displayMenuFunc = nullptr;
194     std::string attrKey;
195
196     switch (resourceType)
197     {
198         case RESOURCE_TEMP:
199             attrKey = "Temperature";
200             initServer("/a/TempSensor", "oic.r.temperaturesensor", attrKey);
201
202             displayMenuFunc = displayControlTemperatureMenu;
203             break;
204
205         case RESOURCE_LIGHT:
206             attrKey = "Brightness";
207             initServer("/a/light", "oic.r.light", attrKey);
208
209             displayMenuFunc = displayControlLightMenu;
210             break;
211     }
212
213     if (resourceMode == CUSTOM_SERVER)
214     {
215         g_resource->setGetRequestHandler(requestHandlerForGet);
216         g_resource->setSetRequestHandler(requestHandlerForSet);
217     }
218
219     g_currentRun = std::bind(runResourceControl, displayMenuFunc, std::move(attrKey));
220 }
221
222 void runResourceModeSelection()
223 {
224     std::cout << "========================================================          \n";
225     std::cout << DEFAULT_SERVER << ". Creation of Simple Resource Without Handlers  \n";
226     std::cout << CUSTOM_SERVER << ". Creation of Resource With Set and Get Handlers \n";
227     std::cout << CUSTOM_SERVER + 1 << ". Quit                                       \n";
228     std::cout << "========================================================          \n";
229
230     g_currentRun = std::bind(runResourceTypeSelection,
231             processUserInput(DEFAULT_SERVER, CUSTOM_SERVER));
232 }
233
234 void runPresenceSelection()
235 {
236     constexpr int PRESENCE_ON = 1;
237     constexpr int PRESENCE_OFF = 2;
238
239     std::cout << "========================================================\n";
240     std::cout << PRESENCE_ON << ". Presence On                            \n";
241     std::cout << PRESENCE_OFF << ". Presence Off                          \n";
242     std::cout << PRESENCE_OFF + 1 << ". Quit                              \n";
243     std::cout << "========================================================\n";
244
245     if (processUserInput(PRESENCE_ON, PRESENCE_OFF) == PRESENCE_ON)
246     {
247         g_isPresenceStarted = true;
248         startPresence(3);
249     }
250
251     g_currentRun = runResourceModeSelection;
252 }
253
254 int main(void)
255 {
256     g_currentRun = runPresenceSelection;
257
258     while (true)
259     {
260         try
261         {
262             g_currentRun();
263         }
264         catch (const std::exception& e)
265         {
266             std::cout << e.what() << std::endl;
267         }
268         catch (const CloseApp&)
269         {
270             break;
271         }
272     }
273     std::cout << "Stopping the server" << std::endl;
274
275     g_resource.reset();
276
277     if (g_isPresenceStarted)
278     {
279         try
280         {
281             stopPresence();
282         }
283         catch(...)
284         {
285             std::cout << "presence stop fail" << std::endl;
286         }
287     }
288 }
289