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