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