Merge 'security-basecamp' branch into master with CBOR
[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 <StringConstants.h>
22 #include "ocpayload.h"
23 #include "ocrandom.h"
24
25 namespace OC
26 {
27     class ListenOCContainer
28     {
29         private:
30             static std::vector<std::string> StringLLToVector(OCStringLL* ll)
31             {
32                 std::vector<std::string> strs;
33                 while(ll)
34                 {
35                     strs.push_back(ll->value);
36                     ll = ll->next;
37                 }
38                 return strs;
39             }
40
41         public:
42             ListenOCContainer(std::weak_ptr<IClientWrapper> cw,
43                     OCDevAddr& devAddr, OCDiscoveryPayload* payload)
44                     : m_clientWrapper(cw), m_devAddr(devAddr)
45             {
46                 OCResourcePayload* res = payload->resources;
47
48                 while(res)
49                 {
50                     char uuidString[UUID_STRING_SIZE];
51                     if(OCConvertUuidToString(res->sid, uuidString) != RAND_UUID_OK)
52                     {
53                         uuidString[0]= '\0';
54                     }
55
56                     if (res->secure)
57                     {
58                         m_devAddr.flags =
59                               (OCTransportFlags)(OC_FLAG_SECURE | m_devAddr.flags);
60                     }
61  
62                     if (res->port != 0)
63                     {
64                          m_devAddr.port = res->port;
65                     }
66
67                     m_resources.push_back(std::shared_ptr<OC::OCResource>(
68                                 new OC::OCResource(m_clientWrapper, m_devAddr,
69                                     std::string(res->uri),
70                                     std::string(uuidString),
71                                     (res->bitmap & OC_OBSERVABLE) == OC_OBSERVABLE,
72                                     StringLLToVector(res->types),
73                                     StringLLToVector(res->interfaces)
74                                     )));
75                     res = res->next;
76                 }
77
78             }
79
80             const std::vector<std::shared_ptr<OCResource>>& Resources() const
81             {
82                 return m_resources;
83             }
84         private:
85             std::vector<std::shared_ptr<OC::OCResource>> m_resources;
86             std::weak_ptr<IClientWrapper> m_clientWrapper;
87             OCDevAddr& m_devAddr;
88     };
89     /*
90     class ListenOCContainer
91     {
92         private:
93         enum class OCSecureType
94         {
95             NotSecure,
96             Secure
97         };
98
99         class DiscoveredResources
100         {
101             class Resource
102             {
103                 friend class cereal::access;
104
105                 class ResourcePolicy
106                 {
107                     friend class cereal::access;
108                     friend class Resource;
109
110                     template<class Archive>
111                     void serialize(Archive& ar)
112                     {
113                         try
114                         {
115                             m_observable = false;
116                             ar(cereal::make_nvp(OC::Key::BMKEY, m_bm));
117
118                             if(m_bm & OC_OBSERVABLE)
119                             {
120                                 m_observable = true;
121                             }
122                         }
123                         catch(cereal::Exception&)
124                         {
125                             ar.setNextName(nullptr);
126                         }
127
128                         try
129                         {
130                             m_secure = false;
131                             int secureTemp;
132                             ar(cereal::make_nvp(OC::Key::SECUREKEY, secureTemp));
133                             m_secure = secureTemp != 0;
134
135                             m_port = -1;
136                             ar(cereal::make_nvp(OC::Key::PORTKEY, m_port));
137                         }
138                         catch(cereal::Exception&)
139                         {
140                             ar.setNextName(nullptr);
141                         }
142                      }
143
144                      bool m_observable;
145                      uint8_t m_bm;
146                      bool m_secure;
147                      int m_port;
148                 };
149
150                 template <class Archive>
151                 void serialize(Archive& ar)
152                 {
153                     try
154                     {
155                         ar(cereal::make_nvp(OC::Key::URIKEY, m_uri));
156                         m_loaded = true;
157                     }
158                     catch(cereal::Exception&)
159                     {
160                         ar.setNextName(nullptr);
161                     }
162
163                     try
164                     {
165                         ar(cereal::make_nvp(OC::Key::RESOURCETYPESKEY,m_resourceTypes));
166                         m_loaded = true;
167                     }
168                     catch(cereal::Exception&)
169                     {
170                         ar.setNextName(nullptr);
171                     }
172
173                     try
174                     {
175                         ar(cereal::make_nvp(OC::Key::INTERFACESKEY, m_interfaces));
176                         m_loaded = true;
177                     }
178                     catch(cereal::Exception&)
179                     {
180                         ar.setNextName(nullptr);
181                     }
182
183                     try
184                     {
185                         ar(cereal::make_nvp(OC::Key::POLICYKEY, m_policy));
186                         m_loaded = true;
187                     }
188                     catch(cereal::Exception&)
189                     {
190                         ar.setNextName(nullptr);
191                     }
192
193                     // Although not expected, a server id as part of a resource's own
194                     // representation is legal. It may be used if needed.
195                     try
196                     {
197                         ar(cereal::make_nvp(OC::Key::DEVICEIDKEY, m_serverId));
198                         m_loaded = true;
199                     }
200                     catch(cereal::Exception&)
201                     {
202                         ar.setNextName(nullptr);
203                     }
204                 }
205             public:
206                 Resource(): m_loaded(false)
207                 {}
208
209                 bool observable() const
210                 {
211                     return m_policy.m_observable;
212                 }
213
214                 OCSecureType secureType() const
215                 {
216                     return m_policy.m_secure ? OCSecureType::Secure : OCSecureType::NotSecure;
217                 }
218
219                 int port() const
220                 {
221                     return m_policy.m_port;
222                 }
223
224                 std::vector<std::string> resourceTypes() const
225                 {
226                     return m_resourceTypes;
227                 }
228
229                 std::vector<std::string> interfaces() const
230                 {
231                     return m_interfaces;
232                 }
233
234                 bool loaded() const{
235                     return m_loaded;
236                 }
237
238                 std::string m_uri;
239                 std::string m_serverId;
240                 std::vector<std::string> m_resourceTypes;
241                 std::vector<std::string> m_interfaces;
242                 ResourcePolicy m_policy;
243                 bool m_loaded;
244             };
245
246             public:
247             DiscoveredResources()
248             {}
249
250             private:
251             friend class cereal::access;
252             friend class ListenOCContainer;
253
254             template <class Archive>
255             void serialize(Archive& ar)
256             {
257                 try
258                 {
259                     ar(cereal::make_nvp(OC::Key::DEVICEIDKEY, m_serverIdOfThisDevice));
260                 }
261                 catch(cereal::Exception&) { ar.setNextName(nullptr); }
262
263                 try
264                 {
265                     ar(cereal::make_nvp(OC::Key::LINKS, resources));
266                 }
267                 catch(cereal::Exception&) { ar.setNextName(nullptr); }
268             }
269
270             std::string m_serverIdOfThisDevice;
271             std::vector<Resource> resources;
272         };
273
274         private:
275             friend class cereal::access;
276             template <class Archive>
277             void serialize(Archive& ar)
278             {
279                 std::vector<DiscoveredResources> resources;
280                 ar(resources);
281             }
282         public:
283             ListenOCContainer(std::weak_ptr<IClientWrapper> cw,
284                     const OCDevAddr& devAddr, std::stringstream& json)
285                     : m_clientWrapper(cw), m_devAddr(devAddr)
286
287             {
288                 LoadFromJson(json);
289             }
290
291             const std::vector<std::shared_ptr<OCResource>>& Resources() const
292             {
293                 return m_resources;
294             }
295
296         private:
297             void LoadFromJson(std::stringstream& json)
298             {
299                 cereal::JSONInputArchive archive(json);
300
301                 std::vector<DiscoveredResources> resources;
302                 archive(cereal::make_nvp(OC::Key::OCKEY, resources));
303
304                 m_resources.clear();
305
306                 for(const auto& resourcesAtDevice : resources)
307                 {
308                     std::string serverIDForThisResourceRep = resourcesAtDevice.m_serverIdOfThisDevice;
309
310                     for (const auto& resource : resourcesAtDevice.resources)
311                     {
312                         try
313                         {
314                             if(resource.loaded())
315                             {
316                                 m_resources.push_back(std::shared_ptr<OCResource>
317                                 (
318                                     new OCResource
319                                     (
320                                         m_clientWrapper,
321                                         m_devAddr,
322                                         resource.m_uri,
323                                         serverIDForThisResourceRep,
324                                         resource.observable(),
325                                         resource.resourceTypes(),
326                                         resource.interfaces()
327                                     )
328                                 ));
329                             }
330                         }
331                         catch(ResourceInitException& e)
332                         {
333                             oclog() << "listenCallback(): failed to create resource: " << e.what()
334                                     << std::flush;
335                         }
336                     }
337                 }
338             }
339     };
340 */
341 }