Parsing about a payload including resource information of multiple devices
[platform/upstream/iotivity.git] / resource / include / OCSerialization.h
index 8ab3426..f037213 100644 (file)
 //
 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
 
-#include <cereal/cereal.hpp>
-#include <cereal/types/memory.hpp>
-#include <cereal/types/vector.hpp>
-#include <cereal/archives/json.hpp>
-
 #include <StringConstants.h>
+#include "ocpayload.h"
+#include "ocrandom.h"
+#include "oic_string.h"
 
 namespace OC
 {
     class ListenOCContainer
     {
         private:
-        enum class OCSecureType
-        {
-            IPv4Secure,
-            IPv4
-        };
-
-        class ListenResourceContainer
-        {
-            class ListenResourcePropertiesContainer
-            {
-                friend class cereal::access;
-                friend class ListenResourceContainer;
-
-                template<class Archive>
-                void serialize(Archive& ar)
-                {
-                    try
-                    {
-                        m_observable=false;
-                        int obsTemp;
-                        ar(cereal::make_nvp(OC::Key::OBSERVABLEKEY, obsTemp));
-                        m_observable = obsTemp != 0;
-                    }
-                    catch(cereal::Exception&)
-                    {
-                        // we swallow this exception, since it means the key
-                        // doesn't exist, allowing these to be optional
-                        ar.setNextName(nullptr);
-                    }
-
-                    try
-                    {
-                        m_secure = false;
-                        int secureTemp;
-                        ar(cereal::make_nvp(OC::Key::SECUREKEY, secureTemp));
-                        m_secure = secureTemp != 0;
-
-                        m_port = -1;
-                        ar(cereal::make_nvp(OC::Key::PORTKEY, m_port));
-                    }
-                    catch(cereal::Exception&)
-                    {
-                        ar.setNextName(nullptr);
-                    }
-
-                    try
-                    {
-                        ar(cereal::make_nvp(OC::Key::RESOURCETYPESKEY,m_resourceTypes));
-                    }
-                    catch(cereal::Exception&)
-                    {
-                        ar.setNextName(nullptr);
-                    }
-                    try
-                    {
-                        ar(cereal::make_nvp(OC::Key::INTERFACESKEY, m_interfaces));
-                    }
-                    catch(cereal::Exception&)
-                    {
-                        ar.setNextName(nullptr);
-                    }
-                }
-
-                bool m_observable;
-                std::vector<std::string> m_resourceTypes;
-                std::vector<std::string> m_interfaces;
-                bool m_secure;
-                int m_port;
-            };
-
-            public:
-            ListenResourceContainer() : m_loaded(false)
-            {}
-
-            private:
-            friend class cereal::access;
-            friend class ListenOCContainer;
-
-            template <class Archive>
-            void serialize(Archive& ar)
+            static std::vector<std::string> StringLLToVector(OCStringLL* ll)
             {
-                try
+                std::vector<std::string> strs;
+                while(ll)
                 {
-                    ar(cereal::make_nvp(OC::Key::URIKEY, m_uri));
-                    m_loaded=true;
+                    strs.push_back(ll->value);
+                    ll = ll->next;
                 }
-                catch(cereal::Exception&)
-                {
-                    ar.setNextName(nullptr);
-                }
-                try
-                {
-                    ar(cereal::make_nvp(OC::Key::SERVERIDKEY, m_serverId));
-                    m_loaded=true;
-                }
-                catch(cereal::Exception&)
-                {
-                    ar.setNextName(nullptr);
-                }
-                try
-                {
-                    ar(cereal::make_nvp(OC::Key::PROPERTYKEY, m_props));
-                    m_loaded=true;
-                }
-                catch(cereal::Exception&)
-                {
-                    ar.setNextName(nullptr);
-                }
-            }
-
-
-            std::string m_uri;
-            std::string m_serverId;
-            bool m_loaded;
-            ListenResourcePropertiesContainer m_props;
-
-            bool loaded() const
-            {
-                return m_loaded;
-            }
-
-            bool observable() const
-            {
-                return m_props.m_observable;
-            }
-
-            OCSecureType secureType() const
-            {
-                return m_props.m_secure?OCSecureType::IPv4Secure :OCSecureType::IPv4;
-            }
-
-            int port() const
-            {
-                return m_props.m_port;
-            }
-
-            std::vector<std::string> resourceTypes() const
-            {
-                return m_props.m_resourceTypes;
-            }
-
-            std::vector<std::string> interfaces() const
-            {
-                return m_props.m_interfaces;
+                return strs;
             }
-        };
 
-        private:
-            friend class cereal::access;
-            template <class Archive>
-            void serialize(Archive& ar)
-            {
-                std::vector<ListenResourceContainer> resources;
-                ar(resources);
-            }
         public:
-#ifdef CA_INT
-            ListenOCContainer(std::weak_ptr<IClientWrapper> cw, const OCDevAddr& address,
-                    OCConnectivityType connectivityType, std::stringstream& json):
-                m_clientWrapper(cw), m_address(address), m_connectivityType(connectivityType)
-#else
-            ListenOCContainer(std::weak_ptr<IClientWrapper> cw, const OCDevAddr& address,
-                    std::stringstream& json):
-                m_clientWrapper(cw), m_address(address)
-#endif
-            {
-                LoadFromJson(json);
-            }
-
-            const std::vector<std::shared_ptr<OCResource>>& Resources() const
-            {
-                return m_resources;
-            }
-
-        private:
-            std::string ConvertOCAddrToString(OCSecureType sec, int secureport)
-            {
-                char stringAddress[DEV_ADDR_SIZE_MAX];
-                uint16_t port;
-
-                ostringstream os;
-
-                if(sec== OCSecureType::IPv4)
-                {
-                    os<<"coap://";
-                }
-                else if(sec == OCSecureType::IPv4Secure)
-                {
-                    os<<"coaps://";
-                }
-                else
-                {
-                    oclog() << "ConvertOCAddrToString():  invalid SecureType"<<std::flush;
-                    throw ResourceInitException(false, false, false, false, false, true);
-                }
-
-                if(0== OCDevAddrToString(&m_address, stringAddress))
-                {
-                    // nothing to do, successful case.
-                }
-                else
-                {
-                    oclog() << "ConvertOCAddrToString(): Invalid Ip"
-                            << std::flush;
-                    throw ResourceInitException(false, false, false, false, false, true);
-                }
-
-                os<<stringAddress;
-
-                if(sec == OCSecureType::IPv4Secure && secureport>0 && secureport<=65535)
-                {
-                    port = static_cast<uint16_t>(secureport);
-                }
-                else if(sec == OCSecureType::IPv4 && 0==OCDevAddrToPort(&m_address, &port))
-                {
-                    // nothing to do, this is a successful case
-                }
-                else
-                {
-                    oclog() << "ConvertOCAddrToString() : Invalid Port"
-                            <<std::flush;
-                    throw ResourceInitException(false, false, false, false, true, false);
-                }
-
-                os <<":"<< static_cast<int>(port);
-
-                return os.str();
-            }
-
-            void LoadFromJson(std::stringstream& json)
+            ListenOCContainer(std::weak_ptr<IClientWrapper> cw,
+                    OCDevAddr& devAddr, OCDiscoveryPayload* payload)
+                    : m_clientWrapper(cw), m_devAddr(devAddr)
             {
-                cereal::JSONInputArchive archive(json);
-
-                std::vector<ListenResourceContainer> resources;
-                archive(cereal::make_nvp(OC::Key::OCKEY, resources));
-
-                m_resources.clear();
-
-                for(const auto& res : resources)
+                while (payload)
                 {
-                    try
+                    OCResourcePayload* res = payload->resources;
+                    while (res)
                     {
-                        if(res.loaded())
+                        if (res->secure)
                         {
-#ifdef CA_INT
-                            m_resources.push_back(std::shared_ptr<OCResource>(
-                                new OCResource(m_clientWrapper,
-                                    ConvertOCAddrToString(res.secureType(),res.port()),
-                                    res.m_uri, res.m_serverId, m_connectivityType, res.observable(),
-                                    res.resourceTypes(), res.interfaces())));
-#else
-                            m_resources.push_back(std::shared_ptr<OCResource>(
-                                new OCResource(m_clientWrapper,
-                                    ConvertOCAddrToString(res.secureType(),res.port()),
-                                    res.m_uri, res.m_serverId, res.observable(),
-                                    res.resourceTypes(), res.interfaces())));
-#endif
+                            m_devAddr.flags =
+                                  (OCTransportFlags)(OC_FLAG_SECURE | m_devAddr.flags);
                         }
 
+                        if (res->port != 0)
+                        {
+                             m_devAddr.port = res->port;
+                        }
+                        if (payload->baseURI)
+                        {
+                            OCDevAddr rdPubAddr = m_devAddr;
+                            OICStrcpy(rdPubAddr.addr, sizeof(rdPubAddr.addr), payload->baseURI);
+                            rdPubAddr.port = res->port;
+                            m_resources.push_back(std::shared_ptr<OC::OCResource>(
+                                        new OC::OCResource(m_clientWrapper, rdPubAddr,
+                                            std::string(res->uri),
+                                            std::string(payload->sid),
+                                            (res->bitmap & OC_OBSERVABLE) == OC_OBSERVABLE,
+                                            StringLLToVector(res->types),
+                                            StringLLToVector(res->interfaces)
+                                            )));
+                        }
+                        else
+                        {
+                            m_resources.push_back(std::shared_ptr<OC::OCResource>(
+                                    new OC::OCResource(m_clientWrapper, m_devAddr,
+                                        std::string(res->uri),
+                                        std::string(payload->sid),
+                                        (res->bitmap & OC_OBSERVABLE) == OC_OBSERVABLE,
+                                        StringLLToVector(res->types),
+                                        StringLLToVector(res->interfaces)
+                                        )));
+
+#ifdef TCP_ADAPTER
+                            if (res->tcpPort != 0)
+                            {
+                                OCDevAddr tcpDevAddr = m_devAddr;
+                                tcpDevAddr.port = res->tcpPort;
+                                tcpDevAddr.adapter = OC_ADAPTER_TCP;
+                                m_resources.push_back(std::shared_ptr<OC::OCResource>(
+                                            new OC::OCResource(m_clientWrapper, tcpDevAddr,
+                                                std::string(res->uri),
+                                                std::string(payload->sid),
+                                                (res->bitmap & OC_OBSERVABLE) == OC_OBSERVABLE,
+                                                StringLLToVector(res->types),
+                                                StringLLToVector(res->interfaces)
+                                                )));
+                            }
+#endif
+                        }
+                        res = res->next;
                     }
-                    catch(ResourceInitException& e)
-                    {
-                        oclog() << "listenCallback(): failed to create resource: " << e.what()
-                                << std::flush;
-                    }
+                    payload = payload->next;
                 }
             }
+
+            const std::vector<std::shared_ptr<OCResource>>& Resources() const
+            {
+                return m_resources;
+            }
+        private:
             std::vector<std::shared_ptr<OC::OCResource>> m_resources;
             std::weak_ptr<IClientWrapper> m_clientWrapper;
-            OCDevAddr m_address;
-            OCConnectivityType m_connectivityType;
+            OCDevAddr& m_devAddr;
     };
 }