1bd67040cae9208d86b4323683fea896325e43b2
[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                 rstn_data->rstn_state = STC_RSTN_STATE_ACTIVATED;
554
555                 if (STC_DEBUG_LOG) {
556                         STC_LOGD("Restriction activated "
557                                 "[\033[1;36m%d\033[0;m:\033[1;35m%d\033[0;m]",
558                                 rstn_data->classid, rstn_data->restriction_id);
559                 }
560         }
561         break;
562         case RST_EXCLUDE:
563                 __rstn_add_ipt_rule(rstn_data->classid, NFACCT_ALLOW,
564                                     rstn_data->iftype);
565
566                 rstn_data->rstn_state = STC_RSTN_STATE_ACTIVATED;
567                 rstn_data->limit_exceeded = 0;
568                 rstn_data->limit_notified = 0;
569
570                 if (STC_DEBUG_LOG) {
571                         STC_LOGD("Restriction activated "
572                                 "[\033[1;36m%d\033[0;m:\033[1;35m%d\033[0;m]",
573                                 rstn_data->classid, rstn_data->restriction_id);
574                 }
575                 break;
576         case RST_UNSET:
577         {
578                 int i;
579
580                 if (rstn_data->classid == STC_TETHERING_APP_CLASSID)
581                         __rstn_del_ipt_rule(rstn_data->classid, NFACCT_BLOCK,
582                                             rstn_data->iftype);
583                 else
584                         __rstn_del_ipt_rule(rstn_data->classid, rstn_data->rstn_type,
585                                             rstn_data->iftype);
586
587                 rstn_data->rstn_state = STC_RSTN_STATE_DEACTIVATED;
588                 rstn_data->limit_exceeded = 0;
589                 rstn_data->limit_notified = 0;
590
591                 for (i = 0; i < STC_RSTN_LIMIT_TYPE_MAX; i++)
592                         if (rstn_data->limit[i] >= 0)
593                                 rstn_data->counter[i] = 0;
594
595                 __rstn_set_noti_state(STC_RSTN_STATE_UNSET);
596
597                 if (STC_DEBUG_LOG) {
598                         STC_LOGD("Restriction deactivated "
599                                 "[\033[1;36m%d\033[0;m:\033[1;35m%d\033[0;m]",
600                                 rstn_data->classid, rstn_data->restriction_id);
601                 }
602         }
603         break;
604         default:
605                 break;
606         }
607 }
608
609 static void __rstn_add(gpointer data, gpointer user_data)
610 {
611         stc_rstn_data_s *rstn_data = (stc_rstn_data_s *)data;
612
613         /* rstn rule is activated */
614         if (rstn_data->rstn_state == STC_RSTN_STATE_ACTIVATED) {
615                 if (STC_DEBUG_LOG) {
616                         STC_LOGD("Restriction already activated "
617                                 "[\033[1;36m%d\033[0;m:\033[1;35m%d\033[0;m]",
618                                 rstn_data->classid, rstn_data->restriction_id);
619                 }
620                 return;
621         }
622
623         if (rstn_data->rstn_type == STC_RSTN_TYPE_ACCEPT) {
624                 __rstn_process(RST_EXCLUDE,
625                         rstn_data->app_id, rstn_data, user_data);
626                 __rstn_tethering_process(RST_EXCLUDE,
627                         rstn_data->app_id, rstn_data, user_data);
628         } else {
629                 __rstn_process(RST_SET,
630                         rstn_data->app_id, rstn_data, user_data);
631                 __rstn_tethering_process(RST_SET,
632                         rstn_data->app_id, rstn_data, user_data);
633         }
634
635         if (STC_DEBUG_LOG) {
636                 __print_rstn(rstn_data);
637                 STC_LOGD("\033[1;32mRestriction added\033[0;m "
638                         "[\033[1;36m%d\033[0;m:\033[1;35m%d\033[0;m]",
639                         rstn_data->classid, rstn_data->restriction_id);
640         }
641 }
642
643 static void __rstn_add_by_connection(gpointer key,
644                                         gpointer value, gpointer data)
645 {
646         stc_rstn_value_s *rstn_value = (stc_rstn_value_s *)value;
647
648         g_slist_foreach(rstn_value->rules, __rstn_add, data);
649 }
650
651 static void __rstn_remove(gpointer data, gpointer user_data)
652 {
653         stc_rstn_data_s *rstn_data = (stc_rstn_data_s *)data;
654
655         if (rstn_data->rstn_state == STC_RSTN_STATE_DEACTIVATED) {
656                 STC_LOGD("\033[1;31mRestriction already deactivated\033[0;m "
657                         "[\033[1;36m%d\033[0;m:\033[1;35m%d\033[0;m]",
658                         rstn_data->classid, rstn_data->restriction_id);
659                 return;
660         }
661
662         __rstn_process(RST_UNSET,
663                 rstn_data->app_id, rstn_data, user_data);
664         __rstn_tethering_process(RST_UNSET,
665                 rstn_data->app_id, rstn_data, user_data);
666
667         if (STC_DEBUG_LOG) {
668                 __print_rstn(rstn_data);
669                 STC_LOGD("\033[1;31mRestriction removed\033[0;m "
670                         "[\033[1;36m%d\033[0;m:\033[1;35m%d\033[0;m]",
671                         rstn_data->classid, rstn_data->restriction_id);
672         }
673 }
674
675 static void __rstn_remove_by_connection(gpointer key,
676                                         gpointer value, gpointer data)
677 {
678         stc_rstn_value_s *rstn_value = (stc_rstn_value_s *)value;
679
680         g_slist_foreach(rstn_value->rules, __rstn_remove, data);
681 }
682
683 static void __rstn_update_counter_data(gpointer data,
684                                                 gpointer user_data)
685 {
686         stc_rstn_data_s *rstn_data = (stc_rstn_data_s *)data;
687
688         table_counters_info info = {
689                 .restriction_id = rstn_data->restriction_id,
690                 .data_counter = rstn_data->counter[STC_RSTN_LIMIT_TYPE_DATA],
691                 .warn_counter = rstn_data->counter[STC_RSTN_LIMIT_TYPE_DATA_WARN],
692                 .monthly_counter = rstn_data->counter[STC_RSTN_LIMIT_TYPE_MONTHLY],
693                 .weekly_counter = rstn_data->counter[STC_RSTN_LIMIT_TYPE_WEEKLY],
694                 .daily_counter = rstn_data->counter[STC_RSTN_LIMIT_TYPE_DAILY]
695         };
696
697         table_counters_update_counters(&info);
698 }
699
700 static void __rstn_update_counter_value(gpointer key,
701                                                 gpointer value, gpointer data)
702 {
703         stc_rstn_value_s *rstn_value = (stc_rstn_value_s *)value;
704
705         g_slist_foreach(rstn_value->rules, __rstn_update_counter_data, NULL);
706 }
707
708 static void __rstn_data_destroy(gpointer data)
709 {
710         stc_rstn_data_s *rstn_data = (stc_rstn_data_s *)data;
711
712         FREE(rstn_data->app_id);
713         FREE(rstn_data->ifname);
714         FREE(rstn_data->subscriber_id);
715         FREE(rstn_data->mac);
716
717         FREE(rstn_data);
718 }
719
720 static gint __rstn_data_comp(gconstpointer a, gconstpointer b)
721 {
722         stc_rstn_data_s *da = (stc_rstn_data_s *)a;
723         stc_rstn_data_s *db = (stc_rstn_data_s *)b;
724
725         if ((da->iftype == db->iftype) &&
726                 (g_strcmp0(da->ifname, db->ifname) == 0) &&
727                 (g_strcmp0(da->subscriber_id, db->subscriber_id) == 0) &&
728                 (da->roaming == db->roaming))
729                 return 0;
730
731         return -1;
732 }
733
734 static stc_error_e __rstn_data_remove(stc_rstn_data_s *data)
735 {
736         stc_rstn_value_s *lookup_value;
737         GSList *lookup_list;
738         stc_rstn_data_s *lookup_data;
739         GHashTable *rstns = stc_monitor_get_system_rstns();
740
741         if (!rstns)
742                 return STC_ERROR_NO_DATA;
743
744         lookup_value = g_hash_table_lookup(rstns, GUINT_TO_POINTER(data->classid));
745         if (!lookup_value) {
746                 if (STC_DEBUG_LOG)
747                         STC_LOGE("Restriction not found [\033[1;36m%d\033[0;m]",
748                                                 data->classid);
749                 return STC_ERROR_NO_DATA;
750         }
751
752         lookup_list = g_slist_find_custom(lookup_value->rules,
753                                         data, __rstn_data_comp);
754         if (!lookup_list) {
755                 if (STC_DEBUG_LOG)
756                         STC_LOGE("Restriction not found [%d:%s:%s:%d]",
757                                 data->iftype, data->ifname,
758                                 data->subscriber_id, data->roaming);
759                 return STC_ERROR_NO_DATA;
760         }
761
762         lookup_data = lookup_list->data;
763
764         /* remove counter also */
765         table_counters_delete(lookup_data->restriction_id);
766         __rstn_remove(lookup_data, NULL);
767
768         lookup_value->rules = g_slist_remove(lookup_value->rules,
769                                                         lookup_data);
770         __rstn_data_destroy(lookup_data);
771
772         if (!lookup_value->rules)
773                 g_hash_table_remove(rstns, GUINT_TO_POINTER(data->classid));
774
775         return STC_ERROR_NONE;
776 }
777
778 static stc_error_e __rstn_data_add(stc_rstn_data_s *data)
779 {
780         int i;
781         stc_rstn_value_s *lookup_value;
782         stc_rstn_value_s *rstn_value;
783         stc_rstn_data_s *rstn_data;
784         GHashTable *rstns = stc_monitor_get_system_rstns();
785
786         if (!rstns)
787                 return STC_ERROR_NO_DATA;
788
789         rstn_data = MALLOC0(stc_rstn_data_s, 1);
790         if (!rstn_data) {
791                 if (STC_DEBUG_LOG)
792                         STC_LOGE("Rstn_data allocation failed");
793                 return STC_ERROR_OUT_OF_MEMORY;
794         }
795
796         lookup_value = g_hash_table_lookup(rstns, GUINT_TO_POINTER(data->classid));
797         if (!lookup_value) {
798                 rstn_value = MALLOC0(stc_rstn_value_s, 1);
799                 if (!rstn_value) {
800                         if (STC_DEBUG_LOG)
801                                 STC_LOGE("Rstn_value allocation failed");
802                         FREE(rstn_data);
803                         return STC_ERROR_OUT_OF_MEMORY;
804                 }
805
806                 g_hash_table_insert(rstns, GUINT_TO_POINTER(data->classid),
807                         rstn_value);
808         } else {
809                 rstn_value = lookup_value;
810         }
811
812         rstn_data->classid = data->classid;
813         rstn_data->app_id = g_strdup(data->app_id);
814         rstn_data->iftype = data->iftype;
815         rstn_data->ifname = g_strdup(data->ifname);
816         rstn_data->subscriber_id = g_strdup(data->subscriber_id);
817         rstn_data->roaming = data->roaming;
818         rstn_data->mac = g_strdup(data->mac);
819
820         rstn_data->restriction_id = data->restriction_id;
821         rstn_data->rstn_state = data->rstn_state;
822         rstn_data->rstn_type = data->rstn_type;
823
824         for (i = 0; i < STC_RSTN_LIMIT_TYPE_MAX; i++) {
825                 rstn_data->limit[i] = data->limit[i];
826                 rstn_data->counter[i] = 0;
827         }
828
829         rstn_data->limit_exceeded = 0;
830         rstn_data->limit_notified = 0;
831         rstn_data->month_start_date = data->month_start_date;
832         rstn_data->month_start_ts = data->month_start_ts;
833
834         __rstn_data_remove(rstn_data);
835         rstn_value->rules = g_slist_append(rstn_value->rules, rstn_data);
836
837         __rstn_add(rstn_data, NULL);
838
839         return STC_ERROR_NONE;
840 }
841
842 static void __rstn_value_destroy(gpointer data)
843 {
844         stc_rstn_value_s *rstn_value = (stc_rstn_value_s *)data;
845
846         g_slist_free_full(rstn_value->rules, __rstn_data_destroy);
847
848         FREE(rstn_value);
849 }
850
851 static stc_cb_ret_e __rstn_insert_cb(const table_restrictions_info *info,
852                                             void *user_data)
853 {
854         stc_cb_ret_e ret = STC_CONTINUE;
855         stc_rstn_data_s data;
856
857         memset(&data, 0, sizeof(stc_rstn_data_s));
858
859         if (info->app_id) {
860                 data.classid = get_classid_by_app_id(info->app_id, TRUE);
861                 data.app_id = info->app_id;
862         } else
863                 data.classid = STC_UNKNOWN_CLASSID;
864
865         data.iftype = info->iftype;
866         data.ifname = info->ifname;
867         data.subscriber_id = info->subscriber_id;
868         data.roaming = info->roaming;
869
870         data.rstn_type = info->rstn_type;
871         data.rstn_state = STC_RSTN_STATE_UNKNOWN;
872         data.restriction_id = info->restriction_id;
873
874         data.limit[STC_RSTN_LIMIT_TYPE_DATA] = info->data_limit;
875         data.limit[STC_RSTN_LIMIT_TYPE_DATA_WARN] = info->data_warn_limit;
876         data.limit[STC_RSTN_LIMIT_TYPE_MONTHLY] = info->monthly_limit;
877         data.limit[STC_RSTN_LIMIT_TYPE_WEEKLY] = info->weekly_limit;
878         data.limit[STC_RSTN_LIMIT_TYPE_DAILY] = info->daily_limit;
879
880         if (__rstn_data_add(&data) != STC_ERROR_NONE)
881                 ret = STC_CANCEL;
882
883         return ret;
884 }
885
886 static void __rstn_update_counter(classid_bytes_context_s *context,
887                                 uint32_t classid)
888 {
889         stc_rstn_value_s *lookup;
890         GHashTable *rstns = stc_monitor_get_system_rstns();
891
892         if (!rstns)
893                 return;
894
895         lookup = g_hash_table_lookup(rstns, GUINT_TO_POINTER(classid));
896         if (lookup) {
897                 context->counter->classid = classid;
898                 g_slist_foreach(lookup->rules,
899                         stc_monitor_rstn_update_counter,
900                         context);
901         }
902 }
903
904 static void __rstn_action_when_limit_exceeded_tethering(stc_rstn_data_s *rstn_data,
905                                         classid_bytes_context_s *context)
906 {
907         char *mac_str = NULL;
908         struct nfacct_rule *counter = context->counter;
909
910         /* get the station mac based on classid */
911         stc_plugin_tether_get_station_by_classid(counter->classid, &mac_str);
912         if (!mac_str) {
913                 STC_LOGE("Station not found for classid(%d)", counter->classid);
914                 return;
915         }
916
917         STC_LOGI("Station mac[%s] classid[%u] iftype[%u] iotype[%d] "
918                         "intend[%d] ifname[%s] bytes[%lld]", mac_str,
919                         counter->classid, counter->iftype, counter->iotype,
920                         counter->intend, counter->ifname, context->bytes);
921
922         /* Block tethering station immediately */
923         counter->intend = NFACCT_TETH_BLOCK;
924         __rstn_del_tether_rule(counter->classid, mac_str,
925                         NFACCT_TETH_BLOCK, rstn_data->iftype);
926
927         __rstn_add_tether_rule(counter->classid, mac_str,
928                         NFACCT_TETH_BLOCK, rstn_data->iftype);
929         counter->intend = NFACCT_TETH_COUNTER;
930
931         g_free(mac_str);
932 }
933
934 static void __reset_time_counter_foreach_rstn_data(gpointer data,
935                                                   gpointer user_data)
936 {
937         stc_rstn_data_s *rstn_data = (stc_rstn_data_s *)data;
938         reset_time_limits_context_s *context =
939                 (reset_time_limits_context_s *)user_data;
940         int i;
941         time_t now_month_start_ts;
942
943         if (rstn_data->month_start_date == 0) {
944                 table_counters_info info;
945                 memset(&info, 0, sizeof(table_counters_info));
946                 table_counters_get_timestamps(rstn_data->restriction_id, &info);
947
948                 if (info.month_start_date == 0)
949                         rstn_data->month_start_date = 1;
950                 else
951                         rstn_data->month_start_date = info.month_start_date;
952                 rstn_data->month_start_ts = info.month_start_ts;
953         }
954
955         now_month_start_ts =
956                 stc_time_get_month_start(context->now,
957                                          rstn_data->month_start_date);
958
959         if (rstn_data->month_start_ts != now_month_start_ts) {
960                 rstn_data->month_start_ts = now_month_start_ts;
961                 context->month_start_ts = now_month_start_ts;
962                 context->is_updated |= (1 << STC_RSTN_LIMIT_TYPE_MONTHLY);
963         }
964
965         if (context->is_updated) {
966                 table_counters_info info;
967                 memset(&info, 0, sizeof(table_counters_info));
968
969                 info.restriction_id = rstn_data->restriction_id;
970                 info.month_start_date = rstn_data->month_start_date;
971                 info.month_start_ts = rstn_data->month_start_ts;
972                 info.week_start_ts = context->week_start_ts;
973                 info.day_start_ts = context->day_start_ts;
974
975                 table_counters_update_timestamps(&info);
976         }
977
978         for (i = STC_RSTN_LIMIT_TYPE_MONTHLY; i < STC_RSTN_LIMIT_TYPE_MAX; i++) {
979
980                 if ((context->is_updated) & (1 << i)) {
981                         /* reset limit */
982                         rstn_data->counter[i] = 0;
983
984                         if (rstn_data->limit_exceeded & (1 << i)) {
985                                 /* remove iptables rule */
986                                 char *default_ifname = stc_default_connection_get_ifname();
987                                 struct nfacct_rule counter;
988                                 stc_s *stc = stc_get_manager();
989                                 if (stc == NULL) {
990                                         STC_LOGE("Can't get stc data");
991                                         g_free(default_ifname);
992                                         goto try_next_callback;
993                                 }
994
995                                 if (!stc->carg) {
996                                         stc->carg = MALLOC0(counter_arg_s, 1);
997                                         if (stc->carg == NULL) {
998                                                 g_free(default_ifname);
999                                                 goto try_next_callback;
1000                                         }
1001
1002                                         stc->carg->sock = stc_monitor_get_contr_sock();
1003                                 }
1004
1005                                 memset(&counter, 0, sizeof(struct nfacct_rule));
1006
1007                                 counter.carg = stc->carg;
1008                                 counter.classid = rstn_data->classid;
1009                                 counter.intend = NFACCT_BLOCK;
1010                                 counter.iftype = rstn_data->iftype;
1011                                 g_strlcpy(counter.ifname, default_ifname,
1012                                           MAX_IFACE_LENGTH);
1013
1014                                 g_free(default_ifname);
1015
1016                                 /* iptables rule */
1017                                 stc_monitor_ipt_del_in(&counter);
1018                                 stc_monitor_ipt_del_out(&counter);
1019
1020                                 /* ip6tables rule */
1021                                 stc_monitor_ip6t_del_in(&counter);
1022                                 stc_monitor_ip6t_del_out(&counter);
1023
1024                                 rstn_data->rstn_state = STC_RSTN_STATE_DEACTIVATED;
1025                                 rstn_data->limit_exceeded &= ~(1 << i);
1026                                 rstn_data->limit_notified &= ~(1 << i);
1027                         }
1028                 }
1029         }
1030
1031 try_next_callback:
1032         return;
1033 }
1034
1035 static void __reset_time_counter_foreach_rstn_value(gpointer key,
1036                                                   gpointer value,
1037                                                   gpointer data)
1038 {
1039         stc_rstn_value_s *rstn_value = (stc_rstn_value_s *)value;
1040         g_slist_foreach(rstn_value->rules,
1041                 __reset_time_counter_foreach_rstn_data, data);
1042 }
1043
1044 void stc_monitor_rstn_reset_time_counters_if_required(void)
1045 {
1046         reset_time_limits_context_s context;
1047         GHashTable *rstns = stc_monitor_get_system_rstns();
1048         time_t last_week_ts = stc_monitor_get_last_week_ts();
1049         time_t last_day_ts = stc_monitor_get_last_day_ts();
1050
1051         context.now = time(NULL);
1052         context.week_start_ts = stc_time_get_week_start(context.now);
1053         context.day_start_ts = stc_time_get_day_start(context.now);
1054         context.is_updated = 0;
1055
1056         if (last_week_ts != context.week_start_ts) {
1057                 stc_monitor_set_last_week_ts(context.week_start_ts);
1058                 context.is_updated |= (1 << STC_RSTN_LIMIT_TYPE_WEEKLY);
1059         }
1060
1061         if (last_day_ts != context.day_start_ts) {
1062                 stc_monitor_set_last_day_ts(context.day_start_ts);
1063                 context.is_updated |= (1 << STC_RSTN_LIMIT_TYPE_DAILY);
1064         }
1065
1066         if (rstns) {
1067                 g_hash_table_foreach(rstns,
1068                                __reset_time_counter_foreach_rstn_value,
1069                                &context);
1070
1071                 if (context.is_updated)
1072                         STC_LOGD("Counter reset completed month_start[%ld] "
1073                                 "week_start[%ld] day_start[%ld]",
1074                                 context.month_start_ts, last_week_ts, last_day_ts);
1075         }
1076 }
1077
1078 void stc_monitor_rstn_update_counter(gpointer data,
1079                                         gpointer user_data)
1080 {
1081         int i;
1082         stc_rstn_data_s *rstn_data = (stc_rstn_data_s *)data;
1083         classid_bytes_context_s *context = (classid_bytes_context_s *)user_data;
1084         default_connection_s *default_connection = stc_get_default_connection();
1085
1086         if (rstn_data->iftype != context->counter->iftype)
1087                 return;
1088
1089         if (rstn_data->ifname != NULL &&
1090                 g_strcmp0(rstn_data->ifname, "") &&
1091                 g_strcmp0(rstn_data->ifname, context->counter->ifname) != 0)
1092                 return;
1093
1094         if (rstn_data->subscriber_id != NULL &&
1095                 g_strcmp0(rstn_data->subscriber_id, "") &&
1096                 g_strcmp0(rstn_data->subscriber_id, default_connection->subscriber_id) != 0)
1097                 return;
1098
1099         if (rstn_data->roaming != default_connection->roaming)
1100                 return;
1101
1102         if (rstn_data->limit_exceeded != 0) {
1103                 context->data_limit_exceeded = TRUE;
1104                 return;
1105         }
1106
1107         switch (context->counter->iotype) {
1108         case NFACCT_COUNTER_IN:
1109         case NFACCT_COUNTER_OUT:
1110                 if ((rstn_data->counter[STC_RSTN_LIMIT_TYPE_DATA] == 0 &&
1111                         rstn_data->limit[STC_RSTN_LIMIT_TYPE_DATA] >= 0) ||
1112                         (rstn_data->counter[STC_RSTN_LIMIT_TYPE_DATA_WARN] == 0 &&
1113                         rstn_data->limit[STC_RSTN_LIMIT_TYPE_DATA_WARN] >= 0) ||
1114                         (rstn_data->counter[STC_RSTN_LIMIT_TYPE_MONTHLY] == 0 &&
1115                         rstn_data->limit[STC_RSTN_LIMIT_TYPE_MONTHLY] >= 0) ||
1116                         (rstn_data->counter[STC_RSTN_LIMIT_TYPE_WEEKLY] == 0 &&
1117                         rstn_data->limit[STC_RSTN_LIMIT_TYPE_WEEKLY] >= 0) ||
1118                         (rstn_data->counter[STC_RSTN_LIMIT_TYPE_DAILY] == 0 &&
1119                         rstn_data->limit[STC_RSTN_LIMIT_TYPE_DAILY] >= 0)) {
1120                         table_counters_info info;
1121                         memset(&info, 0, sizeof(table_counters_info));
1122                         table_counters_get(rstn_data->restriction_id, &info);
1123
1124                         rstn_data->counter[STC_RSTN_LIMIT_TYPE_DATA] = info.data_counter;
1125                         rstn_data->counter[STC_RSTN_LIMIT_TYPE_DATA_WARN] = info.warn_counter;
1126                         rstn_data->counter[STC_RSTN_LIMIT_TYPE_MONTHLY] = info.monthly_counter;
1127                         rstn_data->counter[STC_RSTN_LIMIT_TYPE_WEEKLY] = info.weekly_counter;
1128                         rstn_data->counter[STC_RSTN_LIMIT_TYPE_DAILY] = info.daily_counter;
1129                 }
1130
1131                 for (i = 0; i < STC_RSTN_LIMIT_TYPE_MAX; i++) {
1132                         if (rstn_data->limit[i] >= 0 &&
1133                                 !(rstn_data->limit_notified & (1 << i))) {
1134                                 rstn_data->counter[i] += context->bytes;
1135                                 if (rstn_data->limit[i] <= rstn_data->counter[i])
1136                                         stc_monitor_rstn_action_when_limit_exceeded(i,
1137                                                                                 rstn_data,
1138                                                                                 context);
1139                         }
1140                 }
1141
1142                 stc_monitor_set_rstns_updated(TRUE);
1143                 __print_rstn(rstn_data);
1144                 break;
1145         default:
1146                 STC_LOGE("Unknown iotype");
1147         }
1148 }
1149
1150 void stc_monitor_rstn_update_iface_counter(classid_bytes_context_s *context)
1151 {
1152         switch (context->counter->iftype) {
1153         case STC_IFACE_DATACALL:
1154                 __rstn_update_counter(context, STC_TOTAL_DATACALL_CLASSID);
1155                 break;
1156         case STC_IFACE_WIFI:
1157                 __rstn_update_counter(context, STC_TOTAL_WIFI_CLASSID);
1158                 __rstn_update_counter(context, STC_TETHERING_APP_CLASSID);
1159                 break;
1160         case STC_IFACE_BLUETOOTH:
1161                 __rstn_update_counter(context, STC_TOTAL_BLUETOOTH_CLASSID);
1162                 __rstn_update_counter(context, STC_TETHERING_APP_CLASSID);
1163                 break;
1164         case STC_IFACE_USB:
1165                 __rstn_update_counter(context, STC_TETHERING_APP_CLASSID);
1166                 break;
1167         case STC_IFACE_P2P:
1168                 __rstn_update_counter(context, STC_TETHERING_APP_CLASSID);
1169                 break;
1170         default:
1171                 break;
1172         }
1173 }
1174
1175 void stc_monitor_rstn_action_when_limit_exceeded(stc_rstn_limit_type_e limit_type,
1176                                                 stc_rstn_data_s *rstn_data,
1177                                                 classid_bytes_context_s *context)
1178 {
1179         gboolean rv;
1180         char iftype[MAX_INT_LENGTH] = { 0, };
1181         char byte[MAX_INT_LENGTH] = { 0, };
1182         const char *signal_name = NULL;
1183         const char *net_popup_content = NULL;
1184         const char *net_popup_type = NULL;
1185         stc_s *stc = (stc_s *)stc_get_manager();
1186
1187         if (stc == NULL) {
1188                 STC_LOGE("Failed to get stc data");
1189                 return;
1190         }
1191
1192         switch (limit_type) {
1193         case STC_RSTN_LIMIT_TYPE_DATA_WARN:
1194         {
1195                 signal_name = "WarnThresholdCrossed";
1196                 net_popup_content = "warn threshold crossed";
1197                 net_popup_type = "warning_noti";
1198         }
1199         break;
1200         case STC_RSTN_LIMIT_TYPE_DATA:
1201         case STC_RSTN_LIMIT_TYPE_MONTHLY:
1202         case STC_RSTN_LIMIT_TYPE_WEEKLY:
1203         case STC_RSTN_LIMIT_TYPE_DAILY:
1204         {
1205                 signal_name = "RestrictionThresholdCrossed";
1206                 net_popup_content = "restriction threshold crossed";
1207                 net_popup_type = "restriction_noti";
1208
1209                 /* Apply restriction for tethering apps if app_id is of tethering client
1210                  * otherwise do the normal iptables rule */
1211                 if (context->counter->intend == NFACCT_TETH_COUNTER) {
1212
1213                         if (g_str_has_suffix(rstn_data->app_id, STC_TETHERING_APP_SUFFIX) &&
1214                                         rstn_data->classid != STC_TETHERING_APP_CLASSID) {
1215                                 __rstn_action_when_limit_exceeded_tethering(rstn_data,
1216                                                 context);
1217                         }
1218
1219                 } else {
1220                         /* block immediately */
1221                         context->counter->intend = NFACCT_BLOCK;
1222                         stc_monitor_ipt_del_in(context->counter);
1223                         stc_monitor_ipt_del_out(context->counter);
1224                         stc_monitor_ipt_add_in(context->counter);
1225                         stc_monitor_ipt_add_out(context->counter);
1226
1227                         stc_monitor_ip6t_del_in(context->counter);
1228                         stc_monitor_ip6t_del_out(context->counter);
1229                         stc_monitor_ip6t_add_in(context->counter);
1230                         stc_monitor_ip6t_add_out(context->counter);
1231                         context->counter->intend = NFACCT_COUNTER;
1232                 }
1233
1234                 rstn_data->limit_exceeded |= (1 << limit_type);
1235                 __rstn_set_noti_state(STC_RSTN_STATE_SET);
1236         }
1237         break;
1238         default:
1239                 break;
1240         }
1241
1242         if (signal_name == NULL) {
1243                 STC_LOGE("Invalid parameter: limit_type");
1244                 return;
1245         }
1246
1247         /* emit signal */
1248         rv = stc_manager_dbus_emit_signal(stc->connection,
1249                                                   STC_DBUS_SERVICE_RESTRICTION_PATH,
1250                                                   STC_DBUS_INTERFACE_RESTRICTION,
1251                                                   signal_name,
1252                                                   g_variant_new("(si)",
1253                                                   rstn_data->app_id,
1254                                                   rstn_data->iftype));
1255
1256         if (rv == TRUE)
1257                 rstn_data->limit_notified |= (1 << limit_type);
1258
1259         snprintf(iftype, MAX_INT_LENGTH, "%d", rstn_data->iftype);
1260         snprintf(byte, MAX_INT_LENGTH, "%lld", rstn_data->limit[limit_type]);
1261         stc_plugin_appstatus_send_message(net_popup_content,
1262                         net_popup_type, rstn_data->app_id, iftype, byte);
1263
1264         if (STC_DEBUG_LOG)
1265                 STC_LOGD("Limit exceeded [\033[0;31m%s\033[0;m:%d]",
1266                                         net_popup_content, limit_type);
1267 }
1268
1269 gboolean stc_monitor_rstn_flush_contr_to_db(gpointer user_data)
1270 {
1271         time_t current_time = 0;
1272         stc_s *stc = stc_get_manager();
1273         GHashTable *rstns = stc_monitor_get_system_rstns();
1274         gboolean rstns_updated = stc_monitor_get_rstns_updated();
1275
1276         if (stc && stc->carg)
1277                 current_time = stc->carg->last_run_time;
1278
1279         if (rstns_updated == FALSE)
1280                 return G_SOURCE_REMOVE;
1281
1282         stc_monitor_set_rstns_updated(FALSE);
1283
1284         if (rstns)
1285                 g_hash_table_foreach(rstns,
1286                                __rstn_update_counter_value,
1287                                &current_time);
1288
1289         STC_LOGI("Flushed rstns counters to database");
1290         return G_SOURCE_REMOVE;
1291 }
1292
1293 stc_error_e stc_monitor_rstn_add(const table_restrictions_info *info)
1294 {
1295         stc_rstn_data_s data;
1296
1297         memset(&data, 0, sizeof(stc_rstn_data_s));
1298
1299         if (info->app_id) {
1300                 data.classid = get_classid_by_app_id(info->app_id, TRUE);
1301                 data.app_id = info->app_id;
1302         } else
1303                 data.classid = STC_UNKNOWN_CLASSID;
1304
1305         if (data.classid == STC_BACKGROUND_APP_CLASSID) {
1306                 stc_monitor_set_background_state(TRUE);
1307                 __vconf_set_int(VCONFKEY_STC_BACKGROUND_STATE, TRUE);
1308         }
1309
1310         data.iftype = info->iftype;
1311         data.ifname = info->ifname;
1312         data.subscriber_id = info->subscriber_id;
1313         data.roaming = info->roaming;
1314         data.mac = info->mac;
1315
1316         data.rstn_type = info->rstn_type;
1317         data.rstn_state = STC_RSTN_STATE_UNKNOWN;
1318         data.restriction_id = info->restriction_id;
1319
1320         data.limit[STC_RSTN_LIMIT_TYPE_DATA] = info->data_limit;
1321         data.limit[STC_RSTN_LIMIT_TYPE_DATA_WARN] = info->data_warn_limit;
1322         data.limit[STC_RSTN_LIMIT_TYPE_MONTHLY] = info->monthly_limit;
1323         data.limit[STC_RSTN_LIMIT_TYPE_WEEKLY] = info->weekly_limit;
1324         data.limit[STC_RSTN_LIMIT_TYPE_DAILY] = info->daily_limit;
1325         data.month_start_date = info->month_start_date;
1326         data.month_start_ts = stc_time_get_month_start(time(NULL),
1327                                                                                 info->month_start_date);
1328
1329         return __rstn_data_add(&data);
1330 }
1331
1332 void stc_monitor_rstn_add_for_app(uint32_t classid)
1333 {
1334         stc_rstn_value_s *lookup_value;
1335         GHashTable *rstns = stc_monitor_get_system_rstns();
1336
1337         if (!rstns)
1338                 return;
1339
1340         lookup_value = g_hash_table_lookup(rstns, GUINT_TO_POINTER(classid));
1341         if (!lookup_value) {
1342                 if (STC_DEBUG_LOG)
1343                         STC_LOGD("Restriction not found [\033[1;36m%d\033[0;m]",
1344                                                 classid);
1345                 return;
1346         }
1347
1348         g_slist_foreach(lookup_value->rules, __rstn_add, NULL);
1349 }
1350
1351 void stc_monitor_rstn_add_by_connection(default_connection_s *conn)
1352 {
1353         GHashTable *rstns = stc_monitor_get_system_rstns();
1354
1355         if (!rstns)
1356                 return;
1357
1358         g_hash_table_foreach(rstns, __rstn_add_by_connection, conn);
1359 }
1360
1361 stc_error_e stc_monitor_rstn_remove(const table_restrictions_info *info)
1362 {
1363         stc_rstn_data_s data;
1364
1365         memset(&data, 0, sizeof(stc_rstn_data_s));
1366
1367         data.classid = get_classid_by_app_id(info->app_id, TRUE);
1368         data.app_id = info->app_id;
1369
1370         data.iftype = info->iftype;
1371         data.ifname = info->ifname;
1372         data.subscriber_id = info->subscriber_id;
1373         data.roaming = info->roaming;
1374
1375         if (g_strcmp0(info->app_id, STC_BACKGROUND_APP_ID) == 0) {
1376                 stc_monitor_set_background_state(FALSE);
1377                 __vconf_set_int(VCONFKEY_STC_BACKGROUND_STATE, FALSE);
1378         }
1379
1380         return __rstn_data_remove(&data);
1381 }
1382
1383 void stc_monitor_rstn_remove_for_app(uint32_t classid)
1384 {
1385         stc_rstn_value_s *lookup_value;
1386         GHashTable *rstns = stc_monitor_get_system_rstns();
1387
1388         if (!rstns)
1389                 return;
1390
1391         lookup_value = g_hash_table_lookup(rstns, GUINT_TO_POINTER(classid));
1392         if (!lookup_value) {
1393                 if (STC_DEBUG_LOG)
1394                         STC_LOGD("Restriction not found [\033[1;36m%d\033[0;m]",
1395                                                 classid);
1396                 return;
1397         }
1398
1399         g_slist_foreach(lookup_value->rules, __rstn_remove, NULL);
1400 }
1401
1402 void stc_monitor_rstn_remove_by_connection(default_connection_s *conn)
1403 {
1404         GHashTable *rstns = stc_monitor_get_system_rstns();
1405
1406         if (!rstns)
1407                 return;
1408
1409         g_hash_table_foreach(rstns, __rstn_remove_by_connection, conn);
1410 }
1411
1412 void stc_monitor_rstns_load(void)
1413 {
1414         table_restrictions_foreach(__rstn_insert_cb, NULL);
1415
1416         /* __rstn_tree_printall(); */
1417 }
1418
1419 GHashTable *stc_monitor_rstns_init(void)
1420 {
1421         return g_hash_table_new_full(g_direct_hash, g_direct_equal,
1422                                         NULL, __rstn_value_destroy);
1423 }