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