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