[STC Manager] Support set/get for total data usage(Tx + Rx) in restriction.
[platform/core/connectivity/stc-manager.git] / src / database / tables / table-restrictions.c
1 /*
2  * Copyright (c) 2016 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 /**
18  * This file implements restrictions entity handler methods.
19  *
20  * @file        table-restrictions.c
21  */
22
23 #include "stc-db.h"
24 #include "db-internal.h"
25 #include "table-restrictions.h"
26
27 /* DELETE statements */
28 #define DELETE_RESTRICTIONS "DELETE FROM restrictions " \
29         " WHERE binpath = ? AND iftype = ? AND imsi = ?"
30
31 /* SELECT statements */
32 #define SELECT_RESTRICTIONS "SELECT binpath, data_limit, " \
33         " iftype, rst_state, roaming, ifname, imsi, " \
34         " data_warn_limit, restriction_id FROM restrictions"
35
36 #define SELECT_RESTRICTIONS_PER_APP "SELECT binpath, data_limit, " \
37         " iftype, rst_state, roaming, ifname, imsi, " \
38         " data_warn_limit, restriction_id " \
39         " FROM restrictions INDEXED BY restrictions_index " \
40         " WHERE binpath = ?"
41
42 #define SELECT_RESTRICTION_STATE "SELECT rst_state " \
43         " FROM restrictions INDEXED BY restrictions_index " \
44         " WHERE binpath = ? AND iftype = ?"
45
46 #define SELECT_RESTRICTION_STATE_IMSI "SELECT rst_state " \
47         " FROM restrictions INDEXED BY restrictions_index " \
48         " WHERE binpath = ? AND iftype = ? AND imsi = ?"
49
50 #define SELECT_RESTRICTION_ID "SELECT restriction_id FROM restrictions " \
51         " WHERE binpath = ? AND iftype = ? AND imsi = ? AND " \
52         " data_limit = ? AND data_warn_limit = ? AND " \
53         " rst_state = ? AND roaming = ? AND ifname = ?"
54
55 /* UPDATE statement */
56 #define UPDATE_NET_RESTRICTIONS "UPDATE restrictions " \
57         " SET binpath = ?, data_limit = ?, iftype = ?, rst_state = ?, " \
58         " roaming = ?, ifname = ?, imsi = ?, data_warn_limit = ? " \
59         " WHERE restriction_id = ?"
60
61 /* INSERT statement */
62 #define INSERT_NET_RESTRICTIONS "INSERT INTO restrictions " \
63         " (binpath, data_limit, iftype, rst_state, " \
64         " roaming, ifname, imsi, data_warn_limit) " \
65         " VALUES (?, ?, ?, ?, ?, ?, ?, ?)"
66
67 static void __finalize_delete(void);
68
69 #define PREPARE_DELETE(stm, query) do { \
70         rc = sqlite3_prepare_v2(db, query, -1, &stm, NULL); \
71         if (rc != SQLITE_OK) { \
72                 stm = NULL; \
73                 __finalize_delete(); \
74                 STC_LOGE("Failed to prepare \"%s\"query" \
75                          , query); \
76                 return rc; \
77         } \
78 } while (0)
79
80 static void __finalize_select(void);
81
82 #define PREPARE_SELECT(stm, query) do { \
83         rc = sqlite3_prepare_v2(db, query, -1, &stm, NULL); \
84         if (rc != SQLITE_OK) { \
85                 stm = NULL; \
86                 __finalize_select(); \
87                 STC_LOGE("Failed to prepare \"%s\"query" \
88                          , query); \
89                 return rc; \
90         } \
91 } while (0)
92
93 static void __finalize_update(void);
94
95 #define PREPARE_UPDATE(stm, query) do { \
96         rc = sqlite3_prepare_v2(db, query, -1, &stm, NULL); \
97         if (rc != SQLITE_OK) { \
98                 stm = NULL; \
99                 __finalize_update(); \
100                 STC_LOGE("Failed to prepare \"%s\"query" \
101                          , query); \
102                 return rc; \
103         } \
104 } while (0)
105
106 static void __finalize_insert(void);
107
108 #define PREPARE_INSERT(stm, query) do { \
109         rc = sqlite3_prepare_v2(db, query, -1, &stm, NULL); \
110         if (rc != SQLITE_OK) { \
111                 stm = NULL; \
112                 __finalize_insert(); \
113                 STC_LOGE("Failed to prepare \"%s\"query" \
114                          , query); \
115                 return rc; \
116         } \
117 } while (0)
118
119 #define FINALIZE(stm) do { \
120         if (stm) { \
121                 sqlite3_finalize(stm); \
122                 stm = NULL; \
123         } \
124 } while (0)
125
126 /* DELETE statements */
127 static sqlite3_stmt *delete_restrictions;
128
129 /* SELECT statements */
130 static sqlite3_stmt *select_restriction;
131 static sqlite3_stmt *select_restriction_per_app;
132 static sqlite3_stmt *select_restriction_state;
133 static sqlite3_stmt *select_restriction_state_imsi;
134 static sqlite3_stmt *select_restriction_id;
135
136 /* REPLACE statements */
137 static sqlite3_stmt *update_net_restrictions;
138
139 /* INSERT statements */
140 static sqlite3_stmt *insert_net_restrictions;
141
142 static int __prepare_delete(sqlite3 *db)
143 {
144         __STC_LOG_FUNC_ENTER__;
145         int rc;
146         static int initialized;
147
148         if (initialized) {
149                 __STC_LOG_FUNC_EXIT__;
150                 return SQLITE_OK;
151         }
152
153         PREPARE_DELETE(delete_restrictions, DELETE_RESTRICTIONS);
154
155         initialized = 1;
156         __STC_LOG_FUNC_EXIT__;
157         return rc;
158 }
159
160 static void __finalize_delete(void)
161 {
162         __STC_LOG_FUNC_ENTER__;
163
164         FINALIZE(delete_restrictions);
165
166         __STC_LOG_FUNC_EXIT__;
167 }
168
169 static int __prepare_select(sqlite3 *db)
170 {
171         __STC_LOG_FUNC_ENTER__;
172         int rc;
173         static int initialized;
174
175         if (initialized) {
176                 __STC_LOG_FUNC_EXIT__;
177                 return SQLITE_OK;
178         }
179
180         PREPARE_SELECT(select_restriction, SELECT_RESTRICTIONS);
181         PREPARE_SELECT(select_restriction_per_app, SELECT_RESTRICTIONS_PER_APP);
182         PREPARE_SELECT(select_restriction_state, SELECT_RESTRICTION_STATE);
183         PREPARE_SELECT(select_restriction_state_imsi, SELECT_RESTRICTION_STATE_IMSI);
184         PREPARE_SELECT(select_restriction_id, SELECT_RESTRICTION_ID);
185
186         initialized = 1;
187         __STC_LOG_FUNC_EXIT__;
188         return rc;
189 }
190
191 static void __finalize_select(void)
192 {
193         __STC_LOG_FUNC_ENTER__;
194
195         FINALIZE(select_restriction);
196         FINALIZE(select_restriction_per_app);
197         FINALIZE(select_restriction_state);
198         FINALIZE(select_restriction_state_imsi);
199         FINALIZE(select_restriction_id);
200
201         __STC_LOG_FUNC_EXIT__;
202 }
203
204 static int __prepare_replace(sqlite3 *db)
205 {
206         __STC_LOG_FUNC_ENTER__;
207         int rc;
208         static int initialized;
209
210         if (initialized) {
211                 __STC_LOG_FUNC_EXIT__;
212                 return SQLITE_OK;
213         }
214
215         PREPARE_UPDATE(update_net_restrictions, UPDATE_NET_RESTRICTIONS);
216
217         initialized = 1;
218         __STC_LOG_FUNC_EXIT__;
219         return rc;
220 }
221
222 static void __finalize_update(void)
223 {
224         __STC_LOG_FUNC_ENTER__;
225
226         FINALIZE(update_net_restrictions);
227
228         __STC_LOG_FUNC_EXIT__;
229 }
230
231 static int __prepare_insert(sqlite3 *db)
232 {
233         __STC_LOG_FUNC_ENTER__;
234         int rc;
235         static int initialized;
236
237         if (initialized) {
238                 __STC_LOG_FUNC_EXIT__;
239                 return SQLITE_OK;
240         }
241
242         PREPARE_UPDATE(insert_net_restrictions, INSERT_NET_RESTRICTIONS);
243
244         initialized = 1;
245         __STC_LOG_FUNC_EXIT__;
246         return rc;
247 }
248
249 static void __finalize_insert(void)
250 {
251         __STC_LOG_FUNC_ENTER__;
252
253         FINALIZE(insert_net_restrictions);
254
255         __STC_LOG_FUNC_EXIT__;
256 }
257
258 stc_error_e table_restrictions_per_app(const gchar* app_id,
259                                        const table_restrictions_info_cb restriction_cb,
260                                        void *user_data)
261 {
262         __STC_LOG_FUNC_ENTER__;
263         table_restrictions_info data;
264         int rc;
265         stc_error_e error_code = STC_ERROR_NONE;
266         sqlite3_stmt *stmt = select_restriction_per_app;
267
268         if (!app_id) {
269                 __STC_LOG_FUNC_EXIT__;
270                 return STC_ERROR_DB_FAILED;
271         }
272
273         DB_ACTION(sqlite3_bind_text(stmt, 1, app_id, -1,
274                                     SQLITE_TRANSIENT));
275         data.app_id = (char *)app_id;
276
277         do {
278                 rc = sqlite3_step(stmt);
279
280                 memset(&data, 0, sizeof(data));
281
282                 switch (rc) {
283                 case SQLITE_DONE:
284                         break;
285                 case SQLITE_ROW:
286                         data.app_id = (char *)sqlite3_column_text(stmt, 0);
287                         data.data_limit = sqlite3_column_int64(stmt, 1);
288                         data.iftype = (stc_iface_type_e)sqlite3_column_int(stmt, 2);
289                         data.rst_state =
290                                 (stc_restriction_state_e)sqlite3_column_int(stmt, 3);
291                         data.roaming = sqlite3_column_int(stmt, 4);
292                         data.ifname = (char *)sqlite3_column_text(stmt, 5);
293                         data.imsi = (char *)sqlite3_column_text(stmt, 6);
294                         data.data_warn_limit = sqlite3_column_int64(stmt, 7);
295                         data.restriction_id = sqlite3_column_int64(stmt, 8);
296
297                         if (restriction_cb(&data, user_data) == STC_CANCEL)
298                                 rc = SQLITE_DONE;
299                         break;
300                 case SQLITE_ERROR:
301                 default:
302                         STC_LOGE("Failed to enumerate restrictions: %s\n",
303                                  sqlite3_errmsg(stc_db_get_database()));
304
305                         __STC_LOG_FUNC_EXIT__;
306                         error_code = STC_ERROR_DB_FAILED;
307                 }
308         } while (rc == SQLITE_ROW);
309
310 handle_error:
311         sqlite3_reset(stmt);
312         __STC_LOG_FUNC_EXIT__;
313         return error_code;
314 }
315
316 stc_error_e table_restrictions_foreach(const table_restrictions_info_cb restriction_cb,
317                                        void *user_data)
318 {
319         __STC_LOG_FUNC_ENTER__;
320         table_restrictions_info data;
321         int rc;
322         stc_error_e error_code = STC_ERROR_NONE;
323         sqlite3_stmt *stmt = select_restriction;
324
325         do {
326                 rc = sqlite3_step(stmt);
327
328                 memset(&data, 0, sizeof(data));
329
330                 switch (rc) {
331                 case SQLITE_DONE:
332                         break;
333                 case SQLITE_ROW:
334                         data.app_id = (char *)sqlite3_column_text(stmt, 0);
335                         data.data_limit = sqlite3_column_int64(stmt, 1);
336                         data.iftype = (stc_iface_type_e)sqlite3_column_int(stmt, 2);
337                         data.rst_state =
338                                 (stc_restriction_state_e)sqlite3_column_int(stmt, 3);
339                         data.roaming = sqlite3_column_int(stmt, 4);
340                         data.ifname = (char *)sqlite3_column_text(stmt, 5);
341                         data.imsi = (char *)sqlite3_column_text(stmt, 6);
342                         data.data_warn_limit = sqlite3_column_int64(stmt, 7);
343                         data.restriction_id = sqlite3_column_int64(stmt, 8);
344
345                         if (restriction_cb(&data, user_data) == STC_CANCEL)
346                                 rc = SQLITE_DONE;
347                         break;
348                 case SQLITE_ERROR:
349                 default:
350                         STC_LOGE("Failed to enumerate restrictions: %s\n",
351                                  sqlite3_errmsg(stc_db_get_database()));
352
353                         __STC_LOG_FUNC_EXIT__;
354                         error_code = STC_ERROR_DB_FAILED;
355                 }
356         } while (rc == SQLITE_ROW);
357
358         sqlite3_reset(stmt);
359         __STC_LOG_FUNC_EXIT__;
360         return error_code;
361 }
362
363 stc_error_e table_restrictions_get_restriction_state_imsi(const char *app_id,
364                                                           stc_iface_type_e iftype,
365                                                           const char *imsi_hash,
366                                                           stc_restriction_state_e *state)
367 {
368         __STC_LOG_FUNC_ENTER__;
369         int error_code = STC_ERROR_NONE;
370         int ret;
371         bool state_imsi = 0;
372
373         if (state == NULL) {
374                 STC_LOGE("Please provide valid argument!");
375                 __STC_LOG_FUNC_EXIT__;
376                 return STC_ERROR_INVALID_PARAMETER;
377         }
378
379         *state = STC_RESTRICTION_UNKNOWN;
380         sqlite3_reset(select_restriction_state_imsi);
381         sqlite3_reset(select_restriction_state);
382
383         if (imsi_hash == NULL) {
384                 state_imsi = 0;
385                 DB_ACTION(sqlite3_bind_text(select_restriction_state, 1,
386                                             app_id ? app_id : "", -1,
387                                             SQLITE_STATIC));
388                 DB_ACTION(sqlite3_bind_int(select_restriction_state, 2,
389                                            iftype));
390                 ret = sqlite3_step(select_restriction_state);
391         } else {
392                 state_imsi = 1;
393                 DB_ACTION(sqlite3_bind_text(select_restriction_state_imsi, 1,
394                                             app_id ? app_id : "", -1,
395                                             SQLITE_STATIC));
396                 DB_ACTION(sqlite3_bind_int(select_restriction_state_imsi, 2,
397                                            iftype));
398                 DB_ACTION(sqlite3_bind_text(select_restriction_state_imsi, 3,
399                                             imsi_hash, -1, SQLITE_STATIC));
400                 ret = sqlite3_step(select_restriction_state_imsi);
401         }
402
403         switch (ret) {
404         case SQLITE_DONE:
405                 break;
406         case SQLITE_ROW:
407                 if (state_imsi)
408                         *state = (stc_restriction_state_e)sqlite3_column_int(select_restriction_state_imsi, 0);
409                 else
410                         *state = (stc_restriction_state_e)sqlite3_column_int(select_restriction_state, 0);
411                 break;
412         case SQLITE_ERROR:
413         default:
414                 STC_LOGE("Can't perform sql query: %s \n%s",
415                          SELECT_RESTRICTION_STATE,
416                          sqlite3_errmsg(stc_db_get_database()));
417                 error_code = STC_ERROR_DB_FAILED;
418         }
419
420 handle_error:
421         sqlite3_reset(select_restriction_state);
422         sqlite3_reset(select_restriction_state_imsi);
423         return error_code;
424 }
425
426 stc_error_e table_restrictions_get_restriction_state(const char *app_id,
427                                                      stc_iface_type_e iftype,
428                                                      stc_restriction_state_e *state)
429 {
430         __STC_LOG_FUNC_ENTER__;
431         __STC_LOG_FUNC_EXIT__;
432         return table_restrictions_get_restriction_state_imsi(app_id, iftype,
433                                                              NULL, state);
434 }
435
436 stc_error_e table_restrictions_delete(const char *app_id,
437                                       const stc_iface_type_e iftype,
438                                       const char *imsi)
439 {
440         stc_error_e error_code = STC_ERROR_NONE;
441         sqlite3_stmt *stmt = delete_restrictions;
442
443         STC_LOGD("app_id [%s], iftype [%d], imsi [%s]",
444                  app_id, iftype, imsi);
445
446         DB_ACTION(sqlite3_bind_text(stmt, 1, app_id ? app_id : "",
447                                     -1, SQLITE_TRANSIENT));
448         DB_ACTION(sqlite3_bind_int(stmt, 2, iftype));
449         DB_ACTION(sqlite3_bind_text(stmt, 3, imsi ? imsi : "", -1,
450                                     SQLITE_TRANSIENT));
451
452         if (sqlite3_step(stmt) != SQLITE_DONE) {
453                 STC_LOGE("Failed to remove restrictions by network interface %s\n",
454                          sqlite3_errmsg(stc_db_get_database()));
455                 error_code = STC_ERROR_DB_FAILED;
456                 goto handle_error;
457         }
458
459         STC_LOGD("Restriction deleted for app_id [%s]", app_id);
460
461 handle_error:
462
463         sqlite3_reset(stmt);
464         return error_code;
465 }
466
467 stc_error_e __get_restriction_id(table_restrictions_info *info)
468 {
469         __STC_LOG_FUNC_ENTER__;
470         int rc;
471         stc_error_e error_code = STC_ERROR_NONE;
472         sqlite3_stmt *stmt = select_restriction_id;
473
474         DB_ACTION(sqlite3_bind_text(stmt, 1, info->app_id ? info->app_id : "",
475                                     -1, SQLITE_TRANSIENT));
476         DB_ACTION(sqlite3_bind_int(stmt, 2, info->iftype));
477         DB_ACTION(sqlite3_bind_text(stmt, 3, info->imsi ? info->imsi : "",
478                                     -1, SQLITE_TRANSIENT));
479         DB_ACTION(sqlite3_bind_int64(stmt, 4, info->data_limit));
480         DB_ACTION(sqlite3_bind_int64(stmt, 5, info->data_warn_limit));
481         DB_ACTION(sqlite3_bind_int(stmt, 6, info->rst_state));
482         DB_ACTION(sqlite3_bind_int(stmt, 7, info->roaming));
483         DB_ACTION(sqlite3_bind_text(stmt, 8, info->ifname ? info->ifname : "",
484                                     -1, SQLITE_TRANSIENT));
485
486         rc = sqlite3_step(stmt);
487
488         switch (rc) {
489         case SQLITE_DONE:
490                 break;
491         case SQLITE_ROW:
492                 info->restriction_id = sqlite3_column_int64(stmt, 0);
493                 STC_LOGD("restriction id [%llu]", info->restriction_id);
494                 break;
495         case SQLITE_ERROR:
496         default:
497                 STC_LOGE("Failed to get restriction id: %s\n",
498                          sqlite3_errmsg(stc_db_get_database()));
499         }
500
501 handle_error:
502         sqlite3_reset(stmt);
503         __STC_LOG_FUNC_EXIT__;
504         return error_code;
505 }
506
507 stc_error_e table_restrictions_update(table_restrictions_info *info)
508 {
509         stc_error_e error_code = STC_ERROR_NONE;
510         sqlite3_stmt *stmt = insert_net_restrictions;
511
512         if (!info) {
513                 error_code = STC_ERROR_INVALID_PARAMETER;
514                 goto handle_error;
515         }
516
517         if (info->restriction_id)
518                 stmt = update_net_restrictions;
519
520         DB_ACTION(sqlite3_bind_text(stmt, 1, info->app_id ? info->app_id : "",
521                                     -1, SQLITE_TRANSIENT));
522         DB_ACTION(sqlite3_bind_int64(stmt, 2, info->data_limit));
523         DB_ACTION(sqlite3_bind_int(stmt, 3, info->iftype));
524         DB_ACTION(sqlite3_bind_int(stmt, 4, info->rst_state));
525         DB_ACTION(sqlite3_bind_int(stmt, 5, info->roaming));
526         DB_ACTION(sqlite3_bind_text(stmt, 6, info->ifname ? info->ifname : "",
527                                     -1, SQLITE_TRANSIENT));
528         DB_ACTION(sqlite3_bind_text(stmt, 7, info->imsi ? info->imsi : "",
529                                     -1, SQLITE_TRANSIENT));
530         DB_ACTION(sqlite3_bind_int64(stmt, 8, info->data_warn_limit));
531
532         if (info->restriction_id)
533                 DB_ACTION(sqlite3_bind_int64(stmt, 11, info->restriction_id));
534
535         if (sqlite3_step(stmt) != SQLITE_DONE) {
536                 STC_LOGE("Failed to set network restriction: %s\n",
537                          sqlite3_errmsg(stc_db_get_database()));
538                 error_code = STC_ERROR_DB_FAILED;
539                 goto handle_error;
540         }
541
542         if (info->restriction_id) {
543                 STC_LOGD("Restriction updated app_id [%s]", info->app_id);
544         } else {
545                 STC_LOGD("Restriction inserted app_id [%s]", info->app_id);
546                 __get_restriction_id(info);
547         }
548
549 handle_error:
550         sqlite3_reset(stmt);
551         return error_code;
552 }
553
554 stc_error_e table_restrictions_prepare(sqlite3 *db)
555 {
556         __STC_LOG_FUNC_ENTER__;
557
558         stc_error_e error_code = STC_ERROR_NONE;
559
560         if (db == NULL) {
561                 __STC_LOG_FUNC_EXIT__;
562                 return STC_ERROR_FAIL;
563         }
564
565         DB_ACTION(__prepare_delete(db));
566         DB_ACTION(__prepare_select(db));
567         DB_ACTION(__prepare_replace(db));
568         DB_ACTION(__prepare_insert(db));
569
570 handle_error:
571
572         __STC_LOG_FUNC_EXIT__;
573         return error_code;
574 }
575
576 void table_restrictions_finalize(void)
577 {
578         __STC_LOG_FUNC_ENTER__;
579         __finalize_delete();
580         __finalize_select();
581         __finalize_update();
582         __finalize_insert();
583         __STC_LOG_FUNC_EXIT__;
584 }