| /** |
| * Copyright (C) ARM Limited 2013-2014. All rights reserved. |
| * |
| * This program is free software; you can redistribute it and/or modify |
| * it under the terms of the GNU General Public License version 2 as |
| * published by the Free Software Foundation. |
| */ |
| |
| // Define to get format macros from inttypes.h |
| #define __STDC_FORMAT_MACROS |
| |
| #include "NetDriver.h" |
| |
| #include <inttypes.h> |
| |
| #include "Logging.h" |
| #include "SessionData.h" |
| |
| class NetCounter : public DriverCounter { |
| public: |
| NetCounter(DriverCounter *next, char *const name, int64_t *const value); |
| ~NetCounter(); |
| |
| int64_t read(); |
| |
| private: |
| int64_t *const mValue; |
| int64_t mPrev; |
| |
| // Intentionally unimplemented |
| NetCounter(const NetCounter &); |
| NetCounter &operator=(const NetCounter &); |
| }; |
| |
| NetCounter::NetCounter(DriverCounter *next, char *const name, int64_t *const value) : DriverCounter(next, name), mValue(value), mPrev(0) { |
| } |
| |
| NetCounter::~NetCounter() { |
| } |
| |
| int64_t NetCounter::read() { |
| int64_t result = *mValue - mPrev; |
| mPrev = *mValue; |
| return result; |
| } |
| |
| NetDriver::NetDriver() : mBuf(), mReceiveBytes(0), mTransmitBytes(0) { |
| } |
| |
| NetDriver::~NetDriver() { |
| } |
| |
| void NetDriver::readEvents(mxml_node_t *const) { |
| // Only for use with perf |
| if (!gSessionData->perf.isSetup()) { |
| return; |
| } |
| |
| setCounters(new NetCounter(getCounters(), strdup("Linux_net_rx"), &mReceiveBytes)); |
| setCounters(new NetCounter(getCounters(), strdup("Linux_net_tx"), &mTransmitBytes)); |
| } |
| |
| bool NetDriver::doRead() { |
| if (!countersEnabled()) { |
| return true; |
| } |
| |
| if (!mBuf.read("/proc/net/dev")) { |
| return false; |
| } |
| |
| // Skip the header |
| char *key; |
| if (((key = strchr(mBuf.getBuf(), '\n')) == NULL) || |
| ((key = strchr(key + 1, '\n')) == NULL)) { |
| return false; |
| } |
| key = key + 1; |
| |
| mReceiveBytes = 0; |
| mTransmitBytes = 0; |
| |
| char *colon; |
| while ((colon = strchr(key, ':')) != NULL) { |
| char *end = strchr(colon + 1, '\n'); |
| if (end != NULL) { |
| *end = '\0'; |
| } |
| *colon = '\0'; |
| |
| int64_t receiveBytes; |
| int64_t transmitBytes; |
| const int count = sscanf(colon + 1, " %" SCNu64 " %*u %*u %*u %*u %*u %*u %*u %" SCNu64, &receiveBytes, &transmitBytes); |
| if (count != 2) { |
| return false; |
| } |
| mReceiveBytes += receiveBytes; |
| mTransmitBytes += transmitBytes; |
| |
| if (end == NULL) { |
| break; |
| } |
| key = end + 1; |
| } |
| |
| return true; |
| } |
| |
| void NetDriver::start() { |
| if (!doRead()) { |
| logg->logError(__FILE__, __LINE__, "Unable to read network stats"); |
| handleException(); |
| } |
| // Initialize previous values |
| for (DriverCounter *counter = getCounters(); counter != NULL; counter = counter->getNext()) { |
| if (!counter->isEnabled()) { |
| continue; |
| } |
| counter->read(); |
| } |
| } |
| |
| void NetDriver::read(Buffer *const buffer) { |
| if (!doRead()) { |
| logg->logError(__FILE__, __LINE__, "Unable to read network stats"); |
| handleException(); |
| } |
| super::read(buffer); |
| } |