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