From: Todd Malsbary Date: Wed, 1 Mar 2017 19:52:54 +0000 (-0800) Subject: Add support for application/vnd.ocf+cbor to resource directory. X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=293024229f8aa721c3ddff5469c30849d28cfbfa;p=contrib%2Fiotivity.git Add support for application/vnd.ocf+cbor to resource directory. - Add support to RD for publishing and storing endpoints. Only publish secure or non-secure eps depending on resource properties. - When creating application/cbor response to discovery, create separate links with the fully-qualified URI containing the supported endpoints. Change-Id: Ifc370825103a73335eddccb4bbde4225d0a0a736 Signed-off-by: Todd Malsbary Reviewed-on: https://gerrit.iotivity.org/gerrit/17631 Tested-by: jenkins-iotivity Reviewed-by: Dan Mihai --- diff --git a/resource/csdk/resource-directory/include/rd_database.h b/resource/csdk/resource-directory/include/rd_database.h index a8285da..01c19f6 100644 --- a/resource/csdk/resource-directory/include/rd_database.h +++ b/resource/csdk/resource-directory/include/rd_database.h @@ -38,11 +38,10 @@ OCStackResult OCRDDatabaseInit(); * Stores in database the published resource. * * @param payload is the the published resource payload. - * @param address provide information about endpoint connectivity details. * * @return ::OC_STACK_OK in case of success or else other value. */ -OCStackResult OCRDDatabaseStoreResources(const OCRepPayload *payload, const OCDevAddr *address); +OCStackResult OCRDDatabaseStoreResources(const OCRepPayload *payload); /** * Delete the RD resources diff --git a/resource/csdk/resource-directory/src/internal/rd_database.c b/resource/csdk/resource-directory/src/internal/rd_database.c index 3e3ed87..4b13774 100644 --- a/resource/csdk/resource-directory/src/internal/rd_database.c +++ b/resource/csdk/resource-directory/src/internal/rd_database.c @@ -57,23 +57,20 @@ static sqlite3 *gRDDB = NULL; #define RD_TABLE \ "create table RD_DEVICE_LIST(ID INTEGER PRIMARY KEY AUTOINCREMENT, " \ XSTR(OC_RSRVD_DEVICE_ID) " UNIQUE NOT NULL, " \ - XSTR(OC_RSRVD_TTL) " NOT NULL, " \ - "ADDRESS NOT NULL);" + XSTR(OC_RSRVD_TTL) " NOT NULL);" #define RD_LL_TABLE \ "create table RD_DEVICE_LINK_LIST("XSTR(OC_RSRVD_INS)" INTEGER PRIMARY KEY AUTOINCREMENT, " \ - XSTR(OC_RSRVD_HREF) "," \ - XSTR(OC_RSRVD_REL) "," \ - XSTR(OC_RSRVD_TITLE) "," \ - XSTR(OC_RSRVD_BITMAP)"," \ - XSTR(OC_RSRVD_TTL) "," \ - XSTR(OC_RSRVD_MEDIA_TYPE) "," \ + XSTR(OC_RSRVD_HREF) "," \ + XSTR(OC_RSRVD_REL) "," \ + XSTR(OC_RSRVD_URI) "," \ + XSTR(OC_RSRVD_BITMAP) "," \ "DEVICE_ID INT NOT NULL, " \ - "FOREIGN KEY(DEVICE_ID) REFERENCES RD_DEVICE_LIST(ID) ON DELETE CASCADE );" + "FOREIGN KEY(DEVICE_ID) REFERENCES RD_DEVICE_LIST(ID) ON DELETE CASCADE);" #define RD_RT_TABLE \ "create table RD_LINK_RT(" XSTR(OC_RSRVD_RESOURCE_TYPE) " NOT NULL, " \ - "LINK_ID INT NOT NULL, "\ + "LINK_ID INT NOT NULL, " \ "FOREIGN KEY("XSTR(LINK_ID)") REFERENCES RD_DEVICE_LINK_LIST("XSTR(OC_RSRVD_INS)") " \ "ON DELETE CASCADE);" @@ -83,6 +80,13 @@ static sqlite3 *gRDDB = NULL; "FOREIGN KEY("XSTR(LINK_ID)") REFERENCES RD_DEVICE_LINK_LIST("XSTR(OC_RSRVD_INS)") " \ "ON DELETE CASCADE);" +#define RD_EP_TABLE \ + "create table RD_LINK_EP(" XSTR(OC_RSRVD_ENDPOINT) " NOT NULL, " \ + XSTR(OC_RSRVD_PRIORITY) " INT NOT NULL, " \ + "LINK_ID INT NOT NULL, "\ + "FOREIGN KEY("XSTR(LINK_ID)") REFERENCES RD_DEVICE_LINK_LIST("XSTR(OC_RSRVD_INS)") " \ + "ON DELETE CASCADE);" + static void errorCallback(void *arg, int errCode, const char *errMsg) { OC_UNUSED(arg); @@ -120,6 +124,9 @@ OCStackResult OCRDDatabaseInit() VERIFY_SQLITE(sqlite3_exec(gRDDB, RD_IF_TABLE, NULL, NULL, NULL)); OIC_LOG(DEBUG, TAG, "RD created RD_LINK_IF table."); + + VERIFY_SQLITE(sqlite3_exec(gRDDB, RD_EP_TABLE, NULL, NULL, NULL)); + OIC_LOG(DEBUG, TAG, "RD created RD_LINK_EP table."); sqlRet = SQLITE_OK; } } @@ -233,6 +240,55 @@ static int storeInterfaceType(char **interfaceTypes, size_t size, sqlite3_int64 return res; } +static int storeEndpoints(OCRepPayload **eps, size_t size, sqlite3_int64 rowid) +{ + int res = 1; + VERIFY_SQLITE(sqlite3_exec(gRDDB, "BEGIN TRANSACTION", NULL, NULL, NULL)); + + const char *deleteEp = "DELETE FROM RD_LINK_EP WHERE LINK_ID=@id"; + const char *insertEp = "INSERT INTO RD_LINK_EP VALUES(@ep, @pri, @id)"; + sqlite3_stmt *stmt = 0; + + VERIFY_SQLITE(sqlite3_prepare_v2(gRDDB, deleteEp, strlen(deleteEp) + 1, &stmt, NULL)); + VERIFY_SQLITE(sqlite3_bind_int64(stmt, sqlite3_bind_parameter_index(stmt, "@id"), rowid)); + res = sqlite3_step(stmt); + VERIFY_SQLITE(sqlite3_finalize(stmt)); + if (res != SQLITE_DONE) + { + sqlite3_exec(gRDDB, "ROLLBACK", NULL, NULL, NULL); + return res; + } + + for (size_t i = 0; i < size; i++) + { + VERIFY_SQLITE(sqlite3_prepare_v2(gRDDB, insertEp, strlen(insertEp) + 1, &stmt, NULL)); + char *ep; + if (OCRepPayloadGetPropString(eps[i], OC_RSRVD_ENDPOINT, &ep)) + { + VERIFY_SQLITE(sqlite3_bind_text(stmt, sqlite3_bind_parameter_index(stmt, "@ep"), + ep, strlen(ep), SQLITE_STATIC)); + } + sqlite3_int64 pri; + if (OCRepPayloadGetPropInt(eps[i], OC_RSRVD_PRIORITY, (int64_t *) &pri)) + { + VERIFY_SQLITE(sqlite3_bind_int64(stmt, sqlite3_bind_parameter_index(stmt, "@pri"), pri)); + } + VERIFY_SQLITE(sqlite3_bind_int64(stmt, sqlite3_bind_parameter_index(stmt, "@id"), rowid)); + res = sqlite3_step(stmt); + VERIFY_SQLITE(sqlite3_finalize(stmt)); + if (res != SQLITE_DONE) + { + sqlite3_exec(gRDDB, "ROLLBACK", NULL, NULL, NULL); + return res; + } + OICFree(ep); + } + + VERIFY_SQLITE(sqlite3_exec(gRDDB, "COMMIT", NULL, NULL, NULL)); + res = SQLITE_OK; + return res; +} + static int storeLinkPayload(OCRepPayload *rdPayload, sqlite3_int64 rowid) { int res = 1 ; @@ -258,7 +314,7 @@ static int storeLinkPayload(OCRepPayload *rdPayload, sqlite3_int64 rowid) { const char *insertDeviceLLList = "INSERT OR IGNORE INTO RD_DEVICE_LINK_LIST (ins, href, DEVICE_ID) " "VALUES((SELECT ins FROM RD_DEVICE_LINK_LIST WHERE DEVICE_ID=@id AND href=@uri),@uri,@id)"; - const char *updateDeviceLLList = "UPDATE RD_DEVICE_LINK_LIST SET bm=@bm,type=@mediaType " + const char *updateDeviceLLList = "UPDATE RD_DEVICE_LINK_LIST SET anchor=@anchor,bm=@bm " "WHERE DEVICE_ID=@id AND href=@uri"; sqlite3_stmt *stmt = 0; @@ -292,22 +348,21 @@ static int storeLinkPayload(OCRepPayload *rdPayload, sqlite3_int64 rowid) VERIFY_SQLITE(sqlite3_bind_text(stmt, sqlite3_bind_parameter_index(stmt, "@uri"), uri, strlen(uri), SQLITE_STATIC)); } + char *anchor; + if (OCRepPayloadGetPropString(link, OC_RSRVD_URI, &anchor)) + { + VERIFY_SQLITE(sqlite3_bind_text(stmt, sqlite3_bind_parameter_index(stmt, "@anchor"), + anchor, strlen(anchor), SQLITE_STATIC)); + } OCRepPayload *p = NULL; if (OCRepPayloadGetPropObject(link, OC_RSRVD_POLICY, &p)) { sqlite3_int64 bm = 0; - if (OCRepPayloadGetPropInt(p, OC_RSRVD_BITMAP, &bm)) + if (OCRepPayloadGetPropInt(p, OC_RSRVD_BITMAP, (int64_t *) &bm)) { VERIFY_SQLITE(sqlite3_bind_int64(stmt, sqlite3_bind_parameter_index(stmt, "@bm"), bm)); } } - size_t mtDim[MAX_REP_ARRAY_DEPTH] = {0}; - char **mediaType = NULL; - if (OCRepPayloadGetStringArray(link, OC_RSRVD_MEDIA_TYPE, &mediaType, mtDim)) - { - VERIFY_SQLITE(sqlite3_bind_text(stmt, sqlite3_bind_parameter_index(stmt, "@mediaType"), - mediaType[0], strlen(mediaType[0]), SQLITE_STATIC)); - } if (sqlite3_step(stmt) != SQLITE_DONE) { sqlite3_exec(gRDDB, "ROLLBACK", NULL, NULL, NULL); @@ -321,6 +376,8 @@ static int storeLinkPayload(OCRepPayload *rdPayload, sqlite3_int64 rowid) size_t rtDim[MAX_REP_ARRAY_DEPTH] = {0}; char **itf = NULL; size_t itfDim[MAX_REP_ARRAY_DEPTH] = {0}; + OCRepPayload** eps = NULL; + size_t epsDim[MAX_REP_ARRAY_DEPTH] = {0}; const char *input = "SELECT ins FROM RD_DEVICE_LINK_LIST WHERE DEVICE_ID=@id AND href=@uri"; VERIFY_SQLITE(sqlite3_prepare_v2(gRDDB, input, strlen(input) + 1, &stmt, NULL)); VERIFY_SQLITE(sqlite3_bind_int64(stmt, sqlite3_bind_parameter_index(stmt, "@id"), rowid)); @@ -332,7 +389,7 @@ static int storeLinkPayload(OCRepPayload *rdPayload, sqlite3_int64 rowid) res = sqlite3_step(stmt); if (res == SQLITE_ROW || res == SQLITE_DONE) { - int64_t ins = sqlite3_column_int64(stmt, 0); + sqlite3_int64 ins = sqlite3_column_int64(stmt, 0); VERIFY_SQLITE(sqlite3_finalize(stmt)); if (!OCRepPayloadSetPropInt(link, OC_RSRVD_INS, ins)) { @@ -341,8 +398,10 @@ static int storeLinkPayload(OCRepPayload *rdPayload, sqlite3_int64 rowid) } OCRepPayloadGetStringArray(link, OC_RSRVD_RESOURCE_TYPE, &rt, rtDim); OCRepPayloadGetStringArray(link, OC_RSRVD_INTERFACE, &itf, itfDim); + OCRepPayloadGetPropObjectArray(link, OC_RSRVD_ENDPOINTS, &eps, epsDim); VERIFY_SQLITE(storeResourceType(rt, rtDim[0], ins)); VERIFY_SQLITE(storeInterfaceType(itf, itfDim[0], ins)); + VERIFY_SQLITE(storeEndpoints(eps, epsDim[0], ins)); } else { @@ -351,11 +410,6 @@ static int storeLinkPayload(OCRepPayload *rdPayload, sqlite3_int64 rowid) OICFree(uri); OCPayloadDestroy((OCPayload *)p); - for (j = 0; j < mtDim[0]; j++) - { - OICFree(mediaType[j]); - } - OICFree(mediaType); for (j = 0; j < rtDim[0]; j++) { OICFree(rt[j]); @@ -373,24 +427,21 @@ static int storeLinkPayload(OCRepPayload *rdPayload, sqlite3_int64 rowid) return res; } -OCStackResult OCRDDatabaseStoreResources(OCRepPayload *payload, const OCDevAddr *address) +OCStackResult OCRDDatabaseStoreResources(OCRepPayload *payload) { CHECK_DATABASE_INIT; char *deviceId = NULL; OCRepPayloadGetPropString(payload, OC_RSRVD_DEVICE_ID, &deviceId); - int64_t ttl = 0; - OCRepPayloadGetPropInt(payload, OC_RSRVD_DEVICE_TTL, &ttl); - char rdAddress[MAX_URI_LENGTH]; - snprintf(rdAddress, MAX_URI_LENGTH, "%s:%d", address->addr, address->port); - OIC_LOG_V(DEBUG, TAG, "Address: %s", rdAddress); + sqlite3_int64 ttl = 0; + OCRepPayloadGetPropInt(payload, OC_RSRVD_DEVICE_TTL, (int64_t *) &ttl); /* INSERT OR IGNORE then UPDATE to update or insert the row without triggering the cascading deletes */ VERIFY_SQLITE(sqlite3_exec(gRDDB, "BEGIN TRANSACTION", NULL, NULL, NULL)); sqlite3_stmt *stmt = 0; - const char *insertDeviceList = "INSERT OR IGNORE INTO RD_DEVICE_LIST (ID, di, ttl, ADDRESS) " - "VALUES ((SELECT ID FROM RD_DEVICE_LIST WHERE di=@deviceId), @deviceId, @ttl, @rdAddress)"; + const char *insertDeviceList = "INSERT OR IGNORE INTO RD_DEVICE_LIST (ID, di, ttl) " + "VALUES ((SELECT ID FROM RD_DEVICE_LIST WHERE di=@deviceId), @deviceId, @ttl)"; VERIFY_SQLITE(sqlite3_prepare_v2(gRDDB, insertDeviceList, strlen(insertDeviceList) + 1, &stmt, NULL)); if (deviceId) @@ -402,8 +453,6 @@ OCStackResult OCRDDatabaseStoreResources(OCRepPayload *payload, const OCDevAddr { VERIFY_SQLITE(sqlite3_bind_int64(stmt, sqlite3_bind_parameter_index(stmt, "@ttl"), ttl)); } - VERIFY_SQLITE(sqlite3_bind_text(stmt, sqlite3_bind_parameter_index(stmt, "@rdAddress"), - rdAddress, strlen(rdAddress), SQLITE_STATIC)); if (sqlite3_step(stmt) != SQLITE_DONE) { sqlite3_exec(gRDDB, "ROLLBACK", NULL, NULL, NULL); @@ -412,7 +461,7 @@ OCStackResult OCRDDatabaseStoreResources(OCRepPayload *payload, const OCDevAddr } VERIFY_SQLITE(sqlite3_finalize(stmt)); - const char *updateDeviceList = "UPDATE RD_DEVICE_LIST SET ttl=@ttl,ADDRESS=@rdAddress WHERE di=@deviceId"; + const char *updateDeviceList = "UPDATE RD_DEVICE_LIST SET ttl=@ttl WHERE di=@deviceId"; VERIFY_SQLITE(sqlite3_prepare_v2(gRDDB, updateDeviceList, strlen(updateDeviceList) + 1, &stmt, NULL)); if (deviceId) @@ -424,8 +473,6 @@ OCStackResult OCRDDatabaseStoreResources(OCRepPayload *payload, const OCDevAddr { VERIFY_SQLITE(sqlite3_bind_int64(stmt, sqlite3_bind_parameter_index(stmt, "@ttl"), ttl)); } - VERIFY_SQLITE(sqlite3_bind_text(stmt, sqlite3_bind_parameter_index(stmt, "@rdAddress"), - rdAddress, strlen(rdAddress), SQLITE_STATIC)); if (sqlite3_step(stmt) != SQLITE_DONE) { sqlite3_exec(gRDDB, "ROLLBACK", NULL, NULL, NULL); @@ -447,7 +494,7 @@ OCStackResult OCRDDatabaseStoreResources(OCRepPayload *payload, const OCDevAddr int res = sqlite3_step(stmt); if (res == SQLITE_ROW || res == SQLITE_DONE) { - int64_t rowid = sqlite3_column_int64(stmt, 0); + sqlite3_int64 rowid = sqlite3_column_int64(stmt, 0); VERIFY_SQLITE(sqlite3_finalize(stmt)); VERIFY_SQLITE(storeLinkPayload(payload, rowid)); } diff --git a/resource/csdk/resource-directory/src/rd_client.c b/resource/csdk/resource-directory/src/rd_client.c index 730819c..18f6912 100644 --- a/resource/csdk/resource-directory/src/rd_client.c +++ b/resource/csdk/resource-directory/src/rd_client.c @@ -19,6 +19,7 @@ //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= #include "rd_client.h" +#include #include #include @@ -27,7 +28,9 @@ #include "octypes.h" #include "ocstack.h" #include "ocpayload.h" +#include "ocendpoint.h" #include "payload_logging.h" +#include "cainterface.h" #define TAG "OIC_RD_CLIENT" @@ -137,130 +140,185 @@ OCStackResult OCRDPublish(OCDoHandle *handle, const char *host, } static OCRepPayload *RDPublishPayloadCreate(const unsigned char *id, - const OCResourceHandle *resourceHandles, uint8_t nHandles) + const OCResourceHandle *resourceHandles, uint8_t nHandles) { - OCRepPayload *rdPayload = (OCRepPayload *)OCRepPayloadCreate(); + assert(id); + + OCStackResult result = OC_STACK_ERROR; + OCRepPayload *rdPayload = NULL; + size_t dim[MAX_REP_ARRAY_DEPTH] = {0}; + CAEndpoint_t *caEps = NULL; + size_t nCaEps = 0; + OCRepPayload **eps = NULL; + + rdPayload = (OCRepPayload *)OCRepPayloadCreate(); if (!rdPayload) { - return NULL; + OIC_LOG(ERROR, TAG, "Memory allocation failed!"); + goto exit; } - if (id) + // Common properties + dim[0] = 1; + char **rts = (char **)OICCalloc(dim[0], sizeof(char *)); + if (!rts) { - OCRepPayloadSetPropString(rdPayload, OC_RSRVD_DEVICE_ID, (const char*) id); + OIC_LOG(ERROR, TAG, "Memory allocation failed!"); + goto exit; } + rts[0] = OICStrdup(OC_RSRVD_RESOURCE_TYPE_RES); + OCRepPayloadSetStringArrayAsOwner(rdPayload, OC_RSRVD_RESOURCE_TYPE, rts, dim); - char *deviceName = NULL; - OCGetPropertyValue(PAYLOAD_TYPE_DEVICE, OC_RSRVD_DEVICE_NAME, (void **) &deviceName); - if (deviceName) + dim[0] = 2; + char **ifs = (char **)OICCalloc(dim[0], sizeof(char *)); + if (!ifs) { - OCRepPayloadSetPropString(rdPayload, OC_RSRVD_DEVICE_NAME, deviceName); - OICFree(deviceName); + OIC_LOG(ERROR, TAG, "Memory allocation failed!"); + goto exit; } + ifs[0] = OICStrdup(OC_RSRVD_INTERFACE_LL); + ifs[1] = OICStrdup(OC_RSRVD_INTERFACE_DEFAULT); + OCRepPayloadSetStringArrayAsOwner(rdPayload, OC_RSRVD_INTERFACE, ifs, dim); - char *platformModelName = NULL; - OCGetPropertyValue(PAYLOAD_TYPE_PLATFORM, OC_RSRVD_MODEL_NUM, (void **) &platformModelName); - if (platformModelName) + char *n; + OCGetPropertyValue(PAYLOAD_TYPE_DEVICE, OC_RSRVD_DEVICE_NAME, (void **) &n); + if (n) { - OCRepPayloadSetPropString(rdPayload, OC_DATA_MODEL_NUMBER, platformModelName); - OICFree(platformModelName); + OCRepPayloadSetPropStringAsOwner(rdPayload, OC_RSRVD_DEVICE_NAME, n); } + // oic.wk.rdpub properties + OCRepPayloadSetPropString(rdPayload, OC_RSRVD_DEVICE_ID, (const char*) id); OCRepPayloadSetPropInt(rdPayload, OC_RSRVD_DEVICE_TTL, OIC_RD_PUBLISH_TTL); - OCRepPayload **linkArr = (OCRepPayload**)OICCalloc(nHandles, sizeof(OCRepPayload *)); - if (!linkArr) + dim[0] = nHandles; + OCRepPayload **links = (OCRepPayload **)OICCalloc(dim[0], sizeof(OCRepPayload *)); + if (!links) { - OCRepPayloadDestroy(rdPayload); - return NULL; + goto exit; } - - size_t dimensions[MAX_REP_ARRAY_DEPTH] = {nHandles, 0, 0}; + OCRepPayloadSetPropObjectArrayAsOwner(rdPayload, OC_RSRVD_LINKS, links, dim); for (uint8_t j = 0; j < nHandles; j++) { OCResourceHandle handle = resourceHandles[j]; if (handle) { - OCRepPayload *link = OCRepPayloadCreate(); + links[j] = OCRepPayloadCreate(); const char *uri = OCGetResourceUri(handle); if (uri) { - OCRepPayloadSetPropString(link, OC_RSRVD_HREF, uri); + OCRepPayloadSetPropString(links[j], OC_RSRVD_HREF, uri); } - uint8_t numElement = 0; - if (OC_STACK_OK == OCGetNumberOfResourceTypes(handle, &numElement)) + uint8_t n; + if (OC_STACK_OK == OCGetNumberOfResourceTypes(handle, &n)) { - size_t rtDim[MAX_REP_ARRAY_DEPTH] = {numElement, 0, 0}; - char **rt = (char **)OICMalloc(sizeof(char *) * numElement); - for (uint8_t i = 0; i < numElement; ++i) + dim[0] = n; + char **rts = (char **)OICCalloc(n, sizeof(char *)); + for (uint8_t i = 0; i < n; i++) { - const char *value = OCGetResourceTypeName(handle, i); - OIC_LOG_V(DEBUG, TAG, "value: %s", value); - rt[i] = OICStrdup(value); + rts[i] = OICStrdup(OCGetResourceTypeName(handle, i)); + OIC_LOG_V(DEBUG, TAG, "value: %s", rts[i]); } - OCRepPayloadSetStringArrayAsOwner(link, OC_RSRVD_RESOURCE_TYPE, rt, rtDim); + OCRepPayloadSetStringArrayAsOwner(links[j], OC_RSRVD_RESOURCE_TYPE, rts, dim); } - numElement = 0; - if (OC_STACK_OK == OCGetNumberOfResourceInterfaces(handle, &numElement)) + if (OC_STACK_OK == OCGetNumberOfResourceInterfaces(handle, &n)) { - size_t ifDim[MAX_REP_ARRAY_DEPTH] = {numElement, 0, 0}; - char **itf = (char **)OICMalloc(sizeof(char *) * numElement); - for (uint8_t i = 0; i < numElement; ++i) + dim[0] = n; + char **ifs = (char **)OICCalloc(n, sizeof(char *)); + for (uint8_t i = 0; i < n; i++) { - const char *value = OCGetResourceInterfaceName(handle, i); - OIC_LOG_V(DEBUG, TAG, "value: %s", value); - itf[i] = OICStrdup(value); + ifs[i] = OICStrdup(OCGetResourceInterfaceName(handle, i)); + OIC_LOG_V(DEBUG, TAG, "value: %s", ifs[i]); } - OCRepPayloadSetStringArrayAsOwner(link, OC_RSRVD_INTERFACE, itf, ifDim); + OCRepPayloadSetStringArrayAsOwner(links[j], OC_RSRVD_INTERFACE, ifs, dim); } - int64_t ins = 0; + // rel is always the default ("hosts") + + char anchor[MAX_URI_LENGTH]; + snprintf(anchor, MAX_URI_LENGTH, "ocf://%s", id); + OCRepPayloadSetPropString(links[j], OC_RSRVD_URI, anchor); + + int64_t ins; if (OC_STACK_OK == OCGetResourceIns(handle, &ins)) { - OCRepPayloadSetPropInt(link, OC_RSRVD_INS, ins); + OCRepPayloadSetPropInt(links[j], OC_RSRVD_INS, ins); } - size_t mtDim[MAX_REP_ARRAY_DEPTH] = {1, 0, 0}; - char **mediaType = (char **)OICMalloc(sizeof(char *) * 1); - if (!mediaType) + OCResourceProperty p = OCGetResourceProperties(handle); + bool isSecure = (p & OC_SECURE); + p &= (OC_DISCOVERABLE | OC_OBSERVABLE); + OCRepPayload *policy = OCRepPayloadCreate(); + if (!policy) { OIC_LOG(ERROR, TAG, "Memory allocation failed!"); + goto exit; + } + OCRepPayloadSetPropInt(policy, OC_RSRVD_BITMAP, p); + OCRepPayloadSetPropObjectAsOwner(links[j], OC_RSRVD_POLICY, policy); - for(uint8_t i = 0; i < nHandles; i++) + CAResult_t caResult = CAGetNetworkInformation(&caEps, &nCaEps); + if (CA_STATUS_FAILED == caResult) + { + OIC_LOG(ERROR, TAG, "CAGetNetworkInformation failed!"); + goto exit; + } + if (nCaEps) + { + dim[0] = 0; + for (uint32_t i = 0; i < nCaEps; i++) { - OCRepPayloadDestroy(linkArr[i]); + if (isSecure == (bool)(caEps[i].flags & OC_FLAG_SECURE)) + { + ++dim[0]; + } + } + eps = (OCRepPayload **)OICCalloc(dim[0], sizeof(OCRepPayload *)); + if (!eps) + { + OIC_LOG(ERROR, TAG, "Memory allocation failed!"); + goto exit; + } + OCRepPayloadSetPropObjectArrayAsOwner(links[j], OC_RSRVD_ENDPOINTS, eps, dim); + uint32_t k = 0; + for (uint32_t i = 0; i < nCaEps; i++) + { + if (isSecure == (bool)(caEps[i].flags & OC_FLAG_SECURE)) + { + eps[k] = OCRepPayloadCreate(); + if (!eps[k]) + { + OIC_LOG(ERROR, TAG, "Memory allocation failed!"); + break; + } + char *epStr = OCCreateEndpointStringFromCA(&caEps[i]); + if (!epStr) + { + OIC_LOG(ERROR, TAG, "Create endpoint string failed!"); + break; + } + OCRepPayloadSetPropStringAsOwner(eps[k], OC_RSRVD_ENDPOINT, epStr); + OCRepPayloadSetPropInt(eps[k], OC_RSRVD_PRIORITY, 1); + ++k; + } } - OICFree(linkArr); - OCRepPayloadDestroy(rdPayload); - return NULL; } - - mediaType[0] = OICStrdup(OC_MEDIA_TYPE_APPLICATION_JSON); - OCRepPayloadSetStringArrayAsOwner(link, OC_RSRVD_MEDIA_TYPE, mediaType, - mtDim); - - OCResourceProperty p = OCGetResourceProperties(handle); - p = (OCResourceProperty) ((p & OC_DISCOVERABLE) | (p & OC_OBSERVABLE)); - OCRepPayload *policy = OCRepPayloadCreate(); - OCRepPayloadSetPropInt(policy, OC_RSRVD_BITMAP, p); - OCRepPayloadSetPropObjectAsOwner(link, OC_RSRVD_POLICY, policy); - - linkArr[j] = link; } } - OCRepPayloadSetPropObjectArray(rdPayload, OC_RSRVD_LINKS, (const OCRepPayload **)linkArr, dimensions); OIC_LOG_PAYLOAD(DEBUG, (OCPayload *) rdPayload); + result = OC_STACK_OK; - for (uint8_t i = 0; i < nHandles; i++) +exit: + OICFree(caEps); + if (OC_STACK_OK != result) { - OCRepPayloadDestroy(linkArr[i]); + OCRepPayloadDestroy(rdPayload); + rdPayload = NULL; } - OICFree(linkArr); - return rdPayload; } @@ -323,8 +381,13 @@ OCStackResult OCRDPublishWithDeviceId(OCDoHandle *handle, const char *host, rdPublishCbData.context = rdPublishContext; rdPublishCbData.cb = RDPublishCallback; rdPublishCbData.cd = RDPublishContextDeleter; + OCHeaderOption options[2]; + size_t numOptions = 0; + uint16_t format = COAP_MEDIATYPE_APPLICATION_VND_OCF_CBOR; + OCSetHeaderOption(options, &numOptions, CA_OPTION_CONTENT_FORMAT, &format, sizeof(format)); + OCSetHeaderOption(options, &numOptions, CA_OPTION_ACCEPT, &format, sizeof(format)); return OCDoResource(handle, OC_REST_POST, targetUri, NULL, (OCPayload *)rdPayload, - connectivityType, qos, &rdPublishCbData, NULL, 0); + connectivityType, qos, &rdPublishCbData, options, numOptions); } OCStackResult OCRDDelete(OCDoHandle *handle, const char *host, diff --git a/resource/csdk/resource-directory/src/rd_server.c b/resource/csdk/resource-directory/src/rd_server.c index 05d2369..d587632 100644 --- a/resource/csdk/resource-directory/src/rd_server.c +++ b/resource/csdk/resource-directory/src/rd_server.c @@ -116,7 +116,7 @@ static OCEntityHandlerResult handlePublishRequest(const OCEntityHandlerRequest * OIC_LOG_PAYLOAD(DEBUG, (OCPayload *) payload); if (OC_STACK_OK == OCRDDatabaseInit(NULL)) { - if (OC_STACK_OK == OCRDDatabaseStoreResources(payload, &ehRequest->devAddr)) + if (OC_STACK_OK == OCRDDatabaseStoreResources(payload)) { OIC_LOG_V(DEBUG, TAG, "Stored resources."); resPayload = payload; diff --git a/resource/csdk/resource-directory/unittests/SConscript b/resource/csdk/resource-directory/unittests/SConscript index 560fa5c..a5a6f9f 100644 --- a/resource/csdk/resource-directory/unittests/SConscript +++ b/resource/csdk/resource-directory/unittests/SConscript @@ -60,6 +60,8 @@ rd_test_env.AppendUnique( src_dir + '/extlibs/hippomocks-master', '../include', src_dir + '/resource/include', + src_dir + '/resource/csdk/connectivity/api', + src_dir + '/resource/csdk/connectivity/lib/libcoap-4.1.1/include', src_dir + '/resource/csdk/include', src_dir + '/resource/csdk/stack/include', src_dir + '/resource/csdk/security/include', diff --git a/resource/csdk/resource-directory/unittests/rddatabase.cpp b/resource/csdk/resource-directory/unittests/rddatabase.cpp index 5fafd74..613e4fd 100644 --- a/resource/csdk/resource-directory/unittests/rddatabase.cpp +++ b/resource/csdk/resource-directory/unittests/rddatabase.cpp @@ -91,7 +91,6 @@ typedef struct Resource const char *uri; const char *rt; const char *itf; - const char *mt; uint8_t bm; } Resource; @@ -112,6 +111,9 @@ static OCRepPayload *CreateRDPublishPayload(const char *deviceId, { OCRepPayload *link = OCRepPayloadCreate(); OCRepPayloadSetPropString(link, OC_RSRVD_HREF, resources[i].uri); + char anchor[MAX_URI_LENGTH]; + snprintf(anchor, MAX_URI_LENGTH, "ocf://%s", deviceId); + OCRepPayloadSetPropString(link, OC_RSRVD_URI, anchor); size_t rtDim[MAX_REP_ARRAY_DEPTH] = {1, 0, 0}; char **rt = (char **)OICMalloc(sizeof(char *) * 1); rt[0] = OICStrdup(resources[i].rt); @@ -122,14 +124,18 @@ static OCRepPayload *CreateRDPublishPayload(const char *deviceId, itf[0] = OICStrdup(resources[i].itf); OCRepPayloadSetStringArray(link, OC_RSRVD_INTERFACE, (const char **)itf, itfDim); - size_t mtDim[MAX_REP_ARRAY_DEPTH] = {1, 0, 0}; - char **mt = (char **)OICMalloc(sizeof(char *) * 1); - mt[0] = OICStrdup(resources[i].mt); - OCRepPayloadSetStringArray(link, OC_RSRVD_MEDIA_TYPE, (const char **)mt, - mtDim); OCRepPayload *policy = OCRepPayloadCreate(); OCRepPayloadSetPropInt(policy, OC_RSRVD_BITMAP, resources[i].bm); OCRepPayloadSetPropObjectAsOwner(link, OC_RSRVD_POLICY, policy); + size_t epsDim[MAX_REP_ARRAY_DEPTH] = {2, 0, 0}; + OCRepPayload *eps[2]; + eps[0] = OCRepPayloadCreate(); + OCRepPayloadSetPropString(eps[0], OC_RSRVD_ENDPOINT, "coap://127.0.0.1:1234"); + OCRepPayloadSetPropInt(eps[0], OC_RSRVD_PRIORITY, 1); + eps[1] = OCRepPayloadCreate(); + OCRepPayloadSetPropString(eps[1], OC_RSRVD_ENDPOINT, "coaps://[::1]:5678"); + OCRepPayloadSetPropInt(eps[1], OC_RSRVD_PRIORITY, 1); + OCRepPayloadSetPropObjectArray(link, OC_RSRVD_ENDPOINTS, (const OCRepPayload **)eps, epsDim); linkArr[i] = link; } @@ -139,11 +145,26 @@ static OCRepPayload *CreateRDPublishPayload(const char *deviceId, return repPayload; } +static void EndpointsVerify(const OCEndpointPayload *eps) +{ + EXPECT_STREQ(eps->tps, "coap"); + EXPECT_STREQ(eps->addr, "127.0.0.1"); + EXPECT_EQ(eps->family, OC_IP_USE_V4); + EXPECT_EQ(eps->port, 1234); + EXPECT_EQ(eps->pri, 1); + EXPECT_STREQ(eps->next->tps, "coaps"); + EXPECT_STREQ(eps->next->addr, "::1"); + EXPECT_EQ(eps->next->family, (OC_FLAG_SECURE | OC_IP_USE_V6)); + EXPECT_EQ(eps->next->port, 5678); + EXPECT_EQ(eps->next->pri, 1); + EXPECT_TRUE(eps->next->next == NULL); +} + static OCRepPayload *CreateResources(const char *deviceId) { Resource resources[] = { - { "/a/thermostat", "core.thermostat", OC_RSRVD_INTERFACE_DEFAULT, OC_MEDIA_TYPE_APPLICATION_JSON, OC_DISCOVERABLE }, - { "/a/light", "core.light", OC_RSRVD_INTERFACE_DEFAULT, OC_MEDIA_TYPE_APPLICATION_JSON, OC_DISCOVERABLE } + { "/a/thermostat", "core.thermostat", OC_RSRVD_INTERFACE_DEFAULT, OC_DISCOVERABLE }, + { "/a/light", "core.light", OC_RSRVD_INTERFACE_DEFAULT, OC_DISCOVERABLE } }; return CreateRDPublishPayload(deviceId, resources, 2); } @@ -158,11 +179,8 @@ TEST_F(RDDatabaseTests, StoreResources) itst::DeadmanTimer killSwitch(SHORT_TEST_TIMEOUT); const char *deviceId = "7a960f46-a52e-4837-bd83-460b1a6dd56b"; OCRepPayload *repPayload = CreateResources(deviceId); - OCDevAddr address; - address.port = 54321; - OICStrcpy(address.addr, MAX_ADDR_STR_SIZE, "192.168.1.1"); - EXPECT_EQ(OC_STACK_OK, OCRDDatabaseStoreResources(repPayload, &address)); + EXPECT_EQ(OC_STACK_OK, OCRDDatabaseStoreResources(repPayload)); OCDiscoveryPayload *discPayload = NULL; EXPECT_EQ(OC_STACK_OK, OCRDDatabaseDiscoveryPayloadCreate(NULL, "core.light", &discPayload)); @@ -185,19 +203,16 @@ TEST_F(RDDatabaseTests, AddResources) { itst::DeadmanTimer killSwitch(SHORT_TEST_TIMEOUT); const char *deviceId = "7a960f46-a52e-4837-bd83-460b1a6dd56b"; - OCDevAddr address; - address.port = 54321; - OICStrcpy(address.addr, MAX_ADDR_STR_SIZE, "192.168.1.1"); OCRepPayload *repPayload = CreateResources(deviceId); - EXPECT_EQ(OC_STACK_OK, OCRDDatabaseStoreResources(repPayload, &address)); + EXPECT_EQ(OC_STACK_OK, OCRDDatabaseStoreResources(repPayload)); OCPayloadDestroy((OCPayload *)repPayload); Resource resources[] = { - { "/a/light2", "core.light", OC_RSRVD_INTERFACE_DEFAULT, OC_MEDIA_TYPE_APPLICATION_JSON, OC_DISCOVERABLE } + { "/a/light2", "core.light", OC_RSRVD_INTERFACE_DEFAULT, OC_DISCOVERABLE } }; repPayload = CreateRDPublishPayload(deviceId, resources, 1); - EXPECT_EQ(OC_STACK_OK, OCRDDatabaseStoreResources(repPayload, &address)); + EXPECT_EQ(OC_STACK_OK, OCRDDatabaseStoreResources(repPayload)); OCPayloadDestroy((OCPayload *)repPayload); OCDiscoveryPayload *discPayload = NULL; @@ -225,29 +240,24 @@ TEST_F(RDDatabaseTests, AddResources) EXPECT_TRUE(foundLight2); OCDiscoveryPayloadDestroy(discPayload); discPayload = NULL; - - OCPayloadDestroy((OCPayload *)repPayload); } TEST_F(RDDatabaseTests, UpdateResources) { itst::DeadmanTimer killSwitch(SHORT_TEST_TIMEOUT); - const char *deviceId = "7a960f46-a52e-4837-bd83-460b1a6dd56b"; - OCDevAddr address; - address.port = 54321; - OICStrcpy(address.addr, MAX_ADDR_STR_SIZE, "192.168.1.1"); + const char *anchor = "ocf://7a960f46-a52e-4837-bd83-460b1a6dd56b"; + const char *deviceId = &anchor[6]; OCRepPayload *repPayload = CreateResources(deviceId); - EXPECT_EQ(OC_STACK_OK, OCRDDatabaseStoreResources(repPayload, &address)); + EXPECT_EQ(OC_STACK_OK, OCRDDatabaseStoreResources(repPayload)); OCPayloadDestroy((OCPayload *)repPayload); Resource resources[] = { - { "/a/thermostat", "x.core.r.thermostat", "x.core.if.thermostat", "application/cbor", OC_DISCOVERABLE | OC_OBSERVABLE }, - { "/a/light", "x.core.r.light", "x.core.if.light", "application/cbor", OC_DISCOVERABLE | OC_OBSERVABLE } + { "/a/thermostat", "x.core.r.thermostat", "x.core.if.thermostat", OC_DISCOVERABLE | OC_OBSERVABLE }, + { "/a/light", "x.core.r.light", "x.core.if.light", OC_DISCOVERABLE | OC_OBSERVABLE } }; repPayload = CreateRDPublishPayload(deviceId, resources, 2); - address.port = 12345; - EXPECT_EQ(OC_STACK_OK, OCRDDatabaseStoreResources(repPayload, &address)); + EXPECT_EQ(OC_STACK_OK, OCRDDatabaseStoreResources(repPayload)); OCPayloadDestroy((OCPayload *)repPayload); OCDiscoveryPayload *discPayload = NULL; @@ -264,6 +274,8 @@ TEST_F(RDDatabaseTests, UpdateResources) EXPECT_STREQ("x.core.if.thermostat", resource->interfaces->value); EXPECT_TRUE(resource->interfaces->next == NULL); EXPECT_EQ(OC_DISCOVERABLE | OC_OBSERVABLE, resource->bitmap); + EXPECT_STREQ(anchor, resource->anchor); + EndpointsVerify(resource->eps); } else if (!strcmp("/a/light", resource->uri)) { @@ -273,36 +285,33 @@ TEST_F(RDDatabaseTests, UpdateResources) EXPECT_STREQ("x.core.if.light", resource->interfaces->value); EXPECT_TRUE(resource->interfaces->next == NULL); EXPECT_EQ(OC_DISCOVERABLE | OC_OBSERVABLE, resource->bitmap); + EXPECT_STREQ(anchor, resource->anchor); + EndpointsVerify(resource->eps); } } EXPECT_TRUE(foundThermostat); EXPECT_TRUE(foundLight); OCDiscoveryPayloadDestroy(discPayload); discPayload = NULL; - - OCPayloadDestroy((OCPayload *)repPayload); } TEST_F(RDDatabaseTests, AddAndUpdateResources) { itst::DeadmanTimer killSwitch(SHORT_TEST_TIMEOUT); - const char *deviceId = "7a960f46-a52e-4837-bd83-460b1a6dd56b"; - OCDevAddr address; - address.port = 54321; - OICStrcpy(address.addr, MAX_ADDR_STR_SIZE, "192.168.1.1"); + const char *anchor = "ocf://7a960f46-a52e-4837-bd83-460b1a6dd56b"; + const char *deviceId = &anchor[6]; OCRepPayload *repPayload = CreateResources(deviceId); - EXPECT_EQ(OC_STACK_OK, OCRDDatabaseStoreResources(repPayload, &address)); + EXPECT_EQ(OC_STACK_OK, OCRDDatabaseStoreResources(repPayload)); OCPayloadDestroy((OCPayload *)repPayload); Resource resources[] = { - { "/a/thermostat", "x.core.r.thermostat", "x.core.if.thermostat", "application/cbor", OC_DISCOVERABLE | OC_OBSERVABLE }, - { "/a/light", "x.core.r.light", "x.core.if.light", "application/cbor", OC_DISCOVERABLE | OC_OBSERVABLE }, - { "/a/light2", "core.light", OC_RSRVD_INTERFACE_DEFAULT, OC_MEDIA_TYPE_APPLICATION_JSON, OC_DISCOVERABLE } + { "/a/thermostat", "x.core.r.thermostat", "x.core.if.thermostat", OC_DISCOVERABLE | OC_OBSERVABLE }, + { "/a/light", "x.core.r.light", "x.core.if.light", OC_DISCOVERABLE | OC_OBSERVABLE }, + { "/a/light2", "core.light", OC_RSRVD_INTERFACE_DEFAULT, OC_DISCOVERABLE } }; repPayload = CreateRDPublishPayload(deviceId, resources, 3); - address.port = 12345; - EXPECT_EQ(OC_STACK_OK, OCRDDatabaseStoreResources(repPayload, &address)); + EXPECT_EQ(OC_STACK_OK, OCRDDatabaseStoreResources(repPayload)); OCPayloadDestroy((OCPayload *)repPayload); OCDiscoveryPayload *discPayload = NULL; @@ -320,6 +329,8 @@ TEST_F(RDDatabaseTests, AddAndUpdateResources) EXPECT_STREQ("x.core.if.thermostat", resource->interfaces->value); EXPECT_TRUE(resource->interfaces->next == NULL); EXPECT_EQ(OC_DISCOVERABLE | OC_OBSERVABLE, resource->bitmap); + EXPECT_STREQ(anchor, resource->anchor); + EndpointsVerify(resource->eps); } else if (!strcmp("/a/light", resource->uri)) { @@ -329,6 +340,8 @@ TEST_F(RDDatabaseTests, AddAndUpdateResources) EXPECT_STREQ("x.core.if.light", resource->interfaces->value); EXPECT_TRUE(resource->interfaces->next == NULL); EXPECT_EQ(OC_DISCOVERABLE | OC_OBSERVABLE, resource->bitmap); + EXPECT_STREQ(anchor, resource->anchor); + EndpointsVerify(resource->eps); } else if (!strcmp("/a/light2", resource->uri)) { @@ -338,6 +351,8 @@ TEST_F(RDDatabaseTests, AddAndUpdateResources) EXPECT_STREQ(OC_RSRVD_INTERFACE_DEFAULT, resource->interfaces->value); EXPECT_TRUE(resource->interfaces->next == NULL); EXPECT_EQ(OC_DISCOVERABLE, resource->bitmap); + EXPECT_STREQ(anchor, resource->anchor); + EndpointsVerify(resource->eps); } } EXPECT_TRUE(foundThermostat); @@ -345,8 +360,6 @@ TEST_F(RDDatabaseTests, AddAndUpdateResources) EXPECT_TRUE(foundLight2); OCDiscoveryPayloadDestroy(discPayload); discPayload = NULL; - - OCPayloadDestroy((OCPayload *)repPayload); } TEST_F(RDDatabaseTests, DeleteResourcesDevice) @@ -360,11 +373,8 @@ TEST_F(RDDatabaseTests, DeleteResourcesDevice) OCRepPayload *payloads[2]; payloads[0] = CreateResources(deviceIds[0]); payloads[1] = CreateResources(deviceIds[1]); - OCDevAddr address; - address.port = 54321; - OICStrcpy(address.addr, MAX_ADDR_STR_SIZE, "192.168.1.1"); - EXPECT_EQ(OC_STACK_OK, OCRDDatabaseStoreResources(payloads[0], &address)); - EXPECT_EQ(OC_STACK_OK, OCRDDatabaseStoreResources(payloads[1], &address)); + EXPECT_EQ(OC_STACK_OK, OCRDDatabaseStoreResources(payloads[0])); + EXPECT_EQ(OC_STACK_OK, OCRDDatabaseStoreResources(payloads[1])); EXPECT_EQ(OC_STACK_OK, OCRDDatabaseDeleteResources(deviceIds[0], NULL, 0)); diff --git a/resource/csdk/resource-directory/unittests/rdtests.cpp b/resource/csdk/resource-directory/unittests/rdtests.cpp index 919510f..35c5f54 100644 --- a/resource/csdk/resource-directory/unittests/rdtests.cpp +++ b/resource/csdk/resource-directory/unittests/rdtests.cpp @@ -28,6 +28,8 @@ extern "C" #include "oic_malloc.h" #include "oic_string.h" #include "payload_logging.h" + #include "cacommon.h" + #include "coap/pdu.h" } #include "gtest/gtest.h" @@ -298,12 +300,15 @@ TEST_F(RDTests, RDDeleteSpecificResource) #endif #if (defined(RD_SERVER) && defined(RD_CLIENT)) -class RDDiscoverTests : public testing::Test +class RDDiscoverTests : public ::testing::TestWithParam { protected: virtual void SetUp() { remove("RD.db"); + numOptions = 0; + uint16_t format = GetParam(); + OCSetHeaderOption(options, &numOptions, CA_OPTION_ACCEPT, &format, sizeof(format)); EXPECT_EQ(OC_STACK_OK, OCInit("127.0.0.1", 5683, OC_CLIENT_SERVER)); EXPECT_EQ(OC_STACK_OK, OCRDStart()); } @@ -315,6 +320,8 @@ class RDDiscoverTests : public testing::Test } public: static const unsigned char *di[3]; + OCHeaderOption options[1]; + size_t numOptions; }; const unsigned char *RDDiscoverTests::di[3] = { @@ -323,6 +330,17 @@ const unsigned char *RDDiscoverTests::di[3] = (const unsigned char *) "9338c0b2-2373-4324-ba78-17c0ef79506d" }; +static bool EndsWith(const char *str, const char *suffix) +{ + size_t len = strlen(str); + size_t suffixLen = strlen(suffix); + if (len < suffixLen) + { + return false; + } + return !strcmp(&str[len - suffixLen], suffix); +} + static OCStackApplicationResult DiscoverAllResourcesVerify(void *ctx, OCDoHandle handle, OCClientResponse *response) @@ -345,13 +363,13 @@ static OCStackApplicationResult DiscoverAllResourcesVerify(void *ctx, foundId = true; for (OCResourcePayload *resource = payload->resources; resource; resource = resource->next) { - if (!strcmp("/a/light", resource->uri)) + if (EndsWith(resource->uri, "/a/light2")) { - foundLight = true; + foundLight2 = true; } - if (!strcmp("/a/light2", resource->uri)) + else if (EndsWith(resource->uri, "/a/light")) { - foundLight2 = true; + foundLight = true; } } } @@ -363,7 +381,7 @@ static OCStackApplicationResult DiscoverAllResourcesVerify(void *ctx, return OC_STACK_DELETE_TRANSACTION; } -TEST_F(RDDiscoverTests, DiscoverAllResources) +TEST_P(RDDiscoverTests, DiscoverAllResources) { itst::DeadmanTimer killSwitch(SHORT_TEST_TIMEOUT); @@ -381,7 +399,7 @@ TEST_F(RDDiscoverTests, DiscoverAllResources) itst::Callback discoverCB(&DiscoverAllResourcesVerify); EXPECT_EQ(OC_STACK_OK, OCDoResource(NULL, OC_REST_DISCOVER, "/oic/res", NULL, 0, CT_DEFAULT, - OC_HIGH_QOS, discoverCB, NULL, 0)); + OC_HIGH_QOS, discoverCB, options, numOptions)); EXPECT_EQ(OC_STACK_OK, discoverCB.Wait(100)); } @@ -401,10 +419,9 @@ static OCStackApplicationResult ResourceQueryMatchesLocalAndRemoteVerify(void *c payload = payload->next) { EXPECT_TRUE(payload->resources != NULL); - if (payload->resources) + for (OCResourcePayload *resource = payload->resources; resource; resource = resource->next) { - EXPECT_TRUE(payload->resources->next == NULL); - EXPECT_STREQ("/a/light", payload->resources->uri); + EXPECT_TRUE(EndsWith(payload->resources->uri, "/a/light")); EXPECT_STREQ("core.light", payload->resources->types->value); EXPECT_TRUE(payload->resources->types->next == NULL); } @@ -413,7 +430,7 @@ static OCStackApplicationResult ResourceQueryMatchesLocalAndRemoteVerify(void *c return OC_STACK_DELETE_TRANSACTION; } -TEST_F(RDDiscoverTests, ResourceQueryMatchesLocalAndRemote) +TEST_P(RDDiscoverTests, ResourceQueryMatchesLocalAndRemote) { itst::DeadmanTimer killSwitch(SHORT_TEST_TIMEOUT); @@ -428,8 +445,7 @@ TEST_F(RDDiscoverTests, ResourceQueryMatchesLocalAndRemote) itst::Callback discoverCB(&ResourceQueryMatchesLocalAndRemoteVerify); EXPECT_EQ(OC_STACK_OK, OCDoResource(NULL, OC_REST_DISCOVER, "/oic/res?rt=core.light", NULL, 0, - CT_DEFAULT, - OC_HIGH_QOS, discoverCB, NULL, 0)); + CT_DEFAULT, OC_HIGH_QOS, discoverCB, options, numOptions)); EXPECT_EQ(OC_STACK_OK, discoverCB.Wait(100)); } @@ -451,7 +467,7 @@ static OCStackApplicationResult ResourceQueryMatchesLocalOnlyVerify(void *ctx, return OC_STACK_DELETE_TRANSACTION; } -TEST_F(RDDiscoverTests, ResourceQueryMatchesLocalOnly) +TEST_P(RDDiscoverTests, ResourceQueryMatchesLocalOnly) { itst::DeadmanTimer killSwitch(SHORT_TEST_TIMEOUT); @@ -471,8 +487,7 @@ TEST_F(RDDiscoverTests, ResourceQueryMatchesLocalOnly) itst::Callback discoverCB(&ResourceQueryMatchesLocalOnlyVerify); EXPECT_EQ(OC_STACK_OK, OCDoResource(NULL, OC_REST_DISCOVER, "/oic/res?rt=core.light", NULL, 0, - CT_DEFAULT, - OC_HIGH_QOS, discoverCB, NULL, 0)); + CT_DEFAULT, OC_HIGH_QOS, discoverCB, options, numOptions)); EXPECT_EQ(OC_STACK_OK, discoverCB.Wait(100)); } @@ -502,7 +517,7 @@ static void SetStringArray(OCRepPayload *payload, const char *name, const char * OCRepPayloadSetStringArray(payload, name, (const char **)ss, dim); } -TEST_F(RDDiscoverTests, ResourceQueryMatchesRemoteOnly) +TEST_P(RDDiscoverTests, ResourceQueryMatchesRemoteOnly) { itst::DeadmanTimer killSwitch(SHORT_TEST_TIMEOUT); @@ -541,13 +556,12 @@ TEST_F(RDDiscoverTests, ResourceQueryMatchesRemoteOnly) itst::Callback publishCB(&handlePublishCB); EXPECT_EQ(OC_STACK_OK, OCDoResource(NULL, OC_REST_POST, "127.0.0.1/oic/rd?rt=oic.wk.rdpub", NULL, - (OCPayload *)repPayload, CT_DEFAULT, OC_HIGH_QOS, publishCB, NULL, 0)); + (OCPayload *)repPayload, CT_DEFAULT, OC_HIGH_QOS, publishCB, options, numOptions)); EXPECT_EQ(OC_STACK_OK, publishCB.Wait(100)); itst::Callback discoverCB(&ResourceQueryMatchesRemoteOnlyVerify); EXPECT_EQ(OC_STACK_OK, OCDoResource(NULL, OC_REST_DISCOVER, "/oic/res?rt=core.light2", NULL, 0, - CT_DEFAULT, - OC_HIGH_QOS, discoverCB, NULL, 0)); + CT_DEFAULT,OC_HIGH_QOS, discoverCB, options, numOptions)); EXPECT_EQ(OC_STACK_OK, discoverCB.Wait(100)); } @@ -568,7 +582,7 @@ static OCStackApplicationResult DatabaseHas0ResourceQueryMatchesVerify(void *ctx return OC_STACK_DELETE_TRANSACTION; } -TEST_F(RDDiscoverTests, DatabaseHas0ResourceQueryMatches) +TEST_P(RDDiscoverTests, DatabaseHas0ResourceQueryMatches) { itst::DeadmanTimer killSwitch(SHORT_TEST_TIMEOUT); @@ -600,8 +614,7 @@ TEST_F(RDDiscoverTests, DatabaseHas0ResourceQueryMatches) itst::Callback discoverCB(&DatabaseHas0ResourceQueryMatchesVerify); EXPECT_EQ(OC_STACK_OK, OCDoResource(NULL, OC_REST_DISCOVER, "/oic/res?rt=core.light", NULL, 0, - CT_DEFAULT, - OC_HIGH_QOS, discoverCB, NULL, 0)); + CT_DEFAULT,OC_HIGH_QOS, discoverCB, options, numOptions)); EXPECT_EQ(OC_STACK_OK, discoverCB.Wait(100)); } @@ -622,10 +635,9 @@ static OCStackApplicationResult DatabaseHas1ResourceQueryMatchVerify(void *ctx, { payload = payload->next; EXPECT_TRUE(payload->resources != NULL); - if (payload->resources) + for (OCResourcePayload *resource = payload->resources; resource; resource = resource->next) { - EXPECT_TRUE(payload->resources->next == NULL); - EXPECT_STREQ("/a/light2", payload->resources->uri); + EXPECT_TRUE(EndsWith(payload->resources->uri, "/a/light2")); EXPECT_STREQ("core.light2", payload->resources->types->value); EXPECT_TRUE(payload->resources->types->next == NULL); } @@ -636,7 +648,7 @@ static OCStackApplicationResult DatabaseHas1ResourceQueryMatchVerify(void *ctx, return OC_STACK_DELETE_TRANSACTION; } -TEST_F(RDDiscoverTests, DatabaseHas1ResourceQueryMatch) +TEST_P(RDDiscoverTests, DatabaseHas1ResourceQueryMatch) { itst::DeadmanTimer killSwitch(SHORT_TEST_TIMEOUT); @@ -668,8 +680,7 @@ TEST_F(RDDiscoverTests, DatabaseHas1ResourceQueryMatch) itst::Callback discoverCB(&DatabaseHas1ResourceQueryMatchVerify); EXPECT_EQ(OC_STACK_OK, OCDoResource(NULL, OC_REST_DISCOVER, "/oic/res?rt=core.light2", NULL, 0, - CT_DEFAULT, - OC_HIGH_QOS, discoverCB, NULL, 0)); + CT_DEFAULT, OC_HIGH_QOS, discoverCB, options, numOptions)); EXPECT_EQ(OC_STACK_OK, discoverCB.Wait(100)); } @@ -692,9 +703,8 @@ static OCStackApplicationResult DatabaseHasNResourceQueryMatchesVerify(void *ctx for (int i = 0; i < 3; ++i) { EXPECT_TRUE(payload->resources != NULL); - if (payload->resources) + for (OCResourcePayload *resource = payload->resources; resource; resource = resource->next) { - EXPECT_TRUE(payload->resources->next == NULL); EXPECT_STREQ("core.light", payload->resources->types->value); EXPECT_TRUE(payload->resources->types->next == NULL); } @@ -706,7 +716,7 @@ static OCStackApplicationResult DatabaseHasNResourceQueryMatchesVerify(void *ctx return OC_STACK_DELETE_TRANSACTION; } -TEST_F(RDDiscoverTests, DatabaseHasNResourceQueryMatches) +TEST_P(RDDiscoverTests, DatabaseHasNResourceQueryMatches) { itst::DeadmanTimer killSwitch(SHORT_TEST_TIMEOUT); @@ -738,8 +748,7 @@ TEST_F(RDDiscoverTests, DatabaseHasNResourceQueryMatches) itst::Callback discoverCB(&DatabaseHasNResourceQueryMatchesVerify); EXPECT_EQ(OC_STACK_OK, OCDoResource(NULL, OC_REST_DISCOVER, "/oic/res?rt=core.light", NULL, 0, - CT_DEFAULT, - OC_HIGH_QOS, discoverCB, NULL, 0)); + CT_DEFAULT, OC_HIGH_QOS, discoverCB, options, numOptions)); EXPECT_EQ(OC_STACK_OK, discoverCB.Wait(100)); } @@ -760,7 +769,7 @@ static OCStackApplicationResult DatabaseHas0InterfaceQueryMatchesVerify(void *ct return OC_STACK_DELETE_TRANSACTION; } -TEST_F(RDDiscoverTests, DatabaseHas0InterfaceQueryMatches) +TEST_P(RDDiscoverTests, DatabaseHas0InterfaceQueryMatches) { itst::DeadmanTimer killSwitch(SHORT_TEST_TIMEOUT); @@ -792,8 +801,7 @@ TEST_F(RDDiscoverTests, DatabaseHas0InterfaceQueryMatches) itst::Callback discoverCB(&DatabaseHas0InterfaceQueryMatchesVerify); EXPECT_EQ(OC_STACK_OK, OCDoResource(NULL, OC_REST_DISCOVER, "/oic/res?if=oic.if.one", NULL, 0, - CT_DEFAULT, - OC_HIGH_QOS, discoverCB, NULL, 0)); + CT_DEFAULT, OC_HIGH_QOS, discoverCB, options, numOptions)); EXPECT_EQ(OC_STACK_OK, discoverCB.Wait(100)); } @@ -816,10 +824,9 @@ static OCStackApplicationResult DatabaseHas1InterfaceQueryMatchVerify(void *ctx, for (int i = 0; i < 1; ++i) { EXPECT_TRUE(payload->resources != NULL); - if (payload->resources) + for (OCResourcePayload *resource = payload->resources; resource; resource = resource->next) { - EXPECT_TRUE(payload->resources->next == NULL); - EXPECT_STREQ("/a/light2", payload->resources->uri); + EXPECT_TRUE(EndsWith(payload->resources->uri, "/a/light2")); bool foundInterface = false; for (OCStringLL *iface = payload->resources->interfaces; iface; iface = iface->next) { @@ -838,7 +845,7 @@ static OCStackApplicationResult DatabaseHas1InterfaceQueryMatchVerify(void *ctx, return OC_STACK_DELETE_TRANSACTION; } -TEST_F(RDDiscoverTests, DatabaseHas1InterfaceQueryMatch) +TEST_P(RDDiscoverTests, DatabaseHas1InterfaceQueryMatch) { itst::DeadmanTimer killSwitch(SHORT_TEST_TIMEOUT); @@ -870,8 +877,7 @@ TEST_F(RDDiscoverTests, DatabaseHas1InterfaceQueryMatch) itst::Callback discoverCB(&DatabaseHas1InterfaceQueryMatchVerify); EXPECT_EQ(OC_STACK_OK, OCDoResource(NULL, OC_REST_DISCOVER, "/oic/res?if=oic.if.two", NULL, 0, - CT_DEFAULT, - OC_HIGH_QOS, discoverCB, NULL, 0)); + CT_DEFAULT, OC_HIGH_QOS, discoverCB, options, numOptions)); EXPECT_EQ(OC_STACK_OK, discoverCB.Wait(100)); } @@ -894,9 +900,8 @@ static OCStackApplicationResult DatabaseHasNInterfaceQueryMatchesVerify(void *ct for (int i = 0; i < 3; ++i) { EXPECT_TRUE(payload->resources != NULL); - if (payload->resources) + for (OCResourcePayload *resource = payload->resources; resource; resource = resource->next) { - EXPECT_TRUE(payload->resources->next == NULL); bool foundInterface = false; for (OCStringLL *iface = payload->resources->interfaces; iface; iface = iface->next) { @@ -915,7 +920,7 @@ static OCStackApplicationResult DatabaseHasNInterfaceQueryMatchesVerify(void *ct return OC_STACK_DELETE_TRANSACTION; } -TEST_F(RDDiscoverTests, DatabaseHasNInterfaceQueryMatches) +TEST_P(RDDiscoverTests, DatabaseHasNInterfaceQueryMatches) { itst::DeadmanTimer killSwitch(SHORT_TEST_TIMEOUT); @@ -947,8 +952,7 @@ TEST_F(RDDiscoverTests, DatabaseHasNInterfaceQueryMatches) itst::Callback discoverCB(&DatabaseHasNInterfaceQueryMatchesVerify); EXPECT_EQ(OC_STACK_OK, OCDoResource(NULL, OC_REST_DISCOVER, "/oic/res?if=oic.if.a", NULL, 0, - CT_DEFAULT, - OC_HIGH_QOS, discoverCB, NULL, 0)); + CT_DEFAULT, OC_HIGH_QOS, discoverCB, options, numOptions)); EXPECT_EQ(OC_STACK_OK, discoverCB.Wait(100)); } @@ -971,10 +975,9 @@ static OCStackApplicationResult ResourceAndInterfaceQueryMatchVerify(void *ctx, for (int i = 0; i < 1; ++i) { EXPECT_TRUE(payload->resources != NULL); - if (payload->resources) + for (OCResourcePayload *resource = payload->resources; resource; resource = resource->next) { - EXPECT_TRUE(payload->resources->next == NULL); - EXPECT_STREQ("/a/light2", payload->resources->uri); + EXPECT_TRUE(EndsWith(payload->resources->uri, "/a/light2")); EXPECT_STREQ("core.light2", payload->resources->types->value); EXPECT_TRUE(payload->resources->types->next == NULL); bool foundInterface = false; @@ -995,7 +998,7 @@ static OCStackApplicationResult ResourceAndInterfaceQueryMatchVerify(void *ctx, return OC_STACK_DELETE_TRANSACTION; } -TEST_F(RDDiscoverTests, ResourceAndInterfaceQueryMatch) +TEST_P(RDDiscoverTests, ResourceAndInterfaceQueryMatch) { itst::DeadmanTimer killSwitch(SHORT_TEST_TIMEOUT); @@ -1019,8 +1022,7 @@ TEST_F(RDDiscoverTests, ResourceAndInterfaceQueryMatch) itst::Callback discoverCB(&ResourceAndInterfaceQueryMatchVerify); EXPECT_EQ(OC_STACK_OK, OCDoResource(NULL, OC_REST_DISCOVER, "/oic/res?rt=core.light2&if=oic.if.two", - NULL, 0, CT_DEFAULT, - OC_HIGH_QOS, discoverCB, NULL, 0)); + NULL, 0, CT_DEFAULT, OC_HIGH_QOS, discoverCB, options, numOptions)); EXPECT_EQ(OC_STACK_OK, discoverCB.Wait(100)); } @@ -1037,7 +1039,7 @@ static OCStackApplicationResult BaselineVerify(void *ctx, OCDoHandle handle, return OC_STACK_DELETE_TRANSACTION; } -TEST_F(RDDiscoverTests, Baseline) +TEST_P(RDDiscoverTests, Baseline) { itst::DeadmanTimer killSwitch(SHORT_TEST_TIMEOUT); @@ -1052,8 +1054,7 @@ TEST_F(RDDiscoverTests, Baseline) itst::Callback discoverCB(&BaselineVerify); EXPECT_EQ(OC_STACK_OK, OCDoResource(NULL, OC_REST_DISCOVER, "/oic/res?if=oic.if.baseline", NULL, 0, - CT_DEFAULT, - OC_HIGH_QOS, discoverCB, NULL, 0)); + CT_DEFAULT, OC_HIGH_QOS, discoverCB, options, numOptions)); EXPECT_EQ(OC_STACK_OK, discoverCB.Wait(100)); } @@ -1076,7 +1077,7 @@ static OCStackApplicationResult DeleteDeviceVerify(void *ctx, OCDoHandle handle, return OC_STACK_DELETE_TRANSACTION; } -TEST_F(RDDiscoverTests, DeleteDevice) +TEST_P(RDDiscoverTests, DeleteDevice) { itst::DeadmanTimer killSwitch(SHORT_TEST_TIMEOUT); @@ -1096,8 +1097,7 @@ TEST_F(RDDiscoverTests, DeleteDevice) itst::Callback discoverCB(&DeleteDeviceVerify); EXPECT_EQ(OC_STACK_OK, OCDoResource(NULL, OC_REST_DISCOVER, "/oic/res", NULL, 0, - CT_DEFAULT, - OC_HIGH_QOS, discoverCB, NULL, 0)); + CT_DEFAULT, OC_HIGH_QOS, discoverCB, options, numOptions)); EXPECT_EQ(OC_STACK_OK, discoverCB.Wait(100)); } @@ -1122,13 +1122,13 @@ static OCStackApplicationResult Delete1Verify(void *ctx, OCDoHandle handle, foundId = true; for (OCResourcePayload *resource = payload->resources; resource; resource = resource->next) { - if (!strcmp("/a/light", resource->uri)) + if (EndsWith(resource->uri, "/a/light2")) { - foundLight = true; + foundLight2 = true; } - if (!strcmp("/a/light2", resource->uri)) + else if (EndsWith(resource->uri, "/a/light")) { - foundLight2 = true; + foundLight = true; } } } @@ -1140,7 +1140,7 @@ static OCStackApplicationResult Delete1Verify(void *ctx, OCDoHandle handle, return OC_STACK_DELETE_TRANSACTION; } -TEST_F(RDDiscoverTests, Delete1) +TEST_P(RDDiscoverTests, Delete1) { itst::DeadmanTimer killSwitch(SHORT_TEST_TIMEOUT); @@ -1163,8 +1163,7 @@ TEST_F(RDDiscoverTests, Delete1) itst::Callback discoverCB(&Delete1Verify); EXPECT_EQ(OC_STACK_OK, OCDoResource(NULL, OC_REST_DISCOVER, "/oic/res", NULL, 0, - CT_DEFAULT, - OC_HIGH_QOS, discoverCB, NULL, 0)); + CT_DEFAULT, OC_HIGH_QOS, discoverCB, options, numOptions)); EXPECT_EQ(OC_STACK_OK, discoverCB.Wait(100)); } @@ -1190,17 +1189,17 @@ static OCStackApplicationResult DeleteNVerify(void *ctx, OCDoHandle handle, foundId = true; for (OCResourcePayload *resource = payload->resources; resource; resource = resource->next) { - if (!strcmp("/a/light", resource->uri)) + if (EndsWith(resource->uri, "/a/light3")) { - foundLight = true; + foundLight3 = true; } - if (!strcmp("/a/light2", resource->uri)) + else if (EndsWith(resource->uri, "/a/light2")) { foundLight2 = true; } - if (!strcmp("/a/light3", resource->uri)) + else if (EndsWith(resource->uri, "/a/light")) { - foundLight3 = true; + foundLight = true; } } } @@ -1213,7 +1212,7 @@ static OCStackApplicationResult DeleteNVerify(void *ctx, OCDoHandle handle, return OC_STACK_DELETE_TRANSACTION; } -TEST_F(RDDiscoverTests, DeleteN) +TEST_P(RDDiscoverTests, DeleteN) { itst::DeadmanTimer killSwitch(SHORT_TEST_TIMEOUT); @@ -1239,9 +1238,11 @@ TEST_F(RDDiscoverTests, DeleteN) itst::Callback discoverCB(&DeleteNVerify); EXPECT_EQ(OC_STACK_OK, OCDoResource(NULL, OC_REST_DISCOVER, "/oic/res", NULL, 0, - CT_DEFAULT, - OC_HIGH_QOS, discoverCB, NULL, 0)); + CT_DEFAULT, OC_HIGH_QOS, discoverCB, options, numOptions)); EXPECT_EQ(OC_STACK_OK, discoverCB.Wait(100)); } + +INSTANTIATE_TEST_CASE_P(ContentFormat, RDDiscoverTests, + ::testing::Values(COAP_MEDIATYPE_APPLICATION_VND_OCF_CBOR, COAP_MEDIATYPE_APPLICATION_CBOR)); #endif diff --git a/resource/csdk/stack/include/internal/ocendpoint.h b/resource/csdk/stack/include/internal/ocendpoint.h index 05f70e1..00f12d5 100644 --- a/resource/csdk/stack/include/internal/ocendpoint.h +++ b/resource/csdk/stack/include/internal/ocendpoint.h @@ -91,6 +91,15 @@ char* OCCreateEndpointString(const OCEndpointPayload* endpoint); /* + * This function returns pointer of endpoint string. + * + * @param[in] endpoint Pointer of Endpoint. + * + * @return char pointer on success, NULL on failure. + */ + char* OCCreateEndpointStringFromCA(const CAEndpoint_t* endpoint); + +/* * This function parse endpoint string from payload. * * @param[in] endpointStr Pointer of Endpoint string. diff --git a/resource/csdk/stack/src/ocendpoint.c b/resource/csdk/stack/src/ocendpoint.c index 09357c1..fa9d0ce 100644 --- a/resource/csdk/stack/src/ocendpoint.c +++ b/resource/csdk/stack/src/ocendpoint.c @@ -173,52 +173,49 @@ OCStackResult OCGetMatchedTpsFlags(const CATransportAdapter_t adapter, return OC_STACK_OK; } - -OCStackResult OCConvertTpsToString(const OCTpsSchemeFlags tps, char** out) +static const char *ConvertTpsToString(const OCTpsSchemeFlags tps) { - // return given tps as string for payload - // OC_COAP_IPV4 -> OC_COAP - - if (!out) - { - return OC_STACK_INVALID_PARAM; - } - switch (tps) { case OC_COAP: - *out = OICStrdup(COAP_STR); - break; + return COAP_STR; case OC_COAPS: - *out = OICStrdup(COAPS_STR); - break; + return COAPS_STR; #ifdef TCP_ADAPTER case OC_COAP_TCP: - *out = OICStrdup(COAP_TCP_STR); - break; + return COAP_TCP_STR; case OC_COAPS_TCP: - *out = OICStrdup(COAPS_TCP_STR); - break; + return COAPS_TCP_STR; #endif #ifdef HTTP_ADAPTER case OC_HTTP: - *out = OICStrdup(HTTP_STR); - break; + return HTTP_STR; case OC_HTTPS: - *out = OICStrdup(HTTPS_STR); - break; + return HTTPS_STR; #endif #ifdef EDR_ADAPTER case OC_COAP_RFCOMM: - *out = OICStrdup(COAP_RFCOMM_STR); - break; + return COAP_RFCOMM_STR; #endif default: - return OC_STACK_INVALID_PARAM; + return NULL; } +} + +OCStackResult OCConvertTpsToString(const OCTpsSchemeFlags tps, char** out) +{ + // return given tps as string for payload + // OC_COAP_IPV4 -> OC_COAP + + if (!out) + { + return OC_STACK_INVALID_PARAM; + } + + *out = OICStrdup(ConvertTpsToString(tps)); VERIFY_NON_NULL(*out); return OC_STACK_OK; @@ -275,6 +272,60 @@ exit: return NULL; } +char* OCCreateEndpointStringFromCA(const CAEndpoint_t* endpoint) +{ + if (!endpoint) + { + return NULL; + } + + OCTpsSchemeFlags tps = OC_NO_TPS; + OCStackResult result = OCGetMatchedTpsFlags(endpoint->adapter, endpoint->flags, &tps); + if (OC_STACK_OK != result) + { + return NULL; + } + + char* buf = (char*)OICCalloc(MAX_ADDR_STR_SIZE, sizeof(char)); + VERIFY_NON_NULL(buf); + + switch (tps) + { + case OC_COAP: case OC_COAPS: +#ifdef TCP_ADAPTER + case OC_COAP_TCP: case OC_COAPS_TCP: +#endif +#ifdef HTTP_ADAPTER + case OC_HTTP: case OC_HTTPS: +#endif + // checking addr is ipv4 or not + if (endpoint->flags & CA_IPV4) + { + // ipv4 + sprintf(buf, "%s://%s:%d", ConvertTpsToString(tps), endpoint->addr, endpoint->port); + } + else + { + // ipv6 + sprintf(buf, "%s://[%s]:%d", ConvertTpsToString(tps), endpoint->addr, endpoint->port); + } + break; +#ifdef EDR_ADAPTER + case OC_COAP_RFCOMM: + // coap+rfcomm + sprintf(buf, "%s://%s", ConvertTpsToString(tps), endpoint->addr); + break; +#endif + default: + OIC_LOG_V(ERROR, TAG, "Payload has invalid TPS!!! %d", tps); + return NULL; + } + return buf; + +exit: + return NULL; +} + OCStackResult OCParseEndpointString(const char* endpointStr, OCEndpointPayload* out) { if (!endpointStr || !out) @@ -292,6 +343,7 @@ OCStackResult OCParseEndpointString(const char* endpointStr, OCEndpointPayload* size_t addrCharsToWrite = 0; OCStackResult isEnabledAdapter = OC_STACK_ADAPTER_NOT_ENABLED; OCTransportAdapter parsedAdapter = OC_DEFAULT_ADAPTER; + bool isSecure = false; tps = (char*)OICCalloc(OC_MAX_TPS_STR_SIZE, sizeof(char)); VERIFY_NON_NULL(tps); @@ -324,6 +376,7 @@ OCStackResult OCParseEndpointString(const char* endpointStr, OCEndpointPayload* { isEnabledAdapter = OC_STACK_OK; parsedAdapter = OC_ADAPTER_IP; + isSecure = true; } #ifdef TCP_ADAPTER else if (strcmp(tps, COAP_TCP_STR) == 0) @@ -335,6 +388,7 @@ OCStackResult OCParseEndpointString(const char* endpointStr, OCEndpointPayload* { isEnabledAdapter = OC_STACK_OK; parsedAdapter = OC_ADAPTER_TCP; + isSecure = true; } #endif #ifdef HTTP_ADAPTER @@ -387,6 +441,10 @@ OCStackResult OCParseEndpointString(const char* endpointStr, OCEndpointPayload* tmp = strrchr(origin, OC_ENDPOINT_ADDR_TOKEN); } VERIFY_NON_NULL(tmp); + if (isSecure) + { + out->family = (OCTransportFlags)(out->family | OC_FLAG_SECURE); + } // copy addr addrCharsToWrite = tmp - tokPos; diff --git a/resource/csdk/stack/src/ocpayloadconvert.c b/resource/csdk/stack/src/ocpayloadconvert.c index 65f1764..f9f5e3b 100755 --- a/resource/csdk/stack/src/ocpayloadconvert.c +++ b/resource/csdk/stack/src/ocpayloadconvert.c @@ -208,6 +208,128 @@ static int64_t OCStringLLJoin(CborEncoder *map, char *type, OCStringLL *val) return err; } +static int64_t OCConvertResourcePayloadCbor(CborEncoder *linkArray, OCResourcePayload *resource, + OCEndpointPayload *endpoint) +{ + int64_t err = CborNoError; + + // resource map inside the links array. + size_t linkMapLen = LINKS_MAP_LEN; + if (resource->rel) + { + ++linkMapLen; + } + CborEncoder linkMap; + err |= cbor_encoder_create_map(linkArray, &linkMap, linkMapLen); + VERIFY_CBOR_SUCCESS(TAG, err, "Failed creating links map"); + + // Below are insertions of the resource properties into the map. + + // Uri + if (endpoint) + { + char *endpointStr = OCCreateEndpointString(endpoint); + if (!endpointStr) + { + err = CborErrorInternalError; + } + VERIFY_CBOR_SUCCESS(TAG, err, "Failed creating endpoint string"); + char uri[MAX_URI_LENGTH]; + snprintf(uri, MAX_URI_LENGTH, "%s%s", endpointStr, resource->uri); + OICFree(endpointStr); + + err |= AddTextStringToMap(&linkMap, OC_RSRVD_HREF, sizeof(OC_RSRVD_HREF) - 1, + uri); + } + else + { + err |= AddTextStringToMap(&linkMap, OC_RSRVD_HREF, sizeof(OC_RSRVD_HREF) - 1, + resource->uri); + } + VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding uri to links map"); + + // Rel - Not a mandatory field + err |= ConditionalAddTextStringToMap(&linkMap, OC_RSRVD_REL, sizeof(OC_RSRVD_REL) - 1, + resource->rel); + VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding rel to links map"); + + // Resource Type + err |= OCStringLLJoin(&linkMap, OC_RSRVD_RESOURCE_TYPE, resource->types); + VERIFY_CBOR_SUCCESS(TAG, err, + "Failed adding resourceType tag/value to links map"); + + // Interface Types + err |= OCStringLLJoin(&linkMap, OC_RSRVD_INTERFACE, resource->interfaces); + VERIFY_CBOR_SUCCESS(TAG, err, + "Failed adding interfaces tag/value to links map"); + + // Policy + CborEncoder policyMap; + err |= cbor_encode_text_string(&linkMap, OC_RSRVD_POLICY, + sizeof(OC_RSRVD_POLICY) - 1); + VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding policy tag to links map"); + err |= cbor_encoder_create_map(&linkMap, &policyMap, CborIndefiniteLength); + VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding policy map to links map"); + + // Bitmap + err |= cbor_encode_text_string(&policyMap, OC_RSRVD_BITMAP, + sizeof(OC_RSRVD_BITMAP) - 1); + VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding bitmap tag to policy map"); + err |= cbor_encode_uint(&policyMap, resource->bitmap); + VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding bitmap value to policy map"); + + // Secure + bool isSecure; + isSecure = endpoint ? (endpoint->family & OC_FLAG_SECURE) : resource->secure; + err |= cbor_encode_text_string(&policyMap, OC_RSRVD_SECURE, + sizeof(OC_RSRVD_SECURE) - 1); + VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding secure tag to policy map"); + err |= cbor_encode_boolean(&policyMap, isSecure); + VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding secure value to policy map"); + + if (isSecure) + { + err |= cbor_encode_text_string(&policyMap, OC_RSRVD_HOSTING_PORT, + sizeof(OC_RSRVD_HOSTING_PORT) - 1); + VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding secure port tag"); + err |= cbor_encode_uint(&policyMap, endpoint ? endpoint->port : resource->port); + VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding secure port value"); + } + +#ifdef TCP_ADAPTER +#ifdef __WITH_TLS__ + // tls + if (isSecure) + { + err |= cbor_encode_text_string(&policyMap, OC_RSRVD_TLS_PORT, + sizeof(OC_RSRVD_TLS_PORT) - 1); + VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding tcp secure port tag"); + err |= cbor_encode_uint(&policyMap, endpoint ? endpoint->port : resource->tcpPort); + VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding tcp secure port value"); + } + + // tcp + else +#endif + { + err |= cbor_encode_text_string(&policyMap, OC_RSRVD_TCP_PORT, + sizeof(OC_RSRVD_TCP_PORT) - 1); + VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding tcp port tag"); + err |= cbor_encode_uint(&policyMap, endpoint ? endpoint->port : 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"); + + // Finished encoding a resource, close the map. + err |= cbor_encoder_close_container(linkArray, &linkMap); + VERIFY_CBOR_SUCCESS(TAG, err, "Failed closing link map"); + +exit: + return err; +} + static int64_t OCConvertDiscoveryPayloadCbor(OCDiscoveryPayload *payload, uint8_t *outPayload, size_t *size) { @@ -284,107 +406,32 @@ static int64_t OCConvertDiscoveryPayloadCbor(OCDiscoveryPayload *payload, err |= cbor_encode_text_string(&rootMap, OC_RSRVD_LINKS, sizeof(OC_RSRVD_LINKS) - 1); VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting links array tag"); size_t resourceCount = OCDiscoveryPayloadGetResourceCount(payload); - err |= cbor_encoder_create_array(&rootMap, &linkArray, resourceCount); + err |= cbor_encoder_create_array(&rootMap, &linkArray, CborIndefiniteLength); VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting links array"); + bool isSelf = !strcmp(payload->sid, OCGetServerInstanceIDString()); for (size_t i = 0; i < resourceCount; ++i) { - CborEncoder linkMap; - size_t linkMapLen; OCResourcePayload *resource = OCDiscoveryPayloadGetResource(payload, i); VERIFY_PARAM_NON_NULL(TAG, resource, "Failed retrieving resource"); - // resource map inside the links array. - linkMapLen = LINKS_MAP_LEN; - if (resource->rel) - { - ++linkMapLen; - } - err |= cbor_encoder_create_map(&linkArray, &linkMap, linkMapLen); - VERIFY_CBOR_SUCCESS(TAG, err, "Failed creating links map"); - - // Below are insertions of the resource properties into the map. - // Uri - err |= AddTextStringToMap(&linkMap, OC_RSRVD_HREF, sizeof(OC_RSRVD_HREF) - 1, - resource->uri); - VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding uri to links map"); - - // Rel - Not a mandatory field - err |= ConditionalAddTextStringToMap(&linkMap, OC_RSRVD_REL, sizeof(OC_RSRVD_REL) - 1, - resource->rel); - VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding rel to links map"); - - // Resource Type - err |= OCStringLLJoin(&linkMap, OC_RSRVD_RESOURCE_TYPE, resource->types); - VERIFY_CBOR_SUCCESS(TAG, err, - "Failed adding resourceType tag/value to links map"); - - // Interface Types - err |= OCStringLLJoin(&linkMap, OC_RSRVD_INTERFACE, resource->interfaces); - VERIFY_CBOR_SUCCESS(TAG, err, - "Failed adding interfaces tag/value to links map"); - - // Policy - CborEncoder policyMap; - err |= cbor_encode_text_string(&linkMap, OC_RSRVD_POLICY, - sizeof(OC_RSRVD_POLICY) - 1); - VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding policy tag to links map"); - err |= cbor_encoder_create_map(&linkMap, &policyMap, CborIndefiniteLength); - VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding policy map to links map"); - - // Bitmap - err |= cbor_encode_text_string(&policyMap, OC_RSRVD_BITMAP, - sizeof(OC_RSRVD_BITMAP) - 1); - VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding bitmap tag to policy map"); - err |= cbor_encode_uint(&policyMap, resource->bitmap); - VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding bitmap value to policy map"); - - // Secure - err |= cbor_encode_text_string(&policyMap, OC_RSRVD_SECURE, - sizeof(OC_RSRVD_SECURE) - 1); - VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding secure tag to policy map"); - err |= cbor_encode_boolean(&policyMap, resource->secure); - VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding secure value to policy map"); - - if (resource->secure) + if (isSelf || !resource->eps) { - err |= cbor_encode_text_string(&policyMap, OC_RSRVD_HOSTING_PORT, - sizeof(OC_RSRVD_HOSTING_PORT) - 1); - VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding secure port tag"); - err |= cbor_encode_uint(&policyMap, resource->port); - VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding secure port value"); + err |= OCConvertResourcePayloadCbor(&linkArray, resource, NULL); + VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting links array"); } - -#ifdef TCP_ADAPTER -#ifdef __WITH_TLS__ - // tls - if (resource->secure) - { - err |= cbor_encode_text_string(&policyMap, OC_RSRVD_TLS_PORT, - sizeof(OC_RSRVD_TLS_PORT) - 1); - VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding tcp secure port tag"); - err |= cbor_encode_uint(&policyMap, resource->tcpPort); - VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding tcp secure port value"); - } - - // tcp else -#endif { - err |= cbor_encode_text_string(&policyMap, OC_RSRVD_TCP_PORT, - sizeof(OC_RSRVD_TCP_PORT) - 1); - VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding tcp port tag"); - err |= cbor_encode_uint(&policyMap, resource->tcpPort); - VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding tcp port value"); + size_t epsCount = OCEndpointPayloadGetEndpointCount(resource->eps); + for (size_t j = 0; j < epsCount; ++j) + { + OCEndpointPayload* ep = OCEndpointPayloadGetEndpoint(resource->eps, j); + err |= OCConvertResourcePayloadCbor(&linkArray, resource, ep); + VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting links array"); + } } -#endif - err |= cbor_encoder_close_container(&linkMap, &policyMap); - VERIFY_CBOR_SUCCESS(TAG, err, "Failed closing policy map"); - - // Finished encoding a resource, close the map. - err |= cbor_encoder_close_container(&linkArray, &linkMap); - VERIFY_CBOR_SUCCESS(TAG, err, "Failed closing link map"); } + // Close links array inside the root map. err |= cbor_encoder_close_container(&rootMap, &linkArray); VERIFY_CBOR_SUCCESS(TAG, err, "Failed closing link array"); @@ -427,15 +474,45 @@ static int64_t OCConvertDiscoveryPayloadVndOcfCbor(OCDiscoveryPayload *payload, ] */ - // Open the main root array - size_t arrayCount = 0; - for (OCDiscoveryPayload *temp = payload; temp; temp = temp->next) + CborEncoder rootMap; + CborEncoder linkArray; + bool isBaseline = payload->name || payload->type || payload->iface; + if (isBaseline) { - arrayCount += OCDiscoveryPayloadGetResourceCount(temp); + // Open the root map + err |= cbor_encoder_create_map(&encoder, &rootMap, CborIndefiniteLength); + VERIFY_CBOR_SUCCESS(TAG, err, "Failed creating discovery map"); + + // Insert Name + err |= ConditionalAddTextStringToMap(&rootMap, OC_RSRVD_DEVICE_NAME, + sizeof(OC_RSRVD_DEVICE_NAME) - 1, payload->name); + VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting name"); + + // Insert Device ID into the root map + err |= AddTextStringToMap(&rootMap, OC_RSRVD_DEVICE_ID, sizeof(OC_RSRVD_DEVICE_ID) - 1, + payload->sid); + VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting device id"); + + // Insert Resource Type + err |= OCStringLLJoin(&rootMap, OC_RSRVD_RESOURCE_TYPE, payload->type); + VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting RT"); + + // Insert interfaces + err |= OCStringLLJoin(&rootMap, OC_RSRVD_INTERFACE, payload->iface); + VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding interface types tag/value"); + + // Insert Links into the root map. + err |= cbor_encode_text_string(&rootMap, OC_RSRVD_LINKS, sizeof(OC_RSRVD_LINKS) - 1); + VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting links array tag"); + + err |= cbor_encoder_create_array(&rootMap, &linkArray, CborIndefiniteLength); + VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting links array"); + } + else + { + err |= cbor_encoder_create_array(&encoder, &linkArray, CborIndefiniteLength); + VERIFY_CBOR_SUCCESS(TAG, err, "Failed creating discovery root array"); } - CborEncoder rootArray; - err |= cbor_encoder_create_array(&encoder, &rootArray, arrayCount); - VERIFY_CBOR_SUCCESS(TAG, err, "Failed creating discovery root array"); while (payload && payload->resources) { @@ -446,7 +523,7 @@ static int64_t OCConvertDiscoveryPayloadVndOcfCbor(OCDiscoveryPayload *payload, // Open a link map in the root array CborEncoder linkMap; - err |= cbor_encoder_create_map(&rootArray, &linkMap, CborIndefiniteLength); + err |= cbor_encoder_create_map(&linkArray, &linkMap, CborIndefiniteLength); VERIFY_CBOR_SUCCESS(TAG, err, "Failed creating discovery map"); // Uri @@ -548,16 +625,29 @@ static int64_t OCConvertDiscoveryPayloadVndOcfCbor(OCDiscoveryPayload *payload, } // Finished encoding a resource, close the map. - err |= cbor_encoder_close_container(&rootArray, &linkMap); + err |= cbor_encoder_close_container(&linkArray, &linkMap); VERIFY_CBOR_SUCCESS(TAG, err, "Failed closing link map"); } payload = payload->next; } - // Close the final root array. - err |= cbor_encoder_close_container(&encoder, &rootArray); - VERIFY_CBOR_SUCCESS(TAG, err, "Failed closing root array"); + if (isBaseline) + { + // Close the final root array. + err |= cbor_encoder_close_container(&rootMap, &linkArray); + VERIFY_CBOR_SUCCESS(TAG, err, "Failed closing root array"); + + // Close root map inside the root array. + err |= cbor_encoder_close_container(&encoder, &rootMap); + VERIFY_CBOR_SUCCESS(TAG, err, "Failed closing root map"); + } + else + { + // Close the final root array. + err |= cbor_encoder_close_container(&encoder, &linkArray); + VERIFY_CBOR_SUCCESS(TAG, err, "Failed closing root array"); + } exit: return checkError(err, &encoder, outPayload, size); diff --git a/resource/csdk/stack/src/ocpayloadparse.c b/resource/csdk/stack/src/ocpayloadparse.c index 0696fc5..2dcd6c6 100755 --- a/resource/csdk/stack/src/ocpayloadparse.c +++ b/resource/csdk/stack/src/ocpayloadparse.c @@ -405,18 +405,77 @@ static OCStackResult OCParseDiscoveryPayloadVndOcfCbor(OCPayload **outPayload, C OCEndpointPayload *endpoint = NULL; size_t len = 0; CborError err = CborNoError; + CborValue linkMap; + CborValue *linkArray = NULL; *outPayload = NULL; VERIFY_PARAM_NON_NULL(TAG, outPayload, "Invalid Parameter outPayload"); VERIFY_PARAM_NON_NULL(TAG, rootValue, "Invalid Parameter rootValue"); - if (cbor_value_is_array(rootValue)) + if (cbor_value_is_map(rootValue)) + { + rootPayload = OCDiscoveryPayloadCreate(); + VERIFY_PARAM_NON_NULL(TAG, rootPayload, "Failed error initializing discovery payload"); + + // Look for DI + CborValue curVal; + err = cbor_value_map_find_value(rootValue, OC_RSRVD_DEVICE_ID, &curVal); + VERIFY_CBOR_SUCCESS(TAG, err, "to find device id tag"); + if (cbor_value_is_valid(&curVal)) + { + if (cbor_value_is_byte_string(&curVal)) + { + err = cbor_value_dup_byte_string(&curVal, (uint8_t **)&(rootPayload->sid), &len, NULL); + VERIFY_CBOR_SUCCESS(TAG, err, "to copy device id value"); + } + else if (cbor_value_is_text_string(&curVal)) + { + err = cbor_value_dup_text_string(&curVal, &(rootPayload->sid), &len, NULL); + VERIFY_CBOR_SUCCESS(TAG, err, "to copy device id value"); + } + } + + // RT - Not a mandatory field + 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, &rootPayload->type); + VERIFY_CBOR_SUCCESS(TAG, err, "to find resource type"); + } + + // IF - Not a mandatory field + err = cbor_value_map_find_value(rootValue, OC_RSRVD_INTERFACE, &curVal); + if (cbor_value_is_valid(&curVal)) + { + err = OCParseStringLL(rootValue, OC_RSRVD_INTERFACE, &rootPayload->iface); + VERIFY_CBOR_SUCCESS(TAG, err, "to find interface"); + } + + // Name - Not a mandatory field + err = cbor_value_map_find_value(rootValue, OC_RSRVD_DEVICE_NAME, &curVal); + if (cbor_value_is_text_string(&curVal)) + { + err = cbor_value_dup_text_string(&curVal, &rootPayload->name, &len, NULL); + VERIFY_CBOR_SUCCESS(TAG, err, "to find device name"); + } + + // Look for Links which will have an array as the value + err = cbor_value_map_find_value(rootValue, OC_RSRVD_LINKS, &linkMap); + VERIFY_CBOR_SUCCESS(TAG, err, "to find links tag"); + linkArray = &linkMap; + } + else + { + linkArray = rootValue; + } + + if (cbor_value_is_array(linkArray)) { // Root value is already inside the main root array // Enter the main root array and start iterating through the array processing // each resource which shows up as a map. CborValue resourceMap; - err = cbor_value_enter_container(rootValue, &resourceMap); + err = cbor_value_enter_container(linkArray, &resourceMap); VERIFY_CBOR_SUCCESS(TAG, err, "to enter root array"); while (cbor_value_is_map(&resourceMap)) @@ -574,7 +633,7 @@ static OCStackResult OCParseDiscoveryPayloadVndOcfCbor(OCPayload **outPayload, C } } - err = cbor_value_leave_container(rootValue, &resourceMap); + err = cbor_value_leave_container(linkArray, &resourceMap); VERIFY_CBOR_SUCCESS(TAG, err, "to leave resource map"); } else diff --git a/resource/csdk/stack/src/oicresourcedirectory.c b/resource/csdk/stack/src/oicresourcedirectory.c index 3e18cd2..076a44c 100644 --- a/resource/csdk/stack/src/oicresourcedirectory.c +++ b/resource/csdk/stack/src/oicresourcedirectory.c @@ -31,6 +31,7 @@ #include "ocrandom.h" #include "logger.h" #include "ocpayload.h" +#include "ocendpoint.h" #include "oic_malloc.h" #include "oic_string.h" @@ -47,9 +48,11 @@ static sqlite3 *gRDDB = NULL; /* Column indices of RD_DEVICE_LINK_LIST table */ static const uint8_t ins_index = 0; -static const uint8_t uri_index = 1; -static const uint8_t p_index = 4; -static const uint8_t d_index = 7; +static const uint8_t href_index = 1; +static const uint8_t rel_index = 2; +static const uint8_t anchor_index = 3; +static const uint8_t bm_index = 4; +static const uint8_t d_index = 5; /* Column indices of RD_LINK_RT table */ static const uint8_t rt_value_index = 0; @@ -57,6 +60,10 @@ static const uint8_t rt_value_index = 0; /* Column indices of RD_LINK_IF table */ static const uint8_t if_value_index = 0; +/* Column indices of RD_LINK_EP table */ +static const uint8_t ep_value_index = 0; +static const uint8_t pri_value_index = 1; + #define VERIFY_SQLITE(arg) \ if (SQLITE_OK != (arg)) \ { \ @@ -151,16 +158,36 @@ static OCStackResult ResourcePayloadCreate(sqlite3_stmt *stmt, OCDiscoveryPayloa } sqlite3_int64 id = sqlite3_column_int64(stmt, ins_index); - const unsigned char *uri = sqlite3_column_text(stmt, uri_index); - sqlite3_int64 bitmap = sqlite3_column_int64(stmt, p_index); + const unsigned char *uri = sqlite3_column_text(stmt, href_index); + const unsigned char *rel = sqlite3_column_text(stmt, rel_index); + const unsigned char *anchor = sqlite3_column_text(stmt, anchor_index); + sqlite3_int64 bitmap = sqlite3_column_int64(stmt, bm_index); sqlite3_int64 deviceId = sqlite3_column_int64(stmt, d_index); - OIC_LOG_V(DEBUG, TAG, " %s %" PRId64, uri, deviceId); + OIC_LOG_V(DEBUG, TAG, " %s %" PRId64, uri, (int64_t) deviceId); resourcePayload->uri = OICStrdup((char *)uri); if (!resourcePayload->uri) { result = OC_STACK_NO_MEMORY; goto exit; } + if (rel) + { + resourcePayload->rel = OICStrdup((char *)rel); + if (!resourcePayload->rel) + { + result = OC_STACK_NO_MEMORY; + goto exit; + } + } + if (anchor) + { + resourcePayload->anchor = OICStrdup((char *)anchor); + if (!resourcePayload->anchor) + { + result = OC_STACK_NO_MEMORY; + goto exit; + } + } sqlite3_stmt *stmtRT = 0; const char rt[] = "SELECT rt FROM RD_LINK_RT WHERE LINK_ID=@id"; @@ -170,8 +197,8 @@ static OCStackResult ResourcePayloadCreate(sqlite3_stmt *stmt, OCDiscoveryPayloa VERIFY_SQLITE(sqlite3_bind_int64(stmtRT, sqlite3_bind_parameter_index(stmtRT, "@id"), id)); while (SQLITE_ROW == sqlite3_step(stmtRT)) { - const unsigned char *rt1 = sqlite3_column_text(stmtRT, rt_value_index); - result = appendStringLL(&resourcePayload->types, rt1); + const unsigned char *tempRt = sqlite3_column_text(stmtRT, rt_value_index); + result = appendStringLL(&resourcePayload->types, tempRt); if (OC_STACK_OK != result) { goto exit; @@ -197,32 +224,62 @@ static OCStackResult ResourcePayloadCreate(sqlite3_stmt *stmt, OCDiscoveryPayloa VERIFY_SQLITE(sqlite3_finalize(stmtIF)); resourcePayload->bitmap = (uint8_t)(bitmap & (OC_OBSERVABLE | OC_DISCOVERABLE)); - resourcePayload->secure = ((bitmap & OC_SECURE) != 0); - const char address[] = "SELECT di FROM RD_DEVICE_LIST " + sqlite3_stmt *stmtEp = 0; + const char ep[] = "SELECT ep,pri FROM RD_LINK_EP WHERE LINK_ID=@id"; + int epSize = (int)sizeof(ep); + + VERIFY_SQLITE(sqlite3_prepare_v2(gRDDB, ep, epSize, &stmtEp, NULL)); + VERIFY_SQLITE(sqlite3_bind_int64(stmtEp, sqlite3_bind_parameter_index(stmtEp, "@id"), id)); + while (SQLITE_ROW == sqlite3_step(stmtEp)) + { + OCEndpointPayload *epPayload = (OCEndpointPayload *)OICCalloc(1, sizeof(OCEndpointPayload)); + if (!epPayload) + { + result = OC_STACK_NO_MEMORY; + goto exit; + } + const unsigned char *tempEp = sqlite3_column_text(stmtEp, ep_value_index); + result = OCParseEndpointString((const char *)tempEp, epPayload); + if (OC_STACK_OK != result) + { + goto exit; + } + sqlite3_int64 pri = sqlite3_column_int64(stmtEp, pri_value_index); + epPayload->pri = (uint16_t)pri; + OCEndpointPayload **tmp = &resourcePayload->eps; + while (*tmp) + { + tmp = &(*tmp)->next; + } + *tmp = epPayload; + } + VERIFY_SQLITE(sqlite3_finalize(stmtEp)); + + const char di[] = "SELECT di FROM RD_DEVICE_LIST " "INNER JOIN RD_DEVICE_LINK_LIST ON RD_DEVICE_LINK_LIST.DEVICE_ID = RD_DEVICE_LIST.ID " "WHERE RD_DEVICE_LINK_LIST.DEVICE_ID=@deviceId"; - int addressSize = (int)sizeof(address); + int diSize = (int)sizeof(di); const uint8_t di_index = 0; - sqlite3_stmt *stmt1 = 0; - VERIFY_SQLITE(sqlite3_prepare_v2(gRDDB, address, addressSize, &stmt1, NULL)); - VERIFY_SQLITE(sqlite3_bind_int64(stmt1, sqlite3_bind_parameter_index(stmt1, "@deviceId"), deviceId)); + sqlite3_stmt *stmtDI = 0; + VERIFY_SQLITE(sqlite3_prepare_v2(gRDDB, di, diSize, &stmtDI, NULL)); + VERIFY_SQLITE(sqlite3_bind_int64(stmtDI, sqlite3_bind_parameter_index(stmtDI, "@deviceId"), deviceId)); - res = sqlite3_step(stmt1); + res = sqlite3_step(stmtDI); if (SQLITE_ROW == res || SQLITE_DONE == res) { - const unsigned char *di = sqlite3_column_text(stmt1, di_index); - OIC_LOG_V(DEBUG, TAG, " %s", di); - discPayload->sid = OICStrdup((char *)di); + const unsigned char *tempDi = sqlite3_column_text(stmtDI, di_index); + OIC_LOG_V(DEBUG, TAG, " %s", tempDi); + discPayload->sid = OICStrdup((char *)tempDi); if (!discPayload->sid) { result = OC_STACK_NO_MEMORY; goto exit; } } - VERIFY_SQLITE(sqlite3_finalize(stmt1)); + VERIFY_SQLITE(sqlite3_finalize(stmtDI)); OCDiscoveryPayloadAddNewResource(discPayload, resourcePayload); res = sqlite3_step(stmt); }