From 6ad3921ee69849916f249461a45c36e283feadb9 Mon Sep 17 00:00:00 2001 From: Todd Malsbary Date: Wed, 8 Mar 2017 20:32:01 -0800 Subject: [PATCH] Clean up error handling in resource directory. - Response to /oic/res query of resource directory leaked the database handle and associated file descriptors. - Update/delete transactions could be non-atomic. - Short-circuit error paths did not clean up properly. Change-Id: I0a6cb8e8332e4f1d6c960d61c8a39320c1381b5f Signed-off-by: Todd Malsbary Reviewed-on: https://gerrit.iotivity.org/gerrit/17793 Tested-by: jenkins-iotivity Reviewed-by: Dan Mihai --- .../resource-directory/src/internal/rd_database.c | 496 +++++++++++++-------- resource/csdk/stack/src/oicresourcedirectory.c | 215 +++++---- 2 files changed, 399 insertions(+), 312 deletions(-) diff --git a/resource/csdk/resource-directory/src/internal/rd_database.c b/resource/csdk/resource-directory/src/internal/rd_database.c index 4b13774..70bb58b 100644 --- a/resource/csdk/resource-directory/src/internal/rd_database.c +++ b/resource/csdk/resource-directory/src/internal/rd_database.c @@ -36,14 +36,6 @@ static sqlite3 *gRDDB = NULL; -#define VERIFY_SQLITE(arg) \ - if (SQLITE_OK != (arg)) \ - { \ - OIC_LOG_V(ERROR, TAG, "Error in " #arg ", Error Message: %s", sqlite3_errmsg(gRDDB)); \ - sqlite3_exec(gRDDB, "ROLLBACK", NULL, NULL, NULL); \ - return OC_STACK_ERROR; \ - } - #define CHECK_DATABASE_INIT \ if (!gRDDB) \ { \ @@ -51,6 +43,13 @@ static sqlite3 *gRDDB = NULL; return OC_STACK_ERROR; \ } +#define VERIFY_SQLITE(arg) \ + if (SQLITE_OK != (res = (arg))) \ + { \ + OIC_LOG_V(ERROR, TAG, "Error in " #arg ", Error Message: %s", sqlite3_errmsg(gRDDB)); \ + goto exit; \ + } + #define STR(a) #a #define XSTR(a) STR(a) @@ -95,84 +94,24 @@ static void errorCallback(void *arg, int errCode, const char *errMsg) OIC_LOG_V(ERROR, TAG, "SQLLite Error: %s : %d", errMsg, errCode); } -OCStackResult OCRDDatabaseInit() -{ - if (SQLITE_OK == sqlite3_config(SQLITE_CONFIG_LOG, errorCallback)) - { - OIC_LOG_V(INFO, TAG, "SQLite debugging log initialized."); - } - - int sqlRet; - sqlRet = sqlite3_open_v2(OCRDDatabaseGetStorageFilename(), &gRDDB, - SQLITE_OPEN_READWRITE, NULL); - if (SQLITE_OK != sqlRet) - { - OIC_LOG(DEBUG, TAG, "RD database file did not open, as no table exists."); - OIC_LOG(DEBUG, TAG, "RD creating new table."); - sqlRet = sqlite3_open_v2(OCRDDatabaseGetStorageFilename(), &gRDDB, - SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL); - if (SQLITE_OK == sqlRet) - { - VERIFY_SQLITE(sqlite3_exec(gRDDB, RD_TABLE, NULL, NULL, NULL)); - OIC_LOG(DEBUG, TAG, "RD created RD_DEVICE_LIST table."); - - VERIFY_SQLITE(sqlite3_exec(gRDDB, RD_LL_TABLE, NULL, NULL, NULL)); - OIC_LOG(DEBUG, TAG, "RD created RD_DEVICE_LINK_LIST table."); - - VERIFY_SQLITE(sqlite3_exec(gRDDB, RD_RT_TABLE, NULL, NULL, NULL)); - OIC_LOG(DEBUG, TAG, "RD created RD_LINK_RT table."); - - 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; - } - } - - if (sqlRet == SQLITE_OK) - { - sqlite3_stmt *stmt = 0; - VERIFY_SQLITE(sqlite3_prepare_v2 (gRDDB, "PRAGMA foreign_keys = ON;", -1, &stmt, NULL)); - - if (SQLITE_DONE != sqlite3_step(stmt)) - { - sqlite3_finalize(stmt); - return OC_STACK_ERROR; - } - - VERIFY_SQLITE(sqlite3_finalize(stmt)); - } - - return OC_STACK_OK; -} - -OCStackResult OCRDDatabaseClose() +static int storeResourceTypes(char **resourceTypes, size_t size, sqlite3_int64 rowid) { - CHECK_DATABASE_INIT; - VERIFY_SQLITE(sqlite3_close_v2(gRDDB)); - return OC_STACK_OK; -} - -static int storeResourceType(char **resourceTypes, size_t size, sqlite3_int64 rowid) -{ - int res = 1; - VERIFY_SQLITE(sqlite3_exec(gRDDB, "BEGIN TRANSACTION", NULL, NULL, NULL)); + int res; + VERIFY_SQLITE(sqlite3_exec(gRDDB, "SAVEPOINT storeResourceTypes", NULL, NULL, NULL)); const char *deleteRT = "DELETE FROM RD_LINK_RT WHERE LINK_ID=@id"; const char *insertRT = "INSERT INTO RD_LINK_RT VALUES(@resourceType, @id)"; - sqlite3_stmt *stmt = 0; + sqlite3_stmt *stmt = NULL; VERIFY_SQLITE(sqlite3_prepare_v2(gRDDB, deleteRT, strlen(deleteRT) + 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) + if (SQLITE_DONE != res) { - sqlite3_exec(gRDDB, "ROLLBACK", NULL, NULL, NULL); - return res; + goto exit; } + VERIFY_SQLITE(sqlite3_finalize(stmt)); + stmt = NULL; for (size_t i = 0; i < size; i++) { @@ -180,93 +119,107 @@ static int storeResourceType(char **resourceTypes, size_t size, sqlite3_int64 ro if (resourceTypes[i]) { VERIFY_SQLITE(sqlite3_bind_text(stmt, sqlite3_bind_parameter_index(stmt, "@resourceType"), - resourceTypes[i], strlen(resourceTypes[i]), SQLITE_STATIC)); + resourceTypes[i], strlen(resourceTypes[i]), SQLITE_STATIC)); 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) + if (SQLITE_DONE != res) { - sqlite3_exec(gRDDB, "ROLLBACK", NULL, NULL, NULL); - return res; + goto exit; } + VERIFY_SQLITE(sqlite3_finalize(stmt)); + stmt = NULL; } - VERIFY_SQLITE(sqlite3_exec(gRDDB, "COMMIT", NULL, NULL, NULL)); + VERIFY_SQLITE(sqlite3_exec(gRDDB, "RELEASE storeResourceTypes", NULL, NULL, NULL)); res = SQLITE_OK; +exit: + sqlite3_finalize(stmt); + if (SQLITE_OK != res) + { + sqlite3_exec(gRDDB, "ROLLBACK TO storeResourceTypes", NULL, NULL, NULL); + } return res; } -static int storeInterfaceType(char **interfaceTypes, size_t size, sqlite3_int64 rowid) +static int storeInterfaces(char **interfaces, size_t size, sqlite3_int64 rowid) { - int res = 1; - VERIFY_SQLITE(sqlite3_exec(gRDDB, "BEGIN TRANSACTION", NULL, NULL, NULL)); + int res; + VERIFY_SQLITE(sqlite3_exec(gRDDB, "SAVEPOINT storeInterfaces", NULL, NULL, NULL)); const char *deleteIF = "DELETE FROM RD_LINK_IF WHERE LINK_ID=@id"; const char *insertIF = "INSERT INTO RD_LINK_IF VALUES(@interfaceType, @id)"; - sqlite3_stmt *stmt = 0; + sqlite3_stmt *stmt = NULL; VERIFY_SQLITE(sqlite3_prepare_v2(gRDDB, deleteIF, strlen(deleteIF) + 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) + if (SQLITE_DONE != res) { - sqlite3_exec(gRDDB, "ROLLBACK", NULL, NULL, NULL); - return res; + goto exit; } + VERIFY_SQLITE(sqlite3_finalize(stmt)); + stmt = NULL; for (size_t i = 0; i < size; i++) { VERIFY_SQLITE(sqlite3_prepare_v2(gRDDB, insertIF, strlen(insertIF) + 1, &stmt, NULL)); - if (interfaceTypes[i]) + if (interfaces[i]) { VERIFY_SQLITE(sqlite3_bind_text(stmt, sqlite3_bind_parameter_index(stmt, "@interfaceType"), - interfaceTypes[i], strlen(interfaceTypes[i]), SQLITE_STATIC)); + interfaces[i], strlen(interfaces[i]), SQLITE_STATIC)); 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) + if (SQLITE_DONE != res) { - sqlite3_exec(gRDDB, "ROLLBACK", NULL, NULL, NULL); - return res; + goto exit; } + VERIFY_SQLITE(sqlite3_finalize(stmt)); + stmt = NULL; } - VERIFY_SQLITE(sqlite3_exec(gRDDB, "COMMIT", NULL, NULL, NULL)); + VERIFY_SQLITE(sqlite3_exec(gRDDB, "RELEASE storeInterfaces", NULL, NULL, NULL)); res = SQLITE_OK; + +exit: + sqlite3_finalize(stmt); + if (SQLITE_OK != res) + { + sqlite3_exec(gRDDB, "ROLLBACK TO storeInterfaces", NULL, NULL, NULL); + } 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)); + char *ep = NULL; + + int res; + VERIFY_SQLITE(sqlite3_exec(gRDDB, "SAVEPOINT storeEndpoints", 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; + sqlite3_stmt *stmt = NULL; 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) + if (SQLITE_DONE != res) { - sqlite3_exec(gRDDB, "ROLLBACK", NULL, NULL, NULL); - return res; + goto exit; } + VERIFY_SQLITE(sqlite3_finalize(stmt)); + stmt = NULL; 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)); + ep, strlen(ep), SQLITE_STATIC)); } sqlite3_int64 pri; if (OCRepPayloadGetPropInt(eps[i], OC_RSRVD_PRIORITY, (int64_t *) &pri)) @@ -275,24 +228,32 @@ static int storeEndpoints(OCRepPayload **eps, size_t size, sqlite3_int64 rowid) } 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) + if (SQLITE_DONE != res) { - sqlite3_exec(gRDDB, "ROLLBACK", NULL, NULL, NULL); - return res; + goto exit; } + VERIFY_SQLITE(sqlite3_finalize(stmt)); + stmt = NULL; OICFree(ep); + ep = NULL; } - VERIFY_SQLITE(sqlite3_exec(gRDDB, "COMMIT", NULL, NULL, NULL)); + VERIFY_SQLITE(sqlite3_exec(gRDDB, "RELEASE storeEndpoints", NULL, NULL, NULL)); res = SQLITE_OK; + +exit: + OICFree(ep); + sqlite3_finalize(stmt); + if (SQLITE_OK != res) + { + sqlite3_exec(gRDDB, "ROLLBACK TO storeInterfaces", NULL, NULL, NULL); + } return res; } static int storeLinkPayload(OCRepPayload *rdPayload, sqlite3_int64 rowid) { - int res = 1 ; - size_t j = 0; + int res = SQLITE_OK; /* * Iterate over the properties manually rather than OCRepPayloadGetPropObjectArray to avoid @@ -312,49 +273,57 @@ static int storeLinkPayload(OCRepPayload *rdPayload, sqlite3_int64 rowid) } if (links != NULL) { + sqlite3_stmt *stmt = NULL; + char *uri = NULL; + char *anchor = NULL; + OCRepPayload *p = NULL; + char **rt = NULL; + 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 *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 anchor=@anchor,bm=@bm " "WHERE DEVICE_ID=@id AND href=@uri"; - sqlite3_stmt *stmt = 0; - - for (size_t i = 0; i < links->arr.dimensions[0]; i++) + for (size_t i = 0; (SQLITE_OK == res) && (i < links->arr.dimensions[0]); i++) { - VERIFY_SQLITE(sqlite3_prepare_v2(gRDDB, insertDeviceLLList, strlen(insertDeviceLLList) + 1, &stmt, NULL)); - VERIFY_SQLITE(sqlite3_exec(gRDDB, "BEGIN TRANSACTION", NULL, NULL, NULL)); + VERIFY_SQLITE(sqlite3_exec(gRDDB, "SAVEPOINT storeLinkPayload", NULL, NULL, NULL)); + + VERIFY_SQLITE(sqlite3_prepare_v2(gRDDB, insertDeviceLLList, + strlen(insertDeviceLLList) + 1, &stmt, NULL)); OCRepPayload *link = links->arr.objArray[i]; VERIFY_SQLITE(sqlite3_bind_int64(stmt, sqlite3_bind_parameter_index(stmt, "@id"), rowid)); - char *uri = NULL; if (OCRepPayloadGetPropString(link, OC_RSRVD_HREF, &uri)) { VERIFY_SQLITE(sqlite3_bind_text(stmt, sqlite3_bind_parameter_index(stmt, "@uri"), - uri, strlen(uri), SQLITE_STATIC)); + uri, strlen(uri), SQLITE_STATIC)); } - if (sqlite3_step(stmt) != SQLITE_DONE) + res = sqlite3_step(stmt); + if (SQLITE_DONE != res) { - sqlite3_exec(gRDDB, "ROLLBACK", NULL, NULL, NULL); - sqlite3_finalize(stmt); - return res; + goto exit; } VERIFY_SQLITE(sqlite3_finalize(stmt)); + stmt = NULL; - VERIFY_SQLITE(sqlite3_prepare_v2(gRDDB, updateDeviceLLList, strlen(updateDeviceLLList) + 1, - &stmt, NULL)); + VERIFY_SQLITE(sqlite3_prepare_v2(gRDDB, updateDeviceLLList, + strlen(updateDeviceLLList) + 1, &stmt, NULL)); VERIFY_SQLITE(sqlite3_bind_int64(stmt, sqlite3_bind_parameter_index(stmt, "@id"), rowid)); if (uri) { VERIFY_SQLITE(sqlite3_bind_text(stmt, sqlite3_bind_parameter_index(stmt, "@uri"), - uri, strlen(uri), SQLITE_STATIC)); + 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)); + anchor, strlen(anchor), SQLITE_STATIC)); } - OCRepPayload *p = NULL; if (OCRepPayloadGetPropObject(link, OC_RSRVD_POLICY, &p)) { sqlite3_int64 bm = 0; @@ -363,34 +332,28 @@ static int storeLinkPayload(OCRepPayload *rdPayload, sqlite3_int64 rowid) VERIFY_SQLITE(sqlite3_bind_int64(stmt, sqlite3_bind_parameter_index(stmt, "@bm"), bm)); } } - if (sqlite3_step(stmt) != SQLITE_DONE) + res = sqlite3_step(stmt); + if (SQLITE_DONE != res) { - sqlite3_exec(gRDDB, "ROLLBACK", NULL, NULL, NULL); - sqlite3_finalize(stmt); - return res; + goto exit; } VERIFY_SQLITE(sqlite3_finalize(stmt)); - VERIFY_SQLITE(sqlite3_exec(gRDDB, "COMMIT", NULL, NULL, NULL)); - - char **rt = NULL; - 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}; + stmt = NULL; + 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)); if (uri) { VERIFY_SQLITE(sqlite3_bind_text(stmt, sqlite3_bind_parameter_index(stmt, "@uri"), - uri, strlen(uri), SQLITE_STATIC)); + uri, strlen(uri), SQLITE_STATIC)); } res = sqlite3_step(stmt); if (res == SQLITE_ROW || res == SQLITE_DONE) { sqlite3_int64 ins = sqlite3_column_int64(stmt, 0); VERIFY_SQLITE(sqlite3_finalize(stmt)); + stmt = NULL; if (!OCRepPayloadSetPropInt(link, OC_RSRVD_INS, ins)) { OIC_LOG_V(ERROR, TAG, "Error setting 'ins' value"); @@ -399,89 +362,117 @@ 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(storeResourceTypes(rt, rtDim[0], ins)); + VERIFY_SQLITE(storeInterfaces(itf, itfDim[0], ins)); VERIFY_SQLITE(storeEndpoints(eps, epsDim[0], ins)); } else { VERIFY_SQLITE(sqlite3_finalize(stmt)); + stmt = NULL; } - OICFree(uri); - OCPayloadDestroy((OCPayload *)p); - for (j = 0; j < rtDim[0]; j++) + VERIFY_SQLITE(sqlite3_exec(gRDDB, "RELEASE storeLinkPayload", NULL, NULL, NULL)); + res = SQLITE_OK; + + exit: + if (eps) + { + for (size_t j = 0; j < epsDim[0]; j++) + { + OCRepPayloadDestroy(eps[j]); + } + OICFree(eps); + eps = NULL; + } + if (itf) + { + for (size_t j = 0; j < itfDim[0]; j++) + { + OICFree(itf[j]); + } + OICFree(itf); + itf = NULL; + } + if (rt) { - OICFree(rt[j]); + for (size_t j = 0; j < rtDim[0]; j++) + { + OICFree(rt[j]); + } + OICFree(rt); + rt = NULL; } - OICFree(rt); - for (j = 0; j < itfDim[0]; j++) + OCPayloadDestroy((OCPayload *)p); + p = NULL; + OICFree(anchor); + anchor = NULL; + OICFree(uri); + uri = NULL; + sqlite3_finalize(stmt); + stmt = NULL; + if (SQLITE_OK != res) { - OICFree(itf[j]); + sqlite3_exec(gRDDB, "ROLLBACK TO storeLinkPayload", NULL, NULL, NULL); } - OICFree(itf); } - - res = SQLITE_OK; } + return res; } -OCStackResult OCRDDatabaseStoreResources(OCRepPayload *payload) +static int storeResources(OCRepPayload *payload) { - CHECK_DATABASE_INIT; - char *deviceId = NULL; OCRepPayloadGetPropString(payload, OC_RSRVD_DEVICE_ID, &deviceId); 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 */ + int res; VERIFY_SQLITE(sqlite3_exec(gRDDB, "BEGIN TRANSACTION", NULL, NULL, NULL)); - sqlite3_stmt *stmt = 0; + /* INSERT OR IGNORE then UPDATE to update or insert the row without triggering the cascading deletes */ + sqlite3_stmt *stmt = NULL; 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)); - + VERIFY_SQLITE(sqlite3_prepare_v2(gRDDB, insertDeviceList, strlen(insertDeviceList) + 1, + &stmt, NULL)); if (deviceId) { VERIFY_SQLITE(sqlite3_bind_text(stmt, sqlite3_bind_parameter_index(stmt, "@deviceId"), - deviceId, strlen(deviceId), SQLITE_STATIC)); + deviceId, strlen(deviceId), SQLITE_STATIC)); } if (ttl) { VERIFY_SQLITE(sqlite3_bind_int64(stmt, sqlite3_bind_parameter_index(stmt, "@ttl"), ttl)); } - if (sqlite3_step(stmt) != SQLITE_DONE) + res = sqlite3_step(stmt); + if (SQLITE_DONE != res) { - sqlite3_exec(gRDDB, "ROLLBACK", NULL, NULL, NULL); - sqlite3_finalize(stmt); - return OC_STACK_ERROR; + goto exit; } VERIFY_SQLITE(sqlite3_finalize(stmt)); + stmt = NULL; 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)); + &stmt, NULL)); if (deviceId) { VERIFY_SQLITE(sqlite3_bind_text(stmt, sqlite3_bind_parameter_index(stmt, "@deviceId"), - deviceId, strlen(deviceId), SQLITE_STATIC)); + deviceId, strlen(deviceId), SQLITE_STATIC)); } if (ttl) { VERIFY_SQLITE(sqlite3_bind_int64(stmt, sqlite3_bind_parameter_index(stmt, "@ttl"), ttl)); } - if (sqlite3_step(stmt) != SQLITE_DONE) + res = sqlite3_step(stmt); + if (SQLITE_DONE != res) { - sqlite3_exec(gRDDB, "ROLLBACK", NULL, NULL, NULL); - sqlite3_finalize(stmt); - return OC_STACK_ERROR; + goto exit; } VERIFY_SQLITE(sqlite3_finalize(stmt)); - - VERIFY_SQLITE(sqlite3_exec(gRDDB, "COMMIT", NULL, NULL, NULL)); + stmt = NULL; /* Store the rest of the payload */ const char *input = "SELECT ID FROM RD_DEVICE_LIST WHERE di=@deviceId"; @@ -489,37 +480,50 @@ OCStackResult OCRDDatabaseStoreResources(OCRepPayload *payload) if (deviceId) { VERIFY_SQLITE(sqlite3_bind_text(stmt, sqlite3_bind_parameter_index(stmt, "@deviceId"), - deviceId, strlen(deviceId), SQLITE_STATIC)); + deviceId, strlen(deviceId), SQLITE_STATIC)); } - int res = sqlite3_step(stmt); + res = sqlite3_step(stmt); if (res == SQLITE_ROW || res == SQLITE_DONE) { sqlite3_int64 rowid = sqlite3_column_int64(stmt, 0); VERIFY_SQLITE(sqlite3_finalize(stmt)); + stmt = NULL; VERIFY_SQLITE(storeLinkPayload(payload, rowid)); } else { VERIFY_SQLITE(sqlite3_finalize(stmt)); + stmt = NULL; } + VERIFY_SQLITE(sqlite3_exec(gRDDB, "COMMIT", NULL, NULL, NULL)); + res = SQLITE_OK; + +exit: + sqlite3_finalize(stmt); OICFree(deviceId); - return OC_STACK_OK; + if (SQLITE_OK != res) + { + sqlite3_exec(gRDDB, "ROLLBACK", NULL, NULL, NULL); + } + return res; } -OCStackResult OCRDDatabaseDeleteResources(const char *deviceId, const uint8_t *instanceIds, uint8_t nInstanceIds) +static int deleteResources(const char *deviceId, const uint8_t *instanceIds, uint8_t nInstanceIds) { - CHECK_DATABASE_INIT; + char *delResource = NULL; + int res; VERIFY_SQLITE(sqlite3_exec(gRDDB, "BEGIN TRANSACTION", NULL, NULL, NULL)); - sqlite3_stmt *stmt = 0; + + sqlite3_stmt *stmt = NULL; if (!instanceIds || !nInstanceIds) { char *delDevice = "DELETE FROM RD_DEVICE_LIST WHERE di=@deviceId"; - VERIFY_SQLITE(sqlite3_prepare_v2(gRDDB, delDevice, strlen(delDevice) + 1, &stmt, NULL)); - + VERIFY_SQLITE(sqlite3_prepare_v2(gRDDB, delDevice, strlen(delDevice) + 1, + &stmt, NULL)); VERIFY_SQLITE(sqlite3_bind_text(stmt, sqlite3_bind_parameter_index(stmt, "@deviceId"), - deviceId, strlen(deviceId), SQLITE_STATIC)); + deviceId, strlen(deviceId), SQLITE_STATIC)); } else { @@ -531,11 +535,11 @@ OCStackResult OCRDDatabaseDeleteResources(const char *deviceId, const uint8_t *i size_t inLen = nInstanceIds + (nInstanceIds - 1); const char post[] = "))"; size_t len = sizeof(pre) + inLen + sizeof(post); - char *delResource = OICCalloc(len, 1); + delResource = OICCalloc(len, 1); if (!delResource) { - OIC_LOG(ERROR, TAG, "SQL query is NULL"); - return OC_STACK_ERROR; + res = SQLITE_NOMEM; + goto exit; } OICStrcat(delResource, len, pre); OICStrcat(delResource, len, "?"); @@ -544,28 +548,126 @@ OCStackResult OCRDDatabaseDeleteResources(const char *deviceId, const uint8_t *i OICStrcat(delResource, len, ",?"); } OICStrcat(delResource, len, post); - int prepareResult = sqlite3_prepare_v2(gRDDB, delResource, strlen(delResource) + 1, &stmt, NULL); - OICFree(delResource); - VERIFY_SQLITE(prepareResult); - + VERIFY_SQLITE(sqlite3_prepare_v2(gRDDB, delResource, strlen(delResource) + 1, + &stmt, NULL)); VERIFY_SQLITE(sqlite3_bind_text(stmt, sqlite3_bind_parameter_index(stmt, "@deviceId"), - deviceId, strlen(deviceId), SQLITE_STATIC)); + deviceId, strlen(deviceId), SQLITE_STATIC)); assert(sqlite3_bind_parameter_index(stmt, "@deviceId") == 1); for (uint8_t i = 0; i < nInstanceIds; ++i) { VERIFY_SQLITE(sqlite3_bind_int(stmt, 2 + i, instanceIds[i])); } } - if (sqlite3_step(stmt) != SQLITE_DONE) + + res = sqlite3_step(stmt); + if (SQLITE_DONE != res) { - sqlite3_exec(gRDDB, "ROLLBACK", NULL, NULL, NULL); - sqlite3_finalize(stmt); - return OC_STACK_ERROR; + goto exit; } VERIFY_SQLITE(sqlite3_finalize(stmt)); + stmt = NULL; + VERIFY_SQLITE(sqlite3_exec(gRDDB, "COMMIT", NULL, NULL, NULL)); + res = SQLITE_OK; + +exit: + OICFree(delResource); + sqlite3_finalize(stmt); + if (SQLITE_OK != res) + { + sqlite3_exec(gRDDB, "ROLLBACK", NULL, NULL, NULL); + } + return res; +} - return OC_STACK_OK; +OCStackResult OCRDDatabaseInit() +{ + if (SQLITE_OK == sqlite3_config(SQLITE_CONFIG_LOG, errorCallback)) + { + OIC_LOG_V(INFO, TAG, "SQLite debugging log initialized."); + } + + sqlite3_stmt *stmt = NULL; + int res; + res = sqlite3_open_v2(OCRDDatabaseGetStorageFilename(), &gRDDB, SQLITE_OPEN_READWRITE, NULL); + if (SQLITE_OK != res) + { + OIC_LOG(DEBUG, TAG, "RD database file did not open, as no table exists."); + OIC_LOG(DEBUG, TAG, "RD creating new table."); + VERIFY_SQLITE(sqlite3_open_v2(OCRDDatabaseGetStorageFilename(), &gRDDB, + SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL)); + + VERIFY_SQLITE(sqlite3_exec(gRDDB, RD_TABLE, NULL, NULL, NULL)); + OIC_LOG(DEBUG, TAG, "RD created RD_DEVICE_LIST table."); + + VERIFY_SQLITE(sqlite3_exec(gRDDB, RD_LL_TABLE, NULL, NULL, NULL)); + OIC_LOG(DEBUG, TAG, "RD created RD_DEVICE_LINK_LIST table."); + + VERIFY_SQLITE(sqlite3_exec(gRDDB, RD_RT_TABLE, NULL, NULL, NULL)); + OIC_LOG(DEBUG, TAG, "RD created RD_LINK_RT table."); + + 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."); + + res = SQLITE_OK; + } + + if (SQLITE_OK == res) + { + VERIFY_SQLITE(sqlite3_prepare_v2(gRDDB, "PRAGMA foreign_keys = ON;", -1, &stmt, NULL)); + res = sqlite3_step(stmt); + if (SQLITE_DONE != res) + { + goto exit; + } + VERIFY_SQLITE(sqlite3_finalize(stmt)); + stmt = NULL; + } + +exit: + sqlite3_finalize(stmt); + if (SQLITE_OK == res) + { + return OC_STACK_OK; + } + else + { + sqlite3_close(gRDDB); + gRDDB = NULL; + return OC_STACK_ERROR; + } +} + +OCStackResult OCRDDatabaseClose() +{ + CHECK_DATABASE_INIT; + int res; + VERIFY_SQLITE(sqlite3_close(gRDDB)); + gRDDB = NULL; +exit: + return (SQLITE_OK == res) ? OC_STACK_OK : OC_STACK_ERROR; +} + +OCStackResult OCRDDatabaseStoreResources(OCRepPayload *payload) +{ + CHECK_DATABASE_INIT; + int res; + VERIFY_SQLITE(storeResources(payload)); +exit: + return (SQLITE_OK == res) ? OC_STACK_OK : OC_STACK_ERROR; +} + +OCStackResult OCRDDatabaseDeleteResources(const char *deviceId, const uint8_t *instanceIds, + uint8_t nInstanceIds) +{ + CHECK_DATABASE_INIT; + int res; + VERIFY_SQLITE(deleteResources(deviceId, instanceIds, nInstanceIds)); +exit: + return (SQLITE_OK == res) ? OC_STACK_OK : OC_STACK_ERROR; } #endif diff --git a/resource/csdk/stack/src/oicresourcedirectory.c b/resource/csdk/stack/src/oicresourcedirectory.c index 076a44c..ab7fa0f 100644 --- a/resource/csdk/stack/src/oicresourcedirectory.c +++ b/resource/csdk/stack/src/oicresourcedirectory.c @@ -37,8 +37,13 @@ #define TAG "OIC_RI_RESOURCEDIRECTORY" -#define VERIFY_NON_NULL(arg, logLevel, retVal) { if (!(arg)) { OIC_LOG((logLevel), \ - TAG, #arg " is NULL"); return (retVal); } } +#define VERIFY_NON_NULL(arg) \ +if (!(arg)) \ +{ \ + OIC_LOG(ERROR, TAG, #arg " is NULL"); \ + result = OC_STACK_NO_MEMORY; \ + goto exit; \ +} #ifdef RD_SERVER @@ -68,13 +73,13 @@ static const uint8_t pri_value_index = 1; if (SQLITE_OK != (arg)) \ { \ OIC_LOG_V(ERROR, TAG, "Error in " #arg ", Error Message: %s", sqlite3_errmsg(gRDDB)); \ - sqlite3_exec(gRDDB, "ROLLBACK", NULL, NULL, NULL); \ - return OC_STACK_ERROR; \ + result = OC_STACK_ERROR; \ + goto exit; \ } OCStackResult OCRDDatabaseSetStorageFilename(const char *filename) { - if(!filename) + if (!filename) { OIC_LOG(ERROR, TAG, "The persistent storage filename is invalid"); return OC_STACK_INVALID_PARAM; @@ -96,33 +101,13 @@ static void errorCallback(void *arg, int errCode, const char *errMsg) OIC_LOG_V(ERROR, TAG, "SQLLite Error: %s : %d", errMsg, errCode); } -static OCStackResult initializeDatabase() -{ - if (SQLITE_OK == sqlite3_config(SQLITE_CONFIG_LOG, errorCallback)) - { - OIC_LOG_V(INFO, TAG, "SQLite debugging log initialized."); - } - - sqlite3_open_v2(OCRDDatabaseGetStorageFilename(), &gRDDB, SQLITE_OPEN_READONLY, NULL); - if (!gRDDB) - { - return OC_STACK_ERROR; - } - return OC_STACK_OK; -} - static OCStackResult appendStringLL(OCStringLL **type, const unsigned char *value) { + OCStackResult result; OCStringLL *temp= (OCStringLL*)OICCalloc(1, sizeof(OCStringLL)); - if (!temp) - { - return OC_STACK_NO_MEMORY; - } + VERIFY_NON_NULL(temp); temp->value = OICStrdup((char *)value); - if (!temp->value) - { - return OC_STACK_NO_MEMORY; - } + VERIFY_NON_NULL(temp->value); temp->next = NULL; if (!*type) @@ -135,7 +120,16 @@ static OCStackResult appendStringLL(OCStringLL **type, const unsigned char *valu for (; tmp->next; tmp = tmp->next); tmp->next = temp; } - return OC_STACK_OK; + temp = NULL; + result = OC_STACK_OK; + +exit: + if (temp) + { + OICFree(temp->value); + OICFree(temp); + } + return result; } /* stmt is of form "SELECT * FROM RD_DEVICE_LINK_LIST ..." */ @@ -146,16 +140,18 @@ static OCStackResult ResourcePayloadCreate(sqlite3_stmt *stmt, OCDiscoveryPayloa { return OC_STACK_NO_RESOURCE; } - OCStackResult result = OC_STACK_OK; + + OCStackResult result; OCResourcePayload *resourcePayload = NULL; + OCEndpointPayload *epPayload = NULL; + sqlite3_stmt *stmtRT = NULL; + sqlite3_stmt *stmtIF = NULL; + sqlite3_stmt *stmtEP = NULL; + sqlite3_stmt *stmtDI = NULL; while (SQLITE_ROW == res) { resourcePayload = (OCResourcePayload *)OICCalloc(1, sizeof(OCResourcePayload)); - if (!resourcePayload) - { - result = OC_STACK_NO_MEMORY; - goto exit; - } + VERIFY_NON_NULL(resourcePayload); sqlite3_int64 id = sqlite3_column_int64(stmt, ins_index); const unsigned char *uri = sqlite3_column_text(stmt, href_index); @@ -164,35 +160,22 @@ static OCStackResult ResourcePayloadCreate(sqlite3_stmt *stmt, OCDiscoveryPayloa 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, (int64_t) deviceId); + resourcePayload->uri = OICStrdup((char *)uri); - if (!resourcePayload->uri) - { - result = OC_STACK_NO_MEMORY; - goto exit; - } + VERIFY_NON_NULL(resourcePayload->uri) if (rel) { resourcePayload->rel = OICStrdup((char *)rel); - if (!resourcePayload->rel) - { - result = OC_STACK_NO_MEMORY; - goto exit; - } + VERIFY_NON_NULL(resourcePayload->rel); } if (anchor) { resourcePayload->anchor = OICStrdup((char *)anchor); - if (!resourcePayload->anchor) - { - result = OC_STACK_NO_MEMORY; - goto exit; - } + VERIFY_NON_NULL(resourcePayload->anchor); } - sqlite3_stmt *stmtRT = 0; const char rt[] = "SELECT rt FROM RD_LINK_RT WHERE LINK_ID=@id"; int rtSize = (int)sizeof(rt); - VERIFY_SQLITE(sqlite3_prepare_v2(gRDDB, rt, rtSize, &stmtRT, NULL)); VERIFY_SQLITE(sqlite3_bind_int64(stmtRT, sqlite3_bind_parameter_index(stmtRT, "@id"), id)); while (SQLITE_ROW == sqlite3_step(stmtRT)) @@ -205,11 +188,10 @@ static OCStackResult ResourcePayloadCreate(sqlite3_stmt *stmt, OCDiscoveryPayloa } } VERIFY_SQLITE(sqlite3_finalize(stmtRT)); + stmtRT = NULL; - sqlite3_stmt *stmtIF = 0; const char itf[] = "SELECT if FROM RD_LINK_IF WHERE LINK_ID=@id"; int itfSize = (int)sizeof(itf); - VERIFY_SQLITE(sqlite3_prepare_v2(gRDDB, itf, itfSize, &stmtIF, NULL)); VERIFY_SQLITE(sqlite3_bind_int64(stmtIF, sqlite3_bind_parameter_index(stmtIF, "@id"), id)); while (SQLITE_ROW == sqlite3_step(stmtIF)) @@ -222,30 +204,25 @@ static OCStackResult ResourcePayloadCreate(sqlite3_stmt *stmt, OCDiscoveryPayloa } } VERIFY_SQLITE(sqlite3_finalize(stmtIF)); + stmtIF = NULL; resourcePayload->bitmap = (uint8_t)(bitmap & (OC_OBSERVABLE | OC_DISCOVERABLE)); - 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)) + 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); + epPayload = (OCEndpointPayload *)OICCalloc(1, sizeof(OCEndpointPayload)); + VERIFY_NON_NULL(epPayload); + 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); + sqlite3_int64 pri = sqlite3_column_int64(stmtEP, pri_value_index); epPayload->pri = (uint16_t)pri; OCEndpointPayload **tmp = &resourcePayload->eps; while (*tmp) @@ -253,51 +230,48 @@ static OCStackResult ResourcePayloadCreate(sqlite3_stmt *stmt, OCDiscoveryPayloa tmp = &(*tmp)->next; } *tmp = epPayload; + epPayload = NULL; } - VERIFY_SQLITE(sqlite3_finalize(stmtEp)); + VERIFY_SQLITE(sqlite3_finalize(stmtEP)); + stmtEP = NULL; 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 diSize = (int)sizeof(di); - const uint8_t di_index = 0; - - 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(stmtDI); if (SQLITE_ROW == res || SQLITE_DONE == res) { 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_NON_NULL(discPayload->sid); } VERIFY_SQLITE(sqlite3_finalize(stmtDI)); + stmtDI = NULL; + OCDiscoveryPayloadAddNewResource(discPayload, resourcePayload); + resourcePayload = NULL; res = sqlite3_step(stmt); } + result = OC_STACK_OK; + exit: - if (OC_STACK_OK != result) - { - OCDiscoveryResourceDestroy(resourcePayload); - } + sqlite3_finalize(stmtDI); + sqlite3_finalize(stmtEP); + sqlite3_finalize(stmtIF); + sqlite3_finalize(stmtRT); + OICFree(epPayload); + OCDiscoveryResourceDestroy(resourcePayload); return result; } static OCStackResult CheckResources(const char *interfaceType, const char *resourceType, OCDiscoveryPayload *discPayload) { - if (initializeDatabase() != OC_STACK_OK) - { - return OC_STACK_INTERNAL_SERVER_ERROR; - } if (!interfaceType && !resourceType) { return OC_STACK_INVALID_QUERY; @@ -319,22 +293,22 @@ static OCStackResult CheckResources(const char *interfaceType, const char *resou } OCStackResult result = OC_STACK_OK; - sqlite3_stmt *stmt = 0; + sqlite3_stmt *stmt = NULL; if (resourceType) { - if (!interfaceType || 0 == strcmp(interfaceType, OC_RSRVD_INTERFACE_LL)) + if (!interfaceType || 0 == strcmp(interfaceType, OC_RSRVD_INTERFACE_LL) || + 0 == strcmp(interfaceType, OC_RSRVD_INTERFACE_DEFAULT)) { const char input[] = "SELECT * FROM RD_DEVICE_LINK_LIST " "INNER JOIN RD_DEVICE_LIST ON RD_DEVICE_LINK_LIST.DEVICE_ID=RD_DEVICE_LIST.ID " "INNER JOIN RD_LINK_RT ON RD_DEVICE_LINK_LIST.INS=RD_LINK_RT.LINK_ID " "WHERE RD_DEVICE_LIST.di LIKE @di AND RD_LINK_RT.rt LIKE @resourceType"; int inputSize = (int)sizeof(input); - VERIFY_SQLITE(sqlite3_prepare_v2(gRDDB, input, inputSize, &stmt, NULL)); VERIFY_SQLITE(sqlite3_bind_text(stmt, sqlite3_bind_parameter_index(stmt, "@di"), - discPayload->sid, (int)sidLength, SQLITE_STATIC)); + discPayload->sid, (int)sidLength, SQLITE_STATIC)); VERIFY_SQLITE(sqlite3_bind_text(stmt, sqlite3_bind_parameter_index(stmt, "@resourceType"), - resourceType, (int)resourceTypeLength, SQLITE_STATIC)); + resourceType, (int)resourceTypeLength, SQLITE_STATIC)); } else { @@ -346,29 +320,28 @@ static OCStackResult CheckResources(const char *interfaceType, const char *resou "AND RD_LINK_RT.rt LIKE @resourceType " "AND RD_LINK_IF.if LIKE @interfaceType"; int inputSize = (int)sizeof(input); - VERIFY_SQLITE(sqlite3_prepare_v2(gRDDB, input, inputSize, &stmt, NULL)); VERIFY_SQLITE(sqlite3_bind_text(stmt, sqlite3_bind_parameter_index(stmt, "@di"), - discPayload->sid, (int)sidLength, SQLITE_STATIC)); + discPayload->sid, (int)sidLength, SQLITE_STATIC)); VERIFY_SQLITE(sqlite3_bind_text(stmt, sqlite3_bind_parameter_index(stmt, "@resourceType"), - resourceType, (int)resourceTypeLength, SQLITE_STATIC)); + resourceType, (int)resourceTypeLength, SQLITE_STATIC)); VERIFY_SQLITE(sqlite3_bind_text(stmt, sqlite3_bind_parameter_index(stmt, "@interfaceType"), - interfaceType, (int)interfaceTypeLength, SQLITE_STATIC)); + interfaceType, (int)interfaceTypeLength, SQLITE_STATIC)); } result = ResourcePayloadCreate(stmt, discPayload); } else if (interfaceType) { - if (0 == strcmp(interfaceType, OC_RSRVD_INTERFACE_LL)) + if (0 == strcmp(interfaceType, OC_RSRVD_INTERFACE_LL) || + 0 == strcmp(interfaceType, OC_RSRVD_INTERFACE_DEFAULT)) { const char input[] = "SELECT * FROM RD_DEVICE_LINK_LIST " "INNER JOIN RD_DEVICE_LIST ON RD_DEVICE_LINK_LIST.DEVICE_ID=RD_DEVICE_LIST.ID " "WHERE RD_DEVICE_LIST.di LIKE @di"; int inputSize = (int)sizeof(input); - VERIFY_SQLITE(sqlite3_prepare_v2(gRDDB, input, inputSize, &stmt, NULL)); VERIFY_SQLITE(sqlite3_bind_text(stmt, sqlite3_bind_parameter_index(stmt, "@di"), - discPayload->sid, (int)sidLength, SQLITE_STATIC)); + discPayload->sid, (int)sidLength, SQLITE_STATIC)); } else { @@ -377,19 +350,17 @@ static OCStackResult CheckResources(const char *interfaceType, const char *resou "INNER JOIN RD_LINK_IF ON RD_DEVICE_LINK_LIST.INS=RD_LINK_IF.LINK_ID " "WHERE RD_DEVICE_LIST.di LIKE @di AND RD_LINK_IF.if LIKE @interfaceType"; int inputSize = (int)sizeof(input); - VERIFY_SQLITE(sqlite3_prepare_v2(gRDDB, input, inputSize, &stmt, NULL)); VERIFY_SQLITE(sqlite3_bind_text(stmt, sqlite3_bind_parameter_index(stmt, "@di"), - discPayload->sid, (int)sidLength, SQLITE_STATIC)); + discPayload->sid, (int)sidLength, SQLITE_STATIC)); VERIFY_SQLITE(sqlite3_bind_text(stmt, sqlite3_bind_parameter_index(stmt, "@interfaceType"), - interfaceType, (int)interfaceTypeLength, SQLITE_STATIC)); + interfaceType, (int)interfaceTypeLength, SQLITE_STATIC)); } result = ResourcePayloadCreate(stmt, discPayload); } - if (stmt) - { - VERIFY_SQLITE(sqlite3_finalize(stmt)); - } + +exit: + sqlite3_finalize(stmt); return result; } @@ -397,9 +368,10 @@ OCStackResult OCRDDatabaseDiscoveryPayloadCreate(const char *interfaceType, const char *resourceType, OCDiscoveryPayload **payload) { - OCStackResult result = OC_STACK_NO_RESOURCE; + OCStackResult result; OCDiscoveryPayload *head = NULL; OCDiscoveryPayload **tail = &head; + sqlite3_stmt *stmt = NULL; if (*payload) { @@ -408,15 +380,22 @@ OCStackResult OCRDDatabaseDiscoveryPayloadCreate(const char *interfaceType, * caller provided payload. */ OIC_LOG_V(ERROR, TAG, "Payload is already allocated"); - return OC_STACK_INTERNAL_SERVER_ERROR; + result = OC_STACK_INTERNAL_SERVER_ERROR; + goto exit; + } + + if (SQLITE_OK == sqlite3_config(SQLITE_CONFIG_LOG, errorCallback)) + { + OIC_LOG_V(INFO, TAG, "SQLite debugging log initialized."); } - if (initializeDatabase() != OC_STACK_OK) + sqlite3_open_v2(OCRDDatabaseGetStorageFilename(), &gRDDB, SQLITE_OPEN_READONLY, NULL); + if (!gRDDB) { + result = OC_STACK_ERROR; goto exit; } const char *serverID = OCGetServerInstanceIDString(); - sqlite3_stmt *stmt = 0; const char input[] = "SELECT di FROM RD_DEVICE_LIST"; int inputSize = (int)sizeof(input); const uint8_t di_index = 0; @@ -429,9 +408,10 @@ OCStackResult OCRDDatabaseDiscoveryPayloadCreate(const char *interfaceType, continue; } *tail = OCDiscoveryPayloadCreate(); - VERIFY_PARAM_NON_NULL(TAG, *tail, "Failed creating discovery payload."); + result = OC_STACK_INTERNAL_SERVER_ERROR; + VERIFY_NON_NULL(*tail); (*tail)->sid = (char *)OICCalloc(1, UUID_STRING_SIZE); - VERIFY_PARAM_NON_NULL(TAG, (*tail)->sid, "Failed adding device id to discovery payload."); + VERIFY_NON_NULL((*tail)->sid); memcpy((*tail)->sid, di, UUID_STRING_SIZE); result = CheckResources(interfaceType, resourceType, *tail); if (OC_STACK_OK == result) @@ -444,12 +424,17 @@ OCStackResult OCRDDatabaseDiscoveryPayloadCreate(const char *interfaceType, *tail = NULL; } } - VERIFY_SQLITE(sqlite3_finalize(stmt)); + result = head ? OC_STACK_OK : OC_STACK_NO_RESOURCE; + +exit: + if (OC_STACK_OK != result) + { + OCPayloadDestroy((OCPayload *) head); + head = NULL; + } *payload = head; + sqlite3_finalize(stmt); + sqlite3_close(gRDDB); return result; -exit: - OCPayloadDestroy((OCPayload *) *tail); - *payload = NULL; - return OC_STACK_INTERNAL_SERVER_ERROR; } #endif -- 2.7.4