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