//
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-#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;
+ return strs;
}
- bool observable() const
+ public:
+ ListenOCContainer(std::weak_ptr<IClientWrapper> cw,
+ OCDevAddr& devAddr, OCDiscoveryPayload* payload)
+ : m_clientWrapper(cw), m_devAddr(devAddr)
{
- return m_props.m_observable;
- }
+ while (payload)
+ {
+ OCResourcePayload* res = payload->resources;
+ while (res)
+ {
+ if (res->secure)
+ {
+ m_devAddr.flags =
+ (OCTransportFlags)(OC_FLAG_SECURE | m_devAddr.flags);
+ }
- OCSecureType secureType() const
- {
- return m_props.m_secure?OCSecureType::IPv4Secure :OCSecureType::IPv4;
- }
+ if (res->port != 0)
+ {
+ m_devAddr.port = res->port;
+ }
- int port() const
- {
- return m_props.m_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,
+ 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,
+ 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,
+ StringLLToVector(res->types),
+ StringLLToVector(res->interfaces)
+ )));
+ }
+#endif
+ }
+ res = res->next;
+ }
+ payload = payload->next;
+ }
}
- std::vector<std::string> resourceTypes() const
+#ifdef WITH_MQ
+ ListenOCContainer(std::weak_ptr<IClientWrapper> cw,
+ OCDevAddr& devAddr, OCRepPayload* payload)
+ : m_clientWrapper(cw), m_devAddr(devAddr)
{
- return m_props.m_resourceTypes;
- }
+ if (payload)
+ {
+ char**topicList = nullptr;
+ size_t dimensions[MAX_REP_ARRAY_DEPTH] = {0};
+ OCRepPayloadGetStringArray(payload, "topiclist", &topicList, dimensions);
- std::vector<std::string> interfaces() const
- {
- return m_props.m_interfaces;
+ for(size_t idx = 0; idx < dimensions[0]; idx++)
+ {
+ m_resources.push_back(std::shared_ptr<OC::OCResource>(
+ new OC::OCResource(m_clientWrapper, m_devAddr,
+ std::string(topicList[idx]),
+ "",
+ OC_OBSERVABLE,
+ {OC_RSRVD_RESOURCE_TYPE_MQ_TOPIC},
+ {DEFAULT_INTERFACE})));
+ }
+ }
}
- };
- private:
- friend class cereal::access;
- template <class Archive>
- void serialize(Archive& ar)
+ ListenOCContainer(std::weak_ptr<IClientWrapper> cw,
+ OCDevAddr& devAddr, const std::string& topicUri)
+ : m_clientWrapper(cw), m_devAddr(devAddr)
{
- std::vector<ListenResourceContainer> resources;
- ar(resources);
- }
- public:
- ListenOCContainer(std::weak_ptr<IClientWrapper> cw, const OCDevAddr& address,
- std::stringstream& json):
- m_clientWrapper(cw), m_address(address)
- {
- LoadFromJson(json);
+ m_resources.push_back(std::shared_ptr<OC::OCResource>(
+ new OC::OCResource(m_clientWrapper, m_devAddr,
+ topicUri,
+ "",
+ OC_OBSERVABLE,
+ {OC_RSRVD_RESOURCE_TYPE_MQ_TOPIC},
+ {DEFAULT_INTERFACE})));
}
+#endif
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)
- {
- cereal::JSONInputArchive archive(json);
-
- std::vector<ListenResourceContainer> resources;
- archive(cereal::make_nvp(OC::Key::OCKEY, resources));
-
- m_resources.clear();
-
- for(const auto& res : resources)
- {
- try
- {
- if(res.loaded())
- {
-#ifdef CA_INT
- //CA_TODO: To get the connectivity type correctly.
- uint8_t connectivityType;
- m_resources.push_back(std::shared_ptr<OCResource>(
- new OCResource(m_clientWrapper,
- ConvertOCAddrToString(res.secureType(),res.port()),
- res.m_uri, res.m_serverId, 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
- }
-
- }
- catch(ResourceInitException& e)
- {
- oclog() << "listenCallback(): failed to create resource: " << e.what()
- << std::flush;
- }
- }
- }
std::vector<std::shared_ptr<OC::OCResource>> m_resources;
std::weak_ptr<IClientWrapper> m_clientWrapper;
- OCDevAddr m_address;
+ OCDevAddr& m_devAddr;
};
}