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