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