Updated Makefiles and CMakeLists.txt to point to resource, not oic-resource
[platform/upstream/iotivity.git] / include / OCApi.h
1 //******************************************************************
2 //
3 // Copyright 2014 Intel Mobile Communications GmbH 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 #ifndef __INTEL_OCAPI_H_2014_07_10
22 #define __INTEL_OCAPI_H_2014_07_10
23
24 #include <string>
25 #include <sstream>
26 #include <vector>
27 #include <map>
28 #include <memory>
29 #include <iterator>
30
31 #include <boost/property_tree/ptree.hpp>
32 #include <boost/property_tree/json_parser.hpp>
33 #include <boost/variant.hpp>
34
35 #include "ocstack.h"
36 #include "OCHeaderOption.h"
37 #include <OCException.h>
38 #include "StringConstants.h"
39 #include "oc_logger.hpp"
40
41 namespace OC
42 {
43     class OCResource;
44     class OCResourceRequest;
45     class OCResourceResponse;
46 } // namespace OC
47
48 namespace OC
49 {
50     typedef boost::iostreams::stream<OC::oc_log_stream>     log_target_t;
51
52     namespace detail
53     {
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&
58         {
59             static OC::oc_log_stream    ols(oc_make_ostream_logger);
60             static log_target_t         os(ols);
61
62             return os;
63         };
64     } // namespace OC::detail
65
66     auto oclog = []() -> boost::iostreams::stream<OC::oc_log_stream>&
67     {
68         return detail::oclog_target();
69     };
70
71 } // namespace OC
72
73 namespace OC
74 {
75     enum class OCPlatformStatus
76     {
77         PlatformUp,
78         PlatformDown
79     };
80
81     enum class OCAdvertisementStatus
82     {
83         None
84     };
85
86     typedef std::string URI;
87
88     enum class ServiceType
89     {
90         InProc,
91         OutOfProc
92     };
93
94     enum class ModeType
95     {
96         Server,
97         Client,
98         Both
99     };
100
101     enum class QualityOfService : uint8_t
102     {
103         LowQos      = OC_LOW_QOS,
104         MidQos      = OC_MEDIUM_QOS,
105         HighQos     = OC_HIGH_QOS,
106         NaQos       = OC_NA_QOS // No Quality is defined, let the stack decide
107     };
108
109     /**
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.
119     */
120     struct PlatformConfig
121     {
122         ServiceType                serviceType;
123         ModeType                   mode;
124         std::string                ipAddress;
125         uint16_t                   port;
126
127         QualityOfService           QoS;
128
129         public:
130             PlatformConfig()
131                 : serviceType(ServiceType::InProc),
132                 mode(ModeType::Both),
133                 ipAddress("0.0.0.0"),
134                 port(0),
135                 QoS(QualityOfService::NaQos)
136         {}
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_),
143                 mode(mode_),
144                 ipAddress(ipAddress_),
145                 port(port_),
146                 QoS(QoS_)
147         {}
148     };
149
150     enum RequestHandlerFlag
151     {
152         InitFlag = 1 << 0,
153         RequestFlag = 1 << 1,
154         ObserverFlag = 1 << 2
155     };
156
157     enum class ObserveType
158     {
159         Observe,
160         ObserveAll
161     };
162
163     // Helper function to escape character in a string.
164     std::string escapeString(const std::string& value);
165
166     typedef std::map<std::string, std::string> AttributeMap;
167
168     class OCRepresentation
169     {
170         private:
171         std::string m_uri;
172         AttributeMap m_attributeMap;
173         std::vector<std::string> m_resourceTypes;
174         std::vector<std::string> m_resourceInterfaces;
175         int errorCode;
176
177         std::vector<OCRepresentation> m_children;
178
179         public:
180         OCRepresentation() {}
181
182         bool erase(const std::string& str)
183         {
184             return m_attributeMap.erase(str) != 0;
185         }
186
187         std::string getUri(void) const
188         {
189             return m_uri;
190         }
191
192         template <typename T>
193         void setValue(const std::string& str, const T& val);
194
195         template <typename T>
196         bool getValue(const std::string& str, T& val) const;
197
198         template <typename T>
199         T getValue(const std::string& str) const;
200
201         bool hasAttribute(const std::string& str) const
202         {
203             return m_attributeMap.find(str) != m_attributeMap.end();
204         }
205
206         void setNULL(const std::string& str)
207         {
208             m_attributeMap[str] = "null";
209         }
210
211         bool isNULL(const std::string& str) const
212         {
213             auto x = m_attributeMap.find(str);
214
215             if(m_attributeMap.end() != x)
216             {
217                 return x->second.compare("null") == 0;
218             }
219             else
220             {
221                 std::ostringstream message;
222                 message << "attribute: " << str << " doesn't exist\n";
223                 throw OCException(message.str());
224             }
225
226             return false;
227         }
228
229         int numberOfAttributes() const
230         {
231             return m_attributeMap.size();
232         }
233
234         void setUri(std::string uri)
235         {
236             m_uri = uri;
237         }
238
239         std::vector<OCRepresentation> getChildren(void) const
240         {
241             return m_children;
242         }
243
244         void setChildren(const std::vector<OCRepresentation>& children)
245         {
246             m_children = children;
247         }
248
249         std::weak_ptr<OCResource> getResource() const
250         {
251             // TODO Needs to be implemented
252             std::weak_ptr<OCResource> wp;
253             return wp;
254         }
255
256         AttributeMap getAttributeMap() const
257         {
258             return m_attributeMap;
259         }
260
261         void setAttributeMap(const AttributeMap& map)
262         {
263             m_attributeMap = map;
264         }
265
266         std::string getJSONRepresentation(void) const
267         {
268             std::ostringstream json;
269
270             json << "{";
271
272             for(auto itr = m_attributeMap.begin(); itr!= m_attributeMap.end(); ++ itr)
273             {
274                 if(itr != m_attributeMap.begin())
275                 {
276                     json << ',';
277                 }
278                 json << "\""<<itr->first<<"\":"<< itr->second;
279             }
280             json << "}";
281
282             return json.str();
283         }
284
285         std::vector<std::string> getResourceTypes() const
286         {
287             return m_resourceTypes;
288         }
289
290         void setResourceTypes(const std::vector<std::string>& resourceTypes)
291         {
292             m_resourceTypes = resourceTypes;
293         }
294
295         std::vector<std::string> getResourceInterfaces(void) const
296         {
297             return m_resourceInterfaces;
298         }
299
300         void setResourceInterfaces(const std::vector<std::string>& resourceInterfaces)
301         {
302             m_resourceInterfaces = resourceInterfaces;
303         }
304     };
305
306     OCRepresentation parseJSONToRepresentation(const std::string& str);
307
308     inline OCRepresentation parseJSONToRepresentation(const std::string& str)
309     {
310         OCRepresentation rep;
311
312         AttributeMap attributeMap;
313
314         std::stringstream requestStream;
315         requestStream << str;
316         boost::property_tree::ptree payload;
317         try
318         {
319             boost::property_tree::read_json(requestStream, payload);
320         }
321         catch(boost::property_tree::json_parser::json_parser_error &e)
322         {
323             throw OCException(OC::Exception::GENERAL_JSON_PARSE_FAILED);
324         }
325
326         for(auto& item: payload)
327         {
328             std::string name = item.first.data();
329             std::string value = item.second.data();
330
331             attributeMap[name] = value;
332         }
333
334         rep.setAttributeMap(attributeMap);
335
336         return rep;
337     }
338
339     typedef boost::variant<
340                 int,
341                 double,
342                 bool,
343                 OCRepresentation,
344                 std::string,
345                 std::vector<int>,
346                 std::vector<double>,
347                 std::vector<bool>,
348                 std::vector<std::string>,
349                 std::vector<OCRepresentation>
350                 > AttributeValue;
351
352     template <typename T>
353     inline std::string getJSONFromVector(const std::vector<T>& v)
354     {
355         std::ostringstream json;
356
357         json << "\"[";
358         if(v.size() != 0)
359         {
360             std::copy(v.begin(), v.end() - 1, std::ostream_iterator<T>(json, ","));
361             json << v.back();
362         }
363         json << "]\"";
364
365         return json.str();
366     }
367
368     class ComposeVisitor : public boost::static_visitor<std::string>
369     {
370         public:
371
372             // TODO different int sizes
373             std::string operator() (const int i) const
374             {
375                 return std::to_string(i);
376             }
377
378             std::string operator() (const double d) const
379             {
380                 return std::to_string(d);
381             }
382
383             std::string operator() (const std::string& str) const
384             {
385                 std::ostringstream json;
386                 json << "\"";
387                 json << str;
388                 json << "\"";
389
390                 return json.str();
391             }
392
393             std::string operator() (const bool b) const
394             {
395                 if(b)
396                 {
397                     return "true";
398                 }
399                 else
400                 {
401                     return "false";
402                 }
403             }
404
405             std::string operator() (const std::vector<int>& numbers) const
406             {
407                 return getJSONFromVector(numbers);
408             }
409
410             std::string operator() (const std::vector<double>& numbers) const
411             {
412                 return getJSONFromVector(numbers);
413             }
414
415             std::string operator() (const std::vector<bool>& bools) const
416             {
417                 std::ostringstream json;
418                 int first = 1;
419
420                 json << "\"[";
421                 for(auto b: bools)
422                 {
423                     if(first)
424                     {
425                         b ? json << "true" : json << "false";
426                         first = 0;
427                     }
428                     else
429                     {
430                         b ? json << ",true" : json << ",false";
431                     }
432                 }
433                 json << "]\"";
434
435                 return json.str();
436             }
437
438             std::string operator() (const std::vector<std::string>& strings) const
439             {
440                 return getJSONFromVector(strings);
441             }
442
443             std::string operator() (const OCRepresentation& rep) const
444             {
445                 std::ostringstream json;
446
447                 json << "\"";
448
449                 json << escapeString(rep.getJSONRepresentation());
450
451                 json << "\"";
452
453                 return json.str();
454             }
455
456             std::string operator() (const std::vector<OCRepresentation>& reps) const
457             {
458                 std::ostringstream json;
459                 int first = 1;
460
461                 json << "\"[";
462                 for(auto rep: reps)
463                 {
464                     if(first)
465                     {
466                         first = 0;
467                         json << escapeString(rep.getJSONRepresentation());
468                     }
469                     else
470                     {
471                         json << ",";
472                         json << escapeString(rep.getJSONRepresentation());
473                     }
474                 }
475                 json << "]\"";
476
477                 return json.str();
478             }
479
480
481     };
482
483     inline void split(std::string input, char delimiter, std::vector<std::string>& tokens)
484     {
485         std::stringstream ss(input);
486         std::string item;
487
488         while(std::getline(ss, item, delimiter))
489         {
490             tokens.push_back(item);
491         }
492     }
493
494     class ParseVisitor : public boost::static_visitor<void>
495     {
496         public:
497
498             ParseVisitor(std::string str): m_str(str)
499             {
500             }
501
502             void operator() (int& i) const
503             {
504                 i = std::stoi(m_str);
505             }
506
507             void operator() (double& d) const
508             {
509                 d = std::stod(m_str);
510             }
511
512             void operator() (std::string& str) const
513             {
514                 str = m_str;
515             }
516
517             void operator() (bool& b) const
518             {
519                 b = m_str.compare("true") == 0;
520             }
521
522             void operator() (std::vector<int>& numbers) const
523             {
524                 numbers.clear();
525
526                 if(m_str.length() >= 2)
527                 {
528                     std::string str = m_str.substr(1, m_str.length()-2);
529
530                     std::vector<std::string> tokens;
531                     split(str, ',', tokens);
532
533                     for(auto s: tokens)
534                     {
535                         numbers.push_back(std::stoi(s));
536                     }
537                 }
538                 else
539                 {
540                     throw OCException(OC::Exception::INVALID_ARRAY);
541                 }
542
543             }
544
545             void operator() (std::vector<double>& numbers) const
546             {
547                 numbers.clear();
548
549                 if(m_str.length() >= 2)
550                 {
551                     std::string str = m_str.substr(1, m_str.length()-2);
552                     std::vector<std::string> tokens;
553                     split(str, ',', tokens);
554
555                     for(auto s: tokens)
556                     {
557                         numbers.push_back(std::stod(s));
558                     }
559                 }
560                 else
561                 {
562                     throw OCException(OC::Exception::INVALID_ARRAY);
563                 }
564             }
565
566             void operator() (std::vector<bool>& bools) const
567             {
568                 bools.clear();
569
570                 if(m_str.length() >= 2)
571                 {
572                     std::string str = m_str.substr(2, m_str.length()-3);
573
574                     std::vector<std::string> tokens;
575                     split(str, ',', tokens);
576
577                     for(auto s: tokens)
578                     {
579                         bools.push_back(s.compare("true") == 0);
580                     }
581                 }
582                 else
583                 {
584                     throw OCException(OC::Exception::INVALID_ARRAY);
585                 }
586
587             }
588
589             void operator() (std::vector<std::string>& strings) const
590             {
591                 strings.clear();
592
593                 if(m_str.length() >= 2)
594                 {
595                     std::string str = m_str.substr(1, m_str.length()-2);
596
597                     std::vector<std::string> tokens;
598                     split(str, ',', tokens);
599
600                     for(auto s: tokens)
601                     {
602                         strings.push_back(s);
603                     }
604                 }
605                 else
606                 {
607                     throw OCException(OC::Exception::INVALID_ARRAY);
608                 }
609             }
610
611             void operator() (std::vector<OCRepresentation>& reps) const
612             {
613                 reps.clear();
614
615                 if(m_str.length() >= 2)
616                 {
617                     std::string str = m_str.substr(1, m_str.length()-2);
618
619                     std::vector<std::string> tokens;
620                     split(str, ',', tokens);
621
622                     for(auto s: tokens)
623                     {
624                         reps.push_back(parseJSONToRepresentation(s));
625                     }
626                 }
627                 else
628                 {
629                     throw OCException(OC::Exception::INVALID_ARRAY);
630                 }
631             }
632
633             void operator() (OCRepresentation& rep) const
634             {
635                 rep = parseJSONToRepresentation(m_str);
636             }
637
638         private:
639             std::string m_str;
640     };
641
642
643     inline std::string getJSON(const AttributeValue& v)
644     {
645         return boost::apply_visitor(ComposeVisitor(), v);
646     }
647
648     inline void parseJSON(AttributeValue& v, std::string str)
649     {
650         boost::apply_visitor(ParseVisitor(str), v);
651     }
652
653     template <typename T>
654     void OCRepresentation::setValue(const std::string& str, const T& val)
655     {
656         m_attributeMap[str] = getJSON(val);
657     }
658
659     template <typename T>
660     T OCRepresentation::getValue(const std::string& str) const
661     {
662         T val = T();
663
664         auto x = m_attributeMap.find(str);
665
666         if(m_attributeMap.end() != x)
667         {
668             AttributeValue v = val;
669             parseJSON(v, x->second);
670             val = boost::get<T>(v);
671         }
672
673         return val;
674     }
675
676     template <typename T>
677     bool OCRepresentation::getValue(const std::string& str, T& val) const
678     {
679         auto x = m_attributeMap.find(str);
680
681         if(m_attributeMap.end() != x)
682         {
683             AttributeValue v = val;
684             parseJSON(v, x->second);
685             val = boost::get<T>(v);
686             return true;
687         }
688         else
689         {
690             return false;
691         }
692     }
693
694     // Typedef for header option vector
695     // OCHeaderOption class is in HeaderOption namespace
696     typedef std::vector<HeaderOption::OCHeaderOption> HeaderOptions;
697
698     // Typedef for query parameter map
699     typedef std::map<std::string, std::string> QueryParamsMap;
700
701     // Typedef for list of observation IDs
702     typedef std::vector<OCObservationId> ObservationIds;
703
704     enum class ObserveAction
705     {
706         ObserveRegister,
707         ObserveUnregister
708     };
709
710     typedef struct
711     {
712         // Action associated with observation request
713         ObserveAction action;
714         // Identifier for observation being registered/unregistered
715         OCObservationId obsId;
716     } ObservationInfo;
717
718     // const strings for different interfaces
719
720     // Default interface
721     const std::string DEFAULT_INTERFACE = "oc.mi.def";
722
723     // Used in discovering (GET) links to other resources of a collection.
724     const std::string LINK_INTERFACE = "oc.mi.ll";
725
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";
728
729     typedef std::function<void(std::shared_ptr<OCResource>)> FindCallback;
730
731     typedef std::function<OCEntityHandlerResult (const std::shared_ptr<OCResourceRequest>,
732                                 const std::shared_ptr<OCResourceResponse>)> EntityHandler;
733
734     typedef std::function<void(OCStackResult, const unsigned int)> SubscribeCallback;
735
736     typedef std::function<void(const HeaderOptions&,
737                                 const OCRepresentation&, const int)> GetCallback;
738
739     typedef std::function<void(const HeaderOptions&,
740                                 const OCRepresentation&, const int)> PostCallback;
741
742     typedef std::function<void(const HeaderOptions&,
743                                 const OCRepresentation&, const int)> PutCallback;
744
745     typedef std::function<void(const HeaderOptions&, const int)> DeleteCallback;
746
747     typedef std::function<void(const HeaderOptions&,
748                                 const OCRepresentation&, const int, const int)> ObserveCallback;
749 } // namespace OC
750
751 #endif