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