[IOT-1591] Add warning code as notification type
[platform/upstream/iotivity.git] / service / resource-hosting / src / HostingObject.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 "HostingObject.h"
22
23 #include "RCSSeparateResponse.h"
24 #include "RequestObject.h"
25
26 namespace OIC
27 {
28     namespace Service
29     {
30
31         namespace
32         {
33             const auto sizeofHostingTag = strlen("/hosting");
34         }
35
36         HostingObject::HostingObject()
37         : remoteObject(nullptr), mirroredServer(nullptr),
38           pDataUpdateCB(nullptr), pDestroyCB(nullptr)
39         {
40         }
41
42         HostingObject::~HostingObject()
43         {
44             pDataUpdateCB = {};
45
46             if (remoteObject)
47             {
48                 remoteObject->stopMonitoring();
49                 remoteObject->stopCaching();
50             }
51         }
52
53         auto HostingObject::getRemoteResource() const -> RemoteObjectPtr
54         {
55             return remoteObject;
56         }
57
58         auto HostingObject::createHostingObject(const RemoteObjectPtr & rResource,
59                 DestroyedCallback destroyCB) -> Ptr
60         {
61             auto newObject = std::make_shared<HostingObject>();
62
63             newObject->remoteObject = rResource;
64             newObject->pDestroyCB = destroyCB;
65
66             newObject->pDataUpdateCB = std::bind(&HostingObject::dataChangedCB, newObject,
67                     std::placeholders::_1);
68
69             newObject->remoteObject->startMonitoring(
70                     std::bind(&HostingObject::stateChangedCB, newObject,
71                             std::placeholders::_1));
72             newObject->remoteObject->startCaching(newObject->pDataUpdateCB);
73
74             return newObject;
75         }
76
77         void HostingObject::destroyHostingObject()
78         {
79             if (pDestroyCB)
80             {
81                 pDestroyCB();
82             }
83         }
84
85         void HostingObject::stateChangedCB(ResourceState state)
86         {
87             switch (state)
88             {
89             case ResourceState::ALIVE:
90             {
91                 if (!this->remoteObject->isCaching())
92                 {
93                     try
94                     {
95                         this->remoteObject->startCaching(pDataUpdateCB);
96                     } catch (const RCSException & e)
97                     {
98                         OIC_HOSTING_LOG(DEBUG,
99                                 "[HostingObject::stateChangedCB]startCaching InvalidParameterException:%s",
100                                 e.what());
101                     }
102                 }
103                 break;
104             }
105             case ResourceState::LOST_SIGNAL:
106             case ResourceState::DESTROYED:
107             {
108                 try
109                 {
110                     this->remoteObject->stopCaching();
111                     this->remoteObject->stopMonitoring();
112                 } catch (const RCSException & e)
113                 {
114                     OIC_HOSTING_LOG(DEBUG,
115                             "[HostingObject::stateChangedCB]stopWatching InvalidParameterException:%s",
116                             e.what());
117                 }
118                 mirroredServer.reset();
119                 destroyHostingObject();
120                 break;
121             }
122             default:
123             {
124                 // not support of state
125                 break;
126             }
127             }
128         }
129
130         void HostingObject::dataChangedCB(const RCSResourceAttributes & attributes)
131         {
132             if (attributes.empty())
133             {
134                 return;
135             }
136
137             std::unique_lock<std::mutex> lock(mutexForCB);
138             if (mirroredServer == nullptr)
139             {
140                 try
141                 {
142                     mirroredServer = createMirroredServer(this->remoteObject);
143                 } catch (const RCSException & e)
144                 {
145                     OIC_HOSTING_LOG(DEBUG,
146                                 "[HostingObject::dataChangedCB]createMirroredServer Exception:%s",
147                                 e.what());
148                     return;
149                 }
150             }
151             lock.unlock();
152
153             RCSResourceObject::LockGuard guard(mirroredServer);
154             mirroredServer->getAttributes() = std::move(attributes);
155         }
156
157         auto HostingObject::createMirroredServer(RemoteObjectPtr rObject) -> ResourceObjectPtr
158         {
159             if (rObject == nullptr)
160             {
161                 throw RCSPlatformException(OC_STACK_ERROR);
162             }
163
164             std::string fulluri = rObject->getUri();
165             std::string uri = fulluri.substr(0, fulluri.size() - sizeofHostingTag);
166             std::vector<std::string> types = rObject->getTypes();
167             std::vector<std::string> interfaces = rObject->getInterfaces();
168             try
169             {
170                 auto resourceBuild = RCSResourceObject::Builder(uri, types[0], interfaces[0]);
171                 for (unsigned int i = 1; i < types.size(); ++i)
172                 {
173                     resourceBuild.addType(types[i]);
174                 }
175                 for (unsigned int i = 1; i < interfaces.size(); ++i)
176                 {
177                     resourceBuild.addInterface(interfaces[i]);
178                 }
179                 auto retResource = resourceBuild.build();
180
181                 retResource->setAutoNotifyPolicy(RCSResourceObject::AutoNotifyPolicy::UPDATED);
182                 retResource->setSetRequestHandler(
183                         std::bind(&HostingObject::setRequestHandler, this,
184                                 std::placeholders::_1, std::placeholders::_2));
185                 return retResource;
186             }
187             catch (...)
188             {
189                 OIC_HOSTING_LOG(DEBUG, "[HostingObject::createMirroredServer] %s", "Exception");
190                 throw;
191             }
192         }
193
194         RCSSetResponse HostingObject::setRequestHandler(const RCSRequest & primitiveRequest,
195                     RCSResourceAttributes & resourceAttibutes)
196         {
197             try
198             {
199                 RequestObject::invokeRequest(getRemoteResource(),
200                         primitiveRequest, RequestObject::RequestMethod::Set, resourceAttibutes);
201
202             }
203             catch (const RCSPlatformException & e)
204             {
205                 OIC_HOSTING_LOG(DEBUG,
206                         "[HostingObject::setRequestHandler] PlatformException:%s",
207                         e.what());
208                 throw;
209             }
210
211             return RCSSetResponse::separate();
212         }
213
214     } /* namespace Service */
215 } /* namespace OIC */