From 13c3d44533a6f0b1a61e383af2ca0e3d60e3225e Mon Sep 17 00:00:00 2001 From: Habib Virji Date: Fri, 11 Mar 2016 12:37:43 +0000 Subject: [PATCH] [IOT-921]Return correct resource type in /oic/d It adds support to add device resource type via API. Jira Issue: IOT-921 Signed-off-by: Habib Virji Change-Id: Ib47f637ff343b5bc8dbce5d5f0cc2b5f1eab46ab Reviewed-on: https://gerrit.iotivity.org/gerrit/5747 Tested-by: jenkins-iotivity Reviewed-on: https://gerrit.iotivity.org/gerrit/7825 --- plugins/samples/linux/IotivityandZigbeeServer.c | 12 ++++-- resource/csdk/stack/include/ocpayload.h | 2 +- resource/csdk/stack/include/octypes.h | 20 +++++----- resource/csdk/stack/include/payload_logging.h | 8 ++++ .../samples/linux/SimpleClientServer/ocserver.cpp | 3 ++ .../samples/tizen/SimpleClientServer/ocserver.cpp | 3 ++ resource/csdk/stack/src/ocpayload.c | 9 ++++- resource/csdk/stack/src/ocpayloadconvert.c | 15 ++++++++ resource/csdk/stack/src/ocpayloadparse.c | 9 ++++- resource/csdk/stack/src/ocresource.c | 13 ++++++- resource/examples/devicediscoveryserver.cpp | 7 ++-- resource/src/OCRepresentation.cpp | 4 ++ resource/unittests/OCPlatformTest.cpp | 43 +++++++++++++++++++++- .../unittests/OCRepresentationEncodingTest.cpp | 9 +++++ 14 files changed, 134 insertions(+), 23 deletions(-) diff --git a/plugins/samples/linux/IotivityandZigbeeServer.c b/plugins/samples/linux/IotivityandZigbeeServer.c index 30a8c79..dc011aa 100644 --- a/plugins/samples/linux/IotivityandZigbeeServer.c +++ b/plugins/samples/linux/IotivityandZigbeeServer.c @@ -22,6 +22,8 @@ #include #include #include +#include "oic_string.h" +#include "oic_malloc.h" #define TAG "IoTivityZigbeeServer" #define defaultComPort "/dev/ttyUSB0" @@ -134,11 +136,14 @@ OCStackResult SetPlatformInfo() OCStackResult SetDeviceInfo() { - static const OCDeviceInfo deviceInfo = + static OCDeviceInfo deviceInfo = { - .deviceName = "IoTivity/Zigbee Server Sample" + .deviceName = "IoTivity/Zigbee Server Sample", }; - + char *dup = OICStrdup("oic.wk.d"); + deviceInfo.types = (OCStringLL *)OICCalloc(1, sizeof(OCStringLL)); + deviceInfo.types->value = dup; + OICFree(dup); return OCSetDeviceInfo(deviceInfo); } @@ -160,4 +165,3 @@ void processCancel(int signal) processSignal(true); } } - diff --git a/resource/csdk/stack/include/ocpayload.h b/resource/csdk/stack/include/ocpayload.h index 789d5d7..8354eb9 100755 --- a/resource/csdk/stack/include/ocpayload.h +++ b/resource/csdk/stack/include/ocpayload.h @@ -235,7 +235,7 @@ void OCDiscoveryPayloadDestroy(OCDiscoveryPayload* payload); // Device Payload OCDevicePayload* OCDevicePayloadCreate(const char* sid, const char* dname, - const char* specVer, const char* dmVer); + const OCStringLL *types, const char* specVer, const char* dmVer); void OCDevicePayloadDestroy(OCDevicePayload* payload); // Platform Payload diff --git a/resource/csdk/stack/include/octypes.h b/resource/csdk/stack/include/octypes.h index 8196a83..fcdc71d 100644 --- a/resource/csdk/stack/include/octypes.h +++ b/resource/csdk/stack/include/octypes.h @@ -425,6 +425,12 @@ typedef enum #define OC_MASK_MODS (0x0FF0) #define OC_MASK_FAMS (OC_IP_USE_V6|OC_IP_USE_V4) +typedef struct OCStringLL +{ + struct OCStringLL *next; + char* value; +} OCStringLL; + /** * End point identity. */ @@ -931,7 +937,8 @@ typedef struct { /** Pointer to the device name.*/ char *deviceName; - + /** Pointer to the types.*/ + OCStringLL *types; } OCDeviceInfo; #ifdef RA_ADAPTER @@ -1040,12 +1047,6 @@ typedef struct OCRepPayloadValue } OCRepPayloadValue; -typedef struct OCStringLL -{ - struct OCStringLL *next; - char* value; -} OCStringLL; - // used for get/set/put/observe/etc representations typedef struct OCRepPayload { @@ -1193,7 +1194,8 @@ typedef struct typedef struct { OCPayload base; - char* sid; + char *sid; + OCStringLL *types; char* deviceName; char* specVersion; char* dataModelVersion; @@ -1437,7 +1439,7 @@ typedef OCEntityHandlerResult (*OCDeviceEntityHandler) * Callback function definition of direct-pairing * * @param[OUT] peer - pairing device info. - * @param[OUT} result - It's returned with 'OC_STACK_XXX'. It will return 'OC_STACK_OK' + * @param[OUT} result - It's returned with 'OC_STACK_XXX'. It will return 'OC_STACK_OK' * if D2D pairing is success without error */ typedef void (*OCDirectPairingCB)(OCDPDev_t *peer, OCStackResult result); diff --git a/resource/csdk/stack/include/payload_logging.h b/resource/csdk/stack/include/payload_logging.h index f94500a..746f360 100644 --- a/resource/csdk/stack/include/payload_logging.h +++ b/resource/csdk/stack/include/payload_logging.h @@ -212,6 +212,14 @@ static inline void OCPayloadLogDevice(LogLevel level, OCDevicePayload* payload) OIC_LOG_V(level, PL_TAG, "\tDevice Name:%s", payload->deviceName); OIC_LOG_V(level, PL_TAG, "\tSpec Version%s", payload->specVersion); OIC_LOG_V(level, PL_TAG, "\tData Model Version:%s", payload->dataModelVersion); + if (payload->types) + { + OIC_LOG(level, PL_TAG, "\tResource Type:"); + for (OCStringLL *strll = payload->types; strll; strll = strll->next) + { + OIC_LOG_V(level, PL_TAG, "\t\t%s", strll->value); + } + } } static inline void OCPayloadLogPlatform(LogLevel level, OCPlatformPayload* payload) diff --git a/resource/csdk/stack/samples/linux/SimpleClientServer/ocserver.cpp b/resource/csdk/stack/samples/linux/SimpleClientServer/ocserver.cpp index 018d34d..5eaa227 100644 --- a/resource/csdk/stack/samples/linux/SimpleClientServer/ocserver.cpp +++ b/resource/csdk/stack/samples/linux/SimpleClientServer/ocserver.cpp @@ -1051,6 +1051,9 @@ int main(int argc, char* argv[]) exit (EXIT_FAILURE); } + OCResourcePayloadAddStringLL(&deviceInfo.types, "oic.wk.d"); + OCResourcePayloadAddStringLL(&deviceInfo.types, "oic.d.tv"); + registrationResult = OCSetDeviceInfo(deviceInfo); if (registrationResult != OC_STACK_OK) diff --git a/resource/csdk/stack/samples/tizen/SimpleClientServer/ocserver.cpp b/resource/csdk/stack/samples/tizen/SimpleClientServer/ocserver.cpp index c5af603..9fa52e3 100644 --- a/resource/csdk/stack/samples/tizen/SimpleClientServer/ocserver.cpp +++ b/resource/csdk/stack/samples/tizen/SimpleClientServer/ocserver.cpp @@ -992,6 +992,9 @@ int main(int argc, char* argv[]) exit (EXIT_FAILURE); } + OCResourcePayloadAddStringLL(&deviceInfo.types, "oic.wk.d"); + OCResourcePayloadAddStringLL(&deviceInfo.types, "oic.d.tv"); + registrationResult = OCSetDeviceInfo(deviceInfo); if (registrationResult != OC_STACK_OK) diff --git a/resource/csdk/stack/src/ocpayload.c b/resource/csdk/stack/src/ocpayload.c index 09c5dc7..87c7e77 100755 --- a/resource/csdk/stack/src/ocpayload.c +++ b/resource/csdk/stack/src/ocpayload.c @@ -1534,7 +1534,7 @@ void OCDiscoveryPayloadDestroy(OCDiscoveryPayload* payload) } OCDevicePayload* OCDevicePayloadCreate(const char* sid, const char* dname, - const char* specVer, const char* dmVer) + const OCStringLL *types, const char* specVer, const char* dmVer) { OCDevicePayload* payload = (OCDevicePayload*)OICCalloc(1, sizeof(OCDevicePayload)); @@ -1569,6 +1569,12 @@ OCDevicePayload* OCDevicePayloadCreate(const char* sid, const char* dname, goto exit; } + payload->types = CloneOCStringLL((OCStringLL *)types); + if (types && !payload->types) + { + goto exit; + } + return payload; exit: @@ -1587,6 +1593,7 @@ void OCDevicePayloadDestroy(OCDevicePayload* payload) OICFree(payload->deviceName); OICFree(payload->specVersion); OICFree(payload->dataModelVersion); + OCFreeOCStringLL(payload->types); OICFree(payload); } diff --git a/resource/csdk/stack/src/ocpayloadconvert.c b/resource/csdk/stack/src/ocpayloadconvert.c index eb7c896..75cf6d9 100644 --- a/resource/csdk/stack/src/ocpayloadconvert.c +++ b/resource/csdk/stack/src/ocpayloadconvert.c @@ -381,6 +381,21 @@ static int64_t OCConvertDevicePayload(OCDevicePayload *payload, uint8_t *outPayl err |= cbor_encoder_create_map(&encoder, &repMap, CborIndefiniteLength); VERIFY_CBOR_SUCCESS(TAG, err, "Failed creating device map"); + // Resource Type + if (payload->types) + { + OIC_LOG(INFO, TAG, "Payload has types"); + err |= cbor_encode_text_string(&repMap, OC_RSRVD_RESOURCE_TYPE, + sizeof(OC_RSRVD_RESOURCE_TYPE) - 1); + VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding rep resource type tag"); + char *joinedTypes = OCStringLLJoin(payload->types); + printf(" JOINED TYPES : %s %zd \n", joinedTypes, strlen(joinedTypes)); + VERIFY_PARAM_NON_NULL(TAG, joinedTypes, "Failed creating joined string"); + err |= cbor_encode_text_string(&repMap, joinedTypes, strlen(joinedTypes)); + OICFree(joinedTypes); + VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding rep resource type value"); + } + // Device ID err |= AddTextStringToMap(&repMap, OC_RSRVD_DEVICE_ID, sizeof(OC_RSRVD_DEVICE_ID) - 1 , payload->sid); VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding device id"); diff --git a/resource/csdk/stack/src/ocpayloadparse.c b/resource/csdk/stack/src/ocpayloadparse.c index f06aec4..f731823 100755 --- a/resource/csdk/stack/src/ocpayloadparse.c +++ b/resource/csdk/stack/src/ocpayloadparse.c @@ -331,9 +331,16 @@ static OCStackResult OCParseDevicePayload(OCPayload **outPayload, CborValue *roo if (cbor_value_is_map(rootValue)) { + CborValue curVal; + // Resource Type + err = cbor_value_map_find_value(rootValue, OC_RSRVD_RESOURCE_TYPE, &curVal); + if (cbor_value_is_valid(&curVal)) + { + err = OCParseStringLL(rootValue, OC_RSRVD_RESOURCE_TYPE, &out->types); + VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find rt type tag/value"); + } // Device ID size_t len = 0; - CborValue curVal; err = cbor_value_map_find_value(rootValue, OC_RSRVD_DEVICE_ID, &curVal); if (cbor_value_is_valid(&curVal)) { diff --git a/resource/csdk/stack/src/ocresource.c b/resource/csdk/stack/src/ocresource.c index d338499..b323481 100755 --- a/resource/csdk/stack/src/ocresource.c +++ b/resource/csdk/stack/src/ocresource.c @@ -756,7 +756,7 @@ static OCStackResult HandleVirtualResource (OCServerRequest *request, OCResource else { payload = (OCPayload*) OCDevicePayloadCreate(deviceId, savedDeviceInfo.deviceName, - OC_SPEC_VERSION, OC_DATA_MODEL_VERSION); + savedDeviceInfo.types, OC_SPEC_VERSION, OC_DATA_MODEL_VERSION); if (!payload) { discoveryResult = OC_STACK_NO_MEMORY; @@ -1220,7 +1220,9 @@ void DeleteDeviceInfo() OIC_LOG(INFO, TAG, "Deleting device info."); OICFree(savedDeviceInfo.deviceName); + OCFreeOCStringLL(savedDeviceInfo.types); savedDeviceInfo.deviceName = NULL; + } static OCStackResult DeepCopyDeviceInfo(OCDeviceInfo info) @@ -1233,6 +1235,15 @@ static OCStackResult DeepCopyDeviceInfo(OCDeviceInfo info) return OC_STACK_NO_MEMORY; } + if (info.types) + { + savedDeviceInfo.types = CloneOCStringLL(info.types); + if(!savedDeviceInfo.types && info.types) + { + DeleteDeviceInfo(); + return OC_STACK_NO_MEMORY; + } + } return OC_STACK_OK; } diff --git a/resource/examples/devicediscoveryserver.cpp b/resource/examples/devicediscoveryserver.cpp index 8f9ec9b..2112ae6 100644 --- a/resource/examples/devicediscoveryserver.cpp +++ b/resource/examples/devicediscoveryserver.cpp @@ -29,6 +29,7 @@ #include "OCPlatform.h" #include "OCApi.h" +#include "ocpayload.h" using namespace OC; @@ -137,6 +138,8 @@ int main() result = SetDeviceInfo(deviceName); + OCResourcePayloadAddStringLL(&deviceInfo.types, "oic.wk.d"); + OCResourcePayloadAddStringLL(&deviceInfo.types, "oic.d.tv"); result = OCPlatform::registerDeviceInfo(deviceInfo); @@ -164,7 +167,3 @@ int main() return 0; } - - - - diff --git a/resource/src/OCRepresentation.cpp b/resource/src/OCRepresentation.cpp index 051c0cc..a8d5ef3 100644 --- a/resource/src/OCRepresentation.cpp +++ b/resource/src/OCRepresentation.cpp @@ -85,6 +85,10 @@ namespace OC rep[OC_RSRVD_DATA_MODEL_VERSION] = payload->dataModelVersion ? std::string(payload->dataModelVersion) : std::string(); + for (OCStringLL *strll = payload->types; strll; strll = strll->next) + { + rep.addResourceType(strll->value); + } m_reps.push_back(std::move(rep)); } diff --git a/resource/unittests/OCPlatformTest.cpp b/resource/unittests/OCPlatformTest.cpp index 078aa89..e7dd2a9 100644 --- a/resource/unittests/OCPlatformTest.cpp +++ b/resource/unittests/OCPlatformTest.cpp @@ -20,6 +20,7 @@ #include #include +#include #include namespace OCPlatformTest @@ -61,9 +62,22 @@ namespace OCPlatformTest } //Helper methods + void DeleteStringLL(OCStringLL* ll) + { + if (!ll) + { + return; + } + + DeleteStringLL(ll->next); + delete[] ll->value; + OICFree(ll); + } + void DeleteDeviceInfo(OCDeviceInfo deviceInfo) { delete[] deviceInfo.deviceName; + DeleteStringLL(deviceInfo.types); } @@ -73,6 +87,30 @@ namespace OCPlatformTest strncpy(*targetString, sourceString.c_str(), (sourceString.length() + 1)); } + bool OCResourcePayloadAddStringLL(OCStringLL **stringLL, std::string value) + { + char *dup = NULL; + DuplicateString(&dup, value); + if (!*stringLL) + { + *stringLL = (OCStringLL *)OICCalloc(1, sizeof(OCStringLL)); + (*stringLL)->value = dup; + return true; + } + else + { + OCStringLL *temp = *stringLL; + while(temp->next) + { + temp = temp->next; + } + temp->next = (OCStringLL *)OICCalloc(1, sizeof(OCStringLL)); + temp->next->value = dup; + return true; + } + return false; + } + OCResourceHandle RegisterResource(std::string uri, std::string type, std::string iface) { PlatformConfig cfg @@ -697,15 +735,16 @@ namespace OCPlatformTest TEST(RegisterDeviceInfoTest, RegisterDeviceInfoWithValidParameters) { OCDeviceInfo deviceInfo; - DuplicateString(&deviceInfo.deviceName, "myDeviceName"); + deviceInfo.types = NULL; + OCResourcePayloadAddStringLL(&deviceInfo.types, "oic.d.tv"); EXPECT_EQ(OC_STACK_OK, OCPlatform::registerDeviceInfo(deviceInfo)); EXPECT_NO_THROW(DeleteDeviceInfo(deviceInfo)); } TEST(RegisterDeviceInfoTest, RegisterDeviceInfoWithEmptyObject) { - OCDeviceInfo di = {0}; + OCDeviceInfo di = {0, 0}; EXPECT_ANY_THROW(OCPlatform::registerDeviceInfo(di)); } diff --git a/resource/unittests/OCRepresentationEncodingTest.cpp b/resource/unittests/OCRepresentationEncodingTest.cpp index e3e50ee..397f5e0 100644 --- a/resource/unittests/OCRepresentationEncodingTest.cpp +++ b/resource/unittests/OCRepresentationEncodingTest.cpp @@ -53,12 +53,17 @@ namespace OCRepresentationEncodingTest static const char devicename1[] = "device name"; static const char specver1[] = "spec version"; static const char dmver1[] = "data model version"; + static OCStringLL *types = NULL; // Device Payloads TEST(DeviceDiscoveryEncoding, Normal) { + OCResourcePayloadAddStringLL(&types, "oic.wk.d"); + OCResourcePayloadAddStringLL(&types, "oic.d.tv"); + OCDevicePayload* device = OCDevicePayloadCreate( sid1, devicename1, + types, specver1, dmver1); EXPECT_STREQ(sid1, device->sid); @@ -66,6 +71,8 @@ namespace OCRepresentationEncodingTest EXPECT_STREQ(specver1, device->specVersion); EXPECT_STREQ(dmver1, device->dataModelVersion); EXPECT_EQ(PAYLOAD_TYPE_DEVICE, ((OCPayload*)device)->type); + EXPECT_STREQ("oic.wk.d", device->types->value); + EXPECT_STREQ("oic.d.tv", device->types->next->value); uint8_t* cborData; size_t cborSize; @@ -79,6 +86,8 @@ namespace OCRepresentationEncodingTest EXPECT_STREQ(device->deviceName, ((OCDevicePayload*)parsedDevice)->deviceName); EXPECT_STREQ(device->specVersion, ((OCDevicePayload*)parsedDevice)->specVersion); EXPECT_STREQ(device->dataModelVersion, ((OCDevicePayload*)parsedDevice)->dataModelVersion); + EXPECT_STREQ("oic.wk.d", ((OCDevicePayload*)parsedDevice)->types->value); + EXPECT_STREQ("oic.d.tv", ((OCDevicePayload*)parsedDevice)->types->next->value); EXPECT_EQ(device->base.type, ((OCDevicePayload*)parsedDevice)->base.type); OCPayloadDestroy((OCPayload*)device); -- 2.7.4