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