e75c0695779a6b830b1c86bddf306bcedd6d530b
[profile/mobile/platform/kernel/linux-3.10-sc7730.git] / tools / gator / daemon / NetDriver.cpp
1 /**
2  * Copyright (C) ARM Limited 2013-2014. All rights reserved.
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation.
7  */
8
9 // Define to get format macros from inttypes.h
10 #define __STDC_FORMAT_MACROS
11
12 #include "NetDriver.h"
13
14 #include <inttypes.h>
15
16 #include "Logging.h"
17 #include "SessionData.h"
18
19 class NetCounter : public DriverCounter {
20 public:
21         NetCounter(DriverCounter *next, char *const name, int64_t *const value);
22         ~NetCounter();
23
24         int64_t read();
25
26 private:
27         int64_t *const mValue;
28         int64_t mPrev;
29
30         // Intentionally unimplemented
31         NetCounter(const NetCounter &);
32         NetCounter &operator=(const NetCounter &);
33 };
34
35 NetCounter::NetCounter(DriverCounter *next, char *const name, int64_t *const value) : DriverCounter(next, name), mValue(value), mPrev(0) {
36 }
37
38 NetCounter::~NetCounter() {
39 }
40
41 int64_t NetCounter::read() {
42         int64_t result = *mValue - mPrev;
43         mPrev = *mValue;
44         return result;
45 }
46
47 NetDriver::NetDriver() : mBuf(), mReceiveBytes(0), mTransmitBytes(0) {
48 }
49
50 NetDriver::~NetDriver() {
51 }
52
53 void NetDriver::readEvents(mxml_node_t *const) {
54         // Only for use with perf
55         if (!gSessionData->perf.isSetup()) {
56                 return;
57         }
58
59         setCounters(new NetCounter(getCounters(), strdup("Linux_net_rx"), &mReceiveBytes));
60         setCounters(new NetCounter(getCounters(), strdup("Linux_net_tx"), &mTransmitBytes));
61 }
62
63 bool NetDriver::doRead() {
64         if (!countersEnabled()) {
65                 return true;
66         }
67
68         if (!mBuf.read("/proc/net/dev")) {
69                 return false;
70         }
71
72         // Skip the header
73         char *key;
74         if (((key = strchr(mBuf.getBuf(), '\n')) == NULL) ||
75                         ((key = strchr(key + 1, '\n')) == NULL)) {
76                 return false;
77         }
78         key = key + 1;
79
80         mReceiveBytes = 0;
81         mTransmitBytes = 0;
82
83         char *colon;
84         while ((colon = strchr(key, ':')) != NULL) {
85                 char *end = strchr(colon + 1, '\n');
86                 if (end != NULL) {
87                         *end = '\0';
88                 }
89                 *colon = '\0';
90
91                 int64_t receiveBytes;
92                 int64_t transmitBytes;
93                 const int count = sscanf(colon + 1, " %" SCNu64 " %*u %*u %*u %*u %*u %*u %*u %" SCNu64, &receiveBytes, &transmitBytes);
94                 if (count != 2) {
95                         return false;
96                 }
97                 mReceiveBytes += receiveBytes;
98                 mTransmitBytes += transmitBytes;
99
100                 if (end == NULL) {
101                         break;
102                 }
103                 key = end + 1;
104         }
105
106         return true;
107 }
108
109 void NetDriver::start() {
110         if (!doRead()) {
111                 logg->logError(__FILE__, __LINE__, "Unable to read network stats");
112                 handleException();
113         }
114         // Initialize previous values
115         for (DriverCounter *counter = getCounters(); counter != NULL; counter = counter->getNext()) {
116                 if (!counter->isEnabled()) {
117                         continue;
118                 }
119                 counter->read();
120         }
121 }
122
123 void NetDriver::read(Buffer *const buffer) {
124         if (!doRead()) {
125                 logg->logError(__FILE__, __LINE__, "Unable to read network stats");
126                 handleException();
127         }
128         super::read(buffer);
129 }