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 lastSequenceNum = _seq;
213 if (state != CACHE_STATE::READY)
215 state = CACHE_STATE::READY;
219 if (mode != CACHE_MODE::OBSERVE)
221 mode = CACHE_MODE::OBSERVE;
224 networkTimer.cancel(networkTimeOutHandle);
225 networkTimeOutHandle = networkTimer.post(CACHE_DEFAULT_EXPIRED_MILLITIME, pTimerCB);
227 notifyObservers(_rep.getAttributes(), _result);
230 void DataCache::onGet(const HeaderOptions & /*_hos*/,
231 const ResponseStatement &_rep, int _result)
233 if (_result != OC_STACK_OK || _rep.getAttributes().empty())
238 if (state != CACHE_STATE::READY)
240 state = CACHE_STATE::READY;
244 if (mode != CACHE_MODE::OBSERVE)
246 networkTimer.cancel(networkTimeOutHandle);
247 networkTimeOutHandle = networkTimer.post(
248 CACHE_DEFAULT_EXPIRED_MILLITIME, pTimerCB);
250 pollingHandle = pollingTimer.post(CACHE_DEFAULT_REPORT_MILLITIME, pPollingCB);
253 notifyObservers(_rep.getAttributes(), _result);
256 void DataCache::notifyObservers(const RCSResourceAttributes Att, int eCode)
259 std::lock_guard<std::mutex> lock(att_mutex);
260 if (attributes == Att)
267 std::lock_guard<std::mutex> lock(m_mutex);
268 for (auto &i : * subscriberList)
270 if (i.second.first.rf == REPORT_FREQUENCY::UPTODATE)
272 i.second.second(this->sResource, Att, eCode);
277 CACHE_STATE DataCache::getCacheState() const
282 void DataCache::onTimeOut(unsigned int /*timerID*/)
284 if (mode == CACHE_MODE::OBSERVE)
286 sResource->cancelObserve();
287 mode = CACHE_MODE::FREQUENCY;
289 networkTimer.cancel(networkTimeOutHandle);
290 networkTimeOutHandle = networkTimer.post(
291 CACHE_DEFAULT_EXPIRED_MILLITIME, pTimerCB);
293 pollingHandle = pollingTimer.post(CACHE_DEFAULT_REPORT_MILLITIME, pPollingCB);
297 state = CACHE_STATE::LOST_SIGNAL;
299 void DataCache::onPollingOut(const unsigned int /*timerID*/)
301 if (sResource != nullptr)
303 mode = CACHE_MODE::FREQUENCY;
304 sResource->requestGet(pGetCB);
309 CacheID DataCache::generateCacheID()
314 if (findSubscriber(retID).first == 0 && retID != 0)
319 retID = OCGetRandom();
324 void DataCache::requestGet()
326 state = CACHE_STATE::UPDATING;
327 if (sResource != nullptr)
329 sResource->requestGet(pGetCB);
333 bool DataCache::isEmptySubscriber() const
335 std::lock_guard<std::mutex> lock(m_mutex);
336 return (subscriberList != nullptr) ? subscriberList->empty() : true;
338 } // namespace Service