Fix to apply Coding convention on services.
[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()))
49             {
50                 resAttrs[kv.key()] = kv.value();
51             }
52         }
53     }
54
55     RCSSeparateResponse(request).set();
56
57     std::cout << "Separate response is set!" << std::endl;
58 }
59
60 void doSeparateResponse(const RCSRequest& request, const RCSResourceAttributes& requestedAttrs)
61 {
62     int delay = std::rand() % 3000 + 500;
63
64     std::cout << "Response will be sent in " << delay << "ms" << std::endl;
65
66     std::thread(handleRequestWithDelay, delay, request, requestedAttrs).detach();
67 }
68
69 int processUserInput(int min, int max)
70 {
71     assert(min <= max);
72
73     int input;
74
75     while(true)
76     {
77         std::cin >> input;
78
79         if (!std::cin.fail())
80         {
81             if(min <= input && input <= max)
82             {
83                 return input;
84             }
85         }
86
87         std::cin.clear();
88         std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
89
90         std::cout << "Invalid Input, please try again\n";
91     }
92 }
93
94 void printAttributes(const RCSResourceAttributes& attrs)
95 {
96     for(const auto& attr : attrs)
97     {
98         std::cout << "\tkey : " << attr.key() << "\n\tvalue : "
99                   << attr.value().toString() << std::endl;
100     }
101 }
102
103 RCSGetResponse requestHandlerForGet(const RCSRequest& request, RCSResourceAttributes&)
104 {
105     std::cout << "Received a Get request from Client" << std::endl;
106
107     doSeparateResponse(request, RCSResourceAttributes{ });
108
109     return RCSGetResponse::separate();
110 }
111
112 RCSSetResponse requestHandlerForSet(const RCSRequest& request, RCSResourceAttributes& attrs)
113 {
114     std::cout << "Received a Set request from Client" << std::endl;
115     printAttributes(attrs);
116
117     doSeparateResponse(request, attrs);
118
119     return RCSSetResponse::separate();
120 }
121
122 void initServer(const std::string& resourceUri, const std::string& resourceType)
123 {
124     g_resource = RCSResourceObject::Builder(resourceUri, resourceType, "oic.if.").build();
125 }
126
127 void selectResourceType()
128 {
129     std::cout << "========================================================\n";
130     std::cout << "Select Resource Type                                    \n";
131     std::cout << RESOURCE_TEMP << ". Temperature                          \n";
132     std::cout << RESOURCE_LIGHT << ". Light                               \n";
133     std::cout << "========================================================\n";
134
135     int resourceType = processUserInput(RESOURCE_TEMP, RESOURCE_LIGHT);
136
137     switch (resourceType)
138     {
139         case RESOURCE_TEMP:
140             initServer("/a/TempSensor", "oic.r.temperaturesensor");
141             break;
142
143         case RESOURCE_LIGHT:
144             initServer("/a/light", "oic.r.light");
145             break;
146     }
147
148     g_resource->setGetRequestHandler(requestHandlerForGet);
149     g_resource->setSetRequestHandler(requestHandlerForSet);
150 }
151
152 int main(void)
153 {
154     selectResourceType();
155
156     std::cout << "Resource successfully created!" << std::endl;
157
158     std::cout << "Press '1' to stop the process" << std::endl;
159
160     while (std::cin.get() != '1');
161
162     std::cout << "Stopping the server" << std::endl;
163
164     g_resource.reset();
165 }
166