10620f9706d9aa06ba7f8982840eeb7ab2ad90e7aAdam Lesinski/* 20620f9706d9aa06ba7f8982840eeb7ab2ad90e7aAdam Lesinski * Copyright (C) 2016 The Android Open Source Project 30620f9706d9aa06ba7f8982840eeb7ab2ad90e7aAdam Lesinski * 40620f9706d9aa06ba7f8982840eeb7ab2ad90e7aAdam Lesinski * Licensed under the Apache License, Version 2.0 (the "License"); 50620f9706d9aa06ba7f8982840eeb7ab2ad90e7aAdam Lesinski * you may not use this file except in compliance with the License. 60620f9706d9aa06ba7f8982840eeb7ab2ad90e7aAdam Lesinski * You may obtain a copy of the License at 70620f9706d9aa06ba7f8982840eeb7ab2ad90e7aAdam Lesinski * 80620f9706d9aa06ba7f8982840eeb7ab2ad90e7aAdam Lesinski * http://www.apache.org/licenses/LICENSE-2.0 90620f9706d9aa06ba7f8982840eeb7ab2ad90e7aAdam Lesinski * 100620f9706d9aa06ba7f8982840eeb7ab2ad90e7aAdam Lesinski * Unless required by applicable law or agreed to in writing, software 110620f9706d9aa06ba7f8982840eeb7ab2ad90e7aAdam Lesinski * distributed under the License is distributed on an "AS IS" BASIS, 120620f9706d9aa06ba7f8982840eeb7ab2ad90e7aAdam Lesinski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 130620f9706d9aa06ba7f8982840eeb7ab2ad90e7aAdam Lesinski * See the License for the specific language governing permissions and 140620f9706d9aa06ba7f8982840eeb7ab2ad90e7aAdam Lesinski * limitations under the License. 150620f9706d9aa06ba7f8982840eeb7ab2ad90e7aAdam Lesinski */ 160620f9706d9aa06ba7f8982840eeb7ab2ad90e7aAdam Lesinski 17ee96a3c60fca590d38025925c072d264e06493c4Myles Watson/******************************************************************************* 180620f9706d9aa06ba7f8982840eeb7ab2ad90e7aAdam Lesinski * 19a5764686f719d8d779d8a5ff8cc64010b7893e36Marie Janssen * Filename: btif_uid.cc 200620f9706d9aa06ba7f8982840eeb7ab2ad90e7aAdam Lesinski * 210620f9706d9aa06ba7f8982840eeb7ab2ad90e7aAdam Lesinski * Description: Contains data structures and functions for keeping track of 220620f9706d9aa06ba7f8982840eeb7ab2ad90e7aAdam Lesinski * socket usage per app UID. 230620f9706d9aa06ba7f8982840eeb7ab2ad90e7aAdam Lesinski * 24ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/ 25a5764686f719d8d779d8a5ff8cc64010b7893e36Marie Janssen#include <mutex> 262f0c1fff33eda347cb45d00b005e805c39474dceMark Salyzyn 270620f9706d9aa06ba7f8982840eeb7ab2ad90e7aAdam Lesinski#include "bt_common.h" 280620f9706d9aa06ba7f8982840eeb7ab2ad90e7aAdam Lesinski#include "btif_uid.h" 290620f9706d9aa06ba7f8982840eeb7ab2ad90e7aAdam Lesinski 300620f9706d9aa06ba7f8982840eeb7ab2ad90e7aAdam Lesinskitypedef struct uid_set_node_t { 316bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson struct uid_set_node_t* next; 326bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson bt_uid_traffic_t data; 330620f9706d9aa06ba7f8982840eeb7ab2ad90e7aAdam Lesinski} uid_set_node_t; 340620f9706d9aa06ba7f8982840eeb7ab2ad90e7aAdam Lesinski 350620f9706d9aa06ba7f8982840eeb7ab2ad90e7aAdam Lesinskitypedef struct uid_set_t { 366bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson std::mutex lock; 376bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson uid_set_node_t* head; 380620f9706d9aa06ba7f8982840eeb7ab2ad90e7aAdam Lesinski} uid_set_t; 390620f9706d9aa06ba7f8982840eeb7ab2ad90e7aAdam Lesinski 400620f9706d9aa06ba7f8982840eeb7ab2ad90e7aAdam Lesinskiuid_set_t* uid_set_create(void) { 416bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson uid_set_t* set = (uid_set_t*)osi_calloc(sizeof(uid_set_t)); 426bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson return set; 430620f9706d9aa06ba7f8982840eeb7ab2ad90e7aAdam Lesinski} 440620f9706d9aa06ba7f8982840eeb7ab2ad90e7aAdam Lesinski 450620f9706d9aa06ba7f8982840eeb7ab2ad90e7aAdam Lesinskivoid uid_set_destroy(uid_set_t* set) { 466bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson std::unique_lock<std::mutex> lock(set->lock); 476bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson uid_set_node_t* node = set->head; 486bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson while (node) { 496bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson uid_set_node_t* temp = node; 506bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson node = node->next; 516bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson osi_free(temp); 526bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson } 536bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson set->head = NULL; 546bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson osi_free(set); 550620f9706d9aa06ba7f8982840eeb7ab2ad90e7aAdam Lesinski} 560620f9706d9aa06ba7f8982840eeb7ab2ad90e7aAdam Lesinski 570620f9706d9aa06ba7f8982840eeb7ab2ad90e7aAdam Lesinski// Lock in uid_set_t must be held. 586bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watsonstatic uid_set_node_t* uid_set_find_or_create_node(uid_set_t* set, 596bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson int32_t app_uid) { 606bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson uid_set_node_t* node = set->head; 616bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson while (node && node->data.app_uid != app_uid) { 626bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson node = node->next; 636bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson } 646bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson 656bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson if (!node) { 666bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson node = (uid_set_node_t*)osi_calloc(sizeof(uid_set_node_t)); 676bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson node->data.app_uid = app_uid; 686bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson node->next = set->head; 696bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson set->head = node; 706bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson } 716bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson return node; 720620f9706d9aa06ba7f8982840eeb7ab2ad90e7aAdam Lesinski} 730620f9706d9aa06ba7f8982840eeb7ab2ad90e7aAdam Lesinski 740620f9706d9aa06ba7f8982840eeb7ab2ad90e7aAdam Lesinskivoid uid_set_add_tx(uid_set_t* set, int32_t app_uid, uint64_t bytes) { 756bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson if (app_uid == -1 || bytes == 0) return; 760620f9706d9aa06ba7f8982840eeb7ab2ad90e7aAdam Lesinski 776bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson std::unique_lock<std::mutex> lock(set->lock); 786bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson uid_set_node_t* node = uid_set_find_or_create_node(set, app_uid); 796bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson node->data.tx_bytes += bytes; 800620f9706d9aa06ba7f8982840eeb7ab2ad90e7aAdam Lesinski} 810620f9706d9aa06ba7f8982840eeb7ab2ad90e7aAdam Lesinski 820620f9706d9aa06ba7f8982840eeb7ab2ad90e7aAdam Lesinskivoid uid_set_add_rx(uid_set_t* set, int32_t app_uid, uint64_t bytes) { 836bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson if (app_uid == -1 || bytes == 0) return; 840620f9706d9aa06ba7f8982840eeb7ab2ad90e7aAdam Lesinski 856bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson std::unique_lock<std::mutex> lock(set->lock); 866bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson uid_set_node_t* node = uid_set_find_or_create_node(set, app_uid); 876bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson node->data.rx_bytes += bytes; 880620f9706d9aa06ba7f8982840eeb7ab2ad90e7aAdam Lesinski} 890620f9706d9aa06ba7f8982840eeb7ab2ad90e7aAdam Lesinski 900620f9706d9aa06ba7f8982840eeb7ab2ad90e7aAdam Lesinskibt_uid_traffic_t* uid_set_read_and_clear(uid_set_t* set) { 916bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson std::unique_lock<std::mutex> lock(set->lock); 926bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson 936bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson // Find the length 946bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson size_t len = 0; 956bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson uid_set_node_t* node = set->head; 966bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson while (node) { 976bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson len++; 986bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson node = node->next; 996bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson } 1006bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson 1016bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson // Allocate an array of elements + 1, to signify the end with app_uid set to 1026bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson // -1. 1036bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson bt_uid_traffic_t* result = 1046bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson (bt_uid_traffic_t*)osi_calloc(sizeof(bt_uid_traffic_t) * (len + 1)); 1056bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson 1066bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson bt_uid_traffic_t* data = result; 1076bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson node = set->head; 1086bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson while (node) { 1096bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson // Copy the data. 1106bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson *data = node->data; 1116bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson data++; 1126bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson 1136bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson // Clear the counters. 1146bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson node->data.rx_bytes = 0; 1156bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson node->data.tx_bytes = 0; 1166bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson node = node->next; 1176bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson } 1186bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson 1196bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson // Mark the last entry 1206bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson data->app_uid = -1; 1216bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson 1226bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson return result; 1230620f9706d9aa06ba7f8982840eeb7ab2ad90e7aAdam Lesinski} 124