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 void vertifyObserveCB(
43 const HeaderOptions &_hos, const ResponseStatement &_rep,
44 int _result, int _seq, std::weak_ptr<DataCache> rpPtr)
46 std::lock_guard<std::mutex> lock(cbMutex);
47 std::shared_ptr<DataCache> Ptr = rpPtr.lock();
50 Ptr->onObserve(_hos, _rep, _result, _seq);
53 ObserveCB vertifiedObserveCB(std::weak_ptr<DataCache> rpPtr)
55 return std::bind(vertifyObserveCB,
56 std::placeholders::_1, std::placeholders::_2,
57 std::placeholders::_3, std::placeholders::_4, rpPtr);
61 const HeaderOptions &_hos, const ResponseStatement &_rep,
62 int _result, std::weak_ptr<DataCache> rpPtr)
64 std::lock_guard<std::mutex> lock(cbMutex);
65 std::shared_ptr<DataCache> Ptr = rpPtr.lock();
68 Ptr->onGet(_hos, _rep, _result);
71 GetCB vertifiedGetCB(std::weak_ptr<DataCache> rpPtr)
73 return std::bind(vertifyGetCB,
74 std::placeholders::_1, std::placeholders::_2,
75 std::placeholders::_3, rpPtr);
79 DataCache::DataCache()
81 subscriberList = std::unique_ptr<SubscriberInfo>(new SubscriberInfo());
85 state = CACHE_STATE::READY_YET;
86 mode = CACHE_MODE::FREQUENCY;
88 networkTimeOutHandle = 0;
92 DataCache::~DataCache()
94 state = CACHE_STATE::DESTROYED;
96 if (subscriberList != nullptr)
98 subscriberList->clear();
99 subscriberList.release();
102 if(mode == CACHE_MODE::OBSERVE)
106 sResource->cancelObserve();
109 // ignore the exception because data cache was released.
114 void DataCache::initializeDataCache(PrimitiveResourcePtr pResource)
116 sResource = pResource;
117 pObserveCB = vertifiedObserveCB(std::weak_ptr<DataCache>(shared_from_this()));
118 pGetCB = vertifiedGetCB(std::weak_ptr<DataCache>(shared_from_this()));
119 pTimerCB = (TimerCB)(std::bind(&DataCache::onTimeOut, this, std::placeholders::_1));
120 pPollingCB = (TimerCB)(std::bind(&DataCache::onPollingOut, this, std::placeholders::_1));
122 sResource->requestGet(pGetCB);
123 if (sResource->isObservable())
125 sResource->requestObserve(pObserveCB);
127 networkTimeOutHandle = networkTimer.postTimer(CACHE_DEFAULT_EXPIRED_MILLITIME, pTimerCB);
130 CacheID DataCache::addSubscriber(CacheCB func, REPORT_FREQUENCY rf, long repeatTime)
134 newItem.repeatTime = repeatTime;
137 newItem.reportID = generateCacheID();
139 std::lock_guard<std::mutex> lock(m_mutex);
140 if (subscriberList != nullptr)
142 subscriberList->insert(
143 std::make_pair(newItem.reportID, std::make_pair(newItem, func)));
146 return newItem.reportID;
149 CacheID DataCache::deleteSubscriber(CacheID id)
153 SubscriberInfoPair pair = findSubscriber(id);
155 std::lock_guard<std::mutex> lock(m_mutex);
159 subscriberList->erase(pair.first);
165 SubscriberInfoPair DataCache::findSubscriber(CacheID id)
167 SubscriberInfoPair ret;
169 std::lock_guard<std::mutex> lock(m_mutex);
170 for (auto &i : *subscriberList)
174 ret = std::make_pair(i.first, std::make_pair((Report_Info)i.second.first,
175 (CacheCB)i.second.second));
183 const PrimitiveResourcePtr DataCache::getPrimitiveResource() const
185 return (sResource != nullptr) ? sResource : nullptr;
188 const RCSResourceAttributes DataCache::getCachedData() const
190 if (state != CACHE_STATE::READY || attributes.empty())
192 return RCSResourceAttributes();
194 const RCSResourceAttributes retAtt = attributes;
198 void DataCache::onObserve(
199 const HeaderOptions &_hos, const ResponseStatement &_rep, int _result, int _seq)
202 if (_result != OC_STACK_OK || _rep.getAttributes().empty())
207 if (state != CACHE_STATE::READY)
209 state = CACHE_STATE::READY;
212 if (mode != CACHE_MODE::OBSERVE)
214 mode = CACHE_MODE::OBSERVE;
217 networkTimer.cancelTimer(networkTimeOutHandle);
218 networkTimeOutHandle = networkTimer.postTimer(CACHE_DEFAULT_EXPIRED_MILLITIME, pTimerCB);
220 notifyObservers(_rep.getAttributes());
223 void DataCache::onGet(const HeaderOptions &_hos,
224 const ResponseStatement &_rep, int _result)
226 if (_result != OC_STACK_OK || _rep.getAttributes().empty())
231 if (state != CACHE_STATE::READY)
233 state = CACHE_STATE::READY;
236 if (mode != CACHE_MODE::OBSERVE)
238 networkTimer.cancelTimer(networkTimeOutHandle);
239 networkTimeOutHandle = networkTimer.postTimer(
240 CACHE_DEFAULT_EXPIRED_MILLITIME, pTimerCB);
242 pollingHandle = pollingTimer.postTimer(CACHE_DEFAULT_REPORT_MILLITIME, pPollingCB);
245 notifyObservers(_rep.getAttributes());
248 void DataCache::notifyObservers(const RCSResourceAttributes Att)
250 if (attributes == Att)
257 std::lock_guard<std::mutex> lock(m_mutex);
258 for (auto &i : * subscriberList)
260 if (i.second.first.rf == REPORT_FREQUENCY::UPTODATE)
262 i.second.second(this->sResource, Att);
267 CACHE_STATE DataCache::getCacheState() const
272 void DataCache::onTimeOut(unsigned int timerID)
274 if(mode == CACHE_MODE::OBSERVE)
276 sResource->cancelObserve();
277 mode = CACHE_MODE::FREQUENCY;
279 networkTimer.cancelTimer(networkTimeOutHandle);
280 networkTimeOutHandle = networkTimer.postTimer(
281 CACHE_DEFAULT_EXPIRED_MILLITIME, pTimerCB);
283 pollingHandle = pollingTimer.postTimer(CACHE_DEFAULT_REPORT_MILLITIME, pPollingCB);
287 state = CACHE_STATE::LOST_SIGNAL;
289 void DataCache::onPollingOut(const unsigned int timerID)
291 if (sResource != nullptr)
293 mode = CACHE_MODE::FREQUENCY;
294 sResource->requestGet(pGetCB);
299 CacheID DataCache::generateCacheID()
306 if (findSubscriber(retID).first == 0 && retID != 0)
316 void DataCache::requestGet()
318 state = CACHE_STATE::UPDATING;
319 if (sResource != nullptr)
321 sResource->requestGet(pGetCB);
325 bool DataCache::isEmptySubscriber() const
327 std::lock_guard<std::mutex> lock(m_mutex);
328 return (subscriberList != nullptr) ? subscriberList->empty() : true;
330 } // namespace Service