1 //******************************************************************
3 // Copyright 2014 Intel Mobile Communications GmbH 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 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
21 #ifndef __INTEL_OCAPI_H_2014_07_10
22 #define __INTEL_OCAPI_H_2014_07_10
31 #include <boost/property_tree/ptree.hpp>
32 #include <boost/property_tree/json_parser.hpp>
33 #include <boost/variant.hpp>
36 #include "OCHeaderOption.h"
37 #include <OCException.h>
38 #include "StringConstants.h"
39 #include "oc_logger.hpp"
44 class OCResourceRequest;
45 class OCResourceResponse;
50 typedef boost::iostreams::stream<OC::oc_log_stream> log_target_t;
54 /* We'll want to provide some sort of explicit hook for custom logging at some
55 point; until then, this should do nicely (note that since these are lambdas,
56 later a special target could be captured, allowing much flexibility): */
57 auto oclog_target = []() -> log_target_t&
59 static OC::oc_log_stream ols(oc_make_ostream_logger);
60 static log_target_t os(ols);
64 } // namespace OC::detail
66 auto oclog = []() -> boost::iostreams::stream<OC::oc_log_stream>&
68 return detail::oclog_target();
75 enum class OCPlatformStatus
81 enum class OCAdvertisementStatus
86 typedef std::string URI;
88 enum class ServiceType
101 enum class QualityOfService : uint8_t
104 MidQos = OC_MEDIUM_QOS,
105 HighQos = OC_HIGH_QOS,
106 NaQos = OC_NA_QOS // No Quality is defined, let the stack decide
110 * Data structure to provide the configuration.
111 * ServiceType: indicate InProc or OutOfProc
112 * ModeType : indicate whether we want to do server, client or both
113 * ipAddress : ip address of server.
114 * if you speecifiy 0.0.0.0 : it listens on any interface.
115 * port : port of server.
116 * : if you specifiy 0 : next available random port is used.
117 * : if you specify 5683 : client discovery can work even if they don't specify port.
118 * QoS : Quality of Service : CONFIRMABLE or NON CONFIRMABLE.
120 struct PlatformConfig
122 ServiceType serviceType;
124 std::string ipAddress;
127 QualityOfService QoS;
131 : serviceType(ServiceType::InProc),
132 mode(ModeType::Both),
133 ipAddress("0.0.0.0"),
135 QoS(QualityOfService::NaQos)
137 PlatformConfig(const ServiceType serviceType_,
138 const ModeType mode_,
139 const std::string& ipAddress_,
140 const uint16_t port_,
141 const QualityOfService QoS_)
142 : serviceType(serviceType_),
144 ipAddress(ipAddress_),
150 enum RequestHandlerFlag
153 RequestFlag = 1 << 1,
154 ObserverFlag = 1 << 2
157 enum class ObserveType
163 // Helper function to escape character in a string.
164 std::string escapeString(const std::string& value);
166 typedef std::map<std::string, std::string> AttributeMap;
168 class OCRepresentation
172 AttributeMap m_attributeMap;
173 std::vector<std::string> m_resourceTypes;
174 std::vector<std::string> m_resourceInterfaces;
177 std::vector<OCRepresentation> m_children;
180 OCRepresentation() {}
182 bool erase(const std::string& str)
184 return m_attributeMap.erase(str) != 0;
187 std::string getUri(void) const
192 template <typename T>
193 void setValue(const std::string& str, const T& val);
195 template <typename T>
196 bool getValue(const std::string& str, T& val) const;
198 template <typename T>
199 T getValue(const std::string& str) const;
201 bool hasAttribute(const std::string& str) const
203 return m_attributeMap.find(str) != m_attributeMap.end();
206 void setNULL(const std::string& str)
208 m_attributeMap[str] = "null";
211 bool isNULL(const std::string& str) const
213 auto x = m_attributeMap.find(str);
215 if(m_attributeMap.end() != x)
217 return x->second.compare("null") == 0;
221 std::ostringstream message;
222 message << "attribute: " << str << " doesn't exist\n";
223 throw OCException(message.str());
229 int numberOfAttributes() const
231 return m_attributeMap.size();
234 void setUri(std::string uri)
239 std::vector<OCRepresentation> getChildren(void) const
244 void setChildren(const std::vector<OCRepresentation>& children)
246 m_children = children;
249 std::weak_ptr<OCResource> getResource() const
251 // TODO Needs to be implemented
252 std::weak_ptr<OCResource> wp;
256 AttributeMap getAttributeMap() const
258 return m_attributeMap;
261 void setAttributeMap(const AttributeMap& map)
263 m_attributeMap = map;
266 std::string getJSONRepresentation(void) const
268 std::ostringstream json;
272 for(auto itr = m_attributeMap.begin(); itr!= m_attributeMap.end(); ++ itr)
274 if(itr != m_attributeMap.begin())
278 json << "\""<<itr->first<<"\":"<< itr->second;
285 std::vector<std::string> getResourceTypes() const
287 return m_resourceTypes;
290 void setResourceTypes(const std::vector<std::string>& resourceTypes)
292 m_resourceTypes = resourceTypes;
295 std::vector<std::string> getResourceInterfaces(void) const
297 return m_resourceInterfaces;
300 void setResourceInterfaces(const std::vector<std::string>& resourceInterfaces)
302 m_resourceInterfaces = resourceInterfaces;
306 OCRepresentation parseJSONToRepresentation(const std::string& str);
308 inline OCRepresentation parseJSONToRepresentation(const std::string& str)
310 OCRepresentation rep;
312 AttributeMap attributeMap;
314 std::stringstream requestStream;
315 requestStream << str;
316 boost::property_tree::ptree payload;
319 boost::property_tree::read_json(requestStream, payload);
321 catch(boost::property_tree::json_parser::json_parser_error &e)
323 throw OCException(OC::Exception::GENERAL_JSON_PARSE_FAILED);
326 for(auto& item: payload)
328 std::string name = item.first.data();
329 std::string value = item.second.data();
331 attributeMap[name] = value;
334 rep.setAttributeMap(attributeMap);
339 typedef boost::variant<
348 std::vector<std::string>,
349 std::vector<OCRepresentation>
352 template <typename T>
353 inline std::string getJSONFromVector(const std::vector<T>& v)
355 std::ostringstream json;
360 std::copy(v.begin(), v.end() - 1, std::ostream_iterator<T>(json, ","));
368 class ComposeVisitor : public boost::static_visitor<std::string>
372 // TODO different int sizes
373 std::string operator() (const int i) const
375 return std::to_string(i);
378 std::string operator() (const double d) const
380 return std::to_string(d);
383 std::string operator() (const std::string& str) const
385 std::ostringstream json;
393 std::string operator() (const bool b) const
405 std::string operator() (const std::vector<int>& numbers) const
407 return getJSONFromVector(numbers);
410 std::string operator() (const std::vector<double>& numbers) const
412 return getJSONFromVector(numbers);
415 std::string operator() (const std::vector<bool>& bools) const
417 std::ostringstream json;
425 b ? json << "true" : json << "false";
430 b ? json << ",true" : json << ",false";
438 std::string operator() (const std::vector<std::string>& strings) const
440 return getJSONFromVector(strings);
443 std::string operator() (const OCRepresentation& rep) const
445 std::ostringstream json;
449 json << escapeString(rep.getJSONRepresentation());
456 std::string operator() (const std::vector<OCRepresentation>& reps) const
458 std::ostringstream json;
467 json << escapeString(rep.getJSONRepresentation());
472 json << escapeString(rep.getJSONRepresentation());
483 inline void split(std::string input, char delimiter, std::vector<std::string>& tokens)
485 std::stringstream ss(input);
488 while(std::getline(ss, item, delimiter))
490 tokens.push_back(item);
494 class ParseVisitor : public boost::static_visitor<void>
498 ParseVisitor(std::string str): m_str(str)
502 void operator() (int& i) const
504 i = std::stoi(m_str);
507 void operator() (double& d) const
509 d = std::stod(m_str);
512 void operator() (std::string& str) const
517 void operator() (bool& b) const
519 b = m_str.compare("true") == 0;
522 void operator() (std::vector<int>& numbers) const
526 if(m_str.length() >= 2)
528 std::string str = m_str.substr(1, m_str.length()-2);
530 std::vector<std::string> tokens;
531 split(str, ',', tokens);
535 numbers.push_back(std::stoi(s));
540 throw OCException(OC::Exception::INVALID_ARRAY);
545 void operator() (std::vector<double>& numbers) const
549 if(m_str.length() >= 2)
551 std::string str = m_str.substr(1, m_str.length()-2);
552 std::vector<std::string> tokens;
553 split(str, ',', tokens);
557 numbers.push_back(std::stod(s));
562 throw OCException(OC::Exception::INVALID_ARRAY);
566 void operator() (std::vector<bool>& bools) const
570 if(m_str.length() >= 2)
572 std::string str = m_str.substr(2, m_str.length()-3);
574 std::vector<std::string> tokens;
575 split(str, ',', tokens);
579 bools.push_back(s.compare("true") == 0);
584 throw OCException(OC::Exception::INVALID_ARRAY);
589 void operator() (std::vector<std::string>& strings) const
593 if(m_str.length() >= 2)
595 std::string str = m_str.substr(1, m_str.length()-2);
597 std::vector<std::string> tokens;
598 split(str, ',', tokens);
602 strings.push_back(s);
607 throw OCException(OC::Exception::INVALID_ARRAY);
611 void operator() (std::vector<OCRepresentation>& reps) const
615 if(m_str.length() >= 2)
617 std::string str = m_str.substr(1, m_str.length()-2);
619 std::vector<std::string> tokens;
620 split(str, ',', tokens);
624 reps.push_back(parseJSONToRepresentation(s));
629 throw OCException(OC::Exception::INVALID_ARRAY);
633 void operator() (OCRepresentation& rep) const
635 rep = parseJSONToRepresentation(m_str);
643 inline std::string getJSON(const AttributeValue& v)
645 return boost::apply_visitor(ComposeVisitor(), v);
648 inline void parseJSON(AttributeValue& v, std::string str)
650 boost::apply_visitor(ParseVisitor(str), v);
653 template <typename T>
654 void OCRepresentation::setValue(const std::string& str, const T& val)
656 m_attributeMap[str] = getJSON(val);
659 template <typename T>
660 T OCRepresentation::getValue(const std::string& str) const
664 auto x = m_attributeMap.find(str);
666 if(m_attributeMap.end() != x)
668 AttributeValue v = val;
669 parseJSON(v, x->second);
670 val = boost::get<T>(v);
676 template <typename T>
677 bool OCRepresentation::getValue(const std::string& str, T& val) const
679 auto x = m_attributeMap.find(str);
681 if(m_attributeMap.end() != x)
683 AttributeValue v = val;
684 parseJSON(v, x->second);
685 val = boost::get<T>(v);
694 // Typedef for header option vector
695 // OCHeaderOption class is in HeaderOption namespace
696 typedef std::vector<HeaderOption::OCHeaderOption> HeaderOptions;
698 // Typedef for query parameter map
699 typedef std::map<std::string, std::string> QueryParamsMap;
701 // Typedef for list of observation IDs
702 typedef std::vector<OCObservationId> ObservationIds;
704 enum class ObserveAction
712 // Action associated with observation request
713 ObserveAction action;
714 // Identifier for observation being registered/unregistered
715 OCObservationId obsId;
718 // const strings for different interfaces
721 const std::string DEFAULT_INTERFACE = "oc.mi.def";
723 // Used in discovering (GET) links to other resources of a collection.
724 const std::string LINK_INTERFACE = "oc.mi.ll";
726 // Used in GET, PUT, POST, DELETE methods on links to other resources of a collection.
727 const std::string BATCH_INTERFACE = "oc.mi.b";
729 typedef std::function<void(std::shared_ptr<OCResource>)> FindCallback;
731 typedef std::function<OCEntityHandlerResult (const std::shared_ptr<OCResourceRequest>,
732 const std::shared_ptr<OCResourceResponse>)> EntityHandler;
734 typedef std::function<void(OCStackResult, const unsigned int)> SubscribeCallback;
736 typedef std::function<void(const HeaderOptions&,
737 const OCRepresentation&, const int)> GetCallback;
739 typedef std::function<void(const HeaderOptions&,
740 const OCRepresentation&, const int)> PostCallback;
742 typedef std::function<void(const HeaderOptions&,
743 const OCRepresentation&, const int)> PutCallback;
745 typedef std::function<void(const HeaderOptions&, const int)> DeleteCallback;
747 typedef std::function<void(const HeaderOptions&,
748 const OCRepresentation&, const int, const int)> ObserveCallback;