1 //******************************************************************
3 // Copyright 2014 Intel Corporation.
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 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
24 #include "WrapResource.h"
26 unsigned long GetTickCount()
29 if (gettimeofday(&tv, NULL) != 0)
31 return (tv.tv_sec * 1000) + (tv.tv_usec / 1000);
34 WrapResource::WrapResource(string resourceID, ocresource_t resource)
35 : m_resourceID(resourceID), m_ocResource(resource),
36 m_listIndex(-1), m_x(0), m_repGetReady(false), m_gettingRep(false),
37 m_observeCB(nullptr), m_callbackRunning(false),
38 m_requestToken(0), m_observeRequest(nullptr),
39 m_typeRequest(nullptr)
43 string WrapResource::getResourceID() {
47 token_t WrapResource::getResource()
52 wreq = newRequest(RT_Get);
53 m_ocResource->get(m, wreq->m_getCB, QualityOfService::HighQos);
57 token_t WrapResource::putResource(OCRepresentation& rep)
62 wreq = newRequest(RT_Put);
63 rep.setUri(m_ocResource->uri());
64 m_ocResource->put(rep, m, wreq->m_putCB, QualityOfService::HighQos);
68 token_t WrapResource::observeResource(observecb_t& cb)
74 wreq = newRequest(RT_Observe);
75 m_observeRequest = wreq;
77 m_callbackRunning = true;
78 type = ObserveType::Observe;
79 m_ocResource->observe(type, m, wreq->m_obsCB);
83 bool WrapResource::cancelObserve()
85 m_callbackRunning = false;
86 m_observeCB = nullptr;
88 if (!m_observeRequest)
91 OCStackResult result = m_ocResource->cancelObserve();
92 if (result != OC_STACK_OK)
95 m_observeRequest->m_touchTime = GetTickCount();
99 WrapRequest *WrapResource::waitResource(token_t token)
106 wreq = m_requestMap.at(token);
108 } catch (const out_of_range& oor) {
113 std::unique_lock<std::mutex> lk(m_mutexGet);
114 st = wreq->m_cvGet.wait_for(lk, chrono::seconds(5));
115 return (st == cv_status::no_timeout) ? wreq : nullptr;
118 std::vector<std::string> WrapResource::getResourceTypes()
120 return m_ocResource->getResourceTypes();
123 std::vector<std::string> WrapResource::getResourceInterfaces()
125 return m_ocResource->getResourceInterfaces();
128 WrapRequest *WrapResource::newRequest(RequestType type)
130 WrapRequest *wreq = new WrapRequest(this, type, ++m_requestToken);
131 m_requestMap[m_requestToken] = wreq;
135 void WrapResource::resourceCallback(WrapRequest *wreq)
139 if (wreq->m_forTypeOnly) {
140 wreq->m_typeReady = true;
144 if (wreq->m_type == RT_Observe) {
146 if (m_callbackRunning)
147 cout << "callback missing " << m_resourceID << '\n';
150 m_observeCB(wreq->m_token, wreq->m_headerOptions, wreq->m_rep, wreq->m_eCode,
151 wreq->m_sequenceNumber);
153 wreq->m_cvGet.notify_one();
156 wreq->m_touchTime = GetTickCount();
160 * this parser infers types from json string since no other introspection
161 * is available. It also parses the key-value pairs.
163 void WrapResource::parseJSON(WrapRequest *wreq)
166 string anchor = "\"rep\":{";
167 string json = wreq->m_rep.getJSONRepresentation();
168 string name, type, value, next;
169 size_t r, e, e1, s, c;
171 r = json.find(anchor);
172 if (r == string::npos) {
175 c = r + anchor.length() - 1;
178 if (json[c] != '"') {
184 e = json.find(sep, c);
185 if (e == string::npos) {
188 name = json.substr(c, e - c);
189 s = e + sep.length();
195 e1 = json.find_first_of(",}", s + 1);
196 if (e1 == string::npos) {
199 value = json.substr(s, e1 - s);
204 e1 = json.find_first_of("\"", s);
205 if (e1 == string::npos) {
208 value = json.substr(s, e1 - s);
223 e1 = json.find_first_of(",}", s + 1);
224 if (e1 == string::npos) {
227 value = json.substr(s, e1 - s);
232 wreq->m_valueMap[name] = value; // key-value map
233 m_typeMap[name] = type; // key-type map
235 } while (json[c] == ',');
238 void WrapResource::findTypes()
240 delete m_typeRequest;
241 m_typeRequest = new WrapRequest(this, RT_Get, ++m_requestToken);
242 m_typeRequest->m_forTypeOnly = true;
246 const stringmap_t& WrapResource::getFormats()
251 /********** WrapRequest ***********/
253 WrapRequest::WrapRequest(WrapResource *wres, RequestType type, token_t token)
254 : m_eCode(0), m_sequenceNumber(0), m_parent(wres), m_type(type),
255 m_token(token), m_forTypeOnly(false), m_typeReady(false)
257 m_getCB = std::bind(&WrapRequest::getCB, this,
258 placeholders::_1, placeholders::_2, placeholders::_3);
259 m_putCB = std::bind(&WrapRequest::putCB, this,
260 placeholders::_1, placeholders::_2, placeholders::_3);
261 m_obsCB = std::bind(&WrapRequest::observeCB, this,
262 placeholders::_1, placeholders::_2, placeholders::_3, placeholders::_4);
263 m_touchTime = GetTickCount();
266 void WrapRequest::getCB(const HeaderOptions& headerOptions, const OCRepresentation& rep, int eCode)
268 m_headerOptions = headerOptions;
271 m_parent->resourceCallback(this);
274 void WrapRequest::putCB(const HeaderOptions& headerOptions, const OCRepresentation& rep, int eCode)
276 m_headerOptions = headerOptions;
279 m_parent->resourceCallback(this);
282 void WrapRequest::observeCB(const HeaderOptions& headerOptions, const OCRepresentation& rep, int eCode, int sequenceNumber)
284 m_headerOptions = headerOptions;
287 m_sequenceNumber = sequenceNumber;
288 m_parent->resourceCallback(this);