Initialize smart traffic control manager package
[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, rcv_limit, " \
33         "send_limit, iftype, rst_state, roaming, ifname, imsi, " \
34         "rcv_warn_limit, send_warn_limit, restriction_id FROM restrictions"
35
36 #define SELECT_RESTRICTIONS_PER_APP "SELECT binpath, rcv_limit, " \
37         "send_limit, iftype, rst_state, roaming, ifname, imsi, " \
38         "rcv_warn_limit, send_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 send_limit=? " \
52         "AND rcv_limit=? AND rcv_warn_limit=? AND send_warn_limit=? " \
53         "AND rst_state=? AND roaming=? AND ifname=?"
54
55 /* UPDATE statement */
56 #define UPDATE_NET_RESTRICTIONS "UPDATE restrictions " \
57         "SET binpath=?, rcv_limit=?, send_limit=?, iftype=?, rst_state=?, " \
58         "roaming=?, ifname=?, imsi=?, rcv_warn_limit=?, send_warn_limit=? " \
59         "WHERE restriction_id=?"
60
61 /* INSERT statement */
62 #define INSERT_NET_RESTRICTIONS "INSERT INTO restrictions " \
63         "(binpath, rcv_limit, send_limit, iftype, rst_state, " \
64         "roaming, ifname, imsi, rcv_warn_limit, send_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.rcv_limit = sqlite3_column_int64(stmt, 1);
288                         data.send_limit = sqlite3_column_int64(stmt, 2);
289                         data.iftype = (stc_iface_type_e)sqlite3_column_int(stmt, 3);
290                         data.rst_state =
291                                 (stc_restriction_state_e)sqlite3_column_int(stmt, 4);
292                         data.roaming = sqlite3_column_int(stmt, 5);
293                         data.ifname = (char *)sqlite3_column_text(stmt, 6);
294                         data.imsi = (char *)sqlite3_column_text(stmt, 7);
295                         data.rcv_warn_limit = sqlite3_column_int64(stmt, 8);
296                         data.send_warn_limit = sqlite3_column_int64(stmt, 9);
297                         data.restriction_id = sqlite3_column_int64(stmt, 10);
298
299                         if (restriction_cb(&data, user_data) == STC_CANCEL)
300                                 rc = SQLITE_DONE;
301                         break;
302                 case SQLITE_ERROR:
303                 default:
304                         STC_LOGE("Failed to enumerate restrictions: %s\n",
305                                  sqlite3_errmsg(stc_db_get_database()));
306
307                         __STC_LOG_FUNC_EXIT__;
308                         error_code = STC_ERROR_DB_FAILED;
309                 }
310         } while (rc == SQLITE_ROW);
311
312 handle_error:
313         sqlite3_reset(stmt);
314         __STC_LOG_FUNC_EXIT__;
315         return error_code;
316 }
317
318 stc_error_e table_restrictions_foreach(const table_restrictions_info_cb restriction_cb,
319                                        void *user_data)
320 {
321         __STC_LOG_FUNC_ENTER__;
322         table_restrictions_info data;
323         int rc;
324         stc_error_e error_code = STC_ERROR_NONE;
325         sqlite3_stmt *stmt = select_restriction;
326
327         do {
328                 rc = sqlite3_step(stmt);
329
330                 memset(&data, 0, sizeof(data));
331
332                 switch (rc) {
333                 case SQLITE_DONE:
334                         break;
335                 case SQLITE_ROW:
336                         data.app_id = (char *)sqlite3_column_text(stmt, 0);
337                         data.rcv_limit = sqlite3_column_int64(stmt, 1);
338                         data.send_limit = sqlite3_column_int64(stmt, 2);
339                         data.iftype = (stc_iface_type_e)sqlite3_column_int(stmt, 3);
340                         data.rst_state =
341                                 (stc_restriction_state_e)sqlite3_column_int(stmt, 4);
342                         data.roaming = sqlite3_column_int(stmt, 5);
343                         data.ifname = (char *)sqlite3_column_text(stmt, 6);
344                         data.imsi = (char *)sqlite3_column_text(stmt, 7);
345                         data.rcv_warn_limit = sqlite3_column_int64(stmt, 8);
346                         data.send_warn_limit = sqlite3_column_int64(stmt, 9);
347                         data.restriction_id = sqlite3_column_int64(stmt, 10);
348
349                         if (restriction_cb(&data, user_data) == STC_CANCEL)
350                                 rc = SQLITE_DONE;
351                         break;
352                 case SQLITE_ERROR:
353                 default:
354                         STC_LOGE("Failed to enumerate restrictions: %s\n",
355                                  sqlite3_errmsg(stc_db_get_database()));
356
357                         __STC_LOG_FUNC_EXIT__;
358                         error_code = STC_ERROR_DB_FAILED;
359                 }
360         } while (rc == SQLITE_ROW);
361
362         sqlite3_reset(stmt);
363         __STC_LOG_FUNC_EXIT__;
364         return error_code;
365 }
366
367 stc_error_e table_restrictions_get_restriction_state_imsi(const char *app_id,
368                                                           stc_iface_type_e iftype,
369                                                           const char *imsi_hash,
370                                                           stc_restriction_state_e *state)
371 {
372         __STC_LOG_FUNC_ENTER__;
373         int error_code = STC_ERROR_NONE;
374         int ret;
375         bool state_imsi = 0;
376
377         if (state == NULL) {
378                 STC_LOGE("Please provide valid argument!");
379                 __STC_LOG_FUNC_EXIT__;
380                 return STC_ERROR_INVALID_PARAMETER;
381         }
382
383         *state = STC_RESTRICTION_UNKNOWN;
384         sqlite3_reset(select_restriction_state_imsi);
385         sqlite3_reset(select_restriction_state);
386
387         if (imsi_hash == NULL) {
388                 state_imsi = 0;
389                 DB_ACTION(sqlite3_bind_text(select_restriction_state, 1,
390                                             app_id ? app_id : "", -1,
391                                             SQLITE_STATIC));
392                 DB_ACTION(sqlite3_bind_int(select_restriction_state, 2,
393                                            iftype));
394                 ret = sqlite3_step(select_restriction_state);
395         } else {
396                 state_imsi = 1;
397                 DB_ACTION(sqlite3_bind_text(select_restriction_state_imsi, 1,
398                                             app_id ? app_id : "", -1,
399                                             SQLITE_STATIC));
400                 DB_ACTION(sqlite3_bind_int(select_restriction_state_imsi, 2,
401                                            iftype));
402                 DB_ACTION(sqlite3_bind_text(select_restriction_state_imsi, 3,
403                                             imsi_hash, -1, SQLITE_STATIC));
404                 ret = sqlite3_step(select_restriction_state_imsi);
405         }
406
407         switch (ret) {
408         case SQLITE_DONE:
409                 break;
410         case SQLITE_ROW:
411                 if (state_imsi)
412                         *state = (stc_restriction_state_e)sqlite3_column_int(select_restriction_state_imsi, 0);
413                 else
414                         *state = (stc_restriction_state_e)sqlite3_column_int(select_restriction_state, 0);
415                 break;
416         case SQLITE_ERROR:
417         default:
418                 STC_LOGE("Can't perform sql query: %s \n%s",
419                          SELECT_RESTRICTION_STATE,
420                          sqlite3_errmsg(stc_db_get_database()));
421                 error_code = STC_ERROR_DB_FAILED;
422         }
423
424 handle_error:
425         sqlite3_reset(select_restriction_state);
426         sqlite3_reset(select_restriction_state_imsi);
427         return error_code;
428 }
429
430 stc_error_e table_restrictions_get_restriction_state(const char *app_id,
431                                                      stc_iface_type_e iftype,
432                                                      stc_restriction_state_e *state)
433 {
434         __STC_LOG_FUNC_ENTER__;
435         __STC_LOG_FUNC_EXIT__;
436         return table_restrictions_get_restriction_state_imsi(app_id, iftype,
437                                                              NULL, state);
438 }
439
440 stc_error_e table_restrictions_delete(const char *app_id,
441                                       const stc_iface_type_e iftype,
442                                       const char *imsi)
443 {
444         stc_error_e error_code = STC_ERROR_NONE;
445         sqlite3_stmt *stmt = delete_restrictions;
446
447         STC_LOGD("app_id [%s], iftype [%d], imsi [%s]",
448                  app_id, iftype, imsi);
449
450         DB_ACTION(sqlite3_bind_text(stmt, 1, app_id ? app_id : "",
451                                     -1, SQLITE_TRANSIENT));
452         DB_ACTION(sqlite3_bind_int(stmt, 2, iftype));
453         DB_ACTION(sqlite3_bind_text(stmt, 3, imsi ? imsi : "", -1,
454                                     SQLITE_TRANSIENT));
455
456         if (sqlite3_step(stmt) != SQLITE_DONE) {
457                 STC_LOGE("Failed to remove restrictions by network interface %s\n",
458                          sqlite3_errmsg(stc_db_get_database()));
459                 error_code = STC_ERROR_DB_FAILED;
460                 goto handle_error;
461         }
462
463         STC_LOGD("Restriction deleted for app_id [%s]", app_id);
464
465 handle_error:
466
467         sqlite3_reset(stmt);
468         return error_code;
469 }
470
471 stc_error_e __get_restriction_id(table_restrictions_info *info)
472 {
473         __STC_LOG_FUNC_ENTER__;
474         int rc;
475         stc_error_e error_code = STC_ERROR_NONE;
476         sqlite3_stmt *stmt = select_restriction_id;
477
478         DB_ACTION(sqlite3_bind_text(stmt, 1, info->app_id ? info->app_id : "",
479                                     -1, SQLITE_TRANSIENT));
480         DB_ACTION(sqlite3_bind_int(stmt, 2, info->iftype));
481         DB_ACTION(sqlite3_bind_text(stmt, 3, info->imsi ? info->imsi : "",
482                                     -1, SQLITE_TRANSIENT));
483         DB_ACTION(sqlite3_bind_int64(stmt, 4, info->send_limit));
484         DB_ACTION(sqlite3_bind_int64(stmt, 5, info->rcv_limit));
485         DB_ACTION(sqlite3_bind_int64(stmt, 6, info->rcv_warn_limit));
486         DB_ACTION(sqlite3_bind_int64(stmt, 7, info->send_warn_limit));
487
488         DB_ACTION(sqlite3_bind_int(stmt, 8, info->rst_state));
489         DB_ACTION(sqlite3_bind_int(stmt, 9, info->roaming));
490         DB_ACTION(sqlite3_bind_text(stmt, 10, info->ifname ? info->ifname : "",
491                                     -1, SQLITE_TRANSIENT));
492
493         rc = sqlite3_step(stmt);
494
495         switch (rc) {
496         case SQLITE_DONE:
497                 break;
498         case SQLITE_ROW:
499                 info->restriction_id = sqlite3_column_int64(stmt, 0);
500                 STC_LOGD("restriction id [%llu]", info->restriction_id);
501                 break;
502         case SQLITE_ERROR:
503         default:
504                 STC_LOGE("Failed to get restriction id: %s\n",
505                          sqlite3_errmsg(stc_db_get_database()));
506         }
507
508 handle_error:
509         sqlite3_reset(stmt);
510         __STC_LOG_FUNC_EXIT__;
511         return error_code;
512 }
513
514 stc_error_e table_restrictions_update(table_restrictions_info *info)
515 {
516         stc_error_e error_code = STC_ERROR_NONE;
517         sqlite3_stmt *stmt = insert_net_restrictions;
518
519         if (!info) {
520                 error_code = STC_ERROR_INVALID_PARAMETER;
521                 goto handle_error;
522         }
523
524         if (info->restriction_id)
525                 stmt = update_net_restrictions;
526
527         DB_ACTION(sqlite3_bind_text(stmt, 1, info->app_id ? info->app_id : "",
528                                     -1, SQLITE_TRANSIENT));
529         DB_ACTION(sqlite3_bind_int64(stmt, 2, info->rcv_limit));
530         DB_ACTION(sqlite3_bind_int64(stmt, 3, info->send_limit));
531         DB_ACTION(sqlite3_bind_int(stmt, 4, info->iftype));
532         DB_ACTION(sqlite3_bind_int(stmt, 5, info->rst_state));
533         DB_ACTION(sqlite3_bind_int(stmt, 6, info->roaming));
534         DB_ACTION(sqlite3_bind_text(stmt, 7, info->ifname ? info->ifname : "",
535                                     -1, SQLITE_TRANSIENT));
536         DB_ACTION(sqlite3_bind_text(stmt, 8, info->imsi ? info->imsi : "",
537                                     -1, SQLITE_TRANSIENT));
538         DB_ACTION(sqlite3_bind_int64(stmt, 9, info->rcv_warn_limit));
539         DB_ACTION(sqlite3_bind_int64(stmt, 10, info->send_warn_limit));
540
541         if (info->restriction_id)
542                 DB_ACTION(sqlite3_bind_int64(stmt, 11, info->restriction_id));
543
544         if (sqlite3_step(stmt) != SQLITE_DONE) {
545                 STC_LOGE("Failed to set network restriction: %s\n",
546                          sqlite3_errmsg(stc_db_get_database()));
547                 error_code = STC_ERROR_DB_FAILED;
548                 goto handle_error;
549         }
550
551         if (info->restriction_id) {
552                 STC_LOGD("Restriction updated app_id [%s]", info->app_id);
553         } else {
554                 STC_LOGD("Restriction inserted app_id [%s]", info->app_id);
555                 __get_restriction_id(info);
556         }
557
558 handle_error:
559         sqlite3_reset(stmt);
560         return error_code;
561 }
562
563 stc_error_e table_restrictions_prepare(sqlite3 *db)
564 {
565         __STC_LOG_FUNC_ENTER__;
566
567         stc_error_e error_code = STC_ERROR_NONE;
568
569         if (db == NULL) {
570                 __STC_LOG_FUNC_EXIT__;
571                 return STC_ERROR_FAIL;
572         }
573
574         DB_ACTION(__prepare_delete(db));
575         DB_ACTION(__prepare_select(db));
576         DB_ACTION(__prepare_replace(db));
577         DB_ACTION(__prepare_insert(db));
578
579 handle_error:
580
581         __STC_LOG_FUNC_EXIT__;
582         return error_code;
583 }
584
585 void table_restrictions_finalize(void)
586 {
587         __STC_LOG_FUNC_ENTER__;
588         __finalize_delete();
589         __finalize_select();
590         __finalize_update();
591         __finalize_insert();
592         __STC_LOG_FUNC_EXIT__;
593 }