Modify resourceCacheManager
[platform/upstream/iotivity.git] / service / resource-manipulation / modules / resourceCache / src / DataCache.cpp
1 //******************************************************************
2 //
3 // Copyright 2015 Samsung Electronics All Rights Reserved.
4 //
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
6 //
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
10 //
11 //      http://www.apache.org/licenses/LICENSE-2.0
12 //
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.
18 //
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
20
21 #include <memory>
22 #include <cstdlib>
23 #include <functional>
24 #include <map>
25 #include <utility>
26 #include <ctime>
27
28 //#include "OCApi.h"
29
30 #include "DataCache.h"
31
32 #include "ResponseStatement.h"
33 #include "ResourceAttributes.h"
34 #include "ExpiryTimer.h"
35
36 namespace OIC
37 {
38     namespace Service
39     {
40         DataCache::DataCache()
41         {
42             subscriberList = std::unique_ptr<SubscriberInfo>(new SubscriberInfo());
43
44             sResource = nullptr;
45
46             state = CACHE_STATE::READY_YET;
47
48             pObserveCB = (ObserveCB)(std::bind(&DataCache::onObserve, this,
49                     std::placeholders::_1, std::placeholders::_2,
50                     std::placeholders::_3, std::placeholders::_4));
51             pGetCB = (GetCB)(std::bind(&DataCache::onGet, this,
52                     std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
53             pTimerCB = (TimerCB)(std::bind(&DataCache::onTimeOut, this, std::placeholders::_1));
54             pPollingCB = (TimerCB)(std::bind(&DataCache::onPollingOut, this, std::placeholders::_1));
55
56         }
57
58         DataCache::~DataCache()
59         {
60             state = CACHE_STATE::DESTROYED;
61             if(subscriberList != nullptr)
62             {
63                 subscriberList->clear();
64                 subscriberList.release();
65             }
66         }
67
68         void DataCache::initializeDataCache(PrimitiveResourcePtr pResource)
69         {
70             sResource = pResource;
71
72             sResource->requestGet(pGetCB);
73             if(sResource->isObservable())
74             {
75                 sResource->requestObserve(pObserveCB);
76             }
77             networkTimeOutHandle = networkTimer.requestTimer(DEFAULT_EXPIRED_TIME, pTimerCB);
78         }
79
80         CacheID DataCache::addSubscriber(CacheCB func, REPORT_FREQUENCY rf, long repeatTime)
81         {
82             Report_Info newItem;
83             newItem.rf = rf;
84             newItem.repeatTime = repeatTime;
85             newItem.timerID = 0;
86
87             newItem.reportID = generateCacheID();
88
89             if(subscriberList != nullptr)
90             {
91                 subscriberList->insert(std::make_pair(newItem.reportID, std::make_pair(newItem, func)));
92             }
93
94             return newItem.reportID;
95         }
96
97         CacheID DataCache::deleteSubscriber(CacheID id)
98         {
99             CacheID ret = 0;
100
101             SubscriberInfoPair pair = findSubscriber(id);
102             if(pair.first != 0)
103             {
104                 ret = pair.first;
105                 subscriberList->erase(pair.first);
106             }
107
108             return ret;
109         }
110
111         SubscriberInfoPair DataCache::findSubscriber(CacheID id)
112         {
113             SubscriberInfoPair ret;
114
115             for(auto & i : *subscriberList)
116             {
117                 if(i.first == id)
118                 {
119                     ret = std::make_pair(i.first, std::make_pair((Report_Info)i.second.first,
120                             (CacheCB)i.second.second));
121                     break;
122                 }
123             }
124
125             return ret;
126         }
127
128         const PrimitiveResourcePtr DataCache::getPrimitiveResource() const
129         {
130             return (sResource!=nullptr)?sResource:nullptr;
131         }
132
133         const ResourceAttributes DataCache::getCachedData() const
134         {
135             if(state != CACHE_STATE::READY || attributes.empty())
136             {
137                 return ResourceAttributes();
138             }
139             const ResourceAttributes retAtt = attributes;
140             return retAtt;
141         }
142
143         void DataCache::onObserve(
144                 const HeaderOptions& _hos, const ResponseStatement& _rep, int _result, int _seq)
145         {
146
147             if(_result != OC_STACK_OK || _rep.getAttributes().empty())
148             {
149                 return;
150             }
151
152             if(state != CACHE_STATE::READY)
153             {
154                 state = CACHE_STATE::READY;
155             }
156
157             networkTimer.cancelTimer(networkTimeOutHandle);
158             networkTimeOutHandle = networkTimer.requestTimer(DEFAULT_EXPIRED_TIME, pTimerCB);
159
160             notifyObservers(_rep.getAttributes());
161         }
162
163         void DataCache::onGet(const HeaderOptions& _hos,
164                 const ResponseStatement& _rep, int _result)
165         {
166             if(_result != OC_STACK_OK || _rep.getAttributes().empty())
167             {
168                 return;
169             }
170
171             if(state != CACHE_STATE::READY)
172             {
173                 state = CACHE_STATE::READY;
174             }
175
176             if(!sResource->isObservable())
177             {
178                 networkTimer.cancelTimer(networkTimeOutHandle);
179                 networkTimeOutHandle = networkTimer.requestTimer(DEFAULT_EXPIRED_TIME, pTimerCB);
180
181                 pollingHandle = pollingTimer.requestTimer(DEFAULT_REPORT_TIME, pPollingCB);
182             }
183
184             notifyObservers(_rep.getAttributes());
185         }
186
187         void DataCache::notifyObservers(ResourceAttributes Att)
188         {
189             if(attributes == Att)
190             {
191                 return;
192             }
193
194             attributes = Att;
195
196             ResourceAttributes retAtt = Att;
197             for(auto & i : * subscriberList)
198             {
199                 if(i.second.first.rf == REPORT_FREQUENCY::UPTODATE)
200                 {
201                     i.second.second(this->sResource, retAtt);
202                 }
203             }
204         }
205
206         CACHE_STATE DataCache::getCacheState() const
207         {
208             return state;
209         }
210
211         void *DataCache::onTimeOut(unsigned int timerID)
212         {
213             state = CACHE_STATE::LOST_SIGNAL;
214             return NULL;
215         }
216         void *DataCache::onPollingOut(const unsigned int timerID)
217         {
218             if(sResource != nullptr)
219             {
220                 sResource->requestGet(pGetCB);
221             }
222             return NULL;
223         }
224
225         CacheID DataCache::generateCacheID()
226         {
227             CacheID retID = 0;
228             srand(time(NULL));
229
230             while(1)
231             {
232                 if(findSubscriber(retID).first == 0 && retID != 0)
233                 {
234                     break;
235                 }
236                 retID = rand();
237             }
238
239             return retID;
240         }
241
242         void DataCache::requestGet()
243         {
244             state = CACHE_STATE::UPDATING;
245             if(sResource != nullptr)
246             {
247                 sResource->requestGet(pGetCB);
248             }
249         }
250
251         bool DataCache::isEmptySubscriber() const
252         {
253             return (subscriberList!=nullptr)?subscriberList->empty():true;
254         }
255     } // namespace Service
256 } // namespace OIC