Modify resourceCache/DataCache file
[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
62             sResource->cancelObserve();
63             if(subscriberList != nullptr)
64             {
65                 subscriberList->clear();
66                 subscriberList.release();
67             }
68         }
69
70         void DataCache::initializeDataCache(PrimitiveResourcePtr pResource)
71         {
72             sResource = pResource;
73
74             sResource->requestGet(pGetCB);
75             if(sResource->isObservable())
76             {
77                 sResource->requestObserve(pObserveCB);
78             }
79             networkTimeOutHandle = networkTimer.postTimer(DEFAULT_EXPIRED_TIME, pTimerCB);
80         }
81
82         CacheID DataCache::addSubscriber(CacheCB func, REPORT_FREQUENCY rf, long repeatTime)
83         {
84             Report_Info newItem;
85             newItem.rf = rf;
86             newItem.repeatTime = repeatTime;
87             newItem.timerID = 0;
88
89             newItem.reportID = generateCacheID();
90
91             if(subscriberList != nullptr)
92             {
93                 subscriberList->insert(std::make_pair(newItem.reportID, std::make_pair(newItem, func)));
94             }
95
96             return newItem.reportID;
97         }
98
99         CacheID DataCache::deleteSubscriber(CacheID id)
100         {
101             CacheID ret = 0;
102
103             SubscriberInfoPair pair = findSubscriber(id);
104             if(pair.first != 0)
105             {
106                 ret = pair.first;
107                 subscriberList->erase(pair.first);
108             }
109
110             return ret;
111         }
112
113         SubscriberInfoPair DataCache::findSubscriber(CacheID id)
114         {
115             SubscriberInfoPair ret;
116
117             for(auto & i : *subscriberList)
118             {
119                 if(i.first == id)
120                 {
121                     ret = std::make_pair(i.first, std::make_pair((Report_Info)i.second.first,
122                             (CacheCB)i.second.second));
123                     break;
124                 }
125             }
126
127             return ret;
128         }
129
130         const PrimitiveResourcePtr DataCache::getPrimitiveResource() const
131         {
132             return (sResource!=nullptr)?sResource:nullptr;
133         }
134
135         const ResourceAttributes DataCache::getCachedData() const
136         {
137             if(state != CACHE_STATE::READY || attributes.empty())
138             {
139                 return ResourceAttributes();
140             }
141             const ResourceAttributes retAtt = attributes;
142             return retAtt;
143         }
144
145         void DataCache::onObserve(
146                 const HeaderOptions& _hos, const ResponseStatement& _rep, int _result, int _seq)
147         {
148
149             if(_result != OC_STACK_OK || _rep.getAttributes().empty())
150             {
151                 return;
152             }
153
154             if(state != CACHE_STATE::READY)
155             {
156                 state = CACHE_STATE::READY;
157             }
158
159             networkTimer.cancelTimer(networkTimeOutHandle);
160             networkTimeOutHandle = networkTimer.postTimer(DEFAULT_EXPIRED_TIME, pTimerCB);
161
162             notifyObservers(_rep.getAttributes());
163         }
164
165         void DataCache::onGet(const HeaderOptions& _hos,
166                 const ResponseStatement& _rep, int _result)
167         {
168             if(_result != OC_STACK_OK || _rep.getAttributes().empty())
169             {
170                 return;
171             }
172
173             if(state != CACHE_STATE::READY)
174             {
175                 state = CACHE_STATE::READY;
176             }
177
178             if(!sResource->isObservable())
179             {
180                 networkTimer.cancelTimer(networkTimeOutHandle);
181                 networkTimeOutHandle = networkTimer.postTimer(DEFAULT_EXPIRED_TIME, pTimerCB);
182
183                 pollingHandle = pollingTimer.postTimer(DEFAULT_REPORT_TIME, pPollingCB);
184             }
185
186             notifyObservers(_rep.getAttributes());
187         }
188
189         void DataCache::notifyObservers(ResourceAttributes Att)
190         {
191             if(attributes == Att)
192             {
193                 return;
194             }
195
196             attributes = Att;
197
198             ResourceAttributes retAtt = Att;
199             for(auto & i : * subscriberList)
200             {
201                 if(i.second.first.rf == REPORT_FREQUENCY::UPTODATE)
202                 {
203                     i.second.second(this->sResource, retAtt);
204                 }
205             }
206         }
207
208         CACHE_STATE DataCache::getCacheState() const
209         {
210             return state;
211         }
212
213         void *DataCache::onTimeOut(unsigned int timerID)
214         {
215             state = CACHE_STATE::LOST_SIGNAL;
216             return NULL;
217         }
218         void *DataCache::onPollingOut(const unsigned int timerID)
219         {
220             if(sResource != nullptr)
221             {
222                 sResource->requestGet(pGetCB);
223             }
224             return NULL;
225         }
226
227         CacheID DataCache::generateCacheID()
228         {
229             CacheID retID = 0;
230             srand(time(NULL));
231
232             while(1)
233             {
234                 if(findSubscriber(retID).first == 0 && retID != 0)
235                 {
236                     break;
237                 }
238                 retID = rand();
239             }
240
241             return retID;
242         }
243
244         void DataCache::requestGet()
245         {
246             state = CACHE_STATE::UPDATING;
247             if(sResource != nullptr)
248             {
249                 sResource->requestGet(pGetCB);
250             }
251         }
252
253         bool DataCache::isEmptySubscriber() const
254         {
255             return (subscriberList!=nullptr)?subscriberList->empty():true;
256         }
257     } // namespace Service
258 } // namespace OIC