Updated C++ SDK for discovering secure resources
[platform/upstream/iotivity.git] / resource / include / OCSerialization.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 #include <cereal/cereal.hpp>
22 #include <cereal/types/memory.hpp>
23 #include <cereal/types/vector.hpp>
24 #include <cereal/archives/json.hpp>
25
26 #include <StringConstants.h>
27
28 namespace OC
29 {
30     class ListenOCContainer
31     {
32         private:
33         enum class OCSecureType
34         {
35             NotSecure,
36             Secure
37         };
38
39         class ListenResourceContainer
40         {
41             class ListenResourcePolicyContainer
42             {
43                 friend class cereal::access;
44                 friend class ListenResourceContainer;
45                 friend class ListenResourcePropertiesContainer;
46
47                 template<class Archive>
48                 void serialize(Archive& ar)
49                 {
50                     try
51                     {
52                         m_observable = false;
53                         ar(cereal::make_nvp(OC::Key::BMKEY, m_bm));
54                         // In case of observable
55                         if(m_bm & OC_OBSERVABLE)
56                         {
57                             m_observable = true;
58                         }
59                     }
60                     catch(cereal::Exception&)
61                     {
62                         ar.setNextName(nullptr);
63                     }
64                     try
65                     {
66                         m_secure = false;
67                         int secureTemp;
68                         ar(cereal::make_nvp(OC::Key::SECUREKEY, secureTemp));
69                         m_secure = secureTemp != 0;
70
71                         m_port = -1;
72                         ar(cereal::make_nvp(OC::Key::PORTKEY, m_port));
73                     }
74                     catch(cereal::Exception&)
75                     {
76                        ar.setNextName(nullptr);
77                     }
78
79                  }
80
81                  bool m_observable;
82                  uint8_t m_bm;
83                  bool m_secure;
84                  int m_port;
85             };
86
87             class ListenResourcePropertiesContainer
88             {
89                 friend class cereal::access;
90                 friend class ListenResourceContainer;
91
92                 template<class Archive>
93                 void serialize(Archive& ar)
94                 {
95                     try
96                     {
97                         ar(cereal::make_nvp(OC::Key::POLICYKEY, m_policy));
98
99                     }
100                     catch(cereal::Exception&)
101                     {
102                         // we swallow this exception, since it means the key
103                         // doesn't exist, allowing these to be optional
104                         oclog() << "Invalid POLICYKEY"<<std::flush;
105                         ar.setNextName(nullptr);
106                     }
107
108                     try
109                     {
110                         ar(cereal::make_nvp(OC::Key::RESOURCETYPESKEY,m_resourceTypes));
111                     }
112                     catch(cereal::Exception&)
113                     {
114                         ar.setNextName(nullptr);
115                     }
116                     try
117                     {
118                         ar(cereal::make_nvp(OC::Key::INTERFACESKEY, m_interfaces));
119                     }
120                     catch(cereal::Exception&)
121                     {
122                         ar.setNextName(nullptr);
123                     }
124                 }
125
126                 std::vector<std::string> m_resourceTypes;
127                 std::vector<std::string> m_interfaces;
128                 ListenResourcePolicyContainer m_policy;
129             };
130
131             public:
132             ListenResourceContainer() : m_loaded(false)
133             {}
134
135             private:
136             friend class cereal::access;
137             friend class ListenOCContainer;
138
139             template <class Archive>
140             void serialize(Archive& ar)
141             {
142                 try
143                 {
144                     ar(cereal::make_nvp(OC::Key::URIKEY, m_uri));
145                     m_loaded=true;
146                 }
147                 catch(cereal::Exception&)
148                 {
149                     ar.setNextName(nullptr);
150                 }
151                 try
152                 {
153                     ar(cereal::make_nvp(OC::Key::SERVERIDKEY, m_serverId));
154                     m_loaded=true;
155                 }
156                 catch(cereal::Exception&)
157                 {
158                     ar.setNextName(nullptr);
159                 }
160                 try
161                 {
162                     ar(cereal::make_nvp(OC::Key::PROPERTYKEY, m_props));
163                     m_loaded=true;
164                 }
165                 catch(cereal::Exception&)
166                 {
167                     ar.setNextName(nullptr);
168                 }
169
170             }
171
172             std::string m_uri;
173             std::string m_serverId;
174             bool m_loaded;
175             ListenResourcePropertiesContainer m_props;
176
177             bool loaded() const
178             {
179                 return m_loaded;
180             }
181
182             bool observable() const
183             {
184                 return m_props.m_policy.m_observable;
185             }
186
187             OCSecureType secureType() const
188             {
189                 return m_props.m_policy.m_secure ? OCSecureType::Secure : OCSecureType::NotSecure;
190             }
191
192             int port() const
193             {
194                 return m_props.m_policy.m_port;
195             }
196
197             std::vector<std::string> resourceTypes() const
198             {
199                 return m_props.m_resourceTypes;
200             }
201
202             std::vector<std::string> interfaces() const
203             {
204                 return m_props.m_interfaces;
205             }
206         };
207
208         private:
209             friend class cereal::access;
210             template <class Archive>
211             void serialize(Archive& ar)
212             {
213                 std::vector<ListenResourceContainer> resources;
214                 ar(resources);
215             }
216         public:
217             ListenOCContainer(std::weak_ptr<IClientWrapper> cw,
218                     const OCDevAddr& devAddr, std::stringstream& json)
219                     : m_clientWrapper(cw), m_devAddr(devAddr)
220             {
221                 LoadFromJson(json);
222             }
223
224             const std::vector<std::shared_ptr<OCResource>>& Resources() const
225             {
226                 return m_resources;
227             }
228
229         private:
230             void LoadFromJson(std::stringstream& json)
231             {
232                 cereal::JSONInputArchive archive(json);
233
234                 std::vector<ListenResourceContainer> resources;
235                 archive(cereal::make_nvp(OC::Key::OCKEY, resources));
236
237                 m_resources.clear();
238
239                 for(const auto& res : resources)
240                 {
241                     try
242                     {
243                         if(res.loaded())
244                         {
245                             if (res.secureType() == OCSecureType::Secure)
246                             {
247                                 m_devAddr.flags =
248                                     (OCTransportFlags)(OC_FLAG_SECURE | m_devAddr.flags);
249                             }
250                             if (res.port() != -1)
251                             {
252                                 m_devAddr.port = res.port();
253                             }
254                             m_resources.push_back(std::shared_ptr<OCResource>(
255                                 new OCResource(m_clientWrapper, m_devAddr,
256                                     res.m_uri, res.m_serverId, res.observable(),
257                                     res.resourceTypes(), res.interfaces())));
258                         }
259
260                     }
261                     catch(ResourceInitException& e)
262                     {
263                         oclog() << "listenCallback(): failed to create resource: " << e.what()
264                                 << std::flush;
265                     }
266                 }
267             }
268             std::vector<std::shared_ptr<OC::OCResource>> m_resources;
269             std::weak_ptr<IClientWrapper> m_clientWrapper;
270             OCDevAddr m_devAddr;
271     };
272 }