Refactor getTetherStats in preparation for IPv6 tether counters.

Bug: 9580643
Change-Id: I11565cafbefbc06a7992d1ff18c707165d5b31ed
diff --git a/server/BandwidthController.cpp b/server/BandwidthController.cpp
index f52c087..5596784 100644
--- a/server/BandwidthController.cpp
+++ b/server/BandwidthController.cpp
@@ -1082,6 +1082,16 @@
     return res;
 }
 
+void BandwidthController::addStats(TetherStatsList& statsList, const TetherStats& stats) {
+    for (TetherStats& existing : statsList) {
+        if (existing.addStatsIfMatch(stats)) {
+            return;
+        }
+    }
+    // No match. Insert a new interface pair.
+    statsList.push_back(stats);
+}
+
 /*
  * Parse the ptks and bytes out of:
  *   Chain natctrl_tether_counters (4 references)
@@ -1093,8 +1103,9 @@
  * It results in an error if invoked and no tethering counter rules exist. The constraint
  * helps detect complete parsing failure.
  */
-int BandwidthController::parseForwardChainStats(SocketClient *cli, const TetherStats filter,
-                                                FILE *fp, std::string &extraProcessingInfo) {
+int BandwidthController::addForwardChainStats(const TetherStats& filter,
+                                              TetherStatsList& statsList, FILE *fp,
+                                              std::string &extraProcessingInfo) {
     int res;
     char lineBuffer[MAX_IPT_OUTPUT_LINE_LEN];
     char iface0[MAX_IPT_OUTPUT_LINE_LEN];
@@ -1170,17 +1181,13 @@
         }
         if (stats.rxBytes != -1 && stats.txBytes != -1) {
             ALOGV("rx_bytes=%" PRId64" tx_bytes=%" PRId64" filterPair=%d", stats.rxBytes, stats.txBytes, filterPair);
-            /* Send out stats, and prep for the next if needed. */
-            char *msg = stats.getStatsLine();
+            addStats(statsList, stats);
             if (filterPair) {
-                cli->sendMsg(ResponseCode::TetheringStatsResult, msg, false);
                 return 0;
             } else {
-                cli->sendMsg(ResponseCode::TetheringStatsListResult, msg, false);
+                statsFound++;
                 stats = filter;
             }
-            free(msg);
-            statsFound++;
         }
     }
 
@@ -1190,7 +1197,6 @@
         (!statsFound && !filterPair)) {
         return -1;
     }
-    cli->sendMsg(ResponseCode::CommandOkay, "Tethering stats list completed", false);
     return 0;
 }
 
@@ -1201,11 +1207,14 @@
     return msg;
 }
 
-int BandwidthController::getTetherStats(SocketClient *cli, TetherStats &stats, std::string &extraProcessingInfo) {
+int BandwidthController::getTetherStats(SocketClient *cli, TetherStats& filter,
+                                        std::string &extraProcessingInfo) {
     int res;
     std::string fullCmd;
     FILE *iptOutput;
 
+    TetherStatsList statsList;
+
     /*
      * Why not use some kind of lib to talk to iptables?
      * Because the only libs are libiptc and libip6tc in iptables, and they are
@@ -1222,9 +1231,21 @@
             extraProcessingInfo += "Failed to run iptables.";
         return -1;
     }
-    res = parseForwardChainStats(cli, stats, iptOutput, extraProcessingInfo);
+
+    res = addForwardChainStats(filter, statsList, iptOutput, extraProcessingInfo);
     pclose(iptOutput);
 
+    if (filter.intIface[0] && filter.extIface[0] && statsList.size() == 1) {
+        cli->sendMsg(ResponseCode::TetheringStatsResult, statsList[0].getStatsLine(), false);
+    } else {
+        for (const auto& stats: statsList) {
+            cli->sendMsg(ResponseCode::TetheringStatsListResult, stats.getStatsLine(), false);
+        }
+        if (res == 0) {
+            cli->sendMsg(ResponseCode::CommandOkay, "Tethering stats list completed", false);
+        }
+    }
+
     /* Currently NatController doesn't do ipv6 tethering, so we are done. */
     return res;
 }