Merge branch 'easysetup'
[platform/upstream/iotivity.git] / service / resource-encapsulation / examples / linux / SeparateResponseServer.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 "RCSSeparateResponse.h"
24
25 #include "OCPlatform.h"
26
27 using namespace OC::OCPlatform;
28 using namespace OIC::Service;
29
30 constexpr int RESOURCE_TEMP = 1;
31 constexpr int RESOURCE_LIGHT = 2;
32
33 RCSResourceObject::Ptr g_resource;
34
35 void handleRequestWithDelay(int delayInMillis, const RCSRequest& request,
36         const RCSResourceAttributes& requestedAttrs)
37 {
38     std::this_thread::sleep_for(std::chrono::milliseconds{ delayInMillis });
39
40     if (!requestedAttrs.empty())
41     {
42         auto resObject = request.getResourceObject().lock();
43
44         RCSResourceObject::LockGuard lock{ resObject };
45         auto& resAttrs = resObject->getAttributes();
46         for (const auto& kv : requestedAttrs)
47         {
48             if (resAttrs.contains(kv.key())) resAttrs[kv.key()] = kv.value();
49         }
50     }
51
52     RCSSeparateResponse(request).set();
53
54     std::cout << "Separate response is set!" << std::endl;
55 }
56
57 void doSeparateResponse(const RCSRequest& request, const RCSResourceAttributes& requestedAttrs)
58 {
59     int delay = std::rand() % 3000 + 500;
60
61     std::cout << "Response will be sent in " << delay << "ms" << std::endl;
62
63     std::thread(handleRequestWithDelay, delay, request, requestedAttrs).detach();
64 }
65
66 int processUserInput(int min, int max)
67 {
68     assert(min <= max);
69
70     int input;
71
72     while(true)
73     {
74         std::cin >> input;
75
76         if (!std::cin.fail())
77         {
78             if(min <= input && input <= max) return input;
79         }
80
81         std::cin.clear();
82         std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
83
84         std::cout << "Invalid Input, please try again\n";
85     }
86 }
87
88 void printAttributes(const RCSResourceAttributes& attrs)
89 {
90     for(const auto& attr : attrs)
91     {
92         std::cout << "\tkey : " << attr.key() << "\n\tvalue : "
93                   << attr.value().toString() << std::endl;
94     }
95 }
96
97 RCSGetResponse requestHandlerForGet(const RCSRequest& request, RCSResourceAttributes&)
98 {
99     std::cout << "Received a Get request from Client" << std::endl;
100
101     doSeparateResponse(request, RCSResourceAttributes{ });
102
103     return RCSGetResponse::separate();
104 }
105
106 RCSSetResponse requestHandlerForSet(const RCSRequest& request, RCSResourceAttributes& attrs)
107 {
108     std::cout << "Received a Set request from Client" << std::endl;
109     printAttributes(attrs);
110
111     doSeparateResponse(request, attrs);
112
113     return RCSSetResponse::separate();
114 }
115
116 void initServer(const std::string& resourceUri, const std::string& resourceType)
117 {
118     g_resource = RCSResourceObject::Builder(resourceUri, resourceType, "oic.if.").build();
119 }
120
121 void selectResourceType()
122 {
123     std::cout << "========================================================\n";
124     std::cout << "Select Resource Type                                    \n";
125     std::cout << RESOURCE_TEMP << ". Temperature                          \n";
126     std::cout << RESOURCE_LIGHT << ". Light                               \n";
127     std::cout << "========================================================\n";
128
129     int resourceType = processUserInput(RESOURCE_TEMP, RESOURCE_LIGHT);
130
131     switch (resourceType)
132     {
133         case RESOURCE_TEMP:
134             initServer("/a/TempSensor", "oic.r.temperaturesensor");
135             break;
136
137         case RESOURCE_LIGHT:
138             initServer("/a/light", "oic.r.light");
139             break;
140     }
141
142     g_resource->setGetRequestHandler(requestHandlerForGet);
143     g_resource->setSetRequestHandler(requestHandlerForSet);
144 }
145
146 int main(void)
147 {
148     selectResourceType();
149
150     std::cout << "Resource successfully created!" << std::endl;
151
152     std::cout << "Press '1' to stop the process" << std::endl;
153
154     while (std::cin.get() != '1');
155
156     std::cout << "Stopping the server" << std::endl;
157
158     g_resource.reset();
159 }
160