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