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