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 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
28 #include "DataCache.h"
30 #include "ResponseStatement.h"
31 #include "RCSResourceAttributes.h"
32 #include "ExpiryTimer.h"
44 const HeaderOptions &_hos, const ResponseStatement &_rep,
45 int _result, unsigned int _seq, std::weak_ptr<DataCache> rpPtr)
47 std::shared_ptr<DataCache> ptr = rpPtr.lock();
50 ptr->onObserve(_hos, _rep, _result, _seq);
54 ObserveCB verifiedObserveCB(std::weak_ptr<DataCache> rpPtr)
56 return std::bind(verifyObserveCB,
57 std::placeholders::_1, std::placeholders::_2,
58 std::placeholders::_3, std::placeholders::_4, rpPtr);
62 const HeaderOptions &_hos, const ResponseStatement &_rep,
63 int _result, std::weak_ptr<DataCache> rpPtr)
65 std::shared_ptr<DataCache> Ptr = rpPtr.lock();
68 Ptr->onGet(_hos, _rep, _result);
72 GetCB verifiedGetCB(std::weak_ptr<DataCache> rpPtr)
74 return std::bind(verifyGetCB,
75 std::placeholders::_1, std::placeholders::_2,
76 std::placeholders::_3, rpPtr);
80 DataCache::DataCache()
82 subscriberList = std::unique_ptr<SubscriberInfo>(new SubscriberInfo());
86 state = CACHE_STATE::READY_YET;
87 mode = CACHE_MODE::FREQUENCY;
89 networkTimeOutHandle = 0;
95 DataCache::~DataCache()
97 state = CACHE_STATE::DESTROYED;
99 if (subscriberList != nullptr)
101 subscriberList->clear();
102 subscriberList.release();
105 if (sResource->isObservable())
109 sResource->cancelObserve();
113 // ignore the exception because data cache was released.
118 void DataCache::initializeDataCache(PrimitiveResourcePtr pResource)
120 sResource = pResource;
121 pObserveCB = verifiedObserveCB(std::weak_ptr<DataCache>(shared_from_this()));
122 pGetCB = verifiedGetCB(std::weak_ptr<DataCache>(shared_from_this()));
123 pTimerCB = (TimerCB)(std::bind(&DataCache::onTimeOut, this, std::placeholders::_1));
124 pPollingCB = (TimerCB)(std::bind(&DataCache::onPollingOut, this, std::placeholders::_1));
126 sResource->requestGet(pGetCB);
127 if (sResource->isObservable())
129 sResource->requestObserve(pObserveCB);
131 networkTimeOutHandle = networkTimer.post(CACHE_DEFAULT_EXPIRED_MILLITIME, pTimerCB);
134 CacheID DataCache::addSubscriber(CacheCB func, REPORT_FREQUENCY rf, long repeatTime)
138 newItem.repeatTime = repeatTime;
141 newItem.reportID = generateCacheID();
143 std::lock_guard<std::mutex> lock(m_mutex);
144 if (subscriberList != nullptr)
146 subscriberList->insert(
147 std::make_pair(newItem.reportID, std::make_pair(newItem, func)));
150 return newItem.reportID;
153 CacheID DataCache::deleteSubscriber(CacheID id)
157 SubscriberInfoPair pair = findSubscriber(id);
159 std::lock_guard<std::mutex> lock(m_mutex);
163 subscriberList->erase(pair.first);
169 SubscriberInfoPair DataCache::findSubscriber(CacheID id)
171 SubscriberInfoPair ret;
173 std::lock_guard<std::mutex> lock(m_mutex);
174 for (auto &i : *subscriberList)
178 ret = std::make_pair(i.first, std::make_pair((Report_Info)i.second.first,
179 (CacheCB)i.second.second));
187 const PrimitiveResourcePtr DataCache::getPrimitiveResource() const
192 const RCSResourceAttributes DataCache::getCachedData() const
194 std::lock_guard<std::mutex> lock(att_mutex);
195 if (state != CACHE_STATE::READY)
197 return RCSResourceAttributes();
202 bool DataCache::isCachedData() const
207 void DataCache::onObserve(const HeaderOptions & /*_hos*/,
208 const ResponseStatement &_rep, int _result, unsigned int _seq)
211 if (_result != OC_STACK_OK || _rep.getAttributes().empty() || lastSequenceNum > _seq)
217 lastSequenceNum = _seq;
220 if (state != CACHE_STATE::READY)
222 state = CACHE_STATE::READY;
226 if (mode != CACHE_MODE::OBSERVE)
228 mode = CACHE_MODE::OBSERVE;
231 networkTimer.cancel(networkTimeOutHandle);
232 networkTimeOutHandle = networkTimer.post(CACHE_DEFAULT_EXPIRED_MILLITIME, pTimerCB);
234 notifyObservers(_rep.getAttributes());
237 void DataCache::onGet(const HeaderOptions & /*_hos*/,
238 const ResponseStatement &_rep, int _result)
240 if (_result != OC_STACK_OK || _rep.getAttributes().empty())
245 if (state != CACHE_STATE::READY)
247 state = CACHE_STATE::READY;
251 if (mode != CACHE_MODE::OBSERVE)
253 networkTimer.cancel(networkTimeOutHandle);
254 networkTimeOutHandle = networkTimer.post(
255 CACHE_DEFAULT_EXPIRED_MILLITIME, pTimerCB);
257 pollingHandle = pollingTimer.post(CACHE_DEFAULT_REPORT_MILLITIME, pPollingCB);
260 notifyObservers(_rep.getAttributes());
263 void DataCache::notifyObservers(const RCSResourceAttributes Att)
266 std::lock_guard<std::mutex> lock(att_mutex);
267 if (attributes == Att)
274 std::lock_guard<std::mutex> lock(m_mutex);
275 for (auto &i : * subscriberList)
277 if (i.second.first.rf == REPORT_FREQUENCY::UPTODATE)
279 i.second.second(this->sResource, Att);
284 CACHE_STATE DataCache::getCacheState() const
289 void DataCache::onTimeOut(unsigned int /*timerID*/)
291 if (mode == CACHE_MODE::OBSERVE)
293 sResource->cancelObserve();
294 mode = CACHE_MODE::FREQUENCY;
296 networkTimer.cancel(networkTimeOutHandle);
297 networkTimeOutHandle = networkTimer.post(
298 CACHE_DEFAULT_EXPIRED_MILLITIME, pTimerCB);
300 pollingHandle = pollingTimer.post(CACHE_DEFAULT_REPORT_MILLITIME, pPollingCB);
304 state = CACHE_STATE::LOST_SIGNAL;
306 void DataCache::onPollingOut(const unsigned int /*timerID*/)
308 if (sResource != nullptr)
310 mode = CACHE_MODE::FREQUENCY;
311 sResource->requestGet(pGetCB);
316 CacheID DataCache::generateCacheID()
321 if (findSubscriber(retID).first == 0 && retID != 0)
326 retID = OCGetRandom();
331 void DataCache::requestGet()
333 state = CACHE_STATE::UPDATING;
334 if (sResource != nullptr)
336 sResource->requestGet(pGetCB);
340 bool DataCache::isEmptySubscriber() const
342 std::lock_guard<std::mutex> lock(m_mutex);
343 return (subscriberList != nullptr) ? subscriberList->empty() : true;
345 } // namespace Service