*/
static void OCSetNetworkMonitorHandler(CAAdapterStateChangedCB adapterHandler,
CAConnectionStateChangedCB connectionHandler);
+/**
+ * Map zoneId to endpoint address which scope is ipv6 link-local.
+ * @param payload Discovery payload which has Endpoint information.
+ * @param ifindex index which indicate network interface.
+ */
+#ifndef WITH_ARDUINO
+static OCStackResult OCMapZoneIdToLinkLocalEndpoint(OCDiscoveryPayload *payload, uint32_t ifindex);
+#endif
//-----------------------------------------------------------------------------
// Internal functions
return OC_STACK_INVALID_PARAM;
}
+#ifndef WITH_ARDUINO
+OCStackResult OCMapZoneIdToLinkLocalEndpoint(OCDiscoveryPayload *payload, uint32_t ifindex)
+{
+ if (!payload)
+ {
+ OIC_LOG(ERROR, TAG, "Given argument payload is NULL!!");
+ return OC_STACK_INVALID_PARAM;
+ }
+
+ OCResourcePayload *curRes = payload->resources;
+
+ while (curRes != NULL)
+ {
+ OCEndpointPayload* eps = curRes->eps;
+
+ while (eps != NULL)
+ {
+ if (eps->family & OC_IP_USE_V6)
+ {
+ CATransportFlags_t scopeLevel;
+ if (CA_STATUS_OK == CAGetIpv6AddrScope(eps->addr, &scopeLevel))
+ {
+ if (CA_SCOPE_LINK == scopeLevel)
+ {
+ char *zoneId = NULL;
+ if (OC_STACK_OK == OCGetLinkLocalZoneId(ifindex, &zoneId))
+ {
+ assert(zoneId != NULL);
+ // put zoneId to end of addr
+ OICStrcat(eps->addr, OC_MAX_ADDR_STR_SIZE, "%");
+ OICStrcat(eps->addr, OC_MAX_ADDR_STR_SIZE, zoneId);
+ OICFree(zoneId);
+ }
+ else
+ {
+ OIC_LOG(ERROR, TAG, "failed at parse zone-id for link-local address");
+ return OC_STACK_ERROR;
+ }
+ }
+ }
+ else
+ {
+ OIC_LOG(ERROR, TAG, "failed at parse ipv6 scope level");
+ return OC_STACK_ERROR;
+ }
+ }
+ eps = eps->next;
+ }
+ curRes = curRes->next;
+ }
+
+ return OC_STACK_OK;
+}
+#endif
+
void OCHandleResponse(const CAEndpoint_t* endPoint, const CAResponseInfo_t* responseInfo)
{
OIC_LOG(DEBUG, TAG, "Enter OCHandleResponse");
OCPayloadDestroy(response->payload);
return;
}
+
+ // Check endpoints has link-local ipv6 address.
+ // if there is, map zone-id which parsed from ifindex
+#ifndef WITH_ARDUINO
+ if (PAYLOAD_TYPE_DISCOVERY == response->payload->type)
+ {
+ OCDiscoveryPayload *disPayload = (OCDiscoveryPayload*)(response->payload);
+ if (OC_STACK_OK !=
+ OCMapZoneIdToLinkLocalEndpoint(disPayload, response->devAddr.ifindex))
+ {
+ OIC_LOG(ERROR, TAG, "failed at map zone-id for link-local address");
+ OCPayloadDestroy(response->payload);
+ return;
+ }
+ }
+#endif
}
else
{
std::cout << "\t\t" << resourceInterfaces << std::endl;
}
+ // Get Resource current host
+ std::cout << "\tHost of resource: " << std::endl;
+ std::cout << "\t\t" << resource->host() << std::endl;
+
+ // Get Resource Endpoint Infomation
+ std::cout << "\tList of resource endpoints: " << std::endl;
+ for(auto &resourceEndpoints : resource->getAllHosts())
+ {
+ std::cout << "\t\t" << resourceEndpoints << std::endl;
+ }
+
+ // If resource is found from ip based adapter.
+ if (std::string::npos != resource->host().find("coap://") ||
+ std::string::npos != resource->host().find("coaps://") ||
+ std::string::npos != resource->host().find("coap+tcp://") ||
+ std::string::npos != resource->host().find("coaps+tcp://"))
+ {
+ for(auto &resourceEndpoints : resource->getAllHosts())
+ {
+ if (resourceEndpoints.compare(resource->host()) != 0 &&
+ std::string::npos == resourceEndpoints.find("coap+rfcomm"))
+ {
+ std::string newHost = resourceEndpoints;
+
+ if (std::string::npos != newHost.find("tcp"))
+ {
+ TRANSPORT_TYPE_TO_USE = OCConnectivityType::CT_ADAPTER_TCP;
+ }
+ else
+ {
+ TRANSPORT_TYPE_TO_USE = OCConnectivityType::CT_ADAPTER_IP;
+ }
+ // Change Resource host if another host exists
+ std::cout << "\tChange host of resource endpoints" << std::endl;
+ std::cout << "\t\t" << "Current host is "
+ << resource->setHost(newHost) << std::endl;
+ break;
+ }
+ }
+ }
+
if(resourceURI == "/a/light")
{
if (resource->connectivityType() & TRANSPORT_TYPE_TO_USE)
EntityHandler& entityHandler,
uint8_t resourceProperty) = 0;
+ virtual OCStackResult registerResourceWithTps(
+ OCResourceHandle& resourceHandle,
+ std::string& resourceURI,
+ const std::string& resourceTypeName,
+ const std::string& resourceInterface,
+ EntityHandler& entityHandler,
+ uint8_t resourceProperty,
+ OCTpsSchemeFlags resourceTpsTypes) = 0;
+
// @deprecated: Use setPropertyValue instead.
virtual OCStackResult registerDeviceInfo(
const OCDeviceInfo deviceInfo) = 0;
virtual OCStackResult stop() = 0;
virtual OCStackResult start() = 0;
+
+ virtual OCStackResult getSupportedTransportsInfo(OCTpsSchemeFlags& supportedTps) = 0;
};
}
EntityHandler& entityHandler,
uint8_t resourceProperty);
+ virtual OCStackResult registerResourceWithTps(
+ OCResourceHandle& resourceHandle,
+ std::string& resourceURI,
+ const std::string& resourceTypeName,
+ const std::string& resourceInterface,
+ EntityHandler& entityHandler,
+ uint8_t resourceProperty,
+ OCTpsSchemeFlags resourceTpsTypes);
+
// @deprecated: Use setPropertyValue instead.
virtual OCStackResult registerDeviceInfo(
const OCDeviceInfo deviceInfo);
virtual OCStackResult start();
+ virtual OCStackResult getSupportedTransportsInfo(OCTpsSchemeFlags& supportedTps);
private:
void processFunc();
std::thread m_processThread;
QualityOfService QoS);
/**
+ * This function returns flags of supported endpoint TPS on stack.
+ *
+ * @param[out] supportedTps Bit combinations of supported OCTpsSchemeFlags.
+ *
+ * @return Returns ::OC_STACK_OK if success.
+ */
+ OCStackResult getSupportedTransportsInfo(OCTpsSchemeFlags& supportedTps);
+
+ /**
* This API registers a resource with the server
* @note This API applies to server side only.
*
* @param resourceHandle Upon successful registration, resourceHandle will be filled
* @param resourceURI The URI of the resource. Example: "a/light". See NOTE below
- * @param resourceTypeName The resource type. Example: "light"
+ * @param resourceTypeName The resource type. Example: "core.light"
* @param resourceInterface The resource interface (whether it is collection etc).
* @param entityHandler entity handler callback.
- * @param resourceProperty indicates the property of the resource. Defined in ocstack.h.
+ * @param resourceProperty indicates the property of the resource. Defined in octypes.h.
* setting resourceProperty as OC_DISCOVERABLE will allow Discovery of this resource
* setting resourceProperty as OC_OBSERVABLE will allow observation
- * settings resourceProperty as OC_DISCOVERABLE | OC_OBSERVABLE will allow both discovery and
- * observation
+ * setting resourceProperty as OC_DISCOVERABLE | OC_OBSERVABLE will allow both discovery
+ * and observation
*
* @return Returns ::OC_STACK_OK if success.
- * @note "a/light" is a relative URI.
- * Above relative URI will be prepended (by core) with a host IP + namespace "oic"
- * Therefore, fully qualified URI format would be //HostIP-Address/namespace/relativeURI"
- * Example, a relative URI: 'a/light' will result in a fully qualified URI:
- * //192.168.1.1/oic/a/light"
- * First parameter can take a relative URI and core will take care of preparing the fully
- * qualified URI OR
- * first parameter can take fully qualified URI and core will take that as is for further
- * operations
- * @note OCStackResult is defined in ocstack.h.
+ * @note "a/light" is a relative reference to URI.
+ * Above relative reference to URI will be prepended (by core) with a host IP
+ * Therefore, fully qualified URI format would be
+ * "CoAP(s)+protocol-URI-Scheme://HostIP-Address/relativeURI"
+ * Example, a relative reference to URI: 'a/light' will result in a fully qualified URI:
+ * "coap://192.168.1.1:5246/a/light", "coaps://192.168.1.1:5246/a/light"
+ * @note OCStackResult is defined in octypes.h.
* @note entity handler callback :
* When you set specific return value like OC_EH_CHANGED, OC_EH_CONTENT,
* OC_EH_SLOW and etc in entity handler callback,
uint8_t resourceProperty);
/**
+ * This API registers a resource with the server
+ * @note This API applies to server side only.
+ *
+ * @param resourceHandle Upon successful registration, resourceHandle will be filled
+ * @param resourceURI The URI of the resource. Example: "a/light". See NOTE below
+ * @param resourceTypeName The resource type. Example: "core.light"
+ * @param resourceInterface The resource interface (whether it is collection etc).
+ * @param entityHandler Entity handler callback.
+ * @param resourceProperty indicates the property of the resource. Defined in octypes.h.
+ * @param resourceTpsTypes Transport Protocol Suites(TPS) types of resource for
+ open resource to specific transport adapter (e.g., TCP, UDP)
+ with messaging protocol(e.g., COAP, COAPS).
+ Example: "OC_COAP | OC_COAP_TCP"
+ * setting resourceProperty as OC_DISCOVERABLE will allow Discovery of this resource
+ * setting resourceProperty as OC_OBSERVABLE will allow observation
+ * setting resourceProperty as OC_DISCOVERABLE | OC_OBSERVABLE will allow both discovery
+ * and observation
+ *
+ * @return Returns ::OC_STACK_OK if success.
+ * @note "a/light" is a relative reference to URI.
+ * Above relative reference to URI will be prepended (by core) with a host IP
+ * Therefore, fully qualified URI format would be
+ * "CoAP(s)+protocol-URI-Scheme://HostIP-Address/relativeURI"
+ * Example, a relative reference to URI: 'a/light' will result in a fully qualified URI:
+ * "coap://192.168.1.1:5246/a/light", "coaps://192.168.1.1:5246/a/light"
+ * @note OCStackResult is defined in octypes.h.
+ * @note entity handler callback :
+ * When you set specific return value like OC_EH_CHANGED, OC_EH_CONTENT,
+ * OC_EH_SLOW and etc in entity handler callback,
+ * ocstack will be not send response automatically to client
+ * except for error return value like OC_EH_ERROR
+ * If you want to send response to client with specific result,
+ * OCDoResponse API should be called with the result value.
+ */
+ OCStackResult registerResource(OCResourceHandle& resourceHandle,
+ std::string& resourceURI,
+ const std::string& resourceTypeName,
+ const std::string& resourceInterface,
+ EntityHandler entityHandler,
+ uint8_t resourceProperty,
+ OCTpsSchemeFlags resourceTpsTypes);
+
+ /**
* This API registers a resource with the server
* @note This API applies to server & client side.
*
* to be a Client or Client/Server. Otherwise, this will return an empty
* shared ptr.
*
- * @param host a string containing a resolvable host address of the server
- * holding the resource. Currently this should be in the format of
- * coap://address:port for IPv4 and in the format of
- * coap://[address%25ZoneID]:port for IPv6. In the future, we expect
- * "coap:" section is removed from this format.
+ * @param host a string containing a resolvable "coap(s)", "coap(s)+protocol" uri scheme
+ * of the server holding the resource.
+ * Currently this should be in the format coap(s)://address:port or
+ * coap(s)+protocol://address:port, though in the future, we expect this to
+ * change to //address:port
*
* @param uri the rest of the resource's URI that will permit messages to be
* properly routed. Example: /a/light
*
* @param connectivityType ::OCConnectivityType type of connectivity indicating the
- * interface. Example: CT_DEFAULT, CT_ADAPTER_IP, CT_ADAPTER_TCP.
+ * transport method and IP address scope.
+ * Example: CT_DEFAULT, CT_ADAPTER_IP, CT_ADAPTER_TCP.
* if you want to use a specific Flag like IPv4,
* you should apply OR operation for the flag in here.
* Example: static_cast<OCConnectivityType>(CT_ADAPTER_TCP
std::vector<std::string>& value);
/**
+ * This function returns flags of supported endpoint TPS on stack.
+ *
+ * @param[out] supportedTps Bit combinations of supported OCTpsSchemeFlags.
+ *
+ * @return Returns ::OC_STACK_OK if success.
+ */
+ OCStackResult getSupportedTransportsInfo(OCTpsSchemeFlags& supportedTps);
+
+ /**
+ * This API registers a resource with the server
+ * @note This API applies to server side only.
+ *
+ * @param resourceHandle Upon successful registration, resourceHandle will be filled
+ * @param resourceURI The URI of the resource. Example: "a/light". See NOTE below
+ * @param resourceTypeName The resource type. Example: "core.light"
+ * @param resourceInterface The resource interface (whether it is collection etc).
+ * @param entityHandler Entity handler callback.
+ * @param resourceProperty indicates the property of the resource. Defined in octypes.h.
+ * @param resourceTpsTypes Transport Protocol Suites(TPS) types of resource for
+ open resource to specific transport adapter (e.g., TCP, UDP)
+ with messaging protocol(e.g., COAP, COAPS).
+ Example: "OC_COAP | OC_COAP_TCP"
+ * setting resourceProperty as OC_DISCOVERABLE will allow Discovery of this resource
+ * setting resourceProperty as OC_OBSERVABLE will allow observation
+ * setting resourceProperty as OC_DISCOVERABLE | OC_OBSERVABLE will allow both discovery
+ * and observation
+ *
+ * @return Returns ::OC_STACK_OK if success.
+ * @note "a/light" is a relative reference to URI.
+ * Above relative reference to URI will be prepended (by core) with a host IP
+ * Therefore, fully qualified URI format would be
+ * "CoAP(s)+protocol-URI-Scheme://HostIP-Address/relativeURI"
+ * Example, a relative reference to URI: 'a/light' will result in a fully qualified URI:
+ * "coap://192.168.1.1:5246/a/light", "coaps://192.168.1.1:5246/a/light"
+ * @note OCStackResult is defined in octypes.h.
+ * @note entity handler callback :
+ * When you set specific return value like OC_EH_CHANGED, OC_EH_CONTENT,
+ * OC_EH_SLOW and etc in entity handler callback,
+ * ocstack will be not send response automatically to client
+ * except for error return value like OC_EH_ERROR
+ * If you want to send response to client with specific result,
+ * OCDoResponse API should be called with the result value.
+ */
+ OCStackResult registerResource(OCResourceHandle& resourceHandle,
+ std::string& resourceURI,
+ const std::string& resourceTypeName,
+ const std::string& resourceInterface,
+ EntityHandler entityHandler,
+ uint8_t resourceProperty,
+ OCTpsSchemeFlags resourceTpsTypes);
+
+ /**
* This API registers a resource with the server
* @note This API applies to server side only.
*
* @param resourceHandle Upon successful registration, resourceHandle will be filled
* @param resourceURI The URI of the resource. Example: "a/light". See NOTE below
- * @param resourceTypeName The resource type. Example: "light"
+ * @param resourceTypeName The resource type. Example: "core.light"
* @param resourceInterface The resource interface (whether it is collection etc).
* @param entityHandler entity handler callback.
- * @param resourceProperty indicates the property of the resource. Defined in ocstack.h.
+ * @param resourceProperty indicates the property of the resource. Defined in octypes.h.
* setting resourceProperty as OC_DISCOVERABLE will allow Discovery of this resource
* setting resourceProperty as OC_OBSERVABLE will allow observation
- * settings resourceProperty as OC_DISCOVERABLE | OC_OBSERVABLE will allow both discovery
+ * setting resourceProperty as OC_DISCOVERABLE | OC_OBSERVABLE will allow both discovery
* and observation
*
* @return Returns ::OC_STACK_OK if success.
- * @note "a/light" is a relative URI.
- * Above relative URI will be prepended (by core) with a host IP + namespace "oc"
- * Therefore, fully qualified URI format would be //HostIP-Address/namespace/relativeURI"
- * Example, a relative URI: 'a/light' will result in a fully qualified URI:
- * //192.168.1.1/oic/a/light"
- * First parameter can take a relative URI and core will take care of preparing the fully
- * qualified URI OR
- * first parameter can take fully qualified URI and core will take that as is for further
- * operations
- * @note OCStackResult is defined in ocstack.h.
+ * @note "a/light" is a relative reference to URI.
+ * Above relative reference to URI will be prepended (by core) with a host IP
+ * Therefore, fully qualified URI format would be
+ * "CoAP(s)+protocol-URI-Scheme://HostIP-Address/relativeURI"
+ * Example, a relative reference to URI: 'a/light' will result in a fully qualified URI:
+ * "coap://192.168.1.1:5246/a/light", "coaps://192.168.1.1:5246/a/light"
+ * @note OCStackResult is defined in octypes.h.
+ * @note entity handler callback :
+ * When you set specific return value like OC_EH_CHANGED, OC_EH_CONTENT,
+ * OC_EH_SLOW and etc in entity handler callback,
+ * ocstack will be not send response automatically to client
+ * except for error return value like OC_EH_ERROR
+ * If you want to send response to client with specific result,
+ * OCDoResponse API should be called with the result value.
*/
OCStackResult registerResource(OCResourceHandle& resourceHandle,
std::string& resourceURI,
OCConnectivityType connectivityType, bool isObservable,
const std::vector<std::string>& resourceTypes,
const std::vector<std::string>& interfaces);
+
OCStackResult sendResponse(const std::shared_ptr<OCResourceResponse> pResponse);
std::weak_ptr<std::recursive_mutex> csdkLock();
m_resourceTypes(std::move(o.m_resourceTypes)),
m_interfaces(std::move(o.m_interfaces)),
m_children(std::move(m_children)),
+ m_endpoints(std::move(m_endpoints)),
m_observeHandle(std::move(m_observeHandle)),
m_headerOptions(std::move(m_headerOptions))
{
std::string host() const;
/**
+ * Function to get the endpoints information of this resource
+ * @return std::vector<std::string> endpoints information
+ */
+ std::vector<std::string> getAllHosts() const;
+
+ /**
* Function to get the URI for this resource
* @return std::string resource URI
*/
*/
bool isObservable() const;
+ /**
+ * Function to change host of this reource
+ * @return std::string New host Address.
+ * not observable.
+ */
+ std::string setHost(const std::string& host);
#ifdef WITH_MQ
/**
* Function to provide ability to check if this resource is publisher or not
bool operator>=(const OCResource &other) const;
private:
- void setHost(const std::string& host);
std::weak_ptr<IClientWrapper> m_clientWrapper;
std::string m_uri;
OCResourceIdentifier m_resourceId;
std::vector<std::string> m_resourceTypes;
std::vector<std::string> m_interfaces;
std::vector<std::string> m_children;
+ std::vector<std::string> m_endpoints;
OCDoHandle m_observeHandle;
HeaderOptions m_headerOptions;
const std::vector<std::string>& interfaces);
OCResource(std::weak_ptr<IClientWrapper> clientWrapper,
+ const OCDevAddr& devAddr, const std::string& uri,
+ const std::string& serverId, uint8_t property,
+ const std::vector<std::string>& resourceTypes,
+ const std::vector<std::string>& interfaces,
+ const std::vector<std::string>& endpoints);
+
+ OCResource(std::weak_ptr<IClientWrapper> clientWrapper,
const std::string& host, const std::string& uri,
const std::string& serverId,
OCConnectivityType connectivityType, uint8_t property,
const std::vector<std::string>& resourceTypes,
const std::vector<std::string>& interfaces);
+
+ OCResource(std::weak_ptr<IClientWrapper> clientWrapper,
+ const std::string& host, const std::string& uri,
+ const std::string& serverId,
+ OCConnectivityType connectivityType, uint8_t property,
+ const std::vector<std::string>& resourceTypes,
+ const std::vector<std::string>& interfaces,
+ const std::vector<std::string>& endpoints);
};
} // namespace OC
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
#include <StringConstants.h>
+#include <sstream>
+#include <cstring>
#include "ocpayload.h"
#include "ocrandom.h"
#include "oic_string.h"
namespace OC
{
+ static const char EP_ADDR_SPLIT[] = "://";
+ static const char EP_PORT_SPLIT[] = ":";
+ static const char EP_BRAKET_START[] = "[";
+ static const char EP_BRAKET_END[] = "]";
+
class ListenOCContainer
{
private:
return strs;
}
+ static std::vector<std::string> EpsLLToVector(OCEndpointPayload* head)
+ {
+ std::vector<std::string> strs;
+ while (head)
+ {
+ std::ostringstream endpoint;
+ endpoint << head->tps << EP_ADDR_SPLIT;
+
+ switch (head->family)
+ {
+ case OC_DEFAULT_FLAGS:
+ // mac
+ endpoint << head->addr;
+ break;
+
+ case OC_IP_USE_V4:
+ endpoint << head->addr << EP_PORT_SPLIT << head->port;
+ break;
+
+ case OC_IP_USE_V6:
+ endpoint << EP_BRAKET_START << head->addr << EP_BRAKET_END
+ << EP_PORT_SPLIT << head->port;
+ break;
+ default:
+ head = head->next;
+ continue;
+ }
+
+ strs.push_back(endpoint.str());
+ head = head->next;
+ }
+ return strs;
+ }
+
public:
ListenOCContainer(std::weak_ptr<IClientWrapper> cw,
OCDevAddr& devAddr, OCDiscoveryPayload* payload)
currentDevAddr.port = (res->port != 0) ? res->port : devAddr.port;
+ OCEndpointPayload* eps = res->eps;
+ std::vector<std::string> epsVector;
+ if (eps)
+ {
+ //parsing eps from payload
+ epsVector = EpsLLToVector(eps);
+ }
+
if (payload->baseURI)
{
OCDevAddr rdPubAddr = currentDevAddr;
std::string(payload->sid),
res->bitmap,
StringLLToVector(res->types),
- StringLLToVector(res->interfaces)
+ StringLLToVector(res->interfaces),
+ epsVector
)));
}
else
std::string(payload->sid),
res->bitmap,
StringLLToVector(res->types),
- StringLLToVector(res->interfaces)
+ StringLLToVector(res->interfaces),
+ epsVector
)));
#ifdef TCP_ADAPTER
std::string(payload->sid),
res->bitmap,
StringLLToVector(res->types),
- StringLLToVector(res->interfaces)
+ StringLLToVector(res->interfaces),
+ epsVector
)));
}
#endif
static const char PUBLISH_RESOURCE_FAILED[] = "Publish Resource failure";
static const char FORBIDDEN_REQ[] = "Forbidden request";
static const char INTERNAL_SERVER_ERROR[] = "Internal server error";
+ static const char BAD_ENDPOINT[] = "Bad Endpoint";
}
namespace Error
const std::string& resourceInterface,
EntityHandler& eHandler,
uint8_t resourceProperties)
+ {
+ return registerResourceWithTps(resourceHandle, resourceURI, resourceTypeName,
+ resourceInterface, eHandler, resourceProperties, OC_ALL);
+ }
+ OCStackResult InProcServerWrapper::registerResourceWithTps(
+ OCResourceHandle& resourceHandle,
+ std::string& resourceURI,
+ const std::string& resourceTypeName,
+ const std::string& resourceInterface,
+ EntityHandler& eHandler,
+ uint8_t resourceProperties,
+ OCTpsSchemeFlags resourceTpsTypes)
{
OCStackResult result = OC_STACK_ERROR;
if(NULL != eHandler)
{
- result = OCCreateResource(&resourceHandle, // OCResourceHandle *handle
+ result = OCCreateResourceWithEp(&resourceHandle, // OCResourceHandle *handle
resourceTypeName.c_str(), // const char * resourceTypeName
- resourceInterface.c_str(), //const char * resourceInterfaceName //TODO fix this
+ //const char * resourceInterfaceName //TODO fix this
+ resourceInterface.c_str(),
resourceURI.c_str(), // const char * uri
EntityHandlerWrapper, // OCEntityHandler entityHandler
NULL,
- resourceProperties // uint8_t resourceProperties
- );
+ resourceProperties, // uint8_t resourceProperties
+ resourceTpsTypes); // OCTpsSchemeFlags resourceTpsTypes
}
else
{
- result = OCCreateResource(&resourceHandle, // OCResourceHandle *handle
+ result = OCCreateResourceWithEp(&resourceHandle, // OCResourceHandle *handle
resourceTypeName.c_str(), // const char * resourceTypeName
- resourceInterface.c_str(), //const char * resourceInterfaceName //TODO fix this
+ //const char * resourceInterfaceName //TODO fix this
+ resourceInterface.c_str(),
resourceURI.c_str(), // const char * uri
NULL, // OCEntityHandler entityHandler
NULL,
- resourceProperties // uint8_t resourceProperties
- );
+ resourceProperties, // uint8_t resourceProperties
+ resourceTpsTypes); // OCTpsSchemeFlags resourceTpsTypes
}
if(result != OC_STACK_OK)
}
}
+ OCStackResult InProcServerWrapper::getSupportedTransportsInfo(OCTpsSchemeFlags& supportedTps)
+ {
+ auto cLock = m_csdkLock.lock();
+ OCStackResult result = OC_STACK_ERROR;
+ if (cLock)
+ {
+ std::lock_guard<std::recursive_mutex> lock(*cLock);
+ supportedTps = OCGetSupportedEndpointTpsFlags();
+
+ if (OC_NO_TPS != supportedTps)
+ {
+ result = OC_STACK_OK;
+ }
+ }
+ return result;
+ }
+
InProcServerWrapper::~InProcServerWrapper()
{
try
return OC::Exception::FORBIDDEN_REQ;
case OC_STACK_INTERNAL_SERVER_ERROR:
return OC::Exception::INTERNAL_SERVER_ERROR;
+ case OC_STACK_BAD_ENDPOINT:
+ return OC::Exception::BAD_ENDPOINT;
}
return OC::Exception::UNKNOWN_ERROR;
platformInfoHandler, QoS);
}
+ OCStackResult getSupportedTransportsInfo(OCTpsSchemeFlags& supportedTps)
+ {
+ return OCPlatform_impl::Instance().getSupportedTransportsInfo(supportedTps);
+ }
+
OCStackResult registerResource(OCResourceHandle& resourceHandle,
std::string& resourceURI,
const std::string& resourceTypeName,
const std::string& resourceInterface,
EntityHandler entityHandler,
- uint8_t resourceProperty)
+ uint8_t resourceProperty
+ )
{
return OCPlatform_impl::Instance().registerResource(resourceHandle, resourceURI,
resourceTypeName, resourceInterface,
}
OCStackResult registerResource(OCResourceHandle& resourceHandle,
+ std::string& resourceURI,
+ const std::string& resourceTypeName,
+ const std::string& resourceInterface,
+ EntityHandler entityHandler,
+ uint8_t resourceProperty,
+ OCTpsSchemeFlags resourceTpsTypes)
+ {
+ return OCPlatform_impl::Instance().registerResource(resourceHandle, resourceURI,
+ resourceTypeName, resourceInterface,
+ entityHandler, resourceProperty,
+ resourceTpsTypes);
+ }
+
+ OCStackResult registerResource(OCResourceHandle& resourceHandle,
const std::shared_ptr< OCResource > resource)
{
return OCPlatform_impl::Instance().registerResource(resourceHandle, resource);
host, platformURI, connectivityType, platformInfoHandler, QoS);
}
+ OCStackResult OCPlatform_impl::getSupportedTransportsInfo(OCTpsSchemeFlags& supportedTps)
+ {
+ return checked_guard(m_server, &IServerWrapper::getSupportedTransportsInfo, supportedTps);
+ }
+
OCStackResult OCPlatform_impl::registerResource(OCResourceHandle& resourceHandle,
std::string& resourceURI,
const std::string& resourceTypeName,
resourceInterface, entityHandler, resourceProperty);
}
+ OCStackResult OCPlatform_impl::registerResource(OCResourceHandle& resourceHandle,
+ std::string& resourceURI,
+ const std::string& resourceTypeName,
+ const std::string& resourceInterface,
+ EntityHandler entityHandler,
+ uint8_t resourceProperty,
+ OCTpsSchemeFlags resourceTpsTypes)
+ {
+ return checked_guard(m_server, &IServerWrapper::registerResourceWithTps,
+ std::ref(resourceHandle), resourceURI, resourceTypeName,
+ resourceInterface, entityHandler, resourceProperty,
+ resourceTpsTypes);
+ }
+
OCStackResult OCPlatform_impl::registerDeviceInfo(const OCDeviceInfo deviceInfo)
{
return checked_guard(m_server, &IServerWrapper::registerDeviceInfo, deviceInfo);
#include "iotivity_config.h"
#include "OCResource.h"
#include "OCUtilities.h"
+#include "ocstack.h"
+#include "oic_malloc.h"
+#include "cacommon.h"
+#include "cautilinterface.h"
+#include "oic_string.h"
#include <boost/lexical_cast.hpp>
#include <sstream>
}
OCResource::OCResource(std::weak_ptr<IClientWrapper> clientWrapper,
+ const OCDevAddr& devAddr, const std::string& uri,
+ const std::string& serverId, uint8_t property,
+ const std::vector<std::string>& resourceTypes,
+ const std::vector<std::string>& interfaces,
+ const std::vector<std::string>& endpoints)
+ : m_clientWrapper(clientWrapper), m_uri(uri),
+ m_resourceId(serverId, m_uri), m_devAddr(devAddr),
+ m_isCollection(false), m_property(property),
+ m_resourceTypes(resourceTypes), m_interfaces(interfaces),
+ m_endpoints(endpoints),
+ m_observeHandle(nullptr)
+{
+ m_isCollection = std::find(m_interfaces.begin(), m_interfaces.end(), LINK_INTERFACE)
+ != m_interfaces.end();
+
+ if (m_uri.empty() ||
+ resourceTypes.empty() ||
+ interfaces.empty()||
+ m_clientWrapper.expired())
+ {
+ throw ResourceInitException(m_uri.empty(), resourceTypes.empty(),
+ interfaces.empty(), m_clientWrapper.expired(), false, false);
+ }
+}
+
+OCResource::OCResource(std::weak_ptr<IClientWrapper> clientWrapper,
const std::string& host, const std::string& uri,
const std::string& serverId,
OCConnectivityType connectivityType, uint8_t property,
const std::vector<std::string>& resourceTypes,
- const std::vector<std::string>& interfaces)
+ const std::vector<std::string>& interfaces,
+ const std::vector<std::string>& endpoints)
: m_clientWrapper(clientWrapper), m_uri(uri),
m_resourceId(serverId, m_uri),
m_isCollection(false), m_property(property),
m_resourceTypes(resourceTypes), m_interfaces(interfaces),
+ m_endpoints(endpoints),
+ m_observeHandle(nullptr)
+{
+ m_devAddr = OCDevAddr{OC_DEFAULT_ADAPTER, OC_DEFAULT_FLAGS, 0, {0}, 0,
+#if defined (ROUTING_GATEWAY) || defined (ROUTING_EP)
+ {0}
+#endif
+ };
+ m_isCollection = std::find(m_interfaces.begin(), m_interfaces.end(), LINK_INTERFACE)
+ != m_interfaces.end();
+
+ if (m_uri.empty() ||
+ resourceTypes.empty() ||
+ interfaces.empty()||
+ m_clientWrapper.expired())
+ {
+ throw ResourceInitException(m_uri.empty(), resourceTypes.empty(),
+ interfaces.empty(), m_clientWrapper.expired(), false, false);
+ }
+
+ if (uri.length() == 1 && uri[0] == '/')
+ {
+ throw ResourceInitException(m_uri.empty(), resourceTypes.empty(),
+ interfaces.empty(), m_clientWrapper.expired(), false, false);
+ }
+
+ if (uri[0] != '/')
+ {
+ throw ResourceInitException(m_uri.empty(), resourceTypes.empty(),
+ interfaces.empty(), m_clientWrapper.expired(), false, false);
+ }
+
+ // construct the devAddr from the pieces we have
+ m_devAddr.adapter = static_cast<OCTransportAdapter>(connectivityType >> CT_ADAPTER_SHIFT);
+ m_devAddr.flags = static_cast<OCTransportFlags>(connectivityType & CT_MASK_FLAGS);
+
+ this->setHost(host);
+}
+
+OCResource::OCResource(std::weak_ptr<IClientWrapper> clientWrapper,
+ const std::string& host, const std::string& uri,
+ const std::string& serverId,
+ OCConnectivityType connectivityType, uint8_t property,
+ const std::vector<std::string>& resourceTypes,
+ const std::vector<std::string>& interfaces)
+: m_clientWrapper(clientWrapper), m_uri(uri),
+ m_resourceId(serverId, m_uri),
+ m_isCollection(false), m_property(property),
+ m_resourceTypes(resourceTypes), m_interfaces(interfaces),
m_observeHandle(nullptr)
{
m_devAddr = OCDevAddr{OC_DEFAULT_ADAPTER, OC_DEFAULT_FLAGS, 0, {0}, 0,
{
}
-void OCResource::setHost(const std::string& host)
+std::string OCResource::setHost(const std::string& host)
{
size_t prefix_len;
- if (host.compare(0, sizeof(COAP) - 1, COAP) == 0)
- {
- prefix_len = sizeof(COAP) - 1;
- }
- else if (host.compare(0, sizeof(COAPS) - 1, COAPS) == 0)
+ OCDevAddr new_devAddr;
+ memset(&new_devAddr, 0, sizeof(new_devAddr));
+ new_devAddr.adapter = OC_DEFAULT_ADAPTER;
+ new_devAddr.flags = OC_DEFAULT_FLAGS;
+
+ // init m_devAddr
+ m_devAddr = new_devAddr;
+ bool usingIpAddr = false;
+
+ if (host.compare(0, sizeof(COAPS) - 1, COAPS) == 0)
{
+ if (!OC_SECURE)
+ {
+ throw ResourceInitException(m_uri.empty(), m_resourceTypes.empty(),
+ m_interfaces.empty(), m_clientWrapper.expired(), false, false);
+ }
prefix_len = sizeof(COAPS) - 1;
m_devAddr.flags = static_cast<OCTransportFlags>(m_devAddr.flags | OC_SECURE);
+ m_devAddr.adapter = OC_ADAPTER_IP;
+ usingIpAddr = true;
+ }
+ else if (host.compare(0, sizeof(COAP) - 1, COAP) == 0)
+ {
+ prefix_len = sizeof(COAP) - 1;
+ m_devAddr.adapter = OC_ADAPTER_IP;
+ usingIpAddr = true;
}
else if (host.compare(0, sizeof(COAP_TCP) - 1, COAP_TCP) == 0)
{
prefix_len = sizeof(COAP_TCP) - 1;
+ m_devAddr.adapter = OC_ADAPTER_TCP;
+ usingIpAddr = true;
}
else if (host.compare(0, sizeof(COAPS_TCP) - 1, COAPS_TCP) == 0)
{
+ if (!OC_SECURE)
+ {
+ throw ResourceInitException(m_uri.empty(), m_resourceTypes.empty(),
+ m_interfaces.empty(), m_clientWrapper.expired(), false, false);
+ }
prefix_len = sizeof(COAPS_TCP) - 1;
m_devAddr.flags = static_cast<OCTransportFlags>(m_devAddr.flags | OC_SECURE);
+ m_devAddr.adapter = OC_ADAPTER_TCP;
+ usingIpAddr = true;
}
else if (host.compare(0, sizeof(COAP_GATT) - 1, COAP_GATT) == 0)
{
prefix_len = sizeof(COAP_GATT) - 1;
+ m_devAddr.adapter = OC_ADAPTER_GATT_BTLE;
}
else if (host.compare(0, sizeof(COAP_RFCOMM) - 1, COAP_RFCOMM) == 0)
{
prefix_len = sizeof(COAP_RFCOMM) - 1;
+ m_devAddr.adapter = OC_ADAPTER_RFCOMM_BTEDR;
}
else
{
m_interfaces.empty(), m_clientWrapper.expired(), false, false);
}
+ // set flag
+ if (usingIpAddr)
+ {
+ if (host.find('[') != std::string::npos)
+ {
+ // ipv6
+ m_devAddr.flags = static_cast<OCTransportFlags>(m_devAddr.flags | OC_IP_USE_V6);
+ }
+ else
+ {
+ // ipv4
+ m_devAddr.flags = static_cast<OCTransportFlags>(m_devAddr.flags | OC_IP_USE_V4);
+ }
+ }
+
// remove 'coap://' or 'coaps://' or 'coap+tcp://' or 'coap+gatt://' or 'coap+rfcomm://'
std::string host_token = host.substr(prefix_len);
m_interfaces.empty(), m_clientWrapper.expired(), false, false);
}
- OCStackResult result = OCDecodeAddressForRFC6874(m_devAddr.addr,
- sizeof(m_devAddr.addr), ip6Addr.c_str(), nullptr);
+ if (std::string::npos != ip6Addr.find("%25"))
+ {
+ OCStackResult result = OCDecodeAddressForRFC6874(m_devAddr.addr,
+ sizeof(m_devAddr.addr), ip6Addr.c_str(), nullptr);
- if (OC_STACK_OK != result)
+ if (OC_STACK_OK != result)
+ {
+ throw ResourceInitException(m_uri.empty(), m_resourceTypes.empty(),
+ m_interfaces.empty(), m_clientWrapper.expired(), false, false);
+ }
+ }
+ else
{
- throw ResourceInitException(m_uri.empty(), m_resourceTypes.empty(),
- m_interfaces.empty(), m_clientWrapper.expired(), false, false);
+ // It means zone-id is missing, check ipv6Addr is link local
+ CATransportFlags_t scopeLevel;
+ CAResult_t caResult = CAGetIpv6AddrScope(ip6Addr.c_str(), &scopeLevel);
+
+ if (CA_STATUS_OK != caResult)
+ {
+ throw ResourceInitException(m_uri.empty(), m_resourceTypes.empty(),
+ m_interfaces.empty(), m_clientWrapper.expired(), false, false);
+ }
+ else
+ {
+ if (CA_SCOPE_LINK == scopeLevel)
+ {
+ {
+ // Given ip address is link-local scope without zone-id.
+ throw ResourceInitException(m_uri.empty(), m_resourceTypes.empty(),
+ m_interfaces.empty(), m_clientWrapper.expired(), false, false);
+ }
+ }
+ else
+ {
+ if (!OICStrcpy(m_devAddr.addr, sizeof(m_devAddr.addr), ip6Addr.c_str()))
+ {
+ throw ResourceInitException(m_uri.empty(), m_resourceTypes.empty(),
+ m_interfaces.empty(), m_clientWrapper.expired(), false, false);
+ }
+ }
+ }
}
m_devAddr.port = static_cast<uint16_t>(port);
m_devAddr.port = static_cast<uint16_t>(port);
}
}
+ return this->host();
}
OCStackResult OCResource::get(const QueryParamsMap& queryParametersMap,
return ss.str();
}
+std::vector<std::string> OCResource::getAllHosts() const
+{
+ return m_endpoints;
+}
+
std::string OCResource::uri() const
{
return m_uri;
OC_STACK_USER_DENIED_REQ,
OC_STACK_NOT_ACCEPTABLE,
OC_STACK_FORBIDDEN_REQ,
- OC_STACK_INTERNAL_SERVER_ERROR
+ OC_STACK_INTERNAL_SERVER_ERROR,
+ OC_STACK_BAD_ENDPOINT
};
std::string resultMessages[]=
OC::Exception::USER_DENIED_REQ,
OC::Exception::NOT_ACCEPTABLE,
OC::Exception::FORBIDDEN_REQ,
- OC::Exception::INTERNAL_SERVER_ERROR
+ OC::Exception::INTERNAL_SERVER_ERROR,
+ OC::Exception::BAD_ENDPOINT
};
TEST(OCExceptionTest, ReasonCodeMatches)
{
return resourceHandle;
}
+ OCResourceHandle RegisterResource(std::string uri, OCTpsSchemeFlags resourceTpsTypes)
+ {
+ PlatformConfig cfg
+ { OC::ServiceType::OutOfProc, OC::ModeType::Server, "0.0.0.0", 0,
+ OC::QualityOfService::LowQos, &gps };
+ OCPlatform::Configure(cfg);
+ EXPECT_EQ(OC_STACK_OK, OCPlatform::registerResource(
+ resourceHandle, uri, gResourceTypeName,
+ gResourceInterface, entityHandler, gResourceProperty,
+ resourceTpsTypes));
+ return resourceHandle;
+ }
+
//Configure
// Enable it when the stack throw an exception
// https://jira.iotivity.org/browse/IOT-428
gResourceInterface, entityHandler, gResourceProperty));
}
+ TEST(RegisterResourceTest, RegisterWithTpsType)
+ {
+ std::string uri = "/a/light7";
+ std::string type = "core.light";
+ uint8_t gResourceProperty = 0;
+ EXPECT_EQ(OC_STACK_OK, OCPlatform::registerResource(
+ resourceHandle, uri, type,
+ gResourceInterface, entityHandler, gResourceProperty , OC_COAP));
+ }
+
+ TEST(RegisterResourceTest, RegisterWithTpsTypeAll)
+ {
+ std::string uri = "/a/light8";
+ std::string type = "core.light";
+ uint8_t gResourceProperty = 0;
+ EXPECT_EQ(OC_STACK_OK, OCPlatform::registerResource(
+ resourceHandle, uri, type,
+ gResourceInterface, entityHandler, gResourceProperty, OC_ALL));
+ }
+#ifdef TCP_ADAPTER
+ TEST(RegisterResourceTest, RegisterWithTpsTypeBitComb)
+ {
+ std::string uri = "/a/light9";
+ std::string type = "core.light";
+ uint8_t gResourceProperty = 0;
+ EXPECT_EQ(OC_STACK_OK, OCPlatform::registerResource(
+ resourceHandle, uri, type,
+ gResourceInterface, entityHandler, gResourceProperty, (OCTpsSchemeFlags)(OC_COAP || OC_COAP_TCP)));
+ }
+#endif
+
//UnregisterTest
TEST(UnregisterTest, UnregisterZeroHandleValue)
{
OC::QualityOfService::NaQos));
}
+ TEST(GetSupportedTransportsInfoTest, getSupportedTransportsInfoWithValidParm)
+ {
+ OCTpsSchemeFlags input = OC_NO_TPS;
+ EXPECT_EQ(OC_STACK_OK, OCPlatform::getSupportedTransportsInfo(input));
+ }
+
//RegisterDeviceInfo test
TEST(RegisterDeviceInfoTest, RegisterDeviceInfoWithValidParameters)
{
EXPECT_TRUE(resource->host() == "coap://[ffff::ffff%25eth0]:5000");
}
+ // EmptyHosts Test
+ TEST(HostsTest, EmptyHosts)
+ {
+ OCResource::Ptr resource = ConstructResourceObject("coap://192.168.1.2:5000", "/resource");
+ EXPECT_TRUE(resource != NULL);
+ EXPECT_TRUE(resource->getAllHosts().empty());
+ }
+
+ // SetHost Test
+ TEST(SetHostTest, SetHost)
+ {
+ OCResource::Ptr resource = ConstructResourceObject("coap://192.168.1.2:5000", "/resource");
+ EXPECT_TRUE(resource != NULL);
+ EXPECT_TRUE(resource->host() == "coap://192.168.1.2:5000");
+ EXPECT_TRUE(resource->setHost("coap://192.168.1.1:5000") == "coap://192.168.1.1:5000");
+ }
+
+ // SetHost Test2
+ TEST(SetHostTest, SetHost2)
+ {
+ OCResource::Ptr resource = ConstructResourceObject("coap://192.168.1.2:5000", "/resource");
+ EXPECT_TRUE(resource != NULL);
+ EXPECT_TRUE(resource->host() == "coap://192.168.1.2:5000");
+ EXPECT_TRUE(resource->setHost("coap://[3731:54:65fe:2::a7]:32787") ==
+ "coap://[3731:54:65fe:2::a7]:32787");
+ }
+
+ // SetHost Test3
+ TEST(SetHostTest, SetHost3)
+ {
+ OCResource::Ptr resource = ConstructResourceObject("coap://[3731:54:65fe:2::a7]:32787", "/resource");
+ EXPECT_TRUE(resource != NULL);
+ EXPECT_TRUE(resource->host() == "coap://[3731:54:65fe:2::a7]:32787");
+ EXPECT_TRUE(resource->setHost("coap://192.168.1.2:5000") == "coap://192.168.1.2:5000");
+ }
+
//Uri Test
TEST(UriTest, Uri)
{
}
//ConnectivityType Test
- TEST(ConnectivityTypeTest, ConnectivityType)
+ TEST(ConnectivityTypeTest, ConnectivityTypeIpv4)
{
OCResource::Ptr resource = ConstructResourceObject("coap://192.168.1.2:5000", "/resource");
EXPECT_TRUE(resource != NULL);
- EXPECT_TRUE(resource->connectivityType() == CT_DEFAULT);
+ EXPECT_TRUE(resource->connectivityType() == (CT_ADAPTER_IP | CT_IP_USE_V4));
+ }
+
+ //ConnectivityType Test
+ TEST(ConnectivityTypeTest, ConnectivityTypeIpv6)
+ {
+ OCResource::Ptr resource = ConstructResourceObject("coap://[fe80::52b7:c3ff:fead:dc0d%25eth0]:5000", "/resource");
+ EXPECT_TRUE(resource != NULL);
+ EXPECT_TRUE(resource->connectivityType() == (CT_ADAPTER_IP | CT_IP_USE_V6));
}
//IsObservable Test