1 //******************************************************************
3 // Copyright 2015 Samsung Electronics All Rights Reserved.
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
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
11 // http://www.apache.org/licenses/LICENSE-2.0
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.
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
21 #include "ResourcePresence.h"
23 #include <bits/atomic_base.h>
24 #include <bits/shared_ptr_base.h>
32 #include "PrimitiveResource.h"
33 #include "DeviceAssociation.h"
34 #include "DevicePresence.h"
38 using namespace OIC::Service;
40 void getCallback(const HeaderOptions &hos, const ResponseStatement& rep,
41 int eCode, std::weak_ptr<ResourcePresence> this_ptr)
43 OC_LOG_V(DEBUG,BROKER_TAG,"getCallback().\n");
44 std::shared_ptr<ResourcePresence> Ptr = this_ptr.lock();
47 Ptr->getCB(hos, rep, eCode);
50 void timeOutCallback(unsigned int msg, std::weak_ptr<ResourcePresence> this_ptr)
52 OC_LOG_V(DEBUG,BROKER_TAG,"timeOutCallback().\n");
53 std::shared_ptr<ResourcePresence> Ptr = this_ptr.lock();
65 ResourcePresence::ResourcePresence()
66 : requesterList(nullptr), primitiveResource(nullptr),
67 state(BROKER_STATE::REQUESTED), mode(BROKER_MODE::NON_PRESENCE_MODE),
68 isWithinTime(true), receivedTime(0L), timeoutHandle(0)
72 void ResourcePresence::initializeResourcePresence(PrimitiveResourcePtr pResource)
74 OC_LOG_V(DEBUG,BROKER_TAG,"initializeResourcePresence().\n");
75 pGetCB = std::bind(getCallback, std::placeholders::_1, std::placeholders::_2,
76 std::placeholders::_3, std::weak_ptr<ResourcePresence>(shared_from_this()));
77 pTimeoutCB = std::bind(timeOutCallback, std::placeholders::_1,
78 std::weak_ptr<ResourcePresence>(shared_from_this()));
79 pPollingCB = std::bind(&ResourcePresence::pollingCB, this, std::placeholders::_1);
81 primitiveResource = pResource;
83 = std::unique_ptr<std::list<BrokerRequesterInfoPtr>>
84 (new std::list<BrokerRequesterInfoPtr>);
86 timeoutHandle = expiryTimer.post(BROKER_SAFE_MILLISECOND, pTimeoutCB);
87 OC_LOG_V(DEBUG,BROKER_TAG,"initializeResourcePresence::requestGet.\n");
88 primitiveResource->requestGet(pGetCB);
90 registerDevicePresence();
94 ResourcePresence::~ResourcePresence()
96 std::string deviceAddress = primitiveResource->getHost();
98 DevicePresencePtr foundDevice
99 = DeviceAssociation::getInstance()->findDevice(deviceAddress);
101 if(foundDevice != nullptr)
103 foundDevice->removePresenceResource(this);
105 if(foundDevice->isEmptyResourcePresence())
107 DeviceAssociation::getInstance()->removeDevice(foundDevice);
111 requesterList->clear();
113 state = BROKER_STATE::DESTROYED;
116 void ResourcePresence::addBrokerRequester(BrokerID _id, BrokerCB _cb)
118 OC_LOG_V(DEBUG,BROKER_TAG,"addBrokerRequester().\n");
119 requesterList->push_back(
120 std::make_shared<BrokerRequesterInfo>(BrokerRequesterInfo(_id, _cb)));
123 void ResourcePresence::removeAllBrokerRequester()
125 OC_LOG_V(DEBUG,BROKER_TAG,"removeAllBrokerRequester().\n");
126 if(requesterList != nullptr)
128 requesterList->erase(requesterList->begin(), requesterList->end());
132 void ResourcePresence::removeBrokerRequester(BrokerID _id)
134 OC_LOG_V(DEBUG,BROKER_TAG,"removeBrokerRequester().\n");
135 std::list<BrokerRequesterInfoPtr>::iterator iter = requesterList->begin();
136 for(; iter != requesterList->end(); ++iter)
138 if(iter->get()->brokerId == _id)
140 OC_LOG_V(DEBUG,BROKER_TAG,"find broker-id in requesterList.\n");
141 requesterList->erase(iter);
147 bool ResourcePresence::isEmptyRequester() const
149 OC_LOG_V(DEBUG,BROKER_TAG,"isEmptyRequester().\n");
150 return (requesterList!=nullptr)?requesterList->empty():true;
153 int ResourcePresence::requesterListSize() const {
154 OC_LOG_V(DEBUG,BROKER_TAG,"requesterListSize().\n");
155 return (requesterList!=nullptr)?requesterList->size():0;
158 void ResourcePresence::requestResourceState() const
160 OC_LOG_V(DEBUG,BROKER_TAG,"requestResourceState().\n");
161 primitiveResource->requestGet(pGetCB);
162 OC_LOG_V(DEBUG, BROKER_TAG, "Request Get\n");
165 void ResourcePresence::registerDevicePresence()
167 OC_LOG_V(DEBUG,BROKER_TAG,"registerDevicePresence().\n");
168 std::string deviceAddress = primitiveResource->getHost();
170 DevicePresencePtr foundDevice
171 = DeviceAssociation::getInstance()->findDevice(deviceAddress);
173 if(foundDevice == nullptr)
177 foundDevice.reset(new DevicePresence());
178 foundDevice->initializeDevicePresence(primitiveResource);
183 DeviceAssociation::getInstance()->addDevice(foundDevice);
185 foundDevice->addPresenceResource(this);
188 void ResourcePresence::executeAllBrokerCB(BROKER_STATE changedState)
190 OC_LOG_V(DEBUG, BROKER_TAG, "executeAllBrokerCB().\n");
191 if(state != changedState)
193 setResourcestate(changedState);
194 if(requesterList->empty() != true)
196 std::list<BrokerRequesterInfoPtr> list = * requesterList;
197 for(BrokerRequesterInfoPtr item : list)
199 item->brokerCB(state);
205 void ResourcePresence::setResourcestate(BROKER_STATE _state)
207 OC_LOG_V(DEBUG, BROKER_TAG, "setResourcestate().\n");
208 this->state = _state;
211 void ResourcePresence::timeOutCB(unsigned int /*msg*/)
213 OC_LOG_V(DEBUG, BROKER_TAG, "timeOutCB()");
214 OC_LOG_V(DEBUG, BROKER_TAG, "waiting for terminate getCB\n");
215 std::unique_lock<std::mutex> lock(cbMutex);
221 if((receivedTime.load(boost::memory_order_consume) == 0) ||
222 ((receivedTime + BROKER_SAFE_SECOND) > currentTime ))
224 this->isWithinTime = true;
227 this->isWithinTime = false;
228 OC_LOG_V(DEBUG, BROKER_TAG,
229 "Timeout execution. will be discard after receiving cb message.\n");
231 executeAllBrokerCB(BROKER_STATE::LOST_SIGNAL);
235 void ResourcePresence::pollingCB(unsigned int /*msg*/)
237 OC_LOG_V(DEBUG, BROKER_TAG, "pollingCB().\n");
238 if(this->requesterList->size() != 0)
240 this->requestResourceState();
241 timeoutHandle = expiryTimer.post(BROKER_SAFE_MILLISECOND,pTimeoutCB);
245 void ResourcePresence::getCB(const HeaderOptions & /*hos*/,
246 const ResponseStatement & /*rep*/, int eCode)
248 OC_LOG_V(DEBUG, BROKER_TAG, "getCB().\n");
249 OC_LOG_V(DEBUG, BROKER_TAG, "waiting for terminate TimeoutCB.\n");
250 std::unique_lock<std::mutex> lock(cbMutex);
254 receivedTime = currentTime;
256 verifiedGetResponse(eCode);
260 expiryTimer.cancel(timeoutHandle);
264 if(mode == BROKER_MODE::NON_PRESENCE_MODE)
266 expiryTimer.post(BROKER_SAFE_MILLISECOND,pPollingCB);
271 void ResourcePresence::verifiedGetResponse(int eCode)
273 OC_LOG_V(DEBUG, BROKER_TAG, "verifiedGetResponse().\n");
274 BROKER_STATE verifiedState = BROKER_STATE::NONE;
278 case OC_STACK_CONTINUE:
279 verifiedState = BROKER_STATE::ALIVE;
282 case OC_STACK_RESOURCE_DELETED:
283 verifiedState = BROKER_STATE::DESTROYED;
286 case OC_STACK_INVALID_REQUEST_HANDLE:
287 case OC_STACK_TIMEOUT:
288 case OC_STACK_COMM_ERROR:
289 case OC_STACK_PRESENCE_STOPPED:
290 case OC_STACK_PRESENCE_TIMEOUT:
292 verifiedState = BROKER_STATE::LOST_SIGNAL;
296 executeAllBrokerCB(verifiedState);
297 OC_LOG_V(DEBUG, BROKER_TAG, "resource state : %d",(int)state);
300 const PrimitiveResourcePtr ResourcePresence::getPrimitiveResource() const
302 OC_LOG_V(DEBUG, BROKER_TAG, "getPrimitiveResource()\n");
303 return primitiveResource;
306 BROKER_STATE ResourcePresence::getResourceState() const
308 OC_LOG_V(DEBUG, BROKER_TAG, "getResourceState()\n");
312 void ResourcePresence::changePresenceMode(BROKER_MODE newMode)
314 OC_LOG_V(DEBUG, BROKER_TAG, "changePresenceMode()\n");
317 expiryTimer.cancel(timeoutHandle);
318 if(newMode == BROKER_MODE::NON_PRESENCE_MODE)
320 timeoutHandle = expiryTimer.post(BROKER_SAFE_MILLISECOND,pTimeoutCB);
321 requestResourceState();
326 } // namespace Service