From 4c042af222f8f04779d71e740deec0c18b029ce4 Mon Sep 17 00:00:00 2001
From: Chris Manton <cmanton@google.com>
Date: Thu, 7 Oct 2021 10:01:22 -0700
Subject: [PATCH] Add pan profile dumpsys

Bug: 188074901
Tag: #refactor
Test: gd/cert/run

Change-Id: I9a4591c8e541c651bc11a51a1d5c034854a5ea73
---
 system/main/shim/acl.cc                |  2 +
 system/stack/include/pan_api.h         |  2 +
 system/stack/pan/pan_api.cc            | 63 ++++++++++++++++++++++++--
 system/stack/pan/pan_int.h             |  7 +++
 system/stack/pan/pan_main.cc           |  5 ++
 system/test/mock/mock_stack_pan_api.cc |  1 +
 6 files changed, 75 insertions(+), 5 deletions(-)

diff --git a/system/main/shim/acl.cc b/system/main/shim/acl.cc
index f3080da49bf..54a8f58d038 100644
--- a/system/main/shim/acl.cc
+++ b/system/main/shim/acl.cc
@@ -59,6 +59,7 @@
 #include "stack/include/bt_hdr.h"
 #include "stack/include/btm_api.h"
 #include "stack/include/btm_status.h"
+#include "stack/include/pan_api.h"
 #include "stack/include/sec_hci_link_interface.h"
 #include "stack/l2cap/l2c_int.h"
 #include "types/ble_address_with_type.h"
@@ -1128,6 +1129,7 @@ void DumpsysRecord(int fd) {
 #undef DUMPSYS_TAG
 
 void shim::legacy::Acl::Dump(int fd) const {
+  PAN_Dumpsys(fd);
   DumpsysHid(fd);
   DumpsysRecord(fd);
   DumpsysAcl(fd);
diff --git a/system/stack/include/pan_api.h b/system/stack/include/pan_api.h
index a0ebadc4b22..7a732758f21 100644
--- a/system/stack/include/pan_api.h
+++ b/system/stack/include/pan_api.h
@@ -461,4 +461,6 @@ extern uint8_t PAN_SetTraceLevel(uint8_t new_level);
  ******************************************************************************/
 extern void PAN_Init(void);
 
+extern void PAN_Dumpsys(int fd);
+
 #endif /* PAN_API_H */
diff --git a/system/stack/pan/pan_api.cc b/system/stack/pan/pan_api.cc
index 61fe192f8af..9fc53ff82b7 100644
--- a/system/stack/pan/pan_api.cc
+++ b/system/stack/pan/pan_api.cc
@@ -26,13 +26,16 @@
 #include "stack/include/pan_api.h"
 
 #include <base/logging.h>
+#include <base/strings/stringprintf.h>
 
 #include <cstdint>
 
 #include "bta/sys/bta_sys.h"
+#include "main/shim/dumpsys.h"
 #include "osi/include/allocator.h"
 #include "stack/include/bnep_api.h"
 #include "stack/include/bt_hdr.h"
+#include "stack/include/btm_log_history.h"
 #include "stack/include/sdp_api.h"
 #include "stack/include/sdpdefs.h"
 #include "stack/pan/pan_int.h"
@@ -41,6 +44,10 @@
 
 using bluetooth::Uuid;
 
+namespace {
+constexpr char kBtmLogTag[] = "PAN";
+}
+
 /*******************************************************************************
  *
  * Function         PAN_Register
@@ -56,10 +63,10 @@ using bluetooth::Uuid;
  *
  ******************************************************************************/
 void PAN_Register(tPAN_REGISTER* p_register) {
-  pan_register_with_bnep();
-
   if (!p_register) return;
 
+  pan_register_with_bnep();
+
   pan_cb.pan_conn_state_cb = p_register->pan_conn_state_cb;
   pan_cb.pan_bridge_req_cb = p_register->pan_bridge_req_cb;
   pan_cb.pan_data_buf_ind_cb = p_register->pan_data_buf_ind_cb;
@@ -68,7 +75,7 @@ void PAN_Register(tPAN_REGISTER* p_register) {
   pan_cb.pan_mfilt_ind_cb = p_register->pan_mfilt_ind_cb;
   pan_cb.pan_tx_data_flow_cb = p_register->pan_tx_data_flow_cb;
 
-  return;
+  BTM_LogHistory(kBtmLogTag, RawAddress::kEmpty, "Registered");
 }
 
 /*******************************************************************************
@@ -97,7 +104,7 @@ void PAN_Deregister(void) {
   PAN_SetRole(PAN_ROLE_INACTIVE, NULL, NULL);
   BNEP_Deregister();
 
-  return;
+  BTM_LogHistory(kBtmLogTag, RawAddress::kEmpty, "Unregistered");
 }
 
 /*******************************************************************************
@@ -196,6 +203,9 @@ tPAN_RESULT PAN_SetRole(uint8_t role, const char* p_user_name,
 
   pan_cb.role = role;
   PAN_TRACE_EVENT("PAN role set to: %d", role);
+
+  BTM_LogHistory(kBtmLogTag, RawAddress::kEmpty, "Role change",
+                 base::StringPrintf("role:0x%x", role));
   return PAN_SUCCESS;
 }
 
@@ -360,6 +370,8 @@ tPAN_RESULT PAN_Disconnect(uint16_t handle) {
   if (pan_cb.pan_bridge_req_cb && pcb->src_uuid == UUID_SERVCLASS_NAP)
     (*pan_cb.pan_bridge_req_cb)(pcb->rem_bda, false);
 
+  BTM_LogHistory(kBtmLogTag, pcb->rem_bda, "Disconnect");
+
   pan_release_pcb(pcb);
 
   if (result != BNEP_SUCCESS) {
@@ -497,6 +509,9 @@ tPAN_RESULT PAN_WriteBuf(uint16_t handle, const RawAddress& dst,
       return (tPAN_RESULT)result;
     }
 
+    pan_cb.pcb[i].write.octets += p_buf->len;
+    pan_cb.pcb[i].write.packets++;
+
     PAN_TRACE_DEBUG("PAN successfully wrote data for the PANU connection");
     return PAN_SUCCESS;
   }
@@ -511,6 +526,7 @@ tPAN_RESULT PAN_WriteBuf(uint16_t handle, const RawAddress& dst,
 
   if (pcb->con_state != PAN_STATE_CONNECTED) {
     PAN_TRACE_ERROR("PAN Buf write when conn is not active");
+    pcb->write.drops++;
     osi_free(p_buf);
     return PAN_FAILURE;
   }
@@ -518,13 +534,19 @@ tPAN_RESULT PAN_WriteBuf(uint16_t handle, const RawAddress& dst,
   result = BNEP_WriteBuf(pcb->handle, dst, p_buf, protocol, &src, ext);
   if (result == BNEP_IGNORE_CMD) {
     PAN_TRACE_DEBUG("PAN ignored data buf write to PANU");
-    return (tPAN_RESULT)result;
+    pcb->write.errors++;
+    return PAN_IGNORE_CMD;
   } else if (result != BNEP_SUCCESS) {
     PAN_TRACE_ERROR("PAN failed to send data buf to the PANU");
+    pcb->write.errors++;
     return (tPAN_RESULT)result;
   }
 
+  pcb->write.octets += p_buf->len;
+  pcb->write.packets++;
+
   PAN_TRACE_DEBUG("PAN successfully sent data buf to the PANU");
+
   return PAN_SUCCESS;
 }
 
@@ -647,3 +669,34 @@ void PAN_Init(void) {
   pan_cb.trace_level = BT_TRACE_LEVEL_NONE; /* No traces */
 #endif
 }
+
+#define DUMPSYS_TAG "shim::legacy::pan"
+void PAN_Dumpsys(int fd) {
+  LOG_DUMPSYS_TITLE(fd, DUMPSYS_TAG);
+
+  LOG_DUMPSYS(fd, "Connections:%hhu roles configured:%s current:%s previous:%s",
+              pan_cb.num_conns, pan_role_to_text(pan_cb.role).c_str(),
+              pan_role_to_text(pan_cb.active_role).c_str(),
+              pan_role_to_text(pan_cb.prv_active_role).c_str());
+  const tPAN_CONN* pcb = &pan_cb.pcb[0];
+  for (int i = 0; i < MAX_PAN_CONNS; i++, pcb++) {
+    if (pcb->con_state == PAN_STATE_IDLE) continue;
+    LOG_DUMPSYS(fd, "  Id:%d peer:%s", i, PRIVATE_ADDRESS(pcb->rem_bda));
+    LOG_DUMPSYS(
+        fd,
+        "    rx_packets:%-5lu rx_octets:%-8lu rx_errors:%-5lu rx_drops:%-5lu",
+        (unsigned long)pcb->read.packets, (unsigned long)pcb->read.octets,
+        (unsigned long)pcb->read.errors, (unsigned long)pcb->read.drops);
+    LOG_DUMPSYS(
+        fd,
+        "    tx_packets:%-5lu tx_octets:%-8lu tx_errors:%-5lu tx_drops:%-5lu",
+        (unsigned long)pcb->write.packets, (unsigned long)pcb->write.octets,
+        (unsigned long)pcb->write.errors, (unsigned long)pcb->write.drops);
+    LOG_DUMPSYS(fd,
+                "    src_uuid:0x%04x[prev:0x%04x] dst_uuid:0x%04x[prev:0x%04x] "
+                "bad_pkts:%hu",
+                pcb->src_uuid, pcb->dst_uuid, pcb->prv_src_uuid,
+                pcb->prv_dst_uuid, pcb->bad_pkts_rcvd);
+  }
+}
+#undef DUMPSYS_TAG
diff --git a/system/stack/pan/pan_int.h b/system/stack/pan/pan_int.h
index fec07868a0b..709d5ec8d06 100644
--- a/system/stack/pan/pan_int.h
+++ b/system/stack/pan/pan_int.h
@@ -65,6 +65,13 @@ typedef struct {
   uint16_t ip_addr_known;
   uint32_t ip_addr;
 
+  struct {
+    size_t octets{0};
+    size_t packets{0};
+    size_t errors{0};
+    size_t drops{0};
+  } write, read;
+
 } tPAN_CONN;
 
 /*  The main PAN control block
diff --git a/system/stack/pan/pan_main.cc b/system/stack/pan/pan_main.cc
index cad53abd1f0..e4c1151a106 100644
--- a/system/stack/pan/pan_main.cc
+++ b/system/stack/pan/pan_main.cc
@@ -393,6 +393,7 @@ void pan_data_buf_ind_cb(uint16_t handle, const RawAddress& src,
   if (pcb->con_state != PAN_STATE_CONNECTED) {
     PAN_TRACE_ERROR("PAN Data indication in wrong state %d for handle %d",
                     pcb->con_state, handle);
+    pcb->read.drops++;
     osi_free(p_buf);
     return;
   }
@@ -400,6 +401,9 @@ void pan_data_buf_ind_cb(uint16_t handle, const RawAddress& src,
   p_data = (uint8_t*)(p_buf + 1) + p_buf->offset;
   len = p_buf->len;
 
+  pcb->read.octets += len;
+  pcb->read.packets++;
+
   PAN_TRACE_EVENT(
       "pan_data_buf_ind_cb - for handle %d, protocol 0x%x, length %d, ext %d",
       handle, protocol, len, ext);
@@ -447,6 +451,7 @@ void pan_data_buf_ind_cb(uint16_t handle, const RawAddress& src,
       if (result != BNEP_SUCCESS && result != BNEP_IGNORE_CMD)
         PAN_TRACE_ERROR("Failed to write data for PAN connection handle %d",
                         dst_pcb->handle);
+      pcb->read.errors++;
       osi_free(p_buf);
       return;
     }
diff --git a/system/test/mock/mock_stack_pan_api.cc b/system/test/mock/mock_stack_pan_api.cc
index 53a8d088e06..b33e1165a4a 100644
--- a/system/test/mock/mock_stack_pan_api.cc
+++ b/system/test/mock/mock_stack_pan_api.cc
@@ -89,3 +89,4 @@ void PAN_Init(void) { mock_function_count_map[__func__]++; }
 void PAN_Register(tPAN_REGISTER* p_register) {
   mock_function_count_map[__func__]++;
 }
+void PAN_Dumpsys(int fd) { mock_function_count_map[__func__]++; }
-- 
GitLab