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