X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=resource%2Fsrc%2FOCResource.cpp;h=0728df0430cd25a537d82f3c64e28f47b1d7f23c;hb=c315c87e07c4080ecd0ef488e7a1047bc3c509b2;hp=b381b9f7d597c33f1a1d88430cd89244e8a8484f;hpb=81955e9c075c87e751a24e9187c0fd6dcde4e864;p=platform%2Fupstream%2Fiotivity.git diff --git a/resource/src/OCResource.cpp b/resource/src/OCResource.cpp index b381b9f..0728df0 100644 --- a/resource/src/OCResource.cpp +++ b/resource/src/OCResource.cpp @@ -18,6 +18,7 @@ // //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +#include "iotivity_config.h" #include "OCResource.h" #include "OCUtilities.h" @@ -32,12 +33,16 @@ #ifdef HAVE_IN6ADDR_H #include #endif +#include "ocstack.h" namespace OC { static const char COAP[] = "coap://"; static const char COAPS[] = "coaps://"; static const char COAP_TCP[] = "coap+tcp://"; +static const char COAPS_TCP[] = "coaps+tcp://"; +static const char COAP_GATT[] = "coap+gatt://"; +static const char COAP_RFCOMM[] = "coap+rfcomm://"; using OC::nil_guard; using OC::result_guard; @@ -45,14 +50,15 @@ using OC::checked_guard; OCResource::OCResource(std::weak_ptr clientWrapper, const OCDevAddr& devAddr, const std::string& uri, - const std::string& serverId, bool observable, + const std::string& serverId, uint8_t property, const std::vector& resourceTypes, - const std::vector& interfaces) + const std::vector& interfaces, + const std::string& deviceName) : m_clientWrapper(clientWrapper), m_uri(uri), m_resourceId(serverId, m_uri), m_devAddr(devAddr), - m_isObservable(observable), m_isCollection(false), + m_isCollection(false), m_property(property), m_resourceTypes(resourceTypes), m_interfaces(interfaces), - m_observeHandle(nullptr) + m_observeHandle(nullptr), m_deviceName(deviceName) { m_isCollection = std::find(m_interfaces.begin(), m_interfaces.end(), LINK_INTERFACE) != m_interfaces.end(); @@ -62,28 +68,29 @@ OCResource::OCResource(std::weak_ptr clientWrapper, interfaces.empty()|| m_clientWrapper.expired()) { - throw ResourceInitException(m_uri.empty(), resourceTypes.empty(), - interfaces.empty(), m_clientWrapper.expired(), false, false); + throw ResourceInitException(m_uri.empty(), false, resourceTypes.empty(), + interfaces.empty(), m_clientWrapper.expired(), false, false, false); } } OCResource::OCResource(std::weak_ptr clientWrapper, const std::string& host, const std::string& uri, const std::string& serverId, - OCConnectivityType connectivityType, bool observable, + OCConnectivityType connectivityType, uint8_t property, const std::vector& resourceTypes, - const std::vector& interfaces) + const std::vector& interfaces, + const std::string& deviceName) : m_clientWrapper(clientWrapper), m_uri(uri), m_resourceId(serverId, m_uri), - m_isObservable(observable), m_isCollection(false), + m_isCollection(false), m_property(property), m_resourceTypes(resourceTypes), m_interfaces(interfaces), - m_observeHandle(nullptr) + m_observeHandle(nullptr), m_deviceName(deviceName) { m_devAddr = OCDevAddr{OC_DEFAULT_ADAPTER, OC_DEFAULT_FLAGS, 0, {0}, 0, #if defined (ROUTING_GATEWAY) || defined (ROUTING_EP) - {0} + {0}, #endif - }; + {0}}; m_isCollection = std::find(m_interfaces.begin(), m_interfaces.end(), LINK_INTERFACE) != m_interfaces.end(); @@ -92,20 +99,20 @@ OCResource::OCResource(std::weak_ptr clientWrapper, interfaces.empty()|| m_clientWrapper.expired()) { - throw ResourceInitException(m_uri.empty(), resourceTypes.empty(), - interfaces.empty(), m_clientWrapper.expired(), false, false); + throw ResourceInitException(m_uri.empty(), false, resourceTypes.empty(), + interfaces.empty(), m_clientWrapper.expired(), false, false, false); } if (uri.length() == 1 && uri[0] == '/') { - throw ResourceInitException(m_uri.empty(), resourceTypes.empty(), - interfaces.empty(), m_clientWrapper.expired(), false, false); + throw ResourceInitException(m_uri.empty(), true, resourceTypes.empty(), + interfaces.empty(), m_clientWrapper.expired(), false, false, false); } if (uri[0] != '/') { - throw ResourceInitException(m_uri.empty(), resourceTypes.empty(), - interfaces.empty(), m_clientWrapper.expired(), false, false); + throw ResourceInitException(m_uri.empty(), true, resourceTypes.empty(), + interfaces.empty(), m_clientWrapper.expired(), false, false, false); } // construct the devAddr from the pieces we have @@ -123,47 +130,66 @@ void OCResource::setHost(const std::string& host) { size_t prefix_len; - if(host.compare(0, sizeof(COAP) - 1, COAP) == 0) + if (host.compare(0, sizeof(COAP) - 1, COAP) == 0) { prefix_len = sizeof(COAP) - 1; } - else if(host.compare(0, sizeof(COAPS) - 1, COAPS) == 0) + else if (host.compare(0, sizeof(COAPS) - 1, COAPS) == 0) { prefix_len = sizeof(COAPS) - 1; - m_devAddr.flags = static_cast(m_devAddr.flags & OC_SECURE); + m_devAddr.flags = static_cast(m_devAddr.flags | OC_SECURE); } else if (host.compare(0, sizeof(COAP_TCP) - 1, COAP_TCP) == 0) { prefix_len = sizeof(COAP_TCP) - 1; } + else if (host.compare(0, sizeof(COAPS_TCP) - 1, COAPS_TCP) == 0) + { + prefix_len = sizeof(COAPS_TCP) - 1; + m_devAddr.flags = static_cast(m_devAddr.flags | OC_SECURE); + } + else if (host.compare(0, sizeof(COAP_GATT) - 1, COAP_GATT) == 0) + { + prefix_len = sizeof(COAP_GATT) - 1; + } + else if (host.compare(0, sizeof(COAP_RFCOMM) - 1, COAP_RFCOMM) == 0) + { + prefix_len = sizeof(COAP_RFCOMM) - 1; + } else { - throw ResourceInitException(m_uri.empty(), m_resourceTypes.empty(), - m_interfaces.empty(), m_clientWrapper.expired(), false, false); + throw ResourceInitException(m_uri.empty(), false, m_resourceTypes.empty(), + m_interfaces.empty(), m_clientWrapper.expired(), false, false, true); } - // remove 'coap://' or 'coaps://' or 'coap+tcp://' + // remove 'coap://' or 'coaps://' or 'coap+tcp://' or 'coap+gatt://' or 'coap+rfcomm://' std::string host_token = host.substr(prefix_len); - if(host_token[0] == '[') // IPv6 + if (host_token[0] == '[') // IPv6 { size_t bracket = host_token.find(']'); - if(bracket == std::string::npos || bracket == 0) + if (std::string::npos == bracket || 0 == bracket) { - throw ResourceInitException(m_uri.empty(), m_resourceTypes.empty(), - m_interfaces.empty(), m_clientWrapper.expired(), false, false); + throw ResourceInitException(m_uri.empty(), false, m_resourceTypes.empty(), + m_interfaces.empty(), m_clientWrapper.expired(), false, true, false); } // extract the ipv6 address std::string ip6Addr = host_token.substr(1, bracket - 1); // address validity check + std::string ip6AddrToValidityCheck(ip6Addr); + size_t percent = ip6AddrToValidityCheck.find('%'); + if (std::string::npos != percent) + { + ip6AddrToValidityCheck.resize(percent); + } struct in6_addr buf; - const char *cAddr = ip6Addr.c_str(); - if(0 == inet_pton(AF_INET6, cAddr, &buf)) + const char *cAddr = ip6AddrToValidityCheck.c_str(); + if (0 == inet_pton(AF_INET6, cAddr, &buf)) { - throw ResourceInitException(m_uri.empty(), m_resourceTypes.empty(), - m_interfaces.empty(), m_clientWrapper.expired(), false, false); + throw ResourceInitException(m_uri.empty(), false, m_resourceTypes.empty(), + m_interfaces.empty(), m_clientWrapper.expired(), true, false, false); } //skip ']' and ':' characters in host string @@ -172,19 +198,26 @@ void OCResource::setHost(const std::string& host) if (0 > port || UINT16_MAX < port) { - throw ResourceInitException(m_uri.empty(), m_resourceTypes.empty(), - m_interfaces.empty(), m_clientWrapper.expired(), false, false); + throw ResourceInitException(m_uri.empty(), false, m_resourceTypes.empty(), + m_interfaces.empty(), m_clientWrapper.expired(), true, false, false); + } + + OCStackResult result = OCDecodeAddressForRFC6874(m_devAddr.addr, + sizeof(m_devAddr.addr), ip6Addr.c_str(), nullptr); + + if (OC_STACK_OK != result) + { + throw ResourceInitException(m_uri.empty(), false, m_resourceTypes.empty(), + m_interfaces.empty(), m_clientWrapper.expired(), false, true, false); } - ip6Addr.copy(m_devAddr.addr, sizeof(m_devAddr.addr)); - m_devAddr.addr[ip6Addr.length()] = '\0'; m_devAddr.port = static_cast(port); - m_devAddr.flags = static_cast(m_devAddr.flags & OC_IP_USE_V6); + m_devAddr.flags = static_cast(m_devAddr.flags | OC_IP_USE_V6); } else if (host_token[0] == ':') { - throw ResourceInitException(m_uri.empty(), m_resourceTypes.empty(), - m_interfaces.empty(), m_clientWrapper.expired(), false, false); + throw ResourceInitException(m_uri.empty(), false, m_resourceTypes.empty(), + m_interfaces.empty(), m_clientWrapper.expired(), false, false, true); } else { @@ -196,8 +229,8 @@ void OCResource::setHost(const std::string& host) // address validity check if (MAC_ADDR_STR_SIZE != macAddr.length()) { - throw ResourceInitException(m_uri.empty(), m_resourceTypes.empty(), - m_interfaces.empty(), m_clientWrapper.expired(), false, false); + throw ResourceInitException(m_uri.empty(), false, m_resourceTypes.empty(), + m_interfaces.empty(), m_clientWrapper.expired(), false, true, false); } for (size_t blockCnt = 0; blockCnt < MAC_ADDR_BLOCKS; blockCnt++) @@ -206,8 +239,8 @@ void OCResource::setHost(const std::string& host) if (std::string::npos != block.find_first_not_of("0123456789ABCDEFabcdef")) { - throw ResourceInitException(m_uri.empty(), m_resourceTypes.empty(), - m_interfaces.empty(), m_clientWrapper.expired(), false, false); + throw ResourceInitException(m_uri.empty(), false, m_resourceTypes.empty(), + m_interfaces.empty(), m_clientWrapper.expired(), false, true, false); } if (MAC_ADDR_BLOCKS - 1 > blockCnt) @@ -216,8 +249,8 @@ void OCResource::setHost(const std::string& host) if (':' != delimiter) { - throw ResourceInitException(m_uri.empty(), m_resourceTypes.empty(), - m_interfaces.empty(), m_clientWrapper.expired(), false, false); + throw ResourceInitException(m_uri.empty(), false, m_resourceTypes.empty(), + m_interfaces.empty(), m_clientWrapper.expired(), false, true, false); } } } @@ -231,8 +264,8 @@ void OCResource::setHost(const std::string& host) if (colon == std::string::npos || colon == 0) { - throw ResourceInitException(m_uri.empty(), m_resourceTypes.empty(), - m_interfaces.empty(), m_clientWrapper.expired(), false, false); + throw ResourceInitException(m_uri.empty(), false, m_resourceTypes.empty(), + m_interfaces.empty(), m_clientWrapper.expired(), false, true, false); } // extract the ipv4 address @@ -241,10 +274,10 @@ void OCResource::setHost(const std::string& host) // address validity check struct in_addr buf; const char *cAddr = ip4Addr.c_str(); - if(0 == inet_pton(AF_INET, cAddr, &buf)) + if (0 == inet_pton(AF_INET, cAddr, &buf)) { - throw ResourceInitException(m_uri.empty(), m_resourceTypes.empty(), - m_interfaces.empty(), m_clientWrapper.expired(), false, false); + throw ResourceInitException(m_uri.empty(), false, m_resourceTypes.empty(), + m_interfaces.empty(), m_clientWrapper.expired(), true, false, false); } //skip ':' characters in host string @@ -253,8 +286,8 @@ void OCResource::setHost(const std::string& host) if (0 > port || UINT16_MAX < port) { - throw ResourceInitException(m_uri.empty(), m_resourceTypes.empty(), - m_interfaces.empty(), m_clientWrapper.expired(), false, false); + throw ResourceInitException(m_uri.empty(), false, m_resourceTypes.empty(), + m_interfaces.empty(), m_clientWrapper.expired(), true, false, false); } ip4Addr.copy(m_devAddr.addr, sizeof(m_devAddr.addr)); @@ -270,7 +303,7 @@ OCStackResult OCResource::get(const QueryParamsMap& queryParametersMap, return checked_guard(m_clientWrapper.lock(), &IClientWrapper::GetResourceRepresentation, m_devAddr, m_uri, - queryParametersMap, m_headerOptions, + queryParametersMap, m_headerOptions, CT_DEFAULT, attributeHandler, QoS); } @@ -297,12 +330,12 @@ OCStackResult OCResource::get(const std::string& resourceType, const std::string { QueryParamsMap mapCpy(queryParametersMap); - if(!resourceType.empty()) + if (!resourceType.empty()) { mapCpy[OC::Key::RESOURCETYPESKEY]=resourceType; } - if(!resourceInterface.empty()) + if (!resourceInterface.empty()) { mapCpy[OC::Key::INTERFACESKEY]= resourceInterface; } @@ -347,12 +380,12 @@ OCStackResult OCResource::put(const std::string& resourceType, { QueryParamsMap mapCpy(queryParametersMap); - if(!resourceType.empty()) + if (!resourceType.empty()) { mapCpy[OC::Key::RESOURCETYPESKEY]=resourceType; } - if(!resourceInterface.empty()) + if (!resourceInterface.empty()) { mapCpy[OC::Key::INTERFACESKEY]=resourceInterface; } @@ -366,7 +399,7 @@ OCStackResult OCResource::post(const OCRepresentation& rep, { return checked_guard(m_clientWrapper.lock(), &IClientWrapper::PostResourceRepresentation, m_devAddr, m_uri, rep, queryParametersMap, - m_headerOptions, attributeHandler, QoS); + m_headerOptions, CT_DEFAULT, attributeHandler, QoS); } OCStackResult OCResource::post(const OCRepresentation& rep, @@ -397,12 +430,12 @@ OCStackResult OCResource::post(const std::string& resourceType, { QueryParamsMap mapCpy(queryParametersMap); - if(!resourceType.empty()) + if (!resourceType.empty()) { mapCpy[OC::Key::RESOURCETYPESKEY]=resourceType; } - if(!resourceInterface.empty()) + if (!resourceInterface.empty()) { mapCpy[OC::Key::INTERFACESKEY]=resourceInterface; } @@ -413,7 +446,7 @@ OCStackResult OCResource::post(const std::string& resourceType, OCStackResult OCResource::deleteResource(DeleteCallback deleteHandler, QualityOfService QoS) { return checked_guard(m_clientWrapper.lock(), &IClientWrapper::DeleteResource, - m_devAddr, m_uri, m_headerOptions, deleteHandler, QoS); + m_devAddr, m_uri, m_headerOptions, CT_DEFAULT, deleteHandler, QoS); } OCStackResult OCResource::deleteResource(DeleteCallback deleteHandler) @@ -428,11 +461,6 @@ OCStackResult OCResource::observe(ObserveType observeType, const QueryParamsMap& queryParametersMap, ObserveCallback observeHandler, QualityOfService QoS) { - if(m_observeHandle != nullptr) - { - return result_guard(OC_STACK_INVALID_PARAM); - } - return checked_guard(m_clientWrapper.lock(), &IClientWrapper::ObserveResource, observeType, &m_observeHandle, m_devAddr, m_uri, queryParametersMap, m_headerOptions, @@ -457,7 +485,7 @@ OCStackResult OCResource::cancelObserve() OCStackResult OCResource::cancelObserve(QualityOfService QoS) { - if(m_observeHandle == nullptr) + if (m_observeHandle == nullptr) { return result_guard(OC_STACK_INVALID_PARAM); } @@ -466,7 +494,7 @@ OCStackResult OCResource::cancelObserve(QualityOfService QoS) &IClientWrapper::CancelObserveResource, m_observeHandle, (const char*)"", m_uri, m_headerOptions, QoS); - if(result == OC_STACK_OK) + if (result == OC_STACK_OK) { m_observeHandle = nullptr; } @@ -487,23 +515,51 @@ void OCResource::unsetHeaderOptions() std::string OCResource::host() const { std::ostringstream ss; - if (m_devAddr.flags & OC_SECURE) + + if (m_devAddr.adapter & OC_ADAPTER_TCP) + { + if (m_devAddr.flags & OC_SECURE) + { + ss << COAPS_TCP; + } + else + { + ss << COAP_TCP; + } + } + else if (m_devAddr.adapter & OC_ADAPTER_GATT_BTLE) { - ss << COAPS; + ss << COAP_GATT; } - else if ((m_devAddr.adapter & OC_ADAPTER_TCP) - || (m_devAddr.adapter & OC_ADAPTER_GATT_BTLE) - || (m_devAddr.adapter & OC_ADAPTER_RFCOMM_BTEDR)) + else if (m_devAddr.adapter & OC_ADAPTER_RFCOMM_BTEDR) { - ss << COAP_TCP; + ss << COAP_RFCOMM; } else { - ss << COAP; + if (m_devAddr.flags & OC_SECURE) + { + ss << COAPS; + } + else + { + ss << COAP; + } } + if (m_devAddr.flags & OC_IP_USE_V6) { - ss << '[' << m_devAddr.addr << ']'; + char addressEncoded[128] = {0}; + + OCStackResult result = OCEncodeAddressForRFC6874(addressEncoded, + sizeof(addressEncoded), + m_devAddr.addr); + if (OC_STACK_OK != result) + { + throw ResourceInitException(m_uri.empty(), false, m_resourceTypes.empty(), + m_interfaces.empty(), m_clientWrapper.expired(), false, true, false); + } + ss << '[' << addressEncoded << ']'; } else { @@ -529,9 +585,16 @@ OCConnectivityType OCResource::connectivityType() const bool OCResource::isObservable() const { - return m_isObservable; + return (m_property & OC_OBSERVABLE) == OC_OBSERVABLE; } +#ifdef WITH_MQ +bool OCResource::isPublish() const +{ + return (m_property & OC_MQ_PUBLISHER) == OC_MQ_PUBLISHER; +} +#endif + std::vector OCResource::getResourceTypes() const { return m_resourceTypes; @@ -552,6 +615,72 @@ std::string OCResource::sid() const return this->uniqueIdentifier().m_representation; } +std::string OCResource::deviceName() const +{ + return m_deviceName; +} + +OCDevAddr OCResource::getDevAddr() const +{ + return m_devAddr; +} + +#ifdef WITH_MQ +OCStackResult OCResource::discoveryMQTopics(const QueryParamsMap& queryParametersMap, + MQTopicCallback attributeHandler, + QualityOfService qos) +{ + return checked_guard(m_clientWrapper.lock(), + &IClientWrapper::ListenForMQTopic, + m_devAddr, m_uri, + queryParametersMap, m_headerOptions, + attributeHandler, qos); +} + +OCStackResult OCResource::createMQTopic(const OCRepresentation& rep, + const std::string& topicUri, + const QueryParamsMap& queryParametersMap, + MQTopicCallback attributeHandler, + QualityOfService qos) +{ + return checked_guard(m_clientWrapper.lock(), &IClientWrapper::PutMQTopicRepresentation, + m_devAddr, topicUri, rep, queryParametersMap, + m_headerOptions, attributeHandler, qos); +} +#endif +#ifdef MQ_SUBSCRIBER +OCStackResult OCResource::subscribeMQTopic(ObserveType observeType, + const QueryParamsMap& queryParametersMap, + ObserveCallback observeHandler, + QualityOfService qos) +{ + return result_guard(observe(observeType, queryParametersMap, observeHandler, qos)); +} + +OCStackResult OCResource::unsubscribeMQTopic(QualityOfService qos) +{ + return result_guard(cancelObserve(qos)); +} + +OCStackResult OCResource::requestMQPublish(const QueryParamsMap& queryParametersMap, + PostCallback attributeHandler, + QualityOfService qos) +{ + OCRepresentation rep; + rep.setValue(std::string("req_pub"), std::string("true")); + return result_guard(post(rep, queryParametersMap, attributeHandler, qos)); +} +#endif +#ifdef MQ_PUBLISHER +OCStackResult OCResource::publishMQTopic(const OCRepresentation& rep, + const QueryParamsMap& queryParametersMap, + PostCallback attributeHandler, + QualityOfService qos) +{ + return result_guard(post(rep, queryParametersMap, attributeHandler, qos)); +} +#endif + bool OCResource::operator==(const OCResource &other) const { return m_resourceId == other.m_resourceId;