d717326b7e85119b0de3225382c6c5a2f2616ab9
[platform/core/connectivity/stc-manager.git] / src / monitor / stc-monitor-rstn.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 #include <vconf.h>
18 #include <vconf-keys.h>
19
20 #include "counter.h"
21 #include "stc-monitor.h"
22 #include "stc-monitor-rstn.h"
23 #include "stc-monitor-ipt.h"
24 #include "stc-time.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"
31
32 static void __print_rstn(stc_rstn_data_s *rstn_data)
33 {
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]);
59 }
60
61 static int __vconf_get_int(const char *key, int *value)
62 {
63         int ret = 0;
64
65         ret = vconf_get_int(key, value);
66         if (ret != VCONF_OK) {
67                 STC_LOGE("Failed to get vconfkey [%s] value", key);
68                 return -1;
69         }
70
71         return 0;
72 }
73
74 static int __vconf_set_int(const char *key, int value)
75 {
76         int ret = 0;
77
78         ret = vconf_set_int(key, value);
79         if (ret != VCONF_OK) {
80                 STC_LOGE("Failed to set vconfkey [%s] value", key);
81                 return -1;
82         }
83
84         return 0;
85 }
86
87 static stc_cb_ret_e __statistics_info_cb(const table_statistics_info *info,
88                                         void *user_data)
89 {
90         stc_rstn_cumulative_data_s *stat = (stc_rstn_cumulative_data_s *)user_data;
91         int64_t counters = 0;
92
93         counters = info->cnt.in_bytes + info->cnt.out_bytes;
94
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;
100
101         return STC_CONTINUE;
102 }
103
104 static void __rstn_add_tether_rule(int64_t classid, gchar *mac,
105                 nfacct_rule_intend intend, stc_iface_type_e iftype)
106 {
107         default_connection_s *connection = stc_get_default_connection();
108         struct nfacct_rule counter;
109         stc_s *stc = stc_get_manager();
110         char *ipaddr = NULL;
111         int ret;
112
113         if (!stc || !mac)
114                 return;
115
116         if (!stc->carg) {
117                 stc->carg = MALLOC0(counter_arg_s, 1);
118                 if (stc->carg == NULL)
119                         return;
120
121                 stc->carg->sock = stc_monitor_get_contr_sock();
122         }
123
124         memset(&counter, 0, sizeof(struct nfacct_rule));
125
126         counter.carg = stc->carg;
127         counter.classid = classid;
128         counter.intend = intend;
129
130         if (connection->tether_state != TRUE ||
131                 connection->tether_iface.ifname == NULL)
132         return;
133
134         counter.iftype = connection->tether_iface.type;
135         g_strlcpy(counter.ifname, connection->tether_iface.ifname, MAX_IFACE_LENGTH);
136
137         /* get connected station ip based on its mac */
138         ret = stc_plugin_tether_get_station_ip(mac, &ipaddr);
139         if (ret != STC_ERROR_NONE)
140                 return;
141
142         /* tethering iptables rule */
143         stc_monitor_tether_add_in(&counter, ipaddr);
144         stc_monitor_tether_add_out(&counter, ipaddr);
145         g_free(ipaddr);
146 }
147
148 static void __rstn_del_tether_rule(int64_t classid, gchar *mac,
149                 nfacct_rule_intend intend, stc_iface_type_e iftype)
150 {
151         default_connection_s *connection = stc_get_default_connection();
152         struct nfacct_rule counter;
153         stc_s *stc = stc_get_manager();
154         char *ipaddr = NULL;
155         int ret;
156
157         if (!stc || !mac)
158                 return;
159
160         if (!stc->carg) {
161                 stc->carg = MALLOC0(counter_arg_s, 1);
162                 if (stc->carg == NULL)
163                         return;
164
165                 stc->carg->sock = stc_monitor_get_contr_sock();
166         }
167
168         memset(&counter, 0, sizeof(struct nfacct_rule));
169
170         counter.carg = stc->carg;
171         counter.classid = classid;
172         counter.intend = intend;
173
174         if (connection->tether_state != TRUE ||
175                 connection->tether_iface.ifname == NULL)
176         return;
177
178         counter.iftype = connection->tether_iface.type;
179         g_strlcpy(counter.ifname, connection->tether_iface.ifname, MAX_IFACE_LENGTH);
180
181         /* get connected station ip based on its mac */
182         ret = stc_plugin_tether_get_station_ip(mac, &ipaddr);
183         if (ret != STC_ERROR_NONE) {
184                 STC_LOGE("Error: no IP found for station mac(%s)", mac);
185                 return;
186         }
187
188         /* tethering iptables rule */
189         stc_monitor_tether_del_in(&counter, ipaddr);
190         stc_monitor_tether_del_out(&counter, ipaddr);
191         g_free(ipaddr);
192 }
193
194 static void __rstn_add_ipt_rule(int64_t classid, nfacct_rule_intend intend,
195                                 stc_iface_type_e iftype)
196 {
197         char *default_ifname = stc_default_connection_get_ifname();
198         default_connection_s *connection = stc_get_default_connection();
199         struct nfacct_rule counter;
200         stc_s *stc = stc_get_manager();
201         if (!stc) {
202                 g_free(default_ifname);
203                 return;
204         }
205
206         if (!stc->carg) {
207                 stc->carg = MALLOC0(counter_arg_s, 1);
208                 if (stc->carg == NULL) {
209                         g_free(default_ifname);
210                         return;
211                 }
212
213                 stc->carg->sock = stc_monitor_get_contr_sock();
214         }
215
216         memset(&counter, 0, sizeof(struct nfacct_rule));
217
218         counter.carg = stc->carg;
219         counter.classid = classid;
220         counter.intend = intend;
221
222         if (connection && connection->tether_iface.ifname != NULL &&
223                 classid == STC_TETHERING_APP_CLASSID) {
224                 counter.iftype = connection->tether_iface.type;
225                 g_strlcpy(counter.ifname, connection->tether_iface.ifname, MAX_IFACE_LENGTH);
226         } else {
227                 counter.iftype = iftype;
228                 g_strlcpy(counter.ifname, default_ifname, MAX_IFACE_LENGTH);
229         }
230
231         g_free(default_ifname);
232
233         /* iptables rule */
234         stc_monitor_ipt_add_in(&counter);
235         stc_monitor_ipt_add_out(&counter);
236
237         /* ip6tables rule */
238         stc_monitor_ip6t_add_in(&counter);
239         stc_monitor_ip6t_add_out(&counter);
240 }
241
242 static void __rstn_del_ipt_rule(int64_t classid, nfacct_rule_intend intend,
243                                 stc_iface_type_e iftype)
244 {
245         char *default_ifname = stc_default_connection_get_ifname();
246         default_connection_s *connection = stc_get_default_connection();
247         struct nfacct_rule counter;
248         stc_s *stc = stc_get_manager();
249         if (!stc) {
250                 g_free(default_ifname);
251                 return;
252         }
253
254         if (!stc->carg) {
255                 stc->carg = MALLOC0(counter_arg_s, 1);
256                 if (stc->carg == NULL) {
257                         g_free(default_ifname);
258                         return;
259                 }
260
261                 stc->carg->sock = stc_monitor_get_contr_sock();
262         }
263
264         memset(&counter, 0, sizeof(struct nfacct_rule));
265
266         counter.carg = stc->carg;
267         counter.classid = classid;
268         counter.intend = intend;
269
270         if (connection && connection->tether_iface.ifname != NULL &&
271                 classid == STC_TETHERING_APP_CLASSID) {
272                 counter.iftype = connection->tether_iface.type;
273                 g_strlcpy(counter.ifname, connection->tether_iface.ifname, MAX_IFACE_LENGTH);
274         } else {
275                 counter.iftype = iftype;
276                 g_strlcpy(counter.ifname, default_ifname, MAX_IFACE_LENGTH);
277         }
278
279         g_free(default_ifname);
280
281         /* iptables rule */
282         stc_monitor_ipt_del_in(&counter);
283         stc_monitor_ipt_del_out(&counter);
284
285         /* ip6tables rule */
286         stc_monitor_ip6t_del_in(&counter);
287         stc_monitor_ip6t_del_out(&counter);
288 }
289
290 static void __rstn_set_noti_state(int value)
291 {
292         int state = STC_RSTN_STATE_INIT;
293
294         if (__vconf_get_int(VCONFKEY_SETAPPL_DATA_RESTRICTION_INT, &state))
295                 return;
296
297         if (state == value) {
298                 STC_LOGI("No need to change a restriction status: %d", state);
299                 return;
300         }
301
302         __vconf_set_int(VCONFKEY_SETAPPL_DATA_RESTRICTION_INT, value);
303 }
304
305 static void __rstn_tethering_process(enum traffic_restriction_type rstn_type,
306                                 char *app_id, stc_rstn_data_s *rstn_data, void *data)
307 {
308         default_connection_s *old_connection = (default_connection_s *)data;
309         default_connection_s *connection = NULL;
310         char *mac_str = NULL;
311
312         if (old_connection != NULL)
313                 connection = old_connection;
314         else
315                 connection = stc_get_default_connection();
316
317         /* in case tethering is not active */
318         if (connection->tether_state == FALSE)
319                 return;
320
321         /* rstn not applicable for this interface */
322         if (rstn_data->ifname != NULL && g_strcmp0("", rstn_data->ifname) != 0 &&
323                         (g_strcmp0(connection->tether_iface.ifname, rstn_data->ifname) != 0))
324                 return;
325
326         /* in case appid not a tethering app */
327         if (!g_str_has_suffix(app_id, STC_TETHERING_APP_SUFFIX))
328                 return;
329
330         /* Ignore TOTAL_TETHERING,
331          * Process only station appids */
332         if (rstn_data->classid == STC_TETHERING_APP_CLASSID)
333                 return;
334
335         /* get the station mac based on classid */
336         stc_plugin_tether_get_station_by_classid(rstn_data->classid, &mac_str);
337         if (!mac_str) {
338                 STC_LOGE("Station not found for classid(%d)", rstn_data->classid);
339                 return;
340         }
341
342         switch (rstn_type) {
343         case RST_SET:
344         {
345                 int i;
346                 table_counters_info info;
347                 int64_t effective_limit[STC_RSTN_LIMIT_TYPE_MAX] = { 0, };
348
349                         memset(&info, 0, sizeof(table_counters_info));
350                         rstn_data->limit_exceeded = 0;
351
352                         if ((rstn_data->counter[STC_RSTN_LIMIT_TYPE_DATA] == 0 &&
353                                                 rstn_data->limit[STC_RSTN_LIMIT_TYPE_DATA] >= 0) ||
354                                         (rstn_data->counter[STC_RSTN_LIMIT_TYPE_DATA_WARN] == 0 &&
355                                          rstn_data->limit[STC_RSTN_LIMIT_TYPE_DATA_WARN] >= 0) ||
356                                         (rstn_data->counter[STC_RSTN_LIMIT_TYPE_MONTHLY] == 0 &&
357                                          rstn_data->limit[STC_RSTN_LIMIT_TYPE_MONTHLY] >= 0) ||
358                                         (rstn_data->counter[STC_RSTN_LIMIT_TYPE_WEEKLY] == 0 &&
359                                          rstn_data->limit[STC_RSTN_LIMIT_TYPE_WEEKLY] >= 0) ||
360                                         (rstn_data->counter[STC_RSTN_LIMIT_TYPE_DAILY] == 0 &&
361                                          rstn_data->limit[STC_RSTN_LIMIT_TYPE_DAILY] >= 0)) {
362                                 table_counters_get(rstn_data->restriction_id, &info);
363
364                                 time_t current_time = 0;
365                                 stc_rstn_cumulative_data_s stat;
366                                 table_statistics_select_rule rule;
367                                 time_t last_week_ts = stc_monitor_get_last_week_ts();
368                                 time_t last_day_ts = stc_monitor_get_last_day_ts();
369
370                                 memset(&stat, 0, sizeof(stc_rstn_cumulative_data_s));
371                                 stat.month_start_ts = rstn_data->month_start_ts;
372                                 stat.week_start_ts = last_week_ts;
373                                 stat.day_start_ts = last_day_ts;
374
375                                 memset(&rule, 0, sizeof(table_statistics_select_rule));
376                                 rule.from = rstn_data->month_start_ts;
377                                 time(&current_time);
378                                 rule.to = current_time;
379                                 rule.iftype = rstn_data->iftype;
380                                 rule.granularity = GRANULARITY;
381
382                                 table_statistics_per_app(app_id, &rule, __statistics_info_cb, &stat);
383
384                                 rstn_data->counter[STC_RSTN_LIMIT_TYPE_DATA] = info.data_counter;
385                                 rstn_data->counter[STC_RSTN_LIMIT_TYPE_DATA_WARN] = info.warn_counter;
386                                 rstn_data->counter[STC_RSTN_LIMIT_TYPE_MONTHLY] = info.monthly_counter + stat.monthly_stat;
387                                 rstn_data->counter[STC_RSTN_LIMIT_TYPE_WEEKLY] = info.weekly_counter + stat.weekly_stat;
388                                 rstn_data->counter[STC_RSTN_LIMIT_TYPE_DAILY] = info.daily_counter + stat.daily_stat;
389                         }
390
391                         for (i = 0; i < STC_RSTN_LIMIT_TYPE_MAX; i++) {
392                                 if (rstn_data->limit[i] >= 0) {
393                                         effective_limit[i] = rstn_data->limit[i] - rstn_data->counter[i];
394
395                                         if (effective_limit[i] < 0)
396                                                 rstn_data->limit_exceeded |= (1 << i);
397                                 }
398                         }
399
400                         STC_LOGD("Rstn_id[%llu] datausage[%lld]bytes",
401                                         rstn_data->restriction_id, info.data_counter);
402
403                         if (rstn_data->limit_exceeded != 0 &&
404                                         rstn_data->limit_exceeded != (1 << STC_RSTN_LIMIT_TYPE_DATA_WARN)) {
405                                 __rstn_add_tether_rule(rstn_data->classid, mac_str,
406                                                 NFACCT_TETH_BLOCK, rstn_data->iftype);
407                         }
408
409                         rstn_data->rstn_state = STC_RSTN_STATE_ACTIVATED;
410         }
411         break;
412         case RST_EXCLUDE:
413         {
414                 __rstn_add_tether_rule(rstn_data->classid, mac_str,
415                                         NFACCT_TETH_ALLOW, rstn_data->iftype);
416
417                         rstn_data->rstn_state = STC_RSTN_STATE_ACTIVATED;
418                         rstn_data->limit_exceeded = 0;
419                         rstn_data->limit_notified = 0;
420         }
421         break;
422         case RST_UNSET:
423         {
424                         int i;
425                         __rstn_del_tether_rule(rstn_data->classid, mac_str,
426                                         NFACCT_TETH_BLOCK, rstn_data->iftype);
427
428                         rstn_data->rstn_state = STC_RSTN_STATE_DEACTIVATED;
429                         rstn_data->limit_exceeded = 0;
430                         rstn_data->limit_notified = 0;
431
432                         for (i = 0; i < STC_RSTN_LIMIT_TYPE_MAX; i++)
433                                 if (rstn_data->limit[i] >= 0)
434                                         rstn_data->counter[i] = 0;
435         }
436         break;
437         default:
438                 break;
439         }
440         FREE(mac_str);
441 }
442
443 static void __rstn_process(enum traffic_restriction_type rstn_type,
444                                   char *app_id, stc_rstn_data_s *rstn_data, void *data)
445 {
446         default_connection_s *old_connection = (default_connection_s *)data;
447         default_connection_s *connection = NULL;
448
449         if (old_connection != NULL)
450                 connection = old_connection;
451         else
452                 connection = stc_get_default_connection();
453
454         /* no default ifname */
455         if (connection->ifname == NULL)
456                 return;
457
458         /* rstn not applicable for this interface */
459         if (rstn_data->ifname != NULL &&
460                 g_strcmp0(rstn_data->ifname, "") != 0 &&
461             (g_strcmp0(connection->ifname, rstn_data->ifname) != 0) &&
462                 (g_strcmp0(connection->tether_iface.ifname, rstn_data->ifname) != 0))
463                 return;
464
465         /* classid is invalid */
466         if (rstn_data->classid <= STC_UNKNOWN_CLASSID)
467                 return;
468
469         /* Do not proceed for tethering station appid if found here,
470          * for tethering station apps __rstn_tethering_process() call
471          * will handle it */
472         if (g_str_has_suffix(app_id, STC_TETHERING_APP_SUFFIX) &&
473                         rstn_data->classid != STC_TETHERING_APP_CLASSID)
474                 return;
475
476         switch (rstn_type) {
477         case RST_SET:
478         {
479                 int i;
480                 table_counters_info info;
481                 int64_t effective_limit[STC_RSTN_LIMIT_TYPE_MAX] = { 0, };
482
483                 memset(&info, 0, sizeof(table_counters_info));
484                 rstn_data->limit_exceeded = 0;
485
486                 if ((rstn_data->counter[STC_RSTN_LIMIT_TYPE_DATA] == 0 &&
487                         rstn_data->limit[STC_RSTN_LIMIT_TYPE_DATA] >= 0) ||
488                         (rstn_data->counter[STC_RSTN_LIMIT_TYPE_DATA_WARN] == 0 &&
489                         rstn_data->limit[STC_RSTN_LIMIT_TYPE_DATA_WARN] >= 0) ||
490                         (rstn_data->counter[STC_RSTN_LIMIT_TYPE_MONTHLY] == 0 &&
491                         rstn_data->limit[STC_RSTN_LIMIT_TYPE_MONTHLY] >= 0) ||
492                         (rstn_data->counter[STC_RSTN_LIMIT_TYPE_WEEKLY] == 0 &&
493                         rstn_data->limit[STC_RSTN_LIMIT_TYPE_WEEKLY] >= 0) ||
494                         (rstn_data->counter[STC_RSTN_LIMIT_TYPE_DAILY] == 0 &&
495                         rstn_data->limit[STC_RSTN_LIMIT_TYPE_DAILY] >= 0)) {
496                         table_counters_get(rstn_data->restriction_id, &info);
497
498                         time_t current_time = 0;
499                         stc_rstn_cumulative_data_s stat;
500                         table_statistics_select_rule rule;
501                         time_t last_week_ts = stc_monitor_get_last_week_ts();
502                         time_t last_day_ts = stc_monitor_get_last_day_ts();
503
504                         memset(&stat, 0, sizeof(stc_rstn_cumulative_data_s));
505                         stat.month_start_ts = rstn_data->month_start_ts;
506                         stat.week_start_ts = last_week_ts;
507                         stat.day_start_ts = last_day_ts;
508
509                         memset(&rule, 0, sizeof(table_statistics_select_rule));
510                         rule.from = rstn_data->month_start_ts;
511                         time(&current_time);
512                         rule.to = current_time;
513                         rule.iftype = rstn_data->iftype;
514                         rule.granularity = GRANULARITY;
515
516                         table_statistics_per_app(rstn_data->app_id, &rule, __statistics_info_cb, &stat);
517
518                         rstn_data->counter[STC_RSTN_LIMIT_TYPE_DATA] = info.data_counter;
519                         rstn_data->counter[STC_RSTN_LIMIT_TYPE_DATA_WARN] = info.warn_counter;
520                         rstn_data->counter[STC_RSTN_LIMIT_TYPE_MONTHLY] = info.monthly_counter + stat.monthly_stat;
521                         rstn_data->counter[STC_RSTN_LIMIT_TYPE_WEEKLY] = info.weekly_counter + stat.weekly_stat;
522                         rstn_data->counter[STC_RSTN_LIMIT_TYPE_DAILY] = info.daily_counter + stat.daily_stat;
523
524                         if (STC_DEBUG_LOG)
525                                 STC_LOGD("Rstn counter data[%lld] warn[%lld] "
526                                 "monthly[%lld] weekly[%lld] daily[%lld]",
527                                 rstn_data->counter[STC_RSTN_LIMIT_TYPE_DATA],
528                                 rstn_data->counter[STC_RSTN_LIMIT_TYPE_DATA_WARN],
529                                 rstn_data->counter[STC_RSTN_LIMIT_TYPE_MONTHLY],
530                                 rstn_data->counter[STC_RSTN_LIMIT_TYPE_WEEKLY],
531                                 rstn_data->counter[STC_RSTN_LIMIT_TYPE_DAILY]);
532                 }
533
534                 for (i = 0; i < STC_RSTN_LIMIT_TYPE_MAX; i++) {
535                         if (rstn_data->limit[i] >= 0) {
536                                 effective_limit[i] = rstn_data->limit[i] - rstn_data->counter[i];
537
538                                 if (effective_limit[i] < 0)
539                                         rstn_data->limit_exceeded |= (1 << i);
540                         }
541                 }
542
543                 STC_LOGD("Rstn_id[%llu] limit[%lld] datausage[%lld]",
544                                         rstn_data->restriction_id,
545                                         rstn_data->limit[STC_RSTN_LIMIT_TYPE_DATA],
546                                         info.data_counter);
547
548                 if (rstn_data->limit_exceeded != 0 &&
549                         rstn_data->limit_exceeded != (1 << STC_RSTN_LIMIT_TYPE_DATA_WARN)) {
550                         __rstn_add_ipt_rule(rstn_data->classid, NFACCT_BLOCK, rstn_data->iftype);
551                 }
552
553                 if (rstn_data->classid == STC_BACKGROUND_APP_CLASSID)
554                         __rstn_add_ipt_rule(rstn_data->classid, NFACCT_BLOCK, rstn_data->iftype);
555
556                 rstn_data->rstn_state = STC_RSTN_STATE_ACTIVATED;
557
558                 if (STC_DEBUG_LOG) {
559                         STC_LOGD("Restriction activated "
560                                 "[\033[1;36m%d\033[0;m:\033[1;35m%d\033[0;m]",
561                                 rstn_data->classid, rstn_data->restriction_id);
562                 }
563         }
564         break;
565         case RST_EXCLUDE:
566                 __rstn_add_ipt_rule(rstn_data->classid, NFACCT_ALLOW,
567                                     rstn_data->iftype);
568
569                 rstn_data->rstn_state = STC_RSTN_STATE_ACTIVATED;
570                 rstn_data->limit_exceeded = 0;
571                 rstn_data->limit_notified = 0;
572
573                 if (STC_DEBUG_LOG) {
574                         STC_LOGD("Restriction activated "
575                                 "[\033[1;36m%d\033[0;m:\033[1;35m%d\033[0;m]",
576                                 rstn_data->classid, rstn_data->restriction_id);
577                 }
578                 break;
579         case RST_UNSET:
580         {
581                 int i;
582
583                 if (rstn_data->classid == STC_TETHERING_APP_CLASSID)
584                         __rstn_del_ipt_rule(rstn_data->classid, NFACCT_BLOCK,
585                                             rstn_data->iftype);
586                 else
587                         __rstn_del_ipt_rule(rstn_data->classid, rstn_data->rstn_type,
588                                             rstn_data->iftype);
589
590                 rstn_data->rstn_state = STC_RSTN_STATE_DEACTIVATED;
591                 rstn_data->limit_exceeded = 0;
592                 rstn_data->limit_notified = 0;
593
594                 for (i = 0; i < STC_RSTN_LIMIT_TYPE_MAX; i++)
595                         if (rstn_data->limit[i] >= 0)
596                                 rstn_data->counter[i] = 0;
597
598                 __rstn_set_noti_state(STC_RSTN_STATE_UNSET);
599
600                 if (STC_DEBUG_LOG) {
601                         STC_LOGD("Restriction deactivated "
602                                 "[\033[1;36m%d\033[0;m:\033[1;35m%d\033[0;m]",
603                                 rstn_data->classid, rstn_data->restriction_id);
604                 }
605         }
606         break;
607         default:
608                 break;
609         }
610 }
611
612 static void __rstn_add(gpointer data, gpointer user_data)
613 {
614         stc_rstn_data_s *rstn_data = (stc_rstn_data_s *)data;
615
616         /* rstn rule is activated */
617         if (rstn_data->rstn_state == STC_RSTN_STATE_ACTIVATED) {
618                 if (STC_DEBUG_LOG) {
619                         STC_LOGD("Restriction already activated "
620                                 "[\033[1;36m%d\033[0;m:\033[1;35m%d\033[0;m]",
621                                 rstn_data->classid, rstn_data->restriction_id);
622                 }
623                 return;
624         }
625
626         if (rstn_data->rstn_type == STC_RSTN_TYPE_ACCEPT) {
627                 __rstn_process(RST_EXCLUDE,
628                         rstn_data->app_id, rstn_data, user_data);
629                 __rstn_tethering_process(RST_EXCLUDE,
630                         rstn_data->app_id, rstn_data, user_data);
631         } else {
632                 __rstn_process(RST_SET,
633                         rstn_data->app_id, rstn_data, user_data);
634                 __rstn_tethering_process(RST_SET,
635                         rstn_data->app_id, rstn_data, user_data);
636         }
637
638         if (STC_DEBUG_LOG) {
639                 __print_rstn(rstn_data);
640                 STC_LOGD("\033[1;32mRestriction added\033[0;m "
641                         "[\033[1;36m%d\033[0;m:\033[1;35m%d\033[0;m]",
642                         rstn_data->classid, rstn_data->restriction_id);
643         }
644 }
645
646 static void __rstn_add_by_connection(gpointer key,
647                                         gpointer value, gpointer data)
648 {
649         stc_rstn_value_s *rstn_value = (stc_rstn_value_s *)value;
650
651         g_slist_foreach(rstn_value->rules, __rstn_add, data);
652 }
653
654 static void __rstn_remove(gpointer data, gpointer user_data)
655 {
656         stc_rstn_data_s *rstn_data = (stc_rstn_data_s *)data;
657
658         if (rstn_data->rstn_state == STC_RSTN_STATE_DEACTIVATED) {
659                 STC_LOGD("\033[1;31mRestriction already deactivated\033[0;m "
660                         "[\033[1;36m%d\033[0;m:\033[1;35m%d\033[0;m]",
661                         rstn_data->classid, rstn_data->restriction_id);
662                 return;
663         }
664
665         __rstn_process(RST_UNSET,
666                 rstn_data->app_id, rstn_data, user_data);
667         __rstn_tethering_process(RST_UNSET,
668                 rstn_data->app_id, rstn_data, user_data);
669
670         if (STC_DEBUG_LOG) {
671                 __print_rstn(rstn_data);
672                 STC_LOGD("\033[1;31mRestriction removed\033[0;m "
673                         "[\033[1;36m%d\033[0;m:\033[1;35m%d\033[0;m]",
674                         rstn_data->classid, rstn_data->restriction_id);
675         }
676 }
677
678 static void __rstn_remove_by_connection(gpointer key,
679                                         gpointer value, gpointer data)
680 {
681         stc_rstn_value_s *rstn_value = (stc_rstn_value_s *)value;
682
683         g_slist_foreach(rstn_value->rules, __rstn_remove, data);
684 }
685
686 static void __rstn_update_counter_data(gpointer data,
687                                                 gpointer user_data)
688 {
689         stc_rstn_data_s *rstn_data = (stc_rstn_data_s *)data;
690
691         table_counters_info info = {
692                 .restriction_id = rstn_data->restriction_id,
693                 .data_counter = rstn_data->counter[STC_RSTN_LIMIT_TYPE_DATA],
694                 .warn_counter = rstn_data->counter[STC_RSTN_LIMIT_TYPE_DATA_WARN],
695                 .monthly_counter = rstn_data->counter[STC_RSTN_LIMIT_TYPE_MONTHLY],
696                 .weekly_counter = rstn_data->counter[STC_RSTN_LIMIT_TYPE_WEEKLY],
697                 .daily_counter = rstn_data->counter[STC_RSTN_LIMIT_TYPE_DAILY]
698         };
699
700         table_counters_update_counters(&info);
701 }
702
703 static void __rstn_update_counter_value(gpointer key,
704                                                 gpointer value, gpointer data)
705 {
706         stc_rstn_value_s *rstn_value = (stc_rstn_value_s *)value;
707
708         g_slist_foreach(rstn_value->rules, __rstn_update_counter_data, NULL);
709 }
710
711 static void __rstn_data_destroy(gpointer data)
712 {
713         stc_rstn_data_s *rstn_data = (stc_rstn_data_s *)data;
714
715         FREE(rstn_data->app_id);
716         FREE(rstn_data->ifname);
717         FREE(rstn_data->subscriber_id);
718         FREE(rstn_data->mac);
719
720         FREE(rstn_data);
721 }
722
723 static gint __rstn_data_comp(gconstpointer a, gconstpointer b)
724 {
725         stc_rstn_data_s *da = (stc_rstn_data_s *)a;
726         stc_rstn_data_s *db = (stc_rstn_data_s *)b;
727
728         if ((da->iftype == db->iftype) &&
729                 (g_strcmp0(da->ifname, db->ifname) == 0) &&
730                 (g_strcmp0(da->subscriber_id, db->subscriber_id) == 0) &&
731                 (da->roaming == db->roaming))
732                 return 0;
733
734         return -1;
735 }
736
737 static stc_error_e __rstn_data_remove(stc_rstn_data_s *data)
738 {
739         stc_rstn_value_s *lookup_value;
740         GSList *lookup_list;
741         stc_rstn_data_s *lookup_data;
742         GHashTable *rstns = stc_monitor_get_system_rstns();
743
744         if (!rstns)
745                 return STC_ERROR_NO_DATA;
746
747         lookup_value = g_hash_table_lookup(rstns, GUINT_TO_POINTER(data->classid));
748         if (!lookup_value) {
749                 if (STC_DEBUG_LOG)
750                         STC_LOGE("Restriction not found [\033[1;36m%d\033[0;m]",
751                                                 data->classid);
752                 return STC_ERROR_NO_DATA;
753         }
754
755         lookup_list = g_slist_find_custom(lookup_value->rules,
756                                         data, __rstn_data_comp);
757         if (!lookup_list) {
758                 if (STC_DEBUG_LOG)
759                         STC_LOGE("Restriction not found [%d:%s:%s:%d]",
760                                 data->iftype, data->ifname,
761                                 data->subscriber_id, data->roaming);
762                 return STC_ERROR_NO_DATA;
763         }
764
765         lookup_data = lookup_list->data;
766
767         /* remove counter also */
768         table_counters_delete(lookup_data->restriction_id);
769         __rstn_remove(lookup_data, NULL);
770
771         lookup_value->rules = g_slist_remove(lookup_value->rules,
772                                                         lookup_data);
773         __rstn_data_destroy(lookup_data);
774
775         if (!lookup_value->rules)
776                 g_hash_table_remove(rstns, GUINT_TO_POINTER(data->classid));
777
778         return STC_ERROR_NONE;
779 }
780
781 static stc_error_e __rstn_data_add(stc_rstn_data_s *data)
782 {
783         int i;
784         stc_rstn_value_s *lookup_value;
785         stc_rstn_value_s *rstn_value;
786         stc_rstn_data_s *rstn_data;
787         GHashTable *rstns = stc_monitor_get_system_rstns();
788
789         if (!rstns)
790                 return STC_ERROR_NO_DATA;
791
792         rstn_data = MALLOC0(stc_rstn_data_s, 1);
793         if (!rstn_data) {
794                 if (STC_DEBUG_LOG)
795                         STC_LOGE("Rstn_data allocation failed");
796                 return STC_ERROR_OUT_OF_MEMORY;
797         }
798
799         lookup_value = g_hash_table_lookup(rstns, GUINT_TO_POINTER(data->classid));
800         if (!lookup_value) {
801                 rstn_value = MALLOC0(stc_rstn_value_s, 1);
802                 if (!rstn_value) {
803                         if (STC_DEBUG_LOG)
804                                 STC_LOGE("Rstn_value allocation failed");
805                         FREE(rstn_data);
806                         return STC_ERROR_OUT_OF_MEMORY;
807                 }
808
809                 g_hash_table_insert(rstns, GUINT_TO_POINTER(data->classid),
810                         rstn_value);
811         } else {
812                 rstn_value = lookup_value;
813         }
814
815         rstn_data->classid = data->classid;
816         rstn_data->app_id = g_strdup(data->app_id);
817         rstn_data->iftype = data->iftype;
818         rstn_data->ifname = g_strdup(data->ifname);
819         rstn_data->subscriber_id = g_strdup(data->subscriber_id);
820         rstn_data->roaming = data->roaming;
821         rstn_data->mac = g_strdup(data->mac);
822
823         rstn_data->restriction_id = data->restriction_id;
824         rstn_data->rstn_state = data->rstn_state;
825         rstn_data->rstn_type = data->rstn_type;
826
827         for (i = 0; i < STC_RSTN_LIMIT_TYPE_MAX; i++) {
828                 rstn_data->limit[i] = data->limit[i];
829                 rstn_data->counter[i] = 0;
830         }
831
832         rstn_data->limit_exceeded = 0;
833         rstn_data->limit_notified = 0;
834         rstn_data->month_start_date = data->month_start_date;
835         rstn_data->month_start_ts = data->month_start_ts;
836
837         __rstn_data_remove(rstn_data);
838         rstn_value->rules = g_slist_append(rstn_value->rules, rstn_data);
839
840         __rstn_add(rstn_data, NULL);
841
842         return STC_ERROR_NONE;
843 }
844
845 static void __rstn_value_destroy(gpointer data)
846 {
847         stc_rstn_value_s *rstn_value = (stc_rstn_value_s *)data;
848
849         g_slist_free_full(rstn_value->rules, __rstn_data_destroy);
850
851         FREE(rstn_value);
852 }
853
854 static stc_cb_ret_e __rstn_insert_cb(const table_restrictions_info *info,
855                                             void *user_data)
856 {
857         stc_cb_ret_e ret = STC_CONTINUE;
858         stc_rstn_data_s data;
859
860         memset(&data, 0, sizeof(stc_rstn_data_s));
861
862         if (info->app_id) {
863                 data.classid = get_classid_by_app_id(info->app_id, TRUE);
864                 data.app_id = info->app_id;
865         } else
866                 data.classid = STC_UNKNOWN_CLASSID;
867
868         data.iftype = info->iftype;
869         data.ifname = info->ifname;
870         data.subscriber_id = info->subscriber_id;
871         data.roaming = info->roaming;
872
873         data.rstn_type = info->rstn_type;
874         data.rstn_state = STC_RSTN_STATE_UNKNOWN;
875         data.restriction_id = info->restriction_id;
876
877         data.limit[STC_RSTN_LIMIT_TYPE_DATA] = info->data_limit;
878         data.limit[STC_RSTN_LIMIT_TYPE_DATA_WARN] = info->data_warn_limit;
879         data.limit[STC_RSTN_LIMIT_TYPE_MONTHLY] = info->monthly_limit;
880         data.limit[STC_RSTN_LIMIT_TYPE_WEEKLY] = info->weekly_limit;
881         data.limit[STC_RSTN_LIMIT_TYPE_DAILY] = info->daily_limit;
882
883         if (__rstn_data_add(&data) != STC_ERROR_NONE)
884                 ret = STC_CANCEL;
885
886         return ret;
887 }
888
889 static void __rstn_update_counter(classid_bytes_context_s *context,
890                                 uint32_t classid)
891 {
892         stc_rstn_value_s *lookup;
893         GHashTable *rstns = stc_monitor_get_system_rstns();
894
895         if (!rstns)
896                 return;
897
898         lookup = g_hash_table_lookup(rstns, GUINT_TO_POINTER(classid));
899         if (lookup) {
900                 context->counter->classid = classid;
901                 g_slist_foreach(lookup->rules,
902                         stc_monitor_rstn_update_counter,
903                         context);
904         }
905 }
906
907 static void __rstn_action_when_limit_exceeded_tethering(stc_rstn_data_s *rstn_data,
908                                         classid_bytes_context_s *context)
909 {
910         char *mac_str = NULL;
911         struct nfacct_rule *counter = context->counter;
912
913         /* get the station mac based on classid */
914         stc_plugin_tether_get_station_by_classid(counter->classid, &mac_str);
915         if (!mac_str) {
916                 STC_LOGE("Station not found for classid(%d)", counter->classid);
917                 return;
918         }
919
920         STC_LOGI("Station mac[%s] classid[%u] iftype[%u] iotype[%d] "
921                         "intend[%d] ifname[%s] bytes[%lld]", mac_str,
922                         counter->classid, counter->iftype, counter->iotype,
923                         counter->intend, counter->ifname, context->bytes);
924
925         /* Block tethering station immediately */
926         counter->intend = NFACCT_TETH_BLOCK;
927         __rstn_del_tether_rule(counter->classid, mac_str,
928                         NFACCT_TETH_BLOCK, rstn_data->iftype);
929
930         __rstn_add_tether_rule(counter->classid, mac_str,
931                         NFACCT_TETH_BLOCK, rstn_data->iftype);
932         counter->intend = NFACCT_TETH_COUNTER;
933
934         g_free(mac_str);
935 }
936
937 static void __reset_time_counter_foreach_rstn_data(gpointer data,
938                                                   gpointer user_data)
939 {
940         stc_rstn_data_s *rstn_data = (stc_rstn_data_s *)data;
941         reset_time_limits_context_s *context =
942                 (reset_time_limits_context_s *)user_data;
943         int i;
944         time_t now_month_start_ts;
945
946         if (rstn_data->month_start_date == 0) {
947                 table_counters_info info;
948                 memset(&info, 0, sizeof(table_counters_info));
949                 table_counters_get_timestamps(rstn_data->restriction_id, &info);
950
951                 if (info.month_start_date == 0)
952                         rstn_data->month_start_date = 1;
953                 else
954                         rstn_data->month_start_date = info.month_start_date;
955                 rstn_data->month_start_ts = info.month_start_ts;
956         }
957
958         now_month_start_ts =
959                 stc_time_get_month_start(context->now,
960                                          rstn_data->month_start_date);
961
962         if (rstn_data->month_start_ts != now_month_start_ts) {
963                 rstn_data->month_start_ts = now_month_start_ts;
964                 context->month_start_ts = now_month_start_ts;
965                 context->is_updated |= (1 << STC_RSTN_LIMIT_TYPE_MONTHLY);
966         }
967
968         if (context->is_updated) {
969                 table_counters_info info;
970                 memset(&info, 0, sizeof(table_counters_info));
971
972                 info.restriction_id = rstn_data->restriction_id;
973                 info.month_start_date = rstn_data->month_start_date;
974                 info.month_start_ts = rstn_data->month_start_ts;
975                 info.week_start_ts = context->week_start_ts;
976                 info.day_start_ts = context->day_start_ts;
977
978                 table_counters_update_timestamps(&info);
979         }
980
981         for (i = STC_RSTN_LIMIT_TYPE_MONTHLY; i < STC_RSTN_LIMIT_TYPE_MAX; i++) {
982
983                 if ((context->is_updated) & (1 << i)) {
984                         /* reset limit */
985                         rstn_data->counter[i] = 0;
986
987                         if (rstn_data->limit_exceeded & (1 << i)) {
988                                 /* remove iptables rule */
989                                 char *default_ifname = stc_default_connection_get_ifname();
990                                 struct nfacct_rule counter;
991                                 stc_s *stc = stc_get_manager();
992                                 if (stc == NULL) {
993                                         STC_LOGE("Can't get stc data");
994                                         g_free(default_ifname);
995                                         goto try_next_callback;
996                                 }
997
998                                 if (!stc->carg) {
999                                         stc->carg = MALLOC0(counter_arg_s, 1);
1000                                         if (stc->carg == NULL) {
1001                                                 g_free(default_ifname);
1002                                                 goto try_next_callback;
1003                                         }
1004
1005                                         stc->carg->sock = stc_monitor_get_contr_sock();
1006                                 }
1007
1008                                 memset(&counter, 0, sizeof(struct nfacct_rule));
1009
1010                                 counter.carg = stc->carg;
1011                                 counter.classid = rstn_data->classid;
1012                                 counter.intend = NFACCT_BLOCK;
1013                                 counter.iftype = rstn_data->iftype;
1014                                 g_strlcpy(counter.ifname, default_ifname,
1015                                           MAX_IFACE_LENGTH);
1016
1017                                 g_free(default_ifname);
1018
1019                                 /* iptables rule */
1020                                 stc_monitor_ipt_del_in(&counter);
1021                                 stc_monitor_ipt_del_out(&counter);
1022
1023                                 /* ip6tables rule */
1024                                 stc_monitor_ip6t_del_in(&counter);
1025                                 stc_monitor_ip6t_del_out(&counter);
1026
1027                                 rstn_data->rstn_state = STC_RSTN_STATE_DEACTIVATED;
1028                                 rstn_data->limit_exceeded &= ~(1 << i);
1029                                 rstn_data->limit_notified &= ~(1 << i);
1030                         }
1031                 }
1032         }
1033
1034 try_next_callback:
1035         return;
1036 }
1037
1038 static void __reset_time_counter_foreach_rstn_value(gpointer key,
1039                                                   gpointer value,
1040                                                   gpointer data)
1041 {
1042         stc_rstn_value_s *rstn_value = (stc_rstn_value_s *)value;
1043         g_slist_foreach(rstn_value->rules,
1044                 __reset_time_counter_foreach_rstn_data, data);
1045 }
1046
1047 void stc_monitor_rstn_reset_time_counters_if_required(void)
1048 {
1049         reset_time_limits_context_s context;
1050         GHashTable *rstns = stc_monitor_get_system_rstns();
1051         time_t last_week_ts = stc_monitor_get_last_week_ts();
1052         time_t last_day_ts = stc_monitor_get_last_day_ts();
1053
1054         context.now = time(NULL);
1055         context.week_start_ts = stc_time_get_week_start(context.now);
1056         context.day_start_ts = stc_time_get_day_start(context.now);
1057         context.is_updated = 0;
1058
1059         if (last_week_ts != context.week_start_ts) {
1060                 stc_monitor_set_last_week_ts(context.week_start_ts);
1061                 context.is_updated |= (1 << STC_RSTN_LIMIT_TYPE_WEEKLY);
1062         }
1063
1064         if (last_day_ts != context.day_start_ts) {
1065                 stc_monitor_set_last_day_ts(context.day_start_ts);
1066                 context.is_updated |= (1 << STC_RSTN_LIMIT_TYPE_DAILY);
1067         }
1068
1069         if (rstns) {
1070                 g_hash_table_foreach(rstns,
1071                                __reset_time_counter_foreach_rstn_value,
1072                                &context);
1073
1074                 if (context.is_updated)
1075                         STC_LOGD("Counter reset completed month_start[%ld] "
1076                                 "week_start[%ld] day_start[%ld]",
1077                                 context.month_start_ts, last_week_ts, last_day_ts);
1078         }
1079 }
1080
1081 void stc_monitor_rstn_update_counter(gpointer data,
1082                                         gpointer user_data)
1083 {
1084         int i;
1085         stc_rstn_data_s *rstn_data = (stc_rstn_data_s *)data;
1086         classid_bytes_context_s *context = (classid_bytes_context_s *)user_data;
1087         default_connection_s *default_connection = stc_get_default_connection();
1088
1089         if (rstn_data->iftype != context->counter->iftype)
1090                 return;
1091
1092         if (rstn_data->ifname != NULL &&
1093                 g_strcmp0(rstn_data->ifname, "") &&
1094                 g_strcmp0(rstn_data->ifname, context->counter->ifname) != 0)
1095                 return;
1096
1097         if (rstn_data->subscriber_id != NULL &&
1098                 g_strcmp0(rstn_data->subscriber_id, "") &&
1099                 g_strcmp0(rstn_data->subscriber_id, default_connection->subscriber_id) != 0)
1100                 return;
1101
1102         if (rstn_data->roaming != default_connection->roaming)
1103                 return;
1104
1105         if (rstn_data->limit_exceeded != 0) {
1106                 context->data_limit_exceeded = TRUE;
1107                 return;
1108         }
1109
1110         switch (context->counter->iotype) {
1111         case NFACCT_COUNTER_IN:
1112         case NFACCT_COUNTER_OUT:
1113                 if ((rstn_data->counter[STC_RSTN_LIMIT_TYPE_DATA] == 0 &&
1114                         rstn_data->limit[STC_RSTN_LIMIT_TYPE_DATA] >= 0) ||
1115                         (rstn_data->counter[STC_RSTN_LIMIT_TYPE_DATA_WARN] == 0 &&
1116                         rstn_data->limit[STC_RSTN_LIMIT_TYPE_DATA_WARN] >= 0) ||
1117                         (rstn_data->counter[STC_RSTN_LIMIT_TYPE_MONTHLY] == 0 &&
1118                         rstn_data->limit[STC_RSTN_LIMIT_TYPE_MONTHLY] >= 0) ||
1119                         (rstn_data->counter[STC_RSTN_LIMIT_TYPE_WEEKLY] == 0 &&
1120                         rstn_data->limit[STC_RSTN_LIMIT_TYPE_WEEKLY] >= 0) ||
1121                         (rstn_data->counter[STC_RSTN_LIMIT_TYPE_DAILY] == 0 &&
1122                         rstn_data->limit[STC_RSTN_LIMIT_TYPE_DAILY] >= 0)) {
1123                         table_counters_info info;
1124                         memset(&info, 0, sizeof(table_counters_info));
1125                         table_counters_get(rstn_data->restriction_id, &info);
1126
1127                         rstn_data->counter[STC_RSTN_LIMIT_TYPE_DATA] = info.data_counter;
1128                         rstn_data->counter[STC_RSTN_LIMIT_TYPE_DATA_WARN] = info.warn_counter;
1129                         rstn_data->counter[STC_RSTN_LIMIT_TYPE_MONTHLY] = info.monthly_counter;
1130                         rstn_data->counter[STC_RSTN_LIMIT_TYPE_WEEKLY] = info.weekly_counter;
1131                         rstn_data->counter[STC_RSTN_LIMIT_TYPE_DAILY] = info.daily_counter;
1132                 }
1133
1134                 for (i = 0; i < STC_RSTN_LIMIT_TYPE_MAX; i++) {
1135                         if (rstn_data->limit[i] >= 0 &&
1136                                 !(rstn_data->limit_notified & (1 << i))) {
1137                                 rstn_data->counter[i] += context->bytes;
1138                                 if (rstn_data->limit[i] <= rstn_data->counter[i])
1139                                         stc_monitor_rstn_action_when_limit_exceeded(i,
1140                                                                                 rstn_data,
1141                                                                                 context);
1142                         }
1143                 }
1144
1145                 stc_monitor_set_rstns_updated(TRUE);
1146                 __print_rstn(rstn_data);
1147                 break;
1148         default:
1149                 STC_LOGE("Unknown iotype");
1150         }
1151 }
1152
1153 void stc_monitor_rstn_update_iface_counter(classid_bytes_context_s *context)
1154 {
1155         switch (context->counter->iftype) {
1156         case STC_IFACE_DATACALL:
1157                 __rstn_update_counter(context, STC_TOTAL_DATACALL_CLASSID);
1158                 break;
1159         case STC_IFACE_WIFI:
1160                 __rstn_update_counter(context, STC_TOTAL_WIFI_CLASSID);
1161                 __rstn_update_counter(context, STC_TETHERING_APP_CLASSID);
1162                 break;
1163         case STC_IFACE_BLUETOOTH:
1164                 __rstn_update_counter(context, STC_TOTAL_BLUETOOTH_CLASSID);
1165                 __rstn_update_counter(context, STC_TETHERING_APP_CLASSID);
1166                 break;
1167         case STC_IFACE_USB:
1168                 __rstn_update_counter(context, STC_TETHERING_APP_CLASSID);
1169                 break;
1170         case STC_IFACE_P2P:
1171                 __rstn_update_counter(context, STC_TETHERING_APP_CLASSID);
1172                 break;
1173         default:
1174                 break;
1175         }
1176 }
1177
1178 void stc_monitor_rstn_action_when_limit_exceeded(stc_rstn_limit_type_e limit_type,
1179                                                 stc_rstn_data_s *rstn_data,
1180                                                 classid_bytes_context_s *context)
1181 {
1182         gboolean rv;
1183         char iftype[MAX_INT_LENGTH] = { 0, };
1184         char byte[MAX_INT_LENGTH] = { 0, };
1185         const char *signal_name = NULL;
1186         const char *net_popup_content = NULL;
1187         const char *net_popup_type = NULL;
1188         stc_s *stc = (stc_s *)stc_get_manager();
1189
1190         if (stc == NULL) {
1191                 STC_LOGE("Failed to get stc data");
1192                 return;
1193         }
1194
1195         switch (limit_type) {
1196         case STC_RSTN_LIMIT_TYPE_DATA_WARN:
1197         {
1198                 signal_name = "WarnThresholdCrossed";
1199                 net_popup_content = "warn threshold crossed";
1200                 net_popup_type = "warning_noti";
1201         }
1202         break;
1203         case STC_RSTN_LIMIT_TYPE_DATA:
1204         case STC_RSTN_LIMIT_TYPE_MONTHLY:
1205         case STC_RSTN_LIMIT_TYPE_WEEKLY:
1206         case STC_RSTN_LIMIT_TYPE_DAILY:
1207         {
1208                 signal_name = "RestrictionThresholdCrossed";
1209                 net_popup_content = "restriction threshold crossed";
1210                 net_popup_type = "restriction_noti";
1211
1212                 /* Apply restriction for tethering apps if app_id is of tethering client
1213                  * otherwise do the normal iptables rule */
1214                 if (context->counter->intend == NFACCT_TETH_COUNTER) {
1215
1216                         if (g_str_has_suffix(rstn_data->app_id, STC_TETHERING_APP_SUFFIX) &&
1217                                         rstn_data->classid != STC_TETHERING_APP_CLASSID) {
1218                                 __rstn_action_when_limit_exceeded_tethering(rstn_data,
1219                                                 context);
1220                         }
1221
1222                 } else {
1223                         /* block immediately */
1224                         context->counter->intend = NFACCT_BLOCK;
1225                         stc_monitor_ipt_del_in(context->counter);
1226                         stc_monitor_ipt_del_out(context->counter);
1227                         stc_monitor_ipt_add_in(context->counter);
1228                         stc_monitor_ipt_add_out(context->counter);
1229
1230                         stc_monitor_ip6t_del_in(context->counter);
1231                         stc_monitor_ip6t_del_out(context->counter);
1232                         stc_monitor_ip6t_add_in(context->counter);
1233                         stc_monitor_ip6t_add_out(context->counter);
1234                         context->counter->intend = NFACCT_COUNTER;
1235                 }
1236
1237                 rstn_data->limit_exceeded |= (1 << limit_type);
1238                 __rstn_set_noti_state(STC_RSTN_STATE_SET);
1239         }
1240         break;
1241         default:
1242                 break;
1243         }
1244
1245         if (signal_name == NULL) {
1246                 STC_LOGE("Invalid parameter: limit_type");
1247                 return;
1248         }
1249
1250         /* emit signal */
1251         rv = stc_manager_dbus_emit_signal(stc->connection,
1252                                                   STC_DBUS_SERVICE_RESTRICTION_PATH,
1253                                                   STC_DBUS_INTERFACE_RESTRICTION,
1254                                                   signal_name,
1255                                                   g_variant_new("(si)",
1256                                                   rstn_data->app_id,
1257                                                   rstn_data->iftype));
1258
1259         if (rv == TRUE)
1260                 rstn_data->limit_notified |= (1 << limit_type);
1261
1262         snprintf(iftype, MAX_INT_LENGTH, "%d", rstn_data->iftype);
1263         snprintf(byte, MAX_INT_LENGTH, "%lld", rstn_data->limit[limit_type]);
1264         stc_plugin_appstatus_send_message(net_popup_content,
1265                         net_popup_type, rstn_data->app_id, iftype, byte);
1266
1267         if (STC_DEBUG_LOG)
1268                 STC_LOGD("Limit exceeded [\033[0;31m%s\033[0;m:%d]",
1269                                         net_popup_content, limit_type);
1270 }
1271
1272 gboolean stc_monitor_rstn_flush_contr_to_db(gpointer user_data)
1273 {
1274         time_t current_time = 0;
1275         stc_s *stc = stc_get_manager();
1276         GHashTable *rstns = stc_monitor_get_system_rstns();
1277         gboolean rstns_updated = stc_monitor_get_rstns_updated();
1278
1279         if (stc && stc->carg)
1280                 current_time = stc->carg->last_run_time;
1281
1282         if (rstns_updated == FALSE)
1283                 return G_SOURCE_REMOVE;
1284
1285         stc_monitor_set_rstns_updated(FALSE);
1286
1287         if (rstns)
1288                 g_hash_table_foreach(rstns,
1289                                __rstn_update_counter_value,
1290                                &current_time);
1291
1292         STC_LOGI("Flushed rstns counters to database");
1293         return G_SOURCE_REMOVE;
1294 }
1295
1296 stc_error_e stc_monitor_rstn_add(const table_restrictions_info *info)
1297 {
1298         stc_rstn_data_s data;
1299
1300         memset(&data, 0, sizeof(stc_rstn_data_s));
1301
1302         if (info->app_id) {
1303                 data.classid = get_classid_by_app_id(info->app_id, TRUE);
1304                 data.app_id = info->app_id;
1305         } else
1306                 data.classid = STC_UNKNOWN_CLASSID;
1307
1308         if (data.classid == STC_BACKGROUND_APP_CLASSID) {
1309                 stc_monitor_set_background_state(TRUE);
1310                 __vconf_set_int(VCONFKEY_STC_BACKGROUND_STATE, TRUE);
1311         }
1312
1313         data.iftype = info->iftype;
1314         data.ifname = info->ifname;
1315         data.subscriber_id = info->subscriber_id;
1316         data.roaming = info->roaming;
1317         data.mac = info->mac;
1318
1319         data.rstn_type = info->rstn_type;
1320         data.rstn_state = STC_RSTN_STATE_UNKNOWN;
1321         data.restriction_id = info->restriction_id;
1322
1323         data.limit[STC_RSTN_LIMIT_TYPE_DATA] = info->data_limit;
1324         data.limit[STC_RSTN_LIMIT_TYPE_DATA_WARN] = info->data_warn_limit;
1325         data.limit[STC_RSTN_LIMIT_TYPE_MONTHLY] = info->monthly_limit;
1326         data.limit[STC_RSTN_LIMIT_TYPE_WEEKLY] = info->weekly_limit;
1327         data.limit[STC_RSTN_LIMIT_TYPE_DAILY] = info->daily_limit;
1328         data.month_start_date = info->month_start_date;
1329         data.month_start_ts = stc_time_get_month_start(time(NULL),
1330                                                                                 info->month_start_date);
1331
1332         return __rstn_data_add(&data);
1333 }
1334
1335 void stc_monitor_rstn_add_for_app(uint32_t classid)
1336 {
1337         stc_rstn_value_s *lookup_value;
1338         GHashTable *rstns = stc_monitor_get_system_rstns();
1339
1340         if (!rstns)
1341                 return;
1342
1343         lookup_value = g_hash_table_lookup(rstns, GUINT_TO_POINTER(classid));
1344         if (!lookup_value) {
1345                 if (STC_DEBUG_LOG)
1346                         STC_LOGD("Restriction not found [\033[1;36m%d\033[0;m]",
1347                                                 classid);
1348                 return;
1349         }
1350
1351         g_slist_foreach(lookup_value->rules, __rstn_add, NULL);
1352 }
1353
1354 void stc_monitor_rstn_add_by_connection(default_connection_s *conn)
1355 {
1356         GHashTable *rstns = stc_monitor_get_system_rstns();
1357
1358         if (!rstns)
1359                 return;
1360
1361         g_hash_table_foreach(rstns, __rstn_add_by_connection, conn);
1362 }
1363
1364 stc_error_e stc_monitor_rstn_remove(const table_restrictions_info *info)
1365 {
1366         stc_rstn_data_s data;
1367
1368         memset(&data, 0, sizeof(stc_rstn_data_s));
1369
1370         data.classid = get_classid_by_app_id(info->app_id, TRUE);
1371         data.app_id = info->app_id;
1372
1373         data.iftype = info->iftype;
1374         data.ifname = info->ifname;
1375         data.subscriber_id = info->subscriber_id;
1376         data.roaming = info->roaming;
1377
1378         if (g_strcmp0(info->app_id, STC_TOTAL_BACKGROUND) == 0) {
1379                 stc_monitor_set_background_state(FALSE);
1380                 __vconf_set_int(VCONFKEY_STC_BACKGROUND_STATE, FALSE);
1381         }
1382
1383         return __rstn_data_remove(&data);
1384 }
1385
1386 void stc_monitor_rstn_remove_for_app(uint32_t classid)
1387 {
1388         stc_rstn_value_s *lookup_value;
1389         GHashTable *rstns = stc_monitor_get_system_rstns();
1390
1391         if (!rstns)
1392                 return;
1393
1394         lookup_value = g_hash_table_lookup(rstns, GUINT_TO_POINTER(classid));
1395         if (!lookup_value) {
1396                 if (STC_DEBUG_LOG)
1397                         STC_LOGD("Restriction not found [\033[1;36m%d\033[0;m]",
1398                                                 classid);
1399                 return;
1400         }
1401
1402         g_slist_foreach(lookup_value->rules, __rstn_remove, NULL);
1403 }
1404
1405 void stc_monitor_rstn_remove_by_connection(default_connection_s *conn)
1406 {
1407         GHashTable *rstns = stc_monitor_get_system_rstns();
1408
1409         if (!rstns)
1410                 return;
1411
1412         g_hash_table_foreach(rstns, __rstn_remove_by_connection, conn);
1413 }
1414
1415 void stc_monitor_rstns_load(void)
1416 {
1417         table_restrictions_foreach(__rstn_insert_cb, NULL);
1418
1419         /* __rstn_tree_printall(); */
1420 }
1421
1422 GHashTable *stc_monitor_rstns_init(void)
1423 {
1424         return g_hash_table_new_full(g_direct_hash, g_direct_equal,
1425                                         NULL, __rstn_value_destroy);
1426 }