From ddc2c1615c7999c6e79e328f3869f6086072ce41 Mon Sep 17 00:00:00 2001 From: "bg.chun" Date: Fri, 5 Aug 2016 18:48:18 +0900 Subject: [PATCH] [IOT-1207] Endpoint C API with request filtering provide public capi "OCCreateResourceWithEp" for mapping endpoint to resource and filltering request which come from unbinded endpoint. Change-Id: I7f273acdacff9116d99b60afb76f70fa48709341 Signed-off-by: bg.chun Reviewed-on: https://gerrit.iotivity.org/gerrit/10073 Tested-by: jenkins-iotivity Reviewed-by: Dan Mihai Reviewed-by: jihwan seo Reviewed-by: Ashok Babu Channa --- resource/csdk/octbstack_product.def | 6 + .../csdk/stack/include/internal/ocstackinternal.h | 45 ++++- resource/csdk/stack/include/ocpayload.h | 13 +- resource/csdk/stack/include/ocstack.h | 41 +++++ resource/csdk/stack/include/octypes.h | 3 + resource/csdk/stack/include/payload_logging.h | 18 +- .../samples/linux/SimpleClientServer/SConscript | 5 +- .../samples/linux/SimpleClientServer/occlient.cpp | 107 ++++++++++++ .../samples/linux/SimpleClientServer/occlient.h | 11 +- .../samples/linux/SimpleClientServer/ocserver.cpp | 89 +++++++++- .../samples/linux/SimpleClientServer/ocserver.h | 10 ++ resource/csdk/stack/src/ocendpoint.c | 6 +- resource/csdk/stack/src/ocpayload.c | 181 ++++++++++++++++++++- resource/csdk/stack/src/ocpayloadconvert.c | 71 +++++++- resource/csdk/stack/src/ocpayloadparse.c | 61 +++++++ resource/csdk/stack/src/ocresource.c | 118 +++++++++++++- resource/csdk/stack/src/ocstack.c | 88 +++++++++- resource/csdk/stack/test/stacktests.cpp | 87 ++++++++++ 18 files changed, 922 insertions(+), 38 deletions(-) diff --git a/resource/csdk/octbstack_product.def b/resource/csdk/octbstack_product.def index f9c3156..6251601 100644 --- a/resource/csdk/octbstack_product.def +++ b/resource/csdk/octbstack_product.def @@ -39,8 +39,10 @@ OCCancel OCCreateOCStringLL OCCreateResource OCDecodeAddressForRFC6874 +OCCreateResourceWithEp OCDeleteResource OCDiscoverDirectPairingDevices +OCDiscoveryEndpointDestroy OCDiscoveryPayloadCreate OCDiscoveryPayloadDestroy OCDiscoveryPayloadGetResourceCount @@ -48,6 +50,8 @@ OCDoDirectPairing OCDoResource OCDoResponse OCEncodeAddressForRFC6874 +OCEndpointPayloadGetEndpoint +OCEndpointPayloadGetEndpointCount OCFreeOCStringLL OCGetDeviceId OCGetDirectPairedDevices @@ -66,6 +70,7 @@ OCGetResourceTypeName OCGetResourceUri OCGetResourceIns OCGetServerInstanceIDString +OCGetSupportedEndpointTpsFlags OCInit OCInit1 OCNotifyAllObservers @@ -104,6 +109,7 @@ OCRepPayloadSetPropString OCRepPayloadSetStringArray OCRepPayloadSetStringArrayAsOwner OCRepPayloadSetUri +OCResourcePayloadAddNewEndpoint OCResourcePayloadAddStringLL OCSecurityPayloadCreate OCSetDefaultDeviceEntityHandler diff --git a/resource/csdk/stack/include/internal/ocstackinternal.h b/resource/csdk/stack/include/internal/ocstackinternal.h index d0e5909..b3838cf 100644 --- a/resource/csdk/stack/include/internal/ocstackinternal.h +++ b/resource/csdk/stack/include/internal/ocstackinternal.h @@ -227,8 +227,17 @@ OCStackResult BindResourceInterfaceToResource(OCResource* resource, * @param resourceTypeName Name of resource type. * @return ::OC_STACK_OK on success, some other value upon failure. */ -OCStackResult BindResourceTypeToResource(OCResource* resource, +OCStackResult BindResourceTypeToResource(OCResource *resource, const char *resourceTypeName); +/** + * Bind a Transport Protocol Suites type to a resource. + * + * @param resource Target resource. + * @param resourceTpsTypes Name of transport protocol suites type. + * @return ::OC_STACK_OK on success, some other value upon failure. + */ +OCStackResult BindTpsTypeToResource(OCResource *resource, + OCTpsSchemeFlags resourceTpsTypes); /** * Convert OCStackResult to CAResponseResult_t. @@ -316,6 +325,40 @@ OCStackResult OCUpdateResourceInsWithResponse(const char *requestUri, */ void OCDeleteResourceAttributes(OCAttribute *rsrcAttributes); +#ifndef TCP_ADAPTER +/** + * Add resource payload with endpoint payload to discovery payload. + * + * @param payload Pointer to discovery payload. + * @param res Pointer to OCresource structure. + * @param securePort Secure port number. + * @param isVirtual true: virtual resource (e.g., oic/res), false: resource. + * @param networkInfo List of CAEndpoint_t. + * @param infoSize Size of CAEndpoint_t list. + * @param devAddr Pointer to OCDevAddr structure. + */ +void OCDiscoveryPayloadAddResourceWithEps(OCDiscoveryPayload *payload, const OCResource *res, + uint16_t securePort, bool isVirtual, + void *networkInfo, uint32_t infoSize, + const OCDevAddr *devAddr); +#else +/** + * Add resource payload with endpoint payload to discovery payload. + * + * @param payload Pointer to discovery payload. + * @param res Pointer to OCresource structure. + * @param securePort Secure port number. + * @param isVirtual true: virtual resource (e.g., oic/res, oic/d), false: resource. + * @param networkInfo List of CAEndpoint_t. + * @param infoSize Size of CAEndpoint_t list. + * @param devAddr Pointer to OCDevAddr structure. + * @param tcpPort TCP port number. + */ +void OCDiscoveryPayloadAddResourceWithEps(OCDiscoveryPayload *payload, const OCResource *res, + uint16_t securePort, bool isVirtual, + void *networkInfo, uint32_t infoSize, + const OCDevAddr *devAddr, uint16_t tcpPort); +#endif #ifdef __cplusplus } #endif // __cplusplus diff --git a/resource/csdk/stack/include/ocpayload.h b/resource/csdk/stack/include/ocpayload.h index 0c534e9..6b52fe5 100644 --- a/resource/csdk/stack/include/ocpayload.h +++ b/resource/csdk/stack/include/ocpayload.h @@ -240,12 +240,21 @@ void OCDiscoveryPayloadAddResource(OCDiscoveryPayload* payload, const OCResource void OCDiscoveryPayloadAddResource(OCDiscoveryPayload* payload, const OCResource* res, uint16_t securePort, uint16_t tcpPort); #endif -void OCDiscoveryPayloadAddNewResource(OCDiscoveryPayload* payload, OCResourcePayload* res); +void OCDiscoveryPayloadAddNewResource(OCDiscoveryPayload* payload, + OCResourcePayload* res); bool OCResourcePayloadAddStringLL(OCStringLL **payload, const char* type); size_t OCDiscoveryPayloadGetResourceCount(OCDiscoveryPayload* payload); -OCResourcePayload* OCDiscoveryPayloadGetResource(OCDiscoveryPayload* payload, size_t index); +OCResourcePayload* OCDiscoveryPayloadGetResource(OCDiscoveryPayload* payload, + size_t index); +size_t OCEndpointPayloadGetEndpointCount(OCEndpointPayload* payload); +OCEndpointPayload* OCEndpointPayloadGetEndpoint(OCEndpointPayload* payload, + size_t index); + +void OCResourcePayloadAddNewEndpoint(OCResourcePayload* payload, + OCEndpointPayload* endpoint); +void OCDiscoveryEndpointDestroy(OCEndpointPayload* payload); void OCDiscoveryResourceDestroy(OCResourcePayload* payload); void OCDiscoveryPayloadDestroy(OCDiscoveryPayload* payload); diff --git a/resource/csdk/stack/include/ocstack.h b/resource/csdk/stack/include/ocstack.h index 56f7337..61aecda 100644 --- a/resource/csdk/stack/include/ocstack.h +++ b/resource/csdk/stack/include/ocstack.h @@ -288,6 +288,47 @@ OCStackResult OCCreateResource(OCResourceHandle *handle, uint8_t resourceProperties); /** + * This function creates a resource. + * + * @param handle Pointer to handle to newly created resource. Set by ocstack and + * used to refer to resource. + * @param resourceTypeName Name of resource type. Example: "core.led". + * @param resourceInterfaceName Name of resource interface. Example: "core.rw". + * @param uri URI of the resource. Example: "/a/led". + * @param entityHandler Entity handler function that is called by ocstack to handle + * requests, etc. + * NULL for default entity handler. + * @param callbackParam parameter passed back when entityHandler is called. + * @param resourceProperties Properties supported by resource. + * Example: ::OC_DISCOVERABLE|::OC_OBSERVABLE. + * @param resourceTpsTypes Transport Protocol Suites(TPS) types of resource for expose + resource to specific transport adapter (e.g., TCP, UDP) + with messaging protocol (e.g., COAP, COAPS). + Example: "OC_COAP | OC_COAP_TCP" + * + * @note Only supported TPS types on stack will be mapped to resource. + It means "OC_COAPS" and "OC_COAPS_TCP" flags will be ignored if secure option + not enabled on stack. Also "COAP_TCP" and "COAPS_TCP" flags will be ignored + if stack does not support tcp mode. + * + * @return ::OC_STACK_OK on success, some other value upon failure. + */ +OCStackResult OCCreateResourceWithEp(OCResourceHandle *handle, + const char *resourceTypeName, + const char *resourceInterfaceName, + const char *uri, + OCEntityHandler entityHandler, + void *callbackParam, + uint8_t resourceProperties, + OCTpsSchemeFlags resourceTpsTypes); +/* + * This function returns flags of supported endpoint TPS on stack. + * + * @return Bit combinations of supported OCTpsSchemeFlags. + */ +OCTpsSchemeFlags OCGetSupportedEndpointTpsFlags(); + +/** * This function adds a resource to a collection resource. * * @param collectionHandle Handle to the collection resource. diff --git a/resource/csdk/stack/include/octypes.h b/resource/csdk/stack/include/octypes.h index bd1d5a7..4c26bf7 100644 --- a/resource/csdk/stack/include/octypes.h +++ b/resource/csdk/stack/include/octypes.h @@ -998,6 +998,9 @@ typedef enum OC_STACK_AUTHENTICATION_FAILURE, OC_STACK_NOT_ALLOWED_OXM, + /** Request come from endpoint which is not mapped to the resource. */ + OC_STACK_BAD_ENDPOINT, + /** Insert all new error codes here!.*/ #ifdef WITH_PRESENCE OC_STACK_PRESENCE_STOPPED = 128, diff --git a/resource/csdk/stack/include/payload_logging.h b/resource/csdk/stack/include/payload_logging.h index 1b81907..39914ce 100644 --- a/resource/csdk/stack/include/payload_logging.h +++ b/resource/csdk/stack/include/payload_logging.h @@ -174,7 +174,7 @@ INLINE_API void OCPayloadLogRepValues(LogLevel level, OCRepPayloadValue* val) INLINE_API void OCPayloadLogRep(LogLevel level, OCRepPayload* payload) { OIC_LOG(level, (PL_TAG), "Payload Type: Representation"); - int i = 1; + uint32_t i = 1; for (OCRepPayload* rep = payload; rep; rep = rep->next, ++i) { OIC_LOG_V(level, PL_TAG, "\tResource #%d", i); @@ -237,7 +237,7 @@ INLINE_API void OCPayloadLogDiscovery(LogLevel level, OCDiscoveryPayload* payloa OCResourcePayload* res = payload->resources; - int i = 1; + uint32_t i = 1; while(res) { OIC_LOG_V(level, PL_TAG, "\tResource #%d", i); @@ -260,6 +260,20 @@ INLINE_API void OCPayloadLogDiscovery(LogLevel level, OCDiscoveryPayload* payloa OIC_LOG_V(level, PL_TAG, "\tBitmap: %u", res->bitmap); OIC_LOG_V(level, PL_TAG, "\tSecure?: %s", res->secure ? "true" : "false"); OIC_LOG_V(level, PL_TAG, "\tPort: %u", res->port); + + uint32_t j = 1; + OCEndpointPayload* eps = res->eps; + while (eps) + { + OIC_LOG_V(level, PL_TAG, "\tEndpoint #%d", j); + OIC_LOG_V(level, PL_TAG, "\t\ttps: %s", eps->tps); + OIC_LOG_V(level, PL_TAG, "\t\taddr: %s", eps->addr); + OIC_LOG_V(level, PL_TAG, "\t\tport: %d", eps->port); + OIC_LOG_V(level, PL_TAG, "\t\tpri: %d", eps->pri); + eps = eps->next; + ++j; + } + OIC_LOG(level, PL_TAG, ""); res = res->next; ++i; diff --git a/resource/csdk/stack/samples/linux/SimpleClientServer/SConscript b/resource/csdk/stack/samples/linux/SimpleClientServer/SConscript index 020be7c..e2e7cf8 100644 --- a/resource/csdk/stack/samples/linux/SimpleClientServer/SConscript +++ b/resource/csdk/stack/samples/linux/SimpleClientServer/SConscript @@ -59,7 +59,10 @@ if target_os not in ['windows']: samples_env.PrependUnique(LIBS = ['m']) if samples_env.get('SECURED') == '1': - samples_env.AppendUnique(LIBS = ['tinydtls']) + samples_env.AppendUnique(LIBS = ['tinydtls']) + +if target_os in ['windows']: + samples_env.AppendUnique(LIBS = ['ws2_32']) samples_env.AppendUnique(CPPDEFINES = ['TB_LOG']) diff --git a/resource/csdk/stack/samples/linux/SimpleClientServer/occlient.cpp b/resource/csdk/stack/samples/linux/SimpleClientServer/occlient.cpp index 91e445a..f8d58db 100644 --- a/resource/csdk/stack/samples/linux/SimpleClientServer/occlient.cpp +++ b/resource/csdk/stack/samples/linux/SimpleClientServer/occlient.cpp @@ -140,6 +140,12 @@ static void PrintUsage() "add vendor specific header options"); OIC_LOG(INFO, TAG, "-t 19 : Discover Platform"); OIC_LOG(INFO, TAG, "-t 20 : Discover Devices"); + OIC_LOG(INFO, TAG, "-t 21 : Discover Resources and Display endpoints of the server information"); + OIC_LOG(INFO, TAG, "-t 22 : Discover Resources and Perform Get Requests by IPv4 + COAP + UDP "\ + "using server's endpoints information"); + OIC_LOG(INFO, TAG, "-t 23 : Discover Resources and Perform Get Requests by IPv4 + COAP + TCP "\ + "using server's endpoints information"); + } OCStackResult InvokeOCDoResource(std::ostringstream &query, @@ -473,6 +479,15 @@ OCStackApplicationResult discoveryReqCB(void* ctx, OCDoHandle /*handle*/, case TEST_DISCOVER_DEV_REQ: InitDeviceDiscovery(OC_LOW_QOS); break; + case TEST_DISCOVER_REQ_SHOW_EPS: + showEndpointsInfo(resource); + break; + case TEST_GET_REQ_UDP: + InitGetRequestWithCoap(payload, true); + break; + case TEST_GET_REQ_TCP: + InitGetRequestWithCoap(payload, false); + break; default: PrintUsage(); break; @@ -812,6 +827,98 @@ int InitDiscovery(OCQualityOfService qos) return ret; } +int InitGetRequestWithCoap(OCDiscoveryPayload* dis, bool isUdp) +{ + if (!dis) + { + OIC_LOG(INFO, TAG, "Given payload is NULL!!!"); + return -1; + } + + // copy query + std::ostringstream query; + query << coapServerResource; + + // server addr + OCDevAddr dev; + + // find endpoint with ipv4, UDP or TCP + OCResourcePayload* res = dis->resources; + while (res) + { + OCEndpointPayload* eps = res->eps; + while (eps) + { + if (strcmp(eps->tps, (isUdp ? COAP_UDP : COAP_TCP)) == 0 && + strlen(eps->addr) < MAX_LENGTH_IPv4_ADDR) + { + OIC_LOG_V(INFO, TAG, "%s found!!!", (isUdp ? COAP_UDP : COAP_TCP)); + dev.adapter = (isUdp ? OC_ADAPTER_IP : OC_ADAPTER_TCP); + dev.flags = OC_IP_USE_V4; + dev.port = eps->port; + memcpy(dev.addr, eps->addr, sizeof(dev.addr)); + } + eps = eps->next; + } + res = res->next; + } + + if (dev.adapter == (isUdp ? OC_ADAPTER_IP : OC_ADAPTER_TCP) && dev.flags == OC_IP_USE_V4) + { + OIC_LOG_V(INFO, TAG, "dev addr is %s", dev.addr); + OIC_LOG_V(INFO, TAG, "dev port is %d", dev.port); + OIC_LOG_V(INFO, TAG, "dev flags is %d", dev.flags); + OIC_LOG_V(INFO, TAG, "dev adapter is %d", dev.adapter); + + // send ocdoresource + return (InvokeOCDoResource(query, &dev, OC_REST_GET, + OC_LOW_QOS, getReqCB, NULL, 0)); + } + else + { + OIC_LOG(INFO, TAG, "Endpoints infomation not found on given payload!!!"); + return -1; + } +} + +void showEndpointsInfo(OCResourcePayload* res) +{ + if (!res) + { + OIC_LOG(INFO, TAG, "No endpoints information in given payload"); + return; + } + + if (!res->eps) + { + OIC_LOG(INFO, TAG, "No endpoints information in given payload"); + return; + } + + OCEndpointPayload* eps = res->eps; + + while (eps) + { + if (eps->family == OC_IP_USE_V6) + { + OIC_LOG_V(INFO, TAG, "Resource [%s] has endpoint [%s://[%s]:%d]", + res->uri, eps->tps, eps->addr, eps->port); + } + else if (eps->family == OC_IP_USE_V4) + { + OIC_LOG_V(INFO, TAG, "Resource [%s] has endpoint [%s://%s:%d]", + res->uri, eps->tps, eps->addr, eps->port); + } + else + { + OIC_LOG_V(INFO, TAG, "Resource [%s] has endpoint [%s://%s]", + res->uri, eps->tps, eps->addr); + } + + eps = eps->next; + } +} + int main(int argc, char* argv[]) { int opt; diff --git a/resource/csdk/stack/samples/linux/SimpleClientServer/occlient.h b/resource/csdk/stack/samples/linux/SimpleClientServer/occlient.h index 10d0c85..dfe3acb 100644 --- a/resource/csdk/stack/samples/linux/SimpleClientServer/occlient.h +++ b/resource/csdk/stack/samples/linux/SimpleClientServer/occlient.h @@ -28,6 +28,8 @@ // Defines //----------------------------------------------------------------------------- #define TAG "occlient" +#define COAP_UDP "coap" +#define COAP_TCP "coap+tcp" #define DEFAULT_CONTEXT_VALUE 0x99 #ifndef MAX_LENGTH_IPv4_ADDR #define MAX_LENGTH_IPv4_ADDR 16 @@ -63,6 +65,9 @@ typedef enum { TEST_GET_REQ_NON_WITH_VENDOR_HEADER_OPTIONS, TEST_DISCOVER_PLATFORM_REQ, TEST_DISCOVER_DEV_REQ, + TEST_DISCOVER_REQ_SHOW_EPS, + TEST_GET_REQ_UDP, + TEST_GET_REQ_TCP, MAX_TESTS } CLIENT_TEST; @@ -94,8 +99,11 @@ std::string getIPAddrTBServer(OCClientResponse * clientResponse); /* Get the port number the server is listening on */ std::string getPortTBServer(OCClientResponse * clientResponse); +/* Show endpoints information in given resource payload */ +void showEndpointsInfo(OCResourcePayload* res); + /* Following are initialization functions for GET, Observe, PUT - * POST, Delete & Discovery operations + * POST, Delete & Discovery, Get with coap, get with coap+tcp operations */ int InitGetRequestToUnavailableResource(OCQualityOfService qos); int InitObserveRequest(OCQualityOfService qos); @@ -107,6 +115,7 @@ int InitGetRequest(OCQualityOfService qos); int InitDeviceDiscovery(OCQualityOfService qos); int InitPlatformDiscovery(OCQualityOfService qos); int InitDiscovery(OCQualityOfService qos); +int InitGetRequestWithCoap(OCDiscoveryPayload* dis, bool isUdp); /* Call delete operation on already deleted resource */ void* RequestDeleteDeathResourceTask(void* myqos); diff --git a/resource/csdk/stack/samples/linux/SimpleClientServer/ocserver.cpp b/resource/csdk/stack/samples/linux/SimpleClientServer/ocserver.cpp index da6a9ee..53d191a 100644 --- a/resource/csdk/stack/samples/linux/SimpleClientServer/ocserver.cpp +++ b/resource/csdk/stack/samples/linux/SimpleClientServer/ocserver.cpp @@ -42,12 +42,14 @@ #include "ocpayload.h" #include "ocserver.h" #include "common.h" +#include "oic_string.h" //string length of "/a/light/" + std::numeric_limits::digits10 + '\0'" // 9 + 9 + 1 = 19 const int URI_MAXSIZE = 19; static int gObserveNotifyType = 3; +static int gResourceCreateType = ENDPOINT_OPT_NONE; int gQuitFlag = 0; int gLightUnderObservation = 0; @@ -827,13 +829,41 @@ int createLightResource (char *uri, LightResource *lightResource) lightResource->state = false; lightResource->power= 0; - OCStackResult res = OCCreateResource(&(lightResource->handle), + OCTpsSchemeFlags endpointFlags = OC_NO_TPS; + switch (gResourceCreateType) + { + case DISPLAY_SUPPORTED_EPS_FLAG: + case CREATE_RESOURCE_OC_ALL: + // same as OCCreateResource(args...) + endpointFlags = OC_ALL; + break; + + case CREATE_RESOURCE_OC_COAP: + endpointFlags = OC_COAP; + break; + +#ifdef TCP_ADAPTER + case CREATE_RESOURCE_OC_COAP_TCP: + endpointFlags = OC_COAP_TCP; + break; + + case CREATE_RESOURCE_OC_COAP_WITH_TCP: + endpointFlags = (OCTpsSchemeFlags)(OC_COAP | OC_COAP_TCP); + break; +#endif + default: + endpointFlags = OC_ALL; + } + + OCStackResult res = OCCreateResourceWithEp(&(lightResource->handle), "core.light", "oc.mi.def", uri, OCEntityHandlerCb, NULL, - OC_DISCOVERABLE|OC_OBSERVABLE); + OC_DISCOVERABLE|OC_OBSERVABLE, + endpointFlags); + OIC_LOG_V(INFO, TAG, "Created Light resource with result: %s", getResult(res)); return 0; @@ -986,6 +1016,13 @@ static void PrintUsage() OIC_LOG(INFO, TAG, "Usage : ocserver -o <0|1>"); OIC_LOG(INFO, TAG, "-o 0 : Notify all observers"); OIC_LOG(INFO, TAG, "-o 1 : Notify list of observers"); + OIC_LOG(INFO, TAG, "-e 0 : Display supported endpoint flags"); + OIC_LOG(INFO, TAG, "-e 1 : Create resource without endpoint flags"); + OIC_LOG(INFO, TAG, "-e 2 : Create resource with endpoint flag OC_COAP"); +#ifdef TCP_ADAPTER + OIC_LOG(INFO, TAG, "-e 3 : Create resource with endpoint flag OC_COAP_TCP"); + OIC_LOG(INFO, TAG, "-e 4 : Create resource with endpoint flag OC_COAP | OC_COAP_TCP"); +#endif } #ifdef RA_ADAPTER @@ -1016,13 +1053,16 @@ int main(int argc, char* argv[]) #endif int opt = 0; - while ((opt = getopt(argc, argv, "o:s:p:d:u:w:r:j:")) != -1) + while ((opt = getopt(argc, argv, "o:e:s:p:d:u:w:r:j:")) != -1) { switch(opt) { case 'o': gObserveNotifyType = atoi(optarg); break; + case 'e': + gResourceCreateType = atoi(optarg); + break; #ifdef RA_ADAPTER case 's': rainfo.hostname = optarg; @@ -1052,7 +1092,15 @@ int main(int argc, char* argv[]) } } - if ((gObserveNotifyType != 0) && (gObserveNotifyType != 1)) + if ((gObserveNotifyType != 0) && (gObserveNotifyType != 1) && + gResourceCreateType == ENDPOINT_OPT_NONE) + { + PrintUsage(); + return -1; + } + + if (gResourceCreateType < DISPLAY_SUPPORTED_EPS_FLAG || + gResourceCreateType > ENDPOINT_OPT_NONE) { PrintUsage(); return -1; @@ -1077,6 +1125,39 @@ int main(int argc, char* argv[]) } #endif + if (DISPLAY_SUPPORTED_EPS_FLAG == gResourceCreateType) + { + char strBuff[SAMPLE_MAX_STR_BUFF_SIZE] = {0}; + OCTpsSchemeFlags deviceFlags = OCGetSupportedEndpointTpsFlags(); + + if (deviceFlags & OC_COAP) + { + OICStrcat(strBuff, sizeof(strBuff), "OC_COAP"); + } + if (deviceFlags & OC_COAPS) + { + OICStrcat(strBuff, sizeof(strBuff), ", OC_COAPS"); + } +#ifdef TCP_ADAPTER + if (deviceFlags & OC_COAP_TCP) + { + OICStrcat(strBuff, sizeof(strBuff), ", OC_COAP_TCP"); + } + if (deviceFlags & OC_COAPS_TCP) + { + OICStrcat(strBuff, sizeof(strBuff), ", OC_COAPS_TCP"); + } +#endif +#ifdef EDR_ADAPTER + if (deviceFlags & OC_COAP_RFCOMM) + { + OICStrcat(strBuff, sizeof(strBuff), ", OC_COAP_RFCOMM"); + } +#endif + OIC_LOG_V(INFO, TAG, "Endpoint flag %s is supported", strBuff); + return 0; + } + OCSetDefaultDeviceEntityHandler(OCDeviceEntityHandlerCb, NULL); OCStackResult registrationResult = diff --git a/resource/csdk/stack/samples/linux/SimpleClientServer/ocserver.h b/resource/csdk/stack/samples/linux/SimpleClientServer/ocserver.h index 8c87326..f07ee8f 100644 --- a/resource/csdk/stack/samples/linux/SimpleClientServer/ocserver.h +++ b/resource/csdk/stack/samples/linux/SimpleClientServer/ocserver.h @@ -29,6 +29,7 @@ #define TAG "ocserver" #define SAMPLE_MAX_NUM_OBSERVATIONS 8 #define SAMPLE_MAX_NUM_POST_INSTANCE 2 +#define SAMPLE_MAX_STR_BUFF_SIZE 100 //----------------------------------------------------------------------------- // Typedefs @@ -50,6 +51,15 @@ typedef struct OCResourceHandle resourceHandle; } Observers; +typedef enum +{ + DISPLAY_SUPPORTED_EPS_FLAG = 0, + CREATE_RESOURCE_OC_ALL, + CREATE_RESOURCE_OC_COAP, + CREATE_RESOURCE_OC_COAP_TCP, + CREATE_RESOURCE_OC_COAP_WITH_TCP, + ENDPOINT_OPT_NONE +} EndpointOption; //----------------------------------------------------------------------------- // Function prototype //----------------------------------------------------------------------------- diff --git a/resource/csdk/stack/src/ocendpoint.c b/resource/csdk/stack/src/ocendpoint.c index 6a5e7b0..10b53b0 100644 --- a/resource/csdk/stack/src/ocendpoint.c +++ b/resource/csdk/stack/src/ocendpoint.c @@ -384,7 +384,7 @@ exit: OCTpsSchemeFlags OCGetSupportedTpsFlags() { - OCTpsSchemeFlags ret = (OCTpsSchemeFlags)0; + OCTpsSchemeFlags ret = OC_NO_TPS; CATransportAdapter_t SelectedNetwork = CAGetSelectedNetwork(); if (SelectedNetwork & CA_ADAPTER_IP) @@ -397,7 +397,7 @@ OCTpsSchemeFlags OCGetSupportedTpsFlags() } } #ifdef TCP_ADAPTER - else if (SelectedNetwork & CA_ADAPTER_TCP) + if (SelectedNetwork & CA_ADAPTER_TCP) { ret = (OCTpsSchemeFlags)(ret | OC_COAP_TCP); @@ -408,7 +408,7 @@ OCTpsSchemeFlags OCGetSupportedTpsFlags() } #endif #ifdef EDR_ADAPTER - else if (SelectedNetwork & CA_ADAPTER_RFCOMM_BTEDR) + if (SelectedNetwork & CA_ADAPTER_RFCOMM_BTEDR) { ret = (OCTpsSchemeFlags)(ret | OC_COAP_RFCOMM); } diff --git a/resource/csdk/stack/src/ocpayload.c b/resource/csdk/stack/src/ocpayload.c index 6958938..a0554b7 100644 --- a/resource/csdk/stack/src/ocpayload.c +++ b/resource/csdk/stack/src/ocpayload.c @@ -31,6 +31,8 @@ #include "ocstackinternal.h" #include "ocresource.h" #include "logger.h" +#include "ocendpoint.h" +#include "cacommon.h" #define TAG "OIC_RI_PAYLOAD" #define CSV_SEPARATOR ',' @@ -1672,11 +1674,63 @@ OCResourcePayload* OCDiscoveryPayloadGetResource(OCDiscoveryPayload* payload, si return NULL; } +size_t OCEndpointPayloadGetEndpointCount(OCEndpointPayload* payload) +{ + size_t i = 0; + OCEndpointPayload* ep = payload; + while (ep) + { + ++i; + ep = ep->next; + } + return i; +} + +OCEndpointPayload* OCEndpointPayloadGetEndpoint(OCEndpointPayload* payload, size_t index) +{ + size_t i = 0; + OCEndpointPayload* ep = payload; + while (ep) + { + if (i == index) + { + return ep; + } + ++i; + ep = ep->next; + } + return NULL; +} + +void OCResourcePayloadAddNewEndpoint(OCResourcePayload* payload, OCEndpointPayload* endpoint) +{ + if (!payload) + { + return; + } + + if (!payload->eps) + { + payload->eps = endpoint; + } + else + { + OCEndpointPayload* ep = payload->eps; + while (ep->next) + { + ep = ep->next; + } + ep->next = endpoint; + } +} + +static OCResourcePayload* OCCopyResource(const OCResource* res, uint16_t securePort, + bool isVirtual, CAEndpoint_t *networkInfo, + uint32_t infoSize, const OCDevAddr *devAddr #ifndef TCP_ADAPTER -static OCResourcePayload* OCCopyResource(const OCResource* res, uint16_t securePort) + ) #else -static OCResourcePayload* OCCopyResource(const OCResource* res, uint16_t securePort, - uint16_t tcpPort) + , uint16_t tcpPort) #endif { OCResourcePayload* pl = (OCResourcePayload*)OICCalloc(1, sizeof(OCResourcePayload)); @@ -1780,6 +1834,84 @@ static OCResourcePayload* OCCopyResource(const OCResource* res, uint16_t secureP #ifdef TCP_ADAPTER pl->tcpPort = tcpPort; #endif + + if (isVirtual || !networkInfo || infoSize == 0 || !devAddr) + { + pl->eps = NULL; + } + else + { + OCEndpointPayload *lastNode = pl->eps; + if ((OC_ADAPTER_IP | OC_ADAPTER_TCP) & (devAddr->adapter)) + { + for (uint32_t i = 0; i < infoSize; i++) + { + CAEndpoint_t *info = networkInfo + i; + + if (info) + { + if (((CA_ADAPTER_IP | CA_ADAPTER_TCP) & info->adapter && + info->ifindex == devAddr->ifindex) || + info->adapter == CA_ADAPTER_RFCOMM_BTEDR) + { + OCTpsSchemeFlags matchedTps = OC_NO_TPS; + if (OC_STACK_OK != OCGetMatchedTpsFlags(info->adapter, + info->flags, + &matchedTps)) + { + return NULL; + } + + if ((res->endpointType) & matchedTps) + { + // create payload + OCEndpointPayload* tmpNode = (OCEndpointPayload*) + OICCalloc(1, sizeof(OCEndpointPayload)); + if (!tmpNode) + { + return NULL; + } + + OCStackResult ret = OCConvertTpsToString(matchedTps, &(tmpNode->tps)); + if (ret != OC_STACK_OK) + { + OCDiscoveryEndpointDestroy(tmpNode); + OCDiscoveryResourceDestroy(pl); + return NULL; + } + + tmpNode->addr = (char*)OICCalloc(MAX_ADDR_STR_SIZE, sizeof(char)); + if (!tmpNode->addr) + { + OCDiscoveryEndpointDestroy(tmpNode); + OCDiscoveryResourceDestroy(pl); + return NULL; + } + + memcpy(tmpNode->addr, info->addr, sizeof(info->addr)); + tmpNode->family = (OCTransportFlags)(info->flags); + tmpNode->port = info->port; + tmpNode->pri = 1; + tmpNode->next = NULL; + + // store in list + if (!pl->eps) + { + pl->eps = tmpNode; + lastNode = tmpNode; + } + else + { + lastNode->next = tmpNode; + lastNode = tmpNode; + } + } + } + } + } + } + } + return pl; } @@ -1787,13 +1919,37 @@ static OCResourcePayload* OCCopyResource(const OCResource* res, uint16_t secureP void OCDiscoveryPayloadAddResource(OCDiscoveryPayload* payload, const OCResource* res, uint16_t securePort) { - OCDiscoveryPayloadAddNewResource(payload, OCCopyResource(res, securePort)); + OCDiscoveryPayloadAddNewResource(payload, OCCopyResource(res, securePort, false, NULL, 0, NULL)); } #else void OCDiscoveryPayloadAddResource(OCDiscoveryPayload* payload, const OCResource* res, uint16_t securePort, uint16_t tcpPort) { - OCDiscoveryPayloadAddNewResource(payload, OCCopyResource(res, securePort, tcpPort)); + OCDiscoveryPayloadAddNewResource(payload, OCCopyResource(res, securePort, false, NULL, 0, NULL, tcpPort)); +} +#endif + +#ifndef TCP_ADAPTER +void OCDiscoveryPayloadAddResourceWithEps(OCDiscoveryPayload* payload, const OCResource* res, + uint16_t securePort, bool isVirtual, + void *networkInfo, uint32_t infoSize, + const OCDevAddr *devAddr) +{ + OCDiscoveryPayloadAddNewResource(payload, + OCCopyResource(res, securePort, isVirtual, + (CAEndpoint_t *)networkInfo, + infoSize, devAddr)); +} +#else +void OCDiscoveryPayloadAddResourceWithEps(OCDiscoveryPayload* payload, const OCResource* res, + uint16_t securePort, bool isVirtual, + void *networkInfo, uint32_t infoSize, + const OCDevAddr *devAddr, uint16_t tcpPort) +{ + OCDiscoveryPayloadAddNewResource(payload, + OCCopyResource(res, securePort, isVirtual, + (CAEndpoint_t *)networkInfo, + infoSize, devAddr, tcpPort)); } #endif @@ -1850,6 +2006,19 @@ void OCDiscoveryPayloadAddNewResource(OCDiscoveryPayload* payload, OCResourcePay } } +void OCDiscoveryEndpointDestroy(OCEndpointPayload* payload) +{ + if (!payload) + { + return; + } + + OICFree(payload->tps); + OICFree(payload->addr); + OCDiscoveryEndpointDestroy(payload->next); + OICFree(payload); +} + void OCDiscoveryResourceDestroy(OCResourcePayload* payload) { if (!payload) @@ -1860,9 +2029,9 @@ void OCDiscoveryResourceDestroy(OCResourcePayload* payload) OICFree(payload->uri); OCFreeOCStringLL(payload->types); OCFreeOCStringLL(payload->interfaces); + OCDiscoveryEndpointDestroy(payload->eps); OCDiscoveryResourceDestroy(payload->next); OICFree(payload); - } void OCDiscoveryPayloadDestroy(OCDiscoveryPayload* payload) { diff --git a/resource/csdk/stack/src/ocpayloadconvert.c b/resource/csdk/stack/src/ocpayloadconvert.c index 69a928e..af183b7 100644 --- a/resource/csdk/stack/src/ocpayloadconvert.c +++ b/resource/csdk/stack/src/ocpayloadconvert.c @@ -32,14 +32,21 @@ #include "ocrandom.h" #include "ocresourcehandler.h" #include "cbor.h" +#include "ocendpoint.h" #define TAG "OIC_RI_PAYLOADCONVERT" // Arbitrarily chosen size that seems to contain the majority of packages #define INIT_SIZE (255) -// Discovery Links Map Length. -#define LINKS_MAP_LEN 4 +// Discovery Links Map with endpoints Length. +#define LINKS_MAP_LEN_WITH_EPS (5) + +// Discovery Links Map without endpoints Length. +#define LINKS_MAP_LEN_WITHOUT_EPS (4) + +// Endpoint Map length, it contains "ep", "pri". +#define EP_MAP_LEN (2) // Functions all return either a CborError, or a negative version of the OC_STACK return values static int64_t OCConvertPayloadHelper(OCPayload *payload, uint8_t *outPayload, size_t *size); @@ -226,10 +233,10 @@ static int64_t OCConvertDiscoveryPayload(OCDiscoveryPayload *payload, uint8_t *o "di": "0685B960-736F-46F7-BEC0-9E6CBD61ADC1", links :[ // linksArray contains maps of resources { - href, rt, if, policy // Resource 1 + href, rt, if, policy, eps // Resource 1 }, { - href, rt, if, policy // Resource 2 + href, rt, if, policy, eps // Resource 2 }, . . @@ -296,8 +303,16 @@ static int64_t OCConvertDiscoveryPayload(OCDiscoveryPayload *payload, uint8_t *o VERIFY_PARAM_NON_NULL(TAG, resource, "Failed retrieving resource"); // resource map inside the links array. - err |= cbor_encoder_create_map(&linkArray, &linkMap, LINKS_MAP_LEN); - VERIFY_CBOR_SUCCESS(TAG, err, "Failed creating links map"); + if (resource->eps) + { + err |= cbor_encoder_create_map(&linkArray, &linkMap, LINKS_MAP_LEN_WITH_EPS); + VERIFY_CBOR_SUCCESS(TAG, err, "Failed creating links map"); + } + else + { + err |= cbor_encoder_create_map(&linkArray, &linkMap, LINKS_MAP_LEN_WITHOUT_EPS); + VERIFY_CBOR_SUCCESS(TAG, err, "Failed creating links map"); + } // Below are insertions of the resource properties into the map. // Uri @@ -358,10 +373,52 @@ static int64_t OCConvertDiscoveryPayload(OCDiscoveryPayload *payload, uint8_t *o err |= cbor_encode_uint(&policyMap, resource->tcpPort); VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding tcp port value"); #endif - err |= cbor_encoder_close_container(&linkMap, &policyMap); VERIFY_CBOR_SUCCESS(TAG, err, "Failed closing policy map"); + // Endpoints + size_t epsCount = OCEndpointPayloadGetEndpointCount(resource->eps); + + // Embed Endpoints in discovery response when any endpoint exist on the resource. + if (epsCount > 0) + { + CborEncoder epsArray; + err |= cbor_encode_text_string(&linkMap, OC_RSRVD_ENDPOINTS, + sizeof(OC_RSRVD_ENDPOINTS) - 1); + VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting endpoints array tag"); + + err |= cbor_encoder_create_array(&linkMap, &epsArray, epsCount); + VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting endpoints array"); + + for (size_t i = 0; i < epsCount; ++i) + { + CborEncoder endpointMap; + OCEndpointPayload* endpoint = OCEndpointPayloadGetEndpoint(resource->eps, i); + VERIFY_PARAM_NON_NULL(TAG, endpoint, "Failed retrieving endpoint"); + + char* endpointStr = OCCreateEndpointString(endpoint); + VERIFY_PARAM_NON_NULL(TAG, endpointStr, "Failed creating endpoint string"); + + err |= cbor_encoder_create_map(&epsArray, &endpointMap, EP_MAP_LEN); + VERIFY_CBOR_SUCCESS(TAG, err, "Failed creating endpoint map"); + + err |= AddTextStringToMap(&endpointMap, OC_RSRVD_ENDPOINT, + sizeof(OC_RSRVD_ENDPOINT) - 1, endpointStr); + VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding endpoint to endpoint map"); + + err |= cbor_encode_text_string(&endpointMap, OC_RSRVD_PRIORITY, + sizeof(OC_RSRVD_PRIORITY) - 1); + VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding priority tag to endpoint map"); + err |= cbor_encode_uint(&endpointMap, endpoint->pri); + VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding priority value to endpoint map"); + + err |= cbor_encoder_close_container(&epsArray, &endpointMap); + VERIFY_CBOR_SUCCESS(TAG, err, "Failed closing endpoint map"); + } + + err |= cbor_encoder_close_container(&linkMap, &epsArray); + VERIFY_CBOR_SUCCESS(TAG, err, "Failed closing endpoints map"); + } // Finsihed encoding a resource, close the map. err |= cbor_encoder_close_container(&linkArray, &linkMap); VERIFY_CBOR_SUCCESS(TAG, err, "Failed closing link map"); diff --git a/resource/csdk/stack/src/ocpayloadparse.c b/resource/csdk/stack/src/ocpayloadparse.c index 3366fc2..44d5588 100644 --- a/resource/csdk/stack/src/ocpayloadparse.c +++ b/resource/csdk/stack/src/ocpayloadparse.c @@ -36,6 +36,7 @@ #include "ocstackinternal.h" #include "payload_logging.h" #include "platform_features.h" +#include "ocendpoint.h" #define TAG "OIC_RI_PAYLOADPARSE" @@ -175,6 +176,7 @@ static OCStackResult OCParseDiscoveryPayload(OCPayload **outPayload, CborValue * OCDiscoveryPayload *temp = NULL; OCDiscoveryPayload *rootPayload = NULL; OCDiscoveryPayload *curPayload = NULL; + OCEndpointPayload *endpoint = NULL; size_t len = 0; CborError err = CborNoError; *outPayload = NULL; @@ -345,6 +347,64 @@ static OCStackResult OCParseDiscoveryPayload(OCPayload **outPayload, CborValue * resource->tcpPort = (uint16_t)tcpPort; } #endif + // Endpoints + CborValue epsMap; + err = cbor_value_map_find_value(&resourceMap, OC_RSRVD_ENDPOINTS, &epsMap); + VERIFY_CBOR_SUCCESS(TAG, err, "to find eps tag"); + + if (cbor_value_is_valid(&epsMap)) + { + CborValue epMap; + err = cbor_value_enter_container(&epsMap, &epMap); + VERIFY_CBOR_SUCCESS(TAG, err, "to enter endpoint map"); + + while (cbor_value_is_map(&epMap)) + { + endpoint = NULL; + int pri = 0; + char *endpointStr = NULL; + OCStackResult ret = OC_STACK_ERROR; + endpoint = (OCEndpointPayload *)OICCalloc(1, sizeof(OCEndpointPayload)); + VERIFY_PARAM_NON_NULL(TAG, endpoint, "Failed allocating endpoint payload"); + + // ep + err = cbor_value_map_find_value(&epMap, OC_RSRVD_ENDPOINT, &curVal); + VERIFY_CBOR_SUCCESS(TAG, err, "to find endpoint tag"); + err = cbor_value_dup_text_string(&curVal, &endpointStr, &len, NULL); + VERIFY_CBOR_SUCCESS(TAG, err, "to find endpoint value"); + + ret = OCParseEndpointString(endpointStr, endpoint); + OICFree(endpointStr); + + if (OC_STACK_OK == ret) + { + // pri + err = cbor_value_map_find_value(&epMap, OC_RSRVD_PRIORITY, &curVal); + VERIFY_CBOR_SUCCESS(TAG, err, "to find priority tag"); + err = cbor_value_get_int(&curVal, &pri); + VERIFY_CBOR_SUCCESS(TAG, err, "to find priority value"); + endpoint->pri = (uint16_t)pri; + OCResourcePayloadAddNewEndpoint(resource, endpoint); + endpoint = NULL; + } + else + { + if (OC_STACK_ADAPTER_NOT_ENABLED == ret) + { + OIC_LOG(ERROR, TAG, "Ignore unrecognized endpoint info"); + } + // destroy endpoint + OCDiscoveryEndpointDestroy(endpoint); + endpoint = NULL; + } + + err = cbor_value_advance(&epMap); + VERIFY_CBOR_SUCCESS(TAG, err, "to advance endpoint map"); + } + + err = cbor_value_leave_container(&epsMap, &epMap); + VERIFY_CBOR_SUCCESS(TAG, err, "to leave eps map"); + } err = cbor_value_advance(&resourceMap); VERIFY_CBOR_SUCCESS(TAG, err, "to advance resource map"); @@ -386,6 +446,7 @@ static OCStackResult OCParseDiscoveryPayload(OCPayload **outPayload, CborValue * return OC_STACK_OK; exit: + OCDiscoveryEndpointDestroy(endpoint); OCDiscoveryResourceDestroy(resource); OCDiscoveryPayloadDestroy(rootPayload); return ret; diff --git a/resource/csdk/stack/src/ocresource.c b/resource/csdk/stack/src/ocresource.c index a987b29..7a002e3 100755 --- a/resource/csdk/stack/src/ocresource.c +++ b/resource/csdk/stack/src/ocresource.c @@ -52,6 +52,9 @@ #include "ocpayload.h" #include "platform_features.h" #include "payload_logging.h" +#include "ocendpoint.h" +#include "ocstackinternal.h" + #ifdef ROUTING_GATEWAY #include "routingmanager.h" #endif @@ -68,8 +71,10 @@ extern OCResource *headResource; * Prepares a Payload for response. */ static OCStackResult BuildVirtualResourceResponse(const OCResource *resourcePtr, - OCDiscoveryPayload* payload, - OCDevAddr *endpoint); + OCDiscoveryPayload *payload, + OCDevAddr *endpoint, + CAEndpoint_t *networkInfo, + uint32_t infoSize); //----------------------------------------------------------------------------- // Default resource entity handler function @@ -420,9 +425,12 @@ OCStackResult BuildResponseRepresentation(const OCResource *resourcePtr, } OCStackResult BuildVirtualResourceResponse(const OCResource *resourcePtr, - OCDiscoveryPayload *payload, OCDevAddr *devAddr) + OCDiscoveryPayload *payload, + OCDevAddr *devAddr, + CAEndpoint_t *networkInfo, + uint32_t infoSize) { - if (!resourcePtr || !payload) + if (!resourcePtr || !payload || !networkInfo) { return OC_STACK_INVALID_PARAM; } @@ -435,15 +443,22 @@ OCStackResult BuildVirtualResourceResponse(const OCResource *resourcePtr, } } + bool isVirtual = false; + if (GetTypeOfVirtualURI(resourcePtr->uri) != OC_UNKNOWN_URI) + { + isVirtual = true; + } #ifdef TCP_ADAPTER uint16_t tcpPort = 0; if (GetTCPPortInfo(devAddr, &tcpPort) != OC_STACK_OK) { tcpPort = 0; } - OCDiscoveryPayloadAddResource(payload, resourcePtr, securePort, tcpPort); + OCDiscoveryPayloadAddResourceWithEps(payload, resourcePtr, securePort, + isVirtual, networkInfo, infoSize, devAddr, tcpPort); #else - OCDiscoveryPayloadAddResource(payload, resourcePtr, securePort); + OCDiscoveryPayloadAddResourceWithEps(payload, resourcePtr, securePort, + isVirtual, networkInfo, infoSize, devAddr); #endif return OC_STACK_OK; @@ -484,6 +499,37 @@ OCResource *FindResourceByUri(const char* resourceUri) return NULL; } +OCStackResult CheckRequestsEndpoint(const OCDevAddr *reqDevAddr, + OCTpsSchemeFlags resTpsFlags) +{ + if (!reqDevAddr) + { + OIC_LOG(ERROR, TAG, "OCDevAddr* is NULL!!!"); + return OC_STACK_INVALID_PARAM; + } + + OCTpsSchemeFlags reqTpsFlags = OC_NO_TPS; + OCStackResult result = OCGetMatchedTpsFlags((CATransportAdapter_t)reqDevAddr->adapter, + (CATransportFlags_t)reqDevAddr->flags, &reqTpsFlags); + + if (result != OC_STACK_OK) + { + OIC_LOG_V(ERROR, TAG, "Failed at get TPS flags. errcode is %d", result); + return result; + } + + // bit compare between request tps flags and resource tps flags + if (reqTpsFlags & resTpsFlags) + { + OIC_LOG(INFO, TAG, "Request come from registered TPS"); + return OC_STACK_OK; + } + else + { + OIC_LOG(ERROR, TAG, "Request come from unregistered TPS!!!"); + return OC_STACK_BAD_ENDPOINT; + } +} OCStackResult DetermineResourceHandling (const OCServerRequest *request, ResourceHandling *handling, @@ -514,6 +560,27 @@ OCStackResult DetermineResourceHandling (const OCServerRequest *request, { OCResource *resourcePtr = FindResourceByUri((const char*)request->resourceUrl); *resource = resourcePtr; + + // Checking resource TPS flags if resource exist in stack. + if (resourcePtr) + { + OCStackResult result = CheckRequestsEndpoint(&(request->devAddr), resourcePtr->endpointType); + + if (result != OC_STACK_OK) + { + if (result == OC_STACK_BAD_ENDPOINT) + { + OIC_LOG(ERROR, TAG, "Request come from bad endpoint. ignore request!!!"); + return OC_STACK_BAD_ENDPOINT; + } + else + { + OIC_LOG_V(ERROR, TAG, "Failed at get tps flag errcode: %d", result); + return result; + } + } + } + if (!resourcePtr) { if(defaultDeviceHandler) @@ -840,6 +907,28 @@ static OCStackResult HandleVirtualResource (OCServerRequest *request, OCResource #endif ) { + if (request->method == OC_REST_PUT || request->method == OC_REST_POST || + request->method == OC_REST_DELETE) + { + OIC_LOG_V(ERROR, TAG, "Resource : %s not permitted for method: %d", + request->resourceUrl, request->method); + discoveryResult = OC_STACK_UNAUTHORIZED_REQ; + goto exit; + } + + char *interfaceQuery = NULL; + char *resourceTypeQuery = NULL; + + CAEndpoint_t *networkInfo = NULL; + uint32_t infoSize = 0; + + CAResult_t caResult = CAGetNetworkInformation(&networkInfo, &infoSize); + if (CA_STATUS_OK != caResult || !networkInfo || infoSize == 0) + { + OIC_LOG(ERROR, TAG, "CAGetNetworkInformation has error on parsing network infomation"); + return OC_STACK_ERROR; + } + discoveryResult = getQueryParamsForFiltering (virtualUriInRequest, request->query, &interfaceQuery, &resourceTypeQuery); VERIFY_SUCCESS(discoveryResult); @@ -881,11 +970,19 @@ static OCStackResult HandleVirtualResource (OCServerRequest *request, OCResource // This case will handle when no resource type and it is oic.if.ll. if (!resourceTypeQuery && !baselineQuery && (resource->resourceProperties & prop)) { - discoveryResult = BuildVirtualResourceResponse(resource, discPayload, &request->devAddr); + discoveryResult = BuildVirtualResourceResponse(resource, + discPayload, + &request->devAddr, + networkInfo, + infoSize); } else if (includeThisResourceInResponse(resource, interfaceQuery, resourceTypeQuery)) { - discoveryResult = BuildVirtualResourceResponse(resource, discPayload, &request->devAddr); + discoveryResult = BuildVirtualResourceResponse(resource, + discPayload, + &request->devAddr, + networkInfo, + infoSize); } else { @@ -897,6 +994,11 @@ static OCStackResult HandleVirtualResource (OCServerRequest *request, OCResource { discoveryResult = OC_STACK_NO_RESOURCE; } + + if (networkInfo) + { + OICFree(networkInfo); + } } else if (virtualUriInRequest == OC_DEVICE_URI) { diff --git a/resource/csdk/stack/src/ocstack.c b/resource/csdk/stack/src/ocstack.c index 4b5b810..c89716f 100644 --- a/resource/csdk/stack/src/ocstack.c +++ b/resource/csdk/stack/src/ocstack.c @@ -60,6 +60,7 @@ #include "ocpayloadcbor.h" #include "cautilinterface.h" #include "oicgroup.h" +#include "ocendpoint.h" #if defined (ROUTING_GATEWAY) || defined (ROUTING_EP) #include "routingutility.h" @@ -752,6 +753,8 @@ CAResponseResult_t OCToCAStackResult(OCStackResult ocCode, OCMethod method) case OC_STACK_INTERNAL_SERVER_ERROR: ret = CA_INTERNAL_SERVER_ERROR; break; + case OC_STACK_BAD_ENDPOINT: + ret = CA_BAD_REQ; default: break; } @@ -1983,9 +1986,8 @@ void OCHandleRequests(const CAEndpoint_t* endPoint, const CARequestInfo_t* reque requestResult = HandleStackRequests (&serverRequest); - // Send ACK to client as precursor to slow response if (requestResult == OC_STACK_SLOW_RESOURCE) - { + { // Send ACK to client as precursor to slow response if (requestInfo->info.type == CA_MSG_CONFIRM) { SendDirectStackResponse(endPoint, requestInfo->info.messageId, CA_EMPTY, @@ -3217,13 +3219,35 @@ OCStackResult OCSetDefaultDeviceEntityHandler(OCDeviceEntityHandler entityHandle return OC_STACK_OK; } +OCTpsSchemeFlags OCGetSupportedEndpointTpsFlags() +{ + return OCGetSupportedTpsFlags(); +} + OCStackResult OCCreateResource(OCResourceHandle *handle, const char *resourceTypeName, const char *resourceInterfaceName, const char *uri, OCEntityHandler entityHandler, - void* callbackParam, + void *callbackParam, uint8_t resourceProperties) { + return OCCreateResourceWithEp(handle, + resourceTypeName, + resourceInterfaceName, + uri, entityHandler, + callbackParam, + resourceProperties, + OC_ALL); +} + +OCStackResult OCCreateResourceWithEp(OCResourceHandle *handle, + const char *resourceTypeName, + const char *resourceInterfaceName, + const char *uri, OCEntityHandler entityHandler, + void *callbackParam, + uint8_t resourceProperties, + OCTpsSchemeFlags resourceTpsTypes) +{ OCResource *pointer = NULL; OCStackResult result = OC_STACK_ERROR; @@ -3271,6 +3295,26 @@ OCStackResult OCCreateResource(OCResourceHandle *handle, return OC_STACK_INVALID_PARAM; } + // Checking resourceTpsTypes param + OCTpsSchemeFlags validTps = OC_NO_TPS; + validTps = (OCTpsSchemeFlags)(validTps | OC_COAP | OC_COAPS); +#ifdef TCP_ADAPTER + validTps = (OCTpsSchemeFlags)(validTps | OC_COAP_TCP | OC_COAPS_TCP); +#endif +#ifdef HTTP_ADAPTER + validTps = (OCTpsSchemeFlags)(validTps | OC_HTTP | OC_HTTP); +#endif +#ifdef EDR_ADAPTER + validTps = (OCTpsSchemeFlags)(validTps | OC_COAP_RFCOMM); +#endif + + if ((resourceTpsTypes < OC_COAP) || ((resourceTpsTypes != OC_ALL) && + (resourceTpsTypes > validTps))) + { + OIC_LOG(ERROR, TAG, "Invalid TPS Types OC_ALL"); + return OC_STACK_INVALID_PARAM; + } + // If the headResource is NULL, then no resources have been created... pointer = headResource; if (pointer) @@ -3326,6 +3370,13 @@ OCStackResult OCCreateResource(OCResourceHandle *handle, goto exit; } + result = BindTpsTypeToResource(pointer, resourceTpsTypes); + if (result != OC_STACK_OK) + { + OIC_LOG(ERROR, TAG, "Error adding resource TPS types"); + goto exit; + } + // If an entity handler has been passed, attach it to the newly created // resource. Otherwise, set the default entity handler. if (entityHandler) @@ -3654,6 +3705,37 @@ OCStackResult BindResourceInterfaceToResource(OCResource* resource, return result; } +OCStackResult BindTpsTypeToResource(OCResource* resource, + OCTpsSchemeFlags resourceTpsTypes) +{ + if (!resource) + { + OIC_LOG(ERROR, TAG, "Resource pointer is NULL!!!"); + return OC_STACK_INVALID_PARAM; + } + + OCTpsSchemeFlags supportedTps = OC_NO_TPS; + OCStackResult result = OCGetSupportedEndpointFlags(resourceTpsTypes, + &supportedTps); + + if (result != OC_STACK_OK) + { + OIC_LOG(ERROR, TAG, "Failed at get supported endpoint flags"); + return result; + } + + // If there isn`t any enabled flag, return error for notify to user. + if (OC_NO_TPS == supportedTps) + { + OIC_LOG_V(ERROR, TAG, "There isn`t any enabled flag on resource %s", resource->uri); + return OC_STACK_BAD_ENDPOINT; + } + + OIC_LOG_V(INFO, TAG, "Binding %d TPS flags to %s", supportedTps, resource->uri); + resource->endpointType = supportedTps; + return result; +} + OCStackResult OCBindResourceTypeToResource(OCResourceHandle handle, const char *resourceTypeName) { diff --git a/resource/csdk/stack/test/stacktests.cpp b/resource/csdk/stack/test/stacktests.cpp index d48e5b3..8fd4cd6 100644 --- a/resource/csdk/stack/test/stacktests.cpp +++ b/resource/csdk/stack/test/stacktests.cpp @@ -55,6 +55,8 @@ using namespace std; namespace itst = iotivity::test; #define DEFAULT_CONTEXT_VALUE 0x99 +#define INVALID_TPS_FLAGS (250) +#define INVALID_TPS_FLAGS_ZERO (0) //----------------------------------------------------------------------------- // Private variables @@ -873,6 +875,78 @@ TEST(StackResource, CreateResourceGoodResourceType) EXPECT_EQ(OC_STACK_OK, OCStop()); } +TEST(StackResource, CreateResourceWithBadEndpointsFlags) +{ + itst::DeadmanTimer killSwitch(SHORT_TEST_TIMEOUT); + + OIC_LOG(INFO, TAG, "CreateResourceWithEndpointsFlags test"); + + InitStack(OC_SERVER); + + OCResourceHandle handle; + EXPECT_EQ(OC_STACK_INVALID_PARAM, OCCreateResourceWithEp(&handle, + "core.led", + "core.rw", + "/a/led", + 0, + NULL, + OC_DISCOVERABLE|OC_OBSERVABLE, + (OCTpsSchemeFlags)INVALID_TPS_FLAGS)); + + EXPECT_EQ(OC_STACK_OK, OCStop()); +} + +TEST(StackResource, CreateResourceWithGoodEndpointsFlags) +{ + itst::DeadmanTimer killSwitch(SHORT_TEST_TIMEOUT); + + OIC_LOG(INFO, TAG, "CreateResourceWithEndpointsFlags test"); + + InitStack(OC_SERVER); + + OCResourceHandle handle; + EXPECT_EQ(OC_STACK_OK, OCCreateResourceWithEp(&handle, + "core.led", + "core.rw", + "/a/led", + 0, + NULL, + OC_DISCOVERABLE|OC_OBSERVABLE, + OC_ALL)); + OCResourceHandle handle2; + EXPECT_EQ(OC_STACK_OK, OCCreateResourceWithEp(&handle2, + "core.led", + "core.rw", + "/a/led2", + 0, + NULL, + OC_DISCOVERABLE|OC_OBSERVABLE, + OC_COAP)); +#ifdef TCP_ADAPTER + OCResourceHandle handle3; + EXPECT_EQ(OC_STACK_OK, OCCreateResourceWithEp(&handle3, + "core.led", + "core.rw", + "/a/led3", + 0, + NULL, + OC_DISCOVERABLE|OC_OBSERVABLE, + OC_COAP_TCP)); + + OCResourceHandle handle4; + EXPECT_EQ(OC_STACK_OK, OCCreateResourceWithEp(&handle4, + "core.led", + "core.rw", + "/a/led4", + 0, + NULL, + OC_DISCOVERABLE|OC_OBSERVABLE, + (OCTpsSchemeFlags)(OC_COAP | OC_COAP_TCP))); +#endif + + EXPECT_EQ(OC_STACK_OK, OCStop()); +} + TEST(StackResource, ResourceTypeName) { itst::DeadmanTimer killSwitch(SHORT_TEST_TIMEOUT); @@ -2141,3 +2215,16 @@ TEST(StackHeaderOption, getHeaderOption) EXPECT_EQ(optionData[0], 1); EXPECT_EQ(actualDataSize, 8); } + +TEST(StackEndpoints, OCGetSupportedEndpointTpsFlags) +{ + itst::DeadmanTimer killSwitch(SHORT_TEST_TIMEOUT); + + OIC_LOG(INFO, TAG, "OCGetSupportedEndpointTpsFlags test"); + + InitStack(OC_SERVER); + + EXPECT_LE(INVALID_TPS_FLAGS_ZERO, OCGetSupportedEndpointTpsFlags()); + + EXPECT_EQ(OC_STACK_OK, OCStop()); +} -- 2.7.4