1 //******************************************************************
3 // Copyright 2016 Samsung Electronics All Rights Reserved.
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
7 // Licensed under the Apache License, Version 2.0 (the "License");
8 // you may not use this file except in compliance with the License.
9 // You may obtain a copy of the License a
11 // http://www.apache.org/licenses/LICENSE-2.0
13 // Unless required by applicable law or agreed to in writing, software
14 // distributed under the License is distributed on an "AS IS" BASIS,
15 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 // See the License for the specific language governing permissions and
17 // limitations under the License.
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
31 #include "ocpayload.h"
32 #include "oic_malloc.h"
33 #include "oic_string.h"
35 #define TAG "OIC_RI_RESOURCEDIRECTORY"
37 #define VERIFY_NON_NULL(arg, logLevel, retVal) { if (!(arg)) { OIC_LOG((logLevel), \
38 TAG, #arg " is NULL"); return (retVal); } }
42 #define RD_PATH "RD.db"
44 static sqlite3 *gRDDB = NULL;
46 static const uint8_t uri_index = 2;
47 static const uint8_t p_index = 5;
48 static const uint8_t mt_index = 7;
49 static const uint8_t d_index = 8;
51 static const uint8_t rt_value_index = 1;
52 static const uint8_t rt_link_id_index = 2;
54 static const uint8_t if_value_index = 1;
55 static const uint8_t if_link_id_index = 2;
57 #define VERIFY_SQLITE(arg) \
58 if (SQLITE_OK != (arg)) \
60 OIC_LOG_V(ERROR, TAG, "Error in " #arg ", Error Message: %s", sqlite3_errmsg(gRDDB)); \
61 sqlite3_exec(gRDDB, "ROLLBACK", NULL, NULL, NULL); \
62 return OC_STACK_ERROR; \
65 static void errorCallback(void *arg, int errCode, const char *errMsg)
70 OIC_LOG_V(ERROR, TAG, "SQLLite Error: %s : %d", errMsg, errCode);
73 static OCStackResult initializeDatabase(const char *path)
75 if (SQLITE_OK == sqlite3_config(SQLITE_CONFIG_LOG, errorCallback))
77 OIC_LOG_V(INFO, TAG, "SQLite debugging log initialized.");
80 sqlite3_open_v2(!path ? RD_PATH : path, &gRDDB, SQLITE_OPEN_READONLY, NULL);
83 return OC_STACK_ERROR;
88 static OCStackResult appendStringLL(OCStringLL **type, const unsigned char *value)
90 OCStringLL *temp= (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
93 return OC_STACK_NO_MEMORY;
95 temp->value = OICStrdup((char *)value);
98 return OC_STACK_NO_MEMORY;
108 OCStringLL *tmp = *type;
109 for (; tmp->next; tmp = tmp->next);
115 OCStackResult OCRDDatabaseCheckResources(const char *interfaceType, const char *resourceType,
116 OCDiscoveryPayload *discPayload)
118 if (initializeDatabase(NULL) != OC_STACK_OK)
120 return OC_STACK_INTERNAL_SERVER_ERROR;
122 if (!interfaceType && !resourceType)
124 return OC_STACK_INVALID_QUERY;
126 OCResourcePayload *resourcePayload = (OCResourcePayload *)OICCalloc(1, sizeof(OCResourcePayload));
127 if (!resourcePayload)
129 return OC_STACK_NO_MEMORY;
134 sqlite3_stmt *stmt = 0;
135 const char *input = "SELECT * FROM RD_DEVICE_LINK_LIST INNER JOIN RD_LINK_RT ON " \
136 "RD_DEVICE_LINK_LIST.INS=RD_LINK_RT.LINK_ID WHERE RD_LINK_RT.rt LIKE ? ";
138 VERIFY_SQLITE(sqlite3_prepare_v2(gRDDB, input, -1, &stmt, NULL));
139 VERIFY_SQLITE(sqlite3_bind_text(stmt, 1, resourceType, strlen(resourceType) + 1, SQLITE_STATIC));
141 int res = sqlite3_step (stmt);
142 if (res == SQLITE_ROW || res == SQLITE_DONE)
144 int id = sqlite3_column_int(stmt, 0);
145 const unsigned char *uri = sqlite3_column_text(stmt, uri_index - 1);
146 int bitmap = sqlite3_column_int(stmt, p_index - 1);
147 int deviceId = sqlite3_column_int(stmt, d_index - 1);
148 OIC_LOG_V(DEBUG, TAG, " %s %d", uri, deviceId);
149 resourcePayload->uri = OICStrdup((char *)uri);
150 if (!resourcePayload->uri)
152 OCDiscoveryResourceDestroy(resourcePayload);
153 return OC_STACK_NO_MEMORY;
155 res = sqlite3_reset(stmt);
158 sqlite3_stmt *stmtRT = 0;
159 const char *rt = "SELECT rt FROM RD_LINK_RT WHERE LINK_ID=?";
160 VERIFY_SQLITE(sqlite3_prepare_v2(gRDDB, rt, -1, &stmtRT, NULL));
161 VERIFY_SQLITE(sqlite3_bind_int(stmtRT, 1, id));
162 while (SQLITE_ROW == sqlite3_step(stmtRT))
164 const unsigned char *rt1 = sqlite3_column_text(stmtRT, (rt_value_index - 1));
165 appendStringLL(&resourcePayload->types, rt1);
168 sqlite3_stmt *stmtIF = 0;
169 const char *itf = "SELECT if FROM RD_LINK_IF WHERE LINK_ID=?";
170 VERIFY_SQLITE(sqlite3_prepare_v2(gRDDB, itf, -1, &stmtIF, NULL));
171 VERIFY_SQLITE(sqlite3_bind_int(stmtIF, 1, id));
172 while (SQLITE_ROW == sqlite3_step(stmtIF))
174 const unsigned char *itf = sqlite3_column_text(stmtIF, (if_value_index - 1));
175 appendStringLL(&resourcePayload->interfaces, itf);
178 resourcePayload->bitmap = bitmap & (OC_OBSERVABLE | OC_DISCOVERABLE);
179 resourcePayload->secure = (bitmap & OC_SECURE) != 0;
181 const char *address = "SELECT di, address FROM RD_DEVICE_LIST INNER JOIN RD_DEVICE_LINK_LIST ON " \
182 "RD_DEVICE_LINK_LIST.DEVICE_ID = RD_DEVICE_LIST.ID WHERE RD_DEVICE_LINK_LIST.DEVICE_ID=?";
184 sqlite3_stmt *stmt1 = 0;
185 VERIFY_SQLITE(sqlite3_prepare_v2(gRDDB, address, -1, &stmt1, NULL));
186 VERIFY_SQLITE(sqlite3_bind_int(stmt1, 1, deviceId));
187 // TODO: Right now, we have a bug where discovery payload can only send one device information.
188 res = sqlite3_step(stmt1);
189 if (res == SQLITE_ROW || res == SQLITE_DONE)
191 const unsigned char *di = sqlite3_column_text(stmt1, 0);
192 const unsigned char *address = sqlite3_column_text(stmt1, 1);
193 OIC_LOG_V(DEBUG, TAG, " %s %s", di, address);
194 (discPayload)->baseURI = OICStrdup((char *)address);
195 (discPayload)->sid = OICStrdup((char *)di);
197 OCDiscoveryPayloadAddNewResource(discPayload, resourcePayload);
202 sqlite3_stmt *stmt = 0;
203 const char *input = "SELECT * FROM RD_DEVICE_LINK_LIST INNER JOIN RD_LINK_IF ON " \
204 "RD_DEVICE_LINK_LIST.INS=RD_LINK_IF.LINK_ID WHERE RD_LINK_IF.if LIKE ? ";
206 VERIFY_SQLITE(sqlite3_prepare_v2(gRDDB, input, -1, &stmt, NULL));
207 VERIFY_SQLITE(sqlite3_bind_text(stmt, 1, interfaceType, strlen(interfaceType) + 1, SQLITE_STATIC));
209 int res = sqlite3_step (stmt);
210 if (res == SQLITE_ROW || res == SQLITE_DONE)
212 int id = sqlite3_column_int(stmt, 0);
213 const unsigned char *uri = sqlite3_column_text(stmt, uri_index - 1);
214 int bitmap = sqlite3_column_int(stmt, p_index - 1);
215 int deviceId = sqlite3_column_int(stmt, d_index - 1);
216 OIC_LOG_V(DEBUG, TAG, " %s %d", uri, deviceId);
217 resourcePayload->uri = OICStrdup((char *)uri);
218 if (!resourcePayload->uri)
220 OCDiscoveryResourceDestroy(resourcePayload);
221 return OC_STACK_NO_MEMORY;
223 VERIFY_SQLITE(sqlite3_reset(stmt));
225 sqlite3_stmt *stmtRT = 0;
226 const char *rt = "SELECT rt FROM RD_LINK_RT WHERE LINK_ID=?";
227 VERIFY_SQLITE(sqlite3_prepare_v2(gRDDB, rt, -1, &stmtRT, NULL));
228 VERIFY_SQLITE(sqlite3_bind_int(stmtRT, 1, id));
229 while (SQLITE_ROW == sqlite3_step(stmtRT))
231 const unsigned char *rt1 = sqlite3_column_text(stmtRT, (rt_value_index - 1));
232 appendStringLL(&resourcePayload->types, rt1);
235 sqlite3_stmt *stmtIF = 0;
236 const char *itf = "SELECT if FROM RD_LINK_IF WHERE LINK_ID=?";
237 VERIFY_SQLITE(sqlite3_prepare_v2(gRDDB, itf, -1, &stmtIF, NULL));
238 VERIFY_SQLITE(sqlite3_bind_int(stmtIF, 1, id));
239 while (SQLITE_ROW == sqlite3_step (stmtIF))
241 const unsigned char *itf = sqlite3_column_text(stmtIF, (if_value_index - 1));
242 appendStringLL(&resourcePayload->interfaces, itf);
245 resourcePayload->bitmap = bitmap & (OC_OBSERVABLE | OC_DISCOVERABLE);
246 resourcePayload->secure = ((bitmap & OC_SECURE) != 0);
248 const char *address = "SELECT di, address FROM RD_DEVICE_LIST INNER JOIN RD_DEVICE_LINK_LIST ON " \
249 "RD_DEVICE_LINK_LIST.DEVICE_ID = RD_DEVICE_LIST.ID WHERE RD_DEVICE_LINK_LIST.DEVICE_ID=?";
251 sqlite3_stmt *stmt1 = 0;
252 VERIFY_SQLITE(sqlite3_prepare_v2(gRDDB, address, -1, &stmt1, NULL));
253 VERIFY_SQLITE(sqlite3_bind_int(stmt1, 1, deviceId));
255 res = sqlite3_step(stmt1);
256 if (res == SQLITE_ROW || res == SQLITE_DONE)
258 const unsigned char *di = sqlite3_column_text(stmt1, 0);
259 const unsigned char *address = sqlite3_column_text(stmt1, 1);
260 OIC_LOG_V(DEBUG, TAG, " %s %s", di, address);
261 (discPayload)->baseURI = OICStrdup((char *)address);
262 (discPayload)->sid = OICStrdup((char *)di);
264 OCDiscoveryPayloadAddNewResource(discPayload, resourcePayload);