File indexing completed on 2024-06-23 05:27:53

0001 /*
0002     SPDX-FileCopyrightText: 2019 Arjen Hiemstra <ahiemstra@heimr.nl>
0003 
0004     SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0005 */
0006 
0007 #include "Accumulator.h"
0008 
0009 #include "Capture.h"
0010 #include "ConnectionMapping.h"
0011 
0012 using namespace std::chrono_literals;
0013 
0014 Accumulator::Accumulator(std::shared_ptr<Capture> capture, std::shared_ptr<ConnectionMapping> mapping)
0015     : m_capture(capture)
0016     , m_mapping(mapping)
0017     , m_running(true)
0018 {
0019     m_thread = std::thread{&Accumulator::loop, this};
0020 }
0021 
0022 Accumulator::~Accumulator()
0023 {
0024     m_running = false;
0025     if (m_thread.joinable()) {
0026         m_thread.join();
0027     }
0028 }
0029 
0030 Accumulator::PidDataCounterHash Accumulator::data()
0031 {
0032     std::lock_guard<std::mutex> lock{m_mutex};
0033 
0034     auto tmp = m_data;
0035 
0036     auto toErase = std::vector<int>{};
0037     for (auto &entry : m_data) {
0038         if (entry.second.first == 0 && entry.second.second == 0) {
0039             toErase.push_back(entry.first);
0040         } else {
0041             entry.second.first = 0;
0042             entry.second.second = 0;
0043         }
0044     }
0045 
0046     std::for_each(toErase.cbegin(), toErase.cend(), [this](int pid) {
0047         m_data.erase(pid);
0048     });
0049 
0050     return tmp;
0051 }
0052 
0053 void Accumulator::loop()
0054 {
0055     while (m_running) {
0056         auto packet = m_capture->nextPacket();
0057 
0058         auto result = m_mapping->pidForPacket(packet);
0059         if (result.pid == 0) {
0060             continue;
0061         }
0062 
0063         addData(result.direction, packet, result.pid);
0064     }
0065 }
0066 
0067 void Accumulator::addData(Packet::Direction direction, const Packet &packet, int pid)
0068 {
0069     std::lock_guard<std::mutex> lock{m_mutex};
0070 
0071     auto itr = m_data.find(pid);
0072     if (itr == m_data.end()) {
0073         m_data.emplace(pid, InboundOutboundData{0, 0});
0074     }
0075 
0076     if (direction == Packet::Direction::Inbound) {
0077         m_data[pid].first += packet.size();
0078     } else {
0079         m_data[pid].second += packet.size();
0080     };
0081 }