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"
42 const HeaderOptions &_hos, const ResponseStatement &_rep,
43 int _result, int _seq, std::weak_ptr<DataCache> rpPtr)
45 std::shared_ptr<DataCache> Ptr = rpPtr.lock();
48 Ptr->onObserve(_hos, _rep, _result, _seq);
52 ObserveCB verifiedObserveCB(std::weak_ptr<DataCache> rpPtr)
54 return std::bind(verifyObserveCB,
55 std::placeholders::_1, std::placeholders::_2,
56 std::placeholders::_3, std::placeholders::_4, rpPtr);
60 const HeaderOptions &_hos, const ResponseStatement &_rep,
61 int _result, std::weak_ptr<DataCache> rpPtr)
63 std::shared_ptr<DataCache> Ptr = rpPtr.lock();
66 Ptr->onGet(_hos, _rep, _result);
70 GetCB verifiedGetCB(std::weak_ptr<DataCache> rpPtr)
72 return std::bind(verifyGetCB,
73 std::placeholders::_1, std::placeholders::_2,
74 std::placeholders::_3, rpPtr);
78 DataCache::DataCache()
80 subscriberList = std::unique_ptr<SubscriberInfo>(new SubscriberInfo());
84 state = CACHE_STATE::READY_YET;
85 mode = CACHE_MODE::FREQUENCY;
87 networkTimeOutHandle = 0;
93 DataCache::~DataCache()
95 state = CACHE_STATE::DESTROYED;
97 if (subscriberList != nullptr)
99 subscriberList->clear();
100 subscriberList.release();
103 if (mode == CACHE_MODE::OBSERVE)
107 sResource->cancelObserve();
111 // ignore the exception because data cache was released.
116 void DataCache::initializeDataCache(PrimitiveResourcePtr pResource)
118 sResource = pResource;
119 pObserveCB = verifiedObserveCB(std::weak_ptr<DataCache>(shared_from_this()));
120 pGetCB = verifiedGetCB(std::weak_ptr<DataCache>(shared_from_this()));
121 pTimerCB = (TimerCB)(std::bind(&DataCache::onTimeOut, this, std::placeholders::_1));
122 pPollingCB = (TimerCB)(std::bind(&DataCache::onPollingOut, this, std::placeholders::_1));
124 sResource->requestGet(pGetCB);
125 if (sResource->isObservable())
127 sResource->requestObserve(pObserveCB);
129 networkTimeOutHandle = networkTimer.post(CACHE_DEFAULT_EXPIRED_MILLITIME, pTimerCB);
132 CacheID DataCache::addSubscriber(CacheCB func, REPORT_FREQUENCY rf, long repeatTime)
136 newItem.repeatTime = repeatTime;
139 newItem.reportID = generateCacheID();
141 std::lock_guard<std::mutex> lock(m_mutex);
142 if (subscriberList != nullptr)
144 subscriberList->insert(
145 std::make_pair(newItem.reportID, std::make_pair(newItem, func)));
148 return newItem.reportID;
151 CacheID DataCache::deleteSubscriber(CacheID id)
155 SubscriberInfoPair pair = findSubscriber(id);
157 std::lock_guard<std::mutex> lock(m_mutex);
161 subscriberList->erase(pair.first);
167 SubscriberInfoPair DataCache::findSubscriber(CacheID id)
169 SubscriberInfoPair ret;
171 std::lock_guard<std::mutex> lock(m_mutex);
172 for (auto &i : *subscriberList)
176 ret = std::make_pair(i.first, std::make_pair((Report_Info)i.second.first,
177 (CacheCB)i.second.second));
185 const PrimitiveResourcePtr DataCache::getPrimitiveResource() const
187 return (sResource != nullptr) ? sResource : nullptr;
190 const RCSResourceAttributes DataCache::getCachedData() const
192 std::lock_guard<std::mutex> lock(att_mutex);
193 if (state != CACHE_STATE::READY)
195 return RCSResourceAttributes();
200 bool DataCache::isCachedData() const
205 void DataCache::onObserve(const HeaderOptions & /*_hos*/,
206 const ResponseStatement &_rep, int _result, int _seq)
209 if (_result != OC_STACK_OK || _rep.getAttributes().empty() || lastSequenceNum > _seq)
215 lastSequenceNum = _seq;
218 if (state != CACHE_STATE::READY)
220 state = CACHE_STATE::READY;
224 if (mode != CACHE_MODE::OBSERVE)
226 mode = CACHE_MODE::OBSERVE;
229 networkTimer.cancel(networkTimeOutHandle);
230 networkTimeOutHandle = networkTimer.post(CACHE_DEFAULT_EXPIRED_MILLITIME, pTimerCB);
232 notifyObservers(_rep.getAttributes());
235 void DataCache::onGet(const HeaderOptions & /*_hos*/,
236 const ResponseStatement &_rep, int _result)
238 if (_result != OC_STACK_OK || _rep.getAttributes().empty())
243 if (state != CACHE_STATE::READY)
245 state = CACHE_STATE::READY;
249 if (mode != CACHE_MODE::OBSERVE)
251 networkTimer.cancel(networkTimeOutHandle);
252 networkTimeOutHandle = networkTimer.post(
253 CACHE_DEFAULT_EXPIRED_MILLITIME, pTimerCB);
255 pollingHandle = pollingTimer.post(CACHE_DEFAULT_REPORT_MILLITIME, pPollingCB);
258 notifyObservers(_rep.getAttributes());
261 void DataCache::notifyObservers(const RCSResourceAttributes Att)
264 std::lock_guard<std::mutex> lock(att_mutex);
265 if (attributes == Att)
272 std::lock_guard<std::mutex> lock(m_mutex);
273 for (auto &i : * subscriberList)
275 if (i.second.first.rf == REPORT_FREQUENCY::UPTODATE)
277 i.second.second(this->sResource, Att);
282 CACHE_STATE DataCache::getCacheState() const
287 void DataCache::onTimeOut(unsigned int /*timerID*/)
289 if (mode == CACHE_MODE::OBSERVE)
291 sResource->cancelObserve();
292 mode = CACHE_MODE::FREQUENCY;
294 networkTimer.cancel(networkTimeOutHandle);
295 networkTimeOutHandle = networkTimer.post(
296 CACHE_DEFAULT_EXPIRED_MILLITIME, pTimerCB);
298 pollingHandle = pollingTimer.post(CACHE_DEFAULT_REPORT_MILLITIME, pPollingCB);
302 state = CACHE_STATE::LOST_SIGNAL;
304 void DataCache::onPollingOut(const unsigned int /*timerID*/)
306 if (sResource != nullptr)
308 mode = CACHE_MODE::FREQUENCY;
309 sResource->requestGet(pGetCB);
314 CacheID DataCache::generateCacheID()
321 if (findSubscriber(retID).first == 0 && retID != 0)
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