2 * Copyright (c) 2016 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 #include <vconf-keys.h>
21 #include "stc-monitor.h"
22 #include "stc-monitor-rstn.h"
23 #include "stc-monitor-ipt.h"
25 #include "table-counters.h"
26 #include "table-restrictions.h"
27 #include "table-statistics.h"
28 #include "helper-net-cls.h"
29 #include "stc-manager-plugin-appstatus.h"
30 #include "stc-manager-plugin-tether.h"
32 static void __print_rstn(stc_rstn_data_s *rstn_data)
34 STC_LOGI("RstnID[%llu] AppID[%s] classid[%u] "
35 "iftype[%d] ifname[%s] rstn_state[%d] "
36 "rstn_type[%d] roaming[%d] subscriber_id[%s]",
37 rstn_data->restriction_id,
38 rstn_data->app_id, rstn_data->classid,
39 rstn_data->iftype, rstn_data->ifname,
40 rstn_data->rstn_state, rstn_data->rstn_type,
41 rstn_data->roaming, rstn_data->subscriber_id);
42 STC_LOGI("month_start_date[%d] limit[%lld] "
43 "warn_limit[%lld] monthly_limit[%lld] "
44 "weekly_limit[%lld] daily_limit[%lld] ",
45 rstn_data->month_start_date,
46 rstn_data->limit[STC_RSTN_LIMIT_TYPE_DATA],
47 rstn_data->limit[STC_RSTN_LIMIT_TYPE_DATA_WARN],
48 rstn_data->limit[STC_RSTN_LIMIT_TYPE_MONTHLY],
49 rstn_data->limit[STC_RSTN_LIMIT_TYPE_WEEKLY],
50 rstn_data->limit[STC_RSTN_LIMIT_TYPE_DAILY]);
51 STC_LOGI("data_counter[%lld] warn_counter[%lld] "
52 "monthly_counter[%lld] weekly_counter[%lld] "
53 "daily_counter[%lld]",
54 rstn_data->counter[STC_RSTN_LIMIT_TYPE_DATA],
55 rstn_data->counter[STC_RSTN_LIMIT_TYPE_DATA_WARN],
56 rstn_data->counter[STC_RSTN_LIMIT_TYPE_MONTHLY],
57 rstn_data->counter[STC_RSTN_LIMIT_TYPE_WEEKLY],
58 rstn_data->counter[STC_RSTN_LIMIT_TYPE_DAILY]);
61 static int __vconf_get_int(const char *key, int *value)
65 ret = vconf_get_int(key, value);
66 if (ret != VCONF_OK) {
67 STC_LOGE("Failed to get vconfkey [%s] value", key);
74 static int __vconf_set_int(const char *key, int value)
78 ret = vconf_set_int(key, value);
79 if (ret != VCONF_OK) {
80 STC_LOGE("Failed to set vconfkey [%s] value", key);
87 static stc_cb_ret_e __statistics_info_cb(const table_statistics_info *info,
90 stc_rstn_cumulative_data_s *stat = (stc_rstn_cumulative_data_s *)user_data;
93 counters = info->cnt.in_bytes + info->cnt.out_bytes;
95 stat->monthly_stat += counters;
96 if (stat->week_start_ts <= info->interval->from)
97 stat->weekly_stat += counters;
98 if (stat->day_start_ts <= info->interval->from)
99 stat->daily_stat += counters;
104 static void __rstn_add_tether_rule(int64_t classid, gchar *mac,
105 nfacct_rule_intend intend, stc_iface_type_e iftype)
107 GSList *conn_list = stc_get_connection_list();
108 struct nfacct_rule counter;
109 stc_s *stc = stc_get_manager();
116 for (; conn_list != NULL; conn_list = conn_list->next) {
117 stc_connection_s *conn = conn_list->data;
120 stc->carg = MALLOC0(counter_arg_s, 1);
121 if (stc->carg == NULL)
124 stc->carg->sock = stc_monitor_get_contr_sock();
127 memset(&counter, 0, sizeof(struct nfacct_rule));
129 counter.carg = stc->carg;
130 counter.classid = classid;
131 counter.intend = intend;
133 if (conn->tether_state != TRUE ||
134 conn->tether_iface.ifname == NULL)
137 counter.iftype = conn->tether_iface.type;
138 g_strlcpy(counter.ifname, conn->tether_iface.ifname, MAX_IFACE_LENGTH);
140 /* get connected station ip based on its mac */
141 ret = stc_plugin_tether_get_station_ip(mac, &ipaddr);
142 if (ret != STC_ERROR_NONE)
145 /* tethering iptables rule */
146 stc_monitor_tether_add_in(&counter, ipaddr);
147 stc_monitor_tether_add_out(&counter, ipaddr);
152 static void __rstn_del_tether_rule(int64_t classid, gchar *mac,
153 nfacct_rule_intend intend, stc_iface_type_e iftype)
155 GSList *conn_list = stc_get_connection_list();
156 struct nfacct_rule counter;
157 stc_s *stc = stc_get_manager();
164 for (; conn_list != NULL; conn_list = conn_list->next) {
165 stc_connection_s *conn = conn_list->data;
168 stc->carg = MALLOC0(counter_arg_s, 1);
169 if (stc->carg == NULL)
172 stc->carg->sock = stc_monitor_get_contr_sock();
175 memset(&counter, 0, sizeof(struct nfacct_rule));
177 counter.carg = stc->carg;
178 counter.classid = classid;
179 counter.intend = intend;
181 if (conn->tether_state != TRUE ||
182 conn->tether_iface.ifname == NULL)
185 counter.iftype = conn->tether_iface.type;
186 g_strlcpy(counter.ifname, conn->tether_iface.ifname, MAX_IFACE_LENGTH);
188 /* get connected station ip based on its mac */
189 ret = stc_plugin_tether_get_station_ip(mac, &ipaddr);
190 if (ret != STC_ERROR_NONE) {
191 STC_LOGE("Error: no IP found for station mac(%s)", mac);
195 /* tethering iptables rule */
196 stc_monitor_tether_del_in(&counter, ipaddr);
197 stc_monitor_tether_del_out(&counter, ipaddr);
202 static void __rstn_add_ipt_rule(int64_t classid, nfacct_rule_intend intend,
203 stc_iface_type_e iftype)
205 GSList *conn_list = stc_get_connection_list();
206 struct nfacct_rule counter;
207 stc_s *stc = stc_get_manager();
212 for (; conn_list != NULL; conn_list = conn_list->next) {
213 stc_connection_s *conn = conn_list->data;
216 stc->carg = MALLOC0(counter_arg_s, 1);
217 if (stc->carg == NULL)
220 stc->carg->sock = stc_monitor_get_contr_sock();
223 memset(&counter, 0, sizeof(struct nfacct_rule));
225 counter.carg = stc->carg;
226 counter.classid = classid;
227 counter.intend = intend;
229 if (conn && conn->tether_iface.ifname != NULL &&
230 classid == STC_TETHERING_APP_CLASSID) {
231 counter.iftype = conn->tether_iface.type;
232 g_strlcpy(counter.ifname, conn->tether_iface.ifname, MAX_IFACE_LENGTH);
234 counter.iftype = iftype;
235 g_strlcpy(counter.ifname, conn->ifname, MAX_IFACE_LENGTH);
239 stc_monitor_ipt_add_in(&counter);
240 stc_monitor_ipt_add_out(&counter);
243 stc_monitor_ip6t_add_in(&counter);
244 stc_monitor_ip6t_add_out(&counter);
248 static void __rstn_del_ipt_rule(int64_t classid, nfacct_rule_intend intend,
249 stc_iface_type_e iftype)
251 GSList *conn_list = stc_get_connection_list();
252 struct nfacct_rule counter;
253 stc_s *stc = stc_get_manager();
258 for (; conn_list != NULL; conn_list = conn_list->next) {
259 stc_connection_s *conn = conn_list->data;
262 stc->carg = MALLOC0(counter_arg_s, 1);
263 if (stc->carg == NULL)
266 stc->carg->sock = stc_monitor_get_contr_sock();
269 memset(&counter, 0, sizeof(struct nfacct_rule));
271 counter.carg = stc->carg;
272 counter.classid = classid;
273 counter.intend = intend;
275 if (conn && conn->tether_iface.ifname != NULL &&
276 classid == STC_TETHERING_APP_CLASSID) {
277 counter.iftype = conn->tether_iface.type;
278 g_strlcpy(counter.ifname, conn->tether_iface.ifname, MAX_IFACE_LENGTH);
280 counter.iftype = iftype;
281 g_strlcpy(counter.ifname, conn->ifname, MAX_IFACE_LENGTH);
285 stc_monitor_ipt_del_in(&counter);
286 stc_monitor_ipt_del_out(&counter);
289 stc_monitor_ip6t_del_in(&counter);
290 stc_monitor_ip6t_del_out(&counter);
294 static void __rstn_set_noti_state(int value)
296 int state = STC_RSTN_STATE_INIT;
298 if (__vconf_get_int(VCONFKEY_SETAPPL_DATA_RESTRICTION_INT, &state))
301 if (state == value) {
302 STC_LOGI("No need to change a restriction status: %d", state);
306 __vconf_set_int(VCONFKEY_SETAPPL_DATA_RESTRICTION_INT, value);
309 static void __rstn_tethering_process(enum traffic_restriction_type rstn_type,
310 char *app_id, stc_rstn_data_s *rstn_data, void *data)
312 stc_connection_s *old_connection = (stc_connection_s *)data;
313 stc_connection_s *connection = NULL;
314 char *mac_str = NULL;
316 if (old_connection != NULL) {
317 connection = old_connection;
318 if (connection->tether_state == FALSE)
321 /* rstn not applicable for this interface */
322 if (rstn_data->ifname != NULL &&
323 g_strcmp0("", rstn_data->ifname) != 0 &&
324 g_strcmp0(connection->tether_iface.ifname, rstn_data->ifname) != 0)
327 GSList *conn_list = stc_get_connection_list();
328 for (; conn_list != NULL; conn_list = conn_list->next) {
329 stc_connection_s *conn = conn_list->data;
330 if (conn->tether_state == FALSE)
333 if (rstn_data->ifname != NULL &&
334 g_strcmp0(rstn_data->ifname, "") != 0 &&
335 g_strcmp0(conn->tether_iface.ifname, rstn_data->ifname) == 0)
339 if (connection == NULL)
343 /* in case appid not a tethering app */
344 if (!g_str_has_suffix(app_id, STC_TETHERING_APP_SUFFIX))
347 /* Ignore TOTAL_TETHERING,
348 * Process only station appids */
349 if (rstn_data->classid == STC_TETHERING_APP_CLASSID)
352 /* get the station mac based on classid */
353 stc_plugin_tether_get_station_by_classid(rstn_data->classid, &mac_str);
355 STC_LOGE("Station not found for classid(%d)", rstn_data->classid);
363 table_counters_info info;
364 int64_t effective_limit[STC_RSTN_LIMIT_TYPE_MAX] = { 0, };
366 memset(&info, 0, sizeof(table_counters_info));
367 rstn_data->limit_exceeded = 0;
369 if ((rstn_data->counter[STC_RSTN_LIMIT_TYPE_DATA] == 0 &&
370 rstn_data->limit[STC_RSTN_LIMIT_TYPE_DATA] >= 0) ||
371 (rstn_data->counter[STC_RSTN_LIMIT_TYPE_DATA_WARN] == 0 &&
372 rstn_data->limit[STC_RSTN_LIMIT_TYPE_DATA_WARN] >= 0) ||
373 (rstn_data->counter[STC_RSTN_LIMIT_TYPE_MONTHLY] == 0 &&
374 rstn_data->limit[STC_RSTN_LIMIT_TYPE_MONTHLY] >= 0) ||
375 (rstn_data->counter[STC_RSTN_LIMIT_TYPE_WEEKLY] == 0 &&
376 rstn_data->limit[STC_RSTN_LIMIT_TYPE_WEEKLY] >= 0) ||
377 (rstn_data->counter[STC_RSTN_LIMIT_TYPE_DAILY] == 0 &&
378 rstn_data->limit[STC_RSTN_LIMIT_TYPE_DAILY] >= 0)) {
379 table_counters_get(rstn_data->restriction_id, &info);
381 time_t current_time = 0;
382 stc_rstn_cumulative_data_s stat;
383 table_statistics_select_rule rule;
384 time_t last_week_ts = stc_monitor_get_last_week_ts();
385 time_t last_day_ts = stc_monitor_get_last_day_ts();
387 memset(&stat, 0, sizeof(stc_rstn_cumulative_data_s));
388 stat.month_start_ts = rstn_data->month_start_ts;
389 stat.week_start_ts = last_week_ts;
390 stat.day_start_ts = last_day_ts;
392 memset(&rule, 0, sizeof(table_statistics_select_rule));
393 rule.from = rstn_data->month_start_ts;
395 rule.to = current_time;
396 rule.iftype = rstn_data->iftype;
397 rule.granularity = GRANULARITY;
399 table_statistics_per_app(app_id, &rule, __statistics_info_cb, &stat);
401 rstn_data->counter[STC_RSTN_LIMIT_TYPE_DATA] = info.data_counter;
402 rstn_data->counter[STC_RSTN_LIMIT_TYPE_DATA_WARN] = info.warn_counter;
403 rstn_data->counter[STC_RSTN_LIMIT_TYPE_MONTHLY] = info.monthly_counter + stat.monthly_stat;
404 rstn_data->counter[STC_RSTN_LIMIT_TYPE_WEEKLY] = info.weekly_counter + stat.weekly_stat;
405 rstn_data->counter[STC_RSTN_LIMIT_TYPE_DAILY] = info.daily_counter + stat.daily_stat;
408 for (i = 0; i < STC_RSTN_LIMIT_TYPE_MAX; i++) {
409 if (rstn_data->limit[i] >= 0) {
410 effective_limit[i] = rstn_data->limit[i] - rstn_data->counter[i];
412 if (effective_limit[i] < 0)
413 rstn_data->limit_exceeded |= (1 << i);
417 STC_LOGD("Rstn_id[%llu] datausage[%lld]bytes",
418 rstn_data->restriction_id, info.data_counter);
420 if (rstn_data->limit_exceeded != 0 &&
421 rstn_data->limit_exceeded != (1 << STC_RSTN_LIMIT_TYPE_DATA_WARN)) {
422 __rstn_add_tether_rule(rstn_data->classid, mac_str,
423 NFACCT_TETH_BLOCK, rstn_data->iftype);
426 rstn_data->rstn_state = STC_RSTN_STATE_ACTIVATED;
431 __rstn_add_tether_rule(rstn_data->classid, mac_str,
432 NFACCT_TETH_ALLOW, rstn_data->iftype);
434 rstn_data->rstn_state = STC_RSTN_STATE_ACTIVATED;
435 rstn_data->limit_exceeded = 0;
436 rstn_data->limit_notified = 0;
442 __rstn_del_tether_rule(rstn_data->classid, mac_str,
443 NFACCT_TETH_BLOCK, rstn_data->iftype);
445 rstn_data->rstn_state = STC_RSTN_STATE_DEACTIVATED;
446 rstn_data->limit_exceeded = 0;
447 rstn_data->limit_notified = 0;
449 for (i = 0; i < STC_RSTN_LIMIT_TYPE_MAX; i++)
450 if (rstn_data->limit[i] >= 0)
451 rstn_data->counter[i] = 0;
460 static void __rstn_process(enum traffic_restriction_type rstn_type,
461 char *app_id, stc_rstn_data_s *rstn_data, void *data)
463 stc_connection_s *old_connection = (stc_connection_s *)data;
464 stc_connection_s *connection = NULL;
466 if (old_connection != NULL) {
467 connection = old_connection;
468 if (connection->ifname == NULL)
471 /* rstn not applicable for this interface */
472 if (rstn_data->ifname != NULL &&
473 g_strcmp0(rstn_data->ifname, "") != 0 &&
474 g_strcmp0(connection->ifname, rstn_data->ifname) != 0 &&
475 g_strcmp0(connection->tether_iface.ifname, rstn_data->ifname) != 0)
478 GSList *conn_list = stc_get_connection_list();
479 for (; conn_list != NULL; conn_list = conn_list->next) {
480 stc_connection_s *conn = conn_list->data;
481 if (conn == NULL || conn->ifname == NULL)
484 if (rstn_data->ifname != NULL &&
485 g_strcmp0(rstn_data->ifname, "") != 0 &&
486 g_strcmp0(conn->ifname, rstn_data->ifname) == 0 &&
487 g_strcmp0(conn->tether_iface.ifname, rstn_data->ifname) == 0)
491 if (connection == NULL)
495 /* classid is invalid */
496 if (rstn_data->classid <= STC_UNKNOWN_CLASSID)
499 /* Do not proceed for tethering station appid if found here,
500 * for tethering station apps __rstn_tethering_process() call
502 if (g_str_has_suffix(app_id, STC_TETHERING_APP_SUFFIX) &&
503 rstn_data->classid != STC_TETHERING_APP_CLASSID)
510 table_counters_info info;
511 int64_t effective_limit[STC_RSTN_LIMIT_TYPE_MAX] = { 0, };
513 memset(&info, 0, sizeof(table_counters_info));
514 rstn_data->limit_exceeded = 0;
516 if ((rstn_data->counter[STC_RSTN_LIMIT_TYPE_DATA] == 0 &&
517 rstn_data->limit[STC_RSTN_LIMIT_TYPE_DATA] >= 0) ||
518 (rstn_data->counter[STC_RSTN_LIMIT_TYPE_DATA_WARN] == 0 &&
519 rstn_data->limit[STC_RSTN_LIMIT_TYPE_DATA_WARN] >= 0) ||
520 (rstn_data->counter[STC_RSTN_LIMIT_TYPE_MONTHLY] == 0 &&
521 rstn_data->limit[STC_RSTN_LIMIT_TYPE_MONTHLY] >= 0) ||
522 (rstn_data->counter[STC_RSTN_LIMIT_TYPE_WEEKLY] == 0 &&
523 rstn_data->limit[STC_RSTN_LIMIT_TYPE_WEEKLY] >= 0) ||
524 (rstn_data->counter[STC_RSTN_LIMIT_TYPE_DAILY] == 0 &&
525 rstn_data->limit[STC_RSTN_LIMIT_TYPE_DAILY] >= 0)) {
526 table_counters_get(rstn_data->restriction_id, &info);
528 time_t current_time = 0;
529 stc_rstn_cumulative_data_s stat;
530 table_statistics_select_rule rule;
531 time_t last_week_ts = stc_monitor_get_last_week_ts();
532 time_t last_day_ts = stc_monitor_get_last_day_ts();
534 memset(&stat, 0, sizeof(stc_rstn_cumulative_data_s));
535 stat.month_start_ts = rstn_data->month_start_ts;
536 stat.week_start_ts = last_week_ts;
537 stat.day_start_ts = last_day_ts;
539 memset(&rule, 0, sizeof(table_statistics_select_rule));
540 rule.from = rstn_data->month_start_ts;
542 rule.to = current_time;
543 rule.iftype = rstn_data->iftype;
544 rule.granularity = GRANULARITY;
546 table_statistics_per_app(rstn_data->app_id, &rule, __statistics_info_cb, &stat);
548 rstn_data->counter[STC_RSTN_LIMIT_TYPE_DATA] = info.data_counter;
549 rstn_data->counter[STC_RSTN_LIMIT_TYPE_DATA_WARN] = info.warn_counter;
550 rstn_data->counter[STC_RSTN_LIMIT_TYPE_MONTHLY] = info.monthly_counter + stat.monthly_stat;
551 rstn_data->counter[STC_RSTN_LIMIT_TYPE_WEEKLY] = info.weekly_counter + stat.weekly_stat;
552 rstn_data->counter[STC_RSTN_LIMIT_TYPE_DAILY] = info.daily_counter + stat.daily_stat;
555 STC_LOGD("Rstn counter data[%lld] warn[%lld] "
556 "monthly[%lld] weekly[%lld] daily[%lld]",
557 rstn_data->counter[STC_RSTN_LIMIT_TYPE_DATA],
558 rstn_data->counter[STC_RSTN_LIMIT_TYPE_DATA_WARN],
559 rstn_data->counter[STC_RSTN_LIMIT_TYPE_MONTHLY],
560 rstn_data->counter[STC_RSTN_LIMIT_TYPE_WEEKLY],
561 rstn_data->counter[STC_RSTN_LIMIT_TYPE_DAILY]);
564 for (i = 0; i < STC_RSTN_LIMIT_TYPE_MAX; i++) {
565 if (rstn_data->limit[i] >= 0) {
566 effective_limit[i] = rstn_data->limit[i] - rstn_data->counter[i];
568 if (effective_limit[i] < 0)
569 rstn_data->limit_exceeded |= (1 << i);
573 STC_LOGD("Rstn_id[%llu] limit[%lld] datausage[%lld]",
574 rstn_data->restriction_id,
575 rstn_data->limit[STC_RSTN_LIMIT_TYPE_DATA],
578 if (rstn_data->limit_exceeded != 0 &&
579 rstn_data->limit_exceeded != (1 << STC_RSTN_LIMIT_TYPE_DATA_WARN)) {
580 __rstn_add_ipt_rule(rstn_data->classid, NFACCT_BLOCK, rstn_data->iftype);
583 if (rstn_data->classid == STC_BACKGROUND_APP_CLASSID)
584 __rstn_add_ipt_rule(rstn_data->classid, NFACCT_BLOCK, rstn_data->iftype);
586 rstn_data->rstn_state = STC_RSTN_STATE_ACTIVATED;
589 STC_LOGD("Restriction activated "
590 "[\033[1;36m%d\033[0;m:\033[1;35m%d\033[0;m]",
591 rstn_data->classid, rstn_data->restriction_id);
596 __rstn_add_ipt_rule(rstn_data->classid, NFACCT_ALLOW,
599 rstn_data->rstn_state = STC_RSTN_STATE_ACTIVATED;
600 rstn_data->limit_exceeded = 0;
601 rstn_data->limit_notified = 0;
604 STC_LOGD("Restriction activated "
605 "[\033[1;36m%d\033[0;m:\033[1;35m%d\033[0;m]",
606 rstn_data->classid, rstn_data->restriction_id);
613 if (rstn_data->classid == STC_TETHERING_APP_CLASSID)
614 __rstn_del_ipt_rule(rstn_data->classid, NFACCT_BLOCK,
617 __rstn_del_ipt_rule(rstn_data->classid, rstn_data->rstn_type,
620 rstn_data->rstn_state = STC_RSTN_STATE_DEACTIVATED;
621 rstn_data->limit_exceeded = 0;
622 rstn_data->limit_notified = 0;
624 for (i = 0; i < STC_RSTN_LIMIT_TYPE_MAX; i++)
625 if (rstn_data->limit[i] >= 0)
626 rstn_data->counter[i] = 0;
628 __rstn_set_noti_state(STC_RSTN_STATE_UNSET);
631 STC_LOGD("Restriction deactivated "
632 "[\033[1;36m%d\033[0;m:\033[1;35m%d\033[0;m]",
633 rstn_data->classid, rstn_data->restriction_id);
642 static void __rstn_add(gpointer data, gpointer user_data)
644 stc_rstn_data_s *rstn_data = (stc_rstn_data_s *)data;
646 /* rstn rule is activated */
647 if (rstn_data->rstn_state == STC_RSTN_STATE_ACTIVATED) {
649 STC_LOGD("Restriction already activated "
650 "[\033[1;36m%d\033[0;m:\033[1;35m%d\033[0;m]",
651 rstn_data->classid, rstn_data->restriction_id);
656 if (rstn_data->rstn_type == STC_RSTN_TYPE_ACCEPT) {
657 __rstn_process(RST_EXCLUDE,
658 rstn_data->app_id, rstn_data, user_data);
659 __rstn_tethering_process(RST_EXCLUDE,
660 rstn_data->app_id, rstn_data, user_data);
662 __rstn_process(RST_SET,
663 rstn_data->app_id, rstn_data, user_data);
664 __rstn_tethering_process(RST_SET,
665 rstn_data->app_id, rstn_data, user_data);
669 __print_rstn(rstn_data);
670 STC_LOGD("\033[1;32mRestriction added\033[0;m "
671 "[\033[1;36m%d\033[0;m:\033[1;35m%d\033[0;m]",
672 rstn_data->classid, rstn_data->restriction_id);
676 static void __rstn_add_by_connection(gpointer key,
677 gpointer value, gpointer data)
679 stc_rstn_value_s *rstn_value = (stc_rstn_value_s *)value;
681 g_slist_foreach(rstn_value->rules, __rstn_add, data);
684 static void __rstn_remove(gpointer data, gpointer user_data)
686 stc_rstn_data_s *rstn_data = (stc_rstn_data_s *)data;
688 if (rstn_data->rstn_state == STC_RSTN_STATE_DEACTIVATED) {
689 STC_LOGD("\033[1;31mRestriction already deactivated\033[0;m "
690 "[\033[1;36m%d\033[0;m:\033[1;35m%d\033[0;m]",
691 rstn_data->classid, rstn_data->restriction_id);
695 __rstn_process(RST_UNSET,
696 rstn_data->app_id, rstn_data, user_data);
697 __rstn_tethering_process(RST_UNSET,
698 rstn_data->app_id, rstn_data, user_data);
701 __print_rstn(rstn_data);
702 STC_LOGD("\033[1;31mRestriction removed\033[0;m "
703 "[\033[1;36m%d\033[0;m:\033[1;35m%d\033[0;m]",
704 rstn_data->classid, rstn_data->restriction_id);
708 static void __rstn_remove_by_connection(gpointer key,
709 gpointer value, gpointer data)
711 stc_rstn_value_s *rstn_value = (stc_rstn_value_s *)value;
713 g_slist_foreach(rstn_value->rules, __rstn_remove, data);
716 static void __rstn_update_counter_data(gpointer data,
719 stc_rstn_data_s *rstn_data = (stc_rstn_data_s *)data;
721 table_counters_info info = {
722 .restriction_id = rstn_data->restriction_id,
723 .data_counter = rstn_data->counter[STC_RSTN_LIMIT_TYPE_DATA],
724 .warn_counter = rstn_data->counter[STC_RSTN_LIMIT_TYPE_DATA_WARN],
725 .monthly_counter = rstn_data->counter[STC_RSTN_LIMIT_TYPE_MONTHLY],
726 .weekly_counter = rstn_data->counter[STC_RSTN_LIMIT_TYPE_WEEKLY],
727 .daily_counter = rstn_data->counter[STC_RSTN_LIMIT_TYPE_DAILY]
730 table_counters_update_counters(&info);
733 static void __rstn_update_counter_value(gpointer key,
734 gpointer value, gpointer data)
736 stc_rstn_value_s *rstn_value = (stc_rstn_value_s *)value;
738 g_slist_foreach(rstn_value->rules, __rstn_update_counter_data, NULL);
741 static void __rstn_data_destroy(gpointer data)
743 stc_rstn_data_s *rstn_data = (stc_rstn_data_s *)data;
745 FREE(rstn_data->app_id);
746 FREE(rstn_data->ifname);
747 FREE(rstn_data->subscriber_id);
748 FREE(rstn_data->mac);
753 static gint __rstn_data_comp(gconstpointer a, gconstpointer b)
755 stc_rstn_data_s *da = (stc_rstn_data_s *)a;
756 stc_rstn_data_s *db = (stc_rstn_data_s *)b;
758 if ((da->iftype == db->iftype) &&
759 (g_strcmp0(da->ifname, db->ifname) == 0) &&
760 (g_strcmp0(da->subscriber_id, db->subscriber_id) == 0) &&
761 (da->roaming == db->roaming))
767 static stc_error_e __rstn_data_remove(stc_rstn_data_s *data)
769 stc_rstn_value_s *lookup_value;
771 stc_rstn_data_s *lookup_data;
772 GHashTable *rstns = stc_monitor_get_system_rstns();
775 return STC_ERROR_NO_DATA;
777 lookup_value = g_hash_table_lookup(rstns, GUINT_TO_POINTER(data->classid));
780 STC_LOGE("Restriction not found [\033[1;36m%d\033[0;m]",
782 return STC_ERROR_NO_DATA;
785 lookup_list = g_slist_find_custom(lookup_value->rules,
786 data, __rstn_data_comp);
789 STC_LOGE("Restriction not found [%d:%s:%s:%d]",
790 data->iftype, data->ifname,
791 data->subscriber_id, data->roaming);
792 return STC_ERROR_NO_DATA;
795 lookup_data = lookup_list->data;
797 /* remove counter also */
798 table_counters_delete(lookup_data->restriction_id);
799 __rstn_remove(lookup_data, NULL);
801 lookup_value->rules = g_slist_remove(lookup_value->rules,
803 __rstn_data_destroy(lookup_data);
805 if (!lookup_value->rules)
806 g_hash_table_remove(rstns, GUINT_TO_POINTER(data->classid));
808 return STC_ERROR_NONE;
811 static stc_error_e __rstn_data_add(stc_rstn_data_s *data)
814 stc_rstn_value_s *lookup_value;
815 stc_rstn_value_s *rstn_value;
816 stc_rstn_data_s *rstn_data;
817 GHashTable *rstns = stc_monitor_get_system_rstns();
820 return STC_ERROR_NO_DATA;
822 rstn_data = MALLOC0(stc_rstn_data_s, 1);
825 STC_LOGE("Rstn_data allocation failed");
826 return STC_ERROR_OUT_OF_MEMORY;
829 lookup_value = g_hash_table_lookup(rstns, GUINT_TO_POINTER(data->classid));
831 rstn_value = MALLOC0(stc_rstn_value_s, 1);
834 STC_LOGE("Rstn_value allocation failed");
836 return STC_ERROR_OUT_OF_MEMORY;
839 g_hash_table_insert(rstns, GUINT_TO_POINTER(data->classid),
842 rstn_value = lookup_value;
845 rstn_data->classid = data->classid;
846 rstn_data->app_id = g_strdup(data->app_id);
847 rstn_data->iftype = data->iftype;
848 rstn_data->ifname = g_strdup(data->ifname);
849 rstn_data->subscriber_id = g_strdup(data->subscriber_id);
850 rstn_data->roaming = data->roaming;
851 rstn_data->mac = g_strdup(data->mac);
853 rstn_data->restriction_id = data->restriction_id;
854 rstn_data->rstn_state = data->rstn_state;
855 rstn_data->rstn_type = data->rstn_type;
857 for (i = 0; i < STC_RSTN_LIMIT_TYPE_MAX; i++) {
858 rstn_data->limit[i] = data->limit[i];
859 rstn_data->counter[i] = 0;
862 rstn_data->limit_exceeded = 0;
863 rstn_data->limit_notified = 0;
864 rstn_data->month_start_date = data->month_start_date;
865 rstn_data->month_start_ts = data->month_start_ts;
867 __rstn_data_remove(rstn_data);
868 rstn_value->rules = g_slist_append(rstn_value->rules, rstn_data);
870 __rstn_add(rstn_data, NULL);
872 return STC_ERROR_NONE;
875 static void __rstn_value_destroy(gpointer data)
877 stc_rstn_value_s *rstn_value = (stc_rstn_value_s *)data;
879 g_slist_free_full(rstn_value->rules, __rstn_data_destroy);
884 static stc_cb_ret_e __rstn_insert_cb(const table_restrictions_info *info,
887 stc_cb_ret_e ret = STC_CONTINUE;
888 stc_rstn_data_s data;
890 memset(&data, 0, sizeof(stc_rstn_data_s));
893 data.classid = get_classid_by_app_id(info->app_id, TRUE);
894 data.app_id = info->app_id;
896 data.classid = STC_UNKNOWN_CLASSID;
898 data.iftype = info->iftype;
899 data.ifname = info->ifname;
900 data.subscriber_id = info->subscriber_id;
901 data.roaming = info->roaming;
903 data.rstn_type = info->rstn_type;
904 data.rstn_state = STC_RSTN_STATE_UNKNOWN;
905 data.restriction_id = info->restriction_id;
907 data.limit[STC_RSTN_LIMIT_TYPE_DATA] = info->data_limit;
908 data.limit[STC_RSTN_LIMIT_TYPE_DATA_WARN] = info->data_warn_limit;
909 data.limit[STC_RSTN_LIMIT_TYPE_MONTHLY] = info->monthly_limit;
910 data.limit[STC_RSTN_LIMIT_TYPE_WEEKLY] = info->weekly_limit;
911 data.limit[STC_RSTN_LIMIT_TYPE_DAILY] = info->daily_limit;
913 if (__rstn_data_add(&data) != STC_ERROR_NONE)
919 static void __rstn_update_counter(classid_bytes_context_s *context,
922 stc_rstn_value_s *lookup;
923 GHashTable *rstns = stc_monitor_get_system_rstns();
928 lookup = g_hash_table_lookup(rstns, GUINT_TO_POINTER(classid));
930 context->counter->classid = classid;
931 g_slist_foreach(lookup->rules,
932 stc_monitor_rstn_update_counter,
937 static void __rstn_action_when_limit_exceeded_tethering(stc_rstn_data_s *rstn_data,
938 classid_bytes_context_s *context)
940 char *mac_str = NULL;
941 struct nfacct_rule *counter = context->counter;
943 /* get the station mac based on classid */
944 stc_plugin_tether_get_station_by_classid(counter->classid, &mac_str);
946 STC_LOGE("Station not found for classid(%d)", counter->classid);
950 STC_LOGI("Station mac[%s] classid[%u] iftype[%u] iotype[%d] "
951 "intend[%d] ifname[%s] bytes[%lld]", mac_str,
952 counter->classid, counter->iftype, counter->iotype,
953 counter->intend, counter->ifname, context->bytes);
955 /* Block tethering station immediately */
956 counter->intend = NFACCT_TETH_BLOCK;
957 __rstn_del_tether_rule(counter->classid, mac_str,
958 NFACCT_TETH_BLOCK, rstn_data->iftype);
960 __rstn_add_tether_rule(counter->classid, mac_str,
961 NFACCT_TETH_BLOCK, rstn_data->iftype);
962 counter->intend = NFACCT_TETH_COUNTER;
967 static void __reset_time_counter_foreach_rstn_data(gpointer data,
970 stc_rstn_data_s *rstn_data = (stc_rstn_data_s *)data;
971 reset_time_limits_context_s *context =
972 (reset_time_limits_context_s *)user_data;
974 time_t now_month_start_ts;
976 if (rstn_data->month_start_date == 0) {
977 table_counters_info info;
978 memset(&info, 0, sizeof(table_counters_info));
979 table_counters_get_timestamps(rstn_data->restriction_id, &info);
981 if (info.month_start_date == 0)
982 rstn_data->month_start_date = 1;
984 rstn_data->month_start_date = info.month_start_date;
985 rstn_data->month_start_ts = info.month_start_ts;
989 stc_time_get_month_start(context->now,
990 rstn_data->month_start_date);
992 if (rstn_data->month_start_ts != now_month_start_ts) {
993 rstn_data->month_start_ts = now_month_start_ts;
994 context->month_start_ts = now_month_start_ts;
995 context->is_updated |= (1 << STC_RSTN_LIMIT_TYPE_MONTHLY);
998 if (context->is_updated) {
999 table_counters_info info;
1000 memset(&info, 0, sizeof(table_counters_info));
1002 info.restriction_id = rstn_data->restriction_id;
1003 info.month_start_date = rstn_data->month_start_date;
1004 info.month_start_ts = rstn_data->month_start_ts;
1005 info.week_start_ts = context->week_start_ts;
1006 info.day_start_ts = context->day_start_ts;
1008 table_counters_update_timestamps(&info);
1011 for (i = STC_RSTN_LIMIT_TYPE_MONTHLY; i < STC_RSTN_LIMIT_TYPE_MAX; i++) {
1013 if ((context->is_updated) & (1 << i)) {
1015 rstn_data->counter[i] = 0;
1017 if (rstn_data->limit_exceeded & (1 << i)) {
1018 /* remove iptables rule */
1019 GSList *conn_list = stc_get_connection_list();
1020 struct nfacct_rule counter;
1021 stc_s *stc = stc_get_manager();
1023 STC_LOGE("Can't get stc data");
1024 goto try_next_callback;
1028 stc->carg = MALLOC0(counter_arg_s, 1);
1029 if (stc->carg == NULL) {
1030 goto try_next_callback;
1033 stc->carg->sock = stc_monitor_get_contr_sock();
1036 for (; conn_list != NULL; conn_list = conn_list->next) {
1037 stc_connection_s *conn = conn_list->data;
1039 memset(&counter, 0, sizeof(struct nfacct_rule));
1041 counter.carg = stc->carg;
1042 counter.classid = rstn_data->classid;
1043 counter.intend = NFACCT_BLOCK;
1044 counter.iftype = rstn_data->iftype;
1045 g_strlcpy(counter.ifname, conn->ifname, MAX_IFACE_LENGTH);
1048 stc_monitor_ipt_del_in(&counter);
1049 stc_monitor_ipt_del_out(&counter);
1051 /* ip6tables rule */
1052 stc_monitor_ip6t_del_in(&counter);
1053 stc_monitor_ip6t_del_out(&counter);
1055 rstn_data->rstn_state = STC_RSTN_STATE_DEACTIVATED;
1056 rstn_data->limit_exceeded &= ~(1 << i);
1057 rstn_data->limit_notified &= ~(1 << i);
1067 static void __reset_time_counter_foreach_rstn_value(gpointer key,
1071 stc_rstn_value_s *rstn_value = (stc_rstn_value_s *)value;
1072 g_slist_foreach(rstn_value->rules,
1073 __reset_time_counter_foreach_rstn_data, data);
1076 void stc_monitor_rstn_reset_time_counters_if_required(void)
1078 reset_time_limits_context_s context;
1079 GHashTable *rstns = stc_monitor_get_system_rstns();
1080 time_t last_week_ts = stc_monitor_get_last_week_ts();
1081 time_t last_day_ts = stc_monitor_get_last_day_ts();
1083 context.now = time(NULL);
1084 context.week_start_ts = stc_time_get_week_start(context.now);
1085 context.day_start_ts = stc_time_get_day_start(context.now);
1086 context.is_updated = 0;
1088 if (last_week_ts != context.week_start_ts) {
1089 stc_monitor_set_last_week_ts(context.week_start_ts);
1090 context.is_updated |= (1 << STC_RSTN_LIMIT_TYPE_WEEKLY);
1093 if (last_day_ts != context.day_start_ts) {
1094 stc_monitor_set_last_day_ts(context.day_start_ts);
1095 context.is_updated |= (1 << STC_RSTN_LIMIT_TYPE_DAILY);
1099 g_hash_table_foreach(rstns,
1100 __reset_time_counter_foreach_rstn_value,
1103 if (context.is_updated)
1104 STC_LOGD("Counter reset completed month_start[%ld] "
1105 "week_start[%ld] day_start[%ld]",
1106 context.month_start_ts, last_week_ts, last_day_ts);
1110 void stc_monitor_rstn_update_counter(gpointer data,
1114 stc_rstn_data_s *rstn_data = (stc_rstn_data_s *)data;
1115 classid_bytes_context_s *context = (classid_bytes_context_s *)user_data;
1116 GSList *conn_list = stc_get_connection_list();
1118 for (; conn_list != NULL; conn_list = conn_list->next) {
1119 stc_connection_s *conn = conn_list->data;
1121 if (rstn_data->iftype != context->counter->iftype)
1124 if (rstn_data->ifname != NULL &&
1125 g_strcmp0(rstn_data->ifname, "") &&
1126 g_strcmp0(rstn_data->ifname, context->counter->ifname) != 0)
1129 if (rstn_data->subscriber_id != NULL &&
1130 g_strcmp0(rstn_data->subscriber_id, "") &&
1131 g_strcmp0(rstn_data->subscriber_id, conn->subscriber_id) != 0)
1134 if (rstn_data->roaming != conn->roaming)
1137 if (rstn_data->limit_exceeded != 0) {
1138 context->data_limit_exceeded = TRUE;
1142 switch (context->counter->iotype) {
1143 case NFACCT_COUNTER_IN:
1144 case NFACCT_COUNTER_OUT:
1145 if ((rstn_data->counter[STC_RSTN_LIMIT_TYPE_DATA] == 0 &&
1146 rstn_data->limit[STC_RSTN_LIMIT_TYPE_DATA] >= 0) ||
1147 (rstn_data->counter[STC_RSTN_LIMIT_TYPE_DATA_WARN] == 0 &&
1148 rstn_data->limit[STC_RSTN_LIMIT_TYPE_DATA_WARN] >= 0) ||
1149 (rstn_data->counter[STC_RSTN_LIMIT_TYPE_MONTHLY] == 0 &&
1150 rstn_data->limit[STC_RSTN_LIMIT_TYPE_MONTHLY] >= 0) ||
1151 (rstn_data->counter[STC_RSTN_LIMIT_TYPE_WEEKLY] == 0 &&
1152 rstn_data->limit[STC_RSTN_LIMIT_TYPE_WEEKLY] >= 0) ||
1153 (rstn_data->counter[STC_RSTN_LIMIT_TYPE_DAILY] == 0 &&
1154 rstn_data->limit[STC_RSTN_LIMIT_TYPE_DAILY] >= 0)) {
1155 table_counters_info info;
1156 memset(&info, 0, sizeof(table_counters_info));
1157 table_counters_get(rstn_data->restriction_id, &info);
1159 rstn_data->counter[STC_RSTN_LIMIT_TYPE_DATA] = info.data_counter;
1160 rstn_data->counter[STC_RSTN_LIMIT_TYPE_DATA_WARN] = info.warn_counter;
1161 rstn_data->counter[STC_RSTN_LIMIT_TYPE_MONTHLY] = info.monthly_counter;
1162 rstn_data->counter[STC_RSTN_LIMIT_TYPE_WEEKLY] = info.weekly_counter;
1163 rstn_data->counter[STC_RSTN_LIMIT_TYPE_DAILY] = info.daily_counter;
1166 for (i = 0; i < STC_RSTN_LIMIT_TYPE_MAX; i++) {
1167 if (rstn_data->limit[i] >= 0 &&
1168 !(rstn_data->limit_notified & (1 << i))) {
1169 rstn_data->counter[i] += context->bytes;
1170 if (rstn_data->limit[i] <= rstn_data->counter[i])
1171 stc_monitor_rstn_action_when_limit_exceeded(i,
1177 stc_monitor_set_rstns_updated(TRUE);
1178 __print_rstn(rstn_data);
1181 STC_LOGE("Unknown iotype");
1186 void stc_monitor_rstn_update_iface_counter(classid_bytes_context_s *context)
1188 switch (context->counter->iftype) {
1189 case STC_IFACE_DATACALL:
1190 __rstn_update_counter(context, STC_TOTAL_DATACALL_CLASSID);
1192 case STC_IFACE_WIFI:
1193 __rstn_update_counter(context, STC_TOTAL_WIFI_CLASSID);
1194 __rstn_update_counter(context, STC_TETHERING_APP_CLASSID);
1196 case STC_IFACE_BLUETOOTH:
1197 __rstn_update_counter(context, STC_TOTAL_BLUETOOTH_CLASSID);
1198 __rstn_update_counter(context, STC_TETHERING_APP_CLASSID);
1201 __rstn_update_counter(context, STC_TETHERING_APP_CLASSID);
1204 __rstn_update_counter(context, STC_TETHERING_APP_CLASSID);
1211 void stc_monitor_rstn_action_when_limit_exceeded(stc_rstn_limit_type_e limit_type,
1212 stc_rstn_data_s *rstn_data,
1213 classid_bytes_context_s *context)
1216 char iftype[MAX_INT_LENGTH] = { 0, };
1217 char byte[MAX_INT_LENGTH] = { 0, };
1218 const char *signal_name = NULL;
1219 const char *net_popup_content = NULL;
1220 const char *net_popup_type = NULL;
1221 stc_s *stc = (stc_s *)stc_get_manager();
1224 STC_LOGE("Failed to get stc data");
1228 switch (limit_type) {
1229 case STC_RSTN_LIMIT_TYPE_DATA_WARN:
1231 signal_name = "WarnThresholdCrossed";
1232 net_popup_content = "warn threshold crossed";
1233 net_popup_type = "warning_noti";
1236 case STC_RSTN_LIMIT_TYPE_DATA:
1237 case STC_RSTN_LIMIT_TYPE_MONTHLY:
1238 case STC_RSTN_LIMIT_TYPE_WEEKLY:
1239 case STC_RSTN_LIMIT_TYPE_DAILY:
1241 signal_name = "RestrictionThresholdCrossed";
1242 net_popup_content = "restriction threshold crossed";
1243 net_popup_type = "restriction_noti";
1245 /* Apply restriction for tethering apps if app_id is of tethering client
1246 * otherwise do the normal iptables rule */
1247 if (context->counter->intend == NFACCT_TETH_COUNTER) {
1249 if (g_str_has_suffix(rstn_data->app_id, STC_TETHERING_APP_SUFFIX) &&
1250 rstn_data->classid != STC_TETHERING_APP_CLASSID) {
1251 __rstn_action_when_limit_exceeded_tethering(rstn_data,
1256 /* block immediately */
1257 context->counter->intend = NFACCT_BLOCK;
1258 stc_monitor_ipt_del_in(context->counter);
1259 stc_monitor_ipt_del_out(context->counter);
1260 stc_monitor_ipt_add_in(context->counter);
1261 stc_monitor_ipt_add_out(context->counter);
1263 stc_monitor_ip6t_del_in(context->counter);
1264 stc_monitor_ip6t_del_out(context->counter);
1265 stc_monitor_ip6t_add_in(context->counter);
1266 stc_monitor_ip6t_add_out(context->counter);
1267 context->counter->intend = NFACCT_COUNTER;
1270 rstn_data->limit_exceeded |= (1 << limit_type);
1271 __rstn_set_noti_state(STC_RSTN_STATE_SET);
1278 if (signal_name == NULL) {
1279 STC_LOGE("Invalid parameter: limit_type");
1284 rv = stc_manager_dbus_emit_signal(stc->connection,
1285 STC_DBUS_SERVICE_RESTRICTION_PATH,
1286 STC_DBUS_INTERFACE_RESTRICTION,
1288 g_variant_new("(si)",
1290 rstn_data->iftype));
1293 rstn_data->limit_notified |= (1 << limit_type);
1295 snprintf(iftype, MAX_INT_LENGTH, "%d", rstn_data->iftype);
1296 snprintf(byte, MAX_INT_LENGTH, "%lld", rstn_data->limit[limit_type]);
1297 stc_plugin_appstatus_send_message(net_popup_content,
1298 net_popup_type, rstn_data->app_id, iftype, byte);
1301 STC_LOGD("Limit exceeded [\033[0;31m%s\033[0;m:%d]",
1302 net_popup_content, limit_type);
1305 gboolean stc_monitor_rstn_flush_contr_to_db(gpointer user_data)
1307 time_t current_time = 0;
1308 stc_s *stc = stc_get_manager();
1309 GHashTable *rstns = stc_monitor_get_system_rstns();
1310 gboolean rstns_updated = stc_monitor_get_rstns_updated();
1312 if (stc && stc->carg)
1313 current_time = stc->carg->last_run_time;
1315 if (rstns_updated == FALSE)
1316 return G_SOURCE_REMOVE;
1318 stc_monitor_set_rstns_updated(FALSE);
1321 g_hash_table_foreach(rstns,
1322 __rstn_update_counter_value,
1325 STC_LOGI("Flushed rstns counters to database");
1326 return G_SOURCE_REMOVE;
1329 stc_error_e stc_monitor_rstn_add(const table_restrictions_info *info)
1331 stc_rstn_data_s data;
1333 memset(&data, 0, sizeof(stc_rstn_data_s));
1336 data.classid = get_classid_by_app_id(info->app_id, TRUE);
1337 data.app_id = info->app_id;
1339 data.classid = STC_UNKNOWN_CLASSID;
1341 if (data.classid == STC_BACKGROUND_APP_CLASSID) {
1342 stc_monitor_set_background_state(TRUE);
1343 __vconf_set_int(VCONFKEY_STC_BACKGROUND_STATE, TRUE);
1346 data.iftype = info->iftype;
1347 data.ifname = info->ifname;
1348 data.subscriber_id = info->subscriber_id;
1349 data.roaming = info->roaming;
1350 data.mac = info->mac;
1352 data.rstn_type = info->rstn_type;
1353 data.rstn_state = STC_RSTN_STATE_UNKNOWN;
1354 data.restriction_id = info->restriction_id;
1356 data.limit[STC_RSTN_LIMIT_TYPE_DATA] = info->data_limit;
1357 data.limit[STC_RSTN_LIMIT_TYPE_DATA_WARN] = info->data_warn_limit;
1358 data.limit[STC_RSTN_LIMIT_TYPE_MONTHLY] = info->monthly_limit;
1359 data.limit[STC_RSTN_LIMIT_TYPE_WEEKLY] = info->weekly_limit;
1360 data.limit[STC_RSTN_LIMIT_TYPE_DAILY] = info->daily_limit;
1361 data.month_start_date = info->month_start_date;
1362 data.month_start_ts = stc_time_get_month_start(time(NULL),
1363 info->month_start_date);
1365 return __rstn_data_add(&data);
1368 void stc_monitor_rstn_add_for_app(uint32_t classid)
1370 stc_rstn_value_s *lookup_value;
1371 GHashTable *rstns = stc_monitor_get_system_rstns();
1376 lookup_value = g_hash_table_lookup(rstns, GUINT_TO_POINTER(classid));
1377 if (!lookup_value) {
1379 STC_LOGD("Restriction not found [\033[1;36m%d\033[0;m]",
1384 g_slist_foreach(lookup_value->rules, __rstn_add, NULL);
1387 void stc_monitor_rstn_add_by_connection(stc_connection_s *conn)
1389 GHashTable *rstns = stc_monitor_get_system_rstns();
1394 g_hash_table_foreach(rstns, __rstn_add_by_connection, conn);
1397 stc_error_e stc_monitor_rstn_remove(const table_restrictions_info *info)
1399 stc_rstn_data_s data;
1401 memset(&data, 0, sizeof(stc_rstn_data_s));
1403 data.classid = get_classid_by_app_id(info->app_id, TRUE);
1404 data.app_id = info->app_id;
1406 data.iftype = info->iftype;
1407 data.ifname = info->ifname;
1408 data.subscriber_id = info->subscriber_id;
1409 data.roaming = info->roaming;
1411 if (g_strcmp0(info->app_id, STC_TOTAL_BACKGROUND) == 0) {
1412 stc_monitor_set_background_state(FALSE);
1413 __vconf_set_int(VCONFKEY_STC_BACKGROUND_STATE, FALSE);
1416 return __rstn_data_remove(&data);
1419 void stc_monitor_rstn_remove_for_app(uint32_t classid)
1421 stc_rstn_value_s *lookup_value;
1422 GHashTable *rstns = stc_monitor_get_system_rstns();
1427 lookup_value = g_hash_table_lookup(rstns, GUINT_TO_POINTER(classid));
1428 if (!lookup_value) {
1430 STC_LOGD("Restriction not found [\033[1;36m%d\033[0;m]",
1435 g_slist_foreach(lookup_value->rules, __rstn_remove, NULL);
1438 void stc_monitor_rstn_remove_by_connection(stc_connection_s *conn)
1440 GHashTable *rstns = stc_monitor_get_system_rstns();
1445 g_hash_table_foreach(rstns, __rstn_remove_by_connection, conn);
1448 void stc_monitor_rstns_load(void)
1450 table_restrictions_foreach(__rstn_insert_cb, NULL);
1452 /* __rstn_tree_printall(); */
1455 GHashTable *stc_monitor_rstns_init(void)
1457 return g_hash_table_new_full(g_direct_hash, g_direct_equal,
1458 NULL, __rstn_value_destroy);